Browse Source

add support for store group chat provider

pull/18/head
Sun 4 years ago
parent
commit
435f426857
  1. 229
      lib/apps/group_chat/add.dart
  2. 22
      lib/apps/group_chat/models.dart
  3. 24
      lib/apps/group_chat/provider.dart
  4. 1
      lib/l10n/localizations.dart
  5. 2
      lib/l10n/localizations_en.dart
  6. 2
      lib/l10n/localizations_zh.dart
  7. 2
      lib/pages/account_domain.dart
  8. 2
      lib/rpc.dart
  9. 30
      src/apps/group_chat/layer.rs
  10. 2
      src/apps/group_chat/models.rs
  11. 147
      src/apps/group_chat/models/provider.rs
  12. 56
      src/apps/group_chat/rpc.rs
  13. 9
      src/migrate/group_chat.rs

229
lib/apps/group_chat/add.dart

@ -49,6 +49,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -49,6 +49,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
Uint8List? _createAvatarBytes;
int _groupLocation = 0;
bool _groupAddLocation = false;
int _groupType = 1;
bool _groupNeedAgree = false;
//bool _addrOnline = false;
@ -57,6 +58,50 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -57,6 +58,50 @@ class _GroupAddPageState extends State<GroupAddPage> {
bool _requestsLoadMore = true;
Map<int, ProviderServer> _providers = {};
int _providerSelected = -1;
_providerList(List params) {
this._providers.clear();
int index = 0;
params.forEach((param) {
this._providers[index] = ProviderServer.fromList(param);
index += 1;
});
setState(() {});
}
_providerCheck(List params) {
final provider = ProviderServer.fromList(params);
bool contains = false;
this._providers.forEach((k, p) {
if (p.id == provider.id) {
this._providers[k] = provider;
contains = true;
}
});
if (!contains) {
this._providers[this._providers.length] = provider;
}
setState(() {});
}
_providerDelete(List params) {
final id = params[0];
int index = -1;
this._providers.forEach((k, p) {
if (p.id == id) {
index = k;
}
});
if (index > -1) {
this._providers.remove(index);
}
setState(() {});
}
// 0 => remote, 1 => local.
Widget _groupLocationWidget(String text, int value, ColorScheme color, bool disabled) {
return Row(
@ -95,15 +140,40 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -95,15 +140,40 @@ class _GroupAddPageState extends State<GroupAddPage> {
);
}
_checkAddrPermission() {
//
}
_checkGroupAddr() {
final addr = addrParse(_createAddrController.text.trim());
if (addr.length > 0) {
context.read<GroupChatProvider>().check(addr);
}
Widget _providerItem(ProviderServer provider, color, lang, context) {
return ListTile(
leading: IconButton(icon: Icon(Icons.sync, color: color.primary),
onPressed: () => rpc.send('group-chat-provider-check', [
provider.id, provider.addr
])
),
title: Text('group.esse'),
subtitle: Text('remain 10 times'),
trailing: IconButton(icon: Icon(Icons.delete, color: Colors.red),
onPressed: () => showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(lang.delete + " ${provider.name} ?"),
actions: [
TextButton(
child: Text(lang.cancel),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text(lang.ok),
onPressed: () {
Navigator.pop(context);
rpc.send('group-chat-provider-delete', [provider.id]);
rpc.send('group-chat-provider-list', []);
},
),
]
);
},
)
),
);
}
_scanCallback(bool isOk, String app, List params) {
@ -134,7 +204,11 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -134,7 +204,11 @@ class _GroupAddPageState extends State<GroupAddPage> {
}
_create() {
final addr = addrParse(_createAddrController.text.trim());
if (!this._providers.containsKey(this._providerSelected)) {
return;
}
final addr = this._providers[this._providerSelected]!.addr;
if (_groupLocation == 0 && addr.length < 2) {
return;
}
@ -177,10 +251,15 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -177,10 +251,15 @@ class _GroupAddPageState extends State<GroupAddPage> {
setState(() {});
});
rpc.addListener('group-chat-provider-list', _providerList, false);
rpc.addListener('group-chat-provider-check', _providerCheck, false);
rpc.addListener('group-chat-provider-delete', _providerDelete, false);
rpc.send('group-chat-provider-list', []);
rpc.send('group-chat-request-list', [false]);
new Future.delayed(Duration.zero, () {
_myName = context.read<AccountProvider>().activedAccount.name;
context.read<GroupChatProvider>().clearCheck();
setState(() {});
});
}
@ -191,9 +270,6 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -191,9 +270,6 @@ class _GroupAddPageState extends State<GroupAddPage> {
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
final provider = context.watch<GroupChatProvider>();
final checks = provider.createCheckType.lang(lang);
final checkLang = checks[0];
final checkOk = checks[1];
final groups = provider.groups;
final createKeys = provider.createKeys;
@ -201,6 +277,11 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -201,6 +277,11 @@ class _GroupAddPageState extends State<GroupAddPage> {
final requests = provider.requests;
final requestKeys = requests.keys.toList().reversed.toList();
if (this._providerSelected < 0 && this._providers.length > 0) {
this._providerSelected = 0;
}
final maxIndex = this._providers.length - 1;
return DefaultTabController(
initialIndex: 0,
length: 2,
@ -251,7 +332,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -251,7 +332,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
body: TabBarView(
children: <Widget>[
Container(
padding: const EdgeInsets.all(20),
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
@ -300,7 +381,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -300,7 +381,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
),
),
Container(
padding: const EdgeInsets.all(20),
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
@ -309,7 +390,7 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -309,7 +390,7 @@ class _GroupAddPageState extends State<GroupAddPage> {
width: 600.0,
padding: const EdgeInsets.all(10.0),
alignment: Alignment.centerLeft,
child: Text('1. ' + lang.groupChatAddr, textAlign: TextAlign.left,
child: Text('1. ' + lang.groupChatLocation, textAlign: TextAlign.left,
style: Theme.of(context).textTheme.headline6),
),
Container(
@ -326,12 +407,64 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -326,12 +407,64 @@ class _GroupAddPageState extends State<GroupAddPage> {
),
if (_groupLocation == 0)
Container(
height: 50.0,
margin: const EdgeInsets.only(top: 10.0),
width: 600.0,
child: Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Text(lang.domainProvider,
style: TextStyle(fontWeight: FontWeight.bold)),
),
TextButton(child: Icon(Icons.navigate_before),
onPressed: this._providerSelected > 0 ? () => setState(() {
this._providerSelected = this._providerSelected - 1;
}) : null,
),
Expanded(
child: Center(
child: Text(
this._providerSelected >= 0
? this._providers[this._providerSelected]!.name
: '',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0)
),
)),
TextButton(child: Icon(Icons.navigate_next),
onPressed: this._providerSelected < maxIndex ? () => setState(() {
this._providerSelected = this._providerSelected + 1;
}) : null,
),
const SizedBox(width: 20.0),
InkWell(
onTap: () => setState(() {
this._groupAddLocation = !this._groupAddLocation;
}),
child: Container(
height: 40.0,
padding: const EdgeInsets.symmetric(horizontal: 20.0),
decoration: BoxDecoration(
border: Border.all(color: color.primary),
borderRadius: BorderRadius.circular(10.0)),
child: Center(
child: Text(this._groupAddLocation ? lang.cancel : lang.add,
style: TextStyle(fontSize: 16.0, color: color.primary))),
)),
])),
if (this._groupAddLocation)
Container(
margin: const EdgeInsets.only(top: 10.0),
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: color.secondary,
borderRadius: BorderRadius.circular(10.0),
),
width: 600.0,
child: Column(
children: [
ListTile(
leading: Icon(Icons.location_on),
title: Container(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
decoration: BoxDecoration(
color: color.surface,
@ -346,52 +479,24 @@ class _GroupAddPageState extends State<GroupAddPage> { @@ -346,52 +479,24 @@ class _GroupAddPageState extends State<GroupAddPage> {
hintText: lang.address),
controller: _createAddrController,
focusNode: _createAddrFocus,
onSubmitted: (_v) => _checkAddrPermission(),
onChanged: (v) {
if (v.length > 0) {
setState(() {
_addrChecked = true;
});
}
}),
),
),
),
if (checkOk)
Container(
padding: const EdgeInsets.only(left: 8.0),
child: Icon(Icons.cloud_done_rounded,
color: Colors.green),
),
const SizedBox(width: 8.0),
InkWell(
onTap: _addrChecked ? _checkGroupAddr : null,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
height: 45.0,
decoration: BoxDecoration(
color: Color(0xFF6174FF),
borderRadius: BorderRadius.circular(10.0)),
child: Center(
child: Text(lang.search,
style: TextStyle(fontSize: 16.0, color: Colors.white))),
trailing: IconButton(icon: Icon(Icons.send, color: color.primary),
onPressed: () {
final addr = addrParse(_createAddrController.text.trim());
if (addr.length > 0) {
rpc.send('group-chat-provider-check', [0, addr]);
}
},
)),
const SizedBox(width: 8.0),
InkWell(
onTap: _addrChecked ? _checkGroupAddr : null,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
height: 45.0,
decoration: BoxDecoration(
color: Color(0xFF6174FF),
borderRadius: BorderRadius.circular(10.0)),
child: Center(
child: Text(lang.add,
style: TextStyle(fontSize: 16.0, color: Colors.white))),
)),
])),
const SizedBox(height: 8.0),
Text(checkLang, style: TextStyle(fontSize: 14.0,
color: checkOk ? Colors.green : Colors.red)),
const Divider(height: 20.0, color: Color(0x40ADB0BB)),
Column(
children: this._providers.values.map(
(provider) => _providerItem(provider, color, lang, context)
).toList(),
),
]
)),
Container(
width: 600.0,
padding: const EdgeInsets.all(10.0),

22
lib/apps/group_chat/models.dart

@ -216,3 +216,25 @@ class Message extends BaseMessage { @@ -216,3 +216,25 @@ class Message extends BaseMessage {
this.time = RelativeTime.fromInt(params[8]);
}
}
class ProviderServer {
int id = 0;
String name = '';
String addr = '';
List<GroupType> kinds = [];
int remain = 0;
bool isOk = false;
ProviderServer.fromList(List params) {
this.id = params[0];
this.name = params[1];
this.addr = params[2];
params[3].forEach((param) {
this.kinds.add(GroupTypeExtension.fromInt(param));
});
this.remain = params[4];
this.isOk = params[5];
}
}

24
lib/apps/group_chat/provider.dart

@ -9,9 +9,6 @@ import 'package:esse/apps/primitives.dart'; @@ -9,9 +9,6 @@ import 'package:esse/apps/primitives.dart';
import 'package:esse/apps/group_chat/models.dart';
class GroupChatProvider extends ChangeNotifier {
List<GroupType> createSupported = [GroupType.Encrypted, GroupType.Private, GroupType.Open];
CheckType createCheckType = CheckType.Nothing;
Map<int, GroupChat> groups = {};
List<int> createKeys = [];
List<int> orderKeys = [];
@ -71,7 +68,6 @@ class GroupChatProvider extends ChangeNotifier { @@ -71,7 +68,6 @@ class GroupChatProvider extends ChangeNotifier {
GroupChatProvider() {
// rpc.
rpc.addListener('group-chat-list', _list, false);
rpc.addListener('group-chat-check', _check, false);
rpc.addListener('group-chat-create', _create, false);
rpc.addListener('group-chat-result', _result, false);
rpc.addListener('group-chat-detail', _detail, true);
@ -119,15 +115,6 @@ class GroupChatProvider extends ChangeNotifier { @@ -119,15 +115,6 @@ class GroupChatProvider extends ChangeNotifier {
this.requests.clear();
}
check(String addr) {
this.createCheckType = CheckType.Wait;
rpc.send('group-chat-check', [addr]);
}
clearCheck() {
this.createCheckType = CheckType.Nothing;
}
join(GroupType gtype, String gid, String gaddr, String name, String remark, [String proof = '', String key = '']) {
rpc.send('group-chat-join', [gtype.toInt(), gid, gaddr, name, remark, proof, key]);
}
@ -183,17 +170,6 @@ class GroupChatProvider extends ChangeNotifier { @@ -183,17 +170,6 @@ class GroupChatProvider extends ChangeNotifier {
notifyListeners();
}
_check(List params) {
this.createSupported.clear();
if (this.createCheckType == CheckType.Wait) {
this.createCheckType = CheckTypeExtension.fromInt(params[0]);
params[1].forEach((param) {
this.createSupported.add(GroupTypeExtension.fromInt(param));
});
notifyListeners();
}
}
_create(List params) {
final gc = GroupChat.fromList(params);
if (gc.isOk) {

1
lib/l10n/localizations.dart

@ -192,6 +192,7 @@ abstract class AppLocalizations { @@ -192,6 +192,7 @@ abstract class AppLocalizations {
String get groupChatName;
String get groupChatKey;
String get groupChatAddr;
String get groupChatLocation;
String get groupChatInfo;
String get groupChatBio;
String get groupJoin;

2
lib/l10n/localizations_en.dart

@ -291,6 +291,8 @@ class AppLocalizationsEn extends AppLocalizations { @@ -291,6 +291,8 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get groupChatAddr => 'Group Address';
@override
String get groupChatLocation => 'Group Location';
@override
String get groupChatInfo => 'Group Information';
@override
String get groupChatBio => 'Group Bio';

2
lib/l10n/localizations_zh.dart

@ -287,6 +287,8 @@ class AppLocalizationsZh extends AppLocalizations { @@ -287,6 +287,8 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get groupChatAddr => '群聊地址';
@override
String get groupChatLocation => '群位置';
@override
String get groupChatName => '群名称';
@override
String get groupChatKey => '加密密码';

2
lib/pages/account_domain.dart

@ -140,7 +140,7 @@ class AccountDomainScreenState extends State<AccountDomainScreen> { @@ -140,7 +140,7 @@ class AccountDomainScreenState extends State<AccountDomainScreen> {
action: () {
final name = _nameController.text.trim();
if (name.length > 0) {
rpc.send('domain-register', [provider.id, provider.addr, name, '']);
rpc.send('domain-register', [provider.id, provider.addr, name, 'Hello ESSE!']);
setState(() {
this._waiting = true;
this._exist = false;

2
lib/rpc.dart

@ -153,7 +153,7 @@ class WebSocketsNotifications { @@ -153,7 +153,7 @@ class WebSocketsNotifications {
if (gid == Global.gid || method.startsWith('account')) {
try {
callbacks[0](params);
} catch (_e) {
} catch (e) {
print('function is unvalid');
}
} else if (callbacks[1] != null && callbacks[1]) {

30
src/apps/group_chat/layer.rs

@ -8,7 +8,8 @@ use tdn::types::{ @@ -8,7 +8,8 @@ use tdn::types::{
use tokio::sync::RwLock;
use group_chat_types::{
ConnectProof, Event, GroupType, JoinProof, LayerConnect, LayerEvent, LayerResult, PackedEvent,
CheckType, ConnectProof, Event, GroupType, JoinProof, LayerConnect, LayerEvent, LayerResult,
PackedEvent,
};
use tdn_did::Proof;
use tdn_storage::local::DStorage;
@ -21,7 +22,9 @@ use crate::storage::{ @@ -21,7 +22,9 @@ use crate::storage::{
chat_db, delete_avatar, group_chat_db, read_avatar, session_db, write_avatar, write_avatar_sync,
};
use super::models::{from_network_message, Consensus, ConsensusType, GroupChat, Member, Request};
use super::models::{
from_network_message, Consensus, ConsensusType, GroupChat, Member, Provider, Request,
};
use super::{add_layer, add_server_layer, rpc};
// variable statement:
@ -276,10 +279,29 @@ async fn handle_event( @@ -276,10 +279,29 @@ async fn handle_event(
let _ = layer.write().await.running_mut(&ogid)?.active(&gcd, false);
results.rpcs.push(session_connect(ogid, &sid, &addr));
}
LayerEvent::CheckResult(ct, supported) => {
LayerEvent::CheckResult(ct, name, remain, supported) => {
// only client handle it.
println!("check: {:?}, supported: {:?}", ct, supported);
results.rpcs.push(rpc::create_check(ogid, ct, supported))
let mut provider = Provider::get_by_addr(&db, &addr)?;
let rpc_ui = match ct {
CheckType::Allow => {
provider.update(&db, name, supported, remain)?;
rpc::provider_check(ogid, &provider)
}
CheckType::None => {
provider.update(&db, name, supported, 0)?;
rpc::provider_check(ogid, &provider)
}
CheckType::Suspend => {
provider.suspend(&db)?;
rpc::provider_check(ogid, &provider)
}
CheckType::Deny => {
Provider::delete(&db, &provider.id)?;
rpc::provider_delete(ogid, provider.id)
}
};
results.rpcs.push(rpc_ui)
}
LayerEvent::CreateResult(gcd, ok) => {
// only client handle it.

2
src/apps/group_chat/models.rs

@ -4,6 +4,7 @@ mod consensus; @@ -4,6 +4,7 @@ mod consensus;
mod group;
mod member;
mod message;
mod provider;
mod request;
// models.
@ -11,6 +12,7 @@ pub(crate) use consensus::{Consensus, ConsensusType}; @@ -11,6 +12,7 @@ pub(crate) use consensus::{Consensus, ConsensusType};
pub(crate) use group::GroupChat;
pub(crate) use member::Member;
pub(crate) use message::Message;
pub(crate) use provider::Provider;
pub(crate) use request::Request;
pub(crate) use message::{from_network_message, to_network_message};

147
src/apps/group_chat/models/provider.rs

@ -0,0 +1,147 @@ @@ -0,0 +1,147 @@
use tdn::types::{
primitive::{PeerAddr, Result},
rpc::{json, RpcParam},
};
use tdn_storage::local::{DStorage, DsValue};
use group_chat_types::GroupType;
/// Group Chat Provider Model.
pub(crate) struct Provider {
pub id: i64,
name: String,
addr: PeerAddr,
kinds: Vec<GroupType>,
remain: i64,
is_ok: bool,
}
fn parse_kinds(kinds: i64) -> Vec<GroupType> {
let s = kinds.to_string();
s.chars()
.filter_map(|c| match c {
'0' => Some(GroupType::Encrypted),
'1' => Some(GroupType::Private),
'2' => Some(GroupType::Open),
_ => None,
})
.collect()
}
fn kinds_print(kinds: &Vec<GroupType>) -> i64 {
let mut v: Vec<u32> = kinds.iter().map(|k| k.to_u32()).collect();
v.sort_by(|a, b| b.cmp(a));
let s = v
.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join("");
s.parse().unwrap_or(0)
}
impl Provider {
pub fn new(addr: PeerAddr) -> Self {
Self {
addr,
name: String::new(),
kinds: vec![],
is_ok: false,
remain: 0,
id: 0,
}
}
pub fn to_rpc(&self) -> RpcParam {
let kinds: Vec<u32> = self.kinds.iter().map(|v| v.to_u32()).collect();
json!([
self.id,
self.name,
self.addr.to_hex(),
kinds,
self.remain,
self.is_ok
])
}
fn from_values(mut v: Vec<DsValue>) -> Self {
Self {
is_ok: v.pop().unwrap().as_bool(),
remain: v.pop().unwrap().as_i64(),
kinds: parse_kinds(v.pop().unwrap().as_i64()),
addr: PeerAddr::from_hex(v.pop().unwrap().as_string()).unwrap_or(Default::default()),
name: v.pop().unwrap().as_string(),
id: v.pop().unwrap().as_i64(),
}
}
pub fn list(db: &DStorage) -> Result<Vec<Self>> {
let matrix = db.query("SELECT id, name, addr, kinds, remain, is_ok FROM providers")?;
let mut providers = vec![];
for values in matrix {
providers.push(Self::from_values(values));
}
Ok(providers)
}
pub fn get_by_addr(db: &DStorage, addr: &PeerAddr) -> Result<Self> {
let sql = format!(
"SELECT id, name, addr, kinds, remain, is_ok FROM providers WHERE addr = '{}'",
addr.to_hex()
);
let mut matrix = db.query(&sql)?;
if matrix.len() > 0 {
let values = matrix.pop().unwrap(); // safe unwrap()
return Ok(Self::from_values(values));
}
Err(anyhow!("provider is missing"))
}
pub fn insert(&mut self, db: &DStorage) -> Result<()> {
let sql = format!(
"INSERT INTO providers (name,addr,kinds,remain,is_ok) VALUES ('{}','{}',{},{},{})",
self.name,
self.addr.to_hex(),
kinds_print(&self.kinds),
self.remain,
self.is_ok,
);
let id = db.insert(&sql)?;
self.id = id;
Ok(())
}
pub fn update(
&mut self,
db: &DStorage,
name: String,
kinds: Vec<GroupType>,
remain: i64,
) -> Result<()> {
self.name = name;
self.kinds = kinds;
self.remain = remain;
let sql = format!(
"UPDATE providers SET is_ok=true, name='{}', kinds={}, remain={} WHERE id = {}",
self.name,
kinds_print(&self.kinds),
self.remain,
self.id
);
db.update(&sql)?;
Ok(())
}
pub fn suspend(&mut self, db: &DStorage) -> Result<()> {
self.is_ok = false;
let sql = format!("UPDATE providers SET is_ok=false WHERE id = {}", self.id);
db.update(&sql)?;
Ok(())
}
pub fn delete(db: &DStorage, id: &i64) -> Result<()> {
let sql = format!("DELETE FROM providers WHERE id = {}", id);
db.update(&sql)?;
Ok(())
}
}

56
src/apps/group_chat/rpc.rs

@ -7,7 +7,7 @@ use tdn::types::{ @@ -7,7 +7,7 @@ use tdn::types::{
};
use tdn_did::Proof;
use group_chat_types::{CheckType, Event, GroupLocation, GroupType, JoinProof, LayerEvent};
use group_chat_types::{Event, GroupLocation, GroupType, JoinProof, LayerEvent};
use crate::apps::chat::{Friend, MessageType};
use crate::layer::Online;
@ -17,13 +17,23 @@ use crate::storage::{chat_db, group_chat_db, read_avatar, session_db, write_avat @@ -17,13 +17,23 @@ use crate::storage::{chat_db, group_chat_db, read_avatar, session_db, write_avat
use super::add_layer;
use super::models::{
to_network_message, Consensus, ConsensusType, GroupChat, GroupChatKey, Member, Message, Request,
to_network_message, Consensus, ConsensusType, GroupChat, GroupChatKey, Member, Message,
Provider, 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)
pub(crate) fn provider_check(mgid: GroupId, provider: &Provider) -> RpcParam {
rpc_response(
0,
"group-chat-provider-check",
json!(provider.to_rpc()),
mgid,
)
}
#[inline]
pub(crate) fn provider_delete(mgid: GroupId, id: i64) -> RpcParam {
rpc_response(0, "group-chat-provider-delete", json!([id]), mgid)
}
#[inline]
@ -179,9 +189,29 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -179,9 +189,29 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
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().ok_or(RpcError::ParseError)?)?;
"group-chat-provider-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let db = group_chat_db(state.layer.read().await.base(), &gid)?;
let providers: Vec<RpcParam> =
Provider::list(&db)?.iter().map(|p| p.to_rpc()).collect();
Ok(HandleResult::rpc(json!(providers)))
},
);
handler.add_method(
"group-chat-provider-check",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let addr = PeerAddr::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
if id == 0 {
// insert into database.
let db = group_chat_db(state.layer.read().await.base(), &gid)?;
if Provider::get_by_addr(&db, &addr).is_err() {
let mut provider = Provider::new(addr);
provider.insert(&db)?;
}
}
let mut results = HandleResult::new();
let data = bincode::serialize(&LayerEvent::Check)?;
@ -191,6 +221,16 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -191,6 +221,16 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
},
);
handler.add_method(
"group-chat-provider-delete",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let db = group_chat_db(state.layer.read().await.base(), &gid)?;
Provider::delete(&db, &id)?;
Ok(HandleResult::new())
},
);
handler.add_method(
"group-chat-create",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {

9
src/migrate/group_chat.rs

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
#[rustfmt::skip]
pub(super) const GROUP_CHAT_VERSIONS: [&str; 5] = [
pub(super) const GROUP_CHAT_VERSIONS: [&str; 6] = [
"CREATE TABLE IF NOT EXISTS groups(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
height INTEGER NOT NULL,
@ -56,4 +56,11 @@ pub(super) const GROUP_CHAT_VERSIONS: [&str; 5] = [ @@ -56,4 +56,11 @@ pub(super) const GROUP_CHAT_VERSIONS: [&str; 5] = [
height INTEGER NOT NULL,
ctype INTEGER NOT NULL,
cid INTEGER NOT NULL);",
"CREATE TABLE IF NOT EXISTS providers(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
addr TEXT NOT NULL,
kinds INTEGER NOT NULL,
remain INTEGER NOT NULL,
is_ok INTEGER NOT NULL);",
];

Loading…
Cancel
Save