From a2a42f66a2a63d83be947bd89217968d0168b07d Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 30 Nov 2024 00:04:20 +0800 Subject: [PATCH] :sparkles: Editable channel notify level --- assets/translations/en.json | 6 +++ assets/translations/zh.json | 6 +++ lib/screens/chat/channel_detail.dart | 70 +++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/assets/translations/en.json b/assets/translations/en.json index 4f0343b..dc85760 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -184,6 +184,12 @@ "channelLeaveDescription": "Leave this channel, but the messages in the channel will not be removed.", "channelActionLeave": "Leave Channel", "channelActionLeaveDescription": "Delete your profile in this channel.", + "channelNotifyLevel": "Notify Level", + "channelNotifyLevelDescription": "Decide to receive how much notifications from this channel.", + "channelNotifyLevelAll": "All", + "channelNotifyLevelMentioned": "Only Mentioned", + "channelNotifyLevelNone": "Muted", + "channelNotifyLevelApplied": "Channel notify level has been applied.", "fieldChannelProfileNick": "In-Channel Display Name", "fieldChannelProfileNickHint": "The nickname to display in the channel, leave blank to use the account display name.", "fieldRealmAlias": "Realm Alias", diff --git a/assets/translations/zh.json b/assets/translations/zh.json index b8663c8..a01b4dd 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -184,6 +184,12 @@ "channelLeaveDescription": "退出该频道,但是你频道内的信息不会被移除。", "channelActionLeave": "退出频道", "channelActionLeaveDescription": "删除你在这个频道的身份。", + "channelNotifyLevel": "通知级别", + "channelNotifyLevelDescription": "有您决定要接受多少来自这个频道的消息。", + "channelNotifyLevelAll": "全部通知", + "channelNotifyLevelMentioned": "仅提及", + "channelNotifyLevelNone": "全部静音", + "channelNotifyLevelApplied": "已经保存并应用频道通知级别配置。", "fieldChannelProfileNick": "频道内显示名", "fieldChannelProfileNickHint": "在频道内显示的昵称,留空则使用账号显示名。", "fieldRealmAlias": "领域别名", diff --git a/lib/screens/chat/channel_detail.dart b/lib/screens/chat/channel_detail.dart index ed7f876..87ea2cd 100644 --- a/lib/screens/chat/channel_detail.dart +++ b/lib/screens/chat/channel_detail.dart @@ -1,3 +1,4 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; @@ -55,6 +56,7 @@ class _ChannelDetailScreenState extends State { final resp = await sn.client .get('/cgi/im/channels/${_channel!.keyPath}/members/me'); _profile = SnChannelMember.fromJson(resp.data); + _notifyLevel = _profile!.notify; if (!mounted) return; final ud = context.read(); await ud.getAccount(_profile!.accountId); @@ -108,6 +110,37 @@ class _ChannelDetailScreenState extends State { } } + int _notifyLevel = 0; + bool _isUpdatingNotifyLevel = false; + + final kNotifyLevels = { + 0: 'channelNotifyLevelAll'.tr(), + 1: 'channelNotifyLevelMentioned'.tr(), + 2: 'channelNotifyLevelNone'.tr(), + }; + + Future _updateNotifyLevel(int value) async { + if (_isUpdatingNotifyLevel) return; + + setState(() => _isUpdatingNotifyLevel = true); + + try { + final sn = context.read(); + await sn.client.put( + '/cgi/im/channels/${_channel!.keyPath}/members/me/notify', + data: {'notify_level': value}, + ); + _notifyLevel = value; + if (!mounted) return; + context.showSnackbar('channelNotifyLevelApplied'.tr()); + } catch (err) { + if (!mounted) return; + context.showErrorDialog(err); + } finally { + setState(() => _isUpdatingNotifyLevel = false); + } + } + void _showChannelProfileDetail() { showDialog( context: context, @@ -173,7 +206,42 @@ class _ChannelDetailScreenState extends State { .fontSize(17) .tr() .padding(horizontal: 20, bottom: 4), - // TODO add notify level modifier + ListTile( + leading: const Icon(Symbols.notifications), + trailing: DropdownButtonHideUnderline( + child: DropdownButton2( + isExpanded: true, + items: kNotifyLevels.entries + .map((item) => DropdownMenuItem( + enabled: !_isUpdatingNotifyLevel, + value: item.key, + child: Text( + item.value, + style: const TextStyle( + fontSize: 14, + ), + ), + )) + .toList(), + value: _notifyLevel, + onChanged: (int? value) { + if (value == null) return; + _updateNotifyLevel(value); + }, + buttonStyleData: const ButtonStyleData( + padding: EdgeInsets.only(left: 16, right: 1), + height: 40, + width: 140, + ), + menuItemStyleData: const MenuItemStyleData( + height: 40, + ), + ), + ), + title: Text('channelNotifyLevel').tr(), + subtitle: Text('channelNotifyLevelDescription').tr(), + contentPadding: const EdgeInsets.only(left: 24, right: 20), + ), ListTile( leading: AccountImage( content: