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 6f5044813b..5a3e9db51c 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 @@ -26,7 +26,6 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* -import chat.simplex.common.model.ChatController.acceptConditions import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatController.getUserServers import chat.simplex.common.model.ChatController.setUserServers @@ -39,14 +38,14 @@ import chat.simplex.res.MR import kotlinx.coroutines.launch @Composable -fun NetworkAndServersView(close: () -> Unit) { +fun ModalData.NetworkAndServersView(close: () -> 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() } val networkUseSocksProxy: MutableState = remember { mutableStateOf(netCfg.useSocksProxy) } - val currUserServers = remember { mutableStateOf(emptyList()) } - val userServers = remember { mutableStateOf(emptyList()) } - val serverErrors = remember { mutableStateOf(emptyList()) } + val currUserServers = remember { stateGetOrPut("currUserServers") { emptyList() } } + val userServers = remember { stateGetOrPut("userServers") { emptyList() } } + val serverErrors = remember { stateGetOrPut("serverErrors") { emptyList() } } val scope = rememberCoroutineScope() @@ -146,6 +145,9 @@ fun NetworkAndServersView(close: () -> Unit) { val scope = rememberCoroutineScope() LaunchedEffect(Unit) { + if (currUserServers.value.isNotEmpty() || userServers.value.isNotEmpty()) { + return@LaunchedEffect + } try { val servers = getUserServers(rh = currentRemoteHost?.remoteHostId) if (servers != null) { @@ -230,19 +232,6 @@ fun NetworkAndServersView(close: () -> Unit) { SettingsActionItem(painterResource(MR.images.ic_electrical_services), stringResource(MR.strings.webrtc_ice_servers), { ModalManager.start.showModal { RTCServersView(m) } }) } - -// val footerText = when (val c = operator.conditionsAcceptance) { -// is ConditionsAcceptance.Accepted -> if (c.acceptedAt != null) { -// String.format(generalGetString(MR.strings.operator_conditions_accepted), localTimestamp(c.acceptedAt)) -// } else null -// is ConditionsAcceptance.Required -> if (operator.enabled && c.deadline != null) { -// String.format(generalGetString(MR.strings.operator_conditions_accepted_after), localTimestamp(c.deadline)) -// } else null -// } -// if (footerText != null) { -// SectionTextFooter(footerText) -// } - if (appPlatform.isAndroid) { SectionDividerSpaced() SectionView(generalGetString(MR.strings.settings_section_title_network_connection).uppercase()) { @@ -619,7 +608,19 @@ private fun ServerOperatorRow( serverErrors: MutableState>, rhId: Long? ) { - SectionItemView({ ModalManager.start.showModalCloseable { _ -> OperatorView(currUserServers, userServers, serverErrors, index, rhId) } }) { + SectionItemView( + { + ModalManager.start.showModalCloseable { close -> + OperatorView( + currUserServers, + userServers, + serverErrors, + index, + rhId + ) + } + } + ) { Image( painterResource(MR.images.decentralized), operator.tradeName, @@ -782,7 +783,7 @@ private suspend fun saveServers( currUserServers: MutableState>, userServers: MutableState> ) { - val userServersToSave = currUserServers.value + val userServersToSave = userServers.value try { val set = setUserServers(rhId, userServersToSave) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt index aa019fe3c1..2e45c9d518 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt @@ -79,6 +79,18 @@ fun OperatorViewLayout( } UseOperatorToggle(currUserServers = currUserServers, userServers = userServers, serverErrors = serverErrors, operatorIndex = operatorIndex, rhId = rhId) } + val footerText = when (val c = operator.conditionsAcceptance) { + is ConditionsAcceptance.Accepted -> if (c.acceptedAt != null) { + String.format(generalGetString(MR.strings.operator_conditions_accepted_on), localTimestamp(c.acceptedAt)) + } else null + is ConditionsAcceptance.Required -> if (operator.enabled && c.deadline != null) { + String.format(generalGetString(MR.strings.operator_conditions_accepted_after), localTimestamp(c.deadline)) + } else null + } + if (footerText != null) { + SectionTextFooter(footerText) + } + if (operator.enabled) { if (userServers.value[operatorIndex].smpServers.filter { !it.deleted }.isNotEmpty()) { @@ -116,7 +128,6 @@ private fun UseOperatorToggle( operatorIndex: Int, rhId: Long? ) { - val operator = remember { userServers.value[operatorIndex].operator_ } SectionItemView { Text( stringResource(MR.strings.operator_use_operator_toggle_description), @@ -125,12 +136,13 @@ private fun UseOperatorToggle( ) Spacer(Modifier.fillMaxWidth().weight(1f)) DefaultSwitch( - checked = operator.enabled, + checked = userServers.value[operatorIndex].operator?.enabled ?: false, onCheckedChange = { enabled -> + val operator = userServers.value[operatorIndex].operator if (enabled) { - when (val conditionsAcceptance = operator.conditionsAcceptance) { + when (val conditionsAcceptance = operator?.conditionsAcceptance) { is ConditionsAcceptance.Accepted -> { - userServers.value[operatorIndex].operator_.enabled = true + changeOperatorEnabled(userServers, operatorIndex, true) } is ConditionsAcceptance.Required -> { @@ -146,12 +158,14 @@ private fun UseOperatorToggle( ) } } else { - userServers.value[operatorIndex].operator_.enabled = true + changeOperatorEnabled(userServers, operatorIndex, true) } } + + else -> {} } } else { - userServers.value[operatorIndex].operator_.enabled = false + changeOperatorEnabled(userServers, operatorIndex, false) } }, ) @@ -179,7 +193,7 @@ private fun SingleOperatorUsageConditionsView( chatModel.conditions.value = r updateOperatorsConditionsAcceptance(currUserServers, r.serverOperators) updateOperatorsConditionsAcceptance(userServers, r.serverOperators) - userServers.value.getOrNull(operatorIndexToEnable)?.operator?.enabled = true + changeOperatorEnabled(userServers, operatorIndex, true) validateServers(rhId, userServers, serverErrors) close() } catch (ex: Exception) { @@ -377,3 +391,11 @@ private fun ConditionsAppliedToOtherOperatorsText(userServers: List>, operatorIndex: Int, enabled: Boolean) { + userServers.value = userServers.value.toMutableList().apply { + this[operatorIndex] = this[operatorIndex].copy( + operator = this[operatorIndex].operator?.copy(enabled = enabled) + ) + } +} \ No newline at end of file