From 51c7b03ff833a2f34d9ae22f327e8aa080f3f2e4 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 29 Nov 2024 23:48:39 +0800 Subject: [PATCH] :sparkles: Editable channel profile --- assets/translations/en.json | 3 + assets/translations/zh.json | 3 + lib/screens/chat/channel_detail.dart | 94 +++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/assets/translations/en.json b/assets/translations/en.json index ec67311..4f0343b 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -177,12 +177,15 @@ "channelEditProfile": "Edit Channel Profile", "channelEdit": "Edit Channel", "channelEditDescription": "Change the basic information of the channel, metadata, etc.", + "channelProfileEdit": "Edit Channel Profile", "channelActionDelete": "Delete Channel", "channelActionDeleteDescription": "Delete the entire channel, and also delete messages in the channel.", "channelLeave": "Leave Channel {}", "channelLeaveDescription": "Leave this channel, but the messages in the channel will not be removed.", "channelActionLeave": "Leave Channel", "channelActionLeaveDescription": "Delete your profile in this channel.", + "fieldChannelProfileNick": "In-Channel Display Name", + "fieldChannelProfileNickHint": "The nickname to display in the channel, leave blank to use the account display name.", "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 253c2b2..b8663c8 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -177,12 +177,15 @@ "channelEditProfile": "更改频道身份", "channelEdit": "编辑频道", "channelEditDescription": "更改频道基本信息,元数据等。", + "channelProfileEdit": "编辑频道身份", "channelActionDelete": "删除频道", "channelActionDeleteDescription": "删除整个频道,并且删除频道里的所有信息。", "channelLeave": "退出频道 {}", "channelLeaveDescription": "退出该频道,但是你频道内的信息不会被移除。", "channelActionLeave": "退出频道", "channelActionLeaveDescription": "删除你在这个频道的身份。", + "fieldChannelProfileNick": "频道内显示名", + "fieldChannelProfileNickHint": "在频道内显示的昵称,留空则使用账号显示名。", "fieldRealmAlias": "领域别名", "fieldRealmAliasHint": "全站范围内唯一的领域别名,用于在 URL 中表示该领域,留空则自动生成。应遵循 URL-Safe 的原则。", "fieldRealmName": "名称", diff --git a/lib/screens/chat/channel_detail.dart b/lib/screens/chat/channel_detail.dart index 78fa82c..ed7f876 100644 --- a/lib/screens/chat/channel_detail.dart +++ b/lib/screens/chat/channel_detail.dart @@ -108,6 +108,20 @@ class _ChannelDetailScreenState extends State { } } + void _showChannelProfileDetail() { + showDialog( + context: context, + builder: (context) => _ChannelProfileDetailDialog( + channel: _channel!, + current: _profile!, + ), + ).then((value) { + if (value != null && mounted) { + Navigator.pop(context, true); + } + }); + } + @override void initState() { super.initState(); @@ -160,7 +174,6 @@ class _ChannelDetailScreenState extends State { .tr() .padding(horizontal: 20, bottom: 4), // TODO add notify level modifier - // TODO impl this ListTile( leading: AccountImage( content: @@ -175,7 +188,7 @@ class _ChannelDetailScreenState extends State { : _profile!.nick!, ), contentPadding: const EdgeInsets.only(left: 20, right: 20), - onTap: () {}, + onTap: _showChannelProfileDetail, ), if (!isOwned) ListTile( @@ -231,3 +244,80 @@ class _ChannelDetailScreenState extends State { ); } } + +class _ChannelProfileDetailDialog extends StatefulWidget { + final SnChannel channel; + final SnChannelMember current; + const _ChannelProfileDetailDialog({ + required this.channel, + required this.current, + }); + + @override + State<_ChannelProfileDetailDialog> createState() => + _ChannelProfileDetailDialogState(); +} + +class _ChannelProfileDetailDialogState + extends State<_ChannelProfileDetailDialog> { + bool _isBusy = false; + + final TextEditingController _nickController = TextEditingController(); + + Future _updateProfile() async { + setState(() => _isBusy = true); + + try { + final sn = context.read(); + await sn.client.put( + '/cgi/im/channels/${widget.channel.keyPath}/members/me', + data: {'nick': _nickController.text}, + ); + if (!mounted) return; + Navigator.pop(context, true); + } catch (err) { + if (!mounted) return; + context.showErrorDialog(err); + } finally { + setState(() => _isBusy = false); + } + } + + @override + void initState() { + super.initState(); + _nickController.text = widget.current.nick ?? ''; + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: Text('channelProfileEdit').tr(), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + controller: _nickController, + decoration: InputDecoration( + labelText: 'fieldChannelProfileNick'.tr(), + helperText: 'fieldChannelProfileNickHint'.tr(), + helperMaxLines: 2, + ), + onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), + ), + ], + ), + actions: [ + TextButton( + onPressed: _isBusy ? null : () => Navigator.pop(context), + child: Text('dialogCancel').tr(), + ), + TextButton( + onPressed: _isBusy ? null : _updateProfile, + child: Text('apply').tr(), + ), + ], + ); + } +}