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 da9649eee..1918eb72a 100644
--- a/app/src/main/java/org/linphone/ui/contacts/ContactFragment.kt
+++ b/app/src/main/java/org/linphone/ui/contacts/ContactFragment.kt
@@ -33,6 +33,7 @@ import org.linphone.R
import org.linphone.databinding.ContactFragmentBinding
import org.linphone.ui.contacts.viewmodel.ContactViewModel
import org.linphone.ui.viewmodel.SharedMainViewModel
+import org.linphone.utils.Event
class ContactFragment : Fragment() {
private lateinit var binding: ContactFragmentBinding
@@ -76,7 +77,7 @@ class ContactFragment : Fragment() {
viewModel.findContactByRefKey(refKey)
binding.setBackClickListener {
- requireActivity().onBackPressedDispatcher.onBackPressed()
+ sharedViewModel.closeSlidingPaneEvent.value = Event(true)
}
sharedViewModel.isSlidingPaneSlideable.observe(viewLifecycleOwner) { slideable ->
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 9dc80145f..f41459f0e 100644
--- a/app/src/main/java/org/linphone/ui/contacts/ContactsFragment.kt
+++ b/app/src/main/java/org/linphone/ui/contacts/ContactsFragment.kt
@@ -19,53 +19,27 @@
*/
package org.linphone.ui.contacts
-import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-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.findNavController
import androidx.navigation.fragment.findNavController
-import androidx.navigation.navGraphViewModels
-import androidx.recyclerview.widget.LinearLayoutManager
import androidx.slidingpanelayout.widget.SlidingPaneLayout
import androidx.transition.AutoTransition
import org.linphone.R
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
-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? {
- if (findNavController().currentDestination?.id == R.id.newContactFragment) {
- // Holds fragment in place while new contact fragment slides over it
- return AnimationUtils.loadAnimation(activity, R.anim.hold)
- }
- return super.onCreateAnimation(transit, enter, nextAnim)
- }
-
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -84,15 +58,7 @@ class ContactsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- postponeEnterTransition()
-
binding.lifecycleOwner = viewLifecycleOwner
- binding.viewModel = listViewModel
-
- binding.root.setKeyboardInsetListener { keyboardVisible ->
- val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
- listViewModel.bottomNavBarVisible.value = !portraitOrientation || !keyboardVisible
- }
binding.root.doOnPreDraw {
val slidingPane = binding.slidingPaneLayout
@@ -107,85 +73,39 @@ class ContactsFragment : Fragment() {
slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
}
- adapter = ContactsListAdapter(viewLifecycleOwner)
- binding.contactsView.contactsList.setHasFixedSize(true)
- binding.contactsView.contactsList.adapter = adapter
-
- adapter.contactLongClickedEvent.observe(viewLifecycleOwner) {
- it.consume { model ->
- val modalBottomSheet = ContactsListMenuDialogFragment(model.friend) {
- adapter.resetSelection()
- }
- modalBottomSheet.show(parentFragmentManager, ContactsListMenuDialogFragment.TAG)
- }
- }
-
- adapter.contactClickedEvent.observe(viewLifecycleOwner) {
- 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.id ?: ""
- )
- navHostFragment.navController.navigate(action)
-
- if (!binding.slidingPaneLayout.isOpen) {
- binding.slidingPaneLayout.openPane()
- }
- }
- }
- }
-
- val layoutManager = LinearLayoutManager(requireContext())
- binding.contactsView.contactsList.layoutManager = layoutManager
-
- listViewModel.contactsList.observe(
+ sharedViewModel.closeSlidingPaneEvent.observe(
viewLifecycleOwner
) {
- adapter.submitList(it)
-
- (view.parent as? ViewGroup)?.doOnPreDraw {
- startPostponedEnterTransition()
- }
- }
-
- listViewModel.searchFilter.observe(
- viewLifecycleOwner
- ) {
- listViewModel.applyFilter()
- }
-
- listViewModel.focusSearchBarEvent.observe(viewLifecycleOwner) {
- it.consume { show ->
- if (show) {
- // To automatically open keyboard
- binding.topBar.search.showKeyboard(requireActivity().window)
- } else {
- binding.topBar.search.hideKeyboard()
+ it.consume { close ->
+ if (close) {
+ binding.slidingPaneLayout.closePane()
}
}
}
- binding.setOnNewContactClicked {
- if (findNavController().currentDestination?.id == R.id.contactsFragment) {
- findNavController().navigate(R.id.action_contactsFragment_to_newContactFragment)
- }
- }
-
- binding.setOnConversationsClicked {
- if (findNavController().currentDestination?.id == R.id.contactsFragment) {
- val extras = FragmentNavigatorExtras(
- binding.bottomNavBar.root to "bottom_nav_bar"
+ sharedViewModel.showContactEvent.observe(
+ viewLifecycleOwner
+ ) {
+ it.consume { refKey ->
+ val navController = binding.contactsRightNavContainer.findNavController()
+ val action = ContactFragmentDirections.actionGlobalContactFragment(
+ refKey
)
- val action = ContactsFragmentDirections.actionContactsFragmentToConversationsFragment()
- findNavController().navigate(action, extras)
+ navController.navigate(action)
+
+ if (!binding.slidingPaneLayout.isOpen) {
+ binding.slidingPaneLayout.openPane()
+ }
}
}
- binding.setOnAvatarClickListener {
- (requireActivity() as MainActivity).toggleDrawerMenu()
+ sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
+ it.consume {
+ if (findNavController().currentDestination?.id == R.id.contactsFragment) {
+ val action = ContactsFragmentDirections.actionContactsFragmentToConversationsFragment()
+ findNavController().navigate(action)
+ }
+ }
}
}
}
diff --git a/app/src/main/java/org/linphone/ui/contacts/ContactsListFragment.kt b/app/src/main/java/org/linphone/ui/contacts/ContactsListFragment.kt
new file mode 100644
index 000000000..ddcb53053
--- /dev/null
+++ b/app/src/main/java/org/linphone/ui/contacts/ContactsListFragment.kt
@@ -0,0 +1,153 @@
+/*
+ * 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
+
+import android.content.res.Configuration
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+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.findNavController
+import androidx.navigation.navGraphViewModels
+import androidx.recyclerview.widget.LinearLayoutManager
+import org.linphone.R
+import org.linphone.databinding.ContactsListFragmentBinding
+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.Event
+import org.linphone.utils.hideKeyboard
+import org.linphone.utils.setKeyboardInsetListener
+import org.linphone.utils.showKeyboard
+
+class ContactsListFragment : Fragment() {
+ private lateinit var binding: ContactsListFragmentBinding
+
+ private lateinit var sharedViewModel: SharedMainViewModel
+
+ private val listViewModel: ContactsListViewModel by navGraphViewModels(
+ R.id.contactsListFragment
+ )
+
+ private lateinit var adapter: ContactsListAdapter
+
+ override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
+ if (findNavController().currentDestination?.id == R.id.newContactFragment) {
+ // Holds fragment in place while new contact fragment slides over it
+ return AnimationUtils.loadAnimation(activity, R.anim.hold)
+ }
+ return super.onCreateAnimation(transit, enter, nextAnim)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = ContactsListFragmentBinding.inflate(layoutInflater)
+
+ sharedViewModel = requireActivity().run {
+ ViewModelProvider(this)[SharedMainViewModel::class.java]
+ }
+
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ postponeEnterTransition()
+
+ binding.lifecycleOwner = viewLifecycleOwner
+ binding.viewModel = listViewModel
+
+ binding.root.setKeyboardInsetListener { keyboardVisible ->
+ val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
+ listViewModel.bottomNavBarVisible.value = !portraitOrientation || !keyboardVisible
+ }
+
+ adapter = ContactsListAdapter(viewLifecycleOwner)
+ binding.contactsList.setHasFixedSize(true)
+ binding.contactsList.adapter = adapter
+
+ adapter.contactLongClickedEvent.observe(viewLifecycleOwner) {
+ it.consume { model ->
+ val modalBottomSheet = ContactsListMenuDialogFragment(model.friend) {
+ adapter.resetSelection()
+ }
+ modalBottomSheet.show(parentFragmentManager, ContactsListMenuDialogFragment.TAG)
+ }
+ }
+
+ adapter.contactClickedEvent.observe(viewLifecycleOwner) {
+ it.consume { model ->
+ sharedViewModel.showContactEvent.value = Event(model.id ?: "")
+ }
+ }
+
+ val layoutManager = LinearLayoutManager(requireContext())
+ binding.contactsList.layoutManager = layoutManager
+
+ listViewModel.contactsList.observe(
+ viewLifecycleOwner
+ ) {
+ adapter.submitList(it)
+
+ (view.parent as? ViewGroup)?.doOnPreDraw {
+ startPostponedEnterTransition()
+ }
+ }
+
+ listViewModel.focusSearchBarEvent.observe(viewLifecycleOwner) {
+ it.consume { show ->
+ if (show) {
+ // To automatically open keyboard
+ binding.topBar.search.showKeyboard(requireActivity().window)
+ } else {
+ binding.topBar.search.hideKeyboard()
+ }
+ }
+ }
+
+ listViewModel.searchFilter.observe(viewLifecycleOwner) { filter ->
+ listViewModel.applyFilter(filter)
+ }
+
+ binding.setOnNewContactClicked {
+ if (findNavController().currentDestination?.id == R.id.contactsListFragment) {
+ findNavController().navigate(R.id.action_contactsListFragment_to_newContactFragment)
+ }
+ }
+
+ binding.setOnConversationsClicked {
+ sharedViewModel.navigateToConversationsEvent.value = Event(true)
+ }
+
+ binding.setOnAvatarClickListener {
+ (requireActivity() as MainActivity).toggleDrawerMenu()
+ }
+ }
+}
diff --git a/app/src/main/java/org/linphone/ui/contacts/NewContactFragment.kt b/app/src/main/java/org/linphone/ui/contacts/NewContactFragment.kt
index c4a6329dc..0f273c446 100644
--- a/app/src/main/java/org/linphone/ui/contacts/NewContactFragment.kt
+++ b/app/src/main/java/org/linphone/ui/contacts/NewContactFragment.kt
@@ -25,6 +25,7 @@ import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import androidx.fragment.app.Fragment
+import androidx.navigation.fragment.findNavController
import org.linphone.databinding.NewContactFragmentBinding
class NewContactFragment : Fragment() {
@@ -55,7 +56,7 @@ class NewContactFragment : Fragment() {
// postponeEnterTransition()
binding.setCancelClickListener {
- requireActivity().onBackPressedDispatcher.onBackPressed()
+ findNavController().popBackStack()
}
/*(view.parent as? ViewGroup)?.doOnPreDraw {
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 25a8098e7..72e05fba2 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
@@ -25,40 +25,57 @@ import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.contacts.ContactsListener
import org.linphone.core.Friend
import org.linphone.core.MagicSearch
+import org.linphone.core.MagicSearchListenerStub
import org.linphone.core.SearchResult
import org.linphone.core.tools.Log
import org.linphone.ui.contacts.model.ContactModel
import org.linphone.ui.viewmodel.TopBarViewModel
class ContactsListViewModel : TopBarViewModel() {
- val bottomNavBarVisible = MutableLiveData()
-
val contactsList = MutableLiveData>()
+ private var currentFilter = ""
+ private var previousFilter = "NotSet"
+
+ private lateinit var magicSearch: MagicSearch
+
+ private val magicSearchListener = object : MagicSearchListenerStub() {
+ override fun onSearchResultsReceived(magicSearch: MagicSearch) {
+ // Core thread
+ Log.i("[Contacts] Magic search contacts available")
+ processMagicSearchResults(magicSearch.lastSearch)
+ }
+ }
+
private val contactsListener = object : ContactsListener {
override fun onContactsLoaded() {
// Core thread
- applyFilter()
+ applyFilter(currentFilter)
}
}
init {
title.value = "Contacts"
bottomNavBarVisible.value = true
- coreContext.postOnCoreThread {
+
+ coreContext.postOnCoreThread { core ->
coreContext.contactsManager.addListener(contactsListener)
+ magicSearch = core.createMagicSearch()
+ magicSearch.limitedSearch = false
+ magicSearch.addListener(magicSearchListener)
}
- applyFilter()
+ applyFilter(currentFilter)
}
override fun onCleared() {
coreContext.postOnCoreThread {
+ magicSearch.removeListener(magicSearchListener)
coreContext.contactsManager.removeListener(contactsListener)
}
super.onCleared()
}
- override fun processMagicSearchResults(results: Array) {
+ fun processMagicSearchResults(results: Array) {
// Core thread
Log.i("[Contacts List] Processing ${results.size} results")
contactsList.value.orEmpty().forEach(ContactModel::destroy)
@@ -85,9 +102,11 @@ class ContactsListViewModel : TopBarViewModel() {
Log.i("[Contacts] Processed ${results.size} results")
}
- fun applyFilter() {
+ fun applyFilter(filter: String) {
+ // UI thread
coreContext.postOnCoreThread {
applyFilter(
+ filter,
"",
MagicSearch.Source.Friends.toInt(),
MagicSearch.Aggregation.Friend
@@ -95,6 +114,34 @@ class ContactsListViewModel : TopBarViewModel() {
}
}
+ private fun applyFilter(
+ filter: String,
+ domain: String,
+ sources: Int,
+ aggregation: MagicSearch.Aggregation
+ ) {
+ // Core thread
+ if (previousFilter.isNotEmpty() && (
+ previousFilter.length > filter.length ||
+ (previousFilter.length == filter.length && previousFilter != filter)
+ )
+ ) {
+ magicSearch.resetSearchCache()
+ }
+ currentFilter = filter
+ previousFilter = filter
+
+ Log.i(
+ "[Contacts] Asking Magic search for contacts matching filter [$filter], domain [$domain] and in sources [$sources]"
+ )
+ magicSearch.getContactsListAsync(
+ filter,
+ domain,
+ sources,
+ aggregation
+ )
+ }
+
private fun createFriendFromSearchResult(searchResult: SearchResult): Friend {
// Core thread
val searchResultFriend = searchResult.friend
diff --git a/app/src/main/java/org/linphone/ui/conversations/ConversationsFragment.kt b/app/src/main/java/org/linphone/ui/conversations/ConversationsFragment.kt
index b36cb7093..fd6b22559 100644
--- a/app/src/main/java/org/linphone/ui/conversations/ConversationsFragment.kt
+++ b/app/src/main/java/org/linphone/ui/conversations/ConversationsFragment.kt
@@ -166,11 +166,8 @@ class ConversationsFragment : Fragment() {
binding.setOnContactsClicked {
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
- val extras = FragmentNavigatorExtras(
- binding.bottomNavBar.root to "bottom_nav_bar"
- )
val action = ConversationsFragmentDirections.actionConversationsFragmentToContactsFragment()
- findNavController().navigate(action, extras)
+ findNavController().navigate(action)
}
}
}
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 e6b5dfaf2..6ec39c850 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
@@ -27,7 +27,6 @@ import org.linphone.core.ChatMessage
import org.linphone.core.ChatRoom
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.conversations.data.ChatRoomData
import org.linphone.ui.viewmodel.TopBarViewModel
@@ -114,10 +113,6 @@ class ConversationsListViewModel : TopBarViewModel() {
super.onCleared()
}
- override fun processMagicSearchResults(results: Array) {
- TODO("Not yet implemented")
- }
-
private fun addChatRoomToList(chatRoom: ChatRoom) {
val index = findChatRoomIndex(chatRoom)
if (index != -1) {
diff --git a/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt b/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt
index f30268e95..6ac3a1e7f 100644
--- a/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt
@@ -21,7 +21,18 @@ package org.linphone.ui.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
+import org.linphone.utils.Event
class SharedMainViewModel : ViewModel() {
+ /* Sliding Pane & navigation related */
+
val isSlidingPaneSlideable = MutableLiveData()
+
+ val closeSlidingPaneEvent = MutableLiveData>()
+
+ val navigateToConversationsEvent = MutableLiveData>()
+
+ /* Contacts related */
+
+ val showContactEvent = MutableLiveData>()
}
diff --git a/app/src/main/java/org/linphone/ui/viewmodel/TopBarViewModel.kt b/app/src/main/java/org/linphone/ui/viewmodel/TopBarViewModel.kt
index 42f9c2e2b..24188cdc9 100644
--- a/app/src/main/java/org/linphone/ui/viewmodel/TopBarViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/viewmodel/TopBarViewModel.kt
@@ -21,11 +21,6 @@ package org.linphone.ui.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import org.linphone.LinphoneApplication.Companion.coreContext
-import org.linphone.core.MagicSearch
-import org.linphone.core.MagicSearchListenerStub
-import org.linphone.core.SearchResult
-import org.linphone.core.tools.Log
import org.linphone.utils.Event
abstract class TopBarViewModel : ViewModel() {
@@ -39,31 +34,13 @@ abstract class TopBarViewModel : ViewModel() {
MutableLiveData>()
}
- private var previousFilter = "NotSet"
-
- private lateinit var magicSearch: MagicSearch
-
- private val magicSearchListener = object : MagicSearchListenerStub() {
- override fun onSearchResultsReceived(magicSearch: MagicSearch) {
- // Core thread
- Log.i("[Contacts] Magic search contacts available")
- processMagicSearchResults(magicSearch.lastSearch)
- }
- }
+ val bottomNavBarVisible = MutableLiveData()
init {
searchBarVisible.value = false
- coreContext.postOnCoreThread { core ->
- magicSearch = core.createMagicSearch()
- magicSearch.limitedSearch = false
- magicSearch.addListener(magicSearchListener)
- }
}
override fun onCleared() {
- coreContext.postOnCoreThread { core ->
- magicSearch.removeListener(magicSearchListener)
- }
super.onCleared()
}
@@ -83,29 +60,4 @@ abstract class TopBarViewModel : ViewModel() {
// UI thread
searchFilter.value = ""
}
-
- fun applyFilter(domain: String, sources: Int, aggregation: MagicSearch.Aggregation) {
- // Core thread
- val filterValue = searchFilter.value.orEmpty()
- if (previousFilter.isNotEmpty() && (
- previousFilter.length > filterValue.length ||
- (previousFilter.length == filterValue.length && previousFilter != filterValue)
- )
- ) {
- magicSearch.resetSearchCache()
- }
- previousFilter = filterValue
-
- Log.i(
- "[Contacts] Asking Magic search for contacts matching filter [$filterValue], domain [$domain] and in sources [$sources]"
- )
- magicSearch.getContactsListAsync(
- filterValue,
- domain,
- sources,
- aggregation
- )
- }
-
- abstract fun processMagicSearchResults(results: Array)
}
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 9a016b171..71c69d3ea 100644
--- a/app/src/main/res/layout-land/bottom_nav_bar.xml
+++ b/app/src/main/res/layout-land/bottom_nav_bar.xml
@@ -30,7 +30,6 @@
android:id="@+id/bottom_nav_bar"
android:layout_width="75dp"
android:layout_height="match_parent"
- android:transitionName="bottom_nav_bar"
android:background="@color/white">
+ xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ app:defaultNavHost="false"
+ app:navGraph="@navigation/contact_left_nav_graph"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 90253f780..e130a0e1f 100644
--- a/app/src/main/res/layout/bottom_nav_bar.xml
+++ b/app/src/main/res/layout/bottom_nav_bar.xml
@@ -27,7 +27,6 @@
+ xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
-
-
-
-
-
-
-
-
-
+ app:navGraph="@navigation/contact_right_nav_graph"/>
diff --git a/app/src/main/res/layout/contacts_list_fragment.xml b/app/src/main/res/layout/contacts_list_fragment.xml
index 43f0fc48d..1b640ffeb 100644
--- a/app/src/main/res/layout/contacts_list_fragment.xml
+++ b/app/src/main/res/layout/contacts_list_fragment.xml
@@ -5,6 +5,15 @@
+
+
+
@@ -21,6 +30,12 @@
app:constraint_referenced_ids="no_contacts_image, no_contacts_label"
android:visibility="@{viewModel.contactsList.empty ? View.VISIBLE : View.GONE}" />
+
+
+ app:layout_constraintTop_toBottomOf="@id/top_bar" />
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/contact_left_nav_graph.xml b/app/src/main/res/navigation/contact_left_nav_graph.xml
new file mode 100644
index 000000000..f707119b7
--- /dev/null
+++ b/app/src/main/res/navigation/contact_left_nav_graph.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/contact_nav_graph.xml b/app/src/main/res/navigation/contact_right_nav_graph.xml
similarity index 93%
rename from app/src/main/res/navigation/contact_nav_graph.xml
rename to app/src/main/res/navigation/contact_right_nav_graph.xml
index 09f39a722..afda7d6fc 100644
--- a/app/src/main/res/navigation/contact_nav_graph.xml
+++ b/app/src/main/res/navigation/contact_right_nav_graph.xml
@@ -2,7 +2,7 @@
-
+ app:destination="@id/conversationsFragment" />
-
-
-
-
-
-
\ No newline at end of file