From 56f7a39967299186ec05a0c4f45099c47208a103 Mon Sep 17 00:00:00 2001 From: Sun Date: Tue, 25 May 2021 21:43:18 +0800 Subject: [PATCH] add session with chat --- lib/apps/group_chat/detail.dart | 2 +- lib/apps/group_chat/provider.dart | 4 +- src/apps/chat/layer.rs | 65 ++++++++++++++++++++++++++++++- src/apps/chat/rpc.rs | 42 +++++++++++++++++--- src/session.rs | 26 ++++++++++--- 5 files changed, 123 insertions(+), 16 deletions(-) diff --git a/lib/apps/group_chat/detail.dart b/lib/apps/group_chat/detail.dart index 4acd7d4..9fd03f4 100644 --- a/lib/apps/group_chat/detail.dart +++ b/lib/apps/group_chat/detail.dart @@ -214,7 +214,7 @@ class _GroupChatDetailState extends State { child: Text('Waiting...') ); } - final isOnline = provider.online; + final isOnline = provider.activedOnline; return Column( children: [ diff --git a/lib/apps/group_chat/provider.dart b/lib/apps/group_chat/provider.dart index 9a79ca0..f24228b 100644 --- a/lib/apps/group_chat/provider.dart +++ b/lib/apps/group_chat/provider.dart @@ -124,14 +124,14 @@ class GroupChatProvider extends ChangeNotifier { _online(List params) { if (this.actived == params[0]) { - this.online = true; + this.activedOnline = true; notifyListeners(); } } _offline(List params) { if (this.actived == params[0]) { - this.online = false; + this.activedOnline = false; notifyListeners(); } } diff --git a/src/apps/chat/layer.rs b/src/apps/chat/layer.rs index b5eccf8..1c9cd9f 100644 --- a/src/apps/chat/layer.rs +++ b/src/apps/chat/layer.rs @@ -14,8 +14,11 @@ use tdn_did::{user::User, Proof}; use crate::event::{InnerEvent, StatusEvent}; use crate::layer::{Layer, Online}; use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH}; +use crate::rpc::{session_create, session_last}; +use crate::session::{Session, SessionType}; use crate::storage::{ - chat_db, read_avatar, read_file, read_record, write_avatar_sync, write_file, write_image, + chat_db, read_avatar, read_file, read_record, session_db, write_avatar_sync, write_file, + write_image, }; use super::models::{Friend, Message, MessageType, NetworkMessage, Request}; @@ -311,6 +314,19 @@ pub(crate) async fn handle( results .rpcs .push(rpc::request_agree(mgid, request_id, &friend)); + + // ADD NEW SESSION. + let s_db = session_db(&layer.base, &mgid)?; + let mut session = Session::new( + friend.id, + friend.gid, + friend.addr, + SessionType::Chat, + friend.name, + friend.datetime, + ); + session.insert(&s_db)?; + results.rpcs.push(session_create(mgid, &session)); } drop(db); } @@ -396,6 +412,19 @@ pub(crate) async fn handle( results .rpcs .push(rpc::request_agree(mgid, request_id, &friend)); + + // ADD NEW SESSION. + let s_db = session_db(&layer.base, &mgid)?; + let mut session = Session::new( + friend.id, + friend.gid, + friend.addr, + SessionType::Chat, + friend.name, + friend.datetime, + ); + session.insert(&s_db)?; + results.rpcs.push(session_create(mgid, &session)); } drop(db); } @@ -487,6 +516,40 @@ impl LayerEvent { &mut results, )?; results.rpcs.push(rpc::message_create(mgid, &msg)); + + // UPDATE SESSION. + let s_db = session_db(&layer.base, &mgid)?; + if let Ok(id) = Session::last( + &s_db, + &fid, + &SessionType::Chat, + &msg.datetime, + &msg.content, + true, + ) { + results.rpcs.push(session_last( + mgid, + &id, + &msg.datetime, + &msg.content, + true, + )); + } else { + let c_db = chat_db(&layer.base, &mgid)?; + if let Some(f) = Friend::get_id(&c_db, fid)? { + let mut session = Session::new( + f.id, + f.gid, + f.addr, + SessionType::Chat, + f.name, + f.datetime, + ); + session.last_content = msg.content; + session.insert(&s_db)?; + results.rpcs.push(session_create(mgid, &session)); + } + } } } LayerEvent::Info(remote) => { diff --git a/src/apps/chat/rpc.rs b/src/apps/chat/rpc.rs index ba30bd2..81183c0 100644 --- a/src/apps/chat/rpc.rs +++ b/src/apps/chat/rpc.rs @@ -10,8 +10,9 @@ use tdn_did::user::User; use crate::event::InnerEvent; use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH}; -use crate::rpc::{sleep_waiting_close_stable, RpcState}; -use crate::storage::{chat_db, delete_avatar}; +use crate::rpc::{session_create, session_last, sleep_waiting_close_stable, RpcState}; +use crate::session::{Session, SessionType}; +use crate::storage::{chat_db, delete_avatar, session_db}; use super::layer::LayerEvent; use super::{Friend, Message, MessageType, Request}; @@ -124,10 +125,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { |gid: GroupId, _params: Vec, state: Arc| async move { let layer_lock = state.layer.read().await; let db = chat_db(&layer_lock.base, &gid)?; - let mut friends = Friend::all(&db)?; - drop(db); - - Ok(HandleResult::rpc(friend_list(friends))) + Ok(HandleResult::rpc(friend_list(Friend::all(&db)?))) }, ); @@ -337,6 +335,13 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { let f = Friend::from_request(&db, request)?; results.rpcs.push(json!([id, f.to_rpc()])); + // ADD NEW SESSION. + let s_db = session_db(layer_lock.base(), &gid)?; + let mut session = + Session::new(f.id, f.gid, f.addr, SessionType::Chat, f.name, f.datetime); + session.insert(&s_db)?; + results.rpcs.push(session_create(gid, &session)); + let proof = group_lock.prove_addr(&gid, &f.addr)?; let msg = super::layer::rpc_agree_message(&mut layer_lock, id, proof, me, &gid, f.addr)?; @@ -441,6 +446,31 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { let mut results = HandleResult::rpc(json!(msg.to_rpc())); results.layers.push((gid, fgid, s)); + // UPDATE SESSION. + let layer_lock = state.layer.read().await; + let s_db = session_db(&layer_lock.base, &gid)?; + if let Ok(id) = Session::last( + &s_db, + &fid, + &SessionType::Chat, + &msg.datetime, + &msg.content, + true, + ) { + results + .rpcs + .push(session_last(gid, &id, &msg.datetime, &msg.content, true)); + } else { + let c_db = chat_db(&layer_lock.base, &gid)?; + let f = Friend::get_id(&c_db, fid)??; + let mut session = + Session::new(f.id, f.gid, f.addr, SessionType::Chat, f.name, f.datetime); + session.last_content = msg.content; + session.insert(&s_db)?; + results.rpcs.push(session_create(gid, &session)); + } + drop(layer_lock); + match event { LayerEvent::Message(hash, nw) => { state.group.write().await.broadcast( diff --git a/src/session.rs b/src/session.rs index f60b96a..15382b9 100644 --- a/src/session.rs +++ b/src/session.rs @@ -50,9 +50,9 @@ pub(crate) struct Session { pub s_type: SessionType, name: String, is_top: bool, - last_datetime: i64, - last_content: String, - last_readed: bool, + pub last_datetime: i64, + pub last_content: String, + pub last_readed: bool, pub online: bool, } @@ -154,12 +154,26 @@ impl Session { pub fn last( db: &DStorage, - id: &i64, + fid: &i64, + s_type: &SessionType, datetime: &i64, content: &str, readed: bool, - ) -> Result { - db.update(&format!("UPDATE sessions SET last_datetime = {}, last_content = '{}', last_readed = {} WHERE id = {}", datetime, content, if readed { 1 } else { 0 }, id)) + ) -> Result { + let sql = format!( + "SELECT id from sessions WHERE fid = {} AND s_type = {}", + fid, + s_type.to_int() + ); + let mut matrix = db.query(&sql)?; + + if let Some(mut values) = matrix.pop() { + let id = values.pop().unwrap().as_i64(); + db.update(&format!("UPDATE sessions SET last_datetime = {}, last_content = '{}', last_readed = {} WHERE id = {}", datetime, content, if readed { 1 } else { 0 }, id))?; + Ok(id) + } else { + Err(new_io_error("session missing")) + } } pub fn read(db: &DStorage, id: &i64) -> Result {