Notifications: deep linking
This commit is contained in:
@@ -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="" />
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user