mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-03-30 16:25:57 +00:00
android: Two more notifications when contact connected or connection request received (#1129)
* Two more notifications when contact connected or connection request received * Large image in notification * Do not show contact's icon when it't not permitted * Sound and vibrate for notification * No large icon in other cases * Small change
This commit is contained in:
committed by
GitHub
parent
6c7e81777e
commit
409982ad71
@@ -103,6 +103,12 @@
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<!-- NtfManager action processing (buttons in notifications) -->
|
||||
<receiver
|
||||
android:name=".model.NtfManager$NtfActionReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
|
||||
<!-- SimplexService foreground service -->
|
||||
<service
|
||||
android:name=".SimplexService"
|
||||
|
||||
@@ -10,8 +10,8 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import chat.simplex.app.*
|
||||
import chat.simplex.app.views.call.*
|
||||
import chat.simplex.app.views.helpers.base64ToBitmap
|
||||
import chat.simplex.app.views.helpers.generalGetString
|
||||
import chat.simplex.app.views.chatlist.acceptContactRequest
|
||||
import chat.simplex.app.views.helpers.*
|
||||
import chat.simplex.app.views.usersettings.NotificationPreviewMode
|
||||
import kotlinx.datetime.Clock
|
||||
|
||||
@@ -27,6 +27,8 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
const val LockScreenCallChannel: String = "chat.simplex.app.LOCK_SCREEN_CALL_NOTIFICATION"
|
||||
const val AcceptCallAction: String = "chat.simplex.app.ACCEPT_CALL"
|
||||
const val CallNotificationId: Int = -1
|
||||
|
||||
private const val ChatIdKey: String = "chatId"
|
||||
}
|
||||
|
||||
private val manager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
@@ -39,6 +41,10 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
manager.createNotificationChannel(callNotificationChannel())
|
||||
}
|
||||
|
||||
enum class NotificationAction {
|
||||
ACCEPT_CONTACT_REQUEST
|
||||
}
|
||||
|
||||
private fun callNotificationChannel(): NotificationChannel {
|
||||
val callChannel = NotificationChannel(CallChannel, generalGetString(R.string.ntf_channel_calls), NotificationManager.IMPORTANCE_HIGH)
|
||||
val attrs = AudioAttributes.Builder()
|
||||
@@ -64,13 +70,31 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyContactRequestReceived(cInfo: ChatInfo.ContactRequest) {
|
||||
notifyMessageReceived(
|
||||
chatId = cInfo.id,
|
||||
displayName = cInfo.displayName,
|
||||
msgText = generalGetString(R.string.notification_new_contact_request),
|
||||
image = cInfo.image,
|
||||
listOf(NotificationAction.ACCEPT_CONTACT_REQUEST)
|
||||
)
|
||||
}
|
||||
|
||||
fun notifyContactConnected(contact: Contact) {
|
||||
notifyMessageReceived(
|
||||
chatId = contact.id,
|
||||
displayName = contact.displayName,
|
||||
msgText = generalGetString(R.string.notification_contact_connected)
|
||||
)
|
||||
}
|
||||
|
||||
fun notifyMessageReceived(cInfo: ChatInfo, cItem: ChatItem) {
|
||||
if (!cInfo.ntfsEnabled) return
|
||||
|
||||
notifyMessageReceived(chatId = cInfo.id, displayName = cInfo.displayName, msgText = hideSecrets(cItem))
|
||||
}
|
||||
|
||||
fun notifyMessageReceived(chatId: String, displayName: String, msgText: String) {
|
||||
fun notifyMessageReceived(chatId: String, displayName: String, msgText: String, image: String? = null, actions: List<NotificationAction> = emptyList()) {
|
||||
Log.d(TAG, "notifyMessageReceived $chatId")
|
||||
val now = Clock.System.now().toEpochMilliseconds()
|
||||
val recentNotification = (now - prevNtfTime.getOrDefault(chatId, 0) < msgNtfTimeoutMs)
|
||||
@@ -79,18 +103,36 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
val previewMode = appPreferences.notificationPreviewMode.get()
|
||||
val title = if (previewMode == NotificationPreviewMode.HIDDEN.name) generalGetString(R.string.notification_preview_somebody) else displayName
|
||||
val content = if (previewMode != NotificationPreviewMode.MESSAGE.name) generalGetString(R.string.notification_preview_new_message) else msgText
|
||||
val notification = NotificationCompat.Builder(context, MessageChannel)
|
||||
val largeIcon = when {
|
||||
actions.isEmpty() -> null
|
||||
image == null || previewMode == NotificationPreviewMode.HIDDEN.name -> BitmapFactory.decodeResource(context.resources, R.drawable.icon)
|
||||
else -> base64ToBitmap(image)
|
||||
}
|
||||
val builder = NotificationCompat.Builder(context, MessageChannel)
|
||||
.setContentTitle(title)
|
||||
.setContentText(content)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setGroup(MessageGroup)
|
||||
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN)
|
||||
.setSmallIcon(R.drawable.ntf_icon)
|
||||
.setLargeIcon(largeIcon)
|
||||
.setColor(0x88FFFF)
|
||||
.setAutoCancel(true)
|
||||
.setVibrate(if (actions.isEmpty()) null else longArrayOf(0, 250, 250, 250))
|
||||
.setContentIntent(chatPendingIntent(OpenChatAction, chatId))
|
||||
.setSilent(recentNotification)
|
||||
.build()
|
||||
.setSilent(if (actions.isEmpty()) recentNotification else false)
|
||||
|
||||
for (action in actions) {
|
||||
val flags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
val actionIntent = Intent(SimplexApp.context, NtfActionReceiver::class.java)
|
||||
actionIntent.action = action.name
|
||||
actionIntent.putExtra(ChatIdKey, chatId)
|
||||
val actionPendingIntent: PendingIntent = PendingIntent.getBroadcast(SimplexApp.context, 0, actionIntent, flags)
|
||||
val actionButton = when (action) {
|
||||
NotificationAction.ACCEPT_CONTACT_REQUEST -> generalGetString(R.string.accept)
|
||||
}
|
||||
builder.addAction(0, actionButton, actionPendingIntent)
|
||||
}
|
||||
|
||||
val summary = NotificationCompat.Builder(context, MessageChannel)
|
||||
.setSmallIcon(R.drawable.ntf_icon)
|
||||
@@ -103,7 +145,7 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
|
||||
with(NotificationManagerCompat.from(context)) {
|
||||
// using cInfo.id only shows one notification per chat and updates it when the message arrives
|
||||
notify(chatId.hashCode(), notification)
|
||||
notify(chatId.hashCode(), builder.build())
|
||||
notify(0, summary)
|
||||
}
|
||||
}
|
||||
@@ -141,6 +183,10 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
generalGetString(R.string.notification_preview_somebody)
|
||||
else
|
||||
invitation.contact.displayName
|
||||
val largeIcon = if (image == null || previewMode == NotificationPreviewMode.HIDDEN.name)
|
||||
BitmapFactory.decodeResource(context.resources, R.drawable.icon)
|
||||
else
|
||||
base64ToBitmap(image)
|
||||
|
||||
ntfBuilder = ntfBuilder
|
||||
.setContentTitle(title)
|
||||
@@ -148,7 +194,7 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||
.setSmallIcon(R.drawable.ntf_icon)
|
||||
.setLargeIcon(if (image == null) BitmapFactory.decodeResource(context.resources, R.drawable.icon) else base64ToBitmap(image))
|
||||
.setLargeIcon(largeIcon)
|
||||
.setColor(0x88FFFF)
|
||||
.setAutoCancel(true)
|
||||
with(NotificationManagerCompat.from(context)) {
|
||||
@@ -183,10 +229,31 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
||||
var intent = Intent(context, MainActivity::class.java)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
.setAction(intentAction)
|
||||
if (chatId != null) intent = intent.putExtra("chatId", chatId)
|
||||
if (chatId != null) intent = intent.putExtra(ChatIdKey, chatId)
|
||||
return TaskStackBuilder.create(context).run {
|
||||
addNextIntentWithParentStack(intent)
|
||||
getPendingIntent(uniqueInt, PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes every action specified by [NotificationCompat.Builder.addAction] that comes with [NotificationAction]
|
||||
* and [ChatInfo.id] as [ChatIdKey] in extra
|
||||
* */
|
||||
class NtfActionReceiver: BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
val chatId = intent?.getStringExtra(ChatIdKey) ?: return
|
||||
val cInfo = SimplexApp.context.chatModel.getChat(chatId)?.chatInfo
|
||||
when (intent.action) {
|
||||
NotificationAction.ACCEPT_CONTACT_REQUEST.name -> {
|
||||
if (cInfo !is ChatInfo.ContactRequest) return
|
||||
acceptContactRequest(cInfo, SimplexApp.context.chatModel)
|
||||
SimplexApp.context.chatModel.controller.ntfManager.cancelNotificationsForChat(chatId)
|
||||
}
|
||||
else -> {
|
||||
Log.e(TAG, "Unknown action. Make sure you provide action from NotificationAction enum")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.app.ActivityManager.RunningAppProcessInfo
|
||||
import android.app.Application
|
||||
import android.content.*
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.PowerManager
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
@@ -849,7 +848,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
|
||||
chatModel.updateContact(r.contact)
|
||||
chatModel.removeChat(r.contact.activeConn.id)
|
||||
chatModel.updateNetworkStatus(r.contact.id, Chat.NetworkStatus.Connected())
|
||||
// NtfManager.shared.notifyContactConnected(contact)
|
||||
ntfManager.notifyContactConnected(r.contact)
|
||||
}
|
||||
is CR.ContactConnecting -> {
|
||||
chatModel.updateContact(r.contact)
|
||||
@@ -859,7 +858,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
|
||||
val contactRequest = r.contactRequest
|
||||
val cInfo = ChatInfo.ContactRequest(contactRequest)
|
||||
chatModel.addChat(Chat(chatInfo = cInfo, chatItems = listOf()))
|
||||
// NtfManager.shared.notifyContactRequest(contactRequest)
|
||||
ntfManager.notifyContactRequestReceived(cInfo)
|
||||
}
|
||||
is CR.ContactUpdated -> {
|
||||
val cInfo = ChatInfo.Direct(r.toContact)
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
<string name="notification_display_mode_hidden_desc">Kontakt und Nachricht verbergen</string>
|
||||
<string name="notification_preview_somebody">Kontakt verbergen:</string>
|
||||
<string name="notification_preview_new_message">neue Nachricht</string>
|
||||
<string name="notification_new_contact_request">New contact request</string>
|
||||
<string name="notification_contact_connected">Сonnected</string>
|
||||
|
||||
<!-- local authentication notice - SimpleXAPI.kt -->
|
||||
<string name="la_notice_title_simplex_lock">SimpleX Sperre</string>
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
<string name="notification_display_mode_hidden_desc">Скрывать контакт и сообщение</string>
|
||||
<string name="notification_preview_somebody">Контакт скрыт:</string>
|
||||
<string name="notification_preview_new_message">новое сообщение</string>
|
||||
<string name="notification_new_contact_request">Новый запрос на соединение</string>
|
||||
<string name="notification_contact_connected">Соединен(а)</string>
|
||||
|
||||
<!-- local authentication notice - SimpleXAPI.kt -->
|
||||
<string name="la_notice_title_simplex_lock">Блокировка SimpleX</string>
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
<string name="notification_display_mode_hidden_desc">Hide contact and message</string>
|
||||
<string name="notification_preview_somebody">Contact hidden:</string>
|
||||
<string name="notification_preview_new_message">new message</string>
|
||||
<string name="notification_new_contact_request">New contact request</string>
|
||||
<string name="notification_contact_connected">Connected</string>
|
||||
|
||||
<!-- local authentication notice - SimpleXAPI.kt -->
|
||||
<string name="la_notice_title_simplex_lock">SimpleX Lock</string>
|
||||
|
||||
Reference in New Issue
Block a user