diff --git a/lib/http/api.dart b/lib/http/api.dart index 18581e8e..dce369b8 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -831,4 +831,7 @@ class Api { static const String spaceOpus = '/x/polymer/web-dynamic/v1/opus/feed/space'; static const String articleList = '/x/article/list/web/articles'; + + static const String setMsgDnd = + '${HttpString.tUrl}/link_setting/v1/link_setting/set_msg_dnd'; } diff --git a/lib/http/msg.dart b/lib/http/msg.dart index 19b6c6c7..5eedfa19 100644 --- a/lib/http/msg.dart +++ b/lib/http/msg.dart @@ -581,4 +581,30 @@ class MsgHttp { return {'status': false, 'msg': res.data['message']}; } } + + static Future setMsgDnd({ + required uid, + required int setting, + required dndUid, + }) async { + final csrf = Accounts.main.csrf; + var res = await Request().post( + Api.setMsgDnd, + data: { + 'uid': uid, + 'setting': setting, + 'dnd_uid': dndUid, + 'build': 0, + 'mobi_app': 'web', + 'csrf_token': csrf, + 'csrf': csrf, + }, + options: Options(contentType: Headers.formUrlEncodedContentType), + ); + if (res.data['code'] == 0) { + return {'status': true}; + } else { + return {'status': false, 'msg': res.data['message']}; + } + } } diff --git a/lib/pages/common/common_whisper_controller.dart b/lib/pages/common/common_whisper_controller.dart index 7c61cca6..8755c708 100644 --- a/lib/pages/common/common_whisper_controller.dart +++ b/lib/pages/common/common_whisper_controller.dart @@ -4,6 +4,8 @@ import 'package:PiliPlus/grpc/im.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/msg.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart'; +import 'package:PiliPlus/utils/storage.dart'; +import 'package:fixnum/fixnum.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; abstract class CommonWhisperController @@ -40,6 +42,22 @@ abstract class CommonWhisperController } } + Future onSetMute(int index, bool isMuted, Int64 talkerUid) async { + var res = await MsgHttp.setMsgDnd( + uid: Accounts.main.mid, + setting: isMuted ? 0 : 1, + dndUid: talkerUid, + ); + if (res['status']) { + loadingState + ..value.data![index].isMuted = !isMuted + ..refresh(); + SmartDialog.showToast('操作成功'); + } else { + SmartDialog.showToast(res['msg']); + } + } + Future onClearUnread() async { final res = await ImGrpc.clearUnread(pageType: sessionPageType); if (res.isSuccess) { diff --git a/lib/pages/msg_feed_top/like_me/view.dart b/lib/pages/msg_feed_top/like_me/view.dart index 79207d0c..9a61e3ff 100644 --- a/lib/pages/msg_feed_top/like_me/view.dart +++ b/lib/pages/msg_feed_top/like_me/view.dart @@ -321,12 +321,14 @@ class _LikeMePageState extends State { height: 45, src: item.item!.image, ), - if (item.noticeState == 1) + if (item.noticeState == 1) ...[ + if (item.item?.image?.isNotEmpty == true) const SizedBox(width: 4), Icon( size: 18, Icons.notifications_off, color: theme.colorScheme.outline, ), + ], ], ), ); diff --git a/lib/pages/setting/navigation_bar_set.dart b/lib/pages/setting/navigation_bar_set.dart index dba460b1..cbf75fed 100644 --- a/lib/pages/setting/navigation_bar_set.dart +++ b/lib/pages/setting/navigation_bar_set.dart @@ -18,8 +18,8 @@ class _NavigationbarSetPageState extends State { void initState() { super.initState(); defaultNavTabs = defaultNavigationBars; - navBarSort = - GStorage.setting.get(SettingBoxKey.navBarSort, defaultValue: [0, 1, 2]); + navBarSort = List.from(GStorage.setting + .get(SettingBoxKey.navBarSort, defaultValue: [0, 1, 2])); // 对 tabData 进行排序 defaultNavTabs.sort((a, b) { int indexA = navBarSort.indexOf(a['id']); diff --git a/lib/pages/whisper/view.dart b/lib/pages/whisper/view.dart index 9f694915..41c8d506 100644 --- a/lib/pages/whisper/view.dart +++ b/lib/pages/whisper/view.dart @@ -108,6 +108,8 @@ class _WhisperPageState extends State { item: response[index], onSetTop: (isTop, id) => _controller.onSetTop(index, isTop, id), + onSetMute: (isMuted, talkerUid) => + _controller.onSetMute(index, isMuted, talkerUid), onRemove: (talkerId) => _controller.onRemove(index, talkerId), ); }, diff --git a/lib/pages/whisper/widgets/item.dart b/lib/pages/whisper/widgets/item.dart index 76810525..fbb27b9a 100644 --- a/lib/pages/whisper/widgets/item.dart +++ b/lib/pages/whisper/widgets/item.dart @@ -8,6 +8,7 @@ import 'package:PiliPlus/models/common/badge_type.dart'; import 'package:PiliPlus/pages/whisper_secondary/view.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/utils.dart'; +import 'package:fixnum/fixnum.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; @@ -17,11 +18,13 @@ class WhisperSessionItem extends StatelessWidget { super.key, required this.item, required this.onSetTop, + required this.onSetMute, required this.onRemove, }); final Session item; final Function(bool isTop, SessionId id) onSetTop; + final Function(bool isMuted, Int64 talkerUid) onSetMute; final ValueChanged onRemove; @override @@ -42,33 +45,39 @@ class WhisperSessionItem extends StatelessWidget { return AlertDialog( clipBehavior: Clip.hardEdge, contentPadding: const EdgeInsets.symmetric(vertical: 12), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListTile( - dense: true, - onTap: () { - Get.back(); - onSetTop(item.isPinned, item.id); - }, - title: Text( - item.isPinned ? '移除置顶' : '置顶', - style: const TextStyle(fontSize: 14), - ), - ), - if (item.id.privateId.hasTalkerUid()) + content: DefaultTextStyle( + style: const TextStyle(fontSize: 14), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ ListTile( dense: true, onTap: () { Get.back(); - onRemove(item.id.privateId.talkerUid.toInt()); + onSetTop(item.isPinned, item.id); }, - title: const Text( - '删除', - style: TextStyle(fontSize: 14), - ), + title: Text(item.isPinned ? '移除置顶' : '置顶'), ), - ], + if (item.id.privateId.hasTalkerUid()) + ListTile( + dense: true, + onTap: () { + Get.back(); + onSetMute(item.isMuted, item.id.privateId.talkerUid); + }, + title: Text('${item.isMuted ? '关闭' : '开启'}免打扰'), + ), + if (item.id.privateId.hasTalkerUid()) + ListTile( + dense: true, + onTap: () { + Get.back(); + onRemove(item.id.privateId.talkerUid.toInt()); + }, + title: const Text('删除'), + ), + ], + ), ), ); }, @@ -216,16 +225,28 @@ class WhisperSessionItem extends StatelessWidget { style: theme.textTheme.labelMedium! .copyWith(color: theme.colorScheme.outline), ), - trailing: item.hasTimestamp() - ? Text( + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (item.isMuted) ...[ + Icon( + size: 16, + Icons.notifications_off, + color: theme.colorScheme.outline, + ), + if (item.hasTimestamp()) const SizedBox(width: 4), + ], + if (item.hasTimestamp()) + Text( Utils.dateFormat((item.timestamp ~/ 1000000).toInt(), formatType: "day"), style: TextStyle( fontSize: 12, color: theme.colorScheme.outline, ), - ) - : null, + ), + ], + ), ); } } diff --git a/lib/pages/whisper_secondary/view.dart b/lib/pages/whisper_secondary/view.dart index a9732064..bdc608f1 100644 --- a/lib/pages/whisper_secondary/view.dart +++ b/lib/pages/whisper_secondary/view.dart @@ -97,6 +97,8 @@ class _WhisperSecPageState extends State { item: response[index], onSetTop: (isTop, talkerId) => _controller.onSetTop(index, isTop, talkerId), + onSetMute: (isMuted, talkerUid) => + _controller.onSetMute(index, isMuted, talkerUid), onRemove: (talkerId) => _controller.onRemove(index, talkerId), ); },