2018-01-04 19:52:25 +01:00
|
|
|
package jp.juggler.subwaytooter.action
|
|
|
|
|
2019-02-15 02:51:22 +01:00
|
|
|
import androidx.appcompat.app.AlertDialog
|
2021-05-17 16:13:04 +02:00
|
|
|
import jp.juggler.subwaytooter.*
|
2018-01-21 17:47:13 +01:00
|
|
|
import jp.juggler.subwaytooter.api.*
|
2018-08-20 02:07:55 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.*
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.dialog.DlgConfirm
|
2021-05-27 04:15:59 +02:00
|
|
|
import jp.juggler.subwaytooter.dialog.pickAccount
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.table.AcctColor
|
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
|
|
|
import jp.juggler.subwaytooter.table.UserRelation
|
2021-05-27 04:15:59 +02:00
|
|
|
import jp.juggler.util.*
|
|
|
|
|
2021-06-21 05:03:09 +02:00
|
|
|
fun ActMain.clickFollow(
|
|
|
|
pos: Int,
|
|
|
|
accessInfo: SavedAccount,
|
|
|
|
who: TootAccount,
|
|
|
|
whoRef: TootAccountRef,
|
|
|
|
relation: UserRelation,
|
|
|
|
) {
|
|
|
|
when {
|
|
|
|
accessInfo.isPseudo ->
|
|
|
|
followFromAnotherAccount(pos, accessInfo, who)
|
|
|
|
|
|
|
|
accessInfo.isMisskey &&
|
|
|
|
relation.getRequested(who) &&
|
|
|
|
!relation.getFollowing(who) ->
|
|
|
|
followRequestDelete(
|
|
|
|
pos, accessInfo, whoRef,
|
|
|
|
callback = cancelFollowRequestCompleteCallback
|
|
|
|
)
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
val bSet = !(relation.getRequested(who) || relation.getFollowing(who))
|
|
|
|
follow(
|
|
|
|
pos,
|
|
|
|
accessInfo,
|
|
|
|
whoRef,
|
|
|
|
bFollow = bSet,
|
|
|
|
callback = when (bSet) {
|
|
|
|
true -> followCompleteCallback
|
|
|
|
else -> unfollowCompleteCallback
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-27 04:15:59 +02:00
|
|
|
fun ActMain.follow(
|
|
|
|
pos: Int,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo: SavedAccount,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef: TootAccountRef,
|
|
|
|
bFollow: Boolean = true,
|
|
|
|
bConfirmMoved: Boolean = false,
|
|
|
|
bConfirmed: Boolean = false,
|
2021-06-20 15:12:25 +02:00
|
|
|
callback: () -> Unit = {},
|
2021-05-27 04:15:59 +02:00
|
|
|
) {
|
|
|
|
val activity = this@follow
|
|
|
|
val who = whoRef.get()
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isMe(who)) {
|
2021-05-27 04:15:59 +02:00
|
|
|
showToast(false, R.string.it_is_you)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bConfirmMoved && bFollow && who.moved != null) {
|
|
|
|
AlertDialog.Builder(activity)
|
|
|
|
.setMessage(
|
|
|
|
getString(
|
|
|
|
R.string.jump_moved_user,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.getFullAcct(who),
|
|
|
|
accessInfo.getFullAcct(who.moved)
|
2021-05-27 04:15:59 +02:00
|
|
|
)
|
|
|
|
)
|
|
|
|
.setPositiveButton(R.string.ok) { _, _ ->
|
|
|
|
userProfileFromAnotherAccount(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
who.moved
|
|
|
|
)
|
|
|
|
}
|
|
|
|
.setNeutralButton(R.string.ignore_suggestion) { _, _ ->
|
|
|
|
follow(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef,
|
|
|
|
bFollow = bFollow,
|
|
|
|
bConfirmMoved = true, // CHANGED
|
|
|
|
bConfirmed = bConfirmed,
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
.setNegativeButton(R.string.cancel, null)
|
|
|
|
.show()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bConfirmed) {
|
|
|
|
if (bFollow && who.locked) {
|
|
|
|
DlgConfirm.open(
|
|
|
|
activity,
|
|
|
|
activity.getString(
|
|
|
|
R.string.confirm_follow_request_who_from,
|
|
|
|
whoRef.decoded_display_name,
|
2021-06-20 15:12:25 +02:00
|
|
|
AcctColor.getNickname(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
),
|
|
|
|
object : DlgConfirm.Callback {
|
|
|
|
|
|
|
|
override fun onOK() {
|
|
|
|
follow(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef,
|
|
|
|
bFollow = bFollow,
|
|
|
|
bConfirmMoved = bConfirmMoved,
|
|
|
|
bConfirmed = true, // CHANGED
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
override var isConfirmEnabled: Boolean
|
2021-06-20 15:12:25 +02:00
|
|
|
get() = accessInfo.confirm_follow_locked
|
2021-05-27 04:15:59 +02:00
|
|
|
set(value) {
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.confirm_follow_locked = value
|
|
|
|
accessInfo.saveSetting()
|
|
|
|
activity.reloadAccountSetting(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
return
|
|
|
|
} else if (bFollow) {
|
|
|
|
DlgConfirm.open(
|
|
|
|
activity,
|
|
|
|
getString(
|
|
|
|
R.string.confirm_follow_who_from,
|
|
|
|
whoRef.decoded_display_name,
|
2021-06-20 15:12:25 +02:00
|
|
|
AcctColor.getNickname(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
),
|
|
|
|
object : DlgConfirm.Callback {
|
|
|
|
|
|
|
|
override fun onOK() {
|
|
|
|
follow(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef,
|
|
|
|
bFollow = bFollow,
|
|
|
|
bConfirmMoved = bConfirmMoved,
|
|
|
|
bConfirmed = true, //CHANGED
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
override var isConfirmEnabled: Boolean
|
2021-06-20 15:12:25 +02:00
|
|
|
get() = accessInfo.confirm_follow
|
2021-05-27 04:15:59 +02:00
|
|
|
set(value) {
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.confirm_follow = value
|
|
|
|
accessInfo.saveSetting()
|
|
|
|
activity.reloadAccountSetting(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
DlgConfirm.open(
|
|
|
|
activity,
|
|
|
|
getString(
|
|
|
|
R.string.confirm_unfollow_who_from,
|
|
|
|
whoRef.decoded_display_name,
|
2021-06-20 15:12:25 +02:00
|
|
|
AcctColor.getNickname(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
),
|
|
|
|
object : DlgConfirm.Callback {
|
|
|
|
|
|
|
|
override fun onOK() {
|
|
|
|
follow(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef,
|
|
|
|
bFollow = bFollow,
|
|
|
|
bConfirmMoved = bConfirmMoved,
|
|
|
|
bConfirmed = true, // CHANGED
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
override var isConfirmEnabled: Boolean
|
2021-06-20 15:12:25 +02:00
|
|
|
get() = accessInfo.confirm_unfollow
|
2021-05-27 04:15:59 +02:00
|
|
|
set(value) {
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.confirm_unfollow = value
|
|
|
|
accessInfo.saveSetting()
|
|
|
|
activity.reloadAccountSetting(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
launchMain {
|
|
|
|
var resultRelation: UserRelation? = null
|
2021-06-20 15:12:25 +02:00
|
|
|
runApiTask(accessInfo, progressStyle = ApiTask.PROGRESS_NONE) { client ->
|
|
|
|
val parser = TootParser(activity, accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
|
|
|
|
var userId = who.id
|
|
|
|
if (who.isRemote) {
|
|
|
|
|
|
|
|
// リモートユーザの確認
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val skipAccountSync = if (accessInfo.isMisskey) {
|
2021-05-27 04:15:59 +02:00
|
|
|
// Misskey の /users/show はリモートユーザに関して404を返すので
|
|
|
|
// userIdからリモートユーザを照合することはできない。
|
|
|
|
// ただし検索APIがエラーになるかどうかは未確認
|
|
|
|
false
|
|
|
|
} else {
|
|
|
|
// https://github.com/tateisu/SubwayTooter/issues/124
|
|
|
|
// によると、閉じたタンスのユーザを同期しようとすると検索APIがエラーを返す
|
|
|
|
// この問題を回避するため、手持ちのuserIdで照合したユーザのacctが目的のユーザと同じなら
|
|
|
|
// 検索APIを呼び出さないようにする
|
2021-06-20 15:12:25 +02:00
|
|
|
val result = client.request("/api/v1/accounts/$userId")
|
2021-05-27 04:15:59 +02:00
|
|
|
?: return@runApiTask null
|
|
|
|
who.acct == parser.account(result.jsonObject)?.acct
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!skipAccountSync) {
|
|
|
|
// 同タンスのIDではなかった場合、検索APIを使う
|
2021-06-20 15:12:25 +02:00
|
|
|
val (result, ar) = client.syncAccountByAcct(accessInfo, who.acct)
|
2021-05-27 04:15:59 +02:00
|
|
|
val user = ar?.get() ?: return@runApiTask result
|
|
|
|
userId = user.id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isMisskey) {
|
2021-05-27 04:15:59 +02:00
|
|
|
|
|
|
|
client.request(
|
|
|
|
when {
|
|
|
|
bFollow -> "/api/following/create"
|
|
|
|
else -> "/api/following/delete"
|
|
|
|
},
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.putMisskeyApiToken().apply {
|
2021-05-27 04:15:59 +02:00
|
|
|
put("userId", userId)
|
|
|
|
}
|
|
|
|
.toPostRequestBuilder()
|
|
|
|
)?.also { result ->
|
|
|
|
|
|
|
|
fun saveFollow(f: Boolean) {
|
2021-06-20 15:12:25 +02:00
|
|
|
val ur = UserRelation.load(accessInfo.db_id, userId)
|
2021-05-27 04:15:59 +02:00
|
|
|
ur.following = f
|
|
|
|
UserRelation.save1Misskey(
|
|
|
|
System.currentTimeMillis(),
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.db_id,
|
2021-05-27 04:15:59 +02:00
|
|
|
userId.toString(),
|
|
|
|
ur
|
|
|
|
)
|
|
|
|
resultRelation = ur
|
|
|
|
}
|
|
|
|
|
|
|
|
val error = result.error
|
|
|
|
when {
|
|
|
|
// success
|
|
|
|
error == null -> saveFollow(bFollow)
|
|
|
|
|
|
|
|
// already followed/unfollowed
|
|
|
|
error.contains("already following") -> saveFollow(bFollow)
|
|
|
|
error.contains("already not following") -> saveFollow(bFollow)
|
|
|
|
|
|
|
|
// else something error
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
client.request(
|
2021-06-20 15:12:25 +02:00
|
|
|
"/api/v1/accounts/$userId/${if (bFollow) "follow" else "unfollow"}",
|
2021-05-27 04:15:59 +02:00
|
|
|
"".toFormRequestBody().toPost()
|
|
|
|
)?.also { result ->
|
|
|
|
val newRelation = parseItem(::TootRelationShip, parser, result.jsonObject)
|
2021-06-20 15:12:25 +02:00
|
|
|
resultRelation = accessInfo.saveUserRelation(newRelation)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}?.let { result ->
|
|
|
|
val relation = resultRelation
|
|
|
|
when {
|
|
|
|
relation != null -> {
|
|
|
|
|
|
|
|
when {
|
|
|
|
// 鍵付きアカウントにフォローリクエストを申請した状態
|
|
|
|
bFollow && relation.getRequested(who) ->
|
|
|
|
showToast(false, R.string.follow_requested)
|
|
|
|
!bFollow && relation.getRequested(who) ->
|
|
|
|
showToast(false, R.string.follow_request_cant_remove_by_sender)
|
|
|
|
|
|
|
|
// ローカル操作成功、もしくはリモートフォロー成功
|
|
|
|
else -> callback()
|
|
|
|
}
|
2021-06-20 15:12:25 +02:00
|
|
|
showColumnMatchAccount(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
bFollow && who.locked && (result.response?.code ?: -1) == 422 ->
|
|
|
|
showToast(false, R.string.cant_follow_locked_user)
|
|
|
|
|
|
|
|
else -> showToast(false, result.error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// acct で指定したユーザをリモートフォローする
|
|
|
|
private fun ActMain.followRemote(
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo: SavedAccount,
|
2021-05-27 04:15:59 +02:00
|
|
|
acct: Acct,
|
|
|
|
locked: Boolean,
|
|
|
|
bConfirmed: Boolean = false,
|
2021-06-20 15:12:25 +02:00
|
|
|
callback: () -> Unit = {},
|
2021-05-27 04:15:59 +02:00
|
|
|
) {
|
|
|
|
val activity = this@followRemote
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isMe(acct)) {
|
2021-05-27 04:15:59 +02:00
|
|
|
showToast(false, R.string.it_is_you)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bConfirmed) {
|
|
|
|
if (locked) {
|
|
|
|
DlgConfirm.open(
|
|
|
|
activity,
|
|
|
|
getString(
|
|
|
|
R.string.confirm_follow_request_who_from,
|
|
|
|
AcctColor.getNickname(acct),
|
2021-06-20 15:12:25 +02:00
|
|
|
AcctColor.getNickname(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
),
|
|
|
|
object : DlgConfirm.Callback {
|
|
|
|
override fun onOK() {
|
|
|
|
followRemote(
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
acct,
|
|
|
|
locked,
|
|
|
|
bConfirmed = true, //CHANGE
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
override var isConfirmEnabled: Boolean
|
2021-06-20 15:12:25 +02:00
|
|
|
get() = accessInfo.confirm_follow_locked
|
2021-05-27 04:15:59 +02:00
|
|
|
set(value) {
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.confirm_follow_locked = value
|
|
|
|
accessInfo.saveSetting()
|
|
|
|
reloadAccountSetting(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
DlgConfirm.open(
|
|
|
|
activity,
|
|
|
|
getString(
|
|
|
|
R.string.confirm_follow_who_from,
|
|
|
|
AcctColor.getNickname(acct),
|
2021-06-20 15:12:25 +02:00
|
|
|
AcctColor.getNickname(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
),
|
|
|
|
object : DlgConfirm.Callback {
|
|
|
|
|
|
|
|
override fun onOK() {
|
|
|
|
followRemote(
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
acct,
|
|
|
|
locked,
|
|
|
|
bConfirmed = true, //CHANGE
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
override var isConfirmEnabled: Boolean
|
2021-06-20 15:12:25 +02:00
|
|
|
get() = accessInfo.confirm_follow
|
2021-05-27 04:15:59 +02:00
|
|
|
set(value) {
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.confirm_follow = value
|
|
|
|
accessInfo.saveSetting()
|
|
|
|
reloadAccountSetting(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
launchMain {
|
|
|
|
var resultRelation: UserRelation? = null
|
2021-06-20 15:12:25 +02:00
|
|
|
runApiTask(accessInfo, progressStyle = ApiTask.PROGRESS_NONE) { client ->
|
|
|
|
val parser = TootParser(this, accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val (r2, ar) = client.syncAccountByAcct(accessInfo, acct)
|
2021-05-27 04:15:59 +02:00
|
|
|
val user = ar?.get() ?: return@runApiTask r2
|
|
|
|
val userId = user.id
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isMisskey) {
|
2021-05-27 04:15:59 +02:00
|
|
|
client.request(
|
|
|
|
"/api/following/create",
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.putMisskeyApiToken().apply {
|
2021-05-27 04:15:59 +02:00
|
|
|
put("userId", userId)
|
|
|
|
}.toPostRequestBuilder()
|
|
|
|
).also { result ->
|
2021-06-20 15:12:25 +02:00
|
|
|
if (result?.error?.contains("already following") == true ||
|
|
|
|
result?.error?.contains("already not following") == true
|
2021-05-27 04:15:59 +02:00
|
|
|
) {
|
|
|
|
// DBから読み直して値を変更する
|
2021-06-20 15:12:25 +02:00
|
|
|
resultRelation = UserRelation.load(accessInfo.db_id, userId)
|
2021-05-27 04:15:59 +02:00
|
|
|
.apply { following = true }
|
|
|
|
} else {
|
|
|
|
// parserに残ってるRelationをDBに保存する
|
|
|
|
parser.account(result?.jsonObject)?.let {
|
2021-06-20 15:12:25 +02:00
|
|
|
resultRelation = accessInfo.saveUserRelationMisskey(it.id, parser)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
client.request(
|
2021-06-20 15:12:25 +02:00
|
|
|
"/api/v1/accounts/$userId/follow",
|
2021-05-27 04:15:59 +02:00
|
|
|
"".toFormRequestBody().toPost()
|
|
|
|
)?.also { result ->
|
|
|
|
parseItem(::TootRelationShip, parser, result.jsonObject)?.let {
|
2021-06-20 15:12:25 +02:00
|
|
|
resultRelation = accessInfo.saveUserRelation(it)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}?.let { result ->
|
|
|
|
when {
|
|
|
|
resultRelation != null -> {
|
|
|
|
callback()
|
2021-06-20 15:12:25 +02:00
|
|
|
showColumnMatchAccount(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
locked && (result.response?.code ?: -1) == 422 ->
|
|
|
|
showToast(false, R.string.cant_follow_locked_user)
|
|
|
|
|
|
|
|
else ->
|
|
|
|
showToast(false, result.error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun ActMain.followFromAnotherAccount(
|
|
|
|
pos: Int,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo: SavedAccount,
|
2021-05-27 04:15:59 +02:00
|
|
|
account: TootAccount?,
|
2021-06-20 15:12:25 +02:00
|
|
|
bConfirmMoved: Boolean = false,
|
2021-05-27 04:15:59 +02:00
|
|
|
) {
|
|
|
|
account ?: return
|
|
|
|
|
|
|
|
if (!bConfirmMoved && account.moved != null) {
|
|
|
|
AlertDialog.Builder(this)
|
|
|
|
.setMessage(
|
|
|
|
getString(
|
|
|
|
R.string.jump_moved_user,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.getFullAcct(account),
|
|
|
|
accessInfo.getFullAcct(account.moved)
|
2021-05-27 04:15:59 +02:00
|
|
|
)
|
|
|
|
)
|
|
|
|
.setPositiveButton(R.string.ok) { _, _ ->
|
2021-06-20 15:12:25 +02:00
|
|
|
userProfileFromAnotherAccount(pos, accessInfo, account.moved)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
.setNeutralButton(R.string.ignore_suggestion) { _, _ ->
|
|
|
|
followFromAnotherAccount(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
account,
|
|
|
|
bConfirmMoved = true //CHANGED
|
|
|
|
)
|
|
|
|
}
|
|
|
|
.setNegativeButton(android.R.string.cancel, null)
|
|
|
|
.show()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val whoAcct = accessInfo.getFullAcct(account)
|
2021-05-27 04:15:59 +02:00
|
|
|
launchMain {
|
|
|
|
pickAccount(
|
|
|
|
bAuto = false,
|
|
|
|
message = getString(R.string.account_picker_follow),
|
|
|
|
accountListArg = accountListNonPseudo(account.apiHost)
|
|
|
|
)?.let {
|
|
|
|
followRemote(
|
|
|
|
it,
|
2021-06-20 15:12:25 +02:00
|
|
|
whoAcct,
|
2021-05-27 04:15:59 +02:00
|
|
|
account.locked,
|
2021-06-20 15:12:25 +02:00
|
|
|
callback = followCompleteCallback
|
2021-05-27 04:15:59 +02:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun ActMain.followRequestAuthorize(
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo: SavedAccount,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef: TootAccountRef,
|
2021-06-20 15:12:25 +02:00
|
|
|
bAllow: Boolean,
|
2021-05-27 04:15:59 +02:00
|
|
|
) {
|
|
|
|
val who = whoRef.get()
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isMe(who)) {
|
2021-05-27 04:15:59 +02:00
|
|
|
showToast(false, R.string.it_is_you)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
launchMain {
|
2021-06-20 15:12:25 +02:00
|
|
|
runApiTask(accessInfo) { client ->
|
|
|
|
val parser = TootParser(this, accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isMisskey) {
|
2021-05-27 04:15:59 +02:00
|
|
|
client.request(
|
|
|
|
"/api/following/requests/${if (bAllow) "accept" else "reject"}",
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.putMisskeyApiToken().apply {
|
2021-05-27 04:15:59 +02:00
|
|
|
put("userId", who.id)
|
|
|
|
}
|
|
|
|
.toPostRequestBuilder()
|
|
|
|
).also { result ->
|
|
|
|
val user = parser.account(result?.jsonObject)
|
|
|
|
if (user != null) {
|
|
|
|
// parserに残ってるRelationをDBに保存する
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.saveUserRelationMisskey(user.id, parser)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
// 読めなくてもエラー処理は行わない
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
client.request(
|
|
|
|
"/api/v1/follow_requests/${who.id}/${if (bAllow) "authorize" else "reject"}",
|
|
|
|
"".toFormRequestBody().toPost()
|
|
|
|
)?.also { result ->
|
|
|
|
// Mastodon 3.0.0 から更新されたリレーションを返す
|
|
|
|
// https//github.com/tootsuite/mastodon/pull/11800
|
|
|
|
val newRelation = parseItem(::TootRelationShip, parser, result.jsonObject)
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo.saveUserRelation(newRelation)
|
2021-05-27 04:15:59 +02:00
|
|
|
// 読めなくてもエラー処理は行わない
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}?.let { result ->
|
|
|
|
when (result.jsonObject) {
|
|
|
|
null -> showToast(false, result.error)
|
|
|
|
|
|
|
|
else -> {
|
2021-06-20 15:12:25 +02:00
|
|
|
for (column in appState.columnList) {
|
|
|
|
column.removeUser(accessInfo, ColumnType.FOLLOW_REQUESTS, who.id)
|
2021-05-27 04:15:59 +02:00
|
|
|
|
|
|
|
// 他のカラムでもフォロー状態の表示更新が必要
|
2021-06-20 15:12:25 +02:00
|
|
|
if (column.accessInfo == accessInfo &&
|
|
|
|
column.type != ColumnType.FOLLOW_REQUESTS
|
2021-05-27 04:15:59 +02:00
|
|
|
) {
|
|
|
|
column.fireRebindAdapterItems()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
showToast(
|
|
|
|
false,
|
|
|
|
if (bAllow) R.string.follow_request_authorized else R.string.follow_request_rejected,
|
|
|
|
whoRef.decoded_display_name
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun ActMain.followRequestDelete(
|
|
|
|
pos: Int,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo: SavedAccount,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef: TootAccountRef,
|
|
|
|
bConfirmed: Boolean = false,
|
2021-06-20 15:12:25 +02:00
|
|
|
callback: () -> Unit = {},
|
2021-05-27 04:15:59 +02:00
|
|
|
) {
|
2021-06-20 15:12:25 +02:00
|
|
|
if (!accessInfo.isMisskey) {
|
2021-05-27 04:15:59 +02:00
|
|
|
follow(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef,
|
|
|
|
bFollow = false,
|
|
|
|
bConfirmed = bConfirmed,
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
val who = whoRef.get()
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
if (accessInfo.isMe(who)) {
|
2021-05-27 04:15:59 +02:00
|
|
|
showToast(false, R.string.it_is_you)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bConfirmed) {
|
|
|
|
DlgConfirm.openSimple(
|
|
|
|
this,
|
|
|
|
getString(
|
|
|
|
R.string.confirm_cancel_follow_request_who_from,
|
|
|
|
whoRef.decoded_display_name,
|
2021-06-20 15:12:25 +02:00
|
|
|
AcctColor.getNickname(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
)
|
|
|
|
) {
|
|
|
|
followRequestDelete(
|
|
|
|
pos,
|
2021-06-20 15:12:25 +02:00
|
|
|
accessInfo,
|
2021-05-27 04:15:59 +02:00
|
|
|
whoRef,
|
|
|
|
bConfirmed = true, // CHANGED
|
|
|
|
callback = callback
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
launchMain {
|
|
|
|
var resultRelation: UserRelation? = null
|
2021-06-20 15:12:25 +02:00
|
|
|
runApiTask(accessInfo, progressStyle = ApiTask.PROGRESS_NONE) { client ->
|
|
|
|
if (!accessInfo.isMisskey) {
|
2021-05-27 04:15:59 +02:00
|
|
|
TootApiResult("Mastodon has no API to cancel follow request")
|
|
|
|
} else {
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
val parser = TootParser(this, accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
|
|
|
|
var userId: EntityId = who.id
|
|
|
|
|
|
|
|
// リモートユーザの同期
|
|
|
|
if (who.isRemote) {
|
2021-06-20 15:12:25 +02:00
|
|
|
val (result, ar) = client.syncAccountByAcct(accessInfo, who.acct)
|
2021-05-27 04:15:59 +02:00
|
|
|
val user = ar?.get() ?: return@runApiTask result
|
|
|
|
userId = user.id
|
|
|
|
}
|
|
|
|
|
|
|
|
client.request(
|
2021-06-20 15:12:25 +02:00
|
|
|
"/api/following/requests/cancel", accessInfo.putMisskeyApiToken().apply {
|
2021-05-27 04:15:59 +02:00
|
|
|
put("userId", userId)
|
|
|
|
}
|
|
|
|
.toPostRequestBuilder()
|
|
|
|
)?.also { result ->
|
|
|
|
parser.account(result.jsonObject)?.let {
|
|
|
|
// parserに残ってるRelationをDBに保存する
|
2021-06-20 15:12:25 +02:00
|
|
|
resultRelation = accessInfo.saveUserRelationMisskey(it.id, parser)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}?.let { result ->
|
|
|
|
|
|
|
|
when (resultRelation) {
|
|
|
|
null -> showToast(false, result.error)
|
|
|
|
else -> {
|
|
|
|
// ローカル操作成功、もしくはリモートフォロー成功
|
|
|
|
callback()
|
2021-06-20 15:12:25 +02:00
|
|
|
showColumnMatchAccount(accessInfo)
|
2021-05-27 04:15:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|