mod: add reverse from first option

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2024-12-31 12:12:43 +08:00
parent 20a89fbccb
commit 1215d126cc
8 changed files with 80 additions and 59 deletions

View File

@@ -59,7 +59,7 @@ void main() async {
SmartDialog.config.loading =
SmartConfigLoading(backType: SmartBackType.normal);
// 异常捕获 logo记录
final String buildConfig = '''
final String buildConfig = '''\n
Build Time: ${BuildConfig.buildTime}
Commit Hash: ${BuildConfig.commitHash}''';
final Catcher2Options debugConfig = Catcher2Options(

View File

@@ -401,10 +401,17 @@ class _ExtraSettingState extends State<ExtraSetting> {
setKey: SettingBoxKey.showArgueMsg,
defaultVal: true,
),
SetSwitchItem(
title: '倒序播放从首集开始播放',
subTitle: '开启则自动切换为倒序首集,否则保持当前集',
leading: const Icon(Icons.u_turn_right),
setKey: SettingBoxKey.reverseFromFirst,
defaultVal: true,
),
Obx(
() => ListTile(
enableFeedback: true,
onTap: () => settingController.onOpenFeedBack(),
onTap: settingController.onOpenFeedBack,
leading: const Icon(Icons.vibration_outlined),
title: Text('震动反馈', style: titleStyle),
subtitle: Text('请确定手机设置中已开启震动反馈', style: subTitleStyle),

View File

@@ -112,8 +112,8 @@ class _SubDetailPageState extends State<SubDetailPage> {
top: kTextTabBarHeight +
MediaQuery.of(context).padding.top +
15,
left: 20,
right: 20,
left: 12,
right: 12,
),
child: SizedBox(
height: 200,

View File

@@ -224,6 +224,7 @@ class VideoDetailController extends GetxController
late final horizontalSeasonPanel = GStorage.horizontalSeasonPanel;
late int seasonCid = 0;
late RxInt seasonIndex = 0.obs;
late final reverseFromFirst = GStorage.reverseFromFirst;
late final bool enableSponsorBlock;
PlayerStatus? playerStatus;

View File

@@ -50,10 +50,7 @@ class VideoIntroPanel extends StatefulWidget {
class _VideoIntroPanelState extends State<VideoIntroPanel>
with AutomaticKeepAliveClientMixin, SingleTickerProviderStateMixin {
late String heroTag;
late VideoIntroController videoIntroController;
VideoDetailData? videoDetail;
StreamSubscription? _listener;
// 添加页面缓存
@override
@@ -63,55 +60,40 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
void initState() {
super.initState();
/// fix 全屏时参数丢失
// if (Get.arguments != null) {
// heroTag = Get.arguments['heroTag'];
// }
heroTag = widget.heroTag;
videoIntroController = Get.put(VideoIntroController(), tag: heroTag)
..heroTag = heroTag;
// _futureBuilderFuture = videoIntroController.queryVideoIntro();
_listener = videoIntroController.videoDetail.listen((value) {
videoDetail = value;
});
}
@override
void dispose() {
_listener?.cancel();
super.dispose();
videoIntroController = Get.put(VideoIntroController(), tag: widget.heroTag)
..heroTag = widget.heroTag;
}
@override
Widget build(BuildContext context) {
super.build(context);
return Obx(() => videoIntroController.videoDetail.value.title == null
? VideoInfo(
loadingStatus: true,
videoDetail: videoDetail,
heroTag: heroTag,
showAiBottomSheet: widget.showAiBottomSheet,
showIntroDetail: () => widget.showIntroDetail(
videoDetail,
videoIntroController.videoTags,
return Obx(
() => videoIntroController.videoDetail.value.title == null
? VideoInfo(
loadingStatus: true,
videoDetail: videoIntroController.videoDetail.value,
heroTag: widget.heroTag,
showAiBottomSheet: widget.showAiBottomSheet,
showIntroDetail: () => widget.showIntroDetail(
videoIntroController.videoDetail.value,
videoIntroController.videoTags,
),
showEpisodes: widget.showEpisodes,
onShowMemberPage: widget.onShowMemberPage,
)
: VideoInfo(
loadingStatus: false,
videoDetail: videoIntroController.videoDetail.value,
heroTag: widget.heroTag,
showAiBottomSheet: widget.showAiBottomSheet,
showIntroDetail: () => widget.showIntroDetail(
videoIntroController.videoDetail.value,
videoIntroController.videoTags,
),
showEpisodes: widget.showEpisodes,
onShowMemberPage: widget.onShowMemberPage,
),
showEpisodes: widget.showEpisodes,
onShowMemberPage: widget.onShowMemberPage,
)
: VideoInfo(
//key:herotag
key: ValueKey(heroTag),
loadingStatus: false,
videoDetail: videoIntroController.videoDetail.value,
heroTag: heroTag,
showAiBottomSheet: widget.showAiBottomSheet,
showIntroDetail: () => widget.showIntroDetail(
videoIntroController.videoDetail.value,
videoIntroController.videoTags,
),
showEpisodes: widget.showEpisodes,
onShowMemberPage: widget.onShowMemberPage,
));
);
}
}

View File

@@ -54,16 +54,15 @@ class _SeasonPanelState extends State<SeasonPanel> {
// .episodes;
currentIndex.value = episodes.indexWhere(
(EpisodeItem e) => e.cid == _videoDetailController.seasonCid);
_listener = _videoDetailController.cid.listen((int p0) {
_listener = _videoDetailController.cid.listen((int cid) {
if (widget.pages != null && widget.pages!.length != 1) {
bool isPart = widget.pages?.indexWhere((item) => item.cid == p0) != -1;
bool isPart = widget.pages?.indexWhere((item) => item.cid == cid) != -1;
if (isPart) return;
}
_videoDetailController.seasonCid = p0;
_videoDetailController.seasonCid = cid;
_findEpisode();
currentIndex.value = episodes.indexWhere(
(EpisodeItem e) => e.cid == _videoDetailController.seasonCid);
if (!mounted) return;
});
}

View File

@@ -44,6 +44,8 @@ import 'package:PiliPalaX/plugin/pl_player/index.dart';
import 'package:PiliPalaX/plugin/pl_player/models/play_repeat.dart';
import 'package:PiliPalaX/services/service_locator.dart';
import 'package:PiliPalaX/utils/storage.dart';
import 'package:PiliPalaX/models/bangumi/info.dart' as bangumi;
import 'package:PiliPalaX/models/video_detail_res.dart' as video;
import 'package:screen_brightness/screen_brightness.dart';
import '../../../services/shutdown_timer_service.dart';
@@ -1514,7 +1516,12 @@ class _VideoDetailPageState extends State<VideoDetailPage>
? bangumiIntroController.changeSeasonOrbangu
: videoIntroController.changeSeasonOrbangu,
showTitle: false,
onReverse: onReversePlay,
onReverse: () {
onReversePlay(
videoDetailController.bvid,
IdUtils.bv2av(videoDetailController.bvid),
);
},
),
),
),
@@ -1599,7 +1606,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
},
onReverse: () {
Get.back();
onReversePlay();
onReversePlay(bvid, aid);
},
);
if (isFullScreen) {
@@ -1614,7 +1621,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
}
}
void onReversePlay() {
void onReversePlay(bvid, aid) {
videoIntroController.videoDetail.value.ugcSeason!
.sections![videoDetailController.seasonIndex.value].episodes =
videoIntroController
@@ -1625,8 +1632,29 @@ class _VideoDetailPageState extends State<VideoDetailPage>
.episodes!
.reversed
.toList();
videoDetailController.seasonIndex.refresh();
videoDetailController.cid.refresh();
if (videoDetailController.reverseFromFirst.not) {
// keep current episode
videoDetailController.seasonIndex.refresh();
videoDetailController.cid.refresh();
} else {
// switch to first episode
dynamic episode = videoIntroController.videoDetail.value.ugcSeason!
.sections![videoDetailController.seasonIndex.value].episodes!.first;
if (episode.cid != videoDetailController.cid.value) {
videoIntroController.changeSeasonOrbangu(
episode is bangumi.EpisodeItem ? episode.epId : null,
episode.runtimeType.toString() == "EpisodeItem" ? episode.bvid : bvid,
episode.cid,
episode.runtimeType.toString() == "EpisodeItem" ? episode.aid : aid,
episode is video.EpisodeItem
? episode.arc?.pic
: episode is bangumi.EpisodeItem
? episode.cover
: null,
);
}
}
}
void showViewPoints() {

View File

@@ -148,6 +148,9 @@ class GStorage {
static bool get showArgueMsg =>
setting.get(SettingBoxKey.showArgueMsg, defaultValue: true);
static bool get reverseFromFirst =>
setting.get(SettingBoxKey.reverseFromFirst, defaultValue: true);
static List<double> get dynamicDetailRatio => List<double>.from(setting
.get(SettingBoxKey.dynamicDetailRatio, defaultValue: [60.0, 40.0]));
@@ -350,6 +353,7 @@ class SettingBoxKey {
horizontalMemberPage = 'horizontalMemberPage',
replyLengthLimit = 'replyLengthLimit',
showArgueMsg = 'showArgueMsg',
reverseFromFirst = 'reverseFromFirst',
// Sponsor Block
enableSponsorBlock = 'enableSponsorBlock',