From 1542f87722534b7a7393dd32274cb786aea2821a Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Thu, 12 Sep 2024 20:55:13 +0800 Subject: [PATCH] opt: onReply, onDelete --- lib/pages/bangumi/introduction/view.dart | 1 - lib/pages/common/reply_controller.dart | 79 ++++++++++ lib/pages/dynamics/detail/controller.dart | 5 +- lib/pages/dynamics/detail/view.dart | 46 ++---- lib/pages/html/view.dart | 39 ++--- lib/pages/video/detail/reply/view.dart | 146 +----------------- .../detail/reply/widgets/reply_item.dart | 66 -------- .../video/detail/reply_new/reply_page.dart | 46 +++--- lib/pages/video/detail/reply_reply/view.dart | 27 ++-- 9 files changed, 149 insertions(+), 306 deletions(-) diff --git a/lib/pages/bangumi/introduction/view.dart b/lib/pages/bangumi/introduction/view.dart index 01d1176e..ca75b2e3 100644 --- a/lib/pages/bangumi/introduction/view.dart +++ b/lib/pages/bangumi/introduction/view.dart @@ -38,7 +38,6 @@ class _BangumiIntroPanelState extends State with AutomaticKeepAliveClientMixin { late BangumiIntroController bangumiIntroController; late VideoDetailController videoDetailCtr; - late Future _futureBuilderFuture; late int cid; late String heroTag; diff --git a/lib/pages/common/reply_controller.dart b/lib/pages/common/reply_controller.dart index 40b165f5..31b00e27 100644 --- a/lib/pages/common/reply_controller.dart +++ b/lib/pages/common/reply_controller.dart @@ -1,11 +1,15 @@ import 'package:PiliPalaX/http/loading_state.dart'; +import 'package:PiliPalaX/models/common/reply_type.dart'; import 'package:PiliPalaX/pages/common/common_controller.dart'; +import 'package:PiliPalaX/pages/video/detail/reply_new/reply_page.dart'; import 'package:easy_debounce/easy_throttle.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPalaX/models/common/reply_sort_type.dart'; import 'package:PiliPalaX/models/video/reply/item.dart'; import 'package:PiliPalaX/utils/feed_back.dart'; import 'package:PiliPalaX/utils/storage.dart'; +import 'package:get/get_navigation/src/dialog/dialog_route.dart'; abstract class ReplyController extends CommonController { String nextOffset = ""; @@ -19,6 +23,8 @@ abstract class ReplyController extends CommonController { RxString sortTypeTitle = ReplySortType.time.titles.obs; RxString sortTypeLabel = ReplySortType.time.labels.obs; + late final savedReplies = {}; + @override void onInit() { super.onInit(); @@ -105,4 +111,77 @@ abstract class ReplyController extends CommonController { onRefresh(); }); } + + void onReply( + BuildContext context, { + dynamic oid, + dynamic replyItem, + int index = 0, + }) { + dynamic key = oid ?? replyItem.oid + replyItem.rpid + replyItem.rpid; + Navigator.of(context) + .push( + GetDialogRoute( + pageBuilder: (buildContext, animation, secondaryAnimation) { + return ReplyPage( + oid: oid ?? replyItem.oid, + root: oid != null ? 0 : replyItem.rpid, + parent: oid != null ? 0 : replyItem.rpid, + replyType: ReplyType.video, + replyItem: replyItem, + 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)); + + return SlideTransition( + position: animation.drive(tween), + child: child, + ); + }, + ), + ) + .then( + (value) { + if (value != null && value['data'] != null) { + savedReplies[key] = null; + List list = loadingState.value is Success + ? (loadingState.value as Success).response + : []; + if (index == 0) { + list.insert(0, value['data']); + } else { + list[index].replies.add(value['data']); + } + loadingState.value = LoadingState.success(list); + } + }, + ); + } + + onMDelete(rpid, frpid) { + List list = (loadingState.value as Success).response; + list = frpid == null + ? list.where((item) => item.rpid != rpid).toList() + : list.map((item) { + if (item.rpid == frpid) { + return item + ..replies = + item.replies?.where((reply) => reply.rpid != rpid).toList(); + } else { + return item; + } + }).toList(); + loadingState.value = LoadingState.success(list); + } } diff --git a/lib/pages/dynamics/detail/controller.dart b/lib/pages/dynamics/detail/controller.dart index 9b492989..de0d805c 100644 --- a/lib/pages/dynamics/detail/controller.dart +++ b/lib/pages/dynamics/detail/controller.dart @@ -20,13 +20,16 @@ class DynamicDetailController extends ReplyController { count.value = int.parse(item!.modules!.moduleStat!.comment!.count ?? '0'); } - queryData(); + if (oid != 0) { + queryData(); + } } // 根据jumpUrl获取动态html reqHtmlByOpusId(int id) async { var res = await HtmlHttp.reqHtml(id, 'opus'); oid = res['commentId']; + queryData(); } @override diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index 74556bae..58364c04 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -13,7 +13,6 @@ import 'package:PiliPalaX/models/dynamics/result.dart'; import 'package:PiliPalaX/pages/dynamics/detail/index.dart'; import 'package:PiliPalaX/pages/dynamics/widgets/author_panel.dart'; import 'package:PiliPalaX/pages/video/detail/reply/widgets/reply_item.dart'; -import 'package:PiliPalaX/pages/video/detail/reply_new/index.dart'; import 'package:PiliPalaX/pages/video/detail/reply_reply/index.dart'; import 'package:PiliPalaX/utils/feed_back.dart'; import 'package:PiliPalaX/utils/id_utils.dart'; @@ -297,37 +296,9 @@ class _DynamicDetailPageState extends State heroTag: null, onPressed: () { feedBack(); - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext context) { - return VideoReplyNewDialog( - oid: _dynamicDetailController.oid ?? - IdUtils.bv2av(Get.parameters['bvid']!), - root: 0, - parent: 0, - replyType: ReplyType.values[replyType], - ); - }, - ).then( - (value) { - // 完成评论,数据添加 - if (value != null && value['data'] != null) { - _dynamicDetailController.count.value++; - if (value != null && value['data'] != null) { - List list = _dynamicDetailController - .loadingState.value is Success - ? (_dynamicDetailController.loadingState.value - as Success) - .response - : []; - list.insert(0, value['data']); - _dynamicDetailController.loadingState.value = - LoadingState.success(list); - } - } - }, - ); + dynamic oid = _dynamicDetailController.oid ?? + IdUtils.bv2av(Get.parameters['bvid']!); + _dynamicDetailController.onReply(context, oid: oid); }, tooltip: '评论动态', child: const Icon(Icons.reply), @@ -365,7 +336,7 @@ class _DynamicDetailPageState extends State return ScaleTransition(scale: animation, child: child); }, child: Text( - '${_dynamicDetailController.count.value}条回复', + '${_dynamicDetailController.count.value != -1 ? _dynamicDetailController.count.value : 0}条回复', key: ValueKey(_dynamicDetailController.count.value), ), ), @@ -419,9 +390,14 @@ class _DynamicDetailPageState extends State replyLevel: '1', replyReply: replyReply, replyType: ReplyType.values[replyType], - addReply: (replyItem) { - // loadingState.response[index].replies!.add(replyItem); + onReply: () { + _dynamicDetailController.onReply( + context, + replyItem: loadingState.response[index], + index: index, + ); }, + onDelete: _dynamicDetailController.onMDelete, ); } }, diff --git a/lib/pages/html/view.dart b/lib/pages/html/view.dart index 54ebe3d9..f5867e69 100644 --- a/lib/pages/html/view.dart +++ b/lib/pages/html/view.dart @@ -348,31 +348,9 @@ class _HtmlRenderPageState extends State heroTag: null, onPressed: () { feedBack(); - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext context) { - return VideoReplyNewDialog( - oid: _htmlRenderCtr.oid.value, - root: 0, - parent: 0, - replyType: ReplyType.values[type], - ); - }, - ).then( - (value) { - // 完成评论,数据添加 - if (value != null && value['data'] != null) { - _htmlRenderCtr.count.value++; - List list = _htmlRenderCtr.loadingState.value is Success - ? (_htmlRenderCtr.loadingState.value as Success) - .response - : []; - list.insert(0, value['data']); - _htmlRenderCtr.loadingState.value = - LoadingState.success(list); - } - }, + _htmlRenderCtr.onReply( + context, + oid: _htmlRenderCtr.oid.value, ); }, tooltip: '评论动态', @@ -414,11 +392,16 @@ class _HtmlRenderPageState extends State replyItem: loadingState.response[index], showReplyRow: true, replyLevel: '1', - replyReply: (replyItem) => replyReply(replyItem), + replyReply: replyReply, replyType: ReplyType.values[type], - addReply: (replyItem) { - loadingState.response[index].replies!.add(replyItem); + onReply: () { + _htmlRenderCtr.onReply( + context, + replyItem: loadingState.response[index], + index: index, + ); }, + onDelete: _htmlRenderCtr.onMDelete, ); } }, diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart index da632bf3..45a58574 100644 --- a/lib/pages/video/detail/reply/view.dart +++ b/lib/pages/video/detail/reply/view.dart @@ -1,6 +1,5 @@ import 'package:PiliPalaX/common/widgets/http_error.dart'; import 'package:PiliPalaX/http/loading_state.dart'; -import 'package:PiliPalaX/pages/video/detail/reply_new/reply_page.dart'; import 'package:PiliPalaX/pages/video/detail/reply_reply/view.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; @@ -10,7 +9,6 @@ import 'package:PiliPalaX/common/skeleton/video_reply.dart'; import 'package:PiliPalaX/models/common/reply_type.dart'; import 'package:PiliPalaX/utils/feed_back.dart'; import 'package:PiliPalaX/utils/id_utils.dart'; -import 'package:get/get_navigation/src/dialog/dialog_route.dart'; import 'controller.dart'; import 'widgets/reply_item.dart'; @@ -39,8 +37,6 @@ class _VideoReplyPanelState extends State late VideoReplyController _videoReplyController; late AnimationController fabAnimationCtr; - late final _savedReplies = {}; - bool _isFabVisible = true; String replyLevel = '1'; late String heroTag; @@ -204,78 +200,7 @@ class _VideoReplyPanelState extends State feedBack(); dynamic oid = _videoReplyController.aid ?? IdUtils.bv2av(Get.parameters['bvid']!); - Navigator.of(context) - .push( - GetDialogRoute( - pageBuilder: - (buildContext, animation, secondaryAnimation) { - return ReplyPage( - oid: oid, - root: 0, - parent: 0, - replyType: ReplyType.video, - savedReply: _savedReplies[oid], - onSaveReply: (reply) { - _savedReplies[oid] = 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)); - - return SlideTransition( - position: animation.drive(tween), - child: child, - ); - }, - ), - ) - .then( - (value) { - // 完成评论,数据添加 - if (value != null && value['data'] != null) { - _savedReplies[oid] = null; - List list = - _videoReplyController.loadingState.value is Success - ? (_videoReplyController.loadingState.value - as Success) - .response - : []; - list.insert(0, value['data']); - _videoReplyController.loadingState.value = - LoadingState.success(list); - } - }, - ); - // showModalBottomSheet( - // context: context, - // isScrollControlled: true, - // builder: (BuildContext context) { - // return VideoReplyNewDialog( - // oid: _videoReplyController.aid ?? - // IdUtils.bv2av(Get.parameters['bvid']!), - // root: 0, - // parent: 0, - // replyType: ReplyType.video, - // ); - // }, - // ).then( - // (value) => { - // // 完成评论,数据添加 - // if (value != null && value['data'] != null) - // { - // _videoReplyController.replyList - // .insert(0, value['data']) - // } - // }, - // ); + _videoReplyController.onReply(context, oid: oid); }, tooltip: '发表评论', child: const Icon(Icons.reply), @@ -317,70 +242,13 @@ class _VideoReplyPanelState extends State replyReply: replyReply, replyType: ReplyType.video, onReply: () { - dynamic oid = loadingState.response[index].oid; - dynamic root = loadingState.response[index].rpid; - dynamic parent = loadingState.response[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: loadingState.response[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)); - - return SlideTransition( - position: animation.drive(tween), - child: child, - ); - }, - ), - ) - .then((value) { - // 完成评论,数据添加 - if (value != null && value['data'] != null) { - _savedReplies[key] = null; - } - }); - }, - onDelete: (rpid, frpid) { - List list = - (_videoReplyController.loadingState.value as Success) - .response; - list = frpid == null - ? list.where((item) => item.rpid != rpid).toList() - : list.map((item) { - if (item.rpid == frpid) { - return item - ..replies = item.replies - ?.where((reply) => reply.rpid != rpid) - .toList(); - } else { - return item; - } - }).toList(); - _videoReplyController.loadingState.value = - LoadingState.success(list); + _videoReplyController.onReply( + context, + replyItem: loadingState.response[index], + index: index, + ); }, + onDelete: _videoReplyController.onMDelete, ); } }, diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 0ebd261d..072c1f68 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -import 'package:get/get_navigation/src/dialog/dialog_route.dart'; import 'package:hive/hive.dart'; import 'package:PiliPalaX/common/widgets/badge.dart'; import 'package:PiliPalaX/common/widgets/network_img_layer.dart'; @@ -17,7 +16,6 @@ import 'package:PiliPalaX/utils/storage.dart'; import 'package:PiliPalaX/utils/url_utils.dart'; import 'package:PiliPalaX/utils/utils.dart'; import '../../../../../utils/app_scheme.dart'; -import '../../reply_new/reply_page.dart'; import 'zan.dart'; Box setting = GStorage.setting; @@ -26,7 +24,6 @@ class ReplyItem extends StatelessWidget { const ReplyItem({ super.key, this.replyItem, - this.addReply, this.replyLevel, this.showReplyRow = true, this.replyReply, @@ -36,7 +33,6 @@ class ReplyItem extends StatelessWidget { this.onDelete, }); final ReplyItemModel? replyItem; - final Function? addReply; final String? replyLevel; final bool? showReplyRow; final Function? replyReply; @@ -324,68 +320,6 @@ class ReplyItem extends StatelessWidget { onReply!(); return; } - Navigator.of(context) - .push( - GetDialogRoute( - pageBuilder: - (buildContext, animation, secondaryAnimation) { - return ReplyPage( - oid: replyItem!.oid, - root: replyItem!.rpid, - parent: replyItem!.rpid, - replyType: replyType, - replyItem: replyItem, - ); - }, - 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)); - - return SlideTransition( - position: animation.drive(tween), - child: child, - ); - }, - ), - ) - .then((value) => { - // 完成评论,数据添加 - if (value != null && - value['data'] != null && - addReply != null) - { - addReply?.call(value['data']) - // replyControl.replies.add(value['data']), - } - }); - // showModalBottomSheet( - // context: context, - // isScrollControlled: true, - // builder: (builder) { - // return VideoReplyNewDialog( - // oid: replyItem!.oid, - // root: replyItem!.rpid, - // parent: replyItem!.rpid, - // replyType: replyType, - // replyItem: replyItem, - // ); - // }, - // ).then((value) => { - // // 完成评论,数据添加 - // if (value != null && - // value['data'] != null && - // addReply != null) - // { - // addReply?.call(value['data']) - // // replyControl.replies.add(value['data']), - // } - // }); }, child: Row(children: [ Icon(Icons.reply, diff --git a/lib/pages/video/detail/reply_new/reply_page.dart b/lib/pages/video/detail/reply_new/reply_page.dart index 7d8e4976..816dd11b 100644 --- a/lib/pages/video/detail/reply_new/reply_page.dart +++ b/lib/pages/video/detail/reply_new/reply_page.dart @@ -47,7 +47,7 @@ class _ReplyPageState extends State late final _controller = ChatBottomPanelContainerController(); late final TextEditingController _replyContentController = TextEditingController(text: widget.savedReply); - PanelType _currentPanelType = PanelType.none; + // PanelType _currentPanelType = PanelType.none; bool _readOnly = false; final _readOnlyStream = StreamController(); late final _enableSend = StreamController(); @@ -124,28 +124,28 @@ class _ReplyPageState extends State return const SizedBox.shrink(); } }, - onPanelTypeChange: (panelType, data) { - debugPrint('panelType: $panelType'); - switch (panelType) { - case ChatBottomPanelType.none: - _currentPanelType = PanelType.none; - break; - case ChatBottomPanelType.keyboard: - _currentPanelType = PanelType.keyboard; - break; - case ChatBottomPanelType.other: - if (data == null) return; - switch (data) { - case PanelType.emoji: - _currentPanelType = PanelType.emoji; - break; - default: - _currentPanelType = PanelType.none; - break; - } - break; - } - }, + // onPanelTypeChange: (panelType, data) { + // debugPrint('panelType: $panelType'); + // switch (panelType) { + // case ChatBottomPanelType.none: + // _currentPanelType = PanelType.none; + // break; + // case ChatBottomPanelType.keyboard: + // _currentPanelType = PanelType.keyboard; + // break; + // case ChatBottomPanelType.other: + // if (data == null) return; + // switch (data) { + // case PanelType.emoji: + // _currentPanelType = PanelType.emoji; + // break; + // default: + // _currentPanelType = PanelType.none; + // break; + // } + // break; + // } + // }, panelBgColor: Theme.of(context).colorScheme.surface, ); } diff --git a/lib/pages/video/detail/reply_reply/view.dart b/lib/pages/video/detail/reply_reply/view.dart index aaf48c0f..2b2db9be 100644 --- a/lib/pages/video/detail/reply_reply/view.dart +++ b/lib/pages/video/detail/reply_reply/view.dart @@ -114,9 +114,6 @@ class _VideoReplyReplyPanelState extends State { replyItem: widget.firstFloor, replyLevel: '2', showReplyRow: false, - addReply: (replyItem) { - // _videoReplyReplyController.replyList.add(replyItem); - }, replyType: widget.replyType, replyReply: () {}, needDivider: false, @@ -185,6 +182,13 @@ class _VideoReplyReplyPanelState extends State { // 完成评论,数据添加 if (value != null && value['data'] != null) { _savedReplies[key] = null; + List list = _videoReplyReplyController.loadingState.value is Success + ? (_videoReplyReplyController.loadingState.value as Success) + .response + : []; + list.add(value['data']); + _videoReplyReplyController.loadingState.value = + LoadingState.success(list); } }); } @@ -200,9 +204,6 @@ class _VideoReplyReplyPanelState extends State { replyItem: _videoReplyReplyController.root, replyLevel: '2', showReplyRow: false, - addReply: (replyItem) { - // _videoReplyReplyController.replyList.add(replyItem); - }, replyType: widget.replyType, replyReply: () {}, needDivider: false, @@ -244,18 +245,18 @@ class _VideoReplyReplyPanelState extends State { replyItem: loadingState.response[index], replyLevel: '2', showReplyRow: false, - addReply: (replyItem) { - // _videoReplyReplyController.replyList.add(replyItem); - }, replyType: widget.replyType, onReply: () { _onReply(loadingState.response[index]); }, onDelete: (rpid, frpid) { - // _videoReplyReplyController.replyList.value = - // _videoReplyReplyController.replyList - // .where((item) => item.rpid != rpid) - // .toList(); + List list = (_videoReplyReplyController + .loadingState.value as Success) + .response; + list = + list.where((item) => item.rpid != rpid).toList(); + _videoReplyReplyController.loadingState.value = + LoadingState.success(list); }, ); }