feat(#116): add direct reply action to background notifications
This commit is contained in:
@@ -29,6 +29,10 @@
|
|||||||
android:name=".notification.ChatNotificationService"
|
android:name=".notification.ChatNotificationService"
|
||||||
android:foregroundServiceType="dataSync"
|
android:foregroundServiceType="dataSync"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
<receiver
|
||||||
|
android:name=".notification.NotificationReplyReceiver"
|
||||||
|
android:exported="false" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import android.content.Intent
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.RemoteInput
|
||||||
import com.m57.hermescontrol.MainActivity
|
import com.m57.hermescontrol.MainActivity
|
||||||
import com.m57.hermescontrol.R
|
import com.m57.hermescontrol.R
|
||||||
import com.m57.hermescontrol.data.local.AuthManager
|
import com.m57.hermescontrol.data.local.AuthManager
|
||||||
@@ -41,10 +42,10 @@ import kotlinx.coroutines.launch
|
|||||||
*/
|
*/
|
||||||
class ChatNotificationService : Service() {
|
class ChatNotificationService : Service() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val SERVICE_CHANNEL_ID = "hermes_service"
|
internal const val SERVICE_CHANNEL_ID = "hermes_service"
|
||||||
private const val CHAT_CHANNEL_ID = "hermes_chat"
|
internal const val CHAT_CHANNEL_ID = "hermes_chat"
|
||||||
private const val NOTIFICATION_ID = 1
|
internal const val NOTIFICATION_ID = 1
|
||||||
private const val PENDING_NOTIFICATION_ID = 2
|
internal const val PENDING_NOTIFICATION_ID = 2
|
||||||
|
|
||||||
private var isAppInForeground = false
|
private var isAppInForeground = false
|
||||||
|
|
||||||
@@ -75,11 +76,11 @@ class ChatNotificationService : Service() {
|
|||||||
.take(100)
|
.take(100)
|
||||||
.replace("\n", " ")
|
.replace("\n", " ")
|
||||||
.ifBlank { "New message" }
|
.ifBlank { "New message" }
|
||||||
showReplyNotification(preview)
|
showReplyNotification(preview, event.sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
is WsEvent.ClarifyRequest -> {
|
is WsEvent.ClarifyRequest -> {
|
||||||
showReplyNotification("Hermes needs a clarification")
|
showReplyNotification("Hermes needs a clarification", null)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
@@ -89,8 +90,11 @@ class ChatNotificationService : Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showReplyNotification(text: String) {
|
private fun showReplyNotification(
|
||||||
val notification =
|
text: String,
|
||||||
|
sessionId: String?,
|
||||||
|
) {
|
||||||
|
val builder =
|
||||||
NotificationCompat
|
NotificationCompat
|
||||||
.Builder(this, CHAT_CHANNEL_ID)
|
.Builder(this, CHAT_CHANNEL_ID)
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
@@ -100,10 +104,42 @@ class ChatNotificationService : Service() {
|
|||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(buildContentIntent())
|
.setContentIntent(buildContentIntent())
|
||||||
.build()
|
|
||||||
|
if (!sessionId.isNullOrBlank()) {
|
||||||
|
val replyLabel = "Type your reply..."
|
||||||
|
val remoteInput =
|
||||||
|
RemoteInput
|
||||||
|
.Builder(NotificationReplyReceiver.KEY_TEXT_REPLY)
|
||||||
|
.setLabel(replyLabel)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val replyIntent =
|
||||||
|
Intent(this, NotificationReplyReceiver::class.java).apply {
|
||||||
|
putExtra(NotificationReplyReceiver.EXTRA_SESSION_ID, sessionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
val replyPendingIntent =
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
this,
|
||||||
|
sessionId.hashCode(),
|
||||||
|
replyIntent,
|
||||||
|
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
|
||||||
|
)
|
||||||
|
|
||||||
|
val action =
|
||||||
|
NotificationCompat.Action
|
||||||
|
.Builder(
|
||||||
|
R.drawable.ic_notification,
|
||||||
|
"Reply",
|
||||||
|
replyPendingIntent,
|
||||||
|
).addRemoteInput(remoteInput)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
builder.addAction(action)
|
||||||
|
}
|
||||||
|
|
||||||
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
manager.notify(PENDING_NOTIFICATION_ID, notification)
|
manager.notify(PENDING_NOTIFICATION_ID, builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildContentIntent(): PendingIntent =
|
private fun buildContentIntent(): PendingIntent =
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.m57.hermescontrol.notification
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.RemoteInput
|
||||||
|
import com.m57.hermescontrol.R
|
||||||
|
import com.m57.hermescontrol.data.ws.HermesWsClient
|
||||||
|
|
||||||
|
class NotificationReplyReceiver : BroadcastReceiver() {
|
||||||
|
companion object {
|
||||||
|
const val KEY_TEXT_REPLY = "key_text_reply"
|
||||||
|
const val EXTRA_SESSION_ID = "extra_session_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceive(
|
||||||
|
context: Context,
|
||||||
|
intent: Intent,
|
||||||
|
) {
|
||||||
|
val remoteInput = RemoteInput.getResultsFromIntent(intent)
|
||||||
|
val replyText = remoteInput?.getCharSequence(KEY_TEXT_REPLY)?.toString()
|
||||||
|
val sessionId = intent.getStringExtra(EXTRA_SESSION_ID)
|
||||||
|
|
||||||
|
if (!replyText.isNullOrBlank() && !sessionId.isNullOrBlank()) {
|
||||||
|
HermesWsClient.sendMessage(sessionId, replyText)
|
||||||
|
|
||||||
|
val repliedNotification =
|
||||||
|
NotificationCompat
|
||||||
|
.Builder(context, ChatNotificationService.CHAT_CHANNEL_ID)
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setContentTitle("Hermes")
|
||||||
|
.setContentText("Replied")
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
manager.notify(ChatNotificationService.PENDING_NOTIFICATION_ID, repliedNotification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user