通知チェック部分のコードをコルーチン対応にした。AppOpenerはいくつかのOSアクティビティを選択肢から除去するようになった。
This commit is contained in:
parent
301dde36c0
commit
8818f25b6f
|
@ -84,6 +84,7 @@
|
||||||
<w>mastodonsearch</w>
|
<w>mastodonsearch</w>
|
||||||
<w>mimumedon</w>
|
<w>mimumedon</w>
|
||||||
<w>misskey</w>
|
<w>misskey</w>
|
||||||
|
<w>misskeyclientproto</w>
|
||||||
<w>miyon</w>
|
<w>miyon</w>
|
||||||
<w>mpeg</w>
|
<w>mpeg</w>
|
||||||
<w>mpga</w>
|
<w>mpga</w>
|
||||||
|
@ -126,6 +127,7 @@
|
||||||
<w>styler</w>
|
<w>styler</w>
|
||||||
<w>subwaytooter</w>
|
<w>subwaytooter</w>
|
||||||
<w>swipy</w>
|
<w>swipy</w>
|
||||||
|
<w>systemui</w>
|
||||||
<w>taisaku</w>
|
<w>taisaku</w>
|
||||||
<w>tateisu</w>
|
<w>tateisu</w>
|
||||||
<w>tbody</w>
|
<w>tbody</w>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
import jp.juggler.util.LogCategory
|
import jp.juggler.util.LogCategory
|
||||||
import jp.juggler.subwaytooter.util.NotificationHelper
|
import jp.juggler.subwaytooter.util.NotificationHelper
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
class PollingForegrounder : IntentService("PollingForegrounder") {
|
class PollingForegrounder : IntentService("PollingForegrounder") {
|
||||||
|
|
||||||
|
@ -89,17 +90,17 @@ class PollingForegrounder : IntentService("PollingForegrounder") {
|
||||||
|
|
||||||
override fun onHandleIntent(intent : Intent?) {
|
override fun onHandleIntent(intent : Intent?) {
|
||||||
if(intent == null) return
|
if(intent == null) return
|
||||||
val tag = intent.getStringExtra(PollingWorker.EXTRA_TAG)
|
runBlocking {
|
||||||
val context = applicationContext
|
val tag = intent.getStringExtra(PollingWorker.EXTRA_TAG)
|
||||||
PollingWorker.handleFCMMessage(this, tag, object : PollingWorker.JobStatusCallback {
|
val context = applicationContext
|
||||||
override fun onStatus(sv : String) {
|
PollingWorker.handleFCMMessage(context, tag) { sv ->
|
||||||
if(sv.isNotEmpty() && sv != last_status) {
|
if (sv.isEmpty() || sv==last_status) return@handleFCMMessage
|
||||||
log.d("onStatus %s", sv)
|
// 状況が変化したらログと通知領域に出力する
|
||||||
last_status = sv
|
last_status = sv
|
||||||
startForeground(NOTIFICATION_ID_FOREGROUNDER, createNotification(context, sv))
|
log.d("onStatus %s", sv)
|
||||||
}
|
startForeground(NOTIFICATION_ID_FOREGROUNDER, createNotification(context, sv))
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,6 @@
|
||||||
package jp.juggler.subwaytooter.api
|
package jp.juggler.subwaytooter.api
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
|
||||||
import jp.juggler.subwaytooter.*
|
import jp.juggler.subwaytooter.*
|
||||||
import jp.juggler.subwaytooter.api.entity.*
|
import jp.juggler.subwaytooter.api.entity.*
|
||||||
import jp.juggler.subwaytooter.table.ClientInfo
|
import jp.juggler.subwaytooter.table.ClientInfo
|
||||||
|
@ -12,37 +11,11 @@ import okhttp3.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class TootApiClient(
|
class TootApiClient(
|
||||||
internal val context: Context,
|
internal val context: Context,
|
||||||
internal val httpClient: SimpleHttpClient = SimpleHttpClientImpl(
|
internal val httpClient: SimpleHttpClient =
|
||||||
context,
|
SimpleHttpClientImpl(context,App1.ok_http_client),
|
||||||
App1.ok_http_client
|
internal val callback: TootApiCallback
|
||||||
),
|
|
||||||
internal val callback: TootApiCallback
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// 認証に関する設定を保存する
|
|
||||||
internal val pref: SharedPreferences
|
|
||||||
|
|
||||||
// インスタンスのホスト名
|
|
||||||
var apiHost: Host? = null
|
|
||||||
|
|
||||||
// アカウントがある場合に使用する
|
|
||||||
var account: SavedAccount? = null
|
|
||||||
set(value) {
|
|
||||||
apiHost = value?.apiHost
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentCallCallback: CurrentCallCallback?
|
|
||||||
get() = httpClient.currentCallCallback
|
|
||||||
set(value) {
|
|
||||||
httpClient.currentCallCallback = value
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
pref = context.pref()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val log = LogCategory("TootApiClient")
|
private val log = LogCategory("TootApiClient")
|
||||||
|
@ -75,10 +48,10 @@ class TootApiClient(
|
||||||
{ json: JsonObject -> json["error"]?.toString() }
|
{ json: JsonObject -> json["error"]?.toString() }
|
||||||
|
|
||||||
internal fun simplifyErrorHtml(
|
internal fun simplifyErrorHtml(
|
||||||
response: Response,
|
response: Response,
|
||||||
sv: String,
|
sv: String,
|
||||||
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
||||||
): String {
|
): String {
|
||||||
|
|
||||||
// JsonObjectとして解釈できるならエラーメッセージを検出する
|
// JsonObjectとして解釈できるならエラーメッセージを検出する
|
||||||
try {
|
try {
|
||||||
|
@ -104,11 +77,11 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun formatResponse(
|
fun formatResponse(
|
||||||
response: Response,
|
response: Response,
|
||||||
caption: String,
|
caption: String,
|
||||||
bodyString: String? = null,
|
bodyString: String? = null,
|
||||||
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
||||||
): String {
|
): String {
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
try {
|
try {
|
||||||
// body は既に読み終わっているか、そうでなければこれから読む
|
// body は既に読み終わっているか、そうでなければこれから読む
|
||||||
|
@ -155,53 +128,53 @@ class TootApiClient(
|
||||||
if (ti.versionGE(TootInstance.MISSKEY_VERSION_11)) {
|
if (ti.versionGE(TootInstance.MISSKEY_VERSION_11)) {
|
||||||
// https://github.com/syuilo/misskey/blob/master/src/server/api/kinds.ts
|
// https://github.com/syuilo/misskey/blob/master/src/server/api/kinds.ts
|
||||||
arrayOf(
|
arrayOf(
|
||||||
"read:account",
|
"read:account",
|
||||||
"write:account",
|
"write:account",
|
||||||
"read:blocks",
|
"read:blocks",
|
||||||
"write:blocks",
|
"write:blocks",
|
||||||
"read:drive",
|
"read:drive",
|
||||||
"write:drive",
|
"write:drive",
|
||||||
"read:favorites",
|
"read:favorites",
|
||||||
"write:favorites",
|
"write:favorites",
|
||||||
"read:following",
|
"read:following",
|
||||||
"write:following",
|
"write:following",
|
||||||
"read:messaging",
|
"read:messaging",
|
||||||
"write:messaging",
|
"write:messaging",
|
||||||
"read:mutes",
|
"read:mutes",
|
||||||
"write:mutes",
|
"write:mutes",
|
||||||
"write:notes",
|
"write:notes",
|
||||||
"read:notifications",
|
"read:notifications",
|
||||||
"write:notifications",
|
"write:notifications",
|
||||||
"read:reactions",
|
"read:reactions",
|
||||||
"write:reactions",
|
"write:reactions",
|
||||||
"write:votes"
|
"write:votes"
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// https://github.com/syuilo/misskey/issues/2341
|
// https://github.com/syuilo/misskey/issues/2341
|
||||||
arrayOf(
|
arrayOf(
|
||||||
"account-read",
|
"account-read",
|
||||||
"account-write",
|
"account-write",
|
||||||
"account/read",
|
"account/read",
|
||||||
"account/write",
|
"account/write",
|
||||||
"drive-read",
|
"drive-read",
|
||||||
"drive-write",
|
"drive-write",
|
||||||
"favorite-read",
|
"favorite-read",
|
||||||
"favorite-write",
|
"favorite-write",
|
||||||
"favorites-read",
|
"favorites-read",
|
||||||
"following-read",
|
"following-read",
|
||||||
"following-write",
|
"following-write",
|
||||||
"messaging-read",
|
"messaging-read",
|
||||||
"messaging-write",
|
"messaging-write",
|
||||||
"note-read",
|
"note-read",
|
||||||
"note-write",
|
"note-write",
|
||||||
"notification-read",
|
"notification-read",
|
||||||
"notification-write",
|
"notification-write",
|
||||||
"reaction-read",
|
"reaction-read",
|
||||||
"reaction-write",
|
"reaction-write",
|
||||||
"vote-read",
|
"vote-read",
|
||||||
"vote-write"
|
"vote-write"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
// APIのエラーを回避するため、重複を排除する
|
// APIのエラーを回避するため、重複を排除する
|
||||||
|
@ -222,6 +195,25 @@ class TootApiClient(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 認証に関する設定を保存する
|
||||||
|
internal val pref = context.pref()
|
||||||
|
|
||||||
|
// インスタンスのホスト名
|
||||||
|
var apiHost: Host? = null
|
||||||
|
|
||||||
|
// アカウントがある場合に使用する
|
||||||
|
var account: SavedAccount? = null
|
||||||
|
set(value) {
|
||||||
|
apiHost = value?.apiHost
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentCallCallback: (Call) -> Unit
|
||||||
|
get() = httpClient.onCallCreated
|
||||||
|
set(value) {
|
||||||
|
httpClient.onCallCreated = value
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
internal val isApiCancelled: Boolean
|
internal val isApiCancelled: Boolean
|
||||||
get() = callback.isApiCancelled
|
get() = callback.isApiCancelled
|
||||||
|
@ -239,11 +231,11 @@ class TootApiClient(
|
||||||
|
|
||||||
// リクエストをokHttpに渡してレスポンスを取得する
|
// リクエストをokHttpに渡してレスポンスを取得する
|
||||||
internal inline fun sendRequest(
|
internal inline fun sendRequest(
|
||||||
result: TootApiResult,
|
result: TootApiResult,
|
||||||
progressPath: String? = null,
|
progressPath: String? = null,
|
||||||
tmpOkhttpClient: OkHttpClient? = null,
|
tmpOkhttpClient: OkHttpClient? = null,
|
||||||
block: () -> Request
|
block: () -> Request
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return try {
|
return try {
|
||||||
result.response = null
|
result.response = null
|
||||||
result.bodyString = null
|
result.bodyString = null
|
||||||
|
@ -254,10 +246,10 @@ class TootApiClient(
|
||||||
result.requestInfo = "${request.method} ${progressPath ?: request.url.encodedPath}"
|
result.requestInfo = "${request.method} ${progressPath ?: request.url.encodedPath}"
|
||||||
|
|
||||||
callback.publishApiProgress(
|
callback.publishApiProgress(
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.request_api, request.method, progressPath ?: request.url.encodedPath
|
R.string.request_api, request.method, progressPath ?: request.url.encodedPath
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val response = httpClient.getResponse(request, tmpOkhttpClient = tmpOkhttpClient)
|
val response = httpClient.getResponse(request, tmpOkhttpClient = tmpOkhttpClient)
|
||||||
result.response = response
|
result.response = response
|
||||||
|
@ -266,13 +258,53 @@ class TootApiClient(
|
||||||
|
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
result.setError(
|
result.setError(
|
||||||
"${result.caption}: ${
|
"${result.caption}: ${
|
||||||
ex.withCaption(
|
ex.withCaption(
|
||||||
context.resources,
|
context.resources,
|
||||||
R.string.network_error
|
R.string.network_error
|
||||||
)
|
)
|
||||||
}"
|
}"
|
||||||
)
|
)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// リクエストをokHttpに渡してレスポンスを取得する
|
||||||
|
private suspend inline fun sendRequestAsync(
|
||||||
|
result: TootApiResult,
|
||||||
|
progressPath: String? = null,
|
||||||
|
tmpOkhttpClient: OkHttpClient? = null,
|
||||||
|
block: () -> Request
|
||||||
|
): Boolean {
|
||||||
|
return try {
|
||||||
|
result.response = null
|
||||||
|
result.bodyString = null
|
||||||
|
result.data = null
|
||||||
|
|
||||||
|
val request = block()
|
||||||
|
|
||||||
|
result.requestInfo = "${request.method} ${progressPath ?: request.url.encodedPath}"
|
||||||
|
|
||||||
|
callback.publishApiProgress(
|
||||||
|
context.getString(
|
||||||
|
R.string.request_api, request.method, progressPath ?: request.url.encodedPath
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val response = httpClient.getResponseAsync(request, tmpOkhttpClient = tmpOkhttpClient)
|
||||||
|
result.response = response
|
||||||
|
|
||||||
|
null == result.error
|
||||||
|
|
||||||
|
} catch (ex: Throwable) {
|
||||||
|
result.setError(
|
||||||
|
"${result.caption}: ${
|
||||||
|
ex.withCaption(
|
||||||
|
context.resources,
|
||||||
|
R.string.network_error
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,10 +312,10 @@ class TootApiClient(
|
||||||
// レスポンスがエラーかボディがカラならエラー状態を設定する
|
// レスポンスがエラーかボディがカラならエラー状態を設定する
|
||||||
// 例外を出すかも
|
// 例外を出すかも
|
||||||
internal fun readBodyString(
|
internal fun readBodyString(
|
||||||
result: TootApiResult,
|
result: TootApiResult,
|
||||||
progressPath: String? = null,
|
progressPath: String? = null,
|
||||||
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
||||||
): String? {
|
): String? {
|
||||||
|
|
||||||
if (isApiCancelled) return null
|
if (isApiCancelled) return null
|
||||||
|
|
||||||
|
@ -291,12 +323,12 @@ class TootApiClient(
|
||||||
|
|
||||||
val request = response.request
|
val request = response.request
|
||||||
publishApiProgress(
|
publishApiProgress(
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.reading_api,
|
R.string.reading_api,
|
||||||
request.method,
|
request.method,
|
||||||
progressPath ?: result.caption
|
progressPath ?: result.caption
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val bodyString = response.body?.string()
|
val bodyString = response.body?.string()
|
||||||
if (isApiCancelled) return null
|
if (isApiCancelled) return null
|
||||||
|
@ -310,11 +342,11 @@ class TootApiClient(
|
||||||
if (!response.isSuccessful || bodyString?.isEmpty() != false) {
|
if (!response.isSuccessful || bodyString?.isEmpty() != false) {
|
||||||
|
|
||||||
result.error = formatResponse(
|
result.error = formatResponse(
|
||||||
response,
|
response,
|
||||||
result.caption,
|
result.caption,
|
||||||
if (bodyString?.isNotEmpty() == true) bodyString else NO_INFORMATION,
|
if (bodyString?.isNotEmpty() == true) bodyString else NO_INFORMATION,
|
||||||
jsonErrorParser
|
jsonErrorParser
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (result.error != null) {
|
return if (result.error != null) {
|
||||||
|
@ -329,10 +361,10 @@ class TootApiClient(
|
||||||
// レスポンスがエラーかボディがカラならエラー状態を設定する
|
// レスポンスがエラーかボディがカラならエラー状態を設定する
|
||||||
// 例外を出すかも
|
// 例外を出すかも
|
||||||
private fun readBodyBytes(
|
private fun readBodyBytes(
|
||||||
result: TootApiResult,
|
result: TootApiResult,
|
||||||
progressPath: String? = null,
|
progressPath: String? = null,
|
||||||
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
||||||
): ByteArray? {
|
): ByteArray? {
|
||||||
|
|
||||||
if (isApiCancelled) return null
|
if (isApiCancelled) return null
|
||||||
|
|
||||||
|
@ -340,12 +372,12 @@ class TootApiClient(
|
||||||
|
|
||||||
val request = response.request
|
val request = response.request
|
||||||
publishApiProgress(
|
publishApiProgress(
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.reading_api,
|
R.string.reading_api,
|
||||||
request.method,
|
request.method,
|
||||||
progressPath ?: result.caption
|
progressPath ?: result.caption
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val bodyBytes = response.body?.bytes()
|
val bodyBytes = response.body?.bytes()
|
||||||
if (isApiCancelled) return null
|
if (isApiCancelled) return null
|
||||||
|
@ -353,11 +385,11 @@ class TootApiClient(
|
||||||
if (!response.isSuccessful || bodyBytes?.isEmpty() != false) {
|
if (!response.isSuccessful || bodyBytes?.isEmpty() != false) {
|
||||||
|
|
||||||
result.error = formatResponse(
|
result.error = formatResponse(
|
||||||
response,
|
response,
|
||||||
result.caption,
|
result.caption,
|
||||||
if (bodyBytes?.isNotEmpty() == true) bodyBytes.decodeUTF8() else NO_INFORMATION,
|
if (bodyBytes?.isNotEmpty() == true) bodyBytes.decodeUTF8() else NO_INFORMATION,
|
||||||
jsonErrorParser
|
jsonErrorParser
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (result.error != null) {
|
return if (result.error != null) {
|
||||||
|
@ -370,17 +402,16 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseBytes(
|
private fun parseBytes(
|
||||||
result: TootApiResult,
|
result: TootApiResult,
|
||||||
progressPath: String? = null,
|
progressPath: String? = null,
|
||||||
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
|
|
||||||
val response = result.response!! // nullにならないはず
|
val response = result.response!! // nullにならないはず
|
||||||
|
|
||||||
try {
|
try {
|
||||||
readBodyBytes(result, progressPath, jsonErrorParser)
|
readBodyBytes(result, progressPath, jsonErrorParser)
|
||||||
?: return if (isApiCancelled) null else result
|
?: return if (isApiCancelled) null else result
|
||||||
|
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
log.trace(ex)
|
log.trace(ex)
|
||||||
result.error =
|
result.error =
|
||||||
|
@ -390,10 +421,10 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun parseString(
|
internal fun parseString(
|
||||||
result: TootApiResult,
|
result: TootApiResult,
|
||||||
progressPath: String? = null,
|
progressPath: String? = null,
|
||||||
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
|
|
||||||
val response = result.response!! // nullにならないはず
|
val response = result.response!! // nullにならないはず
|
||||||
|
|
||||||
|
@ -413,10 +444,10 @@ class TootApiClient(
|
||||||
|
|
||||||
// レスポンスからJSONデータを読む
|
// レスポンスからJSONデータを読む
|
||||||
internal fun parseJson(
|
internal fun parseJson(
|
||||||
result: TootApiResult,
|
result: TootApiResult,
|
||||||
progressPath: String? = null,
|
progressPath: String? = null,
|
||||||
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
jsonErrorParser: (json: JsonObject) -> String? = DEFAULT_JSON_ERROR_PARSER
|
||||||
): TootApiResult? // 引数に指定したresultそのものか、キャンセルされたらnull
|
): TootApiResult? // 引数に指定したresultそのものか、キャンセルされたらnull
|
||||||
{
|
{
|
||||||
val response = result.response!! // nullにならないはず
|
val response = result.response!! // nullにならないはず
|
||||||
|
|
||||||
|
@ -480,9 +511,9 @@ class TootApiClient(
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
fun request(
|
fun request(
|
||||||
path: String,
|
path: String,
|
||||||
request_builder: Request.Builder = Request.Builder()
|
request_builder: Request.Builder = Request.Builder()
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
|
|
||||||
|
@ -511,6 +542,39 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun requestAsync(
|
||||||
|
path: String,
|
||||||
|
request_builder: Request.Builder = Request.Builder()
|
||||||
|
): TootApiResult? {
|
||||||
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
|
if (result.error != null) return result
|
||||||
|
|
||||||
|
val account = this.account // may null
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!sendRequestAsync(result) {
|
||||||
|
|
||||||
|
log.d("request: $path")
|
||||||
|
|
||||||
|
request_builder.url("https://${apiHost?.ascii}$path")
|
||||||
|
|
||||||
|
val access_token = account?.getAccessToken()
|
||||||
|
if (access_token?.isNotEmpty() == true) {
|
||||||
|
request_builder.header("Authorization", "Bearer $access_token")
|
||||||
|
}
|
||||||
|
|
||||||
|
request_builder.build()
|
||||||
|
|
||||||
|
}) return result
|
||||||
|
|
||||||
|
return parseJson(result)
|
||||||
|
} finally {
|
||||||
|
val error = result.error
|
||||||
|
if (error != null) log.d("error: $error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// misskey authentication
|
// misskey authentication
|
||||||
|
|
||||||
|
@ -594,9 +658,9 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerClientMisskey(
|
private fun registerClientMisskey(
|
||||||
scope_array: JsonArray,
|
scope_array: JsonArray,
|
||||||
client_name: String
|
client_name: String
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
if (sendRequest(result) {
|
if (sendRequest(result) {
|
||||||
|
@ -699,10 +763,10 @@ class TootApiClient(
|
||||||
|
|
||||||
// oAuth2認証の続きを行う
|
// oAuth2認証の続きを行う
|
||||||
fun authentication2Misskey(
|
fun authentication2Misskey(
|
||||||
clientNameArg: String,
|
clientNameArg: String,
|
||||||
token: String,
|
token: String,
|
||||||
misskeyVersion: Int
|
misskeyVersion: Int
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
val instance = result.caption // same to instance
|
val instance = result.caption // same to instance
|
||||||
|
@ -834,9 +898,9 @@ class TootApiClient(
|
||||||
|
|
||||||
// client_credentialを無効にする
|
// client_credentialを無効にする
|
||||||
private fun revokeClientCredential(
|
private fun revokeClientCredential(
|
||||||
client_info: JsonObject,
|
client_info: JsonObject,
|
||||||
client_credential: String
|
client_credential: String
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
|
|
||||||
|
@ -885,10 +949,10 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prepareClientMastodon(
|
private fun prepareClientMastodon(
|
||||||
clientNameArg: String,
|
clientNameArg: String,
|
||||||
ti: TootInstance,
|
ti: TootInstance,
|
||||||
forceUpdateClient: Boolean = false
|
forceUpdateClient: Boolean = false
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
// 前準備
|
// 前準備
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
|
@ -977,10 +1041,10 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun authentication1Mastodon(
|
private fun authentication1Mastodon(
|
||||||
clientNameArg: String,
|
clientNameArg: String,
|
||||||
ti: TootInstance,
|
ti: TootInstance,
|
||||||
forceUpdateClient: Boolean = false
|
forceUpdateClient: Boolean = false
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
|
|
||||||
if (ti.instanceType == TootInstance.InstanceType.Pixelfed) {
|
if (ti.instanceType == TootInstance.InstanceType.Pixelfed) {
|
||||||
return TootApiResult("currently Pixelfed instance is not supported.")
|
return TootApiResult("currently Pixelfed instance is not supported.")
|
||||||
|
@ -996,11 +1060,11 @@ class TootApiClient(
|
||||||
|
|
||||||
// クライアントを登録してブラウザで開くURLを生成する
|
// クライアントを登録してブラウザで開くURLを生成する
|
||||||
fun authentication1(
|
fun authentication1(
|
||||||
clientNameArg: String,
|
clientNameArg: String,
|
||||||
forceUpdateClient: Boolean = false
|
forceUpdateClient: Boolean = false
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
|
|
||||||
val (ti, ri) = TootInstance.get(this)
|
val (ti, ri) = TootInstance.get(this)
|
||||||
ti ?: return ri
|
ti ?: return ri
|
||||||
return when {
|
return when {
|
||||||
ti.misskeyVersion > 0 -> authentication1Misskey(clientNameArg, ti)
|
ti.misskeyVersion > 0 -> authentication1Misskey(clientNameArg, ti)
|
||||||
|
@ -1054,8 +1118,8 @@ class TootApiClient(
|
||||||
|
|
||||||
// アクセストークン手動入力でアカウントを更新する場合、アカウントの情報を取得する
|
// アクセストークン手動入力でアカウントを更新する場合、アカウントの情報を取得する
|
||||||
fun getUserCredential(
|
fun getUserCredential(
|
||||||
access_token: String, tokenInfo: JsonObject = JsonObject(), misskeyVersion: Int = 0
|
access_token: String, tokenInfo: JsonObject = JsonObject(), misskeyVersion: Int = 0
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
if (misskeyVersion > 0) {
|
if (misskeyVersion > 0) {
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
|
@ -1107,16 +1171,16 @@ class TootApiClient(
|
||||||
|
|
||||||
fun createUser1(clientNameArg: String): TootApiResult? {
|
fun createUser1(clientNameArg: String): TootApiResult? {
|
||||||
|
|
||||||
val (ti, ri) = TootInstance.get(this)
|
val (ti, ri) = TootInstance.get(this)
|
||||||
ti ?: return ri
|
ti ?: return ri
|
||||||
|
|
||||||
return when (ti.instanceType) {
|
return when (ti.instanceType) {
|
||||||
TootInstance.InstanceType.Misskey ->
|
TootInstance.InstanceType.Misskey ->
|
||||||
TootApiResult("Misskey has no API to create new account")
|
TootApiResult("Misskey has no API to create new account")
|
||||||
TootInstance.InstanceType.Pleroma ->
|
TootInstance.InstanceType.Pleroma ->
|
||||||
TootApiResult("Pleroma has no API to create new account")
|
TootApiResult("Pleroma has no API to create new account")
|
||||||
TootInstance.InstanceType.Pixelfed ->
|
TootInstance.InstanceType.Pixelfed ->
|
||||||
TootApiResult("Pixelfed has no API to create new account")
|
TootApiResult("Pixelfed has no API to create new account")
|
||||||
else ->
|
else ->
|
||||||
prepareClientMastodon(clientNameArg, ti)
|
prepareClientMastodon(clientNameArg, ti)
|
||||||
// result.JsonObject に credentialつきのclient_info を格納して返す
|
// result.JsonObject に credentialつきのclient_info を格納して返す
|
||||||
|
@ -1125,13 +1189,13 @@ class TootApiClient(
|
||||||
|
|
||||||
// ユーザ名入力の後に呼ばれる
|
// ユーザ名入力の後に呼ばれる
|
||||||
fun createUser2Mastodon(
|
fun createUser2Mastodon(
|
||||||
client_info: JsonObject,
|
client_info: JsonObject,
|
||||||
username: String,
|
username: String,
|
||||||
email: String,
|
email: String,
|
||||||
password: String,
|
password: String,
|
||||||
agreement: Boolean,
|
agreement: Boolean,
|
||||||
reason: String?
|
reason: String?
|
||||||
): TootApiResult? {
|
): TootApiResult? {
|
||||||
|
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
|
@ -1166,10 +1230,9 @@ class TootApiClient(
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// JSONデータ以外を扱うリクエスト
|
// JSONデータ以外を扱うリクエスト
|
||||||
|
|
||||||
fun http(req: Request): TootApiResult? {
|
fun http(req: Request): TootApiResult {
|
||||||
val result = TootApiResult.makeWithCaption(req.url.host)
|
val result = TootApiResult.makeWithCaption(req.url.host)
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
|
|
||||||
sendRequest(result, progressPath = null) { req }
|
sendRequest(result, progressPath = null) { req }
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -1184,12 +1247,9 @@ class TootApiClient(
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// 疑似アカウントでステータスURLからステータスIDを取得するためにHTMLを取得する
|
// 疑似アカウントでステータスURLからステータスIDを取得するためにHTMLを取得する
|
||||||
fun getHttp(url: String): TootApiResult? {
|
fun getHttp(url: String):TootApiResult?{
|
||||||
val result = http(Request.Builder().url(url).build())
|
val result = http(Request.Builder().url(url).build())
|
||||||
if (result != null && result.error == null) {
|
return if (result.error != null) result else parseString(result)
|
||||||
parseString(result)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHttpBytes(url: String): Pair<TootApiResult?, ByteArray?> {
|
fun getHttpBytes(url: String): Pair<TootApiResult?, ByteArray?> {
|
||||||
|
@ -1206,9 +1266,9 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun webSocket(
|
fun webSocket(
|
||||||
path: String,
|
path: String,
|
||||||
ws_listener: WebSocketListener
|
ws_listener: WebSocketListener
|
||||||
): Pair<TootApiResult?, WebSocket?> {
|
): Pair<TootApiResult?, WebSocket?> {
|
||||||
var ws: WebSocket? = null
|
var ws: WebSocket? = null
|
||||||
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
val result = TootApiResult.makeWithCaption(apiHost?.pretty)
|
||||||
if (result.error != null) return Pair(result, null)
|
if (result.error != null) return Pair(result, null)
|
||||||
|
@ -1244,8 +1304,8 @@ class TootApiClient(
|
||||||
|
|
||||||
// query: query_string after ? ( ? itself is excluded )
|
// query: query_string after ? ( ? itself is excluded )
|
||||||
fun TootApiClient.requestMastodonSearch(
|
fun TootApiClient.requestMastodonSearch(
|
||||||
parser: TootParser,
|
parser: TootParser,
|
||||||
query: String
|
query: String
|
||||||
): Pair<TootApiResult?, TootResults?> {
|
): Pair<TootApiResult?, TootResults?> {
|
||||||
|
|
||||||
var searchApiVersion = 2
|
var searchApiVersion = 2
|
||||||
|
@ -1267,8 +1327,8 @@ fun TootApiClient.requestMastodonSearch(
|
||||||
|
|
||||||
// result.data に TootAccountRefを格納して返す。もしくはエラーかキャンセル
|
// result.data に TootAccountRefを格納して返す。もしくはエラーかキャンセル
|
||||||
fun TootApiClient.syncAccountByUrl(
|
fun TootApiClient.syncAccountByUrl(
|
||||||
accessInfo: SavedAccount,
|
accessInfo: SavedAccount,
|
||||||
who_url: String
|
who_url: String
|
||||||
): Pair<TootApiResult?, TootAccountRef?> {
|
): Pair<TootApiResult?, TootAccountRef?> {
|
||||||
|
|
||||||
// misskey由来のアカウントURLは https://host/@user@instance などがある
|
// misskey由来のアカウントURLは https://host/@user@instance などがある
|
||||||
|
@ -1288,18 +1348,18 @@ fun TootApiClient.syncAccountByUrl(
|
||||||
|
|
||||||
val acct = TootAccount.getAcctFromUrl(who_url)
|
val acct = TootAccount.getAcctFromUrl(who_url)
|
||||||
?: return Pair(
|
?: return Pair(
|
||||||
TootApiResult(context.getString(R.string.user_id_conversion_failed)),
|
TootApiResult(context.getString(R.string.user_id_conversion_failed)),
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
|
||||||
var ar: TootAccountRef? = null
|
var ar: TootAccountRef? = null
|
||||||
val result = request(
|
val result = request(
|
||||||
"/api/users/show",
|
"/api/users/show",
|
||||||
accessInfo.putMisskeyApiToken().apply {
|
accessInfo.putMisskeyApiToken().apply {
|
||||||
put("username", acct.username)
|
put("username", acct.username)
|
||||||
acct.host?.let { put("host", it.ascii) }
|
acct.host?.let { put("host", it.ascii) }
|
||||||
}.toPostRequestBuilder()
|
}.toPostRequestBuilder()
|
||||||
)
|
)
|
||||||
?.apply {
|
?.apply {
|
||||||
ar = TootAccountRef.mayNull(parser, parser.account(jsonObject))
|
ar = TootAccountRef.mayNull(parser, parser.account(jsonObject))
|
||||||
if (ar == null && error == null) {
|
if (ar == null && error == null) {
|
||||||
|
@ -1308,10 +1368,10 @@ fun TootApiClient.syncAccountByUrl(
|
||||||
}
|
}
|
||||||
Pair(result, ar)
|
Pair(result, ar)
|
||||||
} else {
|
} else {
|
||||||
val (apiResult, searchResult) = requestMastodonSearch(
|
val (apiResult, searchResult) = requestMastodonSearch(
|
||||||
parser,
|
parser,
|
||||||
"q=${who_url.encodePercent()}&resolve=true"
|
"q=${who_url.encodePercent()}&resolve=true"
|
||||||
)
|
)
|
||||||
val ar = searchResult?.accounts?.firstOrNull()
|
val ar = searchResult?.accounts?.firstOrNull()
|
||||||
if (apiResult != null && apiResult.error == null && ar == null) {
|
if (apiResult != null && apiResult.error == null && ar == null) {
|
||||||
apiResult.setError(context.getString(R.string.user_id_conversion_failed))
|
apiResult.setError(context.getString(R.string.user_id_conversion_failed))
|
||||||
|
@ -1321,27 +1381,27 @@ fun TootApiClient.syncAccountByUrl(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TootApiClient.syncAccountByAcct(
|
fun TootApiClient.syncAccountByAcct(
|
||||||
accessInfo: SavedAccount,
|
accessInfo: SavedAccount,
|
||||||
acctArg: String
|
acctArg: String
|
||||||
): Pair<TootApiResult?, TootAccountRef?> = syncAccountByAcct(accessInfo, Acct.parse(acctArg))
|
): Pair<TootApiResult?, TootAccountRef?> = syncAccountByAcct(accessInfo, Acct.parse(acctArg))
|
||||||
|
|
||||||
fun TootApiClient.syncAccountByAcct(
|
fun TootApiClient.syncAccountByAcct(
|
||||||
accessInfo: SavedAccount,
|
accessInfo: SavedAccount,
|
||||||
acct: Acct
|
acct: Acct
|
||||||
): Pair<TootApiResult?, TootAccountRef?> {
|
): Pair<TootApiResult?, TootAccountRef?> {
|
||||||
|
|
||||||
val parser = TootParser(context, accessInfo)
|
val parser = TootParser(context, accessInfo)
|
||||||
return if (accessInfo.isMisskey) {
|
return if (accessInfo.isMisskey) {
|
||||||
var ar: TootAccountRef? = null
|
var ar: TootAccountRef? = null
|
||||||
val result = request(
|
val result = request(
|
||||||
"/api/users/show",
|
"/api/users/show",
|
||||||
accessInfo.putMisskeyApiToken()
|
accessInfo.putMisskeyApiToken()
|
||||||
.apply {
|
.apply {
|
||||||
if (acct.isValid) put("username", acct.username)
|
if (acct.isValid) put("username", acct.username)
|
||||||
if (acct.host != null) put("host", acct.host.ascii)
|
if (acct.host != null) put("host", acct.host.ascii)
|
||||||
}
|
}
|
||||||
.toPostRequestBuilder()
|
.toPostRequestBuilder()
|
||||||
)
|
)
|
||||||
?.apply {
|
?.apply {
|
||||||
ar = TootAccountRef.mayNull(parser, parser.account(jsonObject))
|
ar = TootAccountRef.mayNull(parser, parser.account(jsonObject))
|
||||||
if (ar == null && error == null) {
|
if (ar == null && error == null) {
|
||||||
|
@ -1350,10 +1410,10 @@ fun TootApiClient.syncAccountByAcct(
|
||||||
}
|
}
|
||||||
Pair(result, ar)
|
Pair(result, ar)
|
||||||
} else {
|
} else {
|
||||||
val (apiResult, searchResult) = requestMastodonSearch(
|
val (apiResult, searchResult) = requestMastodonSearch(
|
||||||
parser,
|
parser,
|
||||||
"q=${acct.ascii.encodePercent()}&resolve=true"
|
"q=${acct.ascii.encodePercent()}&resolve=true"
|
||||||
)
|
)
|
||||||
val ar = searchResult?.accounts?.firstOrNull()
|
val ar = searchResult?.accounts?.firstOrNull()
|
||||||
if (apiResult != null && apiResult.error == null && ar == null) {
|
if (apiResult != null && apiResult.error == null && ar == null) {
|
||||||
apiResult.setError(context.getString(R.string.user_id_conversion_failed))
|
apiResult.setError(context.getString(R.string.user_id_conversion_failed))
|
||||||
|
@ -1364,8 +1424,8 @@ fun TootApiClient.syncAccountByAcct(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TootApiClient.syncStatus(
|
fun TootApiClient.syncStatus(
|
||||||
accessInfo: SavedAccount,
|
accessInfo: SavedAccount,
|
||||||
urlArg: String
|
urlArg: String
|
||||||
): Pair<TootApiResult?, TootStatus?> {
|
): Pair<TootApiResult?, TootStatus?> {
|
||||||
|
|
||||||
var url = urlArg
|
var url = urlArg
|
||||||
|
@ -1380,18 +1440,18 @@ fun TootApiClient.syncStatus(
|
||||||
TootApiClient(context, callback = callback)
|
TootApiClient(context, callback = callback)
|
||||||
.apply { apiHost = host }
|
.apply { apiHost = host }
|
||||||
.request(
|
.request(
|
||||||
"/api/notes/show",
|
"/api/notes/show",
|
||||||
JsonObject().apply {
|
JsonObject().apply {
|
||||||
put("noteId", noteId)
|
put("noteId", noteId)
|
||||||
}
|
}
|
||||||
.toPostRequestBuilder()
|
.toPostRequestBuilder()
|
||||||
)
|
)
|
||||||
?.also { result ->
|
?.also { result ->
|
||||||
TootParser(
|
TootParser(
|
||||||
context,
|
context,
|
||||||
linkHelper = LinkHelper.create(host, misskeyVersion = 10),
|
linkHelper = LinkHelper.create(host, misskeyVersion = 10),
|
||||||
serviceType = ServiceType.MISSKEY
|
serviceType = ServiceType.MISSKEY
|
||||||
)
|
)
|
||||||
.status(result.jsonObject)
|
.status(result.jsonObject)
|
||||||
?.apply {
|
?.apply {
|
||||||
if (accessInfo.matchHost(host)) {
|
if (accessInfo.matchHost(host)) {
|
||||||
|
@ -1409,12 +1469,12 @@ fun TootApiClient.syncStatus(
|
||||||
return if (accessInfo.isMisskey) {
|
return if (accessInfo.isMisskey) {
|
||||||
var targetStatus: TootStatus? = null
|
var targetStatus: TootStatus? = null
|
||||||
val result = request(
|
val result = request(
|
||||||
"/api/ap/show",
|
"/api/ap/show",
|
||||||
accessInfo.putMisskeyApiToken().apply {
|
accessInfo.putMisskeyApiToken().apply {
|
||||||
put("uri", url)
|
put("uri", url)
|
||||||
}
|
}
|
||||||
.toPostRequestBuilder()
|
.toPostRequestBuilder()
|
||||||
)
|
)
|
||||||
?.apply {
|
?.apply {
|
||||||
targetStatus = parser.parseMisskeyApShow(jsonObject) as? TootStatus
|
targetStatus = parser.parseMisskeyApShow(jsonObject) as? TootStatus
|
||||||
if (targetStatus == null && error == null) {
|
if (targetStatus == null && error == null) {
|
||||||
|
@ -1423,10 +1483,10 @@ fun TootApiClient.syncStatus(
|
||||||
}
|
}
|
||||||
Pair(result, targetStatus)
|
Pair(result, targetStatus)
|
||||||
} else {
|
} else {
|
||||||
val (apiResult, searchResult) = requestMastodonSearch(
|
val (apiResult, searchResult) = requestMastodonSearch(
|
||||||
parser,
|
parser,
|
||||||
"q=${url.encodePercent()}&resolve=true"
|
"q=${url.encodePercent()}&resolve=true"
|
||||||
)
|
)
|
||||||
val targetStatus = searchResult?.statuses?.firstOrNull()
|
val targetStatus = searchResult?.statuses?.firstOrNull()
|
||||||
if (apiResult != null && apiResult.error == null && targetStatus == null) {
|
if (apiResult != null && apiResult.error == null && targetStatus == null) {
|
||||||
apiResult.setError(context.getString(R.string.cant_sync_toot))
|
apiResult.setError(context.getString(R.string.cant_sync_toot))
|
||||||
|
@ -1437,8 +1497,8 @@ fun TootApiClient.syncStatus(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TootApiClient.syncStatus(
|
fun TootApiClient.syncStatus(
|
||||||
accessInfo: SavedAccount,
|
accessInfo: SavedAccount,
|
||||||
statusRemote: TootStatus
|
statusRemote: TootStatus
|
||||||
): Pair<TootApiResult?, TootStatus?> {
|
): Pair<TootApiResult?, TootStatus?> {
|
||||||
|
|
||||||
// URL->URIの順に試す
|
// URL->URIの順に試す
|
||||||
|
|
|
@ -262,7 +262,7 @@ class NotificationCache(private val account_db_id : Long) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun request(
|
suspend fun requestAsync(
|
||||||
client : TootApiClient,
|
client : TootApiClient,
|
||||||
account : SavedAccount,
|
account : SavedAccount,
|
||||||
flags : Int,
|
flags : Int,
|
||||||
|
@ -291,9 +291,9 @@ class NotificationCache(private val account_db_id : Long) {
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = if(account.isMisskey) {
|
val result = if(account.isMisskey) {
|
||||||
client.request(path, account.putMisskeyApiToken().toPostRequestBuilder())
|
client.requestAsync(path, account.putMisskeyApiToken().toPostRequestBuilder())
|
||||||
} else {
|
} else {
|
||||||
client.request(path)
|
client.requestAsync(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result == null) {
|
if(result == null) {
|
||||||
|
|
|
@ -48,9 +48,21 @@ private fun Activity.startActivityExcludeMyApp(
|
||||||
val myName = packageName
|
val myName = packageName
|
||||||
|
|
||||||
val filter: (ResolveInfo) -> Boolean = {
|
val filter: (ResolveInfo) -> Boolean = {
|
||||||
it.activityInfo.packageName != myName &&
|
when{
|
||||||
it.activityInfo.exported &&
|
it.activityInfo.packageName == myName -> false
|
||||||
-1 == it.activityInfo.packageName.indexOf("com.huawei.android.internal")
|
!it.activityInfo.exported -> false
|
||||||
|
|
||||||
|
// Huaweiの謎Activityのせいでうまく働かないことがある
|
||||||
|
-1 != it.activityInfo.packageName.indexOf("com.huawei.android.internal") -> false
|
||||||
|
|
||||||
|
// 標準アプリが設定されていない場合、アプリを選択するためのActivityが出てくる場合がある
|
||||||
|
it.activityInfo.packageName == "android" -> false
|
||||||
|
it.activityInfo.javaClass.name.startsWith( "com.android.internal") -> false
|
||||||
|
it.activityInfo.javaClass.name.startsWith("com.android.systemui") -> false
|
||||||
|
|
||||||
|
// たぶんChromeとかfirefoxとか
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveActivity がこのアプリ以外のActivityを返すなら、それがベストなんだろう
|
// resolveActivity がこのアプリ以外のActivityを返すなら、それがベストなんだろう
|
||||||
|
|
|
@ -4,57 +4,69 @@ import android.content.Context
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import jp.juggler.subwaytooter.App1
|
import jp.juggler.subwaytooter.App1
|
||||||
import jp.juggler.util.LogCategory
|
import jp.juggler.util.LogCategory
|
||||||
|
import ru.gildor.coroutines.okhttp.await
|
||||||
|
|
||||||
// okhttpそのままだとモックしづらいので
|
// okhttpそのままだとモックしづらいので
|
||||||
// リクエストを投げてレスポンスを得る部分をインタフェースにまとめる
|
// リクエストを投げてレスポンスを得る部分をインタフェースにまとめる
|
||||||
|
|
||||||
interface CurrentCallCallback {
|
|
||||||
fun onCallCreated(call : Call)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SimpleHttpClient {
|
interface SimpleHttpClient {
|
||||||
var currentCallCallback : CurrentCallCallback?
|
|
||||||
|
var onCallCreated: (Call) -> Unit
|
||||||
fun getResponse(
|
|
||||||
request : Request,
|
fun getResponse(
|
||||||
tmpOkhttpClient : OkHttpClient? = null
|
request: Request,
|
||||||
) : Response
|
tmpOkhttpClient: OkHttpClient? = null
|
||||||
|
): Response
|
||||||
fun getWebSocket(
|
|
||||||
request : Request,
|
suspend fun getResponseAsync(
|
||||||
webSocketListener : WebSocketListener
|
request: Request,
|
||||||
) : WebSocket
|
tmpOkhttpClient: OkHttpClient? = null
|
||||||
|
): Response
|
||||||
|
|
||||||
|
fun getWebSocket(
|
||||||
|
request: Request,
|
||||||
|
webSocketListener: WebSocketListener
|
||||||
|
): WebSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleHttpClientImpl(
|
class SimpleHttpClientImpl(
|
||||||
val context : Context,
|
val context: Context,
|
||||||
private val okHttpClient : OkHttpClient
|
private val okHttpClient: OkHttpClient
|
||||||
) : SimpleHttpClient {
|
) : SimpleHttpClient {
|
||||||
|
|
||||||
|
companion object {
|
||||||
companion object {
|
val log = LogCategory("SimpleHttpClientImpl")
|
||||||
val log = LogCategory("SimpleHttpClientImpl")
|
}
|
||||||
}
|
|
||||||
|
override var onCallCreated: (Call) -> Unit = {}
|
||||||
override var currentCallCallback : CurrentCallCallback? = null
|
|
||||||
|
override fun getResponse(
|
||||||
override fun getResponse(
|
request: Request,
|
||||||
request : Request,
|
tmpOkhttpClient: OkHttpClient?
|
||||||
tmpOkhttpClient : OkHttpClient?
|
): Response {
|
||||||
) : Response {
|
App1.getAppState(context).networkTracker.checkNetworkState()
|
||||||
|
val call = (tmpOkhttpClient ?: this.okHttpClient).newCall(request)
|
||||||
|
onCallCreated(call)
|
||||||
|
return call.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getResponseAsync(
|
||||||
|
request: Request,
|
||||||
|
tmpOkhttpClient: OkHttpClient?
|
||||||
|
): Response {
|
||||||
App1.getAppState(context).networkTracker.checkNetworkState()
|
App1.getAppState(context).networkTracker.checkNetworkState()
|
||||||
val call = (tmpOkhttpClient ?: this.okHttpClient).newCall(request)
|
val call = (tmpOkhttpClient ?: this.okHttpClient).newCall(request)
|
||||||
currentCallCallback?.onCallCreated(call)
|
onCallCreated(call)
|
||||||
return call.execute()
|
return call.await()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getWebSocket(
|
override fun getWebSocket(
|
||||||
request : Request,
|
request: Request,
|
||||||
webSocketListener : WebSocketListener
|
webSocketListener: WebSocketListener
|
||||||
) : WebSocket {
|
): WebSocket {
|
||||||
App1.getAppState(context).networkTracker.checkNetworkState()
|
App1.getAppState(context).networkTracker.checkNetworkState()
|
||||||
return okHttpClient.newWebSocket(request, webSocketListener)
|
return okHttpClient.newWebSocket(request, webSocketListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue