1
0
Fork 0

Refactors the TabTrayDialogFragment to ditch that weird interactor (#11061)

* For #11056 - Removes unused argument when navigating to the collection creation fragment

* For #11056 - Moved the collection creation navigation logic to the TabTrayDialogFragment

* For #11056 - Moves navigating to the share screen from home/browser to the TabTrayDialogFragment

* For #11056 - We moved tab selection logic from home/browser to the tab tray dialog

* For #11056 - Moved new tab tapped logic to the tab tray dialog fragment

* For #11056 - Removes all interactor logic for the TabTrayDialogFragment

* For #11056 - Migrates the presentation / navigation around the TabTrayDialog to the androidx navigation library
master
Jeff Boek 2020-05-29 15:17:56 -07:00 committed by GitHub
parent 3946ec11de
commit 8662164b8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 98 additions and 223 deletions

View File

@ -69,9 +69,7 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.IntentReceiverActivity
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.readermode.DefaultReaderModeController
import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.FindInPageIntegration
import org.mozilla.fenix.components.StoreProvider
@ -95,9 +93,7 @@ import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.sessionsOfType
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.SharedViewModel
import org.mozilla.fenix.tabtray.TabTrayDialogFragment
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration
import java.lang.ref.WeakReference
@ -218,88 +214,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
topSiteStorage = requireComponents.core.topSiteStorage,
sharedViewModel = sharedViewModel,
onTabCounterClicked = {
val tabTrayDialog = TabTrayDialogFragment()
tabTrayDialog.show(parentFragmentManager, null)
tabTrayDialog.interactor = object : TabTrayDialogFragment.Interactor {
override fun onTabSelected(tab: mozilla.components.concept.tabstray.Tab) {
tabTrayDialog.dismiss()
}
override fun onNewTabTapped(private: Boolean) {
(activity as HomeActivity).browsingModeManager.mode = BrowsingMode.fromBoolean(private)
tabTrayDialog.dismiss()
findNavController().navigate(BrowserFragmentDirections.actionGlobalHome())
}
override fun onShareTabsClicked(private: Boolean) {
share(getListOfSessions(private))
}
override fun onCloseAllTabsClicked(private: Boolean) {
val tabs = getListOfSessions(private)
val selectedIndex = sessionManager
.selectedSession?.let { sessionManager.sessions.indexOf(it) } ?: 0
val snapshot = tabs
.map(sessionManager::createSessionSnapshot)
.map {
it.copy(engineSession = null, engineSessionState = it.engineSession?.saveState())
}
.let { SessionManager.Snapshot(it, selectedIndex) }
tabs.forEach {
sessionManager.remove(it)
}
val isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate
val snackbarMessage = if (isPrivate) {
getString(R.string.snackbar_private_tabs_closed)
} else {
getString(R.string.snackbar_tabs_closed)
}
viewLifecycleOwner.lifecycleScope.allowUndo(
tabTrayDialog.requireView(),
snackbarMessage,
getString(R.string.snackbar_deleted_undo),
{
sessionManager.restore(snapshot)
},
operation = { },
elevation = SNACKBAR_ELEVATION
)
}
override fun onSaveToCollectionClicked() {
val tabs = getListOfSessions(false)
val tabIds = tabs.map { it.id }.toList().toTypedArray()
val tabCollectionStorage = (activity as HomeActivity).components.core.tabCollectionStorage
val navController = findNavController()
val step = when {
// Show the SelectTabs fragment if there are multiple opened tabs to select which tabs
// you want to save to a collection.
tabs.size > 1 -> SaveCollectionStep.SelectTabs
// If there is an existing tab collection, show the SelectCollection fragment to save
// the selected tab to a collection of your choice.
tabCollectionStorage.cachedTabCollections.isNotEmpty() ->
SaveCollectionStep.SelectCollection
// Show the NameCollection fragment to create a new collection for the selected tab.
else -> SaveCollectionStep.NameCollection
}
if (navController.currentDestination?.id == R.id.collectionCreationFragment) return
val directions = BrowserFragmentDirections.actionBrowserFragmentToCreateCollectionFragment(
tabIds = tabIds,
previousFragmentId = R.id.tabTrayFragment,
saveCollectionStep = step,
selectedTabIds = tabIds
)
navController.nav(R.id.browserFragment, directions)
}
}
findNavController().navigate(BrowserFragmentDirections.actionGlobalTabTrayDialogFragment())
}
)
@ -1040,16 +955,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
}
}
private fun share(tabs: List<Session>) {
val data = tabs.map {
ShareData(url = it.url, title = it.title)
}
val directions = BrowserFragmentDirections.actionGlobalShareFragment(
data = data.toTypedArray()
)
nav(R.id.browserFragment, directions)
}
private fun getListOfSessions(
private: Boolean = (activity as HomeActivity).browsingModeManager.mode.isPrivate
): List<Session> {

View File

@ -62,7 +62,6 @@ class CollectionCreationFragment : DialogFragment() {
collectionCreationStore = StoreProvider.get(this) {
CollectionCreationStore(
CollectionCreationState(
previousFragmentId = args.previousFragmentId,
tabs = tabs,
selectedTabs = selectedTabs,
saveCollectionStep = args.saveCollectionStep,

View File

@ -35,7 +35,6 @@ enum class SaveCollectionStep {
}
data class CollectionCreationState(
val previousFragmentId: Int,
val tabs: List<Tab> = emptyList(),
val selectedTabs: Set<Tab> = emptySet(),
val saveCollectionStep: SaveCollectionStep = SaveCollectionStep.SelectTabs,

View File

@ -234,7 +234,6 @@ class DefaultBrowserToolbarController(
currentSession?.let { currentSession ->
val directions =
BrowserFragmentDirections.actionGlobalCollectionCreationFragment(
previousFragmentId = R.id.browserFragment,
tabIds = arrayOf(currentSession.id),
selectedTabIds = arrayOf(currentSession.id),
saveCollectionStep = if (tabCollectionStorage.cachedTabCollections.isEmpty()) {

View File

@ -60,7 +60,6 @@ import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.state.MediaState.State.PLAYING
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount
@ -77,7 +76,6 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.addons.runIfFragmentIsAttached
import org.mozilla.fenix.browser.BrowserAnimator.Companion.getToolbarNavOptions
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.cfr.SearchWidgetCFR
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.PrivateShortcutCreateManager
@ -105,7 +103,6 @@ import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.SupportUtils.MozillaPage.PRIVATE_NOTICE
import org.mozilla.fenix.settings.SupportUtils.SumoTopic.HELP
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
import org.mozilla.fenix.tabtray.TabTrayDialogFragment
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.FragmentPreDrawManager
import org.mozilla.fenix.utils.allowUndo
@ -1022,98 +1019,11 @@ class HomeFragment : Fragment() {
}
}
private fun share(tabs: List<Session>) {
val data = tabs.map {
ShareData(url = it.url, title = it.title)
}
val directions = HomeFragmentDirections.actionGlobalShareFragment(
data = data.toTypedArray()
)
nav(R.id.homeFragment, directions)
}
private fun openTabTray() {
invokePendingDeleteJobs()
hideOnboardingIfNeeded()
val tabTrayDialog = TabTrayDialogFragment()
tabTrayDialog.show(parentFragmentManager, null)
tabTrayDialog.interactor = object : TabTrayDialogFragment.Interactor {
override fun onTabSelected(tab: mozilla.components.concept.tabstray.Tab) {
tabTrayDialog.dismiss()
(activity as HomeActivity).openToBrowser(BrowserDirection.FromHome)
}
override fun onNewTabTapped(private: Boolean) {
(activity as HomeActivity).browsingModeManager.mode = BrowsingMode.fromBoolean(private)
tabTrayDialog.dismiss()
}
override fun onShareTabsClicked(private: Boolean) {
share(getListOfSessions(private))
}
override fun onCloseAllTabsClicked(private: Boolean) {
val tabs = getListOfSessions(private)
val selectedIndex = sessionManager
.selectedSession?.let { sessionManager.sessions.indexOf(it) } ?: 0
val snapshot = tabs
.map(sessionManager::createSessionSnapshot)
.map { it.copy(engineSession = null, engineSessionState = it.engineSession?.saveState()) }
.let { SessionManager.Snapshot(it, selectedIndex) }
tabs.forEach {
sessionManager.remove(it)
}
val isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate
val snackbarMessage = if (isPrivate) {
getString(R.string.snackbar_private_tabs_closed)
} else {
getString(R.string.snackbar_tabs_closed)
}
viewLifecycleOwner.lifecycleScope.allowUndo(
tabTrayDialog.requireView(),
snackbarMessage,
getString(R.string.snackbar_deleted_undo),
{
sessionManager.restore(snapshot)
},
operation = { },
elevation = SNACKBAR_ELEVATION
)
}
override fun onSaveToCollectionClicked() {
val tabs = getListOfSessions(false)
val tabIds = tabs.map { it.id }.toList().toTypedArray()
val tabCollectionStorage = (activity as HomeActivity).components.core.tabCollectionStorage
val navController = findNavController()
val step = when {
// Show the SelectTabs fragment if there are multiple opened tabs to select which tabs
// you want to save to a collection.
tabs.size > 1 -> SaveCollectionStep.SelectTabs
// If there is an existing tab collection, show the SelectCollection fragment to save
// the selected tab to a collection of your choice.
tabCollectionStorage.cachedTabCollections.isNotEmpty() -> SaveCollectionStep.SelectCollection
// Show the NameCollection fragment to create a new collection for the selected tab.
else -> SaveCollectionStep.NameCollection
}
if (navController.currentDestination?.id == R.id.collectionCreationFragment) return
val directions = HomeFragmentDirections.actionHomeFragmentToCreateCollectionFragment(
tabIds = tabIds,
previousFragmentId = R.id.tabTrayFragment,
saveCollectionStep = step,
selectedTabIds = tabIds
)
navController.nav(R.id.homeFragment, directions)
}
}
findNavController().navigate(HomeFragmentDirections.actionGlobalTabTrayDialogFragment())
}
companion object {

View File

@ -412,9 +412,8 @@ class DefaultSessionControlController(
registerCollectionStorageObserver()
val tabIds = getListOfTabs().map { it.sessionId }.toTypedArray()
val directions = HomeFragmentDirections.actionHomeFragmentToCreateCollectionFragment(
val directions = HomeFragmentDirections.actionGlobalCollectionCreationFragment(
tabIds = tabIds,
previousFragmentId = R.id.homeFragment,
saveCollectionStep = step,
selectedTabIds = selectedTabIds,
selectedTabCollectionId = selectedTabCollectionId ?: -1

View File

@ -11,28 +11,27 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import kotlinx.android.synthetic.main.component_tabstray.view.*
import kotlinx.android.synthetic.main.fragment_tab_tray_dialog.*
import kotlinx.android.synthetic.main.fragment_tab_tray_dialog.view.*
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.concept.engine.prompt.ShareData
import mozilla.components.concept.tabstray.Tab
import mozilla.components.lib.state.ext.consumeFrom
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.sessionsOfType
import org.mozilla.fenix.utils.allowUndo
@SuppressWarnings("TooManyFunctions")
class TabTrayDialogFragment : AppCompatDialogFragment(), TabTrayInteractor {
interface Interactor {
fun onTabSelected(tab: Tab)
fun onNewTabTapped(private: Boolean)
fun onShareTabsClicked(private: Boolean)
fun onSaveToCollectionClicked()
fun onCloseAllTabsClicked(private: Boolean)
}
private lateinit var tabTrayView: TabTrayView
var interactor: Interactor? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -105,27 +104,101 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), TabTrayInteractor {
}
override fun onTabSelected(tab: Tab) {
interactor?.onTabSelected(tab)
dismissAllowingStateLoss()
if (findNavController().currentDestination?.id == R.id.browserFragment) return
if (!findNavController().popBackStack(R.id.browserFragment, false)) {
findNavController().navigate(R.id.browserFragment)
}
}
override fun onNewTabTapped(private: Boolean) {
interactor?.onNewTabTapped(private)
(activity as HomeActivity).browsingModeManager.mode = BrowsingMode.fromBoolean(private)
findNavController().popBackStack(R.id.homeFragment, false)
dismissAllowingStateLoss()
}
override fun onTabTrayDismissed() {
dismissAllowingStateLoss()
}
override fun onShareTabsClicked(private: Boolean) {
interactor?.onShareTabsClicked(private)
override fun onSaveToCollectionClicked() {
val tabs = getListOfSessions(false)
val tabIds = tabs.map { it.id }.toList().toTypedArray()
val tabCollectionStorage = (activity as HomeActivity).components.core.tabCollectionStorage
val navController = findNavController()
val step = when {
// Show the SelectTabs fragment if there are multiple opened tabs to select which tabs
// you want to save to a collection.
tabs.size > 1 -> SaveCollectionStep.SelectTabs
// If there is an existing tab collection, show the SelectCollection fragment to save
// the selected tab to a collection of your choice.
tabCollectionStorage.cachedTabCollections.isNotEmpty() -> SaveCollectionStep.SelectCollection
// Show the NameCollection fragment to create a new collection for the selected tab.
else -> SaveCollectionStep.NameCollection
}
if (navController.currentDestination?.id == R.id.collectionCreationFragment) return
val directions = TabTrayDialogFragmentDirections.actionGlobalCollectionCreationFragment(
tabIds = tabIds,
saveCollectionStep = step,
selectedTabIds = tabIds
)
navController.navigate(directions)
}
override fun onSaveToCollectionClicked() {
interactor?.onSaveToCollectionClicked()
override fun onShareTabsClicked(private: Boolean) {
val tabs = getListOfSessions(private)
val data = tabs.map {
ShareData(url = it.url, title = it.title)
}
val directions = TabTrayDialogFragmentDirections.actionGlobalShareFragment(
data = data.toTypedArray()
)
findNavController().navigate(directions)
}
override fun onCloseAllTabsClicked(private: Boolean) {
interactor?.onCloseAllTabsClicked(private)
val sessionManager = requireContext().components.core.sessionManager
val tabs = getListOfSessions(private)
val selectedIndex = sessionManager
.selectedSession?.let { sessionManager.sessions.indexOf(it) } ?: 0
val snapshot = tabs
.map(sessionManager::createSessionSnapshot)
.map { it.copy(engineSession = null, engineSessionState = it.engineSession?.saveState()) }
.let { SessionManager.Snapshot(it, selectedIndex) }
tabs.forEach {
sessionManager.remove(it)
}
val isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate
val snackbarMessage = if (isPrivate) {
getString(R.string.snackbar_private_tabs_closed)
} else {
getString(R.string.snackbar_tabs_closed)
}
viewLifecycleOwner.lifecycleScope.allowUndo(
requireView(),
snackbarMessage,
getString(R.string.snackbar_deleted_undo),
{
sessionManager.restore(snapshot)
},
operation = { },
elevation = ELEVATION
)
findNavController().popBackStack(R.id.homeFragment, false)
}
private fun getListOfSessions(private: Boolean): List<Session> {
return requireContext().components.core.sessionManager.sessionsOfType(private = private)
.toList()
}
companion object {

View File

@ -49,6 +49,12 @@
<action android:id="@+id/action_global_accountSettingsFragment" app:destination="@id/accountSettingsFragment" />
<action android:id="@+id/action_global_trackingProtectionPanelDialogFragment" app:destination="@id/trackingProtectionPanelDialogFragment" />
<action android:id="@+id/action_global_quickSettingsSheetDialogFragment" app:destination="@id/quickSettingsSheetDialogFragment"/>
<action android:id="@+id/action_global_tabTrayDialogFragment" app:destination="@id/tabTrayDialogFragment"/>
<dialog
android:id="@+id/tabTrayDialogFragment"
android:name="org.mozilla.fenix.tabtray.TabTrayDialogFragment"
tools:layout="@layout/fragment_tab_tray_dialog"/>
<fragment
android:id="@+id/homeFragment"
@ -59,9 +65,6 @@
app:destination="@id/browserFragment"
app:exitAnim="@anim/zoom_in_fade"
app:popEnterAnim="@anim/zoom_out_fade" />
<action
android:id="@+id/action_homeFragment_to_createCollectionFragment"
app:destination="@id/collectionCreationFragment" />
</fragment>
<fragment
@ -164,9 +167,6 @@
<action
android:id="@+id/action_browserFragment_to_tabsTrayFragment"
app:destination="@+id/tabTrayFragment" />
<action
android:id="@+id/action_browserFragment_to_createCollectionFragment"
app:destination="@id/collectionCreationFragment" />
</fragment>
<fragment
@ -592,10 +592,6 @@
android:name="selectedTabCollectionId"
android:defaultValue="-1L"
app:argType="long" />
<argument
android:name="previousFragmentId"
app:argType="reference"
app:nullable="false" />
<argument
android:name="saveCollectionStep"
app:argType="org.mozilla.fenix.collections.SaveCollectionStep"

View File

@ -64,8 +64,6 @@ class CollectionCreationFragmentTest {
val fragment = createAddedTestFragment {
CollectionCreationFragment().apply {
arguments = CollectionCreationFragmentArgs(
// Fragment crashes if navArgs is null
previousFragmentId = 0,
saveCollectionStep = SaveCollectionStep.SelectTabs
).toBundle()
}

View File

@ -37,7 +37,6 @@ class DefaultCollectionCreationControllerTest {
fun before() {
MockKAnnotations.init(this)
every { state.previousFragmentId } returns 0
every { store.state } returns state
every { state.tabCollections } returns emptyList()
every { state.tabs } returns emptyList()

View File

@ -522,7 +522,6 @@ class DefaultBrowserToolbarControllerTest {
verify {
val directions =
BrowserFragmentDirections.actionGlobalCollectionCreationFragment(
previousFragmentId = R.id.browserFragment,
saveCollectionStep = SaveCollectionStep.SelectCollection,
tabIds = arrayOf(currentSession.id),
selectedTabIds = arrayOf(currentSession.id)
@ -551,7 +550,6 @@ class DefaultBrowserToolbarControllerTest {
verify {
val directions =
BrowserFragmentDirections.actionGlobalCollectionCreationFragment(
previousFragmentId = R.id.browserFragment,
saveCollectionStep = SaveCollectionStep.NameCollection,
tabIds = arrayOf(currentSession.id),
selectedTabIds = arrayOf(currentSession.id)