From d567c296f8a2197070207847ef123398b1b3c515 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Thu, 24 Jul 2025 18:22:49 +0800 Subject: [PATCH] opt video action Signed-off-by: bggRGjQaUbCoE --- lib/models_new/pgc/pgc_info_model/stat.dart | 18 ++--- lib/models_new/video/video_detail/stat.dart | 18 ++--- lib/pages/common/common_intro_controller.dart | 14 ++-- .../video/introduction/pgc/controller.dart | 68 ++++++++++++------ .../video/introduction/ugc/controller.dart | 69 ++++++++++++------- lib/utils/global_data.dart | 2 +- 6 files changed, 118 insertions(+), 71 deletions(-) diff --git a/lib/models_new/pgc/pgc_info_model/stat.dart b/lib/models_new/pgc/pgc_info_model/stat.dart index 23eae9d9..c567b938 100644 --- a/lib/models_new/pgc/pgc_info_model/stat.dart +++ b/lib/models_new/pgc/pgc_info_model/stat.dart @@ -1,22 +1,22 @@ class Stat { - num? coins; + num coins; int? danmakus; - int? favorite; + int favorite; int? favorites; String? followText; - int? likes; + int likes; int? reply; int? share; int? views; int? vt; Stat({ - this.coins, + required this.coins, this.danmakus, - this.favorite, + required this.favorite, this.favorites, this.followText, - this.likes, + required this.likes, this.reply, this.share, this.views, @@ -24,12 +24,12 @@ class Stat { }); factory Stat.fromJson(Map json) => Stat( - coins: json["coins"], + coins: json["coins"] ?? 0, danmakus: json["danmakus"], - favorite: json["favorite"], + favorite: json["favorite"] ?? 0, favorites: json["favorites"], followText: json["follow_text"], - likes: json["likes"], + likes: json["likes"] ?? 0, reply: json["reply"], share: json["share"], views: json["views"], diff --git a/lib/models_new/video/video_detail/stat.dart b/lib/models_new/video/video_detail/stat.dart index d93e235c..7b297fe1 100644 --- a/lib/models_new/video/video_detail/stat.dart +++ b/lib/models_new/video/video_detail/stat.dart @@ -3,12 +3,12 @@ class Stat { int? view; int? danmaku; int? reply; - int? favorite; - num? coin; + int favorite; + num coin; int? share; int? nowRank; int? hisRank; - int? like; + int like; int? dislike; String? evaluation; int? vt; @@ -18,12 +18,12 @@ class Stat { this.view, this.danmaku, this.reply, - this.favorite, - this.coin, + required this.favorite, + required this.coin, this.share, this.nowRank, this.hisRank, - this.like, + required this.like, this.dislike, this.evaluation, this.vt, @@ -34,12 +34,12 @@ class Stat { view: json['view'] as int?, danmaku: json['danmaku'] as int?, reply: json['reply'] as int?, - favorite: json['favorite'] as int?, - coin: json['coin'] as num?, + favorite: json['favorite'] as int? ?? 0, + coin: json['coin'] as num? ?? 0, share: json['share'] as int?, nowRank: json['now_rank'] as int?, hisRank: json['his_rank'] as int?, - like: json['like'] as int?, + like: json['like'] as int? ?? 0, dislike: json['dislike'] as int?, evaluation: json['evaluation'] as String?, vt: json['vt'] as int?, diff --git a/lib/pages/common/common_intro_controller.dart b/lib/pages/common/common_intro_controller.dart index 2a2ec92c..01d6e047 100644 --- a/lib/pages/common/common_intro_controller.dart +++ b/lib/pages/common/common_intro_controller.dart @@ -1,6 +1,5 @@ import 'package:PiliPlus/http/user.dart'; import 'package:PiliPlus/models_new/fav/fav_folder/data.dart'; -import 'package:PiliPlus/models_new/fav/fav_folder/list.dart'; import 'package:PiliPlus/models_new/video/video_tag/data.dart'; import 'package:PiliPlus/services/account_service.dart'; import 'package:PiliPlus/utils/page_utils.dart'; @@ -35,20 +34,23 @@ abstract class CommonIntroController extends GetxController { Future actionFavVideo({String type = 'choose'}); late final enableQuickFav = Pref.enableQuickFav; - late int? quickFavId = Pref.quickFavId; + int? quickFavId; - FavFolderInfo get favFolderInfo { + int get favFolderId { + if (this.quickFavId != null) { + return this.quickFavId!; + } + final quickFavId = Pref.quickFavId; final list = favFolderData.value.list!; if (quickFavId != null) { final folderInfo = list.firstWhereOrNull((e) => e.id == quickFavId); if (folderInfo != null) { - return folderInfo; + return this.quickFavId = quickFavId; } else { - quickFavId = null; GStorage.setting.delete(SettingBoxKey.quickFavId); } } - return list.first; + return this.quickFavId = list.first.id; } // 收藏 diff --git a/lib/pages/video/introduction/pgc/controller.dart b/lib/pages/video/introduction/pgc/controller.dart index 045b775f..6d797455 100644 --- a/lib/pages/video/introduction/pgc/controller.dart +++ b/lib/pages/video/introduction/pgc/controller.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:math' show max; import 'package:PiliPlus/grpc/bilibili/app/viewunite/pgcanymodel.pb.dart' show ViewPgcAny; @@ -59,9 +60,18 @@ class PgcIntroController extends CommonIntroController { var result = await VideoHttp.pgcLikeCoinFav(epId: epId); if (result['status']) { PgcLCF data = result['data']; - hasLike.value = data.like == 1; + final hasLike = data.like == 1; + final hasFav = data.favorite == 1; + late final stat = pgcItem.stat!; + if (hasLike) { + stat.likes = max(1, stat.likes); + } + if (hasFav) { + stat.favorite = max(1, stat.favorite); + } + this.hasLike.value = hasLike; coinNum.value = data.coinNumber!; - hasFav.value = data.favorite == 1; + this.hasFav.value = hasFav; } else { SmartDialog.showToast(result['msg']); } @@ -69,11 +79,16 @@ class PgcIntroController extends CommonIntroController { // (取消)点赞 Future actionLikeVideo() async { - var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value); + if (!accountService.isLogin.value) { + SmartDialog.showToast('账号未登录'); + return; + } + final newVal = !hasLike.value; + var result = await VideoHttp.likeVideo(bvid: bvid, type: newVal); if (result['status']) { - SmartDialog.showToast(!hasLike.value ? result['data']['toast'] : '取消赞'); - pgcItem.stat!.likes = pgcItem.stat!.likes! + (!hasLike.value ? 1 : -1); - hasLike.value = !hasLike.value; + SmartDialog.showToast(newVal ? result['data']['toast'] : '取消赞'); + pgcItem.stat!.likes += newVal ? 1 : -1; + hasLike.value = newVal; } else { SmartDialog.showToast(result['msg']); } @@ -87,13 +102,13 @@ class PgcIntroController extends CommonIntroController { ); if (res['status']) { SmartDialog.showToast('投币成功'); - pgcItem.stat!.coins = pgcItem.stat!.coins! + coin; - if (selectLike && !hasLike.value) { - hasLike.value = true; - pgcItem.stat!.likes = pgcItem.stat!.likes! + 1; - } coinNum.value += coin; GlobalData().afterCoin(coin); + final stat = pgcItem.stat!..coins += coin; + if (selectLike && !hasLike.value) { + stat.likes++; + hasLike.value = true; + } } else { SmartDialog.showToast(res['msg']); } @@ -130,18 +145,17 @@ class PgcIntroController extends CommonIntroController { SmartDialog.showLoading(msg: '请求中'); queryVideoInFolder().then((res) async { if (res['status']) { - final favFolderInfo = this.favFolderInfo; - final defaultFolderId = favFolderInfo.id; - final isFav = favFolderInfo.favState == 1; - var result = isFav + final hasFav = this.hasFav.value; + var result = hasFav ? await FavHttp.unfavAll(rid: epId, type: 24) : await FavHttp.favVideo( resources: '$epId:24', - addIds: defaultFolderId.toString(), + addIds: favFolderId.toString(), ); SmartDialog.dismiss(); if (result['status']) { - hasFav.value = !isFav; + pgcItem.stat!.favorite += hasFav ? -1 : 1; + this.hasFav.value = !hasFav; SmartDialog.showToast('✅ 快速收藏/取消收藏成功'); } else { SmartDialog.showToast(result['msg']); @@ -177,8 +191,12 @@ class PgcIntroController extends CommonIntroController { if (result['status']) { SmartDialog.showToast('操作成功'); Get.back(); - hasFav.value = + final newVal = addMediaIdsNew.isNotEmpty || favIds?.length != delMediaIdsNew.length; + if (hasFav.value != newVal) { + pgcItem.stat!.favorite += newVal ? 1 : -1; + hasFav.value = newVal; + } } else { SmartDialog.showToast(result['msg']); } @@ -483,12 +501,20 @@ class PgcIntroController extends CommonIntroController { var result = await VideoHttp.triple(epId: epId, seasonId: seasonId); if (result['status']) { PgcTriple data = result['data']; - hasLike.value = data.like == 1; - if (data.coin == 1) { + late final stat = pgcItem.stat!; + if ((data.like == 1) != hasLike.value) { + stat.likes++; + hasLike.value = true; + } + if ((data.coin == 1) != hasCoin) { + stat.coins += 2; coinNum.value = 2; GlobalData().afterCoin(2); } - hasFav.value = data.favorite == 1; + if ((data.favorite == 1) != hasFav.value) { + stat.favorite++; + hasFav.value = true; + } SmartDialog.showToast('三连成功'); } else { SmartDialog.showToast(result['msg']); diff --git a/lib/pages/video/introduction/ugc/controller.dart b/lib/pages/video/introduction/ugc/controller.dart index 9f351e43..f8bfcb70 100644 --- a/lib/pages/video/introduction/ugc/controller.dart +++ b/lib/pages/video/introduction/ugc/controller.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:math'; import 'package:PiliPlus/common/widgets/scroll_physics.dart'; import 'package:PiliPlus/http/api.dart'; @@ -200,6 +201,13 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { var result = await VideoHttp.videoRelation(bvid: bvid); if (result['status']) { VideoRelation data = result['data']; + late final stat = videoDetail.value.stat!; + if (data.like!) { + stat.like = max(1, stat.like); + } + if (data.favorite!) { + stat.favorite = max(1, stat.favorite); + } hasLike.value = data.like!; hasDislike.value = data.dislike!; coinNum.value = data.coin!; @@ -222,12 +230,21 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { var result = await VideoHttp.oneThree(bvid: bvid); if (result['status']) { UgcTriple data = result['data']; - hasLike.value = data.like!; - if (data.coin == true) { + late final stat = videoDetail.value.stat!; + if (data.like != hasLike.value) { + stat.like++; + hasLike.value = true; + } + if (data.coin != hasCoin) { + stat.coin += 2; coinNum.value = 2; GlobalData().afterCoin(2); } - hasFav.value = data.fav!; + if (data.fav != hasFav.value) { + stat.favorite++; + hasFav.value = true; + } + hasDislike.value = false; SmartDialog.showToast('三连成功'); } else { SmartDialog.showToast(result['msg']); @@ -240,20 +257,17 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { SmartDialog.showToast('账号未登录'); return; } - if (videoDetail.value.stat?.like == null) { + if (videoDetail.value.stat == null) { return; } - var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value); + final newVal = !hasLike.value; + var result = await VideoHttp.likeVideo(bvid: bvid, type: newVal); if (result['status']) { - if (!hasLike.value) { - SmartDialog.showToast(result['data']['toast']); - hasLike.value = true; + SmartDialog.showToast(newVal ? result['data']['toast'] : '取消赞'); + videoDetail.value.stat!.like += newVal ? 1 : -1; + hasLike.value = newVal; + if (newVal) { hasDislike.value = false; - videoDetail.value.stat!.like = videoDetail.value.stat!.like! + 1; - } else if (hasLike.value) { - SmartDialog.showToast('取消赞'); - hasLike.value = false; - videoDetail.value.stat!.like = videoDetail.value.stat!.like! - 1; } } else { SmartDialog.showToast(result['msg']); @@ -273,7 +287,10 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { if (!hasDislike.value) { SmartDialog.showToast('点踩成功'); hasDislike.value = true; - hasLike.value = false; + if (hasLike.value) { + videoDetail.value.stat!.like--; + hasLike.value = false; + } } else { SmartDialog.showToast('取消踩'); hasDislike.value = false; @@ -292,8 +309,7 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { } Future coinVideo(int coin, [bool selectLike = false]) async { - if (videoDetail.value.stat?.coin == null) { - // not init + if (videoDetail.value.stat == null) { return; } var res = await VideoHttp.coinVideo( @@ -305,10 +321,10 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { SmartDialog.showToast('投币成功'); coinNum.value += coin; GlobalData().afterCoin(coin); - videoDetail.value.stat!.coin = videoDetail.value.stat!.coin! + coin; + final stat = videoDetail.value.stat!..coin += coin; if (selectLike && !hasLike.value) { + stat.like++; hasLike.value = true; - videoDetail.value.stat!.like = videoDetail.value.stat!.like! + 1; } } else { SmartDialog.showToast(res['msg']); @@ -348,18 +364,17 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { SmartDialog.showLoading(msg: '请求中'); queryVideoInFolder().then((res) async { if (res['status']) { - final favFolderInfo = this.favFolderInfo; - final defaultFolderId = favFolderInfo.id; - final isFav = favFolderInfo.favState == 1; - var result = isFav + final hasFav = this.hasFav.value; + var result = hasFav ? await FavHttp.unfavAll(rid: IdUtils.bv2av(bvid), type: 2) : await FavHttp.favVideo( resources: '${IdUtils.bv2av(bvid)}:2', - addIds: defaultFolderId.toString(), + addIds: favFolderId.toString(), ); SmartDialog.dismiss(); if (result['status']) { - hasFav.value = !isFav; + videoDetail.value.stat!.favorite += hasFav ? -1 : 1; + this.hasFav.value = !hasFav; SmartDialog.showToast('✅ 快速收藏/取消收藏成功'); } else { SmartDialog.showToast(result['msg']); @@ -398,8 +413,12 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { SmartDialog.dismiss(); if (result['status']) { Get.back(); - hasFav.value = + final newVal = addMediaIdsNew.isNotEmpty || favIds?.length != delMediaIdsNew.length; + if (hasFav.value != newVal) { + videoDetail.value.stat!.favorite += newVal ? 1 : -1; + hasFav.value = newVal; + } SmartDialog.showToast('操作成功'); } else { SmartDialog.showToast(result['msg']); diff --git a/lib/utils/global_data.dart b/lib/utils/global_data.dart index ea544f5c..d536170f 100644 --- a/lib/utils/global_data.dart +++ b/lib/utils/global_data.dart @@ -5,7 +5,7 @@ class GlobalData { num? coins; - void afterCoin(int coin) { + void afterCoin(num coin) { if (coins != null) { coins = coins! - coin; }