mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
mod: add reverse from first option
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user