mirror of https://github.com/CympleTech/ESSE.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
8.1 KiB
243 lines
8.1 KiB
use std::sync::Arc; |
|
use tdn::types::{ |
|
group::GroupId, |
|
message::SendType, |
|
primitive::{new_io_error, HandleResult, PeerAddr}, |
|
rpc::{json, rpc_response, RpcHandler, RpcParam}, |
|
}; |
|
use tdn_did::Proof; |
|
|
|
use group_chat_types::{CheckType, Event, GroupConnect, GroupType, JoinProof, LayerEvent}; |
|
|
|
use crate::apps::chat::MessageType; |
|
use crate::rpc::RpcState; |
|
use crate::storage::group_chat_db; |
|
|
|
use super::add_layer; |
|
use super::models::{to_network_message, GroupChat, Member, Message, Request}; |
|
|
|
#[inline] |
|
pub(crate) fn create_check(mgid: GroupId, ct: CheckType, supported: Vec<GroupType>) -> RpcParam { |
|
let s: Vec<u32> = supported.iter().map(|v| v.to_u32()).collect(); |
|
rpc_response(0, "group-chat-check", json!([ct.to_u32(), s]), mgid) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn create_result(mgid: GroupId, gid: i64, ok: bool) -> RpcParam { |
|
rpc_response(0, "group-chat-result", json!([gid, ok]), mgid) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn group_online(mgid: GroupId, gid: i64) -> RpcParam { |
|
rpc_response(0, "group-chat-online", json!([gid]), mgid) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn group_offline(mgid: GroupId, fid: i64, gid: &GroupId) -> RpcParam { |
|
rpc_response(0, "group-chat-offline", json!([fid, gid.to_hex()]), mgid) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn member_join(mgid: GroupId, member: Member) -> RpcParam { |
|
rpc_response(0, "group-chat-member-join", json!(member.to_rpc()), mgid) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn member_info(mgid: GroupId, id: i64, addr: PeerAddr, name: String) -> RpcParam { |
|
rpc_response( |
|
0, |
|
"group-chat-member-info", |
|
json!([id, addr.to_hex(), name]), |
|
mgid, |
|
) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn member_online(mgid: GroupId, gid: i64, mid: GroupId, maddr: PeerAddr) -> RpcParam { |
|
rpc_response( |
|
0, |
|
"group-chat-member-online", |
|
json!([gid, mid.to_hex(), maddr.to_hex()]), |
|
mgid, |
|
) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn member_offline(mgid: GroupId, gid: i64, mid: GroupId, maddr: PeerAddr) -> RpcParam { |
|
rpc_response( |
|
0, |
|
"group-chat-member-offline", |
|
json!([gid, mid.to_hex(), maddr.to_hex()]), |
|
mgid, |
|
) |
|
} |
|
|
|
#[inline] |
|
pub(crate) fn message_create(mgid: GroupId, msg: Message) -> RpcParam { |
|
rpc_response(0, "group-chat-message-create", json!(msg.to_rpc()), mgid) |
|
} |
|
|
|
#[inline] |
|
fn group_list(groups: Vec<GroupChat>) -> RpcParam { |
|
let mut results = vec![]; |
|
for group in groups { |
|
results.push(group.to_rpc()); |
|
} |
|
|
|
json!(results) |
|
} |
|
|
|
#[inline] |
|
fn detail_list(members: Vec<Member>, messages: Vec<Message>) -> RpcParam { |
|
let mut member_results = vec![]; |
|
for m in members { |
|
member_results.push(m.to_rpc()); |
|
} |
|
|
|
let mut message_results = vec![]; |
|
for msg in messages { |
|
message_results.push(msg.to_rpc()); |
|
} |
|
|
|
json!([member_results, message_results]) |
|
} |
|
|
|
pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { |
|
handler.add_method("group-chat-echo", |_, params, _| async move { |
|
Ok(HandleResult::rpc(json!(params))) |
|
}); |
|
|
|
handler.add_method( |
|
"group-chat-list", |
|
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move { |
|
let layer_lock = state.layer.read().await; |
|
let db = group_chat_db(&layer_lock.base, &gid)?; |
|
let mut groups = GroupChat::all(&db)?; |
|
drop(db); |
|
|
|
let gids: Vec<&GroupId> = groups.iter().map(|g| &g.g_id).collect(); |
|
let onlines = layer_lock.merge_online(&gid, gids)?; |
|
for (index, online) in onlines.iter().enumerate() { |
|
groups[index].online = *online; |
|
} |
|
|
|
Ok(HandleResult::rpc(group_list(groups))) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"group-chat-detail", |
|
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |
|
let g_did = params[0].as_i64()?; |
|
let db = group_chat_db(state.layer.read().await.base(), &gid)?; |
|
let members = Member::all(&db, &g_did)?; |
|
let messages = Message::all(&db, &g_did)?; |
|
Ok(HandleResult::rpc(detail_list(members, messages))) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"group-chat-check", |
|
|gid: GroupId, params: Vec<RpcParam>, _state: Arc<RpcState>| async move { |
|
let addr = PeerAddr::from_hex(params[0].as_str()?)?; |
|
|
|
let mut results = HandleResult::new(); |
|
let data = postcard::to_allocvec(&GroupConnect::Check).unwrap_or(vec![]); |
|
let s = SendType::Connect(0, addr, None, None, data); |
|
add_layer(&mut results, gid, s); |
|
Ok(results) |
|
}, |
|
); |
|
|
|
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 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 _gcd = gc.g_id; |
|
|
|
// save db |
|
let me = state.group.read().await.clone_user(&gid)?; |
|
gc.insert(&db)?; |
|
Member::new(gc.id, gid, me.addr, me.name, true, gc.datetime).insert(&db)?; |
|
|
|
// TODO save avatar |
|
|
|
let mut results = HandleResult::new(); |
|
// TODO add to rpcs. |
|
results.rpcs.push(json!(gc.to_rpc())); |
|
let info = gc.to_group_info(my_name, 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); |
|
add_layer(&mut results, gid, s); |
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"group-chat-join", |
|
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |
|
let gcd = GroupId::from_hex(params[0].as_str()?)?; |
|
let gaddr = PeerAddr::from_hex(params[1].as_str()?)?; |
|
let gname = params[2].as_str()?.to_owned(); |
|
let gremark = params[3].as_str()?.to_owned(); |
|
|
|
let mut request = Request::new_by_me(gcd, gaddr, gname, gremark); |
|
let db = group_chat_db(state.layer.read().await.base(), &gid)?; |
|
request.insert(&db)?; |
|
drop(db); |
|
|
|
let mut results = HandleResult::rpc(request.to_rpc()); |
|
let me = state.group.read().await.clone_user(&gid)?; |
|
let join_proof = JoinProof::Open(me.name, me.avatar); |
|
let data = postcard::to_allocvec(&GroupConnect::Join(request.gid, join_proof)) |
|
.unwrap_or(vec![]); |
|
let s = SendType::Connect(0, request.addr, None, None, data); |
|
add_layer(&mut results, gid, s); |
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"group-chat-message-create", |
|
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |
|
let gcd = GroupId::from_hex(params[0].as_str()?)?; |
|
let m_type = MessageType::from_int(params[1].as_i64()?); |
|
let m_content = params[2].as_str()?; |
|
|
|
let addr = state.layer.read().await.running(&gid)?.online(&gcd)?; |
|
|
|
let mut results = HandleResult::new(); |
|
let (nmsg, datetime) = to_network_message(m_type, m_content)?; |
|
let event = Event::MessageCreate(gid, nmsg, datetime); |
|
let data = postcard::to_allocvec(&LayerEvent::Sync(gcd, 0, event)).unwrap_or(vec![]); |
|
let msg = SendType::Event(0, addr, data); |
|
add_layer(&mut results, gid, msg); |
|
Ok(results) |
|
}, |
|
); |
|
|
|
handler.add_method( |
|
"group-chat-readed", |
|
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move { |
|
let fid = params[0].as_i64()?; |
|
|
|
let db = group_chat_db(state.layer.read().await.base(), &gid)?; |
|
GroupChat::readed(&db, fid)?; |
|
drop(db); |
|
|
|
Ok(HandleResult::new()) |
|
}, |
|
); |
|
}
|
|
|