more servers

This commit is contained in:
Diogo
2024-11-20 13:07:54 +00:00
parent 58b5058ea2
commit 24c304b1c6
5 changed files with 134 additions and 9 deletions
@@ -3812,8 +3812,8 @@ data class ServerOperator(
@Serializable
data class ServerRoles(
val storage: Boolean,
val proxy: Boolean
var storage: Boolean,
var proxy: Boolean
)
@Serializable
@@ -679,6 +679,7 @@ fun ServerErrorsView(errStr: String) {
.size(19.sp.toDp())
.offset(x = 2.sp.toDp())
)
TextIconSpaced()
Text(errStr, color = MaterialTheme.colors.secondary)
}
}
@@ -1,5 +1,6 @@
package chat.simplex.common.views.usersettings.networkAndServers
import SectionCustomFooter
import SectionDividerSpaced
import SectionItemView
import SectionTextFooter
@@ -32,6 +33,7 @@ import chat.simplex.res.MR
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.launch
import kotlin.random.Random
@Composable
fun ModalData.OperatorView(
@@ -61,7 +63,9 @@ fun OperatorViewLayout(
operatorIndex: Int,
rhId: Long?
) {
val operator = remember { userServers.value[operatorIndex].operator_ }
val operator by remember { derivedStateOf { userServers.value[operatorIndex].operator_ } }
val scope = rememberCoroutineScope()
val duplicateHosts = findDuplicateHosts(serverErrors.value)
Column {
SectionView(generalGetString(MR.strings.operator).uppercase()) {
@@ -92,8 +96,82 @@ fun OperatorViewLayout(
}
if (operator.enabled) {
if (userServers.value[operatorIndex].smpServers.filter { !it.deleted }.isNotEmpty()) {
if (userServers.value[operatorIndex].smpServers.any { !it.deleted }) {
SectionDividerSpaced()
SectionView(generalGetString(MR.strings.operator_use_for_messages).uppercase()) {
SectionItemView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) {
Text(
stringResource(MR.strings.operator_use_for_messages_receiving),
Modifier.padding(end = 24.dp),
color = Color.Unspecified
)
Spacer(Modifier.fillMaxWidth().weight(1f))
DefaultSwitch(
checked = userServers.value[operatorIndex].operator_.smpRoles.storage,
onCheckedChange = { enabled ->
userServers.value = userServers.value.toMutableList().apply {
this[operatorIndex] = this[operatorIndex].copy(
operator = this[operatorIndex].operator?.copy(
smpRoles = this[operatorIndex].operator?.smpRoles?.copy(storage = enabled) ?: ServerRoles(storage = enabled, proxy = false)
)
)
}
scope.launch {
validateServers(rhId, userServers, serverErrors)
}
}
)
}
SectionItemView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) {
Text(
stringResource(MR.strings.operator_use_for_messages_private_routing),
Modifier.padding(end = 24.dp),
color = Color.Unspecified
)
Spacer(Modifier.fillMaxWidth().weight(1f))
DefaultSwitch(
checked = userServers.value[operatorIndex].operator_.smpRoles.proxy,
onCheckedChange = { enabled ->
userServers.value = userServers.value.toMutableList().apply {
this[operatorIndex] = this[operatorIndex].copy(
operator = this[operatorIndex].operator?.copy(
smpRoles = this[operatorIndex].operator?.smpRoles?.copy(proxy = enabled) ?: ServerRoles(storage = false, proxy = enabled)
)
)
}
scope.launch {
validateServers(rhId, userServers, serverErrors)
}
}
)
}
}
val smpErrors = globalSMPServersError(serverErrors.value)
if (smpErrors != null) {
SectionCustomFooter {
ServerErrorsView(smpErrors)
}
}
}
// Preset servers can't be deleted
if (userServers.value[operatorIndex].smpServers.any { it.preset }) {
SectionDividerSpaced()
SectionView(generalGetString(MR.strings.message_servers).uppercase()) {
userServers.value[operatorIndex].smpServers.forEach { server ->
SectionItemView {
ProtocolServerViewLink(
userServers = userServers,
serverErrors = serverErrors,
server = server,
serverProtocol = ServerProtocol.SMP,
rhId = rhId,
duplicateHosts = duplicateHosts
)
}
}
}
}
}
}
@@ -128,7 +206,7 @@ private fun UseOperatorToggle(
operatorIndex: Int,
rhId: Long?
) {
SectionItemView {
SectionItemView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) {
Text(
stringResource(MR.strings.operator_use_operator_toggle_description),
Modifier.padding(end = 24.dp),
@@ -306,7 +384,7 @@ private fun NonScrollableTitle(title: String) {
}
@Composable
private fun ConditionsTextView(
fun ConditionsTextView(
rhId: Long?
) {
val conditionsData = remember { mutableStateOf<Triple<UsageConditionsDetail, String?, UsageConditionsDetail?>?>(null) }
@@ -1,11 +1,18 @@
package chat.simplex.common.views.usersettings.networkAndServers
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import chat.simplex.common.model.UserOperatorServers
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.common.model.*
import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress
import chat.simplex.common.platform.ColumnWithScrollBar
import chat.simplex.common.views.helpers.*
import chat.simplex.res.MR
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
@Composable
@@ -13,4 +20,40 @@ fun ModalData.YourServersView(userServers: MutableState<List<UserOperatorServers
ColumnWithScrollBar {
AppBarTitle(stringResource(MR.strings.your_servers))
}
}
@Composable
fun ProtocolServerViewLink(
userServers: MutableState<List<UserOperatorServers>>,
serverErrors: MutableState<List<UserServersError>>,
server: UserServer,
serverProtocol: ServerProtocol,
duplicateHosts: Set<String>,
rhId: Long?,
) {
val address = parseServerAddress(server.server)
when {
address == null || !address.valid || address.serverProtocol != serverProtocol || address.hostnames.any { it in duplicateHosts } -> InvalidServer()
!server.enabled -> Icon(painterResource(MR.images.ic_do_not_disturb_on), null, tint = MaterialTheme.colors.secondary)
else -> ShowTestStatus(server)
}
Spacer(Modifier.padding(horizontal = 4.dp))
val text = address?.hostnames?.firstOrNull() ?: server.server
if (server.enabled) {
Text(text, color = MaterialTheme.colors.onBackground, maxLines = 1)
} else {
Text(text, maxLines = 1, color = MaterialTheme.colors.secondary)
}
}
@Composable
private fun InvalidServer() {
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())
)
}
@@ -1700,6 +1700,9 @@
<string name="accept_conditions">Accept conditions</string>
<string name="operator_conditions_of_use">Conditions of use</string>
<string name="operator_in_order_to_use_accept_conditions">In order to use operator %s, accept conditions of use.</string>
<string name="operator_use_for_messages">Use for messages</string>
<string name="operator_use_for_messages_receiving">For receiving</string>
<string name="operator_use_for_messages_private_routing">For private routing</string>
<!-- AdvancedNetworkSettings.kt -->
<string name="network_option_tcp_connection">TCP connection</string>