diff --git a/app/src/main/java/org/linphone/ui/calls/fragment/CallsFragment.kt b/app/src/main/java/org/linphone/ui/calls/fragment/CallsFragment.kt
index 5a3ed12ae..009c3ebad 100644
--- a/app/src/main/java/org/linphone/ui/calls/fragment/CallsFragment.kt
+++ b/app/src/main/java/org/linphone/ui/calls/fragment/CallsFragment.kt
@@ -19,6 +19,80 @@
*/
package org.linphone.ui.calls.fragment
-import androidx.fragment.app.Fragment
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.view.doOnPreDraw
+import androidx.navigation.fragment.findNavController
+import androidx.slidingpanelayout.widget.SlidingPaneLayout
+import org.linphone.R
+import org.linphone.databinding.CallsFragmentBinding
+import org.linphone.ui.fragment.GenericFragment
+import org.linphone.utils.SlidingPaneBackPressedCallback
-class CallsFragment : Fragment()
+class CallsFragment : GenericFragment() {
+ private lateinit var binding: CallsFragmentBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = CallsFragmentBinding.inflate(layoutInflater)
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.lifecycleOwner = viewLifecycleOwner
+
+ binding.root.doOnPreDraw {
+ val slidingPane = binding.slidingPaneLayout
+ slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
+
+ sharedViewModel.isSlidingPaneSlideable.value = slidingPane.isSlideable
+
+ requireActivity().onBackPressedDispatcher.addCallback(
+ viewLifecycleOwner,
+ SlidingPaneBackPressedCallback(slidingPane)
+ )
+ }
+
+ sharedViewModel.closeSlidingPaneEvent.observe(
+ viewLifecycleOwner
+ ) {
+ it.consume {
+ binding.slidingPaneLayout.closePane()
+ }
+ }
+
+ sharedViewModel.openSlidingPaneEvent.observe(
+ viewLifecycleOwner
+ ) {
+ it.consume {
+ binding.slidingPaneLayout.openPane()
+ }
+ }
+
+ sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
+ it.consume {
+ if (findNavController().currentDestination?.id == R.id.callsFragment) {
+ val action =
+ CallsFragmentDirections.actionCallsFragmentToConversationsFragment()
+ findNavController().navigate(action)
+ }
+ }
+ }
+
+ sharedViewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
+ it.consume {
+ if (findNavController().currentDestination?.id == R.id.callsFragment) {
+ val action = CallsFragmentDirections.actionCallsFragmentToContactsFragment()
+ findNavController().navigate(action)
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/org/linphone/ui/calls/fragment/CallsListFragment.kt b/app/src/main/java/org/linphone/ui/calls/fragment/CallsListFragment.kt
index 8a53eed43..b83fb4fc2 100644
--- a/app/src/main/java/org/linphone/ui/calls/fragment/CallsListFragment.kt
+++ b/app/src/main/java/org/linphone/ui/calls/fragment/CallsListFragment.kt
@@ -19,6 +19,68 @@
*/
package org.linphone.ui.calls.fragment
-import androidx.fragment.app.Fragment
+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.navigation.fragment.findNavController
+import androidx.navigation.navGraphViewModels
+import org.linphone.R
+import org.linphone.databinding.CallsListFragmentBinding
+import org.linphone.ui.MainActivity
+import org.linphone.ui.calls.viewmodel.CallsListViewModel
+import org.linphone.ui.fragment.GenericFragment
+import org.linphone.utils.Event
+import org.linphone.utils.setKeyboardInsetListener
-class CallsListFragment : Fragment()
+class CallsListFragment : GenericFragment() {
+
+ private lateinit var binding: CallsListFragmentBinding
+
+ private val listViewModel: CallsListViewModel by navGraphViewModels(
+ R.id.callsListFragment
+ )
+
+ 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 = CallsListFragmentBinding.inflate(layoutInflater)
+ return binding.root
+ }
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ binding.lifecycleOwner = viewLifecycleOwner
+ binding.viewModel = listViewModel
+
+ binding.root.setKeyboardInsetListener { keyboardVisible ->
+ val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
+ listViewModel.bottomNavBarVisible.value = !portraitOrientation || !keyboardVisible
+ }
+
+ binding.setOnConversationsClicked {
+ sharedViewModel.navigateToConversationsEvent.value = Event(true)
+ }
+
+ binding.setOnContactsClicked {
+ sharedViewModel.navigateToContactsEvent.value = Event(true)
+ }
+
+ binding.setOnAvatarClickListener {
+ (requireActivity() as MainActivity).toggleDrawerMenu()
+ }
+ }
+}
diff --git a/app/src/main/java/org/linphone/ui/calls/viewmodel/CallsListViewModel.kt b/app/src/main/java/org/linphone/ui/calls/viewmodel/CallsListViewModel.kt
new file mode 100644
index 000000000..aef8b3a2b
--- /dev/null
+++ b/app/src/main/java/org/linphone/ui/calls/viewmodel/CallsListViewModel.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.calls.viewmodel
+
+import org.linphone.ui.viewmodel.TopBarViewModel
+
+class CallsListViewModel : TopBarViewModel() {
+ init {
+ title.value = "Calls"
+ bottomNavBarVisible.value = true
+ }
+}
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 3e88bf773..dcfd4a973 100644
--- a/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/viewmodel/SharedMainViewModel.kt
@@ -36,6 +36,8 @@ class SharedMainViewModel : ViewModel() {
val navigateToCallsEvent = MutableLiveData>()
+ val navigateToContactsEvent = MutableLiveData>()
+
/* Contacts related */
val showContactEvent = MutableLiveData>()
diff --git a/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt b/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt
index b2a623e80..49181c37b 100644
--- a/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt
+++ b/app/src/main/java/org/linphone/utils/SlidingPaneBackPressCallback.kt
@@ -46,5 +46,7 @@ class SlidingPaneBackPressedCallback(private val slidingPaneLayout: SlidingPaneL
isEnabled = false
}
- override fun onPanelSlide(panel: View, slideOffset: Float) { }
+ override fun onPanelSlide(panel: View, slideOffset: Float) {
+ isEnabled = true
+ }
}
diff --git a/app/src/main/res/layout-land/calls_list_fragment.xml b/app/src/main/res/layout-land/calls_list_fragment.xml
new file mode 100644
index 000000000..252d9a7fc
--- /dev/null
+++ b/app/src/main/res/layout-land/calls_list_fragment.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/calls_list_fragment.xml b/app/src/main/res/layout/calls_list_fragment.xml
new file mode 100644
index 000000000..e71d83cf7
--- /dev/null
+++ b/app/src/main/res/layout/calls_list_fragment.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/top_search_bar.xml b/app/src/main/res/layout/top_search_bar.xml
index 0439c6c1d..b6e19ae5c 100644
--- a/app/src/main/res/layout/top_search_bar.xml
+++ b/app/src/main/res/layout/top_search_bar.xml
@@ -45,7 +45,8 @@
android:layout_marginStart="15dp"
app:avatarViewBorderColor="@color/trusted_blue"
app:avatarViewBorderWidth="2dp"
- app:avatarViewIndicatorSizeCriteria="4"
+ app:avatarViewIndicatorSizeCriteria="3"
+ app:avatarViewIndicatorBorderSizeCriteria="4"
app:avatarViewIndicatorEnabled="true"
app:avatarViewIndicatorDrawable="@drawable/trusted"
app:avatarViewIndicatorPosition="bottomLeft"
diff --git a/app/src/main/res/navigation/calls_left_nav_graph.xml b/app/src/main/res/navigation/calls_left_nav_graph.xml
index ca80bb6dd..b14239118 100644
--- a/app/src/main/res/navigation/calls_left_nav_graph.xml
+++ b/app/src/main/res/navigation/calls_left_nav_graph.xml
@@ -1,6 +1,14 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/calls_left_nav_graph"
+ app:startDestination="@id/callsListFragment">
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/calls_right_nav_graph.xml b/app/src/main/res/navigation/calls_right_nav_graph.xml
index ee5e03451..ff131a814 100644
--- a/app/src/main/res/navigation/calls_right_nav_graph.xml
+++ b/app/src/main/res/navigation/calls_right_nav_graph.xml
@@ -1,6 +1,14 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/calls_right_nav_graph"
+ app:startDestination="@id/emptyFragment">
+
+
\ No newline at end of file