BigTextStyleを使う。通知タップ時にアカウントの通知カラムを開く。
This commit is contained in:
parent
ba361806bd
commit
055b196be6
|
@ -140,7 +140,7 @@ class ActPushMessageList : AppCompatActivity() {
|
|||
println("to: ${pm.loginAcct}")
|
||||
println("type: ${pm.notificationType}")
|
||||
println("id: ${pm.notificationId}")
|
||||
println("text: ${pm.rawBody?.size}")
|
||||
println("text: ${pm.textExpand}")
|
||||
println("dataSize: ${pm.rawBody?.size}")
|
||||
println("messageJson=${pm.messageJson?.toString(1, sort = true)}")
|
||||
|
||||
|
@ -207,7 +207,7 @@ class ActPushMessageList : AppCompatActivity() {
|
|||
"type: ${pm.notificationType}",
|
||||
"id: ${pm.notificationId}",
|
||||
"dataSize: ${pm.rawBody?.size}",
|
||||
pm.text
|
||||
pm.textExpand
|
||||
).mapNotNull { it.notBlank() }.joinToString("\n")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,8 @@ private fun ActMain.handleNotificationClick(uri: Uri, dataIdString: String) {
|
|||
return
|
||||
}
|
||||
|
||||
pushRepo.onTapNotification(account)
|
||||
|
||||
recycleClickedNotification(this, uri)
|
||||
|
||||
val columnList = appState.columnList
|
||||
|
|
|
@ -71,8 +71,8 @@ object PullNotification {
|
|||
|
||||
val params = listOf(
|
||||
"db_id" to account.db_id.toString(),
|
||||
"type" to trackingType.str,
|
||||
"notificationId" to notificationId
|
||||
"type" to trackingType.str, // URIをユニークにするため。参照されない
|
||||
"notificationId" to notificationId, // URIをユニークにするため。参照されない
|
||||
).mapNotNull {
|
||||
when (val second = it.second) {
|
||||
null -> null
|
||||
|
|
|
@ -161,6 +161,10 @@ class PushMastodon(
|
|||
pm.text = arrayOf(
|
||||
// あなたのトゥートが tateisu 🤹 さんにお気に入り登録されました
|
||||
json.string("title"),
|
||||
).mapNotNull { it?.trim()?.notBlank() }.joinToString("\n")
|
||||
pm.textExpand = arrayOf(
|
||||
// あなたのトゥートが tateisu 🤹 さんにお気に入り登録されました
|
||||
json.string("title"),
|
||||
// 対象の投稿の本文?
|
||||
json.string("body"),
|
||||
// 対象の投稿の本文? (古い
|
||||
|
|
|
@ -2,11 +2,14 @@ package jp.juggler.subwaytooter.push
|
|||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.await
|
||||
import jp.juggler.crypt.*
|
||||
import jp.juggler.subwaytooter.ActCallback
|
||||
import jp.juggler.subwaytooter.R
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
import jp.juggler.subwaytooter.api.entity.Host
|
||||
|
@ -25,6 +28,7 @@ import jp.juggler.subwaytooter.push.PushWorker.Companion.enqueueRegisterEndpoint
|
|||
import jp.juggler.subwaytooter.table.*
|
||||
import jp.juggler.subwaytooter.util.loadIcon
|
||||
import jp.juggler.util.coroutine.AppDispatchers
|
||||
import jp.juggler.util.coroutine.EmptyScope
|
||||
import jp.juggler.util.data.*
|
||||
import jp.juggler.util.data.Base128.decodeBase128
|
||||
import jp.juggler.util.log.LogCategory
|
||||
|
@ -32,6 +36,7 @@ import jp.juggler.util.log.withCaption
|
|||
import jp.juggler.util.os.applicationContextSafe
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
import org.unifiedpush.android.connector.UnifiedPush
|
||||
|
@ -526,7 +531,7 @@ class PushRepo(
|
|||
}
|
||||
|
||||
// 解読できた(例外が出なかった)なら通知を出す
|
||||
showPushNotification(pm)
|
||||
showPushNotification(pm,account,notificationId)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -608,7 +613,11 @@ class PushRepo(
|
|||
/**
|
||||
* SNSからの通知を表示する
|
||||
*/
|
||||
private suspend fun showPushNotification(pm: PushMessage) {
|
||||
private suspend fun showPushNotification(
|
||||
pm: PushMessage,
|
||||
account: SavedAccount,
|
||||
notificationId:String,
|
||||
) {
|
||||
if (ncPushMessage.isDissabled(context)) {
|
||||
log.w("ncPushMessage isDissabled.")
|
||||
return
|
||||
|
@ -628,8 +637,26 @@ class PushRepo(
|
|||
val iconSmall = pm.loadSmallIcon(context)
|
||||
val iconBitmapLarge = context.loadIcon(pm.iconLarge, (48f * density + 0.5f).toInt())
|
||||
|
||||
val urlTap = "subwaytooter://pushMessage/${pm.id}"
|
||||
val iTap = context.intentNotificationDelete(urlTap.toUri())
|
||||
|
||||
val params = listOf(
|
||||
"db_id" to account.db_id.toString(),
|
||||
// URIをユニークにするため。参照されない
|
||||
"type" to "v2push", // "type" to trackingType.str,
|
||||
// URIをユニークにするため。参照されない
|
||||
"notificationId" to notificationId,
|
||||
).mapNotNull {
|
||||
when (val second = it.second) {
|
||||
null -> null
|
||||
else -> "${it.first.encodePercent()}=${second.encodePercent()}"
|
||||
}
|
||||
}.joinToString("&")
|
||||
|
||||
val iTap = Intent(context, ActCallback::class.java).apply {
|
||||
data = "subwaytooter://notification_click/?$params".toUri()
|
||||
// FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY を付与してはいけない
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
|
||||
val piTap = PendingIntent.getActivity(
|
||||
context,
|
||||
ncPushMessage.pircTap,
|
||||
|
@ -660,6 +687,9 @@ class PushRepo(
|
|||
setContentIntent(piTap)
|
||||
setDeleteIntent(piDelete)
|
||||
setAutoCancel(true)
|
||||
pm.textExpand.notEmpty()?.let {
|
||||
setStyle(NotificationCompat.BigTextStyle().bigText(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,4 +717,18 @@ class PushRepo(
|
|||
?: error("missing messageDbId in $uri")
|
||||
daoPushMessage.dismiss(messageDbId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知タップのインテントをメイン画面が受け取った
|
||||
*/
|
||||
|
||||
fun onTapNotification(account: SavedAccount) {
|
||||
EmptyScope.launch(AppDispatchers.IO) {
|
||||
try{
|
||||
daoPushMessage.dismissByAcct(account.acct)
|
||||
}catch(ex:Throwable){
|
||||
log.e(ex,"onTapNotification failed.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.database.Cursor
|
|||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.provider.BaseColumns
|
||||
import androidx.room.*
|
||||
import jp.juggler.subwaytooter.api.entity.Acct
|
||||
import jp.juggler.util.*
|
||||
import jp.juggler.util.data.*
|
||||
import jp.juggler.util.log.LogCategory
|
||||
|
@ -26,8 +27,10 @@ data class PushMessage(
|
|||
var notificationId: String? = null,
|
||||
// 通知の種別。小アイコン、アクセント色、Misskeyの文言に影響する
|
||||
var notificationType: String? = null,
|
||||
// 通知表示の本文。
|
||||
// 通知表示の本文
|
||||
var text: String? = null,
|
||||
// 展開表示した本文
|
||||
var textExpand: String? = null,
|
||||
// 小アイコンURL。昔のMastodonはバッジ画像が提供されていた。
|
||||
var iconSmall: String? = null,
|
||||
// 大アイコンURL。通知の原因となったユーザのアイコン画像。
|
||||
|
@ -51,6 +54,7 @@ data class PushMessage(
|
|||
private const val COL_NOTIFICATION_ID = "notification_id"
|
||||
private const val COL_NOTIFICATION_TYPE = "notification_type"
|
||||
private const val COL_TEXT = "text"
|
||||
private const val COL_TEXT_EXPAND = "text_expand"
|
||||
private const val COL_ICON_SMALL = "icon_small"
|
||||
private const val COL_ICON_LARGE = "icon_large"
|
||||
private const val COL_MESSAGE_JSON = "message_json"
|
||||
|
@ -61,17 +65,24 @@ data class PushMessage(
|
|||
deleteBeforeCreate = true
|
||||
column(0, COL_ID, MetaColumns.TS_INT_PRIMARY_KEY_NOT_NULL)
|
||||
column(0, COL_LOGIN_ACCT, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_TIMESTAMP, MetaColumns.TS_ZERO)
|
||||
column(0, COL_TIME_SAVE, MetaColumns.TS_ZERO)
|
||||
column(0, COL_TIME_DISMISS, MetaColumns.TS_ZERO)
|
||||
column(0, COL_TIMESTAMP, MetaColumns.TS_ZERO_NOT_NULL)
|
||||
column(0, COL_TIME_SAVE, MetaColumns.TS_ZERO_NOT_NULL)
|
||||
column(0, COL_TIME_DISMISS, MetaColumns.TS_ZERO_NOT_NULL)
|
||||
column(0, COL_NOTIFICATION_ID, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_NOTIFICATION_TYPE, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_TEXT, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_TEXT_EXPAND, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_ICON_SMALL, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_ICON_LARGE, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_MESSAGE_JSON, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_HEADER_JSON, MetaColumns.TS_TEXT_NULL)
|
||||
column(0, COL_RAW_BODY, MetaColumns.TS_BLOB_NULL)
|
||||
createExtra={
|
||||
arrayOf(
|
||||
"create index if not exists ${TABLE}_save on $TABLE($COL_TIME_SAVE)",
|
||||
"create index if not exists ${TABLE}_acct_dismiss on $TABLE($COL_LOGIN_ACCT,$COL_TIME_DISMISS)",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDBCreate(db: SQLiteDatabase) {
|
||||
|
@ -103,6 +114,7 @@ data class PushMessage(
|
|||
val idxNotificationId = cursor.getColumnIndex(COL_NOTIFICATION_ID)
|
||||
val idxNotificationType = cursor.getColumnIndex(COL_NOTIFICATION_TYPE)
|
||||
val idxText = cursor.getColumnIndex(COL_TEXT)
|
||||
val idxTextExpand = cursor.getColumnIndex(COL_TEXT_EXPAND)
|
||||
val idxIconSmall = cursor.getColumnIndex(COL_ICON_SMALL)
|
||||
val idxIconLarge = cursor.getColumnIndex(COL_ICON_LARGE)
|
||||
val idxMessageJson = cursor.getColumnIndex(COL_MESSAGE_JSON)
|
||||
|
@ -119,6 +131,7 @@ data class PushMessage(
|
|||
notificationId = cursor.getStringOrNull(idxNotificationId),
|
||||
notificationType = cursor.getStringOrNull(idxNotificationType),
|
||||
text = cursor.getStringOrNull(idxText),
|
||||
textExpand = cursor.getStringOrNull(idxTextExpand),
|
||||
iconSmall = cursor.getStringOrNull(idxIconSmall),
|
||||
iconLarge = cursor.getStringOrNull(idxIconLarge),
|
||||
messageJson = cursor.getStringOrNull(idxMessageJson)?.decodeJsonObject(),
|
||||
|
@ -148,6 +161,7 @@ data class PushMessage(
|
|||
put(COL_NOTIFICATION_ID, notificationId)
|
||||
put(COL_NOTIFICATION_TYPE, notificationType)
|
||||
put(COL_TEXT, text)
|
||||
put(COL_TEXT_EXPAND, textExpand)
|
||||
put(COL_ICON_SMALL, iconSmall)
|
||||
put(COL_ICON_LARGE, iconLarge)
|
||||
put(COL_MESSAGE_JSON, messageJson?.toString())
|
||||
|
@ -192,6 +206,13 @@ data class PushMessage(
|
|||
}
|
||||
}
|
||||
|
||||
fun dismissByAcct(acct: Acct) {
|
||||
db.execSQL(
|
||||
"update $table set $COL_TIME_DISMISS=? where $COL_LOGIN_ACCT=? and $COL_TIME_DISMISS=0",
|
||||
arrayOf(System.currentTimeMillis().toString(), acct.ascii),
|
||||
)
|
||||
}
|
||||
|
||||
fun deleteOld(now: Long) {
|
||||
try {
|
||||
val expire = now - TimeUnit.DAYS.toMillis(30)
|
||||
|
@ -202,7 +223,7 @@ data class PushMessage(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun listAll(): List<PushMessage> =
|
||||
fun listAll(): List<PushMessage> =
|
||||
db.queryAll(TABLE, "$COL_TIME_SAVE desc")
|
||||
?.use { ColIdx(it).readAll(it) }
|
||||
?: emptyList()
|
||||
|
|
Loading…
Reference in New Issue