Skip to content
This repository has been archived by the owner on Jun 17, 2024. It is now read-only.

Commit

Permalink
Bug 1877203 - Update Page Settings
Browse files Browse the repository at this point in the history
This patch adds the action `UpdatePageSettingsAction` that will take a
given set of page settings, update the state of the browser store, and
dispatch the updated settings to the browser store.
  • Loading branch information
ohall-m committed Feb 7, 2024
1 parent 0945489 commit 481ff15
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,18 @@ sealed class TranslationsAction : BrowserAction() {
override val tabId: String,
val pageSettings: TranslationPageSettings?,
) : TranslationsAction(), ActionWithTab

/**
* Updates the given page settings on the translation engine and syncs the final state on the
* given [tabId]'s store.
*
* @property tabId The ID of the tab the [EngineSession] should be linked to.
* @property pageSettings The new page settings.
*/
data class UpdatePageSettingsAction(
override val tabId: String,
val pageSettings: TranslationPageSettings,
) : TranslationsAction(), ActionWithTab
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ class TranslationsMiddleware(
-> Unit
}
}

is TranslationsAction.UpdatePageSettingsAction -> {
scope.launch {
updateTranslationPageSettings(context, action.tabId, action.pageSettings)
}
}

else -> {
// no-op
}
Expand All @@ -67,7 +74,7 @@ class TranslationsMiddleware(

/**
* Retrieves the list of supported languages using [scope] and dispatches the result to the
* store via [TranslationsAction.TranslateSetLanguagesAction] or else dispatches the failure
* store via [TranslationsAction.SetSupportedLanguagesAction] or else dispatches the failure
* [TranslationsAction.TranslateExceptionAction].
*
* @param context Context to use to dispatch to the store.
Expand Down Expand Up @@ -196,4 +203,164 @@ class TranslationsMiddleware(
)
}
}

/**
* Updates the page settings with the translations engine and syncs the state with the browser
* store.
*
* Will eagerly dispatch a [TranslationsAction.SetPageSettingsAction] with the [newPageSettings]
* and send the new settings to the translations engine.
*
* If a failure occurs updating the translations engine, this will dispatch:
* [TranslationsAction.OperationRequestedAction] of the [TranslationOperation.FETCH_PAGE_SETTINGS]
* variety to fetch the state to ensure the store and translations engine remain in-sync.
*
* @param context Context to use to dispatch to the store.
* @param tabId Tab ID associated with the request.
* @param newPageSettings The page settings to process. If any item is null, then the item
* will not attempt setting.
*/
private suspend fun updateTranslationPageSettings(
context: MiddlewareContext<BrowserState, BrowserAction>,
tabId: String,
newPageSettings: TranslationPageSettings,
){
logger.info("Attempting to update the page preferences with the engine.")

// Eagerly update the browser store, if an error occurs, the state will be re-queried with
// the engine.
TranslationsAction.SetPageSettingsAction(
tabId = tabId,
pageSettings = newPageSettings
)

// Always offer setting
logger.info("Setting the always offer popup preference.")
newPageSettings.alwaysOfferPopup?.let { engine.setTranslationsOfferPopup(it) }

// Page language settings
val pageLanguage = context.store.state.findTab(tabId)
?.translationsState?.translationEngineState?.detectedLanguages?.documentLangTag
val pageLanguageUpdateSuccess = updateLanguageSetting(pageLanguage,
newPageSettings.alwaysTranslateLanguage, newPageSettings.neverTranslateLanguage
)

// Never translate site
val engineSession = context.store.state.findTab(tabId)
?.engineState?.engineSession
val neverTranslateUpdateSuccess = updateNeverTranslateSiteSetting(engineSession,
newPageSettings.neverTranslateSite
)

if(!pageLanguageUpdateSuccess || !neverTranslateUpdateSuccess){
// If something failed to set, then we need to query the engine and have it reset the
// preference state.
context.store.dispatch(
TranslationsAction.OperationRequestedAction(
tabId = tabId,
operation = TranslationOperation.FETCH_PAGE_SETTINGS
)
)
}

}

/**
* Updates the always or never language setting synchronously with the [EngineSession] from the
* engine.
*
* @param languageCode Page language to update the always or never settings for.
* @param alwaysTranslateLanguage The always translate language setting.
* @param neverTranslateLanguage The never translate language setting
*
* @return True if the operation completes or false if an error occurs.
*/
private suspend fun updateLanguageSetting(languageCode: String?,
alwaysTranslateLanguage: Boolean?,
neverTranslateLanguage:Boolean?) : Boolean{
return suspendCoroutine { continuation ->
logger.error("Attempting to update engine language setting.")
if (languageCode == null){
logger.error("Did not receive a language code to use while setting the language preference.")
continuation.resume(false)
return@suspendCoroutine
}

if (alwaysTranslateLanguage == null || neverTranslateLanguage == null){
logger.error("Did not receive a language preference to set.")
continuation.resume(false)
return@suspendCoroutine
}

// These settings need to agree
if(LanguageSetting.checkAlwaysAndNeverAgreement(
alwaysTranslate = alwaysTranslateLanguage,
neverTranslate = neverTranslateLanguage)){
logger.error("Received incompatible settings of always and never language " +
"preferences.")
continuation.resume(false)
return@suspendCoroutine
}

// The always and never settings agree, arbitrarily converting always to the engine format.
val convertedSetting : LanguageSetting? = LanguageSetting.ALWAYS.toLanguageSetting(alwaysTranslateLanguage)
if (convertedSetting == null){
logger.error("Could not convert to a language setting.")
continuation.resume(false)
return@suspendCoroutine
}

engine.setLanguageSetting(
languageCode = languageCode,
languageSetting = convertedSetting ,

onSuccess = {
logger.info("Successfully updated the language preference.")
continuation.resume(true)
},

onError = {
logger.error("Could not update the language preference.", it)
continuation.resume(false)
},
)
}
}


/**
* Updates the never translate site setting synchronously with the [EngineSession]. Will
* return null if an error occurs.
*
* @param engineSession The required engine context on where to perform this operation.
* @return True if the operation completes or false if an error occurs.
*/
private suspend fun updateNeverTranslateSiteSetting(engineSession: EngineSession?, neverTranslateSite: Boolean?): Boolean {
return suspendCoroutine { continuation ->

if (engineSession == null){
logger.error("Did not receive an engine session to set the never translate site preference.")
continuation.resume(false)
return@suspendCoroutine
}

if (neverTranslateSite == null){
logger.error("Did not receive a never translate site preference.")
continuation.resume(false)
return@suspendCoroutine
}

engineSession.setNeverTranslateSiteSetting(
setting = neverTranslateSite,
onResult = {
logger.info("Successfully updated the never translate site preference.")
continuation.resume(true)
},
onException = {
logger.error("Could not update the never translate site preference.", it)
continuation.resume(false)
},
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ enum class LanguageSetting(private val languageSetting: String) {
else ->
throw IllegalArgumentException("The language setting $languageSetting is not mapped.")
}


/**
* Convenience method to confirm an always translate language setting and never translate
* language setting are in agreement and do not contradict each other.
*
* @param alwaysTranslate The boolean of the always translate this language setting.
* @param neverTranslate The boolean of the never translate this language setting.
*/
fun checkAlwaysAndNeverAgreement(alwaysTranslate: Boolean, neverTranslate: Boolean) : Boolean {
return ALWAYS.toLanguageSetting(alwaysTranslate) == NEVER.toLanguageSetting(neverTranslate)
}
}

/**
Expand Down

1 comment on commit 481ff15

@firefoxci-taskcluster
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh! Looks like an error! Details

Failed to fetch task artifact public/github/customCheckRunText.md for GitHub integration.
Make sure the artifact exists on the worker or other location.

Please sign in to comment.