diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 5cce43cff..c9bcc0477 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -37,7 +37,8 @@ import 'platform_model.dart'; typedef HandleMsgBox = Function(Map evt, String id); typedef ReconnectHandle = Function(OverlayDialogManager, SessionID, bool); -final _waitForImage = {}; +final _waitForImageDialogShow = {}; +final _waitForFirstImage = {}; final _constSessionId = Uuid().v4obj(); class FfiModel with ChangeNotifier { @@ -351,6 +352,8 @@ class FfiModel with ChangeNotifier { showElevationError(sessionId, type, title, text, dialogManager); } else if (type == 'relay-hint') { showRelayHintDialog(sessionId, type, title, text, dialogManager, peerId); + } else if (text == 'Connected, waiting for image...') { + showConnectedWaitingForImage(dialogManager, sessionId, type, title, text); } else { var hasRetry = evt['hasRetry'] == 'true'; showMsgBox(sessionId, type, title, text, link, hasRetry, dialogManager); @@ -416,6 +419,27 @@ class FfiModel with ChangeNotifier { }); } + void showConnectedWaitingForImage(OverlayDialogManager dialogManager, + SessionID sessionId, String type, String title, String text) { + onClose() { + closeConnection(); + } + + Future.delayed(Duration.zero, () async { + await dialogManager.show( + (setState, close, context) => CustomAlertDialog( + title: null, + content: SelectionArea(child: msgboxContent(type, title, text)), + actions: [ + dialogButton("Cancel", onPressed: onClose, isOutline: true) + ], + onCancel: onClose), + tag: '$sessionId-waiting-for-image', + ); + _waitForImageDialogShow[sessionId] = true; + }); + } + _updateSessionWidthHeight(SessionID sessionId) { parent.target?.canvasModel.updateViewStyle(); if (display.width <= 0 || display.height <= 0) { @@ -478,13 +502,8 @@ class FfiModel with ChangeNotifier { _updateSessionWidthHeight(sessionId); } if (displays.isNotEmpty) { - parent.target?.dialogManager.showLoading( - translate('Connected, waiting for image...'), - onCancel: closeConnection, - tag: '$peerId-waiting-for-image'); - _waitForImage[sessionId] = true; _reconnects = 1; - bind.sessionOnWaitingForImageDialogShow(sessionId: sessionId); + _waitForFirstImage[sessionId] = true; } Map features = json.decode(evt['features']); _pi.features.privacyMode = features['privacy_mode'] == 1; @@ -629,24 +648,6 @@ class ImageModel with ChangeNotifier { addCallbackOnFirstImage(Function(String) cb) => callbacksOnFirstImage.add(cb); onRgba(Uint8List rgba) { - final waitforImage = _waitForImage[sessionId]; - if (waitforImage == null) { - debugPrint('Exception, peer $id not found for waiting image'); - return; - } - - if (waitforImage == true) { - _waitForImage[sessionId] = false; - parent.target?.dialogManager.dismissAll(); - clearWaitingForImage(parent.target?.dialogManager, id); - - if (isDesktop) { - for (final cb in callbacksOnFirstImage) { - cb(id); - } - } - } - final pid = parent.target?.id; img.decodeImageFromPixels( rgba, @@ -1687,16 +1688,7 @@ class FFI { } } else if (message is EventToUI_Rgba) { if (useTextureRender) { - if (_waitForImage[sessionId]!) { - _waitForImage[sessionId] = false; - dialogManager.dismissAll(); - for (final cb in imageModel.callbacksOnFirstImage) { - cb(id); - } - await canvasModel.updateViewStyle(); - await canvasModel.updateScrollStyle(); - clearWaitingForImage(dialogManager, id); - } + onEvent2UIRgba(); } else { // Fetch the image buffer from rust codes. final sz = platformFFI.getRgbaSize(sessionId); @@ -1705,6 +1697,7 @@ class FFI { } final rgba = platformFFI.getRgba(sessionId, sz); if (rgba != null) { + onEvent2UIRgba(); imageModel.onRgba(rgba); } } @@ -1715,6 +1708,22 @@ class FFI { this.id = id; } + void onEvent2UIRgba() async { + if (_waitForImageDialogShow[sessionId] == true) { + _waitForImageDialogShow[sessionId] = false; + clearWaitingForImage(dialogManager, sessionId); + } + if (_waitForFirstImage[sessionId] == true) { + _waitForFirstImage[sessionId] = false; + dialogManager.dismissAll(); + await canvasModel.updateViewStyle(); + await canvasModel.updateScrollStyle(); + for (final cb in imageModel.callbacksOnFirstImage) { + cb(id); + } + } + } + /// Login with [password], choose if the client should [remember] it. void login(String osUsername, String osPassword, SessionID sessionId, String password, bool remember) { @@ -1891,11 +1900,11 @@ Future initializeCursorAndCanvas(FFI ffi) async { ffi.canvasModel.update(xCanvas, yCanvas, scale); } -clearWaitingForImage(OverlayDialogManager? dialogManager, String id) { +clearWaitingForImage(OverlayDialogManager? dialogManager, SessionID sessionId) { final durations = [100, 500, 1000, 2000]; for (var duration in durations) { Future.delayed(Duration(milliseconds: duration), () { - dialogManager?.dismissByTag('$id-waiting-for-image'); + dialogManager?.dismissByTag('$sessionId-waiting-for-image'); }); } } diff --git a/src/flutter.rs b/src/flutter.rs index ae20b26a9..88290897d 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -238,6 +238,13 @@ impl VideoRenderer { // It is also Ok to skip this check. if self.width != rgba.w || self.height != rgba.h { + log::error!( + "width/height mismatch: ({},{}) != ({},{})", + self.width, + self.height, + rgba.w, + rgba.h + ); return; } @@ -338,14 +345,6 @@ impl FlutterHandler { *self.notify_rendered.write().unwrap() = false; self.renderer.write().unwrap().set_size(width, height); } - - pub fn on_waiting_for_image_dialog_show(&self) { - #[cfg(any(feature = "flutter_texture_render"))] - { - *self.notify_rendered.write().unwrap() = false; - } - // rgba array render will notify every frame - } } impl InvokeUiSession for FlutterHandler { diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 3c483dbce..c4e9c2eb3 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1254,12 +1254,6 @@ pub fn session_change_prefer_codec(session_id: SessionID) { } } -pub fn session_on_waiting_for_image_dialog_show(session_id: SessionID) { - if let Some(session) = SESSIONS.read().unwrap().get(&session_id) { - session.ui_handler.on_waiting_for_image_dialog_show(); - } -} - pub fn main_set_home_dir(_home: String) { #[cfg(any(target_os = "android", target_os = "ios"))] { diff --git a/src/ui_interface.rs b/src/ui_interface.rs index bcc2ab54f..2979f4ceb 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -3,9 +3,7 @@ use hbb_common::password_security; use hbb_common::{ allow_err, config::{self, Config, LocalConfig, PeerConfig}, - directories_next, log, - sodiumoxide::base64, - tokio, + directories_next, log, tokio, }; use hbb_common::{ bytes::Bytes, @@ -615,6 +613,7 @@ pub fn peer_to_map(id: String, p: PeerConfig) -> HashMap<&'static str, String> { #[cfg(feature = "flutter")] pub fn peer_to_map_ab(id: String, p: PeerConfig) -> HashMap<&'static str, String> { + use hbb_common::sodiumoxide::base64; let mut m = peer_to_map(id, p.clone()); m.insert( "hash",