From 58d8b4541b4a4535ebbae406d6d52086db6b1ad0 Mon Sep 17 00:00:00 2001 From: Sun Date: Mon, 10 May 2021 15:41:13 +0800 Subject: [PATCH] abstract chat message --- lib/apps/chat/detail.dart | 3 +- lib/apps/chat/models.dart | 125 ++---------------------------- lib/apps/chat/provider.dart | 1 + lib/apps/group_chat/add.dart | 19 +++-- lib/apps/group_chat/detail.dart | 4 +- lib/apps/group_chat/models.dart | 26 +++++++ lib/apps/group_chat/provider.dart | 3 +- lib/apps/primitives.dart | 123 +++++++++++++++++++++++++++++ lib/widgets/chat_message.dart | 5 +- src/apps/group_chat/models.rs | 20 ++--- src/migrate/group_chat.rs | 1 + 11 files changed, 182 insertions(+), 148 deletions(-) create mode 100644 lib/apps/primitives.dart diff --git a/lib/apps/chat/detail.dart b/lib/apps/chat/detail.dart index 953d642..bb6a3f3 100644 --- a/lib/apps/chat/detail.dart +++ b/lib/apps/chat/detail.dart @@ -14,6 +14,7 @@ import 'package:esse/widgets/chat_message.dart'; import 'package:esse/global.dart'; import 'package:esse/provider.dart'; +import 'package:esse/apps/primitives.dart'; import 'package:esse/apps/chat/models.dart'; import 'package:esse/apps/chat/provider.dart'; @@ -118,7 +119,7 @@ class _ChatDetailState extends State { } void _sendRecord(int time) async { - final raw = Message.rawRecordName(time, _recordName); + final raw = BaseMessage.rawRecordName(time, _recordName); context.read().messageCreate(Message(friend.id, MessageType.Record, raw)); setState(() { diff --git a/lib/apps/chat/models.dart b/lib/apps/chat/models.dart index e96ceef..2814444 100644 --- a/lib/apps/chat/models.dart +++ b/lib/apps/chat/models.dart @@ -2,6 +2,8 @@ import 'package:esse/utils/relative_time.dart'; import 'package:esse/widgets/avatar.dart'; import 'package:esse/global.dart'; +import 'package:esse/apps/primitives.dart'; + class Friend { int id; String gid; @@ -112,127 +114,14 @@ class Request { } } -enum MessageType { - String, - Image, - File, - Contact, - Emoji, - Record, - Phone, - Video, -} - -// use 00-99 -extension MessageTypeExtension on MessageType { - int toInt() { - switch (this) { - case MessageType.String: - return 0; - case MessageType.Image: - return 1; - case MessageType.File: - return 2; - case MessageType.Contact: - return 3; - case MessageType.Emoji: - return 4; - case MessageType.Record: - return 5; - case MessageType.Phone: - return 6; - case MessageType.Video: - return 7; - default: - return 0; - } - } - - static MessageType fromInt(int s) { - switch (s) { - case 0: - return MessageType.String; - case 1: - return MessageType.Image; - case 2: - return MessageType.File; - case 3: - return MessageType.Contact; - case 4: - return MessageType.Emoji; - case 5: - return MessageType.Record; - case 6: - return MessageType.Phone; - case 7: - return MessageType.Video; - default: - return MessageType.String; - } - } -} - -class Message { - int id; +class Message extends BaseMessage { String hash; int fid; - bool isMe = true; - MessageType type; - String content; - bool isDelivery = false; - RelativeTime time = RelativeTime(); - Message(this.fid, this.type, this.content); - - List showContact() { - var name = ''; - var did = ''; - var addr = ''; - - var i_name = this.content.indexOf(';;'); - if (i_name > 0) { - name = this.content.substring(0, i_name).replaceAll('-;', ';'); - } - var raw = this.content.substring(i_name + 2); - var i_did = raw.indexOf(';;'); - if (i_did > 0) { - did = raw.substring(0, i_did); - } - addr = raw.substring(i_did + 2); - - return [name, did, addr, Global.avatarPath + did + '.png']; - } - - static String rawRecordName(int time, String name) { - return time.toString() + '-' + name; - } - - List showRecordTime() { - final len = this.content.indexOf('-'); - if (len > 0) { - final time = int.parse(this.content.substring(0, len)); - final path = this.content.substring(len + 1); - return [time, path]; - } else { - return [0, this.content]; - } - } - - String shortShow() { - switch (this.type) { - case MessageType.Image: - return '[IMAGE]'; - case MessageType.Record: - return '[RECORD]'; - case MessageType.Phone: - return '[PHONE]'; - case MessageType.Video: - return '[VIDEO]'; - case MessageType.Contact: - return '[CONTACT CARD]'; - default: - return this.content; - } + Message(int fid, MessageType type, String content) { + this.fid = fid; + this.type = type; + this.content = content; } Message.fromList(List params) { diff --git a/lib/apps/chat/provider.dart b/lib/apps/chat/provider.dart index cae6d6f..c0ce8d1 100644 --- a/lib/apps/chat/provider.dart +++ b/lib/apps/chat/provider.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:esse/utils/relative_time.dart'; import 'package:esse/rpc.dart'; +import 'package:esse/apps/primitives.dart'; import 'package:esse/apps/chat/models.dart'; import 'package:esse/apps/chat/detail.dart'; diff --git a/lib/apps/group_chat/add.dart b/lib/apps/group_chat/add.dart index 34b4aff..0d822c6 100644 --- a/lib/apps/group_chat/add.dart +++ b/lib/apps/group_chat/add.dart @@ -16,8 +16,7 @@ import 'package:esse/widgets/qr_scan.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'; +import 'package:esse/apps/chat/models.dart' show Request; // TODO delete. import 'package:esse/apps/group_chat/models.dart'; import 'package:esse/apps/group_chat/provider.dart'; @@ -125,7 +124,7 @@ class _GroupAddPageState extends State { var name = _joinNameController.text; var remark = _joinRemarkController.text; - context.read().requestCreate(Request(id, addr, name, remark)); + //context.read().requestCreate(Request(id, addr, name, remark)); setState(() { _joinIdController.text = ''; _joinAddrController.text = ''; @@ -204,7 +203,7 @@ class _GroupAddPageState extends State { if (!isDesktop) GestureDetector( onTap: () { - context.read().requestClear(); + //context.read().requestClear(); Navigator.pop(context); }, child: Container( @@ -529,7 +528,7 @@ class _RequestItem extends StatelessWidget { InkWell( onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).requestDelete(request.id); + //Provider.of(context, listen: false).requestDelete(request.id); }, hoverColor: Colors.transparent, child: Container( @@ -549,7 +548,7 @@ class _RequestItem extends StatelessWidget { InkWell( onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).requestReject(request.id); + //Provider.of(context, listen: false).requestReject(request.id); }, hoverColor: Colors.transparent, child: Container( @@ -565,7 +564,7 @@ class _RequestItem extends StatelessWidget { InkWell( onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).requestAgree(request.id); + //Provider.of(context, listen: false).requestAgree(request.id); }, hoverColor: Colors.transparent, child: Container( @@ -587,7 +586,7 @@ class _RequestItem extends StatelessWidget { InkWell( onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).requestDelete(request.id); + //Provider.of(context, listen: false).requestDelete(request.id); }, hoverColor: Colors.transparent, child: Container( @@ -603,7 +602,7 @@ class _RequestItem extends StatelessWidget { InkWell( onTap: () { Navigator.pop(context); - Provider.of(context, listen: false).requestCreate(request); + //Provider.of(context, listen: false).requestCreate(request); }, hoverColor: Colors.transparent, child: Container( @@ -667,7 +666,7 @@ class _RequestItem extends StatelessWidget { )), if (!request.over && !request.isMe) InkWell( - onTap: () => context.read().requestAgree(request.id), + onTap: () => null, //context.read().requestAgree(request.id), hoverColor: Colors.transparent, child: Container( height: 35.0, diff --git a/lib/apps/group_chat/detail.dart b/lib/apps/group_chat/detail.dart index 703f929..eb95d87 100644 --- a/lib/apps/group_chat/detail.dart +++ b/lib/apps/group_chat/detail.dart @@ -14,8 +14,8 @@ import 'package:esse/widgets/chat_message.dart'; import 'package:esse/global.dart'; import 'package:esse/provider.dart'; +import 'package:esse/apps/primitives.dart'; import 'package:esse/apps/chat/provider.dart'; -import 'package:esse/apps/chat/models.dart' show Message; import 'package:esse/apps/group_chat/models.dart'; import 'package:esse/apps/group_chat/provider.dart'; @@ -120,7 +120,7 @@ class _GroupChatDetailState extends State { } void _sendRecord(int time) async { - final raw = Message.rawRecordName(time, _recordName); + final raw = BaseMessage.rawRecordName(time, _recordName); //context.read().messageCreate(Message(group.id, MessageType.Record, raw)); setState(() { diff --git a/lib/apps/group_chat/models.dart b/lib/apps/group_chat/models.dart index c6a2af7..a48f398 100644 --- a/lib/apps/group_chat/models.dart +++ b/lib/apps/group_chat/models.dart @@ -3,6 +3,8 @@ import 'package:esse/utils/relative_time.dart'; import 'package:esse/widgets/avatar.dart'; import 'package:esse/global.dart'; +import 'package:esse/apps/primitives.dart'; + enum GroupType { Encrypted, Common, @@ -119,3 +121,27 @@ class GroupChat { ); } } + +class Message extends BaseMessage { + int height; + int fid; + int mid; + + Message(int fid, MessageType type, String content) { + this.fid = fid; + this.type = type; + this.content = content; + } + + Message.fromList(List params) { + this.id = params[0]; + this.height = params[1]; + this.isMe = params[2]; + this.fid = params[3]; + this.mid = params[4]; + this.type = MessageTypeExtension.fromInt(params[5]); + this.content = params[6]; + this.isDelivery = params[7]; + this.time = RelativeTime.fromInt(params[8]); + } +} diff --git a/lib/apps/group_chat/provider.dart b/lib/apps/group_chat/provider.dart index bba7c78..3326159 100644 --- a/lib/apps/group_chat/provider.dart +++ b/lib/apps/group_chat/provider.dart @@ -3,8 +3,9 @@ import "dart:collection"; import 'package:flutter/material.dart'; import 'package:esse/rpc.dart'; + +import 'package:esse/apps/primitives.dart'; import 'package:esse/apps/group_chat/models.dart'; -import 'package:esse/apps/chat/models.dart' show Message; class GroupChatProvider extends ChangeNotifier { List createSupported = [GroupType.Encrypted, GroupType.Common, GroupType.Open]; diff --git a/lib/apps/primitives.dart b/lib/apps/primitives.dart new file mode 100644 index 0000000..512cf57 --- /dev/null +++ b/lib/apps/primitives.dart @@ -0,0 +1,123 @@ +import 'package:esse/utils/relative_time.dart'; +import 'package:esse/widgets/avatar.dart'; +import 'package:esse/global.dart'; + +enum MessageType { + String, + Image, + File, + Contact, + Emoji, + Record, + Phone, + Video, +} + +// use 00-99 +extension MessageTypeExtension on MessageType { + int toInt() { + switch (this) { + case MessageType.String: + return 0; + case MessageType.Image: + return 1; + case MessageType.File: + return 2; + case MessageType.Contact: + return 3; + case MessageType.Emoji: + return 4; + case MessageType.Record: + return 5; + case MessageType.Phone: + return 6; + case MessageType.Video: + return 7; + default: + return 0; + } + } + + static MessageType fromInt(int s) { + switch (s) { + case 0: + return MessageType.String; + case 1: + return MessageType.Image; + case 2: + return MessageType.File; + case 3: + return MessageType.Contact; + case 4: + return MessageType.Emoji; + case 5: + return MessageType.Record; + case 6: + return MessageType.Phone; + case 7: + return MessageType.Video; + default: + return MessageType.String; + } + } +} + +class BaseMessage { + int id; + bool isMe = true; + MessageType type; + String content; + bool isDelivery = false; + RelativeTime time = RelativeTime(); + + List showContact() { + var name = ''; + var did = ''; + var addr = ''; + + var i_name = this.content.indexOf(';;'); + if (i_name > 0) { + name = this.content.substring(0, i_name).replaceAll('-;', ';'); + } + var raw = this.content.substring(i_name + 2); + var i_did = raw.indexOf(';;'); + if (i_did > 0) { + did = raw.substring(0, i_did); + } + addr = raw.substring(i_did + 2); + + return [name, did, addr, Global.avatarPath + did + '.png']; + } + + static String rawRecordName(int time, String name) { + return time.toString() + '-' + name; + } + + List showRecordTime() { + final len = this.content.indexOf('-'); + if (len > 0) { + final time = int.parse(this.content.substring(0, len)); + final path = this.content.substring(len + 1); + return [time, path]; + } else { + return [0, this.content]; + } + } + + String shortShow() { + switch (this.type) { + case MessageType.Image: + return '[IMAGE]'; + case MessageType.Record: + return '[RECORD]'; + case MessageType.Phone: + return '[PHONE]'; + case MessageType.Video: + return '[VIDEO]'; + case MessageType.Contact: + return '[CONTACT CARD]'; + default: + return this.content; + } + } +} diff --git a/lib/widgets/chat_message.dart b/lib/widgets/chat_message.dart index 0f7db4c..e3e74fc 100644 --- a/lib/widgets/chat_message.dart +++ b/lib/widgets/chat_message.dart @@ -15,12 +15,13 @@ 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/primitives.dart'; +import 'package:esse/apps/chat/models.dart' show Request; import 'package:esse/apps/chat/provider.dart'; class ChatMessage extends StatelessWidget { final String name; - final Message message; + final BaseMessage message; const ChatMessage({Key key, this.name, this.message}): super(key: key); diff --git a/src/apps/group_chat/models.rs b/src/apps/group_chat/models.rs index b35bd9a..a96f0ec 100644 --- a/src/apps/group_chat/models.rs +++ b/src/apps/group_chat/models.rs @@ -8,6 +8,8 @@ use tdn::types::{ }; use tdn_storage::local::{DStorage, DsValue}; +use crate::apps::chat::MessageType; + pub(super) struct GroupChatKey(Vec); impl GroupChatKey { @@ -262,28 +264,18 @@ pub(super) struct Member { datetime: i64, } -/// Group Chat message type. -pub(super) enum MessageType { - String, - Image, - File, - Contact, - Emoji, - Record, - Phone, - Video, -} - /// Group Chat Message Model. pub(super) struct Message { /// db auto-increment id. id: i64, + /// group message consensus height. + height: i64, + /// message is mine. + is_me: bool, /// group's db id. fid: i64, /// member's db id. m_id: i64, - /// group message consensus height. - height: i64, /// message type. m_type: MessageType, /// message content. diff --git a/src/migrate/group_chat.rs b/src/migrate/group_chat.rs index 8f5a067..5a368b1 100644 --- a/src/migrate/group_chat.rs +++ b/src/migrate/group_chat.rs @@ -42,6 +42,7 @@ pub(super) const GROUP_CHAT_VERSIONS: [&str; 4] = [ fid INTEGER NOT NULL, mid INTEGER NOT NULL, height INTEGER NOT NULL, + is_me INTEGER NOT NULL, m_type INTEGER NOT NULL, content TEXT NOT NULL, is_delivery INTEGER NOT NULL,