From f9f17bcf09b17a8b915796e2585986e9faafd9ee Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 29 Oct 2024 22:48:02 +0800 Subject: [PATCH 1/5] update: positionedList plugin --- lib/common/pages_bottom_sheet.dart | 69 ++++++++++++-------- lib/pages/bangumi/widgets/bangumi_panel.dart | 2 - pubspec.lock | 8 +-- pubspec.yaml | 2 +- 4 files changed, 48 insertions(+), 33 deletions(-) diff --git a/lib/common/pages_bottom_sheet.dart b/lib/common/pages_bottom_sheet.dart index afc74bd2..d7872f13 100644 --- a/lib/common/pages_bottom_sheet.dart +++ b/lib/common/pages_bottom_sheet.dart @@ -5,7 +5,7 @@ import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/models/video_detail_res.dart'; import 'package:pilipala/utils/utils.dart'; -import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; +import 'package:scrollview_observer/scrollview_observer.dart'; import '../models/common/video_episode_type.dart'; import 'widgets/badge.dart'; import 'widgets/stat/danmu.dart'; @@ -83,7 +83,8 @@ class PagesBottomSheet extends StatefulWidget { } class _PagesBottomSheetState extends State { - final ItemScrollController _itemScrollController = ItemScrollController(); + final ScrollController _listScrollController = ScrollController(); + late ListObserverController _listObserverController; final ScrollController _scrollController = ScrollController(); late int currentIndex; @@ -92,10 +93,17 @@ class _PagesBottomSheetState extends State { super.initState(); currentIndex = widget.episodes.indexWhere((dynamic e) => e.cid == widget.currentCid); + _listObserverController = + ListObserverController(controller: _listScrollController); + if (widget.dataType == VideoEpidoesType.videoEpisode) { + _listObserverController.initialIndexModel = ObserverIndexPositionModel( + index: currentIndex, + isFixedHeight: true, + ); + } + WidgetsBinding.instance.addPostFrameCallback((_) { - if (widget.dataType == VideoEpidoesType.videoEpisode) { - _itemScrollController.jumpTo(index: currentIndex); - } else { + if (widget.dataType != VideoEpidoesType.videoEpisode) { double itemHeight = (widget.isFullScreen ? 400 : Get.size.width - 3 * StyleString.safeSpace) / @@ -118,6 +126,12 @@ class _PagesBottomSheetState extends State { return '选集'; } + @override + void dispose() { + _listObserverController.controller?.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return StatefulBuilder( @@ -136,27 +150,30 @@ class _PagesBottomSheetState extends State { Expanded( child: Material( child: widget.dataType == VideoEpidoesType.videoEpisode - ? ScrollablePositionedList.builder( - itemScrollController: _itemScrollController, - itemCount: widget.episodes.length + 1, - itemBuilder: (BuildContext context, int index) { - bool isLastItem = index == widget.episodes.length; - bool isCurrentIndex = currentIndex == index; - return isLastItem - ? SizedBox( - height: - MediaQuery.of(context).padding.bottom + - 20, - ) - : EpisodeListItem( - episode: widget.episodes[index], - index: index, - isCurrentIndex: isCurrentIndex, - dataType: widget.dataType, - changeFucCall: widget.changeFucCall, - isFullScreen: widget.isFullScreen, - ); - }, + ? ListViewObserver( + controller: _listObserverController, + child: ListView.builder( + controller: _listScrollController, + itemCount: widget.episodes.length + 1, + itemBuilder: (BuildContext context, int index) { + bool isLastItem = index == widget.episodes.length; + bool isCurrentIndex = currentIndex == index; + return isLastItem + ? SizedBox( + height: + MediaQuery.of(context).padding.bottom + + 20, + ) + : EpisodeListItem( + episode: widget.episodes[index], + index: index, + isCurrentIndex: isCurrentIndex, + dataType: widget.dataType, + changeFucCall: widget.changeFucCall, + isFullScreen: widget.isFullScreen, + ); + }, + ), ) : Padding( padding: const EdgeInsets.symmetric( diff --git a/lib/pages/bangumi/widgets/bangumi_panel.dart b/lib/pages/bangumi/widgets/bangumi_panel.dart index db29d8e2..cdca500c 100644 --- a/lib/pages/bangumi/widgets/bangumi_panel.dart +++ b/lib/pages/bangumi/widgets/bangumi_panel.dart @@ -7,7 +7,6 @@ import 'package:hive/hive.dart'; import 'package:pilipala/models/bangumi/info.dart'; import 'package:pilipala/pages/video/detail/index.dart'; import 'package:pilipala/utils/storage.dart'; -import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import '../../../common/pages_bottom_sheet.dart'; import '../../../models/common/video_episode_type.dart'; import '../introduction/controller.dart'; @@ -44,7 +43,6 @@ class _BangumiPanelState extends State { late int cid; String heroTag = Get.arguments['heroTag']; late final VideoDetailController videoDetailCtr; - final ItemScrollController itemScrollController = ItemScrollController(); late PersistentBottomSheetController? _bottomSheetController; @override diff --git a/pubspec.lock b/pubspec.lock index 8050b857..35e34ab9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1434,14 +1434,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.1.3" - scrollable_positioned_list: + scrollview_observer: dependency: "direct main" description: - name: scrollable_positioned_list - sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287" + name: scrollview_observer + sha256: fa408bcfd41e19da841eb53fc471f8f952d5ef818b854d2505c4bb3f0c876381 url: "https://pub.flutter-io.cn" source: hosted - version: "0.3.8" + version: "1.22.0" sentry: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0b9711ad..db58395b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -134,7 +134,7 @@ dependencies: # 极验 gt3_flutter_plugin: ^0.1.0 uuid: ^3.0.7 - scrollable_positioned_list: ^0.3.8 + scrollview_observer: ^1.22.0 catcher_2: ^1.2.6 logger: ^2.3.0 path: ^1.9.0 From 3808c3ddae3dfe7a78547e1dc75c42e2083edb99 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Wed, 30 Oct 2024 23:27:54 +0800 Subject: [PATCH 2/5] fix: scheme SchemeEntity --- lib/utils/app_scheme.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/utils/app_scheme.dart b/lib/utils/app_scheme.dart index 5d4196bc..70e7c79d 100644 --- a/lib/utils/app_scheme.dart +++ b/lib/utils/app_scheme.dart @@ -212,9 +212,9 @@ class PiliSchame { } } - static Future biliScheme(Uri value) async { - final String host = value.host; - final String path = value.path; + static Future biliScheme(SchemeEntity value) async { + final String host = value.host!; + final String path = value.path!; switch (host) { case 'root': Navigator.popUntil( From a49429bbf168fb1c86f1d9d3e7b942ee8828e27f Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 31 Oct 2024 23:05:57 +0800 Subject: [PATCH 3/5] fix: replyAdd params --- lib/http/video.dart | 6 +++--- lib/pages/video/detail/reply/view.dart | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/http/video.dart b/lib/http/video.dart index b3970a14..6fa7386c 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -357,8 +357,8 @@ class VideoHttp { 'plat': 1, 'oid': oid, 'type': type.index, - // 'root': root == null || root == 0 ? '' : root, - // 'parent': parent == null || parent == 0 ? '' : parent, + 'root': root == null || root == 0 ? '' : root, + 'parent': parent == null || parent == 0 ? '' : parent, 'message': message, 'at_name_to_mid': {}, if (pictures != null) 'pictures': jsonEncode(pictures), @@ -377,8 +377,8 @@ class VideoHttp { }, data: formData, ); - log(res.toString()); if (res.data['code'] == 0) { + log(res.toString()); return {'status': true, 'data': res.data['data']}; } else { return {'status': false, 'data': [], 'msg': res.data['message']}; diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index 1b70015c..5d9b7dab 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -312,13 +312,13 @@ class _VideoReplyPanelState extends State ); }, ).then( - (value) => { + (value) { // 完成评论,数据添加 - if (value != null && value['data'] != null) - { - _videoReplyController.replyList - .add(value['data']) - } + if (value != null && value['data'] != null) { + _videoReplyController.replyList + .add(value['data']); + _videoReplyController.replyList.refresh(); + } }, ); }, From 91aaa1b5190424f1370b4a9dc666761d4c042ded Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 31 Oct 2024 23:22:29 +0800 Subject: [PATCH 4/5] fix: replyreply load --- .../video/detail/reply_reply/controller.dart | 15 ++++++++------- lib/pages/video/detail/reply_reply/view.dart | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/pages/video/detail/reply_reply/controller.dart b/lib/pages/video/detail/reply_reply/controller.dart index 506e530e..9cf88282 100644 --- a/lib/pages/video/detail/reply_reply/controller.dart +++ b/lib/pages/video/detail/reply_reply/controller.dart @@ -16,7 +16,7 @@ class VideoReplyReplyController extends GetxController { ReplyItemModel? rootReply; RxList replyList = [].obs; // 当前页 - int currentPage = 0; + int currentPage = 1; bool isLoadingMore = false; RxString noMore = ''.obs; // 当前回复的回复 @@ -25,12 +25,12 @@ class VideoReplyReplyController extends GetxController { @override void onInit() { super.onInit(); - currentPage = 0; + currentPage = 1; } Future queryReplyList({type = 'init', currentReply}) async { if (type == 'init') { - currentPage = 0; + currentPage = 1; } if (isLoadingMore) { return; @@ -39,7 +39,7 @@ class VideoReplyReplyController extends GetxController { final res = await ReplyHttp.replyReplyList( oid: aid!, root: rpid!, - pageNum: currentPage + 1, + pageNum: currentPage, type: replyType.index, ); if (res['status']) { @@ -50,12 +50,12 @@ class VideoReplyReplyController extends GetxController { if (replies.length == res['data'].page.count) { noMore.value = '没有更多了'; } - currentPage++; + // currentPage++; } else { // 未登录状态replies可能返回null - noMore.value = currentPage == 0 ? '还没有评论' : '没有更多了'; + noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了'; } - if (type == 'init') { + if (type == 'init' && currentPage == 1) { replyList.value = replies; } else { // 每次回复之后,翻页请求有且只有相同的一条回复数据 @@ -79,6 +79,7 @@ class VideoReplyReplyController extends GetxController { replyList.insert(0, currentReply); } } + currentPage += 1; isLoadingMore = false; return res; } diff --git a/lib/pages/video/detail/reply_reply/view.dart b/lib/pages/video/detail/reply_reply/view.dart index 8ac24302..8da8e535 100644 --- a/lib/pages/video/detail/reply_reply/view.dart +++ b/lib/pages/video/detail/reply_reply/view.dart @@ -183,8 +183,7 @@ class _VideoReplyReplyPanelState extends State { Expanded( child: RefreshIndicator( onRefresh: () async { - setState(() {}); - _videoReplyReplyController.currentPage = 0; + _videoReplyReplyController.currentPage = 1; return await _videoReplyReplyController.queryReplyList( currentReply: widget.currentReply, ); From 4fd49befbb11ef0cb04ad73dd23415b202dd70b1 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 1 Nov 2024 09:17:57 +0800 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20=E8=AF=84=E8=AE=BA=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/dynamics/detail/controller.dart | 21 ++++++++------- lib/pages/dynamics/detail/view.dart | 2 +- lib/pages/video/detail/reply/controller.dart | 28 ++++++++++++-------- lib/pages/video/detail/reply/view.dart | 2 +- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/lib/pages/dynamics/detail/controller.dart b/lib/pages/dynamics/detail/controller.dart index 7ca55c59..e7c179f3 100644 --- a/lib/pages/dynamics/detail/controller.dart +++ b/lib/pages/dynamics/detail/controller.dart @@ -26,6 +26,7 @@ class DynamicDetailController extends GetxController { RxString sortTypeLabel = ReplySortType.time.labels.obs; Box setting = GStrorage.setting; RxInt replyReqCode = 200.obs; + bool isEnd = false; @override void onInit() { @@ -48,7 +49,7 @@ class DynamicDetailController extends GetxController { } Future queryReplyList({reqType = 'init'}) async { - if (isLoadingMore) { + if (isLoadingMore || noMore.value == '没有更多了' || isEnd) { return; } isLoadingMore = true; @@ -56,10 +57,6 @@ class DynamicDetailController extends GetxController { nextOffset = ''; noMore.value = ''; } - if (noMore.value == '没有更多了') { - isLoadingMore = false; - return; - } var res = await ReplyHttp.replyList( oid: oid!, nextOffset: nextOffset, @@ -68,15 +65,14 @@ class DynamicDetailController extends GetxController { ); if (res['status']) { List replies = res['data'].replies; + isEnd = res['data'].cursor.isEnd ?? false; acount.value = res['data'].cursor.allCount; nextOffset = res['data'].cursor.paginationReply.nextOffset ?? ""; if (replies.isNotEmpty) { - noMore.value = '加载中...'; - if (res['data'].cursor.isEnd == true) { - noMore.value = '没有更多了'; - } + noMore.value = isEnd ? '没有更多了' : '加载中...'; } else { - noMore.value = nextOffset == "" ? '还没有评论' : '没有更多了'; + noMore.value = + replyList.isEmpty && nextOffset == "" ? '还没有评论' : '没有更多了'; } if (reqType == 'init') { // 添加置顶回复 @@ -122,4 +118,9 @@ class DynamicDetailController extends GetxController { var res = await HtmlHttp.reqHtml(id, 'opus'); oid = res['commentId']; } + + // 上拉加载 + Future onLoad() async { + queryReplyList(reqType: 'onLoad'); + } } diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index 395f89b8..e80befec 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -140,7 +140,7 @@ class _DynamicDetailPageState extends State if (scrollController.position.pixels >= scrollController.position.maxScrollExtent - 300) { EasyThrottle.throttle('replylist', const Duration(seconds: 2), () { - _dynamicDetailController.queryReplyList(reqType: 'onLoad'); + _dynamicDetailController.onLoad(); }); } diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart index bb1d6a97..a5797c7b 100644 --- a/lib/pages/video/detail/reply/controller.dart +++ b/lib/pages/video/detail/reply/controller.dart @@ -34,6 +34,7 @@ class VideoReplyController extends GetxController { Box setting = GStrorage.setting; RxInt replyReqCode = 200.obs; + bool isEnd = false; @override void onInit() { @@ -49,8 +50,8 @@ class VideoReplyController extends GetxController { sortTypeLabel.value = _sortType.labels; } - Future queryReplyList({type = 'init'}) async { - if (isLoadingMore) { + Future queryReplyList({type = 'init'}) async { + if (isLoadingMore || noMore.value == '没有更多了' || isEnd) { return; } isLoadingMore = true; @@ -58,10 +59,6 @@ class VideoReplyController extends GetxController { nextOffset = ''; noMore.value = ''; } - if (noMore.value == '没有更多了') { - isLoadingMore = false; - return; - } final res = await ReplyHttp.replyList( oid: aid!, nextOffset: nextOffset, @@ -70,14 +67,13 @@ class VideoReplyController extends GetxController { ); if (res['status']) { final List replies = res['data'].replies; + isEnd = res['data'].cursor.isEnd ?? false; nextOffset = res['data'].cursor.paginationReply.nextOffset ?? ""; if (replies.isNotEmpty) { - noMore.value = '加载中...'; - if (res['data'].cursor.isEnd == true) { - noMore.value = '没有更多了'; - } + noMore.value = isEnd ? '没有更多了' : '加载中...'; } else { - noMore.value = nextOffset == "" ? '还没有评论' : '没有更多了'; + noMore.value = + replyList.isEmpty && nextOffset == "" ? '还没有评论' : '没有更多了'; } if (type == 'init') { // 添加置顶回复 @@ -105,6 +101,14 @@ class VideoReplyController extends GetxController { queryReplyList(type: 'onLoad'); } + // 下拉刷新 + Future onRefresh() async { + nextOffset = ""; + noMore.value = ''; + isEnd = false; + queryReplyList(type: 'init'); + } + // 排序搜索评论 queryBySort() { EasyThrottle.throttle('queryBySort', const Duration(seconds: 1), () { @@ -118,6 +122,8 @@ class VideoReplyController extends GetxController { break; default: } + isLoadingMore = false; + isEnd = false; sortTypeTitle.value = _sortType.titles; sortTypeLabel.value = _sortType.labels; nextOffset = ""; diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index 5d9b7dab..54372c5e 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -137,7 +137,7 @@ class _VideoReplyPanelState extends State super.build(context); return RefreshIndicator( onRefresh: () async { - return await _videoReplyController.queryReplyList(type: 'init'); + return await _videoReplyController.onRefresh(); }, child: Stack( children: [