mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-29 05:29:08 +00:00
Merge commit '9329bf61447ad3ce9640d82b7b08f05f1db1729f' into master-android
This commit is contained in:
+9
-5
@@ -38,6 +38,7 @@ import java.net.URI
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.FormatStyle
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.random.Random
|
||||
import kotlin.time.*
|
||||
@@ -1396,19 +1397,21 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
||||
}
|
||||
|
||||
@Serializable @SerialName("invalidJSON")
|
||||
class InvalidJSON(val json: String): ChatInfo() {
|
||||
class InvalidJSON(
|
||||
val json: String,
|
||||
override val apiId: Long = -idGenerator.getAndIncrement(),
|
||||
override val createdAt: Instant = Clock.System.now(),
|
||||
override val updatedAt: Instant = Clock.System.now()
|
||||
): ChatInfo() {
|
||||
override val chatType get() = ChatType.Direct
|
||||
override val localDisplayName get() = invalidChatName
|
||||
override val id get() = ""
|
||||
override val apiId get() = 0L
|
||||
override val id get() = "?$apiId"
|
||||
override val ready get() = false
|
||||
override val chatDeleted get() = false
|
||||
override val sendMsgEnabled get() = false
|
||||
override val incognito get() = false
|
||||
override fun featureEnabled(feature: ChatFeature) = false
|
||||
override val timedMessagesTTL: Int? get() = null
|
||||
override val createdAt get() = Clock.System.now()
|
||||
override val updatedAt get() = Clock.System.now()
|
||||
override val displayName get() = invalidChatName
|
||||
override val fullName get() = invalidChatName
|
||||
override val image get() = null
|
||||
@@ -1416,6 +1419,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
||||
|
||||
companion object {
|
||||
private val invalidChatName = generalGetString(MR.strings.invalid_chat)
|
||||
private val idGenerator = AtomicLong(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+696
-718
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -48,7 +48,7 @@ private fun sendCommand(chatModel: ChatModel, composeState: MutableState<Compose
|
||||
val prefPerformLA = chatModel.controller.appPrefs.performLA.get()
|
||||
val s = composeState.value.message
|
||||
if (s.text.startsWith("/sql") && (!prefPerformLA || !developerTools)) {
|
||||
val resp = CR.ChatCmdError(null, ChatError.ChatErrorChat(ChatErrorType.CommandError("Failed reading: empty")))
|
||||
val resp = API.Error(null, ChatError.ChatErrorChat(ChatErrorType.CommandError("Failed reading: empty")))
|
||||
chatModel.addTerminalItem(TerminalItem.cmd(null, CC.Console(s.text)))
|
||||
chatModel.addTerminalItem(TerminalItem.resp(null, resp))
|
||||
composeState.value = ComposeState(useLinkPreviews = false)
|
||||
|
||||
+5
-5
@@ -10,13 +10,13 @@ import kotlinx.coroutines.*
|
||||
expect fun ActiveCallView()
|
||||
|
||||
fun activeCallWaitDeliveryReceipt(scope: CoroutineScope) = scope.launch(Dispatchers.Default) {
|
||||
for (apiResp in controller.messagesChannel) {
|
||||
for (msg in controller.messagesChannel) {
|
||||
val call = chatModel.activeCall.value
|
||||
if (call == null || call.callState > CallState.InvitationSent) break
|
||||
val msg = apiResp.resp
|
||||
if (apiResp.remoteHostId == call.remoteHostId &&
|
||||
msg is CR.ChatItemsStatusesUpdated &&
|
||||
msg.chatItems.any {
|
||||
if (msg.rhId == call.remoteHostId &&
|
||||
msg is API.Result &&
|
||||
msg.res is CR.ChatItemsStatusesUpdated &&
|
||||
msg.res.chatItems.any {
|
||||
it.chatInfo.id == call.contact.id && it.chatItem.content is CIContent.SndCall && it.chatItem.meta.itemStatus is CIStatus.SndRcvd
|
||||
}
|
||||
) {
|
||||
|
||||
+5
-5
@@ -554,11 +554,11 @@ fun ChatView(
|
||||
ChatItemInfoView(chatRh, cItem, ciInfo, devTools = chatModel.controller.appPrefs.developerTools.get(), chatInfo)
|
||||
LaunchedEffect(cItem.id) {
|
||||
withContext(Dispatchers.Default) {
|
||||
for (apiResp in controller.messagesChannel) {
|
||||
val msg = apiResp.resp
|
||||
if (apiResp.remoteHostId == chatRh &&
|
||||
msg is CR.ChatItemsStatusesUpdated &&
|
||||
msg.chatItems.any { it.chatItem.id == cItem.id }
|
||||
for (msg in controller.messagesChannel) {
|
||||
if (msg.rhId == chatRh &&
|
||||
msg is API.Result &&
|
||||
msg.res is CR.ChatItemsStatusesUpdated &&
|
||||
msg.res.chatItems.any { it.chatItem.id == cItem.id }
|
||||
) {
|
||||
ciInfo = loadChatItemInfo() ?: return@withContext
|
||||
initialCiInfo = ciInfo
|
||||
|
||||
+2
-2
@@ -435,7 +435,7 @@ suspend fun encryptDatabase(
|
||||
}
|
||||
val error = m.controller.apiStorageEncryption(currentKey.value, newKey.value)
|
||||
appPrefs.encryptionStartedAt.set(null)
|
||||
val sqliteError = ((error?.chatError as? ChatError.ChatErrorDatabase)?.databaseError as? DatabaseError.ErrorExport)?.sqliteError
|
||||
val sqliteError = ((error as? ChatError.ChatErrorDatabase)?.databaseError as? DatabaseError.ErrorExport)?.sqliteError
|
||||
when {
|
||||
sqliteError is SQLiteError.ErrorNotADatabase -> {
|
||||
operationEnded(m, progressIndicator) {
|
||||
@@ -449,7 +449,7 @@ suspend fun encryptDatabase(
|
||||
error != null -> {
|
||||
operationEnded(m, progressIndicator) {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_encrypting_database),
|
||||
"failed to set storage encryption: ${error.responseType} ${error.details}"
|
||||
"failed to set storage encryption: error ${error.string}"
|
||||
)
|
||||
}
|
||||
false
|
||||
|
||||
+13
-13
@@ -468,12 +468,12 @@ private suspend fun MutableState<MigrationFromState>.verifyDatabasePassphrase(db
|
||||
val error = controller.testStorageEncryption(dbKey)
|
||||
if (error == null) {
|
||||
state = MigrationFromState.UploadConfirmation
|
||||
} else if (((error.chatError as? ChatError.ChatErrorDatabase)?.databaseError as? DatabaseError.ErrorOpen)?.sqliteError is SQLiteError.ErrorNotADatabase) {
|
||||
} else if (((error as? ChatError.ChatErrorDatabase)?.databaseError as? DatabaseError.ErrorOpen)?.sqliteError is SQLiteError.ErrorNotADatabase) {
|
||||
showErrorOnMigrationIfNeeded(DBMigrationResult.ErrorNotADatabase(""))
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.error),
|
||||
text = generalGetString(MR.strings.migrate_from_device_error_verifying_passphrase) + " " + error.details
|
||||
text = generalGetString(MR.strings.migrate_from_device_error_verifying_passphrase) + " " + error.string
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -556,11 +556,12 @@ private fun MutableState<MigrationFromState>.startUploading(
|
||||
) {
|
||||
withBGApi {
|
||||
chatReceiver.value = MigrationFromChatReceiver(ctrl, tempDatabaseFile) { msg ->
|
||||
when (msg) {
|
||||
val r = msg.result
|
||||
when (r) {
|
||||
is CR.SndFileProgressXFTP -> {
|
||||
val s = state
|
||||
if (s is MigrationFromState.UploadProgress && s.uploadedBytes != s.totalBytes) {
|
||||
state = MigrationFromState.UploadProgress(msg.sentSize, msg.totalSize, msg.fileTransferMeta.fileId, archivePath, ctrl, user)
|
||||
state = MigrationFromState.UploadProgress(r.sentSize, r.totalSize, r.fileTransferMeta.fileId, archivePath, ctrl, user)
|
||||
}
|
||||
}
|
||||
is CR.SndFileRedirectStartXFTP -> {
|
||||
@@ -578,7 +579,7 @@ private fun MutableState<MigrationFromState>.startUploading(
|
||||
requiredHostMode = cfg.requiredHostMode
|
||||
)
|
||||
)
|
||||
state = MigrationFromState.LinkShown(msg.fileTransferMeta.fileId, data.addToLink(msg.rcvURIs[0]), ctrl)
|
||||
state = MigrationFromState.LinkShown(r.fileTransferMeta.fileId, data.addToLink(r.rcvURIs[0]), ctrl)
|
||||
}
|
||||
is CR.SndFileError -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
@@ -692,7 +693,7 @@ private class MigrationFromChatReceiver(
|
||||
val ctrl: ChatCtrl,
|
||||
val databaseUrl: File,
|
||||
var receiveMessages: Boolean = true,
|
||||
val processReceivedMsg: suspend (CR) -> Unit
|
||||
val processReceivedMsg: suspend (API) -> Unit
|
||||
) {
|
||||
fun start() {
|
||||
Log.d(TAG, "MigrationChatReceiver startReceiver")
|
||||
@@ -701,19 +702,18 @@ private class MigrationFromChatReceiver(
|
||||
try {
|
||||
val msg = ChatController.recvMsg(ctrl)
|
||||
if (msg != null && receiveMessages) {
|
||||
val r = msg.resp
|
||||
val rhId = msg.remoteHostId
|
||||
Log.d(TAG, "processReceivedMsg: ${r.responseType}")
|
||||
chatModel.addTerminalItem(TerminalItem.resp(rhId, r))
|
||||
val rhId = msg.rhId
|
||||
Log.d(TAG, "processReceivedMsg: ${msg.responseType}")
|
||||
chatModel.addTerminalItem(TerminalItem.resp(rhId, msg))
|
||||
val finishedWithoutTimeout = withTimeoutOrNull(60_000L) {
|
||||
processReceivedMsg(r)
|
||||
processReceivedMsg(msg)
|
||||
}
|
||||
if (finishedWithoutTimeout == null) {
|
||||
Log.e(TAG, "Timeout reached while processing received message: " + msg.resp.responseType)
|
||||
Log.e(TAG, "Timeout reached while processing received message: " + msg.responseType)
|
||||
if (appPreferences.developerTools.get() && appPreferences.showSlowApiCalls.get()) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.possible_slow_function_title),
|
||||
text = generalGetString(MR.strings.possible_slow_function_desc).format(60, msg.resp.responseType + "\n" + Exception().stackTraceToString()),
|
||||
text = generalGetString(MR.strings.possible_slow_function_desc).format(60, msg.responseType + "\n" + Exception().stackTraceToString()),
|
||||
shareText = true
|
||||
)
|
||||
}
|
||||
|
||||
+16
-16
@@ -580,12 +580,13 @@ private fun MutableState<MigrationToState?>.startDownloading(
|
||||
) {
|
||||
withBGApi {
|
||||
chatReceiver.value = MigrationToChatReceiver(ctrl, tempDatabaseFile) { msg ->
|
||||
when (msg) {
|
||||
is CR.RcvFileProgressXFTP -> {
|
||||
state = MigrationToState.DownloadProgress(msg.receivedSize, msg.totalSize, msg.rcvFileTransfer.fileId, link, archivePath, netCfg, networkProxy, ctrl)
|
||||
val r = msg.result
|
||||
when {
|
||||
r is CR.RcvFileProgressXFTP -> {
|
||||
state = MigrationToState.DownloadProgress(r.receivedSize, r.totalSize, r.rcvFileTransfer.fileId, link, archivePath, netCfg, networkProxy, ctrl)
|
||||
MigrationToDeviceState.save(MigrationToDeviceState.DownloadProgress(link, File(archivePath).name, netCfg, networkProxy))
|
||||
}
|
||||
is CR.RcvStandaloneFileComplete -> {
|
||||
r is CR.RcvStandaloneFileComplete -> {
|
||||
delay(500)
|
||||
// User closed the whole screen before new state was saved
|
||||
if (state == null) {
|
||||
@@ -595,22 +596,22 @@ private fun MutableState<MigrationToState?>.startDownloading(
|
||||
MigrationToDeviceState.save(MigrationToDeviceState.ArchiveImport(File(archivePath).name, netCfg, networkProxy))
|
||||
}
|
||||
}
|
||||
is CR.RcvFileError -> {
|
||||
r is CR.RcvFileError -> {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.migrate_to_device_download_failed),
|
||||
generalGetString(MR.strings.migrate_to_device_file_delete_or_link_invalid)
|
||||
)
|
||||
state = MigrationToState.DownloadFailed(totalBytes, link, archivePath, netCfg, networkProxy)
|
||||
}
|
||||
is CR.ChatRespError -> {
|
||||
if (msg.chatError is ChatError.ChatErrorChat && msg.chatError.errorType is ChatErrorType.NoRcvFileUser) {
|
||||
msg is API.Error -> {
|
||||
if (msg.err is ChatError.ChatErrorChat && msg.err.errorType is ChatErrorType.NoRcvFileUser) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.migrate_to_device_download_failed),
|
||||
generalGetString(MR.strings.migrate_to_device_file_delete_or_link_invalid)
|
||||
)
|
||||
state = MigrationToState.DownloadFailed(totalBytes, link, archivePath, netCfg, networkProxy)
|
||||
} else {
|
||||
Log.d(TAG, "unsupported error: ${msg.responseType}, ${json.encodeToString(msg.chatError)}")
|
||||
Log.d(TAG, "unsupported error: ${msg.responseType}, ${json.encodeToString(msg.err)}")
|
||||
}
|
||||
}
|
||||
else -> Log.d(TAG, "unsupported event: ${msg.responseType}")
|
||||
@@ -739,7 +740,7 @@ private class MigrationToChatReceiver(
|
||||
val ctrl: ChatCtrl,
|
||||
val databaseUrl: File,
|
||||
var receiveMessages: Boolean = true,
|
||||
val processReceivedMsg: suspend (CR) -> Unit
|
||||
val processReceivedMsg: suspend (API) -> Unit
|
||||
) {
|
||||
fun start() {
|
||||
Log.d(TAG, "MigrationChatReceiver startReceiver")
|
||||
@@ -748,19 +749,18 @@ private class MigrationToChatReceiver(
|
||||
try {
|
||||
val msg = ChatController.recvMsg(ctrl)
|
||||
if (msg != null && receiveMessages) {
|
||||
val r = msg.resp
|
||||
val rhId = msg.remoteHostId
|
||||
Log.d(TAG, "processReceivedMsg: ${r.responseType}")
|
||||
chatModel.addTerminalItem(TerminalItem.resp(rhId, r))
|
||||
val rhId = msg.rhId
|
||||
Log.d(TAG, "processReceivedMsg: ${msg.responseType}")
|
||||
chatModel.addTerminalItem(TerminalItem.resp(rhId, msg))
|
||||
val finishedWithoutTimeout = withTimeoutOrNull(60_000L) {
|
||||
processReceivedMsg(r)
|
||||
processReceivedMsg(msg)
|
||||
}
|
||||
if (finishedWithoutTimeout == null) {
|
||||
Log.e(TAG, "Timeout reached while processing received message: " + msg.resp.responseType)
|
||||
Log.e(TAG, "Timeout reached while processing received message: " + msg.responseType)
|
||||
if (appPreferences.developerTools.get() && appPreferences.showSlowApiCalls.get()) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.possible_slow_function_title),
|
||||
text = generalGetString(MR.strings.possible_slow_function_desc).format(60, msg.resp.responseType + "\n" + Exception().stackTraceToString()),
|
||||
text = generalGetString(MR.strings.possible_slow_function_desc).format(60, msg.responseType + "\n" + Exception().stackTraceToString()),
|
||||
shareText = true
|
||||
)
|
||||
}
|
||||
|
||||
+7
-7
@@ -492,7 +492,7 @@ private suspend fun connectDesktopAddress(sessionAddress: MutableState<String>,
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun connectDesktop(sessionAddress: MutableState<String>, connect: suspend () -> Pair<SomeRemoteCtrl?, CR.ChatCmdError?>): Boolean {
|
||||
private suspend fun connectDesktop(sessionAddress: MutableState<String>, connect: suspend () -> Pair<SomeRemoteCtrl?, ChatError?>): Boolean {
|
||||
val res = connect()
|
||||
if (res.first != null) {
|
||||
val (rc_, ctrlAppInfo, v) = res.first!!
|
||||
@@ -505,13 +505,13 @@ private suspend fun connectDesktop(sessionAddress: MutableState<String>, connect
|
||||
} else {
|
||||
val e = res.second ?: return false
|
||||
when {
|
||||
e.chatError is ChatError.ChatErrorRemoteCtrl && e.chatError.remoteCtrlError is RemoteCtrlError.BadInvitation -> showBadInvitationErrorAlert()
|
||||
e.chatError is ChatError.ChatErrorChat && e.chatError.errorType is ChatErrorType.CommandError -> showBadInvitationErrorAlert()
|
||||
e.chatError is ChatError.ChatErrorRemoteCtrl && e.chatError.remoteCtrlError is RemoteCtrlError.BadVersion -> showBadVersionAlert(v = e.chatError.remoteCtrlError.appVersion)
|
||||
e.chatError is ChatError.ChatErrorAgent && e.chatError.agentError is AgentErrorType.RCP && e.chatError.agentError.rcpErr is RCErrorType.VERSION -> showBadVersionAlert(v = null)
|
||||
e.chatError is ChatError.ChatErrorAgent && e.chatError.agentError is AgentErrorType.RCP && e.chatError.agentError.rcpErr is RCErrorType.CTRL_AUTH -> showDesktopDisconnectedErrorAlert()
|
||||
e is ChatError.ChatErrorRemoteCtrl && e.remoteCtrlError is RemoteCtrlError.BadInvitation -> showBadInvitationErrorAlert()
|
||||
e is ChatError.ChatErrorChat && e.errorType is ChatErrorType.CommandError -> showBadInvitationErrorAlert()
|
||||
e is ChatError.ChatErrorRemoteCtrl && e.remoteCtrlError is RemoteCtrlError.BadVersion -> showBadVersionAlert(v = e.remoteCtrlError.appVersion)
|
||||
e is ChatError.ChatErrorAgent && e.agentError is AgentErrorType.RCP && e.agentError.rcpErr is RCErrorType.VERSION -> showBadVersionAlert(v = null)
|
||||
e is ChatError.ChatErrorAgent && e.agentError is AgentErrorType.RCP && e.agentError.rcpErr is RCErrorType.CTRL_AUTH -> showDesktopDisconnectedErrorAlert()
|
||||
else -> {
|
||||
val errMsg = "${e.responseType}: ${e.details}"
|
||||
val errMsg = "error: ${e.string}"
|
||||
Log.e(TAG, "bad response: $errMsg")
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error), errMsg)
|
||||
}
|
||||
|
||||
+2
-2
@@ -291,7 +291,7 @@ private fun DeliveryReceiptsSection(
|
||||
SectionView(stringResource(MR.strings.settings_section_title_delivery_receipts)) {
|
||||
SettingsActionItemWithContent(painterResource(MR.images.ic_person), stringResource(MR.strings.receipts_section_contacts)) {
|
||||
DefaultSwitch(
|
||||
checked = currentUser.sendRcptsContacts ?: false,
|
||||
checked = currentUser.sendRcptsContacts,
|
||||
onCheckedChange = { enable ->
|
||||
setOrAskSendReceiptsContacts(enable)
|
||||
}
|
||||
@@ -299,7 +299,7 @@ private fun DeliveryReceiptsSection(
|
||||
}
|
||||
SettingsActionItemWithContent(painterResource(MR.images.ic_group), stringResource(MR.strings.receipts_section_groups)) {
|
||||
DefaultSwitch(
|
||||
checked = currentUser.sendRcptsSmallGroups ?: false,
|
||||
checked = currentUser.sendRcptsSmallGroups,
|
||||
onCheckedChange = { enable ->
|
||||
setOrAskSendReceiptsGroups(enable)
|
||||
}
|
||||
|
||||
+18
-12
@@ -19,6 +19,7 @@ import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.model.ChatController.appPrefs
|
||||
import chat.simplex.common.ui.theme.*
|
||||
@@ -45,7 +46,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U
|
||||
val sessionMode = remember { mutableStateOf(currentCfgVal.sessionMode) }
|
||||
val smpProxyMode = remember { mutableStateOf(currentCfgVal.smpProxyMode) }
|
||||
val smpProxyFallback = remember { mutableStateOf(currentCfgVal.smpProxyFallback) }
|
||||
val smpWebPort = remember { mutableStateOf(currentCfgVal.smpWebPort) }
|
||||
val smpWebPortServers = remember { mutableStateOf(currentCfgVal.smpWebPortServers) }
|
||||
|
||||
val networkTCPConnectTimeout = remember { mutableStateOf(currentCfgVal.tcpConnectTimeout) }
|
||||
val networkTCPTimeout = remember { mutableStateOf(currentCfgVal.tcpTimeout) }
|
||||
@@ -84,7 +85,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U
|
||||
sessionMode = sessionMode.value,
|
||||
smpProxyMode = smpProxyMode.value,
|
||||
smpProxyFallback = smpProxyFallback.value,
|
||||
smpWebPort = smpWebPort.value,
|
||||
smpWebPortServers = smpWebPortServers.value,
|
||||
tcpConnectTimeout = networkTCPConnectTimeout.value,
|
||||
tcpTimeout = networkTCPTimeout.value,
|
||||
tcpTimeoutPerKb = networkTCPTimeoutPerKb.value,
|
||||
@@ -99,7 +100,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U
|
||||
sessionMode.value = cfg.sessionMode
|
||||
smpProxyMode.value = cfg.smpProxyMode
|
||||
smpProxyFallback.value = cfg.smpProxyFallback
|
||||
smpWebPort.value = cfg.smpWebPort
|
||||
smpWebPortServers.value = cfg.smpWebPortServers
|
||||
networkTCPConnectTimeout.value = cfg.tcpConnectTimeout
|
||||
networkTCPTimeout.value = cfg.tcpTimeout
|
||||
networkTCPTimeoutPerKb.value = cfg.tcpTimeoutPerKb
|
||||
@@ -154,7 +155,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U
|
||||
sessionMode = sessionMode,
|
||||
smpProxyMode = smpProxyMode,
|
||||
smpProxyFallback = smpProxyFallback,
|
||||
smpWebPort,
|
||||
smpWebPortServers,
|
||||
networkTCPConnectTimeout,
|
||||
networkTCPTimeout,
|
||||
networkTCPTimeoutPerKb,
|
||||
@@ -187,7 +188,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U
|
||||
sessionMode: MutableState<TransportSessionMode>,
|
||||
smpProxyMode: MutableState<SMPProxyMode>,
|
||||
smpProxyFallback: MutableState<SMPProxyFallback>,
|
||||
smpWebPort: MutableState<Boolean>,
|
||||
smpWebPortServers: MutableState<SMPWebPortServers>,
|
||||
networkTCPConnectTimeout: MutableState<Long>,
|
||||
networkTCPTimeout: MutableState<Long>,
|
||||
networkTCPTimeoutPerKb: MutableState<Long>,
|
||||
@@ -226,11 +227,16 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (ModalData.() -> Unit) -> U
|
||||
}
|
||||
SectionDividerSpaced()
|
||||
SectionView(stringResource(MR.strings.network_smp_web_port_section_title).uppercase()) {
|
||||
PreferenceToggle(stringResource(MR.strings.network_smp_web_port_toggle), checked = smpWebPort.value) {
|
||||
smpWebPort.value = it
|
||||
}
|
||||
ExposedDropDownSettingRow(
|
||||
stringResource(MR.strings.network_smp_web_port_toggle),
|
||||
SMPWebPortServers.entries.map { it to stringResource(it.text) },
|
||||
smpWebPortServers
|
||||
) { smpWebPortServers.value = it }
|
||||
}
|
||||
SectionTextFooter(String.format(stringResource(MR.strings.network_smp_web_port_footer), if (smpWebPort.value) "443" else "5223"))
|
||||
SectionTextFooter(
|
||||
if (smpWebPortServers.value == SMPWebPortServers.Preset) stringResource(MR.strings.network_smp_web_port_preset_footer)
|
||||
else String.format(stringResource(MR.strings.network_smp_web_port_footer), if (smpWebPortServers.value == SMPWebPortServers.All) "443" else "5223")
|
||||
)
|
||||
SectionDividerSpaced(maxTopPadding = true)
|
||||
|
||||
SectionView(stringResource(MR.strings.network_option_tcp_connection).uppercase()) {
|
||||
@@ -320,7 +326,7 @@ private fun SMPProxyModePicker(
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val values = remember {
|
||||
SMPProxyMode.values().map {
|
||||
SMPProxyMode.entries.map {
|
||||
when (it) {
|
||||
SMPProxyMode.Always -> ValueTitleDesc(SMPProxyMode.Always, generalGetString(MR.strings.network_smp_proxy_mode_always), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_mode_always_description), density))
|
||||
SMPProxyMode.Unknown -> ValueTitleDesc(SMPProxyMode.Unknown, generalGetString(MR.strings.network_smp_proxy_mode_unknown), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_mode_unknown_description), density))
|
||||
@@ -355,7 +361,7 @@ private fun SMPProxyFallbackPicker(
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val values = remember {
|
||||
SMPProxyFallback.values().map {
|
||||
SMPProxyFallback.entries.map {
|
||||
when (it) {
|
||||
SMPProxyFallback.Allow -> ValueTitleDesc(SMPProxyFallback.Allow, generalGetString(MR.strings.network_smp_proxy_fallback_allow), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_fallback_allow_description), density))
|
||||
SMPProxyFallback.AllowProtected -> ValueTitleDesc(SMPProxyFallback.AllowProtected, generalGetString(MR.strings.network_smp_proxy_fallback_allow_protected), escapedHtmlToAnnotatedString(generalGetString(MR.strings.network_smp_proxy_fallback_allow_protected_description), density))
|
||||
@@ -548,7 +554,7 @@ fun PreviewAdvancedNetworkSettingsLayout() {
|
||||
sessionMode = remember { mutableStateOf(TransportSessionMode.User) },
|
||||
smpProxyMode = remember { mutableStateOf(SMPProxyMode.Never) },
|
||||
smpProxyFallback = remember { mutableStateOf(SMPProxyFallback.Allow) },
|
||||
smpWebPort = remember { mutableStateOf(false) },
|
||||
smpWebPortServers = remember { mutableStateOf(SMPWebPortServers.Preset) },
|
||||
networkTCPConnectTimeout = remember { mutableStateOf(10_000000) },
|
||||
networkTCPTimeout = remember { mutableStateOf(10_000000) },
|
||||
networkTCPTimeoutPerKb = remember { mutableStateOf(10_000) },
|
||||
|
||||
@@ -964,6 +964,10 @@
|
||||
<string name="network_smp_web_port_section_title">TCP port for messaging</string>
|
||||
<string name="network_smp_web_port_toggle">Use web port</string>
|
||||
<string name="network_smp_web_port_footer">Use TCP port %1$s when no port is specified.</string>
|
||||
<string name="network_smp_web_port_preset_footer">Use TCP port 443 for preset servers only.</string>
|
||||
<string name="network_smp_web_port_all">All servers</string>
|
||||
<string name="network_smp_web_port_preset">Preset servers</string>
|
||||
<string name="network_smp_web_port_off">Off</string>
|
||||
<string name="appearance_settings">Appearance</string>
|
||||
<string name="customize_theme_title">Customize theme</string>
|
||||
<string name="theme_colors_section_title">INTERFACE COLORS</string>
|
||||
|
||||
@@ -2440,6 +2440,10 @@
|
||||
<string name="report_compose_reason_header_other">Пожаловаться: увидят только модераторы группы.</string>
|
||||
<string name="mute_all_chat">Выключить уведомления для всех</string>
|
||||
<string name="network_smp_web_port_footer">Использовать TCP-порт %1$s, когда порт не указан.</string>
|
||||
<string name="network_smp_web_port_preset_footer">Использовать TCP-порт 443 только для серверов по умолчанию.</string>
|
||||
<string name="network_smp_web_port_all">Все серверы</string>
|
||||
<string name="network_smp_web_port_preset">Серверы по умолчанию</string>
|
||||
<string name="network_smp_web_port_off">Нет</string>
|
||||
<string name="network_smp_web_port_toggle">Использовать веб-порт</string>
|
||||
<string name="privacy_chat_list_open_links_no">Нет</string>
|
||||
<string name="report_compose_reason_header_illegal">Пожаловаться на сообщение: увидят только модераторы группы.</string>
|
||||
|
||||
Reference in New Issue
Block a user