mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-04-25 14:12:27 +00:00
ui: differentiate remote ctrl errors, better error texts (#4302)
This commit is contained in:
@@ -1957,12 +1957,28 @@ func processReceivedMsg(_ res: ChatResponse) async {
|
||||
let state = UIRemoteCtrlSessionState.connected(remoteCtrl: remoteCtrl, sessionCode: m.remoteCtrlSession?.sessionCode ?? "")
|
||||
m.remoteCtrlSession = m.remoteCtrlSession?.updateState(state)
|
||||
}
|
||||
case .remoteCtrlStopped:
|
||||
case let .remoteCtrlStopped(_, rcStopReason):
|
||||
// This delay is needed to cancel the session that fails on network failure,
|
||||
// e.g. when user did not grant permission to access local network yet.
|
||||
if let sess = m.remoteCtrlSession {
|
||||
await MainActor.run {
|
||||
m.remoteCtrlSession = nil
|
||||
dismissAllSheets() {
|
||||
switch rcStopReason {
|
||||
case .connectionFailed(.errorAgent(.RCP(.identity))):
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title: "Connection with desktop stopped",
|
||||
message: "This link was used with another mobile device, please create a new link on the desktop."
|
||||
)
|
||||
default:
|
||||
AlertManager.shared.showAlert(Alert(
|
||||
title: Text("Connection with desktop stopped"),
|
||||
message: Text("Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection.\nPlease share any other issues with the developers."),
|
||||
primaryButton: .default(Text("Ok")),
|
||||
secondaryButton: .default(Text("Copy error")) { UIPasteboard.general.string = String(describing: rcStopReason) }
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
if case .connected = sess.sessionState {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
|
||||
@@ -181,23 +181,27 @@ struct ConnectDesktopView: View {
|
||||
}
|
||||
|
||||
private func connectingDesktopView(_ session: RemoteCtrlSession, _ rc: RemoteCtrlInfo?) -> some View {
|
||||
List {
|
||||
Section("Connecting to desktop") {
|
||||
ctrlDeviceNameText(session, rc)
|
||||
ctrlDeviceVersionText(session)
|
||||
}
|
||||
ZStack {
|
||||
List {
|
||||
Section("Connecting to desktop") {
|
||||
ctrlDeviceNameText(session, rc)
|
||||
ctrlDeviceVersionText(session)
|
||||
}
|
||||
|
||||
if let sessCode = session.sessionCode {
|
||||
Section("Session code") {
|
||||
sessionCodeText(sessCode)
|
||||
if let sessCode = session.sessionCode {
|
||||
Section("Session code") {
|
||||
sessionCodeText(sessCode)
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
disconnectButton()
|
||||
}
|
||||
}
|
||||
.navigationTitle("Connecting to desktop")
|
||||
|
||||
Section {
|
||||
disconnectButton()
|
||||
}
|
||||
ProgressView().scaleEffect(2)
|
||||
}
|
||||
.navigationTitle("Connecting to desktop")
|
||||
}
|
||||
|
||||
private func searchingDesktopView() -> some View {
|
||||
|
||||
@@ -980,7 +980,7 @@ public enum ChatResponse: Decodable, Error {
|
||||
case let .remoteCtrlConnecting(remoteCtrl_, ctrlAppInfo, appVersion): return "remoteCtrl_:\n\(String(describing: remoteCtrl_))\nctrlAppInfo:\n\(String(describing: ctrlAppInfo))\nappVersion: \(appVersion)"
|
||||
case let .remoteCtrlSessionCode(remoteCtrl_, sessionCode): return "remoteCtrl_:\n\(String(describing: remoteCtrl_))\nsessionCode: \(sessionCode)"
|
||||
case let .remoteCtrlConnected(remoteCtrl): return String(describing: remoteCtrl)
|
||||
case .remoteCtrlStopped: return noDetails
|
||||
case let .remoteCtrlStopped(rcsState, rcStopReason): return "rcsState: \(String(describing: rcsState))\nrcStopReason: \(String(describing: rcStopReason))"
|
||||
case let .contactPQEnabled(u, contact, pqEnabled): return withUser(u, "contact: \(String(describing: contact))\npqEnabled: \(pqEnabled)")
|
||||
case let .versionInfo(versionInfo, chatMigrations, agentMigrations): return "\(String(describing: versionInfo))\n\nchat migrations: \(chatMigrations.map(\.upName))\n\nagent migrations: \(agentMigrations.map(\.upName))"
|
||||
case .cmdOk: return noDetails
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
package chat.simplex.common.model
|
||||
|
||||
import SectionItemView
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import chat.simplex.common.model.ChatController.getNetCfg
|
||||
import chat.simplex.common.model.ChatController.setNetCfg
|
||||
import chat.simplex.common.model.ChatModel.updatingChatsMutex
|
||||
@@ -12,7 +21,6 @@ import dev.icerock.moko.resources.compose.painterResource
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.call.*
|
||||
import chat.simplex.common.views.chat.group.toggleShowMemberMessages
|
||||
import chat.simplex.common.views.migration.MigrationFileLinkData
|
||||
import chat.simplex.common.views.onboarding.OnboardingStage
|
||||
import chat.simplex.common.views.usersettings.*
|
||||
@@ -20,6 +28,7 @@ import com.charleskorn.kaml.Yaml
|
||||
import com.charleskorn.kaml.YamlConfiguration
|
||||
import chat.simplex.res.MR
|
||||
import com.russhwolf.settings.Settings
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
@@ -2194,15 +2203,43 @@ object ChatController {
|
||||
val sess = chatModel.remoteCtrlSession.value
|
||||
if (sess != null) {
|
||||
chatModel.remoteCtrlSession.value = null
|
||||
ModalManager.fullscreen.closeModals()
|
||||
fun showAlert(chatError: ChatError) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.remote_ctrl_was_disconnected_title),
|
||||
if (chatError is ChatError.ChatErrorRemoteCtrl) {
|
||||
chatError.remoteCtrlError.localizedString
|
||||
} else {
|
||||
generalGetString(MR.strings.remote_ctrl_disconnected_with_reason).format(chatError.string)
|
||||
}
|
||||
)
|
||||
when {
|
||||
r.rcStopReason is RemoteCtrlStopReason.ConnectionFailed
|
||||
&& r.rcStopReason.chatError is ChatError.ChatErrorAgent
|
||||
&& r.rcStopReason.chatError.agentError is AgentErrorType.RCP
|
||||
&& r.rcStopReason.chatError.agentError.rcpErr is RCErrorType.IDENTITY ->
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.remote_ctrl_was_disconnected_title),
|
||||
text = generalGetString(MR.strings.remote_ctrl_connection_stopped_identity_desc)
|
||||
)
|
||||
else ->
|
||||
AlertManager.shared.showAlertDialogButtonsColumn(
|
||||
title = generalGetString(MR.strings.remote_ctrl_was_disconnected_title),
|
||||
text = if (chatError is ChatError.ChatErrorRemoteCtrl) {
|
||||
chatError.remoteCtrlError.localizedString
|
||||
} else {
|
||||
generalGetString(MR.strings.remote_ctrl_connection_stopped_desc)
|
||||
},
|
||||
buttons = {
|
||||
Column {
|
||||
SectionItemView({
|
||||
AlertManager.shared.hideAlert()
|
||||
}) {
|
||||
Text(stringResource(MR.strings.ok), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
val clipboard = LocalClipboardManager.current
|
||||
SectionItemView({
|
||||
clipboard.setText(AnnotatedString(json.encodeToString(r.rcStopReason)))
|
||||
AlertManager.shared.hideAlert()
|
||||
}) {
|
||||
Text(stringResource(MR.strings.copy_error), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
when (r.rcStopReason) {
|
||||
is RemoteCtrlStopReason.DiscoveryFailed -> showAlert(r.rcStopReason.chatError)
|
||||
@@ -4716,7 +4753,7 @@ sealed class CR {
|
||||
(if (remoteCtrl_ == null) "null" else json.encodeToString(remoteCtrl_)) +
|
||||
"\nsessionCode: $sessionCode"
|
||||
is RemoteCtrlConnected -> json.encodeToString(remoteCtrl)
|
||||
is RemoteCtrlStopped -> noDetails()
|
||||
is RemoteCtrlStopped -> "rcsState: $rcsState\nrcsStopReason: $rcStopReason"
|
||||
is ContactPQAllowed -> withUser(user, "contact: ${contact.id}\npqEncryption: $pqEncryption")
|
||||
is ContactPQEnabled -> withUser(user, "contact: ${contact.id}\npqEnabled: $pqEnabled")
|
||||
is VersionInfo -> "version ${json.encodeToString(versionInfo)}\n\n" +
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
@@ -166,6 +167,24 @@ private fun ConnectingDesktop(session: RemoteCtrlSession, rc: RemoteCtrlInfo?) {
|
||||
SectionView {
|
||||
DisconnectButton(onClick = ::disconnectDesktop)
|
||||
}
|
||||
|
||||
ProgressIndicator()
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ProgressIndicator() {
|
||||
Box(
|
||||
Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator(
|
||||
Modifier
|
||||
.padding(horizontal = 2.dp)
|
||||
.size(30.dp),
|
||||
color = MaterialTheme.colors.secondary,
|
||||
strokeWidth = 3.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -1921,6 +1921,9 @@
|
||||
<string name="remote_ctrl_was_disconnected_title">Connection stopped</string>
|
||||
<string name="remote_host_disconnected_from"><![CDATA[Disconnected from mobile <b>%s</b> with the reason: %s]]></string>
|
||||
<string name="remote_ctrl_disconnected_with_reason">Disconnected with the reason: %s</string>
|
||||
<string name="remote_ctrl_connection_stopped_desc">Please check that mobile and desktop are connected to the same local network, and that desktop firewall allows the connection.\nPlease share any other issues with the developers.</string>
|
||||
<string name="remote_ctrl_connection_stopped_identity_desc">This link was used with another mobile device, please create a new link on the desktop.</string>
|
||||
<string name="copy_error">Copy error</string>
|
||||
<string name="disconnect_desktop_question">Disconnect desktop?</string>
|
||||
<string name="only_one_device_can_work_at_the_same_time">Only one device can work at the same time</string>
|
||||
<string name="open_on_mobile_and_scan_qr_code"><![CDATA[Open <i>Use from desktop</i> in mobile app and scan QR code.]]></string>
|
||||
|
||||
Reference in New Issue
Block a user