Started calls list fragments

This commit is contained in:
Sylvain Berfini 2023-08-08 17:44:48 +02:00
parent 4cc2a11cc5
commit 84e05e9490
10 changed files with 341 additions and 8 deletions

View file

@ -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)
}
}
}
}
}

View file

@ -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()
}
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
package org.linphone.ui.calls.viewmodel
import org.linphone.ui.viewmodel.TopBarViewModel
class CallsListViewModel : TopBarViewModel() {
init {
title.value = "Calls"
bottomNavBarVisible.value = true
}
}

View file

@ -36,6 +36,8 @@ class SharedMainViewModel : ViewModel() {
val navigateToCallsEvent = MutableLiveData<Event<Boolean>>()
val navigateToContactsEvent = MutableLiveData<Event<Boolean>>()
/* Contacts related */
val showContactEvent = MutableLiveData<Event<String>>()

View file

@ -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
}
}

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="onAvatarClickListener"
type="View.OnClickListener" />
<variable
name="onContactsClicked"
type="View.OnClickListener" />
<variable
name="onConversationsClicked"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.calls.viewmodel.CallsListViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primary_color">
<include
android:id="@+id/top_bar"
bind:viewModel="@{viewModel}"
bind:onAvatarClickListener="@{onAvatarClickListener}"
layout="@layout/top_search_bar"
android:layout_height="wrap_content"
android:layout_width="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="7dp"
android:src="@drawable/shape_white_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/top_bar" />
<include
bind:onConversationsClicked="@{onConversationsClicked}"
bind:onContactsClicked="@{onContactsClicked}"
bind:callsSelected="@{true}"
android:id="@+id/bottom_nav_bar"
android:visibility="@{viewModel.bottomNavBarVisible ? View.VISIBLE : View.GONE}"
layout="@layout/bottom_nav_bar"
android:layout_width="75dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/add"
app:tint="@color/gray_8"
app:backgroundTint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:bind="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="onAvatarClickListener"
type="View.OnClickListener" />
<variable
name="onContactsClicked"
type="View.OnClickListener" />
<variable
name="onConversationsClicked"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.calls.viewmodel.CallsListViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/primary_color">
<include
android:id="@+id/top_bar"
bind:viewModel="@{viewModel}"
bind:onAvatarClickListener="@{onAvatarClickListener}"
layout="@layout/top_search_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="7dp"
android:src="@drawable/shape_white_background"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_bar" />
<include
bind:onConversationsClicked="@{onConversationsClicked}"
bind:onContactsClicked="@{onContactsClicked}"
bind:callsSelected="@{true}"
android:id="@+id/bottom_nav_bar"
android:visibility="@{viewModel.bottomNavBarVisible ? View.VISIBLE : View.GONE}"
layout="@layout/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/add"
app:tint="@color/gray_8"
app:backgroundTint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View file

@ -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"

View file

@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/calls_left_nav_graph">
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/calls_left_nav_graph"
app:startDestination="@id/callsListFragment">
<fragment
android:id="@+id/callsListFragment"
android:name="org.linphone.ui.calls.fragment.CallsListFragment"
android:label="CallsListFragment"
tools:layout="@layout/calls_list_fragment"/>
</navigation>

View file

@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/calls_right_nav_graph">
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/calls_right_nav_graph"
app:startDestination="@id/emptyFragment">
<fragment
android:id="@+id/emptyFragment"
android:name="org.linphone.ui.fragment.EmptyFragment"
android:label="EmptyFragment"
tools:layout="@layout/empty_fragment"/>
</navigation>