Merge branch 'fix-seasonChange'

This commit is contained in:
guozhigq
2024-11-10 12:45:29 +08:00
8 changed files with 369 additions and 96 deletions

View File

@ -3,7 +3,9 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/http/video.dart';
import 'package:pilipala/models/video_detail_res.dart'; import 'package:pilipala/models/video_detail_res.dart';
import 'package:pilipala/pages/video/detail/index.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
import 'package:scrollview_observer/scrollview_observer.dart'; import 'package:scrollview_observer/scrollview_observer.dart';
import '../models/common/video_episode_type.dart'; import '../models/common/video_episode_type.dart';
@ -20,6 +22,8 @@ class EpisodeBottomSheet {
final double? sheetHeight; final double? sheetHeight;
bool isFullScreen = false; bool isFullScreen = false;
final UgcSeason? ugcSeason; final UgcSeason? ugcSeason;
final int? currentEpisodeIndex;
final int? currentIndex;
EpisodeBottomSheet({ EpisodeBottomSheet({
required this.episodes, required this.episodes,
@ -30,6 +34,8 @@ class EpisodeBottomSheet {
this.sheetHeight, this.sheetHeight,
this.isFullScreen = false, this.isFullScreen = false,
this.ugcSeason, this.ugcSeason,
this.currentEpisodeIndex,
this.currentIndex,
}); });
Widget buildShowContent() { Widget buildShowContent() {
@ -42,6 +48,8 @@ class EpisodeBottomSheet {
sheetHeight: sheetHeight, sheetHeight: sheetHeight,
isFullScreen: isFullScreen, isFullScreen: isFullScreen,
ugcSeason: ugcSeason, ugcSeason: ugcSeason,
currentEpisodeIndex: currentEpisodeIndex,
currentIndex: currentIndex,
); );
} }
@ -67,6 +75,8 @@ class PagesBottomSheet extends StatefulWidget {
this.sheetHeight, this.sheetHeight,
this.isFullScreen = false, this.isFullScreen = false,
this.ugcSeason, this.ugcSeason,
this.currentEpisodeIndex,
this.currentIndex,
}); });
final List<dynamic> episodes; final List<dynamic> episodes;
@ -77,41 +87,37 @@ class PagesBottomSheet extends StatefulWidget {
final double? sheetHeight; final double? sheetHeight;
final bool isFullScreen; final bool isFullScreen;
final UgcSeason? ugcSeason; final UgcSeason? ugcSeason;
final int? currentEpisodeIndex;
final int? currentIndex;
@override @override
State<PagesBottomSheet> createState() => _PagesBottomSheetState(); State<PagesBottomSheet> createState() => _PagesBottomSheetState();
} }
class _PagesBottomSheetState extends State<PagesBottomSheet> { class _PagesBottomSheetState extends State<PagesBottomSheet>
with TickerProviderStateMixin {
final ScrollController _listScrollController = ScrollController(); final ScrollController _listScrollController = ScrollController();
late ListObserverController _listObserverController; late ListObserverController _listObserverController;
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
late int currentIndex; late int currentIndex;
TabController? tabController;
List<ListObserverController>? _listObserverControllerList;
List<ScrollController>? _listScrollControllerList;
final String heroTag = Get.arguments['heroTag'];
VideoDetailController? _videoDetailController;
late RxInt isSubscribe = (-1).obs;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
currentIndex = currentIndex = widget.currentIndex ??
widget.episodes.indexWhere((dynamic e) => e.cid == widget.currentCid); widget.episodes.indexWhere((dynamic e) => e.cid == widget.currentCid);
_listObserverController = _scrollToInit();
ListObserverController(controller: _listScrollController); _scrollPositionInit();
if (widget.dataType == VideoEpidoesType.videoEpisode) { if (widget.dataType == VideoEpidoesType.videoEpisode) {
_listObserverController.initialIndexModel = ObserverIndexPositionModel( _videoDetailController = Get.find<VideoDetailController>(tag: heroTag);
index: currentIndex, _getSubscribeStatus();
isFixedHeight: true,
);
} }
WidgetsBinding.instance.addPostFrameCallback((_) {
if (widget.dataType != VideoEpidoesType.videoEpisode) {
double itemHeight = (widget.isFullScreen
? 400
: Get.size.width - 3 * StyleString.safeSpace) /
5.2;
double offset = ((currentIndex - 1) / 2).ceil() * itemHeight;
_scrollController.jumpTo(offset);
}
});
} }
String prefix() { String prefix() {
@ -126,9 +132,110 @@ class _PagesBottomSheetState extends State<PagesBottomSheet> {
return '选集'; return '选集';
} }
// 滚动器初始化
void _scrollToInit() {
/// 单个
_listObserverController =
ListObserverController(controller: _listScrollController);
if (widget.dataType == VideoEpidoesType.videoEpisode &&
widget.ugcSeason?.sections != null &&
widget.ugcSeason!.sections!.length > 1) {
tabController = TabController(
length: widget.ugcSeason!.sections!.length,
vsync: this,
initialIndex: widget.currentEpisodeIndex ?? 0,
);
/// 多tab
_listScrollControllerList = List.generate(
widget.ugcSeason!.sections!.length,
(index) {
return ScrollController();
},
);
_listObserverControllerList = List.generate(
widget.ugcSeason!.sections!.length,
(index) {
return ListObserverController(
controller: _listScrollControllerList![index],
);
},
);
}
}
// 滚动器位置初始化
void _scrollPositionInit() {
if (widget.dataType == VideoEpidoesType.videoEpisode) {
// 单个 多tab
if (widget.ugcSeason?.sections != null) {
if (widget.ugcSeason!.sections!.length == 1) {
_listObserverController.initialIndexModel =
ObserverIndexPositionModel(
index: currentIndex,
isFixedHeight: true,
);
} else {
_listObserverControllerList![widget.currentEpisodeIndex!]
.initialIndexModel = ObserverIndexPositionModel(
index: currentIndex,
isFixedHeight: true,
);
}
}
}
WidgetsBinding.instance.addPostFrameCallback((_) {
if (widget.dataType != VideoEpidoesType.videoEpisode) {
double itemHeight = (widget.isFullScreen
? 400
: Get.size.width - 3 * StyleString.safeSpace) /
5.2;
double offset = ((currentIndex - 1) / 2).ceil() * itemHeight;
_scrollController.jumpTo(offset);
}
});
}
// 获取订阅状态
void _getSubscribeStatus() async {
var res =
await VideoHttp.getSubscribeStatus(bvid: _videoDetailController!.bvid);
if (res['status']) {
isSubscribe.value = res['data']['season_fav'] ? 1 : 0;
}
}
// 更改订阅状态
void _changeSubscribeStatus() async {
if (isSubscribe.value == -1) {
return;
}
dynamic result = await VideoHttp.seasonFav(
isFav: isSubscribe.value == 1,
seasonId: widget.ugcSeason!.id,
);
if (result['status']) {
SmartDialog.showToast(isSubscribe.value == 1 ? '取消订阅成功' : '订阅成功');
isSubscribe.value = isSubscribe.value == 1 ? 0 : 1;
} else {
SmartDialog.showToast(result['msg']);
}
}
@override @override
void dispose() { void dispose() {
_listObserverController.controller?.dispose(); try {
_listObserverController.controller?.dispose();
_listScrollController.dispose();
for (var element in _listObserverControllerList!) {
element.controller?.dispose();
}
for (var element in _listScrollControllerList!) {
element.dispose();
}
} catch (_) {}
super.dispose(); super.dispose();
} }
@ -145,36 +252,44 @@ class _PagesBottomSheetState extends State<PagesBottomSheet> {
isFullScreen: widget.isFullScreen, isFullScreen: widget.isFullScreen,
), ),
if (widget.ugcSeason != null) ...[ if (widget.ugcSeason != null) ...[
UgcSeasonBuild(ugcSeason: widget.ugcSeason!), UgcSeasonBuild(
ugcSeason: widget.ugcSeason!,
isSubscribe: isSubscribe,
changeFucCall: _changeSubscribeStatus,
),
], ],
Expanded( Expanded(
child: Material( child: Material(
child: widget.dataType == VideoEpidoesType.videoEpisode child: widget.dataType == VideoEpidoesType.videoEpisode
? ListViewObserver( ? (widget.ugcSeason!.sections!.length == 1
controller: _listObserverController, ? ListViewObserver(
child: ListView.builder( controller: _listObserverController,
controller: _listScrollController, child: ListView.builder(
itemCount: widget.episodes.length + 1, controller: _listScrollController,
itemBuilder: (BuildContext context, int index) { itemCount: widget.episodes.length + 1,
bool isLastItem = index == widget.episodes.length; itemBuilder: (BuildContext context, int index) {
bool isCurrentIndex = currentIndex == index; bool isLastItem =
return isLastItem index == widget.episodes.length;
? SizedBox( bool isCurrentIndex = currentIndex == index;
height: return isLastItem
MediaQuery.of(context).padding.bottom + ? SizedBox(
height: MediaQuery.of(context)
.padding
.bottom +
20, 20,
) )
: EpisodeListItem( : EpisodeListItem(
episode: widget.episodes[index], episode: widget.episodes[index],
index: index, index: index,
isCurrentIndex: isCurrentIndex, isCurrentIndex: isCurrentIndex,
dataType: widget.dataType, dataType: widget.dataType,
changeFucCall: widget.changeFucCall, changeFucCall: widget.changeFucCall,
isFullScreen: widget.isFullScreen, isFullScreen: widget.isFullScreen,
); );
}, },
), ),
) )
: buildTabBar())
: Padding( : Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 12.0), // 设置左右间距为12 horizontal: 12.0), // 设置左右间距为12
@ -206,6 +321,61 @@ class _PagesBottomSheetState extends State<PagesBottomSheet> {
); );
}); });
} }
Widget buildTabBar() {
return Column(
children: [
TabBar(
controller: tabController,
isScrollable: true,
indicatorSize: TabBarIndicatorSize.label,
tabAlignment: TabAlignment.start,
splashBorderRadius: BorderRadius.circular(4),
tabs: [
...widget.ugcSeason!.sections!.map((SectionItem section) {
return Tab(
text: section.title,
);
}).toList()
],
),
Expanded(
child: TabBarView(
controller: tabController,
children: [
...widget.ugcSeason!.sections!.map((SectionItem section) {
final int fIndex = widget.ugcSeason!.sections!.indexOf(section);
return ListViewObserver(
controller: _listObserverControllerList![fIndex],
child: ListView.builder(
controller: _listScrollControllerList![fIndex],
itemCount: section.episodes!.length + 1,
itemBuilder: (BuildContext context, int index) {
final bool isLastItem = index == section.episodes!.length;
return isLastItem
? SizedBox(
height:
MediaQuery.of(context).padding.bottom + 20,
)
: EpisodeListItem(
episode: section.episodes![index], // 调整索引
index: index, // 调整索引
isCurrentIndex: widget.currentCid ==
section.episodes![index].cid,
dataType: widget.dataType,
changeFucCall: widget.changeFucCall,
isFullScreen: widget.isFullScreen,
);
},
),
);
}).toList()
],
),
),
],
);
}
} }
class TitleBar extends StatelessWidget { class TitleBar extends StatelessWidget {
@ -507,16 +677,22 @@ class EpisodeGridItem extends StatelessWidget {
class UgcSeasonBuild extends StatelessWidget { class UgcSeasonBuild extends StatelessWidget {
final UgcSeason ugcSeason; final UgcSeason ugcSeason;
final RxInt isSubscribe;
final Function changeFucCall;
const UgcSeasonBuild({ const UgcSeasonBuild({
Key? key, Key? key,
required this.ugcSeason, required this.ugcSeason,
required this.isSubscribe,
required this.changeFucCall,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData t = Theme.of(context);
final Color outline = t.colorScheme.outline;
return Container( return Container(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 8), padding: const EdgeInsets.fromLTRB(12, 0, 12, 0),
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -542,17 +718,30 @@ class UgcSeasonBuild extends StatelessWidget {
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.outline)), color: Theme.of(context).colorScheme.outline)),
), ),
// SizedBox( Obx(
// height: 32, () => isSubscribe.value == -1
// child: FilledButton.tonal( ? const SizedBox(height: 32)
// onPressed: () {}, : SizedBox(
// style: ButtonStyle( height: 32,
// padding: MaterialStateProperty.all(EdgeInsets.zero), child: FilledButton.tonal(
// ), onPressed: () => changeFucCall.call(),
// child: const Text('订阅'), style: TextButton.styleFrom(
// ), padding: const EdgeInsets.only(
// ), left: 8,
// const SizedBox(width: 6), right: 8,
),
foregroundColor: isSubscribe.value == 1
? outline
: t.colorScheme.onPrimary,
backgroundColor: isSubscribe.value == 1
? t.colorScheme.onInverseSurface
: t.colorScheme.primary, // 设置按钮背景色
),
child: Text(isSubscribe.value == 1 ? '已订阅' : '订阅'),
),
),
),
const SizedBox(width: 6),
], ],
), ),
], ],

View File

@ -609,4 +609,10 @@ class Api {
/// @我的 /// @我的
static const String messageAtAPi = '/x/msgfeed/at?'; static const String messageAtAPi = '/x/msgfeed/at?';
/// 订阅
static const String confirmSub = '/x/v3/fav/season/fav';
/// 订阅状态
static const String videoRelation = '/x/web-interface/archive/relation';
} }

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:pilipala/utils/id_utils.dart';
import '../common/constants.dart'; import '../common/constants.dart';
import '../models/common/reply_type.dart'; import '../models/common/reply_type.dart';
import '../models/home/rcmd/result.dart'; import '../models/home/rcmd/result.dart';
@ -560,4 +561,50 @@ class VideoHttp {
final List body = res.data['body']; final List body = res.data['body'];
return {'content': content, 'body': body}; return {'content': content, 'body': body};
} }
static Future<Map<String, dynamic>> getSubscribeStatus(
{required dynamic bvid}) async {
var res = await Request().get(
Api.videoRelation,
data: {
'aid': IdUtils.bv2av(bvid),
'bvid': bvid,
},
);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
static Future seasonFav({
required bool isFav,
required dynamic seasonId,
}) async {
var res = await Request().post(
isFav ? Api.cancelSub : Api.confirmSub,
data: {
'platform': 'web',
'season_id': seasonId,
'csrf': await Request.getCsrf(),
},
);
if (res.data['code'] == 0) {
return {
'status': true,
};
} else {
return {
'status': false,
'msg': res.data['message'],
};
}
}
} }

View File

@ -641,6 +641,7 @@ class EpisodeItem {
this.page, this.page,
this.bvid, this.bvid,
this.cover, this.cover,
this.pages,
}); });
int? seasonId; int? seasonId;
int? sectionId; int? sectionId;
@ -655,6 +656,7 @@ class EpisodeItem {
int? pubdate; int? pubdate;
int? duration; int? duration;
Stat? stat; Stat? stat;
List<Page>? pages;
EpisodeItem.fromJson(Map<String, dynamic> json) { EpisodeItem.fromJson(Map<String, dynamic> json) {
seasonId = json['season_id']; seasonId = json['season_id'];
@ -670,6 +672,7 @@ class EpisodeItem {
pubdate = json['arc']['pubdate']; pubdate = json['arc']['pubdate'];
duration = json['arc']['duration']; duration = json['arc']['duration'];
stat = Stat.fromJson(json['arc']['stat']); stat = Stat.fromJson(json['arc']['stat']);
pages = json['pages'].map<Page>((e) => Page.fromJson(e)).toList();
} }
} }
@ -712,3 +715,18 @@ class Vip {
status = json['status']; status = json['status'];
} }
} }
class Page {
Page({
this.cid,
this.page,
});
int? cid;
int? page;
Page.fromJson(Map<String, dynamic> json) {
cid = json['cid'];
page = json['page'];
}
}

View File

@ -63,6 +63,7 @@ class VideoIntroController extends GetxController {
PersistentBottomSheetController? bottomSheetController; PersistentBottomSheetController? bottomSheetController;
late bool enableRelatedVideo; late bool enableRelatedVideo;
UgcSeason? ugcSeason; UgcSeason? ugcSeason;
RxList<Part> pages = <Part>[].obs;
@override @override
void onInit() { void onInit() {
@ -84,18 +85,20 @@ class VideoIntroController extends GetxController {
} }
// 获取视频简介&分p // 获取视频简介&分p
Future queryVideoIntro() async { Future queryVideoIntro({cover}) async {
var result = await VideoHttp.videoIntro(bvid: bvid); var result = await VideoHttp.videoIntro(bvid: bvid);
if (result['status']) { if (result['status']) {
videoDetail.value = result['data']!; videoDetail.value = result['data']!;
ugcSeason = result['data']!.ugcSeason; ugcSeason = result['data']!.ugcSeason;
if (videoDetail.value.pages!.isNotEmpty && lastPlayCid.value == 0) { pages.value = result['data']!.pages!;
lastPlayCid.value = videoDetail.value.pages!.first.cid!; lastPlayCid.value = videoDetail.value.cid!;
if (pages.isNotEmpty) {
lastPlayCid.value = pages.first.cid!;
} }
final VideoDetailController videoDetailCtr = final VideoDetailController videoDetailCtr =
Get.find<VideoDetailController>(tag: heroTag); Get.find<VideoDetailController>(tag: heroTag);
videoDetailCtr.tabs.value = ['简介', '评论 ${result['data']?.stat?.reply}']; videoDetailCtr.tabs.value = ['简介', '评论 ${result['data']?.stat?.reply}'];
videoDetailCtr.cover.value = result['data'].pic ?? ''; videoDetailCtr.cover.value = cover ?? result['data'].pic ?? '';
// 获取到粉丝数再返回 // 获取到粉丝数再返回
await queryUserStat(); await queryUserStat();
} }
@ -470,8 +473,7 @@ class VideoIntroController extends GetxController {
videoReplyCtr.queryReplyList(type: 'init'); videoReplyCtr.queryReplyList(type: 'init');
} catch (_) {} } catch (_) {}
this.bvid = bvid; this.bvid = bvid;
lastPlayCid.value = cid; await queryVideoIntro(cover: cover);
await queryVideoIntro();
} }
void startTimer() { void startTimer() {
@ -521,9 +523,8 @@ class VideoIntroController extends GetxController {
final List<EpisodeItem> episodesList = sections[i].episodes!; final List<EpisodeItem> episodesList = sections[i].episodes!;
episodes.addAll(episodesList); episodes.addAll(episodesList);
} }
} else if (videoDetail.value.pages != null) { } else if (pages.isNotEmpty) {
isPages = true; isPages = true;
final List<Part> pages = videoDetail.value.pages!;
episodes.addAll(pages); episodes.addAll(pages);
} }
@ -621,10 +622,9 @@ class VideoIntroController extends GetxController {
} }
} }
} }
if (videoDetail.value.pages != null && if (pages.length > 1) {
videoDetail.value.pages!.length > 1) {
dataType = VideoEpidoesType.videoPart; dataType = VideoEpidoesType.videoPart;
episodes = videoDetail.value.pages!; episodes = pages;
} }
DrawerUtils.showRightDialog( DrawerUtils.showRightDialog(

View File

@ -404,27 +404,18 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
Obx( Obx(
() => SeasonPanel( () => SeasonPanel(
ugcSeason: widget.videoDetail!.ugcSeason!, ugcSeason: widget.videoDetail!.ugcSeason!,
cid: videoIntroController.lastPlayCid.value != 0 cid: videoIntroController.lastPlayCid.value,
? videoIntroController.lastPlayCid.value
: widget.videoDetail!.pages!.first.cid,
sheetHeight: videoDetailCtr.sheetHeight.value, sheetHeight: videoDetailCtr.sheetHeight.value,
changeFuc: (bvid, cid, aid, cover) => changeFuc: videoIntroController.changeSeasonOrbangu,
videoIntroController.changeSeasonOrbangu(
bvid,
cid,
aid,
cover,
),
videoIntroCtr: videoIntroController, videoIntroCtr: videoIntroController,
), ),
) )
], ],
// 合集 videoEpisode // 合集 videoEpisode
if (widget.videoDetail!.pages != null && if (videoIntroController.pages.length > 1) ...[
widget.videoDetail!.pages!.length > 1) ...[
Obx( Obx(
() => PagesPanel( () => PagesPanel(
pages: widget.videoDetail!.pages!, pages: videoIntroController.pages,
cid: videoIntroController.lastPlayCid.value, cid: videoIntroController.lastPlayCid.value,
sheetHeight: videoDetailCtr.sheetHeight.value, sheetHeight: videoDetailCtr.sheetHeight.value,
changeFuc: (cid, cover) => changeFuc: (cid, cover) =>

View File

@ -3,7 +3,6 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/models/video_detail_res.dart'; import 'package:pilipala/models/video_detail_res.dart';
import 'package:pilipala/pages/video/detail/index.dart';
import 'package:pilipala/pages/video/detail/introduction/index.dart'; import 'package:pilipala/pages/video/detail/introduction/index.dart';
import '../../../../../common/pages_bottom_sheet.dart'; import '../../../../../common/pages_bottom_sheet.dart';
import '../../../../../models/common/video_episode_type.dart'; import '../../../../../models/common/video_episode_type.dart';
@ -32,25 +31,26 @@ class _PagesPanelState extends State<PagesPanel> {
late int cid; late int cid;
late RxInt currentIndex = (-1).obs; late RxInt currentIndex = (-1).obs;
final String heroTag = Get.arguments['heroTag']; final String heroTag = Get.arguments['heroTag'];
late VideoDetailController _videoDetailController;
final ScrollController listViewScrollCtr = ScrollController(); final ScrollController listViewScrollCtr = ScrollController();
late PersistentBottomSheetController? _bottomSheetController; PersistentBottomSheetController? _bottomSheetController;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
cid = widget.cid; cid = widget.cid;
episodes = widget.pages; episodes = widget.pages;
_videoDetailController = Get.find<VideoDetailController>(tag: heroTag); updateCurrentIndexAndScroll();
currentIndex.value = episodes.indexWhere((Part e) => e.cid == cid); widget.videoIntroCtr.lastPlayCid.listen((int p0) {
scrollToIndex();
_videoDetailController.cid.listen((int p0) {
cid = p0; cid = p0;
currentIndex.value = episodes.indexWhere((Part e) => e.cid == cid); updateCurrentIndexAndScroll();
scrollToIndex();
}); });
} }
void updateCurrentIndexAndScroll() {
currentIndex.value = widget.pages.indexWhere((Part e) => e.cid == cid);
scrollToIndex();
}
@override @override
void dispose() { void dispose() {
listViewScrollCtr.dispose(); listViewScrollCtr.dispose();
@ -60,7 +60,10 @@ class _PagesPanelState extends State<PagesPanel> {
void changeFucCall(item, i) async { void changeFucCall(item, i) async {
widget.changeFuc?.call(item.cid, item.cover); widget.changeFuc?.call(item.cid, item.cover);
currentIndex.value = i; currentIndex.value = i;
_bottomSheetController?.close(); cid = item.cid;
if (_bottomSheetController != null) {
_bottomSheetController?.close();
}
scrollToIndex(); scrollToIndex();
} }
@ -112,7 +115,7 @@ class _PagesPanelState extends State<PagesPanel> {
widget.videoIntroCtr.bottomSheetController = widget.videoIntroCtr.bottomSheetController =
_bottomSheetController = EpisodeBottomSheet( _bottomSheetController = EpisodeBottomSheet(
currentCid: cid, currentCid: cid,
episodes: episodes, episodes: widget.pages,
changeFucCall: changeFucCall, changeFucCall: changeFucCall,
sheetHeight: widget.sheetHeight, sheetHeight: widget.sheetHeight,
dataType: VideoEpidoesType.videoPart, dataType: VideoEpidoesType.videoPart,

View File

@ -33,6 +33,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
final String heroTag = Get.arguments['heroTag']; final String heroTag = Get.arguments['heroTag'];
late VideoDetailController _videoDetailController; late VideoDetailController _videoDetailController;
late PersistentBottomSheetController? _bottomSheetController; late PersistentBottomSheetController? _bottomSheetController;
int currentEpisodeIndex = -1;
@override @override
void initState() { void initState() {
@ -41,13 +42,12 @@ class _SeasonPanelState extends State<SeasonPanel> {
_videoDetailController = Get.find<VideoDetailController>(tag: heroTag); _videoDetailController = Get.find<VideoDetailController>(tag: heroTag);
/// 根据 cid 找到对应集,找到对应 episodes /// 根据 cid 找到对应集,找到对应 episodes
/// 有多个episodes时只显示其中一个
/// TODO 同时显示多个合集
final List<SectionItem> sections = widget.ugcSeason.sections!; final List<SectionItem> sections = widget.ugcSeason.sections!;
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
final List<EpisodeItem> episodesList = sections[i].episodes!; final List<EpisodeItem> episodesList = sections[i].episodes!;
for (int j = 0; j < episodesList.length; j++) { for (int j = 0; j < episodesList.length; j++) {
if (episodesList[j].cid == cid) { if (episodesList[j].cid == cid) {
currentEpisodeIndex = i;
episodes = episodesList; episodes = episodesList;
continue; continue;
} }
@ -55,10 +55,10 @@ class _SeasonPanelState extends State<SeasonPanel> {
} }
/// 取对应 season_id 的 episodes /// 取对应 season_id 的 episodes
currentIndex.value = episodes.indexWhere((EpisodeItem e) => e.cid == cid); getCurrentIndex();
_videoDetailController.cid.listen((int p0) { _videoDetailController.cid.listen((int p0) {
cid = p0; cid = p0;
currentIndex.value = episodes.indexWhere((EpisodeItem e) => e.cid == cid); getCurrentIndex();
}); });
} }
@ -73,6 +73,23 @@ class _SeasonPanelState extends State<SeasonPanel> {
_bottomSheetController?.close(); _bottomSheetController?.close();
} }
// 获取currentIndex
void getCurrentIndex() {
currentIndex.value = episodes.indexWhere((EpisodeItem e) => e.cid == cid);
final List<SectionItem> sections = widget.ugcSeason.sections!;
if (sections.length == 1 && sections.first.type == 1) {
final List<EpisodeItem> episodesList = sections.first.episodes!;
for (int i = 0; i < episodesList.length; i++) {
for (int j = 0; j < episodesList[i].pages!.length; j++) {
if (episodesList[i].pages![j].cid == cid) {
currentIndex.value = i;
continue;
}
}
}
}
}
Widget buildEpisodeListItem( Widget buildEpisodeListItem(
EpisodeItem episode, EpisodeItem episode,
int index, int index,
@ -125,6 +142,8 @@ class _SeasonPanelState extends State<SeasonPanel> {
sheetHeight: widget.sheetHeight, sheetHeight: widget.sheetHeight,
dataType: VideoEpidoesType.videoEpisode, dataType: VideoEpidoesType.videoEpisode,
ugcSeason: widget.ugcSeason, ugcSeason: widget.ugcSeason,
currentEpisodeIndex: currentEpisodeIndex,
currentIndex: currentIndex.value,
).show(context); ).show(context);
}, },
child: Padding( child: Padding(