Browse Source

clear up UI architecutre

pull/6/head
Sun 4 years ago
parent
commit
b9b334c6cc
  1. 0
      lib/account.dart
  2. 0
      lib/apps/assistant/models.dart
  3. 481
      lib/apps/assistant/pages.dart
  4. 0
      lib/apps/assistant/provider.dart
  5. 41
      lib/apps/chat/add.dart
  6. 34
      lib/apps/chat/detail.dart
  7. 40
      lib/apps/chat/list.dart
  8. 111
      lib/apps/chat/models.dart
  9. 348
      lib/apps/chat/provider.dart
  10. 0
      lib/apps/device/models.dart
  11. 11
      lib/apps/device/page.dart
  12. 97
      lib/apps/device/provider.dart
  13. 0
      lib/apps/domain/models.dart
  14. 0
      lib/apps/domain/page.dart
  15. 0
      lib/apps/domain/provider.dart
  16. 0
      lib/apps/file/models.dart
  17. 247
      lib/apps/file/page.dart
  18. 0
      lib/apps/file/provider.dart
  19. 0
      lib/apps/service/add.dart
  20. 103
      lib/apps/service/list.dart
  21. 0
      lib/apps/service/models.dart
  22. 0
      lib/apps/service/provider.dart
  23. 7
      lib/main.dart
  24. 114
      lib/models/friend.dart
  25. 13
      lib/pages/account_generate.dart
  26. 13
      lib/pages/account_restore.dart
  27. 248
      lib/pages/file.dart
  28. 112
      lib/pages/home.dart
  29. 6
      lib/pages/setting/network.dart
  30. 6
      lib/pages/setting/profile.dart
  31. 191
      lib/provider.dart
  32. 553
      lib/provider/account.dart
  33. 97
      lib/provider/device.dart
  34. 371
      lib/provider/session.dart
  35. 17
      lib/rpc.dart
  36. 18
      lib/security.dart
  37. 11
      lib/utils/better_print.dart
  38. 2
      lib/utils/logined_cache.dart
  39. 13
      lib/widgets/chat_message.dart
  40. 84
      lib/widgets/list_service.dart
  41. 6
      lib/widgets/user_info.dart
  42. 54
      src/apps/chat/rpc.rs
  43. 9
      src/rpc.rs

0
lib/models/account.dart → lib/account.dart

0
lib/models/group.dart → lib/apps/assistant/models.dart

481
lib/apps/assistant/pages.dart

@ -0,0 +1,481 @@ @@ -0,0 +1,481 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/utils/toast.dart';
import 'package:esse/utils/pick_image.dart';
import 'package:esse/utils/pick_file.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/models/message.dart';
import 'package:esse/widgets/emoji.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/audio_recorder.dart';
import 'package:esse/widgets/user_info.dart';
import 'package:esse/widgets/chat_message.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/global.dart';
class AssistantPage extends StatefulWidget {
const AssistantPage({Key key}) : super(key: key);
@override
_AssistantPageState createState() => _AssistantPageState();
}
class _AssistantPageState extends State<AssistantPage> {
TextEditingController textController = TextEditingController();
FocusNode textFocus = FocusNode();
bool emojiShow = false;
bool sendShow = false;
bool menuShow = false;
bool recordShow = false;
String _recordName;
@override
initState() {
super.initState();
textFocus.addListener(() {
if (textFocus.hasFocus) {
setState(() {
emojiShow = false;
menuShow = false;
recordShow = false;
});
}
});
}
_generateRecordPath() {
this._recordName = DateTime.now().millisecondsSinceEpoch.toString() + '_assistant.m4a';
}
void _sendMessage() async {
if (textController.text.length < 1) {
return;
}
// TODO send
setState(() {
textController.text = '';
textFocus.requestFocus();
emojiShow = false;
sendShow = false;
menuShow = false;
recordShow = false;
});
}
void _selectEmoji(value) {
textController.text += value;
}
void _sendImage() async {
final image = await pickImage();
if (image != null) {
// TODO send
}
setState(() {
textFocus.requestFocus();
emojiShow = false;
sendShow = false;
menuShow = false;
recordShow = false;
});
}
void _sendFile() async {
final file = await pickFile();
if (file != null) {
// TODO send
}
setState(() {
textFocus.requestFocus();
emojiShow = false;
sendShow = false;
menuShow = false;
recordShow = false;
});
}
void _sendRecord(int time) async {
final raw = Message.rawRecordName(time, _recordName);
// TODO send
setState(() {
textFocus.requestFocus();
emojiShow = false;
sendShow = false;
menuShow = false;
recordShow = false;
});
}
void _sendContact(ColorScheme color, AppLocalizations lang, friends) {
showShadowDialog(
context,
Icons.person_rounded,
'Contact',
Column(children: [
Container(
height: 40.0,
decoration: BoxDecoration(
color: color.surface,
borderRadius: BorderRadius.circular(15.0)),
child: TextField(
autofocus: false,
textInputAction: TextInputAction.search,
textAlignVertical: TextAlignVertical.center,
style: TextStyle(fontSize: 14.0),
onSubmitted: (value) {
toast(context, 'WIP...');
},
decoration: InputDecoration(
hintText: lang.search,
hintStyle: TextStyle(color: color.onPrimary.withOpacity(0.5)),
border: InputBorder.none,
contentPadding:
EdgeInsets.only(left: 15.0, right: 15.0, bottom: 15.0),
),
),
),
SizedBox(height: 15.0),
Column(
children: friends.map<Widget>((contact) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () async {
// TODO send
Navigator.of(context).pop();
setState(() {
textFocus.requestFocus();
emojiShow = false;
sendShow = false;
menuShow = false;
recordShow = false;
});
},
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 14.0),
child: Row(
children: [
contact.showAvatar(),
SizedBox(width: 15.0),
Text(contact.name, style: TextStyle(fontSize: 16.0)),
],
),
),
);
}).toList())
]));
}
@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
final isDesktop = isDisplayDesktop(context);
final recentMessages = {};
final recentMessageKeys = recentMessages.keys.toList().reversed.toList();
return Column(
children: [
Container(
padding: EdgeInsets.only(left: 20.0, right: 20.0, top: 10.0, bottom: 10.0),
child: Row(
children: [
if (!isDesktop)
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Container(
width: 20.0,
child:
Icon(Icons.arrow_back, color: color.primary)),
),
SizedBox(width: 15.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('esse',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 6.0),
Text(lang.online,
style: TextStyle(color: color.onPrimary.withOpacity(0.5), fontSize: 14.0))
],
),
),
SizedBox(width: 20.0),
GestureDetector(
onTap: () {},
child: Container(
width: 20.0,
child: Icon(Icons.phone_rounded,
color: Color(0x26ADB0BB))),
),
SizedBox(width: 20.0),
GestureDetector(
onTap: () {},
child: Container(
width: 20.0,
child: Icon(Icons.videocam_rounded,
color: Color(0x26ADB0BB))),
),
SizedBox(width: 20.0),
PopupMenuButton<int>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)
),
color: const Color(0xFFEDEDED),
child: Icon(Icons.more_vert_rounded, color: color.primary),
onSelected: (int value) {
if (value == 1) {
// TODO set top
} else if (value == 2) {
showShadowDialog(
context,
Icons.info,
lang.friendInfo,
UserInfo(
id: 'ES0000000000000000000000000000000000000000000000000000000000000000',
name: 'esse',
addr: '0x0000000000000000000000000000000000000000000000000000000000000000')
);
}
},
itemBuilder: (context) {
return <PopupMenuEntry<int>>[
_menuItem(color.primary, 1, Icons.vertical_align_top_rounded, lang.cancelTop),
_menuItem(color.primary, 2, Icons.qr_code_rounded, lang.friendInfo),
];
},
)
]
),
),
const Divider(height: 1.0, color: Color(0x40ADB0BB)),
Expanded(
child: ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 20.0),
itemCount: recentMessageKeys.length,
reverse: true,
itemBuilder: (BuildContext context, index) => ChatMessage(
name: 'esse',
message: recentMessages[recentMessageKeys[index]],
)
)),
Container(
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
child: Row(
children: [
GestureDetector(
onTap: () async {
if (recordShow) {
recordShow = false;
textFocus.requestFocus();
} else {
_generateRecordPath();
setState(() {
menuShow = false;
emojiShow = false;
recordShow = true;
textFocus.unfocus();
});
}
},
child: Container(width: 20.0,
child: Icon(Icons.mic_rounded, color: color.primary)),
),
SizedBox(width: 10.0),
Expanded(
child: Container(
height: 40,
decoration: BoxDecoration(
color: color.surface,
borderRadius: BorderRadius.circular(15.0),
),
child: TextField(
style: TextStyle(fontSize: 14.0),
textInputAction: TextInputAction.send,
onChanged: (value) {
if (value.length == 0 && sendShow) {
setState(() {
sendShow = false;
});
} else {
if (!sendShow) {
setState(() {
sendShow = true;
});
}
}
},
onSubmitted: (_v) => _sendMessage(),
decoration: InputDecoration(
hintText: 'Aa',
border: InputBorder.none,
contentPadding: EdgeInsets.only(
left: 15.0, right: 15.0, bottom: 7.0),
),
controller: textController,
focusNode: textFocus,
),
),
),
SizedBox(width: 10.0),
GestureDetector(
onTap: () {
if (emojiShow) {
textFocus.requestFocus();
} else {
setState(() {
menuShow = false;
recordShow = false;
emojiShow = true;
textFocus.unfocus();
});
}
},
child: Container(
width: 20.0,
child: Icon(
emojiShow
? Icons.keyboard_rounded
: Icons.emoji_emotions_rounded,
color: color.primary)),
),
SizedBox(width: 10.0),
sendShow
? GestureDetector(
onTap: _sendMessage,
child: Container(
width: 50.0,
height: 30.0,
decoration: BoxDecoration(
color: color.primary,
borderRadius: BorderRadius.circular(10.0),
),
child: Center(
child: Icon(Icons.send, color: Colors.white, size: 20.0))),
)
: GestureDetector(
onTap: () {
if (menuShow) {
textFocus.requestFocus();
} else {
setState(() {
emojiShow = false;
recordShow = false;
menuShow = true;
textFocus.unfocus();
});
}
},
child: Container(
width: 20.0,
child: Icon(Icons.add_circle_rounded, color: color.primary)),
),
],
),
),
if (emojiShow) Emoji(action: _selectEmoji),
if (recordShow)
Container(
height: 100.0,
child: AudioRecorder(
path: Global.recordPath + _recordName, onStop: _sendRecord),
),
if (menuShow)
Container(
height: 100.0,
child: Wrap(
spacing: 20.0,
runSpacing: 20.0,
alignment: WrapAlignment.center,
children: <Widget>[
ExtensionButton(
icon: Icons.image_rounded,
text: lang.album,
action: _sendImage,
bgColor: color.surface,
iconColor: color.primary),
ExtensionButton(
icon: Icons.folder_rounded,
text: lang.file,
action: _sendFile,
bgColor: color.surface,
iconColor: color.primary),
ExtensionButton(
icon: Icons.person_rounded,
text: lang.contact,
action: () => _sendContact(color, lang,
context.read<AccountProvider>().friends.values),
bgColor: color.surface,
iconColor: color.primary),
],
),
)
],
);
}
}
class ExtensionButton extends StatelessWidget {
final String text;
final IconData icon;
final Function action;
final Color bgColor;
final Color iconColor;
const ExtensionButton({
Key key,
this.icon,
this.text,
this.action,
this.bgColor,
this.iconColor,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: action,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(10.0),
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(15.0),
),
child: Icon(icon, color: iconColor, size: 36.0)),
SizedBox(height: 5.0),
Text(text, style: TextStyle(fontSize: 14.0)),
],
));
}
}
Widget _menuItem(Color color, int value, IconData icon, String text) {
return PopupMenuItem<int>(
value: value,
child: Row(
children: [
Icon(icon, color: color),
Padding(
padding: const EdgeInsets.only(left: 20.0, right: 10.0),
child: Text(text, style: TextStyle(color: Colors.black, fontSize: 16.0)),
)
]
),
);
}

0
lib/provider/service.dart → lib/apps/assistant/provider.dart

41
lib/pages/friend_add.dart → lib/apps/chat/add.dart

@ -6,28 +6,31 @@ import 'package:provider/provider.dart'; @@ -6,28 +6,31 @@ import 'package:provider/provider.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/utils/better_print.dart';
import 'package:esse/widgets/button_text.dart';
import 'package:esse/widgets/input_text.dart';
import 'package:esse/widgets/user_info.dart';
import 'package:esse/widgets/shadow_button.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/qr_scan.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/global.dart';
import 'package:esse/provider.dart';
class FriendAddPage extends StatefulWidget {
import 'package:esse/apps/chat/models.dart';
import 'package:esse/apps/chat/provider.dart';
class ChatAddPage extends StatefulWidget {
final String id;
final String addr;
final String name;
FriendAddPage({Key key, this.id = '', this.addr = '', this.name = ''}) : super(key: key);
ChatAddPage({Key key, this.id = '', this.addr = '', this.name = ''}) : super(key: key);
@override
_FriendAddPageState createState() => _FriendAddPageState();
_ChatAddPageState createState() => _ChatAddPageState();
}
class _FriendAddPageState extends State<FriendAddPage> {
class _ChatAddPageState extends State<ChatAddPage> {
final _formKey = GlobalKey<FormState>();
TextEditingController userIdEditingController = TextEditingController();
TextEditingController addrEditingController = TextEditingController();
@ -69,7 +72,7 @@ class _FriendAddPageState extends State<FriendAddPage> { @@ -69,7 +72,7 @@ class _FriendAddPageState extends State<FriendAddPage> {
var name = nameEditingController.text;
var remark = remarkEditingController.text;
context.read<AccountProvider>().requestCreate(Request(id, addr, name, remark));
context.read<ChatProvider>().requestCreate(Request(id, addr, name, remark));
setState(() {
userIdEditingController.text = '';
addrEditingController.text = '';
@ -95,7 +98,7 @@ class _FriendAddPageState extends State<FriendAddPage> { @@ -95,7 +98,7 @@ class _FriendAddPageState extends State<FriendAddPage> {
setState(() {});
});
new Future.delayed(Duration.zero, () {
context.read<AccountProvider>().requestList();
context.read<ChatProvider>().requestList();
});
}
@ -104,9 +107,11 @@ class _FriendAddPageState extends State<FriendAddPage> { @@ -104,9 +107,11 @@ class _FriendAddPageState extends State<FriendAddPage> {
final isDesktop = isDisplayDesktop(context);
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
final provider = context.watch<AccountProvider>();
final provider = context.watch<ChatProvider>();
final requests = provider.requests;
final account = provider.activedAccount;
final account = context.read<AccountProvider>().activedAccount;
final requestKeys = requests.keys.toList().reversed.toList(); // it had sorted.
return Scaffold(
@ -119,7 +124,7 @@ class _FriendAddPageState extends State<FriendAddPage> { @@ -119,7 +124,7 @@ class _FriendAddPageState extends State<FriendAddPage> {
if (!isDesktop)
GestureDetector(
onTap: () {
context.read<AccountProvider>().requestClear();
context.read<ChatProvider>().requestClear();
Navigator.pop(context);
},
child: Container(
@ -249,7 +254,7 @@ class _RequestItem extends StatelessWidget { @@ -249,7 +254,7 @@ class _RequestItem extends StatelessWidget {
Expanded(
child: Tooltip(
message: text,
child: Text(Friend.betterPrint(text)),
child: Text(betterPrint(text)),
)
)
]
@ -276,7 +281,7 @@ class _RequestItem extends StatelessWidget { @@ -276,7 +281,7 @@ class _RequestItem extends StatelessWidget {
InkWell(
onTap: () {
Navigator.pop(context);
Provider.of<AccountProvider>(context, listen: false).requestDelete(request.id);
Provider.of<ChatProvider>(context, listen: false).requestDelete(request.id);
},
hoverColor: Colors.transparent,
child: Container(
@ -296,7 +301,7 @@ class _RequestItem extends StatelessWidget { @@ -296,7 +301,7 @@ class _RequestItem extends StatelessWidget {
InkWell(
onTap: () {
Navigator.pop(context);
Provider.of<AccountProvider>(context, listen: false).requestReject(request.id);
Provider.of<ChatProvider>(context, listen: false).requestReject(request.id);
},
hoverColor: Colors.transparent,
child: Container(
@ -312,7 +317,7 @@ class _RequestItem extends StatelessWidget { @@ -312,7 +317,7 @@ class _RequestItem extends StatelessWidget {
InkWell(
onTap: () {
Navigator.pop(context);
Provider.of<AccountProvider>(context, listen: false).requestAgree(request.id);
Provider.of<ChatProvider>(context, listen: false).requestAgree(request.id);
},
hoverColor: Colors.transparent,
child: Container(
@ -334,7 +339,7 @@ class _RequestItem extends StatelessWidget { @@ -334,7 +339,7 @@ class _RequestItem extends StatelessWidget {
InkWell(
onTap: () {
Navigator.pop(context);
Provider.of<AccountProvider>(context, listen: false).requestDelete(request.id);
Provider.of<ChatProvider>(context, listen: false).requestDelete(request.id);
},
hoverColor: Colors.transparent,
child: Container(
@ -350,7 +355,7 @@ class _RequestItem extends StatelessWidget { @@ -350,7 +355,7 @@ class _RequestItem extends StatelessWidget {
InkWell(
onTap: () {
Navigator.pop(context);
Provider.of<AccountProvider>(context, listen: false).requestCreate(request);
Provider.of<ChatProvider>(context, listen: false).requestCreate(request);
},
hoverColor: Colors.transparent,
child: Container(
@ -414,7 +419,7 @@ class _RequestItem extends StatelessWidget { @@ -414,7 +419,7 @@ class _RequestItem extends StatelessWidget {
)),
if (!request.over && !request.isMe)
InkWell(
onTap: () => context.read<AccountProvider>().requestAgree(request.id),
onTap: () => context.read<ChatProvider>().requestAgree(request.id),
hoverColor: Colors.transparent,
child: Container(
height: 35.0,

34
lib/pages/friend.dart → lib/apps/chat/detail.dart

@ -6,15 +6,16 @@ import 'package:esse/utils/toast.dart'; @@ -6,15 +6,16 @@ import 'package:esse/utils/toast.dart';
import 'package:esse/utils/pick_image.dart';
import 'package:esse/utils/pick_file.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/models/message.dart';
import 'package:esse/widgets/emoji.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/audio_recorder.dart';
import 'package:esse/widgets/user_info.dart';
import 'package:esse/widgets/chat_message.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/global.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/chat/models.dart';
import 'package:esse/apps/chat/provider.dart';
class ChatPage extends StatelessWidget {
const ChatPage({Key key}) : super(key: key);
@ -72,7 +73,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -72,7 +73,7 @@ class _ChatDetailState extends State<ChatDetail> {
return;
}
context.read<AccountProvider>().messageCreate(Message(friend.id, MessageType.String, textController.text));
context.read<ChatProvider>().messageCreate(Message(friend.id, MessageType.String, textController.text));
setState(() {
textController.text = '';
textFocus.requestFocus();
@ -91,7 +92,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -91,7 +92,7 @@ class _ChatDetailState extends State<ChatDetail> {
void _sendImage() async {
final image = await pickImage();
if (image != null) {
context.read<AccountProvider>().messageCreate(Message(friend.id, MessageType.Image, image));
context.read<ChatProvider>().messageCreate(Message(friend.id, MessageType.Image, image));
}
setState(() {
textFocus.requestFocus();
@ -105,7 +106,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -105,7 +106,7 @@ class _ChatDetailState extends State<ChatDetail> {
void _sendFile() async {
final file = await pickFile();
if (file != null) {
context.read<AccountProvider>().messageCreate(Message(friend.id, MessageType.File, file));
context.read<ChatProvider>().messageCreate(Message(friend.id, MessageType.File, file));
}
setState(() {
textFocus.requestFocus();
@ -118,7 +119,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -118,7 +119,7 @@ class _ChatDetailState extends State<ChatDetail> {
void _sendRecord(int time) async {
final raw = Message.rawRecordName(time, _recordName);
context.read<AccountProvider>().messageCreate(Message(friend.id, MessageType.Record, raw));
context.read<ChatProvider>().messageCreate(Message(friend.id, MessageType.Record, raw));
setState(() {
textFocus.requestFocus();
@ -163,7 +164,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -163,7 +164,7 @@ class _ChatDetailState extends State<ChatDetail> {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () async {
context.read<AccountProvider>().messageCreate(Message(friend.id, MessageType.Contact, "${contact.id}"));
context.read<ChatProvider>().messageCreate(Message(friend.id, MessageType.Contact, "${contact.id}"));
Navigator.of(context).pop();
setState(() {
textFocus.requestFocus();
@ -195,11 +196,11 @@ class _ChatDetailState extends State<ChatDetail> { @@ -195,11 +196,11 @@ class _ChatDetailState extends State<ChatDetail> {
final lang = AppLocalizations.of(context);
final isDesktop = isDisplayDesktop(context);
final provider = context.watch<AccountProvider>();
final provider = context.watch<ChatProvider>();
final recentMessages = provider.activedMessages;
final recentMessageKeys = recentMessages.keys.toList().reversed.toList();
final meName = provider.activedAccount.name;
final meName = context.read<AccountProvider>().activedAccount.name;
this.friend = provider.activedFriend;
if (this.friend == null) {
@ -219,7 +220,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -219,7 +220,7 @@ class _ChatDetailState extends State<ChatDetail> {
if (!isDesktop)
GestureDetector(
onTap: () {
context.read<AccountProvider>().clearActivedFriend();
context.read<ChatProvider>().clearActivedFriend();
Navigator.pop(context);
},
child: Container(
@ -271,7 +272,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -271,7 +272,7 @@ class _ChatDetailState extends State<ChatDetail> {
child: Icon(Icons.more_vert_rounded, color: color.primary),
onSelected: (int value) {
if (value == 1) {
Provider.of<AccountProvider>(context, listen: false).friendUpdate(
Provider.of<ChatProvider>(context, listen: false).friendUpdate(
this.friend.id, isTop: !this.friend.isTop);
} else if (value == 2) {
showShadowDialog(
@ -302,7 +303,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -302,7 +303,7 @@ class _ChatDetailState extends State<ChatDetail> {
child: Text(lang.ok),
onPressed: () {
Navigator.pop(context);
Provider.of<AccountProvider>(
Provider.of<ChatProvider>(
context, listen: false).friendClose(this.friend.id);
if (!isDesktop) {
Navigator.pop(context);
@ -314,7 +315,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -314,7 +315,7 @@ class _ChatDetailState extends State<ChatDetail> {
},
);
} else if (value == 5) {
Provider.of<AccountProvider>(context, listen: false).requestCreate(
Provider.of<ChatProvider>(context, listen: false).requestCreate(
Request(this.friend.gid, this.friend.addr, this.friend.name, lang.fromContactCard(meName)));
} else if (value == 6) {
showDialog(
@ -333,7 +334,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -333,7 +334,7 @@ class _ChatDetailState extends State<ChatDetail> {
child: Text(lang.ok),
onPressed: () {
Navigator.pop(context);
Provider.of<AccountProvider>(
Provider.of<ChatProvider>(
context, listen: false).friendDelete(this.friend.id);
if (!isDesktop) {
Navigator.pop(context);
@ -521,8 +522,7 @@ class _ChatDetailState extends State<ChatDetail> { @@ -521,8 +522,7 @@ class _ChatDetailState extends State<ChatDetail> {
ExtensionButton(
icon: Icons.person_rounded,
text: lang.contact,
action: () => _sendContact(color, lang,
context.read<AccountProvider>().friends.values),
action: () => _sendContact(color, lang, context.read<ChatProvider>().friends.values),
bgColor: color.surface,
iconColor: color.primary),
],

40
lib/widgets/list_friend.dart → lib/apps/chat/list.dart

@ -3,14 +3,38 @@ import 'package:provider/provider.dart'; @@ -3,14 +3,38 @@ import 'package:provider/provider.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/pages/friend.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/provider.dart';
class ListFriend extends StatelessWidget {
final Friend friend;
import 'package:esse/apps/chat/provider.dart';
import 'package:esse/apps/chat/models.dart';
import 'package:esse/apps/chat/detail.dart';
class ChatList extends StatefulWidget {
const ChatList({Key key}) : super(key: key);
const ListFriend({Key key, this.friend}) : super(key: key);
@override
_ChatListState createState() => _ChatListState();
}
class _ChatListState extends State<ChatList> {
@override
Widget build(BuildContext context) {
final provider = context.watch<ChatProvider>();
final friends = provider.friends;
final chatKeys = provider.orderKeys;
return Expanded(
child: ListView.builder(
itemCount: chatKeys.length,
itemBuilder: (BuildContext ctx, int index) => ListChat(friend: friends[chatKeys[index]]),
));
}
}
class ListChat extends StatelessWidget {
final Friend friend;
const ListChat({Key key, this.friend}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -21,7 +45,7 @@ class ListFriend extends StatelessWidget { @@ -21,7 +45,7 @@ class ListFriend extends StatelessWidget {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
context.read<AccountProvider>().updateActivedFriend(friend.id, isDesktop);
context.read<ChatProvider>().updateActivedFriend(friend.id);
if (!isDesktop) {
Navigator.push(
context,
@ -29,6 +53,8 @@ class ListFriend extends StatelessWidget { @@ -29,6 +53,8 @@ class ListFriend extends StatelessWidget {
builder: (_) => ChatPage(),
),
);
} else {
context.read<AccountProvider>().updateActivedApp(ChatDetail());
}
},
child: Container(

111
lib/models/message.dart → lib/apps/chat/models.dart

@ -1,6 +1,117 @@ @@ -1,6 +1,117 @@
import 'package:esse/utils/relative_time.dart';
import 'package:esse/widgets/avatar.dart';
import 'package:esse/global.dart';
class Friend {
int id;
String gid;
String name;
String addr;
String remark;
bool isTop;
bool isClosed;
RelativeTime lastMessageTime;
String lastMessageContent;
bool lastMessageReaded;
bool online = false;
// new friend from network
Friend(this.gid, this.name, this.addr) {
this.isTop = false;
this.isClosed = false;
this.lastMessageTime = RelativeTime();
this.lastMessageContent = '';
this.lastMessageReaded = true;
}
Avatar showAvatar({double width = 45.0, bool needOnline = true}) {
final avatar = Global.avatarPath + this.gid + '.png';
return Avatar(
width: width,
name: this.name,
avatarPath: avatar,
online: this.online,
needOnline: needOnline,
hasNew: !this.lastMessageReaded,
);
}
updateLastMessage(Message msg, bool isReaded) {
this.lastMessageTime = msg.time;
this.lastMessageContent = msg.shortShow();
this.lastMessageReaded = isReaded;
}
static String betterPrint(String info) {
if (info == null) {
return '';
}
final len = info.length;
if (len > 8) {
return info.substring(0, 8) + '...' + info.substring(len - 6, len);
} else {
return info;
}
}
Friend.fromList(List params) {
this.id = params[0];
this.gid = params[1];
this.addr = params[2];
this.name = params[3];
this.remark = params[4];
this.isTop = params[5] == "1";
this.isClosed = params[6] == "1";
this.lastMessageTime = RelativeTime.fromInt(params[7]);
this.lastMessageContent = params[8];
this.lastMessageReaded = params[9];
this.online = params[10] == "1";
}
}
class Request {
int id;
String gid;
String addr;
String name;
String remark;
bool isMe = true;
bool ok = false;
bool over = false;
bool isDelivery = false;
RelativeTime time = RelativeTime();
Request(this.gid, this.addr, this.name, this.remark);
overIt(bool isOk) {
this.over = true;
this.ok = isOk;
}
Friend toFriend(String gid) {
return Friend(gid, this.name, this.addr);
}
Avatar showAvatar([double width = 45.0]) {
final avatar = Global.avatarPath + this.gid + '.png';
return Avatar(
width: width, name: this.name, avatarPath: avatar, needOnline: false);
}
Request.fromList(List params) {
this.id = params[0];
this.gid = params[1];
this.addr = params[2];
this.name = params[3];
this.remark = params[4];
this.isMe = params[5];
this.ok = params[6];
this.over = params[7];
this.isDelivery = params[8];
this.time = RelativeTime.fromInt(params[9]);
}
}
enum MessageType {
String,
Image,

348
lib/apps/chat/provider.dart

@ -0,0 +1,348 @@ @@ -0,0 +1,348 @@
import 'dart:async';
import "dart:collection";
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:esse/utils/relative_time.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
import 'package:esse/apps/chat/models.dart';
import 'package:esse/apps/chat/detail.dart';
class ChatProvider extends ChangeNotifier {
Map<int, Friend> friends = {}; // all friends. friends need Re-order.
int activedFriendId; // actived friend's id.
Friend get activedFriend => this.friends[this.activedFriendId];
List<int> orderKeys = []; // ordered chat friends with last message.
Map<int, RelativeTime> topKeys = {}; // Set toped friends.
/// all requests. request have order.
SplayTreeMap<int, Request> requests = SplayTreeMap();
/// current show messages. init number is 100, message have order.
SplayTreeMap<int, Message> activedMessages = SplayTreeMap();
void orderFriends(int id) {
if (this.orderKeys.length == 0 || this.orderKeys[0] != id) {
this.orderKeys.remove(id);
this.orderKeys.insert(0, id);
}
}
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);
rpc.addListener('chat-request-list', _requestList, false);
rpc.addListener('chat-request-create', _requestCreate, true);
rpc.addListener('chat-request-delivery', _requestDelivery, false);
rpc.addListener('chat-request-agree', _requestAgree, false);
rpc.addListener('chat-request-reject', _requestReject, false);
rpc.addListener('chat-request-delete', _requestDelete, false);
rpc.addListener('chat-message-list', _messageList, false);
rpc.addListener('chat-message-create', _messageCreate, true);
rpc.addListener('chat-message-delete', _messageDelete, false);
rpc.addListener('chat-message-delivery', _messageDelivery, false);
}
clear() {
this.activedFriendId = null;
this.friends.clear();
this.orderKeys.clear();
this.requests.clear();
this.activedMessages.clear();
}
updateActived() {
this.clear();
// load friends.
rpc.send('chat-friend-list', []);
}
updateActivedFriend(int id) {
this.activedFriendId = id;
this.activedMessages.clear();
this.friends[id].lastMessageReaded = true;
rpc.send('chat-message-list', [this.activedFriendId]);
notifyListeners();
}
clearActivedFriend() {
this.activedFriendId = null;
this.activedMessages.clear();
}
/// delete a friend.
friendUpdate(int id, {String remark, bool isTop}) {
if (remark != null) {
this.friends[id].remark = remark;
}
if (isTop != null) {
this.friends[id].isTop = isTop;
if (isTop) {
this.topKeys[id] = this.friends[id].lastMessageTime;
} else {
this.topKeys.remove(id);
}
}
final friend = this.friends[id];
rpc.send('chat-friend-update', [id, friend.remark, friend.isTop]);
notifyListeners();
}
/// delete a friend.
friendClose(int id) {
this.friends[id].isClosed = true;
this.friends[id].online = false;
rpc.send('chat-friend-close', [id]);
notifyListeners();
}
/// delete a friend.
friendDelete(int id) {
if (id == this.activedFriendId) {
this.activedFriendId = null;
this.activedMessages.clear();
}
this.friends.remove(id);
this.orderKeys.remove(id);
this.topKeys.remove(id);
rpc.send('chat-friend-delete', [id]);
notifyListeners();
}
/// list all request.
requestList() {
rpc.send('chat-request-list', []);
}
/// clear the memory requests.
requestClear() {
this.requests.clear();
}
/// create a request for friend.
requestCreate(Request req) {
this.requests.remove(req.id);
rpc.send('chat-request-create', [req.gid, req.addr, req.name, req.remark]);
notifyListeners();
}
/// agree a request for friend.
requestAgree(int id) {
this.requests[id].overIt(true);
rpc.send('chat-request-agree', [id]);
notifyListeners();
}
/// reject a request for friend.
requestReject(int id) {
this.requests[id].overIt(false);
rpc.send('chat-request-reject', [id]);
notifyListeners();
}
/// delte a request for friend.
requestDelete(int id) {
this.requests.remove(id);
rpc.send('chat-request-delete', [id]);
notifyListeners();
}
/// create a message. need core server handle this message.
/// and then this message will show in message list.
messageCreate(Message msg) {
final fgid = this.friends[msg.fid].gid;
rpc.send('chat-message-create', [msg.fid, fgid, msg.type.toInt(), msg.content]);
notifyListeners();
}
/// delete a message.
messageDelete(int id) {
this.activedMessages.remove(id);
rpc.send('chat-message-delete', [id]);
notifyListeners();
}
/// list all friends.
_friendList(List params) async {
this.orderKeys.clear();
this.friends.clear();
params.forEach((params) {
final id = params[0];
this.friends[id] = Friend.fromList(params);
this.orderKeys.add(id);
if (this.friends[id].isTop) {
this.topKeys[id] = this.friends[id].lastMessageTime;
}
});
notifyListeners();
}
_friendOnline(List params) async {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].online = true;
this.friends[id].addr = params[1];
notifyListeners();
}
}
_friendOffline(List params) async {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].online = false;
notifyListeners();
}
}
_friendInfo(List params) async {
final id = params[0];
this.friends[id] = Friend.fromList(params);
if (this.friends[id].isTop) {
this.topKeys[id] = this.friends[id].lastMessageTime;
}
notifyListeners();
}
_friendUpdate(List params) async {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].isTop = params[1];
this.friends[id].remark = params[2];
if (params[1]) {
this.topKeys[id] = this.friends[id].lastMessageTime;
}
notifyListeners();
}
}
_friendClose(List params) async {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].isClosed = true;
this.friends[id].online = false;
notifyListeners();
}
}
/// list requests for friend.
_requestList(List params) async {
this.requests.clear();
params.forEach((param) {
if (param.length == 10) {
this.requests[param[0]] = Request.fromList(param);
}
});
notifyListeners();
}
/// receive a request for friend.
_requestCreate(List params) async {
this.requests[params[0]] = Request.fromList(params);
notifyListeners();
}
/// created request had delivery.
_requestDelivery(List params) async {
final id = params[0];
final isDelivery = params[1];
if (this.requests.containsKey(id)) {
this.requests[id].isDelivery = isDelivery;
notifyListeners();
}
}
/// request for friend receive agree.
_requestAgree(List params) async {
final id = params[0]; // request's id.
if (this.requests.containsKey(id)) {
this.requests[id].overIt(true);
}
var friend = Friend.fromList(params[1]);
this.friends[friend.id] = friend;
orderFriends(friend.id);
notifyListeners();
}
/// request for friend receive reject.
_requestReject(List params) async {
final id = params[0];
if (this.requests.containsKey(id)) {
this.requests[id].overIt(false);
notifyListeners();
}
}
_requestDelete(List params) async {
this.requests.remove(params[0]);
notifyListeners();
}
/// list message with friend.
_messageList(List params) async {
params.forEach((param) {
if (param.length == 8) {
this.activedMessages[param[0]] = Message.fromList(param);
}
});
notifyListeners();
}
/// friend send message to me.
_messageCreate(List params) async {
final msg = Message.fromList(params);
if (msg.fid == this.activedFriendId) {
if (!msg.isDelivery) {
msg.isDelivery = null; // When message create, set is is none;
}
this.friends[msg.fid].updateLastMessage(msg, true);
this.activedMessages[msg.id] = msg;
rpc.send('chat-friend-readed', [this.activedFriendId]);
} else {
if (this.friends.containsKey(msg.fid)) {
this.friends[msg.fid].updateLastMessage(msg, false);
}
}
orderFriends(msg.fid);
notifyListeners();
}
_messageDelete(List params) {
this.activedMessages.remove(params[0]);
notifyListeners();
}
/// created message had delivery.
_messageDelivery(List params) async {
final id = params[0];
final isDelivery = params[1];
if (this.activedMessages.containsKey(id)) {
this.activedMessages[id].isDelivery = isDelivery;
notifyListeners();
}
}
}

0
lib/models/device.dart → lib/apps/device/models.dart

11
lib/pages/device.dart → lib/apps/device/page.dart

@ -6,15 +6,16 @@ import 'package:qr_flutter/qr_flutter.dart'; @@ -6,15 +6,16 @@ import 'package:qr_flutter/qr_flutter.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/device.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/input_text.dart';
import 'package:esse/widgets/button_text.dart';
import 'package:esse/widgets/show_pin.dart';
import 'package:esse/provider/device.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/device/provider.dart';
import 'package:esse/apps/device/models.dart';
class DevicesPage extends StatefulWidget {
@override
@ -148,7 +149,7 @@ class _DevicesPageState extends State<DevicesPage> { @@ -148,7 +149,7 @@ class _DevicesPageState extends State<DevicesPage> {
TextButton(
child: Text(lang.status),
onPressed: () {
Provider.of<DeviceProvider>(context, listen: false).updateActived(device.id);
Provider.of<DeviceProvider>(context, listen: false).updateActivedDevice(device.id);
final widget = DeviceListenPage();
if (isDesktop) {
Provider.of<AccountProvider>(context, listen: false).updateActivedApp(widget);
@ -352,7 +353,7 @@ class _DeviceListenPageState extends State<DeviceListenPage> { @@ -352,7 +353,7 @@ class _DeviceListenPageState extends State<DeviceListenPage> {
children: [
GestureDetector(
onTap: () {
Provider.of<DeviceProvider>(context, listen: false).clearActived();
Provider.of<DeviceProvider>(context, listen: false).clear();
if (isDesktop) {
Provider.of<AccountProvider>(context, listen: false).updateActivedApp(DevicesPage());
} else {

97
lib/apps/device/provider.dart

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
import 'package:flutter/material.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
import 'package:esse/apps/device/models.dart';
class DeviceProvider extends ChangeNotifier {
Map<int, Device> devices = {};
DeviceStatus status = DeviceStatus();
DeviceProvider() {
// rpc.
rpc.addListener('device-list', _list, false);
rpc.addListener('device-create', _create, true);
rpc.addListener('device-delete', _delete, false);
rpc.addListener('device-online', _online, false);
rpc.addListener('device-offline', _offline, false);
rpc.addListener('device-status', _status, false);
}
clear() {
this.status = DeviceStatus();
}
updateActived() {
this.clear();
// load devices.
rpc.send('device-list', []);
}
updateActivedDevice(int id) {
this.clear();
// load status.
rpc.send('device-status', [this.devices[id].addr]);
}
connect(String addr) {
rpc.send('device-connect', [addr]);
}
delete(int id) {
this.devices.remove(id);
rpc.send('device-delete', [id]);
notifyListeners();
}
_list(List params) {
this.devices.clear();
params.forEach((params) {
if (params.length == 6) {
this.devices[params[0]] = Device.fromList(params);
}
});
notifyListeners();
}
_create(List params) {
if (params.length == 6) {
this.devices[params[0]] = Device.fromList(params);
notifyListeners();
}
}
_delete(List params) {
final id = params[0];
if (this.devices.containsKey(id)) {
this.devices.remove(id);
notifyListeners();
}
}
_online(List params) {
final id = params[0];
if (this.devices.containsKey(id)) {
this.devices[id].online = true;
notifyListeners();
}
}
_offline(List params) {
final id = params[0];
if (this.devices.containsKey(id)) {
this.devices[id].online = false;
notifyListeners();
}
}
_status(List params) {
if (params.length == 9) {
this.status = DeviceStatus.fromList(params);
notifyListeners();
}
}
}

0
lib/widgets/list_app.dart → lib/apps/domain/models.dart

0
lib/apps/domain/page.dart

0
lib/apps/domain/provider.dart

0
lib/apps/file/models.dart

247
lib/apps/file/page.dart

@ -0,0 +1,247 @@ @@ -0,0 +1,247 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/utils/file_image.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/provider.dart';
class FolderList extends StatefulWidget {
@override
_FolderListState createState() => _FolderListState();
}
const List FILE_DIRECTORY = [
["Recent", Icons.label_rounded],
["Starred", Icons.star_rounded],
["Home", Icons.home_rounded],
["Documents", Icons.my_library_books_rounded],
["Pictures", Icons.collections_rounded],
["Music", Icons.my_library_music_rounded],
["Videos", Icons.video_collection_rounded],
["Trash", Icons.auto_delete_rounded],
];
class _FolderListState extends State<FolderList> {
int chooseIndex = 0;
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
final isDesktop = isDisplayDesktop(context);
if (isDesktop) {
loadFolder(true, chooseIndex);
}
});
}
loadFolder(bool isDesktop, int index) async {
final widget = FilePage(title: FILE_DIRECTORY[index][0]);
if (isDesktop) {
Provider.of<AccountProvider>(context, listen: false).updateActivedApp(widget);
} else {
Navigator.push(context, MaterialPageRoute(builder: (_) => widget));
}
}
changeItem(int index, bool isDesktop) {
setState(() {
chooseIndex = index;
loadFolder(isDesktop, index);
});
}
Widget item(int index, ColorScheme color, bool isDesktop) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => changeItem(index, isDesktop),
child: SizedBox(
height: 55.0,
child: Row(
children: [
Container(
width: 45.0,
height: 45.0,
margin: const EdgeInsets.only(left: 20.0, right: 15.0),
child: Icon(FILE_DIRECTORY[index][1], size: 24.0, color: color.primary),
decoration: BoxDecoration(
color: color.surface,
borderRadius: BorderRadius.circular(15.0)
),
),
chooseIndex == index
? Text(FILE_DIRECTORY[index][0], style: TextStyle(fontSize: 16.0, color: color.primary))
: Text(FILE_DIRECTORY[index][0], style: TextStyle(fontSize: 16.0))
],
),
),
);
}
@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme;
final isDesktop = isDisplayDesktop(context);
return Expanded(
child: ListView.builder(
itemCount: FILE_DIRECTORY.length,
itemBuilder: (BuildContext ctx, int index) => item(index, color, isDesktop),
));
}
}
class FilePage extends StatelessWidget {
final String title;
const FilePage({Key key, this.title}) : super(key: key);
String remove_dir(String name) {
if (name.endsWith('.dir')) {
final i = name.lastIndexOf('.');
return name.substring(0, i);
}
return name;
}
Widget item(String name) {
final trueName = remove_dir(name);
return Container(
width: 80.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 60.0,
width: 60.0,
padding: const EdgeInsets.only(bottom: 10.0),
child: fileIcon(name, 48.0),
),
Tooltip(
message: trueName,
child: Text(trueName, style: TextStyle(fontSize: 16.0), maxLines: 1, overflow: TextOverflow.ellipsis),
)
]
)
);
}
@override
Widget build(BuildContext context) {
final isDesktop = isDisplayDesktop(context);
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: isDesktop ? CrossAxisAlignment.start : CrossAxisAlignment.center,
children: <Widget>[
Row(
children: [
if (!isDesktop)
GestureDetector(
onTap: () => Navigator.pop(context),
child: Container(width: 20.0, child: Icon(Icons.arrow_back, color: color.primary)),
),
const SizedBox(width: 15.0),
Expanded(child: Text(title, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0))),
PopupMenuButton<int>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)
),
color: const Color(0xFFEDEDED),
child: Icon(Icons.add_rounded, color: color.primary),
onSelected: (int value) {
if (value == 0) {
// new post
} else if (value == 1) {
// new folder
} else if (value == 2) {
// upload file
}
},
itemBuilder: (context) {
return <PopupMenuEntry<int>>[
PopupMenuItem<int>(value: 0,
child: Text('New Post', style: TextStyle(color: Colors.black, fontSize: 16.0)),
),
PopupMenuItem<int>(value: 1,
child: Text('New Folder', style: TextStyle(color: Colors.black, fontSize: 16.0)),
),
PopupMenuItem<int>(value: 2,
child: Text('Upload File', style: TextStyle(color: Colors.black, fontSize: 16.0)),
),
];
}
),
const SizedBox(width: 15.0),
GestureDetector(
onTap: () {}, // view_module_rounded
child: Container(width: 20.0, child: Icon(Icons.view_list_rounded, color: color.primary)),
),
const SizedBox(width: 10.0),
],
),
SizedBox(height: 5.0),
Row(
children: [
const SizedBox(width: 15.0),
InkWell(
onTap: () {
print('Home');
},
child: Text('Home', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB)))
),
Text('/', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB))),
InkWell(
onTap: () {
print('Home/workspace');
},
child: Text('workspace', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB)))
),
Text('/', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB))),
InkWell(
onTap: () {
print('Home/workspace/cymple');
},
child: Text('cymple', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB)))
),
]
),
SizedBox(height: 15.0),
Expanded(
child: Wrap(
spacing: 4.0,
runSpacing: 16.0,
alignment: WrapAlignment.start,
children: <Widget> [
item('myworks.dir'),
item('ESSE-infos-public.dir'),
item('personal.dir'),
item('others.dir'),
item('logo.jpg'),
item('cat.png'),
item('what-is-esse_en.doc'),
item('20210101-customers.xls'),
item('product.pdf'),
item('deck.ppt'),
item('coder.md'),
item('how-to-live-in-happy.mp4'),
item('something_important'),
item('car.json'),
],
)
)
]
)
)
)
);
}
}

0
lib/apps/file/provider.dart

0
lib/pages/group_add.dart → lib/apps/service/add.dart

103
lib/apps/service/list.dart

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/provider.dart';
class ServiceList extends StatefulWidget {
const ServiceList({Key key}) : super(key: key);
@override
_ServiceListState createState() => _ServiceListState();
}
class _ServiceListState extends State<ServiceList> {
@override
Widget build(BuildContext context) {
final serviceKeys = [];
final services = {};
return Expanded(
child: ListView.builder(
itemCount: serviceKeys.length,
itemBuilder: (BuildContext ctx, int index) => _ListService(),
));
}
}
class _ListService extends StatelessWidget {
const _ListService({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
final isDesktop = isDisplayDesktop(context);
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
// final widget = AssistantPage();
// if (isDesktop) {
// Provider.of<AccountProvider>(context, listen: false).updateActivedApp(widget);
// } else {
// Navigator.push(context, MaterialPageRoute(builder: (_) => widget));
// }
},
child: Container(
height: 55.0,
child: Row(
children: [
Container(
width: 45.0,
height: 45.0,
margin: const EdgeInsets.only(left: 20.0, right: 15.0),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/logo/logo_light.png'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(15.0)
),
),
Expanded(
child: Container(
height: 55.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text('esse',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 16.0))
),
Container(
margin: const EdgeInsets.only(left: 15.0, right: 20.0),
child: Text('2021-11-12',
style: const TextStyle(color: Color(0xFFADB0BB), fontSize: 12.0),
),
)
]),
SizedBox(height: 5.0),
Expanded(
child: Text('esse is a echo robot',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Color(0xFFADB0BB), fontSize: 12.0)),
),
],
),
),
),
],
),
),
);
}
}

0
lib/apps/service/models.dart

0
lib/apps/service/provider.dart

7
lib/main.dart

@ -3,8 +3,6 @@ import 'package:provider/provider.dart'; @@ -3,8 +3,6 @@ import 'package:provider/provider.dart';
import 'package:esse_core/esse_core.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/provider/device.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/utils/home_dir.dart';
import 'package:esse/theme.dart';
import 'package:esse/global.dart';
@ -12,6 +10,10 @@ import 'package:esse/options.dart'; @@ -12,6 +10,10 @@ import 'package:esse/options.dart';
import 'package:esse/security.dart';
import 'package:esse/rpc.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/device/provider.dart';
import 'package:esse/apps/chat/provider.dart';
void coreServer() async {
final path = await homeDir();
print("home path: " + path);
@ -37,6 +39,7 @@ void main() { @@ -37,6 +39,7 @@ void main() {
}),
ChangeNotifierProvider(create: (_) => AccountProvider()),
ChangeNotifierProvider(create: (_) => DeviceProvider()),
ChangeNotifierProvider(create: (_) => ChatProvider()),
],
child: MyApp(),
));

114
lib/models/friend.dart

@ -1,114 +0,0 @@ @@ -1,114 +0,0 @@
import 'package:esse/models/message.dart';
import 'package:esse/utils/relative_time.dart';
import 'package:esse/widgets/avatar.dart';
import 'package:esse/global.dart';
class Friend {
int id;
String gid;
String name;
String addr;
String remark;
bool isTop;
bool isClosed;
RelativeTime lastMessageTime;
String lastMessageContent;
bool lastMessageReaded;
bool online = false;
// new friend from network
Friend(this.gid, this.name, this.addr) {
this.isTop = false;
this.isClosed = false;
this.lastMessageTime = RelativeTime();
this.lastMessageContent = '';
this.lastMessageReaded = true;
}
Avatar showAvatar({double width = 45.0, bool needOnline = true}) {
final avatar = Global.avatarPath + this.gid + '.png';
return Avatar(
width: width,
name: this.name,
avatarPath: avatar,
online: this.online,
needOnline: needOnline,
hasNew: !this.lastMessageReaded,
);
}
updateLastMessage(Message msg, bool isReaded) {
this.lastMessageTime = msg.time;
this.lastMessageContent = msg.shortShow();
this.lastMessageReaded = isReaded;
}
static String betterPrint(String info) {
if (info == null) {
return '';
}
final len = info.length;
if (len > 8) {
return info.substring(0, 8) + '...' + info.substring(len - 6, len);
} else {
return info;
}
}
Friend.fromList(List params) {
this.id = params[0];
this.gid = params[1];
this.addr = params[2];
this.name = params[3];
this.remark = params[4];
this.isTop = params[5] == "1";
this.isClosed = params[6] == "1";
this.lastMessageTime = RelativeTime.fromInt(params[7]);
this.lastMessageContent = params[8];
this.lastMessageReaded = params[9];
this.online = params[10] == "1";
}
}
class Request {
int id;
String gid;
String addr;
String name;
String remark;
bool isMe = true;
bool ok = false;
bool over = false;
bool isDelivery = false;
RelativeTime time = RelativeTime();
Request(this.gid, this.addr, this.name, this.remark);
overIt(bool isOk) {
this.over = true;
this.ok = isOk;
}
Friend toFriend(String gid) {
return Friend(gid, this.name, this.addr);
}
Avatar showAvatar([double width = 45.0]) {
final avatar = Global.avatarPath + this.gid + '.png';
return Avatar(
width: width, name: this.name, avatarPath: avatar, needOnline: false);
}
Request.fromList(List params) {
this.id = params[0];
this.gid = params[1];
this.addr = params[2];
this.name = params[3];
this.remark = params[4];
this.isMe = params[5];
this.ok = params[6];
this.over = params[7];
this.isDelivery = params[8];
this.time = RelativeTime.fromInt(params[9]);
}
}

13
lib/pages/account_generate.dart

@ -12,15 +12,17 @@ import 'package:esse/l10n/localizations.dart'; @@ -12,15 +12,17 @@ import 'package:esse/l10n/localizations.dart';
import 'package:esse/utils/pick_image.dart';
import 'package:esse/utils/mnemonic.dart';
import 'package:esse/utils/device_info.dart';
import 'package:esse/models/account.dart';
import 'package:esse/widgets/button_text.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/show_pin.dart';
import 'package:esse/pages/home.dart';
import 'package:esse/provider/device.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/account.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/device/provider.dart';
import 'package:esse/apps/chat/provider.dart';
class AccountGeneratePage extends StatefulWidget {
const AccountGeneratePage({Key key}) : super(key: key);
@ -100,8 +102,11 @@ class _AccountGeneratePageState extends State<AccountGeneratePage> { @@ -100,8 +102,11 @@ class _AccountGeneratePageState extends State<AccountGeneratePage> {
if (res.isOk) {
// save this User
final account = Account(res.params[0], name, lock, avatar);
Provider.of<AccountProvider>(context, listen: false).addAccount(account);
Provider.of<DeviceProvider>(context, listen: false).init();
Provider.of<DeviceProvider>(context, listen: false).updateActived();
Provider.of<ChatProvider>(context, listen: false).updateActived();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage()));
} else {
// TODO tostor error

13
lib/pages/account_restore.dart

@ -4,16 +4,18 @@ import 'package:provider/provider.dart'; @@ -4,16 +4,18 @@ import 'package:provider/provider.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/utils/device_info.dart';
import 'package:esse/models/account.dart';
import 'package:esse/widgets/button_text.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/show_pin.dart';
import 'package:esse/widgets/qr_scan.dart';
import 'package:esse/pages/home.dart';
import 'package:esse/provider/device.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/account.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/device/provider.dart';
import 'package:esse/apps/chat/provider.dart';
class AccountRestorePage extends StatefulWidget {
const AccountRestorePage({Key key}) : super(key: key);
@ -380,8 +382,11 @@ class _AccountRestorePageState extends State<AccountRestorePage> { @@ -380,8 +382,11 @@ class _AccountRestorePageState extends State<AccountRestorePage> {
if (res.isOk) {
// save this User
final account = Account(res.params[0], this._name, lock);
Provider.of<AccountProvider>(context, listen: false).addAccount(account);
Provider.of<DeviceProvider>(context, listen: false).init();
Provider.of<DeviceProvider>(context, listen: false).updateActived();
Provider.of<ChatProvider>(context, listen: false).updateActived();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage()));
} else {
// TODO tostor error

248
lib/pages/file.dart

@ -1,248 +0,0 @@ @@ -1,248 +0,0 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/utils/file_image.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/provider/account.dart';
class ListFolder extends StatefulWidget {
@override
_ListFolderState createState() => _ListFolderState();
}
const List FILE_DIRECTORY = [
["Recent", Icons.label_rounded],
["Starred", Icons.star_rounded],
["Home", Icons.home_rounded],
["Documents", Icons.my_library_books_rounded],
["Pictures", Icons.collections_rounded],
["Music", Icons.my_library_music_rounded],
["Videos", Icons.video_collection_rounded],
["Trash", Icons.auto_delete_rounded],
];
class _ListFolderState extends State<ListFolder> {
int chooseIndex = 0;
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
final isDesktop = isDisplayDesktop(context);
if (isDesktop) {
loadFolder(true, chooseIndex);
}
});
}
loadFolder(bool isDesktop, int index) async {
print('load folder');
final widget = FilePage(title: FILE_DIRECTORY[index][0]);
if (isDesktop) {
Provider.of<AccountProvider>(context, listen: false).updateActivedApp(widget);
} else {
Navigator.push(context, MaterialPageRoute(builder: (_) => widget));
}
}
changeItem(int index, bool isDesktop) {
setState(() {
chooseIndex = index;
loadFolder(isDesktop, index);
});
}
Widget item(int index, ColorScheme color, bool isDesktop) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => changeItem(index, isDesktop),
child: SizedBox(
height: 55.0,
child: Row(
children: [
Container(
width: 45.0,
height: 45.0,
margin: const EdgeInsets.only(left: 20.0, right: 15.0),
child: Icon(FILE_DIRECTORY[index][1], size: 24.0, color: color.primary),
decoration: BoxDecoration(
color: color.surface,
borderRadius: BorderRadius.circular(15.0)
),
),
chooseIndex == index
? Text(FILE_DIRECTORY[index][0], style: TextStyle(fontSize: 16.0, color: color.primary))
: Text(FILE_DIRECTORY[index][0], style: TextStyle(fontSize: 16.0))
],
),
),
);
}
@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme;
final isDesktop = isDisplayDesktop(context);
return Expanded(
child: ListView.builder(
itemCount: FILE_DIRECTORY.length,
itemBuilder: (BuildContext ctx, int index) => item(index, color, isDesktop),
));
}
}
class FilePage extends StatelessWidget {
final String title;
const FilePage({Key key, this.title}) : super(key: key);
String remove_dir(String name) {
if (name.endsWith('.dir')) {
final i = name.lastIndexOf('.');
return name.substring(0, i);
}
return name;
}
Widget item(String name) {
final trueName = remove_dir(name);
return Container(
width: 80.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 60.0,
width: 60.0,
padding: const EdgeInsets.only(bottom: 10.0),
child: fileIcon(name, 48.0),
),
Tooltip(
message: trueName,
child: Text(trueName, style: TextStyle(fontSize: 16.0), maxLines: 1, overflow: TextOverflow.ellipsis),
)
]
)
);
}
@override
Widget build(BuildContext context) {
final isDesktop = isDisplayDesktop(context);
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: isDesktop ? CrossAxisAlignment.start : CrossAxisAlignment.center,
children: <Widget>[
Row(
children: [
if (!isDesktop)
GestureDetector(
onTap: () => Navigator.pop(context),
child: Container(width: 20.0, child: Icon(Icons.arrow_back, color: color.primary)),
),
const SizedBox(width: 15.0),
Expanded(child: Text(title, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0))),
PopupMenuButton<int>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)
),
color: const Color(0xFFEDEDED),
child: Icon(Icons.add_rounded, color: color.primary),
onSelected: (int value) {
if (value == 0) {
// new post
} else if (value == 1) {
// new folder
} else if (value == 2) {
// upload file
}
},
itemBuilder: (context) {
return <PopupMenuEntry<int>>[
PopupMenuItem<int>(value: 0,
child: Text('New Post', style: TextStyle(color: Colors.black, fontSize: 16.0)),
),
PopupMenuItem<int>(value: 1,
child: Text('New Folder', style: TextStyle(color: Colors.black, fontSize: 16.0)),
),
PopupMenuItem<int>(value: 2,
child: Text('Upload File', style: TextStyle(color: Colors.black, fontSize: 16.0)),
),
];
}
),
const SizedBox(width: 15.0),
GestureDetector(
onTap: () {}, // view_module_rounded
child: Container(width: 20.0, child: Icon(Icons.view_list_rounded, color: color.primary)),
),
const SizedBox(width: 10.0),
],
),
SizedBox(height: 5.0),
Row(
children: [
const SizedBox(width: 15.0),
InkWell(
onTap: () {
print('Home');
},
child: Text('Home', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB)))
),
Text('/', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB))),
InkWell(
onTap: () {
print('Home/workspace');
},
child: Text('workspace', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB)))
),
Text('/', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB))),
InkWell(
onTap: () {
print('Home/workspace/cymple');
},
child: Text('cymple', style: TextStyle(fontSize: 14.0, color: Color(0xFFADB0BB)))
),
]
),
SizedBox(height: 15.0),
Expanded(
child: Wrap(
spacing: 4.0,
runSpacing: 16.0,
alignment: WrapAlignment.start,
children: <Widget> [
item('myworks.dir'),
item('ESSE-infos-public.dir'),
item('personal.dir'),
item('others.dir'),
item('logo.jpg'),
item('cat.png'),
item('what-is-esse_en.doc'),
item('20210101-customers.xls'),
item('product.pdf'),
item('deck.ppt'),
item('coder.md'),
item('how-to-live-in-happy.mp4'),
item('something_important'),
item('car.json'),
],
)
)
]
)
)
)
);
}
}

112
lib/pages/home.dart

@ -8,26 +8,29 @@ import 'package:provider/provider.dart'; @@ -8,26 +8,29 @@ import 'package:provider/provider.dart';
import 'package:flutter/cupertino.dart' show CupertinoSwitch;
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/account.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/user_info.dart';
import 'package:esse/widgets/list_system_app.dart';
import 'package:esse/widgets/list_friend.dart';
import 'package:esse/widgets/show_pin.dart';
import 'package:esse/widgets/qr_scan.dart';
import 'package:esse/pages/device.dart';
import 'package:esse/pages/file.dart';
import 'package:esse/pages/friend_add.dart';
import 'package:esse/pages/group_add.dart';
import 'package:esse/pages/setting/profile.dart';
import 'package:esse/pages/setting/preference.dart';
import 'package:esse/pages/setting/network.dart';
import 'package:esse/pages/setting/about.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/provider/device.dart';
import 'package:esse/account.dart';
import 'package:esse/global.dart';
import 'package:esse/options.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/device/provider.dart';
import 'package:esse/apps/device/page.dart';
import 'package:esse/apps/chat/provider.dart';
import 'package:esse/apps/chat/list.dart';
import 'package:esse/apps/chat/add.dart';
import 'package:esse/apps/file/page.dart';
import 'package:esse/apps/service/list.dart';
import 'package:esse/apps/service/add.dart';
class HomePage extends StatelessWidget {
static GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@ -168,7 +171,7 @@ class _HomeListState extends State<HomeList> { @@ -168,7 +171,7 @@ class _HomeListState extends State<HomeList> {
final id = params[0];
final addr = params[1];
final name = params[2];
final widget = FriendAddPage(id: id, addr: addr, name: name);
final widget = ChatAddPage(id: id, addr: addr, name: name);
Provider.of<AccountProvider>(context, listen: false)
.systemAppGroupAddNew = false;
if (isDesktop) {
@ -194,10 +197,9 @@ class _HomeListState extends State<HomeList> { @@ -194,10 +197,9 @@ class _HomeListState extends State<HomeList> {
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
final provider = context.watch<AccountProvider>();
final topKeys = provider.topKeys;
final chatKeys = provider.orderChats;
final groupKeys = provider.groupKeys;
final chatProvider = context.watch<ChatProvider>();
final chatTops = chatProvider.topKeys;
final friends = chatProvider.friends;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
@ -217,41 +219,16 @@ class _HomeListState extends State<HomeList> { @@ -217,41 +219,16 @@ class _HomeListState extends State<HomeList> {
size: 28.0,
),
),
// Expanded(
// child: Container(
// height: 40.0,
// decoration: BoxDecoration(
// color: color.surface,
// borderRadius: BorderRadius.circular(15.0)),
// child: TextField(
// autofocus: false,
// textInputAction: TextInputAction.search,
// textAlignVertical: TextAlignVertical.center,
// style: TextStyle(fontSize: 14.0),
// onSubmitted: (value) {
// toast(context, lang.wip);
// },
// decoration: InputDecoration(
// hintText: lang.search,
// hintStyle:
// TextStyle(color: color.onPrimary.withOpacity(0.5)),
// border: InputBorder.none,
// contentPadding: EdgeInsets.only(
// left: 15.0, right: 15.0, bottom: 15.0),
// ),
// ),
// ),
// ),
Expanded(
child: Center(
child: Text(
isShowFriends
? lang.chats
: (isShowGroups
? lang.groups
: (isShowFiles ? lang.files : '')),
style: TextStyle(fontWeight: FontWeight.bold),
),
child: Center(
child: Text(
isShowFriends
? lang.chats
: (isShowGroups
? lang.groups
: (isShowFiles ? lang.files : '')),
style: TextStyle(fontWeight: FontWeight.bold),
),
)),
Icon(Icons.search_rounded, color: color.primary),
const SizedBox(width: 20.0),
@ -271,7 +248,7 @@ class _HomeListState extends State<HomeList> { @@ -271,7 +248,7 @@ class _HomeListState extends State<HomeList> {
if (value == 0) {
scanQr(isDesktop);
} else if (value == 1) {
final widget = FriendAddPage();
final widget = ChatAddPage();
if (isDesktop) {
provider.updateActivedApp(widget);
} else {
@ -376,29 +353,17 @@ class _HomeListState extends State<HomeList> { @@ -376,29 +353,17 @@ class _HomeListState extends State<HomeList> {
const SizedBox(height: 5.0),
const Divider(height: 1.0, color: Color(0x40ADB0BB)),
const SizedBox(height: 5.0),
]),
]),
if (this.isShowHome)
Expanded(
child: ListView.builder(
itemCount: topKeys.length,
itemBuilder: (BuildContext ctx, int index) => ListFriend(
friend: provider.friends[topKeys.elementAt(index)]),
)),
if (this.isShowFriends)
Expanded(
child: ListView.builder(
itemCount: chatKeys.length,
itemBuilder: (BuildContext ctx, int index) =>
ListFriend(friend: provider.friends[chatKeys[index]]),
)),
if (this.isShowGroups)
Expanded(
child: ListView.builder(
itemCount: groupKeys.length,
itemBuilder: (BuildContext ctx, int index) =>
ListFriend(friend: provider.groups[groupKeys[index]]),
)),
if (this.isShowFiles) ListFolder(),
Expanded(
child: ListView.builder(
itemCount: chatTops.length,
itemBuilder: (BuildContext ctx, int index) => ListChat(
friend: friends[chatTops.keys.elementAt(index)]),
)),
if (this.isShowFriends) ChatList(),
if (this.isShowGroups) ServiceList(),
if (this.isShowFiles) FolderList(),
],
),
);
@ -414,7 +379,8 @@ class DrawerWidget extends StatelessWidget { @@ -414,7 +379,8 @@ class DrawerWidget extends StatelessWidget {
? () {
Navigator.of(context).pop();
Provider.of<AccountProvider>(context, listen: false).updateActivedAccount(account.gid);
Provider.of<DeviceProvider>(context, listen: false).init();
Provider.of<DeviceProvider>(context, listen: false).updateActived();
Provider.of<ChatProvider>(context, listen: false).updateActived();
}
: null,
child: Padding(
@ -542,8 +508,6 @@ class DrawerWidget extends StatelessWidget { @@ -542,8 +508,6 @@ class DrawerWidget extends StatelessWidget {
style: TextStyle(fontSize: 16.0)),
onTap: () {
Navigator.pop(context);
//showShadowDialog(context, Icons.devices_other_rounded, lang.devices,
// DevicesPage());
_showDevices(context, isDesktop);
}),
ListTile(
@ -600,6 +564,8 @@ class DrawerWidget extends StatelessWidget { @@ -600,6 +564,8 @@ class DrawerWidget extends StatelessWidget {
style: TextStyle(fontSize: 16.0)),
onTap: () {
context.read<AccountProvider>().logout();
context.read<DeviceProvider>().clear();
context.read<ChatProvider>().clear();
Navigator.of(context).pushReplacementNamed('/');
}),
SizedBox(height: 20.0),

6
lib/pages/setting/network.dart

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/utils/better_print.dart';
import 'package:esse/widgets/socket_input.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
@ -173,7 +173,7 @@ class _NetworkDetailState extends State<NetworkDetail> { @@ -173,7 +173,7 @@ class _NetworkDetailState extends State<NetworkDetail> {
size: 18.0,
color: color.primary),
SizedBox(width: 15.0),
Text(Friend.betterPrint(item[0]),
Text(betterPrint(item[0]),
style: TextStyle(fontSize: 14.0))
]));
}),
@ -193,7 +193,7 @@ class _NetworkDetailState extends State<NetworkDetail> { @@ -193,7 +193,7 @@ class _NetworkDetailState extends State<NetworkDetail> {
Icon(Icons.cloud_done_outlined,
size: 18.0, color: color.primary),
SizedBox(width: 15.0),
Text(Friend.betterPrint(item),
Text(betterPrint(item),
style: TextStyle(fontSize: 14.0)),
]));
}),

6
lib/pages/setting/profile.dart

@ -5,13 +5,13 @@ import 'package:flutter/material.dart'; @@ -5,13 +5,13 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/utils/pick_image.dart';
import 'package:esse/utils/better_print.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/show_pin.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
import 'package:esse/provider.dart';
class ProfileDetail extends StatefulWidget {
ProfileDetail({Key key}) : super(key: key);
@ -128,7 +128,7 @@ class _ProfileDetailState extends State<ProfileDetail> { @@ -128,7 +128,7 @@ class _ProfileDetailState extends State<ProfileDetail> {
Expanded(
child: Tooltip(
message: text,
child: Text(Friend.betterPrint(text)),
child: Text(betterPrint(text)),
))
]),
);

191
lib/provider.dart

@ -0,0 +1,191 @@ @@ -0,0 +1,191 @@
import 'dart:async';
import "dart:collection";
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:esse/account.dart';
import 'package:esse/utils/logined_cache.dart';
import 'package:esse/widgets/default_core_show.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
const DEFAULT_ONLINE_INIT = 8;
const DEFAULT_ONLINE_DELAY = 5;
class AccountProvider extends ChangeNotifier {
Map<String, Account> accounts = {}; // account's gid and account.
String activedAccountId; // actived account gid.
Account get activedAccount => this.accounts[activedAccountId];
Set<int> topKeys = Set();
/// current user's did.
String get id => this.activedAccount.id;
Widget coreShowWidget = DefaultCoreShow();
bool systemAppFriendAddNew = false;
bool systemAppGroupAddNew = false;
AccountProvider() {
// rpc notice when account not actived.
rpc.addNotice(_accountNotice);
// rpc
rpc.addListener('account-system-info', _systemInfo, false);
rpc.addListener('account-update', _accountUpdate, false);
rpc.addListener('account-login', _accountLogin, false);
systemInfo();
}
handleTops() {
//
}
/// when security load accounts from rpc.
initAccounts(Map accounts) {
this.accounts = accounts;
initLogined(this.accounts.values.toList());
}
/// when security load accounts from cache.
autoAccounts(String gid, Map accounts) {
Global.changeGid(gid);
this.activedAccountId = gid;
this.accounts = accounts;
this.activedAccount.online = true;
rpc.send('account-login', [gid, this.activedAccount.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_INIT),
() => rpc.send('account-online', [gid]));
this.accounts.forEach((k, v) {
if (k != gid && v.online) {
rpc.send('account-login', [v.gid, v.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_INIT),
() => rpc.send('account-online', [v.gid]));
}
});
}
/// when security add account.
addAccount(Account account) {
Global.changeGid(account.gid);
this.activedAccountId = account.gid;
this.accounts[account.gid] = account;
rpc.send('account-login', [account.gid, account.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
() => rpc.send('account-online', [account.gid]));
updateLogined(account);
}
updateActivedAccount(String gid) {
Global.changeGid(gid);
this.clearActivedAccount();
this.activedAccountId = gid;
this.activedAccount.hasNew = false;
rpc.send('friend-list', []);
if (!this.activedAccount.online) {
this.activedAccount.online = true;
rpc.send('account-login', [gid, this.activedAccount.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
() => rpc.send('account-online', [gid]));
}
mainLogined(gid);
notifyListeners();
}
logout() {
this.accounts.clear();
this.clearActivedAccount();
rpc.send('account-logout', []);
clearLogined();
}
onlineAccount(String gid, String lock) {
this.accounts[gid].online = true;
updateLogined(this.accounts[gid]);
rpc.send('account-login', [gid, lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
() => rpc.send('account-online', [gid]));
notifyListeners();
}
offlineAccount(String gid) {
this.accounts[gid].online = false;
updateLogined(this.accounts[gid]);
if (gid == this.activedAccountId) {
this.clearActivedAccount();
}
rpc.send('account-offline', [gid]);
notifyListeners();
}
updateActivedApp(Widget widget) {
this.coreShowWidget = widget;
this.systemAppFriendAddNew = false;
notifyListeners();
}
clearActivedAccount() {
this.topKeys.clear();
}
accountUpdate(String name, [Uint8List avatar]) {
this.activedAccount.name = name;
if (avatar != null && avatar.length > 0) {
this.activedAccount.avatar = avatar;
rpc.send('account-update', [name, this.activedAccount.encodeAvatar()]);
} else {
rpc.send('account-update', [name, '']);
}
updateLogined(this.activedAccount);
notifyListeners();
}
accountPin(String lock) {
this.activedAccount.lock = lock;
updateLogined(this.activedAccount);
notifyListeners();
}
systemInfo() {
rpc.send('account-system-info', []);
}
// -- callback when receive rpc info. -- //
_systemInfo(List params) {
Global.addr = '0x' + params[0];
}
_accountLogin(List _params) {
// nothing.
}
_accountNotice(String gid) {
if (this.accounts.containsKey(gid)) {
this.accounts[gid].hasNew = true;
notifyListeners();
}
}
_accountUpdate(List params) {
final gid = params[0];
this.accounts[gid].name = params[1];
if (params[2].length > 1) {
this.accounts[gid].updateAvatar(params[2]);
}
notifyListeners();
}
}

553
lib/provider/account.dart

@ -1,553 +0,0 @@ @@ -1,553 +0,0 @@
import 'dart:async';
import "dart:collection";
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:esse/models/account.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/models/message.dart';
import 'package:esse/utils/logined_cache.dart';
import 'package:esse/widgets/default_core_show.dart';
import 'package:esse/pages/friend.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
const DEFAULT_ONLINE_INIT = 8;
const DEFAULT_ONLINE_DELAY = 5;
class AccountProvider extends ChangeNotifier {
Map<String, Account> accounts = {}; // account's gid and account.
String activedAccountId; // actived account gid.
Account get activedAccount => this.accounts[activedAccountId];
Map<int, Friend> friends = {}; // all friends. friends need Re-order.
int activedFriendId; // actived friend's id.
Friend get activedFriend => this.friends[this.activedFriendId];
Set<int> topKeys = Set();
List<int> orderChats = []; // ordered chat friends with last message.
Map<int, Friend> groups = {}; // all apps.
/// all requests. request have order.
SplayTreeMap<int, Request> requests = SplayTreeMap();
/// current show messages. init number is 100, message have order.
SplayTreeMap<int, Message> activedMessages = SplayTreeMap();
/// current user's did.
String get id => this.activedAccount.id;
// List<int> get chatKeys => this.orderChats.values.toList();
List<int> get friendKeys => this.friends.keys.toList(); // TODO
List<int> get groupKeys => this.groups.keys.toList();
Widget coreShowWidget = DefaultCoreShow();
bool systemAppFriendAddNew = false;
bool systemAppGroupAddNew = false;
void orderFriends(int id) {
if (this.orderChats.length == 0 || this.orderChats[0] != id) {
this.orderChats.remove(id);
this.orderChats.insert(0, id);
}
}
void addContacts() {
// TODO order contacts.
}
initStates() {
// rpc
rpc.addListener('system-info', _systemInfo);
rpc.addListener('account-update', _accountUpdate);
rpc.addListener('friend-list', _friendList);
rpc.addListener('friend-online', _friendOnline);
rpc.addListener('friend-offline', _friendOffline);
rpc.addListener('friend-info', _friendInfo);
rpc.addListener('friend-update', _friendUpdate);
rpc.addListener('friend-close', _friendClose);
rpc.addListener('request-list', _requestList);
rpc.addListener('request-create', _requestCreate);
rpc.addListener('request-delivery', _requestDelivery);
rpc.addListener('request-agree', _requestAgree);
rpc.addListener('request-reject', _requestReject);
rpc.addListener('request-delete', _requestDelete);
rpc.addListener('message-list', _messageList);
rpc.addListener('message-create', _messageCreate);
rpc.addListener('message-delete', _messageDelete);
rpc.addListener('message-delivery', _messageDelivery);
systemInfo();
}
/// when security load accounts from rpc.
initAccounts(Map accounts) {
this.accounts = accounts;
initStates();
initLogined(this.accounts.values.toList());
}
/// when security load accounts from cache.
autoAccounts(String gid, Map accounts) {
Global.changeGid(gid);
this.activedAccountId = gid;
this.accounts = accounts;
initStates();
rpc.send('friend-list', []);
this.activedAccount.online = true;
rpc.send('account-login', [gid, this.activedAccount.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_INIT),
() => rpc.send('account-online', [gid]));
this.accounts.forEach((k, v) {
if (k != gid && v.online) {
rpc.send('account-login', [v.gid, v.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_INIT),
() => rpc.send('account-online', [v.gid]));
}
});
}
/// when security add account.
addAccount(Account account) {
Global.changeGid(account.gid);
this.activedAccountId = account.gid;
this.accounts[account.gid] = account;
rpc.send('account-login', [account.gid, account.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
() => rpc.send('account-online', [account.gid]));
updateLogined(account);
}
updateActivedAccount(String gid) {
Global.changeGid(gid);
this.clearActivedAccount();
this.activedAccountId = gid;
this.activedAccount.hasNew = false;
rpc.send('friend-list', []);
if (!this.activedAccount.online) {
this.activedAccount.online = true;
rpc.send('account-login', [gid, this.activedAccount.lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
() => rpc.send('account-online', [gid]));
}
mainLogined(gid);
notifyListeners();
}
logout() {
this.accounts.clear();
this.clearActivedAccount();
rpc.send('account-logout', []);
clearLogined();
}
onlineAccount(String gid, String lock) {
this.accounts[gid].online = true;
updateLogined(this.accounts[gid]);
rpc.send('account-login', [gid, lock]);
new Future.delayed(Duration(seconds: DEFAULT_ONLINE_DELAY),
() => rpc.send('account-online', [gid]));
notifyListeners();
}
offlineAccount(String gid) {
this.accounts[gid].online = false;
updateLogined(this.accounts[gid]);
if (gid == this.activedAccountId) {
this.clearActivedAccount();
}
rpc.send('account-offline', [gid]);
notifyListeners();
}
updateActivedApp(Widget widget) {
this.coreShowWidget = widget;
this.activedFriendId = null;
this.activedMessages.clear();
this.systemAppFriendAddNew = false;
notifyListeners();
}
updateActivedFriend(int id, bool isDesktop) {
this.activedFriendId = id;
this.activedMessages.clear();
this.friends[id].lastMessageReaded = true;
rpc.send('message-list', [this.activedFriendId]);
if (isDesktop && this.coreShowWidget is! ChatPage) {
this.coreShowWidget = ChatPage();
}
notifyListeners();
}
clearActivedAccount() {
this.topKeys.clear();
this.orderChats.clear();
this.friends.clear();
this.requests.clear();
this.clearActivedFriend();
}
clearActivedFriend() {
this.activedFriendId = null;
this.activedMessages.clear();
this.coreShowWidget = DefaultCoreShow();
}
accountUpdate(String name, [Uint8List avatar]) {
this.activedAccount.name = name;
if (avatar != null && avatar.length > 0) {
this.activedAccount.avatar = avatar;
rpc.send('account-update', [name, this.activedAccount.encodeAvatar()]);
} else {
rpc.send('account-update', [name, '']);
}
updateLogined(this.activedAccount);
notifyListeners();
}
accountPin(String lock) {
this.activedAccount.lock = lock;
updateLogined(this.activedAccount);
notifyListeners();
}
systemInfo() {
rpc.send('system-info', []);
}
/// delete a friend.
friendUpdate(int id, {String remark, bool isTop}) {
if (remark != null) {
this.friends[id].remark = remark;
}
if (isTop != null) {
this.friends[id].isTop = isTop;
if (isTop) {
this.topKeys.add(id);
} else {
this.topKeys.remove(id);
}
}
final friend = this.friends[id];
rpc.send('friend-update', [id, friend.remark, friend.isTop]);
notifyListeners();
}
/// delete a friend.
friendClose(int id) {
this.friends[id].isClosed = true;
this.friends[id].online = false;
rpc.send('friend-close', [id]);
notifyListeners();
}
/// delete a friend.
friendDelete(int id) {
if (id == this.activedFriendId) {
this.activedFriendId = null;
this.activedMessages.clear();
this.coreShowWidget = DefaultCoreShow();
}
this.friends.remove(id);
this.orderChats.remove(id);
this.topKeys.remove(id);
rpc.send('friend-delete', [id]);
notifyListeners();
}
/// list all request.
requestList() {
rpc.send('request-list', []);
}
/// clear the memory requests.
requestClear() {
this.requests.clear();
}
/// create a request for friend.
requestCreate(Request req) {
rpc.send('request-create', [req.gid, req.addr, req.name, req.remark]);
this.requests.remove(req.id);
rpc.send('request-list', []);
notifyListeners();
}
/// agree a request for friend.
requestAgree(int id) {
rpc.send('request-agree', [id]);
this.requests[id].overIt(true);
notifyListeners();
}
/// reject a request for friend.
requestReject(int id) {
rpc.send('request-reject', [id]);
this.requests[id].overIt(false);
notifyListeners();
}
/// delte a request for friend.
requestDelete(int id) {
rpc.send('request-delete', [id]);
this.requests.remove(id);
notifyListeners();
}
/// create a message. need core server handle this message.
/// and then this message will show in message list.
messageCreate(Message msg) {
final fgid = this.friends[msg.fid].gid;
rpc.send('message-create', [msg.fid, fgid, msg.type.toInt(), msg.content]);
notifyListeners();
}
/// delete a message.
messageDelete(int id) {
rpc.send('message-delete', [id]);
this.activedMessages.remove(id);
notifyListeners();
}
// -- callback when receive rpc info. -- //
_systemInfo(String _gid, List params) {
Global.addr = '0x' + params[0];
}
_accountUpdate(String gid, List params) {
this.accounts[gid].name = params[0];
if (params[1].length > 0) {
if (params[1].length > 1) {
this.accounts[gid].updateAvatar(params[1]);
}
}
notifyListeners();
}
/// list all friends.
_friendList(String gid, List params) async {
if (gid == this.activedAccountId) {
this.orderChats.clear();
this.friends.clear();
params.forEach((params) {
final id = params[0];
this.friends[id] = Friend.fromList(params);
this.orderChats.add(id);
if (this.friends[id].isTop) {
this.topKeys.add(id);
}
});
notifyListeners();
}
}
_friendOnline(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].online = true;
this.friends[id].addr = params[1];
notifyListeners();
}
}
}
_friendOffline(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].online = false;
notifyListeners();
}
}
}
_friendInfo(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
this.friends[id] = Friend.fromList(params);
if (this.friends[id].isTop) {
this.topKeys.add(id);
}
notifyListeners();
}
}
_friendUpdate(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].isTop = params[1];
this.friends[id].remark = params[2];
notifyListeners();
}
}
}
_friendClose(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].isClosed = true;
this.friends[id].online = false;
notifyListeners();
}
}
}
/// list requests for friend.
_requestList(String gid, List params) async {
if (gid == this.activedAccountId) {
this.requests.clear();
params.forEach((param) {
if (param.length == 10) {
this.requests[param[0]] = Request.fromList(param);
}
});
notifyListeners();
}
}
/// receive a request for friend.
_requestCreate(String gid, List params) async {
if (gid == this.activedAccountId) {
if (params.length == 10) {
this.requests[params[0]] = Request.fromList(params);
this.systemAppFriendAddNew = true;
notifyListeners();
}
} else {
if (this.accounts.containsKey(gid)) {
this.accounts[gid].hasNew = true;
notifyListeners();
}
}
}
/// created request had delivery.
_requestDelivery(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
final isDelivery = params[1];
if (this.requests.containsKey(id)) {
this.requests[id].isDelivery = isDelivery;
notifyListeners();
}
}
}
/// request for friend receive agree.
_requestAgree(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0]; // request's id.
if (this.requests.containsKey(id)) {
this.requests[id].overIt(true);
}
var friend = Friend.fromList(params[1]);
this.friends[friend.id] = friend;
orderFriends(friend.id);
notifyListeners();
} else {
if (this.accounts.containsKey(gid)) {
this.accounts[gid].hasNew = true;
notifyListeners();
}
}
}
/// request for friend receive reject.
_requestReject(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.requests.containsKey(id)) {
this.requests[id].overIt(false);
notifyListeners();
}
}
}
_requestDelete(String gid, List params) async {
if (gid == this.activedAccountId) {
this.requests.remove(params[0]);
notifyListeners();
}
}
/// list message with friend.
_messageList(String gid, List params) async {
if (gid == this.activedAccountId) {
params.forEach((param) {
if (param.length == 8) {
this.activedMessages[param[0]] = Message.fromList(param);
}
});
notifyListeners();
}
}
/// friend send message to me.
_messageCreate(String gid, List params) async {
if (gid == this.activedAccountId) {
if (params.length == 8) {
final msg = Message.fromList(params);
if (msg.fid == this.activedFriendId) {
if (!msg.isDelivery) {
msg.isDelivery = null; // When message create, set is is none;
}
this.friends[msg.fid].updateLastMessage(msg, true);
this.activedMessages[msg.id] = msg;
rpc.send('friend-readed', [this.activedFriendId]);
} else {
if (this.friends.containsKey(msg.fid)) {
this.friends[msg.fid].updateLastMessage(msg, false);
}
}
orderFriends(msg.fid);
notifyListeners();
}
} else {
if (this.accounts.containsKey(gid)) {
this.accounts[gid].hasNew = true;
notifyListeners();
}
}
}
_messageDelete(String gid, List params) {
if (gid == this.activedAccountId) {
this.activedMessages.remove(params[0]);
notifyListeners();
}
}
/// created message had delivery.
_messageDelivery(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
final isDelivery = params[1];
if (this.activedMessages.containsKey(id)) {
this.activedMessages[id].isDelivery = isDelivery;
notifyListeners();
}
}
}
}

97
lib/provider/device.dart

@ -1,97 +0,0 @@ @@ -1,97 +0,0 @@
import 'package:flutter/material.dart';
import 'package:esse/models/account.dart';
import 'package:esse/models/device.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
class DeviceProvider extends ChangeNotifier {
Map<int, Device> devices = {};
int activedId = -1;
DeviceStatus status = DeviceStatus();
init() {
// rpc.
rpc.addListener('device-list', _list);
rpc.addListener('device-create', _create);
rpc.addListener('device-delete', _delete);
rpc.addListener('device-online', _online);
rpc.addListener('device-offline', _offline);
rpc.addListener('device-status', _status);
// init.
rpc.send('device-list', []);
}
updateActived(int id) {
this.status = DeviceStatus();
this.activedId = id;
rpc.send('device-status', [this.devices[id].addr]);
}
clearActived() {
this.activedId = -1;
}
connect(String addr) {
rpc.send('device-connect', [addr]);
}
delete(int id) {
this.activedId = -1;
this.devices.remove(id);
rpc.send('device-delete', [id]);
notifyListeners();
}
_list(String gid, List params) {
if (Global.gid == gid) {
this.devices.clear();
params.forEach((params) {
if (params.length == 6) {
this.devices[params[0]] = Device.fromList(params);
}
});
notifyListeners();
}
}
_create(String gid, List params) {
if (Global.gid == gid) {
if (params.length == 6) {
this.devices[params[0]] = Device.fromList(params);
notifyListeners();
}
}
}
_delete(String gid, List params) {
if (Global.gid == gid) {
this.devices.remove(params[0]);
notifyListeners();
}
}
_online(String gid, List params) {
if (Global.gid == gid) {
this.devices[params[0]].online = true;
notifyListeners();
}
}
_offline(String gid, List params) {
if (Global.gid == gid) {
this.devices[params[0]].online = false;
notifyListeners();
}
}
_status(String gid, List params) {
if (Global.gid == gid) {
if (params.length == 9) {
this.status = DeviceStatus.fromList(params);
notifyListeners();
}
}
}
}

371
lib/provider/session.dart

@ -1,371 +0,0 @@ @@ -1,371 +0,0 @@
import 'dart:async';
import "dart:collection";
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'models/account.dart';
import 'models/friend.dart';
import 'models/message.dart';
import 'models/system.dart';
import 'utils/logined_cache.dart';
import 'widgets/default_core_show.dart';
import 'pages/friend.dart';
import 'rpc.dart';
import 'options.dart';
class SessionProvider extends ChangeNotifier {
Map<int, Friend> friends = {}; // all friends. friends need Re-order.
int activedFriendId; // actived friend's id.
Friend get activedFriend => this.friends[this.activedFriendId];
Set<int> topKeys = Set();
List<int> orderChats = []; // ordered chat friends with last message.
/// all requests. request have order.
SplayTreeMap<int, Request> requests = SplayTreeMap();
/// current show messages. init number is 100, message have order.
SplayTreeMap<int, Message> activedMessages = SplayTreeMap();
/// current user's did.
String get id => this.activedAccount.id;
// List<int> get chatKeys => this.orderChats.values.toList();
List<int> get friendKeys => this.friends.keys.toList(); // TODO
void orderFriends(int id) {
if (this.orderChats.length == 0 || this.orderChats[0] != id) {
this.orderChats.remove(id);
this.orderChats.insert(0, id);
}
}
void addContacts() {
// TODO order contacts.
}
init() {
// rpc
rpc.addListener('friend-list', _friendList);
rpc.addListener('friend-online', _friendOnline);
rpc.addListener('friend-offline', _friendOffline);
rpc.addListener('friend-info', _friendInfo);
rpc.addListener('friend-close', _friendClose);
rpc.addListener('request-list', _requestList);
rpc.addListener('request-create', _requestCreate);
rpc.addListener('request-delivery', _requestDelivery);
rpc.addListener('request-agree', _requestAgree);
rpc.addListener('request-reject', _requestReject);
rpc.addListener('message-list', _messageList);
rpc.addListener('message-create', _messageCreate);
rpc.addListener('message-delivery', _messageDelivery);
}
updateActivedFriend(int id, bool isDesktop) {
this.activedFriendId = id;
this.activedMessages.clear();
this.friends[id].lastMessageReaded = true;
rpc.send('message-list', [this.activedFriendId]);
if (isDesktop && this.coreShowWidget is! ChatPage) {
this.coreShowWidget = ChatPage();
}
notifyListeners();
}
clearActivedFriend() {
this.activedFriendId = null;
this.activedMessages.clear();
this.coreShowWidget = DefaultCoreShow();
}
/// delete a friend.
friendInfo(int id, {String remark, bool isTop, bool isHidden}) {
if (remark != null) {
this.friends[id].remark = remark;
}
if (isTop != null) {
this.friends[id].isTop = isTop;
if (isTop) {
this.topKeys.add(id);
} else {
this.topKeys.remove(id);
}
}
if (isHidden != null) {
this.friends[id].isHidden = isHidden;
}
final friend = this.friends[id];
rpc.send('friend-info', [id, friend.remark, friend.isTop, friend.isHidden]);
notifyListeners();
}
/// delete a friend.
friendClose(int id) {
this.friends[id].isClosed = true;
this.friends[id].online = false;
rpc.send('friend-close', [id]);
notifyListeners();
}
/// delete a friend.
friendDelete(int id) {
if (id == this.activedFriendId) {
this.activedFriendId = null;
this.activedMessages.clear();
this.coreShowWidget = DefaultCoreShow();
}
this.friends.remove(id);
this.orderChats.remove(id);
this.topKeys.remove(id);
rpc.send('friend-delete', [id]);
notifyListeners();
}
/// list all request.
requestList() {
rpc.send('request-list', []);
}
/// clear the memory requests.
requestClear() {
this.requests.clear();
}
/// create a request for friend.
requestCreate(Request req) {
rpc.send('request-create', [req.gid, req.addr, req.name, req.remark]);
this.requests.remove(req.id);
rpc.send('request-list', []);
notifyListeners();
}
/// agree a request for friend.
requestAgree(int id) {
rpc.send('request-agree', [id]);
this.requests[id].overIt(true);
notifyListeners();
}
/// reject a request for friend.
requestReject(int id) {
rpc.send('request-reject', [id]);
this.requests[id].overIt(false);
notifyListeners();
}
/// delte a request for friend.
requestDelete(int id) {
rpc.send('request-delete', [id]);
this.requests.remove(id);
notifyListeners();
}
/// create a message. need core server handle this message.
/// and then this message will show in message list.
messageCreate(Message msg) {
rpc.send('message-create', [msg.fid, msg.type.toInt(), msg.content]);
notifyListeners();
}
/// delete a message.
messageDelete(int id) {
rpc.send('message-delete', [id]);
this.activedMessages.remove(id);
notifyListeners();
}
// -- callback when receive rpc info. -- //
/// list all friends.
_friendList(String gid, List params) async {
if (gid == this.activedAccountId) {
this.orderChats.clear();
this.friends.clear();
params.forEach((params) {
if (params.length == 12) {
final id = params[0];
this.friends[id] = Friend.fromList(params);
this.orderChats.add(id);
if (this.friends[id].isTop) {
this.topKeys.add(id);
}
}
});
notifyListeners();
}
}
_friendOnline(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].online = true;
this.friends[id].addr = params[1];
notifyListeners();
}
}
}
_friendOffline(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].online = false;
notifyListeners();
}
}
}
_friendInfo(String gid, List params) async {
if (gid == this.activedAccountId) {
if (params.length == 12) {
final id = params[0];
this.friends[id] = Friend.fromList(params);
if (this.friends[id].isTop) {
this.topKeys.add(id);
}
notifyListeners();
}
}
}
_friendClose(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.friends.containsKey(id)) {
this.friends[id].isClosed = true;
this.friends[id].online = false;
notifyListeners();
}
}
}
/// list requests for friend.
_requestList(String gid, List params) async {
if (gid == this.activedAccountId) {
this.requests.clear();
params.forEach((param) {
if (param.length == 10) {
this.requests[param[0]] = Request.fromList(param);
}
});
notifyListeners();
}
}
/// receive a request for friend.
_requestCreate(String gid, List params) async {
if (gid == this.activedAccountId) {
if (params.length == 10) {
this.requests[params[0]] = Request.fromList(params);
this.systemAppFriendAddNew = true;
notifyListeners();
}
} else {
if (this.accounts.containsKey(gid)) {
this.accounts[gid].hasNew = true;
notifyListeners();
}
}
}
/// created request had delivery.
_requestDelivery(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
final isDelivery = params[1];
if (this.requests.containsKey(id)) {
this.requests[id].isDelivery = isDelivery;
notifyListeners();
}
}
}
/// request for friend receive agree.
_requestAgree(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0]; // request's id.
if (this.requests.containsKey(id)) {
this.requests[id].overIt(true);
}
if (params[1].length == 12) {
var friend = Friend.fromList(params[1]);
this.friends[friend.id] = friend;
orderFriends(friend.id);
}
notifyListeners();
} else {
if (this.accounts.containsKey(gid)) {
this.accounts[gid].hasNew = true;
notifyListeners();
}
}
}
/// request for friend receive reject.
_requestReject(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
if (this.requests.containsKey(id)) {
this.requests[id].overIt(false);
notifyListeners();
}
}
}
/// list message with friend.
_messageList(String gid, List params) async {
if (gid == this.activedAccountId) {
params.forEach((param) {
if (param.length == 8) {
this.activedMessages[param[0]] = Message.fromList(param);
}
});
notifyListeners();
}
}
/// friend send message to me.
_messageCreate(String gid, List params) async {
if (gid == this.activedAccountId) {
if (params.length == 8) {
final msg = Message.fromList(params);
if (msg.fid == this.activedFriendId) {
this.friends[msg.fid].updateLastMessage(msg, true);
this.activedMessages[msg.id] = msg;
rpc.send('friend-readed', [this.activedFriendId]);
} else {
if (this.friends.containsKey(msg.fid)) {
this.friends[msg.fid].updateLastMessage(msg, false);
}
}
orderFriends(msg.fid);
notifyListeners();
}
} else {
if (this.accounts.containsKey(gid)) {
this.accounts[gid].hasNew = true;
notifyListeners();
}
}
}
/// created message had delivery.
_messageDelivery(String gid, List params) async {
if (gid == this.activedAccountId) {
final id = params[0];
final isDelivery = params[1];
if (this.activedMessages.containsKey(id)) {
this.activedMessages[id].isDelivery = isDelivery;
notifyListeners();
}
}
}
}

17
lib/rpc.dart

@ -59,7 +59,8 @@ class WebSocketsNotifications { @@ -59,7 +59,8 @@ class WebSocketsNotifications {
bool _closed = true;
Map<String, Function> _listeners = new Map<String, Function>();
Map<String, List> _listeners = new Map<String, List>();
Function _notice;
bool isLinked() {
return !_closed;
@ -121,8 +122,12 @@ class WebSocketsNotifications { @@ -121,8 +122,12 @@ class WebSocketsNotifications {
}
}
addListener(String method, Function callback) {
_listeners[method] = callback;
addNotice(Function callback) {
_notice = callback;
}
addListener(String method, Function callback, bool notice) {
_listeners[method] = [callback, notice];
}
removeListener(String method) {
@ -142,7 +147,11 @@ class WebSocketsNotifications { @@ -142,7 +147,11 @@ class WebSocketsNotifications {
List params = response["result"];
String gid = response["gid"];
if (_listeners[method] != null) {
_listeners[method](gid, params);
if (gid == Global.gid || method.startsWith('account')) {
_listeners[method][0](params);
} else {
_notice(gid);
}
} else {
print("has no this " + method);
}

18
lib/security.dart

@ -3,19 +3,21 @@ import 'package:flutter/services.dart'; @@ -3,19 +3,21 @@ import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/account.dart';
import 'package:esse/widgets/button_text.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/show_pin.dart';
import 'package:esse/pages/home.dart';
import 'package:esse/pages/account_generate.dart';
import 'package:esse/pages/account_restore.dart';
import 'package:esse/provider/device.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/utils/logined_cache.dart';
import 'package:esse/account.dart';
import 'package:esse/global.dart';
import 'package:esse/options.dart';
import 'package:esse/rpc.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/device/provider.dart';
import 'package:esse/apps/chat/provider.dart';
class SecurityPage extends StatefulWidget {
const SecurityPage({Key key}) : super(key: key);
@ -161,8 +163,11 @@ class _SecurityPageState extends State<SecurityPage> { @@ -161,8 +163,11 @@ class _SecurityPageState extends State<SecurityPage> {
loginedAccounts.forEach((account) {
accounts[account.gid] = account;
});
Provider.of<AccountProvider>(context, listen: false).autoAccounts(mainAccount.gid, accounts);
Provider.of<DeviceProvider>(context, listen: false).init();
Provider.of<DeviceProvider>(context, listen: false).updateActived();
Provider.of<ChatProvider>(context, listen: false).updateActived();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage()));
return;
} else {
@ -208,8 +213,11 @@ class _SecurityPageState extends State<SecurityPage> { @@ -208,8 +213,11 @@ class _SecurityPageState extends State<SecurityPage> {
if (res.isOk) {
final mainAccount = this._accounts[this._selectedUserId];
Provider.of<AccountProvider>(context, listen: false).updateActivedAccount(mainAccount.gid);
Provider.of<DeviceProvider>(context, listen: false).init();
Provider.of<DeviceProvider>(context, listen: false).updateActived();
Provider.of<ChatProvider>(context, listen: false).updateActived();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomePage()));
} else {
// TODO tostor error

11
lib/utils/better_print.dart

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
String betterPrint(String info) {
if (info == null) {
return '';
}
final len = info.length;
if (len > 8) {
return info.substring(0, 8) + '...' + info.substring(len - 6, len);
} else {
return info;
}
}

2
lib/utils/logined_cache.dart

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
import 'package:shared_preferences/shared_preferences.dart';
import 'package:esse/models/account.dart';
import 'package:esse/account.dart';
const LOGINED_CACHE_NAME = 'logined';

13
lib/widgets/chat_message.dart

@ -6,17 +6,18 @@ import 'package:provider/provider.dart'; @@ -6,17 +6,18 @@ import 'package:provider/provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:open_file/open_file.dart';
import 'package:esse/models/message.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/utils/file_image.dart';
import 'package:esse/utils/better_print.dart';
import 'package:esse/widgets/avatar.dart';
import 'package:esse/widgets/audio_player.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/global.dart';
import 'package:esse/apps/chat/models.dart';
import 'package:esse/apps/chat/provider.dart';
class ChatMessage extends StatelessWidget {
final String name;
final Message message;
@ -219,7 +220,7 @@ class ChatMessage extends StatelessWidget { @@ -219,7 +220,7 @@ class ChatMessage extends StatelessWidget {
InkWell(
onTap: () {
Navigator.pop(context);
Provider.of<AccountProvider>(context, listen: false).requestCreate(
Provider.of<ChatProvider>(context, listen: false).requestCreate(
Request(infos[1], infos[2], infos[0], lang.fromContactCard(name))
);
},
@ -264,7 +265,7 @@ class ChatMessage extends StatelessWidget { @@ -264,7 +265,7 @@ class ChatMessage extends StatelessWidget {
style: TextStyle(
color: color.onPrimary, fontSize: 16.0)),
SizedBox(height: 5.0),
Text(Friend.betterPrint(gid),
Text(betterPrint(gid),
style: TextStyle(
color: Colors.grey, fontSize: 12.0)),
])),
@ -325,7 +326,7 @@ class ChatMessage extends StatelessWidget { @@ -325,7 +326,7 @@ class ChatMessage extends StatelessWidget {
Expanded(
child: Tooltip(
message: text,
child: Text(Friend.betterPrint(text)),
child: Text(betterPrint(text)),
)
)
]

84
lib/widgets/list_service.dart

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/provider/account.dart';
import 'package:esse/apps/assistant/page.dart';
class ListService extends StatelessWidget {
const ListService({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
final isDesktop = isDisplayDesktop(context);
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
final widget = AssistantPage();
if (isDesktop) {
Provider.of<AccountProvider>(context, listen: false).updateActivedApp(widget);
} else {
Navigator.push(context, MaterialPageRoute(builder: (_) => widget));
}
},
child: Container(
height: 55.0,
child: Row(
children: [
Container(
width: 45.0,
height: 45.0,
margin: const EdgeInsets.only(left: 20.0, right: 15.0),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/logo/logo_light.png'),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(15.0)
),
),
Expanded(
child: Container(
height: 55.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text('esse',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 16.0))
),
Container(
margin: const EdgeInsets.only(left: 15.0, right: 20.0),
child: Text('2021-11-12',
style: const TextStyle(color: Color(0xFFADB0BB), fontSize: 12.0),
),
)
]),
SizedBox(height: 5.0),
Expanded(
child: Text('esse is a echo robot',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Color(0xFFADB0BB), fontSize: 12.0)),
),
],
),
),
),
],
),
),
);
}
}

6
lib/widgets/user_info.dart

@ -5,7 +5,7 @@ import 'package:flutter/services.dart'; @@ -5,7 +5,7 @@ import 'package:flutter/services.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/models/friend.dart';
import 'package:esse/utils/better_print.dart';
class UserInfo extends StatefulWidget {
final String id;
@ -95,7 +95,7 @@ class _UserInfoState extends State<UserInfo> { @@ -95,7 +95,7 @@ class _UserInfoState extends State<UserInfo> {
children: [
Icon(Icons.person, size: 20.0, color: color.primary),
Spacer(),
Text(Friend.betterPrint(widget.id), style: TextStyle(fontSize: 14, color: idColor)),
Text(betterPrint(widget.id), style: TextStyle(fontSize: 14, color: idColor)),
Spacer(),
Icon(idCopy ? Icons.file_copy : Icons.copy, size: 20.0, color: color.primary),
]
@ -117,7 +117,7 @@ class _UserInfoState extends State<UserInfo> { @@ -117,7 +117,7 @@ class _UserInfoState extends State<UserInfo> {
children: [
Icon(Icons.location_on, size: 20.0, color: color.primary),
Spacer(),
Text(Friend.betterPrint(widget.addr), style: TextStyle(fontSize: 14, color: addrColor)),
Text(betterPrint(widget.addr), style: TextStyle(fontSize: 14, color: addrColor)),
Spacer(),
Icon(addrCopy ? Icons.file_copy : Icons.copy, size: 20.0, color: color.primary),
]

54
src/apps/chat/rpc.rs

@ -18,72 +18,72 @@ use super::{Friend, Message, MessageType, Request}; @@ -18,72 +18,72 @@ use super::{Friend, Message, MessageType, Request};
#[inline]
pub(crate) fn friend_online(mgid: GroupId, fid: i64, addr: PeerAddr) -> RpcParam {
rpc_response(0, "friend-online", json!([fid, addr.to_hex()]), mgid)
rpc_response(0, "chat-friend-online", json!([fid, addr.to_hex()]), mgid)
}
#[inline]
pub(crate) fn friend_offline(mgid: GroupId, fid: i64) -> RpcParam {
rpc_response(0, "friend-offline", json!([fid]), mgid)
rpc_response(0, "chat-friend-offline", json!([fid]), mgid)
}
#[inline]
pub(crate) fn friend_info(mgid: GroupId, friend: &Friend) -> RpcParam {
rpc_response(0, "friend-info", json!(friend.to_rpc()), mgid)
rpc_response(0, "chat-friend-info", json!(friend.to_rpc()), mgid)
}
#[inline]
pub(crate) fn friend_update(mgid: GroupId, fid: i64, is_top: bool, remark: &str) -> RpcParam {
rpc_response(0, "friend-update", json!([fid, is_top, remark]), mgid)
rpc_response(0, "chat-friend-update", json!([fid, is_top, remark]), mgid)
}
#[inline]
pub(crate) fn friend_close(mgid: GroupId, fid: i64) -> RpcParam {
rpc_response(0, "friend-close", json!([fid]), mgid)
rpc_response(0, "chat-friend-close", json!([fid]), mgid)
}
#[inline]
pub(crate) fn friend_delete(mgid: GroupId, fid: i64) -> RpcParam {
rpc_response(0, "friend-delete", json!([fid]), mgid)
rpc_response(0, "chat-friend-delete", json!([fid]), mgid)
}
#[inline]
pub(crate) fn request_create(mgid: GroupId, req: &Request) -> RpcParam {
rpc_response(0, "request-create", json!(req.to_rpc()), mgid)
rpc_response(0, "chat-request-create", json!(req.to_rpc()), mgid)
}
#[inline]
pub(crate) fn request_delivery(mgid: GroupId, id: i64, is_d: bool) -> RpcParam {
rpc_response(0, "request-delivery", json!([id, is_d]), mgid)
rpc_response(0, "chat-request-delivery", json!([id, is_d]), mgid)
}
#[inline]
pub(crate) fn request_agree(mgid: GroupId, id: i64, friend: &Friend) -> RpcParam {
rpc_response(0, "request-agree", json!([id, friend.to_rpc()]), mgid)
rpc_response(0, "chat-request-agree", json!([id, friend.to_rpc()]), mgid)
}
#[inline]
pub(crate) fn request_reject(mgid: GroupId, id: i64) -> RpcParam {
rpc_response(0, "request-reject", json!([id]), mgid)
rpc_response(0, "chat-request-reject", json!([id]), mgid)
}
#[inline]
pub(crate) fn request_delete(mgid: GroupId, id: i64) -> RpcParam {
rpc_response(0, "request-delete", json!([id]), mgid)
rpc_response(0, "chat-request-delete", json!([id]), mgid)
}
#[inline]
pub(crate) fn message_create(mgid: GroupId, msg: &Message) -> RpcParam {
rpc_response(0, "message-create", json!(msg.to_rpc()), mgid)
rpc_response(0, "chat-message-create", json!(msg.to_rpc()), mgid)
}
#[inline]
pub(crate) fn message_delivery(mgid: GroupId, id: i64, is_d: bool) -> RpcParam {
rpc_response(0, "message-delivery", json!([id, is_d]), mgid)
rpc_response(0, "chat-message-delivery", json!([id, is_d]), mgid)
}
#[inline]
pub(crate) fn message_delete(mgid: GroupId, id: i64) -> RpcParam {
rpc_response(0, "message-delete", json!([id]), mgid)
rpc_response(0, "chat-message-delete", json!([id]), mgid)
}
#[inline]
@ -120,7 +120,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -120,7 +120,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
});
handler.add_method(
"friend-list",
"chat-friend-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let friends = state.layer.read().await.all_friends_with_online(&gid)?;
Ok(HandleResult::rpc(friend_list(friends)))
@ -128,7 +128,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -128,7 +128,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"friend-update",
"chat-friend-update",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;
let remark = params[1].as_str()?;
@ -157,7 +157,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -157,7 +157,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"friend-readed",
"chat-friend-readed",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let fid = params[0].as_i64()?;
@ -170,7 +170,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -170,7 +170,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"friend-close",
"chat-friend-close",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;
@ -210,7 +210,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -210,7 +210,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"friend-delete",
"chat-friend-delete",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;
@ -251,7 +251,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -251,7 +251,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"request-list",
"chat-request-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let layer_lock = state.layer.read().await;
let db = session_db(layer_lock.base(), &gid)?;
@ -263,7 +263,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -263,7 +263,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"request-create",
"chat-request-create",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let remote_gid = GroupId::from_hex(params[0].as_str()?)?;
let remote_addr = PeerAddr::from_hex(params[1].as_str()?)?;
@ -320,7 +320,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -320,7 +320,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"request-agree",
"chat-request-agree",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;
@ -358,7 +358,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -358,7 +358,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"request-reject",
"chat-request-reject",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;
@ -385,7 +385,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -385,7 +385,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"request-delete",
"chat-request-delete",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;
@ -415,7 +415,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -415,7 +415,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"message-list",
"chat-message-list",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let fid = params[0].as_i64()?;
@ -431,7 +431,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -431,7 +431,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"message-create",
"chat-message-create",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let fid = params[0].as_i64()?;
let fgid = GroupId::from_hex(params[1].as_str()?)?;
@ -468,7 +468,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -468,7 +468,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"message-delete",
"chat-message-delete",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;

9
src/rpc.rs

@ -62,7 +62,12 @@ pub(crate) fn network_seed(peers: Vec<SocketAddr>) -> RpcParam { @@ -62,7 +62,12 @@ pub(crate) fn network_seed(peers: Vec<SocketAddr>) -> RpcParam {
#[inline]
pub(crate) fn account_update(mgid: GroupId, name: &str, avatar: String) -> RpcParam {
rpc_response(0, "account-update", json!([name, avatar]), mgid)
rpc_response(
0,
"account-update",
json!([mgid.to_hex(), name, avatar]),
mgid,
)
}
#[inline]
@ -146,7 +151,7 @@ fn new_rpc_handler( @@ -146,7 +151,7 @@ fn new_rpc_handler(
Ok(HandleResult::rpc(json!(params)))
});
handler.add_method("system-info", move |_, _, _| async move {
handler.add_method("account-system-info", move |_, _, _| async move {
Ok(HandleResult::rpc(json!(vec![addr.to_hex()])))
});

Loading…
Cancel
Save