diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index e22782034..4a0e9ac17 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -436,6 +436,8 @@ class FfiModel with ChangeNotifier { parent.target?.chatModel.onVoiceCallIncoming(); } else if (name == 'update_voice_call_state') { parent.target?.serverModel.updateVoiceCallState(evt); + } else if (name == 'update_port_forward') { + parent.target?.serverModel.updatePortForward(evt); } else if (name == 'fingerprint') { FingerprintState.find(peerId).value = evt['fingerprint'] ?? ''; } else if (name == "sync_peer_hash_password_to_personal_ab") { diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 031a62509..1cd2d0f37 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -768,6 +768,16 @@ class ServerModel with ChangeNotifier { } } + void updatePortForward(Map evt) { + final id = int.tryParse(evt['id']?.toString() ?? ''); + final portForward = evt['port_forward']?.toString() ?? ''; + if (id == null || portForward.isEmpty) return; + final index = _clients.indexWhere((c) => c.id == id); + if (index < 0) return; + _clients[index].portForward = portForward; + notifyListeners(); + } + void androidUpdatekeepScreenOn() async { if (!isAndroid) return; var floatingWindowDisabled = diff --git a/src/flutter.rs b/src/flutter.rs index f4971f18c..0ea8b69df 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -1517,6 +1517,13 @@ pub mod connection_manager { ); } + fn update_port_forward(&self, id: i32, port_forward: String) { + self.push_event( + "update_port_forward", + &[("id", &id.to_string()), ("port_forward", &port_forward)], + ); + } + fn change_theme(&self, dark: String) { self.push_event("theme", &[("dark", &dark)]); } diff --git a/src/ipc.rs b/src/ipc.rs index 804b89db6..01e345056 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -348,6 +348,7 @@ pub enum Data { name: String, enabled: bool, }, + UpdatePortForward(String), SystemInfo(Option), ClickTime(i64), #[cfg(not(any(target_os = "android", target_os = "ios")))] diff --git a/src/server/connection.rs b/src/server/connection.rs index 314a6489f..4a4d1c77f 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2241,7 +2241,8 @@ impl Connection { return; }; self.port_forward_address = label.clone(); - log::debug!("port forward targets now {}", label); + log::info!("port forward targets now {}", label); + self.send_to_cm(ipc::Data::UpdatePortForward(label)); } #[inline] diff --git a/src/ui/cm.rs b/src/ui/cm.rs index 4a68a571d..bd9784fa6 100644 --- a/src/ui/cm.rs +++ b/src/ui/cm.rs @@ -72,6 +72,10 @@ impl InvokeUiCM for SciterHandler { ); } + fn update_port_forward(&self, id: i32, port_forward: String) { + self.call("updatePortForward", &make_args!(id, port_forward)); + } + fn file_transfer_log(&self, _action: &str, _log: &str) {} } diff --git a/src/ui/cm.tis b/src/ui/cm.tis index f306e9032..3766b5a4a 100644 --- a/src/ui/cm.tis +++ b/src/ui/cm.tis @@ -434,6 +434,13 @@ handler.addConnection = function(id, is_file_transfer, is_view_camera, is_termin } } +handler.updatePortForward = function(id, port_forward) { + connections.map(function(c) { + if (c.id == id) c.port_forward = port_forward; + }); + update(); +} + handler.removeConnection = function(id, close) { var i = -1; connections.map(function(c, idx) { diff --git a/src/ui_cm_interface.rs b/src/ui_cm_interface.rs index c659170e3..299da2a0b 100644 --- a/src/ui_cm_interface.rs +++ b/src/ui_cm_interface.rs @@ -196,6 +196,8 @@ pub trait InvokeUiCM: Send + Clone + 'static + Sized { fn update_voice_call_state(&self, client: &Client); fn file_transfer_log(&self, action: &str, log: &str); + + fn update_port_forward(&self, id: i32, port_forward: String); } impl Deref for ConnectionManager { @@ -602,6 +604,17 @@ impl IpcTaskRunner { } } } + Data::UpdatePortForward(port_forward) => { + let updated = { + let mut clients = CLIENTS.write().unwrap(); + clients.get_mut(&self.conn_id).map(|c| { + c.port_forward = port_forward.clone(); + }) + }; + if updated.is_some() { + self.cm.ui_handler.update_port_forward(self.conn_id, port_forward); + } + } Data::FS(mut fs) => { if let ipc::FS::WriteBlock { id, file_num, data: _, compressed } = fs { if let Ok(bytes) = self.stream.next_raw().await {