From a7f58336fbaf611356454f253771990e705dc91b Mon Sep 17 00:00:00 2001 From: samiuelson Date: Tue, 20 Feb 2024 19:13:58 +0100 Subject: [PATCH 1/7] Open order details in a single-top When in two-pane mode, we want to avoid stacking multiple OrderDetailFragments in the right pane's NavHostFragment --- .../kotlin/com/woocommerce/android/ui/main/MainActivity.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivity.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivity.kt index 6f93f14c06d..b76a5652801 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivity.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivity.kt @@ -34,6 +34,7 @@ import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks import androidx.navigation.NavController import androidx.navigation.NavDestination +import androidx.navigation.NavOptions import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.NavHostFragment import com.automattic.android.tracks.crashlogging.CrashLogging @@ -1206,7 +1207,11 @@ class MainActivity : remoteNoteId, startPaymentsFlow ).toBundle() - navController.navigate(R.id.orderDetailFragment, bundle) + navController.navigate( + R.id.orderDetailFragment, + bundle, + navOptions = NavOptions.Builder().setLaunchSingleTop(true).build() + ) } ?: run { navController.navigateSafely(action) } From f6adb458ba266019d87b8ad1a5c74a9a554b1126 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 21 Feb 2024 07:52:46 +0100 Subject: [PATCH 2/7] Fix handling navigating up --- .../ui/orders/details/OrderDetailFragment.kt | 2 +- .../ui/orders/list/OrderListFragment.kt | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/OrderDetailFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/OrderDetailFragment.kt index 4440ba95970..8bab08d2994 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/OrderDetailFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/OrderDetailFragment.kt @@ -254,7 +254,7 @@ class OrderDetailFragment : } else { binding.toolbar.navigationIcon = AppCompatResources.getDrawable(requireActivity(), R.drawable.ic_back_24dp) binding.toolbar.setNavigationOnClickListener { - findNavController().navigateUp() + if (!findNavController().popBackStack()) requireActivity().onBackPressedDispatcher.onBackPressed() } } val menuEditOrder = menu.findItem(R.id.menu_edit_order) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index 1f86158c028..300b14747b9 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -72,6 +72,7 @@ import org.wordpress.android.util.DisplayUtils import org.wordpress.android.util.ToastUtils import javax.inject.Inject import org.wordpress.android.util.ActivityUtils as WPActivityUtils +import androidx.navigation.findNavController @AndroidEntryPoint @Suppress("LargeClass") @@ -108,8 +109,6 @@ class OrderListFragment : private val viewModel: OrderListViewModel by viewModels() private var snackBar: Snackbar? = null - private var savedDestinationId: Int = -1 - override fun onStop() { snackBar?.dismiss() super.onStop() @@ -153,7 +152,6 @@ class OrderListFragment : savedInstanceState?.let { bundle -> isSearching = bundle.getBoolean(STATE_KEY_IS_SEARCHING) searchQuery = bundle.getString(STATE_KEY_SEARCH_QUERY, "") - savedDestinationId = savedInstanceState.getInt(CURRENT_NAV_DESTINATION, -1) } requireActivity().onBackPressedDispatcher.addCallback( this, @@ -165,7 +163,15 @@ class OrderListFragment : } else if (isSearching) { handleSearchViewCollapse() } else { - findNavController().navigateUp() + val result = + _binding?.detailNavContainer?.findNavController()?.navigateUp() ?: false + // There are no more fragments in the back stack, UI used to be a two pane layout (tablet) + // and now it's a single pane layout (phone), e.g. due to a configuration change. + if (!result && _binding?.orderRefreshLayout?.isVisible != true && !isTablet()) { + adjustUiForDeviceType(savedInstanceState) + } else { + requireActivity().onBackPressedDispatcher.onBackPressed() + } } } } @@ -216,7 +222,7 @@ class OrderListFragment : initObservers() initializeResultHandlers() - displayTwoPaneLayoutIfTablet(savedInstanceState) + adjustUiForDeviceType(savedInstanceState) binding.orderFiltersCard.setClickListener { viewModel.onFiltersButtonTapped() } initCreateOrderFAB(binding.createOrderButton) initSwipeBehaviour() @@ -272,11 +278,11 @@ class OrderListFragment : return true // Return true to collapse the action view } - private fun displayTwoPaneLayoutIfTablet(savedInstanceState: Bundle?) { + private fun adjustUiForDeviceType(savedInstanceState: Bundle?) { if (isTablet()) { adjustLayoutForTablet() } else { - adjustLayoutForNonTablet() + adjustLayoutForNonTablet(savedInstanceState) savedInstanceState?.putInt(CURRENT_NAV_DESTINATION, -1) } } @@ -285,8 +291,8 @@ class OrderListFragment : binding.twoPaneLayoutGuideline.setGuidelinePercent(TABLET_LANDSCAPE_WIDTH_RATIO) } - private fun adjustLayoutForNonTablet() { - if (savedDestinationId != -1) { + private fun adjustLayoutForNonTablet(savedInstanceState: Bundle?) { + if (savedInstanceState != null && savedInstanceState.getInt(CURRENT_NAV_DESTINATION, -1) != -1) { adjustLayoutForSinglePane() } else { _binding?.detailNavContainer?.visibility = View.GONE From e3a908467e2eaa9e1ab16fa8ba4607af6864b036 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 21 Feb 2024 10:10:54 +0100 Subject: [PATCH 3/7] Clean up code --- .../ui/orders/list/OrderListFragment.kt | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index 300b14747b9..b2592f7fa86 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -165,9 +165,10 @@ class OrderListFragment : } else { val result = _binding?.detailNavContainer?.findNavController()?.navigateUp() ?: false - // There are no more fragments in the back stack, UI used to be a two pane layout (tablet) - // and now it's a single pane layout (phone), e.g. due to a configuration change. if (!result && _binding?.orderRefreshLayout?.isVisible != true && !isTablet()) { + // There are no more fragments in the back stack, UI used to be a two pane layout (tablet) + // and now it's a single pane layout (phone), e.g. due to a configuration change. + // In this case we need to switch panes – show the list pane instead of details pane. adjustUiForDeviceType(savedInstanceState) } else { requireActivity().onBackPressedDispatcher.onBackPressed() @@ -293,20 +294,21 @@ class OrderListFragment : private fun adjustLayoutForNonTablet(savedInstanceState: Bundle?) { if (savedInstanceState != null && savedInstanceState.getInt(CURRENT_NAV_DESTINATION, -1) != -1) { - adjustLayoutForSinglePane() + displayDetailPaneOnly() } else { - _binding?.detailNavContainer?.visibility = View.GONE - _binding?.orderRefreshLayout?.visibility = View.VISIBLE - _binding?.twoPaneLayoutGuideline?.setGuidelinePercent(1f) + displayListPaneOnly() } } - private fun adjustLayoutForSinglePane() { - // Adjust the detail container to occupy the full width in single-pane mode (e.g., phone) + private fun displayListPaneOnly() { + _binding?.detailNavContainer?.visibility = View.GONE + _binding?.orderRefreshLayout?.visibility = View.VISIBLE + _binding?.twoPaneLayoutGuideline?.setGuidelinePercent(1f) + } + + private fun displayDetailPaneOnly() { _binding?.detailNavContainer?.visibility = View.VISIBLE _binding?.twoPaneLayoutGuideline?.setGuidelinePercent(0.0f) - - // Adjust the order list view to be hidden in single-pane mode _binding?.orderRefreshLayout?.visibility = View.GONE } From 8185d43bfdbb10a669509ec8267fc612055c6cb3 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 21 Feb 2024 10:45:36 +0100 Subject: [PATCH 4/7] Reorder imports --- .../com/woocommerce/android/ui/orders/list/OrderListFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index b2592f7fa86..68391594cb0 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -18,6 +18,7 @@ import androidx.core.view.doOnPreDraw import androidx.core.view.isVisible import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels +import androidx.navigation.findNavController import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.findNavController import androidx.paging.PagedList @@ -72,7 +73,6 @@ import org.wordpress.android.util.DisplayUtils import org.wordpress.android.util.ToastUtils import javax.inject.Inject import org.wordpress.android.util.ActivityUtils as WPActivityUtils -import androidx.navigation.findNavController @AndroidEntryPoint @Suppress("LargeClass") From 62efaff65f503dba30aa86aeaed482f8d2b44b21 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 21 Feb 2024 11:52:25 +0100 Subject: [PATCH 5/7] Fix empty state displaying --- .../ui/orders/list/OrderListFragment.kt | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index 68391594cb0..87cc28dffdd 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -1,5 +1,6 @@ package com.woocommerce.android.ui.orders.list +import org.wordpress.android.util.ActivityUtils as WPActivityUtils import android.os.Bundle import android.os.Handler import android.os.Looper @@ -9,7 +10,6 @@ import android.view.MenuItem import android.view.MenuItem.OnActionExpandListener import android.view.View import android.view.ViewGroup -import android.widget.LinearLayout import androidx.activity.OnBackPressedCallback import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView.OnQueryTextListener @@ -72,7 +72,6 @@ import dagger.hilt.android.AndroidEntryPoint import org.wordpress.android.util.DisplayUtils import org.wordpress.android.util.ToastUtils import javax.inject.Inject -import org.wordpress.android.util.ActivityUtils as WPActivityUtils @AndroidEntryPoint @Suppress("LargeClass") @@ -312,15 +311,6 @@ class OrderListFragment : _binding?.orderRefreshLayout?.visibility = View.GONE } - private fun hideDetailPane( - detailContainer: NavHostFragment, - orderListViewLayoutParams: LinearLayout.LayoutParams - ) { - detailContainer.view?.visibility = View.GONE - orderListViewLayoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT - orderListViewLayoutParams.weight = 0f - } - private fun initSwipeBehaviour() { val swipeToComplete = SwipeToComplete(requireContext(), this) val swipeHelper = ItemTouchHelper(swipeToComplete) @@ -568,12 +558,7 @@ class OrderListFragment : emptyView.show(emptyViewType) { ChromeCustomTabUtils.launchUrl(requireActivity(), AppUrls.URL_LEARN_MORE_ORDERS) } - val detailContainer = childFragmentManager.findFragmentById( - R.id.detail_nav_container - ) as NavHostFragment - val orderListViewLayoutParams = binding.orderRefreshLayout.layoutParams - as LinearLayout.LayoutParams - hideDetailPane(detailContainer, orderListViewLayoutParams) + if (isTablet()) displayListPaneOnly() } EmptyViewType.ORDER_LIST_FILTERED -> { From bcba1647210f6456450538fc1cd6c15e7d129633 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 21 Feb 2024 12:26:36 +0100 Subject: [PATCH 6/7] Reorder imports --- .../com/woocommerce/android/ui/orders/list/OrderListFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index 87cc28dffdd..e4fa5487770 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -1,6 +1,5 @@ package com.woocommerce.android.ui.orders.list -import org.wordpress.android.util.ActivityUtils as WPActivityUtils import android.os.Bundle import android.os.Handler import android.os.Looper @@ -72,6 +71,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.wordpress.android.util.DisplayUtils import org.wordpress.android.util.ToastUtils import javax.inject.Inject +import org.wordpress.android.util.ActivityUtils as WPActivityUtils @AndroidEntryPoint @Suppress("LargeClass") From b22a2722acd89ab3ea3db362ade51520c694fb3c Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 21 Feb 2024 15:00:18 +0100 Subject: [PATCH 7/7] Fix switching between empty state and results --- .../woocommerce/android/ui/orders/list/OrderListFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index e4fa5487770..b8f3d5b9f38 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -289,6 +289,8 @@ class OrderListFragment : private fun adjustLayoutForTablet() { binding.twoPaneLayoutGuideline.setGuidelinePercent(TABLET_LANDSCAPE_WIDTH_RATIO) + binding.orderRefreshLayout.visibility = View.VISIBLE + binding.detailNavContainer.visibility = View.VISIBLE } private fun adjustLayoutForNonTablet(savedInstanceState: Bundle?) { @@ -558,7 +560,6 @@ class OrderListFragment : emptyView.show(emptyViewType) { ChromeCustomTabUtils.launchUrl(requireActivity(), AppUrls.URL_LEARN_MORE_ORDERS) } - if (isTablet()) displayListPaneOnly() } EmptyViewType.ORDER_LIST_FILTERED -> {