Fixed various issues with navigation, animations & back stack

This commit is contained in:
Sylvain Berfini 2021-01-19 13:03:30 +01:00
parent 886f225016
commit 6941633a86
20 changed files with 258 additions and 347 deletions

View file

@ -26,6 +26,7 @@ import android.os.Bundle
import android.view.Surface
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.navigation.ActivityNavigator
import java.util.*
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
@ -85,6 +86,11 @@ abstract class GenericActivity : AppCompatActivity() {
coreContext.notificationsManager.stopForegroundNotificationIfPossible()
}
override fun finish() {
super.finish()
ActivityNavigator.applyPopAnimationsToPendingTransition(this)
}
fun isTablet(): Boolean {
return resources.getBoolean(R.bool.isTablet)
}

View file

@ -20,6 +20,7 @@
package org.linphone.activities.assistant.fragments
import android.os.Bundle
import androidx.activity.addCallback
import androidx.navigation.fragment.findNavController
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
@ -29,12 +30,25 @@ import org.linphone.databinding.AssistantTopBarFragmentBinding
class TopBarFragment : GenericFragment<AssistantTopBarFragmentBinding>() {
override fun getLayoutId(): Int = R.layout.assistant_top_bar_fragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(this) {
goBack()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
binding.lifecycleOwner = this
binding.setBackClickListener {
goBack()
}
}
private fun goBack() {
if (!findNavController().popBackStack()) {
requireActivity().finish()
if (corePreferences.enableAnimations) {
@ -46,4 +60,3 @@ class TopBarFragment : GenericFragment<AssistantTopBarFragmentBinding>() {
}
}
}
}

View file

@ -56,9 +56,15 @@ internal fun Fragment.findMasterNavController(): NavController {
}
}
fun getRightToLeftAnimationNavOptions(): NavOptions {
if (!corePreferences.enableAnimations) return NavOptions.Builder().build()
return NavOptions.Builder()
fun getRightToLeftAnimationNavOptions(
popUpTo: Int = -1,
popUpInclusive: Boolean = false,
singleTop: Boolean = true
): NavOptions {
val builder = NavOptions.Builder()
builder.setPopUpTo(popUpTo, popUpInclusive).setLaunchSingleTop(singleTop)
if (!corePreferences.enableAnimations) return builder.build()
return builder
.setEnterAnim(R.anim.enter_right)
.setExitAnim(R.anim.exit_left)
.setPopEnterAnim(R.anim.enter_left)
@ -66,9 +72,15 @@ fun getRightToLeftAnimationNavOptions(): NavOptions {
.build()
}
fun getLeftToRightAnimationNavOptions(): NavOptions {
if (!corePreferences.enableAnimations) return NavOptions.Builder().build()
return NavOptions.Builder()
fun getLeftToRightAnimationNavOptions(
popUpTo: Int = -1,
popUpInclusive: Boolean = false,
singleTop: Boolean = true
): NavOptions {
val builder = NavOptions.Builder()
builder.setPopUpTo(popUpTo, popUpInclusive).setLaunchSingleTop(singleTop)
if (!corePreferences.enableAnimations) return builder.build()
return builder
.setEnterAnim(R.anim.enter_left)
.setExitAnim(R.anim.exit_right)
.setPopEnterAnim(R.anim.enter_right)
@ -76,9 +88,15 @@ fun getLeftToRightAnimationNavOptions(): NavOptions {
.build()
}
fun getRightBottomToLeftTopAnimationNavOptions(): NavOptions {
if (!corePreferences.enableAnimations) return NavOptions.Builder().build()
return NavOptions.Builder()
fun getRightBottomToLeftTopAnimationNavOptions(
popUpTo: Int = -1,
popUpInclusive: Boolean = false,
singleTop: Boolean = true
): NavOptions {
val builder = NavOptions.Builder()
builder.setPopUpTo(popUpTo, popUpInclusive).setLaunchSingleTop(singleTop)
if (!corePreferences.enableAnimations) return builder.build()
return builder
.setEnterAnim(R.anim.enter_right_or_bottom)
.setExitAnim(R.anim.exit_left_or_top)
.setPopEnterAnim(R.anim.enter_left_or_top)
@ -86,9 +104,15 @@ fun getRightBottomToLeftTopAnimationNavOptions(): NavOptions {
.build()
}
fun getLeftTopToRightBottomAnimationNavOptions(): NavOptions {
if (!corePreferences.enableAnimations) return NavOptions.Builder().build()
return NavOptions.Builder()
fun getLeftTopToRightBottomAnimationNavOptions(
popUpTo: Int = -1,
popUpInclusive: Boolean = false,
singleTop: Boolean = true
): NavOptions {
val builder = NavOptions.Builder()
builder.setPopUpTo(popUpTo, popUpInclusive).setLaunchSingleTop(singleTop)
if (!corePreferences.enableAnimations) return builder.build()
return builder
.setEnterAnim(R.anim.enter_left_or_top)
.setExitAnim(R.anim.exit_right_or_bottom)
.setPopEnterAnim(R.anim.enter_right_or_bottom)
@ -96,17 +120,29 @@ fun getLeftTopToRightBottomAnimationNavOptions(): NavOptions {
.build()
}
fun getRightBottomToLeftTopNoPopAnimationNavOptions(): NavOptions {
if (!corePreferences.enableAnimations) return NavOptions.Builder().build()
return NavOptions.Builder()
fun getRightBottomToLeftTopNoPopAnimationNavOptions(
popUpTo: Int = -1,
popUpInclusive: Boolean = false,
singleTop: Boolean = true
): NavOptions {
val builder = NavOptions.Builder()
builder.setPopUpTo(popUpTo, popUpInclusive).setLaunchSingleTop(singleTop)
if (!corePreferences.enableAnimations) return builder.build()
return builder
.setEnterAnim(R.anim.enter_right_or_bottom)
.setExitAnim(R.anim.exit_left_or_top)
.build()
}
fun getLeftTopToRightBottomNoPopAnimationNavOptions(): NavOptions {
if (!corePreferences.enableAnimations) return NavOptions.Builder().build()
return NavOptions.Builder()
fun getLeftTopToRightBottomNoPopAnimationNavOptions(
popUpTo: Int = -1,
popUpInclusive: Boolean = false,
singleTop: Boolean = true
): NavOptions {
val builder = NavOptions.Builder()
builder.setPopUpTo(popUpTo, popUpInclusive).setLaunchSingleTop(singleTop)
if (!corePreferences.enableAnimations) return builder.build()
return builder
.setEnterAnim(R.anim.enter_left_or_top)
.setExitAnim(R.anim.exit_right_or_bottom)
.build()
@ -118,7 +154,7 @@ internal fun MainActivity.navigateToDialer(args: Bundle?) {
findNavController(R.id.nav_host_fragment).navigate(
R.id.action_global_dialerFragment,
args,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.dialerFragment, true)
)
}
@ -129,17 +165,17 @@ internal fun TabsFragment.navigateToCallHistory() {
R.id.masterContactsFragment -> findNavController().navigate(
R.id.action_masterContactsFragment_to_masterCallLogsFragment,
null,
getLeftTopToRightBottomNoPopAnimationNavOptions()
getLeftTopToRightBottomNoPopAnimationNavOptions(R.id.masterCallLogsFragment)
)
R.id.dialerFragment -> findNavController().navigate(
R.id.action_dialerFragment_to_masterCallLogsFragment,
null,
getLeftTopToRightBottomNoPopAnimationNavOptions()
getLeftTopToRightBottomNoPopAnimationNavOptions(R.id.masterCallLogsFragment)
)
R.id.masterChatRoomsFragment -> findNavController().navigate(
R.id.action_masterChatRoomsFragment_to_masterCallLogsFragment,
null,
getLeftTopToRightBottomNoPopAnimationNavOptions()
getLeftTopToRightBottomNoPopAnimationNavOptions(R.id.masterCallLogsFragment)
)
}
}
@ -149,17 +185,17 @@ internal fun TabsFragment.navigateToContacts() {
R.id.masterCallLogsFragment -> findNavController().navigate(
R.id.action_masterCallLogsFragment_to_masterContactsFragment,
null,
getRightBottomToLeftTopNoPopAnimationNavOptions()
getRightBottomToLeftTopNoPopAnimationNavOptions(R.id.masterContactsFragment)
)
R.id.dialerFragment -> findNavController().navigate(
R.id.action_dialerFragment_to_masterContactsFragment,
null,
getLeftTopToRightBottomNoPopAnimationNavOptions()
getLeftTopToRightBottomNoPopAnimationNavOptions(R.id.masterContactsFragment)
)
R.id.masterChatRoomsFragment -> findNavController().navigate(
R.id.action_masterChatRoomsFragment_to_masterContactsFragment,
null,
getLeftTopToRightBottomNoPopAnimationNavOptions()
getLeftTopToRightBottomNoPopAnimationNavOptions(R.id.masterContactsFragment)
)
}
}
@ -169,17 +205,17 @@ internal fun TabsFragment.navigateToDialer() {
R.id.masterCallLogsFragment -> findNavController().navigate(
R.id.action_masterCallLogsFragment_to_dialerFragment,
null,
getRightBottomToLeftTopNoPopAnimationNavOptions()
getRightBottomToLeftTopNoPopAnimationNavOptions(R.id.dialerFragment)
)
R.id.masterContactsFragment -> findNavController().navigate(
R.id.action_masterContactsFragment_to_dialerFragment,
null,
getRightBottomToLeftTopNoPopAnimationNavOptions()
getRightBottomToLeftTopNoPopAnimationNavOptions(R.id.dialerFragment)
)
R.id.masterChatRoomsFragment -> findNavController().navigate(
R.id.action_masterChatRoomsFragment_to_dialerFragment,
null,
getLeftTopToRightBottomNoPopAnimationNavOptions()
getLeftTopToRightBottomNoPopAnimationNavOptions(R.id.dialerFragment)
)
}
}
@ -189,17 +225,17 @@ internal fun TabsFragment.navigateToChatRooms() {
R.id.masterCallLogsFragment -> findNavController().navigate(
R.id.action_masterCallLogsFragment_to_masterChatRoomsFragment,
null,
getRightBottomToLeftTopNoPopAnimationNavOptions()
getRightBottomToLeftTopNoPopAnimationNavOptions(R.id.masterChatRoomsFragment)
)
R.id.masterContactsFragment -> findNavController().navigate(
R.id.action_masterContactsFragment_to_masterChatRoomsFragment,
null,
getRightBottomToLeftTopNoPopAnimationNavOptions()
getRightBottomToLeftTopNoPopAnimationNavOptions(R.id.masterChatRoomsFragment)
)
R.id.dialerFragment -> findNavController().navigate(
R.id.action_dialerFragment_to_masterChatRoomsFragment,
null,
getRightBottomToLeftTopNoPopAnimationNavOptions()
getRightBottomToLeftTopNoPopAnimationNavOptions(R.id.masterChatRoomsFragment)
)
}
}
@ -208,7 +244,10 @@ internal fun TabsFragment.navigateToChatRooms() {
internal fun DialerFragment.navigateToContacts(uriToAdd: String?) {
val deepLink = "linphone-android://contact/new/$uriToAdd"
findNavController().navigate(Uri.parse(deepLink), getLeftTopToRightBottomNoPopAnimationNavOptions())
findNavController().navigate(
Uri.parse(deepLink),
getLeftTopToRightBottomNoPopAnimationNavOptions(R.id.masterContactsFragment, true)
)
}
/* Chat related */
@ -228,7 +267,7 @@ internal fun MasterChatRoomsFragment.navigateToChatRoom() {
navHostFragment.navController.navigate(
R.id.action_global_detailChatRoomFragment,
null,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.emptyChatFragment, true)
)
}
}
@ -251,7 +290,7 @@ internal fun MasterChatRoomsFragment.navigateToChatRoomCreation(
navHostFragment.navController.navigate(
R.id.action_global_chatRoomCreationFragment,
bundle,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.emptyChatFragment, true)
)
}
}
@ -262,8 +301,11 @@ internal fun DetailChatRoomFragment.navigateToContacts(sipUriToAdd: String) {
}
internal fun DetailChatRoomFragment.navigateToChatRooms() {
val deepLink = "linphone-android://chat/"
findMasterNavController().navigate(Uri.parse(deepLink), getLeftToRightAnimationNavOptions())
findMasterNavController().navigate(
R.id.action_global_masterChatRoomsFragment,
null,
getLeftToRightAnimationNavOptions(R.id.masterChatRoomsFragment)
)
}
internal fun DetailChatRoomFragment.navigateToImdn(args: Bundle?) {
@ -318,11 +360,19 @@ internal fun ChatRoomCreationFragment.navigateToGroupInfo(args: Bundle?) {
internal fun ChatRoomCreationFragment.navigateToChatRoom() {
if (findNavController().currentDestination?.id == R.id.chatRoomCreationFragment) {
if (!resources.getBoolean(R.bool.isTablet)) {
findNavController().navigate(
R.id.action_chatRoomCreationFragment_to_detailChatRoomFragment,
null,
getRightToLeftAnimationNavOptions()
)
} else {
findNavController().navigate(
R.id.action_chatRoomCreationFragment_to_detailChatRoomFragment,
null,
getRightToLeftAnimationNavOptions(R.id.emptyFragment, true)
)
}
}
}
@ -330,17 +380,26 @@ internal fun GroupInfoFragment.navigateToChatRoomCreation(args: Bundle?) {
if (findNavController().currentDestination?.id == R.id.groupInfoFragment) {
findNavController().navigate(R.id.action_groupInfoFragment_to_chatRoomCreationFragment,
args,
getLeftToRightAnimationNavOptions()
getLeftToRightAnimationNavOptions(R.id.chatRoomCreationFragment, true)
)
}
}
internal fun GroupInfoFragment.navigateToChatRoom() {
if (findNavController().currentDestination?.id == R.id.groupInfoFragment) {
findNavController().navigate(R.id.action_groupInfoFragment_to_detailChatRoomFragment,
if (!resources.getBoolean(R.bool.isTablet)) {
findNavController().navigate(
R.id.action_groupInfoFragment_to_detailChatRoomFragment,
null,
getRightToLeftAnimationNavOptions()
)
} else {
findNavController().navigate(
R.id.action_groupInfoFragment_to_detailChatRoomFragment,
null,
getRightToLeftAnimationNavOptions(R.id.emptyFragment, true)
)
}
}
}
@ -359,7 +418,7 @@ internal fun MasterContactsFragment.navigateToContact() {
navHostFragment.navController.navigate(
R.id.action_global_detailContactFragment,
null,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.emptyContactFragment, true)
)
}
}
@ -441,7 +500,7 @@ internal fun MasterCallLogsFragment.navigateToCallHistory() {
navHostFragment.navController.navigate(
R.id.action_global_detailCallLogFragment,
null,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.emptyFragment, true)
)
}
}
@ -723,7 +782,7 @@ internal fun SideMenuFragment.navigateToSettings() {
findNavController().navigate(
R.id.action_global_settingsFragment,
null,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.settingsFragment)
)
}
@ -731,7 +790,7 @@ internal fun SideMenuFragment.navigateToAbout() {
findNavController().navigate(
R.id.action_global_aboutFragment,
null,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.aboutFragment)
)
}
@ -739,7 +798,7 @@ internal fun SideMenuFragment.navigateToRecordings() {
findNavController().navigate(
R.id.action_global_recordingsFragment,
null,
getRightToLeftAnimationNavOptions()
getRightToLeftAnimationNavOptions(R.id.recordingsFragment)
)
}
@ -880,7 +939,7 @@ internal fun PhoneAccountValidationFragment.navigateToAccountSettings(args: Bund
findNavController().navigate(
R.id.action_phoneAccountValidationFragment_to_accountSettingsFragment,
args,
getLeftToRightAnimationNavOptions()
getLeftToRightAnimationNavOptions(R.id.accountSettingsFragment, true)
)
}
}

View file

@ -70,15 +70,6 @@ class ChatRoomCreationFragment : SecureFragment<ChatRoomCreationFragmentBinding>
adapter.updateSecurity(viewModel.isEncrypted.value == true)
binding.contactsList.adapter = adapter
// To ensure animation will be smooth
binding.contactsList.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
val layoutManager = LinearLayoutManager(activity)
binding.contactsList.layoutManager = layoutManager

View file

@ -28,13 +28,15 @@ import android.net.Uri
import android.os.Bundle
import android.os.Parcelable
import android.provider.MediaStore
import android.view.*
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.webkit.MimeTypeMap
import androidx.activity.addCallback
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.view.menu.MenuPopupHelper
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.launch
@ -46,9 +48,6 @@ import org.linphone.activities.main.chat.ChatScrollListener
import org.linphone.activities.main.chat.adapters.ChatMessagesListAdapter
import org.linphone.activities.main.chat.viewmodels.*
import org.linphone.activities.main.fragments.MasterFragment
import org.linphone.activities.main.navigateToChatRooms
import org.linphone.activities.main.navigateToContacts
import org.linphone.activities.main.navigateToImdn
import org.linphone.activities.main.viewmodels.DialogViewModel
import org.linphone.activities.main.viewmodels.SharedMainViewModel
import org.linphone.core.*
@ -84,6 +83,14 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
super.onDestroyView()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(this) {
navigateToChatRooms()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
@ -101,11 +108,16 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
arguments?.clear()
val localAddress = Factory.instance().createAddress(localSipUri)
val remoteSipAddress = Factory.instance().createAddress(remoteSipUri)
sharedViewModel.selectedChatRoom.value = coreContext.core.searchChatRoom(null, localAddress, remoteSipAddress, arrayOfNulls(0))
sharedViewModel.selectedChatRoom.value = coreContext.core.searchChatRoom(
null, localAddress, remoteSipAddress, arrayOfNulls(
0
)
)
}
val chatRoom = sharedViewModel.selectedChatRoom.value
chatRoom ?: return
chatRoomAddress = chatRoom.peerAddress.asStringUriOnly()
isSecure = chatRoom.currentParams.encryptionEnabled()
@ -132,15 +144,6 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
binding.chatMessagesList.adapter = adapter
adapter.registerAdapterDataObserver(observer)
// To ensure animation will be smooth
binding.chatMessagesList.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
val layoutManager = LinearLayoutManager(activity)
layoutManager.stackFromEnd = true
binding.chatMessagesList.layoutManager = layoutManager
@ -223,7 +226,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
})
binding.setBackClickListener {
findNavController().popBackStack()
navigateToChatRooms()
}
binding.back.visibility = if (resources.getBoolean(R.bool.isTablet)) View.INVISIBLE else View.VISIBLE
@ -249,7 +252,12 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
pickFile()
} else {
Log.i("[Chat Room] Asking for READ_EXTERNAL_STORAGE and CAMERA permissions")
requestPermissions(arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA), 0)
requestPermissions(
arrayOf(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.CAMERA
), 0
)
}
}
@ -330,7 +338,10 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
lifecycleScope.launch {
val fileToUploadPath = ImageUtils.getImageFilePathFromPickerIntent(data, chatSendingViewModel.temporaryFileUploadPath)
val fileToUploadPath = ImageUtils.getImageFilePathFromPickerIntent(
data,
chatSendingViewModel.temporaryFileUploadPath
)
if (fileToUploadPath != null) {
chatSendingViewModel.addAttachment(fileToUploadPath)
}
@ -353,7 +364,9 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
dialog.dismiss()
}
val okLabel = if (viewModel.oneParticipantOneDevice) getString(R.string.dialog_call) else getString(R.string.dialog_ok)
val okLabel = if (viewModel.oneParticipantOneDevice) getString(R.string.dialog_call) else getString(
R.string.dialog_ok
)
dialogViewModel.showOkButton({ doNotAskAgain ->
if (doNotAskAgain) corePreferences.limeSecurityPopupEnabled = false
@ -456,7 +469,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
}
private fun scrollToBottom() {
if (adapter.itemCount > 0) {
if (_adapter != null && adapter.itemCount > 0) {
binding.chatMessagesList.scrollToPosition(adapter.itemCount - 1)
}
}
@ -489,7 +502,10 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
val chooserIntent =
Intent.createChooser(galleryIntent, getString(R.string.chat_message_pick_file_dialog))
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(arrayOf<Parcelable>()))
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS,
cameraIntents.toArray(arrayOf<Parcelable>())
)
startActivityForResult(chooserIntent, 0)
}
@ -524,7 +540,11 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
} catch (anfe: ActivityNotFoundException) {
Log.e("[Chat Message] Couldn't find an activity to handle MIME type: $type")
val dialogViewModel = DialogViewModel(getString(R.string.dialog_try_open_file_as_text_body), getString(R.string.dialog_try_open_file_as_text_title))
val dialogViewModel = DialogViewModel(
getString(R.string.dialog_try_open_file_as_text_body), getString(
R.string.dialog_try_open_file_as_text_title
)
)
val dialog = DialogUtils.getDialog(requireContext(), dialogViewModel)
dialogViewModel.showCancelButton {

View file

@ -76,15 +76,6 @@ class GroupInfoFragment : SecureFragment<ChatRoomGroupInfoFragmentBinding>() {
)
binding.participants.adapter = adapter
// To ensure animation will be smooth
binding.participants.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
val layoutManager = LinearLayoutManager(activity)
binding.participants.layoutManager = layoutManager

View file

@ -81,15 +81,6 @@ class ImdnFragment : SecureFragment<ChatRoomImdnFragmentBinding>() {
adapter = ImdnAdapter(viewLifecycleOwner)
binding.participantsList.adapter = adapter
// To ensure animation will be smooth
binding.participantsList.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
val layoutManager = LinearLayoutManager(activity)
binding.participantsList.layoutManager = layoutManager

View file

@ -89,15 +89,6 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
adapter.registerAdapterDataObserver(observer)
binding.chatList.adapter = adapter
// To ensure animation will be smooth
binding.chatList.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
val layoutManager = LinearLayoutManager(activity)
binding.chatList.layoutManager = layoutManager

View file

@ -75,15 +75,6 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
_adapter = ContactsListAdapter(listSelectionViewModel, viewLifecycleOwner)
binding.contactsList.adapter = adapter
// To ensure animation will be smooth
binding.contactsList.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
binding.setEditClickListener {
if (PermissionHelper.get().hasWriteContactsPermission()) {
listSelectionViewModel.isEditionEnabled.value = true

View file

@ -21,8 +21,11 @@ package org.linphone.activities.main.fragments
import android.app.Dialog
import android.os.Bundle
import android.view.View
import androidx.core.view.doOnPreDraw
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.R
import org.linphone.activities.main.viewmodels.DialogViewModel
import org.linphone.activities.main.viewmodels.ListTopBarViewModel
@ -85,6 +88,21 @@ abstract class MasterFragment<T : ViewDataBinding, U : SelectionListAdapter<*, *
})
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Do not use postponeEnterTransition when fragment is recreated from the back stack,
// otherwise the previous fragment will be visible until the animation starts
val resume = findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Boolean>("resume")?.value ?: false
if (!resume) {
findNavController().currentBackStackEntry?.savedStateHandle?.set("resume", true)
// To ensure animation will be smooth,
// wait until the adapter is loaded to display the fragment
postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }
}
super.onViewCreated(view, savedInstanceState)
}
private fun delete() {
val list = listSelectionViewModel.selectedItems.value ?: arrayListOf()
deleteItems(list)

View file

@ -81,15 +81,6 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
adapter.registerAdapterDataObserver(observer)
binding.callLogsList.adapter = adapter
// To ensure animation will be smooth
binding.callLogsList.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
binding.setEditClickListener {
listSelectionViewModel.isEditionEnabled.value = true
}

View file

@ -57,15 +57,6 @@ class RecordingsFragment : MasterFragment<RecordingsFragmentBinding, RecordingsL
_adapter = RecordingsListAdapter(listSelectionViewModel, viewLifecycleOwner)
binding.recordingsList.adapter = adapter
// To ensure animation will be smooth
binding.recordingsList.apply {
postponeEnterTransition()
viewTreeObserver.addOnPreDrawListener {
startPostponedEnterTransition()
true
}
}
val layoutManager = LinearLayoutManager(activity)
binding.recordingsList.layoutManager = layoutManager

View file

@ -21,10 +21,7 @@
app:destination="@id/groupInfoFragment" />
<action
android:id="@+id/action_detailChatRoomFragment_to_ephemeralFragment"
app:destination="@id/ephemeralFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/ephemeralFragment"
app:popUpToInclusive="true" />
app:destination="@id/ephemeralFragment" />
</fragment>
<fragment
@ -41,10 +38,7 @@
app:destination="@id/groupInfoFragment" />
<action
android:id="@+id/action_chatRoomCreationFragment_to_detailChatRoomFragment"
app:destination="@id/detailChatRoomFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyFragment"
app:popUpToInclusive="false" />
app:destination="@id/detailChatRoomFragment" />
</fragment>
<fragment
android:id="@+id/devicesFragment"
@ -58,16 +52,10 @@
android:label="GroupInfoFragment" >
<action
android:id="@+id/action_groupInfoFragment_to_chatRoomCreationFragment"
app:destination="@id/chatRoomCreationFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/chatRoomCreationFragment"
app:popUpToInclusive="true" />
app:destination="@id/chatRoomCreationFragment" />
<action
android:id="@+id/action_groupInfoFragment_to_detailChatRoomFragment"
app:destination="@id/detailChatRoomFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyFragment"
app:popUpToInclusive="false" />
app:destination="@id/detailChatRoomFragment" />
</fragment>
<fragment
android:id="@+id/imdnFragment"
@ -83,31 +71,13 @@
android:name="org.linphone.activities.main.fragments.EmptyFragment"
tools:layout="@layout/empty_fragment"
android:label="EmptyFragment" >
<action
android:id="@+id/action_emptyChatFragment_to_detailChatRoomFragment"
app:destination="@id/detailChatRoomFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyChatFragment"
app:popUpToInclusive="true" />
<action
android:id="@+id/action_emptyChatFragment_to_chatRoomCreationFragment2"
app:destination="@id/chatRoomCreationFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyChatFragment"
app:popUpToInclusive="true" />
</fragment>
<action
android:id="@+id/action_global_detailChatRoomFragment"
app:destination="@id/detailChatRoomFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyChatFragment"
app:popUpToInclusive="true" />
app:destination="@id/detailChatRoomFragment" />
<action
android:id="@+id/action_global_chatRoomCreationFragment"
app:destination="@id/chatRoomCreationFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyChatFragment"
app:popUpToInclusive="true" />
app:destination="@id/chatRoomCreationFragment" />
<fragment
android:id="@+id/ephemeralFragment"
android:name="org.linphone.activities.main.chat.fragments.EphemeralFragment"

View file

@ -35,16 +35,10 @@
<action
android:id="@+id/action_global_detailContactFragment"
app:destination="@id/detailContactFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyContactFragment"
app:popUpToInclusive="true" />
app:destination="@id/detailContactFragment" />
<action
android:id="@+id/action_global_contactEditorFragment"
app:destination="@id/contactEditorFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/contactEditorFragment"
app:popUpToInclusive="true" />
app:destination="@id/contactEditorFragment" />
</navigation>

View file

@ -19,9 +19,6 @@
<action
android:id="@+id/action_global_detailCallLogFragment"
app:destination="@id/detailCallLogFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/emptyFragment"
app:popUpToInclusive="true" />
app:destination="@id/detailCallLogFragment" />
</navigation>

View file

@ -21,10 +21,7 @@
app:destination="@id/groupInfoFragment" />
<action
android:id="@+id/action_detailChatRoomFragment_to_ephemeralFragment"
app:destination="@id/ephemeralFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/ephemeralFragment"
app:popUpToInclusive="true" />
app:destination="@id/ephemeralFragment" />
</fragment>
<fragment
@ -41,10 +38,7 @@
app:destination="@id/groupInfoFragment" />
<action
android:id="@+id/action_chatRoomCreationFragment_to_detailChatRoomFragment"
app:destination="@id/detailChatRoomFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="false" />
app:destination="@id/detailChatRoomFragment" />
</fragment>
<fragment
android:id="@+id/devicesFragment"
@ -58,16 +52,10 @@
android:label="GroupInfoFragment" >
<action
android:id="@+id/action_groupInfoFragment_to_chatRoomCreationFragment"
app:destination="@id/chatRoomCreationFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/chatRoomCreationFragment"
app:popUpToInclusive="true" />
app:destination="@id/chatRoomCreationFragment" />
<action
android:id="@+id/action_groupInfoFragment_to_detailChatRoomFragment"
app:destination="@id/detailChatRoomFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="false" />
app:destination="@id/detailChatRoomFragment" />
</fragment>
<fragment
android:id="@+id/imdnFragment"

View file

@ -17,8 +17,7 @@
<action
android:id="@+id/action_detailContactFragment_to_detailChatRoomFragment"
app:destination="@id/chat_nav_graph.xml"
app:launchSingleTop="true" />
app:destination="@id/chat_nav_graph.xml" />
</fragment>

View file

@ -13,13 +13,11 @@
<action
android:id="@+id/action_detailCallLogFragment_to_detailContactFragment"
app:destination="@id/contacts_nav_graph.xml"
app:launchSingleTop="true" />
app:destination="@id/contacts_nav_graph.xml" />
<action
android:id="@+id/action_detailCallLogFragment_to_detailChatRoomFragment"
app:destination="@id/chat_nav_graph.xml"
app:launchSingleTop="true" />
app:destination="@id/chat_nav_graph.xml" />
</fragment>

View file

@ -12,23 +12,16 @@
tools:layout="@layout/chat_room_master_fragment" >
<action
android:id="@+id/action_masterChatRoomsFragment_to_dialerFragment"
app:destination="@id/dialerFragment"
app:popUpTo="@+id/dialerFragment"
app:popUpToInclusive="true" />
app:destination="@id/dialerFragment" />
<action
android:id="@+id/action_masterChatRoomsFragment_to_masterCallLogsFragment"
app:destination="@id/masterCallLogsFragment"
app:popUpTo="@+id/masterCallLogsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterCallLogsFragment" />
<action
android:id="@+id/action_masterChatRoomsFragment_to_masterContactsFragment"
app:destination="@id/masterContactsFragment"
app:popUpTo="@+id/masterContactsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterContactsFragment" />
<action
android:id="@+id/action_masterChatRoomsFragment_to_detailChatRoomFragment"
app:destination="@id/chat_nav_graph.xml"
app:launchSingleTop="true" />
app:destination="@id/chat_nav_graph.xml" />
<action
android:id="@+id/action_masterChatRoomsFragment_to_chatRoomCreationFragment"
app:destination="@id/chatRoomCreationFragment" />
@ -56,27 +49,19 @@
tools:layout="@layout/contact_master_fragment" >
<action
android:id="@+id/action_masterContactsFragment_to_masterCallLogsFragment"
app:destination="@id/masterCallLogsFragment"
app:popUpTo="@+id/masterCallLogsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterCallLogsFragment" />
<action
android:id="@+id/action_masterContactsFragment_to_dialerFragment"
app:destination="@id/dialerFragment"
app:popUpTo="@+id/dialerFragment"
app:popUpToInclusive="true" />
app:destination="@id/dialerFragment" />
<action
android:id="@+id/action_masterContactsFragment_to_masterChatRoomsFragment"
app:destination="@id/masterChatRoomsFragment"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterChatRoomsFragment" />
<action
android:id="@+id/action_masterContactsFragment_to_detailContactFragment"
app:destination="@id/contacts_nav_graph.xml"
app:launchSingleTop="true" />
app:destination="@id/contacts_nav_graph.xml" />
<action
android:id="@+id/action_masterContactsFragment_to_contactEditorFragment"
app:destination="@id/contactEditorFragment"
app:launchSingleTop="false" />
app:destination="@id/contactEditorFragment" />
<argument
android:name="id"
app:argType="string"
@ -102,19 +87,13 @@
tools:layout="@layout/history_master_fragment" >
<action
android:id="@+id/action_masterCallLogsFragment_to_dialerFragment"
app:destination="@id/dialerFragment"
app:popUpTo="@+id/dialerFragment"
app:popUpToInclusive="true" />
app:destination="@id/dialerFragment" />
<action
android:id="@+id/action_masterCallLogsFragment_to_masterContactsFragment"
app:destination="@id/masterContactsFragment"
app:popUpTo="@+id/masterContactsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterContactsFragment" />
<action
android:id="@+id/action_masterCallLogsFragment_to_masterChatRoomsFragment"
app:destination="@id/masterChatRoomsFragment"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterChatRoomsFragment" />
<action
android:id="@+id/action_masterCallLogsFragment_to_detailCallLogFragment"
app:destination="@id/history_nav_graph.xml" />
@ -126,19 +105,13 @@
tools:layout="@layout/dialer_fragment" >
<action
android:id="@+id/action_dialerFragment_to_masterCallLogsFragment"
app:destination="@id/masterCallLogsFragment"
app:popUpTo="@id/masterCallLogsFragment"
app:popUpToInclusive="true"/>
app:destination="@id/masterCallLogsFragment"/>
<action
android:id="@+id/action_dialerFragment_to_masterContactsFragment"
app:destination="@id/masterContactsFragment"
app:popUpTo="@+id/masterContactsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterContactsFragment" />
<action
android:id="@+id/action_dialerFragment_to_masterChatRoomsFragment"
app:destination="@id/masterChatRoomsFragment"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterChatRoomsFragment" />
<argument
android:name="Transfer"
app:argType="boolean"
@ -167,16 +140,10 @@
android:defaultValue="false" />
<action
android:id="@+id/action_chatRoomCreationFragment_to_groupInfoFragment"
app:destination="@id/groupInfoFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/groupInfoFragment"
app:popUpToInclusive="true" />
app:destination="@id/groupInfoFragment" />
<action
android:id="@+id/action_chatRoomCreationFragment_to_detailChatRoomFragment"
app:destination="@id/chat_nav_graph.xml"
app:launchSingleTop="true"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="false" />
app:destination="@id/chat_nav_graph.xml" />
</fragment>
<fragment
android:id="@+id/groupInfoFragment"
@ -185,16 +152,10 @@
android:label="GroupInfoFragment" >
<action
android:id="@+id/action_groupInfoFragment_to_detailChatRoomFragment"
app:destination="@id/chat_nav_graph.xml"
app:launchSingleTop="true"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="false" />
app:destination="@id/chat_nav_graph.xml" />
<action
android:id="@+id/action_groupInfoFragment_to_chatRoomCreationFragment"
app:destination="@id/chatRoomCreationFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/chatRoomCreationFragment"
app:popUpToInclusive="true" />
app:destination="@id/chatRoomCreationFragment" />
</fragment>
<fragment
android:id="@+id/aboutFragment"
@ -203,10 +164,7 @@
android:label="AboutFragment" />
<action
android:id="@+id/action_global_aboutFragment"
app:destination="@id/aboutFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/aboutFragment"
app:popUpToInclusive="true" />
app:destination="@id/aboutFragment" />
<fragment
android:id="@+id/recordingsFragment"
android:name="org.linphone.activities.main.recordings.fragments.RecordingsFragment"
@ -214,10 +172,7 @@
android:label="RecordingsFragment" />
<action
android:id="@+id/action_global_recordingsFragment"
app:destination="@id/recordingsFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/recordingsFragment"
app:popUpToInclusive="true" />
app:destination="@id/recordingsFragment" />
<fragment
android:id="@+id/settingsFragment"
android:name="org.linphone.activities.main.settings.fragments.SettingsFragment"
@ -225,50 +180,31 @@
android:label="SettingsFragment" >
<action
android:id="@+id/action_settingsFragment_to_chatSettingsFragment"
app:destination="@id/chatSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/chatSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_callSettingsFragment"
app:destination="@id/callSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/callSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_advancedSettingsFragment"
app:destination="@id/advancedSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/advancedSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_accountSettingsFragment"
app:destination="@id/accountSettingsFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/accountSettingsFragment"
app:popUpToInclusive="true" />
app:destination="@id/accountSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_audioSettingsFragment"
app:destination="@id/audioSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/audioSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_contactsSettingsFragment"
app:destination="@id/contactsSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/contactsSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_videoSettingsFragment"
app:destination="@id/videoSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/videoSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_networkSettingsFragment"
app:destination="@id/networkSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/networkSettingsFragment" />
<action
android:id="@+id/action_settingsFragment_to_tunnelSettingsFragment"
app:destination="@id/tunnelSettingsFragment"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="false" />
app:destination="@id/tunnelSettingsFragment" />
<deepLink
android:id="@+id/settingsDeepLink"
app:uri="linphone-android://settings/{Identity}"
@ -276,10 +212,7 @@
</fragment>
<action
android:id="@+id/action_global_settingsFragment"
app:destination="@id/settingsFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/settingsFragment"
app:popUpToInclusive="true" />
app:destination="@id/settingsFragment" />
<include app:graph="@navigation/settings_nav_graph" />
<fragment
android:id="@+id/accountSettingsFragment"
@ -339,16 +272,10 @@
android:label="TunnelSettingsFragment" />
<action
android:id="@+id/action_global_masterChatRoomsFragment"
app:destination="@id/masterChatRoomsFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/masterChatRoomsFragment"
app:popUpToInclusive="true" />
app:destination="@id/masterChatRoomsFragment" />
<action
android:id="@+id/action_global_dialerFragment"
app:destination="@id/dialerFragment"
app:launchSingleTop="true"
app:popUpTo="@+id/dialerFragment"
app:popUpToInclusive="true" />
app:destination="@id/dialerFragment" />
<fragment
android:id="@+id/phoneAccountLinkingFragment"
tools:layout="@layout/assistant_phone_account_linking_fragment"
@ -376,10 +303,7 @@
android:label="PhoneAccountValidationFragment" >
<action
android:id="@+id/action_phoneAccountValidationFragment_to_accountSettingsFragment"
app:destination="@id/accountSettingsFragment"
app:launchSingleTop="true"
app:popUpTo="@id/accountSettingsFragment"
app:popUpToInclusive="true" />
app:destination="@id/accountSettingsFragment" />
<argument
android:name="PhoneNumber"
app:argType="string" />

View file

@ -63,40 +63,31 @@
android:label="TunnelSettingsFragment" />
<action
android:id="@+id/action_global_tunnelSettingsFragment"
app:destination="@id/tunnelSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/tunnelSettingsFragment" />
<action
android:id="@+id/action_global_videoSettingsFragment"
app:destination="@id/videoSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/videoSettingsFragment" />
<action
android:id="@+id/action_global_callSettingsFragment"
app:destination="@id/callSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/callSettingsFragment" />
<action
android:id="@+id/action_global_networkSettingsFragment"
app:destination="@id/networkSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/networkSettingsFragment" />
<action
android:id="@+id/action_global_chatSettingsFragment"
app:destination="@id/chatSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/chatSettingsFragment" />
<action
android:id="@+id/action_global_contactsSettingsFragment"
app:destination="@id/contactsSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/contactsSettingsFragment" />
<action
android:id="@+id/action_global_accountSettingsFragment"
app:destination="@id/accountSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/accountSettingsFragment" />
<action
android:id="@+id/action_global_advancedSettingsFragment"
app:destination="@id/advancedSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/advancedSettingsFragment" />
<action
android:id="@+id/action_global_audioSettingsFragment"
app:destination="@id/audioSettingsFragment"
app:launchSingleTop="true" />
app:destination="@id/audioSettingsFragment" />
<fragment
android:id="@+id/phoneAccountLinkingFragment"
tools:layout="@layout/assistant_phone_account_linking_fragment"
@ -124,10 +115,7 @@
android:label="PhoneAccountValidationFragment" >
<action
android:id="@+id/action_phoneAccountValidationFragment_to_accountSettingsFragment"
app:destination="@id/accountSettingsFragment"
app:launchSingleTop="true"
app:popUpTo="@id/accountSettingsFragment"
app:popUpToInclusive="true" />
app:destination="@id/accountSettingsFragment" />
<argument
android:name="PhoneNumber"
app:argType="string" />