Browse Source

Group: change name & delete

pull/18/head
Sun 4 years ago
parent
commit
7558237f31
  1. 4
      lib/apps/chat/detail.dart
  2. 88
      lib/apps/group/detail.dart
  3. 5
      lib/provider.dart
  4. 3
      src/apps/group/layer.rs
  5. 73
      src/apps/group/rpc.rs

4
lib/apps/chat/detail.dart

@ -227,7 +227,9 @@ class _ChatDetailState extends State<ChatDetail> { @@ -227,7 +227,9 @@ class _ChatDetailState extends State<ChatDetail> {
onPressed: () {
Navigator.pop(context);
rpc.send('chat-friend-delete', [_friend.id]);
if (!isDesktop) {
if (isDesktop) {
context.read<AccountProvider>().updateActivedWidget(null);
} else {
Navigator.pop(context);
}
},

88
lib/apps/group/detail.dart

@ -4,6 +4,8 @@ import 'package:provider/provider.dart'; @@ -4,6 +4,8 @@ import 'package:provider/provider.dart';
import 'package:esse/utils/adaptive.dart';
import 'package:esse/l10n/localizations.dart';
import 'package:esse/widgets/avatar.dart';
import 'package:esse/widgets/button_text.dart';
import 'package:esse/widgets/input_text.dart';
import 'package:esse/widgets/shadow_dialog.dart';
import 'package:esse/widgets/user_info.dart';
import 'package:esse/widgets/chat_message.dart';
@ -42,6 +44,7 @@ class _GroupChatDetailState extends State<GroupChatDetail> { @@ -42,6 +44,7 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
rpc.addListener('group-member-offline', _memberOffline);
rpc.addListener('group-message-create', _messageCreate);
rpc.addListener('group-message-delivery', _messageDelivery);
rpc.addListener('group-name', _groupName);
}
// [group, [member], [message]]
@ -120,6 +123,15 @@ class _GroupChatDetailState extends State<GroupChatDetail> { @@ -120,6 +123,15 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
}
}
// [group_id, name]
_groupName(List params) {
final id = params[0];
if (this._group.id == id) {
this._group.name = params[1];
setState(() {});
}
}
_send(MessageType mtype, String raw) {
rpc.send('group-message-create', [_group.id, mtype.toInt(), raw]);
}
@ -195,14 +207,45 @@ class _GroupChatDetailState extends State<GroupChatDetail> { @@ -195,14 +207,45 @@ class _GroupChatDetailState extends State<GroupChatDetail> {
onSelected: (int value) {
if (value == 0) {
} else if (value == 1) {
showShadowDialog(context, Icons.create, lang.rename,
_ChangeNameScreen(_group.id, _group.name), 0.0
);
} else if (value == 2) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(lang.delete),
content: Text(_group.name,
style: TextStyle(color: color.primary)),
actions: [
TextButton(
child: Text(lang.cancel),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text(lang.ok),
onPressed: () {
Navigator.pop(context);
rpc.send('group-delete', [this._group.id]);
if (reallyDesktop) {
context.read<AccountProvider>().updateActivedWidget(null);
} else {
Navigator.pop(context);
}
},
),
]
);
},
);
}
},
itemBuilder: (context) {
return <PopupMenuEntry<int>>[
menuItem(Color(0xFF6174FF), 0, Icons.add_rounded, lang.addFriend),
menuItem(Color(0xFF6174FF), 0, Icons.create_rounded, lang.rename),
menuItem(Colors.red, 6, Icons.delete_rounded, lang.delete),
menuItem(Color(0xFF6174FF), 1, Icons.create_rounded, lang.rename),
menuItem(Colors.red, 2, Icons.delete_rounded, lang.delete),
];
},
)
@ -303,3 +346,44 @@ class _MemberScreenState extends State<_MemberScreen> { @@ -303,3 +346,44 @@ class _MemberScreenState extends State<_MemberScreen> {
));
}
}
class _ChangeNameScreen extends StatelessWidget {
final TextEditingController _nameController = TextEditingController();
final FocusNode _nameFocus = FocusNode();
int id = 0;
_ChangeNameScreen(id, name) {
this.id = id;
this._nameController.text = name;
}
@override
Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme;
final lang = AppLocalizations.of(context);
_nameFocus.requestFocus();
return Column(
children: [
Container(
padding: const EdgeInsets.only(bottom: 20.0, top: 10.0),
child: InputText(
icon: Icons.account_circle,
text: lang.groupChatName,
controller: _nameController,
focus: _nameFocus),
),
ButtonText(
text: lang.send,
action: () {
final name = _nameController.text.trim();
if (name.length < 1) {
return;
}
rpc.send('group-name', [this.id, name]);
Navigator.pop(context);
}),
]
);
}
}

5
lib/provider.dart

@ -229,8 +229,11 @@ class AccountProvider extends ChangeNotifier { @@ -229,8 +229,11 @@ class AccountProvider extends ChangeNotifier {
if (coreWidget != null) {
print("update actived widget");
this.coreShowWidget = coreWidget;
notifyListeners();
} else {
this.actived = 0;
this.coreShowWidget = DefaultCoreShow();
}
notifyListeners();
}
// -- callback when receive rpc info. -- //

3
src/apps/group/layer.rs

@ -180,6 +180,7 @@ fn handle_connect( @@ -180,6 +180,7 @@ fn handle_connect(
}
let _ = GroupChat::update_name(&db, &group.id, &gname);
results.rpcs.push(rpc::group_name(ogid, &group.id, &gname));
// 1.1 get session.
let session_some = connect_session(
@ -254,6 +255,7 @@ async fn handle_server_event( @@ -254,6 +255,7 @@ async fn handle_server_event(
}
LayerEvent::GroupName(_gcd, name) => {
let _ = GroupChat::update_name(&db, &id, &name)?;
results.rpcs.push(rpc::group_name(ogid, &id, &name));
if let Ok(sid) = Session::update_name_by_id(
&session_db(&base, &ogid)?,
&id,
@ -432,6 +434,7 @@ async fn handle_peer_event( @@ -432,6 +434,7 @@ async fn handle_peer_event(
}
LayerEvent::GroupName(_gcd, name) => {
let _ = GroupChat::update_name(&db, &id, &name)?;
results.rpcs.push(rpc::group_name(ogid, &id, &name));
let _ = Session::update_name(&session_db(&base, &ogid)?, &sid, &name);
results.rpcs.push(session_update_name(ogid, &sid, &name));
}

73
src/apps/group/rpc.rs

@ -11,7 +11,7 @@ use group_types::{Event, LayerEvent}; @@ -11,7 +11,7 @@ use group_types::{Event, LayerEvent};
use crate::apps::chat::{Friend, InviteType};
use crate::layer::Online;
use crate::rpc::{session_create, session_delete, RpcState};
use crate::rpc::{session_create, session_delete, session_update_name, RpcState};
use crate::session::{Session, SessionType};
use crate::storage::{chat_db, group_db, read_avatar, session_db, write_avatar};
@ -44,6 +44,11 @@ pub(crate) fn member_offline(mgid: GroupId, gid: i64, mid: i64) -> RpcParam { @@ -44,6 +44,11 @@ pub(crate) fn member_offline(mgid: GroupId, gid: i64, mid: i64) -> RpcParam {
rpc_response(0, "group-member-offline", json!([gid, mid]), mgid)
}
#[inline]
pub(crate) fn group_name(mgid: GroupId, gid: &i64, name: &str) -> RpcParam {
rpc_response(0, "group-name", json!([gid, name]), mgid)
}
#[inline]
pub(crate) fn message_create(mgid: GroupId, msg: &Message) -> RpcParam {
rpc_response(0, "group-message-create", json!(msg.to_rpc()), mgid)
@ -75,10 +80,6 @@ fn detail_list(group: GroupChat, members: Vec<Member>, messages: Vec<Message>) - @@ -75,10 +80,6 @@ fn detail_list(group: GroupChat, members: Vec<Member>, messages: Vec<Message>) -
}
pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
handler.add_method("group-echo", |_, params, _| async move {
Ok(HandleResult::rpc(json!(params)))
});
handler.add_method(
"group-list",
|gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
@ -278,37 +279,67 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) { @@ -278,37 +279,67 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
);
handler.add_method(
"group-delete",
"group-name",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let gcd = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?;
let id = params[1].as_i64().ok_or(RpcError::ParseError)?;
let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let name = params[1].as_str().ok_or(RpcError::ParseError)?;
let addr = state
.layer
.write()
.await
.remove_online(&gid, &gcd)
.ok_or(RpcError::ParseError)?;
let mut results = HandleResult::new();
let base = state.layer.read().await.base().clone();
let db = group_db(&base, &gid)?;
let g = GroupChat::get(&db, &id)?;
let d = bincode::serialize(&LayerEvent::GroupName(g.g_id, name.to_owned()))?;
if let Ok(sid) = Session::update_name_by_id(
&session_db(&base, &gid)?,
&id,
&SessionType::Group,
&name,
) {
results.rpcs.push(session_update_name(gid, &sid, &name));
}
if g.local {
results.rpcs.push(json!([id, name]));
// dissolve group.
for (mgid, maddr) in state.layer.read().await.running(&g.g_id)?.onlines() {
let s = SendType::Event(0, *maddr, d.clone());
add_server_layer(&mut results, *mgid, s);
}
} else {
// leave group.
let msg = SendType::Event(0, g.g_addr, d);
add_layer(&mut results, gid, msg);
}
Ok(results)
},
);
handler.add_method(
"group-delete",
|gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let mut results = HandleResult::new();
let base = state.layer.read().await.base().clone();
let db = group_db(&base, &gid)?;
let group = GroupChat::delete(&db, &id)?;
let g = GroupChat::delete(&db, &id)?;
let sid = Session::delete(&session_db(&base, &gid)?, &id, &SessionType::Group)?;
results.rpcs.push(session_delete(gid, &sid));
if group.g_addr == addr {
if g.local {
// dissolve group.
let data = bincode::serialize(&LayerEvent::GroupClose(gcd))?;
for (mgid, maddr) in state.layer.read().await.running(&gcd)?.onlines() {
let s = SendType::Event(0, *maddr, data.clone());
let d = bincode::serialize(&LayerEvent::GroupClose(g.g_id))?;
for (mgid, maddr) in state.layer.read().await.running(&g.g_id)?.onlines() {
let s = SendType::Event(0, *maddr, d.clone());
add_server_layer(&mut results, *mgid, s);
}
} else {
// leave group.
let data = bincode::serialize(&LayerEvent::Sync(gcd, 0, Event::MemberLeave(gid)))?;
let msg = SendType::Event(0, addr, data);
let d = bincode::serialize(&LayerEvent::Sync(g.g_id, 0, Event::MemberLeave(gid)))?;
let msg = SendType::Event(0, g.g_addr, d);
add_layer(&mut results, gid, msg);
}

Loading…
Cancel
Save