Added delete all call logs menu & dialog

This commit is contained in:
Sylvain Berfini 2023-08-17 13:19:06 +02:00
parent 8fcf3f1baa
commit b2a89a46ca
14 changed files with 337 additions and 17 deletions

View file

@ -23,11 +23,14 @@ import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.PopupWindow
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.navGraphViewModels
@ -35,9 +38,12 @@ import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
import org.linphone.databinding.CallsListFragmentBinding
import org.linphone.databinding.CallsListPopupMenuBinding
import org.linphone.ui.main.calls.adapter.CallsListAdapter
import org.linphone.ui.main.calls.model.RemoveAllCallLogsDialogModel
import org.linphone.ui.main.calls.viewmodel.CallsListViewModel
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.DialogUtils
import org.linphone.utils.Event
import org.linphone.utils.slideInToastFromTopForDuration
@ -125,7 +131,7 @@ class CallsListFragment : GenericFragment() {
}
binding.setMenuClickListener {
// TODO show popup menu with delete all history button
showPopupMenu()
}
}
@ -140,4 +146,47 @@ class CallsListFragment : GenericFragment() {
val target = binding.greenToast.root
target.slideInToastFromTopForDuration(binding.root as ViewGroup, lifecycleScope)
}
private fun showPopupMenu() {
val popupView: CallsListPopupMenuBinding = DataBindingUtil.inflate(
LayoutInflater.from(requireContext()),
R.layout.calls_list_popup_menu,
null,
false
)
val popupWindow = PopupWindow(
popupView.root,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
true
)
popupView.setDeleteAllHistoryClickListener {
val model = RemoveAllCallLogsDialogModel()
val dialog = DialogUtils.getRemoveAllCallLogsConfirmationDialog(
requireActivity(),
model
)
model.dismissEvent.observe(viewLifecycleOwner) {
it.consume {
dialog.dismiss()
}
}
model.confirmRemovalEvent.observe(viewLifecycleOwner) {
it.consume {
listViewModel.removeAllCallLogs()
dialog.dismiss()
}
}
dialog.show()
popupWindow.dismiss()
}
// Elevation is for showing a shadow around the popup
popupWindow.elevation = 20f
popupWindow.showAsDropDown(binding.menu, 0, 0, Gravity.BOTTOM)
}
}

View file

@ -0,0 +1,39 @@
/*
* 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.calls.model
import androidx.lifecycle.MutableLiveData
import org.linphone.utils.Event
class RemoveAllCallLogsDialogModel() {
val dismissEvent = MutableLiveData<Event<Boolean>>()
val confirmRemovalEvent = MutableLiveData<Event<Boolean>>()
fun dismiss() {
// UI thread
dismissEvent.value = Event(true)
}
fun confirmRemoval() {
// UI thread
confirmRemovalEvent.value = Event(true)
}
}

View file

@ -63,6 +63,16 @@ class CallsListViewModel : ViewModel() {
}
}
fun removeAllCallLogs() {
// UI thread
coreContext.postOnCoreThread { core ->
for (callLog in core.callLogs) {
core.removeCallLog(callLog)
}
computeCallLogsList(currentFilter)
}
}
private fun computeCallLogsList(filter: String) {
// Core thread
val list = arrayListOf<CallLogModel>()

View file

@ -20,11 +20,10 @@
package org.linphone.ui.main.contacts.model
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.linphone.ui.main.contacts.viewmodel.ContactViewModel
import org.linphone.utils.Event
class NumberOrAddressPickerDialogModel(viewModel: ContactViewModel) : ViewModel() {
class NumberOrAddressPickerDialogModel(viewModel: ContactViewModel) {
val sipAddressesAndPhoneNumbers = MutableLiveData<ArrayList<ContactNumberOrAddressModel>>()
val dismissEvent = MutableLiveData<Event<Boolean>>()

View file

@ -31,6 +31,8 @@ import androidx.databinding.DataBindingUtil
import org.linphone.R
import org.linphone.databinding.DialogConfirmZrtpSasBinding
import org.linphone.databinding.DialogPickNumberOrAddressBinding
import org.linphone.databinding.DialogRemoveAllCallLogsBinding
import org.linphone.ui.main.calls.model.RemoveAllCallLogsDialogModel
import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel
import org.linphone.ui.voip.model.ZrtpSasConfirmationDialogModel
@ -40,7 +42,7 @@ class DialogUtils {
context: Context,
viewModel: NumberOrAddressPickerDialogModel
): Dialog {
val dialog = Dialog(context)
val dialog = Dialog(context, R.style.Theme_LinphoneDialog)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
val binding: DialogPickNumberOrAddressBinding = DataBindingUtil.inflate(
@ -55,7 +57,7 @@ class DialogUtils {
val d: Drawable = ColorDrawable(
ContextCompat.getColor(dialog.context, R.color.dialog_background)
)
d.alpha = 100
d.alpha = 166
dialog.window
?.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
@ -64,11 +66,40 @@ class DialogUtils {
dialog.window?.setBackgroundDrawable(d)
return dialog
}
fun getRemoveAllCallLogsConfirmationDialog(
context: Context,
model: RemoveAllCallLogsDialogModel
): Dialog {
val dialog = Dialog(context, R.style.Theme_LinphoneDialog)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
val binding: DialogRemoveAllCallLogsBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.dialog_remove_all_call_logs,
null,
false
)
binding.viewModel = model
dialog.setContentView(binding.root)
val d: Drawable = ColorDrawable(
ContextCompat.getColor(dialog.context, R.color.dialog_background)
)
d.alpha = 166
dialog.window
?.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT
)
dialog.window?.setBackgroundDrawable(d)
return dialog
}
fun getZrtpSasConfirmationDialog(
context: Context,
viewModel: ZrtpSasConfirmationDialogModel
): Dialog {
val dialog = Dialog(context)
val dialog = Dialog(context, R.style.Theme_LinphoneDialog)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
val binding: DialogConfirmZrtpSasBinding = DataBindingUtil.inflate(
@ -83,7 +114,7 @@ class DialogUtils {
val d: Drawable = ColorDrawable(
ContextCompat.getColor(dialog.context, R.color.dialog_background)
)
d.alpha = 100
d.alpha = 166
dialog.window
?.setLayout(
WindowManager.LayoutParams.MATCH_PARENT,

View file

@ -41,7 +41,10 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="9dp"
android:adjustViewBounds="true"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:src="@drawable/dot_menu"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -36,12 +36,14 @@
<ImageView
android:id="@+id/menu"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:adjustViewBounds="true"
android:padding="5dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:src="@drawable/dot_menu"
app:tint="@color/primary_color"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -41,7 +41,10 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="9dp"
android:adjustViewBounds="true"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:src="@drawable/dot_menu"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -0,0 +1,38 @@
<?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" />
<import type="android.graphics.Typeface" />
<variable
name="deleteAllHistoryClickListener"
type="View.OnClickListener" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/shape_round_popup_menu_background">
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{deleteAllHistoryClickListener}"
style="@style/default_text_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Delete all history"
android:textSize="14sp"
android:textColor="@color/red_danger"
android:drawableStart="@drawable/delete"
android:drawablePadding="5dp"
app:drawableTint="@color/red_danger"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -15,7 +15,6 @@
android:onClick="@{() -> viewModel.dismiss()}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/in_call_black"
android:clickable="true"
android:focusable="true">
@ -39,10 +38,8 @@
android:src="@drawable/shape_dialog_background"
app:layout_constraintBottom_toBottomOf="@id/anchor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/title"
app:layout_constraintVertical_bias="1.0" />
app:layout_constraintTop_toTopOf="@id/title" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style_800"

View file

@ -0,0 +1,127 @@
<?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" />
<import type="android.graphics.Typeface" />
<variable
name="viewModel"
type="org.linphone.ui.main.calls.model.RemoveAllCallLogsDialogModel" />
</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="25dp"
android:text="Do you really want to delete all calls history?"
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="All calls will be deleted of the history"
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="13dp"
android:paddingTop="13dp"
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.confirmRemoval()}"
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="13dp"
android:paddingTop="13dp"
android:gravity="center"
android:background="@drawable/primary_button_background"
android:text="Ok"
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/anchor"/>
<View
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="20dp"
app:layout_constraintTop_toBottomOf="@id/confirm"
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

@ -5,7 +5,17 @@
<item name="colorPrimary">@color/primary_color</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">@color/primary_color</item>
<!-- https://developer.android.com/guide/topics/display-cutout#best_practices_for_display_cutout_support -->
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<!-- Customize your theme here. -->
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowBackground">@color/white</item>
<item name="android:navigationBarColor">@color/white</item>
</style>
<style name="Theme.LinphoneDialog" parent="Theme.Linphone">
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowBackground">@color/transparent_color</item>
<item name="android:navigationBarColor">@color/black</item>
</style>
</resources>

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="transparent_color">#00000000</color>
<color name="primary_color">#FF5E00</color>
<color name="primary_color_disabled">#FFEACB</color>
<color name="primary_color_pressed">#B72D00</color>

View file

@ -5,7 +5,17 @@
<item name="colorPrimary">@color/primary_color</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">@color/primary_color</item>
<!-- https://developer.android.com/guide/topics/display-cutout#best_practices_for_display_cutout_support -->
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<!-- Customize your theme here. -->
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowBackground">@color/white</item>
<item name="android:navigationBarColor">@color/white</item>
</style>
<style name="Theme.LinphoneDialog" parent="Theme.Linphone">
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowBackground">@color/transparent_color</item>
<item name="android:navigationBarColor">@color/black</item>
</style>
</resources>