tootsearchカラムでは返信元のIDが全く信用できないので投稿を検索してから返信元のIDを調べる

This commit is contained in:
tateisu 2019-09-24 02:02:01 +09:00
parent 9e2d2af14f
commit 6548ebfb83
2 changed files with 131 additions and 56 deletions

View File

@ -479,11 +479,7 @@ internal class ItemViewHolder(
item.hasAnyContent() -> {
// 引用Renote
val colorBg = Pref.ipEventBgColorBoost(activity.pref)
showReply(
R.drawable.ic_repeat,
R.string.renote_to,
reblog
)
showReply(reblog, R.drawable.ic_repeat, R.string.renote_to)
showStatus(item, colorBg)
}
@ -726,16 +722,12 @@ internal class ItemViewHolder(
val in_reply_to_account_id = item.in_reply_to_account_id
when {
reply != null -> {
showReply(
R.drawable.ic_reply,
R.string.reply_to,
reply
)
showReply(reply, R.drawable.ic_reply, R.string.reply_to)
if(colorBgArg == 0) colorBg = Pref.ipEventBgColorMention(activity.pref)
}
in_reply_to_id != null && in_reply_to_account_id != null -> {
showReply(in_reply_to_account_id, item)
showReply(item, in_reply_to_account_id)
if(colorBgArg == 0) colorBg = Pref.ipEventBgColorMention(activity.pref)
}
}
@ -766,11 +758,7 @@ internal class ItemViewHolder(
else -> {
// 引用Renote
showReply(
R.drawable.ic_repeat,
R.string.renote_to,
reblog
)
showReply(reblog, R.drawable.ic_repeat, R.string.renote_to)
showStatus(item, Pref.ipEventBgColorQuote(activity.pref))
}
}
@ -1038,12 +1026,11 @@ internal class ItemViewHolder(
)
}
private fun showReply(
iconId : Int,
text : Spannable
) {
private fun showReply(iconId : Int, text : Spannable) {
llReply.visibility = View.VISIBLE
setIconDrawableId(
activity,
ivReply,
@ -1056,31 +1043,17 @@ internal class ItemViewHolder(
reply_invalidator.register(text)
}
private fun showReply(
iconId : Int,
stringId : Int,
reply : TootStatus
) {
private fun showReply(reply : TootStatus, iconId : Int, stringId : Int) {
status_reply = reply
// val who = reply.account
// showStatusTime(activity, tvReplyTime, who, time = reply.time_created_at)
// setAcct(tvReplyAcct, access_info.getFullAcct(who), who.acct)
val text = reply.accountRef.decoded_display_name.intoStringResource(activity, stringId)
showReply(iconId, text)
showReply(
iconId,
reply.accountRef.decoded_display_name.intoStringResource(activity, stringId)
)
}
private fun showReply(
accountId : EntityId,
reply : TootStatus
) {
status_reply = reply
llReply.visibility = View.VISIBLE
private fun showReply(reply : TootStatus, accountId : EntityId) {
val name = if(accountId == reply.account.id) {
// 自己レスなら
AcctColor.getNicknameWithColor(access_info.getFullAcct(reply.account))
} else {
val m = reply.mentions?.find { it.id == accountId }
@ -1831,12 +1804,19 @@ internal class ItemViewHolder(
llReply -> {
val s = status_reply
if(s != null) {
Action_Toot.conversation(activity, pos, access_info, s)
} else {
val id = status_showing?.in_reply_to_id
if(id != null) {
Action_Toot.conversationLocal(activity, pos, access_info, id)
when {
s != null -> Action_Toot.conversation(activity, pos, access_info, s)
// tootsearchは返信元のIDを取得するのにひと手間必要
column.type == ColumnType.SEARCH_TS ->
Action_Toot.showReplyTootsearch(activity, pos, status_showing)
else -> {
val id = status_showing?.in_reply_to_id
if(id != null) {
Action_Toot.conversationLocal(activity, pos, access_info, id)
}
}
}
}
@ -2019,8 +1999,10 @@ internal class ItemViewHolder(
llReply -> {
val s = status_reply
if(s != null) {
DlgContextMenu(
when {
// 返信元のstatusがあるならコンテキストメニュー
s != null -> DlgContextMenu(
activity,
column,
s.accountRef,
@ -2028,15 +2010,27 @@ internal class ItemViewHolder(
notification,
tvContent
).show()
} else {
val id = status_showing?.in_reply_to_id
if(id != null) {
Action_Toot.conversationLocal(
// それ以外はコンテキストメニューではなく会話を開く
// tootsearchは返信元のIDを取得するのにひと手間必要
column.type == ColumnType.SEARCH_TS ->
Action_Toot.showReplyTootsearch(
activity,
activity.nextPosition(column),
access_info,
id
status_showing
)
else -> {
val id = status_showing?.in_reply_to_id
if(id != null) {
Action_Toot.conversationLocal(
activity,
activity.nextPosition(column),
access_info,
id
)
}
}
}
}

View File

@ -743,7 +743,7 @@ object Action_Toot {
try {
val m = reDetailedStatusTime.matcher(string)
if(m.find()) {
local_status_id = EntityId(m.groupEx(1)!!)
local_status_id = EntityId(m.groupEx(1) !!)
}
} catch(ex : Throwable) {
log.e(ex, "openStatusRemote: can't parse status id from HTML data.")
@ -774,7 +774,88 @@ object Action_Toot {
}
}
})
}
// tootsearchでは返信表記にreplyオブジェクトがない。
// in_reply_to_idを参照するしかない
// ところがtootsearchでは投稿をどのタンスから読んだか分からないので、IDは全面的に信用できない。
// 疑似ではないアカウントを選んだ後に表示中の投稿を検索APIで調べて、そのリプライのIDを取得しなおす
fun showReplyTootsearch(
activity : ActMain,
pos : Int,
status : TootStatus?
) {
status ?: return
// step2: 選択したアカウントで投稿を検索して返信元の投稿のIDを調べる
fun step2(a : SavedAccount) = TootTaskRunner(activity).run(a, object : TootTask {
var tmp:TootStatus? = null
override fun background(client : TootApiClient) : TootApiResult? {
val(result,status)=client.syncStatus(a,status)
this.tmp = status
return result
}
override fun handleResult(result : TootApiResult?) {
result?:return
val status = tmp
val replyId = status?.in_reply_to_id
when {
status ==null -> showToast(activity, true, result.error ?: "?")
replyId == null -> showToast(activity, true, "showReplyTootsearch: in_reply_to_id is null")
else -> conversationLocal(activity,pos,a,replyId)
}
}
})
// step 1: choose account
val dialog = ActionsDialog()
// トゥートの投稿元タンスにあるアカウント
val local_account_list = ArrayList<SavedAccount>()
// その他のタンスにあるアカウント
val other_account_list = ArrayList<SavedAccount>()
val host = status.account.host
for(a in SavedAccount.loadAccountList(activity)) {
// 検索APIはログイン必須なので疑似アカウントは使えない
if(a.isPseudo) continue
if(a.host.equals(host, ignoreCase = true)) {
local_account_list.add(a)
} else {
// 別タンスでも実アカウントなら検索APIでステータスIDを変換できる
other_account_list.add(a)
}
}
SavedAccount.sort(local_account_list)
for(a in local_account_list) {
dialog.addAction(
AcctColor.getStringWithNickname(
activity,
R.string.open_in_account,
a.acct
)
) { step2(a) }
}
SavedAccount.sort(other_account_list)
for(a in other_account_list) {
dialog.addAction(
AcctColor.getStringWithNickname(
activity,
R.string.open_in_account,
a.acct
)
) { step2(a) }
}
dialog.show(activity, activity.getString(R.string.open_status_from))
}
////////////////////////////////////////