diff --git a/lib/pages/member/new/content/member_contribute/content/article/member_article.dart b/lib/pages/member/new/content/member_contribute/content/article/member_article.dart index 263f8f2e..909780e4 100644 --- a/lib/pages/member/new/content/member_contribute/content/article/member_article.dart +++ b/lib/pages/member/new/content/member_contribute/content/article/member_article.dart @@ -6,6 +6,7 @@ import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/models/space_article/item.dart'; import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/article/member_article_ctr.dart'; import 'package:PiliPalaX/utils/app_scheme.dart'; +import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -54,7 +55,11 @@ class _MemberArticleState extends State itemCount: loadingState.response.length, itemBuilder: (_, index) { if (index == loadingState.response.length - 1) { - _controller.onLoadMore(); + EasyThrottle.throttle( + 'memberArticle', const Duration(milliseconds: 500), + () { + _controller.onLoadMore(); + }); } Item item = loadingState.response[index]; return ListTile( diff --git a/lib/pages/member/new/content/member_contribute/content/bangumi/member_bangumi.dart b/lib/pages/member/new/content/member_contribute/content/bangumi/member_bangumi.dart index b5d48e7c..51c41884 100644 --- a/lib/pages/member/new/content/member_contribute/content/bangumi/member_bangumi.dart +++ b/lib/pages/member/new/content/member_contribute/content/bangumi/member_bangumi.dart @@ -5,6 +5,7 @@ import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/pages/bangumi/widgets/bangumi_card_v_member_home.dart'; import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/bangumi/member_bangumi_ctr.dart'; import 'package:PiliPalaX/utils/grid.dart'; +import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -71,7 +72,10 @@ class _MemberBangumiState extends State delegate: SliverChildBuilderDelegate( (context, index) { if (index == loadingState.response.length - 1) { - _controller.onLoadMore(); + EasyThrottle.throttle('memberBangumi', + const Duration(milliseconds: 500), () { + _controller.onLoadMore(); + }); } return BangumiCardVMemberHome( bangumiItem: loadingState.response[index], diff --git a/lib/pages/member/new/content/member_dynamic/member_dynamic.dart b/lib/pages/member/new/content/member_dynamic/member_dynamic.dart index adbfd557..669e93c6 100644 --- a/lib/pages/member/new/content/member_dynamic/member_dynamic.dart +++ b/lib/pages/member/new/content/member_dynamic/member_dynamic.dart @@ -3,6 +3,7 @@ import 'package:PiliPalaX/common/widgets/refresh_indicator.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/pages/dynamics/widgets/dynamic_panel_grpc.dart'; import 'package:PiliPalaX/pages/member/new/content/member_dynamic/member_dynamic_ctr.dart'; +import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -43,7 +44,10 @@ class _MemberDynamicState extends State itemCount: loadingState.response.length, itemBuilder: (_, index) { if (index == loadingState.response.length - 1) { - _controller.onLoadMore(); + EasyThrottle.throttle( + 'memberDynamic', const Duration(milliseconds: 500), () { + _controller.onLoadMore(); + }); } return DynamicPanelGrpc( item: loadingState.response[index], diff --git a/lib/pages/member_search/search_archive.dart b/lib/pages/member_search/search_archive.dart index 32d54a80..11c251f7 100644 --- a/lib/pages/member_search/search_archive.dart +++ b/lib/pages/member_search/search_archive.dart @@ -5,6 +5,7 @@ import 'package:PiliPalaX/common/widgets/video_card_h.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/pages/member_search/controller.dart'; import 'package:PiliPalaX/utils/grid.dart'; +import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart'; @@ -50,7 +51,10 @@ class SearchArchive extends StatelessWidget { delegate: SliverChildBuilderDelegate( (context, index) { if (index == loadingState.response.length - 1) { - ctr.searchArchives(false); + EasyThrottle.throttle('searchArchives', + const Duration(milliseconds: 500), () { + ctr.searchArchives(false); + }); } return VideoCardH( videoItem: loadingState.response[index], diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index fb85abdb..f7338a36 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -79,15 +79,6 @@ class _VideoReplyPanelState extends State void scrollListener() { _videoReplyController.scrollController.addListener( () { - if (_videoReplyController.scrollController.position.pixels >= - _videoReplyController.scrollController.position.maxScrollExtent - - 300) { - EasyThrottle.throttle('replylist', const Duration(milliseconds: 200), - () { - _videoReplyController.onLoadMore(); - }); - } - final ScrollDirection direction = _videoReplyController.scrollController.position.userScrollDirection; if (direction == ScrollDirection.forward) { @@ -219,6 +210,10 @@ class _VideoReplyPanelState extends State (BuildContext context, index) { double bottom = MediaQuery.of(context).padding.bottom; if (index == loadingState.response.replies.length) { + EasyThrottle.throttle( + 'replylist', const Duration(milliseconds: 200), () { + _videoReplyController.onLoadMore(); + }); return Container( padding: EdgeInsets.only(bottom: bottom), height: bottom + 100, @@ -259,6 +254,7 @@ class _VideoReplyPanelState extends State ), ) : HttpError( + errMsg: '还没有评论', callback: _videoReplyController.onReload, ), Error() => HttpError( diff --git a/lib/pages/video/detail/reply_reply/controller.dart b/lib/pages/video/detail/reply_reply/controller.dart index d9b9cdc8..d207d356 100644 --- a/lib/pages/video/detail/reply_reply/controller.dart +++ b/lib/pages/video/detail/reply_reply/controller.dart @@ -2,6 +2,7 @@ import 'package:PiliPalaX/grpc/app/main/community/reply/v1/reply.pb.dart'; import 'package:PiliPalaX/grpc/grpc_repo.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/pages/common/common_controller.dart'; +import 'package:PiliPalaX/utils/extension.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/http/reply.dart'; @@ -29,8 +30,6 @@ class VideoReplyReplyController extends CommonController // rpid 请求楼中楼回复 int? rpid; ReplyType replyType; // = ReplyType.video; - // 当前页 - RxString noMore = ''.obs; // 当前回复的回复 ReplyInfo? currentReplyItem; @@ -45,6 +44,8 @@ class VideoReplyReplyController extends CommonController ReplyInfo? firstFloor; + bool isEnd = false; + @override void onInit() { super.onInit(); @@ -81,7 +82,7 @@ class VideoReplyReplyController extends CommonController @override Future queryData([bool isRefresh = true]) async { - if (['没有更多了', '还没有评论'].contains(noMore.value)) return Future.value(); + if (isRefresh.not && isEnd) return Future.value(); if (!isDialogue && currentPage == 1 && !hasRoot && @@ -109,6 +110,7 @@ class VideoReplyReplyController extends CommonController @override Future onRefresh() { cursor = null; + isEnd = false; return super.onRefresh(); } @@ -158,24 +160,22 @@ class VideoReplyReplyController extends CommonController } if (isDialogue) { if (replies.replies.isNotEmpty) { - noMore.value = '加载中...'; if (replies.cursor.isEnd || replies.replies.length >= count.value) { - noMore.value = '没有更多了'; + isEnd = true; } } else { // 未登录状态replies可能返回null - noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了'; + isEnd = true; } } else { if (replies.root.replies.isNotEmpty) { - noMore.value = '加载中...'; if (replies.cursor.isEnd || replies.root.replies.length >= count.value) { - noMore.value = '没有更多了'; + isEnd = true; } } else { // 未登录状态replies可能返回null - noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了'; + isEnd = true; } } if (isDialogue) { @@ -210,7 +210,6 @@ class VideoReplyReplyController extends CommonController ); queryBySort() { - noMore.value = ''; mode.value = mode.value == Mode.MAIN_LIST_HOT ? Mode.MAIN_LIST_TIME : Mode.MAIN_LIST_HOT; diff --git a/lib/pages/video/detail/reply_reply/view.dart b/lib/pages/video/detail/reply_reply/view.dart index 53ba8d6b..64d46484 100644 --- a/lib/pages/video/detail/reply_reply/view.dart +++ b/lib/pages/video/detail/reply_reply/view.dart @@ -3,7 +3,9 @@ import 'package:PiliPalaX/grpc/app/main/community/reply/v1/reply.pb.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/pages/video/detail/reply/widgets/reply_item_grpc.dart'; import 'package:PiliPalaX/pages/video/detail/reply_new/reply_page.dart'; +import 'package:PiliPalaX/utils/extension.dart'; import 'package:PiliPalaX/utils/utils.dart'; +import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/common/skeleton/video_reply.dart'; @@ -290,66 +292,75 @@ class _VideoReplyReplyPanelState extends State { } Widget _buildBody(LoadingState loadingState, int index) { - if (loadingState is Success) { - if (index == loadingState.response.length) { - _videoReplyReplyController.onLoadMore(); - return Container( - padding: - EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom), - height: MediaQuery.of(context).padding.bottom + 100, - child: Center( - child: Obx( - () => Text( - _videoReplyReplyController.noMore.value, - style: TextStyle( - fontSize: 12, - color: Theme.of(context).colorScheme.outline, + return switch (loadingState) { + Loading() => CustomScrollView( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + slivers: [ + SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, int index) { + return const VideoReplySkeleton(); + }, + childCount: 8, + ), + ) + ], + ), + Success() => () { + if (index == loadingState.response.length) { + EasyThrottle.throttle( + 'replylist', const Duration(milliseconds: 200), () { + _videoReplyReplyController.onLoadMore(); + }); + return Container( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom), + height: MediaQuery.of(context).padding.bottom + 100, + child: Center( + child: Obx( + () => Text( + _videoReplyReplyController.isEnd.not + ? '加载中...' + : loadingState.response.isEmpty + ? '还没有评论' + : '没有更多了', + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.outline, + ), + ), ), ), - ), - ), - ); - } else { - return _videoReplyReplyController.index == index - ? AnimatedBuilder( - animation: _videoReplyReplyController.colorAnimation!, - builder: (context, child) { - return ColoredBox( - color: _videoReplyReplyController.colorAnimation?.value ?? - Theme.of(Get.context!).colorScheme.onInverseSurface, - child: _replyItem(loadingState.response[index], index), - ); - }, - ) - : _replyItem(loadingState.response[index], index); - } - } else if (loadingState is Error) { - return CustomScrollView( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - slivers: [ - HttpError( - errMsg: loadingState.errMsg, - callback: _videoReplyReplyController.onReload, - ) - ], - ); - } else { - return CustomScrollView( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - slivers: [ - SliverList( - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - return const VideoReplySkeleton(); - }, - childCount: 8, - ), - ) - ], - ); - } + ); + } else { + return _videoReplyReplyController.index == index + ? AnimatedBuilder( + animation: _videoReplyReplyController.colorAnimation!, + builder: (context, child) { + return ColoredBox( + color: _videoReplyReplyController + .colorAnimation?.value ?? + Theme.of(Get.context!).colorScheme.onInverseSurface, + child: _replyItem(loadingState.response[index], index), + ); + }, + ) + : _replyItem(loadingState.response[index], index); + } + }(), + Error() => CustomScrollView( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + slivers: [ + HttpError( + errMsg: loadingState.errMsg, + callback: _videoReplyReplyController.onReload, + ) + ], + ), + LoadingState() => throw UnimplementedError(), + }; } Widget _replyItem(replyItem, index) { diff --git a/lib/pages/video/detail/widgets/header_control.dart b/lib/pages/video/detail/widgets/header_control.dart index 2e87c570..450e61de 100644 --- a/lib/pages/video/detail/widgets/header_control.dart +++ b/lib/pages/video/detail/widgets/header_control.dart @@ -1564,9 +1564,9 @@ class _HeaderControlState extends State { !plPlayerController.isOpenDanmu.value; setting.put(SettingBoxKey.enableShowDanmaku, plPlayerController.isOpenDanmu.value); - SmartDialog.showToast( - "已${plPlayerController.isOpenDanmu.value ? '开启' : '关闭'}弹幕", - displayTime: const Duration(seconds: 1)); + // SmartDialog.showToast( + // "已${plPlayerController.isOpenDanmu.value ? '开启' : '关闭'}弹幕", + // displayTime: const Duration(seconds: 1)); }, icon: Icon( plPlayerController.isOpenDanmu.value