Removed unseless Fragment only containing SlidingPaneLayout + using same values for SlidingPaneLayout childs width as on previous releases

This commit is contained in:
Sylvain Berfini 2023-11-14 00:29:39 +01:00
parent 53ca7aef1a
commit 7f10548ecb
30 changed files with 1523 additions and 1962 deletions

View file

@ -1085,7 +1085,7 @@ class NotificationsManager @MainThread constructor(private val context: Context)
return NavDeepLinkBuilder(context)
.setComponentName(MainActivity::class.java)
.setGraph(R.navigation.main_nav_graph)
.setDestination(R.id.conversationsFragment)
.setDestination(R.id.conversationsListFragment)
.setArguments(args)
.createPendingIntent()
}

View file

@ -194,27 +194,27 @@ class MainActivity : AppCompatActivity() {
val startDestination = when (corePreferences.defaultFragment) {
CONTACTS_FRAGMENT_ID -> {
Log.i("$TAG Latest visited page is contacts, setting it as start destination")
R.id.contactsFragment
R.id.contactsListFragment
}
HISTORY_FRAGMENT_ID -> {
Log.i(
"$TAG Latest visited page is call history, setting it as start destination"
)
R.id.historyFragment
R.id.historyListFragment
}
CHAT_FRAGMENT_ID -> {
Log.i(
"$TAG Latest visited page is conversations, setting it as start destination"
)
R.id.conversationsFragment
R.id.conversationsListFragment
}
MEETINGS_FRAGMENT_ID -> {
Log.i("$TAG Latest visited page is meetings, setting it as start destination")
R.id.meetingsFragment
R.id.meetingsListFragment
}
else -> { // Default
Log.i("$TAG No latest visited page stored, using default one (call history)")
R.id.historyFragment
R.id.historyListFragment
}
}
coreContext.postOnMainThread {
@ -230,16 +230,16 @@ class MainActivity : AppCompatActivity() {
override fun onPause() {
val defaultFragmentId = when (sharedViewModel.currentlyDisplayedFragment.value) {
R.id.contactsFragment -> {
R.id.contactsListFragment -> {
CONTACTS_FRAGMENT_ID
}
R.id.historyFragment -> {
R.id.historyListFragment -> {
HISTORY_FRAGMENT_ID
}
R.id.conversationsFragment -> {
R.id.conversationsListFragment -> {
CHAT_FRAGMENT_ID
}
R.id.meetingsFragment -> {
R.id.meetingsListFragment -> {
MEETINGS_FRAGMENT_ID
}
else -> { // Default
@ -352,12 +352,12 @@ class MainActivity : AppCompatActivity() {
if (isNewIntent) {
Log.i("$TAG Going to Conversations fragment")
findNavController().navigate(
R.id.action_global_conversationsFragment,
R.id.action_global_conversationsListFragment,
intent.extras
)
} else {
Log.i("$TAG Going to Conversations fragment instead of default destination")
navGraph.setStartDestination(R.id.conversationsFragment)
navGraph.setStartDestination(R.id.conversationsListFragment)
findNavController().setGraph(navGraph, intent.extras)
}
} else {
@ -415,7 +415,7 @@ class MainActivity : AppCompatActivity() {
}
val navGraph = findNavController().navInflater.inflate(R.navigation.main_nav_graph)
navGraph.setStartDestination(R.id.conversationsFragment)
navGraph.setStartDestination(R.id.conversationsListFragment)
val paths = deferred.awaitAll()
for (path in paths) {

View file

@ -172,7 +172,8 @@ class ConversationFragment : GenericFragment() {
override fun goBack(): Boolean {
coreContext.notificationsManager.resetCurrentlyDisplayedChatRoomId()
sharedViewModel.closeSlidingPaneEvent.value = Event(true)
// If not done, when going back to ConversationsFragment this fragment will be created again
coreContext.notificationsManager.resetCurrentlyDisplayedChatRoomId()
// If not done, when going back to ConversationsListFragment this fragment will be created again
return findNavController().popBackStack()
}
@ -181,7 +182,6 @@ class ConversationFragment : GenericFragment() {
isSlidingPaneChild = true
super.onViewCreated(view, savedInstanceState)
// postponeEnterTransition()
binding.lifecycleOwner = viewLifecycleOwner
@ -234,7 +234,6 @@ class ConversationFragment : GenericFragment() {
}
(view.parent as? ViewGroup)?.doOnPreDraw {
// startPostponedEnterTransition()
sharedViewModel.openSlidingPaneEvent.value = Event(true)
}
}

View file

@ -1,210 +0,0 @@
/*
* 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.main.chat.fragment
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.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.slidingpanelayout.widget.SlidingPaneLayout
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ChatFragmentBinding
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.Event
import org.linphone.utils.SlidingPaneBackPressedCallback
@UiThread
class ConversationsFragment : GenericFragment() {
companion object {
private const val TAG = "[Conversations Fragment]"
}
private lateinit var binding: ChatFragmentBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = ChatFragmentBinding.inflate(layoutInflater)
return binding.root
}
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (
findNavController().currentDestination?.id == R.id.startConversationFragment ||
findNavController().currentDestination?.id == R.id.meetingWaitingRoomFragment
) {
// 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 onViewCreated(view: View, savedInstanceState: Bundle?) {
postponeEnterTransition()
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.conversationsReadyEvent.observe(viewLifecycleOwner) {
it.consume {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true
}
}
}
val args = arguments
if (args != null) {
val localSipUri = args.getString("LocalSipUri")
val remoteSipUri = args.getString("RemoteSipUri")
if (localSipUri != null && remoteSipUri != null) {
Log.i("$TAG Found local [$localSipUri] & remote [$remoteSipUri] URIs in arguments")
val pair = Pair(localSipUri, remoteSipUri)
sharedViewModel.showConversationEvent.value = Event(pair)
args.clear()
}
}
sharedViewModel.closeSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Closing sliding pane")
binding.slidingPaneLayout.closePane()
}
}
}
sharedViewModel.openSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (!binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Opening sliding pane")
binding.slidingPaneLayout.openPane()
}
}
}
sharedViewModel.showStartConversationEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
Log.i("$TAG Navigating to start conversation fragment")
val action =
ConversationsFragmentDirections.actionConversationsFragmentToStartConversationFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.showConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
val localSipUri = pair.first
val remoteSipUri = pair.second
Log.i(
"$TAG Navigating to conversation fragment with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
val action = ConversationFragmentDirections.actionGlobalConversationFragment(
localSipUri,
remoteSipUri
)
binding.chatNavContainer.findNavController().navigate(action)
}
}
sharedViewModel.goToMeetingWaitingRoomEvent.observe(viewLifecycleOwner) {
it.consume { uri ->
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
Log.i("$TAG Navigating to meeting waiting room fragment with URI [$uri]")
val action =
ConversationsFragmentDirections.actionConversationsFragmentToMeetingWaitingRoomFragment(
uri
)
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
// To prevent any previously seen conversation to show up when navigating back to here later
binding.chatNavContainer.findNavController().popBackStack()
val action = ConversationsFragmentDirections.actionConversationsFragmentToContactsFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToHistoryEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
// To prevent any previously seen conversation to show up when navigating back to here later
binding.chatNavContainer.findNavController().popBackStack()
val action = ConversationsFragmentDirections.actionConversationsFragmentToHistoryFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToMeetingsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.conversationsFragment) {
// To prevent any previously seen conversation to show up when navigating back to here later
binding.chatNavContainer.findNavController().popBackStack()
val action = ConversationsFragmentDirections.actionConversationsFragmentToMeetingsFragment()
findNavController().navigate(action)
}
}
}
}
override fun onResume() {
super.onResume()
sharedViewModel.currentlyDisplayedFragment.value = R.id.conversationsFragment
}
}

View file

@ -19,14 +19,17 @@
*/
package org.linphone.ui.main.chat.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.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.R
import org.linphone.core.tools.Log
@ -36,7 +39,6 @@ import org.linphone.ui.main.chat.viewmodel.ConversationsListViewModel
import org.linphone.ui.main.fragment.AbstractTopBarFragment
import org.linphone.ui.main.history.fragment.HistoryMenuDialogFragment
import org.linphone.utils.Event
import org.linphone.utils.setKeyboardInsetListener
@UiThread
class ConversationsListFragment : AbstractTopBarFragment() {
@ -50,6 +52,24 @@ class ConversationsListFragment : AbstractTopBarFragment() {
private lateinit var adapter: ConversationsListAdapter
override fun onDefaultAccountChanged() {
Log.i(
"$TAG Default account changed, updating avatar in top bar & re-computing conversations"
)
listViewModel.applyFilter()
}
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (
findNavController().currentDestination?.id == R.id.startConversationFragment ||
findNavController().currentDestination?.id == R.id.meetingWaitingRoomFragment
) {
// 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?,
@ -118,7 +138,12 @@ class ConversationsListFragment : AbstractTopBarFragment() {
}
binding.setOnNewConversationClicked {
sharedViewModel.showStartConversationEvent.value = Event(true)
if (findNavController().currentDestination?.id == R.id.conversationsListFragment) {
Log.i("$TAG Navigating to start conversation fragment")
val action =
ConversationsListFragmentDirections.actionConversationsListFragmentToStartConversationFragment()
findNavController().navigate(action)
}
}
listViewModel.conversations.observe(viewLifecycleOwner) {
@ -132,7 +157,7 @@ class ConversationsListFragment : AbstractTopBarFragment() {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.conversationsReadyEvent.value = Event(true)
sharedViewModel.isFirstFragmentReady = true
}
}
@ -143,6 +168,36 @@ class ConversationsListFragment : AbstractTopBarFragment() {
}
}
sharedViewModel.showConversationEvent.observe(viewLifecycleOwner) {
it.consume { pair ->
val localSipUri = pair.first
val remoteSipUri = pair.second
Log.i(
"${ConversationsListFragment.TAG} Navigating to conversation fragment with local SIP URI [$localSipUri] and remote SIP URI [$remoteSipUri]"
)
if (findNavController().currentDestination?.id == R.id.conversationsListFragment) {
val action = ConversationFragmentDirections.actionGlobalConversationFragment(
localSipUri,
remoteSipUri
)
binding.chatNavContainer.findNavController().navigate(action)
}
}
}
sharedViewModel.goToMeetingWaitingRoomEvent.observe(viewLifecycleOwner) {
it.consume { uri ->
if (findNavController().currentDestination?.id == R.id.conversationsListFragment) {
Log.i("$TAG Navigating to meeting waiting room fragment with URI [$uri]")
val action =
ConversationsListFragmentDirections.actionConversationsListFragmentToMeetingWaitingRoomFragment(
uri
)
findNavController().navigate(action)
}
}
}
// TopBarFragment related
setViewModelAndTitle(
@ -151,17 +206,23 @@ class ConversationsListFragment : AbstractTopBarFragment() {
getString(R.string.bottom_navigation_conversations_label)
)
binding.root.setKeyboardInsetListener { keyboardVisible ->
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
binding.bottomNavBar.root.visibility = if (!portraitOrientation || !keyboardVisible) View.VISIBLE else View.GONE
}
initBottomNavBar(binding.bottomNavBar.root)
sharedViewModel.defaultAccountChangedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i(
"$TAG Default account changed, updating avatar in top bar & re-computing conversations"
)
listViewModel.applyFilter()
initSlidingPane(binding.slidingPaneLayout)
initNavigation(R.id.conversationsListFragment)
// Handle intent params if any
val args = arguments
if (args != null) {
val localSipUri = args.getString("LocalSipUri")
val remoteSipUri = args.getString("RemoteSipUri")
if (localSipUri != null && remoteSipUri != null) {
Log.i("$TAG Found local [$localSipUri] & remote [$remoteSipUri] URIs in arguments")
val pair = Pair(localSipUri, remoteSipUri)
sharedViewModel.showConversationEvent.value = Event(pair)
args.clear()
}
}
}

View file

@ -265,7 +265,9 @@ class SendMessageInConversationViewModel @UiThread constructor() : ViewModel() {
isParticipantsListOpen.postValue(false)
isEmojiPickerOpen.postValue(false)
stopVoiceRecorder()
if (::voiceMessageRecorder.isInitialized) {
stopVoiceRecorder()
}
voiceRecording.postValue(false)
// Warning: do not delete files

View file

@ -1,177 +0,0 @@
/*
* 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.main.contacts.fragment
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.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.slidingpanelayout.widget.SlidingPaneLayout
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.ContactsFragmentBinding
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.SlidingPaneBackPressedCallback
@UiThread
class ContactsFragment : GenericFragment() {
companion object {
private const val TAG = "[Contacts Fragment]"
}
private lateinit var binding: ContactsFragmentBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = ContactsFragmentBinding.inflate(layoutInflater)
return binding.root
}
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 onViewCreated(view: View, savedInstanceState: Bundle?) {
postponeEnterTransition()
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.contactsReadyEvent.observe(viewLifecycleOwner) {
it.consume {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true
}
}
}
sharedViewModel.closeSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Closing sliding pane")
binding.slidingPaneLayout.closePane()
}
}
}
sharedViewModel.openSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (!binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Opening sliding pane")
binding.slidingPaneLayout.openPane()
}
}
}
sharedViewModel.showContactEvent.observe(
viewLifecycleOwner
) {
it.consume { refKey ->
Log.i("$TAG Displaying contact with ref key [$refKey]")
val navController = binding.contactsNavContainer.findNavController()
val action = ContactFragmentDirections.actionGlobalContactFragment(
refKey
)
navController.navigate(action)
}
}
sharedViewModel.showNewContactEvent.observe(
viewLifecycleOwner
) {
it.consume {
Log.i("$TAG Opening contact editor for creating new contact")
val action = ContactsFragmentDirections.actionContactsFragmentToNewContactFragment()
findNavController().navigate(action)
}
}
sharedViewModel.navigateToHistoryEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.contactsFragment) {
// To prevent any previously seen contact to show up when navigating back to here later
binding.contactsNavContainer.findNavController().popBackStack()
val action = ContactsFragmentDirections.actionContactsFragmentToHistoryFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.contactsFragment) {
// To prevent any previously seen contact to show up when navigating back to here later
binding.contactsNavContainer.findNavController().popBackStack()
val action = ContactsFragmentDirections.actionContactsFragmentToConversationsFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToMeetingsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.contactsFragment) {
// To prevent any previously seen contact to show up when navigating back to here later
binding.contactsNavContainer.findNavController().popBackStack()
val action = ContactsFragmentDirections.actionContactsFragmentToMeetingsFragment()
findNavController().navigate(action)
}
}
}
}
override fun onResume() {
super.onResume()
sharedViewModel.currentlyDisplayedFragment.value = R.id.contactsFragment
}
}

View file

@ -20,7 +20,6 @@
package org.linphone.ui.main.contacts.fragment
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.provider.ContactsContract
import android.view.Gravity
@ -33,6 +32,8 @@ import androidx.core.content.FileProvider
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import java.io.File
import org.linphone.LinphoneApplication.Companion.coreContext
@ -44,7 +45,6 @@ import org.linphone.ui.main.contacts.adapter.ContactsListAdapter
import org.linphone.ui.main.contacts.viewmodel.ContactsListViewModel
import org.linphone.ui.main.fragment.AbstractTopBarFragment
import org.linphone.utils.Event
import org.linphone.utils.setKeyboardInsetListener
@UiThread
class ContactsListFragment : AbstractTopBarFragment() {
@ -59,6 +59,14 @@ class ContactsListFragment : AbstractTopBarFragment() {
private lateinit var adapter: ContactsListAdapter
private lateinit var favouritesAdapter: ContactsListAdapter
override fun onDefaultAccountChanged() {
Log.i(
"$TAG Default account changed, updating avatar in top bar & refreshing contacts list"
)
listViewModel.update()
listViewModel.applyCurrentDefaultAccountFilter()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -106,7 +114,7 @@ class ContactsListFragment : AbstractTopBarFragment() {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.contactsReadyEvent.value = Event(true)
sharedViewModel.isFirstFragmentReady = true
}
}
@ -136,6 +144,32 @@ class ContactsListFragment : AbstractTopBarFragment() {
showFilterPopupMenu(binding.filter)
}
sharedViewModel.showContactEvent.observe(
viewLifecycleOwner
) {
it.consume { refKey ->
Log.i("$TAG Displaying contact with ref key [$refKey]")
val navController = binding.contactsNavContainer.findNavController()
val action = ContactFragmentDirections.actionGlobalContactFragment(
refKey
)
navController.navigate(action)
}
}
sharedViewModel.showNewContactEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (findNavController().currentDestination?.id == R.id.contactsListFragment) {
Log.i("$TAG Opening contact editor for creating new contact")
val action =
ContactsListFragmentDirections.actionContactsListFragmentToNewContactFragment()
findNavController().navigate(action)
}
}
}
// TopBarFragment related
setViewModelAndTitle(
@ -144,20 +178,11 @@ class ContactsListFragment : AbstractTopBarFragment() {
getString(R.string.bottom_navigation_contacts_label)
)
binding.root.setKeyboardInsetListener { keyboardVisible ->
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
binding.bottomNavBar.root.visibility = if (!portraitOrientation || !keyboardVisible) View.VISIBLE else View.GONE
}
initBottomNavBar(binding.bottomNavBar.root)
sharedViewModel.defaultAccountChangedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i(
"$TAG Default account changed, updating avatar in top bar & refreshing contacts list"
)
listViewModel.update()
listViewModel.applyCurrentDefaultAccountFilter()
}
}
initSlidingPane(binding.slidingPaneLayout)
initNavigation(R.id.contactsListFragment)
}
private fun configureAdapter(adapter: ContactsListAdapter) {

View file

@ -19,17 +19,73 @@
*/
package org.linphone.ui.main.fragment
import android.content.res.Configuration
import android.view.View
import androidx.annotation.IdRes
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.navigation.NavDirections
import androidx.navigation.fragment.findNavController
import androidx.slidingpanelayout.widget.SlidingPaneLayout
import com.google.android.material.textfield.TextInputLayout
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.ui.main.MainActivity
import org.linphone.ui.main.chat.fragment.ConversationsListFragmentDirections
import org.linphone.ui.main.contacts.fragment.ContactsListFragmentDirections
import org.linphone.ui.main.history.fragment.HistoryListFragmentDirections
import org.linphone.ui.main.meetings.fragment.MeetingsListFragmentDirections
import org.linphone.ui.main.viewmodel.AbstractTopBarViewModel
import org.linphone.utils.Event
import org.linphone.utils.SlidingPaneBackPressedCallback
import org.linphone.utils.hideKeyboard
import org.linphone.utils.setKeyboardInsetListener
import org.linphone.utils.showKeyboard
@UiThread
abstract class AbstractTopBarFragment : GenericFragment() {
companion object {
private const val TAG = "[Abstract TobBar Fragment]"
}
private var currentFragmentId: Int = 0
abstract fun onDefaultAccountChanged()
fun initSlidingPane(slidingPane: SlidingPaneLayout) {
view?.doOnPreDraw {
slidingPane.lockMode = SlidingPaneLayout.LOCK_MODE_LOCKED
sharedViewModel.isSlidingPaneSlideable.value = slidingPane.isSlideable
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
SlidingPaneBackPressedCallback(slidingPane)
)
}
sharedViewModel.closeSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (slidingPane.isOpen) {
Log.i("$TAG Closing sliding pane")
slidingPane.closePane()
}
}
}
sharedViewModel.openSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (!slidingPane.isOpen) {
Log.i("$TAG Opening sliding pane")
slidingPane.openPane()
}
}
}
}
fun setViewModelAndTitle(
searchBar: TextInputLayout,
viewModel: AbstractTopBarViewModel,
@ -59,34 +115,42 @@ abstract class AbstractTopBarFragment : GenericFragment() {
}
viewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
if (sharedViewModel.currentlyDisplayedFragment.value != R.id.contactsFragment) {
sharedViewModel.navigateToContactsEvent.value = Event(true)
it.consume {
if (currentFragmentId != R.id.contactsListFragment) {
goToContactsList()
}
}
}
viewModel.navigateToHistoryEvent.observe(viewLifecycleOwner) {
if (sharedViewModel.currentlyDisplayedFragment.value != R.id.historyFragment) {
sharedViewModel.navigateToHistoryEvent.value = Event(true)
it.consume {
if (currentFragmentId != R.id.historyListFragment) {
goToHistoryList()
}
}
}
viewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
if (sharedViewModel.currentlyDisplayedFragment.value != R.id.conversationsFragment) {
sharedViewModel.navigateToConversationsEvent.value = Event(true)
it.consume {
if (currentFragmentId != R.id.conversationsListFragment) {
goToConversationsList()
}
}
}
viewModel.navigateToMeetingsEvent.observe(viewLifecycleOwner) {
if (sharedViewModel.currentlyDisplayedFragment.value != R.id.meetingsFragment) {
sharedViewModel.navigateToMeetingsEvent.value = Event(true)
it.consume {
if (currentFragmentId != R.id.meetingsListFragment) {
goToMeetingsList()
}
}
}
sharedViewModel.currentlyDisplayedFragment.observe(viewLifecycleOwner) {
viewModel.contactsSelected.value = it == R.id.contactsFragment
viewModel.callsSelected.value = it == R.id.historyFragment
viewModel.conversationsSelected.value = it == R.id.conversationsFragment
viewModel.meetingsSelected.value = it == R.id.meetingsFragment
viewModel.contactsSelected.value = it == R.id.contactsListFragment
viewModel.callsSelected.value = it == R.id.historyListFragment
viewModel.conversationsSelected.value = it == R.id.conversationsListFragment
viewModel.meetingsSelected.value = it == R.id.meetingsListFragment
}
sharedViewModel.resetMissedCallsCountEvent.observe(viewLifecycleOwner) {
@ -96,8 +160,146 @@ abstract class AbstractTopBarFragment : GenericFragment() {
}
sharedViewModel.defaultAccountChangedEvent.observe(viewLifecycleOwner) {
// Do not consume it!
viewModel.updateAvailableMenus()
it.consume {
Log.i("$TAG Default account changed")
viewModel.updateAvailableMenus()
onDefaultAccountChanged()
}
}
}
fun initBottomNavBar(navBar: View) {
view?.setKeyboardInsetListener { keyboardVisible ->
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
navBar.visibility = if (!portraitOrientation || !keyboardVisible) View.VISIBLE else View.GONE
}
}
fun initNavigation(@IdRes fragmentId: Int) {
currentFragmentId = fragmentId
sharedViewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
it.consume {
goToContactsList()
}
}
sharedViewModel.navigateToHistoryEvent.observe(viewLifecycleOwner) {
it.consume {
goToHistoryList()
}
}
sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
it.consume {
goToConversationsList()
}
}
sharedViewModel.navigateToMeetingsEvent.observe(viewLifecycleOwner) {
it.consume {
goToMeetingsList()
}
}
}
override fun onResume() {
super.onResume()
if (currentFragmentId > 0) {
sharedViewModel.currentlyDisplayedFragment.value = currentFragmentId
}
}
private fun goToContactsList() {
Log.i("$TAG Navigating to contacts list")
when (currentFragmentId) {
R.id.conversationsListFragment -> {
Log.i("$TAG Leaving conversations list")
val action = ConversationsListFragmentDirections.actionConversationsListFragmentToContactsListFragment()
navigateTo(action)
}
R.id.meetingsListFragment -> {
Log.i("$TAG Leaving meetings list")
val action = MeetingsListFragmentDirections.actionMeetingsListFragmentToContactsListFragment()
navigateTo(action)
}
R.id.historyListFragment -> {
Log.i("$TAG Leaving history list")
val action = HistoryListFragmentDirections.actionHistoryListFragmentToContactsListFragment()
navigateTo(action)
}
}
}
private fun goToHistoryList() {
Log.i("$TAG Navigating to history list")
when (currentFragmentId) {
R.id.conversationsListFragment -> {
Log.i("$TAG Leaving conversations list")
val action = ConversationsListFragmentDirections.actionConversationsListFragmentToHistoryListFragment()
navigateTo(action)
}
R.id.contactsListFragment -> {
Log.i("$TAG Leaving contacts list")
val action = ContactsListFragmentDirections.actionContactsListFragmentToHistoryListFragment()
navigateTo(action)
}
R.id.meetingsListFragment -> {
Log.i("$TAG Leaving meetings list")
val action = MeetingsListFragmentDirections.actionMeetingsListFragmentToHistoryListFragment()
navigateTo(action)
}
}
}
private fun goToConversationsList() {
Log.i("$TAG Navigating to conversations list")
when (currentFragmentId) {
R.id.contactsListFragment -> {
Log.i("$TAG Leaving contacts list")
val action = ContactsListFragmentDirections.actionContactsListFragmentToConversationsListFragment()
navigateTo(action)
}
R.id.meetingsListFragment -> {
Log.i("$TAG Leaving meetings list")
val action = MeetingsListFragmentDirections.actionMeetingsListFragmentToConversationsListFragment()
navigateTo(action)
}
R.id.historyListFragment -> {
Log.i("$TAG Leaving history list")
val action = HistoryListFragmentDirections.actionHistoryListFragmentToConversationsListFragment()
navigateTo(action)
}
}
}
private fun goToMeetingsList() {
Log.i("$TAG Navigating to meetings list")
when (currentFragmentId) {
R.id.conversationsListFragment -> {
Log.i("$TAG Leaving conversations list")
val action = ConversationsListFragmentDirections.actionConversationsListFragmentToMeetingsListFragment()
navigateTo(action)
}
R.id.contactsListFragment -> {
Log.i("$TAG Leaving contacts list")
val action = ContactsListFragmentDirections.actionContactsListFragmentToMeetingsListFragment()
navigateTo(action)
}
R.id.historyListFragment -> {
Log.i("$TAG Leaving history list")
val action = HistoryListFragmentDirections.actionHistoryListFragmentToMeetingsListFragment()
navigateTo(action)
}
}
}
private fun navigateTo(action: NavDirections) {
try {
findNavController().navigate(action)
} catch (e: Exception) {
Log.e("$TAG Failed to navigate: $e")
}
}
}

View file

@ -1,175 +0,0 @@
/*
* 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.main.history.fragment
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.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.slidingpanelayout.widget.SlidingPaneLayout
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.HistoryFragmentBinding
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.SlidingPaneBackPressedCallback
@UiThread
class HistoryFragment : GenericFragment() {
companion object {
private const val TAG = "[Calls Fragment]"
}
private lateinit var binding: HistoryFragmentBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = HistoryFragmentBinding.inflate(layoutInflater)
return binding.root
}
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (findNavController().currentDestination?.id == R.id.startCallFragment) {
// 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 onViewCreated(view: View, savedInstanceState: Bundle?) {
postponeEnterTransition()
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.historyReadyEvent.observe(viewLifecycleOwner) {
it.consume {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true
}
}
}
sharedViewModel.closeSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Closing sliding pane")
binding.slidingPaneLayout.closePane()
}
}
}
sharedViewModel.openSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (!binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Opening sliding pane")
binding.slidingPaneLayout.openPane()
}
}
}
sharedViewModel.showStartCallEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i("$TAG Navigating to start call fragment")
val action = HistoryFragmentDirections.actionHistoryFragmentToStartCallFragment()
findNavController().navigate(action)
}
}
sharedViewModel.showCallLogEvent.observe(
viewLifecycleOwner
) {
it.consume { callId ->
Log.i("$TAG Displaying call log with call ID [$callId]")
val navController = binding.historyNavContainer.findNavController()
val action = HistoryContactFragmentDirections.actionGlobalHistoryContactFragment(
callId
)
navController.navigate(action)
}
}
sharedViewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.historyFragment) {
// To prevent any previously seen call log to show up when navigating back to here later
binding.historyNavContainer.findNavController().popBackStack()
val action = HistoryFragmentDirections.actionHistoryFragmentToContactsFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.historyFragment) {
// To prevent any previously seen call log to show up when navigating back to here later
binding.historyNavContainer.findNavController().popBackStack()
val action = HistoryFragmentDirections.actionHistoryFragmentToConversationsFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToMeetingsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.historyFragment) {
// To prevent any previously seen call log to show up when navigating back to here later
binding.historyNavContainer.findNavController().popBackStack()
val action = HistoryFragmentDirections.actionHistoryFragmentToMeetingsFragment()
findNavController().navigate(action)
}
}
}
}
override fun onResume() {
super.onResume()
sharedViewModel.currentlyDisplayedFragment.value = R.id.historyFragment
}
}

View file

@ -22,17 +22,20 @@ package org.linphone.ui.main.history.fragment
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.PopupWindow
import androidx.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.R
@ -46,7 +49,6 @@ import org.linphone.ui.main.history.model.ConfirmationDialogModel
import org.linphone.ui.main.history.viewmodel.HistoryListViewModel
import org.linphone.utils.DialogUtils
import org.linphone.utils.Event
import org.linphone.utils.setKeyboardInsetListener
@UiThread
class HistoryListFragment : AbstractTopBarFragment() {
@ -60,6 +62,22 @@ class HistoryListFragment : AbstractTopBarFragment() {
private lateinit var adapter: HistoryListAdapter
override fun onDefaultAccountChanged() {
Log.i(
"$TAG Default account changed, updating avatar in top bar & re-computing call logs"
)
listViewModel.update()
listViewModel.applyFilter()
}
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (findNavController().currentDestination?.id == R.id.startCallFragment) {
// 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?,
@ -130,8 +148,14 @@ class HistoryListFragment : AbstractTopBarFragment() {
adapter.callLogClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
Log.i("$TAG Show details for call log with ID [${model.id}]")
sharedViewModel.showCallLogEvent.value = Event(model.id ?: "")
val uri = model.id
Log.i("$TAG Show details for call log with ID [$uri]")
if (!uri.isNullOrEmpty()) {
val navController = binding.historyNavContainer.findNavController()
val action =
HistoryContactFragmentDirections.actionGlobalHistoryContactFragment(uri)
navController.navigate(action)
}
}
}
@ -155,7 +179,7 @@ class HistoryListFragment : AbstractTopBarFragment() {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.historyReadyEvent.value = Event(true)
sharedViewModel.isFirstFragmentReady = true
}
}
@ -180,7 +204,12 @@ class HistoryListFragment : AbstractTopBarFragment() {
}
binding.setStartCallClickListener {
sharedViewModel.showStartCallEvent.value = Event(true)
if (findNavController().currentDestination?.id == R.id.historyListFragment) {
Log.i("$TAG Navigating to start call fragment")
val action =
HistoryListFragmentDirections.actionHistoryListFragmentToStartCallFragment()
findNavController().navigate(action)
}
}
// TopBarFragment related
@ -191,20 +220,11 @@ class HistoryListFragment : AbstractTopBarFragment() {
getString(R.string.bottom_navigation_calls_label)
)
binding.root.setKeyboardInsetListener { keyboardVisible ->
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
binding.bottomNavBar.root.visibility = if (!portraitOrientation || !keyboardVisible) View.VISIBLE else View.GONE
}
initBottomNavBar(binding.bottomNavBar.root)
sharedViewModel.defaultAccountChangedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i(
"$TAG Default account changed, updating avatar in top bar & re-computing call logs"
)
listViewModel.update()
listViewModel.applyFilter()
}
}
initSlidingPane(binding.slidingPaneLayout)
initNavigation(R.id.historyListFragment)
}
override fun onResume() {

View file

@ -66,7 +66,7 @@ class MeetingFragment : GenericFragment() {
override fun goBack(): Boolean {
sharedViewModel.closeSlidingPaneEvent.value = Event(true)
// If not done, when going back to ConversationsFragment this fragment will be created again
// If not done, when going back to MeetingsListFragment this fragment will be created again
return findNavController().popBackStack()
}

View file

@ -1,183 +0,0 @@
/*
* 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.main.meetings.fragment
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.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.slidingpanelayout.widget.SlidingPaneLayout
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.MeetingsFragmentBinding
import org.linphone.ui.main.fragment.GenericFragment
import org.linphone.utils.SlidingPaneBackPressedCallback
@UiThread
class MeetingsFragment : GenericFragment() {
companion object {
private const val TAG = "[Meetings Fragment]"
}
private lateinit var binding: MeetingsFragmentBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = MeetingsFragmentBinding.inflate(layoutInflater)
return binding.root
}
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (
findNavController().currentDestination?.id == R.id.scheduleMeetingFragment ||
findNavController().currentDestination?.id == R.id.meetingWaitingRoomFragment
) {
// 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 onViewCreated(view: View, savedInstanceState: Bundle?) {
postponeEnterTransition()
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.meetingsReadyEvent.observe(viewLifecycleOwner) {
it.consume {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.isFirstFragmentReady = true
}
}
}
sharedViewModel.closeSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Closing sliding pane")
binding.slidingPaneLayout.closePane()
}
}
}
sharedViewModel.openSlidingPaneEvent.observe(
viewLifecycleOwner
) {
it.consume {
if (!binding.slidingPaneLayout.isOpen) {
Log.i("$TAG Opening sliding pane")
binding.slidingPaneLayout.openPane()
}
}
}
sharedViewModel.showScheduleMeetingEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i("$TAG Navigating to schedule meeting fragment")
val action = MeetingsFragmentDirections.actionMeetingsFragmentToScheduleMeetingFragment()
findNavController().navigate(action)
}
}
sharedViewModel.goToMeetingWaitingRoomEvent.observe(viewLifecycleOwner) {
it.consume { uri ->
Log.i("$TAG Navigating to meeting waiting room fragment with URI [$uri]")
val action = MeetingsFragmentDirections.actionMeetingsFragmentToMeetingWaitingRoomFragment(
uri
)
findNavController().navigate(action)
}
}
sharedViewModel.showMeetingEvent.observe(viewLifecycleOwner) {
it.consume { uri ->
Log.i("$TAG Navigating to meeting fragment with URI [$uri]")
val action = MeetingFragmentDirections.actionGlobalMeetingFragment(uri)
binding.meetingsNavContainer.findNavController().navigate(action)
}
}
sharedViewModel.navigateToContactsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.meetingsFragment) {
// To prevent any previously seen meeting to show up when navigating back to here later
binding.meetingsNavContainer.findNavController().popBackStack()
val action = MeetingsFragmentDirections.actionMeetingsFragmentToContactsFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToHistoryEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.meetingsFragment) {
// To prevent any previously seen meeting to show up when navigating back to here later
binding.meetingsNavContainer.findNavController().popBackStack()
val action = MeetingsFragmentDirections.actionMeetingsFragmentToHistoryFragment()
findNavController().navigate(action)
}
}
}
sharedViewModel.navigateToConversationsEvent.observe(viewLifecycleOwner) {
it.consume {
if (findNavController().currentDestination?.id == R.id.meetingsFragment) {
// To prevent any previously seen meeting to show up when navigating back to here later
binding.meetingsNavContainer.findNavController().popBackStack()
val action = MeetingsFragmentDirections.actionMeetingsFragmentToConversationsFragment()
findNavController().navigate(action)
}
}
}
}
override fun onResume() {
super.onResume()
sharedViewModel.currentlyDisplayedFragment.value = R.id.meetingsFragment
}
}

View file

@ -19,14 +19,17 @@
*/
package org.linphone.ui.main.meetings.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.annotation.UiThread
import androidx.core.view.doOnPreDraw
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import org.linphone.R
import org.linphone.core.tools.Log
@ -35,9 +38,7 @@ import org.linphone.ui.main.fragment.AbstractTopBarFragment
import org.linphone.ui.main.meetings.adapter.MeetingsListAdapter
import org.linphone.ui.main.meetings.viewmodel.MeetingsListViewModel
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
import org.linphone.utils.RecyclerViewHeaderDecoration
import org.linphone.utils.setKeyboardInsetListener
@UiThread
class MeetingsListFragment : AbstractTopBarFragment() {
@ -51,6 +52,24 @@ class MeetingsListFragment : AbstractTopBarFragment() {
private lateinit var adapter: MeetingsListAdapter
override fun onDefaultAccountChanged() {
Log.i(
"$TAG Default account changed, updating avatar in top bar & re-computing meetings list"
)
listViewModel.applyFilter()
}
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
if (
findNavController().currentDestination?.id == R.id.scheduleMeetingFragment ||
findNavController().currentDestination?.id == R.id.meetingWaitingRoomFragment
) {
// 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?,
@ -78,7 +97,12 @@ class MeetingsListFragment : AbstractTopBarFragment() {
binding.meetingsList.layoutManager = LinearLayoutManager(requireContext())
binding.setNewMeetingClicked {
sharedViewModel.showScheduleMeetingEvent.value = Event(true)
if (findNavController().currentDestination?.id == R.id.meetingsListFragment) {
Log.i("$TAG Navigating to schedule meeting fragment")
val action =
MeetingsListFragmentDirections.actionMeetingsListFragmentToScheduleMeetingFragment()
findNavController().navigate(action)
}
}
binding.setTodayClickListener {
@ -88,7 +112,8 @@ class MeetingsListFragment : AbstractTopBarFragment() {
adapter.meetingClickedEvent.observe(viewLifecycleOwner) {
it.consume { model ->
Log.i("$TAG Show conversation with ID [${model.id}]")
sharedViewModel.showMeetingEvent.value = Event(model.id)
val action = MeetingFragmentDirections.actionGlobalMeetingFragment(model.id)
binding.meetingsNavContainer.findNavController().navigate(action)
}
}
@ -100,7 +125,7 @@ class MeetingsListFragment : AbstractTopBarFragment() {
if (currentCount < it.size) {
(view.parent as? ViewGroup)?.doOnPreDraw {
startPostponedEnterTransition()
sharedViewModel.meetingsReadyEvent.value = Event(true)
sharedViewModel.isFirstFragmentReady = true
scrollToToday()
}
}
@ -113,6 +138,19 @@ class MeetingsListFragment : AbstractTopBarFragment() {
}
}
sharedViewModel.goToMeetingWaitingRoomEvent.observe(viewLifecycleOwner) {
it.consume { uri ->
if (findNavController().currentDestination?.id == R.id.meetingsListFragment) {
Log.i("$TAG Navigating to meeting waiting room fragment with URI [$uri]")
val action =
MeetingsListFragmentDirections.actionMeetingsListFragmentToMeetingWaitingRoomFragment(
uri
)
findNavController().navigate(action)
}
}
}
// TopBarFragment related
setViewModelAndTitle(
@ -121,19 +159,11 @@ class MeetingsListFragment : AbstractTopBarFragment() {
getString(R.string.bottom_navigation_meetings_label)
)
binding.root.setKeyboardInsetListener { keyboardVisible ->
val portraitOrientation = resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE
binding.bottomNavBar.root.visibility = if (!portraitOrientation || !keyboardVisible) View.VISIBLE else View.GONE
}
initBottomNavBar(binding.bottomNavBar.root)
sharedViewModel.defaultAccountChangedEvent.observe(viewLifecycleOwner) {
it.consume {
Log.i(
"$TAG Default account changed, updating avatar in top bar & re-computing meetings list"
)
listViewModel.applyFilter()
}
}
initSlidingPane(binding.slidingPaneLayout)
initNavigation(R.id.meetingsListFragment)
}
private fun scrollToToday() {

View file

@ -76,8 +76,6 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() {
/* Contacts related */
val contactsReadyEvent = MutableLiveData<Event<Boolean>>()
val showContactEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
@ -90,16 +88,6 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() {
/* Call logs related */
val historyReadyEvent = MutableLiveData<Event<Boolean>>()
val showStartCallEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val showCallLogEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val forceRefreshCallLogsListEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
@ -110,12 +98,6 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() {
/* Conversation related */
val conversationsReadyEvent = MutableLiveData<Event<Boolean>>()
val showStartConversationEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val filesToShareFromIntent = MutableLiveData<ArrayList<String>>()
var displayedChatRoom: ChatRoom? = null // Prevents the need to go look for the chat room
@ -128,16 +110,6 @@ class SharedMainViewModel @UiThread constructor() : ViewModel() {
/* Meetings related */
val meetingsReadyEvent = MutableLiveData<Event<Boolean>>()
val showScheduleMeetingEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val showMeetingEvent: MutableLiveData<Event<String>> by lazy {
MutableLiveData<Event<String>>()
}
val forceRefreshMeetingsListEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}

View file

@ -16,107 +16,123 @@
type="org.linphone.ui.main.chat.viewmodel.ConversationsListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_conversation_image, no_conversation_label"
android:visibility="@{viewModel.conversations.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
android:background="@color/orange_main_500">
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_conversation_image, no_conversation_label"
android:visibility="@{viewModel.conversations.empty ? View.VISIBLE : View.GONE}" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageView
android:id="@+id/no_conversation_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_conversation_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_conversation_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/conversations_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_conversation_image" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/conversations_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageView
android:id="@+id/no_conversation_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_conversation_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_conversation"
android:onClick="@{onNewConversationClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_conversation_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/conversations_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_conversation_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/conversations_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toBottomOf="parent" />
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_conversation"
android:onClick="@{onNewConversationClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/chat_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/chat_nav_graph"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -16,162 +16,178 @@
type="org.linphone.ui.main.contacts.viewmodel.ContactsListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_contacts_image, no_contacts_label"
android:visibility="@{viewModel.contactsList.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
android:background="@color/orange_main_500">
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toStartOf="@id/filter"/>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_contacts_image, no_contacts_label"
android:visibility="@{viewModel.contactsList.empty ? View.VISIBLE : View.GONE}" />
<ImageView
android:onClick="@{filterClickListener}"
android:id="@+id/filter"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/funnel"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toStartOf="@id/filter"/>
<ImageView
android:id="@+id/no_contacts_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_contacts_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<ImageView
android:onClick="@{filterClickListener}"
android:id="@+id/filter"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/funnel"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_contacts_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contacts_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_contacts_image" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/favourites_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
onClickListener="@{() -> viewModel.toggleFavouritesVisibility()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="20dp"
android:text="@string/contacts_list_favourites_title"
android:drawableEnd="@drawable/caret_up"
android:drawableTint="@color/gray_main2_600"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"/>
<ImageView
android:id="@+id/no_contacts_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_contacts_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/favourites_contacts_list"
android:visibility="@{viewModel.showFavourites &amp;&amp; !viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/favourites_label" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_contacts_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contacts_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_contacts_image" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/all_contacts_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:text="@string/contacts_list_all_contacts_title"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/favourites_contacts_list"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/favourites_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
onClickListener="@{() -> viewModel.toggleFavouritesVisibility()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="20dp"
android:text="@string/contacts_list_favourites_title"
android:drawableEnd="@drawable/caret_up"
android:drawableTint="@color/gray_main2_600"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/contactsList"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/all_contacts_label"
app:layout_constraintBottom_toBottomOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/favourites_contacts_list"
android:visibility="@{viewModel.showFavourites &amp;&amp; !viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/favourites_label" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_contact"
android:onClick="@{onNewContactClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/user_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/all_contacts_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:text="@string/contacts_list_all_contacts_title"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/favourites_contacts_list"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/contactsList"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/all_contacts_label"
app:layout_constraintBottom_toBottomOf="parent" />
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_contact"
android:onClick="@{onNewContactClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/user_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/contacts_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/contacts_nav_graph"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -22,120 +22,136 @@
type="org.linphone.ui.main.history.viewmodel.HistoryListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_calls_image, no_calls_label"
android:visibility="@{viewModel.callLogs.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
android:background="@color/orange_main_500">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_calls_image, no_calls_label"
android:visibility="@{viewModel.callLogs.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toStartOf="@id/menu"/>
<ImageView
android:onClick="@{menuClickListener}"
android:id="@+id/menu"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/dots_three_vertical"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_calls_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_calls_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_calls_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/history_list_empty_history"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_calls_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:onClick="@{startCallClickListener}"
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/phone_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toStartOf="@id/menu"/>
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />
<ImageView
android:onClick="@{menuClickListener}"
android:id="@+id/menu"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/dots_three_vertical"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/history_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/history_nav_graph"/>
<ImageView
android:id="@+id/no_calls_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_calls_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_calls_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/history_list_empty_history"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_calls_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:onClick="@{startCallClickListener}"
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/phone_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -19,120 +19,136 @@
type="org.linphone.ui.main.meetings.viewmodel.MeetingsListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_meeting_image, no_meeting_label"
android:visibility="@{viewModel.meetings.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
android:background="@color/orange_main_500">
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toStartOf="@id/today"/>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_meeting_image, no_meeting_label"
android:visibility="@{viewModel.meetings.empty ? View.VISIBLE : View.GONE}" />
<ImageView
android:onClick="@{todayClickListener}"
android:id="@+id/today"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/calendar"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="@dimen/landscape_nav_bar_width"
android:layout_height="match_parent"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toStartOf="@id/today"/>
<ImageView
android:id="@+id/no_meeting_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_meeting_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<ImageView
android:onClick="@{todayClickListener}"
android:id="@+id/today"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/calendar"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_meeting_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/meetings_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_meeting_image" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/meetings_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toBottomOf="parent" />
<ImageView
android:id="@+id/no_meeting_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_meeting_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/background" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_meeting"
android:onClick="@{newMeetingClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_meeting_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/meetings_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintTop_toBottomOf="@id/no_meeting_image" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/meetings_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toEndOf="@id/bottom_nav_bar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toBottomOf="parent" />
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/new_meeting"
android:onClick="@{newMeetingClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/meetings_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/meetings_nav_graph"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -1,32 +0,0 @@
<?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">
<data>
<import type="android.view.View" />
</data>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/conversations_list"
android:name="org.linphone.ui.main.chat.fragment.ConversationsListFragment"
android:layout_width="@dimen/sliding_pane_left_fragment_width"
android:layout_height="match_parent"
app:layout="@layout/chat_list_fragment"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/chat_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/chat_nav_graph"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -16,107 +16,123 @@
type="org.linphone.ui.main.chat.viewmodel.ConversationsListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_conversation_image, no_conversation_label"
android:visibility="@{viewModel.conversations.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_conversation_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_conversation_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_conversation_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/conversations_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_conversation_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/conversations_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
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_conversation"
android:onClick="@{onNewConversationClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/chat_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/chat_nav_graph"/>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_conversation_image, no_conversation_label"
android:visibility="@{viewModel.conversations.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_conversation_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_conversation_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_conversation_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/conversations_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_conversation_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/conversations_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
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_conversation"
android:onClick="@{onNewConversationClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -1,32 +0,0 @@
<?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">
<data>
<import type="android.view.View" />
</data>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/contacts_list"
android:name="org.linphone.ui.main.contacts.fragment.ContactsListFragment"
android:layout_width="@dimen/sliding_pane_left_fragment_width"
android:layout_height="match_parent"
app:layout="@layout/contacts_list_fragment"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/contacts_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/contacts_nav_graph"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -16,164 +16,180 @@
type="org.linphone.ui.main.contacts.viewmodel.ContactsListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_contacts_image, no_contacts_label"
android:visibility="@{viewModel.contactsList.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/filter"/>
<ImageView
android:onClick="@{filterClickListener}"
android:id="@+id/filter"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/funnel"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_contacts_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_contacts_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_contacts_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contacts_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_contacts_image" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/favourites_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
onClickListener="@{() -> viewModel.toggleFavouritesVisibility()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:text="@string/contacts_list_favourites_title"
android:drawableEnd="@{viewModel.showFavourites ? @drawable/caret_up : @drawable/caret_down, default=@drawable/caret_up}"
android:drawableTint="@color/gray_main2_600"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/favourites_contacts_list"
android:visibility="@{viewModel.showFavourites &amp;&amp; !viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/favourites_label" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/all_contacts_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:text="@string/contacts_list_all_contacts_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/favourites_contacts_list"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/contactsList"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/all_contacts_label"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
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_contact"
android:onClick="@{onNewContactClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/user_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/contacts_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/contacts_nav_graph"/>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_contacts_image, no_contacts_label"
android:visibility="@{viewModel.contactsList.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/filter"/>
<ImageView
android:onClick="@{filterClickListener}"
android:id="@+id/filter"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/funnel"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_contacts_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_contacts_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_contacts_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/contacts_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_contacts_image" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/favourites_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
onClickListener="@{() -> viewModel.toggleFavouritesVisibility()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:text="@string/contacts_list_favourites_title"
android:drawableEnd="@{viewModel.showFavourites ? @drawable/caret_up : @drawable/caret_down, default=@drawable/caret_up}"
android:drawableTint="@color/gray_main2_600"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/favourites_contacts_list"
android:visibility="@{viewModel.showFavourites &amp;&amp; !viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/favourites_label" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/all_contacts_label"
android:visibility="@{!viewModel.isListFiltered &amp;&amp; viewModel.favourites.size() > 0 ? View.VISIBLE : View.GONE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:text="@string/contacts_list_all_contacts_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/favourites_contacts_list"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/contactsList"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/all_contacts_label"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
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_contact"
android:onClick="@{onNewContactClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/user_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -1,32 +0,0 @@
<?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">
<data>
<import type="android.view.View" />
</data>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/history"
android:name="org.linphone.ui.main.history.fragment.HistoryListFragment"
android:layout_width="@dimen/sliding_pane_left_fragment_width"
android:layout_height="match_parent"
app:layout="@layout/history_list_fragment" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/history_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/history_nav_graph"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -22,120 +22,136 @@
type="org.linphone.ui.main.history.viewmodel.HistoryListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_calls_image, no_calls_label"
android:visibility="@{viewModel.callLogs.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/menu"/>
<ImageView
android:onClick="@{menuClickListener}"
android:id="@+id/menu"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/dots_three_vertical"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_calls_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_calls_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_calls_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/history_list_empty_history"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_calls_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_bar"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:onClick="@{startCallClickListener}"
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/phone_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/history_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/history_nav_graph"/>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_calls_image, no_calls_label"
android:visibility="@{viewModel.callLogs.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/menu"/>
<ImageView
android:onClick="@{menuClickListener}"
android:id="@+id/menu"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/dots_three_vertical"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_calls_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_calls_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_calls_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/history_list_empty_history"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_calls_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_bar"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:onClick="@{startCallClickListener}"
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/phone_plus"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -1,32 +0,0 @@
<?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">
<data>
<import type="android.view.View" />
</data>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/meetings_list"
android:name="org.linphone.ui.main.meetings.fragment.MeetingsListFragment"
android:layout_width="@dimen/sliding_pane_left_fragment_width"
android:layout_height="match_parent"
app:layout="@layout/meetings_list_fragment"/>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/meetings_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/meetings_nav_graph"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -19,120 +19,136 @@
type="org.linphone.ui.main.meetings.viewmodel.MeetingsListViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_meeting_image, no_meeting_label"
android:visibility="@{viewModel.meetings.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/today"/>
<ImageView
android:onClick="@{todayClickListener}"
android:id="@+id/today"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/calendar"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_meeting_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_meeting_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_meeting_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/meetings_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_meeting_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/meetings_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
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_meeting"
android:onClick="@{newMeetingClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/meetings_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="@dimen/sliding_pane_right_fragment_width"
android:layout_height="match_parent"
android:background="@color/orange_main_500">
android:layout_weight="1"
app:defaultNavHost="false"
app:navGraph="@navigation/meetings_nav_graph"/>
<androidx.constraintlayout.widget.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="no_meeting_image, no_meeting_label"
android:visibility="@{viewModel.meetings.empty ? View.VISIBLE : View.GONE}" />
<include
android:id="@+id/top_bar"
layout="@layout/top_bar"
bind:viewModel="@{viewModel}"
android:layout_width="0dp"
android:layout_height="@dimen/top_bar_height"
android:layout_marginEnd="9dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/today"/>
<ImageView
android:onClick="@{todayClickListener}"
android:id="@+id/today"
android:layout_width="@dimen/icon_size"
android:layout_height="0dp"
android:layout_marginEnd="9dp"
android:src="@drawable/calendar"
android:visibility="@{viewModel.searchBarVisible ? View.GONE : View.VISIBLE}"
app:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/top_bar"
app:layout_constraintBottom_toBottomOf="@id/top_bar" />
<ImageView
android:id="@+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@color/white"
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" />
<ImageView
android:id="@+id/no_meeting_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/illu"
android:layout_margin="10dp"
app:layout_constraintHeight_max="200dp"
app:layout_constraintBottom_toTopOf="@id/no_meeting_label"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/background" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/section_header_style"
android:id="@+id/no_meeting_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/meetings_list_empty"
app:layout_constraintBottom_toTopOf="@id/background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_meeting_image" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/meetings_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/background"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
<include
android:id="@+id/bottom_nav_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
layout="@layout/bottom_nav_bar"
viewModel="@{viewModel}"
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_meeting"
android:onClick="@{newMeetingClicked}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus_circle"
app:tint="@color/gray_main2_700"
app:backgroundTint="@color/white"
app:shapeAppearanceOverlay="@style/rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_nav_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--<include
layout="@layout/operation_in_progress"
bind:visibility="@{viewModel.fetchInProgress}" />-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
</layout>

View file

@ -1,36 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--suppress ALL -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_nav_graph"
app:startDestination="@id/historyFragment">
app:startDestination="@id/historyListFragment">
<fragment
android:id="@+id/contactsFragment"
android:name="org.linphone.ui.main.contacts.fragment.ContactsFragment"
android:label="ContactsFragment"
tools:layout="@layout/contacts_fragment">
android:id="@+id/contactsListFragment"
android:name="org.linphone.ui.main.contacts.fragment.ContactsListFragment"
android:label="ContactsListFragment"
tools:layout="@layout/contacts_list_fragment">
<action
android:id="@+id/action_contactsFragment_to_historyFragment"
app:destination="@id/historyFragment"
android:id="@+id/action_contactsListFragment_to_historyListFragment"
app:destination="@id/historyListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/contactsFragment"
app:popUpTo="@id/contactsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_contactsFragment_to_conversationsFragment"
app:destination="@id/conversationsFragment"
android:id="@+id/action_contactsListFragment_to_conversationsListFragment"
app:destination="@id/conversationsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/contactsFragment"
app:popUpTo="@id/contactsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_contactsFragment_to_meetingsFragment"
app:destination="@id/meetingsFragment"
android:id="@+id/action_contactsListFragment_to_meetingsListFragment"
app:destination="@id/meetingsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/contactsFragment"
app:popUpTo="@id/contactsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_contactsFragment_to_newContactFragment"
android:id="@+id/action_contactsListFragment_to_newContactFragment"
app:destination="@id/newContactFragment"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
@ -38,30 +37,30 @@
</fragment>
<fragment
android:id="@+id/historyFragment"
android:name="org.linphone.ui.main.history.fragment.HistoryFragment"
android:label="HistoryFragment"
tools:layout="@layout/history_fragment">
android:id="@+id/historyListFragment"
android:name="org.linphone.ui.main.history.fragment.HistoryListFragment"
android:label="HistoryListFragment"
tools:layout="@layout/history_list_fragment">
<action
android:id="@+id/action_historyFragment_to_contactsFragment"
app:destination="@id/contactsFragment"
android:id="@+id/action_historyListFragment_to_contactsListFragment"
app:destination="@id/contactsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/historyFragment"
app:popUpTo="@id/historyListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_historyFragment_to_conversationsFragment"
app:destination="@id/conversationsFragment"
android:id="@+id/action_historyListFragment_to_conversationsListFragment"
app:destination="@id/conversationsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/historyFragment"
app:popUpTo="@id/historyListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_historyFragment_to_meetingsFragment"
app:destination="@id/meetingsFragment"
android:id="@+id/action_historyListFragment_to_meetingsListFragment"
app:destination="@id/meetingsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/historyFragment"
app:popUpTo="@id/historyListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_historyFragment_to_startCallFragment"
android:id="@+id/action_historyListFragment_to_startCallFragment"
app:destination="@id/startCallFragment"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
@ -192,36 +191,36 @@
</fragment>
<fragment
android:id="@+id/conversationsFragment"
android:name="org.linphone.ui.main.chat.fragment.ConversationsFragment"
android:label="ConversationsFragment"
tools:layout="@layout/chat_fragment" >
android:id="@+id/conversationsListFragment"
android:name="org.linphone.ui.main.chat.fragment.ConversationsListFragment"
android:label="ConversationsListFragment"
tools:layout="@layout/chat_list_fragment" >
<action
android:id="@+id/action_conversationsFragment_to_historyFragment"
app:destination="@id/historyFragment"
android:id="@+id/action_conversationsListFragment_to_historyListFragment"
app:destination="@id/historyListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/conversationsFragment"
app:popUpTo="@id/conversationsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_conversationsFragment_to_contactsFragment"
app:destination="@id/contactsFragment"
android:id="@+id/action_conversationsListFragment_to_contactsListFragment"
app:destination="@id/contactsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/conversationsFragment"
app:popUpTo="@id/conversationsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_conversationsFragment_to_meetingsFragment"
app:destination="@id/meetingsFragment"
android:id="@+id/action_conversationsListFragment_to_meetingsListFragment"
app:destination="@id/meetingsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/conversationsFragment"
app:popUpTo="@id/conversationsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_conversationsFragment_to_startConversationFragment"
android:id="@+id/action_conversationsListFragment_to_startConversationFragment"
app:destination="@id/startConversationFragment"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
app:launchSingleTop="true" />
<action
android:id="@+id/action_conversationsFragment_to_meetingWaitingRoomFragment"
android:id="@+id/action_conversationsListFragment_to_meetingWaitingRoomFragment"
app:destination="@id/meetingWaitingRoomFragment"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
@ -235,36 +234,36 @@
tools:layout="@layout/start_chat_fragment"/>
<fragment
android:id="@+id/meetingsFragment"
android:name="org.linphone.ui.main.meetings.fragment.MeetingsFragment"
android:label="MeetingsFragment"
tools:layout="@layout/meetings_fragment">
android:id="@+id/meetingsListFragment"
android:name="org.linphone.ui.main.meetings.fragment.MeetingsListFragment"
android:label="MeetingsListFragment"
tools:layout="@layout/meetings_list_fragment">
<action
android:id="@+id/action_meetingsFragment_to_historyFragment"
app:destination="@id/historyFragment"
android:id="@+id/action_meetingsListFragment_to_historyListFragment"
app:destination="@id/historyListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/meetingsFragment"
app:popUpTo="@id/meetingsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_meetingsFragment_to_conversationsFragment"
app:destination="@id/conversationsFragment"
android:id="@+id/action_meetingsListFragment_to_conversationsListFragment"
app:destination="@id/conversationsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/meetingsFragment"
app:popUpTo="@id/meetingsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_meetingsFragment_to_contactsFragment"
app:destination="@id/contactsFragment"
android:id="@+id/action_meetingsListFragment_to_contactsListFragment"
app:destination="@id/contactsListFragment"
app:launchSingleTop="true"
app:popUpTo="@id/meetingsFragment"
app:popUpTo="@id/meetingsListFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_meetingsFragment_to_scheduleMeetingFragment"
android:id="@+id/action_meetingsListFragment_to_scheduleMeetingFragment"
app:destination="@id/scheduleMeetingFragment"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
app:launchSingleTop="true" />
<action
android:id="@+id/action_meetingsFragment_to_meetingWaitingRoomFragment"
android:id="@+id/action_meetingsListFragment_to_meetingWaitingRoomFragment"
app:destination="@id/meetingWaitingRoomFragment"
app:enterAnim="@anim/slide_in"
app:popExitAnim="@anim/slide_out"
@ -291,8 +290,8 @@
android:label="AddParticipantsFragment"
tools:layout="@layout/generic_add_participants_fragment"/>
<action android:id="@+id/action_global_conversationsFragment"
app:destination="@id/conversationsFragment"
<action android:id="@+id/action_global_conversationsListFragment"
app:destination="@id/conversationsListFragment"
app:launchSingleTop="true"/>
<fragment

View file

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="sliding_pane_left_fragment_width">450dp</dimen>
<dimen name="sliding_pane_right_fragment_width">0dp</dimen>
<dimen name="call_main_actions_menu_height">110dp</dimen>
<dimen name="call_extra_actions_menu_height">125dp</dimen>
<dimen name="call_all_actions_menu_height">235dp</dimen> <!-- sum of above two -->

View file

@ -5,7 +5,6 @@
<dimen name="screen_bottom_margin">32dp</dimen>
<dimen name="landscape_nav_bar_width">75dp</dimen>
<dimen name="sliding_pane_left_fragment_width">300dp</dimen>
<dimen name="sliding_pane_right_fragment_width">300dp</dimen>
<dimen name="small_icon_size">14dp</dimen>