Browse Source

add group chat card UI and add session type show

pull/18/head
Sun 4 years ago
parent
commit
dbf2c722f3
  1. 6
      lib/apps/chat/detail.dart
  2. 12
      lib/apps/group_chat/add.dart
  3. 14
      lib/apps/group_chat/detail.dart
  4. 11
      lib/apps/group_chat/models.dart
  5. 22
      lib/apps/group_chat/provider.dart
  6. 35
      lib/apps/primitives.dart
  7. 2
      lib/l10n/localizations_en.dart
  8. 2
      lib/l10n/localizations_zh.dart
  9. 8
      lib/session.dart
  10. 58
      lib/widgets/chat_message.dart
  11. 16
      lib/widgets/default_home_show.dart
  12. 46
      lib/widgets/user_info.dart

6
lib/apps/chat/detail.dart

@ -276,7 +276,11 @@ class _ChatDetailState extends State<ChatDetail> { @@ -276,7 +276,11 @@ class _ChatDetailState extends State<ChatDetail> {
app: 'add-friend',
id: 'EH' + friend.gid.toUpperCase(),
name: friend.name,
addr: '0x' + friend.addr)
addr: '0x' + friend.addr,
title: lang.qrFriend,
remark: friend.remark,
),
0.0,
);
} else if (value == 3) {
print('TODO remark');

12
lib/apps/group_chat/add.dart

@ -14,6 +14,7 @@ import 'package:esse/widgets/shadow_button.dart'; @@ -14,6 +14,7 @@ import 'package:esse/widgets/shadow_button.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/qr_scan.dart';
import 'package:esse/global.dart';
import 'package:esse/rpc.dart';
import 'package:esse/provider.dart';
import 'package:esse/apps/group_chat/models.dart';
@ -113,7 +114,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -113,7 +114,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
if (addr.substring(0, 2) == '0x') {
addr = addr.substring(2);
}
context.read<GroupChatProvider>().check(addr);
rpc.send('group-chat-check', [addr]);
}
_scanCallback(bool isOk, String app, List params) {
@ -160,7 +161,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -160,7 +161,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
}
final name = _createNameController.text.trim();
final bio = _createBioController.text.trim();
context.read<GroupChatProvider>().create(_groupType, _myName, addr, name, bio, _groupNeedAgree);
rpc.send('group-chat-create', [_groupType, _myName, addr, name, bio, _groupNeedAgree]);
setState(() {
_createNameController.text = '';
_createBioController.text = '';
@ -195,8 +196,9 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -195,8 +196,9 @@ class _GroupAddPageState extends State<GroupAddPage> {
_createKeyFocus.addListener(() {
setState(() {});
});
rpc.send('group-chat-request-list', [false]);
new Future.delayed(Duration.zero, () {
context.read<GroupChatProvider>().requestList(false);
_myName = context.read<AccountProvider>().activedAccount.name;
});
}
@ -301,7 +303,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -301,7 +303,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
if (_requestsLoadMore)
TextButton(
onPressed: () {
provider.requestList(true);
rpc.send('group-chat-request-list', [true]);
setState(() {
_requestsLoadMore = false;
});
@ -799,7 +801,7 @@ class _CreateItem extends StatelessWidget { @@ -799,7 +801,7 @@ class _CreateItem extends StatelessWidget {
style: TextStyle(color: Color(0xFFADB0BB), fontSize: 14.0),
))
: InkWell(
onTap: () => context.read<GroupChatProvider>().reSend(group.id, name),
onTap: () => rpc.send('group-chat-resend', [group.id, name]),
hoverColor: Colors.transparent,
child: Container(
height: 35.0,

14
lib/apps/group_chat/detail.dart

@ -216,7 +216,7 @@ class _GroupChatDetailState extends State<GroupChatDetail> { @@ -216,7 +216,7 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
return Scaffold(
key: GroupChatDetail._scaffoldKey,
endDrawer: _MemberDrawerWidget(gid: this.group.gid, title: lang.members),
endDrawer: _MemberDrawerWidget(id: this.group.id, gid: this.group.gid, title: lang.members),
drawerScrimColor: color.background,
body: SafeArea(
child: Column(
@ -294,8 +294,11 @@ class _GroupChatDetailState extends State<GroupChatDetail> { @@ -294,8 +294,11 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
app: 'add-group',
id: 'EG' + this.group.gid.toUpperCase(),
name: this.group.name,
addr: '0x' + this.group.addr
)
addr: '0x' + this.group.addr,
title: this.group.type.lang(lang) + ' ' + lang.groupChat,
bio: this.group.bio,
),
0.0,
);
} else if (value == 2) {
showDialog(
@ -590,9 +593,10 @@ Widget _menuItem(Color color, int value, IconData icon, String text) { @@ -590,9 +593,10 @@ Widget _menuItem(Color color, int value, IconData icon, String text) {
}
class _MemberDrawerWidget extends StatelessWidget {
final int id;
final String gid;
final String title;
const _MemberDrawerWidget({Key key, this.gid, this.title}) : super(key: key);
const _MemberDrawerWidget({Key key, this.id, this.gid, this.title}) : super(key: key);
Widget _meItem(Member member, bool meOwner, bool meManager, Color color, lang) {
return Container(
@ -630,7 +634,7 @@ class _MemberDrawerWidget extends StatelessWidget { @@ -630,7 +634,7 @@ class _MemberDrawerWidget extends StatelessWidget {
}
_action(List<int> ids) {
rpc.send('group-chat-invite', [gid, ids]);
rpc.send('group-chat-invite', [id, gid, ids]);
}
_invite(context, String title) {

11
lib/apps/group_chat/models.dart

@ -35,6 +35,17 @@ extension GroupTypeExtension on GroupType { @@ -35,6 +35,17 @@ extension GroupTypeExtension on GroupType {
}
}
String lang(AppLocalizations lang) {
switch (this) {
case GroupType.Encrypted:
return lang.groupTypeEncrypted;
case GroupType.Private:
return lang.groupTypePrivate;
case GroupType.Open:
return lang.groupTypeOpen;
}
}
static GroupType fromInt(int s) {
switch (s) {
case 0:

22
lib/apps/group_chat/provider.dart

@ -118,18 +118,6 @@ class GroupChatProvider extends ChangeNotifier { @@ -118,18 +118,6 @@ class GroupChatProvider extends ChangeNotifier {
this.activedMembers.clear();
}
check(String addr) {
rpc.send('group-chat-check', [addr]);
}
create(int gtype, String myName, String addr, String name, String bio, bool needAgree) {
rpc.send('group-chat-create', [gtype, myName, addr, name, bio, needAgree]);
}
reSend(int id, String myName) {
rpc.send('group-chat-resend', [id, myName]);
}
join(GroupType gtype, String gid, String gaddr, String name, String remark, [String proof = '', String key = '']) {
rpc.send('group-chat-join', [gtype.toInt(), gid, gaddr, name, remark, proof, key]);
}
@ -147,10 +135,6 @@ class GroupChatProvider extends ChangeNotifier { @@ -147,10 +135,6 @@ class GroupChatProvider extends ChangeNotifier {
rpc.send('group-chat-message-create', [gid, mtype.toInt(), content]);
}
requestList(bool all) {
rpc.send('group-chat-request-list', [all]);
}
close(int id) {
// rpc.send('group-chat-close', [id]);
}
@ -163,12 +147,6 @@ class GroupChatProvider extends ChangeNotifier { @@ -163,12 +147,6 @@ class GroupChatProvider extends ChangeNotifier {
// rpc.send('group-chat-readd', [id]);
}
invite(String gid, List<int> ids) {
print(gid);
print(ids);
rpc.send('group-chat-invite', [ids]);
}
memberUpdate(int id, bool isBlock) {
rpc.send('group-chat-member-update', [id, isBlock]);
}

35
lib/apps/primitives.dart

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
import 'package:esse/utils/relative_time.dart';
import 'package:esse/widgets/avatar.dart';
import 'package:esse/global.dart';
import 'package:esse/apps/group_chat/models.dart' show GroupType, GroupTypeExtension;
enum MessageType {
String,
@ -94,6 +95,40 @@ class BaseMessage { @@ -94,6 +95,40 @@ class BaseMessage {
return [name, did, addr, Global.avatarPath + did + '.png'];
}
List showInvite() {
var type = GroupType.Open;
var gid = '';
var addr = '';
var name = '';
var proof = '';
final i_type = this.content.indexOf(';;');
if (i_type > 0) {
type = GroupTypeExtension.fromInt(int.parse(this.content.substring(0, i_type)));
}
final raw_0 = this.content.substring(i_type + 2);
final i_gid = raw_0.indexOf(';;');
if (i_gid > 0) {
gid = raw_0.substring(0, i_gid);
}
final raw_1 = raw_0.substring(i_gid + 2);
final i_addr = raw_1.indexOf(';;');
if (i_addr > 0) {
addr = raw_1.substring(0, i_addr);
}
final raw_2 = raw_1.substring(i_addr + 2);
final i_name = raw_2.indexOf(';;');
if (i_name > 0) {
name = raw_2.substring(0, i_name).replaceAll('-;', ';');
}
proof = raw_2.substring(i_name + 2);
return [type, gid, addr, name, proof];
}
static String rawRecordName(int time, String name) {
return time.toString() + '-' + name;
}

2
lib/l10n/localizations_en.dart

@ -155,7 +155,7 @@ class AppLocalizationsEn extends AppLocalizations { @@ -155,7 +155,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get myQrcode => 'My QRCode';
@override
String get qrFriend => 'Scan for Add';
String get qrFriend => 'Scan for Add Friend';
@override
String get friendInfo => 'Friend Info';
@override

2
lib/l10n/localizations_zh.dart

@ -155,7 +155,7 @@ class AppLocalizationsZh extends AppLocalizations { @@ -155,7 +155,7 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get myQrcode => '我的二维码';
@override
String get qrFriend => '扫二维码添加';
String get qrFriend => '扫二维码添加好友';
@override
String get friendInfo => '好友信息';
@override

8
lib/session.dart

@ -96,15 +96,15 @@ class Session { @@ -96,15 +96,15 @@ class Session {
List parse(AppLocalizations lang) {
switch (this.type) {
case SessionType.Chat:
return [showAvatar(), this.name, this.lastContent, this.lastTime.toString()];
return [showAvatar(), this.name, this.lastContent, this.lastTime.toString(), null];
case SessionType.Group:
return [showAvatar(), this.name, this.lastContent, this.lastTime.toString()];
return [showAvatar(), this.name, this.lastContent, this.lastTime.toString(), Icons.groups];
case SessionType.Assistant:
final params = Session.innerService(InnerService.Assistant, lang);
return [params[0], params[1], params[2], ''];
return [params[0], params[1], params[2], '', Icons.campaign];
case SessionType.Files:
final params = Session.innerService(InnerService.Files, lang);
return [params[0], params[1], params[2], ''];
return [params[0], params[1], params[2], '', Icons.campaign];
}
}

58
lib/widgets/chat_message.dart

@ -309,11 +309,59 @@ class ChatMessage extends StatelessWidget { @@ -309,11 +309,59 @@ class ChatMessage extends StatelessWidget {
}
Widget _showInvite(context, lang, color) {
// contact [name, gid, addr, avatar]
//final infos = message.showContact();
//final gid = 'EG' + infos[1].toUpperCase();
// contact [type, gid, addr, name, proof]
final infos = message.showInvite();
print(infos);
final gid = 'EG' + infos[1].toUpperCase();
if (infos != null) {
return GestureDetector(
onTap: () => showShadowDialog(
context,
Icons.groups_rounded,
lang.groupChat,
Text(infos[3]),
),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
width: 200.0,
decoration: BoxDecoration(
color: const Color(0x40ADB0BB),
borderRadius: BorderRadius.circular(15.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 40.0,
height: 40.0,
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: color.surface,
borderRadius: BorderRadius.circular(15.0),
),
child: Icon(Icons.groups_rounded, color: color.primary),
),
Container(
width: 135.0,
padding: const EdgeInsets.only(left: 10.0),
child: Column(children: [
Text(infos[3], maxLines: 1, overflow: TextOverflow.ellipsis,
style: TextStyle(color: color.onPrimary, fontSize: 16.0)),
const SizedBox(height: 5.0),
Text(betterPrint(gid), style: TextStyle(color: Colors.grey, fontSize: 12.0)),
])),
]),
const SizedBox(height: 5.0),
const Divider(height: 1.0, color: Color(0x40ADB0BB)),
const SizedBox(height: 3.0),
Text(lang.groupChat, style: TextStyle(color: Colors.grey, fontSize: 10.0)),
])));
} else {
final width = MediaQuery.of(context).size.width * 0.6;
// text
return Container(
constraints: BoxConstraints(minWidth: 50, maxWidth: width),
@ -325,7 +373,9 @@ class ChatMessage extends StatelessWidget { @@ -325,7 +373,9 @@ class ChatMessage extends StatelessWidget {
child: Text(message.content,
style: TextStyle(
color: message.isMe ? Colors.white : Color(0xFF1C1939),
fontSize: 14.0)));
fontSize: 14.0))
);
}
}
Widget _infoListTooltip(icon, color, text) {

16
lib/widgets/default_home_show.dart

@ -107,19 +107,29 @@ class _SessionWidget extends StatelessWidget { @@ -107,19 +107,29 @@ class _SessionWidget extends StatelessWidget {
),
Container(
margin: const EdgeInsets.only(left: 15.0, right: 20.0),
child: Text(params[3],
style: const TextStyle(color: Color(0xFFADB0BB), fontSize: 12.0),
),
child: Text(params[3], style: const TextStyle(color: Color(0xFFADB0BB), fontSize: 12.0)),
)
]),
const SizedBox(height: 4.0),
Row(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (params[4] != null)
Container(
margin: const EdgeInsets.only(right: 6.0),
child: Icon(params[4], size: 16.0, color: Color(0xFFADB0BB)),
),
Expanded(
child: Text(params[2],
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Color(0xFFADB0BB), fontSize: 12.0)),
)
]
),
),
Container(width: 8.0, height: 8.0,
margin: const EdgeInsets.only(left: 15.0, right: 20.0),

46
lib/widgets/user_info.dart

@ -12,9 +12,12 @@ class UserInfo extends StatefulWidget { @@ -12,9 +12,12 @@ class UserInfo extends StatefulWidget {
final String id;
final String name;
final String addr;
final String title;
final String remark;
final String bio;
Map qrInfo;
UserInfo({Key key, this.id, this.name, this.addr, this.app}) : super(key: key) {
UserInfo({Key key, this.id, this.name, this.addr, this.app, this.title, this.remark, this.bio}) : super(key: key) {
this.qrInfo = {
"app": this.app,
"params": [this.id, this.addr, this.name],
@ -39,7 +42,11 @@ class _UserInfoState extends State<UserInfo> { @@ -39,7 +42,11 @@ class _UserInfoState extends State<UserInfo> {
Color addrColor = addrCopy ? color.primary : color.onPrimary;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(widget.name, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
Container(
width: 200.0,
padding: const EdgeInsets.all(2.0),
@ -77,9 +84,9 @@ class _UserInfoState extends State<UserInfo> { @@ -77,9 +84,9 @@ class _UserInfoState extends State<UserInfo> {
]
)
),
const SizedBox(height: 20),
Center(child: Text(lang.qrFriend, style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold))),
const SizedBox(height: 20),
const SizedBox(height: 8),
Text(widget.title, style: TextStyle(fontSize: 16.0, fontStyle: FontStyle.italic)),
const SizedBox(height: 10),
const Divider(height: 1.0, color: Color(0x40ADB0BB)),
const SizedBox(height: 20),
InkWell(
@ -103,7 +110,7 @@ class _UserInfoState extends State<UserInfo> { @@ -103,7 +110,7 @@ class _UserInfoState extends State<UserInfo> {
),
)
),
const SizedBox(height: 20),
const SizedBox(height: 16),
InkWell(
onTap: () {
Clipboard.setData(ClipboardData(text: widget.addr));
@ -125,6 +132,35 @@ class _UserInfoState extends State<UserInfo> { @@ -125,6 +132,35 @@ class _UserInfoState extends State<UserInfo> {
),
)
),
if (widget.remark != null)
Container(
width: 250.0,
padding: const EdgeInsets.only(top: 16.0),
child: Row(
children: [
Icon(Icons.turned_in, size: 20.0, color: color.primary),
const SizedBox(width: 16.0),
Expanded(
child: Center(child: Text(widget.remark, style: TextStyle(fontSize: 14))),
)
]
),
),
if (widget.bio != null)
Container(
width: 250.0,
padding: const EdgeInsets.only(top: 16.0),
child: Row(
children: [
Icon(Icons.campaign, size: 20.0, color: color.primary),
const SizedBox(width: 16.0),
Expanded(
child: Center(child: Text(widget.bio, style: TextStyle(fontSize: 14))),
)
]
),
),
const SizedBox(height: 16),
]
);
}

Loading…
Cancel
Save