From 9a2103a9a7c1ee5f39947bb1189f9391edcbb903 Mon Sep 17 00:00:00 2001 From: ekager Date: Fri, 18 Sep 2020 14:03:19 -0700 Subject: [PATCH] For #13934 - Make TabHistory work on PWA/Custom Tabs --- .../fenix/browser/BaseBrowserFragment.kt | 12 +++++-- .../toolbar/BrowserToolbarMenuController.kt | 8 +++-- .../fenix/tabhistory/TabHistoryController.kt | 13 ++++--- .../tabhistory/TabHistoryDialogFragment.kt | 28 ++++++++++++--- .../fenix/tabhistory/TabHistoryView.kt | 25 ++++++-------- app/src/main/res/navigation/nav_graph.xml | 7 +++- ...DefaultBrowserToolbarMenuControllerTest.kt | 4 +-- .../tabhistory/TabHistoryControllerTest.kt | 34 ++++++++++++++++--- 8 files changed, 96 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 78eb413a6..4b662e4b1 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -254,7 +254,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session ) }, onCloseTab = { closedSession -> - val tab = store.state.findTab(closedSession.id) ?: return@DefaultBrowserToolbarController + val tab = store.state.findTab(closedSession.id) + ?: return@DefaultBrowserToolbarController val isSelected = tab.id == context.components.core.store.state.selectedTabId val snackbarMessage = if (tab.content.private) { @@ -875,7 +876,11 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session } override fun onBackLongPressed(): Boolean { - findNavController().navigate(R.id.action_global_tabHistoryDialogFragment) + findNavController().navigate( + NavGraphDirections.actionGlobalTabHistoryDialogFragment( + activeSessionId = customTabSessionId + ) + ) return true } @@ -1118,7 +1123,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session private fun didFirstContentfulHappen() = if (components.settings.waitToShowPageUntilFirstPaint) { - val tab = components.core.store.state.findTabOrCustomTabOrSelectedTab(customTabSessionId) + val tab = + components.core.store.state.findTabOrCustomTabOrSelectedTab(customTabSessionId) tab?.content?.firstContentfulPaint ?: false } else { true diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt index 46692b0a4..4fd69b08e 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt @@ -87,7 +87,9 @@ class DefaultBrowserToolbarMenuController( is ToolbarMenu.Item.Back -> { if (item.viewHistory) { navController.navigate( - BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment() + BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment( + activeSessionId = customTabSession?.id + ) ) } else { sessionUseCases.goBack.invoke(currentSession) @@ -96,7 +98,9 @@ class DefaultBrowserToolbarMenuController( is ToolbarMenu.Item.Forward -> { if (item.viewHistory) { navController.navigate( - BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment() + BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment( + activeSessionId = customTabSession?.id + ) ) } else { sessionUseCases.goForward.invoke(currentSession) diff --git a/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryController.kt b/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryController.kt index 2d6ecc784..91710a0bb 100644 --- a/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryController.kt +++ b/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryController.kt @@ -5,8 +5,8 @@ package org.mozilla.fenix.tabhistory import androidx.navigation.NavController +import mozilla.components.browser.session.SessionManager import mozilla.components.feature.session.SessionUseCases -import org.mozilla.fenix.R interface TabHistoryController { fun handleGoToHistoryItem(item: TabHistoryItem) @@ -14,11 +14,16 @@ interface TabHistoryController { class DefaultTabHistoryController( private val navController: NavController, - private val goToHistoryIndexUseCase: SessionUseCases.GoToHistoryIndexUseCase + private val goToHistoryIndexUseCase: SessionUseCases.GoToHistoryIndexUseCase, + private val customTabId: String? = null, + private val sessionManager: SessionManager ) : TabHistoryController { override fun handleGoToHistoryItem(item: TabHistoryItem) { - navController.popBackStack(R.id.browserFragment, false) - goToHistoryIndexUseCase.invoke(item.index) + navController.navigateUp() + goToHistoryIndexUseCase.invoke( + item.index, + session = customTabId?.let { sessionManager.findSessionById(customTabId) } + ?: sessionManager.selectedSession) } } diff --git a/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryDialogFragment.kt index 5ae534b73..b723d97be 100644 --- a/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryDialogFragment.kt @@ -12,10 +12,16 @@ import androidx.navigation.fragment.findNavController import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import kotlinx.android.synthetic.main.activity_home.* import kotlinx.android.synthetic.main.fragment_tab_history_dialog.* import kotlinx.coroutines.ExperimentalCoroutinesApi -import mozilla.components.lib.state.ext.consumeFrom +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.mapNotNull +import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab +import mozilla.components.lib.state.ext.flowScoped +import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.requireComponents class TabHistoryDialogFragment : BottomSheetDialogFragment() { @@ -25,6 +31,8 @@ class TabHistoryDialogFragment : BottomSheetDialogFragment() { setStyle(STYLE_NO_TITLE, R.style.BottomSheet) } + var customTabSessionId: String? = null + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -35,9 +43,13 @@ class TabHistoryDialogFragment : BottomSheetDialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + customTabSessionId = requireArguments().getString(EXTRA_SESSION_ID) + val controller = DefaultTabHistoryController( navController = findNavController(), - goToHistoryIndexUseCase = requireComponents.useCases.sessionUseCases.goToHistoryIndex + goToHistoryIndexUseCase = requireComponents.useCases.sessionUseCases.goToHistoryIndex, + customTabId = customTabSessionId, + sessionManager = container.requireContext().components.core.sessionManager ) val tabHistoryView = TabHistoryView( container = tabHistoryLayout, @@ -45,12 +57,20 @@ class TabHistoryDialogFragment : BottomSheetDialogFragment() { interactor = TabHistoryInteractor(controller) ) - consumeFrom(requireComponents.core.store) { - tabHistoryView.updateState(it) + requireComponents.core.store.flowScoped(viewLifecycleOwner) { flow -> + flow.mapNotNull { state -> state.findCustomTabOrSelectedTab(customTabSessionId)?.content?.history } + .ifChanged() + .collect { historyState -> + tabHistoryView.updateState(historyState) + } } } private fun expand() { (dialog as BottomSheetDialog).behavior.state = BottomSheetBehavior.STATE_EXPANDED } + + companion object { + const val EXTRA_SESSION_ID = "activeSessionId" + } } diff --git a/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryView.kt b/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryView.kt index f74da7e4d..789db3d60 100644 --- a/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryView.kt +++ b/app/src/main/java/org/mozilla/fenix/tabhistory/TabHistoryView.kt @@ -11,8 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.component_tabhistory.* -import mozilla.components.browser.state.selector.selectedTab -import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.content.HistoryState import org.mozilla.fenix.R interface TabHistoryViewInteractor { @@ -66,18 +65,16 @@ class TabHistoryView( tabHistoryRecyclerView.layoutManager = layoutManager } - fun updateState(state: BrowserState) { - state.selectedTab?.content?.history?.let { historyState -> - currentIndex = historyState.currentIndex - val items = historyState.items.mapIndexed { index, historyItem -> - TabHistoryItem( - title = historyItem.title, - url = historyItem.uri, - index = index, - isSelected = index == historyState.currentIndex - ) - } - adapter.submitList(items) + fun updateState(historyState: HistoryState) { + currentIndex = historyState.currentIndex + val items = historyState.items.mapIndexed { index, historyItem -> + TabHistoryItem( + title = historyItem.title, + url = historyItem.uri, + index = index, + isSelected = index == currentIndex + ) } + adapter.submitList(items) } } diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index c3c5abb3e..1d3033460 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -836,7 +836,12 @@ + tools:layout="@layout/fragment_tab_history_dialog"> + +