From 693092ecc0e9288f2e6af53f58c44554ec0d5bf6 Mon Sep 17 00:00:00 2001 From: Sun Date: Sun, 30 May 2021 11:12:35 +0800 Subject: [PATCH] add group chat member on/offline and suspend --- lib/apps/group_chat/provider.dart | 33 +++++++++++++++++++++++++++++-- lib/provider.dart | 6 +++++- src/apps/chat/layer.rs | 2 +- src/apps/group_chat/layer.rs | 8 +++++--- src/apps/group_chat/models.rs | 10 ++++++++++ src/apps/group_chat/rpc.rs | 4 ++-- src/layer.rs | 7 ++++++- src/rpc.rs | 3 ++- 8 files changed, 62 insertions(+), 11 deletions(-) diff --git a/lib/apps/group_chat/provider.dart b/lib/apps/group_chat/provider.dart index bb046da..149d61c 100644 --- a/lib/apps/group_chat/provider.dart +++ b/lib/apps/group_chat/provider.dart @@ -260,11 +260,40 @@ class GroupChatProvider extends ChangeNotifier { } _memberOnline(List params) { - // + final id = params[0]; + final mgid = params[1]; + final maddr = params[2]; + + if (this.actived == id) { + int mid; + this.activedMembers.forEach((i, m) { + if (m.mid == mgid) { + mid = i; + } + }); + if (mid != null) { + this.activedMembers[mid].addr = maddr; + this.activedMembers[mid].online = true; + notifyListeners(); + } + } } _memberOffline(List params) { - // + final id = params[0]; + final mgid = params[1]; + if (this.actived == id) { + int mid; + this.activedMembers.forEach((i, m) { + if (m.mid == mgid) { + mid = i; + } + }); + if (mid != null) { + this.activedMembers[mid].online = false; + notifyListeners(); + } + } } _messageCreate(List params) { diff --git a/lib/provider.dart b/lib/provider.dart index fb76e20..52a5302 100644 --- a/lib/provider.dart +++ b/lib/provider.dart @@ -221,7 +221,11 @@ class AccountProvider extends ChangeNotifier { if (id > 0) { if (this.actived != id && this.actived > 0) { - rpc.send('session-suspend', [this.actived, this.activedSession.gid]); + bool must = false; + if (this.activedSession.type == SessionType.Group) { + must = true; + } + rpc.send('session-suspend', [this.actived, this.activedSession.gid, must]); } this.actived = id; final online = this.activedSession.online; diff --git a/src/apps/chat/layer.rs b/src/apps/chat/layer.rs index d3326d4..0c124c8 100644 --- a/src/apps/chat/layer.rs +++ b/src/apps/chat/layer.rs @@ -191,7 +191,7 @@ impl LayerEvent { } LayerEvent::Suspend(_) => { let (sid, _fid) = layer.get_running_remote_id(&mgid, &fgid)?; - if layer.running_mut(&mgid)?.suspend(&fgid, false)? { + if layer.running_mut(&mgid)?.suspend(&fgid, false, false)? { results.rpcs.push(session_suspend(mgid, &sid)); } } diff --git a/src/apps/group_chat/layer.rs b/src/apps/group_chat/layer.rs index e418048..71b48ee 100644 --- a/src/apps/group_chat/layer.rs +++ b/src/apps/group_chat/layer.rs @@ -127,7 +127,7 @@ async fn handle_event( LayerEvent::Suspend(gcd) => { let mut layer_lock = layer.write().await; let (sid, _gid) = layer_lock.get_running_remote_id(&mgid, &gcd)?; - if layer_lock.running_mut(&mgid)?.suspend(&gcd, false)? { + if layer_lock.running_mut(&mgid)?.suspend(&gcd, false, true)? { results.rpcs.push(session_suspend(mgid, &sid)); } drop(layer_lock); @@ -197,11 +197,13 @@ async fn handle_event( } LayerEvent::MemberOnline(gcd, mid, maddr) => { let (_sid, gid) = layer.read().await.get_running_remote_id(&mgid, &gcd)?; + let db = group_chat_db(layer.read().await.base(), &mgid)?; + let _ = Member::addr_update(&db, &gid, &mid, &maddr); results.rpcs.push(rpc::member_online(mgid, gid, mid, maddr)); } - LayerEvent::MemberOffline(gcd, mid, ma) => { + LayerEvent::MemberOffline(gcd, mid) => { let (_sid, gid) = layer.read().await.get_running_remote_id(&mgid, &gcd)?; - results.rpcs.push(rpc::member_offline(mgid, gid, mid, ma)); + results.rpcs.push(rpc::member_offline(mgid, gid, mid)); } LayerEvent::Sync(gcd, height, event) => { let (sid, gid) = layer.read().await.get_running_remote_id(&mgid, &gcd)?; diff --git a/src/apps/group_chat/models.rs b/src/apps/group_chat/models.rs index b57821c..23456a2 100644 --- a/src/apps/group_chat/models.rs +++ b/src/apps/group_chat/models.rs @@ -630,6 +630,16 @@ impl Member { } } + pub fn addr_update(db: &DStorage, fid: &i64, mid: &GroupId, addr: &PeerAddr) -> Result { + let sql = format!( + "UPDATE members SET addr='{}' WHERE fid = {} AND mid = '{}'", + addr.to_hex(), + fid, + mid.to_hex(), + ); + db.update(&sql) + } + pub fn update(db: &DStorage, id: &i64, addr: &PeerAddr, name: &str) -> Result { let sql = format!( "UPDATE members SET addr='{}', name='{}' WHERE id = {}", diff --git a/src/apps/group_chat/rpc.rs b/src/apps/group_chat/rpc.rs index aaea990..c009988 100644 --- a/src/apps/group_chat/rpc.rs +++ b/src/apps/group_chat/rpc.rs @@ -63,11 +63,11 @@ pub(crate) fn member_online(mgid: GroupId, gid: i64, mid: GroupId, maddr: PeerAd } #[inline] -pub(crate) fn member_offline(mgid: GroupId, gid: i64, mid: GroupId, maddr: PeerAddr) -> RpcParam { +pub(crate) fn member_offline(mgid: GroupId, gid: i64, mid: GroupId) -> RpcParam { rpc_response( 0, "group-chat-member-offline", - json!([gid, mid.to_hex(), maddr.to_hex()]), + json!([gid, mid.to_hex()]), mgid, ) } diff --git a/src/layer.rs b/src/layer.rs index a208ad6..500811e 100644 --- a/src/layer.rs +++ b/src/layer.rs @@ -232,8 +232,13 @@ impl RunningAccount { } } - pub fn suspend(&mut self, gid: &GroupId, is_me: bool) -> Result { + pub fn suspend(&mut self, gid: &GroupId, is_me: bool, must: bool) -> Result { if let Some(online) = self.sessions.get_mut(gid) { + if must { + online.suspend_me = true; + online.suspend_remote = true; + } + if is_me { online.suspend_me = true; } else { diff --git a/src/rpc.rs b/src/rpc.rs index 78165b4..1c62ae9 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -511,6 +511,7 @@ fn new_rpc_handler( |gid: GroupId, params: Vec, state: Arc| async move { let id = params[0].as_i64()?; let remote = GroupId::from_hex(params[1].as_str()?)?; + let must = params[2].as_bool()?; // if need must suspend. let db = session_db(state.group.read().await.base(), &gid)?; let s = Session::get(&db, &id)?; @@ -528,7 +529,7 @@ fn new_rpc_handler( }; let mut layer_lock = state.layer.write().await; - let suspend = layer_lock.running_mut(&gid)?.suspend(&remote, true)?; + let suspend = layer_lock.running_mut(&gid)?.suspend(&remote, true, must)?; drop(layer_lock); let mut results = HandleResult::new();