Refactored app to use chatRoom.identifier from SDK instead of computing it from local & peer address

This commit is contained in:
Sylvain Berfini 2025-02-13 16:02:01 +01:00
parent ca08ed68be
commit 17511a4c26
39 changed files with 208 additions and 501 deletions

View file

@ -27,7 +27,6 @@ import android.view.View
import android.view.contentcapture.ContentCaptureContext
import android.view.contentcapture.ContentCaptureSession
import androidx.annotation.RequiresApi
import org.linphone.utils.LinphoneUtils
@RequiresApi(Build.VERSION_CODES.Q)
class Api29Compatibility {
@ -59,11 +58,10 @@ class Api29Compatibility {
return intent.getStringExtra(Intent.EXTRA_LOCUS_ID)
}
fun setLocusIdInContentCaptureSession(root: View, localSipUri: String, remoteSipUri: String) {
fun setLocusIdInContentCaptureSession(root: View, conversationId: String) {
val session: ContentCaptureSession? = root.contentCaptureSession
if (session != null) {
val id = LinphoneUtils.getChatRoomId(localSipUri, remoteSipUri)
session.contentCaptureContext = ContentCaptureContext.forLocusId(id)
session.contentCaptureContext = ContentCaptureContext.forLocusId(conversationId)
}
}
}

View file

@ -159,12 +159,11 @@ class Compatibility {
return null
}
fun setLocusIdInContentCaptureSession(root: View, localSipUri: String, remoteSipUri: String) {
fun setLocusIdInContentCaptureSession(root: View, conversationId: String) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return Api29Compatibility.setLocusIdInContentCaptureSession(
root,
localSipUri,
remoteSipUri
conversationId
)
}
}

View file

@ -71,6 +71,8 @@ import org.linphone.core.MediaDirection
import org.linphone.core.tools.Log
import org.linphone.ui.call.CallActivity
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.MainActivity.Companion.ARGUMENTS_CHAT
import org.linphone.ui.main.MainActivity.Companion.ARGUMENTS_CONVERSATION_ID
import org.linphone.utils.AppUtils
import org.linphone.utils.FileUtils
import org.linphone.utils.LinphoneUtils
@ -262,7 +264,7 @@ class NotificationsManager
Log.i("$TAG Received ${messages.size} aggregated messages")
if (corePreferences.disableChat) return
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
if (currentlyDisplayedChatRoomId.isNotEmpty() && id == currentlyDisplayedChatRoomId) {
Log.i(
"$TAG Do not notify received messages for currently displayed conversation [$id]"
@ -301,7 +303,7 @@ class NotificationsManager
"$TAG Reaction received [${reaction.body}] from [${address.asStringUriOnly()}] for message [$message]"
)
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
/*if (id == currentlyDisplayedChatRoomId) {
Log.i(
"$TAG Do not notify received reaction for currently displayed conversation [$id]"
@ -340,7 +342,7 @@ class NotificationsManager
if (corePreferences.disableChat) return
if (chatRoom.muted) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation $id has been muted")
return
}
@ -370,7 +372,7 @@ class NotificationsManager
val notification = createMessageNotification(
notifiable,
pendingIntent,
LinphoneUtils.getChatRoomId(chatRoom),
LinphoneUtils.getConversationId(chatRoom),
me
)
notify(notifiable.notificationId, notification, CHAT_TAG)
@ -389,7 +391,7 @@ class NotificationsManager
@WorkerThread
override fun onChatRoomRead(core: Core, chatRoom: ChatRoom) {
Log.i(
"$TAG Conversation [${LinphoneUtils.getChatRoomId(chatRoom)}] has been marked as read, removing notification if any"
"$TAG Conversation [${LinphoneUtils.getConversationId(chatRoom)}] has been marked as read, removing notification if any"
)
dismissChatNotification(chatRoom)
}
@ -786,7 +788,7 @@ class NotificationsManager
val address = chatRoom.peerAddress.asStringUriOnly()
var notifiable: Notifiable? = chatNotificationsMap[address]
if (notifiable == null) {
notifiable = Notifiable(LinphoneUtils.getChatRoomId(chatRoom).hashCode())
notifiable = Notifiable(LinphoneUtils.getConversationId(chatRoom).hashCode())
notifiable.myself = LinphoneUtils.getDisplayName(chatRoom.localAddress)
notifiable.localIdentity = chatRoom.localAddress.asStringUriOnly()
notifiable.remoteAddress = chatRoom.peerAddress.asStringUriOnly()
@ -834,7 +836,7 @@ class NotificationsManager
val notification = createMessageNotification(
notifiable,
pendingIntent,
LinphoneUtils.getChatRoomId(chatRoom),
LinphoneUtils.getConversationId(chatRoom),
me
)
notify(notifiable.notificationId, notification, CHAT_TAG)
@ -899,7 +901,7 @@ class NotificationsManager
val notification = createMessageNotification(
notifiable,
pendingIntent,
LinphoneUtils.getChatRoomId(chatRoom),
LinphoneUtils.getConversationId(chatRoom),
me
)
notify(notifiable.notificationId, notification, CHAT_TAG)
@ -928,7 +930,7 @@ class NotificationsManager
val notification = createMessageNotification(
notifiable,
pendingIntent,
LinphoneUtils.getChatRoomId(chatRoom),
LinphoneUtils.getConversationId(chatRoom),
me
)
Log.i(
@ -1295,7 +1297,7 @@ class NotificationsManager
return true
} else {
val previousNotificationId = previousChatNotifications.find { id ->
id == LinphoneUtils.getChatRoomId(chatRoom).hashCode()
id == LinphoneUtils.getConversationId(chatRoom).hashCode()
}
if (previousNotificationId != null) {
Log.i(
@ -1362,7 +1364,7 @@ class NotificationsManager
val notification = createMessageNotification(
notifiable,
pendingIntent,
LinphoneUtils.getChatRoomId(chatRoom),
LinphoneUtils.getConversationId(chatRoom),
me
)
notify(notifiable.notificationId, notification, CHAT_TAG)
@ -1585,9 +1587,8 @@ class NotificationsManager
@WorkerThread
private fun getChatRoomPendingIntent(chatRoom: ChatRoom, notificationId: Int): PendingIntent {
val args = Bundle()
args.putBoolean("Chat", true)
args.putString("RemoteSipUri", chatRoom.peerAddress.asStringUriOnly())
args.putString("LocalSipUri", chatRoom.localAddress.asStringUriOnly())
args.putBoolean(ARGUMENTS_CHAT, true)
args.putString(ARGUMENTS_CONVERSATION_ID, LinphoneUtils.getConversationId(chatRoom))
// Not using NavDeepLinkBuilder to prevent stacking a ConversationsListFragment above another one
return TaskStackBuilder.create(context).run {

View file

@ -227,17 +227,12 @@ class ActiveConferenceCallFragment : GenericCallFragment() {
}
callViewModel.conferenceModel.goToConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
it.consume { conversationId ->
if (findNavController().currentDestination?.id == R.id.activeConferenceCallFragment) {
val localSipUri = pair.first
val remoteSipUri = pair.second
Log.i(
"$TAG Display conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
Log.i("$TAG Display conversation with conversation ID [$conversationId]")
val action =
ActiveConferenceCallFragmentDirections.actionActiveConferenceCallFragmentToInCallConversationFragment(
localSipUri,
remoteSipUri
conversationId
)
findNavController().navigate(action)
}

View file

@ -39,6 +39,7 @@ import org.linphone.ui.call.conference.model.ConferenceParticipantModel
import org.linphone.ui.call.conference.view.GridBoxLayout
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
import org.linphone.utils.LinphoneUtils
class ConferenceViewModel
@UiThread
@ -91,8 +92,8 @@ class ConferenceViewModel
MutableLiveData<Event<Pair<String, Participant>>>()
}
val goToConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val goToConversationEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
private lateinit var conference: Conference
@ -369,14 +370,7 @@ class ConferenceViewModel
Log.i("$TAG Navigating to conference's conversation")
val chatRoom = conference.chatRoom
if (chatRoom != null) {
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.e(
"$TAG No chat room available for current conference [${conference.conferenceAddress?.asStringUriOnly()}]"

View file

@ -371,17 +371,14 @@ class ActiveCallFragment : GenericCallFragment() {
}
callViewModel.goToConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
it.consume { conversationId ->
if (findNavController().currentDestination?.id == R.id.activeCallFragment) {
val localSipUri = pair.first
val remoteSipUri = pair.second
Log.i(
"$TAG Display conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
"$TAG Display conversation with conversation ID [$conversationId]"
)
val action =
ActiveCallFragmentDirections.actionActiveCallFragmentToInCallConversationFragment(
localSipUri,
remoteSipUri
conversationId
)
findNavController().navigate(action)
}

View file

@ -199,8 +199,8 @@ class CurrentCallViewModel
val operationInProgress = MutableLiveData<Boolean>()
val goToConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val goToConversationEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val chatRoomCreationErrorEvent: MutableLiveData<Event<Int>> by lazy {
@ -394,21 +394,14 @@ class CurrentCallViewModel
val state = chatRoom.state
if (state == ChatRoom.State.Instantiated) return
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation [$id] (${chatRoom.subject}) state changed: [$state]")
if (state == ChatRoom.State.Created) {
Log.i("$TAG Conversation [$id] successfully created")
chatRoom.removeListener(this)
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else if (state == ChatRoom.State.CreationFailed) {
Log.e("$TAG Conversation [$id] creation has failed!")
chatRoom.removeListener(this)
@ -935,17 +928,10 @@ class CurrentCallViewModel
if (existingConversation != null) {
Log.i(
"$TAG Found existing conversation [${
LinphoneUtils.getChatRoomId(existingConversation)
LinphoneUtils.getConversationId(existingConversation)
}], going to it"
)
goToConversationEvent.postValue(
Event(
Pair(
existingConversation.localAddress.asStringUriOnly(),
existingConversation.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(existingConversation)))
} else {
Log.i("$TAG No existing conversation was found, let's create it")
createCurrentCallConversation(currentCall)
@ -1372,37 +1358,23 @@ class CurrentCallViewModel
operationInProgress.postValue(true)
val params = getChatRoomParams(call) ?: return // TODO: show error to user
val conversation = core.createChatRoom(params, localAddress, participants)
if (conversation != null) {
val chatRoom = core.createChatRoom(params, localAddress, participants)
if (chatRoom != null) {
if (params.chatParams?.backend == ChatRoom.Backend.FlexisipChat) {
if (conversation.state == ChatRoom.State.Created) {
val id = LinphoneUtils.getChatRoomId(conversation)
if (chatRoom.state == ChatRoom.State.Created) {
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG 1-1 conversation [$id] has been created")
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
conversation.localAddress.asStringUriOnly(),
conversation.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.i("$TAG Conversation isn't in Created state yet, wait for it")
conversation.addListener(chatRoomListener)
chatRoom.addListener(chatRoomListener)
}
} else {
val id = LinphoneUtils.getChatRoomId(conversation)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation successfully created [$id]")
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
conversation.localAddress.asStringUriOnly(),
conversation.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
}
} else {
Log.e(

View file

@ -101,12 +101,11 @@ class MediaViewerActivity : GenericActivity() {
val originalPath = args.getString("originalPath", "")
viewModel.initTempModel(path, timestamp, isEncrypted, originalPath)
val localSipUri = args.getString("localSipUri").orEmpty()
val remoteSipUri = args.getString("remoteSipUri").orEmpty()
val conversationId = args.getString("conversationId").orEmpty()
Log.i(
"$TAG Looking up for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri] trying to display file [$path]"
"$TAG Looking up for conversation with conversation ID [$conversationId] trying to display file [$path]"
)
viewModel.findChatRoom(null, localSipUri, remoteSipUri)
viewModel.findChatRoom(null, conversationId)
viewModel.mediaList.observe(this) {
updateMediaList(path, it)

View file

@ -68,7 +68,7 @@ class MediaListViewModel
@WorkerThread
private fun loadMediaList() {
val list = arrayListOf<FileModel>()
val chatRoomId = LinphoneUtils.getChatRoomId(chatRoom)
val chatRoomId = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Loading media contents for conversation [$chatRoomId]")
val media = chatRoom.mediaContents

View file

@ -86,6 +86,9 @@ class MainActivity : GenericActivity() {
private const val HISTORY_FRAGMENT_ID = 2
private const val CHAT_FRAGMENT_ID = 3
private const val MEETINGS_FRAGMENT_ID = 4
const val ARGUMENTS_CHAT = "Chat"
const val ARGUMENTS_CONVERSATION_ID = "ConversationId"
}
private lateinit var binding: MainActivityBinding
@ -514,14 +517,9 @@ class MainActivity : GenericActivity() {
private fun handleLocusOrShortcut(id: String) {
Log.i("$TAG Found locus ID [$id]")
val pair = LinphoneUtils.getLocalAndPeerSipUrisFromChatRoomId(id)
if (pair != null) {
val localSipUri = pair.first
val remoteSipUri = pair.second
Log.i(
"$TAG Navigating to conversation with local [$localSipUri] and peer [$remoteSipUri] addresses, computed from shortcut ID"
)
sharedViewModel.showConversationEvent.value = Event(pair)
if (id.isNotEmpty()) {
Log.i("$TAG Navigating to conversation with ID [$id], computed from shortcut ID")
sharedViewModel.showConversationEvent.value = Event(id)
}
}
@ -547,22 +545,18 @@ class MainActivity : GenericActivity() {
}
}
} else {
if (intent.hasExtra("Chat")) {
if (intent.hasExtra(ARGUMENTS_CHAT)) {
Log.i("$TAG Intent has [Chat] extra")
coreContext.postOnMainThread {
try {
Log.i("$TAG Trying to go to Conversations fragment")
val args = intent.extras
val localSipUri = args?.getString("LocalSipUri", "")
val remoteSipUri = args?.getString("RemoteSipUri", "")
if (remoteSipUri.isNullOrEmpty() || localSipUri.isNullOrEmpty()) {
Log.w("$TAG Found [Chat] extra but no local and/or remote SIP URI!")
val conversationId = args?.getString(ARGUMENTS_CONVERSATION_ID, "")
if (conversationId.isNullOrEmpty()) {
Log.w("$TAG Found [Chat] extra but no conversation ID!")
} else {
Log.i(
"$TAG Found [Chat] extra with local [$localSipUri] and peer [$remoteSipUri] addresses"
)
val pair = Pair(localSipUri, remoteSipUri)
sharedViewModel.showConversationEvent.value = Event(pair)
Log.i("$TAG Found [Chat] extra with conversation ID [$conversationId]")
sharedViewModel.showConversationEvent.value = Event(conversationId)
}
args?.clear()
@ -665,25 +659,23 @@ class MainActivity : GenericActivity() {
Log.i(
"$TAG App is already started and in debug fragment, navigating to conversations list"
)
val pair = parseShortcutIfAny(intent)
if (pair != null) {
val conversationId = parseShortcutIfAny(intent)
if (conversationId != null) {
Log.i(
"$TAG Navigating from debug to conversation with local [${pair.first}] and peer [${pair.second}] addresses, computed from shortcut ID"
"$TAG Navigating from debug to conversation with ID [$conversationId], computed from shortcut ID"
)
sharedViewModel.showConversationEvent.value = Event(pair)
sharedViewModel.showConversationEvent.value = Event(conversationId)
}
val action = DebugFragmentDirections.actionDebugFragmentToConversationsListFragment()
findNavController().navigate(action)
} else {
val pair = parseShortcutIfAny(intent)
if (pair != null) {
val localSipUri = pair.first
val remoteSipUri = pair.second
val conversationId = parseShortcutIfAny(intent)
if (conversationId != null) {
Log.i(
"$TAG Navigating to conversation with local [$localSipUri] and peer [$remoteSipUri] addresses, computed from shortcut ID"
"$TAG Navigating to conversation with conversation ID [$conversationId] addresses, computed from shortcut ID"
)
sharedViewModel.showConversationEvent.value = Event(pair)
sharedViewModel.showConversationEvent.value = Event(conversationId)
}
if (findNavController().currentDestination?.id == R.id.conversationsListFragment) {
@ -698,11 +690,11 @@ class MainActivity : GenericActivity() {
}
}
private fun parseShortcutIfAny(intent: Intent): Pair<String, String>? {
private fun parseShortcutIfAny(intent: Intent): String? {
val shortcutId = intent.getStringExtra("android.intent.extra.shortcut.ID") // Intent.EXTRA_SHORTCUT_ID
if (shortcutId != null) {
Log.i("$TAG Found shortcut ID [$shortcutId]")
return LinphoneUtils.getLocalAndPeerSipUrisFromChatRoomId(shortcutId)
return shortcutId
} else {
Log.i("$TAG No shortcut ID was found")
}

View file

@ -87,7 +87,7 @@ class ConversationsContactsAndSuggestionsListAdapter :
override fun getItemViewType(position: Int): Int {
val model = getItem(position)
return if (model.localAddress != null) {
return if (model.conversationId.isNotEmpty()) {
CONVERSATION_TYPE
} else if (model.friend != null) {
if (model.starred) {

View file

@ -91,13 +91,10 @@ class ConversationDocumentsListFragment : SlidingPaneChildFragment() {
binding.viewModel = viewModel
observeToastEvents(viewModel)
val localSipUri = args.localSipUri
val remoteSipUri = args.remoteSipUri
Log.i(
"$TAG Looking up for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
val conversationId = args.conversationId
Log.i("$TAG Looking up for conversation with conversation ID [$conversationId]")
val chatRoom = sharedViewModel.displayedChatRoom
viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri)
viewModel.findChatRoom(chatRoom, conversationId)
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
binding.documentsList.addItemDecoration(headerItemDecoration)
@ -143,8 +140,7 @@ class ConversationDocumentsListFragment : SlidingPaneChildFragment() {
val bundle = Bundle()
bundle.apply {
putString("localSipUri", viewModel.localSipUri)
putString("remoteSipUri", viewModel.remoteSipUri)
putString("conversationId", viewModel.conversationId)
putString("path", path)
putBoolean("isEncrypted", fileModel.isEncrypted)
putLong("timestamp", fileModel.fileCreationTimestamp)

View file

@ -120,17 +120,11 @@ class ConversationForwardMessageFragment : SlidingPaneChildFragment() {
}
viewModel.chatRoomCreatedEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
Log.i(
"$TAG Navigating to conversation [${pair.second}] with local address [${pair.first}]"
)
it.consume { conversationId ->
Log.i("$TAG Navigating to conversation [$conversationId]")
if (findNavController().currentDestination?.id == R.id.conversationForwardMessageFragment) {
val localSipUri = pair.first
val remoteSipUri = pair.second
val action = ConversationForwardMessageFragmentDirections.actionConversationForwardMessageFragmentToConversationFragment(
localSipUri,
remoteSipUri
conversationId
)
disableConsumingEventOnPause = true
findNavController().navigate(action)

View file

@ -484,14 +484,11 @@ open class ConversationFragment : SlidingPaneChildFragment() {
}
RecyclerViewSwipeUtils(callbacks).attachToRecyclerView(binding.eventsList)
val localSipUri = args.localSipUri
val remoteSipUri = args.remoteSipUri
Log.i(
"$TAG Looking up for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
val conversationId = args.conversationId
Log.i("$TAG Looking up for conversation with conversation ID [$conversationId]")
val chatRoom = sharedViewModel.displayedChatRoom
viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri)
Compatibility.setLocusIdInContentCaptureSession(binding.root, localSipUri, remoteSipUri)
viewModel.findChatRoom(chatRoom, conversationId)
Compatibility.setLocusIdInContentCaptureSession(binding.root, conversationId)
viewModel.chatRoomFoundEvent.observe(viewLifecycleOwner) {
it.consume { found ->
@ -1092,8 +1089,7 @@ open class ConversationFragment : SlidingPaneChildFragment() {
if (findNavController().currentDestination?.id == R.id.conversationFragment) {
val action =
ConversationFragmentDirections.actionConversationFragmentToConversationInfoFragment(
viewModel.localSipUri,
viewModel.remoteSipUri
viewModel.conversationId,
)
findNavController().navigate(action)
}
@ -1113,8 +1109,7 @@ open class ConversationFragment : SlidingPaneChildFragment() {
val bundle = Bundle()
bundle.apply {
putString("localSipUri", viewModel.localSipUri)
putString("remoteSipUri", viewModel.remoteSipUri)
putString("conversationId", viewModel.conversationId)
putString("path", path)
putBoolean("isEncrypted", fileModel.isEncrypted)
putLong("timestamp", fileModel.fileCreationTimestamp)
@ -1199,8 +1194,7 @@ open class ConversationFragment : SlidingPaneChildFragment() {
if (findNavController().currentDestination?.id == R.id.conversationFragment) {
val action =
ConversationFragmentDirections.actionConversationFragmentToConversationMediaListFragment(
localSipUri = viewModel.localSipUri,
remoteSipUri = viewModel.remoteSipUri
viewModel.conversationId
)
findNavController().navigate(action)
}
@ -1211,8 +1205,7 @@ open class ConversationFragment : SlidingPaneChildFragment() {
if (findNavController().currentDestination?.id == R.id.conversationFragment) {
val action =
ConversationFragmentDirections.actionConversationFragmentToConversationDocumentsListFragment(
localSipUri = viewModel.localSipUri,
remoteSipUri = viewModel.remoteSipUri
viewModel.conversationId
)
findNavController().navigate(action)
}

View file

@ -96,13 +96,10 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
binding.viewModel = viewModel
observeToastEvents(viewModel)
val localSipUri = args.localSipUri
val remoteSipUri = args.remoteSipUri
Log.i(
"$TAG Looking up for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
val conversationId = args.conversationId
Log.i("$TAG Looking up for conversation with conversation ID [$conversationId]")
val chatRoom = sharedViewModel.displayedChatRoom
viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri)
viewModel.findChatRoom(chatRoom, conversationId)
binding.participants.isNestedScrollingEnabled = false
binding.participants.setHasFixedSize(false)
@ -116,7 +113,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
it.consume { found ->
if (found) {
Log.i(
"$TAG Found matching conversation for local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
"$TAG Found matching conversation with conversation ID [$conversationId]"
)
startPostponedEnterTransition()
} else {
@ -333,7 +330,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
if (findNavController().currentDestination?.id == R.id.conversationInfoFragment) {
Log.i("$TAG Going to shared media fragment")
val action =
ConversationInfoFragmentDirections.actionConversationInfoFragmentToConversationMediaListFragment(localSipUri, remoteSipUri)
ConversationInfoFragmentDirections.actionConversationInfoFragmentToConversationMediaListFragment(conversationId)
findNavController().navigate(action)
}
}
@ -342,7 +339,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() {
if (findNavController().currentDestination?.id == R.id.conversationInfoFragment) {
Log.i("$TAG Going to shared documents fragment")
val action =
ConversationInfoFragmentDirections.actionConversationInfoFragmentToConversationDocumentsListFragment(localSipUri, remoteSipUri)
ConversationInfoFragmentDirections.actionConversationInfoFragmentToConversationDocumentsListFragment(conversationId)
findNavController().navigate(action)
}
}

View file

@ -94,13 +94,10 @@ class ConversationMediaListFragment : SlidingPaneChildFragment() {
binding.viewModel = viewModel
observeToastEvents(viewModel)
val localSipUri = args.localSipUri
val remoteSipUri = args.remoteSipUri
Log.i(
"$TAG Looking up for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
val conversationId = args.conversationId
Log.i("$TAG Looking up for conversation with conversation ID [$conversationId]")
val chatRoom = sharedViewModel.displayedChatRoom
viewModel.findChatRoom(chatRoom, localSipUri, remoteSipUri)
viewModel.findChatRoom(chatRoom, conversationId)
val headerItemDecoration = RecyclerViewHeaderDecoration(requireContext(), adapter)
binding.mediaList.addItemDecoration(headerItemDecoration)
@ -172,8 +169,7 @@ class ConversationMediaListFragment : SlidingPaneChildFragment() {
val bundle = Bundle()
bundle.apply {
putString("localSipUri", viewModel.localSipUri)
putString("remoteSipUri", viewModel.remoteSipUri)
putString("conversationId", viewModel.conversationId)
putString("path", path)
putBoolean("isEncrypted", fileModel.isEncrypted)
putLong("timestamp", fileModel.fileCreationTimestamp)

View file

@ -39,6 +39,7 @@ import org.linphone.databinding.ChatListFragmentBinding
import org.linphone.ui.GenericActivity
import org.linphone.ui.fileviewer.FileViewerActivity
import org.linphone.ui.fileviewer.MediaViewerActivity
import org.linphone.ui.main.MainActivity.Companion.ARGUMENTS_CONVERSATION_ID
import org.linphone.ui.main.chat.adapter.ConversationsListAdapter
import org.linphone.ui.main.chat.viewmodel.ConversationsListViewModel
import org.linphone.ui.main.fragment.AbstractMainFragment
@ -162,9 +163,7 @@ class ConversationsListFragment : AbstractMainFragment() {
it.consume { model ->
Log.i("$TAG Show conversation with ID [${model.id}]")
sharedViewModel.displayedChatRoom = model.chatRoom
sharedViewModel.showConversationEvent.value = Event(
Pair(model.localSipUri, model.remoteSipUri)
)
sharedViewModel.showConversationEvent.value = Event(model.id)
}
}
@ -191,16 +190,9 @@ class ConversationsListFragment : AbstractMainFragment() {
}
sharedViewModel.showConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
val localSipUri = pair.first
val remoteSipUri = pair.second
Log.i(
"$TAG Navigating to conversation fragment with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
val action = ConversationFragmentDirections.actionGlobalConversationFragment(
localSipUri,
remoteSipUri
)
it.consume { conversationId ->
Log.i("$TAG Navigating to conversation fragment with ID [$conversationId]")
val action = ConversationFragmentDirections.actionGlobalConversationFragment(conversationId)
binding.chatNavContainer.findNavController().navigate(action)
}
}
@ -330,12 +322,10 @@ class ConversationsListFragment : AbstractMainFragment() {
val args = arguments
if (args != null) {
val localSipUri = args.getString("LocalSipUri")
val remoteSipUri = args.getString("RemoteSipUri")
if (localSipUri != null && remoteSipUri != null) {
Log.i("$TAG Found local [$localSipUri] & remote [$remoteSipUri] URIs in arguments")
val pair = Pair(localSipUri, remoteSipUri)
sharedViewModel.showConversationEvent.value = Event(pair)
val conversationId = args.getString(ARGUMENTS_CONVERSATION_ID)
if (!conversationId.isNullOrEmpty()) {
Log.i("$TAG Found conversation ID [$conversationId] in arguments")
sharedViewModel.showConversationEvent.value = Event(conversationId)
args.clear()
}
}

View file

@ -93,11 +93,11 @@ class StartConversationFragment : GenericAddressPickerFragment() {
}
viewModel.chatRoomCreatedEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
it.consume { conversationId ->
Log.i(
"$TAG Conversation [${pair.second}] for local address [${pair.first}] has been created, navigating to it"
"$TAG Conversation [$conversationId] has been created, navigating to it"
)
sharedViewModel.showConversationEvent.value = Event(pair)
sharedViewModel.showConversationEvent.value = Event(conversationId)
goBack()
}
}

View file

@ -48,7 +48,7 @@ class ConversationModel
private const val TAG = "[Conversation Model]"
}
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
val localSipUri = chatRoom.localAddress.asStringUriOnly()

View file

@ -28,8 +28,6 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.core.Address
import org.linphone.core.ChatRoom
import org.linphone.core.ConferenceParams
import org.linphone.core.Factory
import org.linphone.core.MediaDirection
import org.linphone.core.tools.Log
import org.linphone.ui.GenericViewModel
@ -51,9 +49,7 @@ abstract class AbstractConversationViewModel : GenericViewModel() {
lateinit var chatRoom: ChatRoom
lateinit var localSipUri: String
lateinit var remoteSipUri: String
lateinit var conversationId: String
fun isChatRoomInitialized(): Boolean {
return ::chatRoom.isInitialized
@ -68,17 +64,13 @@ abstract class AbstractConversationViewModel : GenericViewModel() {
}
@UiThread
fun findChatRoom(room: ChatRoom?, localSipUri: String, remoteSipUri: String) {
this.localSipUri = localSipUri
this.remoteSipUri = remoteSipUri
fun findChatRoom(room: ChatRoom?, conversationId: String) {
coreContext.postOnCoreThread { core ->
Log.i(
"$TAG Looking for conversation with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
Log.i("$TAG Looking for conversation with conversation ID [$conversationId]")
if (room != null && ::chatRoom.isInitialized && chatRoom == room) {
Log.i("$TAG Conversation object already in memory, skipping")
this@AbstractConversationViewModel.conversationId = conversationId
beforeNotifyingChatRoomFound(sameOne = true)
chatRoomFoundEvent.postValue(Event(true))
afterNotifyingChatRoomFound(sameOne = true)
@ -86,17 +78,12 @@ abstract class AbstractConversationViewModel : GenericViewModel() {
return@postOnCoreThread
}
val localAddress = Factory.instance().createAddress(localSipUri)
val remoteAddress = Factory.instance().createAddress(remoteSipUri)
if (room != null && (!::chatRoom.isInitialized || chatRoom != room)) {
if (localAddress?.weakEqual(room.localAddress) == true && remoteAddress?.weakEqual(
room.peerAddress
) == true
) {
if (conversationId == LinphoneUtils.getConversationId(room)) {
Log.i("$TAG Conversation object available in sharedViewModel, using it")
chatRoom = room
this@AbstractConversationViewModel.conversationId = conversationId
beforeNotifyingChatRoomFound(sameOne = false)
chatRoomFoundEvent.postValue(Event(true))
afterNotifyingChatRoomFound(sameOne = false)
@ -105,18 +92,11 @@ abstract class AbstractConversationViewModel : GenericViewModel() {
}
}
if (localAddress != null && remoteAddress != null) {
if (conversationId.isNotEmpty()) {
Log.i("$TAG Searching for conversation in Core using local & peer SIP addresses")
val params: ConferenceParams? = null
val found = core.searchChatRoom(
params,
localAddress,
remoteAddress,
arrayOfNulls<Address>(
0
)
)
val found = core.searchChatRoomByIdentifier(conversationId)
if (found != null) {
this@AbstractConversationViewModel.conversationId = conversationId
if (::chatRoom.isInitialized && chatRoom == found) {
Log.i("$TAG Conversation object already in memory, keeping it")
beforeNotifyingChatRoomFound(sameOne = true)

View file

@ -58,7 +58,7 @@ class ConversationDocumentsListViewModel
val list = arrayListOf<FileModel>()
Log.i(
"$TAG Loading document contents for conversation [${LinphoneUtils.getChatRoomId(
"$TAG Loading document contents for conversation [${LinphoneUtils.getConversationId(
chatRoom
)}]"
)

View file

@ -48,8 +48,8 @@ class ConversationForwardMessageViewModel
val operationInProgress = MutableLiveData<Boolean>()
val chatRoomCreatedEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val chatRoomCreatedEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val showNumberOrAddressPickerDialogEvent: MutableLiveData<Event<ArrayList<ContactNumberOrAddressModel>>> by lazy {
@ -83,21 +83,14 @@ class ConversationForwardMessageViewModel
val state = chatRoom.state
if (state == ChatRoom.State.Instantiated) return
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation [$id] (${chatRoom.subject}) state changed: [$state]")
if (state == ChatRoom.State.Created) {
Log.i("$TAG Conversation [$id] successfully created")
chatRoom.removeListener(this)
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else if (state == ChatRoom.State.CreationFailed) {
Log.e("$TAG Conversation [$id] creation has failed!")
chatRoom.removeListener(this)
@ -128,16 +121,9 @@ class ConversationForwardMessageViewModel
@UiThread
fun handleClickOnModel(model: ConversationContactOrSuggestionModel) {
coreContext.postOnCoreThread { core ->
if (model.localAddress != null) {
if (model.conversationId.isNotEmpty()) {
Log.i("$TAG User clicked on an existing conversation")
chatRoomCreatedEvent.postValue(
Event(
Pair(
model.localAddress.asStringUriOnly(),
model.address.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(model.conversationId))
if (searchFilter.value.orEmpty().isNotEmpty()) {
// Clear filter after it was used
coreContext.postOnMainThread {
@ -230,33 +216,19 @@ class ConversationForwardMessageViewModel
if (chatRoom != null) {
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
if (chatRoom.state == ChatRoom.State.Created) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG 1-1 conversation [$id] has been created")
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.i("$TAG Conversation isn't in Created state yet, wait for it")
chatRoom.addListener(chatRoomListener)
}
} else {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation successfully created [$id]")
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
}
} else {
Log.e("$TAG Failed to create 1-1 conversation with [${remote.asStringUriOnly()}]!")
@ -268,14 +240,7 @@ class ConversationForwardMessageViewModel
"$TAG A 1-1 conversation between local account [${localAddress?.asStringUriOnly()}] and remote [${remote.asStringUriOnly()}] for given parameters already exists!"
)
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
existingChatRoom.localAddress.asStringUriOnly(),
existingChatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(existingChatRoom)))
}
}
}

View file

@ -151,7 +151,7 @@ class ConversationInfoViewModel
@WorkerThread
override fun onSubjectChanged(chatRoom: ChatRoom, eventLog: EventLog) {
Log.i(
"$TAG Conversation [${LinphoneUtils.getChatRoomId(chatRoom)}] has a new subject [${chatRoom.subject}]"
"$TAG Conversation [${LinphoneUtils.getConversationId(chatRoom)}] has a new subject [${chatRoom.subject}]"
)
showGreenToast(R.string.conversation_subject_changed_toast, R.drawable.check)
@ -218,7 +218,7 @@ class ConversationInfoViewModel
fun leaveGroup() {
coreContext.postOnCoreThread {
if (isChatRoomInitialized()) {
Log.i("$TAG Leaving conversation [${LinphoneUtils.getChatRoomId(chatRoom)}]")
Log.i("$TAG Leaving conversation [${LinphoneUtils.getConversationId(chatRoom)}]")
chatRoom.leave()
}
groupLeftEvent.postValue(Event(true))
@ -230,7 +230,7 @@ class ConversationInfoViewModel
coreContext.postOnCoreThread {
if (isChatRoomInitialized()) {
Log.i(
"$TAG Cleaning conversation [${LinphoneUtils.getChatRoomId(chatRoom)}] history"
"$TAG Cleaning conversation [${LinphoneUtils.getConversationId(chatRoom)}] history"
)
chatRoom.deleteHistory()
}
@ -280,7 +280,7 @@ class ConversationInfoViewModel
coreContext.postOnCoreThread {
val address = participantModel.address
Log.i(
"$TAG Removing participant [$address] from the conversation [${LinphoneUtils.getChatRoomId(
"$TAG Removing participant [$address] from the conversation [${LinphoneUtils.getConversationId(
chatRoom
)}]"
)
@ -301,7 +301,7 @@ class ConversationInfoViewModel
coreContext.postOnCoreThread {
val address = participantModel.address
Log.i(
"$TAG Granting admin rights to participant [$address] from the conversation [${LinphoneUtils.getChatRoomId(
"$TAG Granting admin rights to participant [$address] from the conversation [${LinphoneUtils.getConversationId(
chatRoom
)}]"
)
@ -322,7 +322,7 @@ class ConversationInfoViewModel
coreContext.postOnCoreThread {
val address = participantModel.address
Log.i(
"$TAG Removing admin rights from participant [$address] from the conversation [${LinphoneUtils.getChatRoomId(
"$TAG Removing admin rights from participant [$address] from the conversation [${LinphoneUtils.getConversationId(
chatRoom
)}]"
)

View file

@ -54,7 +54,7 @@ class ConversationMediaListViewModel
private fun loadMediaList() {
val list = arrayListOf<FileModel>()
Log.i(
"$TAG Loading media contents for conversation [${LinphoneUtils.getChatRoomId(
"$TAG Loading media contents for conversation [${LinphoneUtils.getConversationId(
chatRoom
)}]"
)

View file

@ -470,7 +470,7 @@ class ConversationViewModel
fun updateCurrentlyDisplayedConversation() {
coreContext.postOnCoreThread {
if (isChatRoomInitialized()) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i(
"$TAG Asking notifications manager not to notify messages for conversation [$id]"
)

View file

@ -54,7 +54,7 @@ class ConversationsListViewModel
state: ChatRoom.State?
) {
Log.i(
"$TAG Conversation [${LinphoneUtils.getChatRoomId(chatRoom)}] state changed [$state]"
"$TAG Conversation [${LinphoneUtils.getConversationId(chatRoom)}] state changed [$state]"
)
when (state) {
@ -66,7 +66,7 @@ class ConversationsListViewModel
@WorkerThread
override fun onMessageSent(core: Core, chatRoom: ChatRoom, message: ChatMessage) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
val found = conversations.value.orEmpty().find {
it.id == id
}
@ -85,7 +85,7 @@ class ConversationsListViewModel
chatRoom: ChatRoom,
messages: Array<out ChatMessage>
) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
val found = conversations.value.orEmpty().find {
it.id == id
}

View file

@ -55,8 +55,8 @@ class StartConversationViewModel
MutableLiveData<Event<Int>>()
}
val chatRoomCreatedEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val chatRoomCreatedEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
private val chatRoomListener = object : ChatRoomListenerStub() {
@ -65,21 +65,14 @@ class StartConversationViewModel
val state = chatRoom.state
if (state == ChatRoom.State.Instantiated) return
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation [$id] (${chatRoom.subject}) state changed: [$state]")
if (state == ChatRoom.State.Created) {
Log.i("$TAG Conversation [$id] successfully created")
chatRoom.removeListener(this)
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else if (state == ChatRoom.State.CreationFailed) {
Log.e("$TAG Conversation [$id] creation has failed!")
chatRoom.removeListener(this)
@ -138,19 +131,12 @@ class StartConversationViewModel
if (chatRoom != null) {
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
if (chatRoom.state == ChatRoom.State.Created) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i(
"$TAG Group conversation [$id] ($groupChatRoomSubject) has been created"
)
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.i(
"$TAG Conversation [$groupChatRoomSubject] isn't in Created state yet, wait for it"
@ -158,17 +144,10 @@ class StartConversationViewModel
chatRoom.addListener(chatRoomListener)
}
} else {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation successfully created [$id] ($groupChatRoomSubject)")
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
}
} else {
Log.e("$TAG Failed to create group conversation [$groupChatRoomSubject]!")
@ -242,33 +221,19 @@ class StartConversationViewModel
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
val state = chatRoom.state
if (state == ChatRoom.State.Created) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG 1-1 conversation [$id] has been created")
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.i("$TAG Conversation isn't in Created state yet (state is [$state]), wait for it")
chatRoom.addListener(chatRoomListener)
}
} else {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation successfully created [$id]")
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
}
} else {
Log.e("$TAG Failed to create 1-1 conversation with [${remote.asStringUriOnly()}]!")
@ -282,14 +247,7 @@ class StartConversationViewModel
"$TAG A 1-1 conversation between local account [${localAddress?.asStringUriOnly()}] and remote [${remote.asStringUriOnly()}] for given parameters already exists!"
)
operationInProgress.postValue(false)
chatRoomCreatedEvent.postValue(
Event(
Pair(
existingChatRoom.localAddress.asStringUriOnly(),
existingChatRoom.peerAddress.asStringUriOnly()
)
)
)
chatRoomCreatedEvent.postValue(Event(LinphoneUtils.getConversationId(existingChatRoom)))
}
}

View file

@ -188,9 +188,9 @@ class ContactFragment : SlidingPaneChildFragment() {
}
viewModel.goToConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
Log.i("$TAG Going to conversation [${pair.first}][${pair.second}]")
sharedViewModel.showConversationEvent.value = Event(pair)
it.consume { conversationId ->
Log.i("$TAG Going to conversation [$conversationId]")
sharedViewModel.showConversationEvent.value = Event(conversationId)
sharedViewModel.navigateToConversationsEvent.value = Event(true)
}
}

View file

@ -117,8 +117,8 @@ class ContactViewModel
MutableLiveData<Event<String>>()
}
val goToConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val goToConversationEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val vCardTerminatedEvent: MutableLiveData<Event<Pair<String, File>>> by lazy {
@ -198,21 +198,14 @@ class ContactViewModel
val state = chatRoom.state
if (state == ChatRoom.State.Instantiated) return
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation [$id] (${chatRoom.subject}) state changed: [$state]")
if (state == ChatRoom.State.Created) {
Log.i("$TAG Conversation [$id] successfully created")
chatRoom.removeListener(this)
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else if (state == ChatRoom.State.CreationFailed) {
Log.e("$TAG Conversation [$id] creation has failed!")
chatRoom.removeListener(this)
@ -543,13 +536,11 @@ class ContactViewModel
val existingChatRoom = core.searchChatRoom(params, localAddress, null, participants)
if (existingChatRoom != null) {
Log.i(
"$TAG Found existing conversation [${LinphoneUtils.getChatRoomId(
"$TAG Found existing conversation [${LinphoneUtils.getConversationId(
existingChatRoom
)}], going to it"
)
goToConversationEvent.postValue(
Event(Pair(localSipUri, existingChatRoom.peerAddress.asStringUriOnly()))
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(existingChatRoom)))
} else {
Log.i(
"$TAG No existing conversation between [$localSipUri] and [$remoteSipUri] was found, let's create it"
@ -559,33 +550,19 @@ class ContactViewModel
if (chatRoom != null) {
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
if (chatRoom.state == ChatRoom.State.Created) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG 1-1 conversation [$id] has been created")
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.i("$TAG Conversation isn't in Created state yet, wait for it")
chatRoom.addListener(chatRoomListener)
}
} else {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation successfully created [$id]")
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
}
} else {
Log.e(

View file

@ -148,23 +148,20 @@ class HistoryFragment : SlidingPaneChildFragment() {
}
viewModel.goToConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
Log.i("$TAG Going to conversation [${pair.first}][${pair.second}]")
sharedViewModel.showConversationEvent.value = Event(pair)
it.consume { conversationId ->
Log.i("$TAG Going to conversation [$conversationId]")
sharedViewModel.showConversationEvent.value = Event(conversationId)
sharedViewModel.navigateToConversationsEvent.value = Event(true)
}
}
viewModel.goToMeetingConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
val localAddress = pair.first
val remoteAddress = pair.second
it.consume { conversationId ->
if (findNavController().currentDestination?.id == R.id.historyFragment) {
Log.i("$TAG Going to meeting conversation [$localAddress][$remoteAddress]")
Log.i("$TAG Going to meeting conversation [$conversationId]")
val action =
HistoryFragmentDirections.actionHistoryFragmentToConferenceConversationFragment(
localAddress,
remoteAddress
conversationId
)
findNavController().navigate(action)
}

View file

@ -69,12 +69,12 @@ class HistoryViewModel
MutableLiveData<Event<Int>>()
}
val goToMeetingConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val goToMeetingConversationEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val goToConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val goToConversationEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val conferenceToJoinEvent: MutableLiveData<Event<String>> by lazy {
@ -111,21 +111,14 @@ class HistoryViewModel
val state = chatRoom.state
if (state == ChatRoom.State.Instantiated) return
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation [$id] (${chatRoom.subject}) state changed: [$state]")
if (state == ChatRoom.State.Created) {
Log.i("$TAG Conversation [$id] successfully created")
chatRoom.removeListener(this)
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else if (state == ChatRoom.State.CreationFailed) {
Log.e("$TAG Conversation [$id] creation has failed!")
chatRoom.removeListener(this)
@ -212,14 +205,7 @@ class HistoryViewModel
coreContext.postOnCoreThread {
val chatRoom = meetingChatRoom
if (chatRoom != null) {
goToMeetingConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToMeetingConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.e("$TAG Failed to find chat room for current call log!")
}
@ -279,13 +265,11 @@ class HistoryViewModel
val existingChatRoom = core.searchChatRoom(params, localAddress, null, participants)
if (existingChatRoom != null) {
Log.i(
"$TAG Found existing conversation [${LinphoneUtils.getChatRoomId(
"$TAG Found existing conversation [${LinphoneUtils.getConversationId(
existingChatRoom
)}], going to it"
)
goToConversationEvent.postValue(
Event(Pair(localSipUri, existingChatRoom.peerAddress.asStringUriOnly()))
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(existingChatRoom)))
} else {
Log.i(
"$TAG No existing conversation between [$localSipUri] and [$remoteSipUri] was found, let's create it"
@ -295,33 +279,19 @@ class HistoryViewModel
if (chatRoom != null) {
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
if (chatRoom.state == ChatRoom.State.Created) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG 1-1 conversation [$id] has been created")
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
} else {
Log.i("$TAG Conversation isn't in Created state yet, wait for it")
chatRoom.addListener(chatRoomListener)
}
} else {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Conversation successfully created [$id]")
operationInProgress.postValue(false)
goToConversationEvent.postValue(
Event(
Pair(
chatRoom.localAddress.asStringUriOnly(),
chatRoom.peerAddress.asStringUriOnly()
)
)
)
goToConversationEvent.postValue(Event(LinphoneUtils.getConversationId(chatRoom)))
}
} else {
Log.e(

View file

@ -32,7 +32,7 @@ class ConversationContactOrSuggestionModel
@WorkerThread
constructor(
val address: Address,
val localAddress: Address? = null,
val conversationId: String = "",
conversationSubject: String? = null,
val friend: Friend? = null,
private val onClicked: ((Address) -> Unit)? = null

View file

@ -343,6 +343,7 @@ abstract class AddressSelectionViewModel
if (chatRoom.isReadOnly || (!isBasic && chatRoom.participants.isEmpty())) continue
val isOneToOne = chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt())
val conversationId = LinphoneUtils.getConversationId(chatRoom)
val remoteAddress = chatRoom.peerAddress
val matchesFilter: Any? = if (filter.isEmpty()) {
null
@ -383,7 +384,6 @@ abstract class AddressSelectionViewModel
}
}
if (filter.isEmpty() || matchesFilter != null) {
val localAddress = chatRoom.localAddress
val friend = if (isBasic) {
coreContext.contactsManager.findContactByAddress(remoteAddress)
} else {
@ -410,7 +410,7 @@ abstract class AddressSelectionViewModel
}
val model = ConversationContactOrSuggestionModel(
remoteAddress,
localAddress,
conversationId,
subject,
friend
)

View file

@ -118,8 +118,9 @@ class SharedMainViewModel
}
var displayedChatRoom: ChatRoom? = null // Prevents the need to go look for the chat room
val showConversationEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
val showConversationEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val hideConversationEvent: MutableLiveData<Event<Boolean>> by lazy {

View file

@ -439,40 +439,8 @@ class LinphoneUtils {
}
@WorkerThread
fun getChatRoomId(room: ChatRoom): String {
return getChatRoomId(room.localAddress, room.peerAddress)
}
@WorkerThread
fun getChatRoomId(localAddress: Address, remoteAddress: Address): String {
val localSipUri = localAddress.clone()
localSipUri.clean()
val remoteSipUri = remoteAddress.clone()
remoteSipUri.clean()
return getChatRoomId(localSipUri.asStringUriOnly(), remoteSipUri.asStringUriOnly())
}
@AnyThread
fun getChatRoomId(localSipUri: String, remoteSipUri: String): String {
return "$localSipUri$CHAT_ROOM_ID_SEPARATOR$remoteSipUri"
}
@AnyThread
fun getLocalAndPeerSipUrisFromChatRoomId(id: String): Pair<String, String>? {
val split = id.split(CHAT_ROOM_ID_SEPARATOR)
if (split.size == 2) {
val localAddress = split[0]
val peerAddress = split[1]
Log.i(
"$TAG Got local [$localAddress] and peer [$peerAddress] SIP URIs from conversation id [$id]"
)
return Pair(localAddress, peerAddress)
} else {
Log.e(
"$TAG Failed to parse conversation id [$id] with separator [$CHAT_ROOM_ID_SEPARATOR]"
)
}
return null
fun getConversationId(chatRoom: ChatRoom): String {
return chatRoom.identifier ?: ""
}
@WorkerThread

View file

@ -37,6 +37,8 @@ import org.linphone.core.ChatRoom
import org.linphone.core.tools.Log
import org.linphone.mediastream.Version
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.MainActivity.Companion.ARGUMENTS_CHAT
import org.linphone.ui.main.MainActivity.Companion.ARGUMENTS_CONVERSATION_ID
class ShortcutUtils {
companion object {
@ -44,7 +46,7 @@ class ShortcutUtils {
@WorkerThread
fun removeShortcutToChatRoom(chatRoom: ChatRoom) {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
Log.i("$TAG Removing shortcut to conversation [$id]")
ShortcutManagerCompat.removeLongLivedShortcuts(coreContext.context, arrayListOf(id))
}
@ -67,7 +69,7 @@ class ShortcutUtils {
for (chatRoom in defaultAccount.chatRooms) {
if (defaultAccount.params.instantMessagingEncryptionMandatory && !chatRoom.currentParams.isEncryptionEnabled) {
Log.w(
"$TAG Account is in secure mode, skipping not encrypted conversation [${LinphoneUtils.getChatRoomId(
"$TAG Account is in secure mode, skipping not encrypted conversation [${LinphoneUtils.getConversationId(
chatRoom
)}]"
)
@ -99,9 +101,8 @@ class ShortcutUtils {
@WorkerThread
private fun createChatRoomShortcut(context: Context, chatRoom: ChatRoom): ShortcutInfoCompat? {
val localAddress = chatRoom.localAddress
val peerAddress = chatRoom.peerAddress
val id = LinphoneUtils.getChatRoomId(localAddress, peerAddress)
val id = LinphoneUtils.getConversationId(chatRoom)
try {
val categories: ArraySet<String> = ArraySet()
@ -145,19 +146,14 @@ class ShortcutUtils {
val persons = arrayOfNulls<Person>(personsList.size)
personsList.toArray(persons)
val localSipUri = localAddress.asStringUriOnly()
val peerSipUri = peerAddress.asStringUriOnly()
val args = Bundle()
args.putString("RemoteSipUri", peerSipUri)
args.putString("LocalSipUri", localSipUri)
args.putString(ARGUMENTS_CONVERSATION_ID, id)
val intent = Intent(Intent.ACTION_MAIN)
intent.setClass(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.putExtra("Chat", true)
intent.putExtra("RemoteSipUri", peerSipUri)
intent.putExtra("LocalSipUri", localSipUri)
intent.putExtra(ARGUMENTS_CHAT, true)
intent.putExtra(ARGUMENTS_CONVERSATION_ID, id)
return ShortcutInfoCompat.Builder(context, id)
.setShortLabel(subject)
@ -177,7 +173,7 @@ class ShortcutUtils {
@WorkerThread
fun isShortcutToChatRoomAlreadyCreated(context: Context, chatRoom: ChatRoom): Boolean {
val id = LinphoneUtils.getChatRoomId(chatRoom)
val id = LinphoneUtils.getConversationId(chatRoom)
val found = ShortcutManagerCompat.getDynamicShortcuts(context).find {
it.id == id
}

View file

@ -191,10 +191,7 @@
android:label="ConversationFragment"
tools:layout="@layout/chat_conversation_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
android:name="conversationId"
app:argType="string" />
</fragment>

View file

@ -17,10 +17,7 @@
android:label="ConversationFragment"
tools:layout="@layout/chat_conversation_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
android:name="conversationId"
app:argType="string" />
<action
android:id="@+id/action_conversationFragment_to_conversationInfoFragment"
@ -80,10 +77,7 @@
android:label="ConversationInfoFragment"
tools:layout="@layout/chat_info_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
android:name="conversationId"
app:argType="string" />
<action
android:id="@+id/action_conversationInfoFragment_to_addParticipantsFragment"
@ -147,10 +141,7 @@
android:label="ConversationMediaListFragment"
tools:layout="@layout/chat_media_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
android:name="conversationId"
app:argType="string" />
</fragment>
@ -160,10 +151,7 @@
android:label="ConversationDocumentsListFragment"
tools:layout="@layout/chat_documents_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
android:name="conversationId"
app:argType="string" />
</fragment>

View file

@ -48,10 +48,7 @@
android:label="ConferenceConversationFragment"
tools:layout="@layout/chat_conversation_fragment">
<argument
android:name="localSipUri"
app:argType="string" />
<argument
android:name="remoteSipUri"
android:name="conversationId"
app:argType="string" />
</fragment>