Reworked how Persons are used + fixed timestamp issue in chat message notification + fixed chat room being marked as read when answering in the notification

This commit is contained in:
Sylvain Berfini 2023-01-12 16:53:52 +01:00
parent 8a09115623
commit 01c8735caf
3 changed files with 65 additions and 65 deletions

View file

@ -26,6 +26,7 @@ import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.net.Uri
import android.provider.ContactsContract
@ -41,6 +42,7 @@ import org.linphone.R
import org.linphone.core.*
import org.linphone.core.tools.Log
import org.linphone.utils.ImageUtils
import org.linphone.utils.LinphoneUtils
import org.linphone.utils.PermissionHelper
interface ContactsUpdatedListener {
@ -70,6 +72,7 @@ class ContactsManager(private val context: Context) {
val contactAvatar: IconCompat
val groupAvatar: IconCompat
val groupBitmap: Bitmap
private val localFriends = arrayListOf<Friend>()
@ -93,6 +96,7 @@ class ContactsManager(private val context: Context) {
contactAvatar = IconCompat.createWithResource(context, R.drawable.voip_single_contact_avatar_alt)
groupAvatar = IconCompat.createWithResource(context, R.drawable.voip_multiple_contacts_avatar_alt)
groupBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.voip_multiple_contacts_avatar_alt)
val core = coreContext.core
for (list in core.friendsLists) {
@ -120,7 +124,7 @@ class ContactsManager(private val context: Context) {
for (account in coreContext.core.accountList) {
val friend = coreContext.core.createFriend()
friend.name = account.params.identityAddress?.displayName ?: account.params.identityAddress?.username
friend.name = LinphoneUtils.getDisplayName(account.params.identityAddress)
val address = account.params.identityAddress ?: continue
friend.address = address
@ -137,6 +141,17 @@ class ContactsManager(private val context: Context) {
}
}
@Synchronized
fun getMePerson(localAddress: Address): Person {
val friend = localFriends.find { localFriend ->
localFriend.addresses.find { address ->
address.weakEqual(localAddress)
} != null
}
return friend?.getPerson()
?: Person.Builder().setName(LinphoneUtils.getDisplayName(localAddress)).build()
}
@Synchronized
fun getAndroidContactIdFromUri(uri: Uri): String? {
val projection = arrayOf(ContactsContract.Data.CONTACT_ID)
@ -381,14 +396,13 @@ fun Friend.getPerson(): Person {
coreContext.context,
getThumbnailUri()
)
val icon =
personBuilder.setIcon(
if (bm == null) {
coreContext.contactsManager.contactAvatar
} else IconCompat.createWithAdaptiveBitmap(bm)
if (icon != null) {
personBuilder.setIcon(icon)
}
)
personBuilder.setKey(refKey)
personBuilder.setUri(nativeUri)
personBuilder.setImportant(starred)
return personBuilder.build()

View file

@ -76,7 +76,6 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
return
}
room.markAsRead()
if (intent.action == NotificationsManager.INTENT_REPLY_NOTIF_ACTION) {
val reply = getMessageText(intent)?.toString()
if (reply == null) {
@ -90,6 +89,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
msg.send()
Log.i("[Notification Broadcast Receiver] Reply sent for notif id $notificationId")
} else {
room.markAsRead()
if (!coreContext.notificationsManager.dismissChatNotification(room)) {
Log.w("[Notification Broadcast Receiver] Notifications Manager failed to cancel notification")
val notificationManager = context.getSystemService(NotificationManager::class.java)

View file

@ -480,19 +480,18 @@ class NotificationsManager(private val context: Context) {
}
fun getPerson(friend: Friend?, displayName: String, picture: Bitmap?): Person {
return if (friend != null) {
friend.getPerson()
} else {
val builder = Person.Builder().setName(displayName)
val userIcon =
if (picture != null) {
IconCompat.createWithAdaptiveBitmap(picture)
} else {
coreContext.contactsManager.contactAvatar
}
if (userIcon != null) builder.setIcon(userIcon)
builder.build()
}
return friend?.getPerson()
?: Person.Builder()
.setName(displayName)
.setIcon(
if (picture != null) {
IconCompat.createWithAdaptiveBitmap(picture)
} else {
coreContext.contactsManager.contactAvatar
}
)
.setKey(displayName)
.build()
}
fun displayIncomingCallNotification(call: Call, useAsForeground: Boolean) {
@ -665,41 +664,18 @@ class NotificationsManager(private val context: Context) {
)
val id = LinphoneUtils.getChatRoomId(room.localAddress, room.peerAddress)
val notification = createMessageNotification(notifiable, pendingIntent, bubbleIntent, id)
val me = coreContext.contactsManager.getMePerson(room.localAddress)
val notification = createMessageNotification(notifiable, pendingIntent, bubbleIntent, id, me)
notify(notifiable.notificationId, notification, CHAT_TAG)
}
private fun createChatNotifiable(room: ChatRoom, message: ChatMessage): Notifiable {
val notifiable = getNotifiableForRoom(room)
if (notifiable.messages.isNotEmpty() || room.unreadMessagesCount == 1) {
val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress)
val notifiableMessage = getNotifiableMessage(message, friend)
notifiable.messages.add(notifiableMessage)
} else {
for (chatMessage in room.unreadHistory) {
val friend = coreContext.contactsManager.findContactByAddress(chatMessage.fromAddress)
val notifiableMessage = getNotifiableMessage(chatMessage, friend)
notifiable.messages.add(notifiableMessage)
}
}
if (room.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
notifiable.isGroup = false
} else {
notifiable.isGroup = true
notifiable.groupTitle = room.subject
}
return notifiable
}
private fun createChatNotifiable(room: ChatRoom, messages: Array<out ChatMessage>): Notifiable {
val notifiable = getNotifiableForRoom(room)
for (message in messages) {
if (message.isRead || message.isOutgoing) continue
val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress)
val notifiableMessage = getNotifiableMessage(message, friend)
val notifiableMessage = getNotifiableMessage(message, friend, notifiable)
notifiable.messages.add(notifiableMessage)
}
@ -727,7 +703,7 @@ class NotificationsManager(private val context: Context) {
return notifiable
}
private fun getNotifiableMessage(message: ChatMessage, friend: Friend?): NotifiableMessage {
private fun getNotifiableMessage(message: ChatMessage, friend: Friend?, notifiable: Notifiable): NotifiableMessage {
val roundPicture = ImageUtils.getRoundBitmapFromUri(context, friend?.getThumbnailUri())
val displayName = friend?.name ?: LinphoneUtils.getDisplayName(message.fromAddress)
var text = ""
@ -752,7 +728,7 @@ class NotificationsManager(private val context: Context) {
text,
friend,
displayName,
message.time,
message.time * 1000, /* Linphone timestamps are in seconds */
senderAvatar = roundPicture,
isOutgoing = message.isOutgoing
)
@ -784,10 +760,11 @@ class NotificationsManager(private val context: Context) {
Log.i("[Notifications Manager] Updating message notification with reply for notification ${notifiable.notificationId}")
val text = message.contents.find { content -> content.isText }?.utf8Text ?: ""
val senderAddress = message.fromAddress
val reply = NotifiableMessage(
text,
null,
notifiable.myself ?: LinphoneUtils.getDisplayName(message.fromAddress),
notifiable.myself ?: LinphoneUtils.getDisplayName(senderAddress),
System.currentTimeMillis(),
isOutgoing = true
)
@ -836,38 +813,43 @@ class NotificationsManager(private val context: Context) {
notifiable: Notifiable,
pendingIntent: PendingIntent,
bubbleIntent: PendingIntent,
id: String
id: String,
me: Person
): Notification {
val me = Person.Builder().setName(notifiable.myself).build()
val style = NotificationCompat.MessagingStyle(me)
val largeIcon: Bitmap? = notifiable.messages.lastOrNull()?.senderAvatar
val allPersons = arrayListOf<Person>()
var lastPersonAvatar: Bitmap? = null
var lastPerson: Person? = null
for (message in notifiable.messages) {
val friend = message.friend
val person = getPerson(friend, message.sender, message.senderAvatar)
val person = if (message.isOutgoing)
me
else
getPerson(friend, message.sender, message.senderAvatar)
// We don't want to see our own avatar
if (!message.isOutgoing) {
// We don't want to see our own avatar
lastPerson = person
lastPersonAvatar = message.senderAvatar
if (allPersons.find { it.key == person.key } == null) {
allPersons.add(person)
}
}
val msg = if (!corePreferences.hideChatMessageContentInNotification) {
NotificationCompat.MessagingStyle.Message(message.message, message.time, person)
} else {
val msg = if (corePreferences.hideChatMessageContentInNotification) {
NotificationCompat.MessagingStyle.Message(AppUtils.getString(R.string.chat_message_notification_hidden_content), message.time, person)
}
if (message.filePath != null && !corePreferences.hideChatMessageContentInNotification) {
msg.setData(message.fileMime, message.filePath)
} else {
val tmp = NotificationCompat.MessagingStyle.Message(message.message, message.time, person)
if (message.filePath != null) tmp.setData(message.fileMime, message.filePath)
tmp
}
style.addMessage(msg)
}
if (notifiable.isGroup) {
style.conversationTitle = notifiable.groupTitle
}
style.conversationTitle = if (notifiable.isGroup) notifiable.groupTitle else lastPerson?.name
style.isGroupConversation = notifiable.isGroup
val icon = lastPerson?.icon ?: coreContext.contactsManager.contactAvatar
@ -875,11 +857,12 @@ class NotificationsManager(private val context: Context) {
.setDesiredHeightResId(R.dimen.chat_message_bubble_desired_height)
.build()
val largeIcon = if (notifiable.isGroup) coreContext.contactsManager.groupBitmap else lastPersonAvatar
val notificationBuilder = NotificationCompat.Builder(context, context.getString(R.string.notification_channel_chat_id))
.addPerson(lastPerson)
.setSmallIcon(R.drawable.topbar_chat_notification)
.setAutoCancel(true)
.setLargeIcon(largeIcon)
.setColor(ContextCompat.getColor(context, R.color.primary_color))
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setGroup(CHAT_NOTIFICATIONS_GROUP)
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
@ -887,12 +870,15 @@ class NotificationsManager(private val context: Context) {
.setWhen(System.currentTimeMillis())
.setShowWhen(true)
.setStyle(style)
.setColor(ContextCompat.getColor(context, R.color.primary_color))
.addAction(getReplyMessageAction(notifiable))
.addAction(getMarkMessageAsReadAction(notifiable))
.setShortcutId(id)
.setLocusId(LocusIdCompat(id))
for (person in allPersons) {
notificationBuilder.addPerson(person)
}
if (!corePreferences.preventInterfaceFromShowingUp) {
notificationBuilder.setContentIntent(pendingIntent)
}