mirror of
https://github.com/tateisu/SubwayTooter
synced 2025-02-05 21:23:26 +01:00
Account.note中のメンションのacctに表示対象アカウントのドメイン名を補う
This commit is contained in:
parent
71d16a79ca
commit
4cd5fc8365
@ -138,10 +138,10 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
|
||||
this.apiHost = src.string("host")?.let { Host.parse(it) }
|
||||
?: parser.apiHost
|
||||
?: error("missing host")
|
||||
|
||||
?: error("missing host")
|
||||
|
||||
this.url = "https://${apiHost.ascii}/@$username"
|
||||
|
||||
|
||||
this.apDomain = apiHost // FIXME apiHostとapDomainが異なる場合はMisskeyだとどうなの…?
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
@ -175,7 +175,7 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
|
||||
this.id = EntityId.mayDefault(src.string("id"))
|
||||
|
||||
|
||||
|
||||
this.followers_count = src.long("followersCount") ?: - 1L
|
||||
this.following_count = src.long("followingCount") ?: - 1L
|
||||
this.statuses_count = src.long("notesCount") ?: - 1L
|
||||
@ -264,7 +264,7 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
|
||||
val tmpAcct = src.stringOrThrow("acct")
|
||||
|
||||
val(apiHost,apDomain) = findHostFromUrl(tmpAcct, parser.linkHelper, url)
|
||||
val (apiHost, apDomain) = findHostFromUrl(tmpAcct, parser.linkHelper, url)
|
||||
apiHost ?: error("can't get apiHost from acct or url")
|
||||
apDomain ?: error("can't get apDomain from acct or url")
|
||||
this.apiHost = apiHost
|
||||
@ -292,7 +292,7 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
|
||||
val tmpAcct = src.stringOrThrow("acct")
|
||||
|
||||
val(apiHost,apDomain) = findHostFromUrl(tmpAcct, null, url)
|
||||
val (apiHost, apDomain) = findHostFromUrl(tmpAcct, null, url)
|
||||
apiHost ?: error("can't get apiHost from acct or url")
|
||||
apDomain ?: error("can't get apDomain from acct or url")
|
||||
this.apiHost = apiHost
|
||||
@ -317,7 +317,7 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
this.id = EntityId.mayDefault(src.string("id"))
|
||||
|
||||
// MSPはLTLの情報しか持ってないのでacctは常にホスト名部分を持たない
|
||||
val(apiHost,apDomain) = findHostFromUrl(null,null, url)
|
||||
val (apiHost, apDomain) = findHostFromUrl(null, null, url)
|
||||
apiHost ?: error("can't get apiHost from acct or url")
|
||||
apDomain ?: error("can't get apDomain from acct or url")
|
||||
|
||||
@ -347,6 +347,7 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
}
|
||||
|
||||
class Source(src : JsonObject) {
|
||||
|
||||
// デフォルト公開範囲
|
||||
val privacy : String?
|
||||
|
||||
@ -458,7 +459,8 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
decodeEmoji = true,
|
||||
emojiMapProfile = profile_emojis,
|
||||
emojiMapCustom = custom_emojis,
|
||||
unwrapEmojiImageTag = true
|
||||
unwrapEmojiImageTag = true,
|
||||
mentionDefaultDomain = apDomain,
|
||||
).decodeHTML(note)
|
||||
.replaceAllEx(reNoteLineFeed, " ")
|
||||
.trimEx()
|
||||
@ -486,6 +488,7 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val log = LogCategory("TootAccount")
|
||||
|
||||
internal val reWhitespace = "[\\s\\t\\x0d\\x0a]+".asciiPattern()
|
||||
@ -544,7 +547,7 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
// MisskeyのMFMはIDNをサポートしていない
|
||||
private val reMisskeyMentionBase = """@(\w+(?:[\w-]*\w)?)(?:@($reMisskeyHost))?"""
|
||||
.asciiPattern()
|
||||
|
||||
|
||||
// MFMパース時に使う
|
||||
internal val reMisskeyMentionMFM = """\A$reMisskeyMentionBase"""
|
||||
.asciiPattern()
|
||||
@ -597,34 +600,37 @@ open class TootAccount(parser : TootParser, src : JsonObject) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun findApDomain(acctArg : String?, linkHelper : LinkHelper?):Host?{
|
||||
private fun findApDomain(acctArg : String?, linkHelper : LinkHelper?) : Host? {
|
||||
// acctから調べる
|
||||
if(acctArg != null) {
|
||||
val acct = Acct.parse(acctArg)
|
||||
if(acct.host != null) return acct.host
|
||||
}
|
||||
|
||||
|
||||
// Acctはnullか、hostを含まない
|
||||
if(linkHelper != null) return linkHelper.apDomain
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun findApiHost( url:String?):Host?{
|
||||
private fun findApiHost(url : String?) : Host? {
|
||||
// URLから調べる
|
||||
// たぶんどんなURLでもauthorityの部分にホスト名が来るだろう(慢心)
|
||||
url.mayUri()?.authority?.notEmpty()?.let { return Host.parse(it) }
|
||||
|
||||
|
||||
log.e("findApiHost: can't parse host from URL $url")
|
||||
return null
|
||||
}
|
||||
|
||||
// Tootsearch用。URLやUriを使ってアカウントのインスタンス名を調べる
|
||||
fun findHostFromUrl(acctArg : String?, linkHelper : LinkHelper?, url : String?) : Pair<Host?,Host?> {
|
||||
val apDomain = findApDomain(acctArg,linkHelper)
|
||||
fun findHostFromUrl(
|
||||
acctArg : String?,
|
||||
linkHelper : LinkHelper?,
|
||||
url : String?
|
||||
) : Pair<Host?, Host?> {
|
||||
val apDomain = findApDomain(acctArg, linkHelper)
|
||||
val apiHost = findApiHost(url)
|
||||
return Pair( apiHost?: apDomain, apDomain ?: apiHost )
|
||||
return Pair(apiHost ?: apDomain, apDomain ?: apiHost)
|
||||
}
|
||||
|
||||
fun parseFields(src : JsonArray?) : ArrayList<Field>? {
|
||||
|
@ -26,7 +26,8 @@ class TootAccountRef(parser: TootParser, account:TootAccount) : TimelineItem() {
|
||||
decodeEmoji = true,
|
||||
emojiMapProfile = account.profile_emojis,
|
||||
emojiMapCustom = account.custom_emojis,
|
||||
unwrapEmojiImageTag = true
|
||||
unwrapEmojiImageTag = true,
|
||||
mentionDefaultDomain = account.apDomain,
|
||||
).decodeHTML(account.note)
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,7 @@ import android.content.Context
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.ReplacementSpan
|
||||
import jp.juggler.subwaytooter.api.entity.CustomEmoji
|
||||
import jp.juggler.subwaytooter.api.entity.NicoProfileEmoji
|
||||
import jp.juggler.subwaytooter.api.entity.TootAttachmentLike
|
||||
import jp.juggler.subwaytooter.api.entity.TootMention
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
import jp.juggler.subwaytooter.table.HighlightWord
|
||||
import jp.juggler.util.WordTrieTree
|
||||
import java.util.*
|
||||
@ -27,7 +24,9 @@ class DecodeOptions(
|
||||
var enlargeEmoji : Float = 1f,
|
||||
var forceHtml : Boolean = false, // force use HTML instead of Misskey Markdown
|
||||
var mentionFullAcct : Boolean = false,
|
||||
var mentions : ArrayList<TootMention>? = null
|
||||
var mentions : ArrayList<TootMention>? = null,
|
||||
// Account.note などmentionsがない状況でメンションリンクをfull acct化するにはアカウント等からapDomainを補う必要がある
|
||||
var mentionDefaultDomain : Host? = null,
|
||||
) {
|
||||
|
||||
internal fun isMediaAttachment(url : String?) : Boolean {
|
||||
|
@ -607,8 +607,15 @@ object HTMLDecoder {
|
||||
|
||||
// Account.note does not have mentions metadata.
|
||||
// fallback to resolve acct by mention URL.
|
||||
val rawAcct = mention?.acct ?: Acct.parse(originalCaption.toString().substring(1))
|
||||
val fullAcct = getFullAcctOrNull(options.linkHelper, rawAcct, href)
|
||||
val rawAcct = mention?.acct
|
||||
?: Acct.parse(originalCaption.toString().substring(1))
|
||||
|
||||
val fullAcct = getFullAcctOrNull(
|
||||
options.linkHelper,
|
||||
rawAcct,
|
||||
href,
|
||||
mentionDefaultDomain = options.mentionDefaultDomain
|
||||
)
|
||||
|
||||
if(fullAcct != null) {
|
||||
|
||||
|
@ -3,8 +3,10 @@ package jp.juggler.subwaytooter.util
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
import jp.juggler.subwaytooter.api.entity.Host
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccount
|
||||
import jp.juggler.subwaytooter.api.entity.TootMention
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.util.groupEx
|
||||
import java.util.ArrayList
|
||||
|
||||
interface LinkHelper {
|
||||
|
||||
@ -104,16 +106,21 @@ fun getFullAcctOrNull(
|
||||
fun getFullAcctOrNull(
|
||||
linkHelper : LinkHelper?,
|
||||
src : Acct,
|
||||
url : String
|
||||
url : String,
|
||||
mentionDefaultDomain: Host? = null
|
||||
) : Acct? {
|
||||
|
||||
// 既にFull Acctだった
|
||||
if(src.host != null) return src
|
||||
|
||||
val apDomain = linkHelper?.apDomain
|
||||
// Account.noteなどメンション情報が含まれない場合、デフォルトのドメインは投稿者のドメインである
|
||||
if(mentionDefaultDomain!=null){
|
||||
return src.followHost( mentionDefaultDomain)
|
||||
}
|
||||
|
||||
// トゥート検索等でないならアクセス元ホストを補って良いはず
|
||||
if(linkHelper is SavedAccount && ! linkHelper.isNA && apDomain != null) {
|
||||
val apDomain = linkHelper?.apDomain
|
||||
if(apDomain != null && linkHelper is SavedAccount && ! linkHelper.isNA ) {
|
||||
return Acct.parse(src.username, apDomain)
|
||||
}
|
||||
|
||||
|
@ -831,6 +831,7 @@ object MisskeyMarkdownDecoder {
|
||||
) {
|
||||
// ユーザが記述したacct
|
||||
val rawAcct = Acct.parse(username, strHost)
|
||||
.followHost(options.mentionDefaultDomain)
|
||||
|
||||
val linkHelper = linkHelper
|
||||
if(linkHelper == null) {
|
||||
|
@ -11,6 +11,7 @@ import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import java.util.*
|
||||
|
||||
object TootTextEncoder {
|
||||
|
||||
private fun StringBuilder.addAfterLine(text : CharSequence) {
|
||||
if(isNotEmpty() && this[length - 1] != '\n') {
|
||||
append('\n')
|
||||
@ -268,7 +269,13 @@ object TootTextEncoder {
|
||||
|
||||
sb.addAfterLine("\n")
|
||||
|
||||
sb.append(DecodeOptions(context, access_info).decodeHTML(who.note))
|
||||
sb.append(
|
||||
DecodeOptions(
|
||||
context,
|
||||
access_info,
|
||||
mentionDefaultDomain = who.apDomain
|
||||
).decodeHTML(who.note)
|
||||
)
|
||||
|
||||
sb.addAfterLine("\n")
|
||||
|
||||
@ -294,7 +301,7 @@ object TootTextEncoder {
|
||||
addHeader(context, sb, R.string.send_header_account_created_at, who.created_at)
|
||||
addHeader(context, sb, R.string.send_header_account_statuses_count, who.statuses_count)
|
||||
|
||||
if(! Pref.bpHideFollowCount( App1.getAppState(context).pref)) {
|
||||
if(! Pref.bpHideFollowCount(App1.getAppState(context).pref)) {
|
||||
addHeader(
|
||||
context,
|
||||
sb,
|
||||
|
Loading…
x
Reference in New Issue
Block a user