diff --git a/lib/grpc/grpc_repo.dart b/lib/grpc/grpc_repo.dart index e558be1d..4707824e 100644 --- a/lib/grpc/grpc_repo.dart +++ b/lib/grpc/grpc_repo.dart @@ -132,6 +132,7 @@ class GrpcRepo { } static Future detailList({ + int type = 1, required int oid, required int root, required CursorReq cursor, @@ -140,7 +141,7 @@ class GrpcRepo { return await _request(() async { final request = DetailListReq() ..oid = Int64(oid) - ..type = Int64(1) + ..type = Int64(type) ..root = Int64(root) ..cursor = cursor ..scene = scene; @@ -151,13 +152,14 @@ class GrpcRepo { } static Future mainList({ + int type = 1, required int oid, required CursorReq cursor, }) async { return await _request(() async { final request = MainListReq() ..oid = Int64(oid) - ..type = Int64(1) + ..type = Int64(type) ..rpid = Int64(0) ..cursor = cursor; final response = await GrpcClient.instance.replyClient diff --git a/lib/http/reply.dart b/lib/http/reply.dart index d6958a67..89b23af2 100644 --- a/lib/http/reply.dart +++ b/lib/http/reply.dart @@ -57,10 +57,11 @@ class ReplyHttp { } static Future replyListGrpc({ + int type = 1, required int oid, required CursorReq cursor, }) async { - dynamic res = await GrpcRepo.mainList(oid: oid, cursor: cursor); + dynamic res = await GrpcRepo.mainList(type: type, oid: oid, cursor: cursor); if (res['status']) { return LoadingState.success(res['data']); } else { @@ -99,11 +100,13 @@ class ReplyHttp { } static Future replyReplyListGrpc({ + int type = 1, required int oid, required int root, required CursorReq cursor, }) async { dynamic res = await GrpcRepo.detailList( + type: type, oid: oid, root: root, cursor: cursor, diff --git a/lib/pages/common/reply_controller.dart b/lib/pages/common/reply_controller.dart index 4a97e2b9..03e52a21 100644 --- a/lib/pages/common/reply_controller.dart +++ b/lib/pages/common/reply_controller.dart @@ -28,6 +28,10 @@ abstract class ReplyController extends CommonController { bool isLogin = GStorage.userInfo.get('userInfoCache') != null; + CursorReply? cursor; + Mode mode = Mode.MAIN_LIST_HOT; + bool hasUpTop = false; + @override void onInit() { super.onInit(); @@ -44,6 +48,7 @@ abstract class ReplyController extends CommonController { @override Future onRefresh() { + cursor = null; nextOffset = ''; noMore.value = ''; return super.onRefresh(); @@ -57,41 +62,29 @@ abstract class ReplyController extends CommonController { @override bool customHandleResponse(Success response) { - List replies = response.response.replies; - if (!isLogin) { - nextOffset = response.response.cursor.paginationReply.nextOffset ?? ""; + MainListReply replies = response.response; + if (cursor == null) { + count.value = replies.subjectControl.count.toInt(); + hasUpTop = replies.hasUpTop(); + if (replies.hasUpTop()) { + replies.replies.insert(0, replies.upTop); + } } - if (replies.isNotEmpty) { + cursor = replies.cursor; + if (replies.replies.isNotEmpty) { noMore.value = '加载中...'; - - /// 第一页回复数小于20 - if (currentPage == 1 && replies.length < 18) { + if (replies.cursor.isEnd) { noMore.value = '没有更多了'; } } else { // 未登录状态replies可能返回null - noMore.value = nextOffset == "" && currentPage == 1 ? '还没有评论' : '没有更多了'; + noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了'; } - if (currentPage == 1) { - // 添加置顶回复 - if (response.response.upper.top != null) { - final bool flag = response.response.topReplies.any( - (ReplyItemModel reply) => - reply.rpid == response.response.upper.top.rpid) as bool; - if (!flag) { - replies.insert(0, response.response.upper.top); - } - } - replies.insertAll(0, response.response.topReplies); - count.value = !isLogin - ? response.response.cursor.allCount - : response.response.page.count ?? 0; - } else { - replies.insertAll( - 0, - loadingState.value is Success - ? (loadingState.value as Success).response - : []); + if (currentPage != 1) { + List list = loadingState.value is Success + ? (loadingState.value as Success).response.replies + : []; + replies.replies.insertAll(0, list); } loadingState.value = LoadingState.success(replies); return true; @@ -104,9 +97,11 @@ abstract class ReplyController extends CommonController { switch (sortType) { case ReplySortType.time: sortType = ReplySortType.like; + mode = Mode.MAIN_LIST_HOT; break; case ReplySortType.like: sortType = ReplySortType.time; + mode = Mode.MAIN_LIST_TIME; break; default: } diff --git a/lib/pages/dynamics/detail/controller.dart b/lib/pages/dynamics/detail/controller.dart index ad81a28a..8e75e107 100644 --- a/lib/pages/dynamics/detail/controller.dart +++ b/lib/pages/dynamics/detail/controller.dart @@ -1,8 +1,10 @@ +import 'package:PiliPalaX/grpc/app/main/community/reply/v1/reply.pb.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/pages/common/reply_controller.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/http/html.dart'; import 'package:PiliPalaX/http/reply.dart'; +import 'package:fixnum/fixnum.dart' as $fixnum; class DynamicDetailController extends ReplyController { DynamicDetailController(this.oid, this.type); @@ -32,13 +34,23 @@ class DynamicDetailController extends ReplyController { queryData(); } + // @override + // Future customGetData() => ReplyHttp.replyList( + // isLogin: isLogin, + // oid: oid!, + // nextOffset: nextOffset, + // type: type!, + // sort: sortType.index, + // page: currentPage, + // ); + @override - Future customGetData() => ReplyHttp.replyList( - isLogin: isLogin, + Future customGetData() => ReplyHttp.replyListGrpc( + type: type ?? 1, oid: oid!, - nextOffset: nextOffset, - type: type!, - sort: sortType.index, - page: currentPage, + cursor: CursorReq( + next: cursor?.next ?? $fixnum.Int64(0), + mode: mode, + ), ); } diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index 1c734f6c..91b5a1b3 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:math'; import 'package:PiliPalaX/http/loading_state.dart'; +import 'package:PiliPalaX/pages/video/detail/reply/widgets/reply_item_grpc.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -105,20 +106,21 @@ class _DynamicDetailPageState extends State } // 查看二级评论 - void replyReply(replyItem) { - int oid = replyItem.oid; - int rpid = replyItem.rpid!; + void replyReply(replyItem, id) { + int oid = replyItem.oid.toInt(); + int rpid = replyItem.id.toInt()!; Get.to( () => Scaffold( appBar: AppBar( titleSpacing: 0, centerTitle: false, title: Text( - '评论详情${replyItem.rcount > 0 ? '(${replyItem.rcount})' : ''}', + '评论详情', style: Theme.of(context).textTheme.titleMedium, ), ), body: VideoReplyReplyPanel( + id: id, oid: oid, rpid: rpid, source: 'dynamic', @@ -369,7 +371,7 @@ class _DynamicDetailPageState extends State ? SliverList( delegate: SliverChildBuilderDelegate( (context, index) { - if (index == loadingState.response.length) { + if (index == loadingState.response.replies.length) { return Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom), @@ -387,8 +389,8 @@ class _DynamicDetailPageState extends State ), ); } else { - return ReplyItem( - replyItem: loadingState.response[index], + return ReplyItemGrpc( + replyItem: loadingState.response.replies[index], showReplyRow: true, replyLevel: '1', replyReply: replyReply, @@ -396,15 +398,17 @@ class _DynamicDetailPageState extends State onReply: () { _dynamicDetailController.onReply( context, - replyItem: loadingState.response[index], + replyItem: loadingState.response.replies[index], index: index, ); }, onDelete: _dynamicDetailController.onMDelete, + isTop: _dynamicDetailController.hasUpTop && index == 0, + upMid: loadingState.response.subjectControl.upMid, ); } }, - childCount: loadingState.response.length + 1, + childCount: loadingState.response.replies.length + 1, ), ) : loadingState is Error diff --git a/lib/pages/html/controller.dart b/lib/pages/html/controller.dart index 0f0d7b3a..3d695c27 100644 --- a/lib/pages/html/controller.dart +++ b/lib/pages/html/controller.dart @@ -1,8 +1,10 @@ +import 'package:PiliPalaX/grpc/app/main/community/reply/v1/reply.pb.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/pages/common/reply_controller.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/http/html.dart'; import 'package:PiliPalaX/http/reply.dart'; +import 'package:fixnum/fixnum.dart' as $fixnum; class HtmlRenderController extends ReplyController { late String id; @@ -42,13 +44,23 @@ class HtmlRenderController extends ReplyController { } } + // @override + // Future customGetData() => ReplyHttp.replyList( + // isLogin: isLogin, + // oid: oid.value, + // nextOffset: nextOffset, + // type: type, + // sort: sortType.index, + // page: currentPage, + // ); + @override - Future customGetData() => ReplyHttp.replyList( - isLogin: isLogin, - oid: oid.value, - nextOffset: nextOffset, + Future customGetData() => ReplyHttp.replyListGrpc( type: type, - sort: sortType.index, - page: currentPage, + oid: oid.value, + cursor: CursorReq( + next: cursor?.next ?? $fixnum.Int64(0), + mode: mode, + ), ); } diff --git a/lib/pages/html/view.dart b/lib/pages/html/view.dart index 49db667e..89c41eb7 100644 --- a/lib/pages/html/view.dart +++ b/lib/pages/html/view.dart @@ -3,6 +3,7 @@ import 'dart:math'; import 'package:PiliPalaX/common/widgets/article_content.dart'; import 'package:PiliPalaX/common/widgets/http_error.dart'; import 'package:PiliPalaX/http/loading_state.dart'; +import 'package:PiliPalaX/pages/video/detail/reply/widgets/reply_item_grpc.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -108,20 +109,21 @@ class _HtmlRenderPageState extends State } } - void replyReply(replyItem) { - int oid = replyItem.oid; - int rpid = replyItem.rpid!; + void replyReply(replyItem, id) { + int oid = replyItem.oid.toInt(); + int rpid = replyItem.id.toInt(); Get.to( () => Scaffold( appBar: AppBar( titleSpacing: 0, centerTitle: false, title: Text( - '评论详情${replyItem.rcount > 0 ? '(${replyItem.rcount})' : ''}', + '评论详情', style: Theme.of(context).textTheme.titleMedium, ), ), body: VideoReplyReplyPanel( + id: id, oid: oid, rpid: rpid, source: 'dynamic', @@ -330,9 +332,9 @@ class _HtmlRenderPageState extends State Widget replyList(LoadingState loadingState) { return loadingState is Success ? SliverList.builder( - itemCount: loadingState.response.length + 1, + itemCount: loadingState.response.replies.length + 1, itemBuilder: (context, index) { - if (index == loadingState.response.length) { + if (index == loadingState.response.replies.length) { return Container( padding: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom), @@ -350,8 +352,8 @@ class _HtmlRenderPageState extends State ), ); } else { - return ReplyItem( - replyItem: loadingState.response[index], + return ReplyItemGrpc( + replyItem: loadingState.response.replies[index], showReplyRow: true, replyLevel: '1', replyReply: replyReply, @@ -359,11 +361,13 @@ class _HtmlRenderPageState extends State onReply: () { _htmlRenderCtr.onReply( context, - replyItem: loadingState.response[index], + replyItem: loadingState.response.replies[index], index: index, ); }, onDelete: _htmlRenderCtr.onMDelete, + isTop: _htmlRenderCtr.hasUpTop && index == 0, + upMid: loadingState.response.subjectControl.upMid, ); } }, diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart index 2c98008b..6fdfd72d 100644 --- a/lib/pages/video/detail/reply/controller.dart +++ b/lib/pages/video/detail/reply/controller.dart @@ -1,10 +1,7 @@ import 'package:PiliPalaX/grpc/app/main/community/reply/v1/reply.pb.dart'; import 'package:PiliPalaX/http/loading_state.dart'; -import 'package:PiliPalaX/models/common/reply_sort_type.dart'; import 'package:PiliPalaX/pages/common/reply_controller.dart'; import 'package:PiliPalaX/http/reply.dart'; -import 'package:PiliPalaX/utils/feed_back.dart'; -import 'package:easy_debounce/easy_throttle.dart'; import 'package:fixnum/fixnum.dart' as $fixnum; class VideoReplyController extends ReplyController { @@ -20,76 +17,6 @@ class VideoReplyController extends ReplyController { // rpid 请求楼中楼回复 String? rpid; - CursorReply? cursor; - Mode mode = Mode.MAIN_LIST_HOT; - bool hasUpTop = false; - - @override - Future onRefresh() { - cursor = null; - return super.onRefresh(); - } - - @override - queryBySort() { - EasyThrottle.throttle('queryBySort', const Duration(seconds: 1), () { - feedBack(); - switch (sortType) { - case ReplySortType.time: - sortType = ReplySortType.like; - mode = Mode.MAIN_LIST_HOT; - break; - case ReplySortType.like: - sortType = ReplySortType.time; - mode = Mode.MAIN_LIST_TIME; - break; - default: - } - sortTypeTitle.value = sortType.titles; - sortTypeLabel.value = sortType.labels; - nextOffset = ""; - noMore.value = ''; - loadingState.value = LoadingState.loading(); - onRefresh(); - }); - } - - @override - bool customHandleResponse(Success response) { - MainListReply replies = response.response; - if (cursor == null) { - count.value = replies.subjectControl.count.toInt(); - hasUpTop = replies.hasUpTop(); - if (replies.hasUpTop()) { - replies.replies.insert(0, replies.upTop); - } - } - cursor = replies.cursor; - // replies.replies.clear(); - // showDialog( - // context: Get.context!, - // builder: (_) => AlertDialog( - // content: SelectableText(jsonEncode(replies.toProto3Json())), - // )); - if (replies.replies.isNotEmpty) { - noMore.value = '加载中...'; - if (replies.cursor.isEnd) { - noMore.value = '没有更多了'; - } - } else { - // 未登录状态replies可能返回null - noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了'; - } - if (currentPage != 1) { - List list = loadingState.value is Success - ? (loadingState.value as Success).response.replies - : []; - replies.replies.insertAll(0, list); - } - loadingState.value = LoadingState.success(replies); - return true; - } - @override Future customGetData() => ReplyHttp.replyListGrpc( oid: aid!, diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index 36f01f1c..58fbfd45 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -224,7 +224,6 @@ class _VideoReplyPanelState extends State return ReplyItemGrpc( replyItem: loadingState.response.replies[index], showReplyRow: true, - isTop: _videoReplyController.hasUpTop && index == 0, replyLevel: replyLevel, replyReply: widget.replyReply, replyType: ReplyType.video, @@ -236,6 +235,7 @@ class _VideoReplyPanelState extends State ); }, onDelete: _videoReplyController.onMDelete, + isTop: _videoReplyController.hasUpTop && index == 0, upMid: loadingState.response.subjectControl.upMid, ); } diff --git a/lib/pages/video/detail/reply_reply/controller.dart b/lib/pages/video/detail/reply_reply/controller.dart index cd340c83..0a705aaf 100644 --- a/lib/pages/video/detail/reply_reply/controller.dart +++ b/lib/pages/video/detail/reply_reply/controller.dart @@ -131,6 +131,7 @@ class VideoReplyReplyController extends CommonController { @override Future customGetData() => ReplyHttp.replyReplyListGrpc( + type: replyType.index, oid: aid!, root: int.parse(rpid!), cursor: CursorReq( diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 5bbea558..72110314 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -4,7 +4,6 @@ import 'dart:math'; import 'package:PiliPalaX/common/constants.dart'; import 'package:PiliPalaX/common/widgets/list_sheet.dart'; -import 'package:PiliPalaX/grpc/grpc_repo.dart'; import 'package:PiliPalaX/http/loading_state.dart'; import 'package:PiliPalaX/models/bangumi/info.dart'; import 'package:PiliPalaX/models/common/reply_type.dart';