From fcf2ffa39c99f095c57389ded9504c2caf0511c9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Mar 2024 18:18:42 +0100 Subject: [PATCH] Added dialog asking whether to cancel the meeting or not when deleting it --- .../main/meetings/fragment/MeetingFragment.kt | 38 +- .../meetings/viewmodel/MeetingViewModel.kt | 68 +- .../java/org/linphone/utils/DialogUtils.kt | 17 + .../main/res/layout/dialog_cancel_meeting.xml | 103 +++ app/src/main/res/layout/meeting_fragment.xml | 607 +++++++++--------- app/src/main/res/values-fr/strings.xml | 4 + app/src/main/res/values/strings.xml | 4 + 7 files changed, 540 insertions(+), 301 deletions(-) create mode 100644 app/src/main/res/layout/dialog_cancel_meeting.xml diff --git a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt index 78747ae95..bed84bc8e 100644 --- a/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/meetings/fragment/MeetingFragment.kt @@ -43,7 +43,9 @@ import org.linphone.databinding.MeetingFragmentBinding import org.linphone.databinding.MeetingPopupMenuBinding import org.linphone.ui.main.MainActivity import org.linphone.ui.main.fragment.SlidingPaneChildFragment +import org.linphone.ui.main.history.model.ConfirmationDialogModel import org.linphone.ui.main.meetings.viewmodel.MeetingViewModel +import org.linphone.utils.DialogUtils import org.linphone.utils.Event @UiThread @@ -153,6 +155,13 @@ class MeetingFragment : SlidingPaneChildFragment() { goBack() } } + + viewModel.conferenceCancelledEvent.observe(viewLifecycleOwner) { + it.consume { + Log.i("$TAG Meeting has been cancelled successfully, deleting it") + viewModel.delete() + } + } } private fun showPopupMenu() { @@ -170,7 +179,11 @@ class MeetingFragment : SlidingPaneChildFragment() { ) popupView.setDeleteClickListener { - viewModel.delete() + if (viewModel.isEditable.value == true) { + showCancelMeetingDialog() + } else { + viewModel.delete() + } popupWindow.dismiss() } @@ -224,4 +237,27 @@ class MeetingFragment : SlidingPaneChildFragment() { Log.e("$TAG No activity found to handle intent: $exception") } } + + private fun showCancelMeetingDialog() { + Log.i("$TAG Meeting is editable, asking whether to cancel it or not before deleting it") + + val model = ConfirmationDialogModel() + val dialog = DialogUtils.getCancelMeetingDialog(requireContext(), model) + + model.dismissEvent.observe(viewLifecycleOwner) { + it.consume { + viewModel.delete() + dialog.dismiss() + } + } + + model.confirmEvent.observe(viewLifecycleOwner) { + it.consume { + viewModel.cancel() + dialog.dismiss() + } + } + + dialog.show() + } } diff --git a/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingViewModel.kt b/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingViewModel.kt index 858d87045..a79e958b1 100644 --- a/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/meetings/viewmodel/MeetingViewModel.kt @@ -27,7 +27,11 @@ import java.util.Locale import java.util.TimeZone import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R +import org.linphone.core.Address +import org.linphone.core.ChatRoom import org.linphone.core.ConferenceInfo +import org.linphone.core.ConferenceScheduler +import org.linphone.core.ConferenceSchedulerListenerStub import org.linphone.core.Factory import org.linphone.core.Participant import org.linphone.core.tools.Log @@ -66,14 +70,61 @@ class MeetingViewModel @UiThread constructor() : ViewModel() { val startTimeStamp = MutableLiveData() val endTimeStamp = MutableLiveData() + val operationInProgress = MutableLiveData() + + val conferenceCancelledEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + val conferenceInfoDeletedEvent: MutableLiveData> by lazy { MutableLiveData>() } + private val conferenceSchedulerListener = object : ConferenceSchedulerListenerStub() { + override fun onStateChanged( + conferenceScheduler: ConferenceScheduler, + state: ConferenceScheduler.State? + ) { + Log.i("$TAG Conference scheduler state is $state") + if (state == ConferenceScheduler.State.Ready) { + Log.i( + "$TAG Conference ${conferenceScheduler.info?.subject} cancelled" + ) + val chatRoomParams = coreContext.core.createDefaultChatRoomParams() + chatRoomParams.isGroupEnabled = false + chatRoomParams.backend = ChatRoom.Backend.FlexisipChat + chatRoomParams.isEncryptionEnabled = true + chatRoomParams.subject = "Meeting cancelled" // Won't be used + conferenceScheduler.sendInvitations(chatRoomParams) // Send cancel ICS + + operationInProgress.postValue(false) + conferenceCancelledEvent.postValue(Event(true)) + } + } + + override fun onInvitationsSent( + conferenceScheduler: ConferenceScheduler, + failedInvitations: Array? + ) { + if (failedInvitations?.isNotEmpty() == true) { + for (address in failedInvitations) { + Log.e( + "$TAG Conference cancelled ICS wasn't sent to participant ${address.asStringUriOnly()}" + ) + } + } else { + Log.i( + "$TAG Conference cancelled ICS successfully sent to all participants" + ) + } + conferenceScheduler.removeListener(this) + } + } + private lateinit var conferenceInfo: ConferenceInfo - override fun onCleared() { - super.onCleared() + init { + operationInProgress.value = false } @UiThread @@ -109,6 +160,19 @@ class MeetingViewModel @UiThread constructor() : ViewModel() { } } + @UiThread + fun cancel() { + coreContext.postOnCoreThread { core -> + if (::conferenceInfo.isInitialized) { + Log.i("$TAG Cancelling conference information [$conferenceInfo]") + operationInProgress.postValue(true) + val conferenceScheduler = core.createConferenceScheduler() + conferenceScheduler.addListener(conferenceSchedulerListener) + conferenceScheduler.cancelConference(conferenceInfo) + } + } + } + @WorkerThread private fun configureConferenceInfo() { if (::conferenceInfo.isInitialized) { diff --git a/app/src/main/java/org/linphone/utils/DialogUtils.kt b/app/src/main/java/org/linphone/utils/DialogUtils.kt index 002e48b16..4eba289db 100644 --- a/app/src/main/java/org/linphone/utils/DialogUtils.kt +++ b/app/src/main/java/org/linphone/utils/DialogUtils.kt @@ -36,6 +36,7 @@ import org.linphone.databinding.DialogAccountModesExplanationBinding import org.linphone.databinding.DialogAssistantAcceptConditionsAndPolicyBinding import org.linphone.databinding.DialogAssistantCreateAccountConfirmPhoneNumberBinding import org.linphone.databinding.DialogCancelContactChangesBinding +import org.linphone.databinding.DialogCancelMeetingBinding import org.linphone.databinding.DialogConfirmZrtpSasBinding import org.linphone.databinding.DialogContactConfirmTrustCallBinding import org.linphone.databinding.DialogContactTrustProcessBinding @@ -337,6 +338,22 @@ class DialogUtils { return getDialog(context, binding) } + @UiThread + fun getCancelMeetingDialog( + context: Context, + viewModel: ConfirmationDialogModel + ): Dialog { + val binding: DialogCancelMeetingBinding = DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.dialog_cancel_meeting, + null, + false + ) + binding.viewModel = viewModel + + return getDialog(context, binding) + } + @UiThread private fun getDialog(context: Context, binding: ViewDataBinding): Dialog { val dialog = Dialog(context, R.style.Theme_LinphoneDialog) diff --git a/app/src/main/res/layout/dialog_cancel_meeting.xml b/app/src/main/res/layout/dialog_cancel_meeting.xml new file mode 100644 index 000000000..9036c9aef --- /dev/null +++ b/app/src/main/res/layout/dialog_cancel_meeting.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/meeting_fragment.xml b/app/src/main/res/layout/meeting_fragment.xml index f240fefed..eb9dced55 100644 --- a/app/src/main/res/layout/meeting_fragment.xml +++ b/app/src/main/res/layout/meeting_fragment.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:bind="http://schemas.android.com/tools"> @@ -24,329 +25,339 @@ type="org.linphone.ui.main.meetings.viewmodel.MeetingViewModel" /> - + android:layout_height="match_parent"> - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4d821fcff..54a6ae6a8 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -34,6 +34,8 @@ Fermer Installer Ne plus me montrer ce message + Non + Oui &appName; notifications d\'appels en cours &appName; notifications d\'appels entrants @@ -474,6 +476,8 @@ Description Créer Modifier la réunion + Annuler la réunion? + Voulez-vous annuler la réunion et envoyer une notification aux participants? Rejoindre diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 84e1b5e57..7874ea720 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -71,6 +71,8 @@ Close Install Do not show this dialog anymore + No + Yes &appName; active calls notifications @@ -523,6 +525,8 @@ Description Create Edit meeting + Cancel the meeting? + Do you want to cancel the meeting and send a notification to all participants? Join