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];
|
String get description => ['隐藏', '红点', '数字'][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MsgUnReadType { pm, reply, at, like, sysMsg, all }
|
enum MsgUnReadType { pm, reply, at, like, sysMsg }
|
||||||
|
|
||||||
extension MsgUnReadTypeExt on MsgUnReadType {
|
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 int homeIndex = -1;
|
||||||
late DynamicBadgeMode msgBadgeMode = GStorage.msgBadgeMode;
|
late DynamicBadgeMode msgBadgeMode = GStorage.msgBadgeMode;
|
||||||
late MsgUnReadType msgUnReadType = GStorage.msgUnReadType;
|
late List<MsgUnReadType> msgUnReadTypes = GStorage.msgUnReadTypeV2;
|
||||||
late final RxString msgUnReadCount = ''.obs;
|
late final RxString msgUnReadCount = ''.obs;
|
||||||
late int lastCheckUnreadAt = 0;
|
late int lastCheckUnreadAt = 0;
|
||||||
|
|
||||||
@@ -77,11 +77,14 @@ class MainController extends GetxController {
|
|||||||
if (isLogin.value.not || homeIndex == -1) {
|
if (isLogin.value.not || homeIndex == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (msgUnReadTypes.isEmpty) {
|
||||||
|
msgUnReadCount.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
bool shouldCheckPM = msgUnReadType == MsgUnReadType.pm ||
|
bool shouldCheckPM = msgUnReadTypes.contains(MsgUnReadType.pm);
|
||||||
msgUnReadType == MsgUnReadType.all;
|
bool shouldCheckFeed =
|
||||||
bool shouldCheckFeed = msgUnReadType != MsgUnReadType.pm ||
|
([...msgUnReadTypes]..remove(MsgUnReadType.pm)).isNotEmpty;
|
||||||
msgUnReadType == MsgUnReadType.all;
|
|
||||||
List res = await Future.wait([
|
List res = await Future.wait([
|
||||||
if (shouldCheckPM) _queryPMUnread(),
|
if (shouldCheckPM) _queryPMUnread(),
|
||||||
if (shouldCheckFeed) _queryMsgFeedUnread(),
|
if (shouldCheckFeed) _queryMsgFeedUnread(),
|
||||||
@@ -93,18 +96,18 @@ class MainController extends GetxController {
|
|||||||
if ((shouldCheckPM.not && res.firstOrNull?['status'] == true) ||
|
if ((shouldCheckPM.not && res.firstOrNull?['status'] == true) ||
|
||||||
(shouldCheckPM && res.getOrNull(1)?['status'] == true)) {
|
(shouldCheckPM && res.getOrNull(1)?['status'] == true)) {
|
||||||
int index = shouldCheckPM.not ? 0 : 1;
|
int index = shouldCheckPM.not ? 0 : 1;
|
||||||
count += (switch (msgUnReadType) {
|
if (msgUnReadTypes.contains(MsgUnReadType.reply)) {
|
||||||
MsgUnReadType.pm => 0,
|
count += (res[index]['data']['reply'] as int?) ?? 0;
|
||||||
MsgUnReadType.reply => res[index]['data']['reply'],
|
}
|
||||||
MsgUnReadType.at => res[index]['data']['at'],
|
if (msgUnReadTypes.contains(MsgUnReadType.at)) {
|
||||||
MsgUnReadType.like => res[index]['data']['like'],
|
count += (res[index]['data']['at'] as int?) ?? 0;
|
||||||
MsgUnReadType.sysMsg => res[index]['data']['sys_msg'],
|
}
|
||||||
MsgUnReadType.all => res[index]['data']['reply'] +
|
if (msgUnReadTypes.contains(MsgUnReadType.like)) {
|
||||||
res[index]['data']['at'] +
|
count += (res[index]['data']['like'] as int?) ?? 0;
|
||||||
res[index]['data']['like'] +
|
}
|
||||||
res[index]['data']['sys_msg'],
|
if (msgUnReadTypes.contains(MsgUnReadType.sysMsg)) {
|
||||||
} as int?) ??
|
count += (res[index]['data']['sys_msg'] as int?) ?? 0;
|
||||||
0;
|
}
|
||||||
}
|
}
|
||||||
count = count == 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/member/new/controller.dart';
|
||||||
import 'package:PiliPlus/pages/mine/controller.dart';
|
import 'package:PiliPlus/pages/mine/controller.dart';
|
||||||
import 'package:PiliPlus/pages/setting/pages/color_select.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/normal_item.dart';
|
||||||
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
||||||
import 'package:PiliPlus/pages/setting/widgets/slide_dialog.dart';
|
import 'package:PiliPlus/pages/setting/widgets/slide_dialog.dart';
|
||||||
@@ -286,12 +287,12 @@ List<SettingsModel> get styleSettings => [
|
|||||||
SettingsModel(
|
SettingsModel(
|
||||||
settingsType: SettingsType.normal,
|
settingsType: SettingsType.normal,
|
||||||
onTap: (setState) async {
|
onTap: (setState) async {
|
||||||
MsgUnReadType? result = await showDialog(
|
List<MsgUnReadType>? result = await showDialog(
|
||||||
context: Get.context!,
|
context: Get.context!,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return SelectDialog<MsgUnReadType>(
|
return MultiSelectDialog<MsgUnReadType>(
|
||||||
title: '消息未读类型',
|
title: '消息未读类型',
|
||||||
value: GStorage.msgUnReadType,
|
initValues: GStorage.msgUnReadTypeV2,
|
||||||
values: MsgUnReadType.values.map((e) {
|
values: MsgUnReadType.values.map((e) {
|
||||||
return {'title': e.title, 'value': e};
|
return {'title': e.title, 'value': e};
|
||||||
}).toList(),
|
}).toList(),
|
||||||
@@ -299,9 +300,10 @@ List<SettingsModel> get styleSettings => [
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (result != null) {
|
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 mainController = Get.put(MainController());
|
||||||
mainController.msgUnReadType = MsgUnReadType.values[result.index];
|
mainController.msgUnReadTypes = result;
|
||||||
if (mainController.msgBadgeMode != DynamicBadgeMode.hidden) {
|
if (mainController.msgBadgeMode != DynamicBadgeMode.hidden) {
|
||||||
mainController.queryUnreadMsg();
|
mainController.queryUnreadMsg();
|
||||||
}
|
}
|
||||||
@@ -311,7 +313,8 @@ List<SettingsModel> get styleSettings => [
|
|||||||
},
|
},
|
||||||
title: '消息未读类型',
|
title: '消息未读类型',
|
||||||
leading: const Icon(Icons.notifications_active_outlined),
|
leading: const Icon(Icons.notifications_active_outlined),
|
||||||
getSubtitle: () => '当前消息类型:${GStorage.msgUnReadType.title}',
|
getSubtitle: () =>
|
||||||
|
'当前消息类型:${GStorage.msgUnReadTypeV2.map((item) => item.title).join('、')}',
|
||||||
),
|
),
|
||||||
SettingsModel(
|
SettingsModel(
|
||||||
settingsType: SettingsType.sw1tch,
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
TextStyle titleStyle = Theme.of(context).textTheme.titleMedium!;
|
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
title: Text(
|
title: Text(
|
||||||
@@ -111,7 +109,10 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
|||||||
(index) => RadioListTile(
|
(index) => RadioListTile(
|
||||||
dense: true,
|
dense: true,
|
||||||
value: widget.values[index]['value'],
|
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
|
subtitle: widget.title == 'CDN 设置' && cdnSpeedTest
|
||||||
? Text(
|
? Text(
|
||||||
_cdnResList[index] is double
|
_cdnResList[index] is double
|
||||||
|
|||||||
@@ -99,10 +99,11 @@ class GStorage {
|
|||||||
defaultValue: DynamicBadgeMode.number.index,
|
defaultValue: DynamicBadgeMode.number.index,
|
||||||
)];
|
)];
|
||||||
|
|
||||||
static MsgUnReadType get msgUnReadType => MsgUnReadType.values[setting.get(
|
static List<MsgUnReadType> get msgUnReadTypeV2 => List<int>.from(setting.get(
|
||||||
SettingBoxKey.msgUnReadType,
|
SettingBoxKey.msgUnReadTypeV2,
|
||||||
defaultValue: MsgUnReadType.pm.index,
|
defaultValue:
|
||||||
)];
|
List<int>.generate(MsgUnReadType.values.length, (index) => index),
|
||||||
|
)).map((index) => MsgUnReadType.values[index]).toList();
|
||||||
|
|
||||||
static int get defaultHomePage =>
|
static int get defaultHomePage =>
|
||||||
setting.get(SettingBoxKey.defaultHomePage, defaultValue: 0);
|
setting.get(SettingBoxKey.defaultHomePage, defaultValue: 0);
|
||||||
@@ -574,7 +575,8 @@ class SettingBoxKey {
|
|||||||
tabbarSort = 'tabbarSort', // 首页tabbar
|
tabbarSort = 'tabbarSort', // 首页tabbar
|
||||||
dynamicBadgeMode = 'dynamicBadgeMode',
|
dynamicBadgeMode = 'dynamicBadgeMode',
|
||||||
msgBadgeMode = 'msgBadgeMode',
|
msgBadgeMode = 'msgBadgeMode',
|
||||||
msgUnReadType = 'msgUnReadType',
|
// msgUnReadType = 'msgUnReadType',
|
||||||
|
msgUnReadTypeV2 = 'msgUnReadTypeV2',
|
||||||
hiddenSettingUnlocked = 'hiddenSettingUnlocked',
|
hiddenSettingUnlocked = 'hiddenSettingUnlocked',
|
||||||
enableGradientBg = 'enableGradientBg',
|
enableGradientBg = 'enableGradientBg',
|
||||||
navBarSort = 'navBarSort';
|
navBarSort = 'navBarSort';
|
||||||
|
|||||||
Reference in New Issue
Block a user