tor-browser

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

commit 74df37aab1b4b3f08d8d0b2a50e9ca53ce78bbe3
parent 0890d8f6b71be93cfaf876beaa32e1772cf322ef
Author: rmalicdem <rmalicdem@mozilla.com>
Date:   Tue, 11 Nov 2025 21:29:22 +0000

Bug 1969108 - Add 'Translate' to expanded shortcuts r=android-reviewers,Roger

Differential Revision: https://phabricator.services.mozilla.com/D271325

Diffstat:
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt | 1+
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/toolbar/BrowserToolbarMiddleware.kt | 29+++++++++++++++++++++++++++--
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/ToolbarShortcut.kt | 2+-
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt | 40++++++++++++++++++++++++++++++++++++++++
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/toolbar/BrowserToolbarMiddlewareTest.kt | 45+++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt @@ -1027,6 +1027,7 @@ class BrowserToolbarMiddleware( .collect { updateEndBrowserActions(context) updateEndPageActions(context) + updateNavigationActions(context) } } } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/toolbar/BrowserToolbarMiddleware.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/home/toolbar/BrowserToolbarMiddleware.kt @@ -79,6 +79,7 @@ import org.mozilla.fenix.home.toolbar.TabCounterInteractions.TabCounterClicked import org.mozilla.fenix.home.toolbar.TabCounterInteractions.TabCounterLongClicked import org.mozilla.fenix.search.BrowserToolbarSearchMiddleware import org.mozilla.fenix.search.ext.searchEngineShortcuts +import org.mozilla.fenix.settings.ShortcutType import org.mozilla.fenix.tabstray.Page import mozilla.components.lib.state.Action as MVIAction import mozilla.components.ui.icons.R as iconsR @@ -364,12 +365,17 @@ class BrowserToolbarMiddleware( */ private fun buildNavigationActions(): List<Action> { val environment = environment ?: return emptyList() + val settings = environment.context.settings() val isWideWindow = environment.fragment.isWideWindow() val isTallWindow = environment.fragment.isTallWindow() - val shouldUseExpandedToolbar = environment.context.settings().shouldUseExpandedToolbar + val shouldUseExpandedToolbar = settings.shouldUseExpandedToolbar + val useCustomPrimary = settings.shouldShowToolbarCustomization && shouldUseExpandedToolbar + val primarySlotAction = mapShortcutToAction( + settings.toolbarExpandedShortcutKey, + ).takeIf { useCustomPrimary } ?: HomeToolbarAction.FakeBookmark return listOf( - HomeToolbarActionConfig(HomeToolbarAction.FakeBookmark) { + HomeToolbarActionConfig(primarySlotAction) { shouldUseExpandedToolbar && isTallWindow && !isWideWindow }, HomeToolbarActionConfig(HomeToolbarAction.FakeShare) { @@ -476,6 +482,7 @@ class BrowserToolbarMiddleware( FakeBookmark, FakeShare, NewTab, + FakeTranslate, } private data class HomeToolbarActionConfig( @@ -546,5 +553,23 @@ class BrowserToolbarMiddleware( AddNewTab(source) }, ) + + HomeToolbarAction.FakeTranslate -> ActionButtonRes( + drawableResId = iconsR.drawable.mozac_ic_translate_24, + contentDescription = R.string.browser_toolbar_translate, + state = ActionButton.State.DISABLED, + onClick = FakeClicked, + ) + } + + companion object { + @VisibleForTesting + internal fun mapShortcutToAction( + key: String, + ): HomeToolbarAction = when (key) { + ShortcutType.BOOKMARK -> HomeToolbarAction.FakeBookmark + ShortcutType.TRANSLATE -> HomeToolbarAction.FakeTranslate + else -> HomeToolbarAction.FakeBookmark + } } } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/ToolbarShortcut.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/ToolbarShortcut.kt @@ -57,7 +57,7 @@ internal val allShortcutOptions: List<ShortcutOption> = listOf( ShortcutType.TRANSLATE, iconsR.drawable.mozac_ic_translate_24, R.string.toolbar_customize_shortcut_translate, - setOf(ShortcutAvailability.SIMPLE), + setOf(ShortcutAvailability.SIMPLE, ShortcutAvailability.EXPANDED), ), ShortcutOption( ShortcutType.HOMEPAGE, diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt @@ -3099,6 +3099,46 @@ class BrowserToolbarMiddlewareTest { } @Test + fun `GIVEN expanded toolbar use translate shortcut AND current page is not translated WHEN initializing toolbar THEN show Translate in navigation actions`() = runTest { + every { settings.shouldShowToolbarCustomization } returns true + every { settings.shouldUseExpandedToolbar } returns true + every { settings.toolbarExpandedShortcutKey } returns ShortcutType.TRANSLATE + + val pageTranslationStatus: PageTranslationStatus = mockk(relaxed = true) { + every { isTranslationPossible } returns true + every { isTranslated } returns false + every { isTranslateProcessing } returns false + } + + every { browserScreenState.pageTranslationStatus } returns pageTranslationStatus + + val toolbarStore = buildStore() + + val translateButton = toolbarStore.state.displayState.navigationActions.first() as ActionButtonRes + assertEquals(expectedTranslateButton(), translateButton) + } + + @Test + fun `GIVEN expanded toolbar use translate shortcut AND current page is translated WHEN initializing toolbar THEN show ACTIVE Translate in navigation actions`() = runTest { + every { settings.shouldShowToolbarCustomization } returns true + every { settings.shouldUseExpandedToolbar } returns true + every { settings.toolbarExpandedShortcutKey } returns ShortcutType.TRANSLATE + + val pageTranslationStatus: PageTranslationStatus = mockk(relaxed = true) { + every { isTranslationPossible } returns true + every { isTranslated } returns true + every { isTranslateProcessing } returns false + } + + every { browserScreenState.pageTranslationStatus } returns pageTranslationStatus + + val toolbarStore = buildStore() + + val translateButton = toolbarStore.state.displayState.navigationActions.first() as ActionButtonRes + assertEquals(expectedTranslateButton(isActive = true), translateButton) + } + + @Test fun `mapShortcutToAction maps keys to actions and falls back to default set`() { assertEquals( ToolbarAction.NewTab, diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/toolbar/BrowserToolbarMiddlewareTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/toolbar/BrowserToolbarMiddlewareTest.kt @@ -86,6 +86,7 @@ import org.mozilla.fenix.components.usecases.FenixBrowserUseCases import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixGleanTestRule +import org.mozilla.fenix.home.toolbar.BrowserToolbarMiddleware.Companion.mapShortcutToAction import org.mozilla.fenix.home.toolbar.BrowserToolbarMiddleware.HomeToolbarAction import org.mozilla.fenix.home.toolbar.DisplayActions.FakeClicked import org.mozilla.fenix.home.toolbar.DisplayActions.MenuClicked @@ -96,6 +97,7 @@ import org.mozilla.fenix.home.toolbar.TabCounterInteractions.TabCounterClicked import org.mozilla.fenix.home.toolbar.TabCounterInteractions.TabCounterLongClicked import org.mozilla.fenix.search.fixtures.assertSearchSelectorEquals import org.mozilla.fenix.search.fixtures.buildExpectedSearchSelector +import org.mozilla.fenix.settings.ShortcutType import org.mozilla.fenix.tabstray.Page import org.robolectric.Shadows.shadowOf import mozilla.components.ui.icons.R as iconsR @@ -123,6 +125,8 @@ class BrowserToolbarMiddlewareTest { every { testContext.settings().shouldUseExpandedToolbar } returns false every { testContext.settings().isTabStripEnabled } returns false every { testContext.settings().tabManagerEnhancementsEnabled } returns false + every { testContext.settings().shouldShowToolbarCustomization } returns false + every { testContext.settings().toolbarExpandedShortcutKey } returns ShortcutType.BOOKMARK fragment = spyk(Fragment()).apply { every { context } returns mockContext @@ -812,6 +816,40 @@ class BrowserToolbarMiddlewareTest { assertEquals(expectedMenuButton(false), menuButton) } + @Test + fun `GIVEN expanded toolbar use translate shortcut WHEN initializing toolbar THEN show DISABLED Translate in navigation actions`() = runTest { + every { testContext.settings().shouldShowToolbarCustomization } returns true + every { testContext.settings().shouldUseExpandedToolbar } returns true + every { testContext.settings().toolbarExpandedShortcutKey } returns ShortcutType.TRANSLATE + + val middleware = BrowserToolbarMiddleware( + appStore, + browserStore, + mockk(), + mockk(), + ) + val toolbarStore = buildStore(middleware) + + val translateButton = toolbarStore.state.displayState.navigationActions.first() as ActionButtonRes + assertEquals(expectedTranslateButton, translateButton) + } + + @Test + fun `mapShortcutToAction maps keys to actions and falls back to fake bookmark action`() { + assertEquals( + HomeToolbarAction.FakeBookmark, + mapShortcutToAction(key = ShortcutType.BOOKMARK), + ) + assertEquals( + HomeToolbarAction.FakeTranslate, + mapShortcutToAction(key = ShortcutType.TRANSLATE), + ) + assertEquals( + HomeToolbarAction.FakeBookmark, + mapShortcutToAction(key = "does_not_exist"), + ) + } + private fun buildStore( middleware: BrowserToolbarMiddleware, context: Context = testContext, @@ -938,6 +976,13 @@ class BrowserToolbarMiddlewareTest { onClick = AddNewTab(source), ) + private val expectedTranslateButton = ActionButtonRes( + drawableResId = iconsR.drawable.mozac_ic_translate_24, + contentDescription = R.string.browser_toolbar_translate, + state = ActionButton.State.DISABLED, + onClick = FakeClicked, + ) + private class FakeLifecycleOwner(initialState: Lifecycle.State) : LifecycleOwner { override val lifecycle: Lifecycle = LifecycleRegistry(this).apply { currentState = initialState