Added missing add / go to contact action from calls list context menu + added logs

This commit is contained in:
Sylvain Berfini 2023-08-22 16:20:26 +02:00
parent 64c29d495d
commit 60965b767c
9 changed files with 129 additions and 37 deletions

View file

@ -138,7 +138,6 @@ class CallFragment : GenericFragment() {
popupView.contactExists = viewModel.callLogModel.value?.friendExists == true popupView.contactExists = viewModel.callLogModel.value?.friendExists == true
popupView.setAddToContactsListener { popupView.setAddToContactsListener {
// TODO: go to new contact fragment
sharedViewModel.sipAddressToAddToNewContact = viewModel.callLogModel.value?.displayedAddress.orEmpty() sharedViewModel.sipAddressToAddToNewContact = viewModel.callLogModel.value?.displayedAddress.orEmpty()
sharedViewModel.navigateToContactsEvent.value = Event(true) sharedViewModel.navigateToContactsEvent.value = Event(true)
sharedViewModel.showNewContactEvent.value = Event(true) sharedViewModel.showNewContactEvent.value = Event(true)

View file

@ -38,6 +38,7 @@ import androidx.navigation.navGraphViewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.CallsListFragmentBinding import org.linphone.databinding.CallsListFragmentBinding
import org.linphone.databinding.CallsListPopupMenuBinding import org.linphone.databinding.CallsListPopupMenuBinding
import org.linphone.ui.main.MainActivity import org.linphone.ui.main.MainActivity
@ -50,6 +51,9 @@ import org.linphone.utils.Event
@UiThread @UiThread
class CallsListFragment : GenericFragment() { class CallsListFragment : GenericFragment() {
companion object {
const val TAG = "[Calls List Fragment]"
}
private lateinit var binding: CallsListFragmentBinding private lateinit var binding: CallsListFragmentBinding
@ -89,17 +93,45 @@ class CallsListFragment : GenericFragment() {
adapter.callLogLongClickedEvent.observe(viewLifecycleOwner) { adapter.callLogLongClickedEvent.observe(viewLifecycleOwner) {
it.consume { model -> it.consume { model ->
val modalBottomSheet = CallsListMenuDialogFragment({ val modalBottomSheet = CallsListMenuDialogFragment(
// onDismiss model.friendExists,
{ // onDismiss
adapter.resetSelection() adapter.resetSelection()
}, { },
// onCopyNumberOrAddressToClipboard { // onAddToContact
copyNumberOrAddressToClipboard(model.displayedAddress) val addressToAdd = model.displayedAddress
}, { Log.i(
// onDeleteCallLog "$TAG Navigating to new contact with pre-filled value [$addressToAdd]"
)
sharedViewModel.sipAddressToAddToNewContact = addressToAdd
sharedViewModel.navigateToContactsEvent.value = Event(true)
sharedViewModel.showNewContactEvent.value = Event(true)
},
{ // onGoToContact
val friendRefKey = model.friendRefKey
if (!friendRefKey.isNullOrEmpty()) {
Log.i("$TAG Navigating to contact with ref key [$friendRefKey]")
sharedViewModel.navigateToContactsEvent.value = Event(true)
sharedViewModel.showContactEvent.value = Event(friendRefKey)
} else {
Log.w(
"$TAG Can't navigate to existing friend, ref key is null or empty"
)
}
},
{ // onCopyNumberOrAddressToClipboard
val addressToCopy = model.displayedAddress
Log.i("$TAG Copying number [$addressToCopy] to clipboard")
copyNumberOrAddressToClipboard(addressToCopy)
},
{ // onDeleteCallLog
Log.i("$TAG Deleting call log with ref key or call ID [${model.id}]")
model.delete() model.delete()
adapter.deleteSelection() adapter.deleteSelection()
}) }
)
modalBottomSheet.show(parentFragmentManager, CallsListMenuDialogFragment.TAG) modalBottomSheet.show(parentFragmentManager, CallsListMenuDialogFragment.TAG)
} }
} }
@ -113,6 +145,7 @@ class CallsListFragment : GenericFragment() {
adapter.callLogCallBackClickedEvent.observe(viewLifecycleOwner) { adapter.callLogCallBackClickedEvent.observe(viewLifecycleOwner) {
it.consume { model -> it.consume { model ->
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
Log.i("$TAG Starting call to [${model.address.asStringUriOnly()}]")
coreContext.startCall(model.address) coreContext.startCall(model.address)
} }
} }
@ -200,6 +233,7 @@ class CallsListFragment : GenericFragment() {
model.confirmRemovalEvent.observe(viewLifecycleOwner) { model.confirmRemovalEvent.observe(viewLifecycleOwner) {
it.consume { it.consume {
Log.w("$TAG Removing all call entries from database")
listViewModel.removeAllCallLogs() listViewModel.removeAllCallLogs()
dialog.dismiss() dialog.dismiss()
} }

View file

@ -30,7 +30,10 @@ import org.linphone.databinding.CallsListLongPressMenuBinding
@UiThread @UiThread
class CallsListMenuDialogFragment( class CallsListMenuDialogFragment(
private val contactExists: Boolean,
private val onDismiss: (() -> Unit)? = null, private val onDismiss: (() -> Unit)? = null,
private val onAddToContact: (() -> Unit)? = null,
private val onGoToContact: (() -> Unit)? = null,
private val onCopyNumberOrAddressToClipboard: (() -> Unit)? = null, private val onCopyNumberOrAddressToClipboard: (() -> Unit)? = null,
private val onDeleteCallLog: (() -> Unit)? = null private val onDeleteCallLog: (() -> Unit)? = null
) : BottomSheetDialogFragment() { ) : BottomSheetDialogFragment() {
@ -54,6 +57,7 @@ class CallsListMenuDialogFragment(
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
val view = CallsListLongPressMenuBinding.inflate(layoutInflater) val view = CallsListLongPressMenuBinding.inflate(layoutInflater)
view.contactExists = contactExists
view.setCopyNumberClickListener { view.setCopyNumberClickListener {
onCopyNumberOrAddressToClipboard?.invoke() onCopyNumberOrAddressToClipboard?.invoke()
@ -65,8 +69,13 @@ class CallsListMenuDialogFragment(
dismiss() dismiss()
} }
view.setNewContactClickListener { view.setAddToContactsListener {
// TODO onAddToContact?.invoke()
dismiss()
}
view.setGoToContactClickListener {
onGoToContact?.invoke()
dismiss() dismiss()
} }

View file

@ -60,6 +60,12 @@ class ContactsFragment : GenericFragment() {
} }
} }
sharedViewModel.contactEditorReadyToBeDisplayedEvent.observe(viewLifecycleOwner) {
it.consume {
startPostponedEnterTransition()
}
}
binding.root.doOnPreDraw { binding.root.doOnPreDraw {
val slidingPane = binding.slidingPaneLayout val slidingPane = binding.slidingPaneLayout
slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED

View file

@ -32,6 +32,7 @@ import androidx.navigation.navGraphViewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ContactsListFragmentBinding import org.linphone.databinding.ContactsListFragmentBinding
import org.linphone.ui.main.contacts.adapter.ContactsListAdapter import org.linphone.ui.main.contacts.adapter.ContactsListAdapter
import org.linphone.ui.main.contacts.viewmodel.ContactsListViewModel import org.linphone.ui.main.contacts.viewmodel.ContactsListViewModel
@ -40,6 +41,10 @@ import org.linphone.utils.Event
@UiThread @UiThread
class ContactsListFragment : GenericFragment() { class ContactsListFragment : GenericFragment() {
companion object {
const val TAG = "[Contacts List Fragment]"
}
private lateinit var binding: ContactsListFragmentBinding private lateinit var binding: ContactsListFragmentBinding
private val listViewModel: ContactsListViewModel by navGraphViewModels( private val listViewModel: ContactsListViewModel by navGraphViewModels(
@ -95,6 +100,7 @@ class ContactsListFragment : GenericFragment() {
viewLifecycleOwner viewLifecycleOwner
) { ) {
adapter.submitList(it) adapter.submitList(it)
Log.i("$TAG Contacts list is ready with [${it.size}] items")
(view.parent as? ViewGroup)?.doOnPreDraw { (view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition() startPostponedEnterTransition()
@ -106,6 +112,7 @@ class ContactsListFragment : GenericFragment() {
viewLifecycleOwner viewLifecycleOwner
) { ) {
favouritesAdapter.submitList(it) favouritesAdapter.submitList(it)
Log.i("$TAG Favourites contacts list is ready with [${it.size}] items")
} }
sharedViewModel.searchFilter.observe(viewLifecycleOwner) { sharedViewModel.searchFilter.observe(viewLifecycleOwner) {
@ -122,26 +129,35 @@ class ContactsListFragment : GenericFragment() {
private fun configureAdapter(adapter: ContactsListAdapter) { private fun configureAdapter(adapter: ContactsListAdapter) {
adapter.contactLongClickedEvent.observe(viewLifecycleOwner) { adapter.contactLongClickedEvent.observe(viewLifecycleOwner) {
it.consume { model -> it.consume { model ->
val modalBottomSheet = ContactsListMenuDialogFragment(model.friend.starred, { val modalBottomSheet = ContactsListMenuDialogFragment(
model.friend.starred,
{ // ondDismiss
adapter.resetSelection() adapter.resetSelection()
}, { },
// onFavourite { // onFavourite
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
model.friend.edit() model.friend.edit()
model.friend.starred = !model.friend.starred val starred = !model.friend.starred
Log.i(
"$TAG Friend [${model.name.value}] will be ${if (starred) "added" else "removed"} from favourites"
)
model.friend.starred = starred
model.friend.done() model.friend.done()
coreContext.contactsManager.notifyContactsListChanged() coreContext.contactsManager.notifyContactsListChanged()
} }
}, { },
// onShare { // onShare
Log.i("$TAG Sharing friend [${model.name.value}]")
// TODO // TODO
}, { },
// onDelete { // onDelete
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
Log.w("$TAG Removing friend [${model.name.value}]")
model.friend.remove() model.friend.remove()
coreContext.contactsManager.notifyContactsListChanged() coreContext.contactsManager.notifyContactsListChanged()
} }
}) }
)
modalBottomSheet.show(parentFragmentManager, ContactsListMenuDialogFragment.TAG) modalBottomSheet.show(parentFragmentManager, ContactsListMenuDialogFragment.TAG)
} }
} }

View file

@ -101,7 +101,9 @@ class NewContactFragment : GenericFragment() {
val addressToAdd = sharedViewModel.sipAddressToAddToNewContact val addressToAdd = sharedViewModel.sipAddressToAddToNewContact
if (addressToAdd.isNotEmpty()) { if (addressToAdd.isNotEmpty()) {
Log.i("$TAG Pre-filling new contact form with SIP address [$addressToAdd]")
sharedViewModel.sipAddressToAddToNewContact = "" sharedViewModel.sipAddressToAddToNewContact = ""
coreContext.postOnCoreThread { coreContext.postOnCoreThread {
viewModel.addSipAddress(addressToAdd) viewModel.addSipAddress(addressToAdd)
} }
@ -169,6 +171,8 @@ class NewContactFragment : GenericFragment() {
removeCell(model) removeCell(model)
} }
} }
sharedViewModel.contactEditorReadyToBeDisplayedEvent.value = Event(true)
} }
private fun addCell(model: NewOrEditNumberOrAddressModel) { private fun addCell(model: NewOrEditNumberOrAddressModel) {

View file

@ -61,6 +61,8 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() {
val contactsListReadyToBeDisplayedEvent = MutableLiveData<Event<Boolean>>() val contactsListReadyToBeDisplayedEvent = MutableLiveData<Event<Boolean>>()
val contactEditorReadyToBeDisplayedEvent = MutableLiveData<Event<Boolean>>()
val showContactEvent: MutableLiveData<Event<String>> by lazy { val showContactEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>() MutableLiveData<Event<String>>()
} }

View file

@ -39,7 +39,7 @@
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
android:layout_marginEnd="20dp" android:layout_marginEnd="20dp"
android:gravity="left|center_vertical" android:gravity="left|center_vertical"
android:text="Ajouter aux contats" android:text="Ajouter aux contacts"
android:textSize="14sp" android:textSize="14sp"
android:textColor="@color/gray_1" android:textColor="@color/gray_1"
android:drawableStart="@drawable/add" android:drawableStart="@drawable/add"

View file

@ -5,7 +5,10 @@
<data> <data>
<import type="android.view.View" /> <import type="android.view.View" />
<variable <variable
name="newContactClickListener" name="addToContactsListener"
type="View.OnClickListener" />
<variable
name="goToContactClickListener"
type="View.OnClickListener" /> type="View.OnClickListener" />
<variable <variable
name="copyNumberClickListener" name="copyNumberClickListener"
@ -13,6 +16,9 @@
<variable <variable
name="deleteClickListener" name="deleteClickListener"
type="View.OnClickListener" /> type="View.OnClickListener" />
<variable
name="contactExists"
type="Boolean" />
</data> </data>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -21,8 +27,9 @@
android:background="@color/separator"> android:background="@color/separator">
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:id="@+id/favorite" android:id="@+id/add_to_contact"
android:onClick="@{newContactClickListener}" android:onClick="@{addToContactsListener}"
android:visibility="@{contactExists ? View.GONE : View.VISIBLE}"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Ajouter aux contacts" android:text="Ajouter aux contacts"
@ -30,6 +37,21 @@
android:background="@drawable/menu_item_background" android:background="@drawable/menu_item_background"
android:layout_marginBottom="1dp" android:layout_marginBottom="1dp"
android:drawableStart="@drawable/new_contact" android:drawableStart="@drawable/new_contact"
app:layout_constraintBottom_toTopOf="@id/go_to_contact"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/go_to_contact"
android:onClick="@{goToContactClickListener}"
android:visibility="@{contactExists ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Voir le contact"
style="@style/context_menu_action_label_style"
android:background="@drawable/menu_item_background"
android:layout_marginBottom="1dp"
android:drawableStart="@drawable/contact"
app:layout_constraintBottom_toTopOf="@id/share" app:layout_constraintBottom_toTopOf="@id/share"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/> app:layout_constraintEnd_toEndOf="parent"/>