mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-24 01:58:36 +00:00
tweaks (#1738)
* feat: edit dm filter * opt: browser * feat: sb userInfo * mod: tvPlayUrl
This commit is contained in:
committed by
GitHub
parent
9754b061dd
commit
bca5b0419c
@@ -32,10 +32,10 @@ class DanmakuBlockController extends GetxController
|
||||
|
||||
Future<void> queryDanmakuFilter() async {
|
||||
SmartDialog.showLoading(msg: '正在同步弹幕屏蔽规则……');
|
||||
var result = await DanmakuFilterHttp.danmakuFilter();
|
||||
final result = await DanmakuFilterHttp.danmakuFilter();
|
||||
SmartDialog.dismiss();
|
||||
if (result['status']) {
|
||||
DanmakuBlockDataModel data = result['data'];
|
||||
if (result.isSuccess) {
|
||||
final data = result.data;
|
||||
rules[0].addAll(data.rule);
|
||||
rules[1].addAll(data.rule1);
|
||||
rules[2].addAll(data.rule2);
|
||||
@@ -43,19 +43,19 @@ class DanmakuBlockController extends GetxController
|
||||
SmartDialog.showToast(data.toast!);
|
||||
}
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
result.toast();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> danmakuFilterDel(int tabIndex, int itemIndex, int id) async {
|
||||
SmartDialog.showLoading(msg: '正在删除弹幕屏蔽规则……');
|
||||
var result = await DanmakuFilterHttp.danmakuFilterDel(ids: id);
|
||||
final result = await DanmakuFilterHttp.danmakuFilterDel(ids: id);
|
||||
SmartDialog.dismiss();
|
||||
if (result['status']) {
|
||||
if (result.isSuccess) {
|
||||
rules[tabIndex].removeAt(itemIndex);
|
||||
SmartDialog.showToast('删除成功');
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
result.toast();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,17 +67,16 @@ class DanmakuBlockController extends GetxController
|
||||
filter = Crc32Xz().convert(utf8.encode(filter)).toRadixString(16);
|
||||
}
|
||||
SmartDialog.showLoading(msg: '正在添加弹幕屏蔽规则……');
|
||||
var result = await DanmakuFilterHttp.danmakuFilterAdd(
|
||||
final result = await DanmakuFilterHttp.danmakuFilterAdd(
|
||||
filter: filter,
|
||||
type: type,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
if (result['status']) {
|
||||
SimpleRule rule = result['data'];
|
||||
rules[type].add(rule);
|
||||
if (result.isSuccess) {
|
||||
rules[type].add(result.data);
|
||||
SmartDialog.showToast('添加成功');
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
result.toast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget tabViewBuilder(int tabIndex, List<SimpleRule> list) {
|
||||
Widget tabViewBuilder(final int tabIndex, List<SimpleRule> list) {
|
||||
if (list.isEmpty) {
|
||||
return scrollErrorWidget();
|
||||
}
|
||||
@@ -89,31 +89,54 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
||||
),
|
||||
itemBuilder: (context, itemIndex) {
|
||||
final SimpleRule item = list[itemIndex];
|
||||
final child = IconButton(
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
onPressed: () => showConfirmDialog(
|
||||
context: context,
|
||||
title: '确定删除该规则?',
|
||||
onConfirm: () => _controller.danmakuFilterDel(
|
||||
tabIndex,
|
||||
itemIndex,
|
||||
item.id,
|
||||
),
|
||||
),
|
||||
);
|
||||
return ListTile(
|
||||
title: Text(
|
||||
item.filter,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
onPressed: () => showConfirmDialog(
|
||||
context: context,
|
||||
title: '确定删除该规则?',
|
||||
onConfirm: () => _controller.danmakuFilterDel(
|
||||
tabIndex,
|
||||
itemIndex,
|
||||
item.id,
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: tabIndex == 2
|
||||
? child
|
||||
: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
onPressed: () => _showAddDialog(
|
||||
DmBlockType.values[_controller.tabController.index],
|
||||
initFilter: item.filter,
|
||||
itemIndex: itemIndex,
|
||||
itemId: item.id,
|
||||
),
|
||||
),
|
||||
child,
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showAddDialog(DmBlockType type) {
|
||||
String filter = '';
|
||||
String hintText = switch (type) {
|
||||
void _showAddDialog(
|
||||
DmBlockType type, {
|
||||
String initFilter = '',
|
||||
int? itemIndex,
|
||||
int? itemId,
|
||||
}) {
|
||||
assert((itemIndex == null) == (itemId == null));
|
||||
String filter = initFilter;
|
||||
final hintText = switch (type) {
|
||||
DmBlockType.keyword => '输入过滤的关键词,其它类别请切换标签页后添加',
|
||||
DmBlockType.regex => '输入//之间的正则表达式,无需包含头尾的"/"',
|
||||
DmBlockType.uid => '输入用户UID',
|
||||
@@ -123,7 +146,7 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text('添加新的${type.label}规则'),
|
||||
title: Text('${itemId != null ? "编辑" : "添加新的"}${type.label}规则'),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -150,15 +173,24 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('添加'),
|
||||
onPressed: () {
|
||||
if (filter.isNotEmpty) {
|
||||
onPressed: () async {
|
||||
if (filter != initFilter) {
|
||||
Get.back();
|
||||
_controller.danmakuFilterAdd(
|
||||
if (itemId != null) {
|
||||
await _controller.danmakuFilterDel(
|
||||
type.index,
|
||||
itemIndex!,
|
||||
itemId,
|
||||
);
|
||||
}
|
||||
await _controller.danmakuFilterAdd(
|
||||
filter: filter,
|
||||
type: type.index,
|
||||
);
|
||||
} else {
|
||||
SmartDialog.showToast('输入内容不能为空');
|
||||
SmartDialog.showToast(
|
||||
'输入内容${filter.isEmpty ? "不能为空" : "与上次相同"}',
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -78,7 +78,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
if (kDebugMode || Utils.isMobile)
|
||||
TextButton.icon(
|
||||
onPressed: () => PageUtils.launchURL(
|
||||
_loginPageCtr.codeInfo.value.data.url,
|
||||
'bilibili://browser?url=${Uri.encodeComponent(_loginPageCtr.codeInfo.value.data.url)}',
|
||||
mode: LaunchMode.externalNonBrowserApplication,
|
||||
),
|
||||
icon: const Icon(Icons.open_in_browser_outlined),
|
||||
|
||||
@@ -3,9 +3,12 @@ import 'dart:math';
|
||||
import 'package:PiliPlus/common/widgets/pair.dart';
|
||||
import 'package:PiliPlus/http/constants.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/sponsor_block/segment_type.dart';
|
||||
import 'package:PiliPlus/models/common/sponsor_block/skip_type.dart';
|
||||
import 'package:PiliPlus/pages/setting/slide_color_picker.dart';
|
||||
import 'package:PiliPlus/utils/duration_utils.dart';
|
||||
import 'package:PiliPlus/utils/num_utils.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
@@ -35,7 +38,8 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
||||
bool _blockToast = Pref.blockToast;
|
||||
String _blockServer = Pref.blockServer;
|
||||
bool _blockTrack = Pref.blockTrack;
|
||||
final Rx<bool?> _serverStatus = Rx<bool?>(null);
|
||||
final _serverStatus = Rxn<bool>();
|
||||
final _userInfo = LoadingState<_UserInfo>.loading().obs;
|
||||
|
||||
Box setting = GStorage.setting;
|
||||
|
||||
@@ -43,6 +47,7 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_checkServerStatus();
|
||||
_getUserInfo();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -60,6 +65,22 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _getUserInfo() async {
|
||||
final params = {
|
||||
'userID': _userId,
|
||||
'values': '["viewCount","minutesSaved","segmentCount"]',
|
||||
};
|
||||
final res = await Request().get(
|
||||
'$_blockServer/api/userInfo',
|
||||
queryParameters: params,
|
||||
);
|
||||
if (res.statusCode == 200) {
|
||||
_userInfo.value = Success(_UserInfo.fromJson(res.data));
|
||||
} else {
|
||||
_userInfo.value = Error(res.data['message']);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _blockLimitItem(
|
||||
ThemeData theme,
|
||||
TextStyle titleStyle,
|
||||
@@ -270,6 +291,37 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
||||
},
|
||||
);
|
||||
|
||||
Widget _blockUserInfo(
|
||||
ThemeData theme,
|
||||
TextStyle titleStyle,
|
||||
TextStyle subTitleStyle,
|
||||
) => Obx(
|
||||
() {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
_userInfo.value = LoadingState.loading();
|
||||
_getUserInfo();
|
||||
},
|
||||
title: Text(
|
||||
'您的信息',
|
||||
style: titleStyle,
|
||||
),
|
||||
subtitle: switch (_userInfo.value) {
|
||||
Loading() => const SizedBox.shrink(),
|
||||
Success<_UserInfo>(:final response) => Text(
|
||||
response.toString(),
|
||||
style: subTitleStyle,
|
||||
),
|
||||
Error(:final errMsg) => Text(
|
||||
errMsg ?? '服务器错误',
|
||||
style: subTitleStyle.copyWith(color: theme.colorScheme.error),
|
||||
),
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Widget _blockServerItem(
|
||||
ThemeData theme,
|
||||
TextStyle titleStyle,
|
||||
@@ -316,6 +368,8 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
||||
_blockServer = _textController.text;
|
||||
setting.put(SettingBoxKey.blockServer, _blockServer);
|
||||
Request.accountManager.blockServer = _blockServer;
|
||||
_checkServerStatus();
|
||||
_getUserInfo();
|
||||
(context as Element).markNeedsBuild();
|
||||
},
|
||||
child: const Text('确定'),
|
||||
@@ -461,6 +515,10 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
||||
SliverToBoxAdapter(child: _blockToastItem(titleStyle)),
|
||||
sliverDivider,
|
||||
SliverToBoxAdapter(child: _blockTrackItem(titleStyle, subTitleStyle)),
|
||||
sliverDivider,
|
||||
SliverToBoxAdapter(
|
||||
child: _blockUserInfo(theme, titleStyle, subTitleStyle),
|
||||
),
|
||||
dividerL,
|
||||
SliverList.separated(
|
||||
itemCount: _blockSettings.length,
|
||||
@@ -599,3 +657,34 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _UserInfo {
|
||||
final int viewCount;
|
||||
final double minutesSaved;
|
||||
final int segmentCount;
|
||||
|
||||
const _UserInfo({
|
||||
required this.viewCount,
|
||||
required this.minutesSaved,
|
||||
required this.segmentCount,
|
||||
});
|
||||
|
||||
factory _UserInfo.fromJson(Map<String, dynamic> json) => _UserInfo(
|
||||
viewCount: json['viewCount'],
|
||||
minutesSaved: (json['minutesSaved'] as num).toDouble(),
|
||||
segmentCount: json['segmentCount'],
|
||||
);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
String minutes = DurationUtils.formatTimeDuration(
|
||||
Duration(minutes: minutesSaved.round()),
|
||||
);
|
||||
if (minutes.isEmpty) {
|
||||
minutes = '0分钟';
|
||||
}
|
||||
return ('您提交了 ${NumUtils.formatPositiveDecimal(segmentCount)} 片段\n'
|
||||
'您为大家节省了 ${NumUtils.formatPositiveDecimal(viewCount)} 片段\n'
|
||||
'($minutes 的生命)');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user