diff --git a/lib/common/widgets/list_sheet.dart b/lib/common/widgets/list_sheet.dart index 40ddc1e3b..c49e8a520 100644 --- a/lib/common/widgets/list_sheet.dart +++ b/lib/common/widgets/list_sheet.dart @@ -18,6 +18,7 @@ class ListSheet { required this.currentCid, required this.changeFucCall, required this.context, + this.scaffoldState, }); final dynamic episodes; @@ -26,20 +27,27 @@ class ListSheet { final int currentCid; final Function changeFucCall; final BuildContext context; + final ScaffoldState? scaffoldState; late PersistentBottomSheetController bottomSheetController; + Widget get listSheetContent => ListSheetContent( + episodes: episodes, + bvid: bvid, + aid: aid, + currentCid: currentCid, + changeFucCall: changeFucCall, + onClose: bottomSheetController.close, + ); + void buildShowBottomSheet() { - bottomSheetController = showBottomSheet( - context: context, - builder: (context) => ListSheetContent( - episodes: episodes, - bvid: bvid, - aid: aid, - currentCid: currentCid, - changeFucCall: changeFucCall, - onClose: bottomSheetController.close, - )); + bottomSheetController = scaffoldState?.showBottomSheet( + (context) => listSheetContent, + ) ?? + showBottomSheet( + context: context, + builder: (context) => listSheetContent, + ); } } @@ -118,9 +126,9 @@ class _ListSheetContentState extends State { widget.changeFucCall( episode.bvid, episode.cid, episode.aid, episode.cover); } else if (episode.runtimeType.toString() == "EpisodeItem") { - widget.changeFucCall(episode.bvid, episode.cid, episode.aid); + widget.changeFucCall(episode.bvid, episode.cid, episode.aid, null); } else { - widget.changeFucCall(widget.bvid!, episode.cid, widget.aid!); + widget.changeFucCall(widget.bvid!, episode.cid, widget.aid!, null); } }, dense: false, diff --git a/lib/pages/bangumi/introduction/view.dart b/lib/pages/bangumi/introduction/view.dart index ca75b2e36..3dae7f196 100644 --- a/lib/pages/bangumi/introduction/view.dart +++ b/lib/pages/bangumi/introduction/view.dart @@ -24,10 +24,13 @@ import 'widgets/intro_detail.dart'; class BangumiIntroPanel extends StatefulWidget { final int? cid; final String heroTag; + final Function showEpisodes; + const BangumiIntroPanel({ Key? key, this.cid, required this.heroTag, + required this.showEpisodes, }) : super(key: key); @override @@ -72,6 +75,7 @@ class _BangumiIntroPanelState extends State loadingStatus: false, bangumiDetail: loadingState.response, cid: cid, + showEpisodes: widget.showEpisodes, ) : loadingState is Error ? HttpError( @@ -82,6 +86,7 @@ class _BangumiIntroPanelState extends State loadingStatus: true, bangumiDetail: null, cid: cid, + showEpisodes: widget.showEpisodes, ); } } @@ -92,11 +97,13 @@ class BangumiInfo extends StatefulWidget { this.loadingStatus = false, this.bangumiDetail, this.cid, + required this.showEpisodes, }); final bool loadingStatus; final BangumiInfoModel? bangumiDetail; final int? cid; + final Function showEpisodes; @override State createState() => _BangumiInfoState(); @@ -342,6 +349,7 @@ class _BangumiInfoState extends State { ? bangumiItem!.episodes!.first.cid : widget.bangumiDetail!.episodes!.first.cid), changeFuc: bangumiIntroController.changeSeasonOrbangu, + showEpisodes: widget.showEpisodes, ) ], ], diff --git a/lib/pages/bangumi/widgets/bangumi_panel.dart b/lib/pages/bangumi/widgets/bangumi_panel.dart index 45e6273a4..cadb37372 100644 --- a/lib/pages/bangumi/widgets/bangumi_panel.dart +++ b/lib/pages/bangumi/widgets/bangumi_panel.dart @@ -6,7 +6,6 @@ import 'package:PiliPalaX/models/bangumi/info.dart'; import 'package:PiliPalaX/pages/video/detail/index.dart'; import 'package:PiliPalaX/utils/storage.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; -import 'package:PiliPalaX/common/widgets/list_sheet.dart'; class BangumiPanel extends StatefulWidget { const BangumiPanel({ @@ -14,11 +13,13 @@ class BangumiPanel extends StatefulWidget { required this.pages, this.cid, required this.changeFuc, + required this.showEpisodes, }); final List pages; final int? cid; final Function changeFuc; + final Function showEpisodes; @override State createState() => _BangumiPanelState(); @@ -113,18 +114,13 @@ class _BangumiPanelState extends State { height: 34, child: TextButton( style: ButtonStyle( - padding: MaterialStateProperty.all(EdgeInsets.zero), + padding: WidgetStateProperty.all(EdgeInsets.zero), ), - onPressed: () { - ListSheet( - episodes: widget.pages, - bvid: widget.pages[currentIndex].bvid!, - aid: widget.pages[currentIndex].aid!, - currentCid: cid, - changeFucCall: widget.changeFuc, - context: context) - .buildShowBottomSheet(); - }, + onPressed: () => widget.showEpisodes( + widget.pages, + widget.pages[currentIndex].bvid, + widget.pages[currentIndex].aid, + cid), child: Text( '全${widget.pages.length}话', style: const TextStyle(fontSize: 13), diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index 953f099d2..8065214f6 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -467,13 +467,16 @@ class VideoIntroController extends GetxController { } // 修改分P或番剧分集 - Future changeSeasonOrbangu(bvid, cid, aid) async { + Future changeSeasonOrbangu(bvid, cid, aid, cover) async { // 重新获取视频资源 final VideoDetailController videoDetailCtr = Get.find(tag: heroTag); videoDetailCtr.bvid = bvid; videoDetailCtr.oid.value = aid ?? IdUtils.bv2av(bvid); videoDetailCtr.cid.value = cid; + if (cover is String && cover.isNotEmpty) { + videoItem!['pic'] = cover; + } videoDetailCtr.danmakuCid.value = cid; videoDetailCtr.queryVideoUrl(); // 重新请求相关视频 @@ -559,7 +562,7 @@ class VideoIntroController extends GetxController { final int cid = episodes[prevIndex].cid!; final String rBvid = isPages ? bvid : episodes[prevIndex].bvid; final int rAid = isPages ? IdUtils.bv2av(bvid) : episodes[prevIndex].aid!; - changeSeasonOrbangu(rBvid, cid, rAid); + changeSeasonOrbangu(rBvid, cid, rAid, null); return true; } @@ -607,7 +610,7 @@ class VideoIntroController extends GetxController { final int cid = episodes[nextIndex].cid!; final String rBvid = isPages ? bvid : episodes[nextIndex].bvid; final int rAid = isPages ? IdUtils.bv2av(bvid) : episodes[nextIndex].aid!; - changeSeasonOrbangu(rBvid, cid, rAid); + changeSeasonOrbangu(rBvid, cid, rAid, null); return true; } diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index ff24bbe42..245c01aed 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -20,7 +20,6 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart import 'widgets/action_item.dart'; import 'widgets/action_row_item.dart'; import 'widgets/fav_panel.dart'; -import 'widgets/intro_detail.dart'; import 'widgets/page.dart'; import 'widgets/season.dart'; @@ -30,10 +29,12 @@ class VideoIntroPanel extends StatefulWidget { required this.heroTag, required this.showAiBottomSheet, required this.showIntroDetail, + required this.showEpisodes, }); final String heroTag; final Function showAiBottomSheet; final Function showIntroDetail; + final Function showEpisodes; @override State createState() => _VideoIntroPanelState(); @@ -82,6 +83,7 @@ class _VideoIntroPanelState extends State heroTag: heroTag, showAiBottomSheet: widget.showAiBottomSheet, showIntroDetail: widget.showIntroDetail, + showEpisodes: widget.showEpisodes, ) : VideoInfo( //key:herotag @@ -91,6 +93,7 @@ class _VideoIntroPanelState extends State heroTag: heroTag, showAiBottomSheet: widget.showAiBottomSheet, showIntroDetail: widget.showIntroDetail, + showEpisodes: widget.showEpisodes, )); } } @@ -101,6 +104,7 @@ class VideoInfo extends StatefulWidget { final String? heroTag; final Function showAiBottomSheet; final Function showIntroDetail; + final Function showEpisodes; const VideoInfo({ Key? key, @@ -109,6 +113,7 @@ class VideoInfo extends StatefulWidget { this.heroTag, required this.showAiBottomSheet, required this.showIntroDetail, + required this.showEpisodes, }) : super(key: key); @override @@ -433,6 +438,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ? videoIntroController.lastPlayCid.value : widget.videoDetail!.pages!.first.cid, changeFuc: videoIntroController.changeSeasonOrbangu, + showEpisodes: widget.showEpisodes, ), ) ], @@ -445,6 +451,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { cid: videoIntroController.lastPlayCid.value, bvid: videoIntroController.bvid, changeFuc: videoIntroController.changeSeasonOrbangu, + showEpisodes: widget.showEpisodes, )) ], ], diff --git a/lib/pages/video/detail/introduction/widgets/page.dart b/lib/pages/video/detail/introduction/widgets/page.dart index f30e406c1..ebb1ea063 100644 --- a/lib/pages/video/detail/introduction/widgets/page.dart +++ b/lib/pages/video/detail/introduction/widgets/page.dart @@ -1,6 +1,5 @@ import 'dart:math'; -import 'package:PiliPalaX/common/widgets/list_sheet.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/models/video_detail_res.dart'; @@ -16,12 +15,14 @@ class PagesPanel extends StatefulWidget { required this.bvid, required this.changeFuc, required this.heroTag, + required this.showEpisodes, }); final List pages; final int? cid; final String bvid; final Function changeFuc; final String heroTag; + final Function showEpisodes; @override State createState() => _PagesPanelState(); @@ -94,16 +95,8 @@ class _PagesPanelState extends State { style: ButtonStyle( padding: WidgetStateProperty.all(EdgeInsets.zero), ), - onPressed: () { - ListSheet( - episodes: episodes, - bvid: widget.bvid, - aid: IdUtils.bv2av(widget.bvid), - currentCid: cid, - changeFucCall: widget.changeFuc, - context: context, - ).buildShowBottomSheet(); - }, + onPressed: () => widget.showEpisodes( + episodes, widget.bvid, IdUtils.bv2av(widget.bvid), cid), child: Text( '共${widget.pages.length}集', style: const TextStyle(fontSize: 13), diff --git a/lib/pages/video/detail/introduction/widgets/season.dart b/lib/pages/video/detail/introduction/widgets/season.dart index a04a8a882..63dc55e7b 100644 --- a/lib/pages/video/detail/introduction/widgets/season.dart +++ b/lib/pages/video/detail/introduction/widgets/season.dart @@ -1,4 +1,3 @@ -import 'package:PiliPalaX/common/widgets/list_sheet.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/models/video_detail_res.dart'; @@ -11,11 +10,13 @@ class SeasonPanel extends StatefulWidget { this.cid, required this.changeFuc, required this.heroTag, + required this.showEpisodes, }); final UgcSeason ugcSeason; final int? cid; final Function changeFuc; final String heroTag; + final Function showEpisodes; @override State createState() => _SeasonPanelState(); @@ -102,16 +103,7 @@ class _SeasonPanelState extends State { borderRadius: BorderRadius.circular(6), clipBehavior: Clip.hardEdge, child: InkWell( - onTap: () { - ListSheet( - episodes: episodes, - // bvid: IdUtils.av2bv(episodes!.first.aid!), - // aid: episodes!.first.aid!, - currentCid: cid, - changeFucCall: widget.changeFuc, - context: context) - .buildShowBottomSheet(); - }, + onTap: () => widget.showEpisodes(episodes, null, null, cid), child: Padding( padding: const EdgeInsets.fromLTRB(8, 12, 8, 12), child: Row( diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index ca582fa08..9bf40a196 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:math'; import 'package:PiliPalaX/common/constants.dart'; +import 'package:PiliPalaX/common/widgets/list_sheet.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/models/common/reply_type.dart'; import 'package:PiliPalaX/pages/video/detail/introduction/widgets/intro_detail.dart'; @@ -420,6 +421,7 @@ class _VideoDetailPageState extends State Widget tabbarBuild([ bool needIndicator = true, String introText = '简介', + bool isSingle = false, ]) { return Container( width: double.infinity, @@ -439,6 +441,9 @@ class _VideoDetailPageState extends State flex: 1, child: Obx( () => TabBar( + labelColor: needIndicator + ? null + : Theme.of(context).colorScheme.onSurface, indicatorColor: needIndicator ? null : Colors.transparent, padding: EdgeInsets.zero, controller: videoDetailController.tabCtr, @@ -447,7 +452,9 @@ class _VideoDetailPageState extends State horizontal: 10.0), // 设置每个标签的宽度 dividerColor: Colors.transparent, onTap: (value) { - if (!needIndicator || + if (isSingle) { + _videoReplyController.animateToTop(); + } else if (!needIndicator || !videoDetailController.tabCtr.indexIsChanging) { if (value == 0) { _introController.animToTop(); @@ -457,7 +464,7 @@ class _VideoDetailPageState extends State } }, tabs: [ - Tab(text: introText), + if (!isSingle) Tab(text: introText), Tab( text: '评论${_videoReplyController.count.value == -1 ? '' : ' ${_videoReplyController.count.value}'}', @@ -718,14 +725,17 @@ class _VideoDetailPageState extends State heroTag: heroTag, showAiBottomSheet: showAiBottomSheet, showIntroDetail: showIntroDetail, + showEpisodes: showEpisodes, ), ] else if (videoDetailController .videoType == SearchType.media_bangumi) ...[ Obx(() => BangumiIntroPanel( - heroTag: heroTag, - cid: - videoDetailController.cid.value)), + heroTag: heroTag, + cid: + videoDetailController.cid.value, + showEpisodes: showEpisodes, + )), ], SliverToBoxAdapter( child: Padding( @@ -837,12 +847,15 @@ class _VideoDetailPageState extends State heroTag: heroTag, showAiBottomSheet: showAiBottomSheet, showIntroDetail: showIntroDetail, + showEpisodes: showEpisodes, ), ] else if (videoDetailController.videoType == SearchType.media_bangumi) ...[ Obx(() => BangumiIntroPanel( - heroTag: heroTag, - cid: videoDetailController.cid.value)), + heroTag: heroTag, + cid: videoDetailController.cid.value, + showEpisodes: showEpisodes, + )), ], SliverToBoxAdapter( child: Padding( @@ -948,13 +961,16 @@ class _VideoDetailPageState extends State heroTag: heroTag, showAiBottomSheet: showAiBottomSheet, showIntroDetail: showIntroDetail, + showEpisodes: showEpisodes, ), RelatedVideoPanel(heroTag: heroTag), ] else if (videoDetailController.videoType == SearchType.media_bangumi) ...[ Obx(() => BangumiIntroPanel( - heroTag: heroTag, - cid: videoDetailController.cid.value)), + heroTag: heroTag, + cid: videoDetailController.cid.value, + showEpisodes: showEpisodes, + )), ] ], )), @@ -988,12 +1004,16 @@ class _VideoDetailPageState extends State heroTag: heroTag, showAiBottomSheet: showAiBottomSheet, showIntroDetail: showIntroDetail, + showEpisodes: showEpisodes, ), RelatedVideoPanel(heroTag: heroTag), ] else if (videoDetailController.videoType == SearchType.media_bangumi) ...[ Obx(() => BangumiIntroPanel( - heroTag: heroTag, cid: videoDetailController.cid.value)), + heroTag: heroTag, + cid: videoDetailController.cid.value, + showEpisodes: showEpisodes, + )), ] ], )), @@ -1046,9 +1066,16 @@ class _VideoDetailPageState extends State ), ), Expanded( - child: Scaffold( - key: scaffoldKey, - body: videoReplyPanel, + child: Expanded( + child: Scaffold( + key: scaffoldKey, + body: Column( + children: [ + tabbarBuild(false, '', true), + Expanded(child: videoReplyPanel), + ], + ), + ), ), ), // Expanded( @@ -1164,13 +1191,16 @@ class _VideoDetailPageState extends State heroTag: heroTag, showAiBottomSheet: showAiBottomSheet, showIntroDetail: showIntroDetail, + showEpisodes: showEpisodes, ), // RelatedVideoPanel(heroTag: heroTag), ] else if (videoDetailController.videoType == SearchType.media_bangumi) ...[ Obx(() => BangumiIntroPanel( - heroTag: heroTag, - cid: videoDetailController.cid.value)), + heroTag: heroTag, + cid: videoDetailController.cid.value, + showEpisodes: showEpisodes, + )), ] ], ), @@ -1193,7 +1223,13 @@ class _VideoDetailPageState extends State key: scaffoldKey, body: Column( children: [ - tabbarBuild(true, '相关视频'), + tabbarBuild( + videoDetailController.videoType != + SearchType.media_bangumi, + '相关视频', + videoDetailController.videoType == + SearchType.media_bangumi, + ), Expanded( child: TabBarView( physics: const BouncingScrollPhysics(), @@ -1408,4 +1444,16 @@ class _VideoDetailPageState extends State scaffoldKey.currentState?.showBottomSheet( enableDrag: true, (context) => IntroDetail(videoDetail: videoDetail)); } + + showEpisodes(episodes, bvid, aid, cid) { + ListSheet( + episodes: episodes, + bvid: bvid, + aid: aid, + currentCid: cid, + changeFucCall: videoIntroController.changeSeasonOrbangu, + context: context, + scaffoldState: scaffoldKey.currentState, + ).buildShowBottomSheet(); + } }