diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt index b1ce003812..fc17c49c7e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt @@ -431,8 +431,10 @@ fun DesktopScreen(userPickerState: MutableStateFlow) { .fillMaxSize() .padding(start = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier) .clickable(interactionSource = remember { MutableInteractionSource() }, indication = null, onClick = { - ModalManager.start.closeModals() - userPickerState.value = AnimatedViewState.HIDING + if (chatModel.centerPanelBackgroundClickHandler == null || chatModel.centerPanelBackgroundClickHandler?.invoke() == false) { + ModalManager.start.closeModals() + userPickerState.value = AnimatedViewState.HIDING + } }) ) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index e501ed5a91..ca03d0ce72 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -167,6 +167,9 @@ object ChatModel { val processedCriticalError: ProcessedErrors = ProcessedErrors(60_000) val processedInternalError: ProcessedErrors = ProcessedErrors(20_000) + // return true if you handled the click + var centerPanelBackgroundClickHandler: (() -> Boolean)? = null + fun getUser(userId: Long): User? = if (currentUser.value?.userId == userId) { currentUser.value } else { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt index ef5b82a5d9..6b1dcec5d8 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt @@ -39,10 +39,10 @@ import chat.simplex.common.views.onboarding.OnboardingActionButton import chat.simplex.common.views.onboarding.ReadableText import chat.simplex.common.views.usersettings.* import chat.simplex.res.MR -import kotlinx.coroutines.launch +import kotlinx.coroutines.* @Composable -fun ModalData.NetworkAndServersView(close: () -> Unit) { +fun ModalData.NetworkAndServersView(closeNetworkAndServers: () -> Unit) { val currentRemoteHost by remember { chatModel.currentRemoteHost } // It's not a state, just a one-time value. Shouldn't be used in any state-related situations val netCfg = remember { chatModel.controller.getNetCfg() } @@ -50,21 +50,36 @@ fun ModalData.NetworkAndServersView(close: () -> Unit) { val currUserServers = remember { stateGetOrPut("currUserServers") { emptyList() } } val userServers = remember { stateGetOrPut("userServers") { emptyList() } } val serverErrors = remember { stateGetOrPut("serverErrors") { emptyList() } } - val scope = rememberCoroutineScope() val proxyPort = remember { derivedStateOf { appPrefs.networkProxy.state.value.port } } - ModalView( - close = { - if (!serversCanBeSaved(currUserServers.value, userServers.value, serverErrors.value)) { + fun onClose(close: () -> Unit): Boolean = if (!serversCanBeSaved(currUserServers.value, userServers.value, serverErrors.value)) { + chatModel.centerPanelBackgroundClickHandler = null + close() + false + } else { + showUnsavedChangesAlert( + { + CoroutineScope(Dispatchers.Default).launch { + saveServers(currentRemoteHost?.remoteHostId, currUserServers, userServers) + chatModel.centerPanelBackgroundClickHandler = null + close() + } + }, + { + chatModel.centerPanelBackgroundClickHandler = null close() - } else { - showUnsavedChangesAlert( - { scope.launch { saveServers(currentRemoteHost?.remoteHostId, currUserServers, userServers) }}, - close - ) } + ) + true + } + + LaunchedEffect(Unit) { + // Enables unsaved changes alert on this view and all children views. + chatModel.centerPanelBackgroundClickHandler = { + onClose(close = { ModalManager.start.closeModals() }) } - ) { + } + ModalView(close = { onClose(closeNetworkAndServers) }) { NetworkAndServersLayout( currentRemoteHost = currentRemoteHost, networkUseSocksProxy = networkUseSocksProxy,