mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-01 20:08:57 +00:00
edit and view servers
This commit is contained in:
+60
-11
@@ -47,10 +47,56 @@ fun ModalData.OperatorView(
|
||||
val testing = remember { mutableStateOf(false) }
|
||||
val operator = remember { userServers.value[operatorIndex].operator_ }
|
||||
val currentUser = remember { chatModel.currentUser }.value
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
ColumnWithScrollBar(Modifier.alpha(if (testing.value) 0.6f else 1f)) {
|
||||
AppBarTitle(String.format(stringResource(MR.strings.operator_servers_title), operator.tradeName))
|
||||
OperatorViewLayout(currUserServers, userServers, serverErrors, operatorIndex, currentUser, rhId)
|
||||
OperatorViewLayout(
|
||||
currUserServers,
|
||||
userServers,
|
||||
serverErrors,
|
||||
operatorIndex,
|
||||
{ serverIndex, server, protocol ->
|
||||
ModalManager.start.showCustomModal { close ->
|
||||
ProtocolServerView(
|
||||
m = chatModel,
|
||||
server = server,
|
||||
serverProtocol = protocol,
|
||||
userServers = userServers,
|
||||
serverErrors = serverErrors,
|
||||
onDelete = {
|
||||
if (protocol == ServerProtocol.SMP) {
|
||||
deleteSMPServer(userServers, operatorIndex, serverIndex)
|
||||
} else {
|
||||
deleteXFTPServer(userServers, operatorIndex, serverIndex)
|
||||
}
|
||||
close()
|
||||
scope.launch { validateServers(rhId, userServers, serverErrors) }
|
||||
},
|
||||
onUpdate = { updatedServer ->
|
||||
userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
smpServers = if (protocol == ServerProtocol.SMP) {
|
||||
this[operatorIndex].smpServers.toMutableList().apply {
|
||||
this[serverIndex] = updatedServer
|
||||
}
|
||||
} else this[operatorIndex].smpServers,
|
||||
xftpServers = if (protocol == ServerProtocol.XFTP) {
|
||||
this[operatorIndex].xftpServers.toMutableList().apply {
|
||||
this[serverIndex] = updatedServer
|
||||
}
|
||||
} else this[operatorIndex].xftpServers
|
||||
)
|
||||
}
|
||||
},
|
||||
close = close,
|
||||
rhId = rhId
|
||||
)
|
||||
}
|
||||
},
|
||||
currentUser,
|
||||
rhId
|
||||
)
|
||||
if (testing.value) {
|
||||
DefaultProgressView(null)
|
||||
}
|
||||
@@ -63,6 +109,7 @@ fun OperatorViewLayout(
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
serverErrors: MutableState<List<UserServersError>>,
|
||||
operatorIndex: Int,
|
||||
navigateToProtocolView: (Int, UserServer, ServerProtocol) -> Unit,
|
||||
currentUser: User?,
|
||||
rhId: Long?
|
||||
) {
|
||||
@@ -163,8 +210,9 @@ fun OperatorViewLayout(
|
||||
if (userServers.value[operatorIndex].smpServers.any { it.preset }) {
|
||||
SectionDividerSpaced()
|
||||
SectionView(generalGetString(MR.strings.message_servers).uppercase()) {
|
||||
userServers.value[operatorIndex].smpServers.forEach { server ->
|
||||
SectionItemView {
|
||||
userServers.value[operatorIndex].smpServers.forEachIndexed { i, server ->
|
||||
if (!server.preset) return@forEachIndexed
|
||||
SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.SMP) }) {
|
||||
ProtocolServerView(
|
||||
srv = server,
|
||||
serverProtocol = ServerProtocol.SMP,
|
||||
@@ -196,9 +244,9 @@ fun OperatorViewLayout(
|
||||
if (userServers.value[operatorIndex].smpServers.any { !it.preset && !it.deleted }) {
|
||||
SectionDividerSpaced()
|
||||
SectionView(generalGetString(MR.strings.operator_added_message_servers).uppercase()) {
|
||||
userServers.value[operatorIndex].smpServers.forEach { server ->
|
||||
if (server.deleted || server.preset) return@forEach
|
||||
SectionItemView {
|
||||
userServers.value[operatorIndex].smpServers.forEachIndexed { i, server ->
|
||||
if (server.deleted || server.preset) return@forEachIndexed
|
||||
SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.SMP) }) {
|
||||
ProtocolServerView(
|
||||
srv = server,
|
||||
serverProtocol = ServerProtocol.SMP,
|
||||
@@ -248,8 +296,9 @@ fun OperatorViewLayout(
|
||||
if (userServers.value[operatorIndex].xftpServers.any { it.preset }) {
|
||||
SectionDividerSpaced()
|
||||
SectionView(generalGetString(MR.strings.media_and_file_servers).uppercase()) {
|
||||
userServers.value[operatorIndex].xftpServers.forEach { server ->
|
||||
SectionItemView {
|
||||
userServers.value[operatorIndex].xftpServers.forEachIndexed { i, server ->
|
||||
if (!server.preset) return@forEachIndexed
|
||||
SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.XFTP) }) {
|
||||
ProtocolServerView(
|
||||
srv = server,
|
||||
serverProtocol = ServerProtocol.XFTP,
|
||||
@@ -281,9 +330,9 @@ fun OperatorViewLayout(
|
||||
if (userServers.value[operatorIndex].xftpServers.any { !it.preset && !it.deleted}) {
|
||||
SectionDividerSpaced()
|
||||
SectionView(generalGetString(MR.strings.operator_added_xftp_servers).uppercase()) {
|
||||
userServers.value[operatorIndex].xftpServers.forEach { server ->
|
||||
if (server.deleted || server.preset) return@forEach
|
||||
SectionItemView {
|
||||
userServers.value[operatorIndex].xftpServers.forEachIndexed { i, server ->
|
||||
if (server.deleted || server.preset) return@forEachIndexed
|
||||
SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.XFTP) }) {
|
||||
ProtocolServerView(
|
||||
srv = server,
|
||||
serverProtocol = ServerProtocol.XFTP,
|
||||
|
||||
+90
-36
@@ -31,37 +31,90 @@ import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
||||
@Composable
|
||||
fun ProtocolServerView(m: ChatModel, server: UserServer, serverProtocol: ServerProtocol, onUpdate: (UserServer) -> Unit, onDelete: () -> Unit) {
|
||||
fun ProtocolServerView(
|
||||
m: ChatModel,
|
||||
server: UserServer,
|
||||
serverProtocol: ServerProtocol,
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
serverErrors: MutableState<List<UserServersError>>,
|
||||
onDelete: () -> Unit,
|
||||
onUpdate: (UserServer) -> Unit,
|
||||
close: () -> Unit,
|
||||
rhId: Long?
|
||||
) {
|
||||
var testing by remember { mutableStateOf(false) }
|
||||
ProtocolServerLayout(
|
||||
testing,
|
||||
server,
|
||||
serverProtocol,
|
||||
testServer = {
|
||||
testing = true
|
||||
withLongRunningApi {
|
||||
val res = testServerConnection(server, m)
|
||||
if (isActive) {
|
||||
onUpdate(res.first)
|
||||
testing = false
|
||||
val scope = rememberCoroutineScope()
|
||||
val draftServer = remember { mutableStateOf(server) }
|
||||
|
||||
ModalView(
|
||||
close = {
|
||||
scope.launch {
|
||||
val draftResult = serverProtocolAndOperator(draftServer.value, userServers.value)
|
||||
val savedResult = serverProtocolAndOperator(server, userServers.value)
|
||||
|
||||
if (draftResult != null && savedResult != null) {
|
||||
val (serverToEditProtocol, serverToEditOperator) = draftResult
|
||||
val (svProtocol, serverOperator) = savedResult
|
||||
|
||||
if (serverToEditProtocol != svProtocol) {
|
||||
close()
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.error_updating_server_title),
|
||||
text = generalGetString(MR.strings.error_server_protocol_changed)
|
||||
)
|
||||
} else if (serverToEditOperator != serverOperator) {
|
||||
close()
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.error_updating_server_title),
|
||||
text = generalGetString(MR.strings.error_server_operator_changed)
|
||||
)
|
||||
} else {
|
||||
onUpdate(draftServer.value)
|
||||
validateServers(rhId, userServers, serverErrors)
|
||||
close()
|
||||
}
|
||||
} else {
|
||||
close()
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.smp_servers_invalid_address),
|
||||
text = generalGetString(MR.strings.smp_servers_check_address)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
onUpdate,
|
||||
onDelete
|
||||
)
|
||||
if (testing) {
|
||||
Box(
|
||||
Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
Modifier
|
||||
.padding(horizontal = 2.dp)
|
||||
.size(30.dp),
|
||||
color = MaterialTheme.colors.secondary,
|
||||
strokeWidth = 2.5.dp
|
||||
)
|
||||
}
|
||||
) {
|
||||
ProtocolServerLayout(
|
||||
testing,
|
||||
draftServer.value,
|
||||
serverProtocol,
|
||||
testServer = {
|
||||
testing = true
|
||||
withLongRunningApi {
|
||||
val res = testServerConnection(draftServer.value, m)
|
||||
if (isActive) {
|
||||
draftServer.value = res.first
|
||||
testing = false
|
||||
}
|
||||
}
|
||||
},
|
||||
onUpdate = {
|
||||
draftServer.value = it
|
||||
},
|
||||
onDelete
|
||||
)
|
||||
if (testing) {
|
||||
Box(
|
||||
Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
Modifier
|
||||
.padding(horizontal = 2.dp)
|
||||
.size(30.dp),
|
||||
color = MaterialTheme.colors.secondary,
|
||||
strokeWidth = 2.5.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,10 +129,10 @@ private fun ProtocolServerLayout(
|
||||
onDelete: () -> Unit,
|
||||
) {
|
||||
ColumnWithScrollBar {
|
||||
AppBarTitle(stringResource(if (server.preset) MR.strings.smp_servers_preset_server else MR.strings.smp_servers_your_server))
|
||||
AppBarTitle(stringResource(if (serverProtocol == ServerProtocol.XFTP) MR.strings.xftp_server else MR.strings.smp_server))
|
||||
|
||||
if (server.preset) {
|
||||
PresetServer(testing, server, testServer, onUpdate, onDelete)
|
||||
PresetServer(testing, server, testServer, onUpdate)
|
||||
} else {
|
||||
CustomServer(testing, server, serverProtocol, testServer, onUpdate, onDelete)
|
||||
}
|
||||
@@ -93,7 +146,6 @@ private fun PresetServer(
|
||||
server: UserServer,
|
||||
testServer: () -> Unit,
|
||||
onUpdate: (UserServer) -> Unit,
|
||||
onDelete: () -> Unit,
|
||||
) {
|
||||
SectionView(stringResource(MR.strings.smp_servers_preset_address).uppercase()) {
|
||||
SelectionContainer {
|
||||
@@ -108,7 +160,7 @@ private fun PresetServer(
|
||||
}
|
||||
}
|
||||
SectionDividerSpaced()
|
||||
UseServerSection(true, testing, server, testServer, onUpdate, onDelete)
|
||||
UseServerSection(true, testing, server, testServer, onUpdate)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -165,7 +217,7 @@ private fun UseServerSection(
|
||||
server: UserServer,
|
||||
testServer: () -> Unit,
|
||||
onUpdate: (UserServer) -> Unit,
|
||||
onDelete: () -> Unit,
|
||||
onDelete: (() -> Unit)? = null,
|
||||
) {
|
||||
SectionView(stringResource(MR.strings.smp_servers_use_server).uppercase()) {
|
||||
SectionItemViewSpaceBetween(testServer, disabled = !valid || testing) {
|
||||
@@ -181,9 +233,11 @@ private fun UseServerSection(
|
||||
) {
|
||||
onUpdate(server.copy(enabled = it))
|
||||
}
|
||||
|
||||
SectionItemView(onDelete, disabled = testing) {
|
||||
Text(stringResource(MR.strings.smp_servers_delete_server), color = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.error)
|
||||
|
||||
if (onDelete != null) {
|
||||
SectionItemView(onDelete, disabled = testing) {
|
||||
Text(stringResource(MR.strings.smp_servers_delete_server), color = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+53
@@ -245,6 +245,59 @@ private suspend fun runServersTest(servers: List<UserServer>, m: ChatModel, onUp
|
||||
return fs
|
||||
}
|
||||
|
||||
fun deleteXFTPServer(
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
operatorServersIndex: Int,
|
||||
serverIndex: Int
|
||||
) {
|
||||
val serverIsSaved = userServers.value[operatorServersIndex].xftpServers[serverIndex].serverId != null
|
||||
|
||||
if (serverIsSaved) {
|
||||
userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorServersIndex] = this[operatorServersIndex].copy(
|
||||
xftpServers = this[operatorServersIndex].xftpServers.toMutableList().apply {
|
||||
this[serverIndex] = this[serverIndex].copy(deleted = true)
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorServersIndex] = this[operatorServersIndex].copy(
|
||||
xftpServers = this[operatorServersIndex].xftpServers.toMutableList().apply {
|
||||
this.removeAt(serverIndex)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteSMPServer(
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
operatorServersIndex: Int,
|
||||
serverIndex: Int
|
||||
) {
|
||||
val serverIsSaved = userServers.value[operatorServersIndex].smpServers[serverIndex].serverId != null
|
||||
|
||||
if (serverIsSaved) {
|
||||
userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorServersIndex] = this[operatorServersIndex].copy(
|
||||
smpServers = this[operatorServersIndex].smpServers.toMutableList().apply {
|
||||
this[serverIndex] = this[serverIndex].copy(deleted = true)
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorServersIndex] = this[operatorServersIndex].copy(
|
||||
smpServers = this[operatorServersIndex].smpServers.toMutableList().apply {
|
||||
this.removeAt(serverIndex)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun saveServers(rhId: Long?, protocol: ServerProtocol, currServers: MutableState<List<UserServer>>, servers: List<UserServer>, m: ChatModel, afterSave: () -> Unit = {}) {
|
||||
withBGApi {
|
||||
// if (m.controller.setUserServers(rhId, protocol, servers)) {
|
||||
|
||||
@@ -1712,6 +1712,11 @@
|
||||
<string name="xftp_servers_per_user">The servers for new files of your current chat profile</string>
|
||||
<string name="operator_added_xftp_servers">Added media & file servers</string>
|
||||
|
||||
<!-- ProtocolServerView.kt -->
|
||||
<string name="error_updating_server_title">Error updating server</string>
|
||||
<string name="error_server_protocol_changed">Server protocol changed.</string>
|
||||
<string name="error_server_operator_changed">Server operator changed.</string>
|
||||
|
||||
<!-- AdvancedNetworkSettings.kt -->
|
||||
<string name="network_option_tcp_connection">TCP connection</string>
|
||||
<string name="network_options_reset_to_defaults">Reset to defaults</string>
|
||||
|
||||
Reference in New Issue
Block a user