From e3528d3ffea451d05561f196b4baded27e4255b4 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:36:57 +0700 Subject: [PATCH] android: re-apply custom language when webview appears (#5022) * android: re-apply custom language when webview appears There is a bug on Android related to including WebView. App language changes to system language regardless of what was set before in context's configuration. Re-set needed to be done twice: after creating of WebView and after removing it from a view * add link to bug --------- Co-authored-by: Evgeny --- .../chat/simplex/app/views/call/CallActivity.kt | 10 +++++++--- .../kotlin/chat/simplex/common/helpers/Locale.kt | 3 +-- .../simplex/common/views/call/CallView.android.kt | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallActivity.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallActivity.kt index e7503733ac..a5a1726757 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallActivity.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/views/call/CallActivity.kt @@ -24,8 +24,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.platform.* import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -37,7 +36,9 @@ import chat.simplex.app.R import chat.simplex.app.TAG import chat.simplex.app.model.NtfManager import chat.simplex.app.model.NtfManager.AcceptCallAction +import chat.simplex.common.helpers.applyAppLocale import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* import chat.simplex.common.platform.chatModel import chat.simplex.common.ui.theme.* @@ -49,6 +50,7 @@ import dev.icerock.moko.resources.compose.stringResource import kotlinx.coroutines.launch import kotlinx.datetime.Clock import java.lang.ref.WeakReference +import java.util.* import chat.simplex.common.platform.chatModel as m class CallActivity: ComponentActivity(), ServiceConnection { @@ -56,6 +58,7 @@ class CallActivity: ComponentActivity(), ServiceConnection { var boundService: CallService? = null override fun onCreate(savedInstanceState: Bundle?) { + applyAppLocale(appPrefs.appLanguage) super.onCreate(savedInstanceState) callActivity = WeakReference(this) when (intent?.action) { @@ -80,6 +83,7 @@ class CallActivity: ComponentActivity(), ServiceConnection { override fun onDestroy() { super.onDestroy() + (mainActivity.get() ?: this).applyAppLocale(appPrefs.appLanguage) if (isOnLockScreenNow()) { lockAfterIncomingCall() } @@ -233,7 +237,7 @@ fun CallActivityView() { } SimpleXTheme { var prevCall by remember { mutableStateOf(call) } - KeyChangeEffect(m.activeCall.value) { + KeyChangeEffect(m.activeCall.value, remember { appPrefs.appLanguage.state }.value) { if (m.activeCall.value != null) { prevCall = m.activeCall.value activity.boundService?.updateNotification() diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/Locale.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/Locale.kt index b9d7d27ba9..c289715886 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/Locale.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/Locale.kt @@ -31,8 +31,7 @@ private fun Activity.applyLocale(locale: Locale) { Locale.setDefault(locale) val appConf = Configuration(androidAppContext.resources.configuration).apply { setLocale(locale) } val activityConf = Configuration(resources.configuration).apply { setLocale(locale) } - @Suppress("DEPRECATION") - androidAppContext.resources.updateConfiguration(appConf, resources.displayMetrics) + androidAppContext = androidAppContext.createConfigurationContext(appConf) @Suppress("DEPRECATION") resources.updateConfiguration(activityConf, resources.displayMetrics) } diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt index 37bf8d1330..b35f47e36e 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt @@ -41,8 +41,10 @@ import androidx.core.content.ContextCompat import androidx.lifecycle.* import androidx.webkit.WebViewAssetLoader import androidx.webkit.WebViewClientCompat +import chat.simplex.common.helpers.applyAppLocale import chat.simplex.common.helpers.showAllowPermissionInSettingsAlert import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* @@ -702,9 +704,10 @@ fun WebRTCView(callCommand: SnapshotStateList, onResponse: (WVAPIM Box(Modifier.fillMaxSize()) { AndroidView( - factory = { AndroidViewContext -> + factory = { try { (staticWebView ?: WebView(androidAppContext)).apply { + reapplyLocale() layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, @@ -775,6 +778,16 @@ private fun updateActiveCall(initial: Call, transform: (Call) -> Call) { } } +/* +* Creating WebView automatically drops user's custom app locale to default system locale. +* Preventing it by re-applying custom locale +* https://issuetracker.google.com/issues/109833940 +* */ +private fun reapplyLocale() { + mainActivity.get()?.applyAppLocale(appPrefs.appLanguage) + callActivity.get()?.applyAppLocale(appPrefs.appLanguage) +} + private class LocalContentWebViewClient(val webView: MutableState, private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() { override fun shouldInterceptRequest( view: WebView,