diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 26595880db..bfcec69da8 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -1392,10 +1392,10 @@ object ChatController { chatModel.remoteHosts.addAll(hosts) } - suspend fun startRemoteHost(rhId: Long?, multicast: Boolean = false): Pair? { + suspend fun startRemoteHost(rhId: Long?, multicast: Boolean = false): Triple? { val r = sendCmd(null, CC.StartRemoteHost(rhId, multicast)) - if (r is CR.RemoteHostStarted) return r.remoteHost_ to r.invitation - apiErrorAlert("listRemoteHosts", generalGetString(MR.strings.error_alert_title), r) + if (r is CR.RemoteHostStarted) return Triple(r.remoteHost_, r.invitation, r.ctrlPort) + apiErrorAlert("startRemoteHost", generalGetString(MR.strings.error_alert_title), r) return null } @@ -1851,7 +1851,7 @@ object ChatController { generalGetString(MR.strings.remote_host_was_disconnected_toast).format(disconnectedHost.hostDeviceName.ifEmpty { disconnectedHost.remoteHostId.toString() }) ) } - if (chatModel.remoteHostId == r.remoteHostId_) { + if (chatModel.remoteHostId() == r.remoteHostId_) { chatModel.currentRemoteHost.value = null switchUIRemoteHost(null) } @@ -3774,7 +3774,7 @@ sealed class CR { // remote events (desktop) @Serializable @SerialName("remoteHostList") class RemoteHostList(val remoteHosts: List): CR() @Serializable @SerialName("currentRemoteHost") class CurrentRemoteHost(val remoteHost_: RemoteHostInfo?): CR() - @Serializable @SerialName("remoteHostStarted") class RemoteHostStarted(val remoteHost_: RemoteHostInfo?, val invitation: String): CR() + @Serializable @SerialName("remoteHostStarted") class RemoteHostStarted(val remoteHost_: RemoteHostInfo?, val invitation: String, val ctrlPort: String): CR() @Serializable @SerialName("remoteHostSessionCode") class RemoteHostSessionCode(val remoteHost_: RemoteHostInfo?, val sessionCode: String): CR() @Serializable @SerialName("newRemoteHost") class NewRemoteHost(val remoteHost: RemoteHostInfo): CR() @Serializable @SerialName("remoteHostConnected") class RemoteHostConnected(val remoteHost: RemoteHostInfo): CR() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt index 21b71d876b..6e12681dd2 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Utils.kt @@ -56,7 +56,7 @@ fun annotatedStringResource(id: StringResource): AnnotatedString { fun annotatedStringResource(id: StringResource, vararg args: Any?): AnnotatedString { val density = LocalDensity.current return remember(id) { - escapedHtmlToAnnotatedString(id.localized().format(args), density) + escapedHtmlToAnnotatedString(id.localized().format(args = args), density) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt index 974f71cf2c..163d15ce62 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt @@ -161,7 +161,8 @@ private fun ConnectMobileViewLayout( title: String, invitation: String?, deviceName: String?, - sessionCode: String? + sessionCode: String?, + port: String? ) { Column( Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), @@ -169,13 +170,14 @@ private fun ConnectMobileViewLayout( ) { AppBarTitle(title) SectionView { - if (invitation != null && sessionCode == null) { + if (invitation != null && sessionCode == null && port != null) { QRCode( invitation, Modifier .padding(start = DEFAULT_PADDING, top = DEFAULT_PADDING_HALF, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING_HALF) .aspectRatio(1f) ) SectionTextFooter(annotatedStringResource(MR.strings.open_on_mobile_and_scan_qr_code)) + SectionTextFooter(annotatedStringResource(MR.strings.waiting_for_mobile_to_connect_on_port, port)) if (remember { controller.appPrefs.developerTools.state }.value) { val clipboard = LocalClipboardManager.current @@ -232,6 +234,7 @@ fun connectMobileDevice(rh: RemoteHostInfo, connecting: MutableState) { private fun showAddingMobileDevice(connecting: MutableState) { ModalManager.start.showModalCloseable { close -> val invitation = rememberSaveable { mutableStateOf(null) } + val port = rememberSaveable { mutableStateOf(null) } val pairing = remember { chatModel.newRemoteHostPairing } val sessionCode = when (val state = pairing.value?.second) { is RemoteHostSessionState.PendingConfirmation -> state.sessionCode @@ -247,7 +250,8 @@ private fun showAddingMobileDevice(connecting: MutableState) { title = if (cachedSessionCode == null) stringResource(MR.strings.link_a_mobile) else stringResource(MR.strings.verify_connection), invitation = invitation.value, deviceName = remoteDeviceName, - sessionCode = cachedSessionCode + sessionCode = cachedSessionCode, + port = port.value ) val oldRemoteHostId by remember { mutableStateOf(chatModel.currentRemoteHost.value?.remoteHostId) } LaunchedEffect(remember { chatModel.currentRemoteHost }.value) { @@ -266,6 +270,7 @@ private fun showAddingMobileDevice(connecting: MutableState) { if (r != null) { connecting.value = true invitation.value = r.second + port.value = r.third } } onDispose { @@ -284,6 +289,7 @@ private fun showConnectMobileDevice(rh: RemoteHostInfo, connecting: MutableState ModalManager.start.showModalCloseable { close -> val pairing = remember { chatModel.newRemoteHostPairing } val invitation = rememberSaveable { mutableStateOf(null) } + val port = rememberSaveable { mutableStateOf(null) } val sessionCode = when (val state = pairing.value?.second) { is RemoteHostSessionState.PendingConfirmation -> state.sessionCode else -> null @@ -298,6 +304,7 @@ private fun showConnectMobileDevice(rh: RemoteHostInfo, connecting: MutableState invitation = invitation.value, deviceName = pairing.value?.first?.hostDeviceName ?: rh.hostDeviceName, sessionCode = cachedSessionCode, + port = port.value ) var remoteHostId by rememberSaveable { mutableStateOf(null) } LaunchedEffect(Unit) { @@ -307,6 +314,7 @@ private fun showConnectMobileDevice(rh: RemoteHostInfo, connecting: MutableState connecting.value = true remoteHostId = rh_?.remoteHostId invitation.value = inv + port.value = r.third } } LaunchedEffect(remember { chatModel.currentRemoteHost }.value) { @@ -343,7 +351,8 @@ private fun showConnectedMobileDevice(rh: RemoteHostInfo, disconnectHost: () -> title = stringResource(MR.strings.connected_to_mobile), invitation = null, deviceName = rh.hostDeviceName, - sessionCode = sessionCode + sessionCode = sessionCode, + port = null, ) Spacer(Modifier.height(DEFAULT_PADDING_HALF)) SectionItemView(disconnectHost) { diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index 4f29d8cb34..622ba4abb5 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -1662,7 +1662,8 @@ %s]]> Disconnect desktop? Only one device can work at the same time - Use from desktop in mobile app and scan QR code]]> + Use from desktop in mobile app and scan QR code.]]> + %s]]> Bad desktop address Incompatible version Desktop app version %s is not compatible with this app. diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml index 093ca05646..8aa847c78b 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/it/strings.xml @@ -1465,7 +1465,7 @@ Nuovo dispositivo mobile Indirizzo desktop Solo un dispositivo può funzionare nello stesso momento - Usa dal desktop nell\'app mobile e scansiona il codice QR]]> + Usa dal desktop nell\'app mobile e scansiona il codice QR.]]> Versione incompatibile (nuovo)]]> Scollegare il desktop? diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml index c112844395..801df9d609 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/nl/strings.xml @@ -1463,7 +1463,7 @@ Nieuw mobiel apparaat Desktop adres Er kan slechts één apparaat tegelijkertijd werken - Gebruik vanaf desktop in de mobiele app en scan de QR-code]]> + Gebruik vanaf desktop in de mobiele app en scan de QR-code.]]> Incompatibele versie (nieuw)]]> Desktop ontkoppelen? diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml index e672c189a4..90f475135f 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/zh-rCN/strings.xml @@ -1465,7 +1465,7 @@ 新移动设备 桌面地址 同一时刻只有一台设备可以工作 - 从桌面使用并扫描二维码]]> + 从桌面使用并扫描二维码.]]> 不兼容的版本 (新)]]> 取消链接桌面端?