diff --git a/lib/account.dart b/lib/account.dart index f82a294..7549609 100644 --- a/lib/account.dart +++ b/lib/account.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import 'dart:convert'; import 'dart:typed_data'; @@ -63,8 +65,8 @@ class Account { width: width, name: this.name, avatar: this.avatar, - online: online, - needOnline: needOnline, + online: true, + onlineColor: this.online ? const Color(0xFF0EE50A) : const Color(0xFFEDEDED), hasNew: this.hasNew, ); } diff --git a/lib/apps/assistant/message.dart b/lib/apps/assistant/message.dart index 6e5b564..b609978 100644 --- a/lib/apps/assistant/message.dart +++ b/lib/apps/assistant/message.dart @@ -192,12 +192,7 @@ class AssistantMessage extends StatelessWidget { Icons.person_rounded, lang.contact, Column(children: [ - Avatar( - width: 100.0, - name: infos[0], - avatarPath: infos[3], - needOnline: false - ), + Avatar(width: 100.0, name: infos[0], avatarPath: infos[3]), const SizedBox(height: 10.0), Text(infos[0]), const SizedBox(height: 10.0), @@ -245,11 +240,7 @@ class AssistantMessage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(children: [ - Avatar( - width: 40.0, - name: infos[0], - avatarPath: infos[3], - needOnline: false), + Avatar(width: 40.0, name: infos[0], avatarPath: infos[3]), Container( width: 135.0, padding: const EdgeInsets.only(left: 10.0), diff --git a/lib/apps/assistant/page.dart b/lib/apps/assistant/page.dart index 230359a..1f92ed9 100644 --- a/lib/apps/assistant/page.dart +++ b/lib/apps/assistant/page.dart @@ -236,7 +236,7 @@ class _AssistantDetailState extends State { style: TextStyle(fontWeight: FontWeight.bold), ), SizedBox(height: 6.0), - Text(lang.online, + Text(lang.onlineActive, style: TextStyle(color: color.onPrimary.withOpacity(0.5), fontSize: 14.0)) ], ), diff --git a/lib/apps/chat/detail.dart b/lib/apps/chat/detail.dart index 3ca90a1..e15db9a 100644 --- a/lib/apps/chat/detail.dart +++ b/lib/apps/chat/detail.dart @@ -48,11 +48,10 @@ class _ChatDetailState extends State { String _recordName; int _actived; - Friend _friend; - String _meName; @override initState() { + print("Chat detail initState..."); super.initState(); textFocus.addListener(() { if (textFocus.hasFocus) { @@ -63,15 +62,6 @@ class _ChatDetailState extends State { }); } }); - new Future.delayed(Duration.zero, () { - final accountProvider = context.read(); - final chatProvider = context.read(); - this._actived = accountProvider.activedSession.fid; - this._meName = accountProvider.activedAccount.name; - this._friend = chatProvider.friends[this._actived]; - chatProvider.updateActivedFriend(this._actived); - setState(() {}); - }); } _generateRecordPath() { @@ -212,18 +202,21 @@ class _ChatDetailState extends State { final provider = context.watch(); final recentMessages = provider.activedMessages; final recentMessageKeys = recentMessages.keys.toList().reversed.toList(); + final friend = provider.activedFriend; + this._actived = friend.id; - final session = context.watch().activedSession; + final accountProvider = context.watch(); + final session = accountProvider.activedSession; + final meName = accountProvider.activedAccount.name; + final isOnline = session.isActive(); - if (this._friend == null) { + if (friend == null) { return Container( padding: EdgeInsets.only(left: 20.0, right: 20.0, top: 10.0, bottom: 10.0), child: Text('Waiting...') ); } - final isOnline = session.online == OnlineType.Active; - return Column( children: [ Container( @@ -247,13 +240,13 @@ class _ChatDetailState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - this._friend.name, + friend.name, style: TextStyle(fontWeight: FontWeight.bold), ), SizedBox(height: 6.0), - Text(this._friend.isClosed + Text(friend.isClosed ? lang.unfriended - : (isOnline ? lang.online : lang.offline), + : session.onlineLang(lang), style: TextStyle( color: color.onPrimary.withOpacity(0.5), fontSize: 14.0)) @@ -290,9 +283,9 @@ class _ChatDetailState extends State { Icons.info, lang.friendInfo, UserInfo( - id: 'EH' + this._friend.gid.toUpperCase(), - name: this._friend.name, - addr: '0x' + this._friend.addr) + id: 'EH' + friend.gid.toUpperCase(), + name: friend.name, + addr: '0x' + friend.addr) ); } else if (value == 3) { print('TODO remark'); @@ -302,7 +295,7 @@ class _ChatDetailState extends State { builder: (BuildContext context) { return AlertDialog( title: Text(lang.unfriend), - content: Text(this._friend.name, + content: Text(friend.name, style: TextStyle(color: color.primary)), actions: [ TextButton( @@ -314,7 +307,7 @@ class _ChatDetailState extends State { onPressed: () { Navigator.pop(context); Provider.of( - context, listen: false).friendClose(this._friend.id); + context, listen: false).friendClose(friend.id); if (!isDesktop) { Navigator.pop(context); } @@ -326,14 +319,14 @@ class _ChatDetailState extends State { ); } else if (value == 5) { Provider.of(context, listen: false).requestCreate( - Request(this._friend.gid, this._friend.addr, this._friend.name, lang.fromContactCard(this._meName))); + Request(friend.gid, friend.addr, friend.name, lang.fromContactCard(meName))); } else if (value == 6) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text(lang.delete + " " + lang.friend), - content: Text(this._friend.name, + content: Text(friend.name, style: TextStyle(color: Colors.red)), actions: [ TextButton( @@ -345,7 +338,7 @@ class _ChatDetailState extends State { onPressed: () { Navigator.pop(context); Provider.of( - context, listen: false).friendDelete(this._friend.id); + context, listen: false).friendDelete(friend.id); if (!isDesktop) { Navigator.pop(context); } @@ -361,7 +354,7 @@ class _ChatDetailState extends State { return >[ _menuItem(Color(0xFF6174FF), 2, Icons.qr_code_rounded, lang.friendInfo), //_menuItem(color.primary, 3, Icons.turned_in_rounded, lang.remark), - this._friend.isClosed + friend.isClosed ? _menuItem(Color(0xFF6174FF), 5, Icons.send_rounded, lang.addFriend) : _menuItem(Color(0xFF6174FF), 4, Icons.block_rounded, lang.unfriend), _menuItem(Colors.red, 6, Icons.delete_rounded, lang.delete), @@ -378,11 +371,27 @@ class _ChatDetailState extends State { itemCount: recentMessageKeys.length, reverse: true, itemBuilder: (BuildContext context, index) => ChatMessage( - name: this._friend.name, + name: friend.name, message: recentMessages[recentMessageKeys[index]], ) )), - if (!this._friend.isClosed) + if (session.online == OnlineType.Lost) + InkWell( + onTap: () { + context.read().updateActivedSession(session.id); + }, + hoverColor: Colors.transparent, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 8.0), + margin: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: color.primary), + borderRadius: BorderRadius.circular(10.0) + ), + child: Center(child: Text(lang.reconnect, style: TextStyle(color: color.primary))), + ) + ), + if (!friend.isClosed && session.online != OnlineType.Lost) Container( padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), child: Row( diff --git a/lib/apps/chat/list.dart b/lib/apps/chat/list.dart index 0ce3741..3024a0f 100644 --- a/lib/apps/chat/list.dart +++ b/lib/apps/chat/list.dart @@ -35,7 +35,7 @@ class _ChatListState extends State { onPressed: () { final widget = ChatAddPage(); if (isDesktop) { - Provider.of(context, listen: false).updateActivedSession(0, widget); + Provider.of(context, listen: false).updateActivedWidget(widget); } else { Navigator.push(context, MaterialPageRoute(builder: (_) => widget)); } @@ -61,6 +61,8 @@ class ListChat extends StatelessWidget { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { + context.read().updateActivedSession(0, SessionType.Chat, friend.id); + context.read().updateActivedFriend(friend.id); if (!isDesktop) { Navigator.push( context, @@ -69,9 +71,7 @@ class ListChat extends StatelessWidget { ), ); } else { - context.read().updateActivedSessionFromList( - friend.id, SessionType.Chat, ChatDetail() - ); + context.read().updateActivedWidget(ChatDetail()); } }, child: Container( diff --git a/lib/apps/chat/models.dart b/lib/apps/chat/models.dart index cd434d7..e58ce7b 100644 --- a/lib/apps/chat/models.dart +++ b/lib/apps/chat/models.dart @@ -12,7 +12,6 @@ class Friend { String remark; bool isClosed; RelativeTime time; - bool online = false; // new friend from network Friend(this.gid, this.name, this.addr) { @@ -21,12 +20,7 @@ class Friend { Avatar showAvatar({double width = 45.0}) { final avatar = Global.avatarPath + this.gid + '.png'; - return Avatar( - width: width, - name: this.name, - avatarPath: avatar, - needOnline: false, - ); + return Avatar(width: width, name: this.name, avatarPath: avatar); } Friend.fromList(List params) { @@ -65,8 +59,7 @@ class Request { Avatar showAvatar([double width = 45.0]) { final avatar = Global.avatarPath + this.gid + '.png'; - return Avatar( - width: width, name: this.name, avatarPath: avatar, needOnline: false); + return Avatar(width: width, name: this.name, avatarPath: avatar); } Request.fromList(List params) { diff --git a/lib/apps/chat/provider.dart b/lib/apps/chat/provider.dart index 66b54b5..23e661a 100644 --- a/lib/apps/chat/provider.dart +++ b/lib/apps/chat/provider.dart @@ -34,8 +34,6 @@ class ChatProvider extends ChangeNotifier { ChatProvider() { // rpc rpc.addListener('chat-friend-list', _friendList, false); - rpc.addListener('chat-friend-online', _friendOnline, false); - rpc.addListener('chat-friend-offline', _friendOffline, false); rpc.addListener('chat-friend-info', _friendInfo, false); rpc.addListener('chat-friend-update', _friendUpdate, false); rpc.addListener('chat-friend-close', _friendClose, false); @@ -90,7 +88,6 @@ class ChatProvider extends ChangeNotifier { /// delete a friend. friendClose(int id) { this.friends[id].isClosed = true; - this.friends[id].online = false; rpc.send('chat-friend-close', [id]); notifyListeners(); @@ -182,25 +179,6 @@ class ChatProvider extends ChangeNotifier { notifyListeners(); } - _friendOnline(List params) { - final id = params[0]; - if (this.friends.containsKey(id)) { - this.friends[id].online = true; - this.friends[id].addr = params[1]; - notifyListeners(); - } - } - - _friendOffline(List params) { - final id = params[0]; - if (this.friends.containsKey(id)) { - if (this.friends[id].gid == params[1]) { - this.friends[id].online = false; - notifyListeners(); - } - } - } - _friendInfo(List params) { final id = params[0]; this.friends[id] = Friend.fromList(params); @@ -219,7 +197,6 @@ class ChatProvider extends ChangeNotifier { final id = params[0]; if (this.friends.containsKey(id)) { this.friends[id].isClosed = true; - this.friends[id].online = false; notifyListeners(); } } @@ -295,7 +272,6 @@ class ChatProvider extends ChangeNotifier { msg.isDelivery = null; // When message create, set is is none; } this.activedMessages[msg.id] = msg; - rpc.send('chat-friend-readed', [this.activedFriendId]); } orderFriends(msg.fid); notifyListeners(); diff --git a/lib/apps/device/page.dart b/lib/apps/device/page.dart index cbbaf70..a5aa4d5 100644 --- a/lib/apps/device/page.dart +++ b/lib/apps/device/page.dart @@ -152,7 +152,7 @@ class _DevicesPageState extends State { Provider.of(context, listen: false).updateActivedDevice(device.id); final widget = DeviceListenPage(); if (isDesktop) { - Provider.of(context, listen: false).updateActivedSession(0, widget); + Provider.of(context, listen: false).updateActivedWidget(widget); } else { Navigator.push(context, MaterialPageRoute(builder: (_) => widget)); } @@ -355,7 +355,7 @@ class _DeviceListenPageState extends State { onTap: () { Provider.of(context, listen: false).clear(); if (isDesktop) { - Provider.of(context, listen: false).updateActivedSession(0, DevicesPage()); + Provider.of(context, listen: false).updateActivedWidget(DevicesPage()); } else { Navigator.pop(context); } diff --git a/lib/apps/file/page.dart b/lib/apps/file/page.dart index fb2f78d..e12a51c 100644 --- a/lib/apps/file/page.dart +++ b/lib/apps/file/page.dart @@ -39,7 +39,7 @@ class _FolderListState extends State { loadFolder(bool isDesktop, int index) async { final widget = FilePage(title: FILE_DIRECTORY[index][0]); if (isDesktop) { - Provider.of(context, listen: false).updateActivedSession(0, widget); + Provider.of(context, listen: false).updateActivedWidget(widget); } else { Navigator.push(context, MaterialPageRoute(builder: (_) => widget)); } diff --git a/lib/apps/group_chat/detail.dart b/lib/apps/group_chat/detail.dart index 9fd03f4..4d78339 100644 --- a/lib/apps/group_chat/detail.dart +++ b/lib/apps/group_chat/detail.dart @@ -203,7 +203,6 @@ class _GroupChatDetailState extends State { final recentMessages = provider.activedMessages; final recentMessageKeys = recentMessages.keys.toList().reversed.toList(); - final meName = context.read().activedAccount.name; this.group = provider.activedGroup; final isGroupOwner = provider.isActivedGroupOwner; final isGroupManager = provider.isActivedGroupManager; @@ -214,7 +213,11 @@ class _GroupChatDetailState extends State { child: Text('Waiting...') ); } - final isOnline = provider.activedOnline; + + final accountProvider = context.watch(); + final session = accountProvider.activedSession; + final meName = accountProvider.activedAccount.name; + final isOnline = session.isActive(); return Column( children: [ @@ -245,7 +248,7 @@ class _GroupChatDetailState extends State { SizedBox(height: 6.0), Text(this.group.isClosed ? lang.unfriended - : (isOnline ? lang.online : lang.offline), + : session.onlineLang(lang), style: TextStyle( color: color.onPrimary.withOpacity(0.5), fontSize: 14.0)) diff --git a/lib/apps/group_chat/models.dart b/lib/apps/group_chat/models.dart index 1a315b6..e150bf4 100644 --- a/lib/apps/group_chat/models.dart +++ b/lib/apps/group_chat/models.dart @@ -108,12 +108,7 @@ class GroupChat { Avatar showAvatar({double width = 45.0}) { final avatar = Global.avatarPath + this.gid + '.png'; - return Avatar( - width: width, - name: this.name, - avatarPath: avatar, - needOnline: false, - ); + return Avatar(width: width, name: this.name, avatarPath: avatar); } } @@ -137,12 +132,7 @@ class Request { Avatar showAvatar([double width = 45.0]) { final avatar = Global.avatarPath + this.gid + '.png'; - return Avatar( - width: width, - name: this.name, - avatarPath: avatar, - needOnline: false, - ); + return Avatar(width: width, name: this.name, avatarPath: avatar); } Request.fromList(List params) { @@ -191,7 +181,7 @@ class Member { width: width, name: this.name, avatarPath: avatar, - needOnline: false, + online: false, hasNew: this.isManager, hasNewColor: Color(0xFF6174FF), ); diff --git a/lib/apps/group_chat/page.dart b/lib/apps/group_chat/page.dart index d71263e..711e4d9 100644 --- a/lib/apps/group_chat/page.dart +++ b/lib/apps/group_chat/page.dart @@ -35,7 +35,7 @@ class _GroupChatListState extends State { onPressed: () { final widget = GroupAddPage(); if (isDesktop) { - Provider.of(context, listen: false).updateActivedSession(0, widget); + Provider.of(context, listen: false).updateActivedWidget(widget); } else { Navigator.push(context, MaterialPageRoute(builder: (_) => widget)); } @@ -61,6 +61,9 @@ class ListChat extends StatelessWidget { behavior: HitTestBehavior.opaque, onTap: () { context.read().updateActivedGroup(group.id); + + context.read().updateActivedSession(0, SessionType.Group, group.id); + if (!isDesktop) { Navigator.push( context, @@ -69,9 +72,7 @@ class ListChat extends StatelessWidget { ), ); } else { - context.read().updateActivedSessionFromList( - group.id, SessionType.Group, GroupChatDetail() - ); + context.read().updateActivedWidget(GroupChatDetail()); } }, child: Container( diff --git a/lib/apps/service/list.dart b/lib/apps/service/list.dart index 31660ac..dc27476 100644 --- a/lib/apps/service/list.dart +++ b/lib/apps/service/list.dart @@ -73,10 +73,10 @@ class ListInnerService extends StatelessWidget { final widgets = this.callback(); if (widgets != null) { if (this.isDesktop) { - Provider.of(context, listen: false).updateActivedSession(0, widgets[0], widgets[1], widgets[2]); + Provider.of(context, listen: false).updateActivedWidget(widgets[0], widgets[1], widgets[2]); } else { if (widgets[2] != null) { - Provider.of(context, listen: false).updateActivedSession(0, null, widgets[1], widgets[2]); + Provider.of(context, listen: false).updateActivedWidget(null, widgets[1], widgets[2]); } else { Navigator.push(context, MaterialPageRoute(builder: (_) => widgets[0])); } diff --git a/lib/apps/service/models.dart b/lib/apps/service/models.dart index 4f8488e..506d13c 100644 --- a/lib/apps/service/models.dart +++ b/lib/apps/service/models.dart @@ -46,17 +46,17 @@ extension InnerServiceExtension on InnerService { listHome = GroupChatList(); break; } - Provider.of(context, listen: false).updateActivedSession(0, coreWidget, listTitle, listHome); + Provider.of(context, listen: false).updateActivedWidget(coreWidget, listTitle, listHome); } else { switch (this) { case InnerService.Files: - Provider.of(context, listen: false).updateActivedSession(0, null, lang.files, FolderList()); + Provider.of(context, listen: false).updateActivedWidget(null, lang.files, FolderList()); break; case InnerService.Assistant: Navigator.push(context, MaterialPageRoute(builder: (_) => AssistantPage())); break; case InnerService.GroupChat: - Provider.of(context, listen: false).updateActivedSession(0, null, lang.groupChat, GroupChatList()); + Provider.of(context, listen: false).updateActivedWidget(null, lang.groupChat, GroupChatList()); break; } } diff --git a/lib/l10n/localizations.dart b/lib/l10n/localizations.dart index 8a0b50a..484bd1b 100644 --- a/lib/l10n/localizations.dart +++ b/lib/l10n/localizations.dart @@ -51,8 +51,10 @@ abstract class AppLocalizations { String get contact; String get friend; String get logout; - String get online; - String get offline; + String get onlineWaiting; + String get onlineActive; + String get onlineSuspend; + String get onlineLost; String get nickname; String get id; String get address; diff --git a/lib/l10n/localizations_en.dart b/lib/l10n/localizations_en.dart index 6483d7c..73b45cf 100644 --- a/lib/l10n/localizations_en.dart +++ b/lib/l10n/localizations_en.dart @@ -27,9 +27,13 @@ class AppLocalizationsEn extends AppLocalizations { @override String get logout => 'Logout'; @override - String get online => 'Online'; + String get onlineWaiting => 'Waiting...'; @override - String get offline => 'Offline'; + String get onlineActive => 'Active'; + @override + String get onlineSuspend => 'Suspend'; + @override + String get onlineLost => 'Offline'; @override String get nickname => 'Name'; @override diff --git a/lib/l10n/localizations_zh.dart b/lib/l10n/localizations_zh.dart index 80d1208..3fad8a4 100644 --- a/lib/l10n/localizations_zh.dart +++ b/lib/l10n/localizations_zh.dart @@ -27,9 +27,13 @@ class AppLocalizationsZh extends AppLocalizations { @override String get logout => '退出'; @override - String get online => '在线'; + String get onlineWaiting => '连接中...'; @override - String get offline => '离线'; + String get onlineActive => '在线'; + @override + String get onlineSuspend => '挂起'; + @override + String get onlineLost => '离线'; @override String get nickname => '昵称'; @override diff --git a/lib/pages/home.dart b/lib/pages/home.dart index 1cc6465..6638313 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -96,30 +96,7 @@ class HomeList extends StatefulWidget { _HomeListState createState() => _HomeListState(); } -class _HomeListState extends State with SingleTickerProviderStateMixin { - bool isProcess = true; - AnimationController controller; - - @override - void initState() { - controller = AnimationController( - vsync: this, duration: const Duration(seconds: 8) - )..addListener(() { - if (controller.value == 1.0) { - isProcess = false; - } - setState(() {}); - }); - controller.forward(); - super.initState(); - } - - @override - void dispose() { - controller.dispose(); - super.dispose(); - } - +class _HomeListState extends State { _scanQr(bool isDesktop) { Navigator.push( context, @@ -135,7 +112,7 @@ class _HomeListState extends State with SingleTickerProviderStateMixin .systemAppFriendAddNew = false; if (isDesktop) { Provider.of(context, listen: false) - .updateActivedSession(0, widget); + .updateActivedWidget(widget); } else { Navigator.push( context, MaterialPageRoute(builder: (_) => widget)); @@ -199,7 +176,7 @@ class _HomeListState extends State with SingleTickerProviderStateMixin } else if (value == 1) { final widget = ChatAddPage(); if (isDesktop) { - provider.updateActivedSession(0, widget); + provider.updateActivedWidget(widget); } else { provider.systemAppFriendAddNew = false; setState(() {}); @@ -245,13 +222,7 @@ class _HomeListState extends State with SingleTickerProviderStateMixin ), ), const SizedBox(height: 10.0), - isProcess - ? LinearProgressIndicator( - backgroundColor: Color(0x40ADB0BB), - valueColor: AlwaysStoppedAnimation(color.primary), - value: controller.value, - ) - : const Divider(height: 1.0, color: Color(0x40ADB0BB)), + const Divider(height: 1.0, color: Color(0x40ADB0BB)), const SizedBox(height: 5.0), Expanded( child: provider.homeShowWidget, @@ -319,7 +290,7 @@ class DrawerWidget extends StatelessWidget { final widget = DevicesPage(); if (isDesktop) { Provider.of(context, listen: false) - .updateActivedSession(0, widget); + .updateActivedWidget(widget); } else { Navigator.push(context, MaterialPageRoute(builder: (_) => widget)); } @@ -387,7 +358,7 @@ class DrawerWidget extends StatelessWidget { style: TextStyle(fontSize: 16.0)), onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).updateActivedSession(0, + Provider.of(context, listen: false).updateActivedWidget( null, lang.contact, ChatList() ); }), @@ -397,7 +368,7 @@ class DrawerWidget extends StatelessWidget { style: TextStyle(fontSize: 16.0)), onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).updateActivedSession(0, + Provider.of(context, listen: false).updateActivedWidget( null, lang.groups, ServiceList() ); }), diff --git a/lib/provider.dart b/lib/provider.dart index 0500edf..126ac10 100644 --- a/lib/provider.dart +++ b/lib/provider.dart @@ -207,39 +207,42 @@ class AccountProvider extends ChangeNotifier { notifyListeners(); } - updateActivedSessionFromList(int fid, SessionType type, Widget coreWidget) { - int id = 0; - - for (int k in this.sessions.keys) { - final v = this.sessions[k]; - if (v.type == type && v.fid == fid) { - id = k; - break; + updateActivedSession(int id, [SessionType type, int fid]) { + if (fid != null && fid > 0) { + for (int k in this.sessions.keys) { + final v = this.sessions[k]; + if (v.type == type && v.fid == fid) { + id = k; + break; + } } } + print("New session: ${id}"); if (id > 0) { - if (this.actived > 0) { + if (this.actived != id && this.actived > 0) { rpc.send('session-suspend', [this.actived, this.activedSession.gid]); } this.actived = id; - if (this.activedSession.online == OnlineType.Lost) { + final online = this.activedSession.online; + if (online == OnlineType.Lost || online == OnlineType.Suspend) { + if (online == OnlineType.Lost) { + this.activedSession.online = OnlineType.Waiting; + Timer(Duration(seconds: 10), () { + if (this.sessions[id].online == OnlineType.Waiting) { + this.sessions[id].online = OnlineType.Lost; + notifyListeners(); + } + }); + } rpc.send('session-connect', [id, this.activedSession.gid]); + notifyListeners(); } } } - updateActivedSession(int id, [Widget coreWidget, String title, Widget homeWidget]) { - if (id > 0) { - if (this.actived > 0) { - rpc.send('session-suspend', [this.actived, this.activedSession.gid]); - } - this.actived = id; - if (this.activedSession.online == OnlineType.Lost) { - rpc.send('session-connect', [id, this.activedSession.gid]); - } - } - + updateActivedWidget([Widget coreWidget, String title, Widget homeWidget]) { + print("update actived widget"); if (homeWidget != null && title != null) { this.homeShowTitle = title; this.currentListShow = homeWidget; diff --git a/lib/session.dart b/lib/session.dart index 339d589..81d2654 100644 --- a/lib/session.dart +++ b/lib/session.dart @@ -76,6 +76,23 @@ class Session { return [avatar, name, bio]; } + String onlineLang(AppLocalizations lang) { + switch (this.online) { + case OnlineType.Waiting: + return lang.onlineWaiting; + case OnlineType.Active: + return lang.onlineActive; + case OnlineType.Suspend: + return lang.onlineSuspend; + case OnlineType.Lost: + return lang.onlineLost; + } + } + + bool isActive() { + return this.online == OnlineType.Active || this.online == OnlineType.Suspend; + } + List parse(AppLocalizations lang) { switch (this.type) { case SessionType.Chat: @@ -89,15 +106,27 @@ class Session { } } - Avatar showAvatar({double width = 45.0, bool needOnline = true}) { + Avatar showAvatar({double width = 45.0}) { final avatar = Global.avatarPath + this.gid + '.png'; + + Color color; + switch (this.online) { + case OnlineType.Active: + color = Color(0xFF0EE50A); + break; + case OnlineType.Suspend: + color = Colors.blue; + break; + } + return Avatar( width: width, name: this.name, avatarPath: avatar, - online: true, - needOnline: needOnline, + online: this.online != OnlineType.Lost, + onlineColor: color, hasNew: !this.lastReaded, + loading: this.online == OnlineType.Waiting, ); } diff --git a/lib/widgets/avatar.dart b/lib/widgets/avatar.dart index 3322ad1..181a3bb 100644 --- a/lib/widgets/avatar.dart +++ b/lib/widgets/avatar.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; +import 'package:flutter/cupertino.dart' show CupertinoActivityIndicator; class Avatar extends StatelessWidget { final double width; @@ -9,9 +10,10 @@ class Avatar extends StatelessWidget { final Uint8List avatar; final String avatarPath; final bool online; - final bool needOnline; + final Color onlineColor; final bool hasNew; final Color hasNewColor; + final bool loading; const Avatar( {Key key, @@ -20,9 +22,10 @@ class Avatar extends StatelessWidget { this.avatar, this.avatarPath, this.online = false, - this.needOnline = true, + this.onlineColor = Colors.grey, this.hasNew = false, this.hasNewColor = Colors.red, + this.loading = false, }) : super(key: key); @@ -40,52 +43,31 @@ class Avatar extends StatelessWidget { } return Container( - width: width, - height: width, + width: this.width, + height: this.width, decoration: showAvatar != null - ? BoxDecoration( - image: DecorationImage( - image: showAvatar, - fit: BoxFit.cover, - ), - borderRadius: BorderRadius.circular(15.0)) - : BoxDecoration( - color: color.surface, borderRadius: BorderRadius.circular(15.0)), + ? BoxDecoration(image: DecorationImage(image: showAvatar, fit: BoxFit.cover), borderRadius: BorderRadius.circular(15.0)) + : BoxDecoration(color: color.surface, borderRadius: BorderRadius.circular(15.0)), child: Stack( alignment: Alignment.center, children: [ if (showAvatar == null) Text(this.name.length > 0 ? this.name[0].toUpperCase() : "A"), if (this.hasNew) - Positioned( - top: 0.0, - right: 0.0, - child: Container( - width: 9.0, - height: 9.0, - decoration: BoxDecoration( - color: this.hasNewColor, - shape: BoxShape.circle, - ), + Positioned(top: 0.0, right: 0.0, + child: Container(width: 9.0, height: 9.0, + decoration: BoxDecoration(color: this.hasNewColor, shape: BoxShape.circle), ), ), - if (this.needOnline) - Positioned( - bottom: 0.0, - right: 0.0, + if (this.online) + Positioned(bottom: 0.0, right: 0.0, child: Container( padding: const EdgeInsets.all(2.0), - decoration: const ShapeDecoration( - color: Colors.white, - shape: CircleBorder(), - ), - child: Container( - width: 9.0, - height: 9.0, - decoration: BoxDecoration( - color: online ? const Color(0xFF0EE50A) : const Color(0xFFEDEDED), - shape: BoxShape.circle, - ), + decoration: ShapeDecoration(color: color.background, shape: CircleBorder()), + child: this.loading + ? CupertinoActivityIndicator(radius: 5.0, animating: true) + : Container(width: 9.0, height: 9.0, + decoration: BoxDecoration(color: this.onlineColor, shape: BoxShape.circle), ), ), ), diff --git a/lib/widgets/chat_message.dart b/lib/widgets/chat_message.dart index e3e74fc..f0c5ca8 100644 --- a/lib/widgets/chat_message.dart +++ b/lib/widgets/chat_message.dart @@ -193,12 +193,7 @@ class ChatMessage extends StatelessWidget { Icons.person_rounded, lang.contact, Column(children: [ - Avatar( - width: 100.0, - name: infos[0], - avatarPath: infos[3], - needOnline: false - ), + Avatar(width: 100.0, name: infos[0], avatarPath: infos[3]), const SizedBox(height: 10.0), Text(infos[0]), const SizedBox(height: 10.0), @@ -251,11 +246,7 @@ class ChatMessage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(children: [ - Avatar( - width: 40.0, - name: infos[0], - avatarPath: infos[3], - needOnline: false), + Avatar(width: 40.0, name: infos[0], avatarPath: infos[3]), Container( width: 135.0, padding: const EdgeInsets.only(left: 10.0), diff --git a/lib/widgets/default_home_show.dart b/lib/widgets/default_home_show.dart index 5d4e1a0..089b0b1 100644 --- a/lib/widgets/default_home_show.dart +++ b/lib/widgets/default_home_show.dart @@ -9,7 +9,9 @@ import 'package:esse/provider.dart'; import 'package:esse/session.dart'; import 'package:esse/apps/chat/detail.dart'; +import 'package:esse/apps/chat/provider.dart'; import 'package:esse/apps/assistant/page.dart'; +import 'package:esse/apps/file/page.dart'; class DefaultHomeShow extends StatelessWidget { const DefaultHomeShow({Key key}): super(key: key); @@ -63,6 +65,7 @@ class _SessionWidget extends StatelessWidget { switch (session.type) { case SessionType.Chat: + context.read().updateActivedFriend(session.fid); if (!isDesktop) { coreWidget = ChatPage(); } else { @@ -78,8 +81,14 @@ class _SessionWidget extends StatelessWidget { coreWidget = AssistantDetail(); } break; + case SessionType.Files: + listTitle = lang.files; + listWidget = FolderList(); + break; } + context.read().updateActivedSession(session.id); + if (!isDesktop) { Navigator.push( context, @@ -88,8 +97,8 @@ class _SessionWidget extends StatelessWidget { ), ); } else { - context.read().updateActivedSession( - session.id, coreWidget, listTitle, listWidget + context.read().updateActivedWidget( + coreWidget, listTitle, listWidget ); } }, diff --git a/src/apps/chat/layer.rs b/src/apps/chat/layer.rs index 97a7d51..90c2e74 100644 --- a/src/apps/chat/layer.rs +++ b/src/apps/chat/layer.rs @@ -117,8 +117,8 @@ pub(crate) async fn handle( let _ = Friend::addr_update(&db, f.id, &addr); drop(db); } - // 4. online to UI. - results.rpcs.push(rpc::friend_online(mgid, f.id, addr)); + // 4. online to UI. TODO + // 5. connected. let msg = conn_res_message(&layer, &mgid, addr).await?; results.layers.push((mgid, fgid, msg)); @@ -206,7 +206,6 @@ pub(crate) async fn handle( for (mgid, running) in &mut layer.runnings { let peers = running.peer_leave(&addr); for (fgid, fid) in peers { - results.rpcs.push(rpc::friend_offline(*mgid, fid, &fgid)); results .rpcs .push(crate::apps::group_chat::rpc::group_offline( @@ -288,8 +287,9 @@ pub(crate) async fn handle( let db = chat_db(&layer.base, &mgid)?; Friend::addr_update(&db, fid, &addr)?; drop(db); + // 5. online to UI. - results.rpcs.push(rpc::friend_online(mgid, fid, addr)); + layer.group.write().await.status( &mgid, StatusEvent::SessionFriendOnline(fgid), @@ -310,7 +310,7 @@ pub(crate) async fn handle( sid, friend.id, )?; - results.rpcs.push(rpc::friend_online(mgid, friend.id, addr)); + layer.group.write().await.status( &mgid, StatusEvent::SessionFriendOnline(fgid), @@ -393,8 +393,8 @@ pub(crate) async fn handle( let db = chat_db(&layer.base, &mgid)?; Friend::addr_update(&db, fid, &addr)?; drop(db); - // 5. online to UI. - results.rpcs.push(rpc::friend_online(mgid, fid, addr)); + // 5. online to UI. TODO + // 6. connected. let msg = conn_res_message(&layer, &mgid, addr).await?; results.layers.push((mgid, fgid, msg)); @@ -418,7 +418,6 @@ pub(crate) async fn handle( sid, friend.id, )?; - results.rpcs.push(rpc::friend_online(mgid, friend.id, addr)); layer.group.write().await.status( &mgid, StatusEvent::SessionFriendOnline(fgid), @@ -629,7 +628,7 @@ impl LayerEvent { layer .running_mut(&mgid)? .check_add_online(fgid, Online::Direct(addr), sid, fid)?; - results.rpcs.push(rpc::friend_online(mgid, fid, addr)); + let data = postcard::to_allocvec(&LayerEvent::OnlinePong).unwrap_or(vec![]); let msg = SendType::Event(0, addr, data); results.layers.push((mgid, fgid, msg)); @@ -643,7 +642,6 @@ impl LayerEvent { layer .running_mut(&mgid)? .check_add_online(fgid, Online::Direct(addr), sid, fid)?; - results.rpcs.push(rpc::friend_online(mgid, fid, addr)); } LayerEvent::Close => { layer.group.write().await.broadcast( diff --git a/src/apps/chat/rpc.rs b/src/apps/chat/rpc.rs index 81183c0..89b6ba7 100644 --- a/src/apps/chat/rpc.rs +++ b/src/apps/chat/rpc.rs @@ -17,16 +17,6 @@ use crate::storage::{chat_db, delete_avatar, session_db}; use super::layer::LayerEvent; use super::{Friend, Message, MessageType, Request}; -#[inline] -pub(crate) fn friend_online(mgid: GroupId, fid: i64, addr: PeerAddr) -> RpcParam { - rpc_response(0, "chat-friend-online", json!([fid, addr.to_hex()]), mgid) -} - -#[inline] -pub(crate) fn friend_offline(mgid: GroupId, fid: i64, gid: &GroupId) -> RpcParam { - rpc_response(0, "chat-friend-offline", json!([fid, gid.to_hex()]), mgid) -} - #[inline] pub(crate) fn friend_info(mgid: GroupId, friend: &Friend) -> RpcParam { rpc_response(0, "chat-friend-info", json!(friend.to_rpc()), mgid) diff --git a/src/event.rs b/src/event.rs index 4091a2d..8b0dee9 100644 --- a/src/event.rs +++ b/src/event.rs @@ -487,9 +487,7 @@ impl StatusEvent { StatusEvent::SessionFriendOnline(rgid) => { let db = chat_db(group.base(), &gid)?; if let Some(f) = Friend::get_it(&db, &rgid)? { - results - .rpcs - .push(chat_rpc::friend_online(gid, f.id, f.addr)); + // TODO } } StatusEvent::SessionFriendOffline(rgid) => { @@ -503,12 +501,7 @@ impl StatusEvent { tdn::smol::spawn(async move { if let Ok(running) = layer_lock.write().await.running_mut(&ggid) { if running.check_offline(&rgid, &addr) { - let msg = SendMessage::Rpc( - uid, - chat_rpc::friend_offline(ggid, rid, &rgid), - true, - ); - let _ = sender.send(msg).await; + // TODO } } })