diff --git a/lib/common/widgets/save_panel.dart b/lib/common/widgets/save_panel.dart index 92626124..100e547a 100644 --- a/lib/common/widgets/save_panel.dart +++ b/lib/common/widgets/save_panel.dart @@ -166,7 +166,7 @@ class _SavePanelState extends State { case 'DYNAMIC_TYPE_AV': viewType = '观看'; itemType = '视频'; - uri = 'bilibili://video/${item.basic!['comment_id_str']}'; + uri = 'bilibili://video/${item.basic.commentIdStr}'; break; case 'DYNAMIC_TYPE_ARTICLE': diff --git a/lib/pages/article/controller.dart b/lib/pages/article/controller.dart index 77b51920..b4b9d2c3 100644 --- a/lib/pages/article/controller.dart +++ b/lib/pages/article/controller.dart @@ -8,7 +8,6 @@ import 'package:PiliPlus/models/dynamics/article_content_model.dart' import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/models/model_owner.dart'; import 'package:PiliPlus/models/space_article/item.dart'; -import 'package:PiliPlus/models/space_article/stats.dart'; import 'package:PiliPlus/pages/common/reply_controller.dart'; import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/utils/storage.dart'; @@ -88,23 +87,24 @@ class ArticleController extends ReplyController { Future queryOpus(opusId) async { final res = await DynamicsHttp.opusDetail(opusId: opusId); if (res is Success) { - opusData = (res as Success).response; + final opusData = (res as Success).response; //fallback - if (opusData?.fallback?.id != null) { - id = opusData!.fallback!.id!; + if (opusData.fallback?.id != null) { + id = opusData.fallback!.id!; type = 'read'; setUrl(); _queryContent(); return false; } - commentType = opusData!.basic!.commentType!; - commentId = int.parse(opusData!.basic!.commentIdStr!); - if (showDynActionBar && opusData!.modules.moduleStat != null) { - stats.value = opusData!.modules.moduleStat!; + this.opusData = opusData; + commentType = opusData.basic!.commentType!; + commentId = int.parse(opusData.basic!.commentIdStr!); + if (showDynActionBar && opusData.modules.moduleStat != null) { + stats.value = opusData.modules.moduleStat; } summary - ..author ??= opusData!.modules.moduleAuthor - ..title ??= opusData!.modules.moduleTag?.text; + ..author ??= opusData.modules.moduleAuthor + ..title ??= opusData.modules.moduleTag?.text; return true; } return false; @@ -119,28 +119,42 @@ class ArticleController extends ReplyController { ..title ??= articleData!.title ..cover ??= articleData!.originImageUrls?.firstOrNull; - if (showDynActionBar && opusData?.modules.moduleStat == null) { - final dynId = articleData!.dynIdStr; - if (dynId != null) { - _queryReadAsDyn(dynId); - } else { - debugPrint('cvid2opus failed: $id'); - } - _statsToModuleStat(articleData!.stats!); + if (showDynActionBar) { + _queryReadAsDyn(articleData!.dynIdStr); + _getArticleInfo(); } return true; } return false; } - _queryReadAsDyn(id) async { - // 仅用于获取moduleStat + // data for forward + Future _queryReadAsDyn(id) async { + if (opusData != null) { + return; + } final res = await DynamicsHttp.dynamicDetail(id: id); if (res['status']) { - opusData = res['data'] as DynamicItemModel; - if (opusData!.modules.moduleStat != null) { - stats.value = opusData!.modules.moduleStat!; - } + opusData = res['data']; + } + } + + // stats + Future _getArticleInfo() async { + final res = await DynamicsHttp.articleInfo(cvId: id); + if (res['status']) { + stats.value = ModuleStatModel( + comment: DynamicStat(count: res['data']?['stats']?['reply']), + forward: DynamicStat(count: res['data']?['stats']?['share']), + like: DynamicStat( + count: res['data']?['stats']?['like'], + status: res['data']?['like'] == 1, + ), + favorite: DynamicStat( + count: res['data']?['stats']?['reply'], + status: res['data']?['favorite'], + ), + ); } } @@ -201,21 +215,24 @@ class ArticleController extends ReplyController { } } - void _statsToModuleStat(Stats dynStats) { - if (stats.value == null) { - stats.value = ModuleStatModel( - comment: _setCount(dynStats.reply), - forward: _setCount(dynStats.dyn), - like: _setCount(dynStats.like), - favorite: _setCount(dynStats.favorite), - ); + Future onLike(VoidCallback callback) async { + bool isLike = stats.value?.like?.status == true; + final res = await DynamicsHttp.likeDynamic( + dynamicId: opusData?.idStr, up: isLike ? 2 : 1); + if (res['status']) { + stats.value?.like?.status = !isLike; + int count = stats.value?.like?.count ?? 0; + if (isLike) { + stats.value?.like?.count = count - 1; + } else { + stats.value?.like?.count = count + 1; + } + stats.refresh(); + SmartDialog.showToast(!isLike ? '点赞成功' : '取消赞'); } else { - // 动态类无收藏数据 - stats.value!.favorite ??= _setCount(dynStats.favorite); + SmartDialog.showToast(res['msg']); } } - - DynamicStat _setCount(int? count) => DynamicStat(count: count); } class Summary { diff --git a/lib/pages/article/view.dart b/lib/pages/article/view.dart index 445d3b28..56c17b50 100644 --- a/lib/pages/article/view.dart +++ b/lib/pages/article/view.dart @@ -13,7 +13,6 @@ import 'package:PiliPlus/pages/dynamics/repost_dyn_panel.dart'; import 'package:PiliPlus/pages/video/detail/reply/widgets/reply_item_grpc.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/page_utils.dart'; -import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:easy_debounce/easy_throttle.dart'; @@ -600,17 +599,6 @@ class _ArticlePageState extends State PopupMenuButton( icon: const Icon(Icons.more_vert, size: 19), itemBuilder: (BuildContext context) => [ - PopupMenuItem( - onTap: () => Utils.copyText(_articleCtr.url), - child: const Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon(Icons.copy_rounded, size: 19), - SizedBox(width: 10), - Text('复制链接'), - ], - ), - ), PopupMenuItem( onTap: () => Utils.shareText(_articleCtr.url), child: const Row( @@ -622,8 +610,18 @@ class _ArticlePageState extends State ], ), ), - if (_articleCtr.commentType == 12 && - _articleCtr.stats.value != null) + PopupMenuItem( + onTap: () => Utils.copyText(_articleCtr.url), + child: const Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.copy_rounded, size: 19), + SizedBox(width: 10), + Text('复制链接'), + ], + ), + ), + if (_articleCtr.type == 'read' && _articleCtr.stats.value != null) PopupMenuItem( onTap: () { try { @@ -828,16 +826,16 @@ class _ArticlePageState extends State Expanded( child: Builder( builder: (context) => TextButton.icon( - onPressed: () => - RequestUtils.onLikeDynamic( - _articleCtr.opusData!, - () { - if (context.mounted) { - (context as Element?) - ?.markNeedsBuild(); - } - }, - ), + onPressed: () { + _articleCtr.onLike( + () { + if (context.mounted) { + (context as Element?) + ?.markNeedsBuild(); + } + }, + ); + }, icon: Icon( _articleCtr.stats.value?.like ?.status == diff --git a/lib/pages/dynamics/widgets/rich_node_panel.dart b/lib/pages/dynamics/widgets/rich_node_panel.dart index 41ff391a..b115aa76 100644 --- a/lib/pages/dynamics/widgets/rich_node_panel.dart +++ b/lib/pages/dynamics/widgets/rich_node_panel.dart @@ -126,7 +126,7 @@ InlineSpan? richNode(item, BuildContext context) { child: GestureDetector( onTap: () { try { - String dynamicId = item.basic['comment_id_str']; + String dynamicId = item.basic.commentIdStr; Get.toNamed( '/webview', parameters: {