Bug 1856986 - Translations UI Integration Preference Logic - Page Settings

fenix/125.0
iorgamgabriel 3 months ago committed by mergify[bot]
parent fcba28732a
commit 04d03862d2

@ -17,9 +17,6 @@ import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
@ -52,37 +49,15 @@ fun TranslationOptionsDialog(
) {
TranslationOptionsDialogHeader(onBackClicked)
val translationOptionsListState = remember {
translationOptionsList.toMutableStateList()
}
EnabledTranslationOptionsItems(
translationOptionsListState,
)
LazyColumn {
items(translationOptionsListState) { item: TranslationSwitchItem ->
items(translationOptionsList) { item: TranslationSwitchItem ->
val translationSwitchItem = TranslationSwitchItem(
type = item.type,
textLabel = item.textLabel,
description = if (item.isChecked) item.description else null,
importance = item.importance,
isChecked = item.isChecked,
isEnabled = item.isEnabled,
hasDivider = item.hasDivider,
onStateChange = { checked ->
// If the item has the same importance, only one switch should be enabled.
val iterator = translationOptionsListState.iterator()
iterator.forEach {
if (it != item && it.importance == item.importance && it.isChecked) {
it.isChecked = false
}
}
val index = translationOptionsListState.indexOf(item)
translationOptionsListState[index] = translationOptionsListState[index].copy(
isChecked = checked,
)
onStateChange = { translationPageSettingsOption, checked ->
item.onStateChange.invoke(translationPageSettingsOption, checked)
},
)
TranslationOptions(
@ -115,46 +90,33 @@ fun TranslationOptionsDialog(
}
}
/**
* If the item with the highest importance is checked, all other items should be disabled.
* If all items are unchecked, all of them are enabled.
* If the item with the highest importance is unchecked and a item with importance 1 is checked ,
* the item with importance 0 is disabled.
* If the item with importance 0 is checked all the items are enabled.
*/
@Composable
private fun EnabledTranslationOptionsItems(
translationOptionsListState: SnapshotStateList<TranslationSwitchItem>,
) {
val itemCheckedWithHighestImportance =
translationOptionsListState.sortedByDescending { listItem -> listItem.importance }
.firstOrNull { it.isChecked }
if (itemCheckedWithHighestImportance == null || itemCheckedWithHighestImportance.importance == 0) {
translationOptionsListState.forEach {
it.isEnabled = true
}
} else {
translationOptionsListState.forEach {
it.isEnabled = it.importance >= itemCheckedWithHighestImportance.importance
}
}
}
@Composable
private fun TranslationOptions(
translationSwitchItem: TranslationSwitchItem,
) {
SwitchWithLabel(
label = translationSwitchItem.textLabel,
description = translationSwitchItem.description,
description = if (translationSwitchItem.isChecked) {
translationSwitchItem.type.descriptionId?.let {
stringResource(
id = it,
)
}
} else {
null
},
enabled = translationSwitchItem.isEnabled,
checked = translationSwitchItem.isChecked,
onCheckedChange = translationSwitchItem.onStateChange,
onCheckedChange = { checked ->
translationSwitchItem.onStateChange.invoke(
translationSwitchItem.type,
checked,
)
},
modifier = Modifier.padding(start = 72.dp, end = 16.dp),
)
if (translationSwitchItem.hasDivider) {
if (translationSwitchItem.type.hasDivider) {
Divider(Modifier.padding(top = 4.dp, bottom = 4.dp))
}
}
@ -201,52 +163,44 @@ fun getTranslationOptionsList(): List<TranslationSwitchItem> {
return mutableListOf<TranslationSwitchItem>().apply {
add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.AlwaysOfferPopup(),
textLabel = stringResource(R.string.translation_option_bottom_sheet_always_translate),
isChecked = false,
hasDivider = true,
isEnabled = true,
onStateChange = { },
onStateChange = { _, _ -> },
),
)
add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.AlwaysTranslateLanguage(),
textLabel = stringResource(
id = R.string.translation_option_bottom_sheet_always_translate_in_language,
formatArgs = arrayOf(Locale("es").displayName),
),
description = stringResource(id = R.string.translation_option_bottom_sheet_switch_description),
importance = 1,
isChecked = false,
isEnabled = true,
hasDivider = false,
onStateChange = {},
onStateChange = { _, _ -> },
),
)
add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.NeverTranslateLanguage(),
textLabel = stringResource(
id = R.string.translation_option_bottom_sheet_never_translate_in_language,
formatArgs = arrayOf(Locale("es").displayName),
),
description = stringResource(id = R.string.translation_option_bottom_sheet_switch_description),
importance = 1,
isChecked = true,
isEnabled = true,
hasDivider = true,
onStateChange = {},
onStateChange = { _, _ -> },
),
)
add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.NeverTranslateSite(),
textLabel = stringResource(R.string.translation_option_bottom_sheet_never_translate_site),
description = stringResource(
id = R.string.translation_option_bottom_sheet_switch_never_translate_site_description,
),
importance = 2,
isChecked = true,
isEnabled = true,
hasDivider = true,
onStateChange = {},
onStateChange = { _, _ -> },
),
)
}

@ -49,13 +49,18 @@ fun TranslationSettings(
items(translationSwitchList) { item: TranslationSwitchItem ->
SwitchWithLabel(
checked = item.isChecked,
onCheckedChange = item.onStateChange,
onCheckedChange = { checked ->
item.onStateChange.invoke(
item.type,
checked,
)
},
label = item.textLabel,
modifier = Modifier
.padding(start = 72.dp, end = 16.dp),
)
if (item.hasDivider) {
if (item.type.hasDivider) {
Divider(Modifier.padding(top = 8.dp, bottom = 8.dp))
}
}
@ -119,20 +124,24 @@ internal fun getTranslationSettingsSwitchList(): List<TranslationSwitchItem> {
return mutableListOf<TranslationSwitchItem>().apply {
add(
TranslationSwitchItem(
type = TranslationSettingsScreenOption.OfferToTranslate(
hasDivider = false,
),
textLabel = stringResource(R.string.translation_settings_offer_to_translate),
isChecked = true,
hasDivider = false,
isEnabled = true,
onStateChange = {},
onStateChange = { _, _ -> },
),
)
add(
TranslationSwitchItem(
type = TranslationSettingsScreenOption.AlwaysDownloadInSavingMode(
hasDivider = true,
),
textLabel = stringResource(R.string.translation_settings_always_download),
isChecked = false,
hasDivider = true,
isEnabled = true,
onStateChange = {},
onStateChange = { _, _ -> },
),
)
}

@ -4,24 +4,92 @@
package org.mozilla.fenix.translations
import org.mozilla.fenix.R
/**
* TranslationSwitchItem that will appear on Translation screens.
*
* @property type [TranslationSettingsOption] type depending on the screen.
* In [TranslationOptionsDialog] is TranslationPageSettingsOption and in [TranslationSettings] is
* [TranslationSettingsScreenOption].
* @property textLabel The text that will appear on the switch item.
* @property description An optional description text below the label.
* @property importance Based on this, the translation switch item is enabled or disabled.
* @property isChecked Whether the switch is checked or not.
* @property isEnabled Whether the switch is enabled or not.
* @property hasDivider Whether a divider should appear under the switch item.
* @property onStateChange Invoked when the switch item is clicked,
* the new checked state is passed into the callback.
*/
data class TranslationSwitchItem(
val type: TranslationSettingsOption,
val textLabel: String,
var description: String? = null,
val importance: Int = 0,
var isChecked: Boolean,
var isEnabled: Boolean = true,
val hasDivider: Boolean,
val onStateChange: (Boolean) -> Unit,
val onStateChange: (TranslationSettingsOption, Boolean) -> Unit,
)
/**
* Translation settings that is related to the web-page. It will appear in [TranslationsOptionsDialog].
*/
sealed class TranslationPageSettingsOption(
override val descriptionId: Int? = null,
override val hasDivider: Boolean,
) : TranslationSettingsOption(hasDivider = hasDivider) {
/**
* The system should offer a translation on a page.
*/
data class AlwaysOfferPopup(
override val hasDivider: Boolean = true,
) : TranslationPageSettingsOption(hasDivider = hasDivider)
/**
* The page's always translate language setting.
*/
data class AlwaysTranslateLanguage(
override val hasDivider: Boolean = false,
override val descriptionId: Int = R.string.translation_option_bottom_sheet_switch_description,
) : TranslationPageSettingsOption(hasDivider = hasDivider)
/**
* The page's never translate language setting.
*/
data class NeverTranslateLanguage(
override val hasDivider: Boolean = true,
override val descriptionId: Int = R.string.translation_option_bottom_sheet_switch_description,
) : TranslationPageSettingsOption(hasDivider = hasDivider)
/**
* The page's never translate site setting.
*/
data class NeverTranslateSite(
override val hasDivider: Boolean = true,
override val descriptionId:
Int = R.string.translation_option_bottom_sheet_switch_never_translate_site_description,
) : TranslationPageSettingsOption(hasDivider = hasDivider)
}
/**
* @property hasDivider Organizes translation settings toggle layouts.
* Whether a divider should appear under the switch item.
* @property descriptionId An optional description text id below the label.
*
*/
sealed class TranslationSettingsOption(
open val hasDivider: Boolean,
open val descriptionId: Int? = null,
)
/**
* Translation settings that is related to the web-page.It will appear in [TranslationSettings].
*/
sealed class TranslationSettingsScreenOption {
/**
* The page's offer to translate when possible.
*/
data class OfferToTranslate(override val hasDivider: Boolean = true) :
TranslationSettingsOption(hasDivider = hasDivider)
/**
* The page's always download languages in data saving mode.
*/
data class AlwaysDownloadInSavingMode(override val hasDivider: Boolean = true) :
TranslationSettingsOption(hasDivider = hasDivider)
}

@ -4,6 +4,7 @@
package org.mozilla.fenix.translations
import android.content.Context
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.core.FastOutSlowInEasing
@ -22,11 +23,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import mozilla.components.concept.engine.translate.Language
import mozilla.components.concept.engine.translate.TranslationPageSettings
import org.mozilla.fenix.R
import org.mozilla.fenix.theme.FirefoxTheme
private const val BOTTOM_SHEET_HANDLE_WIDTH_PERCENT = 0.1f
@ -154,13 +158,99 @@ internal fun TranslationsDialog(
@Composable
internal fun TranslationsOptionsDialog(
context: Context,
translationPageSettings: TranslationPageSettings? = null,
initialFrom: Language? = null,
onStateChange: (TranslationSettingsOption, Boolean) -> Unit,
onBackClicked: () -> Unit,
onTranslationSettingsClicked: () -> Unit,
aboutTranslationClicked: () -> Unit,
) {
TranslationOptionsDialog(
translationOptionsList = getTranslationOptionsList(),
translationOptionsList = getTranslationSwitchItemList(
translationPageSettings = translationPageSettings,
initialFrom = initialFrom,
context = context,
onStateChange = onStateChange,
),
onBackClicked = onBackClicked,
onTranslationSettingsClicked = onTranslationSettingsClicked,
aboutTranslationClicked = {},
aboutTranslationClicked = aboutTranslationClicked,
)
}
@Composable
private fun getTranslationSwitchItemList(
translationPageSettings: TranslationPageSettings? = null,
initialFrom: Language? = null,
context: Context,
onStateChange: (TranslationSettingsOption, Boolean) -> Unit,
): List<TranslationSwitchItem> {
val translationSwitchItemList = mutableListOf<TranslationSwitchItem>()
translationPageSettings?.let {
val alwaysOfferPopup = translationPageSettings.alwaysOfferPopup
val alwaysTranslateLanguage = translationPageSettings.alwaysTranslateLanguage
val neverTranslateLanguage = translationPageSettings.neverTranslateLanguage
val neverTranslateSite = translationPageSettings.neverTranslateSite
alwaysOfferPopup?.let {
translationSwitchItemList.add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.AlwaysOfferPopup(),
textLabel = context.getString(R.string.translation_option_bottom_sheet_always_translate),
isChecked = it,
isEnabled = !(
alwaysTranslateLanguage == true ||
neverTranslateLanguage == true ||
neverTranslateSite == true
),
onStateChange = onStateChange,
),
)
}
alwaysTranslateLanguage?.let {
translationSwitchItemList.add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.AlwaysTranslateLanguage(),
textLabel = context.getString(
R.string.translation_option_bottom_sheet_always_translate_in_language,
initialFrom?.localizedDisplayName,
),
isChecked = it,
isEnabled = neverTranslateSite != true,
onStateChange = onStateChange,
),
)
}
neverTranslateLanguage?.let {
translationSwitchItemList.add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.NeverTranslateLanguage(),
textLabel = context.getString(
R.string.translation_option_bottom_sheet_never_translate_in_language,
initialFrom?.localizedDisplayName,
),
isChecked = it,
isEnabled = neverTranslateSite != true,
onStateChange = onStateChange,
),
)
}
translationPageSettings.neverTranslateSite?.let {
translationSwitchItemList.add(
TranslationSwitchItem(
type = TranslationPageSettingsOption.NeverTranslateSite(),
textLabel = stringResource(R.string.translation_option_bottom_sheet_never_translate_site),
isChecked = it,
isEnabled = true,
onStateChange = onStateChange,
),
)
}
}
return translationSwitchItemList
}

@ -28,7 +28,9 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.translate.Language
import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.lib.state.ext.observeAsComposableState
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
@ -114,6 +116,14 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
val density = LocalDensity.current
val translationsDialogState =
translationsDialogStore.observeAsComposableState { it }.value
val learnMoreUrl = SupportUtils.getSumoURLForTopic(
requireContext(),
SupportUtils.SumoTopic.TRANSLATIONS,
)
TranslationDialogBottomSheet {
TranslationsAnimation(
translationsVisibility = translationsVisibility,
@ -131,13 +141,9 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
}
},
) {
val learnMoreUrl = SupportUtils.getSumoURLForTopic(
requireContext(),
SupportUtils.SumoTopic.TRANSLATIONS,
)
TranslationsDialogContent(
learnMoreUrl = learnMoreUrl,
translationsDialogState = translationsDialogState,
) {
translationsVisibility = false
}
@ -159,19 +165,12 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
}
},
) {
TranslationsOptionsDialog(
onBackClicked = {
translationsVisibility = true
},
onTranslationSettingsClicked = {
findNavController().navigate(
TranslationsDialogFragmentDirections
.actionTranslationsDialogFragmentToTranslationSettingsFragment(
sessionId = args.sessionId,
),
)
},
)
TranslationsOptionsDialogContent(
learnMoreUrl = learnMoreUrl,
initialFrom = translationsDialogState?.initialFrom,
) {
translationsVisibility = true
}
}
}
}
@ -213,12 +212,13 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
)
}
@Composable
@Suppress("LongMethod")
private fun TranslationsDialogContent(learnMoreUrl: String, onSettingClicked: () -> Unit) {
val translationsDialogState =
translationsDialogStore.observeAsComposableState { it }.value
@Composable
private fun TranslationsDialogContent(
learnMoreUrl: String,
translationsDialogState: TranslationsDialogState? = null,
onSettingClicked: () -> Unit,
) {
translationsDialogState?.let { state ->
isTranslationInProgress = state.isTranslationInProgress
@ -312,6 +312,44 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() {
}
}
@Composable
private fun TranslationsOptionsDialogContent(
learnMoreUrl: String,
initialFrom: Language? = null,
onBackClicked: () -> Unit,
) {
val pageSettingsState =
browserStore.observeAsComposableState { state ->
state.findTab(args.sessionId)?.translationsState?.pageSettings
}.value
TranslationsOptionsDialog(
context = requireContext(),
translationPageSettings = pageSettingsState,
initialFrom = initialFrom,
onStateChange = { type, checked ->
translationsDialogStore.dispatch(
TranslationsDialogAction.UpdatePageSettingsValue(
type as TranslationPageSettingsOption,
checked,
),
)
},
onBackClicked = onBackClicked,
onTranslationSettingsClicked = {
findNavController().navigate(
TranslationsDialogFragmentDirections
.actionTranslationsDialogFragmentToTranslationSettingsFragment(
sessionId = args.sessionId,
),
)
},
aboutTranslationClicked = {
openBrowserAndLoad(learnMoreUrl)
},
)
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
if (isTranslationInProgress == true) {

@ -7,6 +7,7 @@ package org.mozilla.fenix.translations
import mozilla.components.browser.state.action.TranslationsAction
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.translate.TranslationOperation
import mozilla.components.concept.engine.translate.TranslationPageSettingOperation
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
@ -18,6 +19,7 @@ class TranslationsDialogMiddleware(
private val sessionId: String,
) : Middleware<TranslationsDialogState, TranslationsDialogAction> {
@Suppress("LongMethod")
override fun invoke(
context: MiddlewareContext<TranslationsDialogState, TranslationsDialogAction>,
next: (TranslationsDialogAction) -> Unit,
@ -43,6 +45,15 @@ class TranslationsDialogMiddleware(
)
}
is TranslationsDialogAction.FetchPageSettings -> {
browserStore.dispatch(
TranslationsAction.OperationRequestedAction(
tabId = sessionId,
operation = TranslationOperation.FETCH_PAGE_SETTINGS,
),
)
}
is TranslationsDialogAction.TranslateAction -> {
context.state.initialFrom?.code?.let { fromLanguage ->
context.state.initialTo?.code?.let { toLanguage ->
@ -64,6 +75,42 @@ class TranslationsDialogMiddleware(
browserStore.dispatch(TranslationsAction.TranslateRestoreAction(sessionId))
}
is TranslationsDialogAction.UpdatePageSettingsValue -> {
when (action.type) {
is TranslationPageSettingsOption.AlwaysOfferPopup -> browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = sessionId,
operation = TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP,
setting = action.checkValue,
),
)
is TranslationPageSettingsOption.AlwaysTranslateLanguage -> browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = sessionId,
operation = TranslationPageSettingOperation.UPDATE_ALWAYS_TRANSLATE_LANGUAGE,
setting = action.checkValue,
),
)
is TranslationPageSettingsOption.NeverTranslateLanguage -> browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = sessionId,
operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_LANGUAGE,
setting = action.checkValue,
),
)
is TranslationPageSettingsOption.NeverTranslateSite -> browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = sessionId,
operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_SITE,
setting = action.checkValue,
),
)
}
}
else -> {
next(action)
}

@ -3,11 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.translations
import mozilla.components.browser.state.action.TranslationsAction
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.translate.Language
import mozilla.components.concept.engine.translate.TranslationDownloadSize
import mozilla.components.concept.engine.translate.TranslationError
import mozilla.components.concept.engine.translate.TranslationOperation
import mozilla.components.lib.state.Action
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.State
@ -26,7 +26,11 @@ class TranslationsDialogStore(
initialState,
TranslationsDialogReducer::reduce,
middlewares,
)
) {
init {
dispatch(TranslationsDialogAction.FetchPageSettings)
}
}
/**
* The current state of the Translations bottom sheet dialog.
@ -65,23 +69,32 @@ sealed class TranslationsDialogAction : Action {
/**
* Invoked when the [TranslationsDialogStore] is added to the fragment.
*/
object InitTranslationsDialog : TranslationsDialogAction()
data object InitTranslationsDialog : TranslationsDialogAction()
/**
* When FetchSupportedLanguages is dispatched, an [TranslationOperation.FETCH_SUPPORTED_LANGUAGES]
* will be dispatched to the [BrowserStore].
* This action should be used when an [UpdateTranslationError] appears and the user presses the "Try Again" button
* from the [TranslationsDialogBottomSheet].
*/
data object FetchSupportedLanguages : TranslationsDialogAction()
/**
* When FetchSupportedLanguages is dispatched, an [TranslationsAction.OperationRequestedAction]
* will be dispatched to the [BrowserStore]
* When FetchPageSettings is dispatched, an [TranslationOperation.FETCH_PAGE_SETTINGS]
* will be dispatched to the [BrowserStore].
* This action should be used when [TranslationsDialogStore] gets initialised.
*/
object FetchSupportedLanguages : TranslationsDialogAction()
data object FetchPageSettings : TranslationsDialogAction()
/**
* Invoked when the user wants to translate a website.
*/
object TranslateAction : TranslationsDialogAction()
data object TranslateAction : TranslationsDialogAction()
/**
* Invoked when the user wants to restore the website to its original pre-translated content.
*/
object RestoreTranslation : TranslationsDialogAction()
data object RestoreTranslation : TranslationsDialogAction()
/**
* Invoked when a translation error occurs during the translation process.
@ -144,6 +157,14 @@ sealed class TranslationsDialogAction : Action {
*/
data class UpdateTranslatedPageTitle(val title: String) : TranslationsDialogAction()
/**
* Invoked when the user wants to update a PageSettings value.
*/
data class UpdatePageSettingsValue(
val type: TranslationPageSettingsOption,
val checkValue: Boolean,
) : TranslationsDialogAction()
/**
* Updates the translation download file size.
*/
@ -164,17 +185,17 @@ sealed class PositiveButtonType {
/**
* The translating indicator will appear.
*/
object InProgress : PositiveButtonType()
data object InProgress : PositiveButtonType()
/**
* The button is in a disabled state.
*/
object Disabled : PositiveButtonType()
data object Disabled : PositiveButtonType()
/**
* The button is in a enabled state.
*/
object Enabled : PositiveButtonType()
data object Enabled : PositiveButtonType()
}
/**
@ -184,12 +205,12 @@ sealed class DismissDialogState {
/**
* The dialog should be dismissed.
*/
object Dismiss : DismissDialogState()
data object Dismiss : DismissDialogState()
/**
* This is the step when translation is in progress and the dialog is waiting to be dismissed.
*/
object WaitingToBeDismissed : DismissDialogState()
data object WaitingToBeDismissed : DismissDialogState()
}
internal object TranslationsDialogReducer {
@ -298,6 +319,9 @@ internal object TranslationsDialogReducer {
}
is TranslationsDialogAction.TranslateAction,
is TranslationsDialogAction.UpdatePageSettingsValue,
TranslationsDialogAction.TranslateAction,
TranslationsDialogAction.FetchPageSettings,
TranslationsDialogAction.FetchSupportedLanguages,
TranslationsDialogAction.RestoreTranslation,
is TranslationsDialogAction.FetchDownloadFileSizeAction,

@ -11,6 +11,7 @@ import mozilla.components.browser.state.action.TranslationsAction
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.translate.Language
import mozilla.components.concept.engine.translate.TranslationOperation
import mozilla.components.concept.engine.translate.TranslationPageSettingOperation
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.libstate.ext.waitUntilIdle
import org.junit.Test
@ -31,7 +32,8 @@ class TranslationsDialogMiddlewareTest {
initialState = TranslationsDialogState(),
middlewares = listOf(translationsDialogMiddleware),
)
translationStore.dispatch(TranslationsDialogAction.FetchSupportedLanguages).joinBlocking()
translationStore.dispatch(TranslationsDialogAction.FetchSupportedLanguages)
.joinBlocking()
translationStore.waitUntilIdle()
@ -129,4 +131,153 @@ class TranslationsDialogMiddlewareTest {
)
}
}
@Test
fun `GIVEN translationState WHEN FetchPageSettings from TranslationDialogStore is called THEN call FETCH_PAGE_SETTINGS from BrowserStore`() =
runTest {
val browserStore = mockk<BrowserStore>(relaxed = true)
val translationsDialogMiddleware =
TranslationsDialogMiddleware(browserStore = browserStore, sessionId = "tab1")
val translationStore = TranslationsDialogStore(
initialState = TranslationsDialogState(),
middlewares = listOf(translationsDialogMiddleware),
)
translationStore.dispatch(TranslationsDialogAction.FetchPageSettings).joinBlocking()
translationStore.waitUntilIdle()
verify {
browserStore.dispatch(
TranslationsAction.OperationRequestedAction(
tabId = "tab1",
operation = TranslationOperation.FETCH_PAGE_SETTINGS,
),
)
}
}
@Test
fun `GIVEN translationState WHEN UpdatePageSettingsValue with action type AlwaysOfferPopup from TranslationDialogStore is called THEN call UpdatePageSettingAction from BrowserStore`() =
runTest {
val browserStore = mockk<BrowserStore>(relaxed = true)
val translationsDialogMiddleware =
TranslationsDialogMiddleware(browserStore = browserStore, sessionId = "tab1")
val translationStore = TranslationsDialogStore(
initialState = TranslationsDialogState(),
middlewares = listOf(translationsDialogMiddleware),
)
translationStore.dispatch(
TranslationsDialogAction.UpdatePageSettingsValue(
type = TranslationPageSettingsOption.AlwaysOfferPopup(),
checkValue = true,
),
).joinBlocking()
translationStore.waitUntilIdle()
verify {
browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = "tab1",
operation = TranslationPageSettingOperation.UPDATE_ALWAYS_OFFER_POPUP,
setting = true,
),
)
}
}
@Test
fun `GIVEN translationState WHEN UpdatePageSettingsValue with action type AlwaysTranslateLanguage from TranslationDialogStore is called THEN call UpdatePageSettingAction from BrowserStore`() =
runTest {
val browserStore = mockk<BrowserStore>(relaxed = true)
val translationsDialogMiddleware =
TranslationsDialogMiddleware(browserStore = browserStore, sessionId = "tab1")
val translationStore = TranslationsDialogStore(
initialState = TranslationsDialogState(),
middlewares = listOf(translationsDialogMiddleware),
)
translationStore.dispatch(
TranslationsDialogAction.UpdatePageSettingsValue(
type = TranslationPageSettingsOption.AlwaysTranslateLanguage(),
checkValue = false,
),
).joinBlocking()
translationStore.waitUntilIdle()
verify {
browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = "tab1",
operation = TranslationPageSettingOperation.UPDATE_ALWAYS_TRANSLATE_LANGUAGE,
setting = false,
),
)
}
}
@Test
fun `GIVEN translationState WHEN UpdatePageSettingsValue with action type NeverTranslateLanguage from TranslationDialogStore is called THEN call UpdatePageSettingAction from BrowserStore`() =
runTest {
val browserStore = mockk<BrowserStore>(relaxed = true)
val translationsDialogMiddleware =
TranslationsDialogMiddleware(browserStore = browserStore, sessionId = "tab1")
val translationStore = TranslationsDialogStore(
initialState = TranslationsDialogState(),
middlewares = listOf(translationsDialogMiddleware),
)
translationStore.dispatch(
TranslationsDialogAction.UpdatePageSettingsValue(
type = TranslationPageSettingsOption.NeverTranslateLanguage(),
checkValue = true,
),
).joinBlocking()
translationStore.waitUntilIdle()
verify {
browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = "tab1",
operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_LANGUAGE,
setting = true,
),
)
}
}
@Test
fun `GIVEN translationState WHEN UpdatePageSettingsValue with action type NeverTranslateSite from TranslationDialogStore is called THEN call UpdatePageSettingAction from BrowserStore`() =
runTest {
val browserStore = mockk<BrowserStore>(relaxed = true)
val translationsDialogMiddleware =
TranslationsDialogMiddleware(browserStore = browserStore, sessionId = "tab1")
val translationStore = TranslationsDialogStore(
initialState = TranslationsDialogState(),
middlewares = listOf(translationsDialogMiddleware),
)
translationStore.dispatch(
TranslationsDialogAction.UpdatePageSettingsValue(
type = TranslationPageSettingsOption.NeverTranslateSite(),
checkValue = false,
),
).joinBlocking()
translationStore.waitUntilIdle()
verify {
browserStore.dispatch(
TranslationsAction.UpdatePageSettingAction(
tabId = "tab1",
operation = TranslationPageSettingOperation.UPDATE_NEVER_TRANSLATE_SITE,
setting = false,
),
)
}
}
}

Loading…
Cancel
Save