diff --git a/app/src/main/java/org/linphone/ui/assistant/fragment/SingleSignOnFragment.kt b/app/src/main/java/org/linphone/ui/assistant/fragment/SingleSignOnFragment.kt index 9b893e0c2..c3e6d3fde 100644 --- a/app/src/main/java/org/linphone/ui/assistant/fragment/SingleSignOnFragment.kt +++ b/app/src/main/java/org/linphone/ui/assistant/fragment/SingleSignOnFragment.kt @@ -88,7 +88,10 @@ class SingleSignOnFragment : Fragment() { viewModel.onErrorEvent.observe(viewLifecycleOwner) { it.consume { errorMessage -> - (requireActivity() as AssistantActivity).showRedToast(errorMessage, R.drawable.x) + (requireActivity() as AssistantActivity).showRedToast( + errorMessage, + R.drawable.warning_circle + ) findNavController().popBackStack() } } diff --git a/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt index 048dbe310..c50fc4263 100644 --- a/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/fragment/ActiveCallFragment.kt @@ -355,7 +355,7 @@ class ActiveCallFragment : GenericCallFragment() { it.consume { error -> (requireActivity() as CallActivity).showRedToast( error, - R.drawable.x + R.drawable.warning_circle ) } } diff --git a/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt index 59f70b25e..1b550be15 100644 --- a/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/fragment/ConversationFragment.kt @@ -264,7 +264,10 @@ class ConversationFragment : GenericCallFragment() { Log.e("$TAG Failed to find conversation, going back") findNavController().popBackStack() val message = getString(R.string.toast_cant_find_conversation_to_display) - (requireActivity() as CallActivity).showRedToast(message, R.drawable.x) + (requireActivity() as CallActivity).showRedToast( + message, + R.drawable.warning_circle + ) } } else { sendMessageViewModel.configureChatRoom(viewModel.chatRoom) 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 f3aeaf88d..9674a9414 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 @@ -379,7 +379,10 @@ class ConversationFragment : SlidingPaneChildFragment() { Log.e("$TAG Failed to find conversation, going back") goBack() val message = getString(R.string.toast_cant_find_conversation_to_display) - (requireActivity() as MainActivity).showRedToast(message, R.drawable.x) + (requireActivity() as MainActivity).showRedToast( + message, + R.drawable.warning_circle + ) } } else { sendMessageViewModel.configureChatRoom(viewModel.chatRoom) diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt index 3f9d8dc4b..261007eae 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt @@ -116,7 +116,10 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { Log.e("$TAG Failed to find conversation, going back") goBack() val message = getString(R.string.toast_cant_find_conversation_to_display) - (requireActivity() as MainActivity).showRedToast(message, R.drawable.x) + (requireActivity() as MainActivity).showRedToast( + message, + R.drawable.warning_circle + ) } } } @@ -258,7 +261,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { } else { Log.e("$TAG Can't go to contact page, friend ref key is null or empty!") val message = getString(R.string.toast_cant_find_contact_to_display) - (requireActivity() as MainActivity).showRedToast(message, R.drawable.x) + (requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle) } } @@ -272,7 +275,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { } else { Log.e("$TAG Can't add empty/null SIP URI to contacts!") val message = getString(R.string.toast_no_address_to_add_to_contact) - (requireActivity() as MainActivity).showRedToast(message, R.drawable.x) + (requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle) } } @@ -337,7 +340,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { } else { Log.e("$TAG Can't go to contact page, friend ref key is null or empty!") val message = getString(R.string.toast_cant_find_contact_to_display) - (requireActivity() as MainActivity).showRedToast(message, R.drawable.x) + (requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle) } popupWindow.dismiss() } @@ -352,7 +355,7 @@ class ConversationInfoFragment : SlidingPaneChildFragment() { } else { Log.e("$TAG Can't add empty/null SIP URI to contacts!") val message = getString(R.string.toast_no_address_to_add_to_contact) - (requireActivity() as MainActivity).showRedToast(message, R.drawable.x) + (requireActivity() as MainActivity).showRedToast(message, R.drawable.warning_circle) } popupWindow.dismiss() } diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/EventModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/EventModel.kt index d09231583..eb59a0f7b 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/EventModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/EventModel.kt @@ -95,7 +95,7 @@ class EventModel @WorkerThread constructor(private val eventLog: EventLog) { R.drawable.clock_countdown } EventLog.Type.ConferenceTerminated -> { - R.drawable.x + R.drawable.warning_circle } EventLog.Type.ConferenceSubjectChanged -> { R.drawable.pencil_simple 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 5217bfb35..c8d74746f 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 @@ -403,7 +403,7 @@ class ConversationInfoViewModel @UiThread constructor() : AbstractConversationVi val message = AppUtils.getString( R.string.toast_failed_to_add_participant_to_group_conversation ) - showRedToastEvent.postValue(Event(Pair(message, R.drawable.x))) + showRedToastEvent.postValue(Event(Pair(message, R.drawable.warning_circle))) } } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/SendMessageInConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/SendMessageInConversationViewModel.kt index 7367395e0..5d2d68469 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/SendMessageInConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/SendMessageInConversationViewModel.kt @@ -520,7 +520,7 @@ class SendMessageInConversationViewModel @UiThread constructor() : ViewModel() { val message = AppUtils.getString( R.string.toast_voice_recording_max_duration_reached ) - showRedToastEvent.postValue(Event(Pair(message, R.drawable.x))) + showRedToastEvent.postValue(Event(Pair(message, R.drawable.warning_circle))) } } }.launchIn(viewModelScope) diff --git a/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt b/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt index 2a29ff4d6..843c4590b 100644 --- a/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/file_media_viewer/fragment/MediaListViewerFragment.kt @@ -188,7 +188,10 @@ class MediaListViewerFragment : GenericFragment() { val message = AppUtils.getString( R.string.toast_export_file_to_media_store_error ) - (requireActivity() as MainActivity).showRedToast(message, R.drawable.x) + (requireActivity() as MainActivity).showRedToast( + message, + R.drawable.warning_circle + ) } } } diff --git a/app/src/main/java/org/linphone/ui/main/file_media_viewer/viewmodel/FileViewModel.kt b/app/src/main/java/org/linphone/ui/main/file_media_viewer/viewmodel/FileViewModel.kt index 6ce392c39..f7ace6fbb 100644 --- a/app/src/main/java/org/linphone/ui/main/file_media_viewer/viewmodel/FileViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/file_media_viewer/viewmodel/FileViewModel.kt @@ -221,7 +221,7 @@ class FileViewModel @UiThread constructor() : ViewModel() { val message = AppUtils.getString( R.string.toast_export_file_to_documents_error ) - showRedToastEvent.postValue(Event(Pair(message, R.drawable.x))) + showRedToastEvent.postValue(Event(Pair(message, R.drawable.warning_circle))) } } } @@ -246,7 +246,7 @@ class FileViewModel @UiThread constructor() : ViewModel() { val message = AppUtils.getString( R.string.toast_export_file_to_documents_error ) - showRedToastEvent.postValue(Event(Pair(message, R.drawable.x))) + showRedToastEvent.postValue(Event(Pair(message, R.drawable.warning_circle))) } } } diff --git a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingWaitingRoomFragment.kt b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingWaitingRoomFragment.kt index fafba6c4c..7074ad953 100644 --- a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingWaitingRoomFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingWaitingRoomFragment.kt @@ -126,9 +126,9 @@ class MeetingWaitingRoomFragment : GenericFragment() { } } - viewModel.conferenceCreatedEvent.observe(viewLifecycleOwner) { + viewModel.leaveWaitingRoomEvent.observe(viewLifecycleOwner) { it.consume { - Log.i("$TAG Conference was joined, leaving waiting room") + Log.i("$TAG Leaving waiting room") goBack() } } @@ -137,9 +137,9 @@ class MeetingWaitingRoomFragment : GenericFragment() { it.consume { Log.e("$TAG Error joining the conference!") val message = getString( - R.string.toast_no_app_registered_to_handle_content_type_error + R.string.toast_failed_to_join_conference ) - val icon = R.drawable.x + val icon = R.drawable.warning_circle (requireActivity() as MainActivity).showRedToast(message, icon) } } @@ -169,6 +169,7 @@ class MeetingWaitingRoomFragment : GenericFragment() { override fun onPause() { bottomSheetDialog?.dismiss() bottomSheetDialog = null + viewModel.joining.value = false coreContext.postOnCoreThread { core -> core.nativePreviewWindowId = null diff --git a/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingWaitingRoomViewModel.kt b/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingWaitingRoomViewModel.kt index 16e3d348f..2c7162287 100644 --- a/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingWaitingRoomViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingWaitingRoomViewModel.kt @@ -29,7 +29,9 @@ import androidx.lifecycle.ViewModel import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R +import org.linphone.core.Address import org.linphone.core.AudioDevice +import org.linphone.core.Call import org.linphone.core.Conference import org.linphone.core.ConferenceInfo import org.linphone.core.Core @@ -78,7 +80,7 @@ class MeetingWaitingRoomViewModel @UiThread constructor() : ViewModel() { MutableLiveData>>() } - val conferenceCreatedEvent: MutableLiveData> by lazy { + val leaveWaitingRoomEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -86,6 +88,7 @@ class MeetingWaitingRoomViewModel @UiThread constructor() : ViewModel() { MutableLiveData>() } + private lateinit var conferenceAddress: Address private lateinit var conferenceInfo: ConferenceInfo private lateinit var selectedOutputAudioDevice: AudioDevice @@ -95,18 +98,48 @@ class MeetingWaitingRoomViewModel @UiThread constructor() : ViewModel() { private var bluetoothAudioDevice: AudioDevice? = null private val coreListener = object : CoreListenerStub() { + @WorkerThread + override fun onCallStateChanged( + core: Core, + call: Call, + state: Call.State?, + message: String + ) { + if (::conferenceAddress.isInitialized && conferenceAddress.weakEqual(call.remoteAddress)) { + when (state) { + Call.State.End -> { + Log.i("$TAG Call has ended, leaving waiting room fragment") + leaveWaitingRoomEvent.postValue(Event(true)) + } + + Call.State.Error -> { + Log.w("$TAG Call has failed, leaving waiting room fragment") + leaveWaitingRoomEvent.postValue(Event(true)) + } + + else -> {} + } + } + } + + @WorkerThread override fun onConferenceStateChanged( core: Core, conference: Conference, state: Conference.State? ) { - Log.i("$TAG Conference state changed: [$state]") - if (conference.state == Conference.State.Created) { - conferenceCreatedEvent.postValue(Event(true)) - joining.postValue(false) - } else if (conference.state == Conference.State.CreationFailed) { - conferenceCreationError.postValue(Event(true)) - joining.postValue(false) + val remoteAddress = conference.conferenceAddress + if (::conferenceAddress.isInitialized && remoteAddress != null && conferenceAddress.weakEqual( + remoteAddress + ) + ) { + Log.i("$TAG Conference state changed: [$state]") + if (conference.state == Conference.State.Created) { + leaveWaitingRoomEvent.postValue(Event(true)) + } else if (conference.state == Conference.State.CreationFailed) { + conferenceCreationError.postValue(Event(true)) + joining.postValue(false) + } } } } @@ -144,6 +177,7 @@ class MeetingWaitingRoomViewModel @UiThread constructor() : ViewModel() { coreContext.postOnCoreThread { core -> val address = Factory.instance().createAddress(uri) if (address != null) { + conferenceAddress = address val found = core.findConferenceInformationFromUri(address) if (found != null) { Log.i("$TAG Conference info with SIP URI [$uri] was found") @@ -211,6 +245,27 @@ class MeetingWaitingRoomViewModel @UiThread constructor() : ViewModel() { } } + @UiThread + fun cancel() { + coreContext.postOnCoreThread { core -> + if (::conferenceAddress.isInitialized) { + val found = core.calls.find { + it.remoteAddress.weakEqual(conferenceAddress) + } + + if (found != null) { + coreContext.terminateCall(found) + } else { + Log.e( + "$TAG No call found matching conference address [${conferenceAddress.asStringUriOnly()}]" + ) + } + } else { + Log.e("$TAG No conference address stored!") + } + } + } + @UiThread fun switchCamera() { coreContext.postOnCoreThread { diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/CardDavViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/CardDavViewModel.kt index 5b5408368..113752334 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/CardDavViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/CardDavViewModel.kt @@ -79,7 +79,7 @@ class CardDavViewModel : ViewModel() { } FriendList.SyncStatus.Failure -> { syncInProgress.postValue(false) - val icon = R.drawable.x + val icon = R.drawable.warning_circle showErrorToastEvent.postValue(Event(Pair(icon, message.orEmpty()))) if (isEdit.value == false) { Log.e("$TAG Synchronization failed, removing Friend list from Core") @@ -148,7 +148,9 @@ class CardDavViewModel : ViewModel() { val server = serverUrl.value.orEmpty().trim() if (name.isEmpty() || server.isEmpty()) { // TODO: improve toast - showErrorToastEvent.postValue(Event(Pair(R.drawable.x, "Name or Server is empty!"))) + showErrorToastEvent.postValue( + Event(Pair(R.drawable.warning_circle, "Name or Server is empty!")) + ) return } diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt index 668e83842..2eb1924a5 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/LdapViewModel.kt @@ -173,7 +173,7 @@ class LdapViewModel : ViewModel() { Log.e("$TAG Exception while creating LDAP: $e") // TODO: improve toast showErrorToastEvent.postValue( - Event(Pair(R.drawable.x, e.toString())) + Event(Pair(R.drawable.warning_circle, e.toString())) ) } } diff --git a/app/src/main/res/layout-land/meeting_waiting_room_fragment.xml b/app/src/main/res/layout-land/meeting_waiting_room_fragment.xml index f101993dc..21e02f062 100644 --- a/app/src/main/res/layout-land/meeting_waiting_room_fragment.xml +++ b/app/src/main/res/layout-land/meeting_waiting_room_fragment.xml @@ -244,6 +244,24 @@ app:layout_constraintTop_toBottomOf="@id/joining_subtitle" app:layout_constraintBottom_toBottomOf="parent"/> + + diff --git a/app/src/main/res/layout/meeting_waiting_room_fragment.xml b/app/src/main/res/layout/meeting_waiting_room_fragment.xml index dbf0f3ffd..be8999327 100644 --- a/app/src/main/res/layout/meeting_waiting_room_fragment.xml +++ b/app/src/main/res/layout/meeting_waiting_room_fragment.xml @@ -240,6 +240,24 @@ app:layout_constraintTop_toBottomOf="@id/joining_subtitle" app:layout_constraintBottom_toBottomOf="parent"/> + + diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 37b595118..2078ed6cd 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -102,6 +102,7 @@ Appel en cours de transfert L\'appel a été transferré Le transfert a échoué ! + Echec lors de la connexion à la conférence! Configuration appliquée avec succès Erreur durant la récupération ou l\'application de la configuration @@ -499,6 +500,7 @@ La réunion a été annulée Rejoindre + Annuler Connexion à la réunion Vous allez rejoindre la réunion dans quelques instants… diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dbd550702..806ff4d6c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -137,6 +137,7 @@ Call is being transferred Call has been successfully transferred Call transfer failed! + Failed to join conference! Configuration successfully applied Error while trying to download and apply remote configuration @@ -535,6 +536,7 @@ Meeting has been cancelled Join + Cancel Connection in progress You\'ll be joining in a short moment