Private
Public Access
1
0

Notifications: deep linking

This commit is contained in:
2024-03-29 01:04:09 -07:00
parent c2786d268f
commit 46c2fd6bf9
3 changed files with 42 additions and 11 deletions

View File

@@ -27,10 +27,14 @@
android:theme="@style/Theme.KordophoneDroid">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<!-- Message List Deep Link -->
<data android:scheme="kordophone" android:host="messages" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />

View File

@@ -17,14 +17,19 @@ import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.net.toUri
import androidx.navigation.NavDeepLinkBuilder
import androidx.navigation.NavDeepLinkRequest
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import net.buzzert.kordophone.backend.model.Message
import net.buzzert.kordophone.backend.server.ChatRepository
import net.buzzert.kordophonedroid.ui.Destination
import javax.inject.Inject
const val PUSH_CHANNEL_ID = "net.buzzert.kordophone.persistentNotification"
@@ -38,6 +43,7 @@ class UpdateMonitorService: Service()
@Inject lateinit var chatRepository: ChatRepository
private var newMessageID: Int = 0
private var watchJob: Job? = null
private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.IO + job)
@@ -53,7 +59,18 @@ class UpdateMonitorService: Service()
override fun onCreate() {
super.onCreate()
Log.v(UPDATER_LOG, "UpdateMonitor onCreate: Begin watching for updates.")
createNotificationChannel(NEW_MESSAGE_CHANNEL_ID, "New Messages")
// Connect to monitor
chatRepository.beginWatchingForUpdates(scope)
// Connect to new message flow for notifications
watchJob?.cancel()
watchJob = scope.launch {
chatRepository.newMessages.collectLatest(::onReceiveNewMessage)
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@@ -77,14 +94,6 @@ class UpdateMonitorService: Service()
startForeground(5738, notification)
// Connect to monitor
chatRepository.beginWatchingForUpdates(scope)
// Connect to new message flow for notifications
scope.launch {
chatRepository.newMessages.collectLatest(::onReceiveNewMessage)
}
// Restart if we get killed
return START_STICKY
}
@@ -98,25 +107,39 @@ class UpdateMonitorService: Service()
if (message.conversation.unreadCount == 0) {
// Not unread.
Log.v(UPDATER_LOG, "Ignoring read message.")
return
}
if (message.sender == null) {
// From me.
Log.v(UPDATER_LOG, "Ignoring message from me.")
return
}
if (message.conversation.isGroupChat) {
// For now, since these can be noisy and there's no UI for changing it, ignore group chats.
Log.v(UPDATER_LOG, "Ignoring group chat message.")
return
}
val guid = message.conversation.guid
val deepLinkIntent = Intent(
Intent.ACTION_VIEW,
"kordophone://messages/$guid".toUri(),
this,
MainActivity::class.java
)
val pendingIntent = PendingIntent.getActivity(this, 0, deepLinkIntent, PendingIntent.FLAG_IMMUTABLE)
val groupId = message.conversation.guid
val notification = NotificationCompat.Builder(this, NEW_MESSAGE_CHANNEL_ID)
.setContentTitle(message.sender)
.setContentText(message.text)
.setSmallIcon(R.drawable.stat_notify_chat)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setGroup(groupId)
.build()

View File

@@ -17,6 +17,7 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navDeepLink
import kotlinx.coroutines.flow.collectLatest
import net.buzzert.kordophone.backend.server.ChatRepository
@@ -77,11 +78,14 @@ fun KordophoneApp(
navController = navController,
startDestination = Destination.ConversationList.route,
) {
composable(route = Destination.ConversationList.route) {
composable(Destination.ConversationList.route) {
ConversationListScreen()
}
composable(Destination.MessageList.route) {
composable(
route = Destination.MessageList.route,
deepLinks = listOf(navDeepLink { uriPattern = "kordophone://messages/{id}" })
) {
val conversationID = it.arguments?.getString("id")!!
MessageListScreen(conversationGUID = conversationID)
}