Added confirmation dialog when trying to call a particular contact device to increase trust

This commit is contained in:
Sylvain Berfini 2023-08-25 15:47:00 +02:00
parent ea155cd68c
commit 32c5f56be1
15 changed files with 304 additions and 44 deletions

View file

@ -41,6 +41,7 @@ import org.linphone.core.tools.Log
import org.linphone.databinding.ContactFragmentBinding
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
import org.linphone.ui.main.contacts.model.TrustCallDialogModel
import org.linphone.ui.main.contacts.viewmodel.ContactViewModel
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.DialogUtils
@ -178,6 +179,12 @@ class ContactFragment : GenericFragment() {
showTrustProcessDialog()
}
}
viewModel.startCallToDeviceToIncreaseTrustEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
showConfirmTrustCallDialog(pair.first, pair.second)
}
}
}
private fun copyNumberOrAddressToClipboard(value: String, isSip: Boolean) {
@ -225,4 +232,27 @@ class ContactFragment : GenericFragment() {
val dialog = DialogUtils.getContactTrustProcessExplanationDialog(requireActivity())
dialog.show()
}
private fun showConfirmTrustCallDialog(contact: String, device: String) {
val model = TrustCallDialogModel(contact, device)
val dialog = DialogUtils.getContactTrustCallConfirmationDialog(requireActivity(), model)
model.dismissEvent.observe(viewLifecycleOwner) {
it.consume {
dialog.dismiss()
}
}
model.confirmCallEvent.observe(viewLifecycleOwner) {
it.consume {
if (model.doNotShowAnymore.value == true) {
// TODO: never display this anymore
}
// TODO: start call
dialog.dismiss()
}
}
dialog.show()
}
}

View file

@ -23,10 +23,11 @@ import androidx.annotation.UiThread
class ContactDeviceModel @UiThread constructor(
val name: String,
val trusted: Boolean
val trusted: Boolean,
private val onCall: ((model: ContactDeviceModel) -> Unit)? = null
) {
@UiThread
fun startCallToDevice() {
// TODO
onCall?.invoke(this)
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.linphone.ui.main.contacts.model
import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData
import org.linphone.utils.Event
class TrustCallDialogModel @UiThread constructor(contact: String, device: String) {
val message = MutableLiveData<String>()
val doNotShowAnymore = MutableLiveData<Boolean>()
val dismissEvent = MutableLiveData<Event<Boolean>>()
val confirmCallEvent = MutableLiveData<Event<Boolean>>()
init {
message.value = "You're about to call $contact's device $device.\nAre you sure you want to make a call now?"
}
@UiThread
fun dismiss() {
dismissEvent.value = Event(true)
}
@UiThread
fun confirmCall() {
confirmCallEvent.value = Event(true)
}
}

View file

@ -88,6 +88,10 @@ class ContactViewModel @UiThread constructor() : ViewModel() {
MutableLiveData<Event<Boolean>>()
}
val startCallToDeviceToIncreaseTrustEvent: MutableLiveData<Event<Pair<String, String>>> by lazy {
MutableLiveData<Event<Pair<String, String>>>()
}
private val listener = object : ContactNumberOrAddressClickListener {
@UiThread
override fun onClicked(model: ContactNumberOrAddressModel) {
@ -219,7 +223,15 @@ class ContactViewModel @UiThread constructor() : ViewModel() {
// TODO FIXME: use real devices list from API
devicesList.add(ContactDeviceModel("Pixel 6 Pro de Sylvain", true))
devicesList.add(ContactDeviceModel("Sylvain Galaxy Tab S9 Pro+ Ultra", true))
devicesList.add(ContactDeviceModel("MacBook Pro de Marcel", false))
devicesList.add(
ContactDeviceModel("MacBook Pro de Marcel", false) {
// TODO: check if do not show dialog anymore setting is set
if (::friend.isInitialized) {
startCallToDeviceToIncreaseTrustEvent.value =
Event(Pair(friend.name.orEmpty(), it.name))
}
}
)
devicesList.add(ContactDeviceModel("sylvain@fedora-linux-38", true))
devices.postValue(devicesList)

View file

@ -33,11 +33,13 @@ import androidx.databinding.ViewDataBinding
import org.linphone.R
import org.linphone.databinding.DialogCancelContactChangesBinding
import org.linphone.databinding.DialogConfirmZrtpSasBinding
import org.linphone.databinding.DialogContactConfirmTrustCallBinding
import org.linphone.databinding.DialogContactTrustProcessBinding
import org.linphone.databinding.DialogPickNumberOrAddressBinding
import org.linphone.databinding.DialogRemoveAllCallLogsBinding
import org.linphone.ui.main.calls.model.ConfirmationDialogModel
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
import org.linphone.ui.main.contacts.model.TrustCallDialogModel
import org.linphone.ui.voip.model.ZrtpSasConfirmationDialogModel
class DialogUtils {
@ -58,6 +60,23 @@ class DialogUtils {
return getDialog(context, binding)
}
@UiThread
fun getContactTrustCallConfirmationDialog(
context: Context,
viewModel: TrustCallDialogModel
): Dialog {
val binding: DialogContactConfirmTrustCallBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.dialog_contact_confirm_trust_call,
null,
false
)
binding.viewModel = viewModel
return getDialog(context, binding)
}
@UiThread
fun getContactTrustProcessExplanationDialog(context: Context): Dialog {
val binding: DialogContactTrustProcessBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),

View file

@ -137,8 +137,8 @@
android:layout_marginTop="32dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="Login"
@ -210,8 +210,8 @@
android:layout_marginTop="22dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="Scan QR code"
@ -234,8 +234,8 @@
android:layout_marginTop="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="Use third party SIP account"
@ -252,8 +252,6 @@
android:id="@+id/no_account_yet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="No account yet?"
@ -274,8 +272,8 @@
android:layout_marginTop="40dp"
android:layout_marginStart="20dp"
android:layout_marginBottom="20dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="Register"

View file

@ -149,8 +149,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="Create"
@ -200,8 +200,6 @@
android:id="@+id/already_an_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="Already an account?"
@ -222,8 +220,8 @@
android:layout_marginTop="34dp"
android:layout_marginStart="20dp"
android:layout_marginBottom="20dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="Login"

View file

@ -47,7 +47,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="25dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="Don't save changes?"
android:textSize="16sp"
app:layout_constraintVertical_chainStyle="packed"
@ -101,8 +101,8 @@
android:layout_marginTop="16dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:gravity="center"
android:background="@drawable/primary_button_background"
android:text="Ok"
@ -116,7 +116,7 @@
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/confirm"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"

View file

@ -48,7 +48,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingTop="25dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="Vérifiez l'appareil"
android:textSize="16sp"
app:layout_constraintVertical_chainStyle="packed"
@ -165,8 +165,8 @@
android:layout_marginTop="45dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:gravity="center"
android:background="@drawable/shape_red_outlined_button_background"
android:text="Letters don't match!"
@ -180,7 +180,7 @@
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/nothing_matches"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="org.linphone.ui.main.contacts.model.TrustCallDialogModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:onClick="@{() -> viewModel.dismiss()}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="@+id/dialog_background_shadow"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/shape_dialog_orange_shadow"
app:layout_constraintBottom_toBottomOf="@id/anchor"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintTop_toTopOf="@id/dialog_background" />
<ImageView
android:id="@+id/dialog_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="2dp"
android:src="@drawable/shape_dialog_background"
app:layout_constraintBottom_toBottomOf="@id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style_800"
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="Increase trust level"
android:textSize="16sp"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toTopOf="@id/message"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:layout_marginTop="10dp"
android:text="@{viewModel.message, default=`You're about to make a call to %s's device %s.\nDo you want to make the call?`}"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/cancel"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{() -> viewModel.dismiss()}"
style="@style/default_text_style_600"
android:id="@+id/cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:gravity="center"
android:background="@drawable/secondary_button_background"
android:text="Cancel"
android:textSize="18sp"
android:textColor="@color/secondary_button_label_color"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/message"
app:layout_constraintBottom_toTopOf="@id/confirm"/>
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{() -> viewModel.confirmCall()}"
style="@style/default_text_style_600"
android:id="@+id/confirm"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:gravity="center"
android:background="@drawable/primary_button_background"
android:text="Call"
android:textSize="18sp"
android:textColor="@color/primary_button_label_color"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/cancel"
app:layout_constraintBottom_toTopOf="@id/do_not_show_anymore"/>
<androidx.appcompat.widget.AppCompatCheckBox
style="@style/default_text_style"
android:id="@+id/do_not_show_anymore"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:text="Don't show this dialog anymore"
android:textSize="14sp"
android:checked="@={viewModel.doNotShowAnymore}"
app:buttonTint="@color/primary_color"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/confirm"
app:layout_constraintBottom_toTopOf="@id/anchor" />
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/do_not_show_anymore"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -46,7 +46,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="25dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="What does it mean?"
android:textSize="16sp"
app:layout_constraintVertical_chainStyle="packed"
@ -79,8 +79,8 @@
android:layout_marginTop="32dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:gravity="center"
android:background="@drawable/primary_button_background"
android:text="Ok"
@ -94,7 +94,7 @@
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/confirm"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"

View file

@ -23,7 +23,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/shape_dialog_orange_shadow"
app:layout_constraintBottom_toBottomOf="@id/numbers_and_addresses"
app:layout_constraintBottom_toBottomOf="@id/anchor"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintTop_toTopOf="@id/dialog_background" />
@ -36,7 +36,7 @@
android:layout_marginEnd="12dp"
android:layout_marginBottom="2dp"
android:src="@drawable/shape_dialog_background"
app:layout_constraintBottom_toBottomOf="@id/numbers_and_addresses"
app:layout_constraintBottom_toBottomOf="@id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/title" />
@ -47,7 +47,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="25dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="Which canal do you choose?"
android:textSize="16sp"
app:layout_constraintVertical_chainStyle="packed"
@ -64,14 +64,22 @@
android:layout_marginTop="16dp"
android:layout_marginEnd="15dp"
android:orientation="vertical"
android:paddingBottom="20dp"
app:entries="@{viewModel.sipAddressesAndPhoneNumbers}"
app:layout="@{@layout/dialog_number_address_list_cell}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/anchor"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintTop_toBottomOf="@id/title" />
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/numbers_and_addresses"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -47,7 +47,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="25dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="Do you really want to delete all calls history?"
android:textSize="16sp"
app:layout_constraintVertical_chainStyle="packed"
@ -80,8 +80,8 @@
android:layout_marginTop="32dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:gravity="center"
android:background="@drawable/secondary_button_background"
android:text="Cancel"
@ -101,8 +101,8 @@
android:layout_marginTop="16dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:paddingBottom="13dp"
android:paddingTop="13dp"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:gravity="center"
android:background="@drawable/primary_button_background"
android:text="Ok"
@ -116,7 +116,7 @@
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_height="@dimen/dialog_top_bottom_margin"
app:layout_constraintTop_toBottomOf="@id/confirm"
app:layout_constraintStart_toStartOf="@id/dialog_background"
app:layout_constraintEnd_toEndOf="@id/dialog_background"

View file

@ -86,8 +86,8 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="30dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:paddingTop="@dimen/primary_secondary_buttons_label_padding"
android:paddingBottom="@dimen/primary_secondary_buttons_label_padding"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="Add an account"

View file

@ -21,6 +21,9 @@
<dimen name="avatar_presence_badge_big_end_margin">5dp</dimen>
<dimen name="avatar_trust_border_width">2dp</dimen>
<dimen name="primary_secondary_buttons_label_padding">11dp</dimen>
<dimen name="dialog_top_bottom_margin">20dp</dimen>
<dimen name="top_bar_height">55dp</dimen>
<dimen name="toast_top_margin">70dp</dimen> <!-- 15dp + top_bar_height -->