commit 1f77a5472a4fd3fde7f3937791b5ef5983a52c19
parent a49e6d408f5a4e7f09d27065648ee468f1dbf835
Author: Mugurell <Mugurell@users.noreply.github.com>
Date: Mon, 17 Nov 2025 17:52:51 +0000
Bug 1996643 - part 6 - Migrate from the LifecycleHolder idiom within composable bookmarks r=android-reviewers,matt-tighe,nalexander
Differential Revision: https://phabricator.services.mozilla.com/D272159
Diffstat:
3 files changed, 43 insertions(+), 85 deletions(-)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/bookmarks/BookmarkFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/bookmarks/BookmarkFragment.kt
@@ -30,7 +30,6 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.components.QrScanFenixFeature
-import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.VoiceSearchFeature
import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
import org.mozilla.fenix.components.appstate.AppAction
@@ -85,22 +84,20 @@ class BookmarkFragment : Fragment() {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
val toolbarStore = buildToolbarStore()
val searchStore = buildSearchStore(toolbarStore)
- val buildStore = { navController: NavHostController ->
- val store = StoreProvider.get(this@BookmarkFragment) {
- val lifecycleHolder = LifecycleHolder(
- context = requireContext(),
- navController = this@BookmarkFragment.findNavController(),
- composeNavController = navController,
- homeActivity = (requireActivity() as HomeActivity),
- )
+ val buildStore = { composeNavController: NavHostController ->
+ val homeActivity = (requireActivity() as HomeActivity)
+ val navController = this@BookmarkFragment.findNavController()
- BookmarksStore(
- initialState = BookmarksState.default.copy(
- sortOrder = BookmarksListSortOrder.fromString(
- value = requireContext().settings().bookmarkListSortOrder,
- default = BookmarksListSortOrder.Alphabetical(true),
- ),
+ val store by fragmentStore(
+ BookmarksState.default.copy(
+ sortOrder = BookmarksListSortOrder.fromString(
+ value = requireContext().settings().bookmarkListSortOrder,
+ default = BookmarksListSortOrder.Alphabetical(true),
),
+ ),
+ ) {
+ BookmarksStore(
+ initialState = it,
middleware = listOf(
// NB: Order matters — this middleware must be first to intercept actions
// related to private mode and trigger verification before any other middleware runs.
@@ -123,24 +120,24 @@ class BookmarkFragment : Fragment() {
false
} else {
val wasPreviousAppDestinationHome =
- lifecycleHolder.navController
+ navController
.previousBackStackEntry?.destination?.id == R.id.homeFragment
val browsingMode =
- lifecycleHolder.homeActivity.browsingModeManager.mode
+ homeActivity.browsingModeManager.mode
wasPreviousAppDestinationHome || browsingMode.isPrivate
},
- getNavController = { lifecycleHolder.composeNavController },
- exitBookmarks = { lifecycleHolder.navController.popBackStack() },
+ getNavController = { composeNavController },
+ exitBookmarks = { navController.popBackStack() },
navigateToBrowser = {
- lifecycleHolder.navController.navigate(R.id.browserFragment)
+ navController.navigate(R.id.browserFragment)
},
navigateToSearch = {
- lifecycleHolder.navController.navigate(
+ navController.navigate(
NavGraphDirections.actionGlobalSearchDialog(sessionId = null),
)
},
navigateToSignIntoSync = {
- lifecycleHolder.navController
+ navController
.navigate(
BookmarkFragmentDirections.actionGlobalTurnOnSync(
entrypoint = FenixFxAEntryPoint.BookmarkView,
@@ -148,7 +145,7 @@ class BookmarkFragment : Fragment() {
)
},
shareBookmarks = { bookmarks ->
- lifecycleHolder.navController.nav(
+ navController.nav(
R.id.bookmarkFragment,
BookmarkFragmentDirections.actionGlobalShareFragment(
data = bookmarks.asShareDataArray(),
@@ -158,16 +155,16 @@ class BookmarkFragment : Fragment() {
showTabsTray = ::showTabTray,
resolveFolderTitle = {
friendlyRootTitle(
- context = lifecycleHolder.context,
+ context = context,
node = it,
- rootTitles = composeRootTitles(lifecycleHolder.context),
+ rootTitles = composeRootTitles(context),
) ?: ""
},
getBrowsingMode = {
- lifecycleHolder.homeActivity.browsingModeManager.mode
+ homeActivity.browsingModeManager.mode
},
saveBookmarkSortOrder = {
- lifecycleHolder.context.settings().bookmarkListSortOrder =
+ context.settings().bookmarkListSortOrder =
it.asString
},
lastSavedFolderCache = context.settings().lastSavedFolderCache,
@@ -178,17 +175,9 @@ class BookmarkFragment : Fragment() {
},
),
),
- lifecycleHolder = lifecycleHolder,
)
}
- store.lifecycleHolder?.apply {
- this.navController = this@BookmarkFragment.findNavController()
- this.composeNavController = navController
- this.homeActivity = (requireActivity() as HomeActivity)
- this.context = requireContext()
- }
-
store
}
setContent {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/bookmarks/BookmarksStore.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/bookmarks/BookmarksStore.kt
@@ -4,28 +4,9 @@
package org.mozilla.fenix.bookmarks
-import android.content.Context
-import androidx.navigation.NavController
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.Reducer
import mozilla.components.lib.state.Store
-import org.mozilla.fenix.HomeActivity
-
-/**
- * A helper class to be able to change the reference to objects that get replaced when the activity
- * gets recreated.
- *
- * @property context the android [Context]
- * @property navController A [NavController] for interacting with the androidx navigation library.
- * @property composeNavController A [NavController] for navigating within the local Composable nav graph.
- * @property homeActivity so that we can reference openToBrowserAndLoad and browsingMode :(
- */
-internal class LifecycleHolder(
- var context: Context,
- var navController: NavController,
- var composeNavController: NavController,
- var homeActivity: HomeActivity,
-)
/**
* A Store for handling [BookmarksState] and dispatching [BookmarksAction].
@@ -33,14 +14,12 @@ internal class LifecycleHolder(
* @param initialState The initial state for the Store.
* @param reducer Reducer to handle state updates based on dispatched actions.
* @param middleware Middleware to handle side-effects in response to dispatched actions.
- * @property lifecycleHolder a hack to box the references to objects that get recreated with the activity.
* @param bookmarkToLoad The guid of a bookmark to load when landing on the edit screen.
*/
internal class BookmarksStore(
initialState: BookmarksState = BookmarksState.default,
reducer: Reducer<BookmarksState, BookmarksAction> = ::bookmarksReducer,
middleware: List<Middleware<BookmarksState, BookmarksAction>> = listOf(),
- val lifecycleHolder: LifecycleHolder? = null,
bookmarkToLoad: String? = null,
) : Store<BookmarksState, BookmarksAction>(
initialState = initialState,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/bookmarks/EditBookmarkFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/bookmarks/EditBookmarkFragment.kt
@@ -18,9 +18,9 @@ import androidx.navigation.fragment.navArgs
import mozilla.components.compose.browser.toolbar.store.BrowserToolbarState
import mozilla.components.compose.browser.toolbar.store.BrowserToolbarStore
import mozilla.components.compose.browser.toolbar.store.Mode
+import mozilla.components.lib.state.helpers.StoreProvider.Companion.fragmentStore
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
-import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.ext.bookmarkStorage
@@ -47,22 +47,19 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
): View? {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
- val buildStore = { navController: NavHostController ->
+ val buildStore = { composeNavController: NavHostController ->
+ val homeActivity = (requireActivity() as HomeActivity)
+ val navController = findNavController()
val isSignedIntoSync = requireComponents
.backgroundServices.accountManager.authenticatedAccount() != null
- val store = StoreProvider.get(this@EditBookmarkFragment) {
- val lifecycleHolder = LifecycleHolder(
- context = requireContext(),
- navController = this@EditBookmarkFragment.findNavController(),
- composeNavController = navController,
- homeActivity = (requireActivity() as HomeActivity),
- )
-
+ val store by fragmentStore(
+ BookmarksState.default.copy(
+ isSignedIntoSync = isSignedIntoSync,
+ ),
+ ) {
BookmarksStore(
- initialState = BookmarksState.default.copy(
- isSignedIntoSync = isSignedIntoSync,
- ),
+ initialState = it,
middleware = listOf(
BookmarksMiddleware(
bookmarksStorage = requireContext().bookmarkStorage,
@@ -73,16 +70,16 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
openBookmarksInNewTab = if (settings().enableHomepageAsNewTab) {
false
} else {
- lifecycleHolder.homeActivity.browsingModeManager.mode.isPrivate
+ homeActivity.browsingModeManager.mode.isPrivate
},
- getNavController = { lifecycleHolder.composeNavController },
- exitBookmarks = { lifecycleHolder.navController.popBackStack() },
+ getNavController = { composeNavController },
+ exitBookmarks = { navController.popBackStack() },
navigateToBrowser = {
- lifecycleHolder.navController.navigate(R.id.browserFragment)
+ navController.navigate(R.id.browserFragment)
},
navigateToSearch = { },
navigateToSignIntoSync = {
- lifecycleHolder.navController
+ navController
.navigate(
BookmarkFragmentDirections.actionGlobalTurnOnSync(
entrypoint = FenixFxAEntryPoint.BookmarkView,
@@ -90,7 +87,7 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
)
},
shareBookmarks = { bookmarks ->
- lifecycleHolder.navController.nav(
+ navController.nav(
R.id.bookmarkFragment,
BookmarkFragmentDirections.actionGlobalShareFragment(
data = bookmarks.asShareDataArray(),
@@ -100,13 +97,13 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
showTabsTray = { },
resolveFolderTitle = {
friendlyRootTitle(
- context = lifecycleHolder.context,
+ context = context,
node = it,
- rootTitles = composeRootTitles(lifecycleHolder.context),
+ rootTitles = composeRootTitles(context),
) ?: ""
},
getBrowsingMode = {
- lifecycleHolder.homeActivity.browsingModeManager.mode
+ homeActivity.browsingModeManager.mode
},
lastSavedFolderCache = context.settings().lastSavedFolderCache,
saveBookmarkSortOrder = {},
@@ -117,16 +114,9 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
},
),
),
- lifecycleHolder = lifecycleHolder,
bookmarkToLoad = args.guidToEdit,
)
}
- store.lifecycleHolder?.apply {
- this.navController = this@EditBookmarkFragment.findNavController()
- this.composeNavController = navController
- this.homeActivity = (requireActivity() as HomeActivity)
- this.context = requireContext()
- }
store
}