疑似アカウントを作る時にMisskeyタンスかどうかチェック漏れをなくした

This commit is contained in:
tateisu 2018-11-28 02:42:55 +09:00
parent 0275edfdbc
commit 4405028a1d
6 changed files with 205 additions and 113 deletions

View File

@ -62,16 +62,36 @@ internal fun findAccountByName(
internal fun addPseudoAccount(
context : Context,
host : String,
isMisskey : Boolean = false
) : SavedAccount? {
isMisskey : Boolean? = null,
callback : (SavedAccount) -> Unit
) {
try {
val username = "?"
val full_acct = "$username@$host"
var account = SavedAccount.loadAccountByAcct(context, full_acct)
if(account != null) {
return account
callback(account)
return
}
if(isMisskey == null) {
TootTaskRunner(context).run(object : TootTask {
var isMisskey2 : Boolean = false
override fun background(client : TootApiClient) : TootApiResult? {
client.instance = host
val r = client.getInstanceInformation()
isMisskey2 = r?.jsonObject?.optBoolean(TootApiClient.KEY_IS_MISSKEY) ?: false
return r
}
override fun handleResult(result : TootApiResult?) {
if(result != null) addPseudoAccount(context, host, isMisskey2, callback)
}
})
return
}
val account_info = JSONObject()
@ -91,15 +111,15 @@ internal fun addPseudoAccount(
account.notification_reaction = false
account.notification_vote = false
account.saveSetting()
return account
callback(account)
return
} catch(ex : Throwable) {
val log = LogCategory("addPseudoAccount")
log.trace(ex)
log.e(ex, "failed.")
showToast(context, ex, "addPseudoAccount failed.")
}
return null
return
}
// 疑似アカ以外のアカウントのリスト
@ -150,7 +170,7 @@ internal fun loadRelation1Mastodon(
val r2 = rr.result
val jsonArray = r2?.jsonArray
if(jsonArray != null) {
val list = parseList(::TootRelationShip,TootParser(client.context,access_info), jsonArray)
val list = parseList(::TootRelationShip, TootParser(client.context, access_info), jsonArray)
if(list.isNotEmpty()) {
rr.relation = saveUserRelation(access_info, list[0])
}

View File

@ -102,8 +102,11 @@ object Action_Account {
} else {
// 疑似アカウントを追加
val a = addPseudoAccount(activity, instance, data.optBoolean("isMisskey",false))
if(a != null) {
addPseudoAccount(
activity,
instance,
data.optBoolean("isMisskey", false)
) { a ->
showToast(activity, false, R.string.server_confirmed)
val pos = App1.getAppState(activity).column_list.size
activity.addColumn(pos, a, Column.TYPE_LOCAL)
@ -113,7 +116,6 @@ object Action_Account {
} catch(ignored : Throwable) {
// IllegalArgumentException がたまに出る
}
}
}
} else {
@ -155,8 +157,8 @@ object Action_Account {
pos : Int,
type : Int,
bAllowPseudo : Boolean,
bAllowMisskey: Boolean =true,
bAllowMastodon: Boolean =true,
bAllowMisskey : Boolean = true,
bAllowMastodon : Boolean = true,
args : Array<out Any> = emptyArray()
) {
@ -198,7 +200,14 @@ object Action_Account {
bAllowPseudo = false,
bAuto = true,
message = activity.getString(R.string.account_picker_toot)
) { ai -> ActPost.open(activity, ActMain.REQUEST_CODE_POST, ai.db_id, initial_text = initial_text) }
) { ai ->
ActPost.open(
activity,
ActMain.REQUEST_CODE_POST,
ai.db_id,
initial_text = initial_text
)
}
}
}
@ -208,8 +217,8 @@ object Action_Account {
who : TootAccount,
bSet : Boolean
) {
if( access_info.isMisskey ){
showToast(activity,false,"This feature is not provided on Misskey account.")
if(access_info.isMisskey) {
showToast(activity, false, "This feature is not provided on Misskey account.")
return
}
@ -220,20 +229,24 @@ object Action_Account {
override fun background(client : TootApiClient) : TootApiResult? {
val builder = Request.Builder().post(
RequestBody.create(TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED,"")
RequestBody.create(TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED, "")
)
var result = client.request(
"/api/v1/accounts/${who.id}/"+when(bSet){
true ->"pin"
false ->"unpin"
"/api/v1/accounts/${who.id}/" + when(bSet) {
true -> "pin"
false -> "unpin"
}
,builder
, builder
)
val jsonObject = result?.jsonObject
if( jsonObject != null ){
val tr = parseItem(::TootRelationShip,TootParser(client.context,access_info),jsonObject)
if( tr != null ) {
this.relation = saveUserRelation(access_info,tr)
if(jsonObject != null) {
val tr = parseItem(
::TootRelationShip,
TootParser(client.context, access_info),
jsonObject
)
if(tr != null) {
this.relation = saveUserRelation(access_info, tr)
}
}
return result
@ -242,13 +255,15 @@ object Action_Account {
override fun handleResult(result : TootApiResult?) {
result ?: return
if( result.error != null ){
showToast(activity,true,result.error)
}else{
showToast(activity,false,when(bSet){
true->R.string.endorse_succeeded
else->R.string.remove_endorse_succeeded
})
if(result.error != null) {
showToast(activity, true, result.error)
} else {
showToast(
activity, false, when(bSet) {
true -> R.string.endorse_succeeded
else -> R.string.remove_endorse_succeeded
}
)
}
}
})

View File

@ -6,6 +6,7 @@ import jp.juggler.subwaytooter.ActMain
import jp.juggler.subwaytooter.App1
import jp.juggler.subwaytooter.Column
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.api.entity.TootStatus
import jp.juggler.subwaytooter.dialog.ActionsDialog
import jp.juggler.subwaytooter.table.AcctColor
import jp.juggler.subwaytooter.table.SavedAccount
@ -14,14 +15,37 @@ object Action_HashTag {
// ハッシュタグへの操作を選択する
fun dialog(
activity : ActMain, pos : Int, url : String, host : String, tag_without_sharp : String, tag_list : ArrayList<String>?
activity : ActMain,
pos : Int,
url : String,
host : String,
tag_without_sharp : String,
tag_list : ArrayList<String>?
) {
val tag_with_sharp = "#" + tag_without_sharp
val d = ActionsDialog()
.addAction(activity.getString(R.string.open_hashtag_column)) { timelineOtherInstance(activity, pos, url, host, tag_without_sharp) }
.addAction(activity.getString(R.string.open_in_browser)) { App1.openCustomTab(activity, url) }
.addAction(activity.getString(R.string.quote_hashtag_of, tag_with_sharp)) { Action_Account.openPost(activity, tag_with_sharp + " ") }
.addAction(activity.getString(R.string.open_hashtag_column)) {
timelineOtherInstance(
activity,
pos,
url,
host,
tag_without_sharp
)
}
.addAction(activity.getString(R.string.open_in_browser)) {
App1.openCustomTab(
activity,
url
)
}
.addAction(
activity.getString(
R.string.quote_hashtag_of,
tag_with_sharp
)
) { Action_Account.openPost(activity, tag_with_sharp + " ") }
if(tag_list != null && tag_list.size > 1) {
val sb = StringBuilder()
@ -30,7 +54,12 @@ object Action_HashTag {
sb.append(s)
}
val tag_all = sb.toString()
d.addAction(activity.getString(R.string.quote_all_hashtag_of, tag_all)) { Action_Account.openPost(activity, tag_all + " ") }
d.addAction(
activity.getString(
R.string.quote_all_hashtag_of,
tag_all
)
) { Action_Account.openPost(activity, tag_all + " ") }
}
d.show(activity, tag_with_sharp)
@ -43,7 +72,6 @@ object Action_HashTag {
activity.addColumn(pos, access_info, Column.TYPE_HASHTAG, tag_without_sharp)
}
// アカウントを選んでハッシュタグカラムを開く
fun timelineOtherInstance(
activity : ActMain,
@ -76,13 +104,17 @@ object Action_HashTag {
}
// ブラウザで表示する
dialog.addAction(activity.getString(R.string.open_web_on_host, host)) { App1.openCustomTab(activity, url) }
dialog.addAction(activity.getString(R.string.open_web_on_host, host)) {
App1.openCustomTab(
activity,
url
)
}
// 同タンスのアカウントがない場合は疑似アカウントを作成して開く
if(list_original.isEmpty() && list_original_pseudo.isEmpty()) {
dialog.addAction(activity.getString(R.string.open_in_pseudo_account, "?@" + host)) {
val sa = addPseudoAccount(activity, host)
if(sa != null) {
addPseudoAccount(activity, host) { sa ->
timeline(activity, pos, sa, tag_without_sharp)
}
}
@ -90,15 +122,33 @@ object Action_HashTag {
// 分類した順に選択肢を追加する
for(a in list_original) {
dialog.addAction(AcctColor.getStringWithNickname(activity, R.string.open_in_account, a.acct))
dialog.addAction(
AcctColor.getStringWithNickname(
activity,
R.string.open_in_account,
a.acct
)
)
{ timeline(activity, pos, a, tag_without_sharp) }
}
for(a in list_original_pseudo) {
dialog.addAction(AcctColor.getStringWithNickname(activity, R.string.open_in_account, a.acct))
dialog.addAction(
AcctColor.getStringWithNickname(
activity,
R.string.open_in_account,
a.acct
)
)
{ timeline(activity, pos, a, tag_without_sharp) }
}
for(a in list_other) {
dialog.addAction(AcctColor.getStringWithNickname(activity, R.string.open_in_account, a.acct))
dialog.addAction(
AcctColor.getStringWithNickname(
activity,
R.string.open_in_account,
a.acct
)
)
{ timeline(activity, pos, a, tag_without_sharp) }
}

View File

@ -22,12 +22,12 @@ object Action_Instance {
fun information(
activity : ActMain, pos : Int, host : String
) {
activity.addColumn(false,pos, SavedAccount.na, Column.TYPE_INSTANCE_INFORMATION, host)
activity.addColumn(false, pos, SavedAccount.na, Column.TYPE_INSTANCE_INFORMATION, host)
}
// 指定タンスのローカルタイムラインを開く
fun timelineLocal(
activity : ActMain, pos:Int,host : String
activity : ActMain, pos : Int, host : String
) {
// 指定タンスのアカウントを持ってるか?
val account_list = ArrayList<SavedAccount>()
@ -36,8 +36,7 @@ object Action_Instance {
}
if(account_list.isEmpty()) {
// 持ってないなら疑似アカウントを追加する
val ai = addPseudoAccount(activity, host)
if(ai != null) {
addPseudoAccount(activity, host) { ai ->
activity.addColumn(pos, ai, Column.TYPE_LOCAL)
}
} else {
@ -46,14 +45,13 @@ object Action_Instance {
AccountPicker.pick(
activity,
bAllowPseudo = true,
bAuto = false,
bAuto = false,
message = activity.getString(R.string.account_picker_add_timeline_of, host),
accountListArg = account_list
) { ai -> activity.addColumn(pos, ai, Column.TYPE_LOCAL) }
}
}
// ドメインブロック
fun blockDomain(
activity : ActMain, access_info : SavedAccount, domain : String, bBlock : Boolean
@ -72,7 +70,8 @@ object Action_Instance {
)
var request_builder = Request.Builder()
request_builder = if(bBlock) request_builder.post(body) else request_builder.delete(body)
request_builder =
if(bBlock) request_builder.post(body) else request_builder.delete(body)
return client.request("/api/v1/domain_blocks", request_builder)
}
@ -86,7 +85,11 @@ object Action_Instance {
column.onDomainBlockChanged(access_info, domain, bBlock)
}
showToast(activity, false, if(bBlock) R.string.block_succeeded else R.string.unblock_succeeded)
showToast(
activity,
false,
if(bBlock) R.string.block_succeeded else R.string.unblock_succeeded
)
} else {
showToast(activity, false, result.error)
@ -99,70 +102,70 @@ object Action_Instance {
fun timelinePublicAround2(
activity : ActMain,
access_info : SavedAccount,
pos:Int,
id:EntityId,
columnType:Int
pos : Int,
id : EntityId,
columnType : Int
) {
activity.addColumn(pos, access_info, columnType,id)
activity.addColumn(pos, access_info, columnType, id)
}
private fun timelinePublicAround3(
activity : ActMain,
access_info : SavedAccount,
pos:Int,
status:TootStatus,
columnType:Int
pos : Int,
status : TootStatus,
columnType : Int
) {
TootTaskRunner(activity).run(access_info,object:TootTask{
TootTaskRunner(activity).run(access_info, object : TootTask {
override fun background(client : TootApiClient) : TootApiResult? {
return client.syncStatus(access_info,status)
return client.syncStatus(access_info, status)
}
override fun handleResult(result : TootApiResult?) {
result?: return
val localStatus = result. data as? TootStatus
if( localStatus != null ){
timelinePublicAround2(activity,access_info,pos,localStatus.id,columnType)
}else{
showToast(activity,true,result.error)
result ?: return
val localStatus = result.data as? TootStatus
if(localStatus != null) {
timelinePublicAround2(activity, access_info, pos, localStatus.id, columnType)
} else {
showToast(activity, true, result.error)
}
}
})
}
// 指定タンスのローカルタイムラインを開く
fun timelinePublicAround(
activity : ActMain,
access_info : SavedAccount,
pos:Int,
pos : Int,
host : String?,
status:TootStatus?,
columnType:Int,
allowPseudo :Boolean = true
status : TootStatus?,
columnType : Int,
allowPseudo : Boolean = true
) {
if( host?.isEmpty() != false || host == "?") return
status?: return
if(host?.isEmpty() != false || host == "?") return
status ?: return
// 利用可能なアカウントを列挙する
val account_list1 = ArrayList<SavedAccount>() // 閲覧アカウントとホストが同じ
val account_list2 = ArrayList<SavedAccount>() // その他実アカウント
label@ for(a in SavedAccount.loadAccountList(activity)) {
when{
when {
//
a.isNA-> continue@label
a.isNA -> continue@label
// Misskeyアカウントはステータスの同期が出来ないので選択させない
a.isMisskey -> continue@label
// 閲覧アカウントとホスト名が同じならステータスIDの変換が必要ない
a.host.equals( access_info.host,ignoreCase = true) ->{
if( ! allowPseudo && a.isPseudo) continue@label
a.host.equals(access_info.host, ignoreCase = true) -> {
if(! allowPseudo && a.isPseudo) continue@label
account_list1.add(a)
}
// 実アカウントならステータスを同期して同時間帯のTLを見れる
!a.isPseudo ->{
! a.isPseudo -> {
account_list2.add(a)
}
}
@ -171,17 +174,17 @@ object Action_Instance {
SavedAccount.sort(account_list2)
account_list1.addAll(account_list2)
if( account_list1.isNotEmpty()) {
if(account_list1.isNotEmpty()) {
AccountPicker.pick(
activity,
bAuto = true,
bAuto = true,
message = "select account to read timeline",
accountListArg = account_list1
) { ai ->
if( !ai.isNA && ai.host.equals( access_info.host,ignoreCase = true) ){
timelinePublicAround2(activity,account_list1[0], pos, status.id,columnType)
}else {
timelinePublicAround3(activity, ai, pos, status,columnType)
if(! ai.isNA && ai.host.equals(access_info.host, ignoreCase = true)) {
timelinePublicAround2(activity, account_list1[0], pos, status.id, columnType)
} else {
timelinePublicAround3(activity, ai, pos, status, columnType)
}
}
return
@ -190,6 +193,4 @@ object Action_Instance {
showToast(activity, false, R.string.missing_available_account)
}
}

View File

@ -698,12 +698,14 @@ object Action_Toot {
// 同タンスのアカウントがないなら、疑似アカウントで開く選択肢
if(local_account_list.isEmpty()) {
val isMisskey = TootStatus.reStatusPageMisskey.matcher(url).find()
if(status_id_original != null) {
dialog.addAction(
activity.getString(R.string.open_in_pseudo_account, "?@$host_original")
) {
val sa = addPseudoAccount(activity, host_original)
if(sa != null) {
addPseudoAccount(activity, host_original, isMisskey = isMisskey) { sa ->
conversationLocal(activity, pos, sa, status_id_original)
}
}
@ -711,8 +713,7 @@ object Action_Toot {
dialog.addAction(
activity.getString(R.string.open_in_pseudo_account, "?@$host_original")
) {
val sa = addPseudoAccount(activity, host_original)
if(sa != null) {
addPseudoAccount(activity, host_original, isMisskey = isMisskey) { sa ->
conversationRemote(activity, pos, sa, url)
}
}

View File

@ -118,7 +118,7 @@ class TootApiClient(
val DEFAULT_JSON_ERROR_PARSER = { json : JSONObject ->
val v = json.opt("error")
when(v) {
null,JSONObject.NULL -> null
null, JSONObject.NULL -> null
else -> v.toString()
}
}
@ -1477,29 +1477,34 @@ fun TootApiClient.syncStatus(accessInfo : SavedAccount, urlArg : String) : TootA
// これを投稿元タンスのURLに変換しないと、投稿の同期には使えない
val m = TootStatus.reStatusPageMisskey.matcher(urlArg)
if(m.find()) {
val host = m.group(1)
val client2 = TootApiClient(context, callback = callback)
client2.instance =host
val params = JSONObject().put("uri", urlArg)
val result = client2.request("/api/ap/show", params.toPostRequestBuilder())
if(result == null || result.error != null) return result
val obj = parseMisskeyApShow(
TootParser(context, accessInfo,serviceType = ServiceType.MISSKEY),
result.jsonObject
) as? TootStatus
if( obj != null ){
if( host .equals(accessInfo.host,ignoreCase = true)){
val host = m.group(1)
val noteId = m.group(2)
val result = TootApiClient(context, callback = callback)
.apply { instance = host }
.request(
"/api/notes/show",
JSONObject()
.put("noteId", noteId)
.toPostRequestBuilder()
) ?: return null
val obj = TootParser(
context,
accessInfo,
serviceType = ServiceType.MISSKEY
).status(result.jsonObject)
if(obj != null) {
if(host.equals(accessInfo.host, ignoreCase = true)) {
result.data = obj
return result
}
val uri = obj.uri
if(uri?.isNotEmpty() == true){
if(uri?.isNotEmpty() == true) {
url = uri
}
}
}
return if(accessInfo.isMisskey) {