fix: 问题处理~

This commit is contained in:
csw 2026-07-01 18:05:57 +08:00
parent a6b0a2ae95
commit fc445e7c80
5 changed files with 206 additions and 38 deletions

View File

@ -71,21 +71,39 @@ class _MainRootState extends State<HomePage> {
child: SafeArea( child: SafeArea(
child: _homeData.isEmpty child: _homeData.isEmpty
? const SizedBox() ? const SizedBox()
: EasyRefresh( : _newBodyWidget(),
controller: _refreshController,
header: const GifHeader(),
onRefresh: _refreshHome,
child: _bodyWidget(),
),
), ),
); );
} }
Widget _newBodyWidget() {
return Column(
children: [
Container(
height: 204.h,
padding: EdgeInsets.only(left: 25.w, top: 3.h, right: 25.w),
child: HelpImg.asset(ConstImg.homeTopBg, fit: BoxFit.fill),
).addInkWell(onTap: () {
//
HelpNav.to(ResultPage(keyword: ''));
}),
const SizedBox(height: 10),
Expanded(child: EasyRefresh(
controller: _refreshController,
header: const GifHeader(),
onRefresh: _refreshHome,
child: _bodyWidget(),
))
],
);
}
Widget _bodyWidget() { Widget _bodyWidget() {
return CustomScrollView( return CustomScrollView(
slivers: [ slivers: [
_buildTopTwoImgs(), // _buildTopTwoImgs(),
_buildSpace(), // _buildSpace(),
_buildTitleImg(ConstImg.homeTitleDaily),
DailyQuestWidget( DailyQuestWidget(
dramaList: _homeData dramaList: _homeData
.firstWhere((element) => element.moduleKey == 'home_v3_recommand') .firstWhere((element) => element.moduleKey == 'home_v3_recommand')

View File

@ -22,6 +22,9 @@ class DramaDetailPage extends StatefulWidget {
class _DramaDetailPageState extends State<DramaDetailPage> { class _DramaDetailPageState extends State<DramaDetailPage> {
SkywoodDetail? _detailBean; SkywoodDetail? _detailBean;
SkywoodEpisode? _selectedEpisode; SkywoodEpisode? _selectedEpisode;
final PageController _pageController = PageController();
int _currentPageIndex = 0;
int? _requestingVideoId;
@override @override
void initState() { void initState() {
@ -33,33 +36,120 @@ class _DramaDetailPageState extends State<DramaDetailPage> {
); );
} }
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
void _getDetailDrama({ void _getDetailDrama({
required int shortPlayId, required int shortPlayId,
required int shortPlayVideoId, required int shortPlayVideoId,
bool showLoading = true,
}) { }) {
AppToast.showLottieLoading(); _requestingVideoId = shortPlayVideoId;
if (showLoading) {
AppToast.showLottieLoading();
}
PlayClient.getVideoDetail( PlayClient.getVideoDetail(
shortPlayId: shortPlayId, shortPlayId: shortPlayId,
shortPlayVideoId: shortPlayVideoId, shortPlayVideoId: shortPlayVideoId,
).then((value) { ).then((value) {
AppToast.dismiss(); if (showLoading) {
AppToast.dismiss();
}
if (!mounted) return; if (!mounted) return;
if (_requestingVideoId != shortPlayVideoId) return;
setState(() { setState(() {
_detailBean = value; _detailBean = value;
if (value != null) {
_selectedEpisode ??= _resolveCurrentEpisode(value);
_currentPageIndex = _indexOfEpisode(_selectedEpisode);
}
}); });
_jumpToCurrentPage();
}); });
} }
void _onSelectedEpisode(SkywoodEpisode episode) { void _onSelectedEpisode(SkywoodEpisode episode) {
setState(() { setState(() {
_selectedEpisode = episode; _selectedEpisode = episode;
_currentPageIndex = _indexOfEpisode(episode);
});
_jumpToCurrentPage();
_getDetailDrama(
shortPlayId: episode.shortPlayId,
shortPlayVideoId: episode.shortPlayVideoId,
showLoading: false,
);
}
void _onPageChanged(int index) {
final episodes = _detailBean?.episodeList ?? [];
if (index < 0 || index >= episodes.length) return;
final episode = episodes[index];
if (_selectedEpisode?.shortPlayVideoId == episode.shortPlayVideoId) {
_currentPageIndex = index;
return;
}
setState(() {
_selectedEpisode = episode;
_currentPageIndex = index;
}); });
_getDetailDrama( _getDetailDrama(
shortPlayId: episode.shortPlayId, shortPlayId: episode.shortPlayId,
shortPlayVideoId: episode.shortPlayVideoId, shortPlayVideoId: episode.shortPlayVideoId,
showLoading: false,
); );
} }
SkywoodEpisode? _resolveCurrentEpisode(SkywoodDetail detail) {
if (detail.episodeList.isEmpty) return null;
final int? episode =
_selectedEpisode?.episode ??
detail.videoInfo?.episode ??
detail.videoInfo?.currentEpisode ??
detail.shortPlayInfo?.episode ??
detail.shortPlayInfo?.currentEpisode ??
widget.dramaBean.currentEpisode ??
widget.dramaBean.episode;
if (episode != null && episode > 0) {
for (final item in detail.episodeList) {
if (item.episode == episode) return item;
}
}
return detail.episodeList.first;
}
int _indexOfEpisode(SkywoodEpisode? episode) {
final episodes = _detailBean?.episodeList ?? [];
if (episode == null || episodes.isEmpty) return 0;
final index = episodes.indexWhere(
(item) => item.shortPlayVideoId == episode.shortPlayVideoId,
);
return index < 0 ? 0 : index;
}
void _jumpToCurrentPage() {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted || !_pageController.hasClients) return;
final episodes = _detailBean?.episodeList ?? [];
if (episodes.isEmpty) return;
final page = _currentPageIndex.clamp(0, episodes.length - 1);
if ((_pageController.page ?? _pageController.initialPage).round() ==
page) {
return;
}
_pageController.jumpToPage(page);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold(backgroundColor: Colors.black, body: _bodyWidget()); return Scaffold(backgroundColor: Colors.black, body: _bodyWidget());
@ -76,17 +166,7 @@ class _DramaDetailPageState extends State<DramaDetailPage> {
left: 0, left: 0,
right: 0, right: 0,
top: 0, top: 0,
child: SkyPlayerView( child: _buildPlayerPager(),
key: ValueKey(
_selectedEpisode?.shortPlayVideoId ??
_detailBean?.videoInfo?.shortPlayVideoId ??
widget.dramaBean.shortPlayVideoId,
),
detailBean: _detailBean,
dramaBean: widget.dramaBean,
currentEpisode: _selectedEpisode?.episode,
onSelectedEpisode: _onSelectedEpisode,
),
), ),
Positioned( Positioned(
@ -99,6 +179,42 @@ class _DramaDetailPageState extends State<DramaDetailPage> {
); );
} }
Widget _buildPlayerPager() {
final detail = _detailBean!;
final episodes = detail.episodeList;
if (episodes.isEmpty) {
return SkyPlayerView(
detailBean: detail,
dramaBean: widget.dramaBean,
currentEpisode: _selectedEpisode?.episode,
onSelectedEpisode: _onSelectedEpisode,
);
}
return PageView.builder(
controller: _pageController,
scrollDirection: Axis.vertical,
onPageChanged: _onPageChanged,
itemCount: episodes.length,
itemBuilder: (context, index) {
final episode = episodes[index];
final isCurrent = index == _currentPageIndex;
return SkyPlayerView(
key: ValueKey(
'${episode.shortPlayVideoId}-$isCurrent-${detail.videoInfo?.shortPlayVideoId}',
),
autoPlay: isCurrent,
detailBean: detail,
dramaBean: widget.dramaBean,
currentEpisode: episode.episode,
onSelectedEpisode: _onSelectedEpisode,
);
},
);
}
Widget _headerWidget() { Widget _headerWidget() {
return Container( return Container(
height: 40, height: 40,

View File

@ -59,6 +59,17 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
oldWidget.currentEpisode != widget.currentEpisode) { oldWidget.currentEpisode != widget.currentEpisode) {
_disposeController(); _disposeController();
_initializePlayer(); _initializePlayer();
return;
}
if (oldWidget.autoPlay != widget.autoPlay &&
_controllerCreated &&
_isInitialized) {
if (widget.autoPlay) {
_controller.play();
} else {
_controller.pause();
}
} }
} }
@ -70,6 +81,7 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
_currentPosition = Duration.zero; _currentPosition = Duration.zero;
_totalDuration = Duration.zero; _totalDuration = Duration.zero;
_isLiked = widget.dramaBean.isCollect ?? false; _isLiked = widget.dramaBean.isCollect ?? false;
_isReportedHis = false;
}); });
_currentEpisode = _resolveCurrentEpisode(); _currentEpisode = _resolveCurrentEpisode();
@ -105,12 +117,14 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
final videoController = _controller; final videoController = _controller;
final position = videoController.value.position; final position = videoController.value.position;
final duration = videoController.value.duration; if (_isPlaying &&
if (_isPlaying && !_isReportedHis && position.inSeconds > 1) { !_isReportedHis &&
_currentEpisode != null &&
position.inSeconds > 1) {
_isReportedHis = true; _isReportedHis = true;
EventClient.eventCreateHis( EventClient.eventCreateHis(
shortPlayId: _currentEpisode!.shortPlayId.toString(), shortPlayId: _currentEpisode!.shortPlayId.toString(),
videoId: _currentEpisode!.shortPlayVideoId.toString(), videoId: _currentEpisode!.shortPlayVideoId.toString(),
); );
} }
} }
@ -380,12 +394,12 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
return SizedBox( return SizedBox(
width: double.infinity, width: double.infinity,
height: 3, height: 28,
child: SliderTheme( child: SliderTheme(
data: SliderThemeData( data: SliderThemeData(
trackHeight: 3, // 3 trackHeight: 3, // 3
thumbShape: _ImageThumbShape(imagePath: ConstImg.playTag), thumbShape: _ImageThumbShape(imagePath: ConstImg.playTag),
overlayShape: const RoundSliderOverlayShape(overlayRadius: 3), overlayShape: const RoundSliderOverlayShape(overlayRadius: 10),
activeTrackColor: Colors.white, // = activeTrackColor: Colors.white, // =
inactiveTrackColor: Colors.white.withAlpha(126), // = inactiveTrackColor: Colors.white.withAlpha(126), // =
thumbColor: Colors.white, thumbColor: Colors.white,
@ -396,28 +410,46 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
value: progress, value: progress,
min: 0, min: 0,
max: 1, max: 1,
onChangeStart: (_) { onChangeStart: (value) {
_isSeeking = true; if (totalMilliseconds <= 0) return;
setState(() {
_isSeeking = true;
_currentPosition = _durationFromProgress(
value,
totalMilliseconds,
);
});
}, },
onChanged: (value) { onChanged: (value) {
if (totalMilliseconds <= 0) return;
setState(() { setState(() {
_currentPosition = Duration( _currentPosition = _durationFromProgress(
milliseconds: (totalMilliseconds * value).round(), value,
totalMilliseconds,
); );
}); });
}, },
onChangeEnd: (value) { onChangeEnd: (value) {
final position = Duration( if (totalMilliseconds <= 0 || !_controllerCreated) return;
milliseconds: (totalMilliseconds * value).round(), final position = _durationFromProgress(value, totalMilliseconds);
); setState(() {
_controller.seekTo(position); _currentPosition = position;
_isSeeking = false; });
_controller.seekTo(position).whenComplete(() {
if (!mounted) return;
_isSeeking = false;
_syncPlayerValue();
});
}, },
), ),
), ),
); );
} }
Duration _durationFromProgress(double value, int totalMilliseconds) {
return Duration(milliseconds: (totalMilliseconds * value).round());
}
String _formatDuration(Duration duration) { String _formatDuration(Duration duration) {
final minutes = duration.inMinutes.remainder(60).toString().padLeft(2, '0'); final minutes = duration.inMinutes.remainder(60).toString().padLeft(2, '0');
final seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0'); final seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0');

View File

@ -70,7 +70,9 @@ class _CollectionPageState extends State<MineCollectionPage> {
}, },
key: Key(item.shortPlayId.toString()), key: Key(item.shortPlayId.toString()),
child: MineItemView(drama: _collectionList[index]), child: MineItemView(drama: item, onTap: () {
HelpNav.to(DramaDetailPage(dramaBean: item));
}),
); );
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) {

View File

@ -140,7 +140,7 @@ class ResultItemView extends StatelessWidget {
Spacer(), Spacer(),
Row( Row(
children: [ children: [
_tipView(true, text: '10.0'), _tipView(true, text: SkyTimeTool.formatNum(drama.collectTotal, unit: 'k')),
const SizedBox(width: 15), const SizedBox(width: 15),
_tipView(false, text: SkyTimeTool.formatNum(drama.watchTotal, unit: 'k')), _tipView(false, text: SkyTimeTool.formatNum(drama.watchTotal, unit: 'k')),
], ],