アカウント情報を再利用してメモリ消費を軽減する
This commit is contained in:
parent
f1c602704c
commit
77bebca288
|
@ -328,7 +328,7 @@ class Column(
|
|||
|
||||
// プロフカラムでのアカウント情報
|
||||
@Volatile
|
||||
internal var who_account : TootAccount? = null
|
||||
internal var who_account : TootAccountRef? = null
|
||||
|
||||
// リストカラムでのリスト情報
|
||||
@Volatile
|
||||
|
@ -612,13 +612,16 @@ class Column(
|
|||
internal fun getColumnName(bLong : Boolean) : String {
|
||||
return when(column_type) {
|
||||
|
||||
TYPE_PROFILE -> context.getString(
|
||||
R.string.profile_of,
|
||||
if(who_account != null)
|
||||
AcctColor.getNickname(access_info.getFullAcct(who_account))
|
||||
else
|
||||
profile_id.toString()
|
||||
)
|
||||
TYPE_PROFILE -> {
|
||||
val who = who_account?.find()
|
||||
context.getString(
|
||||
R.string.profile_of,
|
||||
if(who != null)
|
||||
AcctColor.getNickname(access_info.getFullAcct(who))
|
||||
else
|
||||
profile_id.toString()
|
||||
)
|
||||
}
|
||||
|
||||
TYPE_LIST_MEMBER -> context.getString(
|
||||
R.string.list_member_of,
|
||||
|
@ -748,8 +751,8 @@ class Column(
|
|||
if(who_id == (o.account?.id ?: INVALID_ACCOUNT)) continue
|
||||
if(who_id == (o.status?.account?.id ?: INVALID_ACCOUNT)) continue
|
||||
if(who_id == (o.status?.reblog?.account?.id ?: INVALID_ACCOUNT)) continue
|
||||
} else if(o is TootAccount) {
|
||||
if(who_id == o.id) continue
|
||||
} else if(o is TootAccountRef) {
|
||||
if(who_id == o.find().id) continue
|
||||
}
|
||||
|
||||
tmp_list.add(o)
|
||||
|
@ -767,8 +770,8 @@ class Column(
|
|||
if(column_type == TYPE_MUTES && target_account.acct == access_info.acct) {
|
||||
val tmp_list = ArrayList<TimelineItem>(list_data.size)
|
||||
for(o in list_data) {
|
||||
if(o is TootAccount) {
|
||||
if(o.id == who_id) continue
|
||||
if(o is TootAccountRef) {
|
||||
if(o.find().id == who_id) continue
|
||||
}
|
||||
tmp_list.add(o)
|
||||
}
|
||||
|
@ -785,8 +788,8 @@ class Column(
|
|||
if(column_type == TYPE_BLOCKS && target_account.acct == access_info.acct) {
|
||||
val tmp_list = ArrayList<TimelineItem>(list_data.size)
|
||||
for(o in list_data) {
|
||||
if(o is TootAccount) {
|
||||
if(o.id == who_id) continue
|
||||
if(o is TootAccountRef) {
|
||||
if(o.find().id == who_id) continue
|
||||
}
|
||||
tmp_list.add(o)
|
||||
}
|
||||
|
@ -805,8 +808,8 @@ class Column(
|
|||
if(column_type == TYPE_FOLLOW_REQUESTS) {
|
||||
val tmp_list = ArrayList<TimelineItem>(list_data.size)
|
||||
for(o in list_data) {
|
||||
if(o is TootAccount) {
|
||||
if(o.id == who_id) continue
|
||||
if(o is TootAccountRef) {
|
||||
if(o.find().id == who_id) continue
|
||||
}
|
||||
tmp_list.add(o)
|
||||
}
|
||||
|
@ -1259,7 +1262,8 @@ class Column(
|
|||
internal fun loadProfileAccount(client : TootApiClient, bForceReload : Boolean) {
|
||||
if(bForceReload || this.who_account == null) {
|
||||
val result = client.request(String.format(Locale.JAPAN, PATH_ACCOUNT, profile_id))
|
||||
val a = TootParser(context, access_info).account(result?.jsonObject)
|
||||
val parser =TootParser(context, access_info)
|
||||
val a = TootAccountRef.mayNull(parser,parser.account(result?.jsonObject))
|
||||
if(a != null) {
|
||||
this.who_account = a
|
||||
client.publishApiProgress("") // カラムヘッダの再表示
|
||||
|
@ -1286,24 +1290,28 @@ class Column(
|
|||
internal val acct_set = HashSet<String>()
|
||||
internal val tag_set = HashSet<String>()
|
||||
|
||||
internal fun add(a : TootAccount?) {
|
||||
if(a == null) return
|
||||
who_set.add(a.id)
|
||||
acct_set.add("@" + access_info.getFullAcct(a))
|
||||
//
|
||||
add(a.moved)
|
||||
internal fun add(whoRef : TootAccountRef?) {
|
||||
add(whoRef?.find())
|
||||
}
|
||||
|
||||
|
||||
internal fun add(who : TootAccount?) {
|
||||
who?:return
|
||||
who_set.add(who.id)
|
||||
acct_set.add("@" + access_info.getFullAcct(who))
|
||||
//
|
||||
add(who.movedRef)
|
||||
}
|
||||
|
||||
internal fun add(s : TootStatus?) {
|
||||
if(s == null) return
|
||||
add(s.account)
|
||||
add(s.accountRef)
|
||||
add(s.reblog)
|
||||
s.tags?.forEach { tag_set.add(it.name) }
|
||||
}
|
||||
|
||||
internal fun add(n : TootNotification?) {
|
||||
if(n == null) return
|
||||
add(n.account)
|
||||
add(n.accountRef)
|
||||
add(n.status)
|
||||
}
|
||||
|
||||
|
@ -1382,17 +1390,17 @@ class Column(
|
|||
private fun updateRelation(
|
||||
client : TootApiClient,
|
||||
list : ArrayList<TimelineItem>?,
|
||||
who : TootAccount?
|
||||
whoRef : TootAccountRef?
|
||||
) {
|
||||
if(access_info.isPseudo) return
|
||||
|
||||
val env = UpdateRelationEnv()
|
||||
|
||||
env.add(who)
|
||||
env.add(whoRef)
|
||||
|
||||
list?.forEach {
|
||||
when(it) {
|
||||
is TootAccount -> env.add(it)
|
||||
is TootAccountRef -> env.add(it)
|
||||
is TootStatus -> env.add(it)
|
||||
is TootNotification -> env.add(it)
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import jp.juggler.subwaytooter.action.Action_Instance
|
|||
import jp.juggler.subwaytooter.action.Action_Notification
|
||||
import jp.juggler.subwaytooter.action.Action_Toot
|
||||
import jp.juggler.subwaytooter.action.Action_User
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccount
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccountRef
|
||||
import jp.juggler.subwaytooter.api.entity.TootNotification
|
||||
import jp.juggler.subwaytooter.api.entity.TootStatus
|
||||
import jp.juggler.subwaytooter.dialog.DlgListMember
|
||||
|
@ -35,7 +35,7 @@ import jp.juggler.subwaytooter.util.showToast
|
|||
internal class DlgContextMenu(
|
||||
val activity : ActMain,
|
||||
private val column : Column,
|
||||
private val who : TootAccount?,
|
||||
private val whoRef : TootAccountRef?,
|
||||
private val status : TootStatus?,
|
||||
private val notification : TootNotification?
|
||||
) : View.OnClickListener, View.OnLongClickListener {
|
||||
|
@ -49,12 +49,12 @@ internal class DlgContextMenu(
|
|||
|
||||
private val dialog : Dialog
|
||||
|
||||
|
||||
init {
|
||||
this.access_info = column.access_info
|
||||
|
||||
val column_type = column.column_type
|
||||
|
||||
val who = this.who
|
||||
|
||||
val who = whoRef?.find()
|
||||
val status = this.status
|
||||
|
||||
this.relation = UserRelation.load(access_info.db_id, who?.id ?: - 1)
|
||||
|
@ -68,7 +68,8 @@ internal class DlgContextMenu(
|
|||
val llStatus = viewRoot.findViewById<View>(R.id.llStatus)
|
||||
val btnStatusWebPage = viewRoot.findViewById<View>(R.id.btnStatusWebPage)
|
||||
val btnText = viewRoot.findViewById<View>(R.id.btnText)
|
||||
val btnFavouriteAnotherAccount = viewRoot.findViewById<View>(R.id.btnFavouriteAnotherAccount)
|
||||
val btnFavouriteAnotherAccount =
|
||||
viewRoot.findViewById<View>(R.id.btnFavouriteAnotherAccount)
|
||||
val btnBoostAnotherAccount = viewRoot.findViewById<View>(R.id.btnBoostAnotherAccount)
|
||||
val btnReplyAnotherAccount = viewRoot.findViewById<View>(R.id.btnReplyAnotherAccount)
|
||||
val btnDelete = viewRoot.findViewById<View>(R.id.btnDelete)
|
||||
|
@ -84,14 +85,18 @@ internal class DlgContextMenu(
|
|||
val btnAccountWebPage = viewRoot.findViewById<View>(R.id.btnAccountWebPage)
|
||||
val btnFollowRequestOK = viewRoot.findViewById<View>(R.id.btnFollowRequestOK)
|
||||
val btnFollowRequestNG = viewRoot.findViewById<View>(R.id.btnFollowRequestNG)
|
||||
val btnFollowFromAnotherAccount = viewRoot.findViewById<View>(R.id.btnFollowFromAnotherAccount)
|
||||
val btnSendMessageFromAnotherAccount = viewRoot.findViewById<View>(R.id.btnSendMessageFromAnotherAccount)
|
||||
val btnOpenProfileFromAnotherAccount = viewRoot.findViewById<View>(R.id.btnOpenProfileFromAnotherAccount)
|
||||
val btnFollowFromAnotherAccount =
|
||||
viewRoot.findViewById<View>(R.id.btnFollowFromAnotherAccount)
|
||||
val btnSendMessageFromAnotherAccount =
|
||||
viewRoot.findViewById<View>(R.id.btnSendMessageFromAnotherAccount)
|
||||
val btnOpenProfileFromAnotherAccount =
|
||||
viewRoot.findViewById<View>(R.id.btnOpenProfileFromAnotherAccount)
|
||||
val btnDomainBlock = viewRoot.findViewById<Button>(R.id.btnDomainBlock)
|
||||
val btnInstanceInformation = viewRoot.findViewById<Button>(R.id.btnInstanceInformation)
|
||||
val ivFollowedBy = viewRoot.findViewById<ImageView>(R.id.ivFollowedBy)
|
||||
val btnOpenTimeline = viewRoot.findViewById<Button>(R.id.btnOpenTimeline)
|
||||
val btnConversationAnotherAccount = viewRoot.findViewById<View>(R.id.btnConversationAnotherAccount)
|
||||
val btnConversationAnotherAccount =
|
||||
viewRoot.findViewById<View>(R.id.btnConversationAnotherAccount)
|
||||
val btnAvatarImage = viewRoot.findViewById<View>(R.id.btnAvatarImage)
|
||||
|
||||
val llNotification = viewRoot.findViewById<View>(R.id.llNotification)
|
||||
|
@ -162,13 +167,14 @@ internal class DlgContextMenu(
|
|||
|
||||
btnDelete.visibility = if(status_by_me) View.VISIBLE else View.GONE
|
||||
|
||||
btnReport.visibility = if(status_by_me || access_info.isPseudo) View.GONE else View.VISIBLE
|
||||
btnReport.visibility =
|
||||
if(status_by_me || access_info.isPseudo) View.GONE else View.VISIBLE
|
||||
|
||||
val application_name = status.application?.name
|
||||
if(status_by_me || application_name ==null || application_name.isEmpty() ) {
|
||||
if(status_by_me || application_name == null || application_name.isEmpty()) {
|
||||
btnMuteApp.visibility = View.GONE
|
||||
} else {
|
||||
btnMuteApp.text = activity.getString(R.string.mute_app_of,application_name)
|
||||
btnMuteApp.text = activity.getString(R.string.mute_app_of, application_name)
|
||||
}
|
||||
|
||||
val btnBoostedBy = viewRoot.findViewById<View>(R.id.btnBoostedBy)
|
||||
|
@ -190,7 +196,7 @@ internal class DlgContextMenu(
|
|||
}
|
||||
var bShowConversationMute = false
|
||||
if(status != null) {
|
||||
if( access_info.isMe(status.account) ){
|
||||
if(access_info.isMe(status.account)) {
|
||||
bShowConversationMute = true
|
||||
} else if(notification != null && TootNotification.TYPE_MENTION == notification.type) {
|
||||
bShowConversationMute = true
|
||||
|
@ -200,7 +206,7 @@ internal class DlgContextMenu(
|
|||
if(! bShowConversationMute) {
|
||||
btnConversationMute.visibility = View.GONE
|
||||
} else {
|
||||
val muted = status ?. muted ?: false
|
||||
val muted = status?.muted ?: false
|
||||
btnConversationMute.setText(if(muted) R.string.unmute_this_conversation else R.string.mute_this_conversation)
|
||||
}
|
||||
|
||||
|
@ -215,7 +221,12 @@ internal class DlgContextMenu(
|
|||
ivFollowedBy.visibility = View.GONE
|
||||
} else {
|
||||
ivFollowedBy.visibility = View.VISIBLE
|
||||
ivFollowedBy.setImageResource(Styler.getAttributeResourceId(activity, R.attr.ic_followed_by))
|
||||
ivFollowedBy.setImageResource(
|
||||
Styler.getAttributeResourceId(
|
||||
activity,
|
||||
R.attr.ic_followed_by
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// follow button
|
||||
|
@ -236,7 +247,8 @@ internal class DlgContextMenu(
|
|||
|
||||
// mute button
|
||||
icon_attr = R.attr.ic_mute
|
||||
color_attr = if(relation.muting) R.attr.colorImageButtonAccent else R.attr.colorImageButton
|
||||
color_attr =
|
||||
if(relation.muting) R.attr.colorImageButtonAccent else R.attr.colorImageButton
|
||||
color = Styler.getAttributeColor(activity, color_attr)
|
||||
d = Styler.getAttributeDrawable(activity, icon_attr).mutate()
|
||||
d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||
|
@ -244,7 +256,8 @@ internal class DlgContextMenu(
|
|||
|
||||
// block button
|
||||
icon_attr = R.attr.ic_block
|
||||
color_attr = if(relation.blocking) R.attr.colorImageButtonAccent else R.attr.colorImageButton
|
||||
color_attr =
|
||||
if(relation.blocking) R.attr.colorImageButtonAccent else R.attr.colorImageButton
|
||||
color = Styler.getAttributeColor(activity, color_attr)
|
||||
d = Styler.getAttributeDrawable(activity, icon_attr).mutate()
|
||||
d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||
|
@ -258,8 +271,9 @@ internal class DlgContextMenu(
|
|||
} else {
|
||||
val who_host = who.host
|
||||
btnInstanceInformation.visibility = View.VISIBLE
|
||||
btnInstanceInformation.text = activity.getString(R.string.instance_information_of, who_host)
|
||||
if( access_info.isPseudo || access_info.host.equals( who_host,ignoreCase = true) ) {
|
||||
btnInstanceInformation.text =
|
||||
activity.getString(R.string.instance_information_of, who_host)
|
||||
if(access_info.isPseudo || access_info.host.equals(who_host, ignoreCase = true)) {
|
||||
// 疑似アカウントではドメインブロックできない
|
||||
// 自ドメインはブロックできない
|
||||
btnDomainBlock.visibility = View.GONE
|
||||
|
@ -304,19 +318,23 @@ internal class DlgContextMenu(
|
|||
btnShowBoost.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
if( who == null ){
|
||||
btnHideFavourite.visibility = View.GONE
|
||||
btnShowFavourite.visibility = View.GONE
|
||||
}else if( FavMute.contains( access_info.getFullAcct(who) )){
|
||||
btnHideFavourite.visibility = View.GONE
|
||||
btnShowFavourite.visibility = View.VISIBLE
|
||||
}else{
|
||||
btnHideFavourite.visibility = View.VISIBLE
|
||||
btnShowFavourite.visibility = View.GONE
|
||||
when {
|
||||
who == null -> {
|
||||
btnHideFavourite.visibility = View.GONE
|
||||
btnShowFavourite.visibility = View.GONE
|
||||
}
|
||||
FavMute.contains(access_info.getFullAcct(who)) -> {
|
||||
btnHideFavourite.visibility = View.GONE
|
||||
btnShowFavourite.visibility = View.VISIBLE
|
||||
}
|
||||
else -> {
|
||||
btnHideFavourite.visibility = View.VISIBLE
|
||||
btnShowFavourite.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
val who_host = who?.host
|
||||
if( who_host==null || who_host.isEmpty() || who_host == "?") {
|
||||
if(who_host == null || who_host.isEmpty() || who_host == "?") {
|
||||
btnOpenTimeline.visibility = View.GONE
|
||||
} else {
|
||||
btnOpenTimeline.text = activity.getString(R.string.open_local_timeline_for, who_host)
|
||||
|
@ -327,7 +345,7 @@ internal class DlgContextMenu(
|
|||
|
||||
fun show() {
|
||||
val window = dialog.window
|
||||
if( window != null ){
|
||||
if(window != null) {
|
||||
val lp = window.attributes
|
||||
lp.width = (0.5f + 280f * activity.density).toInt()
|
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
|
@ -346,6 +364,207 @@ internal class DlgContextMenu(
|
|||
|
||||
val pos = activity.nextPosition(column)
|
||||
|
||||
val whoRef = this.whoRef
|
||||
val who = whoRef?.find()
|
||||
|
||||
if(whoRef != null && who != null) {
|
||||
when(v.id) {
|
||||
R.id.btnReport -> if(status is TootStatus) {
|
||||
Action_User.reportForm(activity, access_info, who, status)
|
||||
}
|
||||
|
||||
R.id.btnFollow ->
|
||||
if(access_info.isPseudo) {
|
||||
Action_Follow.followFromAnotherAccount(activity, pos, access_info, who)
|
||||
} else {
|
||||
val bSet = ! (relation.getFollowing(who) || relation.getRequested(who))
|
||||
Action_Follow.follow(
|
||||
activity, pos, access_info, whoRef,
|
||||
bFollow = bSet,
|
||||
callback = if(bSet) activity.follow_complete_callback else activity.unfollow_complete_callback
|
||||
)
|
||||
}
|
||||
|
||||
R.id.btnAccountText ->
|
||||
ActText.open(activity, ActMain.REQUEST_CODE_TEXT, access_info, who)
|
||||
|
||||
R.id.btnMute ->
|
||||
if(relation.muting) {
|
||||
//解除
|
||||
Action_User.mute(
|
||||
activity,
|
||||
access_info,
|
||||
who,
|
||||
bMute = false
|
||||
)
|
||||
} else {
|
||||
@SuppressLint("InflateParams")
|
||||
val view =
|
||||
activity.layoutInflater.inflate(R.layout.dlg_confirm, null, false)
|
||||
val tvMessage = view.findViewById<TextView>(R.id.tvMessage)
|
||||
tvMessage.text =
|
||||
activity.getString(R.string.confirm_mute_user, who.username)
|
||||
val cbMuteNotification = view.findViewById<CheckBox>(R.id.cbSkipNext)
|
||||
cbMuteNotification.setText(R.string.confirm_mute_notification_for_user)
|
||||
cbMuteNotification.isChecked = true
|
||||
// オプション指定つきでミュート
|
||||
AlertDialog.Builder(activity)
|
||||
.setView(view)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_User.mute(
|
||||
activity,
|
||||
access_info,
|
||||
who,
|
||||
bMuteNotification = cbMuteNotification.isChecked
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
R.id.btnBlock ->
|
||||
if(relation.blocking) {
|
||||
Action_User.block(activity, access_info, who, false)
|
||||
} else {
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(
|
||||
activity.getString(
|
||||
R.string.confirm_block_user,
|
||||
who.username
|
||||
)
|
||||
)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_User.block(
|
||||
activity,
|
||||
access_info,
|
||||
who,
|
||||
true
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
R.id.btnProfile ->
|
||||
Action_User.profileLocal(activity, pos, access_info, who)
|
||||
|
||||
R.id.btnSendMessage ->
|
||||
Action_User.mention(activity, access_info, who)
|
||||
|
||||
R.id.btnAccountWebPage -> who.url?.let { url ->
|
||||
App1.openCustomTab(activity, url)
|
||||
}
|
||||
|
||||
R.id.btnFollowRequestOK ->
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, whoRef, true)
|
||||
|
||||
R.id.btnFollowRequestNG ->
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, whoRef, false)
|
||||
|
||||
R.id.btnFollowFromAnotherAccount ->
|
||||
Action_Follow.followFromAnotherAccount(activity, pos, access_info, who)
|
||||
|
||||
R.id.btnSendMessageFromAnotherAccount ->
|
||||
Action_User.mentionFromAnotherAccount(activity, access_info, who)
|
||||
|
||||
R.id.btnOpenProfileFromAnotherAccount ->
|
||||
Action_User.profileFromAnotherAccount(activity, pos, access_info, who)
|
||||
|
||||
R.id.btnNickname ->
|
||||
ActNickname.open(
|
||||
activity,
|
||||
access_info.getFullAcct(who),
|
||||
true,
|
||||
ActMain.REQUEST_CODE_NICKNAME
|
||||
)
|
||||
|
||||
R.id.btnAccountQrCode ->
|
||||
DlgQRCode.open(
|
||||
activity,
|
||||
whoRef.decoded_display_name,
|
||||
access_info.getUserUrl(who.acct)
|
||||
)
|
||||
|
||||
R.id.btnDomainBlock ->
|
||||
if(access_info.isPseudo) {
|
||||
// 疑似アカウントではドメインブロックできない
|
||||
showToast(activity, false, R.string.domain_block_from_pseudo)
|
||||
return
|
||||
} else {
|
||||
val who_host = who.host
|
||||
|
||||
// 自分のドメインではブロックできない
|
||||
if(access_info.host.equals(who_host, ignoreCase = true)) {
|
||||
showToast(activity, false, R.string.domain_block_from_local)
|
||||
return
|
||||
}
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.confirm_block_domain, who_host))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_Instance.blockDomain(activity, access_info, who_host, true)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
R.id.btnOpenTimeline -> {
|
||||
val who_host = who.host
|
||||
if(who_host.isEmpty() || who_host == "?") {
|
||||
// 何もしない
|
||||
} else {
|
||||
Action_Instance.timelineLocal(activity, pos, who_host)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnAvatarImage -> {
|
||||
val url = if(! who.avatar.isNullOrEmpty()) who.avatar else who.avatar_static
|
||||
if(url != null && url.isNotEmpty()) App1.openCustomTab(activity, url)
|
||||
// XXX: 設定によっては内蔵メディアビューアで開けないか?
|
||||
}
|
||||
|
||||
R.id.btnQuoteName -> {
|
||||
var sv = who.display_name
|
||||
try {
|
||||
val fmt = Pref.spQuoteNameFormat(activity.pref)
|
||||
if(fmt.contains("%1\$s")) {
|
||||
sv = String.format(fmt, sv)
|
||||
}
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
|
||||
Action_Account.openPost(activity, sv)
|
||||
}
|
||||
|
||||
R.id.btnHideBoost ->
|
||||
Action_User.showBoosts(activity, access_info, who, false)
|
||||
|
||||
R.id.btnShowBoost ->
|
||||
Action_User.showBoosts(activity, access_info, who, true)
|
||||
|
||||
R.id.btnHideFavourite -> {
|
||||
val acct = access_info.getFullAcct(who)
|
||||
FavMute.save(acct)
|
||||
showToast(activity, false, R.string.changed)
|
||||
for(column in activity.app_state.column_list) {
|
||||
column.onHideFavouriteNotification(acct)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnShowFavourite -> {
|
||||
FavMute.delete(access_info.getFullAcct(who))
|
||||
showToast(activity, false, R.string.changed)
|
||||
}
|
||||
|
||||
R.id.btnListMemberAddRemove ->
|
||||
DlgListMember(activity, who, access_info).show()
|
||||
|
||||
R.id.btnInstanceInformation ->
|
||||
Action_Instance.information(activity, pos, who.host)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
when(v.id) {
|
||||
|
||||
R.id.btnStatusWebPage -> status?.url?.let { url ->
|
||||
|
@ -356,184 +575,56 @@ internal class DlgContextMenu(
|
|||
ActText.open(activity, ActMain.REQUEST_CODE_TEXT, access_info, status)
|
||||
}
|
||||
|
||||
R.id.btnFavouriteAnotherAccount -> Action_Toot.favouriteFromAnotherAccount(activity, access_info, status)
|
||||
R.id.btnFavouriteAnotherAccount -> Action_Toot.favouriteFromAnotherAccount(
|
||||
activity,
|
||||
access_info,
|
||||
status
|
||||
)
|
||||
|
||||
R.id.btnBoostAnotherAccount -> Action_Toot.boostFromAnotherAccount(activity, access_info, status)
|
||||
R.id.btnBoostAnotherAccount -> Action_Toot.boostFromAnotherAccount(
|
||||
activity,
|
||||
access_info,
|
||||
status
|
||||
)
|
||||
|
||||
R.id.btnReplyAnotherAccount -> Action_Toot.replyFromAnotherAccount(activity, access_info, status)
|
||||
R.id.btnReplyAnotherAccount -> Action_Toot.replyFromAnotherAccount(
|
||||
activity,
|
||||
access_info,
|
||||
status
|
||||
)
|
||||
|
||||
R.id.btnConversationAnotherAccount -> status?.let { status->
|
||||
R.id.btnConversationAnotherAccount -> status?.let { status ->
|
||||
Action_Toot.conversationOtherInstance(activity, pos, status)
|
||||
}
|
||||
|
||||
R.id.btnDelete -> status?.let { status->
|
||||
R.id.btnDelete -> status?.let { status ->
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.confirm_delete_status))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> Action_Toot.delete(activity, access_info, status.id) }
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_Toot.delete(
|
||||
activity,
|
||||
access_info,
|
||||
status.id
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
R.id.btnReport -> who?.let{ who->
|
||||
if( status is TootStatus) {
|
||||
Action_User.reportForm(activity, access_info, who, status)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnMuteApp -> status?.application?.let {
|
||||
Action_App.muteApp(activity, it)
|
||||
}
|
||||
|
||||
R.id.btnBoostedBy -> status?.let {
|
||||
activity.addColumn(false,pos, access_info, Column.TYPE_BOOSTED_BY, it.id)
|
||||
activity.addColumn(false, pos, access_info, Column.TYPE_BOOSTED_BY, it.id)
|
||||
}
|
||||
|
||||
R.id.btnFavouritedBy -> status?.let {
|
||||
activity.addColumn(false,pos, access_info, Column.TYPE_FAVOURITED_BY, it.id)
|
||||
}
|
||||
|
||||
R.id.btnFollow -> who?.let { who ->
|
||||
if(access_info.isPseudo) {
|
||||
Action_Follow.followFromAnotherAccount(activity, pos, access_info, who)
|
||||
} else {
|
||||
val bSet = ! (relation.getFollowing(who) || relation.getRequested(who))
|
||||
Action_Follow.follow(
|
||||
activity, pos, access_info, who,
|
||||
bFollow= bSet,
|
||||
callback = if(bSet) activity.follow_complete_callback else activity.unfollow_complete_callback
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnAccountText -> who?.let { who ->
|
||||
ActText.open(activity, ActMain.REQUEST_CODE_TEXT, access_info, who)
|
||||
}
|
||||
|
||||
R.id.btnMute -> who?.let { who ->
|
||||
if(relation.muting) {
|
||||
//解除
|
||||
Action_User.mute(
|
||||
activity,
|
||||
access_info,
|
||||
who,
|
||||
bMute=false
|
||||
)
|
||||
} else {
|
||||
@SuppressLint("InflateParams")
|
||||
val view = activity.layoutInflater.inflate(R.layout.dlg_confirm, null, false)
|
||||
val tvMessage = view.findViewById<TextView>(R.id.tvMessage)
|
||||
tvMessage.text = activity.getString(R.string.confirm_mute_user, who.username)
|
||||
val cbMuteNotification = view.findViewById<CheckBox>(R.id.cbSkipNext)
|
||||
cbMuteNotification.setText(R.string.confirm_mute_notification_for_user)
|
||||
cbMuteNotification.isChecked = true
|
||||
// オプション指定つきでミュート
|
||||
AlertDialog.Builder(activity)
|
||||
.setView(view)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_User.mute(
|
||||
activity,
|
||||
access_info,
|
||||
who,
|
||||
bMuteNotification=cbMuteNotification.isChecked
|
||||
)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnBlock -> who?.let { who ->
|
||||
// サーバのバグで誰のことか分からないので何もできない
|
||||
if(relation.blocking) {
|
||||
Action_User.block(activity, access_info, who, false)
|
||||
} else {
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.confirm_block_user, who.username))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> Action_User.block(activity, access_info, who, true) }
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnProfile -> who?.let { who ->
|
||||
Action_User.profileLocal(activity, pos, access_info, who)
|
||||
}
|
||||
|
||||
R.id.btnSendMessage -> who?.let { who ->
|
||||
Action_User.mention(activity, access_info, who)
|
||||
}
|
||||
|
||||
R.id.btnAccountWebPage -> who?.url?.let { url ->
|
||||
App1.openCustomTab(activity, url)
|
||||
}
|
||||
|
||||
R.id.btnFollowRequestOK -> who?.let { who ->
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, who, true)
|
||||
}
|
||||
|
||||
R.id.btnFollowRequestNG -> who?.let { who ->
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, who, false)
|
||||
}
|
||||
|
||||
R.id.btnFollowFromAnotherAccount -> who?.let { who ->
|
||||
Action_Follow.followFromAnotherAccount(activity, pos, access_info, who)
|
||||
}
|
||||
|
||||
R.id.btnSendMessageFromAnotherAccount -> who?.let { who ->
|
||||
Action_User.mentionFromAnotherAccount(activity, access_info, who)
|
||||
}
|
||||
|
||||
R.id.btnOpenProfileFromAnotherAccount -> who?.let { who ->
|
||||
Action_User.profileFromAnotherAccount(activity, pos, access_info, who)
|
||||
}
|
||||
|
||||
R.id.btnNickname -> who?.let { who ->
|
||||
ActNickname.open(activity, access_info.getFullAcct(who), true, ActMain.REQUEST_CODE_NICKNAME)
|
||||
activity.addColumn(false, pos, access_info, Column.TYPE_FAVOURITED_BY, it.id)
|
||||
}
|
||||
|
||||
R.id.btnCancel -> dialog.cancel()
|
||||
|
||||
R.id.btnAccountQrCode -> who?.let { who ->
|
||||
DlgQRCode.open(activity, who.decoded_display_name , access_info.getUserUrl(who.acct))
|
||||
}
|
||||
|
||||
R.id.btnDomainBlock -> who?.let { who ->
|
||||
// 疑似アカウントではドメインブロックできない
|
||||
if(access_info.isPseudo) {
|
||||
showToast(activity, false, R.string.domain_block_from_pseudo)
|
||||
return@let
|
||||
}
|
||||
val who_host = who.host
|
||||
|
||||
// 自分のドメインではブロックできない
|
||||
if( access_info.host.equals(who_host,ignoreCase = true)) {
|
||||
showToast(activity, false, R.string.domain_block_from_local)
|
||||
return@let
|
||||
}
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.confirm_block_domain, who_host))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_Instance.blockDomain(activity, access_info, who_host, true)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
R.id.btnOpenTimeline -> {
|
||||
val who_host = who?.host
|
||||
if( who_host?.isEmpty() != false || who_host == "?" ) {
|
||||
// 何もしない
|
||||
} else {
|
||||
Action_Instance.timelineLocal(activity, pos,who_host)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnAvatarImage -> who?.let { who ->
|
||||
val url = if(!who.avatar.isNullOrEmpty() ) who.avatar else who.avatar_static
|
||||
if( url != null && url.isNotEmpty() ) App1.openCustomTab(activity, url)
|
||||
// XXX: 設定によっては内蔵メディアビューアで開けないか?
|
||||
}
|
||||
|
||||
R.id.btnQuoteUrlStatus -> status?.url?.let { url ->
|
||||
if(url.isNotEmpty()) Action_Account.openPost(activity, url)
|
||||
}
|
||||
|
@ -542,7 +633,7 @@ internal class DlgContextMenu(
|
|||
if(url.isNotEmpty()) Action_Account.openPost(activity, url)
|
||||
}
|
||||
|
||||
R.id.btnNotificationDelete -> notification?.let{ notification->
|
||||
R.id.btnNotificationDelete -> notification?.let { notification ->
|
||||
Action_Notification.deleteOne(activity, access_info, notification)
|
||||
}
|
||||
|
||||
|
@ -550,24 +641,6 @@ internal class DlgContextMenu(
|
|||
Action_Toot.muteConversation(activity, access_info, status)
|
||||
}
|
||||
|
||||
R.id.btnQuoteName -> who?.let { who ->
|
||||
var sv = who.display_name
|
||||
try {
|
||||
val fmt = Pref.spQuoteNameFormat( activity.pref)
|
||||
if( fmt.contains("%1\$s")) {
|
||||
sv = String.format(fmt, sv)
|
||||
}
|
||||
} catch(ex : Throwable) {
|
||||
log.trace(ex)
|
||||
}
|
||||
|
||||
Action_Account.openPost(activity, sv)
|
||||
}
|
||||
|
||||
R.id.btnInstanceInformation -> who?.let { who ->
|
||||
Action_Instance.information(activity, pos, who.host)
|
||||
}
|
||||
|
||||
R.id.btnProfilePin -> status?.let { status ->
|
||||
Action_Toot.pin(activity, access_info, status, true)
|
||||
}
|
||||
|
@ -576,35 +649,11 @@ internal class DlgContextMenu(
|
|||
Action_Toot.pin(activity, access_info, status, false)
|
||||
}
|
||||
|
||||
R.id.btnHideBoost -> who?.let { who ->
|
||||
Action_User.showBoosts(activity, access_info, who, false)
|
||||
}
|
||||
|
||||
R.id.btnShowBoost -> who?.let { who ->
|
||||
Action_User.showBoosts(activity, access_info, who, true)
|
||||
}
|
||||
|
||||
R.id.btnHideFavourite -> who?.let { who ->
|
||||
val acct = access_info.getFullAcct(who)
|
||||
FavMute.save( acct)
|
||||
showToast(activity,false,R.string.changed)
|
||||
for( column in activity.app_state.column_list ){
|
||||
column.onHideFavouriteNotification(acct)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.btnShowFavourite -> who?.let { who ->
|
||||
FavMute.delete( access_info.getFullAcct(who))
|
||||
showToast(activity,false,R.string.changed)
|
||||
}
|
||||
|
||||
R.id.btnListMemberAddRemove -> who?.let { who ->
|
||||
DlgListMember(activity, who, access_info).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLongClick(v : View) : Boolean {
|
||||
val who = whoRef?.find()
|
||||
|
||||
when(v.id) {
|
||||
R.id.btnFollow -> {
|
||||
|
@ -613,13 +662,16 @@ internal class DlgContextMenu(
|
|||
} catch(ignored : Throwable) {
|
||||
// IllegalArgumentException がたまに出る
|
||||
}
|
||||
|
||||
Action_Follow.followFromAnotherAccount(activity, activity.nextPosition(column), access_info, who)
|
||||
Action_Follow.followFromAnotherAccount(
|
||||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
who
|
||||
)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -126,9 +126,9 @@ internal class ItemViewHolder(
|
|||
private var item : TimelineItem? = null
|
||||
|
||||
private var status_showing : TootStatus? = null
|
||||
private var status_account : TootAccount? = null
|
||||
private var boost_account : TootAccount? = null
|
||||
private var follow_account : TootAccount? = null
|
||||
private var status_account : TootAccountRef? = null
|
||||
private var boost_account : TootAccountRef? = null
|
||||
private var follow_account : TootAccountRef? = null
|
||||
|
||||
private var boost_time : Long = 0L
|
||||
|
||||
|
@ -344,7 +344,7 @@ internal class ItemViewHolder(
|
|||
this.item = item
|
||||
when(item) {
|
||||
is TootTag -> showSearchTag(item)
|
||||
is TootAccount -> showAccount(item)
|
||||
is TootAccountRef -> showAccount(item)
|
||||
is TootNotification -> showNotification(item)
|
||||
is TootGap -> showGap()
|
||||
is TootDomainBlock -> showDomainBlock(item)
|
||||
|
@ -354,10 +354,10 @@ internal class ItemViewHolder(
|
|||
val reblog = item.reblog
|
||||
if(reblog != null) {
|
||||
showBoost(
|
||||
item.account,
|
||||
item.accountRef,
|
||||
item.time_created_at,
|
||||
R.attr.btn_boost,
|
||||
item.account.decoded_display_name.intoStringResource(
|
||||
item.accountRef.decoded_display_name.intoStringResource(
|
||||
activity,
|
||||
R.string.display_name_boosted_by
|
||||
)
|
||||
|
@ -375,14 +375,15 @@ internal class ItemViewHolder(
|
|||
|
||||
private fun showNotification(n : TootNotification) {
|
||||
val n_status = n.status
|
||||
val n_account = n.account
|
||||
val n_accountRef = n.accountRef
|
||||
val n_account = n_accountRef?.find()
|
||||
when(n.type) {
|
||||
TootNotification.TYPE_FAVOURITE -> {
|
||||
if(n_account != null) showBoost(
|
||||
n_account,
|
||||
n_accountRef,
|
||||
n.time_created_at,
|
||||
if(access_info.isNicoru(n_account)) R.attr.ic_nicoru else R.attr.btn_favourite,
|
||||
n_account.decoded_display_name.intoStringResource(
|
||||
n_accountRef.decoded_display_name.intoStringResource(
|
||||
activity,
|
||||
R.string.display_name_favourited_by
|
||||
)
|
||||
|
@ -392,10 +393,10 @@ internal class ItemViewHolder(
|
|||
|
||||
TootNotification.TYPE_REBLOG -> {
|
||||
if(n_account != null) showBoost(
|
||||
n_account,
|
||||
n_accountRef,
|
||||
n.time_created_at,
|
||||
R.attr.btn_boost,
|
||||
n_account.decoded_display_name.intoStringResource(
|
||||
n_accountRef.decoded_display_name.intoStringResource(
|
||||
activity,
|
||||
R.string.display_name_boosted_by
|
||||
)
|
||||
|
@ -407,25 +408,25 @@ internal class ItemViewHolder(
|
|||
TootNotification.TYPE_FOLLOW -> {
|
||||
if(n_account != null) {
|
||||
showBoost(
|
||||
n_account,
|
||||
n_accountRef,
|
||||
n.time_created_at,
|
||||
R.attr.ic_follow_plus,
|
||||
n_account.decoded_display_name.intoStringResource(
|
||||
n_accountRef.decoded_display_name.intoStringResource(
|
||||
activity,
|
||||
R.string.display_name_followed_by
|
||||
)
|
||||
)
|
||||
showAccount(n_account)
|
||||
showAccount(n_accountRef)
|
||||
}
|
||||
}
|
||||
|
||||
TootNotification.TYPE_MENTION -> {
|
||||
if(! bSimpleList) {
|
||||
if(n_account != null) showBoost(
|
||||
n_account,
|
||||
n_accountRef,
|
||||
n.time_created_at,
|
||||
R.attr.btn_reply,
|
||||
n_account.decoded_display_name.intoStringResource(
|
||||
n_accountRef.decoded_display_name.intoStringResource(
|
||||
activity,
|
||||
R.string.display_name_replied_by
|
||||
)
|
||||
|
@ -460,8 +461,9 @@ internal class ItemViewHolder(
|
|||
btnSearchTag.text = activity.getString(R.string.read_gap)
|
||||
}
|
||||
|
||||
private fun showBoost(who : TootAccount, time : Long, icon_attr_id : Int, text : Spannable) {
|
||||
boost_account = who
|
||||
private fun showBoost(whoRef : TootAccountRef, time : Long, icon_attr_id : Int, text : Spannable) {
|
||||
boost_account = whoRef
|
||||
val who = whoRef.find()
|
||||
boost_time = time
|
||||
llBoosted.visibility = View.VISIBLE
|
||||
ivBoosted.setImageResource(Styler.getAttributeResourceId(activity, icon_attr_id))
|
||||
|
@ -471,16 +473,17 @@ internal class ItemViewHolder(
|
|||
setAcct(tvBoostedAcct, access_info.getFullAcct(who), who.acct)
|
||||
}
|
||||
|
||||
private fun showAccount(who : TootAccount) {
|
||||
follow_account = who
|
||||
private fun showAccount(whoRef : TootAccountRef) {
|
||||
follow_account = whoRef
|
||||
val who = whoRef.find()
|
||||
llFollow.visibility = View.VISIBLE
|
||||
ivFollow.setImageUrl(
|
||||
activity.pref,
|
||||
Styler.calcIconRound(ivFollow.layoutParams),
|
||||
access_info.supplyBaseUrl(who.avatar_static)
|
||||
)
|
||||
tvFollowerName.text = who.decoded_display_name
|
||||
follow_invalidator.register(who.decoded_display_name)
|
||||
tvFollowerName.text = whoRef.decoded_display_name
|
||||
follow_invalidator.register(whoRef.decoded_display_name)
|
||||
|
||||
setAcct(tvFollowerAcct, access_info.getFullAcct(who), who.acct)
|
||||
|
||||
|
@ -498,8 +501,9 @@ internal class ItemViewHolder(
|
|||
|
||||
showStatusTime(activity, tvTime, who = status.account, status = status)
|
||||
|
||||
val who = status.account
|
||||
this.status_account = who
|
||||
val whoRef = status.accountRef
|
||||
val who = whoRef.find()
|
||||
this.status_account = whoRef
|
||||
|
||||
setAcct(tvAcct, access_info.getFullAcct(who), who.acct)
|
||||
|
||||
|
@ -508,8 +512,8 @@ internal class ItemViewHolder(
|
|||
// name_invalidator.register(null)
|
||||
// ivThumbnail.setImageUrl(activity.pref, 16f, null, null)
|
||||
// } else {
|
||||
tvName.text = who.decoded_display_name
|
||||
name_invalidator.register(who.decoded_display_name)
|
||||
tvName.text = whoRef.decoded_display_name
|
||||
name_invalidator.register(whoRef.decoded_display_name)
|
||||
ivThumbnail.setImageUrl(
|
||||
activity.pref,
|
||||
Styler.calcIconRound(ivThumbnail.layoutParams),
|
||||
|
@ -874,27 +878,27 @@ internal class ItemViewHolder(
|
|||
|
||||
}
|
||||
|
||||
ivThumbnail -> status_account?.let { who ->
|
||||
ivThumbnail -> status_account?.let { whoRef ->
|
||||
if(access_info.isPseudo) {
|
||||
DlgContextMenu(activity, column, who, null, notification).show()
|
||||
DlgContextMenu(activity, column, whoRef, null, notification).show()
|
||||
} else {
|
||||
Action_User.profileLocal(activity, pos, access_info, who)
|
||||
Action_User.profileLocal(activity, pos, access_info, whoRef.find())
|
||||
}
|
||||
}
|
||||
|
||||
llBoosted -> boost_account?.let { who ->
|
||||
llBoosted -> boost_account?.let { whoRef ->
|
||||
if(access_info.isPseudo) {
|
||||
DlgContextMenu(activity, column, who, null, notification).show()
|
||||
DlgContextMenu(activity, column, whoRef, null, notification).show()
|
||||
} else {
|
||||
Action_User.profileLocal(activity, pos, access_info, who)
|
||||
Action_User.profileLocal(activity, pos, access_info, whoRef.find())
|
||||
}
|
||||
}
|
||||
|
||||
llFollow -> follow_account?.let { who ->
|
||||
llFollow -> follow_account?.let { whoRef ->
|
||||
if(access_info.isPseudo) {
|
||||
DlgContextMenu(activity, column, who, null, notification).show()
|
||||
DlgContextMenu(activity, column, whoRef, null, notification).show()
|
||||
} else {
|
||||
Action_User.profileLocal(activity, pos, access_info, who)
|
||||
Action_User.profileLocal(activity, pos, access_info, whoRef.find())
|
||||
}
|
||||
}
|
||||
btnFollow -> follow_account?.let { who ->
|
||||
|
@ -962,15 +966,17 @@ internal class ItemViewHolder(
|
|||
.show(activity, item.title)
|
||||
}
|
||||
|
||||
btnFollowRequestAccept -> follow_account?.let { who ->
|
||||
btnFollowRequestAccept -> follow_account?.let { whoRef ->
|
||||
val who = whoRef.find()
|
||||
DlgConfirm.openSimple(activity,activity.getString(R.string.follow_accept_confirm,AcctColor.getNickname(access_info.getFullAcct(who)))){
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, who, true)
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, whoRef, true)
|
||||
}
|
||||
}
|
||||
|
||||
btnFollowRequestDeny -> follow_account?.let { who ->
|
||||
btnFollowRequestDeny -> follow_account?.let { whoRef ->
|
||||
val who = whoRef.find()
|
||||
DlgConfirm.openSimple(activity,activity.getString(R.string.follow_deny_confirm,AcctColor.getNickname(access_info.getFullAcct(who)))){
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, who, false)
|
||||
Action_Follow.authorizeFollowRequest(activity, access_info, whoRef, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,11 +1022,11 @@ internal class ItemViewHolder(
|
|||
}
|
||||
|
||||
llFollow -> {
|
||||
follow_account?.let { who ->
|
||||
follow_account?.let { whoRef ->
|
||||
DlgContextMenu(
|
||||
activity,
|
||||
column,
|
||||
who,
|
||||
whoRef,
|
||||
null,
|
||||
notification
|
||||
).show()
|
||||
|
@ -1029,12 +1035,12 @@ internal class ItemViewHolder(
|
|||
}
|
||||
|
||||
btnFollow -> {
|
||||
follow_account?.let { who ->
|
||||
follow_account?.let { whoRef ->
|
||||
Action_Follow.followFromAnotherAccount(
|
||||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
who
|
||||
whoRef.find()
|
||||
)
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -1579,7 +1579,7 @@ class PollingWorker private constructor(c : Context) {
|
|||
|
||||
var a = getNotificationLine(
|
||||
item.notification.type,
|
||||
item.notification.account?.decoded_display_name ?: "?"
|
||||
item.notification.accountRef?.decoded_display_name ?: "?"
|
||||
)
|
||||
val acct = item.access_info.acct
|
||||
if(data_list.size == 1) {
|
||||
|
@ -1598,7 +1598,7 @@ class PollingWorker private constructor(c : Context) {
|
|||
item = data_list[i]
|
||||
a = getNotificationLine(
|
||||
item.notification.type,
|
||||
item.notification.account?.decoded_display_name ?: "?"
|
||||
item.notification.accountRef?.decoded_display_name ?: "?"
|
||||
)
|
||||
style.addLine(a)
|
||||
}
|
||||
|
|
|
@ -226,7 +226,8 @@ internal class StatusButtons(
|
|||
}
|
||||
|
||||
btnFollow2 -> {
|
||||
val account = status.account
|
||||
val accountRef = status.accountRef
|
||||
val account = accountRef.find()
|
||||
val relation = this.relation ?: return
|
||||
|
||||
when {
|
||||
|
@ -250,7 +251,7 @@ internal class StatusButtons(
|
|||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
account,
|
||||
accountRef,
|
||||
bFollow = false,
|
||||
callback = activity.unfollow_complete_callback
|
||||
)
|
||||
|
@ -262,7 +263,7 @@ internal class StatusButtons(
|
|||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
account,
|
||||
accountRef,
|
||||
bFollow = true,
|
||||
callback = activity.follow_complete_callback
|
||||
)
|
||||
|
@ -270,7 +271,7 @@ internal class StatusButtons(
|
|||
}
|
||||
}
|
||||
|
||||
btnMore -> DlgContextMenu(activity, column, status.account, status, notification).show()
|
||||
btnMore -> DlgContextMenu(activity, column, status.accountRef, status, notification).show()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import jp.juggler.emoji.EmojiMap201709
|
|||
import jp.juggler.subwaytooter.action.Action_Follow
|
||||
import jp.juggler.subwaytooter.action.Action_User
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccount
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccountRef
|
||||
import jp.juggler.subwaytooter.api.entity.TootStatus
|
||||
import jp.juggler.subwaytooter.table.AcctColor
|
||||
import jp.juggler.subwaytooter.table.UserRelation
|
||||
|
@ -49,9 +50,9 @@ internal class ViewHolderHeaderProfile(
|
|||
private val note_invalidator : NetworkEmojiInvalidator
|
||||
private val llFields : LinearLayout
|
||||
|
||||
private var who : TootAccount? = null
|
||||
private var whoRef : TootAccountRef? = null
|
||||
|
||||
private var who_moved : TootAccount? = null
|
||||
private var movedRef : TootAccountRef? = null
|
||||
|
||||
private val llMoved : View
|
||||
private val tvMoved : TextView
|
||||
|
@ -140,8 +141,9 @@ internal class ViewHolderHeaderProfile(
|
|||
tvCreated.textSize = activity.acct_font_size_sp
|
||||
}
|
||||
|
||||
val who = column.who_account
|
||||
this.who = who
|
||||
val whoRef = column.who_account
|
||||
this.whoRef = whoRef
|
||||
val who = whoRef?.find()
|
||||
|
||||
showColor()
|
||||
|
||||
|
@ -184,7 +186,7 @@ internal class ViewHolderHeaderProfile(
|
|||
access_info.supplyBaseUrl(who.avatar)
|
||||
)
|
||||
|
||||
val name = who.decoded_display_name
|
||||
val name = whoRef.decoded_display_name
|
||||
tvDisplayName.text = name
|
||||
name_invalidator.register(name)
|
||||
|
||||
|
@ -210,7 +212,7 @@ internal class ViewHolderHeaderProfile(
|
|||
}
|
||||
tvAcct.text = sb
|
||||
|
||||
val note = who.decoded_note
|
||||
val note = whoRef.decoded_note
|
||||
tvNote.text = note
|
||||
note_invalidator.register(note)
|
||||
|
||||
|
@ -221,7 +223,7 @@ internal class ViewHolderHeaderProfile(
|
|||
val relation = UserRelation.load(access_info.db_id, who.id)
|
||||
Styler.setFollowIcon(activity, btnFollow, ivFollowedBy, relation, who)
|
||||
|
||||
showMoved(who, who.moved)
|
||||
showMoved(who, who.movedRef)
|
||||
|
||||
if(who.fields != null) {
|
||||
|
||||
|
@ -295,9 +297,10 @@ internal class ViewHolderHeaderProfile(
|
|||
}
|
||||
}
|
||||
|
||||
private fun showMoved(who : TootAccount, who_moved : TootAccount?) {
|
||||
if(who_moved == null) return
|
||||
this.who_moved = who_moved
|
||||
private fun showMoved(who : TootAccount, movedRef : TootAccountRef?) {
|
||||
if(movedRef == null) return
|
||||
this.movedRef = movedRef
|
||||
val moved = movedRef.find()
|
||||
|
||||
llMoved.visibility = View.VISIBLE
|
||||
tvMoved.visibility = View.VISIBLE
|
||||
|
@ -314,16 +317,16 @@ internal class ViewHolderHeaderProfile(
|
|||
ivMoved.setImageUrl(
|
||||
activity.pref,
|
||||
Styler.calcIconRound(ivMoved.layoutParams),
|
||||
access_info.supplyBaseUrl(who_moved.avatar_static)
|
||||
access_info.supplyBaseUrl(moved.avatar_static)
|
||||
)
|
||||
|
||||
tvMovedName.text = who_moved.decoded_display_name
|
||||
moved_name_invalidator.register(who_moved.decoded_display_name)
|
||||
tvMovedName.text = movedRef.decoded_display_name
|
||||
moved_name_invalidator.register(movedRef.decoded_display_name)
|
||||
|
||||
setAcct(tvMovedAcct, access_info.getFullAcct(who_moved), who_moved.acct)
|
||||
setAcct(tvMovedAcct, access_info.getFullAcct(moved), moved.acct)
|
||||
|
||||
val relation = UserRelation.load(access_info.db_id, who_moved.id)
|
||||
Styler.setFollowIcon(activity, btnMoved, ivMovedBy, relation, who_moved)
|
||||
val relation = UserRelation.load(access_info.db_id, moved.id)
|
||||
Styler.setFollowIcon(activity, btnMoved, ivMovedBy, relation, moved)
|
||||
}
|
||||
|
||||
private fun setAcct(tv : TextView, acctLong : String, acctShort : String) {
|
||||
|
@ -353,7 +356,7 @@ internal class ViewHolderHeaderProfile(
|
|||
|
||||
when(v.id) {
|
||||
|
||||
R.id.ivBackground, R.id.tvRemoteProfileWarning -> who?.url?.let { url ->
|
||||
R.id.ivBackground, R.id.tvRemoteProfileWarning -> whoRef?.find()?.url?.let { url ->
|
||||
App1.openCustomTab(activity, url)
|
||||
}
|
||||
|
||||
|
@ -375,27 +378,27 @@ internal class ViewHolderHeaderProfile(
|
|||
column.startLoading()
|
||||
}
|
||||
|
||||
R.id.btnMore -> who?.let { who ->
|
||||
DlgContextMenu(activity, column, who, null, null).show()
|
||||
R.id.btnMore -> whoRef?.let { whoRef ->
|
||||
DlgContextMenu(activity, column, whoRef, null, null).show()
|
||||
}
|
||||
|
||||
R.id.btnFollow -> who?.let { who ->
|
||||
DlgContextMenu(activity, column, who, null, null).show()
|
||||
R.id.btnFollow -> whoRef?.let { whoRef ->
|
||||
DlgContextMenu(activity, column, whoRef, null, null).show()
|
||||
}
|
||||
|
||||
R.id.btnMoved -> who_moved?.let { who_moved ->
|
||||
DlgContextMenu(activity, column, who_moved, null, null).show()
|
||||
R.id.btnMoved -> movedRef?.let { movedRef ->
|
||||
DlgContextMenu(activity, column, movedRef, null, null).show()
|
||||
}
|
||||
|
||||
R.id.llMoved -> who_moved?.let { who_moved ->
|
||||
R.id.llMoved -> movedRef?.let { movedRef ->
|
||||
if(access_info.isPseudo) {
|
||||
DlgContextMenu(activity, column, who_moved, null, null).show()
|
||||
DlgContextMenu(activity, column, movedRef, null, null).show()
|
||||
} else {
|
||||
Action_User.profileLocal(
|
||||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
who_moved
|
||||
movedRef.find()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +413,7 @@ internal class ViewHolderHeaderProfile(
|
|||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
who
|
||||
whoRef?.find()
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
@ -420,7 +423,7 @@ internal class ViewHolderHeaderProfile(
|
|||
activity,
|
||||
activity.nextPosition(column),
|
||||
access_info,
|
||||
who_moved
|
||||
movedRef?.find()
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
@ -433,7 +436,7 @@ internal class ViewHolderHeaderProfile(
|
|||
}
|
||||
|
||||
fun updateRelativeTime() {
|
||||
val who = this.who
|
||||
val who = whoRef?.find()
|
||||
if(who != null) {
|
||||
tvCreated.text = TootStatus.formatTime(tvCreated.context, who.time_created_at, true)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import jp.juggler.subwaytooter.App1
|
|||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.*
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccount
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccountRef
|
||||
import jp.juggler.subwaytooter.api.entity.TootRelationShip
|
||||
import jp.juggler.subwaytooter.api.entity.parseItem
|
||||
import jp.juggler.subwaytooter.dialog.AccountPicker
|
||||
|
@ -26,12 +27,14 @@ object Action_Follow {
|
|||
activity : ActMain,
|
||||
pos : Int,
|
||||
access_info : SavedAccount,
|
||||
who : TootAccount,
|
||||
bFollow : Boolean =true,
|
||||
bConfirmMoved : Boolean =false,
|
||||
bConfirmed : Boolean =false,
|
||||
whoRef : TootAccountRef,
|
||||
bFollow : Boolean = true,
|
||||
bConfirmMoved : Boolean = false,
|
||||
bConfirmed : Boolean = false,
|
||||
callback : EmptyCallback? = null
|
||||
) {
|
||||
val who = whoRef.find()
|
||||
|
||||
if(access_info.isMe(who)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
return
|
||||
|
@ -39,15 +42,27 @@ object Action_Follow {
|
|||
|
||||
if(! bConfirmMoved && bFollow && who.moved != null) {
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.jump_moved_user, access_info.getFullAcct(who), access_info.getFullAcct(who.moved)
|
||||
))
|
||||
.setPositiveButton(R.string.ok) { _, _ -> Action_User.profileFromAnotherAccount(activity, pos, access_info, who.moved) }
|
||||
.setMessage(
|
||||
activity.getString(
|
||||
R.string.jump_moved_user,
|
||||
access_info.getFullAcct(who),
|
||||
access_info.getFullAcct(who.moved)
|
||||
)
|
||||
)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_User.profileFromAnotherAccount(
|
||||
activity,
|
||||
pos,
|
||||
access_info,
|
||||
who.moved
|
||||
)
|
||||
}
|
||||
.setNeutralButton(R.string.ignore_suggestion) { _, _ ->
|
||||
follow(
|
||||
activity,
|
||||
pos,
|
||||
access_info,
|
||||
who,
|
||||
whoRef,
|
||||
bFollow = bFollow,
|
||||
bConfirmMoved = true, // CHANGED
|
||||
bConfirmed = bConfirmed,
|
||||
|
@ -63,33 +78,41 @@ object Action_Follow {
|
|||
if(bFollow && who.locked) {
|
||||
DlgConfirm.open(
|
||||
activity,
|
||||
activity.getString(R.string.confirm_follow_request_who_from, who.decoded_display_name, AcctColor.getNickname(access_info.acct))
|
||||
activity.getString(
|
||||
R.string.confirm_follow_request_who_from,
|
||||
whoRef.decoded_display_name,
|
||||
AcctColor.getNickname(access_info.acct)
|
||||
)
|
||||
, object : DlgConfirm.Callback {
|
||||
|
||||
override fun onOK() {
|
||||
follow(
|
||||
activity,
|
||||
pos,
|
||||
access_info,
|
||||
who,
|
||||
bFollow = bFollow,
|
||||
bConfirmMoved =bConfirmMoved,
|
||||
bConfirmed=true, // CHANGED
|
||||
callback=callback
|
||||
)
|
||||
}
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
get() = access_info.confirm_follow_locked
|
||||
set(value) {
|
||||
access_info.confirm_follow_locked = value
|
||||
access_info.saveSetting()
|
||||
activity.reloadAccountSetting(access_info)
|
||||
|
||||
override fun onOK() {
|
||||
follow(
|
||||
activity,
|
||||
pos,
|
||||
access_info,
|
||||
whoRef,
|
||||
bFollow = bFollow,
|
||||
bConfirmMoved = bConfirmMoved,
|
||||
bConfirmed = true, // CHANGED
|
||||
callback = callback
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
get() = access_info.confirm_follow_locked
|
||||
set(value) {
|
||||
access_info.confirm_follow_locked = value
|
||||
access_info.saveSetting()
|
||||
activity.reloadAccountSetting(access_info)
|
||||
}
|
||||
})
|
||||
return
|
||||
} else if(bFollow) {
|
||||
val msg = activity.getString(R.string.confirm_follow_who_from, who.decoded_display_name, AcctColor.getNickname(access_info.acct))
|
||||
val msg = activity.getString(
|
||||
R.string.confirm_follow_who_from,
|
||||
whoRef.decoded_display_name,
|
||||
AcctColor.getNickname(access_info.acct)
|
||||
)
|
||||
|
||||
DlgConfirm.open(
|
||||
activity,
|
||||
|
@ -101,11 +124,12 @@ object Action_Follow {
|
|||
activity,
|
||||
pos,
|
||||
access_info,
|
||||
who,
|
||||
bFollow=bFollow,
|
||||
bConfirmMoved=bConfirmMoved,
|
||||
bConfirmed =true, //CHANGED
|
||||
callback=callback)
|
||||
whoRef,
|
||||
bFollow = bFollow,
|
||||
bConfirmMoved = bConfirmMoved,
|
||||
bConfirmed = true, //CHANGED
|
||||
callback = callback
|
||||
)
|
||||
}
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
|
@ -120,7 +144,11 @@ object Action_Follow {
|
|||
} else {
|
||||
DlgConfirm.open(
|
||||
activity,
|
||||
activity.getString(R.string.confirm_unfollow_who_from, who.decoded_display_name, AcctColor.getNickname(access_info.acct)),
|
||||
activity.getString(
|
||||
R.string.confirm_unfollow_who_from,
|
||||
whoRef.decoded_display_name,
|
||||
AcctColor.getNickname(access_info.acct)
|
||||
),
|
||||
object : DlgConfirm.Callback {
|
||||
|
||||
override fun onOK() {
|
||||
|
@ -128,11 +156,12 @@ object Action_Follow {
|
|||
activity,
|
||||
pos,
|
||||
access_info,
|
||||
who,
|
||||
bFollow=bFollow,
|
||||
bConfirmMoved=bConfirmMoved,
|
||||
bConfirmed =true, // CHANGED
|
||||
callback=callback)
|
||||
whoRef,
|
||||
bFollow = bFollow,
|
||||
bConfirmMoved = bConfirmMoved,
|
||||
bConfirmed = true, // CHANGED
|
||||
callback = callback
|
||||
)
|
||||
}
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
|
@ -158,11 +187,13 @@ object Action_Follow {
|
|||
// リモートフォローする
|
||||
val request_builder = Request.Builder().post(
|
||||
RequestBody.create(
|
||||
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, "uri=" + who.acct.encodePercent()
|
||||
))
|
||||
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED,
|
||||
"uri=" + who.acct.encodePercent()
|
||||
)
|
||||
)
|
||||
|
||||
result = client.request("/api/v1/follows", request_builder)
|
||||
val remote_who = TootParser(activity, access_info).account( result?.jsonObject)
|
||||
val remote_who = TootParser(activity, access_info).account(result?.jsonObject)
|
||||
if(remote_who != null) {
|
||||
val rr = loadRelation1(client, access_info, remote_who.id)
|
||||
result = rr.result
|
||||
|
@ -176,12 +207,16 @@ object Action_Follow {
|
|||
val request_builder = Request.Builder().post(
|
||||
RequestBody.create(
|
||||
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, "" // 空データ
|
||||
))
|
||||
result = client.request("/api/v1/accounts/" + who.id
|
||||
+ if(bFollow) "/follow" else "/unfollow", request_builder)
|
||||
)
|
||||
)
|
||||
result = client.request(
|
||||
"/api/v1/accounts/" + who.id
|
||||
+ if(bFollow) "/follow" else "/unfollow", request_builder
|
||||
)
|
||||
val jsonObject = result?.jsonObject
|
||||
if(jsonObject != null) {
|
||||
relation = saveUserRelation(access_info, parseItem(::TootRelationShip,jsonObject))
|
||||
relation =
|
||||
saveUserRelation(access_info, parseItem(::TootRelationShip, jsonObject))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,17 +232,17 @@ object Action_Follow {
|
|||
|
||||
activity.showColumnMatchAccount(access_info)
|
||||
|
||||
if(bFollow && relation .getRequested(who)) {
|
||||
if(bFollow && relation.getRequested(who)) {
|
||||
// 鍵付きアカウントにフォローリクエストを申請した状態
|
||||
showToast(activity, false, R.string.follow_requested)
|
||||
} else if(! bFollow && relation .getRequested(who)) {
|
||||
} else if(! bFollow && relation.getRequested(who)) {
|
||||
showToast(activity, false, R.string.follow_request_cant_remove_by_sender)
|
||||
} else {
|
||||
// ローカル操作成功、もしくはリモートフォロー成功
|
||||
if(callback != null) callback()
|
||||
}
|
||||
|
||||
} else if(bFollow && who.locked && ( result.response?.code() ?: -1) == 422) {
|
||||
} else if(bFollow && who.locked && (result.response?.code() ?: - 1) == 422) {
|
||||
showToast(activity, false, R.string.cant_follow_locked_user)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
|
@ -223,8 +258,8 @@ object Action_Follow {
|
|||
access_info : SavedAccount,
|
||||
acct : String,
|
||||
locked : Boolean,
|
||||
bConfirmed : Boolean =false,
|
||||
callback : EmptyCallback? =null
|
||||
bConfirmed : Boolean = false,
|
||||
callback : EmptyCallback? = null
|
||||
) {
|
||||
if(access_info.isMe(acct)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
|
@ -233,49 +268,63 @@ object Action_Follow {
|
|||
|
||||
if(! bConfirmed) {
|
||||
if(locked) {
|
||||
DlgConfirm.open(activity, activity.getString(R.string.confirm_follow_request_who_from, AcctColor.getNickname(acct), AcctColor.getNickname(access_info.acct)), object : DlgConfirm.Callback {
|
||||
override fun onOK() {
|
||||
followRemote(
|
||||
activity,
|
||||
access_info,
|
||||
acct,
|
||||
locked,
|
||||
bConfirmed= true, //CHANGE
|
||||
callback=callback
|
||||
)
|
||||
}
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
get() = access_info.confirm_follow_locked
|
||||
set(value) {
|
||||
access_info.confirm_follow_locked = value
|
||||
access_info.saveSetting()
|
||||
activity.reloadAccountSetting(access_info)
|
||||
DlgConfirm.open(
|
||||
activity,
|
||||
activity.getString(
|
||||
R.string.confirm_follow_request_who_from,
|
||||
AcctColor.getNickname(acct),
|
||||
AcctColor.getNickname(access_info.acct)
|
||||
),
|
||||
object : DlgConfirm.Callback {
|
||||
override fun onOK() {
|
||||
followRemote(
|
||||
activity,
|
||||
access_info,
|
||||
acct,
|
||||
locked,
|
||||
bConfirmed = true, //CHANGE
|
||||
callback = callback
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
get() = access_info.confirm_follow_locked
|
||||
set(value) {
|
||||
access_info.confirm_follow_locked = value
|
||||
access_info.saveSetting()
|
||||
activity.reloadAccountSetting(access_info)
|
||||
}
|
||||
})
|
||||
return
|
||||
} else {
|
||||
DlgConfirm.open(activity, activity.getString(R.string.confirm_follow_who_from, AcctColor.getNickname(acct), AcctColor.getNickname(access_info.acct)), object : DlgConfirm.Callback {
|
||||
|
||||
override fun onOK() {
|
||||
followRemote(
|
||||
activity,
|
||||
access_info,
|
||||
acct,
|
||||
locked,
|
||||
bConfirmed= true, //CHANGE
|
||||
callback=callback
|
||||
)
|
||||
}
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
get() = access_info.confirm_follow
|
||||
set(value) {
|
||||
access_info.confirm_follow = value
|
||||
access_info.saveSetting()
|
||||
activity.reloadAccountSetting(access_info)
|
||||
DlgConfirm.open(
|
||||
activity,
|
||||
activity.getString(
|
||||
R.string.confirm_follow_who_from,
|
||||
AcctColor.getNickname(acct),
|
||||
AcctColor.getNickname(access_info.acct)
|
||||
),
|
||||
object : DlgConfirm.Callback {
|
||||
|
||||
override fun onOK() {
|
||||
followRemote(
|
||||
activity,
|
||||
access_info,
|
||||
acct,
|
||||
locked,
|
||||
bConfirmed = true, //CHANGE
|
||||
callback = callback
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
override var isConfirmEnabled : Boolean
|
||||
get() = access_info.confirm_follow
|
||||
set(value) {
|
||||
access_info.confirm_follow = value
|
||||
access_info.saveSetting()
|
||||
activity.reloadAccountSetting(access_info)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -289,13 +338,14 @@ object Action_Follow {
|
|||
val request_builder = Request.Builder().post(
|
||||
RequestBody.create(
|
||||
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, "uri=" + acct.encodePercent()
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
var result = client.request("/api/v1/follows", request_builder)
|
||||
val remote_who = TootParser(activity, access_info).account(result?.jsonObject)
|
||||
if(remote_who != null) {
|
||||
this.remote_who = remote_who
|
||||
val rr = loadRelation1(client, access_info, remote_who .id)
|
||||
val rr = loadRelation1(client, access_info, remote_who.id)
|
||||
result = rr.result
|
||||
relation = rr.relation
|
||||
}
|
||||
|
@ -313,7 +363,7 @@ object Action_Follow {
|
|||
|
||||
if(callback != null) callback()
|
||||
|
||||
} else if(locked && (result.response?.code() ?: -1 )== 422) {
|
||||
} else if(locked && (result.response?.code() ?: - 1) == 422) {
|
||||
showToast(activity, false, R.string.cant_follow_locked_user)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
|
@ -328,14 +378,19 @@ object Action_Follow {
|
|||
pos : Int,
|
||||
access_info : SavedAccount,
|
||||
account : TootAccount?,
|
||||
bConfirmMoved : Boolean =false
|
||||
bConfirmMoved : Boolean = false
|
||||
) {
|
||||
if(account == null) return
|
||||
|
||||
if(! bConfirmMoved && account.moved != null) {
|
||||
AlertDialog.Builder(activity)
|
||||
.setMessage(activity.getString(R.string.jump_moved_user, access_info.getFullAcct(account), access_info.getFullAcct(account.moved)
|
||||
))
|
||||
.setMessage(
|
||||
activity.getString(
|
||||
R.string.jump_moved_user,
|
||||
access_info.getFullAcct(account),
|
||||
access_info.getFullAcct(account.moved)
|
||||
)
|
||||
)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
Action_User.profileFromAnotherAccount(activity, pos, access_info, account.moved)
|
||||
}
|
||||
|
@ -371,8 +426,12 @@ object Action_Follow {
|
|||
}
|
||||
|
||||
fun authorizeFollowRequest(
|
||||
activity : ActMain, access_info : SavedAccount, who : TootAccount, bAllow : Boolean
|
||||
activity : ActMain,
|
||||
access_info : SavedAccount,
|
||||
whoRef : TootAccountRef,
|
||||
bAllow : Boolean
|
||||
) {
|
||||
val who = whoRef.find()
|
||||
if(access_info.isMe(who)) {
|
||||
showToast(activity, false, R.string.it_is_you)
|
||||
return
|
||||
|
@ -383,10 +442,13 @@ object Action_Follow {
|
|||
val request_builder = Request.Builder().post(
|
||||
RequestBody.create(
|
||||
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, "" // 空データ
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
return client.request(
|
||||
"/api/v1/follow_requests/" + who.id + if(bAllow) "/authorize" else "/reject", request_builder)
|
||||
"/api/v1/follow_requests/" + who.id + if(bAllow) "/authorize" else "/reject",
|
||||
request_builder
|
||||
)
|
||||
}
|
||||
|
||||
override fun handleResult(result : TootApiResult?) {
|
||||
|
@ -398,7 +460,12 @@ object Action_Follow {
|
|||
column.removeFollowRequest(access_info, who.id)
|
||||
}
|
||||
|
||||
showToast(activity, false, if(bAllow) R.string.follow_request_authorized else R.string.follow_request_rejected, who.decoded_display_name)
|
||||
showToast(
|
||||
activity,
|
||||
false,
|
||||
if(bAllow) R.string.follow_request_authorized else R.string.follow_request_rejected,
|
||||
whoRef.decoded_display_name
|
||||
)
|
||||
} else {
|
||||
showToast(activity, false, result.error)
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ object Action_User {
|
|||
if(jsonObject != null) {
|
||||
val tmp = TootParser(activity, access_info).results(jsonObject)
|
||||
if(tmp != null && tmp.accounts.isNotEmpty()) {
|
||||
who_local = tmp.accounts[0]
|
||||
who_local = tmp.accounts[0].find()
|
||||
} else {
|
||||
return TootApiResult(activity.getString(R.string.user_id_conversion_failed))
|
||||
}
|
||||
|
|
|
@ -56,9 +56,10 @@ class DuplicateMap {
|
|||
|
||||
}
|
||||
|
||||
is TootAccount -> {
|
||||
if(set_account_id.contains(o.id)) return true
|
||||
set_account_id.add(o.id)
|
||||
is TootAccountRef -> {
|
||||
val id = o.find().id
|
||||
if(set_account_id.contains(id)) return true
|
||||
set_account_id.add(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package jp.juggler.subwaytooter.api
|
|||
|
||||
import jp.juggler.subwaytooter.api.entity.ServiceType
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccount
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccountRef
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
object TootAccountMap{
|
||||
|
@ -48,6 +49,9 @@ object TootAccountMap{
|
|||
fun find(id : Int) : TootAccount {
|
||||
return requireNotNull(accountMap[id])
|
||||
}
|
||||
fun find(ref: TootAccountRef) : TootAccount {
|
||||
return requireNotNull(accountMap[ref.id])
|
||||
}
|
||||
|
||||
fun register(parser:TootParser, who : TootAccount) : Int {
|
||||
val key = AccountUniqueKey(parser,who)
|
||||
|
|
|
@ -18,7 +18,7 @@ class TootParser(
|
|||
) {
|
||||
|
||||
fun account(src : JSONObject?) = parseItem(::TootAccount, this, src)
|
||||
fun accountList(array : JSONArray?) = parseList(::TootAccount, this, array)
|
||||
fun accountList(array : JSONArray?) = TootAccountRef.wrapList(this,parseList(::TootAccount, this, array))
|
||||
|
||||
fun status(src : JSONObject?) = parseItem(::TootStatus, this, src)
|
||||
fun statusList(array : JSONArray?) = parseList(::TootStatus, this, array)
|
||||
|
|
|
@ -15,7 +15,7 @@ import java.util.regex.Pattern
|
|||
open class TootAccount(
|
||||
parser : TootParser,
|
||||
src : JSONObject
|
||||
) : TimelineItem() {
|
||||
) {
|
||||
|
||||
//URL of the user's profile page (can be remote)
|
||||
// https://mastodon.juggler.jp/@tateisu
|
||||
|
@ -36,9 +36,6 @@ open class TootAccount(
|
|||
// The account's display name
|
||||
val display_name : String
|
||||
|
||||
// The account's display name
|
||||
val decoded_display_name : Spannable
|
||||
|
||||
//Boolean for when the account cannot be followed without waiting for approval first
|
||||
val locked : Boolean
|
||||
|
||||
|
@ -60,8 +57,6 @@ open class TootAccount(
|
|||
// 説明文。改行は\r\n。リンクなどはHTMLタグで書かれている
|
||||
val note : String?
|
||||
|
||||
val decoded_note : Spannable
|
||||
|
||||
// URL to the avatar image
|
||||
val avatar : String?
|
||||
|
||||
|
@ -78,19 +73,22 @@ open class TootAccount(
|
|||
|
||||
val profile_emojis : HashMap<String, NicoProfileEmoji>?
|
||||
|
||||
val movedRef : TootAccountRef?
|
||||
|
||||
val moved : TootAccount?
|
||||
get() = movedRef?.find()
|
||||
|
||||
val fields : ArrayList<Pair<String, String>>?
|
||||
|
||||
val custom_emojis : java.util.HashMap<String, CustomEmoji>?
|
||||
|
||||
val bot :Boolean
|
||||
val bot : Boolean
|
||||
|
||||
init {
|
||||
var sv : String?
|
||||
|
||||
// 絵文字データは先に読んでおく
|
||||
this.custom_emojis = parseMapOrNull(::CustomEmoji, src.optJSONArray("emojis") )
|
||||
this.custom_emojis = parseMapOrNull(::CustomEmoji, src.optJSONArray("emojis"))
|
||||
this.profile_emojis = parseMapOrNull(::NicoProfileEmoji, src.optJSONArray("profile_emojis"))
|
||||
|
||||
// 疑似アカウントにacctとusernameだけ
|
||||
|
@ -100,28 +98,22 @@ open class TootAccount(
|
|||
//
|
||||
sv = src.parseString("display_name")
|
||||
this.display_name = if(sv?.isNotEmpty() == true) sv.sanitizeBDI() else username
|
||||
this.decoded_display_name = decodeDisplayName(parser.context)
|
||||
|
||||
//
|
||||
this.note = src.parseString("note")
|
||||
this.decoded_note = DecodeOptions(
|
||||
parser.context,
|
||||
parser.linkHelper,
|
||||
short = true,
|
||||
decodeEmoji = true,
|
||||
emojiMapProfile = this.profile_emojis,
|
||||
emojiMapCustom = this.custom_emojis,
|
||||
unwrapEmojiImageTag = true
|
||||
).decodeHTML(this.note)
|
||||
|
||||
this.source = parseSource(src.optJSONObject("source"))
|
||||
this.moved =
|
||||
src.optJSONObject("moved")?.let { TootAccount(parser, it) }
|
||||
this.movedRef = TootAccountRef.mayNull(
|
||||
parser,
|
||||
src.optJSONObject("moved")?.let {
|
||||
TootAccount(parser, it)
|
||||
}
|
||||
)
|
||||
this.locked = src.optBoolean("locked")
|
||||
|
||||
this.fields = parseFields(src.optJSONArray("fields"))
|
||||
|
||||
this.bot = src.optBoolean("bot",false)
|
||||
this.bot = src.optBoolean("bot", false)
|
||||
|
||||
when(parser.serviceType) {
|
||||
ServiceType.MASTODON -> {
|
||||
|
@ -297,9 +289,9 @@ open class TootAccount(
|
|||
val v = item.parseString("value") ?: continue
|
||||
dst.add(Pair(k, v))
|
||||
}
|
||||
return if( dst.isEmpty() ){
|
||||
return if(dst.isEmpty()) {
|
||||
null
|
||||
}else{
|
||||
} else {
|
||||
dst
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import android.text.Spannable
|
||||
import jp.juggler.subwaytooter.api.TootAccountMap
|
||||
import jp.juggler.subwaytooter.api.TootParser
|
||||
import jp.juggler.subwaytooter.util.DecodeOptions
|
||||
|
||||
class TootAccountRef(parser: TootParser, account:TootAccount) : TimelineItem() {
|
||||
|
||||
val id:Int
|
||||
// The account's display name
|
||||
val decoded_display_name : Spannable
|
||||
val decoded_note : Spannable
|
||||
|
||||
init{
|
||||
this.id = TootAccountMap.register(parser,account)
|
||||
this.decoded_display_name = account.decodeDisplayName(parser.context)
|
||||
this.decoded_note = DecodeOptions(
|
||||
parser.context,
|
||||
parser.linkHelper,
|
||||
short = true,
|
||||
decodeEmoji = true,
|
||||
emojiMapProfile = account.profile_emojis,
|
||||
emojiMapCustom = account.custom_emojis,
|
||||
unwrapEmojiImageTag = true
|
||||
).decodeHTML(account.note)
|
||||
}
|
||||
|
||||
fun find() : TootAccount {
|
||||
return TootAccountMap.find(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun mayNull(parser: TootParser, account:TootAccount?) :TootAccountRef? {
|
||||
return when(account) {
|
||||
null -> null
|
||||
else -> TootAccountRef(parser,account)
|
||||
}
|
||||
}
|
||||
|
||||
fun wrapList(parser: TootParser, src : ArrayList<TootAccount>) : ArrayList<TootAccountRef> {
|
||||
val dst = ArrayList<TootAccountRef>()
|
||||
for( a in src){
|
||||
dst.add( TootAccountRef(parser,a))
|
||||
}
|
||||
return dst
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package jp.juggler.subwaytooter.api.entity
|
||||
|
||||
import jp.juggler.subwaytooter.api.TootAccountMap
|
||||
import jp.juggler.subwaytooter.api.TootParser
|
||||
import jp.juggler.subwaytooter.util.notEmptyOrThrow
|
||||
import jp.juggler.subwaytooter.util.parseLong
|
||||
|
@ -12,11 +13,14 @@ class TootNotification(
|
|||
val id : Long,
|
||||
val type : String, // One of: "mention", "reblog", "favourite", "follow"
|
||||
private val created_at : String?, // The time the notification was created
|
||||
val account : TootAccount?, // The Account sending the notification to the user
|
||||
val accountRef : TootAccountRef?, // The Account sending the notification to the user
|
||||
val status : TootStatus? // The Status associated with the notification, if applicable
|
||||
) : TimelineItem() {
|
||||
|
||||
val time_created_at : Long
|
||||
|
||||
val account : TootAccount?
|
||||
get() = accountRef?.find()
|
||||
|
||||
init {
|
||||
time_created_at = TootStatus.parseTime(created_at)
|
||||
|
@ -27,7 +31,7 @@ class TootNotification(
|
|||
id = src.parseLong("id") ?: - 1L,
|
||||
type = src.notEmptyOrThrow("type"),
|
||||
created_at = src.parseString("created_at"),
|
||||
account = parser.account(src.optJSONObject("account")),
|
||||
accountRef = TootAccountRef.mayNull( parser, parser.account(src.optJSONObject("account"))),
|
||||
status = parser.status(src.optJSONObject("status"))
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import java.util.ArrayList
|
|||
import jp.juggler.subwaytooter.api.TootParser
|
||||
|
||||
class TootResults(
|
||||
val accounts : ArrayList<TootAccount>, // An array of matched Accounts
|
||||
val accounts : ArrayList<TootAccountRef>, // An array of matched Accounts
|
||||
val statuses : ArrayList<TootStatus>, // An array of matched Statuses
|
||||
val hashtags : ArrayList<TootTag> // An array of matched hashtags
|
||||
) {
|
||||
|
|
|
@ -47,12 +47,14 @@ class TootStatus(parser : TootParser, src : JSONObject) :
|
|||
// 取得に失敗するとINVALID_IDになる
|
||||
val id : Long
|
||||
|
||||
|
||||
|
||||
// The TootAccount which posted the status
|
||||
val accountRef : Int
|
||||
val accountRef : TootAccountRef
|
||||
|
||||
val account : TootAccount
|
||||
get(){
|
||||
return TootAccountMap.find(accountRef)
|
||||
return TootAccountMap.find(accountRef.id)
|
||||
}
|
||||
|
||||
//The number of reblogs for the status
|
||||
|
@ -164,7 +166,7 @@ class TootStatus(parser : TootParser, src : JSONObject) :
|
|||
val who =parser.account(src.optJSONObject("account"))
|
||||
?: throw RuntimeException("missing account")
|
||||
|
||||
this.accountRef = TootAccountMap.register(parser,who)
|
||||
this.accountRef = TootAccountRef( parser,who)
|
||||
|
||||
when(parser.serviceType) {
|
||||
ServiceType.MASTODON -> {
|
||||
|
|
|
@ -192,7 +192,8 @@ class DlgListMember(
|
|||
|
||||
val search_result = TootParser(activity, list_owner ).results(jsonObject)
|
||||
if(search_result != null) {
|
||||
for(a in search_result.accounts) {
|
||||
for(aRef in search_result.accounts) {
|
||||
val a = aRef.find()
|
||||
if(target_user_full_acct.equals(list_owner .getFullAcct(a), ignoreCase = true)) {
|
||||
local_who = a
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue