mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: Add separate notifications for waypoints (#4131)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
e5f78d101c
commit
c46fb23f00
12 changed files with 145 additions and 44 deletions
|
|
@ -477,7 +477,7 @@ constructor(
|
|||
dataPacket.alert ?: getString(Res.string.critical_alert),
|
||||
)
|
||||
} else if (updateNotification) {
|
||||
scope.handledLaunch { updateMessageNotification(contactKey, dataPacket) }
|
||||
scope.handledLaunch { updateNotification(contactKey, dataPacket) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -487,30 +487,37 @@ constructor(
|
|||
private fun getSenderName(packet: DataPacket): String =
|
||||
nodeManager.nodeDBbyID[packet.from]?.user?.longName ?: getString(Res.string.unknown_username)
|
||||
|
||||
private suspend fun updateMessageNotification(contactKey: String, dataPacket: DataPacket) {
|
||||
val message =
|
||||
when (dataPacket.dataType) {
|
||||
Portnums.PortNum.TEXT_MESSAGE_APP_VALUE -> dataPacket.text!!
|
||||
Portnums.PortNum.WAYPOINT_APP_VALUE ->
|
||||
getString(Res.string.waypoint_received, dataPacket.waypoint!!.name)
|
||||
|
||||
else -> return
|
||||
private suspend fun updateNotification(contactKey: String, dataPacket: DataPacket) {
|
||||
when (dataPacket.dataType) {
|
||||
Portnums.PortNum.TEXT_MESSAGE_APP_VALUE -> {
|
||||
val message = dataPacket.text!!
|
||||
val channelName =
|
||||
if (dataPacket.to == DataPacket.ID_BROADCAST) {
|
||||
radioConfigRepository.channelSetFlow.first().settingsList.getOrNull(dataPacket.channel)?.name
|
||||
} else {
|
||||
null
|
||||
}
|
||||
serviceNotifications.updateMessageNotification(
|
||||
contactKey,
|
||||
getSenderName(dataPacket),
|
||||
message,
|
||||
dataPacket.to == DataPacket.ID_BROADCAST,
|
||||
channelName,
|
||||
)
|
||||
}
|
||||
|
||||
val channelName =
|
||||
if (dataPacket.to == DataPacket.ID_BROADCAST) {
|
||||
radioConfigRepository.channelSetFlow.first().settingsList.getOrNull(dataPacket.channel)?.name
|
||||
} else {
|
||||
null
|
||||
Portnums.PortNum.WAYPOINT_APP_VALUE -> {
|
||||
val message = getString(Res.string.waypoint_received, dataPacket.waypoint!!.name)
|
||||
serviceNotifications.updateWaypointNotification(
|
||||
contactKey,
|
||||
getSenderName(dataPacket),
|
||||
message,
|
||||
dataPacket.waypoint!!.id,
|
||||
)
|
||||
}
|
||||
|
||||
serviceNotifications.updateMessageNotification(
|
||||
contactKey,
|
||||
getSenderName(dataPacket),
|
||||
message,
|
||||
dataPacket.to == DataPacket.ID_BROADCAST,
|
||||
channelName,
|
||||
)
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
|
||||
private fun rememberReaction(packet: MeshPacket) = scope.handledLaunch {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.geeksville.mesh.service
|
||||
|
||||
import android.app.Notification
|
||||
|
|
@ -55,6 +54,7 @@ import org.meshtastic.core.strings.meshtastic_low_battery_temporary_remote_notif
|
|||
import org.meshtastic.core.strings.meshtastic_messages_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_new_nodes_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_service_notifications
|
||||
import org.meshtastic.core.strings.meshtastic_waypoints_notifications
|
||||
import org.meshtastic.core.strings.new_node_seen
|
||||
import org.meshtastic.core.strings.no_local_stats
|
||||
import org.meshtastic.core.strings.reply
|
||||
|
|
@ -111,6 +111,13 @@ class MeshServiceNotificationsImpl @Inject constructor(@ApplicationContext priva
|
|||
NotificationManager.IMPORTANCE_DEFAULT,
|
||||
)
|
||||
|
||||
object Waypoint :
|
||||
NotificationType(
|
||||
"my_waypoints",
|
||||
Res.string.meshtastic_waypoints_notifications,
|
||||
NotificationManager.IMPORTANCE_DEFAULT,
|
||||
)
|
||||
|
||||
object Alert :
|
||||
NotificationType(
|
||||
"my_alerts",
|
||||
|
|
@ -152,6 +159,7 @@ class MeshServiceNotificationsImpl @Inject constructor(@ApplicationContext priva
|
|||
ServiceState,
|
||||
DirectMessage,
|
||||
BroadcastMessage,
|
||||
Waypoint,
|
||||
Alert,
|
||||
NewNode,
|
||||
LowBatteryLocal,
|
||||
|
|
@ -190,6 +198,7 @@ class MeshServiceNotificationsImpl @Inject constructor(@ApplicationContext priva
|
|||
|
||||
NotificationType.DirectMessage,
|
||||
NotificationType.BroadcastMessage,
|
||||
NotificationType.Waypoint,
|
||||
NotificationType.NewNode,
|
||||
NotificationType.LowBatteryLocal,
|
||||
NotificationType.LowBatteryRemote,
|
||||
|
|
@ -283,6 +292,11 @@ class MeshServiceNotificationsImpl @Inject constructor(@ApplicationContext priva
|
|||
notificationManager.notify(contactKey.hashCode(), notification)
|
||||
}
|
||||
|
||||
override fun updateWaypointNotification(contactKey: String, name: String, message: String, waypointId: Int) {
|
||||
val notification = createWaypointNotification(name, message, waypointId)
|
||||
notificationManager.notify(contactKey.hashCode(), notification)
|
||||
}
|
||||
|
||||
override fun showAlertNotification(contactKey: String, name: String, alert: String) {
|
||||
val notification = createAlertNotification(contactKey, name, alert)
|
||||
// Use a consistent, unique ID for each alert source.
|
||||
|
|
@ -373,6 +387,20 @@ class MeshServiceNotificationsImpl @Inject constructor(@ApplicationContext priva
|
|||
return builder.build()
|
||||
}
|
||||
|
||||
private fun createWaypointNotification(name: String, message: String, waypointId: Int): Notification {
|
||||
val person = Person.Builder().setName(name).build()
|
||||
val style = NotificationCompat.MessagingStyle(person).addMessage(message, System.currentTimeMillis(), person)
|
||||
|
||||
return commonBuilder(NotificationType.Waypoint, createOpenWaypointIntent(waypointId))
|
||||
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||
.setAutoCancel(true)
|
||||
.setStyle(style)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setShowWhen(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createAlertNotification(contactKey: String, name: String, alert: String): Notification {
|
||||
val person = Person.Builder().setName(name).build()
|
||||
val style = NotificationCompat.MessagingStyle(person).addMessage(alert, System.currentTimeMillis(), person)
|
||||
|
|
@ -454,6 +482,19 @@ class MeshServiceNotificationsImpl @Inject constructor(@ApplicationContext priva
|
|||
}
|
||||
}
|
||||
|
||||
private fun createOpenWaypointIntent(waypointId: Int): PendingIntent {
|
||||
val deepLinkUri = "$DEEP_LINK_BASE_URI/map?waypointId=$waypointId".toUri()
|
||||
val deepLinkIntent =
|
||||
Intent(Intent.ACTION_VIEW, deepLinkUri, context, MainActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
}
|
||||
|
||||
return TaskStackBuilder.create(context).run {
|
||||
addNextIntentWithParentStack(deepLinkIntent)
|
||||
getPendingIntent(waypointId, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createReplyAction(contactKey: String): NotificationCompat.Action {
|
||||
val replyLabel = getString(Res.string.reply)
|
||||
val remoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@file:Suppress("MatchingDeclarationName")
|
||||
|
||||
package com.geeksville.mesh.ui
|
||||
|
|
@ -161,7 +160,7 @@ import org.meshtastic.proto.MeshProtos
|
|||
enum class TopLevelDestination(val label: StringResource, val icon: ImageVector, val route: Route) {
|
||||
Conversations(Res.string.conversations, MeshtasticIcons.Conversations, ContactsRoutes.ContactsGraph),
|
||||
Nodes(Res.string.nodes, MeshtasticIcons.Nodes, NodesRoutes.NodesGraph),
|
||||
Map(Res.string.map, MeshtasticIcons.Map, MapRoutes.Map),
|
||||
Map(Res.string.map, MeshtasticIcons.Map, MapRoutes.Map()),
|
||||
Settings(Res.string.bottom_nav_settings, MeshtasticIcons.Settings, SettingsRoutes.SettingsGraph()),
|
||||
Connections(Res.string.connections, Icons.Rounded.Wifi, ConnectionsRoutes.ConnectionsGraph),
|
||||
;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue