2018-01-04 19:52:25 +01:00
|
|
|
package jp.juggler.subwaytooter.action
|
|
|
|
|
|
|
|
import org.json.JSONArray
|
|
|
|
import org.json.JSONObject
|
|
|
|
|
|
|
|
import java.util.regex.Pattern
|
|
|
|
|
|
|
|
import jp.juggler.subwaytooter.ActMain
|
|
|
|
import jp.juggler.subwaytooter.App1
|
|
|
|
import jp.juggler.subwaytooter.R
|
2018-01-21 17:47:13 +01:00
|
|
|
import jp.juggler.subwaytooter.api.*
|
2018-08-18 12:58:14 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.EntityId
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.api.entity.TootAccount
|
|
|
|
import jp.juggler.subwaytooter.api.entity.TootRelationShip
|
2018-01-10 16:47:35 +01:00
|
|
|
import jp.juggler.subwaytooter.api.entity.parseList
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.dialog.DlgConfirm
|
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
2018-01-21 13:46:36 +01:00
|
|
|
import jp.juggler.subwaytooter.util.encodePercent
|
|
|
|
import jp.juggler.subwaytooter.util.showToast
|
2018-08-31 14:47:40 +02:00
|
|
|
import jp.juggler.subwaytooter.util.toPostRequestBuilder
|
2018-01-21 13:46:36 +01:00
|
|
|
import jp.juggler.subwaytooter.util.withCaption
|
2018-01-04 19:52:25 +01:00
|
|
|
import okhttp3.Request
|
|
|
|
import okhttp3.RequestBody
|
|
|
|
|
|
|
|
object Action_ListMember {
|
|
|
|
|
|
|
|
private val reFollowError = Pattern.compile("follow", Pattern.CASE_INSENSITIVE)
|
|
|
|
|
|
|
|
interface Callback {
|
|
|
|
fun onListMemberUpdated(willRegistered : Boolean, bSuccess : Boolean)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun add(
|
2018-01-21 13:46:36 +01:00
|
|
|
activity : ActMain,
|
|
|
|
access_info : SavedAccount,
|
2018-08-18 12:58:14 +02:00
|
|
|
list_id : EntityId,
|
2018-01-21 13:46:36 +01:00
|
|
|
local_who : TootAccount,
|
2018-08-31 14:47:40 +02:00
|
|
|
bFollow : Boolean = false,
|
2018-01-21 13:46:36 +01:00
|
|
|
callback : Callback?
|
2018-01-04 19:52:25 +01:00
|
|
|
) {
|
2018-08-31 14:47:40 +02:00
|
|
|
if(access_info.isMe(local_who)) {
|
|
|
|
showToast(activity, false, R.string.it_is_you)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-01-10 16:47:35 +01:00
|
|
|
TootTaskRunner(activity).run(access_info, object : TootTask {
|
2018-01-04 19:52:25 +01:00
|
|
|
override fun background(client : TootApiClient) : TootApiResult? {
|
|
|
|
|
|
|
|
var result : TootApiResult?
|
|
|
|
|
2018-11-01 13:48:54 +01:00
|
|
|
val parser = TootParser(activity, access_info)
|
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
return if(access_info.isMisskey) {
|
|
|
|
// misskeyのリストはフォロー無関係
|
|
|
|
|
|
|
|
val params = access_info.putMisskeyApiToken(JSONObject())
|
|
|
|
.put("listId", list_id)
|
|
|
|
.put("userId", local_who.id)
|
|
|
|
|
|
|
|
client.request("/api/users/lists/push", params.toPostRequestBuilder())
|
|
|
|
// 204 no content
|
|
|
|
} else {
|
|
|
|
if(bFollow) {
|
|
|
|
val relation : TootRelationShip?
|
|
|
|
if(access_info.isLocalUser(local_who)) {
|
|
|
|
val request_builder = Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, "" // 空データ
|
|
|
|
)
|
2018-01-21 13:46:36 +01:00
|
|
|
)
|
2018-08-31 14:47:40 +02:00
|
|
|
|
|
|
|
result = client.request(
|
|
|
|
"/api/v1/accounts/" + local_who.id + "/follow",
|
|
|
|
request_builder
|
2018-01-21 13:46:36 +01:00
|
|
|
)
|
2018-08-31 14:47:40 +02:00
|
|
|
} else {
|
|
|
|
// リモートフォローする
|
|
|
|
val request_builder = Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED,
|
|
|
|
"uri=" + local_who.acct.encodePercent()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
result = client.request("/api/v1/follows", request_builder)
|
|
|
|
|
|
|
|
val jsonObject = result?.jsonObject ?: return result
|
|
|
|
|
2018-11-01 13:48:54 +01:00
|
|
|
val a = parser.account(jsonObject)
|
2018-08-31 14:47:40 +02:00
|
|
|
?: return result.setError("parse error.")
|
|
|
|
|
|
|
|
// リモートフォローの後にリレーションシップを取得しなおす
|
|
|
|
result = client.request("/api/v1/accounts/relationships?id[]=" + a.id)
|
|
|
|
}
|
|
|
|
val jsonArray = result?.jsonArray ?: return result
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2018-11-01 13:48:54 +01:00
|
|
|
val relation_list = parseList(::TootRelationShip,parser, jsonArray)
|
2018-08-31 14:47:40 +02:00
|
|
|
relation = if(relation_list.isEmpty()) null else relation_list[0]
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
if(relation == null) {
|
|
|
|
return TootApiResult("parse error.")
|
|
|
|
}
|
|
|
|
saveUserRelation(access_info, relation)
|
|
|
|
|
|
|
|
if(! relation.following) {
|
|
|
|
if(relation.requested) {
|
|
|
|
return TootApiResult(activity.getString(R.string.cant_add_list_follow_requesting))
|
|
|
|
} else {
|
|
|
|
// リモートフォローの場合、正常ケースでもここを通る場合がある
|
|
|
|
// 何もしてはいけない…
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
// リストメンバー追加
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
val content = JSONObject()
|
|
|
|
try {
|
|
|
|
val account_ids = JSONArray()
|
|
|
|
account_ids.put(local_who.id.toString())
|
|
|
|
content.put("account_ids", account_ids)
|
|
|
|
} catch(ex : Throwable) {
|
|
|
|
return TootApiResult(ex.withCaption("can't encoding json parameter."))
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
2018-08-31 14:47:40 +02:00
|
|
|
val request_builder = Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_JSON, content.toString()
|
|
|
|
)
|
2018-01-21 13:46:36 +01:00
|
|
|
)
|
2018-08-31 14:47:40 +02:00
|
|
|
|
|
|
|
client.request("/api/v1/lists/$list_id/accounts", request_builder)
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun handleResult(result : TootApiResult?) {
|
|
|
|
var bSuccess = false
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if(result == null) return // cancelled.
|
|
|
|
|
|
|
|
if(result.jsonObject != null) {
|
|
|
|
for(column in App1.getAppState(activity).column_list) {
|
|
|
|
// リストメンバー追加イベントをカラムに伝達
|
|
|
|
column.onListMemberUpdated(access_info, list_id, local_who, true)
|
|
|
|
}
|
|
|
|
// フォロー状態の更新を表示に反映させる
|
|
|
|
if(bFollow) activity.showColumnMatchAccount(access_info)
|
|
|
|
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(activity, false, R.string.list_member_added)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
bSuccess = true
|
|
|
|
|
|
|
|
} else {
|
2018-01-10 16:47:35 +01:00
|
|
|
val response = result.response
|
|
|
|
val error = result.error
|
|
|
|
if(response != null
|
2018-01-21 13:46:36 +01:00
|
|
|
&& response.code() == 422
|
2018-08-31 14:47:40 +02:00
|
|
|
&& error != null
|
|
|
|
&& reFollowError.matcher(error).find()
|
|
|
|
) {
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
if(! bFollow) {
|
|
|
|
DlgConfirm.openSimple(
|
2018-01-21 13:46:36 +01:00
|
|
|
activity,
|
|
|
|
activity.getString(
|
|
|
|
R.string.list_retry_with_follow,
|
|
|
|
access_info.getFullAcct(local_who)
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
Action_ListMember.add(
|
|
|
|
activity,
|
|
|
|
access_info,
|
|
|
|
list_id,
|
|
|
|
local_who,
|
2018-08-31 14:47:40 +02:00
|
|
|
bFollow = true,
|
|
|
|
callback = callback
|
2018-01-21 13:46:36 +01:00
|
|
|
)
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
} else {
|
|
|
|
android.app.AlertDialog.Builder(activity)
|
|
|
|
.setCancelable(true)
|
|
|
|
.setMessage(R.string.cant_add_list_follow_requesting)
|
|
|
|
.setNeutralButton(R.string.close, null)
|
|
|
|
.show()
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(activity, true, error)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
callback?.onListMemberUpdated(true, bSuccess)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fun delete(
|
2018-01-21 13:46:36 +01:00
|
|
|
activity : ActMain,
|
|
|
|
access_info : SavedAccount,
|
2018-08-18 12:58:14 +02:00
|
|
|
list_id : EntityId,
|
2018-01-21 13:46:36 +01:00
|
|
|
local_who : TootAccount,
|
|
|
|
callback : Callback?
|
2018-01-04 19:52:25 +01:00
|
|
|
) {
|
2018-08-31 14:47:40 +02:00
|
|
|
|
|
|
|
if(access_info.isMisskey) {
|
|
|
|
showToast(activity, false, "Misskey has no API to delete member from the list.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-01-10 16:47:35 +01:00
|
|
|
TootTaskRunner(activity).run(access_info, object : TootTask {
|
2018-01-04 19:52:25 +01:00
|
|
|
override fun background(client : TootApiClient) : TootApiResult? {
|
|
|
|
return client.request(
|
2018-01-21 13:46:36 +01:00
|
|
|
"/api/v1/lists/" + list_id + "/accounts?account_ids[]=" + local_who.id,
|
|
|
|
Request.Builder().delete()
|
2018-01-04 19:52:25 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun handleResult(result : TootApiResult?) {
|
|
|
|
var bSuccess = false
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if(result == null) return // cancelled.
|
|
|
|
|
|
|
|
if(result.jsonObject != null) {
|
|
|
|
|
|
|
|
for(column in App1.getAppState(activity).column_list) {
|
|
|
|
column.onListMemberUpdated(access_info, list_id, local_who, false)
|
|
|
|
}
|
|
|
|
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(activity, false, R.string.delete_succeeded)
|
2018-01-04 19:52:25 +01:00
|
|
|
|
|
|
|
bSuccess = true
|
|
|
|
|
|
|
|
} else {
|
2018-01-21 13:46:36 +01:00
|
|
|
showToast(activity, false, result.error)
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
callback?.onListMemberUpdated(false, bSuccess)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|