diff --git a/lib/common/pages_bottom_sheet.dart b/lib/common/pages_bottom_sheet.dart index 49300949..64ed40e8 100644 --- a/lib/common/pages_bottom_sheet.dart +++ b/lib/common/pages_bottom_sheet.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/constants.dart'; @@ -183,7 +182,7 @@ class _PagesBottomSheetState extends State isFixedHeight: true, ); } else { - _listObserverControllerList![widget.currentEpisodeIndex!] + _listObserverControllerList![widget.currentEpisodeIndex ?? 0] .initialIndexModel = ObserverIndexPositionModel( index: currentIndex, isFixedHeight: true, diff --git a/lib/common/widgets/html_render.dart b/lib/common/widgets/html_render.dart index b2aa75ff..e4e3ef77 100644 --- a/lib/common/widgets/html_render.dart +++ b/lib/common/widgets/html_render.dart @@ -5,6 +5,8 @@ import 'package:pilipala/plugin/pl_gallery/hero_dialog_route.dart'; import 'package:pilipala/plugin/pl_gallery/interactiveviewer_gallery.dart'; import 'package:pilipala/utils/highlight.dart'; +import '../../utils/global_data_cache.dart'; + // ignore: must_be_immutable class HtmlRender extends StatelessWidget { const HtmlRender({ @@ -41,6 +43,8 @@ class HtmlRender extends StatelessWidget { TagExtension( tagsToExtend: {'img'}, builder: (ExtensionContext extensionContext) { + int defaultImgQuality = 10; + defaultImgQuality = GlobalDataCache.imgQuality; try { final Map attributes = extensionContext.attributes; @@ -99,13 +103,13 @@ class HtmlRender extends StatelessWidget { ), ); }, - child: CachedNetworkImage(imageUrl: imgUrl), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: CachedNetworkImage( + imageUrl: '$imgUrl@${defaultImgQuality}q.webp', + ), + ), ); - // return NetworkImgLayer( - // width: isEmote ? 22 : Get.size.width - 24, - // height: isEmote ? 22 : 200, - // src: imgUrl, - // ); } catch (err) { return const SizedBox(); } @@ -138,6 +142,14 @@ class HtmlRender extends StatelessWidget { textAlign: TextAlign.justify, ), 'img': Style(margin: Margins.only(top: 4, bottom: 4)), + 'figcaption': Style( + textAlign: TextAlign.center, + margin: Margins.only(top: 8, bottom: 20), + color: Theme.of(context).colorScheme.secondary, + ), + 'figure': Style( + margin: Margins.zero, + ), }, ); } diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index b1f9bea8..5c8f85e3 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -20,7 +20,6 @@ import '../../../models/video/reply/item.dart'; import '../widgets/dynamic_panel.dart'; class DynamicDetailPage extends StatefulWidget { - // const DynamicDetailPage({super.key}); const DynamicDetailPage({Key? key}) : super(key: key); @override @@ -90,19 +89,22 @@ class _DynamicDetailPageState extends State _dynamicDetailController = Get.put( DynamicDetailController(oid, replyType), tag: opusId.toString()); + _futureBuilderFuture = _dynamicDetailController.queryReplyList(); await _dynamicDetailController.reqHtmlByOpusId(opusId!); setState(() {}); } } else { oid = moduleDynamic.major!.draw!.id!; } - } catch (_) {} + } catch (err) { + print('err:${err.toString()}'); + } } if (!isOpusId) { _dynamicDetailController = Get.put(DynamicDetailController(oid, replyType), tag: oid.toString()); + _futureBuilderFuture = _dynamicDetailController.queryReplyList(); } - _futureBuilderFuture = _dynamicDetailController.queryReplyList(); } // 查看二级评论 @@ -132,7 +134,7 @@ class _DynamicDetailPageState extends State // 分页加载 if (scrollController.position.pixels >= scrollController.position.maxScrollExtent - 300) { - EasyThrottle.throttle('replylist', const Duration(seconds: 2), () { + EasyThrottle.throttle('replyList', const Duration(seconds: 2), () { _dynamicDetailController.onLoad(); }); } diff --git a/lib/pages/later/controller.dart b/lib/pages/later/controller.dart index 6cb8a3c0..cf408d97 100644 --- a/lib/pages/later/controller.dart +++ b/lib/pages/later/controller.dart @@ -122,6 +122,7 @@ class LaterController extends GetxController { 'heroTag': heroTag, 'sourceType': 'watchLater', 'count': laterList.length, + 'mediaId': userInfo!.mid, }, ); } diff --git a/lib/pages/opus/view.dart b/lib/pages/opus/view.dart index 42c0c419..971bb678 100644 --- a/lib/pages/opus/view.dart +++ b/lib/pages/opus/view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/models/read/opus.dart'; + import 'controller.dart'; import 'text_helper.dart'; @@ -26,16 +27,18 @@ class _OpusPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), - body: SingleChildScrollView( + body: CustomScrollView( controller: controller.scrollController, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildTitle(), - _buildFutureContent(), - ], - ), + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + [ + _buildTitle(), + _buildFutureContent(), + ], + ), + ), + ], ), ); } diff --git a/lib/pages/read/view.dart b/lib/pages/read/view.dart index 710934eb..4bc93326 100644 --- a/lib/pages/read/view.dart +++ b/lib/pages/read/view.dart @@ -6,6 +6,7 @@ import 'package:pilipala/models/read/opus.dart'; import 'package:pilipala/models/read/read.dart'; import 'package:pilipala/pages/opus/text_helper.dart'; import 'package:pilipala/utils/utils.dart'; + import 'controller.dart'; class ReadPage extends StatefulWidget { @@ -38,16 +39,18 @@ class _ReadPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), - body: SingleChildScrollView( + body: CustomScrollView( controller: controller.scrollController, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildTitle(), - _buildFutureContent(), - ], - ), + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + [ + _buildTitle(), + _buildFutureContent(), + ], + ), + ), + ], ), ); } diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index cc2cbffc..4fdf8420 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -487,7 +487,7 @@ class VideoDetailController extends GetxController if (result['status']) { if (result['data'].subtitles.isNotEmpty) { subtitles = result['data'].subtitles; - getDanmaku(subtitles); + getSubtitleContent(subtitles); } } headerControl = HeaderControl( @@ -501,8 +501,8 @@ class VideoDetailController extends GetxController plPlayerController.setHeaderControl(headerControl); } - // 获取弹幕 - Future getDanmaku(List subtitles) async { + // 获取字幕 + Future getSubtitleContent(List subtitles) async { if (subtitles.isNotEmpty) { for (var i in subtitles) { final Map res = await VideoHttp.getSubtitleContent( diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index bc8fe81a..d16d85a8 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -523,7 +523,7 @@ class VideoIntroController extends GetxController { Get.find(tag: heroTag); /// 优先稍后再看、收藏夹 - if (videoDetailCtr.isWatchLaterVisible.value) { + if (videoDetailCtr.sourceType.value != 'normal') { episodes.addAll(videoDetailCtr.mediaList); } else if (videoDetail.value.ugcSeason != null) { final UgcSeason ugcSeason = videoDetail.value.ugcSeason!; @@ -617,6 +617,7 @@ class VideoIntroController extends GetxController { // 播放器底栏 选集 回调 void showEposideHandler() { late List episodes; + int currentEpisodeIndex = 0; VideoEpidoesType dataType = VideoEpidoesType.videoEpisode; if (videoDetail.value.ugcSeason != null) { dataType = VideoEpidoesType.videoEpisode; @@ -625,6 +626,7 @@ class VideoIntroController extends GetxController { final List episodesList = sections[i].episodes!; for (int j = 0; j < episodesList.length; j++) { if (episodesList[j].cid == lastPlayCid.value) { + currentEpisodeIndex = i; episodes = episodesList; continue; } @@ -644,6 +646,7 @@ class VideoIntroController extends GetxController { sheetHeight: Get.size.height, isFullScreen: true, ugcSeason: ugcSeason, + currentEpisodeIndex: currentEpisodeIndex, changeFucCall: (item, index) { if (dataType == VideoEpidoesType.videoEpisode) { changeSeasonOrbangu( diff --git a/lib/pages/video/detail/introduction/widgets/season_panel.dart b/lib/pages/video/detail/introduction/widgets/season_panel.dart index acc5f115..05f67631 100644 --- a/lib/pages/video/detail/introduction/widgets/season_panel.dart +++ b/lib/pages/video/detail/introduction/widgets/season_panel.dart @@ -42,23 +42,14 @@ class _SeasonPanelState extends State { _videoDetailController = Get.find(tag: heroTag); /// 根据 cid 找到对应集,找到对应 episodes - final List sections = widget.ugcSeason.sections!; - for (int i = 0; i < sections.length; i++) { - final List episodesList = sections[i].episodes!; - for (int j = 0; j < episodesList.length; j++) { - if (episodesList[j].cid == cid) { - currentEpisodeIndex = i; - episodes = episodesList; - continue; - } - } - } + getCurrentEpisodeIndex(); /// 取对应 season_id 的 episodes getCurrentIndex(); _videoDetailController.cid.listen((int p0) { cid = p0; getCurrentIndex(); + getCurrentEpisodeIndex(); }); } @@ -94,6 +85,21 @@ class _SeasonPanelState extends State { } } + // 获取currentEpisodeIndex + void getCurrentEpisodeIndex() { + final List sections = widget.ugcSeason.sections!; + for (int i = 0; i < sections.length; i++) { + final List episodesList = sections[i].episodes!; + for (int j = 0; j < episodesList.length; j++) { + if (episodesList[j].cid == cid) { + currentEpisodeIndex = i; + episodes = episodesList; + continue; + } + } + } + } + Widget buildEpisodeListItem( EpisodeItem episode, int index, diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart index 4af59b9d..38d59617 100644 --- a/lib/pages/video/detail/reply/controller.dart +++ b/lib/pages/video/detail/reply/controller.dart @@ -70,6 +70,13 @@ class VideoReplyController extends GetxController { isEnd = res['data'].cursor.isEnd ?? false; nextOffset = res['data'].cursor.paginationReply.nextOffset ?? ""; if (replies.isNotEmpty) { + /// 临时修复 + final bool flag = replyList + .any((ReplyItemModel reply) => reply.rpid == replies.first.rpid); + if (replies.length == 1 && flag) { + replies.clear(); + isEnd = true; + } noMore.value = isEnd ? '没有更多了' : '加载中...'; } else { noMore.value = diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 55aafeb5..c7896480 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -685,6 +685,11 @@ class _VideoDetailPageState extends State canPop: plPlayerController?.isFullScreen.value != true, onPopInvoked: (bool didPop) { + if (plPlayerController?.controlsLock.value == + true) { + plPlayerController?.onLockControl(false); + return; + } if (plPlayerController?.isFullScreen.value == true) { plPlayerController! diff --git a/lib/pages/video/detail/widgets/watch_later_list.dart b/lib/pages/video/detail/widgets/watch_later_list.dart index 93326ec3..6d675dd8 100644 --- a/lib/pages/video/detail/widgets/watch_later_list.dart +++ b/lib/pages/video/detail/widgets/watch_later_list.dart @@ -85,9 +85,12 @@ class _MediaListPanelState extends State { AppBar( toolbarHeight: 45, automaticallyImplyLeading: false, - title: Text( - widget.panelTitle ?? '稍后再看', - style: Theme.of(context).textTheme.titleSmall, + title: Padding( + padding: const EdgeInsets.only(left: 12), + child: Text( + widget.panelTitle ?? '稍后再看', + style: Theme.of(context).textTheme.titleSmall, + ), ), actions: [ IconButton( diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index c2c3027a..dab32b5c 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -917,7 +917,7 @@ class PlPlayerController { if (videoType == 'live') { return; } - if (controlsLock.value) { + if (_controlsLock.value) { return; } _doubleSpeedStatus.value = val; @@ -1093,6 +1093,7 @@ class PlPlayerController { videoFitChangedTimer?.cancel(); // _position.close(); _playerEventSubs?.cancel(); + _controlsLock.value = false; // _sliderPosition.close(); // _sliderTempPosition.close(); // _isSliderMoving.close();