tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/DownloadFragment.kt | 12++++++++++++
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/DownloadsScreen.kt | 25+++++++++++++++++++++++++
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/listscreen/store/DownloadUIState.kt | 3+++
Mmobile/android/fenix/app/src/main/res/values/strings.xml | 2++
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/downloads/listscreen/store/DownloadUIStateTest.kt | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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) + } }