Browse Source

add new group invite

pull/18/head
Sun 4 years ago
parent
commit
e01d1bf224
  1. 8
      lib/apps/group/add.dart
  2. 4
      lib/apps/primitives.dart
  3. 57
      src/apps/chat/layer.rs
  4. 3
      src/apps/chat/mod.rs
  5. 74
      src/apps/chat/models.rs
  6. 18
      src/apps/chat/models/message.rs
  7. 14
      src/apps/device/models.rs
  8. 2
      src/apps/device/rpc.rs
  9. 11
      src/apps/group/layer.rs
  10. 2
      src/apps/group/models/group.rs
  11. 5
      src/apps/group/models/message.rs
  12. 39
      src/apps/group/rpc.rs
  13. 6
      src/event.rs
  14. 3
      src/migrate/consensus.rs
  15. 26
      src/migrate/organization.rs

8
lib/apps/group/add.dart

@ -39,13 +39,13 @@ class _GroupAddScreenState extends State<GroupAddScreen> { @@ -39,13 +39,13 @@ class _GroupAddScreenState extends State<GroupAddScreen> {
final res = await httpPost('group-create', [name]);
if (res.isOk) {
final id = res.params[0];
final widget = GroupChatDetail(id: id);
if (widget != null) {
final w = GroupChatDetail(id: id);
if (w != null) {
if (isDesktop) {
Provider.of<AccountProvider>(context, listen: false).updateActivedWidget(widget);
Provider.of<AccountProvider>(context, listen: false).updateActivedWidget(w);
rpc.send('group-member-join', [id, widget.fid]);
} else {
Navigator.push(context, MaterialPageRoute(builder: (_) => widget));
Navigator.push(context, MaterialPageRoute(builder: (_) => w));
}
}
Navigator.pop(context);

4
lib/apps/primitives.dart

@ -148,7 +148,7 @@ class BaseMessage { @@ -148,7 +148,7 @@ class BaseMessage {
}
List showInvite() {
//var type = GroupType.Open;
var type = GroupType.Tmp;
var gid = '';
var addr = '';
var name = '';
@ -157,7 +157,7 @@ class BaseMessage { @@ -157,7 +157,7 @@ class BaseMessage {
final iType = this.content.indexOf(';;');
if (iType > 0) {
//type = GroupTypeExtension.fromInt(int.parse(this.content.substring(0, iType)));
type = GroupTypeExtension.fromInt(int.parse(this.content.substring(0, iType)));
}
final raw_0 = this.content.substring(iType + 2);

57
src/apps/chat/layer.rs

@ -296,8 +296,16 @@ impl LayerEvent { @@ -296,8 +296,16 @@ impl LayerEvent {
let (_sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?;
let db = chat_db(&layer.base, &mgid)?;
if !Message::exist(&db, &hash)? {
let (msg, scontent) =
handle_nmsg(m.clone(), false, mgid, &layer.base, &db, fid, hash)?;
let msg = handle_nmsg(
m.clone(),
false,
mgid,
&layer.base,
&db,
fid,
hash,
&mut results,
)?;
layer.group.write().await.broadcast(
&mgid,
InnerEvent::SessionMessageCreate(fgid, false, hash, m),
@ -308,19 +316,7 @@ impl LayerEvent { @@ -308,19 +316,7 @@ impl LayerEvent {
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,
&scontent,
true,
) {
results
.rpcs
.push(session_last(mgid, &id, &msg.datetime, &scontent, false));
}
update_session(&layer.base, &mgid, &fid, &msg, &mut results);
}
}
LayerEvent::Info(remote) => {
@ -459,3 +455,34 @@ pub(super) fn agree_message(proof: Proof, me: User, addr: PeerId) -> Result<Send @@ -459,3 +455,34 @@ pub(super) fn agree_message(proof: Proof, me: User, addr: PeerId) -> Result<Send
fn _res_reject() -> Vec<u8> {
bincode::serialize(&LayerEvent::Reject).unwrap_or(vec![])
}
// UPDATE SESSION.
pub(crate) fn update_session(
base: &PathBuf,
gid: &GroupId,
id: &i64,
msg: &Message,
results: &mut HandleResult,
) {
let scontent = match msg.m_type {
MessageType::String => {
format!("{}:{}", msg.m_type.to_int(), msg.content)
}
_ => format!("{}:", msg.m_type.to_int()),
};
if let Ok(s_db) = session_db(base, gid) {
if let Ok(sid) = Session::last(
&s_db,
id,
&SessionType::Chat,
&msg.datetime,
&scontent,
true,
) {
results
.rpcs
.push(session_last(*gid, &sid, &msg.datetime, &scontent, false));
}
}
}

3
src/apps/chat/mod.rs

@ -6,6 +6,7 @@ pub(crate) use layer::handle; @@ -6,6 +6,7 @@ pub(crate) use layer::handle;
pub(crate) use layer::LayerEvent;
pub(crate) use layer::{chat_conn, event_message};
pub(crate) use models::{
from_model, from_network_message, handle_nmsg, raw_to_network_message, Friend, Message, Request,
from_model, from_network_message, handle_nmsg, raw_to_network_message, Friend, InviteType,
Message, Request,
};
pub(crate) use rpc::new_rpc_handler;

74
src/apps/chat/models.rs

@ -8,17 +8,23 @@ pub(crate) use self::request::Request; @@ -8,17 +8,23 @@ pub(crate) use self::request::Request;
use chat_types::{MessageType, NetworkMessage};
use std::path::PathBuf;
use tdn::types::{group::GroupId, primitive::Result};
use tdn::types::{
group::GroupId,
primitive::{HandleResult, PeerId, Result},
};
use crate::apps::group::GroupChat;
use crate::rpc::session_create;
use crate::storage::{
chat_db, read_avatar, read_file, read_record, write_avatar_sync, write_file, write_file_sync,
write_image, write_image_sync, write_record_sync,
chat_db, group_db, read_avatar, read_file, read_record, session_db, write_avatar_sync,
write_file, write_file_sync, write_image, write_image_sync, write_record_sync,
};
pub(crate) fn from_network_message(
nmsg: NetworkMessage,
base: &PathBuf,
ogid: &GroupId,
results: &mut HandleResult,
) -> Result<(MessageType, String)> {
match nmsg {
NetworkMessage::String(content) => Ok((MessageType::String, content)),
@ -44,7 +50,26 @@ pub(crate) fn from_network_message( @@ -44,7 +50,26 @@ pub(crate) fn from_network_message(
let record_name = write_record_sync(base, ogid, time, bytes)?;
Ok((MessageType::Record, record_name))
}
NetworkMessage::Invite(content) => Ok((MessageType::Invite, content)),
NetworkMessage::Invite(content) => {
// check is Tmp group.
let itype = InviteType::deserialize(&content)?;
match itype {
InviteType::Group(gcd, addr, name) => {
// 1 add group chat.
let db = group_db(&base, &ogid)?;
let mut g = GroupChat::from(gcd, 0, addr, name);
g.insert(&db)?;
// 2 add new session.
let mut session = g.to_session();
let s_db = session_db(&base, &ogid)?;
session.insert(&s_db)?;
results.rpcs.push(session_create(*ogid, &session));
}
}
Ok((MessageType::Invite, content))
}
NetworkMessage::Phone => {
// TODO
Ok((MessageType::Phone, "".to_owned()))
@ -130,11 +155,42 @@ pub(crate) async fn raw_to_network_message( @@ -130,11 +155,42 @@ pub(crate) async fn raw_to_network_message(
}
}
pub(crate) async fn clear_message(
base: &PathBuf,
ogid: &GroupId,
mtype: &MessageType,
content: &str,
pub(crate) async fn _clear_message(
_base: &PathBuf,
_ogid: &GroupId,
_mtype: &MessageType,
_content: &str,
) -> Result<()> {
todo!()
}
/// Invite types.
pub(crate) enum InviteType {
Group(GroupId, PeerId, String),
}
impl InviteType {
pub fn serialize(&self) -> String {
match self {
InviteType::Group(gcd, addr, name) => {
format!("0;;{};;{};;{}", gcd.to_hex(), addr.to_hex(), name)
}
}
}
pub fn deserialize(s: &str) -> Result<InviteType> {
match &s[0..3] {
"0;;" => {
if s.len() < 134 {
Err(anyhow!("invite invalid"))
} else {
let gcd = GroupId::from_hex(&s[3..67])?;
let addr = PeerId::from_hex(&s[69..133])?;
let name = s[135..].to_owned();
Ok(InviteType::Group(gcd, addr, name))
}
}
_ => Err(anyhow!("invite invalid")),
}
}
}

18
src/apps/chat/models/message.rs

@ -2,7 +2,7 @@ use std::path::PathBuf; @@ -2,7 +2,7 @@ use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
use tdn::types::{
group::{EventId, GroupId},
primitive::{PeerId, Result},
primitive::{HandleResult, PeerId, Result},
rpc::{json, RpcParam},
};
use tdn_storage::local::{DStorage, DsValue};
@ -21,21 +21,13 @@ pub(crate) fn handle_nmsg( @@ -21,21 +21,13 @@ pub(crate) fn handle_nmsg(
db: &DStorage,
fid: i64,
hash: EventId,
) -> Result<(Message, String)> {
results: &mut HandleResult,
) -> Result<Message> {
// handle event.
let (m_type, raw) = from_network_message(nmsg, base, &gid)?;
let scontent = match m_type {
MessageType::String => {
format!("{}:{}", m_type.to_int(), raw)
}
_ => format!("{}:", m_type.to_int()),
};
let (m_type, raw) = from_network_message(nmsg, base, &gid, results)?;
let mut msg = Message::new_with_id(hash, fid, is_me, m_type, raw, true);
msg.insert(db)?;
Ok((msg, scontent))
Ok(msg)
}
pub(crate) fn from_model(base: &PathBuf, gid: &GroupId, model: Message) -> Result<NetworkMessage> {

14
src/apps/device/models.rs

@ -55,9 +55,8 @@ impl Device { @@ -55,9 +55,8 @@ impl Device {
}
/// load account devices.
pub fn all(db: &DStorage) -> Result<Vec<Device>> {
let matrix = db
.query("SELECT id, name, info, addr, lasttime FROM devices where is_deleted = false")?;
pub fn list(db: &DStorage) -> Result<Vec<Device>> {
let matrix = db.query("SELECT id, name, info, addr, lasttime FROM devices")?;
let mut devices = vec![];
for values in matrix {
if values.len() == 5 {
@ -68,7 +67,7 @@ impl Device { @@ -68,7 +67,7 @@ impl Device {
}
pub fn distributes(db: &DStorage) -> Result<HashMap<PeerId, (Peer, i64, bool)>> {
let matrix = db.query("SELECT id, addr FROM devices where is_deleted = false")?;
let matrix = db.query("SELECT id, addr FROM devices")?;
let mut devices = HashMap::new();
for mut values in matrix {
if values.len() == 2 {
@ -96,7 +95,7 @@ impl Device { @@ -96,7 +95,7 @@ impl Device {
pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let sql = format!(
"INSERT INTO devices (name, info, addr, lasttime, is_deleted) VALUES ('{}', '{}', '{}', {}, false)",
"INSERT INTO devices (name, info, addr, lasttime) VALUES ('{}', '{}', '{}', {})",
self.name,
self.info,
self.addr.to_hex(),
@ -114,10 +113,7 @@ impl Device { @@ -114,10 +113,7 @@ impl Device {
/// used in rpc, when what to delete a friend.
pub fn _delete(&self, db: &DStorage) -> Result<usize> {
let sql = format!(
"UPDATE devices SET is_deleted = true WHERE id = {}",
self.id
);
let sql = format!("DELETE FROM devices WHERE id = {}", self.id);
db.update(&sql)
}
}

2
src/apps/device/rpc.rs

@ -71,7 +71,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -71,7 +71,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
"device-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let db = consensus_db(state.layer.read().await.base(), &gid)?;
let devices = Device::all(&db)?;
let devices = Device::list(&db)?;
drop(db);
let online_devices = state.group.read().await.online_devices(&gid, devices);
Ok(HandleResult::rpc(device_list(online_devices)))

11
src/apps/group/layer.rs

@ -295,7 +295,9 @@ async fn handle_server_event( @@ -295,7 +295,9 @@ async fn handle_server_event(
broadcast(&LayerEvent::Sync(gcd, new_h, new_e), layer, &gcd, results).await?;
GroupChat::add_height(&db, id, new_h)?;
let msg = handle_network_message(new_h, id, mgid, &ogid, nmsg, mtime, &base)?;
let msg = handle_network_message(
new_h, id, mgid, &ogid, nmsg, mtime, &base, results,
)?;
results.rpcs.push(rpc::message_create(ogid, &msg));
println!("Sync: create message ok");
@ -466,7 +468,9 @@ async fn handle_peer_event( @@ -466,7 +468,9 @@ async fn handle_peer_event(
println!("Sync: create message start");
let _mdid = Member::get_id(&db, &id, &mgid)?;
let msg = handle_network_message(height, id, mgid, &ogid, nmsg, mtime, &base)?;
let msg = handle_network_message(
height, id, mgid, &ogid, nmsg, mtime, &base, results,
)?;
results.rpcs.push(rpc::message_create(ogid, &msg));
GroupChat::add_height(&db, id, height)?;
@ -493,7 +497,8 @@ async fn handle_peer_event( @@ -493,7 +497,8 @@ async fn handle_peer_event(
let mut last_message = None;
for (height, mgid, nm, time) in adds {
let msg = handle_network_message(height, id, mgid, &ogid, nm, time, &base)?;
let msg =
handle_network_message(height, id, mgid, &ogid, nm, time, &base, results)?;
results.rpcs.push(rpc::message_create(ogid, &msg));
last_message = Some(msg);
from += 1;

2
src/apps/group/models/group.rs

@ -44,7 +44,7 @@ impl GroupChat { @@ -44,7 +44,7 @@ impl GroupChat {
}
}
fn _new_from(g_id: GroupId, height: i64, g_addr: PeerId, g_name: String) -> Self {
pub fn from(g_id: GroupId, height: i64, g_addr: PeerId, g_name: String) -> Self {
Self {
g_id,
g_addr,

5
src/apps/group/models/message.rs

@ -2,7 +2,7 @@ use std::path::PathBuf; @@ -2,7 +2,7 @@ use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
use tdn::types::{
group::GroupId,
primitive::Result,
primitive::{HandleResult, Result},
rpc::{json, RpcParam},
};
use tdn_storage::local::{DStorage, DsValue};
@ -177,11 +177,12 @@ pub(crate) fn handle_network_message( @@ -177,11 +177,12 @@ pub(crate) fn handle_network_message(
msg: NetworkMessage,
datetime: i64,
base: &PathBuf,
results: &mut HandleResult,
) -> Result<Message> {
let db = group_db(base, mgid)?;
let mdid = Member::get_id(&db, &gdid, &mid)?;
let is_me = &mid == mgid;
let (m_type, raw) = from_network_message(msg, base, mgid)?;
let (m_type, raw) = from_network_message(msg, base, mgid, results)?;
let mut msg = Message::new_with_time(height, gdid, mdid, is_me, m_type, raw, datetime);
msg.insert(&db)?;
Ok(msg)

39
src/apps/group/rpc.rs

@ -9,11 +9,11 @@ use tdn::types::{ @@ -9,11 +9,11 @@ use tdn::types::{
use chat_types::MessageType;
use group_types::{Event, LayerEvent};
use crate::apps::chat::Friend;
use crate::apps::chat::{Friend, InviteType};
use crate::layer::Online;
use crate::rpc::{session_create, session_delete, session_last, RpcState};
use crate::session::{Session, SessionType};
use crate::storage::{chat_db, group_db, session_db, write_avatar};
use crate::storage::{chat_db, group_db, read_avatar, session_db, write_avatar};
use super::layer::{broadcast, update_session};
use super::models::{to_network_message, GroupChat, Member, Message};
@ -176,13 +176,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -176,13 +176,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
let gcd = g.g_id;
let mut results = HandleResult::new();
let tmp_name = g.g_name.replace(";", "-;");
let contact_values = format!(
"group;;{};;{};;{}",
gcd.to_hex(),
g.g_addr.to_hex(),
tmp_name
);
let contact_values = InviteType::Group(gcd, g.g_addr, g.g_name).serialize();
let (msg, nw, sc) = crate::apps::chat::LayerEvent::from_message(
&base,
@ -207,6 +201,33 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -207,6 +201,33 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
.push(session_last(gid, &id, &msg.datetime, &sc, false));
}
let avatar = read_avatar(&base, &gid, &f.gid).await.unwrap_or(vec![]);
let event = Event::MemberJoin(f.gid, f.addr, f.name.clone(), avatar);
if g.local {
// local save.
let new_h = state.layer.write().await.running_mut(&gcd)?.increased();
let mut mem = Member::new(new_h, g.id, f.gid, f.addr, f.name);
mem.insert(&group_db)?;
results.rpcs.push(mem.to_rpc());
GroupChat::add_height(&group_db, id, new_h)?;
// broadcast.
broadcast(
&LayerEvent::Sync(gcd, new_h, event),
&state.layer,
&gcd,
&mut results,
)
.await?;
} else {
// send to server.
let data = bincode::serialize(&LayerEvent::Sync(gcd, 0, event))?;
let msg = SendType::Event(0, g.g_addr, data);
add_layer(&mut results, gid, msg);
}
Ok(results)
},
);

6
src/event.rs

@ -323,7 +323,7 @@ impl InnerEvent { @@ -323,7 +323,7 @@ impl InnerEvent {
));
}
let (msg, _) = handle_nmsg(m, is_me, gid, group.base(), &db, f.id, hash)?;
let msg = handle_nmsg(m, is_me, gid, group.base(), &db, f.id, hash, results)?;
results.rpcs.push(chat_rpc::message_create(gid, &msg));
(MESSAGE_TABLE_PATH, msg.id)
} else {
@ -709,9 +709,7 @@ impl SyncEvent { @@ -709,9 +709,7 @@ impl SyncEvent {
// save to db.
request.insert(&chat_db)?;
let rid = request.id;
results.rpcs.push(chat_rpc::request_create(gid, &request));
request
};
@ -796,7 +794,7 @@ impl SyncEvent { @@ -796,7 +794,7 @@ impl SyncEvent {
}
let id = if let Ok(f) = Friend::get_id(&chat_db, &fgid) {
let (msg, _) = handle_nmsg(m, is_me, gid, &base, &chat_db, f.id, eid)?;
let msg = handle_nmsg(m, is_me, gid, &base, &chat_db, f.id, eid, results)?;
results.rpcs.push(chat_rpc::message_create(gid, &msg));
msg.id
} else {

3
src/migrate/consensus.rs

@ -11,8 +11,7 @@ pub(super) const CONSENSUS_VERSIONS: [&str; 9] = [ @@ -11,8 +11,7 @@ pub(super) const CONSENSUS_VERSIONS: [&str; 9] = [
name TEXT NOT NULL,
info TEXT NOT NULL,
addr TEXT NOT NULL,
lasttime INTEGER NOT NULL,
is_deleted INTEGER NOT NULL);",
lasttime INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS db_tables(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
db_name TEXT NOT NULL,

26
src/migrate/organization.rs

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
#[rustfmt::skip]
pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [
"CREATE TABLE IF NOT EXISTS groups(
pub(super) const ORGANIZATION_VERSIONS: [&str; 8] = [
"CREATE TABLE IF NOT EXISTS organizations(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
height INTEGER NOT NULL,
owner TEXT NOT NULL,
@ -14,8 +14,17 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [ @@ -14,8 +14,17 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [
is_closed INTEGER NOT NULL,
key TEXT NOT NULL,
datetime INTEGER NOT NULL,
is_remote INTEGER NOT NULL,
is_deleted INTEGER NOT NULL);",
is_remote INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS categories(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
fid INTEGER NOT NULL,
name TEXT NOT NULL);",
"CREATE TABLE IF NOT EXISTS channels(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
fid INTEGER NOT NULL,
c_type INTEGER NOT NULL,
name TEXT NOT NULL,
public INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS requests(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
fid INTEGER NOT NULL,
@ -27,8 +36,7 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [ @@ -27,8 +36,7 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [
key TEXT NOT NULL,
is_ok INTEGER NOT NULL,
is_over INTEGER NOT NULL,
datetime INTEGER NOT NULL,
is_deleted INTEGER NOT NULL);",
datetime INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS members(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
fid INTEGER NOT NULL,
@ -37,8 +45,7 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [ @@ -37,8 +45,7 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [
name TEXT NOT NULL,
is_manager INTEGER NOT NULL,
is_block INTEGER NOT NULL,
datetime INTEGER NOT NULL,
is_deleted INTEGER NOT NULL);",
datetime INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS messages(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
height INTEGER NOT NULL,
@ -48,8 +55,7 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [ @@ -48,8 +55,7 @@ pub(super) const ORGANIZATION_VERSIONS: [&str; 6] = [
m_type INTEGER NOT NULL,
content TEXT NOT NULL,
is_delivery INTEGER NOT NULL,
datetime INTEGER NOT NULL,
is_deleted INTEGER NOT NULL);",
datetime INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS consensus(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
fid INTEGER NOT NULL,

Loading…
Cancel
Save