diff --git a/lib/pages/player/episode_comments_sheet.dart b/lib/pages/player/episode_comments_sheet.dart index d8c7b6f6..f82a3f7e 100644 --- a/lib/pages/player/episode_comments_sheet.dart +++ b/lib/pages/player/episode_comments_sheet.dart @@ -15,8 +15,7 @@ class EpisodeCommentsSheet extends StatefulWidget { State createState() => _EpisodeCommentsSheetState(); } -class _EpisodeCommentsSheetState extends State - with AutomaticKeepAliveClientMixin { +class _EpisodeCommentsSheetState extends State { final infoController = Modular.get(); bool isLoading = false; bool commentsQueryTimeout = false; @@ -58,30 +57,39 @@ class _EpisodeCommentsSheetState extends State Widget get episodeCommentsBody { return SelectionArea( - child: Padding( - padding: const EdgeInsets.fromLTRB(4, 0, 4, 4), - child: Observer(builder: (context) { - if (isLoading) { - return const Center( - child: CircularProgressIndicator(), - ); - } - if (commentsQueryTimeout) { - return const Center( - child: Text('空空如也'), - ); - } - return SingleChildScrollView( - child: ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: infoController.episodeCommentsList.length, - itemBuilder: (context, index) { - return EpisodeCommentsCard( - commentItem: infoController.episodeCommentsList[index]); - })); - }), - )); + child: CustomScrollView( + slivers: [ + SliverPadding( + padding: const EdgeInsets.fromLTRB(4, 0, 4, 4), + sliver: Observer(builder: (context) { + if (isLoading) { + return const SliverFillRemaining( + child: Center( + child: CircularProgressIndicator(), + ), + ); + } + if (commentsQueryTimeout) { + return const SliverFillRemaining( + child: Center( + child: Text('空空如也'), + ), + ); + } + return SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) { + return EpisodeCommentsCard( + commentItem: infoController.episodeCommentsList[index]); + }, + childCount: infoController.episodeCommentsList.length, + ), + ); + }), + ), + ], + ), + ); } Widget get commentsInfo { @@ -184,7 +192,6 @@ class _EpisodeCommentsSheetState extends State @override Widget build(BuildContext context) { - super.build(context); return Scaffold( body: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -192,7 +199,4 @@ class _EpisodeCommentsSheetState extends State ), ); } - - @override - bool get wantKeepAlive => true; } diff --git a/lib/pages/player/player_item.dart b/lib/pages/player/player_item.dart index 47e0fc46..0c94067d 100644 --- a/lib/pages/player/player_item.dart +++ b/lib/pages/player/player_item.dart @@ -31,18 +31,21 @@ import 'package:kazumi/pages/player/player_item_surface.dart'; import 'package:mobx/mobx.dart' as mobx; class PlayerItem extends StatefulWidget { - const PlayerItem( - {super.key, - required this.openMenu, - required this.locateEpisode, - required this.changeEpisode, - required this.onBackPressed}); + const PlayerItem({ + super.key, + required this.openMenu, + required this.locateEpisode, + required this.changeEpisode, + required this.onBackPressed, + required this.keyboardFocus, + }); final VoidCallback openMenu; final VoidCallback locateEpisode; final Future Function(int episode, {int currentRoad, int offset}) changeEpisode; final void Function(BuildContext) onBackPressed; + final FocusNode keyboardFocus; @override State createState() => _PlayerItemState(); @@ -60,7 +63,6 @@ class _PlayerItemState extends State final HistoryController historyController = Modular.get(); final InfoController infoController = Modular.get(); final CollectController collectController = Modular.get(); - final FocusNode _focusNode = FocusNode(); late DanmakuController danmakuController; // 1. 在看 @@ -289,10 +291,8 @@ class _PlayerItemState extends State Timer getPlayerTimer() { return Timer.periodic(const Duration(seconds: 1), (timer) { playerController.playing = playerController.playerPlaying; - playerController.isBuffering = - playerController.playerBuffering; - playerController.currentPosition = - playerController.playerPosition; + playerController.isBuffering = playerController.playerBuffering; + playerController.currentPosition = playerController.playerPosition; playerController.buffer = playerController.playerBuffer; playerController.duration = playerController.playerDuration; playerController.completed = playerController.playerCompleted; @@ -361,8 +361,7 @@ class _PlayerItemState extends State }); } // 历史记录相关 - if (playerController.playerPlaying && - !videoPageController.loading) { + if (playerController.playerPlaying && !videoPageController.loading) { historyController.updateHistory( videoPageController.currentEpisode, videoPageController.currentRoad, @@ -481,7 +480,7 @@ class _PlayerItemState extends State TextButton( onPressed: () { KazumiDialog.dismiss(); - _focusNode.requestFocus(); + widget.keyboardFocus.requestFocus(); }, child: Text( '取消', @@ -644,7 +643,8 @@ class _PlayerItemState extends State child: Focus( // workaround for #461 // I don't know why, but the focus node will break popscope. - focusNode: Utils.isDesktop() ? _focusNode : null, + focusNode: + Utils.isDesktop() ? widget.keyboardFocus : null, autofocus: Utils.isDesktop(), onKeyEvent: (focusNode, KeyEvent event) { if (event is KeyDownEvent) { @@ -919,9 +919,7 @@ class _PlayerItemState extends State ), ), ), - ) - // SizedBox(child: Text("${videoController.androidFullscreen}")), - ; + ); }, ); } diff --git a/lib/pages/video/video_page.dart b/lib/pages/video/video_page.dart index bdf98f98..22536e32 100644 --- a/lib/pages/video/video_page.dart +++ b/lib/pages/video/video_page.dart @@ -41,6 +41,7 @@ class _VideoPageState extends State late bool playResume; bool showDebugLog = false; List logLines = []; + final FocusNode keyboardFocus = FocusNode(); ScrollController scrollController = ScrollController(); late GridObserverController observerController; @@ -200,6 +201,7 @@ class _VideoPageState extends State Future.delayed(const Duration(milliseconds: 100), () { videoPageController.showTabBody = false; }); + keyboardFocus.requestFocus(); } void onBackPressed(BuildContext context) async { @@ -270,7 +272,7 @@ class _VideoPageState extends State width: MediaQuery.of(context).size.width, child: playerBody, ), - if (videoPageController.showTabBody) + if (videoPageController.showTabBody) ...[ GestureDetector( onTap: () { closeTabBodyAnimated(); @@ -281,17 +283,18 @@ class _VideoPageState extends State height: double.infinity, ), ), - SlideTransition( - position: _rightOffsetAnimation, - child: SizedBox( - height: MediaQuery.of(context).size.height, - width: - MediaQuery.of(context).size.width * 1 / 3 > 420 - ? 420 - : MediaQuery.of(context).size.width * 1 / 3, - child: tabBody, + SlideTransition( + position: _rightOffsetAnimation, + child: SizedBox( + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width * 1 / 3 > + 420 + ? 420 + : MediaQuery.of(context).size.width * 1 / 3, + child: tabBody, + ), ), - ), + ], ], ) : (!videoPageController.isFullscreen) @@ -522,6 +525,7 @@ class _VideoPageState extends State locateEpisode: menuJumpToCurrentEpisode, changeEpisode: changeEpisode, onBackPressed: onBackPressed, + keyboardFocus: keyboardFocus, ), ), @@ -718,50 +722,46 @@ class _VideoPageState extends State episodeNum = videoPageController.currentEpisode; } - return Visibility( - maintainState: true, - visible: videoPageController.showTabBody, - child: Container( - color: Theme.of(context).canvasColor, - child: DefaultTabController( - length: 2, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TabBar( - dividerHeight: Utils.isDesktop() ? 0.5 : 0.2, - isScrollable: true, - tabAlignment: TabAlignment.start, - labelPadding: - const EdgeInsetsDirectional.only(start: 30, end: 30), - onTap: (index) { - if (index == 0) { - menuJumpToCurrentEpisode(); - } - }, - tabs: const [ - Tab(text: '选集'), - Tab(text: '评论'), - ], - ), - Expanded( - child: TabBarView( - children: [ - GridViewObserver( - controller: observerController, - child: Column( - children: [ - menuBar, - menuBody, - ], - ), + return Container( + color: Theme.of(context).canvasColor, + child: DefaultTabController( + length: 2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TabBar( + dividerHeight: Utils.isDesktop() ? 0.5 : 0.2, + isScrollable: true, + tabAlignment: TabAlignment.start, + labelPadding: + const EdgeInsetsDirectional.only(start: 30, end: 30), + onTap: (index) { + if (index == 0) { + menuJumpToCurrentEpisode(); + } + }, + tabs: const [ + Tab(text: '选集'), + Tab(text: '评论'), + ], + ), + Expanded( + child: TabBarView( + children: [ + GridViewObserver( + controller: observerController, + child: Column( + children: [ + menuBar, + menuBody, + ], ), - EpisodeCommentsSheet(episode: episodeNum), - ], - ), + ), + EpisodeCommentsSheet(episode: episodeNum), + ], ), - ], - ), + ), + ], ), ), );