| 
									
										
										
										
											2023-02-02 21:39:25 +09:00
										 |  |  | import 'dart:async'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 17:24:02 +08:00
										 |  |  | import 'package:dash_chat_2/dash_chat_2.dart'; | 
					
						
							| 
									
										
										
										
											2023-07-06 09:40:03 +08:00
										 |  |  | import 'package:desktop_multi_window/desktop_multi_window.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  | import 'package:draggable_float_widget/draggable_float_widget.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-28 21:26:44 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  | import 'package:flutter/services.dart'; | 
					
						
							| 
									
										
										
										
											2023-07-06 09:40:03 +08:00
										 |  |  | import 'package:flutter_hbb/common/shared_state.dart'; | 
					
						
							|  |  |  | import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  | import 'package:flutter_hbb/mobile/pages/home_page.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  | import 'package:flutter_hbb/models/platform_model.dart'; | 
					
						
							| 
									
										
										
										
											2023-07-06 09:40:03 +08:00
										 |  |  | import 'package:flutter_hbb/models/state_model.dart'; | 
					
						
							| 
									
										
										
										
											2023-02-06 09:54:21 +09:00
										 |  |  | import 'package:get/get_rx/src/rx_types/rx_types.dart'; | 
					
						
							| 
									
										
										
										
											2023-02-06 20:10:39 +08:00
										 |  |  | import 'package:get/get.dart'; | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  | import 'package:uuid/uuid.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-22 20:12:58 +08:00
										 |  |  | import 'package:window_manager/window_manager.dart'; | 
					
						
							| 
									
										
										
										
											2023-05-29 09:46:16 +08:00
										 |  |  | import 'package:flutter_svg/flutter_svg.dart'; | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 11:07:20 +08:00
										 |  |  | import '../consts.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  | import '../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-13 09:03:34 +08:00
										 |  |  | import '../common/widgets/overlay.dart'; | 
					
						
							| 
									
										
										
										
											2023-06-20 12:43:38 +08:00
										 |  |  | import '../main.dart'; | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  | import 'model.dart'; | 
					
						
							| 
									
										
										
										
											2022-02-28 21:26:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  | class MessageKey { | 
					
						
							|  |  |  |   final String peerId; | 
					
						
							|  |  |  |   final int connId; | 
					
						
							| 
									
										
										
										
											2023-07-10 21:03:35 +08:00
										 |  |  |   bool get isOut => connId == ChatModel.clientModeID; | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   MessageKey(this.peerId, this.connId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   bool operator ==(other) { | 
					
						
							|  |  |  |     return other is MessageKey && | 
					
						
							|  |  |  |         other.peerId == peerId && | 
					
						
							|  |  |  |         other.isOut == isOut; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   int get hashCode => peerId.hashCode ^ isOut.hashCode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-16 00:01:27 +08:00
										 |  |  | class MessageBody { | 
					
						
							|  |  |  |   ChatUser chatUser; | 
					
						
							|  |  |  |   List<ChatMessage> chatMessages; | 
					
						
							|  |  |  |   MessageBody(this.chatUser, this.chatMessages); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-04 17:24:02 +08:00
										 |  |  |   void insert(ChatMessage cm) { | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |     chatMessages.insert(0, cm); | 
					
						
							| 
									
										
										
										
											2022-05-16 00:01:27 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void clear() { | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |     chatMessages.clear(); | 
					
						
							| 
									
										
										
										
											2022-05-16 00:01:27 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-28 21:26:44 +08:00
										 |  |  | class ChatModel with ChangeNotifier { | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   static final clientModeID = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |   OverlayEntry? chatIconOverlayEntry; | 
					
						
							|  |  |  |   OverlayEntry? chatWindowOverlayEntry; | 
					
						
							| 
									
										
										
										
											2023-02-06 20:10:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |   bool isConnManager = false; | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-06 09:54:21 +09:00
										 |  |  |   RxBool isWindowFocus = true.obs; | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |   BlockableOverlayState? _blockableOverlayState; | 
					
						
							| 
									
										
										
										
											2023-02-06 20:10:39 +08:00
										 |  |  |   final Rx<VoiceCallStatus> _voiceCallStatus = Rx(VoiceCallStatus.notStarted); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Rx<VoiceCallStatus> get voiceCallStatus => _voiceCallStatus; | 
					
						
							| 
									
										
										
										
											2023-02-06 09:54:21 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |   TextEditingController textController = TextEditingController(); | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |   RxInt mobileUnreadSum = 0.obs; | 
					
						
							| 
									
										
										
										
											2023-07-10 21:58:27 +08:00
										 |  |  |   MessageKey? latestReceivedKey; | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void dispose() { | 
					
						
							|  |  |  |     textController.dispose(); | 
					
						
							|  |  |  |     super.dispose(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |   final ChatUser me = ChatUser( | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |     id: Uuid().v4().toString(), | 
					
						
							| 
									
										
										
										
											2023-03-13 20:43:03 +01:00
										 |  |  |     firstName: translate("Me"), | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   late final Map<MessageKey, MessageBody> _messages = {}; | 
					
						
							| 
									
										
										
										
											2022-05-16 00:01:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |   MessageKey _currentKey = MessageKey('', -2); // -2 is invalid value
 | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |   late bool _isShowCMChatPage = false; | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   Map<MessageKey, MessageBody> get messages => _messages; | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   MessageKey get currentKey => _currentKey; | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |   bool get isShowCMChatPage => _isShowCMChatPage; | 
					
						
							| 
									
										
										
										
											2022-08-22 20:12:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |   void setOverlayState(BlockableOverlayState blockableOverlayState) { | 
					
						
							|  |  |  |     _blockableOverlayState = blockableOverlayState; | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |     _blockableOverlayState!.addMiddleBlockedListener((v) { | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  |       if (!v) { | 
					
						
							|  |  |  |         isWindowFocus.value = false; | 
					
						
							|  |  |  |         if (isWindowFocus.value) { | 
					
						
							|  |  |  |           isWindowFocus.toggle(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-27 20:35:02 +08:00
										 |  |  |   final WeakReference<FFI> parent; | 
					
						
							| 
									
										
										
										
											2022-06-13 21:07:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 07:39:44 +08:00
										 |  |  |   late final SessionID sessionId; | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |   late FocusNode inputNode; | 
					
						
							| 
									
										
										
										
											2023-06-06 07:39:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ChatModel(this.parent) { | 
					
						
							|  |  |  |     sessionId = parent.target!.sessionId; | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |     inputNode = FocusNode( | 
					
						
							| 
									
										
										
										
											2023-06-09 10:07:27 +02:00
										 |  |  |       onKey: (_, event) { | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |         bool isShiftPressed = event.isKeyPressed(LogicalKeyboardKey.shiftLeft); | 
					
						
							|  |  |  |         bool isEnterPressed = event.isKeyPressed(LogicalKeyboardKey.enter); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-09 10:07:27 +02:00
										 |  |  |         // don't send empty messages
 | 
					
						
							|  |  |  |         if (isEnterPressed && isEnterPressed && textController.text.isEmpty) { | 
					
						
							|  |  |  |           return KeyEventResult.handled; | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (isEnterPressed && !isShiftPressed) { | 
					
						
							|  |  |  |           final ChatMessage message = ChatMessage( | 
					
						
							| 
									
										
										
										
											2023-06-09 10:07:27 +02:00
										 |  |  |             text: textController.text, | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |             user: me, | 
					
						
							|  |  |  |             createdAt: DateTime.now(), | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |           send(message); | 
					
						
							| 
									
										
										
										
											2023-06-09 10:07:27 +02:00
										 |  |  |           textController.clear(); | 
					
						
							|  |  |  |           return KeyEventResult.handled; | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return KeyEventResult.ignored; | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   ChatUser? get currentUser => _messages[_currentKey]?.chatUser; | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |   showChatIconOverlay({Offset offset = const Offset(200, 50)}) { | 
					
						
							|  |  |  |     if (chatIconOverlayEntry != null) { | 
					
						
							|  |  |  |       chatIconOverlayEntry!.remove(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // mobile check navigationBar
 | 
					
						
							|  |  |  |     final bar = navigationBarKey.currentWidget; | 
					
						
							|  |  |  |     if (bar != null) { | 
					
						
							|  |  |  |       if ((bar as BottomNavigationBar).currentIndex == 1) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |     final overlayState = _blockableOverlayState?.state; | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |     if (overlayState == null) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     final overlay = OverlayEntry(builder: (context) { | 
					
						
							|  |  |  |       return DraggableFloatWidget( | 
					
						
							| 
									
										
										
										
											2023-05-20 15:12:52 +02:00
										 |  |  |         config: DraggableFloatWidgetBaseConfig( | 
					
						
							|  |  |  |           initPositionYInTop: false, | 
					
						
							|  |  |  |           initPositionYMarginBorder: 100, | 
					
						
							|  |  |  |           borderTopContainTopBar: true, | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         child: FloatingActionButton( | 
					
						
							|  |  |  |           onPressed: () { | 
					
						
							|  |  |  |             if (chatWindowOverlayEntry == null) { | 
					
						
							|  |  |  |               showChatWindowOverlay(); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               hideChatWindowOverlay(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |           backgroundColor: Theme.of(context).colorScheme.primary, | 
					
						
							| 
									
										
										
										
											2023-05-24 14:18:42 +08:00
										 |  |  |           child: SvgPicture.asset('assets/chat2.svg'), | 
					
						
							| 
									
										
										
										
											2023-05-20 15:12:52 +02:00
										 |  |  |         ), | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |     }); | 
					
						
							|  |  |  |     overlayState.insert(overlay); | 
					
						
							|  |  |  |     chatIconOverlayEntry = overlay; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hideChatIconOverlay() { | 
					
						
							|  |  |  |     if (chatIconOverlayEntry != null) { | 
					
						
							|  |  |  |       chatIconOverlayEntry!.remove(); | 
					
						
							|  |  |  |       chatIconOverlayEntry = null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  |   showChatWindowOverlay({Offset? chatInitPos}) { | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |     if (chatWindowOverlayEntry != null) return; | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  |     isWindowFocus.value = true; | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |     _blockableOverlayState?.setMiddleBlocked(true); | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |     final overlayState = _blockableOverlayState?.state; | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |     if (overlayState == null) return; | 
					
						
							| 
									
										
										
										
											2023-07-10 21:58:27 +08:00
										 |  |  |     if (isMobile && | 
					
						
							|  |  |  |         !gFFI.chatModel.currentKey.isOut && // not in remote page
 | 
					
						
							|  |  |  |         gFFI.chatModel.latestReceivedKey != null) { | 
					
						
							|  |  |  |       gFFI.chatModel.changeCurrentKey(gFFI.chatModel.latestReceivedKey!); | 
					
						
							|  |  |  |       gFFI.chatModel.mobileClearClientUnread(gFFI.chatModel.currentKey.connId); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |     final overlay = OverlayEntry(builder: (context) { | 
					
						
							| 
									
										
										
										
											2023-02-06 09:54:21 +09:00
										 |  |  |       return Listener( | 
					
						
							|  |  |  |           onPointerDown: (_) { | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  |             if (!isWindowFocus.value) { | 
					
						
							|  |  |  |               isWindowFocus.value = true; | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |               _blockableOverlayState?.setMiddleBlocked(true); | 
					
						
							| 
									
										
										
										
											2023-02-06 09:54:21 +09:00
										 |  |  |             } | 
					
						
							|  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  |           child: DraggableChatWindow( | 
					
						
							|  |  |  |               position: chatInitPos ?? Offset(20, 80), | 
					
						
							|  |  |  |               width: 250, | 
					
						
							|  |  |  |               height: 350, | 
					
						
							|  |  |  |               chatModel: this)); | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |     }); | 
					
						
							|  |  |  |     overlayState.insert(overlay); | 
					
						
							|  |  |  |     chatWindowOverlayEntry = overlay; | 
					
						
							| 
									
										
										
										
											2023-02-02 21:39:25 +09:00
										 |  |  |     requestChatInputFocus(); | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   hideChatWindowOverlay() { | 
					
						
							|  |  |  |     if (chatWindowOverlayEntry != null) { | 
					
						
							| 
									
										
										
										
											2023-02-08 22:01:15 +09:00
										 |  |  |       _blockableOverlayState?.setMiddleBlocked(false); | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |       chatWindowOverlayEntry!.remove(); | 
					
						
							|  |  |  |       chatWindowOverlayEntry = null; | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |   _isChatOverlayHide() => ((!isDesktop && chatIconOverlayEntry == null) || | 
					
						
							|  |  |  |       chatWindowOverlayEntry == null); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  |   toggleChatOverlay({Offset? chatInitPos}) { | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |     if (_isChatOverlayHide()) { | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |       gFFI.invokeMethod("enable_soft_keyboard", true); | 
					
						
							| 
									
										
										
										
											2022-09-08 22:18:02 +08:00
										 |  |  |       if (!isDesktop) { | 
					
						
							|  |  |  |         showChatIconOverlay(); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-02-07 00:11:48 +09:00
										 |  |  |       showChatWindowOverlay(chatInitPos: chatInitPos); | 
					
						
							| 
									
										
										
										
											2022-08-11 10:19:12 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       hideChatIconOverlay(); | 
					
						
							|  |  |  |       hideChatWindowOverlay(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-29 09:46:16 +08:00
										 |  |  |   hideChatOverlay() { | 
					
						
							|  |  |  |     if (!_isChatOverlayHide()) { | 
					
						
							|  |  |  |       hideChatIconOverlay(); | 
					
						
							|  |  |  |       hideChatWindowOverlay(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   showChatPage(MessageKey key) async { | 
					
						
							| 
									
										
										
										
											2023-07-08 16:08:23 +08:00
										 |  |  |     if (isDesktop) { | 
					
						
							|  |  |  |       if (isConnManager) { | 
					
						
							|  |  |  |         if (!_isShowCMChatPage) { | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |           await toggleCMChatPage(key); | 
					
						
							| 
									
										
										
										
											2023-07-08 16:08:23 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         if (_isChatOverlayHide()) { | 
					
						
							|  |  |  |           await toggleChatOverlay(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |       if (key.connId == clientModeID) { | 
					
						
							| 
									
										
										
										
											2023-07-08 16:08:23 +08:00
										 |  |  |         if (_isChatOverlayHide()) { | 
					
						
							|  |  |  |           await toggleChatOverlay(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   toggleCMChatPage(MessageKey key) async { | 
					
						
							|  |  |  |     if (gFFI.chatModel.currentKey != key) { | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |       gFFI.chatModel.changeCurrentKey(key); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:12:58 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |     if (_isShowCMChatPage) { | 
					
						
							| 
									
										
										
										
											2023-07-10 17:59:04 +08:00
										 |  |  |       _isShowCMChatPage = !_isShowCMChatPage; | 
					
						
							|  |  |  |       notifyListeners(); | 
					
						
							| 
									
										
										
										
											2023-07-11 10:01:56 +08:00
										 |  |  |       await windowManager.show(); | 
					
						
							|  |  |  |       await windowManager.setSizeAlignment( | 
					
						
							|  |  |  |           kConnectionManagerWindowSizeClosedChat, Alignment.topRight); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:12:58 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2023-02-02 21:39:25 +09:00
										 |  |  |       requestChatInputFocus(); | 
					
						
							| 
									
										
										
										
											2023-07-11 10:01:56 +08:00
										 |  |  |       await windowManager.show(); | 
					
						
							| 
									
										
										
										
											2023-05-18 11:41:16 +02:00
										 |  |  |       await windowManager.setSizeAlignment( | 
					
						
							|  |  |  |           kConnectionManagerWindowSizeOpenChat, Alignment.topRight); | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |       _isShowCMChatPage = !_isShowCMChatPage; | 
					
						
							| 
									
										
										
										
											2022-08-22 20:12:58 +08:00
										 |  |  |       notifyListeners(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |   changeCurrentKey(MessageKey key) { | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |     updateConnIdOfKey(key); | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |     String? peerName; | 
					
						
							|  |  |  |     if (key.connId == clientModeID) { | 
					
						
							|  |  |  |       peerName = parent.target?.ffiModel.pi.username; | 
					
						
							| 
									
										
										
										
											2022-04-04 14:54:00 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |       peerName = parent.target?.serverModel.clients | 
					
						
							|  |  |  |           .firstWhereOrNull((client) => client.peerId == key.peerId) | 
					
						
							|  |  |  |           ?.name; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!_messages.containsKey(key)) { | 
					
						
							| 
									
										
										
										
											2022-05-16 00:01:27 +08:00
										 |  |  |       final chatUser = ChatUser( | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |         id: key.peerId, | 
					
						
							|  |  |  |         firstName: peerName, | 
					
						
							| 
									
										
										
										
											2022-05-16 00:01:27 +08:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |       _messages[key] = MessageBody(chatUser, []); | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       if (peerName != null && peerName.isNotEmpty) { | 
					
						
							|  |  |  |         _messages[key]?.chatUser.firstName = peerName; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |     _currentKey = key; | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |     mobileClearClientUnread(key.connId); | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 17:53:51 +08:00
										 |  |  |   receive(int id, String text) async { | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |     final session = parent.target; | 
					
						
							|  |  |  |     if (session == null) { | 
					
						
							|  |  |  |       debugPrint("Failed to receive msg, session state is null"); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |     if (text.isEmpty) return; | 
					
						
							| 
									
										
										
										
											2023-06-20 12:43:38 +08:00
										 |  |  |     if (desktopType == DesktopType.cm) { | 
					
						
							|  |  |  |       await showCmWindow(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |     String? peerId; | 
					
						
							|  |  |  |     if (id == clientModeID) { | 
					
						
							|  |  |  |       peerId = session.id; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       peerId = session.serverModel.clients | 
					
						
							|  |  |  |           .firstWhereOrNull((e) => e.id == id) | 
					
						
							|  |  |  |           ?.peerId; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (peerId == null) { | 
					
						
							|  |  |  |       debugPrint("Failed to receive msg, peerId is null"); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     final messagekey = MessageKey(peerId, id); | 
					
						
							| 
									
										
										
										
											2023-06-20 12:43:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-22 20:12:58 +08:00
										 |  |  |     // mobile: first message show overlay icon
 | 
					
						
							| 
									
										
										
										
											2023-07-10 21:58:27 +08:00
										 |  |  |     if (!isDesktop && chatIconOverlayEntry == null) { | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |       showChatIconOverlay(); | 
					
						
							| 
									
										
										
										
											2022-08-22 20:12:58 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-04 21:43:51 +08:00
										 |  |  |     // show chat page
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |     await showChatPage(messagekey); | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |     late final ChatUser chatUser; | 
					
						
							| 
									
										
										
										
											2022-04-05 00:51:47 +08:00
										 |  |  |     if (id == clientModeID) { | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |       chatUser = ChatUser( | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |         firstName: session.ffiModel.pi.username, | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |         id: peerId, | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2023-07-06 09:40:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (isDesktop) { | 
					
						
							|  |  |  |         if (Get.isRegistered<DesktopTabController>()) { | 
					
						
							|  |  |  |           DesktopTabController tabController = Get.find<DesktopTabController>(); | 
					
						
							|  |  |  |           var index = tabController.state.value.tabs | 
					
						
							|  |  |  |               .indexWhere((e) => e.key == session.id); | 
					
						
							|  |  |  |           final notSelected = | 
					
						
							|  |  |  |               index >= 0 && tabController.state.value.selected != index; | 
					
						
							|  |  |  |           // minisized: top and switch tab
 | 
					
						
							|  |  |  |           // not minisized: add count
 | 
					
						
							|  |  |  |           if (await WindowController.fromWindowId(stateGlobal.windowId) | 
					
						
							|  |  |  |               .isMinimized()) { | 
					
						
							| 
									
										
										
										
											2023-08-02 20:38:09 +08:00
										 |  |  |             windowOnTop(stateGlobal.windowId); | 
					
						
							| 
									
										
										
										
											2023-07-06 09:40:03 +08:00
										 |  |  |             if (notSelected) { | 
					
						
							|  |  |  |               tabController.jumpTo(index); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             if (notSelected) { | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |               UnreadChatCountState.find(peerId).value += 1; | 
					
						
							| 
									
										
										
										
											2023-07-06 09:40:03 +08:00
										 |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-04-05 00:51:47 +08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |       final client = session.serverModel.clients | 
					
						
							|  |  |  |           .firstWhereOrNull((client) => client.id == id); | 
					
						
							|  |  |  |       if (client == null) { | 
					
						
							|  |  |  |         debugPrint("Failed to receive msg, client is null"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-09-01 21:18:53 +08:00
										 |  |  |       if (isDesktop) { | 
					
						
							| 
									
										
										
										
											2023-08-02 20:38:09 +08:00
										 |  |  |         windowOnTop(null); | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |         // disable auto jumpTo other tab when hasFocus, and mark unread message
 | 
					
						
							|  |  |  |         final currentSelectedTab = | 
					
						
							|  |  |  |             session.serverModel.tabController.state.value.selectedTabInfo; | 
					
						
							|  |  |  |         if (currentSelectedTab.key != id.toString() && inputNode.hasFocus) { | 
					
						
							| 
									
										
										
										
											2023-07-05 17:01:33 +08:00
										 |  |  |           client.unreadChatMessageCount.value += 1; | 
					
						
							| 
									
										
										
										
											2022-10-26 23:50:36 +09:00
										 |  |  |         } else { | 
					
						
							|  |  |  |           parent.target?.serverModel.jumpTo(id); | 
					
						
							| 
									
										
										
										
											2022-09-01 21:18:53 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         if (HomePage.homeKey.currentState?.selectedIndex != 1 || | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |             _currentKey != messagekey) { | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |           client.unreadChatMessageCount.value += 1; | 
					
						
							|  |  |  |           mobileUpdateUnreadSum(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-01 21:18:53 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-04 17:24:02 +08:00
										 |  |  |       chatUser = ChatUser(id: client.peerId, firstName: client.name); | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |     insertMessage(messagekey, | 
					
						
							| 
									
										
										
										
											2022-08-04 17:24:02 +08:00
										 |  |  |         ChatMessage(text: text, user: chatUser, createdAt: DateTime.now())); | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |     if (id == clientModeID || _currentKey.peerId.isEmpty) { | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |       // client or invalid
 | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |       _currentKey = messagekey; | 
					
						
							|  |  |  |       mobileClearClientUnread(messagekey.connId); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-10 21:58:27 +08:00
										 |  |  |     latestReceivedKey = messagekey; | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  |   send(ChatMessage message) { | 
					
						
							| 
									
										
										
										
											2023-06-09 10:07:27 +02:00
										 |  |  |     String trimmedText = message.text.trim(); | 
					
						
							|  |  |  |     if (trimmedText.isEmpty) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     message.text = trimmedText; | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |     insertMessage(_currentKey, message); | 
					
						
							|  |  |  |     if (_currentKey.connId == clientModeID && parent.target != null) { | 
					
						
							| 
									
										
										
										
											2023-06-09 10:07:27 +02:00
										 |  |  |       bind.sessionSendChat(sessionId: sessionId, text: message.text); | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |       bind.cmSendChat(connId: _currentKey.connId, msg: message.text); | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-06-09 10:07:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |     notifyListeners(); | 
					
						
							| 
									
										
										
										
											2023-06-08 16:00:48 +02:00
										 |  |  |     inputNode.requestFocus(); | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-02-28 21:26:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   insertMessage(MessageKey key, ChatMessage message) { | 
					
						
							|  |  |  |     updateConnIdOfKey(key); | 
					
						
							|  |  |  |     if (!_messages.containsKey(key)) { | 
					
						
							|  |  |  |       _messages[key] = MessageBody(message.user, []); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _messages[key]?.insert(message); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   updateConnIdOfKey(MessageKey key) { | 
					
						
							|  |  |  |     if (_messages.keys | 
					
						
							|  |  |  |             .toList() | 
					
						
							|  |  |  |             .firstWhereOrNull((e) => e == key && e.connId != key.connId) != | 
					
						
							|  |  |  |         null) { | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |       final value = _messages.remove(key); | 
					
						
							|  |  |  |       if (value != null) { | 
					
						
							|  |  |  |         _messages[key] = value; | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-10 16:02:47 +08:00
										 |  |  |     if (_currentKey == key || _currentKey.peerId.isEmpty) { | 
					
						
							| 
									
										
										
										
											2023-07-10 09:40:41 +08:00
										 |  |  |       _currentKey = key; // hash != assign
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void mobileUpdateUnreadSum() { | 
					
						
							|  |  |  |     if (!isMobile) return; | 
					
						
							|  |  |  |     var sum = 0; | 
					
						
							|  |  |  |     parent.target?.serverModel.clients | 
					
						
							|  |  |  |         .map((e) => sum += e.unreadChatMessageCount.value) | 
					
						
							|  |  |  |         .toList(); | 
					
						
							|  |  |  |     Future.delayed(Duration.zero, () { | 
					
						
							|  |  |  |       mobileUnreadSum.value = sum; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void mobileClearClientUnread(int id) { | 
					
						
							|  |  |  |     if (!isMobile) return; | 
					
						
							|  |  |  |     final client = parent.target?.serverModel.clients | 
					
						
							|  |  |  |         .firstWhereOrNull((client) => client.id == id); | 
					
						
							|  |  |  |     if (client != null) { | 
					
						
							|  |  |  |       Future.delayed(Duration.zero, () { | 
					
						
							|  |  |  |         client.unreadChatMessageCount.value = 0; | 
					
						
							|  |  |  |         mobileUpdateUnreadSum(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-09 19:14:57 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 16:34:27 +08:00
										 |  |  |   close() { | 
					
						
							| 
									
										
										
										
											2022-03-03 14:58:57 +08:00
										 |  |  |     hideChatIconOverlay(); | 
					
						
							|  |  |  |     hideChatWindowOverlay(); | 
					
						
							|  |  |  |     notifyListeners(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-05-16 00:01:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   resetClientMode() { | 
					
						
							|  |  |  |     _messages[clientModeID]?.clear(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-02-02 21:39:25 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void requestChatInputFocus() { | 
					
						
							|  |  |  |     Timer(Duration(milliseconds: 100), () { | 
					
						
							|  |  |  |       if (inputNode.hasListeners && inputNode.canRequestFocus) { | 
					
						
							|  |  |  |         inputNode.requestFocus(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-02-08 22:29:51 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-06 20:10:39 +08:00
										 |  |  |   void onVoiceCallWaiting() { | 
					
						
							|  |  |  |     _voiceCallStatus.value = VoiceCallStatus.waitingForResponse; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onVoiceCallStarted() { | 
					
						
							|  |  |  |     _voiceCallStatus.value = VoiceCallStatus.connected; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onVoiceCallClosed(String reason) { | 
					
						
							|  |  |  |     _voiceCallStatus.value = VoiceCallStatus.notStarted; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void onVoiceCallIncoming() { | 
					
						
							|  |  |  |     if (isConnManager) { | 
					
						
							|  |  |  |       _voiceCallStatus.value = VoiceCallStatus.incoming; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-02-07 16:11:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 07:39:44 +08:00
										 |  |  |   void closeVoiceCall() { | 
					
						
							|  |  |  |     bind.sessionCloseVoiceCall(sessionId: sessionId); | 
					
						
							| 
									
										
										
										
											2023-02-07 16:11:55 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-02-06 20:10:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum VoiceCallStatus { | 
					
						
							|  |  |  |   notStarted, | 
					
						
							|  |  |  |   waitingForResponse, | 
					
						
							|  |  |  |   connected, | 
					
						
							|  |  |  |   // Connection manager only.
 | 
					
						
							|  |  |  |   incoming | 
					
						
							| 
									
										
										
										
											2022-03-22 16:40:23 +08:00
										 |  |  | } |