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