Browse Source

group chat agree/reject/sync

pull/18/head
Sun 4 years ago
parent
commit
44be5c8602
  1. 14
      lib/apps/group_chat/add.dart
  2. 5
      lib/apps/group_chat/models.dart
  3. 33
      lib/apps/group_chat/provider.dart
  4. 69
      src/apps/group_chat/layer.rs
  5. 10
      src/apps/group_chat/models.rs
  6. 39
      src/apps/group_chat/rpc.rs

14
lib/apps/group_chat/add.dart

@ -53,6 +53,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -53,6 +53,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
bool _groupHasNeedAgree = true;
bool _addrOnline = false;
bool _addrChecked = false;
String _myName = '';
// 0 => encrypted, 1 => common, 2 => open.
Widget _groupTypeWidget(String text, int value, ColorScheme color) {
@ -132,7 +133,6 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -132,7 +133,6 @@ class _GroupAddPageState extends State<GroupAddPage> {
}
_create() {
final myName = context.read<AccountProvider>().activedAccount.name;
var addr = _createAddrController.text.trim();
// if has 0x, need remove
if (addr.substring(0, 2) == '0x') {
@ -140,7 +140,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -140,7 +140,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
}
final name = _createNameController.text.trim();
final bio = _createBioController.text.trim();
context.read<GroupChatProvider>().create(myName, addr, name, bio, _groupNeedAgree);
context.read<GroupChatProvider>().create(_groupType, _myName, addr, name, bio, _groupNeedAgree);
setState(() {
_createNameController.text = '';
_createBioController.text = '';
@ -151,6 +151,8 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -151,6 +151,8 @@ class _GroupAddPageState extends State<GroupAddPage> {
@override
void initState() {
super.initState();
_addrChecked = false;
_joinIdController.text = widget.id;
_joinAddrController.text = widget.addr;
_joinNameController.text = widget.name;
@ -178,6 +180,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -178,6 +180,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
});
new Future.delayed(Duration.zero, () {
//context.read<ChatProvider>().requestList();
_myName = context.read<AccountProvider>().activedAccount.name;
});
}
@ -460,7 +463,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -460,7 +463,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
physics: ClampingScrollPhysics(),
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) =>
_CreateItem(group: groups[createKeys[index]]),
_CreateItem(group: groups[createKeys[index]], name: _myName),
),
)
],
@ -695,7 +698,8 @@ class _RequestItem extends StatelessWidget { @@ -695,7 +698,8 @@ class _RequestItem extends StatelessWidget {
class _CreateItem extends StatelessWidget {
final GroupChat group;
const _CreateItem({Key key, this.group}) : super(key: key);
final String name;
const _CreateItem({Key key, this.group, this.name}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -738,7 +742,7 @@ class _CreateItem extends StatelessWidget { @@ -738,7 +742,7 @@ class _CreateItem extends StatelessWidget {
style: TextStyle(color: Color(0xFFADB0BB), fontSize: 14.0),
))
: InkWell(
onTap: () => context.read<GroupChatProvider>().reSend(group.id),
onTap: () => context.read<GroupChatProvider>().reSend(group.id, name),
hoverColor: Colors.transparent,
child: Container(
height: 35.0,

5
lib/apps/group_chat/models.dart

@ -148,6 +148,11 @@ class Request { @@ -148,6 +148,11 @@ class Request {
bool get isMe => this.fid == 0;
overIt(bool ok) {
this.ok = ok;
this.over = true;
}
Avatar showAvatar([double width = 45.0]) {
final avatar = Global.avatarPath + this.gid + '.png';
return Avatar(

33
lib/apps/group_chat/provider.dart

@ -43,8 +43,8 @@ class GroupChatProvider extends ChangeNotifier { @@ -43,8 +43,8 @@ class GroupChatProvider extends ChangeNotifier {
rpc.addListener('group-chat-detail', _detail, true);
// rpc.addListener('group-chat-update', _update, false);
rpc.addListener('group-chat-join', _join, true);
// rpc.addListener('group-chat-agree', _agree, true);
// rpc.addListener('group-chat-reject', _reject, false);
rpc.addListener('group-chat-agree', _agree, true);
rpc.addListener('group-chat-reject', _reject, false);
rpc.addListener('group-chat-member-join', _memberJoin, false);
rpc.addListener('group-chat-member-info', _memberInfo, false);
// rpc.addListener('group-chat-member-leave', _memberLeave, false);
@ -85,13 +85,12 @@ class GroupChatProvider extends ChangeNotifier { @@ -85,13 +85,12 @@ class GroupChatProvider extends ChangeNotifier {
rpc.send('group-chat-check', [addr]);
}
create(String myName, String addr, String name, String bio, bool needAgree) {
print(addr);
rpc.send('group-chat-create', [myName, addr, name, bio, needAgree]);
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) {
//
reSend(int id, String myName) {
rpc.send('group-chat-resend', [id, myName]);
}
join(String gid, String gaddr, String name, String remark, [String key = '']) {
@ -183,6 +182,26 @@ class GroupChatProvider extends ChangeNotifier { @@ -183,6 +182,26 @@ class GroupChatProvider extends ChangeNotifier {
notifyListeners();
}
_agree(List params) {
final id = params[0];
if (this.requests.containsKey(id)) {
this.requests[id].overIt(false);
}
final gc = GroupChat.fromList(params[1]);
this.orderKeys.add(gc.id);
this.groups[gc.id] = gc;
notifyListeners();
}
_reject(List params) {
final id = params[0];
if (this.requests.containsKey(id)) {
this.requests[id].overIt(false);
notifyListeners();
}
}
_memberJoin(List params) {
final member = Member.fromList(params);
if (this.actived == member.fid) {

69
src/apps/group_chat/layer.rs

@ -9,7 +9,7 @@ use tdn::{ @@ -9,7 +9,7 @@ use tdn::{
},
};
use group_chat_types::{Event, GroupConnect, GroupResult, JoinProof, LayerEvent};
use group_chat_types::{Event, GroupConnect, GroupResult, JoinProof, LayerEvent, PackedEvent};
use tdn_did::Proof;
use crate::layer::{Layer, Online};
@ -73,11 +73,12 @@ pub(crate) async fn handle( @@ -73,11 +73,12 @@ pub(crate) async fn handle(
// 3. online to UI.
results.rpcs.push(rpc::group_online(mgid, group.id));
// 4. TODO online ping.
// 4. online ping.
add_layer(&mut results, mgid, ping(gcd, addr));
// 5. TODO sync group height.
// 5. sync group height.
if group.height < height {
//
add_layer(&mut results, mgid, sync(gcd, addr, group.height));
}
} else {
let msg = SendType::Result(0, addr, false, false, vec![]);
@ -90,6 +91,7 @@ pub(crate) async fn handle( @@ -90,6 +91,7 @@ pub(crate) async fn handle(
// TODO waiting
}
GroupResult::Agree(gcd, info, height) => {
println!("Agree..........");
let base = layer.read().await.base.clone();
let db = group_chat_db(&base, &mgid)?;
let (rid, key) = Request::over(&db, &gcd, true)?;
@ -102,10 +104,13 @@ pub(crate) async fn handle( @@ -102,10 +104,13 @@ pub(crate) async fn handle(
results.rpcs.push(rpc::group_agree(mgid, rid, group));
// 3. online ping.
add_layer(&mut results, mgid, ping(gcd, addr));
// 4. sync group height.
add_layer(&mut results, mgid, sync(gcd, addr, 0));
}
GroupResult::Reject(gcd) => {
println!("Reject..........");
let db = group_chat_db(layer.read().await.base(), &mgid)?;
let (rid, _key) = Request::over(&db, &gcd, true)?;
results.rpcs.push(rpc::group_reject(mgid, rid));
@ -145,7 +150,11 @@ async fn handle_event( @@ -145,7 +150,11 @@ async fn handle_event(
| LayerEvent::OnlinePong(gcd)
| LayerEvent::MemberOnline(gcd, ..)
| LayerEvent::MemberOffline(gcd, ..)
| LayerEvent::Sync(gcd, ..) => layer.read().await.get_running_remote_id(&mgid, &gcd)?,
| LayerEvent::Sync(gcd, ..)
| LayerEvent::SyncReq(gcd, ..)
| LayerEvent::PackedSync(gcd, ..) => {
layer.read().await.get_running_remote_id(&mgid, &gcd)?
}
};
match event {
@ -162,6 +171,12 @@ async fn handle_event( @@ -162,6 +171,12 @@ async fn handle_event(
LayerEvent::OnlinePong(_) => {
results.rpcs.push(rpc::group_online(mgid, gid));
}
LayerEvent::MemberOnline(_, mid, maddr) => {
results.rpcs.push(rpc::member_online(mgid, gid, mid, maddr));
}
LayerEvent::MemberOffline(_, mid, ma) => {
results.rpcs.push(rpc::member_offline(mgid, gid, mid, ma));
}
LayerEvent::Sync(_, height, event) => {
let base = layer.read().await.base().clone();
let db = group_chat_db(&base, &mgid)?;
@ -200,12 +215,10 @@ async fn handle_event( @@ -200,12 +215,10 @@ async fn handle_event(
// save event.
GroupChat::add_height(&db, gid, height)?;
}
LayerEvent::MemberOnline(_, mid, maddr) => {
results.rpcs.push(rpc::member_online(mgid, gid, mid, maddr));
}
LayerEvent::MemberOffline(_, mid, ma) => {
results.rpcs.push(rpc::member_offline(mgid, gid, mid, ma));
LayerEvent::PackedSync(gcd, height, from, to, events) => {
handle_sync(mgid, gcd, addr, height, from, to, events, results);
}
LayerEvent::SyncReq(..) => {} // Never here.
}
Ok(())
@ -222,3 +235,39 @@ pub(crate) fn group_chat_conn(proof: Proof, addr: PeerAddr, gid: GroupId) -> Sen @@ -222,3 +235,39 @@ pub(crate) fn group_chat_conn(proof: Proof, addr: PeerAddr, gid: GroupId) -> Sen
postcard::to_allocvec(&GroupConnect::Join(gid, JoinProof::Had(proof))).unwrap_or(vec![]);
SendType::Connect(0, addr, None, None, data)
}
fn ping(gcd: GroupId, addr: PeerAddr) -> SendType {
let data = postcard::to_allocvec(&LayerEvent::OnlinePing(gcd)).unwrap_or(vec![]);
SendType::Event(0, addr, data)
}
fn sync(gcd: GroupId, addr: PeerAddr, height: i64) -> SendType {
let data = postcard::to_allocvec(&LayerEvent::SyncReq(gcd, height + 1)).unwrap_or(vec![]);
SendType::Event(0, addr, data)
}
fn handle_sync(
mgid: GroupId,
gcd: GroupId,
addr: PeerAddr,
height: i64,
mut from: i64,
to: i64,
events: Vec<PackedEvent>,
results: &mut HandleResult,
) {
for event in events {
handle_sync_event(from, event);
from += 1;
}
if to < height {
add_layer(results, mgid, sync(gcd, addr, to + 1));
}
// update group chat height.
}
fn handle_sync_event(height: i64, event: PackedEvent) {
//
}

10
src/apps/group_chat/models.rs

@ -315,6 +315,16 @@ impl GroupChat { @@ -315,6 +315,16 @@ impl GroupChat {
Ok(None)
}
pub fn get_id(db: &DStorage, id: &i64) -> Result<Option<GroupChat>> {
let sql = format!("SELECT id, height, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime FROM groups WHERE id = {} AND is_deleted = false", id);
let mut matrix = db.query(&sql)?;
if matrix.len() > 0 {
let values = matrix.pop().unwrap(); // safe unwrap()
return Ok(Some(GroupChat::from_values(values, false)));
}
Ok(None)
}
pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let sql = format!("INSERT INTO groups (height, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime, is_deleted) VALUES ({}, '{}', '{}', {}, '{}', '{}', '{}', {}, {}, {}, {}, '{}', {}, '{}', {}, {}, false)",
self.height,

39
src/apps/group_chat/rpc.rs

@ -162,15 +162,16 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -162,15 +162,16 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
handler.add_method(
"group-chat-create",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let my_name = params[0].as_str()?.to_owned();
let addr = PeerAddr::from_hex(params[1].as_str()?)?;
let name = params[2].as_str()?.to_owned();
let bio = params[3].as_str()?.to_owned();
let need_agree = params[4].as_bool()?;
let gtype = GroupType::from_u32(params[0].as_i64()? as u32);
let my_name = params[1].as_str()?.to_owned();
let addr = PeerAddr::from_hex(params[2].as_str()?)?;
let name = params[3].as_str()?.to_owned();
let bio = params[4].as_str()?.to_owned();
let need_agree = params[5].as_bool()?;
let avatar = vec![];
let db = group_chat_db(state.layer.read().await.base(), &gid)?;
let mut gc = GroupChat::new(gid, GroupType::Common, addr, name, bio, need_agree);
let mut gc = GroupChat::new(gid, gtype, addr, name, bio, need_agree);
let _gcd = gc.g_id;
// save db
@ -195,6 +196,32 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -195,6 +196,32 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
},
);
handler.add_method(
"group-chat-resend",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64()?;
let mname = params[1].as_str()?.to_owned();
let db = group_chat_db(state.layer.read().await.base(), &gid)?;
let gc = GroupChat::get_id(&db, &id)??;
drop(db);
// TODO load avatar
let avatar = vec![];
let addr = gc.g_addr;
let info = gc.to_group_info(mname, avatar);
// TODO create proof.
let proof: Proof = Default::default();
let data = postcard::to_allocvec(&GroupConnect::Create(info, proof)).unwrap_or(vec![]);
let s = SendType::Connect(0, addr, None, None, data);
let mut results = HandleResult::new();
add_layer(&mut results, gid, s);
Ok(results)
},
);
handler.add_method(
"group-chat-join",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {

Loading…
Cancel
Save