メンションの入力補完でIDNドメインを選択するとpunycodeを入力する。MMFパーサはデコード結果にIDNドメインを使う。
This commit is contained in:
parent
36b86e4471
commit
6ae0ef4df9
|
@ -744,7 +744,8 @@ class ActPost : AppCompatActivity(),
|
|||
sv = intent.getStringExtra(KEY_REPLY_STATUS)
|
||||
if(sv != null && account != null) {
|
||||
try {
|
||||
val reply_status = TootParser(this@ActPost, account).status(sv.decodeJsonObject())
|
||||
val reply_status =
|
||||
TootParser(this@ActPost, account).status(sv.decodeJsonObject())
|
||||
|
||||
val isQuoterRenote = intent.getBooleanExtra(KEY_QUOTED_RENOTE, false)
|
||||
|
||||
|
@ -764,12 +765,12 @@ class ActPost : AppCompatActivity(),
|
|||
}
|
||||
|
||||
// 新しいメンションリスト
|
||||
val mention_list = ArrayList<String>()
|
||||
val mention_list = ArrayList<Acct>()
|
||||
|
||||
// 自己レス以外なら元レスへのメンションを追加
|
||||
// 最初に追加する https://github.com/tateisu/SubwayTooter/issues/94
|
||||
if(! account.isMe(reply_status.account)) {
|
||||
mention_list.add("@${account.getFullAcct(reply_status.account).pretty}")
|
||||
mention_list.add(account.getFullAcct(reply_status.account))
|
||||
}
|
||||
|
||||
// 元レスに含まれていたメンションを複製
|
||||
|
@ -783,16 +784,9 @@ class ActPost : AppCompatActivity(),
|
|||
// 自分なら追加しない
|
||||
if(account.isMe(who_acct)) return@forEach
|
||||
|
||||
// 既出なら追加しない
|
||||
val strMention = "@${account.getFullAcct(who_acct).pretty}"
|
||||
if(mention_list.contains(strMention)) return@forEach
|
||||
mention_list.add(strMention)
|
||||
|
||||
/*
|
||||
FIXME インスタンスのバージョンが3.1.0 以降ならメンションのホスト部分にIDNドメインを使いたいが、
|
||||
投稿画面でのアカウント切り替え時にタンスのバージョンが異なると破綻する可能性が高い。
|
||||
*/
|
||||
|
||||
// 既出でないなら追加する
|
||||
val acct = account.getFullAcct(who_acct)
|
||||
if(! mention_list.contains(acct)) mention_list.add(acct)
|
||||
}
|
||||
|
||||
if(mention_list.isNotEmpty()) {
|
||||
|
@ -800,7 +794,7 @@ class ActPost : AppCompatActivity(),
|
|||
StringBuilder().apply {
|
||||
for(acct in mention_list) {
|
||||
if(isNotEmpty()) append(' ')
|
||||
append(acct)
|
||||
append("@${acct.ascii}")
|
||||
}
|
||||
append(' ')
|
||||
}.toString()
|
||||
|
@ -852,7 +846,8 @@ class ActPost : AppCompatActivity(),
|
|||
sv = intent.getStringExtra(KEY_REDRAFT_STATUS)
|
||||
if(sv != null && account != null) {
|
||||
try {
|
||||
val base_status = TootParser(this@ActPost, account).status(sv.decodeJsonObject())
|
||||
val base_status =
|
||||
TootParser(this@ActPost, account).status(sv.decodeJsonObject())
|
||||
if(base_status != null) {
|
||||
|
||||
redraft_status_id = base_status.id
|
||||
|
|
|
@ -632,7 +632,9 @@ object Action_User {
|
|||
|
||||
// メンションを含むトゥートを作る
|
||||
private fun mention(
|
||||
activity : ActMain, account : SavedAccount, initial_text : String
|
||||
activity : ActMain,
|
||||
account : SavedAccount,
|
||||
initial_text : String
|
||||
) {
|
||||
ActPost.open(
|
||||
activity,
|
||||
|
@ -646,7 +648,7 @@ object Action_User {
|
|||
fun mention(
|
||||
activity : ActMain, account : SavedAccount, who : TootAccount
|
||||
) {
|
||||
mention(activity, account, "@${account.getFullAcct(who).pretty} ")
|
||||
mention(activity, account, "@${account.getFullAcct(who).ascii} ")
|
||||
}
|
||||
|
||||
// メンションを含むトゥートを作る
|
||||
|
@ -656,7 +658,7 @@ object Action_User {
|
|||
if(who == null) return
|
||||
val who_host = who.host
|
||||
|
||||
val initial_text = "@${access_info.getFullAcct(who).pretty} "
|
||||
val initial_text = "@${access_info.getFullAcct(who).ascii} "
|
||||
AccountPicker.pick(
|
||||
activity,
|
||||
bAllowPseudo = false,
|
||||
|
|
|
@ -12,9 +12,12 @@ import android.text.style.StrikethroughSpan
|
|||
import android.util.SparseArray
|
||||
import android.util.SparseBooleanArray
|
||||
import jp.juggler.subwaytooter.ActMain
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccount
|
||||
import jp.juggler.subwaytooter.api.entity.TootMention
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
import jp.juggler.subwaytooter.api.entity.Host
|
||||
import jp.juggler.subwaytooter.span.*
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.HighlightWord
|
||||
|
@ -844,38 +847,25 @@ object MisskeyMarkdownDecoder {
|
|||
|
||||
MENTION({
|
||||
val username = it.args[0]
|
||||
val host = it.args[1]
|
||||
val strHost = it.args[1].notEmpty()
|
||||
val rawAcct = Acct.parse(username, strHost?.let{ Host.parse(it)})
|
||||
val linkHelper = linkHelper
|
||||
if(linkHelper == null) {
|
||||
appendText(
|
||||
when {
|
||||
host.isEmpty() -> "@$username"
|
||||
else -> "@$username@$host"
|
||||
}
|
||||
|
||||
)
|
||||
appendText("@${rawAcct.pretty}")
|
||||
} else {
|
||||
|
||||
when(
|
||||
val userHost = (host.notEmpty()
|
||||
?: linkHelper.host?.ascii
|
||||
?: "?"
|
||||
).toLowerCase(Locale.JAPAN)
|
||||
) {
|
||||
|
||||
when( strHost ){
|
||||
// https://github.com/syuilo/misskey/pull/3603
|
||||
|
||||
"github.com", "twitter.com" -> {
|
||||
appendLink(
|
||||
"@$username@$userHost",
|
||||
"https://$userHost/$username" // no @
|
||||
"@${rawAcct.pretty}",
|
||||
"https://$strHost/$username" // no @
|
||||
)
|
||||
}
|
||||
|
||||
"gmail.com" -> {
|
||||
appendLink(
|
||||
"@$username@$userHost",
|
||||
"mailto:$username@$userHost"
|
||||
"@${rawAcct.pretty}",
|
||||
"mailto:$username@$strHost"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -883,23 +873,25 @@ object MisskeyMarkdownDecoder {
|
|||
// MFMはメンションからユーザのURIを調べる正式な方法がない
|
||||
// たとえば @group_dev_jp@gup.pe の正式なURLは https://gup.pe/u/group_dev_jp
|
||||
// だが、 misskey.io ではメンションのリンク先は https://misskey.io/@group_dev_jp@gup.pe になる
|
||||
val userUrl = "https://$userHost/@$username"
|
||||
|
||||
val shortAcct = when {
|
||||
val fullAcct = rawAcct.followHost(linkHelper.host)
|
||||
|
||||
host.isEmpty() || linkHelper.host?.match(host) == true -> username
|
||||
|
||||
else -> "$username@$host"
|
||||
val shortAcct = if(fullAcct.host != linkHelper.host) {
|
||||
fullAcct
|
||||
} else {
|
||||
Acct.parse(username)
|
||||
}
|
||||
|
||||
val userUrl = "https://${fullAcct.ascii}/@${username.encodePercent()}"
|
||||
|
||||
val mentions = prepareMentions()
|
||||
|
||||
if(null == mentions.find { m -> m.acct.ascii == shortAcct || m.acct.pretty == shortAcct }) {
|
||||
if(null == mentions.find { m -> m.acct == shortAcct }) {
|
||||
mentions.add(
|
||||
TootMention(
|
||||
jp.juggler.subwaytooter.api.entity.EntityId.DEFAULT
|
||||
, userUrl
|
||||
, shortAcct
|
||||
, shortAcct.ascii
|
||||
, username
|
||||
)
|
||||
)
|
||||
|
@ -907,9 +899,11 @@ object MisskeyMarkdownDecoder {
|
|||
|
||||
appendLink(
|
||||
when {
|
||||
jp.juggler.subwaytooter.Pref.bpMentionFullAcct(jp.juggler.subwaytooter.App1.pref) ->
|
||||
"@$username@$userHost"
|
||||
else -> "@$shortAcct"
|
||||
Pref.bpMentionFullAcct(jp.juggler.subwaytooter.App1.pref) ->
|
||||
"@${fullAcct.pretty}"
|
||||
else -> {
|
||||
"@${rawAcct.pretty}"
|
||||
}
|
||||
}
|
||||
, userUrl
|
||||
)
|
||||
|
|
|
@ -15,12 +15,14 @@ import android.widget.LinearLayout
|
|||
import android.widget.PopupWindow
|
||||
import jp.juggler.subwaytooter.Pref
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
import jp.juggler.subwaytooter.view.MyEditText
|
||||
import jp.juggler.util.LogCategory
|
||||
import jp.juggler.util.getAttributeColor
|
||||
import jp.juggler.util.groupEx
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.math.min
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
internal class PopupAutoCompleteAcct(
|
||||
|
@ -135,8 +137,8 @@ internal class PopupAutoCompleteAcct(
|
|||
val sb = SpannableStringBuilder()
|
||||
|
||||
val src_length = editable.length
|
||||
start = Math.min(src_length, sel_start)
|
||||
val end = Math.min(src_length, sel_end)
|
||||
start = min(src_length, sel_start)
|
||||
val end = min(src_length, sel_end)
|
||||
sb.append(editable.subSequence(0, start))
|
||||
val remain = editable.subSequence(end, src_length)
|
||||
|
||||
|
@ -147,8 +149,13 @@ internal class PopupAutoCompleteAcct(
|
|||
sb.append(findShortCode(acct.toString()))
|
||||
// セパレータにZWSPを使う設定なら、補完した次の位置にもZWSPを追加する。連続して入力補完できるようになる。
|
||||
if( separator != ' ') sb.append(separator)
|
||||
} else if(acct[0] == '@' && null != acct.find{ it >= 0x80.toChar() } ) {
|
||||
// @user@host IDNドメインを含む
|
||||
// 直後に空白を付与する
|
||||
sb.append("@" + Acct.parse(acct.toString().substring(1)).ascii).append(" ")
|
||||
}else{
|
||||
// @user@host, #hashtag
|
||||
// @user@host
|
||||
// #hashtag
|
||||
// 直後に空白を付与する
|
||||
sb.append(acct).append(" ")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue