Browse Source

handle member join

pull/18/head
Sun 4 years ago
parent
commit
0608138c4b
  1. 5
      lib/apps/group_chat/models.dart
  2. 6
      lib/apps/group_chat/provider.dart
  3. 1
      lib/l10n/localizations.dart
  4. 2
      lib/l10n/localizations_en.dart
  5. 2
      lib/l10n/localizations_zh.dart
  6. 44
      src/apps/group_chat/layer.rs
  7. 62
      src/apps/group_chat/models.rs
  8. 10
      src/apps/group_chat/rpc.rs
  9. 1
      src/migrate/group_chat.rs

5
lib/apps/group_chat/models.dart

@ -16,6 +16,7 @@ enum GroupType { @@ -16,6 +16,7 @@ enum GroupType {
enum CheckType {
Allow,
None,
Suspend,
Deny,
Wait,
}
@ -55,6 +56,8 @@ extension CheckTypeExtension on CheckType { @@ -55,6 +56,8 @@ extension CheckTypeExtension on CheckType {
return [lang.groupCheckTypeAllow, true];
case CheckType.None:
return [lang.groupCheckTypeNone, false];
case CheckType.Suspend:
return [lang.groupCheckTypeSuspend, false];
case CheckType.Deny:
return [lang.groupCheckTypeDeny, false];
default:
@ -69,6 +72,8 @@ extension CheckTypeExtension on CheckType { @@ -69,6 +72,8 @@ extension CheckTypeExtension on CheckType {
case 1:
return CheckType.None;
case 2:
return CheckType.Suspend;
case 3:
return CheckType.Deny;
default:
return CheckType.Deny;

6
lib/apps/group_chat/provider.dart

@ -45,7 +45,7 @@ class GroupChatProvider extends ChangeNotifier { @@ -45,7 +45,7 @@ class GroupChatProvider extends ChangeNotifier {
// rpc.addListener('group-chat-join', _join, true);
// rpc.addListener('group-chat-agree', _agree, true);
// rpc.addListener('group-chat-reject', _reject, false);
// rpc.addListener('group-chat-member-join', _memberJoin, false);
rpc.addListener('group-chat-member-join', _memberJoin, false);
// rpc.addListener('group-chat-member-info', _memberInfo, false);
// rpc.addListener('group-chat-member-leave', _memberLeave, false);
rpc.addListener('group-chat-member-online', _memberOnline, false);
@ -173,6 +173,10 @@ class GroupChatProvider extends ChangeNotifier { @@ -173,6 +173,10 @@ class GroupChatProvider extends ChangeNotifier {
}
}
_memberJoin(List params) {
//
}
_memberOnline(List params) {
//
}

1
lib/l10n/localizations.dart

@ -165,6 +165,7 @@ abstract class AppLocalizations { @@ -165,6 +165,7 @@ abstract class AppLocalizations {
String get groupChatBio;
String get groupCheckTypeAllow;
String get groupCheckTypeNone;
String get groupCheckTypeSuspend;
String get groupCheckTypeDeny;
String get members;
}

2
lib/l10n/localizations_en.dart

@ -241,6 +241,8 @@ class AppLocalizationsEn extends AppLocalizations { @@ -241,6 +241,8 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get groupCheckTypeNone => 'Restricted, the allowed number is full';
@override
String get groupCheckTypeSuspend => 'Account is suspended';
@override
String get groupCheckTypeDeny => 'No permission to create here';
@override
String get members => 'Members';

2
lib/l10n/localizations_zh.dart

@ -241,6 +241,8 @@ class AppLocalizationsZh extends AppLocalizations { @@ -241,6 +241,8 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get groupCheckTypeNone => '创建被限制,允许数目已满';
@override
String get groupCheckTypeSuspend => '账户被暂停使用';
@override
String get groupCheckTypeDeny => '没有权限在此创建群聊';
@override
String get members => '成员';

44
src/apps/group_chat/layer.rs

@ -9,13 +9,13 @@ use tdn::{ @@ -9,13 +9,13 @@ use tdn::{
},
};
use group_chat_types::{Event, GroupConnect, GroupResult, JoinProof, LayerEvent, NetworkMessage};
use group_chat_types::{Event, GroupConnect, GroupResult, JoinProof, LayerEvent};
use tdn_did::Proof;
use crate::layer::{Layer, Online};
use crate::storage::group_chat_db;
use super::models::{from_network_message, GroupChat};
use super::models::{from_network_message, GroupChat, Member};
use super::{add_layer, rpc};
pub(crate) async fn handle(
@ -27,9 +27,7 @@ pub(crate) async fn handle( @@ -27,9 +27,7 @@ pub(crate) async fn handle(
match msg {
RecvType::Connect(..) => {} // Never to here.
RecvType::Leave(_addr) => {
//
}
RecvType::Leave(..) => {} // Never to here. handled in chat.
RecvType::Result(addr, _is_ok, data) => {
let res: GroupResult = postcard::from_bytes(&data)
.map_err(|_e| new_io_error("Deseralize result failure"))?;
@ -76,11 +74,7 @@ pub(crate) async fn handle( @@ -76,11 +74,7 @@ pub(crate) async fn handle(
results.rpcs.push(rpc::group_online(mgid, group.id));
// 5. sync group height.
let db = group_chat_db(&base, &mgid)?;
let my_height = GroupChat::get_height(&db, &group.id)?;
drop(db);
if my_height < height {
if group.height < height {
// TOOD
}
} else {
@ -153,23 +147,25 @@ async fn handle_event( @@ -153,23 +147,25 @@ async fn handle_event(
}
LayerEvent::Sync(_, height, event) => {
match event {
Event::Message(mid, nmsg) => {
Event::GroupInfo => {}
Event::GroupTransfer => {}
Event::GroupManagerAdd => {}
Event::GroupManagerDel => {}
Event::GroupClose => {}
Event::MemberInfo(mid, maddr, mname, mavatar) => {}
Event::MemberJoin(mid, maddr, mname, mavatar, mtime) => {
let db = group_chat_db(layer.read().await.base(), &mgid)?;
let mut member = Member::new(gid, mid, maddr, mname, false, mtime);
member.insert(&db)?;
results.rpcs.push(rpc::member_join(mgid, member));
}
Event::MemberLeave(mid) => {}
Event::MessageCreate(mid, nmsg, mtime) => {
let base = layer.read().await.base.clone();
let msg = from_network_message(height as i64, gid, mid, mgid, nmsg, base)?;
let msg =
from_network_message(height as i64, gid, mid, mgid, nmsg, mtime, base)?;
results.rpcs.push(rpc::message_create(mgid, msg));
}
Event::GroupUpdate => {
//
}
Event::GroupTransfer => {
//
}
Event::UserInfo => {
//
}
Event::Close => {
//
}
}
// save event.

62
src/apps/group_chat/models.rs

@ -57,6 +57,8 @@ impl GroupChatKey { @@ -57,6 +57,8 @@ impl GroupChatKey {
pub(crate) struct GroupChat {
/// db auto-increment id.
pub id: i64,
/// consensus height.
pub height: i64,
/// group chat owner.
pub owner: GroupId,
/// group chat id.
@ -123,6 +125,7 @@ impl GroupChat { @@ -123,6 +125,7 @@ impl GroupChat {
key,
datetime,
id: 0,
height: 0,
is_top: true,
is_ok: false,
is_closed: false,
@ -206,13 +209,14 @@ impl GroupChat { @@ -206,13 +209,14 @@ impl GroupChat {
g_type: GroupType::from_u32(v.pop().unwrap().as_i64() as u32),
g_id: GroupId::from_hex(v.pop().unwrap().as_string()).unwrap_or(Default::default()),
owner: GroupId::from_hex(v.pop().unwrap().as_string()).unwrap_or(Default::default()),
height: v.pop().unwrap().as_i64(),
id: v.pop().unwrap().as_i64(),
}
}
/// use in rpc when load account friends.
pub fn all(db: &DStorage) -> Result<Vec<GroupChat>> {
let matrix = db.query("SELECT id, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime FROM groups WHERE is_deleted = false ORDER BY last_datetime DESC")?;
let matrix = db.query("SELECT id, height, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime FROM groups WHERE is_deleted = false ORDER BY last_datetime DESC")?;
let mut groups = vec![];
for values in matrix {
groups.push(GroupChat::from_values(values, false));
@ -222,7 +226,7 @@ impl GroupChat { @@ -222,7 +226,7 @@ impl GroupChat {
/// use in rpc when load account groups.
pub fn all_ok(db: &DStorage) -> Result<Vec<GroupChat>> {
let matrix = db.query("SELECT id, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime FROM groups WHERE is_closed = false ORDER BY last_datetime DESC")?;
let matrix = db.query("SELECT id, height, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime FROM groups WHERE is_closed = false ORDER BY last_datetime DESC")?;
let mut groups = vec![];
for values in matrix {
groups.push(GroupChat::from_values(values, false));
@ -231,7 +235,7 @@ impl GroupChat { @@ -231,7 +235,7 @@ impl GroupChat {
}
pub fn get(db: &DStorage, gid: &GroupId) -> Result<Option<GroupChat>> {
let sql = format!("SELECT id, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime FROM groups WHERE gcd = '{}' AND is_deleted = false", gid.to_hex());
let sql = format!("SELECT id, height, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime FROM groups WHERE gcd = '{}' AND is_deleted = false", gid.to_hex());
let mut matrix = db.query(&sql)?;
if matrix.len() > 0 {
let values = matrix.pop().unwrap(); // safe unwrap()
@ -240,13 +244,9 @@ impl GroupChat { @@ -240,13 +244,9 @@ impl GroupChat {
Ok(None)
}
pub fn get_height(db: &DStorage, id: &i64) -> Result<u64> {
// TODO
Ok(0)
}
pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let sql = format!("INSERT INTO groups (owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime, is_deleted) VALUES ('{}', '{}', {}, '{}', '{}', '{}', {}, {}, {}, {}, '{}', {}, '{}', {}, {}, false)",
let sql = format!("INSERT INTO groups (height, owner, gcd, gtype, addr, name, bio, is_top, is_ok, is_need_agree, is_closed, key, last_datetime, last_content, last_readed, datetime, is_deleted) VALUES ({}, '{}', '{}', {}, '{}', '{}', '{}', {}, {}, {}, {}, '{}', {}, '{}', {}, {}, false)",
self.height,
self.owner.to_hex(),
self.g_id.to_hex(),
self.g_type.to_u32(),
@ -263,7 +263,6 @@ impl GroupChat { @@ -263,7 +263,6 @@ impl GroupChat {
if self.last_readed { 1 } else { 0 },
self.datetime,
);
println!("{}", sql);
let id = db.insert(&sql)?;
self.id = id;
Ok(())
@ -293,7 +292,7 @@ impl GroupChat { @@ -293,7 +292,7 @@ impl GroupChat {
}
/// Group Member Model.
pub(super) struct Member {
pub(crate) struct Member {
/// db auto-increment id.
id: i64,
/// group's db id.
@ -426,20 +425,15 @@ pub(crate) struct Message { @@ -426,20 +425,15 @@ pub(crate) struct Message {
}
impl Message {
pub(crate) fn new(
pub(crate) fn new_with_time(
height: i64,
fid: i64,
mid: i64,
is_me: bool,
m_type: MessageType,
content: String,
datetime: i64,
) -> Message {
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 {
fid,
mid,
@ -453,6 +447,22 @@ impl Message { @@ -453,6 +447,22 @@ impl Message {
id: 0,
}
}
pub(crate) fn new(
height: i64,
fid: i64,
mid: i64,
is_me: bool,
m_type: MessageType,
content: String,
) -> Message {
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::new_with_time(height, fid, mid, is_me, m_type, content, datetime)
}
/// here is zero-copy and unwrap is safe. checked.
fn from_values(mut v: Vec<DsValue>, contains_deleted: bool) -> Message {
let is_deleted = if contains_deleted {
@ -515,12 +525,26 @@ impl Message { @@ -515,12 +525,26 @@ impl Message {
}
}
pub(super) fn to_network_message(
mtype: MessageType,
content: &str,
) -> Result<(NetworkMessage, i64)> {
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.
Ok((NetworkMessage::String(content.to_owned()), datetime))
}
pub(super) fn from_network_message(
height: i64,
gdid: i64,
mid: GroupId,
mgid: GroupId,
msg: NetworkMessage,
datetime: i64,
base: PathBuf,
) -> Result<Message> {
let db = group_chat_db(&base, &mgid)?;
@ -572,7 +596,7 @@ pub(super) fn from_network_message( @@ -572,7 +596,7 @@ pub(super) fn from_network_message(
}
};
let mut msg = Message::new(height, gdid, mdid, is_me, m_type, raw);
let mut msg = Message::new_with_time(height, gdid, mdid, is_me, m_type, raw, datetime);
msg.insert(&db)?;
GroupChat::update_last_message(&db, gdid, &msg, false)?;
Ok(msg)

10
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::{GroupChat, Member, Message};
use super::models::{to_network_message, GroupChat, Member, Message};
#[inline]
pub(crate) fn create_check(mgid: GroupId, ct: CheckType, supported: Vec<GroupType>) -> RpcParam {
@ -37,6 +37,11 @@ pub(crate) fn group_offline(mgid: GroupId, fid: i64, gid: &GroupId) -> RpcParam @@ -37,6 +37,11 @@ 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_online(mgid: GroupId, gid: i64, mid: GroupId, maddr: PeerAddr) -> RpcParam {
rpc_response(
@ -183,7 +188,8 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -183,7 +188,8 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
let addr = state.layer.read().await.running(&gid)?.online(&gcd)?;
let mut results = HandleResult::new();
let event = Event::Message(gid, NetworkMessage::String(m_content.to_owned()));
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);

1
src/migrate/group_chat.rs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
pub(super) const GROUP_CHAT_VERSIONS: [&str; 4] = [
"CREATE TABLE IF NOT EXISTS groups(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
height INTEGER NOT NULL,
owner TEXT NOT NULL,
gcd TEXT NOT NULL,
gtype INTEGER NOT NULL,

Loading…
Cancel
Save