mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-31 08:08:19 +08:00
committed by
GitHub
parent
0460030a2b
commit
ed2bd069ee
@@ -1,6 +1,6 @@
|
||||
import 'dart:async' show StreamSubscription, Timer;
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/pair.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/sponsor_block.dart';
|
||||
@@ -21,15 +21,17 @@ import 'package:media_kit/media_kit.dart';
|
||||
mixin BlockConfigMixin {
|
||||
late final pgcSkipType = Pref.pgcSkipType;
|
||||
late final enablePgcSkip = pgcSkipType != SkipType.disable;
|
||||
late final bool enableSponsorBlock = Pref.enableSponsorBlock;
|
||||
late final bool enableBlock = enableSponsorBlock || enablePgcSkip;
|
||||
late final double blockLimit = Pref.blockLimit;
|
||||
late final enableSponsorBlock = Pref.enableSponsorBlock;
|
||||
late final enableBlock = enableSponsorBlock || enablePgcSkip;
|
||||
late final blockColor = Pref.blockColor;
|
||||
late final blockLimit = Pref.blockLimit;
|
||||
late final blockSettings = Pref.blockSettings;
|
||||
late final List<Color> blockColor = Pref.blockColor;
|
||||
late final Set<String> enableList = blockSettings
|
||||
late final enableList = blockSettings
|
||||
.where((item) => item.second != SkipType.disable)
|
||||
.map((item) => item.first.name)
|
||||
.toSet();
|
||||
|
||||
Color _getColor(SegmentType segment) => blockColor[segment.index];
|
||||
}
|
||||
|
||||
mixin BlockMixin on GetxController {
|
||||
@@ -37,14 +39,12 @@ mixin BlockMixin on GetxController {
|
||||
BlockConfigMixin get blockConfig;
|
||||
StreamSubscription<Duration>? _blockListener;
|
||||
StreamSubscription<Duration>? get blockListener => _blockListener;
|
||||
Color _getBlockColor(SegmentType segment) =>
|
||||
blockConfig.blockColor[segment.index];
|
||||
late final List<SegmentModel> _segmentList = <SegmentModel>[];
|
||||
late final RxList<Segment> segmentProgressList = <Segment>[].obs;
|
||||
|
||||
Timer? _skipTimer;
|
||||
late final listKey = GlobalKey<AnimatedListState>();
|
||||
late final List listData = [];
|
||||
late final List<Object> listData = [];
|
||||
|
||||
RxString? get videoLabel => null;
|
||||
Player? get player;
|
||||
@@ -89,8 +89,7 @@ mixin BlockMixin on GetxController {
|
||||
// debugPrint(
|
||||
// '${position.inSeconds},,${item.segment.first},,${item.segment.second},,${item.skipType.name},,${item.hasSkipped}');
|
||||
// }
|
||||
if (msPos <= item.segment.first &&
|
||||
item.segment.first <= msPos + 1000) {
|
||||
if (msPos <= item.segment.$1 && item.segment.$1 <= msPos + 1000) {
|
||||
switch (item.skipType) {
|
||||
case SkipType.alwaysSkip:
|
||||
onSkip(item, isSeek: false);
|
||||
@@ -118,7 +117,7 @@ mixin BlockMixin on GetxController {
|
||||
Future<void> handleSBData(List<SegmentItemModel> list) async {
|
||||
if (list.isNotEmpty) {
|
||||
try {
|
||||
Future? future;
|
||||
Future<void>? future;
|
||||
final duration = list.first.videoDuration ?? timeLength!;
|
||||
// segmentList
|
||||
_segmentList.addAll(
|
||||
@@ -130,41 +129,19 @@ mixin BlockMixin on GetxController {
|
||||
)
|
||||
.map(
|
||||
(item) {
|
||||
final segmentType = SegmentType.values.byName(item.category);
|
||||
if (item.segment[0] == 0 && item.segment[1] == 0) {
|
||||
videoLabel?.value +=
|
||||
'${videoLabel!.value.isNotEmpty ? '/' : ''}${segmentType.title}';
|
||||
}
|
||||
SkipType skipType;
|
||||
if (isBlock) {
|
||||
skipType =
|
||||
blockConfig.blockSettings[segmentType.index].second;
|
||||
if (skipType != SkipType.showOnly) {
|
||||
if (item.segment[1] == item.segment[0] ||
|
||||
item.segment[1] - item.segment[0] <
|
||||
blockConfig.blockLimit) {
|
||||
skipType = SkipType.showOnly;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
skipType = blockConfig.pgcSkipType;
|
||||
}
|
||||
|
||||
final segmentModel = SegmentModel(
|
||||
UUID: item.uuid,
|
||||
segmentType: segmentType,
|
||||
segment: Pair(
|
||||
first: item.segment[0],
|
||||
second: item.segment[1],
|
||||
),
|
||||
skipType: skipType,
|
||||
final segmentModel = SegmentModel.fromItemModel(
|
||||
item,
|
||||
isBlock ? blockConfig : null,
|
||||
);
|
||||
if (segmentModel.segment == const (0, 0)) {
|
||||
videoLabel?.value +=
|
||||
'${videoLabel!.value.isNotEmpty ? '/' : ''}${segmentModel.segmentType.title}';
|
||||
}
|
||||
|
||||
if (_blockListener == null && autoPlay && player != null) {
|
||||
final currPos = currPosInMilliseconds;
|
||||
|
||||
if (currPos >= segmentModel.segment.first &&
|
||||
currPos < segmentModel.segment.second) {
|
||||
if (segmentModel.segment.contains(currPos)) {
|
||||
_lastBlockPos = currPos;
|
||||
|
||||
switch (segmentModel.skipType) {
|
||||
@@ -182,7 +159,7 @@ mixin BlockMixin on GetxController {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}, orElse: () => false);
|
||||
}
|
||||
break;
|
||||
case SkipType.skipManually:
|
||||
@@ -202,12 +179,12 @@ mixin BlockMixin on GetxController {
|
||||
// _segmentProgressList
|
||||
segmentProgressList.addAll(
|
||||
_segmentList.map((e) {
|
||||
double start = (e.segment.first / duration).clamp(0.0, 1.0);
|
||||
double end = (e.segment.second / duration).clamp(0.0, 1.0);
|
||||
double start = (e.segment.$1 / duration).clamp(0.0, 1.0);
|
||||
double end = (e.segment.$2 / duration).clamp(0.0, 1.0);
|
||||
return Segment(
|
||||
start: start,
|
||||
end: end,
|
||||
color: _getBlockColor(e.segmentType),
|
||||
color: blockConfig._getColor(e.segmentType),
|
||||
);
|
||||
}),
|
||||
);
|
||||
@@ -222,7 +199,7 @@ mixin BlockMixin on GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
void onAddItem(dynamic item) {
|
||||
void onAddItem(Object item) {
|
||||
if (listData.contains(item)) return;
|
||||
listData.insert(0, item);
|
||||
listKey.currentState?.insertItem(0);
|
||||
@@ -233,7 +210,7 @@ mixin BlockMixin on GetxController {
|
||||
});
|
||||
}
|
||||
|
||||
void onRemoveItem(int index, item) {
|
||||
void onRemoveItem(int index, Object item) {
|
||||
EasyThrottle.throttle(
|
||||
'onRemoveItem',
|
||||
const Duration(milliseconds: 500),
|
||||
@@ -252,7 +229,7 @@ mixin BlockMixin on GetxController {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildItem(dynamic item, Animation<double> animation) =>
|
||||
Widget buildItem(Object item, Animation<double> animation) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
void _stopSkipTimer() {
|
||||
@@ -264,6 +241,15 @@ mixin BlockMixin on GetxController {
|
||||
|
||||
Future<void>? seekTo(Duration duration, {required bool isSeek});
|
||||
|
||||
void _skipToast(SegmentModel item) {
|
||||
if (autoPlay && Pref.blockToast) {
|
||||
_showBlockToast('已跳过${item.segmentType.shortTitle}片段');
|
||||
}
|
||||
if (isBlock && Pref.blockTrack) {
|
||||
SponsorBlock.viewedVideoSponsorTime(item.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onSkip(
|
||||
SegmentModel item, {
|
||||
bool isSkip = true,
|
||||
@@ -271,16 +257,11 @@ mixin BlockMixin on GetxController {
|
||||
}) async {
|
||||
try {
|
||||
await seekTo(
|
||||
Duration(milliseconds: item.segment.second),
|
||||
Duration(milliseconds: item.segment.$2),
|
||||
isSeek: isSeek,
|
||||
);
|
||||
if (isSkip) {
|
||||
if (autoPlay && Pref.blockToast) {
|
||||
_showBlockToast('已跳过${item.segmentType.shortTitle}片段');
|
||||
}
|
||||
if (isBlock && Pref.blockTrack) {
|
||||
SponsorBlock.viewedVideoSponsorTime(item.UUID);
|
||||
}
|
||||
_skipToast(item);
|
||||
} else {
|
||||
_showBlockToast('已跳至${item.segmentType.shortTitle}');
|
||||
}
|
||||
@@ -316,7 +297,7 @@ mixin BlockMixin on GetxController {
|
||||
title: const Text('赞成票', style: TextStyle(fontSize: 14)),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
_doVote(segment.UUID, 1);
|
||||
_doVote(segment.uuid, 1);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
@@ -324,7 +305,7 @@ mixin BlockMixin on GetxController {
|
||||
title: const Text('反对票', style: TextStyle(fontSize: 14)),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
_doVote(segment.UUID, 0);
|
||||
_doVote(segment.uuid, 0);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
@@ -363,7 +344,7 @@ mixin BlockMixin on GetxController {
|
||||
onTap: () {
|
||||
Get.back();
|
||||
SponsorBlock.voteOnSponsorTime(
|
||||
uuid: segment.UUID,
|
||||
uuid: segment.uuid,
|
||||
category: item,
|
||||
).then((i) {
|
||||
SmartDialog.showToast(
|
||||
@@ -381,7 +362,7 @@ mixin BlockMixin on GetxController {
|
||||
width: 10,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: _getBlockColor(item),
|
||||
color: blockConfig._getColor(item),
|
||||
),
|
||||
),
|
||||
style: const TextStyle(fontSize: 14, height: 1),
|
||||
@@ -431,7 +412,7 @@ mixin BlockMixin on GetxController {
|
||||
width: 10,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: _getBlockColor(item.segmentType),
|
||||
color: blockConfig._getColor(item.segmentType),
|
||||
),
|
||||
),
|
||||
style: const TextStyle(fontSize: 14, height: 1),
|
||||
@@ -445,7 +426,7 @@ mixin BlockMixin on GetxController {
|
||||
),
|
||||
contentPadding: const EdgeInsets.only(left: 16, right: 8),
|
||||
subtitle: Text(
|
||||
'${DurationUtils.formatDuration(item.segment.first / 1000)} 至 ${DurationUtils.formatDuration(item.segment.second / 1000)}',
|
||||
'${DurationUtils.formatDuration(item.segment.$1 / 1000)} 至 ${DurationUtils.formatDuration(item.segment.$2 / 1000)}',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
trailing: Row(
|
||||
@@ -455,7 +436,7 @@ mixin BlockMixin on GetxController {
|
||||
item.skipType.label,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
if (item.segment.second != 0)
|
||||
if (item.segment.$2 != 0)
|
||||
SizedBox(
|
||||
width: 36,
|
||||
height: 36,
|
||||
@@ -514,6 +495,30 @@ mixin BlockMixin on GetxController {
|
||||
segmentProgressList.clear();
|
||||
}
|
||||
|
||||
Duration? getFirstSegment([int pos = 0]) {
|
||||
for (var i in _segmentList..sort()) {
|
||||
final (start, end) = i.segment;
|
||||
if (start == end) {
|
||||
continue;
|
||||
} else if (start - pos < 100) {
|
||||
if (switch (i.skipType) {
|
||||
.alwaysSkip => true,
|
||||
.skipOnce => !i.hasSkipped,
|
||||
_ => false,
|
||||
}) {
|
||||
_skipToast(i);
|
||||
pos = math.max(pos, i.segment.$2);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos != 0) {
|
||||
return Duration(milliseconds: pos);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
_stopSkipTimer();
|
||||
|
||||
Reference in New Issue
Block a user