android: custom servers view (#5224)

This commit is contained in:
spaced4ndy
2024-11-21 12:27:27 +04:00
committed by GitHub
parent 204bc21695
commit 3817a1609a
2 changed files with 188 additions and 84 deletions
@@ -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()
}
}
}
@@ -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()