From 956ec7128a1678bd89812f490d271aa6c3653658 Mon Sep 17 00:00:00 2001 From: tateisu Date: Thu, 17 Jan 2019 00:27:37 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juggler/subwaytooter/ActAccountSetting.kt | 54 +++---- .../subwaytooter/ActColumnCustomize.kt | 21 +-- .../jp/juggler/subwaytooter/ActMediaViewer.kt | 31 ++-- .../java/jp/juggler/subwaytooter/ActPost.kt | 10 +- .../java/jp/juggler/subwaytooter/Column.kt | 4 +- .../jp/juggler/subwaytooter/StreamReader.kt | 21 +-- .../subwaytooter/action/Action_Instance.kt | 7 +- .../subwaytooter/action/Action_Toot.kt | 142 ++++++++---------- .../juggler/subwaytooter/api/TootApiClient.kt | 130 ++++++++-------- .../subwaytooter/dialog/DlgFocusPoint.kt | 9 +- .../subwaytooter/dialog/DlgListMember.kt | 4 +- .../util/PushSubscriptionHelper.kt | 6 +- 12 files changed, 215 insertions(+), 224 deletions(-) diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.kt b/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.kt index bbec9931..e7e3ba7f 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ActAccountSetting.kt @@ -509,7 +509,10 @@ class ActAccountSetting R.id.btnAccountRemove -> performAccountRemove() R.id.btnVisibility -> performVisibility() - R.id.btnOpenBrowser -> App1.openBrowser(this@ActAccountSetting,"https://" + account.host + "/") + R.id.btnOpenBrowser -> App1.openBrowser( + this@ActAccountSetting, + "https://" + account.host + "/" + ) R.id.btnPushSubscription -> startTest() R.id.btnUserCustom -> ActNickname.open( @@ -727,8 +730,8 @@ class ActAccountSetting private fun initializeProfile() { // 初期状態 val question_id = R.drawable.wide_question - ivProfileAvatar.setErrorImage( defaultColorIcon(this,question_id)) - ivProfileAvatar.setDefaultImage( defaultColorIcon(this,question_id)) + ivProfileAvatar.setErrorImage(defaultColorIcon(this, question_id)) + ivProfileAvatar.setDefaultImage(defaultColorIcon(this, question_id)) val loadingText = when(account.isPseudo) { true -> "(disabled for pseudo account)" @@ -778,8 +781,8 @@ class ActAccountSetting } else { - var result = account.checkConfirmed(this@ActAccountSetting,client) - if(result == null || result.error!=null) return result + var result = account.checkConfirmed(this@ActAccountSetting, client) + if(result == null || result.error != null) return result result = client.request("/api/v1/accounts/verify_credentials") val jsonObject = result?.jsonObject @@ -942,7 +945,7 @@ class ActAccountSetting private fun uploadImageMisskey( client : TootApiClient, opener : InputStreamOpener - ) : TootApiResult? { + ) : Pair { val size = getStreamSize(true, opener.open()) @@ -982,21 +985,19 @@ class ActAccountSetting } ) + var ta : TootAttachment? = null val result = client.request( "/api/drive/files/create", multipart_builder.build().toPost() - ) - - val jsonObject = result?.jsonObject - if(jsonObject != null) { - val a = parseItem(::TootAttachment, ServiceType.MISSKEY, jsonObject) - if(a == null) { - result.error = "TootAttachment.parse failed" - } else { - result.data = a + )?.also { result -> + val jsonObject = result.jsonObject + if(jsonObject != null) { + ta = parseItem(::TootAttachment, ServiceType.MISSKEY, jsonObject) + if(ta == null) result.error = "TootAttachment.parse failed" } } - return result + + return Pair(result, ta) } var data : TootAccount? = null @@ -1024,8 +1025,8 @@ class ActAccountSetting is Boolean -> params.put(misskeyKey, value) is InputStreamOpener -> { - val result = uploadImageMisskey(client, value) - val ta = result?.data as? TootAttachment ?: return result + val (result, ta) = uploadImageMisskey(client, value) + ta ?: return result params.put(misskeyKey, ta.id) } } @@ -1084,8 +1085,6 @@ class ActAccountSetting } } - - val result = client.request( "/api/v1/accounts/update_credentials", multipart_body_builder.build().toPatch() @@ -1184,13 +1183,16 @@ class ActAccountSetting // Mastodon 2.7 でnoteの文字数計算が変わる // https://github.com/tootsuite/mastodon/commit/45899cfa691b1e4f43da98c456ae8faa584eb437 private val reLinkUrl = Pattern.compile("""(https?://[\w/:%#@${'$'}&?!()\[\]~.=+\-]+)""") - private val reMention =Pattern.compile("""(?<=^|[^/\w\p{Pc}])@((\w+([\w.-]+\w+)?)(?:@[a-z0-9.\-]+[a-z0-9]+)?)""",Pattern.CASE_INSENSITIVE) - private val strUrlReplacement = (0 until 23).map{ ' '}.joinToString() - private fun countNoteText(s:String):Int{ + private val reMention = Pattern.compile( + """(?<=^|[^/\w\p{Pc}])@((\w+([\w.-]+\w+)?)(?:@[a-z0-9.\-]+[a-z0-9]+)?)""", + Pattern.CASE_INSENSITIVE + ) + private val strUrlReplacement = (0 until 23).map { ' ' }.joinToString() + private fun countNoteText(s : String) : Int { val s2 = s - .replaceAll(reLinkUrl,strUrlReplacement) - .replaceAll(reMention,"@\\2") - return s2.codePointCount(0,s2.length) + .replaceAll(reLinkUrl, strUrlReplacement) + .replaceAll(reMention, "@\\2") + return s2.codePointCount(0, s2.length) } private fun sendLocked(willLocked : Boolean) { diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.kt b/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.kt index 19588517..56bfdfb8 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ActColumnCustomize.kt @@ -232,6 +232,8 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke private fun updateBackground(uriArg : Uri) { TootTaskRunner(this).run(object : TootTask { + var bgUri : String? = null + override fun background(client : TootApiClient) : TootApiResult? { try { val backgroundDir = Column.getBackgroundImageDir(this@ActColumnCustomize) @@ -271,9 +273,8 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke } } - val result = TootApiResult() - result.data = fileUri.toString() - return result + bgUri = fileUri.toString() + return TootApiResult() } catch(ex : Throwable) { log.trace(ex) return TootApiResult(ex.withCaption("can't update background image.")) @@ -281,14 +282,16 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke } override fun handleResult(result : TootApiResult?) { + val bgUri = this.bgUri when { result == null -> return - result.error != null -> showToast(this@ActColumnCustomize, true, result.error) - else -> { - column.column_bg_image = result.data as String + bgUri != null -> { + column.column_bg_image = bgUri show() } + + else -> showToast(this@ActColumnCustomize, true, result.error ?: "?") } } }) @@ -448,17 +451,17 @@ class ActColumnCustomize : AppCompatActivity(), View.OnClickListener, ColorPicke private fun loadImage(ivColumnBackground : ImageView, url : String) { try { - if( url.isEmpty() ){ + if(url.isEmpty()) { closeBitmaps() return - }else if(url == last_image_uri) { + } else if(url == last_image_uri) { // 今表示してるのと同じ return } // 直前のBitmapを掃除する closeBitmaps() - + val uri = url.mayUri() ?: return // 画像をロードして、成功したら表示してURLを覚える diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt b/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt index ec2a7c7b..a690619f 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ActMediaViewer.kt @@ -612,7 +612,7 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener { return bitmap2 } - fun getHttpCached(client : TootApiClient, url : String) : TootApiResult? { + fun getHttpCached(client : TootApiClient, url : String) : Pair { val result = TootApiResult.makeWithCaption(url) val request = Request.Builder() @@ -626,46 +626,49 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener { tmpOkhttpClient = App1.ok_http_client_media_viewer ) { request - }) return result + } + ) return Pair(result,null) + + if(client.isApiCancelled) return Pair(null,null) - if(client.isApiCancelled) return null val response = requireNotNull(result.response) if(! response.isSuccessful) { - return result.setError(TootApiClient.formatResponse(response, result.caption)) + result.setError(TootApiClient.formatResponse(response, result.caption)) + return Pair(result,null) } - // log.d("cached=${ response.cacheResponse() != null }") try { - result.data = ProgressResponseBody.bytes(response) { bytesRead, bytesTotal -> + val ba = ProgressResponseBody.bytes(response) { bytesRead, bytesTotal -> // 50MB以上のデータはキャンセルする if(Math.max(bytesRead, bytesTotal) >= 50000000) { throw RuntimeException("media attachment is larger than 50000000") } client.publishApiProgressRatio(bytesRead.toInt(), bytesTotal.toInt()) } - if(client.isApiCancelled) return null + if(client.isApiCancelled) return Pair(null,null) + return Pair(result,ba) } catch(ex : Throwable) { result.setError(TootApiClient.formatResponse(response, result.caption, "?")) + return Pair(result,null) } - return result } override fun background(client : TootApiClient) : TootApiResult? { if(urlList.isEmpty()) return TootApiResult("missing url") - var result : TootApiResult? = null + var lastResult : TootApiResult? = null for(url in urlList) { - result = getHttpCached(client, url) - val data = result?.data as? ByteArray - if(data != null) { + val(result,ba) = getHttpCached(client, url) + lastResult = result + if( ba != null){ client.publishApiProgress("decoding image…") - val bitmap = decodeBitmap(data, 2048) + val bitmap = decodeBitmap(ba, 2048) if(bitmap != null) { this.bitmap = bitmap break } } } - return result + return lastResult } override fun handleResult(result : TootApiResult?) { diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActPost.kt b/app/src/main/java/jp/juggler/subwaytooter/ActPost.kt index 70077dd6..a05e1bc6 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActPost.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/ActPost.kt @@ -1294,14 +1294,8 @@ class ActPost : AppCompatActivity(), var target_status : TootStatus? = null override fun background(client : TootApiClient) : TootApiResult? { - - val result = client.syncStatus(access_info, in_reply_to_url) - if(result?.data != null) { - target_status = result.data as? TootStatus - if(target_status == null) { - return TootApiResult(getString(R.string.status_id_conversion_failed)) - } - } + val (result, localStatus) = client.syncStatus(access_info, in_reply_to_url) + target_status = localStatus return result } diff --git a/app/src/main/java/jp/juggler/subwaytooter/Column.kt b/app/src/main/java/jp/juggler/subwaytooter/Column.kt index 270b1720..ffcdd435 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/Column.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/Column.kt @@ -2008,8 +2008,8 @@ class Column( } else { // カラムに紐付けられたアカウントのタンスのインスタンス情報 } - val result = client.parseInstanceInformation(client.getInstanceInformation()) - instance_tmp = result?.data as? TootInstance + val(result,ti) = client.parseInstanceInformation(client.getInstanceInformation()) + instance_tmp = ti return result } diff --git a/app/src/main/java/jp/juggler/subwaytooter/StreamReader.kt b/app/src/main/java/jp/juggler/subwaytooter/StreamReader.kt index 6e856cf2..2a615ab5 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/StreamReader.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/StreamReader.kt @@ -343,18 +343,15 @@ internal class StreamReader( TootTaskRunner(context).run(access_info, object : TootTask { override fun background(client : TootApiClient) : TootApiResult? { - val result = client.webSocket(end_point, this@Reader) + val( result ,ws) = client.webSocket(end_point, this@Reader) - if(result == null) { - log.d("startRead: cancelled.") - bListening.set(false) - fireListeningChanged() - } else { - val ws = result.data as? WebSocket - if(ws != null) { - socket.set(ws) + when { + result == null -> { + log.d("startRead: cancelled.") + bListening.set(false) fireListeningChanged() - } else { + } + ws == null -> { val error = result.error log.d("startRead: error. $error") bListening.set(false) @@ -363,6 +360,10 @@ internal class StreamReader( handler.removeCallbacks(proc_reconnect) handler.postDelayed(proc_reconnect, 5000L) } + else->{ + socket.set(ws) + fireListeningChanged() + } } return result } diff --git a/app/src/main/java/jp/juggler/subwaytooter/action/Action_Instance.kt b/app/src/main/java/jp/juggler/subwaytooter/action/Action_Instance.kt index 3aedb193..4acda155 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/action/Action_Instance.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/action/Action_Instance.kt @@ -120,13 +120,16 @@ object Action_Instance { columnType : Int ) { TootTaskRunner(activity).run(access_info, object : TootTask { + var localStatus: TootStatus? = null override fun background(client : TootApiClient) : TootApiResult? { - return client.syncStatus(access_info, status) + val(result,localStatus) = client.syncStatus(access_info, status) + this.localStatus = localStatus + return result } override fun handleResult(result : TootApiResult?) { result ?: return - val localStatus = result.data as? TootStatus + val localStatus = this.localStatus if(localStatus != null) { timelinePublicAround2(activity, access_info, pos, localStatus.id, columnType) } else { diff --git a/app/src/main/java/jp/juggler/subwaytooter/action/Action_Toot.kt b/app/src/main/java/jp/juggler/subwaytooter/action/Action_Toot.kt index 07af6d1c..95185ba4 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/action/Action_Toot.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/action/Action_Toot.kt @@ -118,59 +118,52 @@ object Action_Toot { var new_status : TootStatus? = null override fun background(client : TootApiClient) : TootApiResult? { - var result : TootApiResult? - val target_status : TootStatus - if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) { + val target_status = if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) { - result = client.syncStatus(access_info, arg_status) - if(result?.data == null) return result - target_status = result.data as? TootStatus - ?: - return TootApiResult(activity.getString(R.string.status_id_conversion_failed)) - if(target_status.favourited) { + val(result,status) = client.syncStatus(access_info, arg_status) + status ?: return result + if(status.favourited) { return TootApiResult(activity.getString(R.string.already_favourited)) } - + status } else { - target_status = arg_status + arg_status } - if(access_info.isMisskey) { - val params = access_info.putMisskeyApiToken(JSONObject()) - .put("noteId", target_status.id.toString()) - - result = client.request( + + return if(access_info.isMisskey) { + client.request( if(bSet) { "/api/notes/favorites/create" } else { "/api/notes/favorites/delete" + }, + access_info + .putMisskeyApiToken(JSONObject()) + .put("noteId", target_status.id.toString()) + .toPostRequestBuilder() + )?.also{ result-> + // 正常レスポンスは 204 no content + // 既にお気に入り済みならエラー文字列に'already favorited' が返る + if(result.response?.code() == 204 + || result.error?.contains("already favorited") == true + || result.error?.contains("already not favorited") == true + ) { + // 成功した + new_status = target_status.apply{ + favourited = bSet + } } - , params.toPostRequestBuilder() - ) - - // 正常レスポンスは 204 no content - // 既にお気に入り済みならエラー文字列に'already favorited' が返る - if(result?.response?.code() == 204 - || result?.error?.contains("already favorited") == true - || result?.error?.contains("already not favorited") == true - ) { - // 成功した - target_status.favourited = bSet - new_status = target_status } - } else { - result = client.request( + client.request( "/api/v1/statuses/${target_status.id}/${if(bSet) "favourite" else "unfavourite"}", "".toRequestBody().toPost() - ) - val jsonObject = result?.jsonObject - new_status = TootParser(activity, access_info).status(jsonObject) - + )?.also{ result-> + new_status = TootParser(activity, access_info).status(result.jsonObject) + } } - return result - } override fun handleResult(result : TootApiResult?) { @@ -364,34 +357,29 @@ object Action_Toot { val parser = TootParser(activity, access_info) - var result : TootApiResult? - val target_status : TootStatus - if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) { - - result = client.syncStatus(access_info, arg_status) - if(result?.data == null) return result - target_status = result.data as? TootStatus - ?: - return TootApiResult(activity.getString(R.string.status_id_conversion_failed)) - if(target_status.reblogged) { + + val target_status = if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) { + val(result,status) = client.syncStatus(access_info, arg_status) + if(status == null) return result + if(status.reblogged) { return TootApiResult(activity.getString(R.string.already_boosted)) } + status } else { // 既に自タンスのステータスがある - target_status = arg_status + arg_status } if(access_info.isMisskey) { if(! bSet) { - return TootApiResult("Misskey has no 'unrenote' API.") } else { val params = access_info.putMisskeyApiToken(JSONObject()) .put("renoteId", target_status.id.toString()) - result = client.request("/api/notes/create", params.toPostRequestBuilder()) + val result = client.request("/api/notes/create", params.toPostRequestBuilder()) val jsonObject = result?.jsonObject if(jsonObject != null) { val new_status = parser.status( @@ -405,8 +393,7 @@ object Action_Toot { } } else { - - result = client.request( + val result = client.request( "/api/v1/statuses/${target_status.id}/${if(bSet) "reblog" else "unreblog"}", "".toRequestBody().toPost() ) @@ -749,11 +736,10 @@ object Action_Toot { .run(access_info, object : TootTask { var local_status_id : EntityId? = null - override fun background(client : TootApiClient) : TootApiResult? { - var result : TootApiResult? + override fun background(client : TootApiClient) : TootApiResult? = if(access_info.isPseudo) { // 疑似アカウントではURLからIDを取得するのにHTMLと正規表現を使う - result = client.getHttp(remote_status_url) + val result = client.getHttp(remote_status_url) val string = result?.string if(string != null) { try { @@ -765,22 +751,19 @@ object Action_Toot { log.e(ex, "openStatusRemote: can't parse status id from HTML data.") } - if(local_status_id == null) { - result = TootApiResult( - activity.getString(R.string.status_id_conversion_failed) - ) + if(result.error == null && local_status_id == null) { + result.setError(activity.getString(R.string.status_id_conversion_failed)) } } + result } else { - result = client.syncStatus(access_info, remote_status_url) - if(result?.data == null) return result - val status = result.data as? TootStatus - ?: return TootApiResult(activity.getString(R.string.status_id_conversion_failed)) - local_status_id = status.id - log.d("status id conversion %s => %s", remote_status_url, status.id) + val(result,status) = client.syncStatus(access_info, remote_status_url) + if(status != null){ + local_status_id = status.id + log.d("status id conversion %s => %s", remote_status_url, status.id) + } + result } - return result - } override fun handleResult(result : TootApiResult?) { if(result == null) return // cancelled. @@ -888,11 +871,8 @@ object Action_Toot { var local_status : TootStatus? = null override fun background(client : TootApiClient) : TootApiResult? { - val result = client.syncStatus(access_info, remote_status_url) - if(result?.data == null) return result - local_status = result.data as? TootStatus - ?: - return TootApiResult(activity.getString(R.string.status_id_conversion_failed)) + val (result,status) = client.syncStatus(access_info, remote_status_url) + local_status = status return result } @@ -1108,21 +1088,21 @@ object Action_Toot { override fun background(client : TootApiClient) : TootApiResult? { - val target_status : TootStatus - if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) { + val target_status = if(nCrossAccountMode == CROSS_ACCOUNT_REMOTE_INSTANCE) { - val result = client.syncStatus(access_info, arg_status) - if(result?.data == null) return result - target_status = result.data as? TootStatus - ?: return TootApiResult( - activity.getString(R.string.status_id_conversion_failed) - ) - if(target_status.myReaction != null) { + val(result,status) = client.syncStatus(access_info, arg_status) + + status?: return result + + if(status.myReaction != null) { return TootApiResult(activity.getString(R.string.already_reactioned)) } + + status + } else { // 既に自タンスのステータスがある - target_status = arg_status + arg_status } diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt index 04e97dfb..77bb1974 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.kt @@ -544,21 +544,18 @@ class TootApiClient( } // インスタンス情報を取得する - internal fun parseInstanceInformation(result : TootApiResult?) : TootApiResult? { + internal fun parseInstanceInformation(result : TootApiResult?) : Pair { + var ti: TootInstance? = null val json = result?.jsonObject if(json != null) { val parser = TootParser( context, LinkHelper.newLinkHelper(instance, isMisskey = json.optBoolean(KEY_IS_MISSKEY)) ) - val ti = parser.instance(json) - if(ti != null) { - result.data = ti - } else { - result.setError("can't parse data in instance information.") - } + ti = parser.instance(json) + if(ti == null) result.setError("can't parse data in instance information.") } - return result + return Pair(result,ti) } private fun getAppInfoMisskey(appId : String?) : TootApiResult? { @@ -1054,21 +1051,26 @@ class TootApiClient( // クライアントを登録してブラウザで開くURLを生成する fun authentication1(clientNameArg : String) : TootApiResult? { + var lastRi : TootApiResult? = null // misskeyのインスタンス情報 - var ri = parseInstanceInformation(getInstanceInformationMisskey()) - var ti = ri?.data as? TootInstance - if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { - return authentication1Misskey(clientNameArg, ti) + run{ + val (ri ,ti) = parseInstanceInformation(getInstanceInformationMisskey()) + lastRi = ri + if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { + return authentication1Misskey(clientNameArg, ti) + } } // マストドンのインスタンス情報 - ri = parseInstanceInformation(getInstanceInformationMastodon()) - ti = ri?.data as? TootInstance - if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { - return authentication1Mastodon(clientNameArg, ti) + run{ + val (ri,ti) = parseInstanceInformation(getInstanceInformationMastodon()) + lastRi = ri + if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { + return authentication1Mastodon(clientNameArg, ti) + } } - return ri + return lastRi } // oAuth2認証の続きを行う @@ -1172,25 +1174,30 @@ class TootApiClient( } fun createUser1(clientNameArg : String) : TootApiResult? { + var lastRi : TootApiResult? = null // misskeyのインスタンス情報 - var ri = parseInstanceInformation(getInstanceInformationMisskey()) - var ti = ri?.data as? TootInstance - if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { - return TootApiResult("Misskey has no API to create new account") + run { + val (ri, ti) = parseInstanceInformation(getInstanceInformationMisskey()) + lastRi = ri + if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { + return TootApiResult("Misskey has no API to create new account") + } + } // マストドンのインスタンス情報 - ri = parseInstanceInformation(getInstanceInformationMastodon()) - ti = ri?.data as? TootInstance - if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { - if(ti.version?.matches("""\bPleroma\b""".toRegex()) == true) { - return TootApiResult("Pleroma has no API to create new account") + run { + val (ri, ti) = parseInstanceInformation(getInstanceInformationMastodon()) + lastRi = ri + if(ti != null && (ri?.response?.code() ?: 0) in 200 until 300) { + if(ti.version?.matches("""\bPleroma\b""".toRegex()) == true) { + return TootApiResult("Pleroma has no API to create new account") + } + // result.jsonObject に credentialつきのclient_info を格納して返す + return prepareClientMastodon(clientNameArg, ti) } - // result.jsonObject に credentialつきのclient_info を格納して返す - return prepareClientMastodon(clientNameArg, ti) } - - return ri + return lastRi } // ユーザ名入力の後に呼ばれる @@ -1354,21 +1361,24 @@ class TootApiClient( return result } - fun getHttpBytes(url : String) : TootApiResult? { + fun getHttpBytes(url : String) :Pair { val result = TootApiResult.makeWithCaption(url) - if(result.error != null) return result + if(result.error != null) return Pair(result,null) - if(! sendRequest(result, progressPath = url) { + if( !sendRequest(result, progressPath = url) { Request.Builder().url(url).build() - }) return result - return parseBytes(result) - + }) { + return Pair(result, null) + } + val r2 = parseBytes(result) + return Pair(r2,r2?.data as? ByteArray) } - fun webSocket(path : String, ws_listener : WebSocketListener) : TootApiResult? { + fun webSocket(path : String, ws_listener : WebSocketListener) : Pair { + var ws:WebSocket? = null val result = TootApiResult.makeWithCaption(instance) - if(result.error != null) return result - val account = this.account ?: return TootApiResult("account is null") + if(result.error != null) return Pair(result,null) + val account = this.account ?: return Pair(TootApiResult("account is null"),null) try { var url = "wss://$instance$path" @@ -1382,18 +1392,16 @@ class TootApiClient( val request = request_builder.url(url).build() publishApiProgress(context.getString(R.string.request_api, request.method(), path)) - val ws = httpClient.getWebSocket(request, ws_listener) + ws = httpClient.getWebSocket(request, ws_listener) if(isApiCancelled) { ws.cancel() - return null + return Pair(null,null) } - result.data = ws } catch(ex : Throwable) { log.trace(ex) - result.error = - "${result.caption}: ${ex.withCaption(context.resources, R.string.network_error)}" + result.error = "${result.caption}: ${ex.withCaption(context.resources, R.string.network_error)}" } - return result + return Pair(result,ws) } @@ -1497,7 +1505,7 @@ fun TootApiClient.syncAccountByAcct( return Pair(result, ar) } -fun TootApiClient.syncStatus(accessInfo : SavedAccount, urlArg : String) : TootApiResult? { +fun TootApiClient.syncStatus(accessInfo : SavedAccount, urlArg : String) : Pair { var url = urlArg @@ -1516,7 +1524,6 @@ fun TootApiClient.syncStatus(accessInfo : SavedAccount, urlArg : String) : TootA .put("noteId", noteId) .toPostRequestBuilder() ) - ?.also { result -> TootParser( context, @@ -1526,19 +1533,19 @@ fun TootApiClient.syncStatus(accessInfo : SavedAccount, urlArg : String) : TootA .status(result.jsonObject) ?.apply { if(host.equals(accessInfo.host, ignoreCase = true)) { - result.data = this - return result + return Pair(result,this) } uri.letNotEmpty { url = it } } + } - - ?: return null // cancelled. + ?: return Pair(null,null) // cancelled. } // 使いたいタンス上の投稿IDを取得する val parser = TootParser(context, accessInfo) - return if(accessInfo.isMisskey) { + var targetStatus :TootStatus? = null + val result = if(accessInfo.isMisskey) { request( "/api/ap/show", accessInfo.putMisskeyApiToken() @@ -1546,26 +1553,27 @@ fun TootApiClient.syncStatus(accessInfo : SavedAccount, urlArg : String) : TootA .toPostRequestBuilder() ) ?.apply { - data = parser.parseMisskeyApShow(jsonObject) - if(data == null && error == null) { + targetStatus = parser.parseMisskeyApShow(jsonObject) as? TootStatus + if(targetStatus == null && error == null) { setError(context.getString(R.string.cant_sync_toot)) } } } else { request("/api/v1/search?q=${url.encodePercent()}&resolve=true") ?.apply { - data = parser.results(jsonObject)?.statuses?.firstOrNull() - if(data == null && error == null) { + targetStatus = parser.results(jsonObject)?.statuses?.firstOrNull() + if(targetStatus == null && error == null) { setError(context.getString(R.string.cant_sync_toot)) } } } + return Pair(result,targetStatus) } fun TootApiClient.syncStatus( accessInfo : SavedAccount, statusRemote : TootStatus -) : TootApiResult? { +) : Pair { // URL->URIの順に試す @@ -1592,11 +1600,11 @@ fun TootApiClient.syncStatus( } for(uri in uriList) { - val result = syncStatus(accessInfo, uri) - if(result == null || result.data is TootStatus) { - return result + val pair = syncStatus(accessInfo, uri) + if( pair.second != null || pair.first == null ) { + return pair } } - return TootApiResult("can't resolve status URL/URI.") + return Pair(TootApiResult("can't resolve status URL/URI."),null) } diff --git a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgFocusPoint.kt b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgFocusPoint.kt index 232efde4..f4d5634d 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgFocusPoint.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgFocusPoint.kt @@ -90,18 +90,15 @@ class DlgFocusPoint(val activity : Activity, val attachment : TootAttachment) : var bitmap : Bitmap? = null override fun background(client : TootApiClient) : TootApiResult? { - - val result = client.getHttpBytes(url) - try { - val data = result?.data as? ByteArray ?: return result + val(result,data) = client.getHttpBytes(url) + data ?: return result bitmap = decodeBitmap(data, 1024) if(bitmap == null) return TootApiResult("image decode failed.") + return result } catch(ex : Throwable) { return TootApiResult(ex.withCaption("preview loading failed.")) } - - return result } override fun handleResult(result : TootApiResult?) { diff --git a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgListMember.kt b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgListMember.kt index 0aa318b5..0a1f2ff9 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgListMember.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgListMember.kt @@ -175,8 +175,8 @@ class DlgListMember( override fun background(client : TootApiClient) : TootApiResult? { // リストに追加したいアカウントの自タンスでのアカウントIDを取得する - var result = client.syncAccountByAcct(list_owner,target_user_full_acct) - val local_who = (result?.data as? TootAccountRef)?.get() + var (result,ar) = client.syncAccountByAcct(list_owner,target_user_full_acct) + val local_who = ar?.get() ?: return TootApiResult(activity.getString(R.string.account_sync_failed)) this@DlgListMember.local_who = local_who diff --git a/app/src/main/java/jp/juggler/subwaytooter/util/PushSubscriptionHelper.kt b/app/src/main/java/jp/juggler/subwaytooter/util/PushSubscriptionHelper.kt index 31709d5e..8641d491 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/util/PushSubscriptionHelper.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/util/PushSubscriptionHelper.kt @@ -231,9 +231,9 @@ class PushSubscriptionHelper( if(oldSubscription == null) { // 現在の購読状況が分からない場合はインスタンスのバージョンを調べる必要がある - r = client.parseInstanceInformation(client.getInstanceInformation()) - val ti = r?.data as? TootInstance ?: return r - + val(result,ti) = client.parseInstanceInformation(client.getInstanceInformation()) + ti ?: return result + if(! ti.versionGE(TootInstance.VERSION_2_4_0_rc1)) { // 2.4.0rc1 未満にはプッシュ購読APIはない return TootApiResult(