From e971fbc8768287e42f0adb2a9a281b7ac5f527fb Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 28 Apr 2023 23:05:29 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E6=A5=BC=E4=B8=AD=E6=A5=BC=E5=9B=9E?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 3 + lib/http/reply.dart | 34 +++++++++++ lib/models/video/reply/item.dart | 2 +- lib/pages/video/detail/reply/controller.dart | 23 +++++-- lib/pages/video/detail/reply/view.dart | 24 +++++++- .../detail/reply/widgets/reply_item.dart | 60 ++++++++++++++++++- lib/pages/video/detail/view.dart | 2 +- 7 files changed, 136 insertions(+), 12 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index de89bee9..068d7d24 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -16,4 +16,7 @@ class Api { // 评论列表 static const String replyList = '/x/v2/reply'; + + // 楼中楼 + static const String replyReplyList = '/x/v2/reply/reply'; } diff --git a/lib/http/reply.dart b/lib/http/reply.dart index 88000996..e9a609d2 100644 --- a/lib/http/reply.dart +++ b/lib/http/reply.dart @@ -33,4 +33,38 @@ class ReplyHttp { }; } } + + static Future replyReplyList({ + required String oid, + required String root, + required int pageNum, + required int type, + int sort = 1, + }) async { + var res = await Request().get(Api.replyReplyList, data: { + 'oid': oid, + 'root': root, + 'pn': pageNum, + 'type': type, + 'sort': 1, + }); + if (res.data['code'] == 0) { + return { + 'status': true, + 'data': res.data['data'], + }; + } else { + Map errMap = { + -400: '请求错误', + -404: '无此项', + 12002: '评论区已关闭', + 12009: '评论主体的type不合法', + }; + return { + 'status': false, + 'date': [], + 'msg': errMap[res.data['code']] ?? '请求异常', + }; + } + } } diff --git a/lib/models/video/reply/item.dart b/lib/models/video/reply/item.dart index 53b71b6e..c6838a13 100644 --- a/lib/models/video/reply/item.dart +++ b/lib/models/video/reply/item.dart @@ -149,6 +149,6 @@ class ReplyControl { entryText = json['sub_reply_entry_text']; titleText = json['sub_reply_title_text']; time = json['time_desc']; - location = json['location']; + location = json['location'] ?? ''; } } diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart index 23447a37..a82241d5 100644 --- a/lib/pages/video/detail/reply/controller.dart +++ b/lib/pages/video/detail/reply/controller.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/http/reply.dart'; @@ -5,9 +7,18 @@ import 'package:pilipala/models/video/reply/data.dart'; import 'package:pilipala/models/video/reply/item.dart'; class VideoReplyController extends GetxController { + VideoReplyController( + this.aid, + this.rpid, + this.level, + ); final ScrollController scrollController = ScrollController(); - // 视频aid - String aid = Get.parameters['aid']!; + // 视频aid 请求时使用的oid + String? aid; + // 层级 2为楼中楼 + String? level; + // rpid 请求楼中楼回复 + String? rpid; RxList replyList = [ReplyItemModel()].obs; // 当前页 int currentPage = 0; @@ -16,8 +27,11 @@ class VideoReplyController extends GetxController { Future queryReplyList({type = 'init'}) async { isLoadingMore = true; - var res = - await ReplyHttp.replyList(oid: aid, pageNum: currentPage + 1, type: 1); + var res = level == '1' + ? await ReplyHttp.replyList( + oid: aid!, pageNum: currentPage + 1, type: 1) + : await ReplyHttp.replyReplyList( + oid: aid!, root: rpid!, pageNum: currentPage + 1, type: 1); if (res['status']) { res['data'] = ReplyData.fromJson(res['data']); if (res['data'].replies.isNotEmpty) { @@ -27,6 +41,7 @@ class VideoReplyController extends GetxController { if (currentPage == 0) { } else { noMore = true; + return; } } if (type == 'init') { diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index b1ce3fad..c91ae3fa 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -7,7 +7,15 @@ import 'controller.dart'; import 'widgets/reply_item.dart'; class VideoReplyPanel extends StatefulWidget { - const VideoReplyPanel({super.key}); + int oid; + int rpid; + String level; + VideoReplyPanel({ + this.oid = 0, + this.rpid = 0, + this.level = '', + super.key, + }); @override State createState() => _VideoReplyPanelState(); @@ -15,8 +23,8 @@ class VideoReplyPanel extends StatefulWidget { class _VideoReplyPanelState extends State with AutomaticKeepAliveClientMixin { - final VideoReplyController _videoReplyController = - Get.put(VideoReplyController(), tag: Get.arguments['heroTag']); + late VideoReplyController _videoReplyController; + // List? replyList; Future? _futureBuilderFuture; // 添加页面缓存 @@ -26,6 +34,16 @@ class _VideoReplyPanelState extends State @override void initState() { super.initState(); + if (widget.level == '2') { + _videoReplyController = Get.put( + VideoReplyController( + widget.oid.toString(), widget.rpid.toString(), '2'), + tag: widget.rpid.toString()); + } else { + _videoReplyController = Get.put( + VideoReplyController(Get.parameters['aid']!, '', '1'), + tag: Get.arguments['heroTag']); + } _futureBuilderFuture = _videoReplyController.queryReplyList(); _videoReplyController.scrollController.addListener( diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 93ca58d1..2faba135 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/models/video/reply/item.dart'; +import 'package:pilipala/pages/video/detail/reply/index.dart'; import 'package:pilipala/utils/utils.dart'; class ReplyItem extends StatelessWidget { @@ -16,11 +17,13 @@ class ReplyItem extends StatelessWidget { child: Column( children: [ Padding( - padding: const EdgeInsets.fromLTRB(12, 6, 8, 0), + padding: const EdgeInsets.fromLTRB(12, 8, 8, 2), child: content(context), ), Divider( height: 1, + indent: 52, + endIndent: 10, color: Theme.of(context).dividerColor.withOpacity(0.08), ) ], @@ -113,6 +116,7 @@ class ReplyItem extends StatelessWidget { child: ReplyItemRow( replies: replyItem!.replies, replyControl: replyItem!.replyControl, + f_rpid: replyItem!.rpid, ), ), ], @@ -171,9 +175,11 @@ class ReplyItemRow extends StatelessWidget { super.key, this.replies, this.replyControl, + this.f_rpid, }); List? replies; ReplyControl? replyControl; + int? f_rpid; @override Widget build(BuildContext context) { @@ -195,7 +201,7 @@ class ReplyItemRow extends StatelessWidget { if (extraRow == 1 && index == replies!.length) { // 有楼中楼回复,在最后显示 return InkWell( - onTap: () {}, + onTap: () => replyReply(context), child: Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8), @@ -223,7 +229,13 @@ class ReplyItemRow extends StatelessWidget { return InkWell( onTap: () {}, child: Padding( - padding: EdgeInsets.fromLTRB(8, index == 0 ? 8 : 4, 8, 4), + padding: EdgeInsets.fromLTRB( + 8, + index == 0 && (extraRow == 1 || replies!.length > 1) + ? 8 + : 5, + 8, + 5), child: Text.rich( overflow: extraRow == 1 ? TextOverflow.ellipsis @@ -260,6 +272,48 @@ class ReplyItemRow extends StatelessWidget { ), ); } + + void replyReply(context) { + Get.bottomSheet( + barrierColor: Colors.transparent, + useRootNavigator: true, + isScrollControlled: true, + Container( + height: Get.size.height - Get.size.width * 9 / 16 - 50, + color: Theme.of(context).colorScheme.background, + child: Column( + children: [ + AppBar( + automaticallyImplyLeading: false, + centerTitle: false, + title: Text( + '评论详情', + style: Theme.of(context).textTheme.titleMedium, + ), + actions: [ + IconButton( + icon: const Icon(Icons.close), + onPressed: () async { + await Future.delayed(const Duration(milliseconds: 200)); + Get.back(); + }, + ) + ], + ), + Expanded( + child: VideoReplyPanel( + oid: replies!.first.oid, + rpid: f_rpid!, + level: '2', + ), + ) + ], + ), + ), + persistent: false, + backgroundColor: Theme.of(context).bottomSheetTheme.backgroundColor, + ); + } } InlineSpan buildContent(BuildContext context, content) { diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 1ff41764..6747ea69 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -136,7 +136,7 @@ class _VideoDetailPageState extends State { ); }, ), - const VideoReplyPanel() + VideoReplyPanel() ], ), ),