commit d5eeb5b97c6405fe13181186285467a5c8003f10
parent b0974e7912c1292375895388fe0e5deada976a12
Author: Cathy Lu <calu@mozilla.com>
Date: Wed, 7 Jan 2026 16:38:59 +0000
Bug 2002280 - Add settings icon to the downloads screen r=android-reviewers,android-l10n-reviewers,007,flod
Differential Revision: https://phabricator.services.mozilla.com/D277923
Diffstat:
5 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/DownloadFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/DownloadFragment.kt
@@ -26,6 +26,8 @@ import org.mozilla.fenix.downloads.listscreen.store.DownloadUIState
import org.mozilla.fenix.downloads.listscreen.store.DownloadUIStore
import org.mozilla.fenix.downloads.listscreen.store.FileItem
import org.mozilla.fenix.ext.components
+import org.mozilla.fenix.ext.hideToolbar
+import org.mozilla.fenix.settings.settingssearch.PreferenceFileInformation
import org.mozilla.fenix.theme.FirefoxTheme
/**
@@ -68,6 +70,11 @@ class DownloadFragment : Fragment() {
this@DownloadFragment.findNavController().popBackStack()
}
},
+ onSettingsClick = {
+ findNavController().navigate(
+ resId = PreferenceFileInformation.DownloadsSettingsPreferences.fragmentId,
+ )
+ },
)
}
}
@@ -96,4 +103,9 @@ class DownloadFragment : Fragment() {
}
}
}
+
+ override fun onResume() {
+ super.onResume()
+ hideToolbar()
+ }
}
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/DownloadsScreen.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/DownloadsScreen.kt
@@ -84,6 +84,7 @@ import mozilla.components.ui.icons.R as iconsR
* @param downloadsStore The [DownloadUIStore] used to manage and access the state of download items.
* @param onItemClick Callback invoked when a download item is clicked.
* @param onNavigationIconClick Callback for the back button click in the toolbar.
+ * @param onSettingsClick Callback for the settings button click in the toolbar.
*/
@Suppress("LongMethod", "CognitiveComplexMethod")
@Composable
@@ -91,6 +92,7 @@ fun DownloadsScreen(
downloadsStore: DownloadUIStore,
onItemClick: (FileItem) -> Unit,
onNavigationIconClick: () -> Unit,
+ onSettingsClick: () -> Unit,
) {
val uiState by downloadsStore.observeAsState(initialValue = downloadsStore.state) { it }
val snackbarHostState = remember { SnackbarHostState() }
@@ -171,6 +173,15 @@ fun DownloadsScreen(
}
},
actions = {
+ if (uiState.isSettingsIconVisible) {
+ IconButton(onClick = onSettingsClick) {
+ Icon(
+ painter = painterResource(iconsR.drawable.mozac_ic_settings_24),
+ contentDescription = stringResource(R.string.download_navigate_settings_description),
+ tint = toolbarConfig.iconColor,
+ )
+ }
+ }
if (uiState.mode is Mode.Editing) {
ToolbarEditActions(
downloadsStore = downloadsStore,
@@ -748,6 +759,13 @@ private fun DownloadsScreenPreviews(
)
}
},
+ onSettingsClick = {
+ scope.launch {
+ snackbarHostState.displaySnackbar(
+ message = "Navigation to Downloads Settings clicked",
+ )
+ }
+ },
)
SnackbarHost(
hostState = snackbarHostState,
@@ -784,6 +802,13 @@ private fun DownloadsScreenPrivatePreviews(
)
}
},
+ onSettingsClick = {
+ scope.launch {
+ snackbarHostState.displaySnackbar(
+ message = "Navigation to Downloads Settings clicked",
+ )
+ }
+ },
)
SnackbarHost(
hostState = snackbarHostState,
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/store/DownloadUIState.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/store/DownloadUIState.kt
@@ -109,6 +109,9 @@ data class DownloadUIState(
val isSearchIconVisible: Boolean
get() = itemsNotPendingDeletion.isNotEmpty() && !isSearchFieldVisible && mode is Mode.Normal
+ val isSettingsIconVisible: Boolean
+ get() = !isSearchFieldVisible && mode is Mode.Normal
+
val isBackHandlerEnabled: Boolean
get() = isSearchFieldRequested || mode is Mode.Editing
diff --git a/mobile/android/fenix/app/src/main/res/values/strings.xml b/mobile/android/fenix/app/src/main/res/values/strings.xml
@@ -1566,6 +1566,8 @@
<string name="download_delete_item">Delete</string>
<!-- Content description for the toolbar "Navigate back" button -->
<string name="download_navigate_back_description">Navigate back</string>
+ <!-- Content description for the toolbar "Navigate to Downloads Settings" button -->
+ <string name="download_navigate_settings_description">Navigate to Downloads Settings</string>
<!-- Content description for the toolbar back button while searching the downloads -->
<string name="download_close_search_description">Back and close search</string>
<!-- Content description for the search bar clear text button on the downloads screen -->
diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/downloads/listscreen/store/DownloadUIStateTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/downloads/listscreen/store/DownloadUIStateTest.kt
@@ -1330,4 +1330,61 @@ class DownloadUIStateTest {
assertEquals(false, downloadUIState.isBackHandlerEnabled)
}
+
+ @Test
+ fun `WHEN search field is visible THEN settings icon is not visible`() {
+ val downloadUIState = DownloadUIState(
+ items = emptyList(),
+ mode = DownloadUIState.Mode.Normal,
+ pendingDeletionIds = emptySet(),
+ isSearchFieldRequested = true,
+ searchQuery = "",
+ )
+
+ assertEquals(false, downloadUIState.isSettingsIconVisible)
+ }
+
+ @Test
+ fun `WHEN state is in edit mode THEN settings icon is not visible`() {
+ val fileItem1 = fileItem(
+ id = "1",
+ fileName = "somefile",
+ displayedShortUrl = "firefox.com",
+ timeCategory = TimeCategory.LAST_30_DAYS,
+ )
+
+ val downloadUIState = DownloadUIState(
+ items = listOf(fileItem1),
+ mode = DownloadUIState.Mode.Editing(
+ selectedItems = setOf(fileItem1),
+ ),
+ pendingDeletionIds = emptySet(),
+ isSearchFieldRequested = false,
+ searchQuery = "",
+ )
+
+ assertEquals(false, downloadUIState.isSettingsIconVisible)
+ }
+
+ @Test
+ fun `WHEN search field is not visible and state is in normal mode THEN settings icon is visible`() {
+ val fileItems = listOf(
+ fileItem(
+ id = "1",
+ fileName = "somefile",
+ displayedShortUrl = "firefox.com",
+ timeCategory = TimeCategory.LAST_30_DAYS,
+ ),
+ )
+
+ val downloadUIState = DownloadUIState(
+ items = fileItems,
+ mode = DownloadUIState.Mode.Normal,
+ pendingDeletionIds = emptySet(),
+ isSearchFieldRequested = false,
+ searchQuery = "",
+ )
+
+ assertEquals(true, downloadUIState.isSettingsIconVisible)
+ }
}