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"> android:theme="@style/Theme.KordophoneDroid">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<!-- Message List Deep Link -->
<data android:scheme="kordophone" android:host="messages" />
</intent-filter>
<meta-data <meta-data
android:name="android.app.lib_name" android:name="android.app.lib_name"
android:value="" /> android:value="" />

View File

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

View File

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