Refactor notifications (#4883)

Also fixes https://github.com/tuskyapp/Tusky/issues/4858.
But apart from that there should be no functional change.
This commit is contained in:
UlrichKu 2025-01-22 21:16:33 +01:00 committed by GitHub
commit 3a3e056572
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 1072 additions and 1217 deletions

View file

@ -20,9 +20,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import com.keylesspalace.tusky.components.systemnotifications.isUnifiedPushAvailable
import com.keylesspalace.tusky.components.systemnotifications.isUnifiedPushNotificationEnabledForAccount
import com.keylesspalace.tusky.components.systemnotifications.updateUnifiedPushSubscription
import com.keylesspalace.tusky.components.systemnotifications.NotificationService
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.di.ApplicationScope
import com.keylesspalace.tusky.network.MastodonApi
@ -39,13 +37,16 @@ class NotificationBlockStateBroadcastReceiver : BroadcastReceiver() {
@Inject
lateinit var accountManager: AccountManager
@Inject
lateinit var notificationService: NotificationService
@Inject
@ApplicationScope
lateinit var externalScope: CoroutineScope
override fun onReceive(context: Context, intent: Intent) {
if (Build.VERSION.SDK_INT < 28) return
if (!isUnifiedPushAvailable(context)) return
if (!notificationService.isUnifiedPushAvailable()) return
val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
@ -61,15 +62,9 @@ class NotificationBlockStateBroadcastReceiver : BroadcastReceiver() {
} ?: return
accountManager.getAccountByIdentifier(gid)?.let { account ->
if (isUnifiedPushNotificationEnabledForAccount(account)) {
// Update UnifiedPush notification subscription
if (account.isPushNotificationsEnabled()) {
externalScope.launch {
updateUnifiedPushSubscription(
context,
mastodonApi,
accountManager,
account
)
notificationService.updateUnifiedPushSubscription(account)
}
}
}

View file

@ -1,4 +1,4 @@
/* Copyright 2018 Jeremiasz Nelz <remi6397(a)gmail.com>
/* Copyright 2018 Tusky contributors
*
* This file is a part of Tusky.
*
@ -24,7 +24,7 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.RemoteInput
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.systemnotifications.NotificationHelper
import com.keylesspalace.tusky.components.systemnotifications.NotificationService
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.service.SendStatusService
@ -34,8 +34,6 @@ import com.keylesspalace.tusky.util.randomAlphanumericString
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
private const val TAG = "SendStatusBR"
@AndroidEntryPoint
class SendStatusBroadcastReceiver : BroadcastReceiver() {
@ -44,20 +42,20 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() {
@SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == NotificationHelper.REPLY_ACTION) {
val serverNotificationId = intent.getStringExtra(NotificationHelper.KEY_SERVER_NOTIFICATION_ID)
val senderId = intent.getLongExtra(NotificationHelper.KEY_SENDER_ACCOUNT_ID, -1)
if (intent.action == NotificationService.REPLY_ACTION) {
val serverNotificationId = intent.getStringExtra(NotificationService.KEY_SERVER_NOTIFICATION_ID)
val senderId = intent.getLongExtra(NotificationService.KEY_SENDER_ACCOUNT_ID, -1)
val senderIdentifier = intent.getStringExtra(
NotificationHelper.KEY_SENDER_ACCOUNT_IDENTIFIER
NotificationService.KEY_SENDER_ACCOUNT_IDENTIFIER
)
val senderFullName = intent.getStringExtra(
NotificationHelper.KEY_SENDER_ACCOUNT_FULL_NAME
NotificationService.KEY_SENDER_ACCOUNT_FULL_NAME
)
val citedStatusId = intent.getStringExtra(NotificationHelper.KEY_CITED_STATUS_ID)
val citedStatusId = intent.getStringExtra(NotificationService.KEY_CITED_STATUS_ID)
val visibility =
intent.getSerializableExtraCompat<Status.Visibility>(NotificationHelper.KEY_VISIBILITY)!!
val spoiler = intent.getStringExtra(NotificationHelper.KEY_SPOILER).orEmpty()
val mentions = intent.getStringArrayExtra(NotificationHelper.KEY_MENTIONS).orEmpty()
intent.getSerializableExtraCompat<Status.Visibility>(NotificationService.KEY_VISIBILITY)!!
val spoiler = intent.getStringExtra(NotificationService.KEY_SPOILER).orEmpty()
val mentions = intent.getStringArrayExtra(NotificationService.KEY_MENTIONS).orEmpty()
val account = accountManager.getAccountById(senderId)
@ -70,7 +68,7 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() {
val notification = NotificationCompat.Builder(
context,
NotificationHelper.CHANNEL_MENTION + senderIdentifier
NotificationService.CHANNEL_MENTION + senderIdentifier
)
.setSmallIcon(R.drawable.ic_notify)
.setColor(context.getColor(R.color.tusky_blue))
@ -115,7 +113,7 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() {
// Notifications with remote input active can't be cancelled, so let's replace it with another one that will dismiss automatically
val notification = NotificationCompat.Builder(
context,
NotificationHelper.CHANNEL_MENTION + senderIdentifier
NotificationService.CHANNEL_MENTION + senderIdentifier
)
.setSmallIcon(R.drawable.ic_notify)
.setColor(context.getColor(R.color.notification_color))
@ -138,6 +136,10 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() {
private fun getReplyMessage(intent: Intent): CharSequence {
val remoteInput = RemoteInput.getResultsFromIntent(intent)
return remoteInput?.getCharSequence(NotificationHelper.KEY_REPLY, "") ?: ""
return remoteInput?.getCharSequence(NotificationService.KEY_REPLY, "") ?: ""
}
companion object {
const val TAG = "SendStatusBroadcastReceiver"
}
}

View file

@ -19,8 +19,7 @@ import android.content.Context
import android.util.Log
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import com.keylesspalace.tusky.components.systemnotifications.registerUnifiedPushEndpoint
import com.keylesspalace.tusky.components.systemnotifications.unregisterUnifiedPushEndpoint
import com.keylesspalace.tusky.components.systemnotifications.NotificationService
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.di.ApplicationScope
import com.keylesspalace.tusky.network.MastodonApi
@ -33,16 +32,15 @@ import org.unifiedpush.android.connector.MessagingReceiver
@AndroidEntryPoint
class UnifiedPushBroadcastReceiver : MessagingReceiver() {
companion object {
const val TAG = "UnifiedPush"
}
@Inject
lateinit var accountManager: AccountManager
@Inject
lateinit var mastodonApi: MastodonApi
@Inject
lateinit var notificationService: NotificationService
@Inject
@ApplicationScope
lateinit var externalScope: CoroutineScope
@ -57,9 +55,7 @@ class UnifiedPushBroadcastReceiver : MessagingReceiver() {
override fun onNewEndpoint(context: Context, endpoint: String, instance: String) {
Log.d(TAG, "Endpoint available for account $instance: $endpoint")
accountManager.getAccountById(instance.toLong())?.let {
externalScope.launch {
registerUnifiedPushEndpoint(context, mastodonApi, accountManager, it, endpoint)
}
externalScope.launch { notificationService.registerUnifiedPushEndpoint(it, endpoint) }
}
}
@ -69,7 +65,11 @@ class UnifiedPushBroadcastReceiver : MessagingReceiver() {
Log.d(TAG, "Endpoint unregistered for account $instance")
accountManager.getAccountById(instance.toLong())?.let {
// It's fine if the account does not exist anymore -- that means it has been logged out
externalScope.launch { unregisterUnifiedPushEndpoint(mastodonApi, accountManager, it) }
externalScope.launch { notificationService.unregisterUnifiedPushEndpoint(it) }
}
}
companion object {
const val TAG = "UnifiedPush"
}
}