diff --git a/Cargo.toml b/Cargo.toml index 6775032..838c615 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ tdn_did = { version = "0.6" } tdn_storage = { git = "https://github.com/cypherlink/tdn_storage", branch="main" } #group-chat_types = { git = "https://github.com/cympletech/esse_types", branch="main" } #domain_types = { git = "https://github.com/cympletech/esse_types", branch="main" } +chat_types = { path = "../esse_types/chat" } group_types = { path = "../esse_types/group" } organization_types = { path = "../esse_types/organization" } domain_types = { path = "../esse_types/domain" } diff --git a/src/apps/chat/layer.rs b/src/apps/chat/layer.rs index d3a291a..e5cc87b 100644 --- a/src/apps/chat/layer.rs +++ b/src/apps/chat/layer.rs @@ -10,6 +10,8 @@ use tdn::types::{ use tdn_did::Proof; use tokio::sync::RwLock; +use chat_types::{MessageType, NetworkMessage}; + use crate::account::User; use crate::event::InnerEvent; use crate::layer::{Layer, Online}; @@ -21,7 +23,7 @@ use crate::storage::{ write_image, }; -use super::models::{Friend, Message, MessageType, NetworkMessage, Request}; +use super::models::{handle_nmsg, Friend, Message, Request}; use super::rpc; /// ESSE chat layer Event. @@ -300,7 +302,7 @@ impl LayerEvent { let db = chat_db(&layer.base, &mgid)?; if !Message::exist(&db, &hash)? { let (msg, scontent) = - m.clone().handle(false, mgid, &layer.base, &db, fid, hash)?; + handle_nmsg(m.clone(), false, mgid, &layer.base, &db, fid, hash)?; layer.group.write().await.broadcast( &mgid, InnerEvent::SessionMessageCreate(fgid, false, hash, m), diff --git a/src/apps/chat/mod.rs b/src/apps/chat/mod.rs index 4f3e42a..2370786 100644 --- a/src/apps/chat/mod.rs +++ b/src/apps/chat/mod.rs @@ -5,5 +5,5 @@ pub(crate) mod rpc; pub(crate) use layer::handle; pub(crate) use layer::LayerEvent; pub(crate) use layer::{chat_conn, event_message}; -pub(crate) use models::{Friend, Message, MessageType, NetworkMessage, Request}; +pub(crate) use models::{from_model, handle_nmsg, Friend, Message, Request}; pub(crate) use rpc::new_rpc_handler; diff --git a/src/apps/chat/models.rs b/src/apps/chat/models.rs index 077bc34..bf105ad 100644 --- a/src/apps/chat/models.rs +++ b/src/apps/chat/models.rs @@ -3,5 +3,5 @@ mod message; mod request; pub(crate) use self::friend::Friend; -pub(crate) use self::message::{Message, MessageType, NetworkMessage}; +pub(crate) use self::message::{from_model, handle_nmsg, Message}; pub(crate) use self::request::Request; diff --git a/src/apps/chat/models/message.rs b/src/apps/chat/models/message.rs index a165582..3a1ba22 100644 --- a/src/apps/chat/models/message.rs +++ b/src/apps/chat/models/message.rs @@ -1,4 +1,3 @@ -use serde::{Deserialize, Serialize}; use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; use tdn::types::{ @@ -8,180 +7,108 @@ use tdn::types::{ }; use tdn_storage::local::{DStorage, DsValue}; +use chat_types::{MessageType, NetworkMessage}; + use crate::storage::{ read_avatar_sync, read_file_sync, read_image_sync, read_record_sync, write_avatar_sync, write_file_sync, write_image_sync, write_record_sync, }; -/// message type use in network. -#[derive(Serialize, Deserialize, Clone)] -pub(crate) enum NetworkMessage { - String(String), // content - Image(Vec), // image bytes. - File(String, Vec), // filename, file bytes. - Contact(String, GroupId, PeerId, Vec), // name, gid, addr, avatar bytes. - Record(Vec, u32), // record audio bytes. - Emoji, - Phone, - Video, - Invite(String), - None, -} - -impl NetworkMessage { - pub(crate) fn handle( - self, - is_me: bool, - gid: GroupId, - base: &PathBuf, - db: &DStorage, - fid: i64, - hash: EventId, - ) -> Result<(Message, String)> { - // handle event. - let (m_type, raw) = match self { - NetworkMessage::String(content) => (MessageType::String, content), - NetworkMessage::Image(bytes) => { - let image_name = write_image_sync(base, &gid, bytes)?; - (MessageType::Image, image_name) - } - NetworkMessage::File(old_name, bytes) => { - let filename = write_file_sync(base, &gid, &old_name, bytes)?; - (MessageType::File, filename) - } - NetworkMessage::Contact(name, rgid, addr, avatar_bytes) => { - write_avatar_sync(base, &gid, &rgid, avatar_bytes)?; - let tmp_name = name.replace(";", "-;"); - let contact_values = format!("{};;{};;{}", tmp_name, rgid.to_hex(), addr.to_hex()); - (MessageType::Contact, contact_values) - } - NetworkMessage::Emoji => { - // TODO - (MessageType::Emoji, "".to_owned()) - } - NetworkMessage::Record(bytes, time) => { - let record_name = write_record_sync(base, &gid, fid, time, bytes)?; - (MessageType::Record, record_name) - } - NetworkMessage::Phone => { - // TODO - (MessageType::Phone, "".to_owned()) - } - NetworkMessage::Video => { - // TODO - (MessageType::Video, "".to_owned()) - } - NetworkMessage::Invite(content) => (MessageType::Invite, content), - NetworkMessage::None => { - return Ok(( - Message::new_with_id( - hash, - fid, - is_me, - MessageType::String, - "".to_owned(), - true, - ), - "".to_owned(), - )); - } - }; - - let scontent = match m_type { - MessageType::String => { - format!("{}:{}", m_type.to_int(), raw) - } - _ => format!("{}:", m_type.to_int()), - }; - - let mut msg = Message::new_with_id(hash, fid, is_me, m_type, raw, true); - msg.insert(db)?; - - Ok((msg, scontent)) - } +pub(crate) fn handle_nmsg( + nmsg: NetworkMessage, + is_me: bool, + gid: GroupId, + base: &PathBuf, + db: &DStorage, + fid: i64, + hash: EventId, +) -> Result<(Message, String)> { + // handle event. + let (m_type, raw) = match nmsg { + NetworkMessage::String(content) => (MessageType::String, content), + NetworkMessage::Image(bytes) => { + let image_name = write_image_sync(base, &gid, bytes)?; + (MessageType::Image, image_name) + } + NetworkMessage::File(old_name, bytes) => { + let filename = write_file_sync(base, &gid, &old_name, bytes)?; + (MessageType::File, filename) + } + NetworkMessage::Contact(name, rgid, addr, avatar_bytes) => { + write_avatar_sync(base, &gid, &rgid, avatar_bytes)?; + let tmp_name = name.replace(";", "-;"); + let contact_values = format!("{};;{};;{}", tmp_name, rgid.to_hex(), addr.to_hex()); + (MessageType::Contact, contact_values) + } + NetworkMessage::Emoji => { + // TODO + (MessageType::Emoji, "".to_owned()) + } + NetworkMessage::Record(bytes, time) => { + let record_name = write_record_sync(base, &gid, fid, time, bytes)?; + (MessageType::Record, record_name) + } + NetworkMessage::Phone => { + // TODO + (MessageType::Phone, "".to_owned()) + } + NetworkMessage::Video => { + // TODO + (MessageType::Video, "".to_owned()) + } + NetworkMessage::Invite(content) => (MessageType::Invite, content), + }; - pub fn from_model(base: &PathBuf, gid: &GroupId, model: Message) -> Result { - // handle message's type. - match model.m_type { - MessageType::String => Ok(NetworkMessage::String(model.content)), - MessageType::Image => { - let bytes = read_image_sync(base, gid, &model.content)?; - Ok(NetworkMessage::Image(bytes)) - } - MessageType::File => { - let bytes = read_file_sync(base, gid, &model.content)?; - Ok(NetworkMessage::File(model.content, bytes)) - } - MessageType::Contact => { - let v: Vec<&str> = model.content.split(";;").collect(); - if v.len() != 3 { - return Ok(NetworkMessage::None); - } - let cname = v[0].to_owned(); - let cgid = GroupId::from_hex(v[1])?; - let caddr = PeerId::from_hex(v[2])?; - let avatar_bytes = read_avatar_sync(base, gid, &cgid)?; - Ok(NetworkMessage::Contact(cname, cgid, caddr, avatar_bytes)) - } - MessageType::Record => { - let (bytes, time) = if let Some(i) = model.content.find('-') { - let time = model.content[0..i].parse().unwrap_or(0); - let bytes = read_record_sync(base, gid, &model.content[i + 1..])?; - (bytes, time) - } else { - (vec![], 0) - }; - Ok(NetworkMessage::Record(bytes, time)) - } - MessageType::Invite => Ok(NetworkMessage::Invite(model.content)), - MessageType::Emoji => Ok(NetworkMessage::Emoji), - MessageType::Phone => Ok(NetworkMessage::Phone), - MessageType::Video => Ok(NetworkMessage::Video), + let scontent = match m_type { + MessageType::String => { + format!("{}:{}", m_type.to_int(), raw) } - } -} + _ => format!("{}:", m_type.to_int()), + }; + + let mut msg = Message::new_with_id(hash, fid, is_me, m_type, raw, true); + msg.insert(db)?; -#[derive(Eq, PartialEq)] -pub(crate) enum MessageType { - String, - Image, - File, - Contact, - Emoji, - Record, - Phone, - Video, - Invite, + Ok((msg, scontent)) } -impl MessageType { - pub fn to_int(&self) -> i64 { - match self { - MessageType::String => 0, - MessageType::Image => 1, - MessageType::File => 2, - MessageType::Contact => 3, - MessageType::Emoji => 4, - MessageType::Record => 5, - MessageType::Phone => 6, - MessageType::Video => 7, - MessageType::Invite => 8, +pub fn from_model(base: &PathBuf, gid: &GroupId, model: Message) -> Result { + // handle message's type. + match model.m_type { + MessageType::String => Ok(NetworkMessage::String(model.content)), + MessageType::Image => { + let bytes = read_image_sync(base, gid, &model.content)?; + Ok(NetworkMessage::Image(bytes)) } - } - - pub fn from_int(i: i64) -> MessageType { - match i { - 0 => MessageType::String, - 1 => MessageType::Image, - 2 => MessageType::File, - 3 => MessageType::Contact, - 4 => MessageType::Emoji, - 5 => MessageType::Record, - 6 => MessageType::Phone, - 7 => MessageType::Video, - 8 => MessageType::Invite, - _ => MessageType::String, + MessageType::File => { + let bytes = read_file_sync(base, gid, &model.content)?; + Ok(NetworkMessage::File(model.content, bytes)) + } + MessageType::Contact => { + let v: Vec<&str> = model.content.split(";;").collect(); + if v.len() != 3 { + return Err(anyhow!("message is invalid")); + } + let cname = v[0].to_owned(); + let cgid = GroupId::from_hex(v[1])?; + let caddr = PeerId::from_hex(v[2])?; + let avatar_bytes = read_avatar_sync(base, gid, &cgid)?; + Ok(NetworkMessage::Contact(cname, cgid, caddr, avatar_bytes)) + } + MessageType::Record => { + let (bytes, time) = if let Some(i) = model.content.find('-') { + let time = model.content[0..i].parse().unwrap_or(0); + let bytes = read_record_sync(base, gid, &model.content[i + 1..])?; + (bytes, time) + } else { + (vec![], 0) + }; + Ok(NetworkMessage::Record(bytes, time)) } + MessageType::Invite => Ok(NetworkMessage::Invite(model.content)), + MessageType::Emoji => Ok(NetworkMessage::Emoji), + MessageType::Phone => Ok(NetworkMessage::Phone), + MessageType::Video => Ok(NetworkMessage::Video), } } diff --git a/src/apps/chat/rpc.rs b/src/apps/chat/rpc.rs index 9ec1930..0684a1b 100644 --- a/src/apps/chat/rpc.rs +++ b/src/apps/chat/rpc.rs @@ -7,6 +7,8 @@ use tdn::types::{ rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam}, }; +use chat_types::MessageType; + use crate::account::User; use crate::event::InnerEvent; use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH}; @@ -15,7 +17,7 @@ use crate::session::{Session, SessionType}; use crate::storage::{chat_db, delete_avatar, session_db}; use super::layer::LayerEvent; -use super::{Friend, Message, MessageType, Request}; +use super::{Friend, Message, Request}; #[inline] pub(crate) fn friend_info(mgid: GroupId, friend: &Friend) -> RpcParam { diff --git a/src/apps/group/models/message.rs b/src/apps/group/models/message.rs index 2764650..e0d0cd5 100644 --- a/src/apps/group/models/message.rs +++ b/src/apps/group/models/message.rs @@ -7,9 +7,9 @@ use tdn::types::{ }; use tdn_storage::local::{DStorage, DsValue}; -use group_types::NetworkMessage; +use chat_types::{MessageType, NetworkMessage}; -use crate::apps::chat::{Friend, MessageType}; +use crate::apps::chat::Friend; use crate::storage::{ chat_db, group_db, read_avatar, read_file, read_record, write_avatar_sync, write_file_sync, write_image_sync, write_record_sync, @@ -214,7 +214,7 @@ pub(crate) async fn to_network_message( // TODO NetworkMessage::Video } - MessageType::Invite => NetworkMessage::None, + MessageType::Invite => NetworkMessage::Invite(content.to_owned()), }; Ok((nmsg, datetime)) @@ -266,19 +266,6 @@ pub(crate) fn from_network_message( // TODO (MessageType::Video, "".to_owned()) } - NetworkMessage::None => { - return Ok(( - Message::new( - height, - gdid, - mdid, - is_me, - MessageType::String, - "".to_owned(), - ), - "".to_owned(), - )); - } }; let scontent = match m_type { diff --git a/src/apps/group/rpc.rs b/src/apps/group/rpc.rs index c2925f2..c8718ac 100644 --- a/src/apps/group/rpc.rs +++ b/src/apps/group/rpc.rs @@ -6,9 +6,10 @@ use tdn::types::{ rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam}, }; +use chat_types::MessageType; use group_types::{Event, LayerEvent}; -use crate::apps::chat::{Friend, MessageType}; +use crate::apps::chat::Friend; use crate::layer::Online; use crate::rpc::{session_create, session_delete, session_last, RpcState}; use crate::session::{Session, SessionType}; diff --git a/src/event.rs b/src/event.rs index 534b1f6..e3e87cd 100644 --- a/src/event.rs +++ b/src/event.rs @@ -11,6 +11,8 @@ use tdn::types::{ use tdn_storage::local::DStorage; use tokio::sync::{mpsc::Sender, RwLock}; +use chat_types::NetworkMessage; + use crate::account::{Account, User}; use crate::apps::chat::LayerEvent; use crate::consensus::Event; @@ -21,7 +23,7 @@ use crate::migrate::consensus::{ }; use crate::apps::chat::rpc as chat_rpc; -use crate::apps::chat::{Friend, Message, NetworkMessage, Request}; +use crate::apps::chat::{from_model, handle_nmsg, Friend, Message, Request}; use crate::apps::file::{FileDid, RootDirectory}; use crate::rpc; use crate::storage::{ @@ -331,7 +333,7 @@ impl InnerEvent { )); } - let (msg, _) = m.handle(is_me, gid, group.base(), &db, f.id, hash)?; + let (msg, _) = handle_nmsg(m, is_me, gid, group.base(), &db, f.id, hash)?; results.rpcs.push(chat_rpc::message_create(gid, &msg)); (MESSAGE_TABLE_PATH, msg.id) } else { @@ -625,19 +627,12 @@ impl SyncEvent { if msg.is_deleted { // eid, friend_gid, msg_id, is_me, message. - SyncEvent::Message( - hash, - fgid, - msg.hash, - msg.is_me, - NetworkMessage::None, - ) + SyncEvent::None } else { // create let mid = msg.hash; let is_me = msg.is_me; - let nm = NetworkMessage::from_model(base, gid, msg) - .unwrap_or(NetworkMessage::None); + let nm = from_model(base, gid, msg)?; SyncEvent::Message(hash, fgid, mid, is_me, nm) } } else { @@ -849,7 +844,7 @@ impl SyncEvent { } let id = if let Some(f) = Friend::get_it(&chat_db, &fgid)? { - let (msg, _) = m.handle(is_me, gid, &base, &chat_db, f.id, eid)?; + let (msg, _) = handle_nmsg(m, is_me, gid, &base, &chat_db, f.id, eid)?; results.rpcs.push(chat_rpc::message_create(gid, &msg)); msg.id } else {