diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 06260ba85..257295485 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -7,11 +7,11 @@ - + - + \ No newline at end of file diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt index e75e92d95..ac0e2962b 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt @@ -21,6 +21,7 @@ package org.linphone.contacts import androidx.loader.app.LoaderManager import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.core.Friend import org.linphone.ui.MainActivity class ContactsManager { @@ -55,6 +56,10 @@ class ContactsManager { } } + fun findContactById(id: String): Friend? { + return coreContext.core.defaultFriendList?.findFriendByRefKey(id) + } + fun onCoreStarted() { } diff --git a/app/src/main/java/org/linphone/ui/contacts/ContactFragment.kt b/app/src/main/java/org/linphone/ui/contacts/ContactFragment.kt index 3e4cb3d9a..da9649eee 100644 --- a/app/src/main/java/org/linphone/ui/contacts/ContactFragment.kt +++ b/app/src/main/java/org/linphone/ui/contacts/ContactFragment.kt @@ -25,13 +25,24 @@ import android.view.View import android.view.ViewGroup import androidx.core.view.doOnPreDraw import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.navArgs +import androidx.navigation.navGraphViewModels import androidx.transition.ChangeBounds +import org.linphone.R import org.linphone.databinding.ContactFragmentBinding +import org.linphone.ui.contacts.viewmodel.ContactViewModel +import org.linphone.ui.viewmodel.SharedMainViewModel class ContactFragment : Fragment() { private lateinit var binding: ContactFragmentBinding + private lateinit var sharedViewModel: SharedMainViewModel + + private val viewModel: ContactViewModel by navGraphViewModels( + R.id.contactFragment + ) + private val args: ContactFragmentArgs by navArgs() override fun onCreate(savedInstanceState: Bundle?) { @@ -45,6 +56,11 @@ class ContactFragment : Fragment() { savedInstanceState: Bundle? ): View { binding = ContactFragmentBinding.inflate(layoutInflater) + + sharedViewModel = requireActivity().run { + ViewModelProvider(this)[SharedMainViewModel::class.java] + } + return binding.root } @@ -54,16 +70,23 @@ class ContactFragment : Fragment() { postponeEnterTransition() binding.lifecycleOwner = viewLifecycleOwner + binding.viewModel = viewModel - val model = args.contact - binding.model = model + val refKey = args.contactRefKey + viewModel.findContactByRefKey(refKey) binding.setBackClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() } - (view.parent as? ViewGroup)?.doOnPreDraw { - startPostponedEnterTransition() + sharedViewModel.isSlidingPaneSlideable.observe(viewLifecycleOwner) { slideable -> + viewModel.showBackButton.value = slideable + } + + viewModel.contact.observe(viewLifecycleOwner) { + (view.parent as? ViewGroup)?.doOnPreDraw { + startPostponedEnterTransition() + } } } } diff --git a/app/src/main/java/org/linphone/ui/contacts/ContactsFragment.kt b/app/src/main/java/org/linphone/ui/contacts/ContactsFragment.kt index 8e7fd2b83..9dc80145f 100644 --- a/app/src/main/java/org/linphone/ui/contacts/ContactsFragment.kt +++ b/app/src/main/java/org/linphone/ui/contacts/ContactsFragment.kt @@ -28,6 +28,7 @@ import android.view.animation.Animation import android.view.animation.AnimationUtils import androidx.core.view.doOnPreDraw import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController @@ -40,6 +41,7 @@ import org.linphone.databinding.ContactsFragmentBinding import org.linphone.ui.MainActivity import org.linphone.ui.contacts.adapter.ContactsListAdapter import org.linphone.ui.contacts.viewmodel.ContactsListViewModel +import org.linphone.ui.viewmodel.SharedMainViewModel import org.linphone.utils.SlidingPaneBackPressedCallback import org.linphone.utils.hideKeyboard import org.linphone.utils.setKeyboardInsetListener @@ -47,9 +49,13 @@ import org.linphone.utils.showKeyboard class ContactsFragment : Fragment() { private lateinit var binding: ContactsFragmentBinding + + private lateinit var sharedViewModel: SharedMainViewModel + private val listViewModel: ContactsListViewModel by navGraphViewModels( R.id.contactsFragment ) + private lateinit var adapter: ContactsListAdapter override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? { @@ -67,6 +73,11 @@ class ContactsFragment : Fragment() { ): View { binding = ContactsFragmentBinding.inflate(layoutInflater) sharedElementEnterTransition = AutoTransition() + + sharedViewModel = requireActivity().run { + ViewModelProvider(this)[SharedMainViewModel::class.java] + } + return binding.root } @@ -85,16 +96,20 @@ class ContactsFragment : Fragment() { binding.root.doOnPreDraw { val slidingPane = binding.slidingPaneLayout + + sharedViewModel.isSlidingPaneSlideable.value = slidingPane.isSlideable + requireActivity().onBackPressedDispatcher.addCallback( viewLifecycleOwner, SlidingPaneBackPressedCallback(slidingPane) ) + slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED } adapter = ContactsListAdapter(viewLifecycleOwner) - binding.contactsList.setHasFixedSize(true) - binding.contactsList.adapter = adapter + binding.contactsView.contactsList.setHasFixedSize(true) + binding.contactsView.contactsList.adapter = adapter adapter.contactLongClickedEvent.observe(viewLifecycleOwner) { it.consume { model -> @@ -106,15 +121,14 @@ class ContactsFragment : Fragment() { } adapter.contactClickedEvent.observe(viewLifecycleOwner) { - it.consume { pair -> - val b = pair.first - val model = pair.second - + it.consume { model -> if (findNavController().currentDestination?.id == R.id.contactsFragment) { val navHostFragment = childFragmentManager.findFragmentById( R.id.contacts_nav_container ) as NavHostFragment - val action = ContactFragmentDirections.actionGlobalContactFragment(model) + val action = ContactFragmentDirections.actionGlobalContactFragment( + model.id ?: "" + ) navHostFragment.navController.navigate(action) if (!binding.slidingPaneLayout.isOpen) { @@ -125,7 +139,7 @@ class ContactsFragment : Fragment() { } val layoutManager = LinearLayoutManager(requireContext()) - binding.contactsList.layoutManager = layoutManager + binding.contactsView.contactsList.layoutManager = layoutManager listViewModel.contactsList.observe( viewLifecycleOwner @@ -156,13 +170,7 @@ class ContactsFragment : Fragment() { binding.setOnNewContactClicked { if (findNavController().currentDestination?.id == R.id.contactsFragment) { - val navHostFragment = - childFragmentManager.findFragmentById(R.id.contacts_nav_container) as NavHostFragment? - if (navHostFragment != null) { - navHostFragment.navController.navigate(R.id.action_global_newContactFragment) - } else { - findNavController().navigate(R.id.action_contactsFragment_to_newContactFragment) - } + findNavController().navigate(R.id.action_contactsFragment_to_newContactFragment) } } diff --git a/app/src/main/java/org/linphone/ui/contacts/adapter/ContactsListAdapter.kt b/app/src/main/java/org/linphone/ui/contacts/adapter/ContactsListAdapter.kt index 24b76c258..df3705eb0 100644 --- a/app/src/main/java/org/linphone/ui/contacts/adapter/ContactsListAdapter.kt +++ b/app/src/main/java/org/linphone/ui/contacts/adapter/ContactsListAdapter.kt @@ -18,8 +18,8 @@ class ContactsListAdapter( ) : ListAdapter(ContactDiffCallback()) { var selectedAdapterPosition = -1 - val contactClickedEvent: MutableLiveData>> by lazy { - MutableLiveData>>() + val contactClickedEvent: MutableLiveData> by lazy { + MutableLiveData>() } val contactLongClickedEvent: MutableLiveData> by lazy { @@ -74,7 +74,7 @@ class ContactsListAdapter( binding.root.isSelected = bindingAdapterPosition == selectedAdapterPosition binding.setOnClickListener { - contactClickedEvent.value = Event(Pair(binding, contactModel)) + contactClickedEvent.value = Event(contactModel) } binding.setOnLongClickListener { diff --git a/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt b/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt index 512081b8c..edec25aac 100644 --- a/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt +++ b/app/src/main/java/org/linphone/ui/contacts/model/ContactModel.kt @@ -23,13 +23,12 @@ import android.content.ContentUris import android.net.Uri import android.provider.ContactsContract import androidx.lifecycle.MutableLiveData -import java.io.Serializable import org.linphone.core.ConsolidatedPresence import org.linphone.core.Friend import org.linphone.core.FriendListenerStub import org.linphone.utils.LinphoneUtils -class ContactModel(val friend: Friend) : Serializable { +class ContactModel(val friend: Friend) { val id = friend.refKey val initials = LinphoneUtils.getInitials(friend.name.orEmpty()) diff --git a/app/src/main/java/org/linphone/ui/contacts/viewmodel/ContactViewModel.kt b/app/src/main/java/org/linphone/ui/contacts/viewmodel/ContactViewModel.kt new file mode 100644 index 000000000..977e83ca4 --- /dev/null +++ b/app/src/main/java/org/linphone/ui/contacts/viewmodel/ContactViewModel.kt @@ -0,0 +1,44 @@ +/* + * 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 . + */ +package org.linphone.ui.contacts.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import org.linphone.LinphoneApplication.Companion.coreContext +import org.linphone.ui.contacts.model.ContactModel + +class ContactViewModel : ViewModel() { + val contact = MutableLiveData() + + val showBackButton = MutableLiveData() + + init { + } + + fun findContactByRefKey(refKey: String) { + // UI thread + coreContext.postOnCoreThread { + val friend = coreContext.contactsManager.findContactById(refKey) + if (friend != null) { + contact.postValue(ContactModel(friend)) + } + } + } +} diff --git a/app/src/main/java/org/linphone/ui/contacts/viewmodel/ContactsListViewModel.kt b/app/src/main/java/org/linphone/ui/contacts/viewmodel/ContactsListViewModel.kt index ea9865c10..25a8098e7 100644 --- a/app/src/main/java/org/linphone/ui/contacts/viewmodel/ContactsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/contacts/viewmodel/ContactsListViewModel.kt @@ -27,8 +27,8 @@ import org.linphone.core.Friend import org.linphone.core.MagicSearch import org.linphone.core.SearchResult import org.linphone.core.tools.Log -import org.linphone.ui.TopBarViewModel import org.linphone.ui.contacts.model.ContactModel +import org.linphone.ui.viewmodel.TopBarViewModel class ContactsListViewModel : TopBarViewModel() { val bottomNavBarVisible = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/conversations/viewmodel/ConversationsListViewModel.kt b/app/src/main/java/org/linphone/ui/conversations/viewmodel/ConversationsListViewModel.kt index da6535e15..e6b5dfaf2 100644 --- a/app/src/main/java/org/linphone/ui/conversations/viewmodel/ConversationsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/conversations/viewmodel/ConversationsListViewModel.kt @@ -29,8 +29,8 @@ import org.linphone.core.Core import org.linphone.core.CoreListenerStub import org.linphone.core.SearchResult import org.linphone.core.tools.Log -import org.linphone.ui.TopBarViewModel import org.linphone.ui.conversations.data.ChatRoomData +import org.linphone.ui.viewmodel.TopBarViewModel import org.linphone.utils.Event import org.linphone.utils.LinphoneUtils diff --git a/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt b/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt new file mode 100644 index 000000000..f30268e95 --- /dev/null +++ b/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt @@ -0,0 +1,27 @@ +/* + * 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 . + */ +package org.linphone.ui.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class SharedMainViewModel : ViewModel() { + val isSlidingPaneSlideable = MutableLiveData() +} diff --git a/app/src/main/java/org/linphone/ui/TopBarViewModel.kt b/app/src/main/java/org/linphone/ui/viewmodel/TopBarViewModel.kt similarity index 99% rename from app/src/main/java/org/linphone/ui/TopBarViewModel.kt rename to app/src/main/java/org/linphone/ui/viewmodel/TopBarViewModel.kt index d6823c4f3..42f9c2e2b 100644 --- a/app/src/main/java/org/linphone/ui/TopBarViewModel.kt +++ b/app/src/main/java/org/linphone/ui/viewmodel/TopBarViewModel.kt @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.ui +package org.linphone.ui.viewmodel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel diff --git a/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt b/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt index 87cb0c6d4..b2a623e80 100644 --- a/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt +++ b/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt @@ -22,7 +22,6 @@ package org.linphone.utils import android.view.View import androidx.activity.OnBackPressedCallback import androidx.slidingpanelayout.widget.SlidingPaneLayout -import org.linphone.core.tools.Log class SlidingPaneBackPressedCallback(private val slidingPaneLayout: SlidingPaneLayout) : OnBackPressedCallback( @@ -31,25 +30,19 @@ class SlidingPaneBackPressedCallback(private val slidingPaneLayout: SlidingPaneL SlidingPaneLayout.PanelSlideListener { init { - Log.d( - "[Master Fragment] SlidingPane isSlideable = ${slidingPaneLayout.isSlideable}, isOpen = ${slidingPaneLayout.isOpen}" - ) slidingPaneLayout.addPanelSlideListener(this) } override fun handleOnBackPressed() { - Log.d("[Master Fragment] handleOnBackPressed, closing sliding pane") slidingPaneLayout.hideKeyboard() slidingPaneLayout.closePane() } override fun onPanelOpened(panel: View) { - Log.d("[Master Fragment] onPanelOpened") isEnabled = true } override fun onPanelClosed(panel: View) { - Log.d("[Master Fragment] onPanelClosed") isEnabled = false } diff --git a/app/src/main/res/layout-land/bottom_nav_bar.xml b/app/src/main/res/layout-land/bottom_nav_bar.xml index e51499a7a..9a016b171 100644 --- a/app/src/main/res/layout-land/bottom_nav_bar.xml +++ b/app/src/main/res/layout-land/bottom_nav_bar.xml @@ -43,6 +43,8 @@ android:gravity="center" android:onClick="@{onContactsClicked}" android:text="Contacts" + android:maxLines="1" + android:ellipsize="end" android:textColor="@color/gray_9" android:textSize="11sp" android:textStyle="@{contactsSelected ? Typeface.BOLD : Typeface.NORMAL}" @@ -60,6 +62,8 @@ android:drawableTint="@{callsSelected ? @color/primary_color : @color/gray_9, default=@color/gray_9}" android:gravity="center" android:text="Calls" + android:maxLines="1" + android:ellipsize="end" android:textColor="@color/gray_9" android:textSize="11sp" android:textStyle="@{callsSelected ? Typeface.BOLD : Typeface.NORMAL}" @@ -78,6 +82,8 @@ android:gravity="center" android:onClick="@{onConversationsClicked}" android:text="Conversations" + android:maxLines="1" + android:ellipsize="end" android:textColor="@color/gray_9" android:textSize="11sp" android:textStyle="@{conversationsSelected ? Typeface.BOLD : Typeface.NORMAL}" @@ -95,6 +101,8 @@ android:drawableTint="@{meetingsSelected ? @color/primary_color : @color/gray_9, default=@color/gray_9}" android:gravity="center" android:text="Meetings" + android:maxLines="1" + android:ellipsize="end" android:textColor="@color/gray_9" android:textSize="11sp" android:textStyle="@{meetingsSelected ? Typeface.BOLD : Typeface.NORMAL}" diff --git a/app/src/main/res/layout-land/contacts_fragment.xml b/app/src/main/res/layout-land/contacts_fragment.xml index 3c9085c25..79dd2ec87 100644 --- a/app/src/main/res/layout-land/contacts_fragment.xml +++ b/app/src/main/res/layout-land/contacts_fragment.xml @@ -19,122 +19,88 @@ type="org.linphone.ui.contacts.viewmodel.ContactsListViewModel" /> - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_nav_bar.xml b/app/src/main/res/layout/bottom_nav_bar.xml index ac60ed60b..90253f780 100644 --- a/app/src/main/res/layout/bottom_nav_bar.xml +++ b/app/src/main/res/layout/bottom_nav_bar.xml @@ -43,6 +43,8 @@ android:drawableTop="@drawable/contacts" android:drawablePadding="10dp" android:text="Contacts" + android:maxLines="1" + android:ellipsize="end" android:textSize="11sp" android:gravity="center" android:textColor="@color/gray_9" @@ -63,6 +65,8 @@ android:drawableTop="@drawable/calls" android:drawablePadding="10dp" android:text="Calls" + android:maxLines="1" + android:ellipsize="end" android:textSize="11sp" android:gravity="center" android:textColor="@color/gray_9" @@ -84,6 +88,8 @@ android:drawableTop="@drawable/conversations" android:drawablePadding="10dp" android:text="Conversations" + android:maxLines="1" + android:ellipsize="end" android:textSize="11sp" android:gravity="center" android:textColor="@color/gray_9" @@ -104,6 +110,8 @@ android:drawableTop="@drawable/meetings" android:drawablePadding="10dp" android:text="Meetings" + android:maxLines="1" + android:ellipsize="end" android:textSize="11sp" android:gravity="center" android:textColor="@color/gray_9" diff --git a/app/src/main/res/layout/contact_fragment.xml b/app/src/main/res/layout/contact_fragment.xml index a65d26f74..e183e6517 100644 --- a/app/src/main/res/layout/contact_fragment.xml +++ b/app/src/main/res/layout/contact_fragment.xml @@ -8,8 +8,8 @@ name="backClickListener" type="View.OnClickListener" /> + name="viewModel" + type="org.linphone.ui.contacts.viewmodel.ContactViewModel" /> - - - - - - - - - + app:layout_constraintTop_toBottomOf="@id/top_bar" + app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" + app:layout_constraintEnd_toEndOf="parent"/> + app:navGraph="@navigation/contact_nav_graph"/> diff --git a/app/src/main/res/layout/contacts_list_fragment.xml b/app/src/main/res/layout/contacts_list_fragment.xml new file mode 100644 index 000000000..43f0fc48d --- /dev/null +++ b/app/src/main/res/layout/contacts_list_fragment.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml index 81fc65647..293f00ce7 100644 --- a/app/src/main/res/layout/main_activity.xml +++ b/app/src/main/res/layout/main_activity.xml @@ -11,7 +11,7 @@ type="View.OnClickListener" /> + type="org.linphone.ui.viewmodel.TopBarViewModel" /> diff --git a/app/src/main/res/layout/top_search_bar.xml b/app/src/main/res/layout/top_search_bar.xml index 3ecb3b382..a4f186d87 100644 --- a/app/src/main/res/layout/top_search_bar.xml +++ b/app/src/main/res/layout/top_search_bar.xml @@ -10,7 +10,7 @@ type="View.OnClickListener" /> + type="org.linphone.ui.viewmodel.TopBarViewModel" /> + android:name="contactRefKey" + app:argType="string" /> - - - - \ No newline at end of file diff --git a/app/src/main/res/navigation/main_nav_graph.xml b/app/src/main/res/navigation/main_nav_graph.xml index 1ffc3a710..c52c87dba 100644 --- a/app/src/main/res/navigation/main_nav_graph.xml +++ b/app/src/main/res/navigation/main_nav_graph.xml @@ -79,11 +79,14 @@ android:label="ContactFragment" tools:layout="@layout/contact_fragment" > + android:name="contactRefKey" + app:argType="string" /> - + \ No newline at end of file