diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt index 49793c5e9..a40a7de31 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationFragment.kt @@ -183,7 +183,11 @@ class ConversationFragment : GenericFragment() { adapter.showDeliveryForChatMessageModelEvent.observe(viewLifecycleOwner) { it.consume { model -> - showDeliveryBottomSheetDialog(model) + if (viewModel.isGroup.value == true) { + showDeliveryBottomSheetDialog(model) + } else { + Log.w("$TAG Conversation is not a group, not showing delivery bottom sheet") + } } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageDeliveryModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageDeliveryModel.kt index 1365e17c7..50ad304f4 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageDeliveryModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageDeliveryModel.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.MutableLiveData import org.linphone.R import org.linphone.core.ChatMessage import org.linphone.core.ChatMessage.State +import org.linphone.core.tools.Log import org.linphone.utils.AppUtils class ChatMessageDeliveryModel @WorkerThread constructor( @@ -58,45 +59,80 @@ class ChatMessageDeliveryModel @WorkerThread constructor( @WorkerThread private fun computeDeliveryStatus() { for (participant in chatMessage.getParticipantsByImdnState(State.Displayed)) { - displayedModels.add(ChatMessageParticipantDeliveryModel(participant)) + displayedModels.add( + ChatMessageParticipantDeliveryModel( + participant.participant.address, + participant.stateChangeTime + ) + ) } + // Always add ourselves to prevent empty list + displayedModels.add( + ChatMessageParticipantDeliveryModel( + chatMessage.localAddress, + chatMessage.time + ) + ) + val readCount = displayedModels.size.toString() readLabel.postValue( AppUtils.getFormattedString( R.string.message_delivery_info_read_title, - displayedModels.size.toString() + readCount ) ) for (participant in chatMessage.getParticipantsByImdnState(State.DeliveredToUser)) { - deliveredModels.add(ChatMessageParticipantDeliveryModel(participant)) + deliveredModels.add( + ChatMessageParticipantDeliveryModel( + participant.participant.address, + participant.stateChangeTime + ) + ) } + val receivedCount = deliveredModels.size.toString() receivedLabel.postValue( AppUtils.getFormattedString( R.string.message_delivery_info_received_title, - deliveredModels.size.toString() + receivedCount ) ) for (participant in chatMessage.getParticipantsByImdnState(State.Delivered)) { - sentModels.add(ChatMessageParticipantDeliveryModel(participant)) + sentModels.add( + ChatMessageParticipantDeliveryModel( + participant.participant.address, + participant.stateChangeTime + ) + ) } + val sentCount = sentModels.size.toString() sentLabel.postValue( AppUtils.getFormattedString( R.string.message_delivery_info_sent_title, - sentModels.size.toString() + sentCount ) ) for (participant in chatMessage.getParticipantsByImdnState(State.NotDelivered)) { - errorModels.add(ChatMessageParticipantDeliveryModel(participant)) + errorModels.add( + ChatMessageParticipantDeliveryModel( + participant.participant.address, + participant.stateChangeTime + ) + ) } + val errorCount = errorModels.size.toString() errorLabel.postValue( AppUtils.getFormattedString( R.string.message_delivery_info_error_title, - errorModels.size.toString() + errorCount ) ) deliveryModels.postValue(displayedModels) + Log.i("$TAG Message ID [${chatMessage.messageId}] is in state [${chatMessage.state}]") + Log.i( + "$TAG There are [$readCount] that have read this message, [$receivedCount] that have received it, [$sentCount] that haven't received it yet and [$errorCount] that probably won't receive it due to an error" + ) } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt index 04a4c8a42..8040b8a93 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt @@ -23,7 +23,6 @@ import androidx.annotation.UiThread import androidx.annotation.WorkerThread import androidx.lifecycle.MutableLiveData import org.linphone.LinphoneApplication.Companion.coreContext -import org.linphone.R import org.linphone.core.Address import org.linphone.core.ChatMessage import org.linphone.core.ChatMessageListenerStub @@ -66,7 +65,7 @@ class ChatMessageModel @WorkerThread constructor( private val chatMessageListener = object : ChatMessageListenerStub() { @WorkerThread override fun onMsgStateChanged(message: ChatMessage, messageState: ChatMessage.State?) { - computeStatusIcon(chatMessage.state) + statusIcon.postValue(LinphoneUtils.getChatIconResId(chatMessage.state)) } @WorkerThread @@ -84,7 +83,7 @@ class ChatMessageModel @WorkerThread constructor( init { chatMessage.addListener(chatMessageListener) - computeStatusIcon(chatMessage.state) + statusIcon.postValue(LinphoneUtils.getChatIconResId(chatMessage.state)) } @WorkerThread @@ -101,26 +100,4 @@ class ChatMessageModel @WorkerThread constructor( dismissLongPressMenuEvent.postValue(Event(true)) } } - - @WorkerThread - private fun computeStatusIcon(state: ChatMessage.State) { - val icon = when (state) { - ChatMessage.State.Displayed -> { - R.drawable.checks - } - ChatMessage.State.DeliveredToUser -> { - R.drawable.check - } - ChatMessage.State.Delivered -> { - R.drawable.envelope_simple - } - ChatMessage.State.NotDelivered -> { - R.drawable.warning_circle - } - else -> { - R.drawable.in_progress - } - } - statusIcon.postValue(icon) - } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageParticipantDeliveryModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageParticipantDeliveryModel.kt index d1ccb4b36..33690a7eb 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageParticipantDeliveryModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageParticipantDeliveryModel.kt @@ -1,18 +1,15 @@ package org.linphone.ui.main.chat.model import androidx.annotation.WorkerThread -import org.linphone.LinphoneApplication -import org.linphone.core.ParticipantImdnState +import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.core.Address import org.linphone.utils.TimestampUtils class ChatMessageParticipantDeliveryModel @WorkerThread constructor( - imdnState: ParticipantImdnState + address: Address, + timestamp: Long ) { - val address = imdnState.participant.address + val avatarModel = coreContext.contactsManager.getContactAvatarModelForAddress(address) - val avatarModel = LinphoneApplication.coreContext.contactsManager.getContactAvatarModelForAddress( - address - ) - - val time = TimestampUtils.toString(imdnState.stateChangeTime) + val time = TimestampUtils.toString(timestamp) } diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt index ff284e177..e2efd3ad1 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt @@ -228,32 +228,7 @@ class ConversationModel @WorkerThread constructor(private val chatRoom: ChatRoom val isOutgoing = message.isOutgoing isLastMessageOutgoing.postValue(isOutgoing) if (isOutgoing) { - val icon = when (message.state) { - ChatMessage.State.Displayed -> { - R.drawable.checks - } - - ChatMessage.State.DeliveredToUser -> { - R.drawable.check - } - - ChatMessage.State.Delivered -> { - R.drawable.sent - } - - ChatMessage.State.InProgress, ChatMessage.State.FileTransferInProgress -> { - R.drawable.in_progress - } - - ChatMessage.State.NotDelivered, ChatMessage.State.FileTransferError -> { - R.drawable.warning_circle - } - - else -> { - R.drawable.info - } - } - lastMessageIcon.postValue(icon) + lastMessageIcon.postValue(LinphoneUtils.getChatIconResId(message.state)) } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt index 8626c2b20..2dd41c78d 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationInfoViewModel.kt @@ -262,7 +262,7 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() { isMyselfAdmin.postValue(chatRoom.me?.isAdmin) - val isGroupChatRoom = isChatRoomAGroup() + val isGroupChatRoom = LinphoneUtils.isChatRoomAGroup(chatRoom) isGroup.postValue(isGroupChatRoom) val empty = chatRoom.hasCapability(ChatRoom.Capabilities.Conference.toInt()) && chatRoom.participants.isEmpty() @@ -279,8 +279,8 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() { @WorkerThread private fun computeParticipantsList() { - val groupChatRoom = isChatRoomAGroup() - val selfAdmin = chatRoom.me?.isAdmin == true + val groupChatRoom = LinphoneUtils.isChatRoomAGroup(chatRoom) + val selfAdmin = if (groupChatRoom) chatRoom.me?.isAdmin == true else false val friends = arrayListOf() val participantsList = arrayListOf() @@ -315,13 +315,4 @@ class ConversationInfoViewModel @UiThread constructor() : ViewModel() { participants.postValue(participantsList) } - - @WorkerThread - private fun isChatRoomAGroup(): Boolean { - return if (::chatRoom.isInitialized) { - LinphoneUtils.isChatRoomAGroup(chatRoom) - } else { - false - } - } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt index 012d8e55c..900d3769c 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt @@ -98,7 +98,15 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { } else { false } - list.add(EventLogModel(eventLog, avatarModel, isChatRoomAGroup(), group, true)) + list.add( + EventLogModel( + eventLog, + avatarModel, + LinphoneUtils.isChatRoomAGroup(chatRoom), + group, + true + ) + ) events.postValue(list) } @@ -277,7 +285,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { Log.w("$TAG Chat room with subject [${chatRoom.subject}] is read only!") } - val group = isChatRoomAGroup() + val group = LinphoneUtils.isChatRoomAGroup(chatRoom) isGroup.postValue(group) subject.postValue(chatRoom.subject) @@ -324,6 +332,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { private fun processGroupedEvents( groupedEventLogs: ArrayList ): ArrayList { + val groupChatRoom = LinphoneUtils.isChatRoomAGroup(chatRoom) val eventsList = arrayListOf() // Handle all events in group, then re-start a new group with current item @@ -335,7 +344,7 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { val model = EventLogModel( groupedEvent, avatar, - isChatRoomAGroup(), + groupChatRoom, index > 0, index == groupedEventLogs.size - 1 ) @@ -434,13 +443,4 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { composingLabel.postValue("") } } - - @WorkerThread - private fun isChatRoomAGroup(): Boolean { - return if (::chatRoom.isInitialized) { - LinphoneUtils.isChatRoomAGroup(chatRoom) - } else { - false - } - } } diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt index 48b1103c5..52f4a1118 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt @@ -185,6 +185,31 @@ class LinphoneUtils { } } + @AnyThread + @IntegerRes + fun getChatIconResId(chatState: ChatMessage.State): Int { + return when (chatState) { + ChatMessage.State.Displayed -> { + R.drawable.checks + } + ChatMessage.State.DeliveredToUser -> { + R.drawable.check + } + ChatMessage.State.Delivered -> { + R.drawable.envelope_simple + } + ChatMessage.State.InProgress, ChatMessage.State.FileTransferInProgress -> { + R.drawable.in_progress + } + ChatMessage.State.NotDelivered, ChatMessage.State.FileTransferError -> { + R.drawable.warning_circle + } + else -> { + R.drawable.not_trusted + } + } + } + @WorkerThread fun getChatRoomId(room: ChatRoom): String { return getChatRoomId(room.localAddress, room.peerAddress) @@ -206,8 +231,9 @@ class LinphoneUtils { @WorkerThread fun isChatRoomAGroup(chatRoom: ChatRoom): Boolean { - return !chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt()) && - chatRoom.hasCapability(ChatRoom.Capabilities.Conference.toInt()) + val oneToOne = chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt()) + val conference = chatRoom.hasCapability(ChatRoom.Capabilities.Conference.toInt()) + return !oneToOne && conference } @WorkerThread diff --git a/app/src/main/res/drawable/sent.xml b/app/src/main/res/drawable/sent.xml deleted file mode 100644 index a21c10136..000000000 --- a/app/src/main/res/drawable/sent.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - -