Added swipe to remove on call logs & contacts + improved confirmation dialog messages
This commit is contained in:
parent
766891301c
commit
bf24a6b2a9
8 changed files with 150 additions and 9 deletions
|
@ -49,6 +49,7 @@ import org.linphone.databinding.ChatRoomMasterFragmentBinding
|
|||
import org.linphone.utils.*
|
||||
|
||||
class MasterChatRoomsFragment : MasterFragment() {
|
||||
override val dialogConfirmationMessageBeforeRemoval = R.plurals.chat_room_delete_dialog
|
||||
private lateinit var binding: ChatRoomMasterFragmentBinding
|
||||
private lateinit var listViewModel: ChatRoomsListViewModel
|
||||
private lateinit var adapter: ChatRoomsListAdapter
|
||||
|
@ -94,6 +95,7 @@ class MasterChatRoomsFragment : MasterFragment() {
|
|||
val layoutManager = LinearLayoutManager(activity)
|
||||
binding.chatList.layoutManager = layoutManager
|
||||
|
||||
// Swipe action
|
||||
val swipeConfiguration = RecyclerViewSwipeConfiguration()
|
||||
val white = ContextCompat.getColor(requireContext(), R.color.white_color)
|
||||
|
||||
|
@ -102,7 +104,7 @@ class MasterChatRoomsFragment : MasterFragment() {
|
|||
override fun onLeftToRightSwipe(viewHolder: RecyclerView.ViewHolder) {}
|
||||
|
||||
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
|
||||
val viewModel = DialogViewModel(getString(R.string.dialog_default_delete_message))
|
||||
val viewModel = DialogViewModel(getString(R.string.chat_room_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
viewModel.showCancelButton {
|
||||
|
|
|
@ -131,7 +131,7 @@ class DetailContactFragment : Fragment() {
|
|||
}
|
||||
|
||||
private fun confirmContactRemoval() {
|
||||
val dialogViewModel = DialogViewModel(getString(R.string.contact_confirm_removal_dialog))
|
||||
val dialogViewModel = DialogViewModel(getString(R.string.contact_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
|
||||
|
||||
dialogViewModel.showCancelButton {
|
||||
|
|
|
@ -19,33 +19,37 @@
|
|||
*/
|
||||
package org.linphone.activities.main.contact.fragments
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.main.MainActivity
|
||||
import org.linphone.activities.main.contact.adapters.ContactsListAdapter
|
||||
import org.linphone.activities.main.contact.viewmodels.ContactsListViewModel
|
||||
import org.linphone.activities.main.fragments.MasterFragment
|
||||
import org.linphone.activities.main.viewmodels.DialogViewModel
|
||||
import org.linphone.activities.main.viewmodels.SharedMainViewModel
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.core.Factory
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.ContactMasterFragmentBinding
|
||||
import org.linphone.utils.Event
|
||||
import org.linphone.utils.PermissionHelper
|
||||
import org.linphone.utils.RecyclerViewHeaderDecoration
|
||||
import org.linphone.utils.*
|
||||
|
||||
class MasterContactsFragment : MasterFragment() {
|
||||
override val dialogConfirmationMessageBeforeRemoval = R.plurals.contact_delete_dialog
|
||||
private lateinit var binding: ContactMasterFragmentBinding
|
||||
private lateinit var listViewModel: ContactsListViewModel
|
||||
private lateinit var adapter: ContactsListAdapter
|
||||
|
@ -90,6 +94,34 @@ class MasterContactsFragment : MasterFragment() {
|
|||
val layoutManager = LinearLayoutManager(activity)
|
||||
binding.contactsList.layoutManager = layoutManager
|
||||
|
||||
// Swipe action
|
||||
val swipeConfiguration = RecyclerViewSwipeConfiguration()
|
||||
val white = ContextCompat.getColor(requireContext(), R.color.white_color)
|
||||
|
||||
swipeConfiguration.rightToLeftAction = RecyclerViewSwipeConfiguration.Action("Delete", white, ContextCompat.getColor(requireContext(), R.color.red_color))
|
||||
val swipeListener = object : RecyclerViewSwipeListener {
|
||||
override fun onLeftToRightSwipe(viewHolder: RecyclerView.ViewHolder) {}
|
||||
|
||||
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
|
||||
val viewModel = DialogViewModel(getString(R.string.contact_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(viewHolder.adapterPosition)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton({
|
||||
listViewModel.deleteContact(listViewModel.contactsList.value?.get(viewHolder.adapterPosition))
|
||||
dialog.dismiss()
|
||||
}, getString(R.string.dialog_delete))
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
RecyclerViewSwipeUtils(ItemTouchHelper.LEFT, swipeConfiguration, swipeListener)
|
||||
.attachToRecyclerView(binding.contactsList)
|
||||
|
||||
// Divider between items
|
||||
val dividerItemDecoration = DividerItemDecoration(context, layoutManager.orientation)
|
||||
dividerItemDecoration.setDrawable(resources.getDrawable(R.drawable.divider, null))
|
||||
|
|
|
@ -73,6 +73,38 @@ class ContactsListViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
fun deleteContact(contact: Contact?) {
|
||||
contact ?: return
|
||||
|
||||
val select = ContactsContract.Data.CONTACT_ID + " = ?"
|
||||
val ops = ArrayList<ContentProviderOperation>()
|
||||
|
||||
if (contact is NativeContact) {
|
||||
val nativeContact: NativeContact = contact
|
||||
Log.i("[Contacts] Adding Android contact id ${nativeContact.nativeId} to batch removal")
|
||||
val args = arrayOf(nativeContact.nativeId)
|
||||
ops.add(
|
||||
ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
|
||||
.withSelection(select, args)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
if (contact.friend != null) {
|
||||
Log.i("[Contacts] Removing friend")
|
||||
contact.friend?.remove()
|
||||
}
|
||||
|
||||
if (ops.isNotEmpty()) {
|
||||
try {
|
||||
Log.i("[Contacts] Removing ${ops.size} contacts")
|
||||
coreContext.context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
|
||||
} catch (e: Exception) {
|
||||
Log.e("[Contacts] $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteContacts(list: ArrayList<Contact>) {
|
||||
val select = ContactsContract.Data.CONTACT_ID + " = ?"
|
||||
val ops = ArrayList<ContentProviderOperation>()
|
||||
|
|
|
@ -27,6 +27,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import org.linphone.R
|
||||
import org.linphone.activities.main.viewmodels.DialogViewModel
|
||||
import org.linphone.activities.main.viewmodels.ListTopBarViewModel
|
||||
import org.linphone.utils.AppUtils
|
||||
import org.linphone.utils.DialogUtils
|
||||
|
||||
/**
|
||||
|
@ -35,6 +36,7 @@ import org.linphone.utils.DialogUtils
|
|||
*/
|
||||
abstract class MasterFragment : Fragment() {
|
||||
protected lateinit var listSelectionViewModel: ListTopBarViewModel
|
||||
protected open val dialogConfirmationMessageBeforeRemoval: Int = R.plurals.dialog_default_delete
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
@ -60,7 +62,8 @@ abstract class MasterFragment : Fragment() {
|
|||
|
||||
listSelectionViewModel.deleteSelectionEvent.observe(viewLifecycleOwner, Observer {
|
||||
it.consume {
|
||||
val viewModel = DialogViewModel(getString(R.string.dialog_default_delete_message))
|
||||
val confirmationDialog = AppUtils.getStringWithPlural(dialogConfirmationMessageBeforeRemoval, listSelectionViewModel.selectedItems.value.orEmpty().size)
|
||||
val viewModel = DialogViewModel(confirmationDialog)
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
viewModel.showCancelButton {
|
||||
|
|
|
@ -19,15 +19,18 @@
|
|||
*/
|
||||
package org.linphone.activities.main.history.fragments
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
|
@ -35,14 +38,16 @@ import org.linphone.R
|
|||
import org.linphone.activities.main.fragments.MasterFragment
|
||||
import org.linphone.activities.main.history.adapters.CallLogsListAdapter
|
||||
import org.linphone.activities.main.history.viewmodels.CallLogsListViewModel
|
||||
import org.linphone.activities.main.viewmodels.DialogViewModel
|
||||
import org.linphone.activities.main.viewmodels.SharedMainViewModel
|
||||
import org.linphone.activities.main.viewmodels.TabsViewModel
|
||||
import org.linphone.core.CallLog
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.HistoryMasterFragmentBinding
|
||||
import org.linphone.utils.RecyclerViewHeaderDecoration
|
||||
import org.linphone.utils.*
|
||||
|
||||
class MasterCallLogsFragment : MasterFragment() {
|
||||
override val dialogConfirmationMessageBeforeRemoval = R.plurals.history_delete_dialog
|
||||
private lateinit var binding: HistoryMasterFragmentBinding
|
||||
private lateinit var listViewModel: CallLogsListViewModel
|
||||
private lateinit var adapter: CallLogsListAdapter
|
||||
|
@ -86,6 +91,34 @@ class MasterCallLogsFragment : MasterFragment() {
|
|||
val layoutManager = LinearLayoutManager(activity)
|
||||
binding.callLogsList.layoutManager = layoutManager
|
||||
|
||||
// Swipe action
|
||||
val swipeConfiguration = RecyclerViewSwipeConfiguration()
|
||||
val white = ContextCompat.getColor(requireContext(), R.color.white_color)
|
||||
|
||||
swipeConfiguration.rightToLeftAction = RecyclerViewSwipeConfiguration.Action("Delete", white, ContextCompat.getColor(requireContext(), R.color.red_color))
|
||||
val swipeListener = object : RecyclerViewSwipeListener {
|
||||
override fun onLeftToRightSwipe(viewHolder: RecyclerView.ViewHolder) {}
|
||||
|
||||
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
|
||||
val viewModel = DialogViewModel(getString(R.string.history_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(viewHolder.adapterPosition)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton({
|
||||
listViewModel.deleteCallLog(listViewModel.callLogs.value?.get(viewHolder.adapterPosition))
|
||||
dialog.dismiss()
|
||||
}, getString(R.string.dialog_delete))
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
RecyclerViewSwipeUtils(ItemTouchHelper.LEFT, swipeConfiguration, swipeListener)
|
||||
.attachToRecyclerView(binding.callLogsList)
|
||||
|
||||
// Divider between items
|
||||
val dividerItemDecoration = DividerItemDecoration(context, layoutManager.orientation)
|
||||
dividerItemDecoration.setDrawable(resources.getDrawable(R.drawable.divider, null))
|
||||
|
|
|
@ -70,6 +70,23 @@ class CallLogsListViewModel : ViewModel() {
|
|||
super.onCleared()
|
||||
}
|
||||
|
||||
fun deleteCallLog(callLog: CallLog?) {
|
||||
val list = arrayListOf<CallLog>()
|
||||
list.addAll(callLogs.value.orEmpty())
|
||||
|
||||
val missedList = arrayListOf<CallLog>()
|
||||
missedList.addAll(missedCallLogs.value.orEmpty())
|
||||
|
||||
if (callLog != null) {
|
||||
coreContext.core.removeCallLog(callLog)
|
||||
list.remove(callLog)
|
||||
missedList.remove(callLog)
|
||||
}
|
||||
|
||||
callLogs.value = list
|
||||
missedCallLogs.value = missedList
|
||||
}
|
||||
|
||||
fun deleteCallLogs(listToDelete: ArrayList<CallLog>) {
|
||||
val list = arrayListOf<CallLog>()
|
||||
list.addAll(callLogs.value.orEmpty())
|
||||
|
|
|
@ -81,6 +81,12 @@
|
|||
<string name="history_calls_list">Calls</string>
|
||||
<string name="no_call_history">No call in your history</string>
|
||||
<string name="no_missed_call_history">No missed call in your history</string>
|
||||
<string name="history_delete_one_dialog">Do you want to delete this record?</string>
|
||||
<string name="history_delete_many_dialog">Do you want to delete these records?</string>
|
||||
<plurals name="history_delete_dialog">
|
||||
<item quantity="one">@string/history_delete_one_dialog</item>
|
||||
<item quantity="other">@string/history_delete_many_dialog</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Contacts -->
|
||||
<string name="contact_invite_friend">Invite</string>
|
||||
|
@ -94,7 +100,12 @@
|
|||
<string name="contact_organization">Organization</string>
|
||||
<string name="contact_choose_existing_or_new_to_add_number">Select a contact or create a new one</string>
|
||||
<string name="contact_editor_write_permission_denied">Write Contacts permission denied, can\'t edit contact</string>
|
||||
<string name="contact_confirm_removal_dialog">Do you want to delete this contact?\nIt will also be removed from your device addressbook</string>
|
||||
<string name="contact_delete_one_dialog">Do you want to delete this contact?\nIt will also be removed from your device addressbook</string>
|
||||
<string name="contact_delete_many_dialog">Are you sure you want to delete these contacts?\nThey will also be removed from your device addressbook</string>
|
||||
<plurals name="contact_delete_dialog">
|
||||
<item quantity="one">@string/contact_delete_one_dialog</item>
|
||||
<item quantity="other">@string/contact_delete_many_dialog</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Dialer -->
|
||||
<string name="dialer_address_bar_hint">Enter a number or an address</string>
|
||||
|
@ -178,6 +189,12 @@
|
|||
</plurals>
|
||||
<string name="chat_room_creation_failed_snack">Chat room creation failed</string>
|
||||
<string name="chat_room_removal_failed_snack">Chat room removal failed</string>
|
||||
<string name="chat_room_delete_one_dialog">Are you sure you want to delete this conversation?</string>
|
||||
<string name="chat_room_delete_many_dialog">Are you sure you want to delete these conversations?</string>
|
||||
<plurals name="chat_room_delete_dialog">
|
||||
<item quantity="one">@string/chat_room_delete_one_dialog</item>
|
||||
<item quantity="other">@string/chat_room_delete_many_dialog</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Recordings -->
|
||||
<string name="recordings_empty_list">No recordings</string>
|
||||
|
@ -531,9 +548,14 @@
|
|||
<string name="dialog_delete">Delete</string>
|
||||
<string name="dialog_ok">OK</string>
|
||||
<string name="dialog_call">Call</string>
|
||||
<string name="dialog_default_delete_message">Are you sure you want to delete your selection?</string>
|
||||
<string name="dialog_lime_security_message">Instant messages are end-to-end encrypted in secured conversations. It is possible to upgrade the security level of a conversation by authenticating participants. To do so, call the contact and follow the authentication process.</string>
|
||||
<string name="operation_in_progress_wait">Operation in progress, please wait</string>
|
||||
<string name="dialog_default_delete_one">Are you sure you want to delete this item?</string>
|
||||
<string name="dialog_default_delete_many">Are you sure you want to delete your selection?</string>
|
||||
<plurals name="dialog_default_delete">
|
||||
<item quantity="one">@string/dialog_default_delete_one</item>
|
||||
<item quantity="other">@string/dialog_default_delete_many</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Content description -->
|
||||
<string name="content_description_add_sip_address_field">Add a SIP address field</string>
|
||||
|
|
Loading…
Reference in a new issue