アカウント追加時のサーバ名入力でIDNドメインを入力補完する。カラムヘッダにprettyAcctを表示する。
This commit is contained in:
parent
7f159a191c
commit
0201e0027f
|
@ -1178,7 +1178,7 @@ class ColumnViewHolder(
|
||||||
tvColumnContext.text = if(nickname != null && nickname.isNotEmpty())
|
tvColumnContext.text = if(nickname != null && nickname.isNotEmpty())
|
||||||
nickname
|
nickname
|
||||||
else
|
else
|
||||||
acct
|
column.access_info.prettyAcct
|
||||||
|
|
||||||
|
|
||||||
tvColumnContext.setTextColor(
|
tvColumnContext.setTextColor(
|
||||||
|
|
|
@ -14,6 +14,7 @@ import jp.juggler.util.LogCategory
|
||||||
import jp.juggler.util.showToast
|
import jp.juggler.util.showToast
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
|
import java.net.IDN
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object LoginForm {
|
object LoginForm {
|
||||||
|
@ -111,31 +112,35 @@ object LoginForm {
|
||||||
showToast(activity, true, R.string.instance_not_need_slash)
|
showToast(activity, true, R.string.instance_not_need_slash)
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
|
val instanceAscii = IDN.toASCII(instance,IDN.ALLOW_UNASSIGNED)
|
||||||
val actionPos = spAction.selectedItemPosition
|
val actionPos = spAction.selectedItemPosition
|
||||||
when(val action = Action.values().find { it.pos == actionPos }) {
|
when(val action = Action.values().find { it.pos == actionPos }) {
|
||||||
null -> {
|
null -> {
|
||||||
} // will no happened
|
} // will no happened
|
||||||
else -> onClickOk(dialog, instance, action)
|
else -> onClickOk(dialog, instanceAscii, action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.findViewById<View>(R.id.btnCancel).setOnClickListener { dialog.cancel() }
|
view.findViewById<View>(R.id.btnCancel).setOnClickListener { dialog.cancel() }
|
||||||
|
|
||||||
val instance_list = ArrayList<String>()
|
val instance_list = HashSet<String>().apply{
|
||||||
try {
|
try {
|
||||||
activity.resources.openRawResource(R.raw.server_list).use { inStream ->
|
activity.resources.openRawResource(R.raw.server_list).use { inStream ->
|
||||||
val br = BufferedReader(InputStreamReader(inStream, "UTF-8"))
|
val br = BufferedReader(InputStreamReader(inStream, "UTF-8"))
|
||||||
while(true) {
|
while(true) {
|
||||||
val s : String =
|
val s : String =
|
||||||
br.readLine()?.trim { it <= ' ' }?.toLowerCase(Locale.JAPAN) ?: break
|
br.readLine()?.trim { it <= ' ' }?.toLowerCase(Locale.JAPAN) ?: break
|
||||||
if(s.isNotEmpty()) instance_list.add(s)
|
if(s.isEmpty()) continue
|
||||||
|
add(s)
|
||||||
|
add(IDN.toASCII(s,IDN.ALLOW_UNASSIGNED))
|
||||||
|
add(IDN.toUnicode(s,IDN.ALLOW_UNASSIGNED))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch(ex : Throwable) {
|
||||||
|
log.trace(ex)
|
||||||
}
|
}
|
||||||
instance_list.sort()
|
}.toList().sorted()
|
||||||
} catch(ex : Throwable) {
|
|
||||||
log.trace(ex)
|
|
||||||
}
|
|
||||||
|
|
||||||
val adapter = object : ArrayAdapter<String>(
|
val adapter = object : ArrayAdapter<String>(
|
||||||
activity, R.layout.lv_spinner_dropdown, ArrayList()
|
activity, R.layout.lv_spinner_dropdown, ArrayList()
|
||||||
|
@ -146,23 +151,22 @@ object LoginForm {
|
||||||
return value as String
|
return value as String
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun performFiltering(constraint : CharSequence?) : FilterResults {
|
override fun performFiltering(constraint : CharSequence?) : FilterResults =
|
||||||
val result = FilterResults()
|
FilterResults().also { result ->
|
||||||
if(constraint?.isNotEmpty() == true) {
|
if(constraint?.isNotEmpty() == true) {
|
||||||
val key = constraint.toString().toLowerCase(Locale.JAPAN)
|
val key = constraint.toString().toLowerCase(Locale.JAPAN)
|
||||||
// suggestions リストは毎回生成する必要がある。publishResultsと同時にアクセスされる場合がある
|
// suggestions リストは毎回生成する必要がある。publishResultsと同時にアクセスされる場合がある
|
||||||
val suggestions = StringArray()
|
val suggestions = StringArray()
|
||||||
for(s in instance_list) {
|
for(s in instance_list) {
|
||||||
if(s.contains(key)) {
|
if(s.contains(key)) {
|
||||||
suggestions.add(s)
|
suggestions.add(s)
|
||||||
if(suggestions.size >= 20) break
|
if(suggestions.size >= 20) break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
result.values = suggestions
|
||||||
|
result.count = suggestions.size
|
||||||
}
|
}
|
||||||
result.values = suggestions
|
|
||||||
result.count = suggestions.size
|
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun publishResults(
|
override fun publishResults(
|
||||||
constraint : CharSequence?,
|
constraint : CharSequence?,
|
||||||
|
|
|
@ -16,6 +16,7 @@ import jp.juggler.subwaytooter.api.entity.TootNotification
|
||||||
import jp.juggler.subwaytooter.api.entity.TootVisibility
|
import jp.juggler.subwaytooter.api.entity.TootVisibility
|
||||||
import jp.juggler.subwaytooter.util.LinkHelper
|
import jp.juggler.subwaytooter.util.LinkHelper
|
||||||
import jp.juggler.util.*
|
import jp.juggler.util.*
|
||||||
|
import java.net.IDN
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
@ -69,13 +70,18 @@ class SavedAccount(
|
||||||
var last_subscription_error : String? = null
|
var last_subscription_error : String? = null
|
||||||
var last_push_endpoint : String? = null
|
var last_push_endpoint : String? = null
|
||||||
|
|
||||||
|
val prettyAcct :String
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val pos = acct.indexOf('@')
|
val pos = acct.indexOf('@')
|
||||||
if(pos == - 1) {
|
if(pos == - 1) {
|
||||||
this.username = acct
|
this.username = acct
|
||||||
|
prettyAcct = acct
|
||||||
} else {
|
} else {
|
||||||
this.username = acct.substring(0, pos)
|
this.username = acct.substring(0, pos)
|
||||||
|
prettyAcct = username+"@"+IDN.toUnicode(acct.substring(pos+1),IDN.ALLOW_UNASSIGNED)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(username.isEmpty()) throw RuntimeException("missing username in acct")
|
if(username.isEmpty()) throw RuntimeException("missing username in acct")
|
||||||
|
|
||||||
this.host = if(hostArg != null && hostArg.isNotEmpty()) {
|
this.host = if(hostArg != null && hostArg.isNotEmpty()) {
|
||||||
|
|
|
@ -10073,3 +10073,4 @@ zuyadon.tk
|
||||||
zwitscher.l-uni.co
|
zwitscher.l-uni.co
|
||||||
zxc.st
|
zxc.st
|
||||||
zzz.cat
|
zzz.cat
|
||||||
|
xn--3-pfuzbe6htf.juggler.jp
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package jp.juggler.subwaytooter
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import java.net.IDN
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class TestIDN {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(Exception::class)
|
||||||
|
fun testIDN() {
|
||||||
|
// normal conversion
|
||||||
|
assertEquals("xn--3-pfuzbe6htf.juggler.jp", IDN.toASCII("マストドン3.juggler.jp",IDN.ALLOW_UNASSIGNED))
|
||||||
|
assertEquals("マストドン3.juggler.jp", IDN.toUnicode("xn--3-pfuzbe6htf.juggler.jp",IDN.ALLOW_UNASSIGNED))
|
||||||
|
|
||||||
|
// not IDN domain
|
||||||
|
assertEquals("mastodon.juggler.jp", IDN.toASCII("mastodon.juggler.jp",IDN.ALLOW_UNASSIGNED))
|
||||||
|
assertEquals("mastodon.juggler.jp", IDN.toUnicode("mastodon.juggler.jp",IDN.ALLOW_UNASSIGNED))
|
||||||
|
|
||||||
|
// 既に変換済みの引数
|
||||||
|
assertEquals("xn--3-pfuzbe6htf.juggler.jp", IDN.toASCII("xn--3-pfuzbe6htf.juggler.jp",IDN.ALLOW_UNASSIGNED))
|
||||||
|
assertEquals("マストドン3.juggler.jp", IDN.toUnicode("マストドン3.juggler.jp",IDN.ALLOW_UNASSIGNED))
|
||||||
|
|
||||||
|
// 複数のpunycode
|
||||||
|
assertEquals("թութ.հայ", IDN.toUnicode("xn--69aa8bzb.xn--y9a3aq",IDN.ALLOW_UNASSIGNED))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue