From 6029d409e7d7f308902c66db9e273b4d4d3f6afe Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Fri, 6 Sep 2024 11:36:03 +0800 Subject: [PATCH] opt: reply page --- lib/pages/video/detail/reply/controller.dart | 3 + lib/pages/video/detail/reply/view.dart | 287 +++++++++++-------- lib/pages/video/detail/view.dart | 3 +- 3 files changed, 171 insertions(+), 122 deletions(-) diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart index a9faf6ae..cbcd2bce 100644 --- a/lib/pages/video/detail/reply/controller.dart +++ b/lib/pages/video/detail/reply/controller.dart @@ -37,6 +37,8 @@ class VideoReplyController extends GetxController { Box setting = GStorage.setting; + Future? futureBuilderFuture; + @override void onInit() { super.onInit(); @@ -98,6 +100,7 @@ class VideoReplyController extends GetxController { replyList.addAll(replies); } } + return res; } // 上拉加载 diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index 2a5f163b..3eaaca06 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -1,3 +1,4 @@ +import 'package:PiliPalaX/common/widgets/http_error.dart'; import 'package:PiliPalaX/pages/video/detail/reply_new/reply_page.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; @@ -180,130 +181,174 @@ class _VideoReplyPanelState extends State ), ), ), - Obx( - () => _videoReplyController.isLoadingMore && - _videoReplyController.replyList.isEmpty && - (_videoReplyController.noMore.value == '' || - _videoReplyController.noMore.value == '加载中...') - ? SliverList( - delegate: SliverChildBuilderDelegate( - (BuildContext context, index) { - return const VideoReplySkeleton(); - }, childCount: 5), - ) - : SliverList( - delegate: SliverChildBuilderDelegate( - (BuildContext context, index) { - double bottom = - MediaQuery.of(context).padding.bottom; - if (index == - _videoReplyController.replyList.length) { - return Container( - padding: EdgeInsets.only(bottom: bottom), - height: bottom + 100, - child: Center( - child: Obx( - () => Text( - _videoReplyController.noMore.value, - style: TextStyle( - fontSize: 12, - color: Theme.of(context) - .colorScheme - .outline, - ), - ), - ), - ), - ); - } else { - return ReplyItem( - replyItem: - _videoReplyController.replyList[index], - showReplyRow: true, - replyLevel: replyLevel, - replyReply: (replyItem) => - replyReply(replyItem), - replyType: ReplyType.video, - onReply: () { - dynamic oid = _videoReplyController - .replyList[index].oid; - dynamic root = _videoReplyController - .replyList[index].rpid; - dynamic parent = _videoReplyController - .replyList[index].rpid; - dynamic key = oid + root + parent; - Navigator.of(context) - .push( - GetDialogRoute( - pageBuilder: (buildContext, animation, - secondaryAnimation) { - return ReplyPage( - oid: oid, - root: root, - parent: parent, - replyType: ReplyType.video, - replyItem: _videoReplyController - .replyList[index], - savedReply: _savedReplies[key], - onSaveReply: (reply) { - _savedReplies[key] = reply; - }, - ); - }, - transitionDuration: - const Duration(milliseconds: 500), - transitionBuilder: (context, animation, - secondaryAnimation, child) { - const begin = Offset(0.0, 1.0); - const end = Offset.zero; - const curve = Curves.linear; + FutureBuilder( + future: _videoReplyController.futureBuilderFuture, + builder: (BuildContext context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + var data = snapshot.data; + if (data['status']) { + // 请求成功 + return Obx( + () => _videoReplyController.isLoadingMore && + _videoReplyController.replyList.isEmpty + ? SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, index) { + return const VideoReplySkeleton(); + }, childCount: 5), + ) + : SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, index) { + double bottom = + MediaQuery.of(context).padding.bottom; + if (index == + _videoReplyController + .replyList.length) { + return Container( + padding: + EdgeInsets.only(bottom: bottom), + height: bottom + 100, + child: Center( + child: Obx( + () => Text( + _videoReplyController + .noMore.value, + style: TextStyle( + fontSize: 12, + color: Theme.of(context) + .colorScheme + .outline, + ), + ), + ), + ), + ); + } else { + return ReplyItem( + replyItem: _videoReplyController + .replyList[index], + showReplyRow: true, + replyLevel: replyLevel, + replyReply: (replyItem) => + replyReply(replyItem), + replyType: ReplyType.video, + onReply: () { + dynamic oid = _videoReplyController + .replyList[index].oid; + dynamic root = _videoReplyController + .replyList[index].rpid; + dynamic parent = _videoReplyController + .replyList[index].rpid; + dynamic key = oid + root + parent; + Navigator.of(context) + .push( + GetDialogRoute( + pageBuilder: (buildContext, + animation, + secondaryAnimation) { + return ReplyPage( + oid: oid, + root: root, + parent: parent, + replyType: ReplyType.video, + replyItem: + _videoReplyController + .replyList[index], + savedReply: + _savedReplies[key], + onSaveReply: (reply) { + _savedReplies[key] = reply; + }, + ); + }, + transitionDuration: + const Duration( + milliseconds: 500), + transitionBuilder: (context, + animation, + secondaryAnimation, + child) { + const begin = Offset(0.0, 1.0); + const end = Offset.zero; + const curve = Curves.linear; - var tween = Tween( - begin: begin, end: end) - .chain(CurveTween(curve: curve)); + var tween = Tween( + begin: begin, end: end) + .chain(CurveTween( + curve: curve)); - return SlideTransition( - position: animation.drive(tween), - child: child, - ); - }, - ), - ) - .then((value) { - // 完成评论,数据添加 - if (value != null && - value['data'] != null) { - _savedReplies[key] = null; + return SlideTransition( + position: + animation.drive(tween), + child: child, + ); + }, + ), + ) + .then((value) { + // 完成评论,数据添加 + if (value != null && + value['data'] != null) { + _savedReplies[key] = null; + } + }); + }, + onDelete: (rpid, frpid) { + _videoReplyController.replyList.value = + frpid == null + ? _videoReplyController + .replyList + .where((item) => + item.rpid != rpid) + .toList() + : _videoReplyController + .replyList + .map((item) { + if (item.rpid == frpid) { + return item + ..replies = item + .replies + ?.where((reply) => + reply.rpid != + rpid) + .toList(); + } else { + return item; + } + }).toList(); + }, + ); } - }); - }, - onDelete: (rpid, frpid) { - frpid == null - ? _videoReplyController.replyList.value = - _videoReplyController.replyList - .where( - (item) => item.rpid != rpid) - .toList() - : _videoReplyController.replyList - .map((item) { - if (item.rpid == frpid) { - return item - ..replies = item.replies - ?.where((reply) => - reply.rpid != rpid) - .toList(); - } else { - return item; - } - }).toList(); - }, - ); - } - }, - childCount: - _videoReplyController.replyList.length + 1, - ), - ), + }, + childCount: + _videoReplyController.replyList.length + + 1, + ), + ), + ); + } else { + // 请求错误 + return HttpError( + errMsg: data['msg'], + fn: () { + setState(() { + _videoReplyController.futureBuilderFuture = + _videoReplyController.queryReplyList(); + }); + }, + ); + } + } else { + // 骨架屏 + return SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, index) { + return const VideoReplySkeleton(); + }, childCount: 5), + ); + } + }, ), ], ), diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index b24c7894..20d979b9 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -148,7 +148,8 @@ class _VideoDetailPageState extends State // 获取视频资源,初始化播放器 Future videoSourceInit() async { _futureBuilderFuture = videoDetailController.queryVideoUrl(); - _videoReplyController.queryReplyList(type: 'init'); + _videoReplyController.futureBuilderFuture = + _videoReplyController.queryReplyList(type: 'init'); if (videoDetailController.autoPlay.value) { plPlayerController = videoDetailController.plPlayerController; plPlayerController!.addStatusLister(playerListener);