diff --git a/lib/pages/dynamics/widgets/forward_panel.dart b/lib/pages/dynamics/widgets/forward_panel.dart index f893e494..0304140c 100644 --- a/lib/pages/dynamics/widgets/forward_panel.dart +++ b/lib/pages/dynamics/widgets/forward_panel.dart @@ -320,16 +320,16 @@ Widget forWard( ); // 课堂 case 'DYNAMIC_TYPE_COURSES_SEASON': - return Row( - children: [ - Expanded( - child: Text( - "课堂💪:${item.modules.moduleDynamic!.major!.courses!['title']}", - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ) - ], + return SizedBox( + width: double.infinity, + child: Padding( + padding: floor == 1 + ? const EdgeInsets.symmetric(horizontal: 12) + : EdgeInsets.zero, + child: Text( + "课堂:${item.modules.moduleDynamic!.major!.courses!['title']}", + ), + ), ); // 活动 case 'DYNAMIC_TYPE_COMMON_SQUARE': diff --git a/lib/pages/dynamics_detail/controller.dart b/lib/pages/dynamics_detail/controller.dart index 361e0208..71de2b4b 100644 --- a/lib/pages/dynamics_detail/controller.dart +++ b/lib/pages/dynamics_detail/controller.dart @@ -1,7 +1,6 @@ import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart' show MainListReply, ReplyInfo; import 'package:PiliPlus/grpc/reply.dart'; -import 'package:PiliPlus/http/dynamics.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/pages/common/reply_controller.dart'; @@ -10,40 +9,23 @@ import 'package:PiliPlus/utils/storage.dart'; import 'package:get/get.dart'; class DynamicDetailController extends ReplyController { - DynamicDetailController(this.oid, this.type); - int oid; - int type; - late DynamicItemModel item; - int? floor; + late int oid; + late int replyType; + late DynamicItemModel dynItem; late final horizontalPreview = GStorage.horizontalPreview; late final showDynActionBar = GStorage.showDynActionBar; @override - dynamic get sourceId => type == 1 ? IdUtils.av2bv(oid) : oid; + dynamic get sourceId => replyType == 1 ? IdUtils.av2bv(oid) : oid; @override void onInit() { super.onInit(); - item = Get.arguments['item']; - floor = Get.arguments['floor']; - if (floor == 1) { - count.value = item.modules.moduleStat?.comment?.count ?? 0; - } - - if (oid != 0) { - queryData(); - } - } - - Future getCommentParams(int id) async { - var res = await DynamicsHttp.opusDetail(opusId: id); - if (res is Success) { - final data = (res as Success).response; - type = data.basic!.commentType!; - oid = int.parse(data.basic!.commentIdStr!); - queryData(); - } + dynItem = Get.arguments['item']; + oid = int.parse(dynItem.basic!.commentIdStr!); + replyType = dynItem.basic!.commentType!; + queryData(); } @override @@ -53,7 +35,7 @@ class DynamicDetailController extends ReplyController { @override Future> customGetData() => ReplyGrpc.mainList( - type: type, + type: replyType, oid: oid, mode: mode.value, cursorNext: cursorNext, diff --git a/lib/pages/dynamics_detail/view.dart b/lib/pages/dynamics_detail/view.dart index af5c6130..1e8783c8 100644 --- a/lib/pages/dynamics_detail/view.dart +++ b/lib/pages/dynamics_detail/view.dart @@ -39,23 +39,20 @@ class DynamicDetailPage extends StatefulWidget { class _DynamicDetailPageState extends State with TickerProviderStateMixin { - late DynamicDetailController _dynamicDetailController; + final _controller = + Get.put(DynamicDetailController(), tag: Utils.generateRandomString(8)); late final AnimationController _fabAnimationCtr; late final Animation _anim; + final RxBool _visibleTitle = false.obs; - // 回复类型 - late int replyType; bool _isFabVisible = true; bool? _imageStatus; - int oid = 0; - int? opusId; - bool isOpusId = false; late final List _ratio = GStorage.dynamicDetailRatio; bool get _horizontalPreview => context.orientation == Orientation.landscape && - _dynamicDetailController.horizontalPreview; + _controller.horizontalPreview; late final _key = GlobalKey(); @@ -103,9 +100,6 @@ class _DynamicDetailPageState extends State @override void initState() { super.initState(); - // floor 1原创 2转发 - init(); - _fabAnimationCtr = AnimationController( vsync: this, duration: const Duration(milliseconds: 300), @@ -118,50 +112,7 @@ class _DynamicDetailPageState extends State curve: Curves.easeInOut, )); _fabAnimationCtr.forward(); - _dynamicDetailController.scrollController.addListener(listener); - } - - // 页面初始化 - Future init() async { - Map args = Get.arguments; - // 楼层 - int floor = args['floor']; - // 评论类型 - final item = args['item'] as DynamicItemModel; - int commentType = item.basic?.commentType ?? 11; - replyType = (commentType == 0) ? 11 : commentType; - - if (floor == 1) { - oid = int.parse(item.basic!.commentIdStr!); - } else { - try { - final moduleDynamic = item.modules.moduleDynamic!; - String majorType = moduleDynamic.major!.type!; - - if (majorType == 'MAJOR_TYPE_OPUS') { - // 转发的动态 - String jumpUrl = moduleDynamic.major!.opus!.jumpUrl!; - opusId = int.parse(jumpUrl.split('/').last); - if (opusId != null) { - isOpusId = true; - _dynamicDetailController = Get.put( - DynamicDetailController(oid, replyType), - tag: Utils.makeHeroTag(opusId), - ); - await _dynamicDetailController.getCommentParams(opusId!); - setState(() {}); - } - } else { - oid = moduleDynamic.major!.draw!.id!; - } - } catch (_) {} - } - if (!isOpusId) { - _dynamicDetailController = Get.put( - DynamicDetailController(oid, replyType), - tag: Utils.makeHeroTag(oid), - ); - } + _controller.scrollController.addListener(listener); } // 查看二级评论 @@ -189,7 +140,7 @@ class _DynamicDetailPageState extends State oid: oid, rpid: rpid, source: 'dynamic', - replyType: replyType, + replyType: _controller.replyType, firstFloor: replyItem, onDispose: onDispose, ), @@ -200,7 +151,7 @@ class _DynamicDetailPageState extends State replyReplyPage, routeName: 'dynamicDetail-Copy', arguments: { - 'item': _dynamicDetailController.item, + 'item': _controller.dynItem, }, ); } else { @@ -230,7 +181,7 @@ class _DynamicDetailPageState extends State replyReplyPage, routeName: 'dynamicDetail-Copy', arguments: { - 'item': _dynamicDetailController.item, + 'item': _controller.dynItem, }, ); } @@ -242,10 +193,9 @@ class _DynamicDetailPageState extends State void didChangeDependencies() { super.didChangeDependencies(); WidgetsBinding.instance.addPostFrameCallback((_) { - if (_dynamicDetailController.scrollController.hasClients) { + if (_controller.scrollController.hasClients) { _visibleTitle.value = - _dynamicDetailController.scrollController.positions.first.pixels > - 55; + _controller.scrollController.positions.first.pixels > 55; } }); } @@ -253,13 +203,13 @@ class _DynamicDetailPageState extends State void listener() { // 标题 _visibleTitle.value = - _dynamicDetailController.scrollController.positions.first.pixels > 55; + _controller.scrollController.positions.first.pixels > 55; // fab按钮 - final ScrollDirection direction1 = _dynamicDetailController - .scrollController.positions.first.userScrollDirection; - late final ScrollDirection direction2 = _dynamicDetailController - .scrollController.positions.last.userScrollDirection; + final ScrollDirection direction1 = + _controller.scrollController.positions.first.userScrollDirection; + late final ScrollDirection direction2 = + _controller.scrollController.positions.last.userScrollDirection; if (direction1 == ScrollDirection.forward || direction2 == ScrollDirection.forward) { _showFab(); @@ -286,7 +236,7 @@ class _DynamicDetailPageState extends State @override void dispose() { _fabAnimationCtr.dispose(); - _dynamicDetailController.scrollController.removeListener(listener); + _controller.scrollController.removeListener(listener); super.dispose(); } @@ -304,7 +254,7 @@ class _DynamicDetailPageState extends State opacity: _visibleTitle.value ? 1 : 0, duration: const Duration(milliseconds: 300), child: AuthorPanel( - item: _dynamicDetailController.item, + item: _controller.dynItem, source: 'detail', //to remove tag ), ); @@ -364,7 +314,7 @@ class _DynamicDetailPageState extends State bottom: false, child: context.orientation == Orientation.portrait ? refreshIndicator( - onRefresh: _dynamicDetailController.onRefresh, + onRefresh: _controller.onRefresh, child: _buildBody(context.orientation, theme), ) : _buildBody(context.orientation, theme), @@ -380,20 +330,19 @@ class _DynamicDetailPageState extends State double padding = max(context.width / 2 - Grid.smallCardWidth, 0); if (orientation == Orientation.portrait) { return CustomScrollView( - controller: _dynamicDetailController.scrollController, + controller: _controller.scrollController, physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverToBoxAdapter( child: DynamicPanel( - item: _dynamicDetailController.item, + item: _controller.dynItem, source: 'detail', callback: _getImageCallback, ), ), replyPersistentHeader(theme), Obx( - () => replyList( - theme, _dynamicDetailController.loadingState.value), + () => replyList(theme, _controller.loadingState.value), ), ] .map((e) => SliverPadding( @@ -407,7 +356,7 @@ class _DynamicDetailPageState extends State Expanded( flex: _ratio[0].toInt(), child: CustomScrollView( - controller: _dynamicDetailController.scrollController, + controller: _controller.scrollController, physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( @@ -417,7 +366,7 @@ class _DynamicDetailPageState extends State ), sliver: SliverToBoxAdapter( child: DynamicPanel( - item: _dynamicDetailController.item, + item: _controller.dynItem, source: 'detail', callback: _getImageCallback, ), @@ -432,10 +381,9 @@ class _DynamicDetailPageState extends State key: _key, backgroundColor: Colors.transparent, body: refreshIndicator( - onRefresh: _dynamicDetailController.onRefresh, + onRefresh: _controller.onRefresh, child: CustomScrollView( - controller: - _dynamicDetailController.scrollController, + controller: _controller.scrollController, physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( @@ -446,9 +394,7 @@ class _DynamicDetailPageState extends State padding: EdgeInsets.only(right: padding / 4), sliver: Obx( () => replyList( - theme, - _dynamicDetailController - .loadingState.value), + theme, _controller.loadingState.value), ), ), ], @@ -473,16 +419,16 @@ class _DynamicDetailPageState extends State heroTag: null, onPressed: () { feedBack(); - _dynamicDetailController.onReply( + _controller.onReply( context, - oid: _dynamicDetailController.oid, - replyType: replyType, + oid: _controller.oid, + replyType: _controller.replyType, ); }, tooltip: '评论动态', child: const Icon(Icons.reply), ); - return _dynamicDetailController.showDynActionBar.not + return _controller.showDynActionBar.not ? Align( alignment: Alignment.bottomRight, child: Padding( @@ -527,27 +473,25 @@ class _DynamicDetailPageState extends State isScrollControlled: true, useSafeArea: true, builder: (context) => RepostPanel( - item: - _dynamicDetailController.item, + item: _controller.dynItem, callback: () { - int count = - _dynamicDetailController - .item - .modules - .moduleStat - ?.forward - ?.count ?? - 0; - _dynamicDetailController.item - .modules.moduleStat ??= + int count = _controller + .dynItem + .modules + .moduleStat + ?.forward + ?.count ?? + 0; + _controller.dynItem.modules + .moduleStat ??= ModuleStatModel(); - _dynamicDetailController - .item + _controller + .dynItem .modules .moduleStat ?.forward ??= DynamicStat(); - _dynamicDetailController - .item + _controller + .dynItem .modules .moduleStat! .forward! @@ -573,20 +517,15 @@ class _DynamicDetailPageState extends State theme.colorScheme.outline, ), label: Text( - _dynamicDetailController - .item - .modules - .moduleStat - ?.forward - ?.count != + _controller.dynItem.modules.moduleStat + ?.forward?.count != null - ? Utils.numFormat( - _dynamicDetailController - .item - .modules - .moduleStat! - .forward! - .count) + ? Utils.numFormat(_controller + .dynItem + .modules + .moduleStat! + .forward! + .count) : '转发', ), ), @@ -596,7 +535,7 @@ class _DynamicDetailPageState extends State child: TextButton.icon( onPressed: () { Utils.shareText( - '${HttpString.dynamicShareBaseUrl}/${_dynamicDetailController.item.idStr}'); + '${HttpString.dynamicShareBaseUrl}/${_controller.dynItem.idStr}'); }, icon: Icon( CustomIcon.share_node, @@ -618,7 +557,7 @@ class _DynamicDetailPageState extends State builder: (context) => TextButton.icon( onPressed: () => RequestUtils.onLikeDynamic( - _dynamicDetailController.item, + _controller.dynItem, () { if (context.mounted) { (context as Element?) @@ -627,18 +566,14 @@ class _DynamicDetailPageState extends State }, ), icon: Icon( - _dynamicDetailController - .item - .modules - .moduleStat - ?.like - ?.status == + _controller.dynItem.modules.moduleStat + ?.like?.status == true ? FontAwesomeIcons.solidThumbsUp : FontAwesomeIcons.thumbsUp, size: 16, - color: _dynamicDetailController - .item + color: _controller + .dynItem .modules .moduleStat ?.like @@ -646,16 +581,15 @@ class _DynamicDetailPageState extends State true ? theme.colorScheme.primary : theme.colorScheme.outline, - semanticLabel: - _dynamicDetailController - .item - .modules - .moduleStat - ?.like - ?.status == - true - ? "已赞" - : "点赞", + semanticLabel: _controller + .dynItem + .modules + .moduleStat + ?.like + ?.status == + true + ? "已赞" + : "点赞", ), style: TextButton.styleFrom( padding: const EdgeInsets.fromLTRB( @@ -672,24 +606,23 @@ class _DynamicDetailPageState extends State scale: animation, child: child); }, child: Text( - _dynamicDetailController - .item + _controller + .dynItem .modules .moduleStat ?.like ?.count != null - ? Utils.numFormat( - _dynamicDetailController - .item - .modules - .moduleStat! - .like! - .count) + ? Utils.numFormat(_controller + .dynItem + .modules + .moduleStat! + .like! + .count) : '点赞', style: TextStyle( - color: _dynamicDetailController - .item + color: _controller + .dynItem .modules .moduleStat ?.like @@ -732,8 +665,8 @@ class _DynamicDetailPageState extends State return ScaleTransition(scale: animation, child: child); }, child: Text( - '${_dynamicDetailController.count.value == -1 ? 0 : Utils.numFormat(_dynamicDetailController.count.value)}条回复', - key: ValueKey(_dynamicDetailController.count.value), + '${_controller.count.value == -1 ? 0 : Utils.numFormat(_controller.count.value)}条回复', + key: ValueKey(_controller.count.value), ), ), ), @@ -741,14 +674,14 @@ class _DynamicDetailPageState extends State SizedBox( height: 35, child: TextButton.icon( - onPressed: () => _dynamicDetailController.queryBySort(), + onPressed: () => _controller.queryBySort(), icon: Icon( Icons.sort, size: 16, color: theme.colorScheme.secondary, ), label: Obx(() => Text( - _dynamicDetailController.sortType.value.label, + _controller.sortType.value.label, style: TextStyle( fontSize: 13, color: theme.colorScheme.secondary, @@ -777,14 +710,14 @@ class _DynamicDetailPageState extends State ? SliverList.builder( itemBuilder: (context, index) { if (index == response.length) { - _dynamicDetailController.onLoadMore(); + _controller.onLoadMore(); return Container( alignment: Alignment.center, margin: EdgeInsets.only( bottom: MediaQuery.of(context).padding.bottom), height: 125, child: Text( - _dynamicDetailController.isEnd ? '没有更多了' : '加载中...', + _controller.isEnd ? '没有更多了' : '加载中...', style: TextStyle( fontSize: 12, color: theme.colorScheme.outline, @@ -798,23 +731,22 @@ class _DynamicDetailPageState extends State replyReply: (replyItem, id) => replyReply(context, replyItem, id), onReply: () { - _dynamicDetailController.onReply( + _controller.onReply( context, replyItem: response[index], index: index, ); }, onDelete: (subIndex) => - _dynamicDetailController.onRemove(index, subIndex), - upMid: _dynamicDetailController.upMid, + _controller.onRemove(index, subIndex), + upMid: _controller.upMid, callback: _getImageCallback, onCheckReply: (item) => - _dynamicDetailController.onCheckReply(context, item), - onToggleTop: (isUpTop, rpid) => - _dynamicDetailController.onToggleTop( + _controller.onCheckReply(context, item), + onToggleTop: (isUpTop, rpid) => _controller.onToggleTop( index, - _dynamicDetailController.oid, - _dynamicDetailController.type, + _controller.oid, + _controller.replyType, isUpTop, rpid, ), @@ -824,11 +756,11 @@ class _DynamicDetailPageState extends State itemCount: response!.length + 1, ) : HttpError( - onReload: _dynamicDetailController.onReload, + onReload: _controller.onReload, ), Error(:var errMsg) => HttpError( errMsg: errMsg, - onReload: _dynamicDetailController.onReload, + onReload: _controller.onReload, ), }; } diff --git a/lib/utils/page_utils.dart b/lib/utils/page_utils.dart index 9a6a55b8..e9c49f3a 100644 --- a/lib/utils/page_utils.dart +++ b/lib/utils/page_utils.dart @@ -284,8 +284,6 @@ class PageUtils { '/dynamicDetail', arguments: { 'item': res['data'], - 'floor': 1, - 'action': 'detail', }, off: off, ); @@ -350,16 +348,25 @@ class PageUtils { {action = 'all'}) async { feedBack(); + void push() { + var commentType = item.basic?.commentType; + if (commentType != null && + commentType != 0 && + item.basic?.commentIdStr?.isNotEmpty == true) { + toDupNamed( + '/dynamicDetail', + arguments: { + 'item': item, + }, + ); + } else { + pushDynFromId(id: item.idStr); + } + } + /// 点击评论action 直接查看评论 if (action == 'comment') { - toDupNamed( - '/dynamicDetail', - arguments: { - 'item': item, - 'floor': floor, - 'action': action, - }, - ); + push(); return; } @@ -496,18 +503,7 @@ class PageUtils { // 图文动态查看 // case 'DYNAMIC_TYPE_DRAW': default: - if (item.basic?.commentIdStr?.isNotEmpty == true) { - toDupNamed( - '/dynamicDetail', - arguments: { - 'item': item, - 'floor': floor, - }, - ); - } else { - pushDynFromId(id: item.idStr); - } - + push(); break; } }