diff --git a/flutter/lib/models/chat_model.dart b/flutter/lib/models/chat_model.dart index 8ee93ae28..eaf8d2243 100644 --- a/flutter/lib/models/chat_model.dart +++ b/flutter/lib/models/chat_model.dart @@ -6,41 +6,68 @@ import 'package:flutter/material.dart'; import '../widgets/overlay.dart'; import 'model.dart'; +class MessageBody { + ChatUser chatUser; + List chatMessages; + MessageBody(this.chatUser, this.chatMessages); + + void add(ChatMessage cm) { + this.chatMessages.add(cm); + } + + void clear() { + this.chatMessages.clear(); + } +} + class ChatModel with ChangeNotifier { static final clientModeID = -1; - final Map> _messages = Map()..[clientModeID] = []; - final ChatUser me = ChatUser( uid: "", name: "Me", ); + late final Map _messages = Map() + ..[clientModeID] = MessageBody(me, []); + final _scroller = ScrollController(); var _currentID = clientModeID; ScrollController get scroller => _scroller; - Map> get messages => _messages; + Map get messages => _messages; int get currentID => _currentID; - ChatUser get currentUser => - FFI.serverModel.clients[_currentID]?.chatUser ?? me; + ChatUser get currentUser { + final user = messages[currentID]?.chatUser; + if (user == null) { + _currentID = clientModeID; + return me; + } else { + return user; + } + } changeCurrentID(int id) { if (_messages.containsKey(id)) { _currentID = id; notifyListeners(); } else { - final chatUser = FFI.serverModel.clients[id]?.chatUser; - if (chatUser == null) { + final client = FFI.serverModel.clients[id]; + if (client == null) { return debugPrint( "Failed to changeCurrentID,remote user doesn't exist"); } - _messages[id] = []; + final chatUser = ChatUser( + uid: client.peerId, + name: client.name, + ); + _messages[id] = MessageBody(chatUser, []); _currentID = id; + notifyListeners(); } } @@ -57,13 +84,15 @@ class ChatModel with ChangeNotifier { uid: FFI.getId(), ); } else { - chatUser = FFI.serverModel.clients[id]?.chatUser; - } - if (chatUser == null) { - return debugPrint("Failed to receive msg,user doesn't exist"); + final client = FFI.serverModel.clients[id]; + if (client == null) { + return debugPrint("Failed to receive msg,user doesn't exist"); + } + chatUser = ChatUser(uid: client.peerId, name: client.name); } + if (!_messages.containsKey(id)) { - _messages[id] = []; + _messages[id] = MessageBody(chatUser, []); } _messages[id]!.add(ChatMessage(text: text, user: chatUser)); _currentID = id; @@ -100,4 +129,8 @@ class ChatModel with ChangeNotifier { hideChatWindowOverlay(); notifyListeners(); } + + resetClientMode() { + _messages[clientModeID]?.clear(); + } } diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index bb5ce7325..a7355ae49 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -221,8 +221,8 @@ class FfiModel with ChangeNotifier { void showMsgBox(String type, String title, String text, bool hasRetry) { msgBox(type, title, text); + _timer?.cancel(); if (hasRetry) { - _timer?.cancel(); _timer = Timer(Duration(seconds: _reconnects), () { FFI.reconnect(); showLoading(translate('Connecting...')); @@ -245,7 +245,7 @@ class FfiModel with ChangeNotifier { if (isPeerAndroid) { _touchMode = true; if (FFI.ffiModel.permissions['keyboard'] != false) { - showMobileActionsOverlay(); + Timer(Duration(milliseconds: 100), showMobileActionsOverlay); } } else { _touchMode = FFI.getByName('peer_option', "touch-mode") != ''; @@ -757,6 +757,7 @@ class FFI { if (isFileTransfer) { setByName('connect_file_transfer', id); } else { + FFI.chatModel.resetClientMode(); setByName('connect', id); } FFI.id = id; diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 91edba104..9eeec886d 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -448,7 +448,6 @@ class Client { bool keyboard = false; bool clipboard = false; bool audio = false; - late ChatUser chatUser; Client(this.authorized, this.isFileTransfer, this.name, this.peerId, this.keyboard, this.clipboard, this.audio); @@ -462,10 +461,6 @@ class Client { keyboard = json['keyboard']; clipboard = json['clipboard']; audio = json['audio']; - chatUser = ChatUser( - uid: peerId, - name: name, - ); } Map toJson() { diff --git a/flutter/lib/pages/chat_page.dart b/flutter/lib/pages/chat_page.dart index 62c520cce..af940a29e 100644 --- a/flutter/lib/pages/chat_page.dart +++ b/flutter/lib/pages/chat_page.dart @@ -21,10 +21,9 @@ class ChatPage extends StatelessWidget implements PageShape { icon: Icon(Icons.group), itemBuilder: (context) { final chatModel = FFI.chatModel; - final serverModel = FFI.serverModel; return chatModel.messages.entries.map((entry) { final id = entry.key; - final user = serverModel.clients[id]?.chatUser ?? chatModel.me; + final user = entry.value.chatUser; return PopupMenuItem( child: Text("${user.name} ${user.uid}"), value: id, @@ -54,7 +53,9 @@ class ChatPage extends StatelessWidget implements PageShape { chatModel.send(chatMsg); }, user: chatModel.me, - messages: chatModel.messages[chatModel.currentID] ?? [], + messages: + chatModel.messages[chatModel.currentID]?.chatMessages ?? + [], // default scrollToBottom has bug https://github.com/fayeed/dash_chat/issues/53 scrollToBottom: false, scrollController: chatModel.scroller, diff --git a/flutter/lib/pages/remote_page.dart b/flutter/lib/pages/remote_page.dart index e323f1ecb..6ddb10238 100644 --- a/flutter/lib/pages/remote_page.dart +++ b/flutter/lib/pages/remote_page.dart @@ -91,7 +91,9 @@ class _RemotePageState extends State { if (v < 100) { SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); - if (chatWindowOverlayEntry == null) { + // [pi.version.isNotEmpty] -> check ready or not,avoid login without soft-keyboard + if (chatWindowOverlayEntry == null && + FFI.ffiModel.pi.version.isNotEmpty) { FFI.invokeMethod("enable_soft_keyboard", false); } } @@ -397,33 +399,33 @@ class _RemotePageState extends State { ] + (isDesktop ? [] - : [ - IconButton( - color: Colors.white, - icon: Icon(Icons.keyboard), - onPressed: openKeyboard), - FFI.ffiModel.isPeerAndroid - ? (keyboard - ? IconButton( - color: Colors.white, - icon: Icon(Icons.build), - onPressed: () { - if (mobileActionsOverlayEntry == null) { - showMobileActionsOverlay(); - } else { - hideMobileActionsOverlay(); - } - }, - ) - : SizedBox.shrink()) - : IconButton( + : FFI.ffiModel.isPeerAndroid + ? [ + IconButton( + color: Colors.white, + icon: Icon(Icons.build), + onPressed: () { + if (mobileActionsOverlayEntry == null) { + showMobileActionsOverlay(); + } else { + hideMobileActionsOverlay(); + } + }, + ) + ] + : [ + IconButton( color: Colors.white, - icon: Icon(FFI.ffiModel.touchMode - ? Icons.touch_app - : Icons.mouse), - onPressed: changeTouchMode, - ) - ]) + + icon: Icon(Icons.keyboard), + onPressed: openKeyboard), + IconButton( + color: Colors.white, + icon: Icon(FFI.ffiModel.touchMode + ? Icons.touch_app + : Icons.mouse), + onPressed: changeTouchMode, + ), + ]) + (isWeb ? [] : [ diff --git a/flutter/lib/widgets/overlay.dart b/flutter/lib/widgets/overlay.dart index 8861321eb..a90492f51 100644 --- a/flutter/lib/widgets/overlay.dart +++ b/flutter/lib/widgets/overlay.dart @@ -97,6 +97,12 @@ showChatIconOverlay({Offset offset = const Offset(200, 50)}) { } if (globalKey.currentState == null || globalKey.currentState!.overlay == null) return; + final bar = navigationBarKey.currentWidget; + if (bar != null) { + if ((bar as BottomNavigationBar).currentIndex == 1) { + return; + } + } final globalOverlayState = globalKey.currentState!.overlay!; final overlay = OverlayEntry(builder: (context) { @@ -118,7 +124,6 @@ showChatIconOverlay({Offset offset = const Offset(200, 50)}) { }); globalOverlayState.insert(overlay); chatIconOverlayEntry = overlay; - debugPrint("created"); } hideChatIconOverlay() { @@ -140,7 +145,6 @@ showChatWindowOverlay() { }); globalOverlayState.insert(overlay); chatWindowOverlayEntry = overlay; - debugPrint("chatEntry created"); } hideChatWindowOverlay() { @@ -237,8 +241,7 @@ showMobileActionsOverlay() { final double overlayW = 200; final double overlayH = 45; final left = (screenW - overlayW) / 2; - final top = screenH - overlayH - 60; - debugPrint("left top : $left,$top"); + final top = screenH - overlayH - 80; final overlay = OverlayEntry(builder: (context) { return DraggableMobileActions( @@ -256,7 +259,6 @@ showMobileActionsOverlay() { }); globalOverlayState.insert(overlay); mobileActionsOverlayEntry = overlay; - debugPrint("mobileActionsOverlay created"); } hideMobileActionsOverlay() { diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index e999ba2ce..6eba46f77 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -15,8 +15,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# 1.1.9-1 works for android, but for ios it becomes 1.1.91, need to set it to 1.1.9-a.1 for iOS, will get 1.1.9.1 -version: 1.1.9-a.1+26 +# 1.1.9-1 works for android, but for ios it becomes 1.1.91, need to set it to 1.1.9-a.1 for iOS, will get 1.1.9.1, but iOS store not allow 4 numbers +version: 1.1.10+27 environment: sdk: ">=2.12.0 <3.0.0"