diff --git a/lib/models_new/media_list/media_list.dart b/lib/models_new/media_list/media_list.dart index d8d707619..54662209b 100644 --- a/lib/models_new/media_list/media_list.dart +++ b/lib/models_new/media_list/media_list.dart @@ -5,7 +5,6 @@ import 'package:PiliPlus/models_new/media_list/ogv_info.dart'; import 'package:PiliPlus/models_new/media_list/page.dart'; import 'package:PiliPlus/models_new/media_list/rights.dart'; import 'package:PiliPlus/models_new/video/video_detail/episode.dart'; -import 'package:PiliPlus/utils/extension.dart'; class MediaListItemModel extends BaseEpisodeItem { @override @@ -35,6 +34,8 @@ class MediaListItemModel extends BaseEpisodeItem { bool? forbidFav; int? moreType; int? businessOid; + @override + int? get cid => pages?.firstOrNull?.id; MediaListItemModel({ super.aid, @@ -105,6 +106,5 @@ class MediaListItemModel extends BaseEpisodeItem { forbidFav = json['forbid_fav'] as bool?; moreType = json['more_type'] as int?; businessOid = json['business_oid'] as int?; - cid = pages.getOrNull((page ?? 1) - 1)?.id; } } diff --git a/lib/pages/fav_detail/controller.dart b/lib/pages/fav_detail/controller.dart index 3a9e95a74..f7cabf17a 100644 --- a/lib/pages/fav_detail/controller.dart +++ b/lib/pages/fav_detail/controller.dart @@ -24,7 +24,7 @@ mixin BaseFavController bool get isOwner; int get mediaId; - ValueChanged? updateLength; + ValueChanged? updateCount; void onViewFav(FavDetailItemModel item, int? index); @@ -37,7 +37,7 @@ mixin BaseFavController loadingState ..value.data!.removeAt(index) ..refresh(); - updateLength?.call(1); + updateCount?.call(1); SmartDialog.showToast('取消收藏'); } else { SmartDialog.showToast(result['msg']); @@ -59,7 +59,7 @@ mixin BaseFavController delIds: mediaId.toString(), ); if (result['status']) { - updateLength?.call(removeList.length); + updateCount?.call(removeList.length); afterDelete(removeList); SmartDialog.showToast('取消收藏'); } else { @@ -124,7 +124,7 @@ class FavDetailController } @override - ValueChanged? get updateLength => + ValueChanged? get updateCount => (count) => folderInfo ..value.mediaCount -= count ..refresh(); @@ -147,9 +147,6 @@ class FavDetailController if (element.ugc?.firstCid == null) { continue; } else { - if (element.bvid != list.first.bvid) { - SmartDialog.showToast('已跳过不支持播放的视频'); - } onViewFav(element, null); break; } diff --git a/lib/pages/later/child_view.dart b/lib/pages/later/child_view.dart index 0ae04c2b9..ddca2e23e 100644 --- a/lib/pages/later/child_view.dart +++ b/lib/pages/later/child_view.dart @@ -76,6 +76,7 @@ class _LaterViewChildPageState extends State } var videoItem = response[index]; return VideoCardHLater( + index: index, videoItem: videoItem, ctr: _laterController, onViewLater: (cid) { @@ -97,12 +98,6 @@ class _LaterViewChildPageState extends State }, ); }, - onRemove: () => _laterController.toViewDel( - context, - index, - videoItem.aid, - onSuccess: () => _laterController.updateLength?.call(1), - ), ); }, childCount: response!.length, diff --git a/lib/pages/later/controller.dart b/lib/pages/later/controller.dart index 3d4644c77..9a90d4e02 100644 --- a/lib/pages/later/controller.dart +++ b/lib/pages/later/controller.dart @@ -22,7 +22,7 @@ mixin BaseLaterController CommonListController, CommonMultiSelectMixin, DeleteItemMixin { - ValueChanged? updateLength; + ValueChanged? updateCount; @override void onRemove() { @@ -37,7 +37,7 @@ mixin BaseLaterController aids: removeList.map((item) => item.aid).join(','), ); if (res['status']) { - updateLength?.call(removeList.length); + updateCount?.call(removeList.length); afterDelete(removeList); } SmartDialog.dismiss(); @@ -50,9 +50,8 @@ mixin BaseLaterController void toViewDel( BuildContext context, int index, - int? aid, { - VoidCallback? onSuccess, - }) { + int? aid, + ) { showDialog( context: context, builder: (context) { @@ -75,7 +74,7 @@ mixin BaseLaterController loadingState ..value.data!.removeAt(index) ..refresh(); - onSuccess?.call(); + updateCount?.call(1); } SmartDialog.showToast(res['msg']); }, @@ -169,9 +168,6 @@ class LaterController extends MultiSelectController if (item.cid == null || item.pgcLabel?.isNotEmpty == true) { continue; } else { - if (item.bvid != list.first.bvid) { - SmartDialog.showToast('已跳过不支持播放的视频'); - } PageUtils.toVideoPage( bvid: item.bvid, cid: item.cid!, @@ -192,7 +188,7 @@ class LaterController extends MultiSelectController } @override - ValueChanged? get updateLength => + ValueChanged? get updateCount => (count) => baseCtr.counts[laterViewType] = baseCtr.counts[laterViewType]! - count; diff --git a/lib/pages/later/widgets/video_card_h_later.dart b/lib/pages/later/widgets/video_card_h_later.dart index 8cc54326a..35433c657 100644 --- a/lib/pages/later/widgets/video_card_h_later.dart +++ b/lib/pages/later/widgets/video_card_h_later.dart @@ -21,14 +21,14 @@ class VideoCardHLater extends StatelessWidget { const VideoCardHLater({ super.key, required this.ctr, + required this.index, required this.videoItem, - this.onViewLater, - required this.onRemove, + required this.onViewLater, }); + final int index; final BaseLaterController ctr; final LaterItemModel videoItem; - final ValueChanged? onViewLater; - final VoidCallback onRemove; + final ValueChanged onViewLater; @override Widget build(BuildContext context) { @@ -72,7 +72,7 @@ class VideoCardHLater extends StatelessWidget { bvid: videoItem.bvid, ); if (cid != null) { - onViewLater!(cid); + onViewLater(cid); } } catch (err) { SmartDialog.showToast(err.toString()); @@ -192,7 +192,7 @@ class VideoCardHLater extends StatelessWidget { iconButton( tooltip: '移除', context: context, - onPressed: onRemove, + onPressed: () => ctr..toViewDel(context, index, videoItem.aid), icon: Icons.clear, iconColor: theme.colorScheme.outline, bgColor: Colors.transparent, diff --git a/lib/pages/later_search/view.dart b/lib/pages/later_search/view.dart index e41d0cf2c..27beb1da7 100644 --- a/lib/pages/later_search/view.dart +++ b/lib/pages/later_search/view.dart @@ -38,6 +38,7 @@ class _LaterSearchPageState } final item = list[index]; return VideoCardHLater( + index: index, videoItem: item, ctr: controller, onViewLater: (cid) { @@ -57,11 +58,6 @@ class _LaterSearchPageState }, ); }, - onRemove: () => controller.toViewDel( - context, - index, - item.aid!, - ), ); }), ); diff --git a/lib/pages/member_video/controller.dart b/lib/pages/member_video/controller.dart index 6f0f48e3a..8607aa59e 100644 --- a/lib/pages/member_video/controller.dart +++ b/lib/pages/member_video/controller.dart @@ -11,7 +11,6 @@ import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/id_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart'; -import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; class MemberVideoCtr @@ -186,9 +185,6 @@ class MemberVideoCtr if (element.cid == null) { continue; } else { - if (element.bvid != list.first.bvid) { - SmartDialog.showToast('已跳过不支持播放的视频'); - } bool desc = seasonId != null ? false : true; desc = (seasonId != null || seriesId != null) && diff --git a/lib/pages/video/introduction/ugc/controller.dart b/lib/pages/video/introduction/ugc/controller.dart index 354a7acd5..3773d3a41 100644 --- a/lib/pages/video/introduction/ugc/controller.dart +++ b/lib/pages/video/introduction/ugc/controller.dart @@ -534,17 +534,16 @@ class UgcIntroController extends CommonIntroController with ReloadMixin { /// 播放上一个 @override - bool prevPlay([bool skipPages = false]) { + bool prevPlay([bool skipPart = false]) { final List episodes = []; - bool isPages = false; + bool isPart = false; final videoDetailCtr = Get.find(tag: heroTag); final videoDetail = this.videoDetail.value; - if (!skipPages && (videoDetail.pages?.length ?? 0) > 1) { - isPages = true; - final List pages = videoDetail.pages!; - episodes.addAll(pages); + if (!skipPart && (videoDetail.pages?.length ?? 0) > 1) { + isPart = true; + episodes.addAll(videoDetail.pages!); } else if (videoDetailCtr.isPlayAll) { episodes.addAll(videoDetailCtr.mediaList); } else if (videoDetail.ugcSeason != null) { @@ -559,18 +558,19 @@ class UgcIntroController extends CommonIntroController with ReloadMixin { final int currentIndex = episodes.indexWhere( (e) => e.cid == - (skipPages + (skipPart ? videoDetail.isPageReversed == true ? videoDetail.pages!.last.cid : videoDetail.pages!.first.cid - : cid.value), + : this.cid.value), ); + int prevIndex = currentIndex - 1; final PlayRepeat playRepeat = videoDetailCtr.plPlayerController.playRepeat; // 列表循环 if (prevIndex < 0) { - if (isPages && + if (isPart && (videoDetailCtr.isPlayAll || videoDetail.ugcSeason != null)) { return prevPlay(true); } @@ -580,22 +580,36 @@ class UgcIntroController extends CommonIntroController with ReloadMixin { return false; } } - onChangeEpisode(episodes[prevIndex]); - return true; + + int? cid = episodes[prevIndex].cid; + while (cid == null) { + prevIndex--; + if (prevIndex < 0) { + return false; + } + cid = episodes[prevIndex].cid; + } + + if (cid != this.cid.value) { + onChangeEpisode(episodes[prevIndex]); + return true; + } else { + return false; + } } /// 列表循环或者顺序播放时,自动播放下一个 @override - bool nextPlay([bool skipPages = false]) { + bool nextPlay([bool skipPart = false]) { try { final List episodes = []; - bool isPages = false; + bool isPart = false; final videoDetailCtr = Get.find(tag: heroTag); final videoDetail = this.videoDetail.value; // part -> playall -> season - if (!skipPages && (videoDetail.pages?.length ?? 0) > 1) { - isPages = true; + if (!skipPart && (videoDetail.pages?.length ?? 0) > 1) { + isPart = true; final List pages = videoDetail.pages!; episodes.addAll(pages); } else if (videoDetailCtr.isPlayAll) { @@ -623,16 +637,16 @@ class UgcIntroController extends CommonIntroController with ReloadMixin { final int currentIndex = episodes.indexWhere( (e) => e.cid == - (skipPages + (skipPart ? videoDetail.isPageReversed == true ? videoDetail.pages!.last.cid : videoDetail.pages!.first.cid - : videoDetailCtr.cid.value), + : this.cid.value), ); int nextIndex = currentIndex + 1; - if (!isPages && + if (!isPart && videoDetailCtr.isPlayAll && currentIndex == episodes.length - 2) { videoDetailCtr.getMediaList(); @@ -640,7 +654,7 @@ class UgcIntroController extends CommonIntroController with ReloadMixin { // 列表循环 if (nextIndex >= episodes.length) { - if (isPages && + if (isPart && (videoDetailCtr.isPlayAll || videoDetail.ugcSeason != null)) { return nextPlay(true); } @@ -655,18 +669,21 @@ class UgcIntroController extends CommonIntroController with ReloadMixin { } } - int cid = episodes[nextIndex].cid!; - - while (cid == -1) { - SmartDialog.showToast('当前视频暂不支持播放,自动跳过'); + int? cid = episodes[nextIndex].cid; + while (cid == null) { nextIndex++; if (nextIndex >= episodes.length) { return false; } - cid = episodes[nextIndex].cid!; + cid = episodes[nextIndex].cid; + } + + if (cid != this.cid.value) { + onChangeEpisode(episodes[nextIndex]); + return true; + } else { + return false; } - onChangeEpisode(episodes[nextIndex]); - return true; } catch (_) { return false; } diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index 8ac7a72d6..13c674cc2 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -2011,7 +2011,7 @@ class _VideoDetailPageVState extends State } void showEpisodes([int? index, season, episodes, bvid, aid, cid]) { - if (bvid == null) { + if (cid == null) { videoDetailController.showMediaListPanel(context); return; } diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 6fc611f1b..c17fc24ef 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -7,7 +7,6 @@ import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.da import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart'; import 'package:PiliPlus/models/common/super_resolution_type.dart'; import 'package:PiliPlus/models_new/video/video_detail/episode.dart'; -import 'package:PiliPlus/models_new/video/video_detail/page.dart'; import 'package:PiliPlus/models_new/video/video_detail/section.dart'; import 'package:PiliPlus/models_new/video/video_shot/data.dart'; import 'package:PiliPlus/pages/common/common_intro_controller.dart'; @@ -257,11 +256,14 @@ class _PLVideoPlayerState extends State // 动态构建底部控制条 Widget buildBottomControl() { final videoDetail = introController.videoDetail.value; - bool isSeason = videoDetail.ugcSeason != null; - bool isPage = videoDetail.pages != null && videoDetail.pages!.length > 1; - bool isPgc = pgcIntroController != null; - bool anySeason = isSeason || isPage || isPgc; - double widgetWidth = isFullScreen && context.isLandscape ? 42 : 35; + final isSeason = videoDetail.ugcSeason != null; + final isPart = videoDetail.pages != null && videoDetail.pages!.length > 1; + final isPgc = pgcIntroController != null; + final anySeason = isSeason || isPart || isPgc; + final isPlayAll = widget.videoDetailController?.isPlayAll == true; + + final double widgetWidth = isFullScreen && context.isLandscape ? 42 : 35; + Map videoProgressWidgets = { /// 上一集 BottomControlType.pre: Container( @@ -460,7 +462,8 @@ class _PLVideoPlayerState extends State color: Colors.white, ), onTap: () { - if (!anySeason || widget.videoDetailController?.isPlayAll == true) { + // part -> playAll -> season(pgc) + if (!anySeason || !isPart) { widget.showEpisodes?.call(); return; } @@ -481,9 +484,8 @@ class _PLVideoPlayerState extends State } } } - } else if (isPage) { - final List pages = videoDetail.pages!; - episodes = pages; + } else if (isPart) { + episodes = videoDetail.pages!; } else if (isPgc) { episodes = pgcIntroController!.pgcItem.episodes!; } @@ -493,7 +495,7 @@ class _PLVideoPlayerState extends State isSeason ? null : episodes, bvid, IdUtils.bv2av(bvid), - isSeason && isPage + isSeason && isPart ? widget.videoDetailController?.seasonCid ?? currentCid : currentCid, ); @@ -642,7 +644,7 @@ class _PLVideoPlayerState extends State List userSpecifyItemLeft = [ BottomControlType.playOrPause, BottomControlType.time, - if (anySeason || widget.videoDetailController?.isPlayAll == true) ...[ + if (anySeason || isPlayAll) ...[ BottomControlType.pre, BottomControlType.next, ], @@ -652,8 +654,7 @@ class _PLVideoPlayerState extends State BottomControlType.dmChart, BottomControlType.superResolution, BottomControlType.viewPoints, - if (anySeason || widget.videoDetailController?.isPlayAll == true) - BottomControlType.episode, + if (anySeason || isPlayAll) BottomControlType.episode, if (isFullScreen) BottomControlType.fit, BottomControlType.subtitle, BottomControlType.speed,