mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-07-09 23:11:52 +00:00
android: custom servers view (#5224)
This commit is contained in:
+89
-66
@@ -1,5 +1,6 @@
|
||||
package chat.simplex.common.views.usersettings.networkAndServers
|
||||
|
||||
import SectionBottomSpacer
|
||||
import SectionCustomFooter
|
||||
import SectionDividerSpaced
|
||||
import SectionItemView
|
||||
@@ -33,8 +34,8 @@ 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
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.random.Random
|
||||
|
||||
@Composable
|
||||
fun ModalData.OperatorView(
|
||||
@@ -49,60 +50,77 @@ fun ModalData.OperatorView(
|
||||
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,
|
||||
{ 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
|
||||
)
|
||||
Box {
|
||||
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,
|
||||
navigateToProtocolView = { serverIndex, server, protocol ->
|
||||
navigateToProtocolView(scope, userServers, serverErrors, operatorIndex, rhId, serverIndex, server, protocol)
|
||||
},
|
||||
currentUser,
|
||||
rhId,
|
||||
testing
|
||||
)
|
||||
}
|
||||
|
||||
if (testing.value) {
|
||||
DefaultProgressView(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun navigateToProtocolView(
|
||||
scope: CoroutineScope,
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
serverErrors: MutableState<List<UserServersError>>,
|
||||
operatorIndex: Int,
|
||||
rhId: Long?,
|
||||
serverIndex: Int,
|
||||
server: UserServer,
|
||||
protocol: ServerProtocol
|
||||
) {
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OperatorViewLayout(
|
||||
currUserServers: MutableState<List<UserOperatorServers>>,
|
||||
@@ -111,12 +129,12 @@ fun OperatorViewLayout(
|
||||
operatorIndex: Int,
|
||||
navigateToProtocolView: (Int, UserServer, ServerProtocol) -> Unit,
|
||||
currentUser: User?,
|
||||
rhId: Long?
|
||||
rhId: Long?,
|
||||
testing: MutableState<Boolean>
|
||||
) {
|
||||
val operator by remember { derivedStateOf { userServers.value[operatorIndex].operator_ } }
|
||||
val scope = rememberCoroutineScope()
|
||||
val duplicateHosts = findDuplicateHosts(serverErrors.value)
|
||||
val testing = remember { mutableStateOf(false) }
|
||||
|
||||
Column {
|
||||
SectionView(generalGetString(MR.strings.operator).uppercase()) {
|
||||
@@ -362,24 +380,29 @@ fun OperatorViewLayout(
|
||||
}
|
||||
|
||||
SectionDividerSpaced()
|
||||
TestServersButton(
|
||||
testing = testing,
|
||||
smpServers = userServers.value[operatorIndex].smpServers,
|
||||
xftpServers = userServers.value[operatorIndex].xftpServers,
|
||||
) { p, l ->
|
||||
when (p) {
|
||||
ServerProtocol.XFTP -> userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
xftpServers = l
|
||||
)
|
||||
}
|
||||
ServerProtocol.SMP -> userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
smpServers = l
|
||||
)
|
||||
SectionView {
|
||||
TestServersButton(
|
||||
testing = testing,
|
||||
smpServers = userServers.value[operatorIndex].smpServers,
|
||||
xftpServers = userServers.value[operatorIndex].xftpServers,
|
||||
) { p, l ->
|
||||
when (p) {
|
||||
ServerProtocol.XFTP -> userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
xftpServers = l
|
||||
)
|
||||
}
|
||||
|
||||
ServerProtocol.SMP -> userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
smpServers = l
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SectionBottomSpacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+99
-18
@@ -9,8 +9,6 @@ import SectionView
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
@@ -36,10 +34,26 @@ fun ModalData.YourServersView(
|
||||
rhId: Long?
|
||||
) {
|
||||
val testing = remember { mutableStateOf(false) }
|
||||
val currentUser = remember { chatModel.currentUser }.value
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Box {
|
||||
ColumnWithScrollBar {
|
||||
AppBarTitle(stringResource(MR.strings.your_servers))
|
||||
YourServersViewLayout(
|
||||
currUserServers,
|
||||
userServers,
|
||||
serverErrors,
|
||||
operatorIndex,
|
||||
navigateToProtocolView = { serverIndex, server, protocol ->
|
||||
navigateToProtocolView(scope, userServers, serverErrors, operatorIndex, rhId, serverIndex, server, protocol)
|
||||
},
|
||||
currentUser,
|
||||
rhId,
|
||||
testing
|
||||
)
|
||||
}
|
||||
|
||||
ColumnWithScrollBar {
|
||||
AppBarTitle(stringResource(MR.strings.your_servers))
|
||||
YourServersViewLayout(currUserServers, userServers, serverErrors, operatorIndex, rhId, testing.value)
|
||||
if (testing.value) {
|
||||
DefaultProgressView(null)
|
||||
}
|
||||
@@ -52,17 +66,19 @@ fun YourServersViewLayout(
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
serverErrors: MutableState<List<UserServersError>>,
|
||||
operatorIndex: Int,
|
||||
navigateToProtocolView: (Int, UserServer, ServerProtocol) -> Unit,
|
||||
currentUser: User?,
|
||||
rhId: Long?,
|
||||
testing: Boolean
|
||||
testing: MutableState<Boolean>
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val duplicateHosts = findDuplicateHosts(serverErrors.value)
|
||||
|
||||
Column {
|
||||
if (userServers.value[operatorIndex].smpServers.any { !it.deleted }) {
|
||||
SectionView(generalGetString(MR.strings.message_servers).uppercase()) {
|
||||
userServers.value[operatorIndex].smpServers.forEach { server ->
|
||||
SectionItemView {
|
||||
userServers.value[operatorIndex].smpServers.forEachIndexed { i, server ->
|
||||
if (server.deleted) return@forEachIndexed
|
||||
SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.SMP) }) {
|
||||
ProtocolServerView(
|
||||
srv = server,
|
||||
serverProtocol = ServerProtocol.SMP,
|
||||
@@ -76,30 +92,95 @@ fun YourServersViewLayout(
|
||||
SectionCustomFooter {
|
||||
ServerErrorsView(smpErrors)
|
||||
}
|
||||
} else {
|
||||
SectionTextFooter(
|
||||
remember(currentUser?.displayName) {
|
||||
buildAnnotatedString {
|
||||
append(generalGetString(MR.strings.smp_servers_per_user) + " ")
|
||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(currentUser?.displayName ?: "")
|
||||
}
|
||||
append(".")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SectionDividerSpaced()
|
||||
if (userServers.value[operatorIndex].xftpServers.any { !it.deleted }) {
|
||||
SectionDividerSpaced()
|
||||
SectionView(generalGetString(MR.strings.media_and_file_servers).uppercase()) {
|
||||
userServers.value[operatorIndex].xftpServers.forEachIndexed { i, server ->
|
||||
if (server.deleted) return@forEachIndexed
|
||||
SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.XFTP) }) {
|
||||
ProtocolServerView(
|
||||
srv = server,
|
||||
serverProtocol = ServerProtocol.XFTP,
|
||||
duplicateHosts = duplicateHosts
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
val xftpErrors = globalXFTPServersError(serverErrors.value)
|
||||
if (xftpErrors != null) {
|
||||
SectionCustomFooter {
|
||||
ServerErrorsView(xftpErrors)
|
||||
}
|
||||
} else {
|
||||
SectionTextFooter(
|
||||
remember(currentUser?.displayName) {
|
||||
buildAnnotatedString {
|
||||
append(generalGetString(MR.strings.xftp_servers_per_user) + " ")
|
||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(currentUser?.displayName ?: "")
|
||||
}
|
||||
append(".")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
userServers.value[operatorIndex].smpServers.any { !it.deleted } ||
|
||||
userServers.value[operatorIndex].xftpServers.any { !it.deleted }
|
||||
) {
|
||||
SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false)
|
||||
}
|
||||
|
||||
SectionView {
|
||||
SettingsActionItem(
|
||||
painterResource(MR.images.ic_add),
|
||||
stringResource(MR.strings.smp_servers_add),
|
||||
click = { showAddServerDialog(userServers, serverErrors, operatorIndex, rhId) },
|
||||
disabled = testing,
|
||||
textColor = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.primary,
|
||||
iconColor = if (testing) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
|
||||
disabled = testing.value,
|
||||
textColor = if (testing.value) MaterialTheme.colors.secondary else MaterialTheme.colors.primary,
|
||||
iconColor = if (testing.value) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
|
||||
)
|
||||
}
|
||||
SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false)
|
||||
|
||||
SectionView {
|
||||
// TODO Test servers button
|
||||
SectionItemView { Text("Test servers") }
|
||||
}
|
||||
SectionDividerSpaced(maxBottomPadding = false)
|
||||
TestServersButton(
|
||||
testing = testing,
|
||||
smpServers = userServers.value[operatorIndex].smpServers,
|
||||
xftpServers = userServers.value[operatorIndex].xftpServers,
|
||||
) { p, l ->
|
||||
when (p) {
|
||||
ServerProtocol.XFTP -> userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
xftpServers = l
|
||||
)
|
||||
}
|
||||
|
||||
ServerProtocol.SMP -> userServers.value = userServers.value.toMutableList().apply {
|
||||
this[operatorIndex] = this[operatorIndex].copy(
|
||||
smpServers = l
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SectionView {
|
||||
HowToButton()
|
||||
}
|
||||
SectionBottomSpacer()
|
||||
|
||||
Reference in New Issue
Block a user