mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
opt: danmaku filter (#486)
This commit is contained in:
committed by
GitHub
parent
066f3d4132
commit
99b14d0f0e
@@ -39,7 +39,8 @@ class DanmakuFilterHttp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future danmakuFilterAdd({required String filter, required int type}) async {
|
static Future danmakuFilterAdd(
|
||||||
|
{required String filter, required int type}) async {
|
||||||
var res = await Request().post(
|
var res = await Request().post(
|
||||||
Api.danmakuFilterAdd,
|
Api.danmakuFilterAdd,
|
||||||
queryParameters: {
|
queryParameters: {
|
||||||
@@ -51,7 +52,7 @@ class DanmakuFilterHttp {
|
|||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
return {
|
return {
|
||||||
'status': true,
|
'status': true,
|
||||||
'data': Rule.fromJson(res.data['data']),
|
'data': SimpleRule.fromJson(res.data['data']),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class DanmakuBlockDataModel {
|
class DanmakuBlockDataModel {
|
||||||
List<Rule>? rule;
|
List<SimpleRule>? rule;
|
||||||
String? toast;
|
String? toast;
|
||||||
int? valid;
|
int? valid;
|
||||||
int? ver;
|
int? ver;
|
||||||
@@ -7,88 +7,22 @@ class DanmakuBlockDataModel {
|
|||||||
DanmakuBlockDataModel({this.rule, this.toast, this.valid, this.ver});
|
DanmakuBlockDataModel({this.rule, this.toast, this.valid, this.ver});
|
||||||
|
|
||||||
DanmakuBlockDataModel.fromJson(Map<String, dynamic> json) {
|
DanmakuBlockDataModel.fromJson(Map<String, dynamic> json) {
|
||||||
if (json['rule'] != null) {
|
rule = (json['rule'] as List?)?.map((v) => SimpleRule.fromJson(v)).toList();
|
||||||
rule = <Rule>[];
|
|
||||||
json['rule'].forEach((v) {
|
|
||||||
rule!.add(Rule.fromJson(v));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
toast = json['toast'];
|
toast = json['toast'];
|
||||||
valid = json['valid'];
|
valid = json['valid'];
|
||||||
ver = json['ver'];
|
ver = json['ver'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
|
||||||
if (rule != null) {
|
|
||||||
data['rule'] = rule!.map((v) => v.toJson()).toList();
|
|
||||||
}
|
|
||||||
data['toast'] = toast;
|
|
||||||
data['valid'] = valid;
|
|
||||||
data['ver'] = ver;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Rule {
|
|
||||||
int? id;
|
|
||||||
int? mid;
|
|
||||||
int? type;
|
|
||||||
String? filter;
|
|
||||||
String? comment;
|
|
||||||
int? ctime;
|
|
||||||
int? mtime;
|
|
||||||
|
|
||||||
Rule(
|
|
||||||
{this.id,
|
|
||||||
this.mid,
|
|
||||||
this.type,
|
|
||||||
this.filter,
|
|
||||||
this.comment,
|
|
||||||
this.ctime,
|
|
||||||
this.mtime});
|
|
||||||
|
|
||||||
Rule.fromJson(Map<String, dynamic> json) {
|
|
||||||
id = json['id'];
|
|
||||||
mid = json['mid'];
|
|
||||||
type = json['type'];
|
|
||||||
filter = json['filter'];
|
|
||||||
comment = json['comment'];
|
|
||||||
ctime = json['ctime'];
|
|
||||||
mtime = json['mtime'];
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
final Map<String, dynamic> data = <String, dynamic>{};
|
|
||||||
data['id'] = id;
|
|
||||||
data['mid'] = mid;
|
|
||||||
data['type'] = type;
|
|
||||||
data['filter'] = filter;
|
|
||||||
data['comment'] = comment;
|
|
||||||
data['ctime'] = ctime;
|
|
||||||
data['mtime'] = mtime;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleRule {
|
class SimpleRule {
|
||||||
final int id;
|
late final int id;
|
||||||
final int type;
|
late final int type;
|
||||||
String filter;
|
late String filter;
|
||||||
SimpleRule(this.id, this.type, this.filter);
|
SimpleRule(this.id, this.type, this.filter);
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
return {
|
|
||||||
'id': id,
|
|
||||||
'type': type,
|
|
||||||
'filter': filter,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
factory SimpleRule.fromMap(Map<String, dynamic> map) {
|
SimpleRule.fromJson(Map<String, dynamic> json) {
|
||||||
return SimpleRule(
|
id = json['id'];
|
||||||
map['id'],
|
type = json['type'];
|
||||||
map['type'],
|
filter = json['filter'];
|
||||||
map['filter'],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
lib/models/user/danmaku_rule.dart
Normal file
44
lib/models/user/danmaku_rule.dart
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import 'package:PiliPlus/grpc/dm/v1/dm.pb.dart';
|
||||||
|
|
||||||
|
class RuleFilter {
|
||||||
|
static final _regExp = RegExp(r'^/(.*)/$');
|
||||||
|
|
||||||
|
List<String> dmFilterString = [];
|
||||||
|
List<RegExp> dmRegExp = [];
|
||||||
|
Set<String> dmUid = {};
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
RuleFilter(this.dmFilterString, this.dmRegExp, this.dmUid, [int? count]) {
|
||||||
|
this.count =
|
||||||
|
count ?? dmFilterString.length + dmRegExp.length + dmUid.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleFilter.fromRuleTypeEntires(
|
||||||
|
Iterable<MapEntry<int, Map<int, String>>> rules) {
|
||||||
|
for (var rule in rules) {
|
||||||
|
switch (rule.key) {
|
||||||
|
case 0:
|
||||||
|
dmFilterString.addAll(rule.value.values);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dmRegExp.addAll(rule.value.values.map((i) => RegExp(
|
||||||
|
_regExp.matchAsPrefix(i)?.group(1) ?? i,
|
||||||
|
caseSensitive: false)));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dmUid.addAll(rule.value.values);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count = dmFilterString.length + dmRegExp.length + dmUid.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuleFilter.empty();
|
||||||
|
|
||||||
|
bool retain(DanmakuElem elem) {
|
||||||
|
return !(dmUid.contains(elem.midHash) ||
|
||||||
|
dmFilterString.any((i) => elem.content.contains(i)) ||
|
||||||
|
dmRegExp.any((i) => i.hasMatch(elem.content)));
|
||||||
|
}
|
||||||
|
}
|
||||||
36
lib/models/user/danmaku_rule_adapter.dart
Normal file
36
lib/models/user/danmaku_rule_adapter.dart
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import 'package:PiliPlus/models/user/danmaku_rule.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
|
||||||
|
class RuleFilterAdapter extends TypeAdapter<RuleFilter> {
|
||||||
|
@override
|
||||||
|
final int typeId = 12;
|
||||||
|
|
||||||
|
@override
|
||||||
|
RuleFilter read(BinaryReader reader) {
|
||||||
|
return RuleFilter(
|
||||||
|
reader.readStringList(),
|
||||||
|
reader
|
||||||
|
.readStringList()
|
||||||
|
.map((i) => RegExp(i, caseSensitive: false))
|
||||||
|
.toList(),
|
||||||
|
reader.readStringList().toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void write(BinaryWriter writer, RuleFilter obj) {
|
||||||
|
writer
|
||||||
|
..writeStringList(obj.dmFilterString)
|
||||||
|
..writeStringList(obj.dmRegExp.map((i) => i.pattern).toList())
|
||||||
|
..writeStringList(obj.dmUid.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => typeId.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is RuleFilterAdapter &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
typeId == other.typeId;
|
||||||
|
}
|
||||||
@@ -69,21 +69,13 @@ class PlDanmakuController {
|
|||||||
queryDanmaku(segmentIndex);
|
queryDanmaku(segmentIndex);
|
||||||
}
|
}
|
||||||
if (plPlayerController.danmakuWeight == 0 &&
|
if (plPlayerController.danmakuWeight == 0 &&
|
||||||
plPlayerController.filterCount == 0) {
|
plPlayerController.filters.count == 0) {
|
||||||
return dmSegMap[progress ~/ 100];
|
return dmSegMap[progress ~/ 100];
|
||||||
} else {
|
} else {
|
||||||
return dmSegMap[progress ~/ 100]
|
return dmSegMap[progress ~/ 100]
|
||||||
?.where(
|
?..retainWhere((element) =>
|
||||||
(element) => element.weight >= plPlayerController.danmakuWeight)
|
element.weight >= plPlayerController.danmakuWeight &&
|
||||||
.where(filterDanmaku)
|
plPlayerController.filters.retain(element));
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool filterDanmaku(DanmakuElem elem) {
|
|
||||||
return !(plPlayerController.dmUid.contains(elem.midHash) ||
|
|
||||||
plPlayerController.dmFilterString
|
|
||||||
.any((i) => elem.content.contains(i)) ||
|
|
||||||
plPlayerController.dmRegExp.any((i) => i.hasMatch(elem.content)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:PiliPlus/models/user/danmaku_rule.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -38,38 +39,11 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
final regExp = RegExp(r'^/(.*)/$');
|
final ruleFilter = RuleFilter.fromRuleTypeEntires(
|
||||||
List<Map<String, dynamic>> simpleRuleList = _danmakuBlockController
|
_danmakuBlockController.ruleTypes.entries);
|
||||||
.ruleTypes.values
|
plPlayerController.filters = ruleFilter;
|
||||||
.expand((element) => element)
|
|
||||||
.map<Map<String, dynamic>>((e) {
|
|
||||||
//当正则表达式前后都有"/"时,去掉,避免RegExp解析错误
|
|
||||||
if (e.type == 1) {
|
|
||||||
String? filter = regExp.firstMatch(e.filter)?.group(1);
|
|
||||||
if (filter != null) {
|
|
||||||
e.filter = filter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return e.toMap();
|
|
||||||
}).toList();
|
|
||||||
// debugPrint("simpleRuleList:$simpleRuleList");
|
|
||||||
plPlayerController.filterCount = simpleRuleList.length;
|
|
||||||
for (var item in simpleRuleList) {
|
|
||||||
switch (item['type']) {
|
|
||||||
case 0:
|
|
||||||
plPlayerController.dmFilterString.add(item['filter']);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
plPlayerController.dmRegExp
|
|
||||||
.add(RegExp(item['filter'], caseSensitive: false));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
plPlayerController.dmUid.add(item['filter']);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scrollController.dispose();
|
scrollController.dispose();
|
||||||
GStorage.localCache.put(LocalCacheKey.danmakuFilterRule, simpleRuleList);
|
GStorage.localCache.put(LocalCacheKey.danmakuFilterRules, ruleFilter);
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,19 +76,16 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
|||||||
]),
|
]),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
TextButton(
|
TextButton(
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
child: const Text('取消'),
|
child: const Text('取消'),
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
child: const Text('添加'),
|
child: const Text('添加'),
|
||||||
onPressed: () async {
|
onPressed: () {
|
||||||
String filter = textController.text;
|
String filter = textController.text;
|
||||||
if (filter.isNotEmpty) {
|
if (filter.isNotEmpty) {
|
||||||
await _danmakuBlockController.danmakuFilterAdd(
|
_danmakuBlockController.danmakuFilterAdd(
|
||||||
filter: filter, type: type);
|
filter: filter, type: type);
|
||||||
if (!context.mounted) return;
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast('输入内容不能为空');
|
SmartDialog.showToast('输入内容不能为空');
|
||||||
@@ -143,7 +114,8 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
|||||||
controller: _danmakuBlockController.tabController,
|
controller: _danmakuBlockController.tabController,
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < ruleLabels.length; i++)
|
for (var i = 0; i < ruleLabels.length; i++)
|
||||||
Obx(() => tabViewBuilder(i, _danmakuBlockController.ruleTypes[i]!)),
|
Obx(() => tabViewBuilder(
|
||||||
|
i, _danmakuBlockController.ruleTypes[i]!.entries.toList())),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
@@ -155,7 +127,7 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget tabViewBuilder(int tabIndex, List<SimpleRule> list) {
|
Widget tabViewBuilder(int tabIndex, List<MapEntry<int, String>> list) {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
itemCount: list.length,
|
itemCount: list.length,
|
||||||
@@ -163,16 +135,13 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
|||||||
itemBuilder: (BuildContext context, int listIndex) {
|
itemBuilder: (BuildContext context, int listIndex) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
list[listIndex].filter,
|
list[listIndex].value,
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
),
|
),
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
icon: const Icon(Icons.delete),
|
icon: const Icon(Icons.delete),
|
||||||
onPressed: () async {
|
onPressed: () => _danmakuBlockController.danmakuFilterDel(
|
||||||
await _danmakuBlockController.danmakuFilterDel(
|
tabIndex, list[listIndex].key)));
|
||||||
tabIndex, list[listIndex].id);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -180,12 +149,7 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
|||||||
|
|
||||||
class DanmakuBlockController extends GetxController
|
class DanmakuBlockController extends GetxController
|
||||||
with GetTickerProviderStateMixin {
|
with GetTickerProviderStateMixin {
|
||||||
RxList<Rule> danmakuRules = <Rule>[].obs;
|
final ruleTypes = RxMap<int, Map<int, String>>({0: {}, 1: {}, 2: {}});
|
||||||
RxMap<int, List<SimpleRule>> ruleTypes = {
|
|
||||||
0: <SimpleRule>[],
|
|
||||||
1: <SimpleRule>[],
|
|
||||||
2: <SimpleRule>[],
|
|
||||||
}.obs;
|
|
||||||
late TabController tabController;
|
late TabController tabController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -200,50 +164,44 @@ class DanmakuBlockController extends GetxController
|
|||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future queryDanmakuFilter() async {
|
Future<void> queryDanmakuFilter() async {
|
||||||
SmartDialog.showLoading(msg: '正在同步弹幕屏蔽规则……');
|
SmartDialog.showLoading(msg: '正在同步弹幕屏蔽规则……');
|
||||||
var result = await DanmakuFilterHttp.danmakuFilter();
|
var result = await DanmakuFilterHttp.danmakuFilter();
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
if (result['data']?.rule != null) {
|
if (result['data']?.rule != null) {
|
||||||
danmakuRules.value = result['data']?.rule;
|
final List<SimpleRule> filter = result['data']?.rule;
|
||||||
danmakuRules.map((e) {
|
for (var rule in filter) {
|
||||||
SimpleRule simpleRule = SimpleRule(e.id!, e.type!, e.filter!);
|
ruleTypes[rule.type]![rule.id] = rule.filter;
|
||||||
ruleTypes[e.type!]!.add(simpleRule);
|
}
|
||||||
}).toList();
|
|
||||||
ruleTypes.refresh();
|
ruleTypes.refresh();
|
||||||
}
|
}
|
||||||
SmartDialog.showToast(result['data'].toast);
|
SmartDialog.showToast(result['data'].toast);
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast(result['msg']);
|
SmartDialog.showToast(result['msg']);
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future danmakuFilterDel(int type, int id) async {
|
Future<void> danmakuFilterDel(int type, int id) async {
|
||||||
SmartDialog.showLoading(msg: '正在删除弹幕屏蔽规则……');
|
SmartDialog.showLoading(msg: '正在删除弹幕屏蔽规则……');
|
||||||
var result = await DanmakuFilterHttp.danmakuFilterDel(ids: id);
|
var result = await DanmakuFilterHttp.danmakuFilterDel(ids: id);
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
danmakuRules.removeWhere((e) => e.id == id);
|
ruleTypes[type]!.remove(id);
|
||||||
ruleTypes[type]!.removeWhere((e) => e.id == id);
|
|
||||||
ruleTypes.refresh();
|
ruleTypes.refresh();
|
||||||
SmartDialog.showToast(result['msg']);
|
|
||||||
} else {
|
|
||||||
SmartDialog.showToast(result['msg']);
|
|
||||||
}
|
}
|
||||||
|
SmartDialog.showToast(result['msg']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future danmakuFilterAdd({required String filter, required int type}) async {
|
Future<void> danmakuFilterAdd(
|
||||||
|
{required String filter, required int type}) async {
|
||||||
SmartDialog.showLoading(msg: '正在添加弹幕屏蔽规则……');
|
SmartDialog.showLoading(msg: '正在添加弹幕屏蔽规则……');
|
||||||
var result =
|
var result =
|
||||||
await DanmakuFilterHttp.danmakuFilterAdd(filter: filter, type: type);
|
await DanmakuFilterHttp.danmakuFilterAdd(filter: filter, type: type);
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
Rule data = result['data'];
|
SimpleRule rule = result['data'];
|
||||||
danmakuRules.add(data);
|
ruleTypes[type]![rule.id] = rule.filter;
|
||||||
SimpleRule simpleRule = SimpleRule(data.id!, data.type!, data.filter!);
|
|
||||||
ruleTypes[type]!.add(simpleRule);
|
|
||||||
ruleTypes.refresh();
|
ruleTypes.refresh();
|
||||||
SmartDialog.showToast('添加成功');
|
SmartDialog.showToast('添加成功');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1523,8 +1523,8 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
Get.toNamed('/danmakuBlock',
|
Get.toNamed('/danmakuBlock',
|
||||||
arguments: widget.controller)
|
arguments: widget.controller)
|
||||||
},
|
},
|
||||||
child:
|
child: Text(
|
||||||
Text("屏蔽管理(${widget.controller.filterCount})")),
|
"屏蔽管理(${plPlayerController.filters.count})")),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/constants.dart';
|
|||||||
import 'package:PiliPlus/common/widgets/segment_progress_bar.dart';
|
import 'package:PiliPlus/common/widgets/segment_progress_bar.dart';
|
||||||
import 'package:PiliPlus/http/init.dart';
|
import 'package:PiliPlus/http/init.dart';
|
||||||
import 'package:PiliPlus/models/common/audio_normalization.dart';
|
import 'package:PiliPlus/models/common/audio_normalization.dart';
|
||||||
|
import 'package:PiliPlus/models/user/danmaku_rule.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:canvas_danmaku/canvas_danmaku.dart';
|
import 'package:canvas_danmaku/canvas_danmaku.dart';
|
||||||
@@ -261,10 +262,7 @@ class PlPlayerController {
|
|||||||
|
|
||||||
/// 弹幕权重
|
/// 弹幕权重
|
||||||
int danmakuWeight = 0;
|
int danmakuWeight = 0;
|
||||||
int filterCount = 0;
|
late RuleFilter filters;
|
||||||
List dmFilterString = [];
|
|
||||||
List<RegExp> dmRegExp = [];
|
|
||||||
Set dmUid = {};
|
|
||||||
// 关联弹幕控制器
|
// 关联弹幕控制器
|
||||||
DanmakuController? danmakuController;
|
DanmakuController? danmakuController;
|
||||||
bool showDanmaku = true;
|
bool showDanmaku = true;
|
||||||
@@ -406,22 +404,7 @@ class PlPlayerController {
|
|||||||
isOpenDanmu.value =
|
isOpenDanmu.value =
|
||||||
setting.get(SettingBoxKey.enableShowDanmaku, defaultValue: true);
|
setting.get(SettingBoxKey.enableShowDanmaku, defaultValue: true);
|
||||||
danmakuWeight = setting.get(SettingBoxKey.danmakuWeight, defaultValue: 0);
|
danmakuWeight = setting.get(SettingBoxKey.danmakuWeight, defaultValue: 0);
|
||||||
List rules = GStorage.localCache
|
filters = GStorage.danmakuFilterRule;
|
||||||
.get(LocalCacheKey.danmakuFilterRule, defaultValue: []);
|
|
||||||
filterCount = rules.length;
|
|
||||||
for (var item in rules) {
|
|
||||||
switch (item['type']) {
|
|
||||||
case 0:
|
|
||||||
dmFilterString.add(item['filter']);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
dmRegExp.add(RegExp(item['filter'], caseSensitive: false));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
dmUid.add(item['filter']);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
blockTypes = setting.get(SettingBoxKey.danmakuBlockType, defaultValue: []);
|
blockTypes = setting.get(SettingBoxKey.danmakuBlockType, defaultValue: []);
|
||||||
showArea = setting.get(SettingBoxKey.danmakuShowArea, defaultValue: 0.5);
|
showArea = setting.get(SettingBoxKey.danmakuShowArea, defaultValue: 0.5);
|
||||||
// 不透明度
|
// 不透明度
|
||||||
@@ -1636,7 +1619,7 @@ class PlPlayerController {
|
|||||||
_isQueryingVideoShot = true;
|
_isQueryingVideoShot = true;
|
||||||
try {
|
try {
|
||||||
dynamic res = await Request().get(
|
dynamic res = await Request().get(
|
||||||
'https://api.bilibili.com/x/player/videoshot',
|
'/x/player/videoshot',
|
||||||
queryParameters: {
|
queryParameters: {
|
||||||
// 'aid': IdUtils.bv2av(_bvid),
|
// 'aid': IdUtils.bv2av(_bvid),
|
||||||
'bvid': _bvid,
|
'bvid': _bvid,
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import 'package:PiliPlus/models/common/sponsor_block/skip_type.dart';
|
|||||||
import 'package:PiliPlus/models/common/tab_type.dart';
|
import 'package:PiliPlus/models/common/tab_type.dart';
|
||||||
import 'package:PiliPlus/models/common/theme_type.dart';
|
import 'package:PiliPlus/models/common/theme_type.dart';
|
||||||
import 'package:PiliPlus/models/common/up_panel_position.dart';
|
import 'package:PiliPlus/models/common/up_panel_position.dart';
|
||||||
|
import 'package:PiliPlus/models/user/danmaku_rule.dart';
|
||||||
|
import 'package:PiliPlus/models/user/danmaku_rule_adapter.dart';
|
||||||
import 'package:PiliPlus/models/video/play/CDN.dart';
|
import 'package:PiliPlus/models/video/play/CDN.dart';
|
||||||
import 'package:PiliPlus/models/video/play/quality.dart';
|
import 'package:PiliPlus/models/video/play/quality.dart';
|
||||||
import 'package:PiliPlus/models/video/play/subtitle.dart';
|
import 'package:PiliPlus/models/video/play/subtitle.dart';
|
||||||
@@ -426,8 +428,8 @@ class GStorage {
|
|||||||
static List<int> get blackMidsList => List<int>.from(GStorage.localCache
|
static List<int> get blackMidsList => List<int>.from(GStorage.localCache
|
||||||
.get(LocalCacheKey.blackMidsList, defaultValue: <int>[]));
|
.get(LocalCacheKey.blackMidsList, defaultValue: <int>[]));
|
||||||
|
|
||||||
static List get danmakuFilterRule => GStorage.localCache
|
static RuleFilter get danmakuFilterRule => GStorage.localCache
|
||||||
.get(LocalCacheKey.danmakuFilterRule, defaultValue: []);
|
.get(LocalCacheKey.danmakuFilterRules, defaultValue: RuleFilter.empty());
|
||||||
|
|
||||||
static void setBlackMidsList(blackMidsList) {
|
static void setBlackMidsList(blackMidsList) {
|
||||||
if (blackMidsList is! List<int>) return;
|
if (blackMidsList is! List<int>) return;
|
||||||
@@ -535,6 +537,7 @@ class GStorage {
|
|||||||
Hive.registerAdapter(BiliCookieJarAdapter());
|
Hive.registerAdapter(BiliCookieJarAdapter());
|
||||||
Hive.registerAdapter(LoginAccountAdapter());
|
Hive.registerAdapter(LoginAccountAdapter());
|
||||||
Hive.registerAdapter(AccountTypeAdapter());
|
Hive.registerAdapter(AccountTypeAdapter());
|
||||||
|
Hive.registerAdapter(RuleFilterAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> close() async {
|
static Future<void> close() async {
|
||||||
@@ -756,7 +759,7 @@ class LocalCacheKey {
|
|||||||
// 隐私设置-黑名单管理
|
// 隐私设置-黑名单管理
|
||||||
blackMidsList = 'blackMidsList',
|
blackMidsList = 'blackMidsList',
|
||||||
// 弹幕屏蔽规则
|
// 弹幕屏蔽规则
|
||||||
danmakuFilterRule = 'danmakuFilterRule',
|
danmakuFilterRules = 'danmakuFilterRules',
|
||||||
// // access_key
|
// // access_key
|
||||||
// accessKey = 'accessKey',
|
// accessKey = 'accessKey',
|
||||||
|
|
||||||
@@ -817,6 +820,7 @@ class Accounts {
|
|||||||
|
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
GStorage.localCache.delete('accessKey'),
|
GStorage.localCache.delete('accessKey'),
|
||||||
|
GStorage.localCache.delete('danmakuFilterRule'),
|
||||||
dir.delete(recursive: true),
|
dir.delete(recursive: true),
|
||||||
if (isLogin)
|
if (isLogin)
|
||||||
LoginAccount(cookies, localAccessKey['value'],
|
LoginAccount(cookies, localAccessKey['value'],
|
||||||
|
|||||||
Reference in New Issue
Block a user