diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index e09acda7bf..61a1b8b0fe 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -3866,47 +3866,45 @@ sealed class UserServersError { val globalError: String? get() = when (this) { - is NoServers -> protocol.toGlobalError(this, ::globalSMPError, ::globalXFTPError) - is StorageMissing -> protocol.toGlobalError(this, ::globalSMPError, ::globalXFTPError) - is ProxyMissing -> protocol.toGlobalError(this, ::globalSMPError, ::globalXFTPError) + is NoServers -> protocol.toGlobalError( { this.globalSMPError }, { this.globalXFTPError }) + is StorageMissing -> protocol.toGlobalError({ this.globalSMPError }, { this.globalXFTPError }) + is ProxyMissing -> protocol.toGlobalError({ this.globalSMPError }, { this.globalXFTPError }) else -> null } - private fun globalSMPError(error: UserServersError): String? { - return when (error) { - is NoServers -> error.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_message_servers_configured)}" } + val globalSMPError: String? + get() = when (this) { + is NoServers -> this.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_message_servers_configured)}" } ?: generalGetString(MR.strings.no_message_servers_configured) - is StorageMissing -> error.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_message_servers_configured_for_receiving)}" } + is StorageMissing -> this.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_message_servers_configured_for_receiving)}" } ?: generalGetString(MR.strings.no_message_servers_configured_for_receiving) - is ProxyMissing -> error.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_message_servers_configured_for_private_routing)}" } + is ProxyMissing -> this.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_message_servers_configured_for_private_routing)}" } ?: generalGetString(MR.strings.no_message_servers_configured_for_private_routing) else -> null } - } - private fun globalXFTPError(error: UserServersError): String? { - return when (error) { - is NoServers -> error.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_media_servers_configured)}" } + + val globalXFTPError: String? + get() = when (this) { + is NoServers -> this.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_media_servers_configured)}" } ?: generalGetString(MR.strings.no_media_servers_configured) - is StorageMissing -> error.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_media_servers_configured_for_sending)}" } + is StorageMissing -> this.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_media_servers_configured_for_sending)}" } ?: generalGetString(MR.strings.no_media_servers_configured_for_sending) - is ProxyMissing -> error.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_media_servers_configured_for_private_routing)}" } + is ProxyMissing -> this.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_media_servers_configured_for_private_routing)}" } ?: generalGetString(MR.strings.no_media_servers_configured_for_private_routing) else -> null } - } private fun userStr(user: UserRef): String { return String.format(generalGetString(MR.strings.for_chat_profile), user.localDisplayName) } private fun ServerProtocol.toGlobalError( - error: UserServersError, - smpHandler: (UserServersError) -> String?, - xftpHandler: (UserServersError) -> String? + smpHandler: () -> String?, + xftpHandler: () -> String? ): String? { return when (this) { - ServerProtocol.SMP -> smpHandler(error) - ServerProtocol.XFTP -> xftpHandler(error) + ServerProtocol.SMP -> smpHandler() + ServerProtocol.XFTP -> xftpHandler() } } } 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 cb845193a6..6f5044813b 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 @@ -24,6 +24,7 @@ import androidx.compose.foundation.Image import androidx.compose.ui.graphics.* 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 @@ -52,7 +53,7 @@ fun NetworkAndServersView(close: () -> Unit) { val proxyPort = remember { derivedStateOf { appPrefs.networkProxy.state.value.port } } ModalView( close = { - if (currUserServers.value != userServers.value) { + if (currUserServers.value == userServers.value) { close() } else { showUnsavedChangesAlert( @@ -666,29 +667,18 @@ private fun ConditionsButton(conditionsAction: UsageConditionsAction) { } } -private suspend fun saveServers( - rhId: Long?, - currUserServers: MutableState>, - userServers: MutableState> -) { - val userServersToSave = currUserServers.value - try { - val set = setUserServers(rhId, userServersToSave) - - if (set) { - val updatedServers = getUserServers(rhId) - - if (updatedServers != null) { - currUserServers.value = updatedServers - userServers.value = updatedServers - } else { - currUserServers.value = userServersToSave - } - } else { - currUserServers.value = userServersToSave - } - } catch (ex: Exception) { - Log.e(TAG, ex.stackTraceToString()) +@Composable +fun ServerErrorsView(errStr: String) { + Row { + Icon( + painterResource(MR.images.ic_error), + contentDescription = stringResource(MR.strings.server_error), + tint = Color.Red, + modifier = Modifier + .size(19.sp.toDp()) + .offset(x = 2.sp.toDp()) + ) + Text(errStr, color = MaterialTheme.colors.secondary) } } @@ -741,6 +731,78 @@ suspend fun validateServers( } } +fun serversCanBeSaved( + currUserServers: List, + userServers: List, + serverErrors: List +): Boolean { + return userServers != currUserServers && serverErrors.isEmpty() +} + +fun globalServersError(serverErrors: List): String? { + for (err in serverErrors) { + if (err.globalError != null) { + return err.globalError + } + } + return null +} + +fun globalSMPServersError(serverErrors: List): String? { + for (err in serverErrors) { + if (err.globalSMPError != null) { + return err.globalSMPError + } + } + return null +} + +fun globalXFTPServersError(serverErrors: List): String? { + for (err in serverErrors) { + if (err.globalXFTPError != null) { + return err.globalXFTPError + } + } + return null +} + +fun findDuplicateHosts(serverErrors: List): Set { + val duplicateHostsList = serverErrors.mapNotNull { err -> + if (err is UserServersError.DuplicateServer) { + err.duplicateHost + } else { + null + } + } + return duplicateHostsList.toSet() +} + +private suspend fun saveServers( + rhId: Long?, + currUserServers: MutableState>, + userServers: MutableState> +) { + val userServersToSave = currUserServers.value + try { + val set = setUserServers(rhId, userServersToSave) + + if (set) { + val updatedServers = getUserServers(rhId) + + if (updatedServers != null) { + currUserServers.value = updatedServers + userServers.value = updatedServers + } else { + currUserServers.value = userServersToSave + } + } else { + currUserServers.value = userServersToSave + } + } catch (ex: Exception) { + Log.e(TAG, ex.stackTraceToString()) + } +} + @Preview @Composable fun PreviewNetworkAndServersLayout() {