Merge pull request #4939 from 21pages/fix_chat

opt chat model
This commit is contained in:
RustDesk 2023-07-10 16:10:23 +08:00 committed by GitHub
commit 4e19777ba0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 40 deletions

View File

@ -9,6 +9,7 @@ import '../../mobile/pages/home_page.dart';
enum ChatPageType { enum ChatPageType {
mobileMain, mobileMain,
desktopCM,
} }
class ChatPage extends StatelessWidget implements PageShape { class ChatPage extends StatelessWidget implements PageShape {
@ -43,30 +44,39 @@ class ChatPage extends StatelessWidget implements PageShape {
// only mobile need [appBarActions], just bind gFFI.chatModel // only mobile need [appBarActions], just bind gFFI.chatModel
final chatModel = gFFI.chatModel; final chatModel = gFFI.chatModel;
return chatModel.messages.entries.map((entry) { return chatModel.messages.entries.map((entry) {
final id = entry.key; final key = entry.key;
final user = entry.value.chatUser; final user = entry.value.chatUser;
final client = gFFI.serverModel.clients final client = gFFI.serverModel.clients
.firstWhereOrNull((e) => e.id == id.connId); .firstWhereOrNull((e) => e.id == key.connId);
final connected =
gFFI.serverModel.clients.any((e) => e.id == key.connId);
return PopupMenuItem<MessageKey>( return PopupMenuItem<MessageKey>(
child: Row( child: Row(
children: [ children: [
Icon( Icon(
id.isOut key.isOut
? Icons.call_made_rounded ? Icons.call_made_rounded
: Icons.call_received_rounded, : Icons.call_received_rounded,
color: MyTheme.accent) color: MyTheme.accent)
.marginOnly(right: 6), .marginOnly(right: 6),
Text("${user.firstName} ${user.id}"), Text("${user.firstName} ${user.id}"),
if (connected)
Container(
width: 10,
height: 10,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.green),
).marginSymmetric(horizontal: 2),
if (client != null) if (client != null)
unreadMessageCountBuilder(client.unreadChatMessageCount) unreadMessageCountBuilder(client.unreadChatMessageCount)
], ],
), ),
value: id, value: key,
); );
}).toList(); }).toList();
}, },
onSelected: (id) { onSelected: (key) {
gFFI.chatModel.changeCurrentID(id); gFFI.chatModel.changeCurrentKey(key);
}) })
]; ];
@ -79,6 +89,17 @@ class ChatPage extends StatelessWidget implements PageShape {
child: Consumer<ChatModel>( child: Consumer<ChatModel>(
builder: (context, chatModel, child) { builder: (context, chatModel, child) {
final currentUser = chatModel.currentUser; final currentUser = chatModel.currentUser;
final readOnly = type == ChatPageType.mobileMain &&
(chatModel.currentKey.connId == ChatModel.clientModeID ||
gFFI.serverModel.clients.every((e) =>
e.id != chatModel.currentKey.connId ||
chatModel.currentUser == null)) ||
type == ChatPageType.desktopCM &&
gFFI.serverModel.clients
.firstWhereOrNull(
(e) => e.id == chatModel.currentKey.connId)
?.disconnected ==
true;
return Stack( return Stack(
children: [ children: [
LayoutBuilder(builder: (context, constraints) { LayoutBuilder(builder: (context, constraints) {
@ -88,11 +109,7 @@ class ChatPage extends StatelessWidget implements PageShape {
messages: chatModel messages: chatModel
.messages[chatModel.currentKey]?.chatMessages ?? .messages[chatModel.currentKey]?.chatMessages ??
[], [],
readOnly: type == ChatPageType.mobileMain && readOnly: readOnly,
(chatModel.currentKey.connId ==
ChatModel.clientModeID ||
gFFI.serverModel.clients.every(
(e) => e.id != chatModel.currentKey.connId)),
inputOptions: InputOptions( inputOptions: InputOptions(
focusNode: chatModel.inputNode, focusNode: chatModel.inputNode,
textController: chatModel.textController, textController: chatModel.textController,

View File

@ -103,7 +103,7 @@ class ConnectionManagerState extends State<ConnectionManager> {
final client = final client =
gFFI.serverModel.clients.firstWhereOrNull((e) => e.id == client_id); gFFI.serverModel.clients.firstWhereOrNull((e) => e.id == client_id);
if (client != null) { if (client != null) {
gFFI.chatModel.changeCurrentID(MessageKey(client.peerId, client.id)); gFFI.chatModel.changeCurrentKey(MessageKey(client.peerId, client.id));
if (client.unreadChatMessageCount.value > 0) { if (client.unreadChatMessageCount.value > 0) {
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
client.unreadChatMessageCount.value = 0; client.unreadChatMessageCount.value = 0;
@ -181,7 +181,8 @@ class ConnectionManagerState extends State<ConnectionManager> {
right: BorderSide( right: BorderSide(
color: Theme.of(context) color: Theme.of(context)
.dividerColor))), .dividerColor))),
child: ChatPage()), child:
ChatPage(type: ChatPageType.desktopCM)),
), ),
) )
: Offstage(), : Offstage(),

View File

@ -1453,7 +1453,7 @@ class _ChatMenuState extends State<_ChatMenu> {
initPos = Offset(pos.dx, pos.dy + _ToolbarTheme.dividerHeight); initPos = Offset(pos.dx, pos.dy + _ToolbarTheme.dividerHeight);
} }
widget.ffi.chatModel.changeCurrentID( widget.ffi.chatModel.changeCurrentKey(
MessageKey(widget.ffi.id, ChatModel.clientModeID)); MessageKey(widget.ffi.id, ChatModel.clientModeID));
widget.ffi.chatModel.toggleChatOverlay(chatInitPos: initPos); widget.ffi.chatModel.toggleChatOverlay(chatInitPos: initPos);
}); });

View File

@ -72,6 +72,8 @@ class _RemotePageState extends State<RemotePage> {
keyboardVisibilityController.onChange.listen(onSoftKeyboardChanged); keyboardVisibilityController.onChange.listen(onSoftKeyboardChanged);
_blockableOverlayState.applyFfi(gFFI); _blockableOverlayState.applyFfi(gFFI);
initSharedStates(widget.id); initSharedStates(widget.id);
gFFI.chatModel
.changeCurrentKey(MessageKey(widget.id, ChatModel.clientModeID));
} }
@override @override
@ -351,7 +353,7 @@ class _RemotePageState extends State<RemotePage> {
color: Colors.white, color: Colors.white,
icon: Icon(Icons.message), icon: Icon(Icons.message),
onPressed: () { onPressed: () {
gFFI.chatModel.changeCurrentID(MessageKey( gFFI.chatModel.changeCurrentKey(MessageKey(
widget.id, ChatModel.clientModeID)); widget.id, ChatModel.clientModeID));
gFFI.chatModel.toggleChatOverlay(); gFFI.chatModel.toggleChatOverlay();
}, },

View File

@ -420,7 +420,7 @@ class ConnectionManager extends StatelessWidget {
? const SizedBox.shrink() ? const SizedBox.shrink()
: IconButton( : IconButton(
onPressed: () { onPressed: () {
gFFI.chatModel.changeCurrentID( gFFI.chatModel.changeCurrentKey(
MessageKey(client.peerId, client.id)); MessageKey(client.peerId, client.id));
final bar = navigationBarKey.currentWidget; final bar = navigationBarKey.currentWidget;
if (bar != null) { if (bar != null) {

View File

@ -12,6 +12,7 @@ import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/state_model.dart'; import 'package:flutter_hbb/models/state_model.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:uuid/uuid.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@ -77,13 +78,13 @@ class ChatModel with ChangeNotifier {
} }
final ChatUser me = ChatUser( final ChatUser me = ChatUser(
id: "", id: Uuid().v4().toString(),
firstName: translate("Me"), firstName: translate("Me"),
); );
late final Map<MessageKey, MessageBody> _messages = {}; late final Map<MessageKey, MessageBody> _messages = {};
MessageKey _currentKey = MessageKey('', clientModeID); MessageKey _currentKey = MessageKey('', -2); // -2 is invalid value
late bool _isShowCMChatPage = false; late bool _isShowCMChatPage = false;
Map<MessageKey, MessageBody> get messages => _messages; Map<MessageKey, MessageBody> get messages => _messages;
@ -266,7 +267,7 @@ class ChatModel with ChangeNotifier {
toggleCMChatPage(MessageKey key) async { toggleCMChatPage(MessageKey key) async {
if (gFFI.chatModel.currentKey != key) { if (gFFI.chatModel.currentKey != key) {
gFFI.chatModel.changeCurrentID(key); gFFI.chatModel.changeCurrentKey(key);
} }
if (_isShowCMChatPage) { if (_isShowCMChatPage) {
_isShowCMChatPage = !_isShowCMChatPage; _isShowCMChatPage = !_isShowCMChatPage;
@ -284,12 +285,8 @@ class ChatModel with ChangeNotifier {
} }
} }
changeCurrentID(MessageKey key) { changeCurrentKey(MessageKey key) {
updateConnIdOfKey(key); updateConnIdOfKey(key);
if (_messages.containsKey(key)) {
_currentKey = key;
notifyListeners();
} else {
String? peerName; String? peerName;
if (key.connId == clientModeID) { if (key.connId == clientModeID) {
peerName = parent.target?.ffiModel.pi.username; peerName = parent.target?.ffiModel.pi.username;
@ -298,14 +295,19 @@ class ChatModel with ChangeNotifier {
.firstWhereOrNull((client) => client.peerId == key.peerId) .firstWhereOrNull((client) => client.peerId == key.peerId)
?.name; ?.name;
} }
if (!_messages.containsKey(key)) {
final chatUser = ChatUser( final chatUser = ChatUser(
id: key.peerId, id: key.peerId,
firstName: peerName, firstName: peerName,
); );
_messages[key] = MessageBody(chatUser, []); _messages[key] = MessageBody(chatUser, []);
} else {
if (peerName != null && peerName.isNotEmpty) {
_messages[key]?.chatUser.firstName = peerName;
}
}
_currentKey = key; _currentKey = key;
notifyListeners(); notifyListeners();
}
mobileClearClientUnread(key.connId); mobileClearClientUnread(key.connId);
} }
@ -388,7 +390,7 @@ class ChatModel with ChangeNotifier {
} }
} else { } else {
if (HomePage.homeKey.currentState?.selectedIndex != 1 || if (HomePage.homeKey.currentState?.selectedIndex != 1 ||
_currentKey.peerId != client.peerId) { _currentKey != messagekey) {
client.unreadChatMessageCount.value += 1; client.unreadChatMessageCount.value += 1;
mobileUpdateUnreadSum(); mobileUpdateUnreadSum();
} }
@ -398,7 +400,7 @@ class ChatModel with ChangeNotifier {
insertMessage(messagekey, insertMessage(messagekey,
ChatMessage(text: text, user: chatUser, createdAt: DateTime.now())); ChatMessage(text: text, user: chatUser, createdAt: DateTime.now()));
if (id == clientModeID || _currentKey.peerId.isEmpty) { if (id == clientModeID || _currentKey.peerId.isEmpty) {
// Invalid // client or invalid
_currentKey = messagekey; _currentKey = messagekey;
mobileClearClientUnread(messagekey.connId); mobileClearClientUnread(messagekey.connId);
} }
@ -435,12 +437,12 @@ class ChatModel with ChangeNotifier {
.toList() .toList()
.firstWhereOrNull((e) => e == key && e.connId != key.connId) != .firstWhereOrNull((e) => e == key && e.connId != key.connId) !=
null) { null) {
final old = _messages.remove(key); final value = _messages.remove(key);
if (old != null) { if (value != null) {
_messages[key] = old; _messages[key] = value;
} }
} }
if (_currentKey == key) { if (_currentKey == key || _currentKey.peerId.isEmpty) {
_currentKey = key; // hash != assign _currentKey = key; // hash != assign
} }
} }

View File

@ -64,7 +64,7 @@ static void my_application_activate(GApplication* application) {
int width = 800, height = 600; int width = 800, height = 600;
if (gIsConnectionManager) { if (gIsConnectionManager) {
width = 300; width = 300;
height = 400; height = 490;
} }
gtk_window_set_default_size(window, width, height); // <-- comment this line gtk_window_set_default_size(window, width, height); // <-- comment this line
gtk_widget_show(GTK_WIDGET(window)); gtk_widget_show(GTK_WIDGET(window));