From 041be961c46e5df3011263bacd81fb320eafb361 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 28 Nov 2024 23:51:13 +0800 Subject: [PATCH] :sparkles: Delete account --- assets/translations/en.json | 2 + assets/translations/zh.json | 2 + lib/screens/chat.dart | 73 ++++++++++++++++------------ lib/screens/chat/channel_detail.dart | 34 ++++++++++++- lib/screens/chat/room.dart | 4 +- 5 files changed, 81 insertions(+), 34 deletions(-) diff --git a/assets/translations/en.json b/assets/translations/en.json index f618f70..007337f 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -177,6 +177,8 @@ "channelEditProfile": "Edit Channel Profile", "channelEdit": "Edit Channel", "channelEditDescription": "Change the basic information of the channel, metadata, etc.", + "channelActionDelete": "Delete Channel", + "channelActionDeleteDescription": "Delete the entire channel, and also delete messages in the channel.", "fieldRealmAlias": "Realm Alias", "fieldRealmAliasHint": "The unique realm alias within the site, used to represent the realm in URL, leave blank to auto generate. Should be URL-Safe.", "fieldRealmName": "Name", diff --git a/assets/translations/zh.json b/assets/translations/zh.json index 01ad3c0..73b639f 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -177,6 +177,8 @@ "channelEditProfile": "更改频道身份", "channelEdit": "编辑频道", "channelEditDescription": "更改频道基本信息,元数据等。", + "channelActionDelete": "删除频道", + "channelActionDeleteDescription": "删除整个频道,并且删除频道里的所有信息。", "fieldRealmAlias": "领域别名", "fieldRealmAliasHint": "全站范围内唯一的领域别名,用于在 URL 中表示该领域,留空则自动生成。应遵循 URL-Safe 的原则。", "fieldRealmName": "名称", diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart index 0c2d846..a42e593 100644 --- a/lib/screens/chat.dart +++ b/lib/screens/chat.dart @@ -21,9 +21,7 @@ class _ChatScreenState extends State { List? _channels; - @override - void initState() { - super.initState(); + void _refreshChannels() { final chan = context.read(); chan.fetchChannels().listen((channels) { if (mounted) setState(() => _channels = channels); @@ -39,6 +37,12 @@ class _ChatScreenState extends State { }); } + @override + void initState() { + super.initState(); + _refreshChannels(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -48,40 +52,47 @@ class _ChatScreenState extends State { floatingActionButton: FloatingActionButton( child: const Icon(Symbols.chat_add_on), onPressed: () { - GoRouter.of(context).pushNamed('chatManage'); + GoRouter.of(context).pushNamed('chatManage').then((value) { + if (value != null && context.mounted) _refreshChannels(); + }); }, ), body: Column( children: [ LoadingIndicator(isActive: _isBusy), Expanded( - child: ListView.builder( - itemCount: _channels?.length ?? 0, - itemBuilder: (context, idx) { - final channel = _channels![idx]; - return ListTile( - title: Text(channel.name), - subtitle: Text( - channel.description, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - contentPadding: const EdgeInsets.symmetric(horizontal: 16), - leading: AccountImage( - content: null, - fallbackWidget: const Icon(Symbols.chat, size: 20), - ), - onTap: () { - GoRouter.of(context).pushNamed( - 'chatRoom', - pathParameters: { - 'scope': channel.realm?.alias ?? 'global', - 'alias': channel.alias, - }, - ); - }, - ); - }, + child: RefreshIndicator( + onRefresh: () => Future.sync(() => _refreshChannels()), + child: ListView.builder( + itemCount: _channels?.length ?? 0, + itemBuilder: (context, idx) { + final channel = _channels![idx]; + return ListTile( + title: Text(channel.name), + subtitle: Text( + channel.description, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 16), + leading: AccountImage( + content: null, + fallbackWidget: const Icon(Symbols.chat, size: 20), + ), + onTap: () { + GoRouter.of(context).pushNamed( + 'chatRoom', + pathParameters: { + 'scope': channel.realm?.alias ?? 'global', + 'alias': channel.alias, + }, + ).then((value) { + if (value == true) _refreshChannels(); + }); + }, + ); + }, + ), ), ), ], diff --git a/lib/screens/chat/channel_detail.dart b/lib/screens/chat/channel_detail.dart index d4ef6c0..69aed08 100644 --- a/lib/screens/chat/channel_detail.dart +++ b/lib/screens/chat/channel_detail.dart @@ -65,6 +65,27 @@ class _ChannelDetailScreenState extends State { } } + Future _deleteChannel() async { + final confirm = await context.showConfirmDialog( + 'channelDelete'.tr(args: [_channel!.name]), + 'channelDeleteDescription'.tr(), + ); + if (!confirm) return; + if (!mounted) return; + + try { + final sn = context.read(); + await sn.client.delete( + '/cgi/im/channels/${_channel!.realm?.alias ?? 'global'}/${_channel!.id}', + ); + if (!mounted) return; + Navigator.pop(context, false); + } catch (err) { + if (!mounted) return; + context.showErrorDialog(err); + } + } + @override void initState() { super.initState(); @@ -119,8 +140,9 @@ class _ChannelDetailScreenState extends State { trailing: const Icon(Symbols.chevron_right), title: Text('channelEditProfile').tr(), subtitle: Text( - _profile?.nick ?? - ud.getAccountFromCache(_profile!.accountId)!.nick, + (_profile?.nick?.isEmpty ?? true) + ? ud.getAccountFromCache(_profile!.accountId)!.nick + : _profile!.nick!, ), contentPadding: const EdgeInsets.only(left: 20, right: 20), onTap: () {}, @@ -152,6 +174,14 @@ class _ChannelDetailScreenState extends State { }); }, ), + ListTile( + leading: const Icon(Symbols.delete), + trailing: const Icon(Symbols.chevron_right), + title: Text('channelActionDelete').tr(), + subtitle: Text('channelActionDeleteDescription').tr(), + contentPadding: const EdgeInsets.symmetric(horizontal: 24), + onTap: _deleteChannel, + ), ], ), ], diff --git a/lib/screens/chat/room.dart b/lib/screens/chat/room.dart index 5ffd7e7..0b014e6 100644 --- a/lib/screens/chat/room.dart +++ b/lib/screens/chat/room.dart @@ -205,7 +205,9 @@ class _ChatRoomScreenState extends State { 'scope': widget.scope, 'alias': widget.alias, }).then((value) { - if (value != null) { + if (value == false && context.mounted) { + Navigator.pop(context, true); + } else if (value != null && context.mounted) { _fetchChannel(); } });