Browse Source

domain add active & deletable

pull/18/head
Sun 4 years ago
parent
commit
9a325f29da
  1. 1
      lib/apps/domain/models.dart
  2. 82
      lib/apps/domain/page.dart
  3. 5
      lib/l10n/localizations.dart
  4. 11
      lib/l10n/localizations_en.dart
  5. 11
      lib/l10n/localizations_zh.dart
  6. 20
      src/apps/domain/layer.rs
  7. 46
      src/apps/domain/models.rs
  8. 62
      src/apps/domain/rpc.rs

1
lib/apps/domain/models.dart

@ -6,6 +6,7 @@ class ProviderServer {
bool isDefault; bool isDefault;
bool isProxy; bool isProxy;
bool isActived; bool isActived;
bool deletable = true;
ProviderServer.empty(): ProviderServer.empty():
this.id = 0, this.id = 0,

82
lib/apps/domain/page.dart

@ -39,7 +39,9 @@ class _DomainDetailState extends State<DomainDetail> {
}); });
this._names.clear(); this._names.clear();
params[1].forEach((param) { params[1].forEach((param) {
this._names.add(Name.fromList(param)); final name = Name.fromList(param);
this._providers[name.provider]!.deletable = false;
this._names.add(name);
}); });
setState(() {}); setState(() {});
} }
@ -146,6 +148,7 @@ class _ListNameScreen extends StatefulWidget {
} }
class _ListNameScreenState extends State<_ListNameScreen> { class _ListNameScreenState extends State<_ListNameScreen> {
bool _deleteTime = false;
List<_NameItem> _data = []; List<_NameItem> _data = [];
@override @override
@ -153,7 +156,7 @@ class _ListNameScreenState extends State<_ListNameScreen> {
final color = Theme.of(context).colorScheme; final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context); final lang = AppLocalizations.of(context);
if (this._data.length != widget.names.length) { if (!this._deleteTime && this._data.length != widget.names.length) {
this._data = widget.names.map((name) { this._data = widget.names.map((name) {
return _NameItem( return _NameItem(
name: name, name: name,
@ -161,6 +164,7 @@ class _ListNameScreenState extends State<_ListNameScreen> {
); );
}).toList(); }).toList();
} }
this._deleteTime = false;
return ExpansionPanelList( return ExpansionPanelList(
elevation: 0.0, elevation: 0.0,
@ -171,6 +175,7 @@ class _ListNameScreenState extends State<_ListNameScreen> {
}, },
children: _data.map<ExpansionPanel>((_NameItem item) { children: _data.map<ExpansionPanel>((_NameItem item) {
return ExpansionPanel( return ExpansionPanel(
backgroundColor: color.surface,
headerBuilder: (BuildContext context, bool isExpanded) { headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile( return ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 8.0), contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 8.0),
@ -196,17 +201,36 @@ class _ListNameScreenState extends State<_ListNameScreen> {
leading: Icon(Icons.location_on), leading: Icon(Icons.location_on),
title: Text(item.provider.name), title: Text(item.provider.name),
), ),
ListTile( item.name.isActived
leading: Icon(Icons.cancel, color: color.primary), ? ListTile(
title: Text('Set to unactived ?', style: TextStyle(color: color.primary)), leading: Icon(Icons.cancel, color: Colors.orange),
title: Text(lang.domainSetUnactived, style: TextStyle(color: Colors.orange)),
onTap: () {
rpc.send('domain-active', [item.name.name, item.provider.addr, false]);
setState(() {
item.name.isActived = false;
item.isExpanded = false;
});
})
: ListTile(
leading: Icon(Icons.done, color: color.primary),
title: Text(lang.domainSetActived, style: TextStyle(color: color.primary)),
onTap: () { onTap: () {
// rpc.send('domain-active', [item.name.name, item.provider.addr, true]);
setState(() {
item.name.isActived = true;
item.isExpanded = false;
});
}), }),
ListTile( ListTile(
leading: const Icon(Icons.delete, color: Colors.red), leading: const Icon(Icons.delete, color: Colors.red),
title: Text('Delete from provider ?', style: TextStyle(color: Colors.red)), title: Text(lang.domainDelete, style: TextStyle(color: Colors.red)),
onTap: () { onTap: () {
// rpc.send('domain-remove', [item.name.name, item.provider.addr]);
setState(() {
this._data.removeWhere((_NameItem currentItem) => item == currentItem);
this._deleteTime = true;
});
}), }),
] ]
), ),
@ -241,23 +265,26 @@ class _ListProviderScreen extends StatelessWidget {
const _ListProviderScreen(this.providers); const _ListProviderScreen(this.providers);
Widget _providerItem(int id, String name, String address, bool isDefault, ColorScheme color, AppLocalizations lang) { Widget _providerItem(ProviderServer provider, ColorScheme color, AppLocalizations lang, context) {
return Container( return Container(
margin: const EdgeInsets.only(bottom: 10.0), margin: const EdgeInsets.only(bottom: 10.0),
decoration: BoxDecoration(color: color.surface), decoration: BoxDecoration(color: color.surface),
child: ListTile( child: ListTile(
contentPadding: EdgeInsets.symmetric(vertical: 4.0), contentPadding: EdgeInsets.symmetric(vertical: 4.0),
leading: Tooltip( leading: Tooltip(
message: 'set default ?', message: lang.domainSetDefault,
child: TextButton( child: TextButton(
child: Icon(Icons.check_circle, color: isDefault ? Color(0xFF6174FF) : Colors.grey), child: Icon(Icons.check_circle, color: provider.isDefault ? Color(0xFF6174FF) : Colors.grey),
onPressed: () {} onPressed: () {
rpc.send('domain-provider-default', [provider.id]);
rpc.send('domain-list', []);
}
), ),
), ),
title: Text(name, style: TextStyle(fontWeight: FontWeight.bold)), title: Text(provider.name, style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Row( subtitle: Row(
children: <Widget>[ children: <Widget>[
Expanded(child: Text(address, style: TextStyle(fontSize: 14.0))), Expanded(child: Text(addrPrint(provider.addr), style: TextStyle(fontSize: 14.0))),
], ],
), ),
trailing: Container( trailing: Container(
@ -265,8 +292,29 @@ class _ListProviderScreen extends StatelessWidget {
decoration: new BoxDecoration( decoration: new BoxDecoration(
border: new Border(left: const BorderSide(width: 1.0, color: Color(0xA0ADB0BB)))), border: new Border(left: const BorderSide(width: 1.0, color: Color(0xA0ADB0BB)))),
child: TextButton( child: TextButton(
child: Icon(Icons.delete, color: Colors.red), child: Icon(Icons.delete, color: provider.deletable ? Colors.red : Colors.grey),
onPressed: () {} onPressed: provider.deletable ? () => 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('domain-provider-remove', [provider.id]);
rpc.send('domain-list', []);
},
),
]
);
},
) : null
)), )),
) )
); );
@ -279,7 +327,7 @@ class _ListProviderScreen extends StatelessWidget {
return Column( return Column(
children: this.providers.values.map( children: this.providers.values.map(
(provider) => _providerItem(provider.id, provider.name, addrPrint(provider.addr), provider.isDefault, color, lang) (provider) => _providerItem(provider, color, lang, context)
).toList(), ).toList(),
); );
} }

5
lib/l10n/localizations.dart

@ -217,6 +217,11 @@ abstract class AppLocalizations {
String get domainAddProvider; String get domainAddProvider;
String get domainSearch; String get domainSearch;
String get domainRegisterFailure; String get domainRegisterFailure;
String get domainSetDefault;
String get domainSetUnactived;
String get domainSetActived;
String get domainDelete;
String get domainNotDelete;
String get cloud; String get cloud;
String get cloudIntro; String get cloudIntro;

11
lib/l10n/localizations_en.dart

@ -339,6 +339,17 @@ class AppLocalizationsEn extends AppLocalizations {
String get domainSearch => 'Public ID Search'; String get domainSearch => 'Public ID Search';
@override @override
String get domainRegisterFailure => 'username already existed!'; String get domainRegisterFailure => 'username already existed!';
@override
String get domainSetDefault => 'Set default ?';
@override
String get domainSetUnactived => 'Set to unactived ?';
@override
String get domainSetActived => 'Set to actived ?';
@override
String get domainDelete => 'Delete from provider ?';
@override
String get domainNotDelete => 'Had ID, cannot delete';
@override @override
String get cloud => 'Cloud Peer'; String get cloud => 'Cloud Peer';
@override @override

11
lib/l10n/localizations_zh.dart

@ -339,6 +339,17 @@ class AppLocalizationsZh extends AppLocalizations {
String get domainSearch => '个人ID搜索'; String get domainSearch => '个人ID搜索';
@override @override
String get domainRegisterFailure => '用户名已存在!'; String get domainRegisterFailure => '用户名已存在!';
@override
String get domainSetDefault => '设为默认?';
@override
String get domainSetUnactived => '设为暂停状态?';
@override
String get domainSetActived => '设为正常状态?';
@override
String get domainDelete => '从站点中删除?';
@override
String get domainNotDelete => '有注册ID,无法删除';
@override @override
String get cloud => '云节点'; String get cloud => '云节点';
@override @override

20
src/apps/domain/layer.rs

@ -51,7 +51,7 @@ pub(crate) async fn handle(
user.is_actived = true; user.is_actived = true;
results.rpcs.push(rpc::register_success(ogid, &user)); results.rpcs.push(rpc::register_success(ogid, &user));
} else { } else {
Name::delete(&db, &user.id)?; user.delete(&db)?;
results.rpcs.push(rpc::register_failure(ogid, &name)); results.rpcs.push(rpc::register_failure(ogid, &name));
} }
} }
@ -63,6 +63,24 @@ pub(crate) async fn handle(
ServerEvent::None(uname) => { ServerEvent::None(uname) => {
results.rpcs.push(rpc::search_none(ogid, &uname)); results.rpcs.push(rpc::search_none(ogid, &uname));
} }
ServerEvent::Actived(uname, is_actived) => {
let provider = Provider::get_by_addr(&db, &addr)?;
let name = Name::get_by_name_provider(&db, &uname, &provider.id)?;
Name::active(&db, &name.id, is_actived)?;
let ps = Provider::list(&db)?;
let names = Name::list(&db)?;
results.rpcs.push(rpc::domain_list(ogid, &ps, &names));
}
ServerEvent::Deleted(uname) => {
let provider = Provider::get_by_addr(&db, &addr)?;
let name = Name::get_by_name_provider(&db, &uname, &provider.id)?;
name.delete(&db)?;
let ps = Provider::list(&db)?;
let names = Name::list(&db)?;
results.rpcs.push(rpc::domain_list(ogid, &ps, &names));
}
ServerEvent::Response(_ugid, _uname, _is_ok) => {} ServerEvent::Response(_ugid, _uname, _is_ok) => {}
} }
} }

46
src/apps/domain/models.rs

@ -11,7 +11,7 @@ pub(crate) struct Provider {
/// name. /// name.
name: String, name: String,
/// address. /// address.
addr: PeerAddr, pub addr: PeerAddr,
/// is add ok. /// is add ok.
is_ok: bool, is_ok: bool,
/// is default. /// is default.
@ -85,6 +85,16 @@ impl Provider {
Err(anyhow!("provider is missing")) Err(anyhow!("provider is missing"))
} }
/// use in rpc when load provider by id.
pub fn get_default(db: &DStorage) -> Result<Self> {
let mut matrix = db.query("SELECT id, name, addr, is_ok, is_default, is_proxy, is_actived FROM providers WHERE is_default = true")?;
if matrix.len() > 0 {
let values = matrix.pop().unwrap(); // safe unwrap()
return Ok(Self::from_values(values));
}
Err(anyhow!("provider is missing"))
}
/// insert a new provider. /// insert a new provider.
pub fn get_by_addr(db: &DStorage, addr: &PeerAddr) -> Result<Self> { pub fn get_by_addr(db: &DStorage, addr: &PeerAddr) -> Result<Self> {
let sql = format!( let sql = format!(
@ -148,6 +158,16 @@ impl Provider {
Ok(()) Ok(())
} }
/// return if is closed
pub fn default(&self, db: &DStorage, default: bool) -> Result<()> {
let sql = format!(
"UPDATE providers SET is_default = {} WHERE id = {}",
default, self.id
);
db.update(&sql)?;
Ok(())
}
/// return if is closed /// return if is closed
pub fn delete(db: &DStorage, id: &i64) -> Result<()> { pub fn delete(db: &DStorage, id: &i64) -> Result<()> {
let sql = format!("UPDATE providers SET is_actived = false WHERE id = {}", id); let sql = format!("UPDATE providers SET is_actived = false WHERE id = {}", id);
@ -161,7 +181,7 @@ pub(crate) struct Name {
/// db auto-increment id. /// db auto-increment id.
pub id: i64, pub id: i64,
/// provider database id. /// provider database id.
provider: i64, pub provider: i64,
/// name. /// name.
pub name: String, pub name: String,
/// bio. /// bio.
@ -218,18 +238,18 @@ impl Name {
Ok(names) Ok(names)
} }
/// use in rpc when load provider by id. /// get name register.
pub fn get(db: &DStorage, id: &i64) -> Result<Self> { pub fn get_by_provider(db: &DStorage, provider: &i64) -> Result<Vec<Self>> {
let sql = format!( let sql = format!(
"SELECT id, provider, name, bio, is_ok, is_actived FROM names WHERE id = {}", "SELECT id, provider, name, bio, is_ok, is_actived FROM names WHERE provider = {}",
id provider
); );
let mut matrix = db.query(&sql)?; let matrix = db.query(&sql)?;
if matrix.len() > 0 { let mut names = vec![];
let values = matrix.pop().unwrap(); // safe unwrap() for values in matrix {
return Ok(Self::from_values(values)); names.push(Self::from_values(values));
} }
Err(anyhow!("name is missing")) Ok(names)
} }
/// get name register. /// get name register.
@ -275,8 +295,8 @@ impl Name {
} }
/// delete the name. /// delete the name.
pub fn delete(db: &DStorage, id: &i64) -> Result<()> { pub fn delete(&self, db: &DStorage) -> Result<()> {
let sql = format!("DELETE names WHERE id = {}", id); let sql = format!("DELETE names WHERE id = {}", self.id);
db.delete(&sql)?; db.delete(&sql)?;
Ok(()) Ok(())
} }

62
src/apps/domain/rpc.rs

@ -28,6 +28,13 @@ pub(crate) fn register_failure(mgid: GroupId, name: &str) -> RpcParam {
rpc_response(0, "domain-register-failure", json!([name]), mgid) rpc_response(0, "domain-register-failure", json!([name]), mgid)
} }
#[inline]
pub(crate) fn domain_list(mgid: GroupId, providers: &[Provider], names: &[Name]) -> RpcParam {
let providers: Vec<RpcParam> = providers.iter().map(|p| p.to_rpc()).collect();
let names: Vec<RpcParam> = names.iter().map(|p| p.to_rpc()).collect();
rpc_response(0, "domain-list", json!([providers, names]), mgid)
}
#[inline] #[inline]
pub(crate) fn search_result( pub(crate) fn search_result(
mgid: GroupId, mgid: GroupId,
@ -94,19 +101,35 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
handler.add_method( handler.add_method(
"domain-provider-default", "domain-provider-default",
|_gid: GroupId, params: Vec<RpcParam>, _state: Arc<RpcState>| async move { |gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let _id = params[0].as_i64().ok_or(RpcError::ParseError)?; let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let db = domain_db(state.layer.read().await.base(), &gid)?;
let provider = Provider::get(&db, &id)?;
if let Ok(default) = Provider::get_default(&db) {
if default.id == provider.id {
return Ok(HandleResult::new());
}
default.default(&db, false)?;
}
provider.default(&db, true)?;
Ok(HandleResult::rpc(json!(params))) Ok(HandleResult::new())
}, },
); );
handler.add_method( handler.add_method(
"domain-provider-remove", "domain-provider-remove",
|_gid: GroupId, params: Vec<RpcParam>, _state: Arc<RpcState>| async move { |gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let _id = params[0].as_i64().ok_or(RpcError::ParseError)?; let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let db = domain_db(state.layer.read().await.base(), &gid)?;
let names = Name::get_by_provider(&db, &id)?;
if names.len() == 0 {
Provider::delete(&db, &id)?;
}
Ok(HandleResult::rpc(json!(params))) Ok(HandleResult::new())
}, },
); );
@ -135,19 +158,34 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
handler.add_method( handler.add_method(
"domain-active", "domain-active",
|_gid: GroupId, params: Vec<RpcParam>, _state: Arc<RpcState>| async move { |gid: GroupId, params: Vec<RpcParam>, _state: Arc<RpcState>| async move {
let _id = params[0].as_i64().ok_or(RpcError::ParseError)?; let name = params[0].as_str().ok_or(RpcError::ParseError)?.to_owned();
let provider = PeerAddr::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
let active = params[2].as_bool().ok_or(RpcError::ParseError)?;
let mut results = HandleResult::new();
let event = if active {
PeerEvent::Active(name)
} else {
PeerEvent::Suspend(name)
};
add_layer(&mut results, provider, event, gid)?;
Ok(HandleResult::rpc(json!(params))) Ok(results)
}, },
); );
handler.add_method( handler.add_method(
"domain-remove", "domain-remove",
|_gid: GroupId, params: Vec<RpcParam>, _state: Arc<RpcState>| async move { |gid: GroupId, params: Vec<RpcParam>, _state: Arc<RpcState>| async move {
let _id = params[0].as_i64().ok_or(RpcError::ParseError)?; let name = params[0].as_str().ok_or(RpcError::ParseError)?.to_owned();
let provider = PeerAddr::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?;
Ok(HandleResult::rpc(json!(params))) let mut results = HandleResult::new();
let event = PeerEvent::Delete(name);
add_layer(&mut results, provider, event, gid)?;
Ok(results)
}, },
); );

Loading…
Cancel
Save