desktop: changing language without reload (#2896)
* desktop: changing language without reload * comment --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
parent
7a41957d7b
commit
1bc880877d
@ -214,7 +214,7 @@ object AppearanceScope {
|
|||||||
"ru" to "Русский",
|
"ru" to "Русский",
|
||||||
"zh-CN" to "简体中文"
|
"zh-CN" to "简体中文"
|
||||||
)
|
)
|
||||||
val values by remember { mutableStateOf(supportedLanguages.map { it.key to it.value }) }
|
val values by remember(ChatController.appPrefs.appLanguage.state.value) { mutableStateOf(supportedLanguages.map { it.key to it.value }) }
|
||||||
ExposedDropDownSettingRow(
|
ExposedDropDownSettingRow(
|
||||||
generalGetString(MR.strings.settings_section_title_language).lowercase().replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.US) else it.toString() },
|
generalGetString(MR.strings.settings_section_title_language).lowercase().replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.US) else it.toString() },
|
||||||
values,
|
values,
|
||||||
@ -228,7 +228,9 @@ object AppearanceScope {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun ThemeSelector(state: State<String>, onSelected: (String) -> Unit) {
|
private fun ThemeSelector(state: State<String>, onSelected: (String) -> Unit) {
|
||||||
val darkTheme = chat.simplex.common.ui.theme.isSystemInDarkTheme()
|
val darkTheme = chat.simplex.common.ui.theme.isSystemInDarkTheme()
|
||||||
val values by remember { mutableStateOf(ThemeManager.allThemes(darkTheme).map { it.second.name to it.third }) }
|
val values by remember(ChatController.appPrefs.appLanguage.state.value) {
|
||||||
|
mutableStateOf(ThemeManager.allThemes(darkTheme).map { it.second.name to it.third })
|
||||||
|
}
|
||||||
ExposedDropDownSettingRow(
|
ExposedDropDownSettingRow(
|
||||||
generalGetString(MR.strings.theme),
|
generalGetString(MR.strings.theme),
|
||||||
values,
|
values,
|
||||||
|
@ -14,6 +14,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.window.*
|
import androidx.compose.ui.window.*
|
||||||
import chat.simplex.common.model.ChatController
|
import chat.simplex.common.model.ChatController
|
||||||
import chat.simplex.common.model.ChatModel
|
import chat.simplex.common.model.ChatModel
|
||||||
|
import chat.simplex.common.platform.defaultLocale
|
||||||
import chat.simplex.common.platform.desktopPlatform
|
import chat.simplex.common.platform.desktopPlatform
|
||||||
import chat.simplex.common.ui.theme.SimpleXTheme
|
import chat.simplex.common.ui.theme.SimpleXTheme
|
||||||
import chat.simplex.common.views.helpers.FileDialogChooser
|
import chat.simplex.common.views.helpers.FileDialogChooser
|
||||||
@ -34,84 +35,87 @@ fun showApp() = application {
|
|||||||
val width = if (desktopPlatform.isLinux()) 1376.dp else 1366.dp
|
val width = if (desktopPlatform.isLinux()) 1376.dp else 1366.dp
|
||||||
val windowState = rememberWindowState(placement = WindowPlacement.Floating, width = width, height = 768.dp)
|
val windowState = rememberWindowState(placement = WindowPlacement.Floating, width = width, height = 768.dp)
|
||||||
simplexWindowState.windowState = windowState
|
simplexWindowState.windowState = windowState
|
||||||
Window(state = windowState, onCloseRequest = ::exitApplication, onKeyEvent = {
|
// Reload all strings in all @Composable's after language change at runtime
|
||||||
if (it.key == Key.Escape && it.type == KeyEventType.KeyUp) {
|
if (remember { ChatController.appPrefs.appLanguage.state }.value != "") {
|
||||||
simplexWindowState.backstack.lastOrNull()?.invoke() != null
|
Window(state = windowState, onCloseRequest = ::exitApplication, onKeyEvent = {
|
||||||
} else {
|
if (it.key == Key.Escape && it.type == KeyEventType.KeyUp) {
|
||||||
false
|
simplexWindowState.backstack.lastOrNull()?.invoke() != null
|
||||||
}
|
} else {
|
||||||
}, title = "SimpleX") {
|
false
|
||||||
SimpleXTheme {
|
|
||||||
AppScreen()
|
|
||||||
if (simplexWindowState.openDialog.isAwaiting) {
|
|
||||||
FileDialogChooser(
|
|
||||||
title = "SimpleX",
|
|
||||||
isLoad = true,
|
|
||||||
params = simplexWindowState.openDialog.params,
|
|
||||||
onResult = {
|
|
||||||
simplexWindowState.openDialog.onResult(it.firstOrNull())
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
}, title = "SimpleX") {
|
||||||
if (simplexWindowState.openMultipleDialog.isAwaiting) {
|
SimpleXTheme {
|
||||||
FileDialogChooser(
|
AppScreen()
|
||||||
title = "SimpleX",
|
if (simplexWindowState.openDialog.isAwaiting) {
|
||||||
isLoad = true,
|
FileDialogChooser(
|
||||||
params = simplexWindowState.openMultipleDialog.params,
|
title = "SimpleX",
|
||||||
onResult = {
|
isLoad = true,
|
||||||
simplexWindowState.openMultipleDialog.onResult(it)
|
params = simplexWindowState.openDialog.params,
|
||||||
}
|
onResult = {
|
||||||
)
|
simplexWindowState.openDialog.onResult(it.firstOrNull())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (simplexWindowState.saveDialog.isAwaiting) {
|
|
||||||
FileDialogChooser(
|
|
||||||
title = "SimpleX",
|
|
||||||
isLoad = false,
|
|
||||||
params = simplexWindowState.saveDialog.params,
|
|
||||||
onResult = { simplexWindowState.saveDialog.onResult(it.firstOrNull()) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val toasts = remember { simplexWindowState.toasts }
|
|
||||||
val toast = toasts.firstOrNull()
|
|
||||||
if (toast != null) {
|
|
||||||
Box(Modifier.fillMaxSize().padding(bottom = 20.dp), contentAlignment = Alignment.BottomCenter) {
|
|
||||||
Text(
|
|
||||||
toast.first,
|
|
||||||
Modifier.background(MaterialTheme.colors.primary, RoundedCornerShape(100)).padding(vertical = 5.dp, horizontal = 10.dp),
|
|
||||||
color = MaterialTheme.colors.onPrimary,
|
|
||||||
style = MaterialTheme.typography.body1
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Shows toast in insertion order with preferred delay per toast. New one will be shown once previous one expires
|
|
||||||
LaunchedEffect(toast, toasts.size) {
|
if (simplexWindowState.openMultipleDialog.isAwaiting) {
|
||||||
delay(toast.second)
|
FileDialogChooser(
|
||||||
simplexWindowState.toasts.removeFirst()
|
title = "SimpleX",
|
||||||
}
|
isLoad = true,
|
||||||
}
|
params = simplexWindowState.openMultipleDialog.params,
|
||||||
}
|
onResult = {
|
||||||
var windowFocused by remember { simplexWindowState.windowFocused }
|
simplexWindowState.openMultipleDialog.onResult(it)
|
||||||
LaunchedEffect(windowFocused) {
|
}
|
||||||
val delay = ChatController.appPrefs.laLockDelay.get()
|
)
|
||||||
if (!windowFocused && ChatModel.performLA.value && delay > 0) {
|
|
||||||
delay(delay * 1000L)
|
|
||||||
// Trigger auth state check when delay ends (and if it ends)
|
|
||||||
AppLock.recheckAuthState()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
window.addWindowFocusListener(object : WindowFocusListener {
|
|
||||||
override fun windowGainedFocus(p0: WindowEvent?) {
|
|
||||||
windowFocused = true
|
|
||||||
AppLock.recheckAuthState()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun windowLostFocus(p0: WindowEvent?) {
|
if (simplexWindowState.saveDialog.isAwaiting) {
|
||||||
windowFocused = false
|
FileDialogChooser(
|
||||||
AppLock.appWasHidden()
|
title = "SimpleX",
|
||||||
|
isLoad = false,
|
||||||
|
params = simplexWindowState.saveDialog.params,
|
||||||
|
onResult = { simplexWindowState.saveDialog.onResult(it.firstOrNull()) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
val toasts = remember { simplexWindowState.toasts }
|
||||||
|
val toast = toasts.firstOrNull()
|
||||||
|
if (toast != null) {
|
||||||
|
Box(Modifier.fillMaxSize().padding(bottom = 20.dp), contentAlignment = Alignment.BottomCenter) {
|
||||||
|
Text(
|
||||||
|
toast.first,
|
||||||
|
Modifier.background(MaterialTheme.colors.primary, RoundedCornerShape(100)).padding(vertical = 5.dp, horizontal = 10.dp),
|
||||||
|
color = MaterialTheme.colors.onPrimary,
|
||||||
|
style = MaterialTheme.typography.body1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// Shows toast in insertion order with preferred delay per toast. New one will be shown once previous one expires
|
||||||
|
LaunchedEffect(toast, toasts.size) {
|
||||||
|
delay(toast.second)
|
||||||
|
simplexWindowState.toasts.removeFirst()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var windowFocused by remember { simplexWindowState.windowFocused }
|
||||||
|
LaunchedEffect(windowFocused) {
|
||||||
|
val delay = ChatController.appPrefs.laLockDelay.get()
|
||||||
|
if (!windowFocused && ChatModel.performLA.value && delay > 0) {
|
||||||
|
delay(delay * 1000L)
|
||||||
|
// Trigger auth state check when delay ends (and if it ends)
|
||||||
|
AppLock.recheckAuthState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
window.addWindowFocusListener(object: WindowFocusListener {
|
||||||
|
override fun windowGainedFocus(p0: WindowEvent?) {
|
||||||
|
windowFocused = true
|
||||||
|
AppLock.recheckAuthState()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun windowLostFocus(p0: WindowEvent?) {
|
||||||
|
windowFocused = false
|
||||||
|
AppLock.appWasHidden()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user