diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 92213c5..f59fa92 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -27,10 +27,14 @@
android:theme="@style/Theme.KordophoneDroid">
-
+
+
+
+
+
diff --git a/app/src/main/java/net/buzzert/kordophonedroid/UpdateMonitorService.kt b/app/src/main/java/net/buzzert/kordophonedroid/UpdateMonitorService.kt
index 4d790db..32d32ab 100644
--- a/app/src/main/java/net/buzzert/kordophonedroid/UpdateMonitorService.kt
+++ b/app/src/main/java/net/buzzert/kordophonedroid/UpdateMonitorService.kt
@@ -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()
diff --git a/app/src/main/java/net/buzzert/kordophonedroid/ui/KordophoneApp.kt b/app/src/main/java/net/buzzert/kordophonedroid/ui/KordophoneApp.kt
index 35fc62d..48ff26b 100644
--- a/app/src/main/java/net/buzzert/kordophonedroid/ui/KordophoneApp.kt
+++ b/app/src/main/java/net/buzzert/kordophonedroid/ui/KordophoneApp.kt
@@ -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)
}