Browse Source

add group join agree & encrypted-key added request

pull/18/head
Sun 4 years ago
parent
commit
4d6daf2467
  1. 4
      lib/apps/group_chat/provider.dart
  2. 31
      src/apps/group_chat/layer.rs
  3. 116
      src/apps/group_chat/models.rs
  4. 16
      src/apps/group_chat/rpc.rs
  5. 3
      src/migrate/group_chat.rs

4
lib/apps/group_chat/provider.dart

@ -94,8 +94,8 @@ class GroupChatProvider extends ChangeNotifier { @@ -94,8 +94,8 @@ class GroupChatProvider extends ChangeNotifier {
//
}
join(String gid, String gaddr, String name, String remark) {
rpc.send('group-chat-join', [gid, gaddr, name, remark]);
join(String gid, String gaddr, String name, String remark, [String key = '']) {
rpc.send('group-chat-join', [gid, gaddr, name, remark, key]);
}
messageCreate(MessageType mtype, String content) {

31
src/apps/group_chat/layer.rs

@ -15,7 +15,7 @@ use tdn_did::Proof; @@ -15,7 +15,7 @@ use tdn_did::Proof;
use crate::layer::{Layer, Online};
use crate::storage::{group_chat_db, write_avatar_sync};
use super::models::{from_network_message, GroupChat, Member};
use super::models::{from_network_message, GroupChat, Member, Request};
use super::{add_layer, rpc};
pub(crate) async fn handle(
@ -73,9 +73,11 @@ pub(crate) async fn handle( @@ -73,9 +73,11 @@ pub(crate) async fn handle(
// 3. online to UI.
results.rpcs.push(rpc::group_online(mgid, group.id));
// 5. sync group height.
// 4. TODO online ping.
// 5. TODO sync group height.
if group.height < height {
// TOOD
//
}
} else {
let msg = SendType::Result(0, addr, false, false, vec![]);
@ -87,11 +89,26 @@ pub(crate) async fn handle( @@ -87,11 +89,26 @@ pub(crate) async fn handle(
GroupResult::Waiting(_gcd) => {
// TODO waiting
}
GroupResult::Agree(_gcd, _group_info, _height) => {
// TOOD
GroupResult::Agree(gcd, info, height) => {
let base = layer.read().await.base.clone();
let db = group_chat_db(&base, &mgid)?;
let (rid, key) = Request::over(&db, &gcd, true)?;
// 1. add group chat.
let mut group = GroupChat::from_info(key, info, height, addr, base, &mgid)?;
group.insert(&db)?;
// 2. update UI.
results.rpcs.push(rpc::group_agree(mgid, rid, group));
// 3. online ping.
// 4. sync group height.
}
GroupResult::Reject(_gcd) => {
// TOOD
GroupResult::Reject(gcd) => {
let db = group_chat_db(layer.read().await.base(), &mgid)?;
let (rid, _key) = Request::over(&db, &gcd, true)?;
results.rpcs.push(rpc::group_reject(mgid, rid));
}
}
}

116
src/apps/group_chat/models.rs

@ -15,7 +15,7 @@ use crate::storage::{ @@ -15,7 +15,7 @@ use crate::storage::{
group_chat_db, write_avatar_sync, write_file_sync, write_image_sync, write_record_sync,
};
pub(super) struct GroupChatKey(Vec<u8>);
pub(crate) struct GroupChatKey(Vec<u8>);
impl GroupChatKey {
pub fn new(value: Vec<u8>) -> Self {
@ -137,6 +137,77 @@ impl GroupChat { @@ -137,6 +137,77 @@ impl GroupChat {
}
}
fn new_from(
g_id: GroupId,
height: i64,
owner: GroupId,
g_type: GroupType,
g_addr: PeerAddr,
g_name: String,
g_bio: String,
is_need_agree: bool,
key: GroupChatKey,
) -> Self {
let start = SystemTime::now();
let datetime = start
.duration_since(UNIX_EPOCH)
.map(|s| s.as_secs())
.unwrap_or(0) as i64; // safe for all life.
Self {
owner,
g_id,
g_type,
g_addr,
g_name,
g_bio,
is_need_agree,
key,
datetime,
id: 0,
height,
is_top: true,
is_ok: true,
is_closed: false,
last_datetime: datetime,
last_content: Default::default(),
last_readed: true,
online: false,
is_deleted: false,
}
}
pub fn from_info(
key: GroupChatKey,
info: GroupInfo,
height: i64,
addr: PeerAddr,
base: PathBuf,
mgid: &GroupId,
) -> Result<Self> {
match info {
GroupInfo::Common(owner, _, g_id, g_type, agree, name, g_bio, avatar) => {
write_avatar_sync(&base, &mgid, &g_id, avatar)?;
Ok(Self::new_from(
g_id, height, owner, g_type, addr, name, g_bio, agree, key,
))
}
GroupInfo::Encrypted(owner, _, g_id, agree, _hash, _name, _bio, avatar) => {
// TODO decrypted.
let g_type = GroupType::Encrypted;
let name = "".to_owned();
let bio = "".to_owned();
write_avatar_sync(&base, &mgid, &g_id, avatar)?;
Ok(Self::new_from(
g_id, height, owner, g_type, addr, name, bio, agree, key,
))
}
}
}
pub fn to_group_info(self, name: String, avatar: Vec<u8>) -> GroupInfo {
match self.g_type {
GroupType::Common | GroupType::Open => GroupInfo::Common(
@ -304,6 +375,7 @@ pub(crate) struct Request { @@ -304,6 +375,7 @@ pub(crate) struct Request {
pub gid: GroupId,
pub addr: PeerAddr,
pub name: String,
key: GroupChatKey,
remark: String,
is_ok: bool,
is_over: bool,
@ -326,13 +398,20 @@ impl Request { @@ -326,13 +398,20 @@ impl Request {
name,
remark,
datetime,
key: GroupChatKey(vec![]),
is_ok: false,
is_over: false,
id: 0,
}
}
pub fn new_by_me(gid: GroupId, addr: PeerAddr, name: String, remark: String) -> Self {
pub fn new_by_me(
gid: GroupId,
addr: PeerAddr,
name: String,
remark: String,
key: GroupChatKey,
) -> Self {
let start = SystemTime::now();
let datetime = start
.duration_since(UNIX_EPOCH)
@ -345,6 +424,7 @@ impl Request { @@ -345,6 +424,7 @@ impl Request {
name,
remark,
datetime,
key,
is_ok: false,
is_over: false,
fid: 0,
@ -367,12 +447,13 @@ impl Request { @@ -367,12 +447,13 @@ impl Request {
}
pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let sql = format!("INSERT INTO requests (fid, gid, addr, name, remark, is_ok, is_over, datetime, is_deleted) VALUES ({}, '{}', '{}', '{}', '{}', {}, {}, {}, false)",
let sql = format!("INSERT INTO requests (fid, gid, addr, name, remark, key, is_ok, is_over, datetime, is_deleted) VALUES ({}, '{}', '{}', '{}', '{}', '{}', {}, {}, {}, false)",
self.fid,
self.gid.to_hex(),
self.addr.to_hex(),
self.name,
self.remark,
self.key.to_hex(),
if self.is_ok { 1 } else { 0 },
if self.is_over { 1 } else { 0 },
self.datetime,
@ -382,6 +463,33 @@ impl Request { @@ -382,6 +463,33 @@ impl Request {
self.id = id;
Ok(())
}
pub fn over(db: &DStorage, gcd: &GroupId, is_ok: bool) -> Result<(i64, GroupChatKey)> {
let matrix = db.query(&format!(
"SELECT id, key from requests WHERE gid = '{}' AND is_over = 0 ORDER BY id",
gcd.to_hex()
))?;
let mut requests = vec![];
for mut values in matrix {
let id = values.pop().unwrap().as_i64();
let key = GroupChatKey::from_hex(values.pop().unwrap().as_string())
.unwrap_or(GroupChatKey::new(vec![]));
requests.push((id, key));
}
let sql = format!(
"UPDATE requests SET is_ok={}, is_over=1 WHERE gid = '{}' AND is_over = 0",
if is_ok { 1 } else { 0 },
gcd.to_hex(),
);
db.update(&sql)?;
if requests.len() > 0 {
Ok(requests.pop().unwrap()) // safe.
} else {
Err(new_io_error("no requests"))
}
}
}
/// Group Member Model.
@ -629,7 +737,7 @@ impl Message { @@ -629,7 +737,7 @@ impl Message {
}
pub(super) fn to_network_message(
mtype: MessageType,
_mtype: MessageType,
content: &str,
) -> Result<(NetworkMessage, i64)> {
let start = SystemTime::now();

16
src/apps/group_chat/rpc.rs

@ -14,7 +14,7 @@ use crate::rpc::RpcState; @@ -14,7 +14,7 @@ use crate::rpc::RpcState;
use crate::storage::group_chat_db;
use super::add_layer;
use super::models::{to_network_message, GroupChat, Member, Message, Request};
use super::models::{to_network_message, GroupChat, GroupChatKey, Member, Message, Request};
#[inline]
pub(crate) fn create_check(mgid: GroupId, ct: CheckType, supported: Vec<GroupType>) -> RpcParam {
@ -37,6 +37,16 @@ pub(crate) fn group_offline(mgid: GroupId, fid: i64, gid: &GroupId) -> RpcParam @@ -37,6 +37,16 @@ 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 group_agree(mgid: GroupId, rid: i64, group: GroupChat) -> RpcParam {
rpc_response(0, "group-chat-agree", json!([rid, group.to_rpc()]), mgid)
}
#[inline]
pub(crate) fn group_reject(mgid: GroupId, rid: i64) -> RpcParam {
rpc_response(0, "group-chat-reject", json!([rid]), mgid)
}
#[inline]
pub(crate) fn member_join(mgid: GroupId, member: Member) -> RpcParam {
rpc_response(0, "group-chat-member-join", json!(member.to_rpc()), mgid)
@ -192,8 +202,10 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -192,8 +202,10 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
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 gkey = params[4].as_str()?;
let key = GroupChatKey::from_hex(gkey).unwrap_or(GroupChatKey::new(vec![]));
let mut request = Request::new_by_me(gcd, gaddr, gname, gremark);
let mut request = Request::new_by_me(gcd, gaddr, gname, gremark, key);
let db = group_chat_db(state.layer.read().await.base(), &gid)?;
request.insert(&db)?;
drop(db);

3
src/migrate/group_chat.rs

@ -25,7 +25,8 @@ pub(super) const GROUP_CHAT_VERSIONS: [&str; 4] = [ @@ -25,7 +25,8 @@ pub(super) const GROUP_CHAT_VERSIONS: [&str; 4] = [
gid TEXT NOT NULL,
addr TEXT NOT NULL,
name TEXT NOT NULL,
remark TEXT,
remark TEXT NOT NULL,
key TEXT NOT NULL,
is_ok INTEGER NOT NULL,
is_over INTEGER NOT NULL,
datetime INTEGER NOT NULL,

Loading…
Cancel
Save