mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
opt: unread msg
Closes #122 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -4,8 +4,8 @@ extension DynamicBadgeModeDesc on DynamicBadgeMode {
|
||||
String get description => ['隐藏', '红点', '数字'][index];
|
||||
}
|
||||
|
||||
enum MsgUnReadType { pm, reply, at, like, sysMsg, all }
|
||||
enum MsgUnReadType { pm, reply, at, like, sysMsg }
|
||||
|
||||
extension MsgUnReadTypeExt on MsgUnReadType {
|
||||
String get title => ['私信', '回复我的', '@我', '收到的赞', '系统通知', '全部'][index];
|
||||
String get title => ['私信', '回复我的', '@我', '收到的赞', '系统通知'][index];
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class MainController extends GetxController {
|
||||
|
||||
late int homeIndex = -1;
|
||||
late DynamicBadgeMode msgBadgeMode = GStorage.msgBadgeMode;
|
||||
late MsgUnReadType msgUnReadType = GStorage.msgUnReadType;
|
||||
late List<MsgUnReadType> msgUnReadTypes = GStorage.msgUnReadTypeV2;
|
||||
late final RxString msgUnReadCount = ''.obs;
|
||||
late int lastCheckUnreadAt = 0;
|
||||
|
||||
@@ -77,11 +77,14 @@ class MainController extends GetxController {
|
||||
if (isLogin.value.not || homeIndex == -1) {
|
||||
return;
|
||||
}
|
||||
if (msgUnReadTypes.isEmpty) {
|
||||
msgUnReadCount.value = '';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
bool shouldCheckPM = msgUnReadType == MsgUnReadType.pm ||
|
||||
msgUnReadType == MsgUnReadType.all;
|
||||
bool shouldCheckFeed = msgUnReadType != MsgUnReadType.pm ||
|
||||
msgUnReadType == MsgUnReadType.all;
|
||||
bool shouldCheckPM = msgUnReadTypes.contains(MsgUnReadType.pm);
|
||||
bool shouldCheckFeed =
|
||||
([...msgUnReadTypes]..remove(MsgUnReadType.pm)).isNotEmpty;
|
||||
List res = await Future.wait([
|
||||
if (shouldCheckPM) _queryPMUnread(),
|
||||
if (shouldCheckFeed) _queryMsgFeedUnread(),
|
||||
@@ -93,18 +96,18 @@ class MainController extends GetxController {
|
||||
if ((shouldCheckPM.not && res.firstOrNull?['status'] == true) ||
|
||||
(shouldCheckPM && res.getOrNull(1)?['status'] == true)) {
|
||||
int index = shouldCheckPM.not ? 0 : 1;
|
||||
count += (switch (msgUnReadType) {
|
||||
MsgUnReadType.pm => 0,
|
||||
MsgUnReadType.reply => res[index]['data']['reply'],
|
||||
MsgUnReadType.at => res[index]['data']['at'],
|
||||
MsgUnReadType.like => res[index]['data']['like'],
|
||||
MsgUnReadType.sysMsg => res[index]['data']['sys_msg'],
|
||||
MsgUnReadType.all => res[index]['data']['reply'] +
|
||||
res[index]['data']['at'] +
|
||||
res[index]['data']['like'] +
|
||||
res[index]['data']['sys_msg'],
|
||||
} as int?) ??
|
||||
0;
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.reply)) {
|
||||
count += (res[index]['data']['reply'] as int?) ?? 0;
|
||||
}
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.at)) {
|
||||
count += (res[index]['data']['at'] as int?) ?? 0;
|
||||
}
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.like)) {
|
||||
count += (res[index]['data']['like'] as int?) ?? 0;
|
||||
}
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.sysMsg)) {
|
||||
count += (res[index]['data']['sys_msg'] as int?) ?? 0;
|
||||
}
|
||||
}
|
||||
count = count == 0
|
||||
? ''
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:PiliPlus/pages/main/controller.dart';
|
||||
import 'package:PiliPlus/pages/member/new/controller.dart';
|
||||
import 'package:PiliPlus/pages/mine/controller.dart';
|
||||
import 'package:PiliPlus/pages/setting/pages/color_select.dart';
|
||||
import 'package:PiliPlus/pages/setting/widgets/multi_select_dialog.dart';
|
||||
import 'package:PiliPlus/pages/setting/widgets/normal_item.dart';
|
||||
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
||||
import 'package:PiliPlus/pages/setting/widgets/slide_dialog.dart';
|
||||
@@ -286,12 +287,12 @@ List<SettingsModel> get styleSettings => [
|
||||
SettingsModel(
|
||||
settingsType: SettingsType.normal,
|
||||
onTap: (setState) async {
|
||||
MsgUnReadType? result = await showDialog(
|
||||
List<MsgUnReadType>? result = await showDialog(
|
||||
context: Get.context!,
|
||||
builder: (context) {
|
||||
return SelectDialog<MsgUnReadType>(
|
||||
return MultiSelectDialog<MsgUnReadType>(
|
||||
title: '消息未读类型',
|
||||
value: GStorage.msgUnReadType,
|
||||
initValues: GStorage.msgUnReadTypeV2,
|
||||
values: MsgUnReadType.values.map((e) {
|
||||
return {'title': e.title, 'value': e};
|
||||
}).toList(),
|
||||
@@ -299,9 +300,10 @@ List<SettingsModel> get styleSettings => [
|
||||
},
|
||||
);
|
||||
if (result != null) {
|
||||
GStorage.setting.put(SettingBoxKey.msgUnReadType, result.index);
|
||||
GStorage.setting.put(SettingBoxKey.msgUnReadTypeV2,
|
||||
result.map((item) => item.index).toList()..sort());
|
||||
MainController mainController = Get.put(MainController());
|
||||
mainController.msgUnReadType = MsgUnReadType.values[result.index];
|
||||
mainController.msgUnReadTypes = result;
|
||||
if (mainController.msgBadgeMode != DynamicBadgeMode.hidden) {
|
||||
mainController.queryUnreadMsg();
|
||||
}
|
||||
@@ -311,7 +313,8 @@ List<SettingsModel> get styleSettings => [
|
||||
},
|
||||
title: '消息未读类型',
|
||||
leading: const Icon(Icons.notifications_active_outlined),
|
||||
getSubtitle: () => '当前消息类型:${GStorage.msgUnReadType.title}',
|
||||
getSubtitle: () =>
|
||||
'当前消息类型:${GStorage.msgUnReadTypeV2.map((item) => item.title).join('、')}',
|
||||
),
|
||||
SettingsModel(
|
||||
settingsType: SettingsType.sw1tch,
|
||||
|
||||
87
lib/pages/setting/widgets/multi_select_dialog.dart
Normal file
87
lib/pages/setting/widgets/multi_select_dialog.dart
Normal file
@@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class MultiSelectDialog<T> extends StatefulWidget {
|
||||
final List<T> initValues;
|
||||
final String title;
|
||||
final List<dynamic> values;
|
||||
|
||||
const MultiSelectDialog({
|
||||
super.key,
|
||||
required this.initValues,
|
||||
required this.values,
|
||||
required this.title,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MultiSelectDialog<T>> createState() => _MultiSelectDialogState<T>();
|
||||
}
|
||||
|
||||
class _MultiSelectDialogState<T> extends State<MultiSelectDialog<T>> {
|
||||
late Set<T> _tempValues;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tempValues = widget.initValues.toSet();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
title: Text(
|
||||
widget.title,
|
||||
style: TextStyle(fontSize: 18),
|
||||
),
|
||||
contentPadding: const EdgeInsets.only(top: 12),
|
||||
content: StatefulBuilder(builder: (context, StateSetter setState) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: List.generate(
|
||||
widget.values.length,
|
||||
(index) {
|
||||
bool isChecked =
|
||||
_tempValues.contains(widget.values[index]['value']);
|
||||
return CheckboxListTile(
|
||||
dense: true,
|
||||
value: isChecked,
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
title: Text(
|
||||
widget.values[index]['title'],
|
||||
style: Theme.of(context).textTheme.titleMedium!,
|
||||
),
|
||||
onChanged: (value) {
|
||||
if (isChecked) {
|
||||
_tempValues.remove(widget.values[index]['value']);
|
||||
} else {
|
||||
_tempValues.add(widget.values[index]['value']);
|
||||
}
|
||||
setState(() {});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
actionsPadding: EdgeInsets.only(left: 16, right: 16, bottom: 12),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Get.back(result: _tempValues.toList()),
|
||||
child: const Text('确定'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -93,8 +93,6 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
TextStyle titleStyle = Theme.of(context).textTheme.titleMedium!;
|
||||
|
||||
return AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
title: Text(
|
||||
@@ -111,7 +109,10 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
||||
(index) => RadioListTile(
|
||||
dense: true,
|
||||
value: widget.values[index]['value'],
|
||||
title: Text(widget.values[index]['title'], style: titleStyle),
|
||||
title: Text(
|
||||
widget.values[index]['title'],
|
||||
style: Theme.of(context).textTheme.titleMedium!,
|
||||
),
|
||||
subtitle: widget.title == 'CDN 设置' && cdnSpeedTest
|
||||
? Text(
|
||||
_cdnResList[index] is double
|
||||
|
||||
@@ -99,10 +99,11 @@ class GStorage {
|
||||
defaultValue: DynamicBadgeMode.number.index,
|
||||
)];
|
||||
|
||||
static MsgUnReadType get msgUnReadType => MsgUnReadType.values[setting.get(
|
||||
SettingBoxKey.msgUnReadType,
|
||||
defaultValue: MsgUnReadType.pm.index,
|
||||
)];
|
||||
static List<MsgUnReadType> get msgUnReadTypeV2 => List<int>.from(setting.get(
|
||||
SettingBoxKey.msgUnReadTypeV2,
|
||||
defaultValue:
|
||||
List<int>.generate(MsgUnReadType.values.length, (index) => index),
|
||||
)).map((index) => MsgUnReadType.values[index]).toList();
|
||||
|
||||
static int get defaultHomePage =>
|
||||
setting.get(SettingBoxKey.defaultHomePage, defaultValue: 0);
|
||||
@@ -574,7 +575,8 @@ class SettingBoxKey {
|
||||
tabbarSort = 'tabbarSort', // 首页tabbar
|
||||
dynamicBadgeMode = 'dynamicBadgeMode',
|
||||
msgBadgeMode = 'msgBadgeMode',
|
||||
msgUnReadType = 'msgUnReadType',
|
||||
// msgUnReadType = 'msgUnReadType',
|
||||
msgUnReadTypeV2 = 'msgUnReadTypeV2',
|
||||
hiddenSettingUnlocked = 'hiddenSettingUnlocked',
|
||||
enableGradientBg = 'enableGradientBg',
|
||||
navBarSort = 'navBarSort';
|
||||
|
||||
Reference in New Issue
Block a user