Reworked click on SIP URI in chat message to prevent long press on it from starting the call

This commit is contained in:
Sylvain Berfini 2025-05-13 14:02:45 +02:00
parent df9a346de5
commit 34af601090
4 changed files with 35 additions and 15 deletions

View file

@ -94,6 +94,7 @@ import org.linphone.utils.hideKeyboard
import org.linphone.utils.setKeyboardInsetListener
import org.linphone.utils.showKeyboard
import androidx.core.net.toUri
import androidx.lifecycle.observe
@UiThread
open class ConversationFragment : SlidingPaneChildFragment() {
@ -766,6 +767,19 @@ open class ConversationFragment : SlidingPaneChildFragment() {
}
}
viewModel.sipUriToCallEvent.observe(viewLifecycleOwner) {
it.consume { sipUri ->
if (messageLongPressViewModel.visible.value == true) return@consume
val address = coreContext.core.interpretUrl(sipUri, false)
if (address != null) {
Log.i("$TAG Starting audio call to parsed SIP URI [${address.asStringUriOnly()}]")
coreContext.startAudioCall(address)
} else {
Log.w("$TAG Failed to parse [$sipUri] as SIP URI")
}
}
}
viewModel.conferenceToJoinEvent.observe(viewLifecycleOwner) {
it.consume { conferenceUri ->
if (messageLongPressViewModel.visible.value == true) return@consume

View file

@ -34,6 +34,7 @@ class EventLogModel
isGroupedWithNextOne: Boolean = false,
currentFilter: String = "",
onContentClicked: ((fileModel: FileModel) -> Unit)? = null,
onSipUriClicked: ((uri: String) -> Unit)? = null,
onJoinConferenceClicked: ((uri: String) -> Unit)? = null,
onWebUrlClicked: ((url: String) -> Unit)? = null,
onContactClicked: ((friendRefKey: String) -> Unit)? = null,
@ -86,6 +87,7 @@ class EventLogModel
isGroupedWithNextOne,
currentFilter,
onContentClicked,
onSipUriClicked,
onJoinConferenceClicked,
onWebUrlClicked,
onContactClicked,

View file

@ -79,6 +79,7 @@ class MessageModel
isGroupedWithNextOne: Boolean,
private val currentFilter: String = "",
private val onContentClicked: ((fileModel: FileModel) -> Unit)? = null,
private val onSipUriClicked: ((uri: String) -> Unit)? = null,
private val onJoinConferenceClicked: ((uri: String) -> Unit)? = null,
private val onWebUrlClicked: ((url: String) -> Unit)? = null,
private val onContactClicked: ((friendRefKey: String) -> Unit)? = null,
@ -673,8 +674,8 @@ class MessageModel
spannableBuilder.replace(start, end, "@$displayName")
val span = PatternClickableSpan.StyledClickableSpan(
object :
SpannableClickedListener {
object : SpannableClickedListener {
@UiThread
override fun onSpanClicked(text: String) {
val friendRefKey = friend.refKey ?: ""
Log.i(
@ -707,12 +708,7 @@ class MessageModel
override fun onSpanClicked(text: String) {
coreContext.postOnCoreThread {
Log.i("$TAG Clicked on SIP URI: $text")
val address = coreContext.core.interpretUrl(text, false)
if (address != null) {
coreContext.startAudioCall(address)
} else {
Log.w("$TAG Failed to parse [$text] as SIP URI")
}
onSipUriClicked?.invoke(text)
}
}
}
@ -722,6 +718,7 @@ class MessageModel
HTTP_LINK_REGEXP
),
object : SpannableClickedListener {
@UiThread
override fun onSpanClicked(text: String) {
Log.i("$TAG Clicked on web URL: $text")
onWebUrlClicked?.invoke(text)

View file

@ -111,6 +111,10 @@ class ConversationViewModel
MutableLiveData<Event<FileModel>>()
}
val sipUriToCallEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val conferenceToJoinEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
@ -763,25 +767,28 @@ class ConversationViewModel
index > 0,
index != groupedEventLogs.size - 1,
searchFilter.value.orEmpty(),
{ fileModel ->
{ fileModel -> // onContentClicked
fileToDisplayEvent.postValue(Event(fileModel))
},
{ conferenceUri ->
{ sipUri -> // onSipUriClicked
sipUriToCallEvent.postValue(Event(sipUri))
},
{ conferenceUri -> // onJoinConferenceClicked
conferenceToJoinEvent.postValue(Event(conferenceUri))
},
{ url ->
{ url -> // onWebUrlClicked
openWebBrowserEvent.postValue(Event(url))
},
{ friendRefKey ->
{ friendRefKey -> // onContactClicked
contactToDisplayEvent.postValue(Event(friendRefKey))
},
{ redToast ->
{ redToast -> // onRedToastToShow
showRedToastEvent.postValue(Event(redToast))
},
{ id ->
{ id -> // onVoiceRecordingPlaybackEnded
voiceRecordPlaybackEndedEvent.postValue(Event(id))
},
{ filePath ->
{ filePath -> // onFileToExportToNativeGallery
viewModelScope.launch {
withContext(Dispatchers.IO) {
Log.i("$TAG Export file [$filePath] to Android's MediaStore")