mirror of
https://github.com/tateisu/SubwayTooter
synced 2025-02-07 23:58:44 +01:00
通知のアクセント色をリソースXMLに移す
This commit is contained in:
parent
d520f9ddfd
commit
60bacaac64
@ -21,8 +21,8 @@ import jp.juggler.subwaytooter.databinding.ActPushMessageListBinding
|
||||
import jp.juggler.subwaytooter.databinding.LvPushMessageBinding
|
||||
import jp.juggler.subwaytooter.dialog.actionsDialog
|
||||
import jp.juggler.subwaytooter.dialog.runInProgress
|
||||
import jp.juggler.subwaytooter.notification.NotificationIconAndColor
|
||||
import jp.juggler.subwaytooter.notification.notificationIconAndColor
|
||||
import jp.juggler.subwaytooter.notification.PushMessageIconColor
|
||||
import jp.juggler.subwaytooter.notification.iconColor
|
||||
import jp.juggler.subwaytooter.push.pushRepo
|
||||
import jp.juggler.subwaytooter.table.PushMessage
|
||||
import jp.juggler.subwaytooter.table.daoAccountNotificationStatus
|
||||
@ -165,11 +165,13 @@ class ActPushMessageList : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private val tintIconMap = HashMap<String, Drawable>()
|
||||
fun tintIcon(ic: NotificationIconAndColor) =
|
||||
|
||||
fun tintIcon(ic: PushMessageIconColor) =
|
||||
tintIconMap.getOrPut(ic.name) {
|
||||
val src = ContextCompat.getDrawable(this@ActPushMessageList, ic.iconId)!!
|
||||
val context = this
|
||||
val src = ContextCompat.getDrawable(context, ic.iconId)!!
|
||||
DrawableCompat.wrap(src).also {
|
||||
DrawableCompat.setTint(it, ic.color)
|
||||
DrawableCompat.setTint(it, ContextCompat.getColor(context, ic.colorRes))
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +192,7 @@ class ActPushMessageList : AppCompatActivity() {
|
||||
pm ?: return
|
||||
lastItem = pm
|
||||
|
||||
val iconAndColor = pm.notificationIconAndColor()
|
||||
val iconAndColor = pm.iconColor()
|
||||
Glide.with(views.ivSmall)
|
||||
.load(pm.iconSmall)
|
||||
.error(tintIcon(iconAndColor))
|
||||
|
@ -25,7 +25,6 @@ import jp.juggler.subwaytooter.column.startLoading
|
||||
import jp.juggler.subwaytooter.dialog.actionsDialog
|
||||
import jp.juggler.subwaytooter.dialog.pickAccount
|
||||
import jp.juggler.subwaytooter.dialog.runInProgress
|
||||
import jp.juggler.subwaytooter.notification.PushSubscriptionHelper
|
||||
import jp.juggler.subwaytooter.notification.checkNotificationImmediate
|
||||
import jp.juggler.subwaytooter.notification.checkNotificationImmediateAll
|
||||
import jp.juggler.subwaytooter.notification.recycleClickedNotification
|
||||
@ -47,7 +46,6 @@ import jp.juggler.util.queryIntentActivitiesCompat
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.unifiedpush.android.connector.UnifiedPush
|
||||
import java.util.ArrayList
|
||||
|
||||
private val log = LogCategory("ActMainIntent")
|
||||
|
||||
@ -351,7 +349,7 @@ fun ActMain.handleSharedIntent(intent: Intent) {
|
||||
}
|
||||
|
||||
// アカウントを追加/更新したらappServerHashの取得をやりなおす
|
||||
fun ActMain.updatePushDistributer(){
|
||||
fun ActMain.updatePushDistributer() {
|
||||
when {
|
||||
fcmHandler.noFcm && prefDevice.pushDistributor.isNullOrEmpty() -> {
|
||||
try {
|
||||
@ -361,7 +359,7 @@ fun ActMain.updatePushDistributer(){
|
||||
// 選択しなかった場合は購読の更新を行わない
|
||||
}
|
||||
}
|
||||
else -> PushWorker.enqueueRegisterEndpoint(this)
|
||||
else -> PushWorker.enqueueRegisterEndpoint(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,488 +1,488 @@
|
||||
package jp.juggler.subwaytooter.notification
|
||||
|
||||
import android.content.Context
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.TootApiClient
|
||||
import jp.juggler.subwaytooter.api.TootApiResult
|
||||
import jp.juggler.subwaytooter.api.entity.*
|
||||
import jp.juggler.subwaytooter.table.SavedAccount
|
||||
import jp.juggler.subwaytooter.table.SubscriptionServerKey
|
||||
import jp.juggler.subwaytooter.table.appDatabase
|
||||
import jp.juggler.util.*
|
||||
import jp.juggler.util.data.*
|
||||
import jp.juggler.util.log.*
|
||||
import jp.juggler.util.network.toPostRequestBuilder
|
||||
import jp.juggler.util.ui.*
|
||||
import okhttp3.Request
|
||||
|
||||
class PushSubscriptionHelper(
|
||||
val context: Context,
|
||||
val account: SavedAccount,
|
||||
private val verbose: Boolean = false,
|
||||
private val daoSubscriptionServerKey: SubscriptionServerKey.Access =
|
||||
SubscriptionServerKey.Access(appDatabase),
|
||||
) {
|
||||
companion object {
|
||||
private val log = LogCategory("PushSubscriptionHelper")
|
||||
}
|
||||
|
||||
private val logBuffer = StringBuilder()
|
||||
|
||||
val logString: String
|
||||
get() = logBuffer.toString()
|
||||
|
||||
private var subscribed: Boolean = false
|
||||
|
||||
val flags = account.notificationFlags()
|
||||
|
||||
private fun addLog(s: String?) {
|
||||
if (s?.isNotEmpty() == true) {
|
||||
if (logBuffer.isNotEmpty()) logBuffer.append('\n')
|
||||
logBuffer.append(s)
|
||||
}
|
||||
}
|
||||
|
||||
// アプリサーバにendpoint URLの変更を伝える
|
||||
private suspend fun registerEndpoint(
|
||||
client: TootApiClient,
|
||||
deviceId: String,
|
||||
endpoint: String,
|
||||
): TootApiResult {
|
||||
|
||||
// deprecated
|
||||
// if (account.last_push_endpoint == endpoint) return TootApiResult()
|
||||
|
||||
return client.http(
|
||||
buildJsonObject {
|
||||
put("acct", account.acct.ascii)
|
||||
put("deviceId", deviceId)
|
||||
put("endpoint", endpoint)
|
||||
}
|
||||
.toPostRequestBuilder()
|
||||
.url("$APP_SERVER/webpushendpoint")
|
||||
.build()
|
||||
).also { result ->
|
||||
result.response?.let { res ->
|
||||
when (res.code.also { res.close() }) {
|
||||
in 200 until 300 -> {
|
||||
// deprecated
|
||||
// account.updateLastPushEndpoint(endpoint)
|
||||
}
|
||||
else -> {
|
||||
result.caption = "(SubwayTooter App server)"
|
||||
client.readBodyString(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// suspend fun updateSubscription(
|
||||
// client: TootApiClient,
|
||||
// force: Boolean = false,
|
||||
// progress: suspend (SavedAccount, PollingState) -> Unit = { _, _ -> },
|
||||
// ): TootApiResult? = try {
|
||||
// when {
|
||||
// account.isPseudo ->
|
||||
// TootApiResult(context.getString(R.string.pseudo_account_not_supported))
|
||||
//
|
||||
// else -> {
|
||||
// progress(account, PollingState.CheckPushSubscription)
|
||||
// when {
|
||||
// account.isMisskey -> updateSubscriptionMisskey(client)
|
||||
// else -> updateSubscriptionMastodon(client, force)
|
||||
//import android.content.Context
|
||||
//import jp.juggler.subwaytooter.R
|
||||
//import jp.juggler.subwaytooter.api.TootApiClient
|
||||
//import jp.juggler.subwaytooter.api.TootApiResult
|
||||
//import jp.juggler.subwaytooter.api.entity.*
|
||||
//import jp.juggler.subwaytooter.table.SavedAccount
|
||||
//import jp.juggler.subwaytooter.table.SubscriptionServerKey
|
||||
//import jp.juggler.subwaytooter.table.appDatabase
|
||||
//import jp.juggler.util.*
|
||||
//import jp.juggler.util.data.*
|
||||
//import jp.juggler.util.log.*
|
||||
//import jp.juggler.util.network.toPostRequestBuilder
|
||||
//import jp.juggler.util.ui.*
|
||||
//import okhttp3.Request
|
||||
//
|
||||
//class PushSubscriptionHelper(
|
||||
// val context: Context,
|
||||
// val account: SavedAccount,
|
||||
// private val verbose: Boolean = false,
|
||||
// private val daoSubscriptionServerKey: SubscriptionServerKey.Access =
|
||||
// SubscriptionServerKey.Access(appDatabase),
|
||||
//) {
|
||||
// companion object {
|
||||
// private val log = LogCategory("PushSubscriptionHelper")
|
||||
// }
|
||||
//
|
||||
// private val logBuffer = StringBuilder()
|
||||
//
|
||||
// val logString: String
|
||||
// get() = logBuffer.toString()
|
||||
//
|
||||
// private var subscribed: Boolean = false
|
||||
//
|
||||
// val flags = account.notificationFlags()
|
||||
//
|
||||
// private fun addLog(s: String?) {
|
||||
// if (s?.isNotEmpty() == true) {
|
||||
// if (logBuffer.isNotEmpty()) logBuffer.append('\n')
|
||||
// logBuffer.append(s)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // アプリサーバにendpoint URLの変更を伝える
|
||||
// private suspend fun registerEndpoint(
|
||||
// client: TootApiClient,
|
||||
// deviceId: String,
|
||||
// endpoint: String,
|
||||
// ): TootApiResult {
|
||||
//
|
||||
// // deprecated
|
||||
// // if (account.last_push_endpoint == endpoint) return TootApiResult()
|
||||
//
|
||||
// return client.http(
|
||||
// buildJsonObject {
|
||||
// put("acct", account.acct.ascii)
|
||||
// put("deviceId", deviceId)
|
||||
// put("endpoint", endpoint)
|
||||
// }
|
||||
// .toPostRequestBuilder()
|
||||
// .url("$APP_SERVER/webpushendpoint")
|
||||
// .build()
|
||||
// ).also { result ->
|
||||
// result.response?.let { res ->
|
||||
// when (res.code.also { res.close() }) {
|
||||
// in 200 until 300 -> {
|
||||
// // deprecated
|
||||
// // account.updateLastPushEndpoint(endpoint)
|
||||
// }
|
||||
// else -> {
|
||||
// result.caption = "(SubwayTooter App server)"
|
||||
// client.readBodyString(result)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (ex: Throwable) {
|
||||
// TootApiResult(ex.withCaption("error."))
|
||||
// }?.apply {
|
||||
// }
|
||||
//
|
||||
// if (error != null) addLog("$error $requestInfo".trimEnd())
|
||||
//
|
||||
// // update error text on account table
|
||||
// val log = logString
|
||||
// when {
|
||||
// log.contains(ERROR_PREVENT_FREQUENTLY_CHECK) -> {
|
||||
// // don't update if check was skipped.
|
||||
// }
|
||||
//
|
||||
// subscribed || log.isEmpty() -> Unit
|
||||
// // clear error text if succeeded or no error log
|
||||
//// if (account.last_subscription_error != null) {
|
||||
//// account.updateSubscriptionError(null)
|
||||
//// suspend fun updateSubscription(
|
||||
//// client: TootApiClient,
|
||||
//// force: Boolean = false,
|
||||
//// progress: suspend (SavedAccount, PollingState) -> Unit = { _, _ -> },
|
||||
//// ): TootApiResult? = try {
|
||||
//// when {
|
||||
//// account.isPseudo ->
|
||||
//// TootApiResult(context.getString(R.string.pseudo_account_not_supported))
|
||||
////
|
||||
//// else -> {
|
||||
//// progress(account, PollingState.CheckPushSubscription)
|
||||
//// when {
|
||||
//// account.isMisskey -> updateSubscriptionMisskey(client)
|
||||
//// else -> updateSubscriptionMastodon(client, force)
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//// } catch (ex: Throwable) {
|
||||
//// TootApiResult(ex.withCaption("error."))
|
||||
//// }?.apply {
|
||||
////
|
||||
//// if (error != null) addLog("$error $requestInfo".trimEnd())
|
||||
////
|
||||
//// // update error text on account table
|
||||
//// val log = logString
|
||||
//// when {
|
||||
//// log.contains(ERROR_PREVENT_FREQUENTLY_CHECK) -> {
|
||||
//// // don't update if check was skipped.
|
||||
//// }
|
||||
////
|
||||
//// subscribed || log.isEmpty() -> Unit
|
||||
//// // clear error text if succeeded or no error log
|
||||
////// if (account.last_subscription_error != null) {
|
||||
////// account.updateSubscriptionError(null)
|
||||
////// }
|
||||
////
|
||||
//// else -> Unit
|
||||
//// // record error text
|
||||
////// account.updateSubscriptionError(log)
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// else -> Unit
|
||||
// // record error text
|
||||
//// account.updateSubscriptionError(log)
|
||||
// }
|
||||
// }
|
||||
|
||||
// private suspend fun updateSubscriptionMisskey(client: TootApiClient): TootApiResult? {
|
||||
//// private suspend fun updateSubscriptionMisskey(client: TootApiClient): TootApiResult? {
|
||||
////
|
||||
//// // 現在の購読状態を取得できないので、毎回購読の更新を行う
|
||||
//// // FCMのデバイスIDを取得
|
||||
//// val deviceId = try {
|
||||
//// loadFirebaseMessagingToken(context)
|
||||
//// } catch (ex: Throwable) {
|
||||
//// log.e(ex, "loadFirebaseMessagingToken failed.")
|
||||
//// return when (ex) {
|
||||
//// is CancellationException -> null
|
||||
//// else -> TootApiResult(error = context.getString(R.string.missing_fcm_device_id))
|
||||
//// }
|
||||
//// }
|
||||
////
|
||||
//// // アクセストークン
|
||||
//// val accessToken = account.misskeyApiToken
|
||||
//// ?: return TootApiResult(error = "missing misskeyApiToken.")
|
||||
////
|
||||
//// // インストールIDを取得
|
||||
//// val installId = try {
|
||||
//// loadInstallId(
|
||||
//// context,
|
||||
//// account,
|
||||
//// deviceId
|
||||
//// ) { a, s -> log.i("[${a.acct.pretty}]${s.desc}") }
|
||||
//// } catch (ex: Throwable) {
|
||||
//// log.e(ex, "loadInstallId failed.")
|
||||
//// return when (ex) {
|
||||
//// is CancellationException -> null
|
||||
//// else -> TootApiResult(error = context.getString(R.string.missing_install_id))
|
||||
//// }
|
||||
//// }
|
||||
////
|
||||
//// // クライアント識別子
|
||||
//// val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url()
|
||||
////
|
||||
//// // 購読が不要な場合
|
||||
//// // アプリサーバが410を返せるように状態を通知する
|
||||
//// if (flags == 0) return registerEndpoint(client, deviceId, "none").also {
|
||||
//// if (it.error == null && verbose) addLog(context.getString(R.string.push_subscription_updated))
|
||||
//// }
|
||||
////
|
||||
//// /*
|
||||
//// https://github.com/syuilo/misskey/blob/master/src/services/create-notification.ts#L46
|
||||
//// Misskeyは通知に既読の概念があり、イベント発生後2秒たっても未読の時だけプッシュ通知が発生する。
|
||||
//// STでプッシュ通知を試すにはSTの画面を非表示にする必要があるのでWebUIを使って投稿していたが、
|
||||
//// WebUIを開いていると通知はすぐ既読になるのでプッシュ通知は発生しない。
|
||||
//// プッシュ通知のテスト時はST2台を使い、片方をプッシュ通知の受信チェック、もう片方を投稿などの作業に使うことになる。
|
||||
//// */
|
||||
////
|
||||
//// // https://github.com/syuilo/misskey/issues/2541
|
||||
//// // https://github.com/syuilo/misskey/commit/4c6fb60dd25d7e2865fc7c4d97728593ffc3c902
|
||||
//// // 2018/9/1 の上記コミット以降、Misskeyでもサーバ公開鍵を得られるようになった
|
||||
////
|
||||
//// val endpoint =
|
||||
//// "$APP_SERVER/webpushcallback/${deviceId.encodePercent()}/${account.acct.ascii.encodePercent()}/$flags/$clientIdentifier/misskey"
|
||||
////
|
||||
//// // アプリサーバが過去のendpoint urlに410を返せるよう、状態を通知する
|
||||
//// val r = registerEndpoint(client, deviceId, endpoint.toUri().encodedPath!!)
|
||||
//// if (r.error != null) return r
|
||||
////
|
||||
//// // 購読
|
||||
//// @Suppress("SpellCheckingInspection")
|
||||
//// return client.request(
|
||||
//// "/api/sw/register",
|
||||
//// account.putMisskeyApiToken().apply {
|
||||
//// put("endpoint", endpoint)
|
||||
//// put("auth", "iRdmDrOS6eK6xvG1H6KshQ")
|
||||
//// put(
|
||||
//// "publickey",
|
||||
//// "BBEUVi7Ehdzzpe_ZvlzzkQnhujNJuBKH1R0xYg7XdAKNFKQG9Gpm0TSGRGSuaU7LUFKX-uz8YW0hAshifDCkPuE"
|
||||
//// )
|
||||
//// }
|
||||
//// .toPostRequestBuilder()
|
||||
//// )?.also { result ->
|
||||
//// val jsonObject = result.jsonObject
|
||||
//// if (jsonObject == null) {
|
||||
//// addLog("API error.")
|
||||
//// } else {
|
||||
//// if (verbose) addLog(context.getString(R.string.push_subscription_updated))
|
||||
//// subscribed = true
|
||||
//// return updateServerKey(
|
||||
//// client,
|
||||
//// clientIdentifier,
|
||||
//// jsonObject.string("key") ?: "3q2+rw"
|
||||
//// )
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// // 現在の購読状態を取得できないので、毎回購読の更新を行う
|
||||
// // FCMのデバイスIDを取得
|
||||
// val deviceId = try {
|
||||
// loadFirebaseMessagingToken(context)
|
||||
// } catch (ex: Throwable) {
|
||||
// log.e(ex, "loadFirebaseMessagingToken failed.")
|
||||
// return when (ex) {
|
||||
// is CancellationException -> null
|
||||
// else -> TootApiResult(error = context.getString(R.string.missing_fcm_device_id))
|
||||
// }
|
||||
// }
|
||||
//// private suspend fun updateSubscriptionMastodon(
|
||||
//// client: TootApiClient,
|
||||
//// force: Boolean,
|
||||
//// ): TootApiResult? {
|
||||
////
|
||||
//// // 現在の購読状態を取得
|
||||
//// // https://github.com/tootsuite/mastodon/pull/7471
|
||||
//// // https://github.com/tootsuite/mastodon/pull/7472
|
||||
////
|
||||
//// val subscription404: Boolean
|
||||
//// val oldSubscription: TootPushSubscription?
|
||||
//// checkCurrentSubscription(client).let {
|
||||
//// if (it.failed) return it.result
|
||||
//// subscription404 = it.is404
|
||||
//// oldSubscription = parseItem(::TootPushSubscription, it.result?.jsonObject)
|
||||
//// }
|
||||
////
|
||||
//// if (oldSubscription == null) {
|
||||
//// log.i("${account.acct}: oldSubscription is null")
|
||||
//// val (ti, result) = TootInstance.get(client)
|
||||
//// ti ?: return result
|
||||
//// checkInstanceVersionMastodon(ti, subscription404)?.let { return it }
|
||||
//// }
|
||||
////
|
||||
//// // FCMのデバイスIDを取得
|
||||
//// val deviceId = try {
|
||||
//// loadFirebaseMessagingToken(context)
|
||||
//// } catch (ex: Throwable) {
|
||||
//// log.e(ex, "loadFirebaseMessagingToken failed.")
|
||||
//// return when (ex) {
|
||||
//// is CancellationException -> null
|
||||
//// else -> TootApiResult(error = context.getString(R.string.missing_fcm_device_id))
|
||||
//// }
|
||||
//// }
|
||||
////
|
||||
//// // インストールIDを取得
|
||||
//// val installId = try {
|
||||
//// loadInstallId(
|
||||
//// context,
|
||||
//// account,
|
||||
//// deviceId
|
||||
//// ) { a, s -> log.i("[${a.acct.pretty}]${s.desc}") }
|
||||
//// } catch (ex: Throwable) {
|
||||
//// log.e(ex, "loadInstallId failed.")
|
||||
//// return when (ex) {
|
||||
//// is CancellationException -> null
|
||||
//// else -> TootApiResult(error = context.getString(R.string.missing_install_id))
|
||||
//// }
|
||||
//// }
|
||||
//// // アクセストークン
|
||||
//// val accessToken = account.bearerAccessToken
|
||||
//// ?: return TootApiResult(error = "missing access token.")
|
||||
////
|
||||
//// // アクセストークンのダイジェスト
|
||||
//// val tokenDigest = accessToken.digestSHA256Base64Url()
|
||||
////
|
||||
//// // クライアント識別子
|
||||
//// val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url()
|
||||
////
|
||||
//// val endpoint =
|
||||
//// "$APP_SERVER/webpushcallback/${deviceId.encodePercent()}/${account.acct.ascii.encodePercent()}/$flags/$clientIdentifier"
|
||||
////
|
||||
//// val newAlerts = JsonObject().apply {
|
||||
//// put("follow", account.notification_follow)
|
||||
//// put(TootNotification.TYPE_ADMIN_SIGNUP, account.notification_follow)
|
||||
//// put("favourite", account.notification_favourite)
|
||||
//// put("reblog", account.notification_boost)
|
||||
//// put("mention", account.notification_mention)
|
||||
//// put("poll", account.notification_vote)
|
||||
//// put("follow_request", account.notification_follow_request)
|
||||
//// put("status", account.notification_post)
|
||||
//// put("update", account.notification_update)
|
||||
//// put("emoji_reaction", account.notification_reaction) // fedibird拡張
|
||||
//// }
|
||||
////
|
||||
//// if (!force) {
|
||||
//// canSkipSubscriptionMastodon(
|
||||
//// client = client,
|
||||
//// clientIdentifier = clientIdentifier,
|
||||
//// endpoint = endpoint,
|
||||
//// oldSubscription = oldSubscription,
|
||||
//// newAlerts = newAlerts,
|
||||
//// )?.let { return it }
|
||||
//// }
|
||||
////
|
||||
//// // アクセストークンの優先権を取得
|
||||
//// checkDeviceHasPriority(
|
||||
//// client,
|
||||
//// tokenDigest = tokenDigest,
|
||||
//// installId = installId,
|
||||
//// ).let {
|
||||
//// if (it.failed) return it.result
|
||||
//// }
|
||||
////
|
||||
//// return when (flags) {
|
||||
//// // 通知設定が全てカラなので、購読を取り消したい
|
||||
//// 0 -> unsubscribeMastodon(client)
|
||||
////
|
||||
//// // 通知設定が空ではないので購読を行いたい
|
||||
//// else -> subscribeMastodon(
|
||||
//// client = client,
|
||||
//// clientIdentifier = clientIdentifier,
|
||||
//// endpoint = endpoint,
|
||||
//// newAlerts = newAlerts
|
||||
//// )
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// // アクセストークン
|
||||
// val accessToken = account.misskeyApiToken
|
||||
// ?: return TootApiResult(error = "missing misskeyApiToken.")
|
||||
//
|
||||
// // インストールIDを取得
|
||||
// val installId = try {
|
||||
// loadInstallId(
|
||||
// context,
|
||||
// account,
|
||||
// deviceId
|
||||
// ) { a, s -> log.i("[${a.acct.pretty}]${s.desc}") }
|
||||
// } catch (ex: Throwable) {
|
||||
// log.e(ex, "loadInstallId failed.")
|
||||
// return when (ex) {
|
||||
// is CancellationException -> null
|
||||
// else -> TootApiResult(error = context.getString(R.string.missing_install_id))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // クライアント識別子
|
||||
// val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url()
|
||||
//
|
||||
// // 購読が不要な場合
|
||||
// // アプリサーバが410を返せるように状態を通知する
|
||||
// if (flags == 0) return registerEndpoint(client, deviceId, "none").also {
|
||||
// if (it.error == null && verbose) addLog(context.getString(R.string.push_subscription_updated))
|
||||
// }
|
||||
//
|
||||
// /*
|
||||
// https://github.com/syuilo/misskey/blob/master/src/services/create-notification.ts#L46
|
||||
// Misskeyは通知に既読の概念があり、イベント発生後2秒たっても未読の時だけプッシュ通知が発生する。
|
||||
// STでプッシュ通知を試すにはSTの画面を非表示にする必要があるのでWebUIを使って投稿していたが、
|
||||
// WebUIを開いていると通知はすぐ既読になるのでプッシュ通知は発生しない。
|
||||
// プッシュ通知のテスト時はST2台を使い、片方をプッシュ通知の受信チェック、もう片方を投稿などの作業に使うことになる。
|
||||
// */
|
||||
//
|
||||
// // https://github.com/syuilo/misskey/issues/2541
|
||||
// // https://github.com/syuilo/misskey/commit/4c6fb60dd25d7e2865fc7c4d97728593ffc3c902
|
||||
// // 2018/9/1 の上記コミット以降、Misskeyでもサーバ公開鍵を得られるようになった
|
||||
//
|
||||
// val endpoint =
|
||||
// "$APP_SERVER/webpushcallback/${deviceId.encodePercent()}/${account.acct.ascii.encodePercent()}/$flags/$clientIdentifier/misskey"
|
||||
//
|
||||
// // アプリサーバが過去のendpoint urlに410を返せるよう、状態を通知する
|
||||
// val r = registerEndpoint(client, deviceId, endpoint.toUri().encodedPath!!)
|
||||
// if (r.error != null) return r
|
||||
//
|
||||
// // 購読
|
||||
// @Suppress("SpellCheckingInspection")
|
||||
// return client.request(
|
||||
// "/api/sw/register",
|
||||
// account.putMisskeyApiToken().apply {
|
||||
// put("endpoint", endpoint)
|
||||
// put("auth", "iRdmDrOS6eK6xvG1H6KshQ")
|
||||
// put(
|
||||
// "publickey",
|
||||
// "BBEUVi7Ehdzzpe_ZvlzzkQnhujNJuBKH1R0xYg7XdAKNFKQG9Gpm0TSGRGSuaU7LUFKX-uz8YW0hAshifDCkPuE"
|
||||
// )
|
||||
// }
|
||||
// .toPostRequestBuilder()
|
||||
// )?.also { result ->
|
||||
// val jsonObject = result.jsonObject
|
||||
// if (jsonObject == null) {
|
||||
// addLog("API error.")
|
||||
// } else {
|
||||
// if (verbose) addLog(context.getString(R.string.push_subscription_updated))
|
||||
// subscribed = true
|
||||
// return updateServerKey(
|
||||
// client,
|
||||
// clientIdentifier,
|
||||
// jsonObject.string("key") ?: "3q2+rw"
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private suspend fun updateSubscriptionMastodon(
|
||||
// client: TootApiClient,
|
||||
// force: Boolean,
|
||||
// // returns null if no error
|
||||
// private fun checkInstanceVersionMastodon(
|
||||
// ti: TootInstance,
|
||||
// subscription404: Boolean,
|
||||
// ): TootApiResult? {
|
||||
//
|
||||
// // 現在の購読状態を取得
|
||||
// // https://github.com/tootsuite/mastodon/pull/7471
|
||||
// // https://github.com/tootsuite/mastodon/pull/7472
|
||||
//
|
||||
// val subscription404: Boolean
|
||||
// val oldSubscription: TootPushSubscription?
|
||||
// checkCurrentSubscription(client).let {
|
||||
// if (it.failed) return it.result
|
||||
// subscription404 = it.is404
|
||||
// oldSubscription = parseItem(::TootPushSubscription, it.result?.jsonObject)
|
||||
// }
|
||||
//
|
||||
// if (oldSubscription == null) {
|
||||
// log.i("${account.acct}: oldSubscription is null")
|
||||
// val (ti, result) = TootInstance.get(client)
|
||||
// ti ?: return result
|
||||
// checkInstanceVersionMastodon(ti, subscription404)?.let { return it }
|
||||
// }
|
||||
//
|
||||
// // FCMのデバイスIDを取得
|
||||
// val deviceId = try {
|
||||
// loadFirebaseMessagingToken(context)
|
||||
// } catch (ex: Throwable) {
|
||||
// log.e(ex, "loadFirebaseMessagingToken failed.")
|
||||
// return when (ex) {
|
||||
// is CancellationException -> null
|
||||
// else -> TootApiResult(error = context.getString(R.string.missing_fcm_device_id))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // インストールIDを取得
|
||||
// val installId = try {
|
||||
// loadInstallId(
|
||||
// context,
|
||||
// account,
|
||||
// deviceId
|
||||
// ) { a, s -> log.i("[${a.acct.pretty}]${s.desc}") }
|
||||
// } catch (ex: Throwable) {
|
||||
// log.e(ex, "loadInstallId failed.")
|
||||
// return when (ex) {
|
||||
// is CancellationException -> null
|
||||
// else -> TootApiResult(error = context.getString(R.string.missing_install_id))
|
||||
// }
|
||||
// }
|
||||
// // アクセストークン
|
||||
// val accessToken = account.bearerAccessToken
|
||||
// ?: return TootApiResult(error = "missing access token.")
|
||||
//
|
||||
// // アクセストークンのダイジェスト
|
||||
// val tokenDigest = accessToken.digestSHA256Base64Url()
|
||||
//
|
||||
// // クライアント識別子
|
||||
// val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url()
|
||||
//
|
||||
// val endpoint =
|
||||
// "$APP_SERVER/webpushcallback/${deviceId.encodePercent()}/${account.acct.ascii.encodePercent()}/$flags/$clientIdentifier"
|
||||
//
|
||||
// val newAlerts = JsonObject().apply {
|
||||
// put("follow", account.notification_follow)
|
||||
// put(TootNotification.TYPE_ADMIN_SIGNUP, account.notification_follow)
|
||||
// put("favourite", account.notification_favourite)
|
||||
// put("reblog", account.notification_boost)
|
||||
// put("mention", account.notification_mention)
|
||||
// put("poll", account.notification_vote)
|
||||
// put("follow_request", account.notification_follow_request)
|
||||
// put("status", account.notification_post)
|
||||
// put("update", account.notification_update)
|
||||
// put("emoji_reaction", account.notification_reaction) // fedibird拡張
|
||||
// }
|
||||
//
|
||||
// if (!force) {
|
||||
// canSkipSubscriptionMastodon(
|
||||
// client = client,
|
||||
// clientIdentifier = clientIdentifier,
|
||||
// endpoint = endpoint,
|
||||
// oldSubscription = oldSubscription,
|
||||
// newAlerts = newAlerts,
|
||||
// )?.let { return it }
|
||||
// }
|
||||
//
|
||||
// // アクセストークンの優先権を取得
|
||||
// checkDeviceHasPriority(
|
||||
// client,
|
||||
// tokenDigest = tokenDigest,
|
||||
// installId = installId,
|
||||
// ).let {
|
||||
// if (it.failed) return it.result
|
||||
// }
|
||||
//
|
||||
// return when (flags) {
|
||||
// // 通知設定が全てカラなので、購読を取り消したい
|
||||
// 0 -> unsubscribeMastodon(client)
|
||||
//
|
||||
// // 通知設定が空ではないので購読を行いたい
|
||||
// else -> subscribeMastodon(
|
||||
// client = client,
|
||||
// clientIdentifier = clientIdentifier,
|
||||
// endpoint = endpoint,
|
||||
// newAlerts = newAlerts
|
||||
// // 2.4.0rc1 未満にはプッシュ購読APIはない
|
||||
// if (!ti.versionGE(TootInstance.VERSION_2_4_0_rc1)) {
|
||||
// return TootApiResult(
|
||||
// context.getString(R.string.instance_does_not_support_push_api, ti.version)
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// if (subscription404 && flags == 0) {
|
||||
// when {
|
||||
// ti.versionGE(TootInstance.VERSION_2_4_0_rc2) -> {
|
||||
// // 購読が不要で現在の状況が404だった場合
|
||||
// // 2.4.0rc2以降では「購読が存在しない」を示すので何もしなくてよい
|
||||
// if (verbose) addLog(context.getString(R.string.push_subscription_not_exists))
|
||||
// return TootApiResult()
|
||||
// }
|
||||
//
|
||||
// else -> {
|
||||
// // 2.4.0rc1では「APIが存在しない」と「購読が存在しない」を判別できない
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
|
||||
// returns null if no error
|
||||
private fun checkInstanceVersionMastodon(
|
||||
ti: TootInstance,
|
||||
subscription404: Boolean,
|
||||
): TootApiResult? {
|
||||
|
||||
// 2.4.0rc1 未満にはプッシュ購読APIはない
|
||||
if (!ti.versionGE(TootInstance.VERSION_2_4_0_rc1)) {
|
||||
return TootApiResult(
|
||||
context.getString(R.string.instance_does_not_support_push_api, ti.version)
|
||||
)
|
||||
}
|
||||
|
||||
if (subscription404 && flags == 0) {
|
||||
when {
|
||||
ti.versionGE(TootInstance.VERSION_2_4_0_rc2) -> {
|
||||
// 購読が不要で現在の状況が404だった場合
|
||||
// 2.4.0rc2以降では「購読が存在しない」を示すので何もしなくてよい
|
||||
if (verbose) addLog(context.getString(R.string.push_subscription_not_exists))
|
||||
return TootApiResult()
|
||||
}
|
||||
|
||||
else -> {
|
||||
// 2.4.0rc1では「APIが存在しない」と「購読が存在しない」を判別できない
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private class CheckCurrentSubscriptionResult(
|
||||
val result: TootApiResult?,
|
||||
val failed: Boolean,
|
||||
val is404: Boolean,
|
||||
)
|
||||
|
||||
@Suppress("BooleanLiteralArgument")
|
||||
private suspend fun checkCurrentSubscription(client: TootApiClient): CheckCurrentSubscriptionResult {
|
||||
val r = client.request("/api/v1/push/subscription")
|
||||
fun rvError() = CheckCurrentSubscriptionResult(r, true, false)
|
||||
fun rvOk() = CheckCurrentSubscriptionResult(r, false, false)
|
||||
fun rv404() = CheckCurrentSubscriptionResult(r, false, true)
|
||||
val res = r?.response ?: return rvError() // cancelled or missing response
|
||||
|
||||
if (res.code != 200) log.i("${account.acct}: check existing subscription: code=${res.code}")
|
||||
|
||||
return when (res.code) {
|
||||
200 -> {
|
||||
if (r.error?.isNotEmpty() == true && r.jsonObject == null) {
|
||||
// Pleromaが200応答でもエラーHTMLを返す場合がある
|
||||
addLog(context.getString(R.string.instance_does_not_support_push_api_pleroma))
|
||||
rvError()
|
||||
} else {
|
||||
// たぶん購読が存在する
|
||||
rvOk()
|
||||
}
|
||||
}
|
||||
|
||||
// この時点では存在しないのが購読なのかAPIなのか分からない
|
||||
404 -> rv404()
|
||||
|
||||
403 -> {
|
||||
// アクセストークンにpushスコープがない
|
||||
if (flags != 0 || verbose) addLog(context.getString(R.string.missing_push_scope))
|
||||
rvError()
|
||||
}
|
||||
|
||||
in 400 until 500 -> {
|
||||
addLog(context.getString(R.string.instance_does_not_support_push_api_pleroma))
|
||||
rvError()
|
||||
}
|
||||
|
||||
else -> {
|
||||
addLog("${res.request}")
|
||||
addLog("${res.code} ${res.message}")
|
||||
rvOk() // 後でリトライする
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun unsubscribeMastodon(
|
||||
client: TootApiClient,
|
||||
): TootApiResult? {
|
||||
|
||||
val r = client.request("/api/v1/push/subscription", Request.Builder().delete())
|
||||
val res = r?.response ?: return r
|
||||
|
||||
return when (res.code) {
|
||||
200 -> {
|
||||
if (verbose) addLog(context.getString(R.string.push_subscription_deleted))
|
||||
TootApiResult()
|
||||
}
|
||||
|
||||
404 -> {
|
||||
if (verbose) {
|
||||
addLog(context.getString(R.string.missing_push_api))
|
||||
r
|
||||
} else {
|
||||
TootApiResult()
|
||||
}
|
||||
}
|
||||
|
||||
403 -> {
|
||||
addLog(context.getString(R.string.missing_push_scope))
|
||||
r
|
||||
}
|
||||
|
||||
else -> {
|
||||
addLog("${res.request}")
|
||||
addLog("${res.code} ${res.message}")
|
||||
r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun subscribeMastodon(
|
||||
client: TootApiClient,
|
||||
endpoint: String,
|
||||
newAlerts: JsonObject,
|
||||
): TootApiResult? {
|
||||
@Suppress("SpellCheckingInspection")
|
||||
val params = JsonObject().apply {
|
||||
put("subscription", JsonObject().apply {
|
||||
put("endpoint", endpoint)
|
||||
put("keys", JsonObject().apply {
|
||||
put(
|
||||
"p256dh",
|
||||
"BBEUVi7Ehdzzpe_ZvlzzkQnhujNJuBKH1R0xYg7XdAKNFKQG9Gpm0TSGRGSuaU7LUFKX-uz8YW0hAshifDCkPuE"
|
||||
)
|
||||
put("auth", "iRdmDrOS6eK6xvG1H6KshQ")
|
||||
})
|
||||
})
|
||||
put("data", JsonObject().apply {
|
||||
put("alerts", newAlerts)
|
||||
account.pushPolicy?.let { put("policy", it) }
|
||||
})
|
||||
}
|
||||
|
||||
val r = client.request(
|
||||
"/api/v1/push/subscription",
|
||||
params.toPostRequestBuilder()
|
||||
) ?: return null
|
||||
|
||||
val res = r.response ?: return r
|
||||
|
||||
return when (res.code) {
|
||||
404 -> {
|
||||
addLog(context.getString(R.string.missing_push_api))
|
||||
r
|
||||
}
|
||||
|
||||
403 -> {
|
||||
addLog(context.getString(R.string.missing_push_scope))
|
||||
r
|
||||
}
|
||||
|
||||
200 -> {
|
||||
subscribed = true
|
||||
if (verbose) addLog(context.getString(R.string.push_subscription_updated))
|
||||
return TootApiResult()
|
||||
}
|
||||
|
||||
else -> {
|
||||
addLog(r.jsonObject?.toString())
|
||||
r
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// private class CheckCurrentSubscriptionResult(
|
||||
// val result: TootApiResult?,
|
||||
// val failed: Boolean,
|
||||
// val is404: Boolean,
|
||||
// )
|
||||
//
|
||||
// @Suppress("BooleanLiteralArgument")
|
||||
// private suspend fun checkCurrentSubscription(client: TootApiClient): CheckCurrentSubscriptionResult {
|
||||
// val r = client.request("/api/v1/push/subscription")
|
||||
// fun rvError() = CheckCurrentSubscriptionResult(r, true, false)
|
||||
// fun rvOk() = CheckCurrentSubscriptionResult(r, false, false)
|
||||
// fun rv404() = CheckCurrentSubscriptionResult(r, false, true)
|
||||
// val res = r?.response ?: return rvError() // cancelled or missing response
|
||||
//
|
||||
// if (res.code != 200) log.i("${account.acct}: check existing subscription: code=${res.code}")
|
||||
//
|
||||
// return when (res.code) {
|
||||
// 200 -> {
|
||||
// if (r.error?.isNotEmpty() == true && r.jsonObject == null) {
|
||||
// // Pleromaが200応答でもエラーHTMLを返す場合がある
|
||||
// addLog(context.getString(R.string.instance_does_not_support_push_api_pleroma))
|
||||
// rvError()
|
||||
// } else {
|
||||
// // たぶん購読が存在する
|
||||
// rvOk()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // この時点では存在しないのが購読なのかAPIなのか分からない
|
||||
// 404 -> rv404()
|
||||
//
|
||||
// 403 -> {
|
||||
// // アクセストークンにpushスコープがない
|
||||
// if (flags != 0 || verbose) addLog(context.getString(R.string.missing_push_scope))
|
||||
// rvError()
|
||||
// }
|
||||
//
|
||||
// in 400 until 500 -> {
|
||||
// addLog(context.getString(R.string.instance_does_not_support_push_api_pleroma))
|
||||
// rvError()
|
||||
// }
|
||||
//
|
||||
// else -> {
|
||||
// addLog("${res.request}")
|
||||
// addLog("${res.code} ${res.message}")
|
||||
// rvOk() // 後でリトライする
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private suspend fun unsubscribeMastodon(
|
||||
// client: TootApiClient,
|
||||
// ): TootApiResult? {
|
||||
//
|
||||
// val r = client.request("/api/v1/push/subscription", Request.Builder().delete())
|
||||
// val res = r?.response ?: return r
|
||||
//
|
||||
// return when (res.code) {
|
||||
// 200 -> {
|
||||
// if (verbose) addLog(context.getString(R.string.push_subscription_deleted))
|
||||
// TootApiResult()
|
||||
// }
|
||||
//
|
||||
// 404 -> {
|
||||
// if (verbose) {
|
||||
// addLog(context.getString(R.string.missing_push_api))
|
||||
// r
|
||||
// } else {
|
||||
// TootApiResult()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// 403 -> {
|
||||
// addLog(context.getString(R.string.missing_push_scope))
|
||||
// r
|
||||
// }
|
||||
//
|
||||
// else -> {
|
||||
// addLog("${res.request}")
|
||||
// addLog("${res.code} ${res.message}")
|
||||
// r
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private suspend fun subscribeMastodon(
|
||||
// client: TootApiClient,
|
||||
// endpoint: String,
|
||||
// newAlerts: JsonObject,
|
||||
// ): TootApiResult? {
|
||||
// @Suppress("SpellCheckingInspection")
|
||||
// val params = JsonObject().apply {
|
||||
// put("subscription", JsonObject().apply {
|
||||
// put("endpoint", endpoint)
|
||||
// put("keys", JsonObject().apply {
|
||||
// put(
|
||||
// "p256dh",
|
||||
// "BBEUVi7Ehdzzpe_ZvlzzkQnhujNJuBKH1R0xYg7XdAKNFKQG9Gpm0TSGRGSuaU7LUFKX-uz8YW0hAshifDCkPuE"
|
||||
// )
|
||||
// put("auth", "iRdmDrOS6eK6xvG1H6KshQ")
|
||||
// })
|
||||
// })
|
||||
// put("data", JsonObject().apply {
|
||||
// put("alerts", newAlerts)
|
||||
// account.pushPolicy?.let { put("policy", it) }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// val r = client.request(
|
||||
// "/api/v1/push/subscription",
|
||||
// params.toPostRequestBuilder()
|
||||
// ) ?: return null
|
||||
//
|
||||
// val res = r.response ?: return r
|
||||
//
|
||||
// return when (res.code) {
|
||||
// 404 -> {
|
||||
// addLog(context.getString(R.string.missing_push_api))
|
||||
// r
|
||||
// }
|
||||
//
|
||||
// 403 -> {
|
||||
// addLog(context.getString(R.string.missing_push_scope))
|
||||
// r
|
||||
// }
|
||||
//
|
||||
// 200 -> {
|
||||
// subscribed = true
|
||||
// if (verbose) addLog(context.getString(R.string.push_subscription_updated))
|
||||
// return TootApiResult()
|
||||
// }
|
||||
//
|
||||
// else -> {
|
||||
// addLog(r.jsonObject?.toString())
|
||||
// r
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package jp.juggler.subwaytooter.notification
|
||||
package jp.juggler.subwaytooter.push
|
||||
|
||||
import android.graphics.Color
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.table.PushMessage
|
||||
@ -9,86 +8,84 @@ import jp.juggler.util.log.LogCategory
|
||||
|
||||
private val log = LogCategory("NotificationIconAndColor")
|
||||
|
||||
enum class NotificationIconAndColor(
|
||||
@ColorInt colorArg: Int,
|
||||
enum class PushMessageIconColor(
|
||||
@ColorRes val colorRes: Int,
|
||||
@DrawableRes val iconId: Int,
|
||||
val keys: Array<String>,
|
||||
) {
|
||||
Favourite(
|
||||
0xe5e825,
|
||||
R.color.colorNotificationAccentFavourite,
|
||||
R.drawable.ic_star_outline,
|
||||
arrayOf("favourite"),
|
||||
),
|
||||
Mention(
|
||||
0x60f516,
|
||||
R.color.colorNotificationAccentMention,
|
||||
R.drawable.outline_alternate_email_24,
|
||||
arrayOf("mention"),
|
||||
),
|
||||
Reply(
|
||||
0xff3dbb,
|
||||
R.color.colorNotificationAccentReply,
|
||||
R.drawable.ic_reply,
|
||||
arrayOf("reply")
|
||||
),
|
||||
Reblog(
|
||||
0x39e3d5,
|
||||
R.color.colorNotificationAccentReblog,
|
||||
R.drawable.ic_repeat,
|
||||
arrayOf("reblog", "renote"),
|
||||
),
|
||||
Quote(
|
||||
0x40a9ff,
|
||||
R.color.colorNotificationAccentQuote,
|
||||
R.drawable.ic_quote,
|
||||
arrayOf("quote"),
|
||||
),
|
||||
Follow(
|
||||
0xf57a33,
|
||||
R.color.colorNotificationAccentFollow,
|
||||
R.drawable.ic_person_add,
|
||||
arrayOf("follow", "followRequestAccepted")
|
||||
),
|
||||
Unfollow(
|
||||
0x9433f5,
|
||||
R.color.colorNotificationAccentUnfollow,
|
||||
R.drawable.ic_follow_cross,
|
||||
arrayOf("unfollow")
|
||||
),
|
||||
Reaction(
|
||||
0xf5f233,
|
||||
R.color.colorNotificationAccentReaction,
|
||||
R.drawable.outline_add_reaction_24,
|
||||
arrayOf("reaction", "emoji_reaction", "pleroma:emoji_reaction")
|
||||
),
|
||||
FollowRequest(
|
||||
0xf53333,
|
||||
R.color.colorNotificationAccentFollowRequest,
|
||||
R.drawable.ic_follow_wait,
|
||||
arrayOf("follow_request", "receiveFollowRequest"),
|
||||
),
|
||||
Poll(
|
||||
0x33f59b,
|
||||
R.color.colorNotificationAccentPoll,
|
||||
R.drawable.outline_poll_24,
|
||||
arrayOf("pollVote", "poll_vote", "poll"),
|
||||
),
|
||||
Status(
|
||||
0x33f597,
|
||||
R.color.colorNotificationAccentStatus,
|
||||
R.drawable.ic_edit,
|
||||
arrayOf("status", "update", "status_reference")
|
||||
),
|
||||
SignUp(
|
||||
0xf56a33,
|
||||
R.color.colorNotificationAccentSignUp,
|
||||
R.drawable.outline_group_add_24,
|
||||
arrayOf("admin.sign_up"),
|
||||
),
|
||||
|
||||
Unknown(
|
||||
0xae1aed,
|
||||
R.color.colorNotificationAccentUnknown,
|
||||
R.drawable.ic_question,
|
||||
arrayOf("unknown"),
|
||||
arrayOf("unknown", "admin.sign_up"),
|
||||
)
|
||||
;
|
||||
|
||||
val color = Color.BLACK or colorArg
|
||||
|
||||
companion object {
|
||||
val map = buildMap {
|
||||
values().forEach {
|
||||
for (k in it.keys) {
|
||||
val old: NotificationIconAndColor? = get(k)
|
||||
val old: PushMessageIconColor? = get(k)
|
||||
if (old != null) {
|
||||
error("NotificationIconAndColor: $k is duplicate: ${it.name} and ${old.name}")
|
||||
} else {
|
||||
@ -100,20 +97,6 @@ enum class NotificationIconAndColor(
|
||||
}
|
||||
}
|
||||
|
||||
fun String.findNotificationIconAndColor() =
|
||||
NotificationIconAndColor.map[this]
|
||||
|
||||
fun PushMessage.notificationIconAndColor(): NotificationIconAndColor {
|
||||
// mastodon
|
||||
messageJson?.string("notification_type")
|
||||
?.findNotificationIconAndColor()?.let { return it }
|
||||
|
||||
// misskey
|
||||
when (messageJson?.string("type")) {
|
||||
"notification" ->
|
||||
messageJson?.jsonObject("body")?.string("type")
|
||||
?.findNotificationIconAndColor()?.let { return it }
|
||||
}
|
||||
|
||||
return NotificationIconAndColor.Unknown
|
||||
}
|
||||
fun PushMessage.iconColor() =
|
||||
notificationType?.let { PushMessageIconColor.map[it] }
|
||||
?: PushMessageIconColor.Unknown
|
@ -4,11 +4,11 @@ import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.await
|
||||
import jp.juggler.anko.BuildConfig
|
||||
import jp.juggler.crypt.*
|
||||
import jp.juggler.subwaytooter.ActCallback
|
||||
import jp.juggler.subwaytooter.R
|
||||
@ -20,7 +20,7 @@ import jp.juggler.subwaytooter.api.push.ApiPushMisskey
|
||||
import jp.juggler.subwaytooter.dialog.SuspendProgress
|
||||
import jp.juggler.subwaytooter.notification.NotificationChannels
|
||||
import jp.juggler.subwaytooter.notification.NotificationDeleteReceiver.Companion.intentNotificationDelete
|
||||
import jp.juggler.subwaytooter.notification.notificationIconAndColor
|
||||
import jp.juggler.subwaytooter.notification.iconColor
|
||||
import jp.juggler.subwaytooter.pref.PrefDevice
|
||||
import jp.juggler.subwaytooter.pref.prefDevice
|
||||
import jp.juggler.subwaytooter.push.*
|
||||
@ -637,7 +637,7 @@ class PushRepo(
|
||||
}
|
||||
|
||||
val density = context.resources.displayMetrics.density
|
||||
val iconAndColor = pm.notificationIconAndColor()
|
||||
val iconAndColor = pm.iconColor()
|
||||
|
||||
suspend fun PushMessage.loadSmallIcon(context: Context): IconCompat {
|
||||
iconSmall?.notEmpty()
|
||||
@ -687,7 +687,7 @@ class PushRepo(
|
||||
// val piTap = PendingIntent.getActivity(this, nc.pircTap, iTap, PendingIntent.FLAG_IMMUTABLE)
|
||||
|
||||
ncPushMessage.notify(context, urlDelete) {
|
||||
color = iconAndColor.color
|
||||
color = ContextCompat.getColor(context,iconAndColor.colorRes)
|
||||
setSmallIcon(iconSmall)
|
||||
iconBitmapLarge?.let { setLargeIcon(it) }
|
||||
setContentTitle(pm.loginAcct)
|
||||
|
@ -156,4 +156,20 @@
|
||||
<!-- 白テーマのナビゲーションバーは白ではない -->
|
||||
<color name="colorNavigationBarWorkaround">#707070</color>
|
||||
|
||||
<!-- 通知のアクセント色 Pushメッセージ用 -->
|
||||
<color name="colorNotificationAccentFavourite">#e5e825</color>
|
||||
<color name="colorNotificationAccentFollow">#f57a33</color>
|
||||
<color name="colorNotificationAccentFollowRequest">#f53333</color>
|
||||
<color name="colorNotificationAccentMention">#60f516</color>
|
||||
<color name="colorNotificationAccentPoll">#33f59b</color>
|
||||
<color name="colorNotificationAccentQuote">#40a9ff</color>
|
||||
<color name="colorNotificationAccentReaction">#f5f233</color>
|
||||
<color name="colorNotificationAccentReblog">#39e3d5</color>
|
||||
<color name="colorNotificationAccentReply">#ff3dbb</color>
|
||||
<color name="colorNotificationAccentSignUp">#f56a33</color>
|
||||
<color name="colorNotificationAccentStatus">#33f597</color>
|
||||
<color name="colorNotificationAccentUnfollow">#9433f5</color>
|
||||
<color name="colorNotificationAccentUnknown">#ae1aed</color>
|
||||
|
||||
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user