Browse Source

update get contacts

pull/18/head
Sun 4 years ago
parent
commit
f3ca17e065
  1. 2
      lib/apps/chat/list.dart
  2. 17
      lib/apps/chat/models.dart
  3. 13
      lib/apps/group/detail.dart
  4. 5
      lib/apps/primitives.dart
  5. 2
      lib/widgets/chat_input.dart
  6. 73
      lib/widgets/show_contact.dart
  7. 2
      src/apps/chat/layer.rs
  8. 14
      src/apps/chat/models/friend.rs
  9. 21
      src/apps/chat/rpc.rs
  10. 18
      src/layer.rs

2
lib/apps/chat/list.dart

@ -29,7 +29,7 @@ class _ChatListState extends State<ChatList> { @@ -29,7 +29,7 @@ class _ChatListState extends State<ChatList> {
_loadFriends() async {
this._friends.clear();
final res = await httpPost('chat-friend-list', []);
final res = await httpPost('chat-friend-list', [false]);
if (res.isOk) {
print(res.params);
res.params.forEach((params) {

17
lib/apps/chat/models.dart

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
import 'package:flutter/material.dart';
import 'package:esse/utils/relative_time.dart';
import 'package:esse/widgets/avatar.dart';
import 'package:esse/global.dart';
@ -13,13 +15,21 @@ class Friend { @@ -13,13 +15,21 @@ class Friend {
String remark = '';
bool isClosed = false;
RelativeTime time = RelativeTime();
bool online = false;
// new friend from network
Friend(this.gid, this.name, this.addr);
Avatar showAvatar({double width = 45.0}) {
Avatar showAvatar({bool needOnline = false, double width = 45.0}) {
final avatar = Global.avatarPath + this.gid + '.png';
return Avatar(width: width, name: this.name, avatarPath: avatar);
if (needOnline) {
return Avatar(width: width, name: this.name, avatarPath: avatar,
online: this.online,
onlineColor: Color(0xFF0EE50A),
);
} else {
return Avatar(width: width, name: this.name, avatarPath: avatar);
}
}
Friend.fromList(List params) {
@ -31,6 +41,9 @@ class Friend { @@ -31,6 +41,9 @@ class Friend {
this.remark = params[5];
this.isClosed = params[6];
this.time = RelativeTime.fromInt(params[7]);
if (params.length == 9) {
this.online = params[8];
}
}
}

13
lib/apps/group/detail.dart

@ -7,6 +7,7 @@ import 'package:esse/widgets/avatar.dart'; @@ -7,6 +7,7 @@ import 'package:esse/widgets/avatar.dart';
import 'package:esse/widgets/button_text.dart';
import 'package:esse/widgets/input_text.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/show_contact.dart';
import 'package:esse/widgets/user_info.dart';
import 'package:esse/widgets/chat_message.dart';
import 'package:esse/widgets/chat_input.dart';
@ -136,6 +137,12 @@ class _GroupChatDetailState extends State<GroupChatDetail> { @@ -136,6 +137,12 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
rpc.send('group-message-create', [_group.id, mtype.toInt(), raw]);
}
_invite(List<int> ids) {
ids.forEach((id) {
rpc.send('group-member-join', [_group.id, id]);
});
}
@override
void deactivate() {
if (!isDisplayDesktop(context)) {
@ -206,6 +213,12 @@ class _GroupChatDetailState extends State<GroupChatDetail> { @@ -206,6 +213,12 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
child: Icon(Icons.more_vert_rounded, color: color.primary),
onSelected: (int value) {
if (value == 0) {
showShadowDialog(context, Icons.add, lang.addFriend,
ContactList(callback: _invite, multiple: true,
filters: this._members.values.map((v) => v.mid).toList(),
online: true,
), 0.0
);
} else if (value == 1) {
showShadowDialog(context, Icons.create, lang.rename,
_ChangeNameScreen(_group.id, _group.name), 0.0

5
lib/apps/primitives.dart

@ -155,6 +155,8 @@ class BaseMessage { @@ -155,6 +155,8 @@ class BaseMessage {
var proof = '';
var key = '';
print(this.content);
final iType = this.content.indexOf(';;');
if (iType > 0) {
type = GroupTypeExtension.fromInt(int.parse(this.content.substring(0, iType)));
@ -176,6 +178,9 @@ class BaseMessage { @@ -176,6 +178,9 @@ class BaseMessage {
final iName = raw_2.indexOf(';;');
if (iName > 0) {
name = raw_2.substring(0, iName).replaceAll('-;', ';');
} else {
name = raw_2.replaceAll('-;', ';');
return [type, gid, addr, name, proof, key];
}
final raw_3 = raw_2.substring(iName + 2);

2
lib/widgets/chat_input.dart

@ -85,7 +85,7 @@ class ChatInputState extends State<ChatInput> { @@ -85,7 +85,7 @@ class ChatInputState extends State<ChatInput> {
context,
Icons.person_rounded,
lang.contact,
ContactList(callback: _contactCallback, multiple: false),
ContactList(callback: _contactCallback, multiple: false, filters: [], online: false),
0.0
);
}

73
lib/widgets/show_contact.dart

@ -8,8 +8,14 @@ import 'package:esse/rpc.dart'; @@ -8,8 +8,14 @@ import 'package:esse/rpc.dart';
class ContactList extends StatefulWidget {
final Function callback;
final bool multiple;
const ContactList({Key? key, required this.callback, this.multiple = true})
: super(key: key);
final List<String> filters;
final bool online;
const ContactList({Key? key,
required this.callback,
required this.multiple,
required this.filters,
required this.online
}) : super(key: key);
@override
_ContactListState createState() => _ContactListState();
@ -27,12 +33,30 @@ class _ContactListState extends State<ContactList> { @@ -27,12 +33,30 @@ class _ContactListState extends State<ContactList> {
_loadFriends() async {
this._friends.clear();
final res = await httpPost('chat-friend-list', []);
final res = await httpPost('chat-friend-list', [widget.online]);
if (res.isOk) {
print(res.params);
res.params.forEach((params) {
this._friends.add(Friend.fromList(params));
});
if (widget.online) {
List<Friend> onlines = [];
List<Friend> offlines = [];
res.params.forEach((params) {
final friend = Friend.fromList(params);
if (!widget.filters.contains(friend.gid)) {
if (friend.online) {
onlines.add(friend);
} else {
offlines.add(friend);
}
}
});
this._friends = onlines + offlines;
} else {
res.params.forEach((params) {
final friend = Friend.fromList(params);
if (!widget.filters.contains(friend.gid)) {
this._friends.add(friend);
}
});
}
_checks = List<bool>.generate(_friends.length, (_) => false);
setState(() {});
} else {
@ -41,23 +65,26 @@ class _ContactListState extends State<ContactList> { @@ -41,23 +65,26 @@ class _ContactListState extends State<ContactList> {
}
Widget _friend(int i, Friend friend) {
final text = widget.online && !friend.online
? Text(friend.name, style: TextStyle(color: Colors.grey))
: Text(friend.name);
return Container(
height: 55.0,
child: widget.multiple
? ListTile(
leading: friend.showAvatar(),
title: Text(friend.name),
trailing: Checkbox(
value: _checks[i],
onChanged: (value) => setState(() => _checks[i] = value!)))
: ListTile(
onTap: () {
Navigator.pop(context);
widget.callback(friend.id);
},
leading: friend.showAvatar(),
title: Text(friend.name),
));
height: 55.0,
child: widget.multiple
? ListTile(
leading: friend.showAvatar(needOnline: widget.online),
title: text,
trailing: widget.online && !friend.online ? null : Checkbox(
value: _checks[i],
onChanged: (value) => setState(() => _checks[i] = value!)))
: ListTile(
onTap: widget.online && !friend.online ? null : () {
Navigator.pop(context);
widget.callback(friend.id);
},
leading: friend.showAvatar(),
title: text,
));
}
@override

2
src/apps/chat/layer.rs

@ -357,7 +357,7 @@ impl LayerEvent { @@ -357,7 +357,7 @@ impl LayerEvent {
Friend::id_close(&db, fid)?;
drop(db);
results.rpcs.push(rpc::friend_close(mgid, fid));
if !layer.is_online(&addr) {
if !layer.is_addr_online(&addr) {
results
.layers
.push((mgid, fgid, SendType::Disconnect(addr)))

14
src/apps/chat/models/friend.rs

@ -97,6 +97,20 @@ impl Friend { @@ -97,6 +97,20 @@ impl Friend {
])
}
pub fn to_rpc_online(&self, online: bool) -> RpcParam {
json!([
self.id,
self.gid.to_hex(),
self.addr.to_hex(),
self.name,
self.wallet,
self.remark,
self.is_closed,
self.datetime,
online
])
}
pub fn get_id(db: &DStorage, gid: &GroupId) -> Result<Friend> {
let sql = format!("SELECT id, gid, addr, name, wallet, remark, is_closed, datetime FROM friends WHERE gid = '{}'", gid.to_hex());
let mut matrix = db.query(&sql)?;

21
src/apps/chat/rpc.rs

@ -122,10 +122,27 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -122,10 +122,27 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
handler.add_method(
"chat-friend-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let need_online = params[0].as_bool().ok_or(RpcError::ParseError)?;
let layer_lock = state.layer.read().await;
let db = chat_db(&layer_lock.base, &gid)?;
Ok(HandleResult::rpc(friend_list(Friend::list(&db)?)))
let friends = Friend::list(&db)?;
let mut results = vec![];
if need_online {
for friend in friends {
let online = layer_lock.is_online(&gid, &friend.gid);
results.push(friend.to_rpc_online(online));
}
} else {
for friend in friends {
results.push(friend.to_rpc());
}
}
drop(layer_lock);
Ok(HandleResult::rpc(json!(results)))
},
);

18
src/layer.rs

@ -152,12 +152,22 @@ impl Layer { @@ -152,12 +152,22 @@ impl Layer {
Ok(conns)
}
pub fn is_online(&self, faddr: &PeerId) -> bool {
pub fn is_addr_online(&self, faddr: &PeerId) -> bool {
for (_, running) in &self.runnings {
running.check_addr_online(faddr);
if running.check_addr_online(faddr) {
return true;
}
}
return false;
}
pub fn is_online(&self, gid: &GroupId, fgid: &GroupId) -> bool {
if let Some(running) = self.runnings.get(gid) {
running.is_online(fgid)
} else {
false
}
}
}
/// online info.
@ -316,6 +326,10 @@ impl RunningLayer { @@ -316,6 +326,10 @@ impl RunningLayer {
.collect()
}
pub fn is_online(&self, gid: &GroupId) -> bool {
self.sessions.contains_key(gid)
}
/// check add online.
pub fn check_add_online(
&mut self,

Loading…
Cancel
Save