SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/action/Action_Follow.kt

476 lines
13 KiB
Kotlin
Raw Normal View History

package jp.juggler.subwaytooter.action
import android.support.v7.app.AlertDialog
import jp.juggler.subwaytooter.ActMain
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
import jp.juggler.subwaytooter.dialog.DlgConfirm
import jp.juggler.subwaytooter.table.AcctColor
import jp.juggler.subwaytooter.table.SavedAccount
import jp.juggler.subwaytooter.table.UserRelation
import jp.juggler.subwaytooter.util.EmptyCallback
import jp.juggler.subwaytooter.util.encodePercent
import jp.juggler.subwaytooter.util.showToast
import okhttp3.Request
import okhttp3.RequestBody
object Action_Follow {
fun follow(
activity : ActMain,
pos : Int,
access_info : SavedAccount,
whoRef : TootAccountRef,
bFollow : Boolean = true,
bConfirmMoved : Boolean = false,
bConfirmed : Boolean = false,
callback : EmptyCallback? = null
) {
2018-05-18 19:08:46 +02:00
val who = whoRef.get()
if(access_info.isMe(who)) {
showToast(activity, false, R.string.it_is_you)
return
}
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
)
}
.setNeutralButton(R.string.ignore_suggestion) { _, _ ->
follow(
activity,
pos,
access_info,
whoRef,
bFollow = bFollow,
bConfirmMoved = true, // CHANGED
bConfirmed = bConfirmed,
callback = callback
)
}
.setNegativeButton(android.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,
AcctColor.getNickname(access_info.acct)
)
, object : DlgConfirm.Callback {
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,
whoRef.decoded_display_name,
AcctColor.getNickname(access_info.acct)
)
DlgConfirm.open(
activity,
msg,
object : DlgConfirm.Callback {
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
set(value) {
access_info.confirm_follow = value
access_info.saveSetting()
activity.reloadAccountSetting(access_info)
}
})
return
} else {
DlgConfirm.open(
activity,
activity.getString(
R.string.confirm_unfollow_who_from,
whoRef.decoded_display_name,
AcctColor.getNickname(access_info.acct)
),
object : DlgConfirm.Callback {
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_unfollow
set(value) {
access_info.confirm_unfollow = value
access_info.saveSetting()
activity.reloadAccountSetting(access_info)
}
})
return
}
}
TootTaskRunner(activity, TootTaskRunner.PROGRESS_NONE).run(access_info, object : TootTask {
internal var relation : UserRelation? = null
override fun background(client : TootApiClient) : TootApiResult? {
var result : TootApiResult?
if(bFollow and who.acct.contains("@")) {
// リモートフォローする
val request_builder = Request.Builder().post(
RequestBody.create(
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)
if(remote_who != null) {
val rr = loadRelation1(client, access_info, remote_who.id)
result = rr.result
relation = rr.relation
}
} else {
// ローカルでフォロー/アンフォローする
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
)
val jsonObject = result?.jsonObject
if(jsonObject != null) {
relation =
saveUserRelation(access_info, parseItem(::TootRelationShip, jsonObject))
}
}
return result
}
override fun handleResult(result : TootApiResult?) {
if(result == null) return // cancelled.
val relation = this.relation
if(relation != null) {
activity.showColumnMatchAccount(access_info)
if(bFollow && relation.getRequested(who)) {
// 鍵付きアカウントにフォローリクエストを申請した状態
showToast(activity, false, R.string.follow_requested)
} 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) {
showToast(activity, false, R.string.cant_follow_locked_user)
} else {
showToast(activity, false, result.error)
}
}
})
}
// acct で指定したユーザをリモートフォローする
fun followRemote(
activity : ActMain,
access_info : SavedAccount,
acct : String,
locked : Boolean,
bConfirmed : Boolean = false,
callback : EmptyCallback? = null
) {
if(access_info.isMe(acct)) {
showToast(activity, false, R.string.it_is_you)
return
}
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)
}
})
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)
}
})
return
}
}
TootTaskRunner(activity, TootTaskRunner.PROGRESS_NONE).run(access_info, object : TootTask {
internal var remote_who : TootAccount? = null
internal var relation : UserRelation? = null
override fun background(client : TootApiClient) : TootApiResult? {
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)
result = rr.result
relation = rr.relation
}
return result
}
override fun handleResult(result : TootApiResult?) {
if(result == null) return // cancelled.
if(relation != null) {
activity.showColumnMatchAccount(access_info)
if(callback != null) callback()
} else if(locked && (result.response?.code() ?: - 1) == 422) {
showToast(activity, false, R.string.cant_follow_locked_user)
} else {
showToast(activity, false, result.error)
}
}
})
}
fun followFromAnotherAccount(
activity : ActMain,
pos : Int,
access_info : SavedAccount,
account : TootAccount?,
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)
)
)
.setPositiveButton(R.string.ok) { _, _ ->
Action_User.profileFromAnotherAccount(activity, pos, access_info, account.moved)
}
.setNeutralButton(R.string.ignore_suggestion) { _, _ ->
followFromAnotherAccount(
activity,
pos,
access_info,
account,
bConfirmMoved = true //CHANGED
)
}
.setNegativeButton(android.R.string.cancel, null)
.show()
return
}
val who_acct = access_info.getFullAcct(account)
AccountPicker.pick(
activity,
2018-01-13 07:15:52 +01:00
bAuto = false,
message = activity.getString(R.string.account_picker_follow),
accountListArg = makeAccountListNonPseudo(activity, account.host)
) { ai ->
followRemote(
activity,
ai,
who_acct,
account.locked,
callback = activity.follow_complete_callback
)
}
}
fun authorizeFollowRequest(
activity : ActMain,
access_info : SavedAccount,
whoRef : TootAccountRef,
bAllow : Boolean
) {
2018-05-18 19:08:46 +02:00
val who = whoRef.get()
if(access_info.isMe(who)) {
showToast(activity, false, R.string.it_is_you)
return
}
TootTaskRunner(activity).run(access_info, object : TootTask {
override fun background(client : TootApiClient) : TootApiResult? {
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
)
}
override fun handleResult(result : TootApiResult?) {
if(result == null) return // cancelled.
val jsonObject = result.jsonObject
if(jsonObject != null) {
for(column in App1.getAppState(activity).column_list) {
column.removeFollowRequest(access_info, who.id)
}
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)
}
}
})
}
}