Changes related to chat messages aggregation in SDK
This commit is contained in:
parent
7c267dad25
commit
5642d4c8c3
9 changed files with 118 additions and 76 deletions
|
@ -16,6 +16,8 @@ auto_answer_replacing_calls=1
|
||||||
ping_with_options=0
|
ping_with_options=0
|
||||||
use_cpim=1
|
use_cpim=1
|
||||||
zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512
|
zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512
|
||||||
|
chat_messages_aggregation_delay=1000
|
||||||
|
chat_messages_aggregation=1
|
||||||
|
|
||||||
[sound]
|
[sound]
|
||||||
#remove this property for any application that is not Linphone public version itself
|
#remove this property for any application that is not Linphone public version itself
|
||||||
|
|
|
@ -61,7 +61,7 @@ class ChatBubbleActivity : GenericActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val listener = object : ChatRoomListenerStub() {
|
private val listener = object : ChatRoomListenerStub() {
|
||||||
override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) {
|
override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array<out EventLog>) {
|
||||||
chatRoom.markAsRead()
|
chatRoom.markAsRead()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,31 +56,10 @@ class ChatMessagesListViewModel(private val chatRoom: ChatRoom) : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() {
|
private val chatRoomListener: ChatRoomListenerStub = object : ChatRoomListenerStub() {
|
||||||
override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) {
|
override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array<out EventLog>) {
|
||||||
if (eventLog.type == EventLog.Type.ConferenceChatMessage) {
|
for (eventLog in eventLogs) {
|
||||||
val chatMessage = eventLog.chatMessage
|
addChatMessageEventLog(eventLog)
|
||||||
chatMessage ?: return
|
|
||||||
chatMessage.userData = events.value.orEmpty().size
|
|
||||||
|
|
||||||
val existingEvent = events.value.orEmpty().find { data ->
|
|
||||||
data.eventLog == eventLog
|
|
||||||
}
|
|
||||||
if (existingEvent != null) {
|
|
||||||
Log.w("[Chat Messages] Found already present chat message, don't add it it's probably the result of an auto download")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
|
||||||
for (content in chatMessage.contents) {
|
|
||||||
if (content.isFileTransfer) {
|
|
||||||
Log.i("[Chat Messages] Android < 10 detected and WRITE_EXTERNAL_STORAGE permission isn't granted yet")
|
|
||||||
requestWriteExternalStoragePermissionEvent.value = Event(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addEvent(eventLog)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChatMessageSending(chatRoom: ChatRoom, eventLog: EventLog) {
|
override fun onChatMessageSending(chatRoom: ChatRoom, eventLog: EventLog) {
|
||||||
|
@ -245,4 +224,31 @@ class ChatMessagesListViewModel(private val chatRoom: ChatRoom) : ViewModel() {
|
||||||
events.value.orEmpty().forEach(EventLogData::destroy)
|
events.value.orEmpty().forEach(EventLogData::destroy)
|
||||||
events.value = getEvents()
|
events.value = getEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addChatMessageEventLog(eventLog: EventLog) {
|
||||||
|
if (eventLog.type == EventLog.Type.ConferenceChatMessage) {
|
||||||
|
val chatMessage = eventLog.chatMessage
|
||||||
|
chatMessage ?: return
|
||||||
|
chatMessage.userData = events.value.orEmpty().size
|
||||||
|
|
||||||
|
val existingEvent = events.value.orEmpty().find { data ->
|
||||||
|
data.eventLog == eventLog
|
||||||
|
}
|
||||||
|
if (existingEvent != null) {
|
||||||
|
Log.w("[Chat Messages] Found already present chat message, don't add it it's probably the result of an auto download")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
|
for (content in chatMessage.contents) {
|
||||||
|
if (content.isFileTransfer) {
|
||||||
|
Log.i("[Chat Messages] Android < 10 detected and WRITE_EXTERNAL_STORAGE permission isn't granted yet")
|
||||||
|
requestWriteExternalStoragePermissionEvent.value = Event(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addEvent(eventLog)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ class ChatRoomViewModel(val chatRoom: ChatRoom) : ViewModel(), ContactDataInterf
|
||||||
subject.value = chatRoom.subject
|
subject.value = chatRoom.subject
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChatMessageReceived(chatRoom: ChatRoom, eventLog: EventLog) {
|
override fun onChatMessagesReceived(chatRoom: ChatRoom, eventLogs: Array<out EventLog>) {
|
||||||
updateUnreadMessageCount()
|
updateUnreadMessageCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,19 +56,15 @@ class ChatRoomsListViewModel : MessageNotifierViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
||||||
when (findChatRoomIndex(chatRoom)) {
|
onChatRoomMessageEvent(chatRoom)
|
||||||
-1 -> updateChatRooms()
|
|
||||||
0 -> chatRoomIndexUpdatedEvent.value = Event(0)
|
|
||||||
else -> reorderChatRooms()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
override fun onMessagesReceived(
|
||||||
when (findChatRoomIndex(chatRoom)) {
|
core: Core,
|
||||||
-1 -> updateChatRooms()
|
chatRoom: ChatRoom,
|
||||||
0 -> chatRoomIndexUpdatedEvent.value = Event(0)
|
messages: Array<out ChatMessage>
|
||||||
else -> reorderChatRooms()
|
) {
|
||||||
}
|
onChatRoomMessageEvent(chatRoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
|
override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
|
||||||
|
@ -168,4 +164,12 @@ class ChatRoomsListViewModel : MessageNotifierViewModel() {
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onChatRoomMessageEvent(chatRoom: ChatRoom) {
|
||||||
|
when (findChatRoomIndex(chatRoom)) {
|
||||||
|
-1 -> updateChatRooms()
|
||||||
|
0 -> chatRoomIndexUpdatedEvent.value = Event(0)
|
||||||
|
else -> reorderChatRooms()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,11 @@ class TabsViewModel : ViewModel() {
|
||||||
updateUnreadChatCount()
|
updateUnreadChatCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
override fun onMessagesReceived(
|
||||||
|
core: Core,
|
||||||
|
chatRoom: ChatRoom,
|
||||||
|
messages: Array<out ChatMessage>
|
||||||
|
) {
|
||||||
updateUnreadChatCount()
|
updateUnreadChatCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,11 @@ class CallsViewModel : ViewModel() {
|
||||||
updateUnreadChatCount()
|
updateUnreadChatCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
override fun onMessagesReceived(
|
||||||
|
core: Core,
|
||||||
|
chatRoom: ChatRoom,
|
||||||
|
messages: Array<out ChatMessage>
|
||||||
|
) {
|
||||||
updateUnreadChatCount()
|
updateUnreadChatCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,18 +247,13 @@ class CoreContext(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
|
override fun onMessagesReceived(
|
||||||
if (core.maxSizeForAutoDownloadIncomingFiles != -1) {
|
core: Core,
|
||||||
var hasFile = false
|
chatRoom: ChatRoom,
|
||||||
for (content in message.contents) {
|
messages: Array<out ChatMessage>
|
||||||
if (content.isFile) {
|
) {
|
||||||
hasFile = true
|
for (message in messages) {
|
||||||
break
|
exportFileInMessage(message)
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasFile) {
|
|
||||||
exportFilesInMessageToMediaStore(message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -817,7 +812,22 @@ class CoreContext(
|
||||||
|
|
||||||
/* Coroutine related */
|
/* Coroutine related */
|
||||||
|
|
||||||
fun exportFilesInMessageToMediaStore(message: ChatMessage) {
|
private fun exportFileInMessage(message: ChatMessage) {
|
||||||
|
if (core.maxSizeForAutoDownloadIncomingFiles != -1) {
|
||||||
|
var hasFile = false
|
||||||
|
for (content in message.contents) {
|
||||||
|
if (content.isFile) {
|
||||||
|
hasFile = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasFile) {
|
||||||
|
exportFilesInMessageToMediaStore(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun exportFilesInMessageToMediaStore(message: ChatMessage) {
|
||||||
if (message.isEphemeral) {
|
if (message.isEphemeral) {
|
||||||
Log.w("[Context] Do not make ephemeral file(s) public")
|
Log.w("[Context] Do not make ephemeral file(s) public")
|
||||||
return
|
return
|
||||||
|
|
|
@ -139,11 +139,16 @@ class NotificationsManager(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(core: Core, room: ChatRoom, message: ChatMessage) {
|
override fun onMessagesReceived(
|
||||||
if (message.isOutgoing || corePreferences.disableChat) return
|
core: Core,
|
||||||
|
room: ChatRoom,
|
||||||
|
messages: Array<out ChatMessage>
|
||||||
|
) {
|
||||||
|
Log.i("[Notifications Manager] Received ${messages.size} aggregated messages")
|
||||||
|
if (corePreferences.disableChat) return
|
||||||
|
|
||||||
if (corePreferences.preventInterfaceFromShowingUp) {
|
if (corePreferences.preventInterfaceFromShowingUp) {
|
||||||
Log.w("[Context] We were asked to not show the chat notifications")
|
Log.w("[Notifications Manager] We were asked to not show the chat notifications")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,24 +165,6 @@ class NotificationsManager(private val context: Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.errorInfo.reason == Reason.UnsupportedContent) {
|
|
||||||
Log.w("[Notifications Manager] Received message with unsupported content, do not notify")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.contents.find { content ->
|
|
||||||
content.isFile or content.isFileTransfer or content.isText
|
|
||||||
} == null
|
|
||||||
) {
|
|
||||||
Log.w("[Notifications Manager] Received message with neither text or attachment, do not notify")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.isRead) {
|
|
||||||
Log.w("[Notifications Manager] Received message is already marked as read, do not notify")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (corePreferences.chatRoomShortcuts) {
|
if (corePreferences.chatRoomShortcuts) {
|
||||||
if (ShortcutsHelper.isShortcutToChatRoomAlreadyCreated(context, room)) {
|
if (ShortcutsHelper.isShortcutToChatRoomAlreadyCreated(context, room)) {
|
||||||
Log.i("[Notifications Manager] Chat room shortcut already exists")
|
Log.i("[Notifications Manager] Chat room shortcut already exists")
|
||||||
|
@ -187,7 +174,12 @@ class NotificationsManager(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
displayIncomingChatNotification(room, message)
|
val notifiable = createChatNotifiable(room, messages)
|
||||||
|
if (notifiable.messages.isNotEmpty()) {
|
||||||
|
displayChatNotifiable(room, notifiable)
|
||||||
|
} else {
|
||||||
|
Log.w("[Notifications Manager] No message to display in received aggregated messages")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
|
override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
|
||||||
|
@ -661,7 +653,7 @@ class NotificationsManager(private val context: Context) {
|
||||||
notify(notifiable.notificationId, notification, CHAT_TAG)
|
notify(notifiable.notificationId, notification, CHAT_TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun displayIncomingChatNotification(room: ChatRoom, message: ChatMessage) {
|
private fun createChatNotifiable(room: ChatRoom, message: ChatMessage): Notifiable {
|
||||||
val notifiable = getNotifiableForRoom(room)
|
val notifiable = getNotifiableForRoom(room)
|
||||||
if (notifiable.messages.isNotEmpty() || room.unreadMessagesCount == 1) {
|
if (notifiable.messages.isNotEmpty() || room.unreadMessagesCount == 1) {
|
||||||
val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress)
|
val friend = coreContext.contactsManager.findContactByAddress(message.fromAddress)
|
||||||
|
@ -682,7 +674,27 @@ class NotificationsManager(private val context: Context) {
|
||||||
notifiable.groupTitle = room.subject
|
notifiable.groupTitle = room.subject
|
||||||
}
|
}
|
||||||
|
|
||||||
displayChatNotifiable(room, notifiable)
|
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)
|
||||||
|
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 getNotifiableForRoom(room: ChatRoom): Notifiable {
|
private fun getNotifiableForRoom(room: ChatRoom): Notifiable {
|
||||||
|
|
Loading…
Reference in a new issue