mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-30 23:58:13 +08:00
opt: unify fav & coin of video & pgc (#916)
This commit is contained in:
committed by
GitHub
parent
e945daba3a
commit
05c9269531
@@ -682,7 +682,7 @@ class FavHttp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 查看视频被收藏在哪个文件夹
|
// 查看视频被收藏在哪个文件夹
|
||||||
static Future videoInFolder({
|
static Future<LoadingState<FavFolderData>> videoInFolder({
|
||||||
dynamic mid,
|
dynamic mid,
|
||||||
dynamic rid,
|
dynamic rid,
|
||||||
dynamic type,
|
dynamic type,
|
||||||
@@ -696,9 +696,9 @@ class FavHttp {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
return {'status': true, 'data': FavFolderData.fromJson(res.data['data'])};
|
return Success(FavFolderData.fromJson(res.data['data']));
|
||||||
} else {
|
} else {
|
||||||
return {'status': false, 'msg': res.data['message']};
|
return Error(res.data['message']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class PgcInfoModel {
|
|||||||
int? showSeasonType;
|
int? showSeasonType;
|
||||||
String? squareCover;
|
String? squareCover;
|
||||||
String? staff;
|
String? staff;
|
||||||
Stat? stat;
|
PgcStat? stat;
|
||||||
int? status;
|
int? status;
|
||||||
List? styles;
|
List? styles;
|
||||||
String? subtitle;
|
String? subtitle;
|
||||||
@@ -187,7 +187,7 @@ class PgcInfoModel {
|
|||||||
staff: json['staff'] as String?,
|
staff: json['staff'] as String?,
|
||||||
stat: json['stat'] == null
|
stat: json['stat'] == null
|
||||||
? null
|
? null
|
||||||
: Stat.fromJson(json['stat'] as Map<String, dynamic>),
|
: PgcStat.fromJson(json['stat'] as Map<String, dynamic>),
|
||||||
status: json['status'] as int?,
|
status: json['status'] as int?,
|
||||||
styles: json['styles'],
|
styles: json['styles'],
|
||||||
subtitle: json['subtitle'] as String?,
|
subtitle: json['subtitle'] as String?,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class Season {
|
|||||||
int? seasonId;
|
int? seasonId;
|
||||||
String? seasonTitle;
|
String? seasonTitle;
|
||||||
int? seasonType;
|
int? seasonType;
|
||||||
Stat? stat;
|
PgcStat? stat;
|
||||||
|
|
||||||
Season({
|
Season({
|
||||||
this.badge,
|
this.badge,
|
||||||
@@ -58,6 +58,6 @@ class Season {
|
|||||||
seasonType: json['season_type'] as int?,
|
seasonType: json['season_type'] as int?,
|
||||||
stat: json['stat'] == null
|
stat: json['stat'] == null
|
||||||
? null
|
? null
|
||||||
: Stat.fromJson(json['stat'] as Map<String, dynamic>),
|
: PgcStat.fromJson(json['stat'] as Map<String, dynamic>),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,19 @@
|
|||||||
class Stat {
|
import 'package:PiliPlus/models_new/video/video_detail/stat_detail.dart';
|
||||||
num coins;
|
|
||||||
int? danmakus;
|
class PgcStat extends StatDetail {
|
||||||
int favorite;
|
|
||||||
int? favorites;
|
int? favorites;
|
||||||
String? followText;
|
String? followText;
|
||||||
int likes;
|
|
||||||
int? reply;
|
|
||||||
int? share;
|
|
||||||
int? views;
|
|
||||||
int? vt;
|
|
||||||
|
|
||||||
Stat({
|
PgcStat.fromJson(Map<String, dynamic> json) {
|
||||||
required this.coins,
|
coin = json["coins"] ?? 0;
|
||||||
this.danmakus,
|
danmaku = json["danmakus"];
|
||||||
required this.favorite,
|
favorite = json["favorite"] ?? 0;
|
||||||
this.favorites,
|
favorites = json["favorites"];
|
||||||
this.followText,
|
followText = json["follow_text"];
|
||||||
required this.likes,
|
like = json["likes"] ?? 0;
|
||||||
this.reply,
|
reply = json["reply"];
|
||||||
this.share,
|
share = json["share"];
|
||||||
this.views,
|
view = json["views"];
|
||||||
this.vt,
|
vt = json["vt"];
|
||||||
});
|
}
|
||||||
|
|
||||||
factory Stat.fromJson(Map<String, dynamic> json) => Stat(
|
|
||||||
coins: json["coins"] ?? 0,
|
|
||||||
danmakus: json["danmakus"],
|
|
||||||
favorite: json["favorite"] ?? 0,
|
|
||||||
favorites: json["favorites"],
|
|
||||||
followText: json["follow_text"],
|
|
||||||
likes: json["likes"] ?? 0,
|
|
||||||
reply: json["reply"],
|
|
||||||
share: json["share"],
|
|
||||||
views: json["views"],
|
|
||||||
vt: json["vt"],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:PiliPlus/models/model_owner.dart';
|
import 'package:PiliPlus/models/model_owner.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_detail/dimension.dart';
|
import 'package:PiliPlus/models/model_video.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_detail/rights.dart';
|
import 'package:PiliPlus/models_new/video/video_detail/rights.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_detail/stat.dart';
|
import 'package:PiliPlus/models_new/video/video_detail/stat.dart';
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ class Arc {
|
|||||||
int? duration;
|
int? duration;
|
||||||
Rights? rights;
|
Rights? rights;
|
||||||
Owner? author;
|
Owner? author;
|
||||||
Stat? stat;
|
VideoStat? stat;
|
||||||
String? dynam1c;
|
String? dynam1c;
|
||||||
Dimension? dimension;
|
Dimension? dimension;
|
||||||
bool? isChargeableSeason;
|
bool? isChargeableSeason;
|
||||||
@@ -77,7 +77,7 @@ class Arc {
|
|||||||
: Owner.fromJson(json['author'] as Map<String, dynamic>),
|
: Owner.fromJson(json['author'] as Map<String, dynamic>),
|
||||||
stat: json['stat'] == null
|
stat: json['stat'] == null
|
||||||
? null
|
? null
|
||||||
: Stat.fromJson(json['stat'] as Map<String, dynamic>),
|
: VideoStat.fromJson(json['stat'] as Map<String, dynamic>),
|
||||||
dynam1c: json['dynamic'] as String?,
|
dynam1c: json['dynamic'] as String?,
|
||||||
dimension: json['dimension'] == null
|
dimension: json['dimension'] == null
|
||||||
? null
|
? null
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class VideoDetailData {
|
|||||||
int? duration;
|
int? duration;
|
||||||
Rights? rights;
|
Rights? rights;
|
||||||
Owner? owner;
|
Owner? owner;
|
||||||
Stat? stat;
|
VideoStat? stat;
|
||||||
ArgueInfo? argueInfo;
|
ArgueInfo? argueInfo;
|
||||||
String? dynam1c;
|
String? dynam1c;
|
||||||
int? cid;
|
int? cid;
|
||||||
@@ -137,7 +137,7 @@ class VideoDetailData {
|
|||||||
: Owner.fromJson(json['owner'] as Map<String, dynamic>),
|
: Owner.fromJson(json['owner'] as Map<String, dynamic>),
|
||||||
stat: json['stat'] == null
|
stat: json['stat'] == null
|
||||||
? null
|
? null
|
||||||
: Stat.fromJson(json['stat'] as Map<String, dynamic>),
|
: VideoStat.fromJson(json['stat'] as Map<String, dynamic>),
|
||||||
argueInfo: json['argue_info'] == null
|
argueInfo: json['argue_info'] == null
|
||||||
? null
|
? null
|
||||||
: ArgueInfo.fromJson(json['argue_info'] as Map<String, dynamic>),
|
: ArgueInfo.fromJson(json['argue_info'] as Map<String, dynamic>),
|
||||||
|
|||||||
@@ -1,47 +1,25 @@
|
|||||||
class Stat {
|
import 'package:PiliPlus/models_new/video/video_detail/stat_detail.dart';
|
||||||
|
|
||||||
|
class VideoStat extends StatDetail {
|
||||||
int? aid;
|
int? aid;
|
||||||
int? view;
|
|
||||||
int? danmaku;
|
|
||||||
int? reply;
|
|
||||||
int favorite;
|
|
||||||
num coin;
|
|
||||||
int? share;
|
|
||||||
int? nowRank;
|
int? nowRank;
|
||||||
int? hisRank;
|
int? hisRank;
|
||||||
int like;
|
|
||||||
int? dislike;
|
int? dislike;
|
||||||
String? evaluation;
|
String? evaluation;
|
||||||
int? vt;
|
|
||||||
|
|
||||||
Stat({
|
VideoStat.fromJson(Map<String, dynamic> json) {
|
||||||
this.aid,
|
aid = json['aid'] as int?;
|
||||||
this.view,
|
view = json['view'] as int?;
|
||||||
this.danmaku,
|
danmaku = json['danmaku'] as int?;
|
||||||
this.reply,
|
reply = json['reply'] as int?;
|
||||||
required this.favorite,
|
favorite = json['favorite'] as int? ?? 0;
|
||||||
required this.coin,
|
coin = json['coin'] as num? ?? 0;
|
||||||
this.share,
|
share = json['share'] as int?;
|
||||||
this.nowRank,
|
nowRank = json['now_rank'] as int?;
|
||||||
this.hisRank,
|
hisRank = json['his_rank'] as int?;
|
||||||
required this.like,
|
like = json['like'] as int? ?? 0;
|
||||||
this.dislike,
|
dislike = json['dislike'] as int?;
|
||||||
this.evaluation,
|
evaluation = json['evaluation'] as String?;
|
||||||
this.vt,
|
vt = json['vt'] as int?;
|
||||||
});
|
}
|
||||||
|
|
||||||
factory Stat.fromJson(Map<String, dynamic> json) => Stat(
|
|
||||||
aid: json['aid'] as int?,
|
|
||||||
view: json['view'] as int?,
|
|
||||||
danmaku: json['danmaku'] as int?,
|
|
||||||
reply: json['reply'] as int?,
|
|
||||||
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? ?? 0,
|
|
||||||
dislike: json['dislike'] as int?,
|
|
||||||
evaluation: json['evaluation'] as String?,
|
|
||||||
vt: json['vt'] as int?,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
10
lib/models_new/video/video_detail/stat_detail.dart
Normal file
10
lib/models_new/video/video_detail/stat_detail.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
abstract class StatDetail {
|
||||||
|
late num coin;
|
||||||
|
int? danmaku;
|
||||||
|
late int favorite;
|
||||||
|
late int like;
|
||||||
|
int? reply;
|
||||||
|
int? share;
|
||||||
|
int? view;
|
||||||
|
int? vt;
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ class UgcSeason {
|
|||||||
int? signState;
|
int? signState;
|
||||||
int? attribute;
|
int? attribute;
|
||||||
List<SectionItem>? sections;
|
List<SectionItem>? sections;
|
||||||
Stat? stat;
|
VideoStat? stat;
|
||||||
int? epCount;
|
int? epCount;
|
||||||
int? seasonType;
|
int? seasonType;
|
||||||
bool? isPaySeason;
|
bool? isPaySeason;
|
||||||
@@ -45,7 +45,7 @@ class UgcSeason {
|
|||||||
.toList(),
|
.toList(),
|
||||||
stat: json['stat'] == null
|
stat: json['stat'] == null
|
||||||
? null
|
? null
|
||||||
: Stat.fromJson(json['stat'] as Map<String, dynamic>),
|
: VideoStat.fromJson(json['stat'] as Map<String, dynamic>),
|
||||||
epCount: json['ep_count'] as int?,
|
epCount: json['ep_count'] as int?,
|
||||||
seasonType: json['season_type'] as int?,
|
seasonType: json['season_type'] as int?,
|
||||||
isPaySeason: json['is_pay_season'] as bool?,
|
isPaySeason: json['is_pay_season'] as bool?,
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
|
import 'package:PiliPlus/http/fav.dart';
|
||||||
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/http/user.dart';
|
import 'package:PiliPlus/http/user.dart';
|
||||||
|
import 'package:PiliPlus/http/video.dart';
|
||||||
import 'package:PiliPlus/models_new/fav/fav_folder/data.dart';
|
import 'package:PiliPlus/models_new/fav/fav_folder/data.dart';
|
||||||
|
import 'package:PiliPlus/models_new/video/video_detail/stat_detail.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_tag/data.dart';
|
import 'package:PiliPlus/models_new/video/video_tag/data.dart';
|
||||||
import 'package:PiliPlus/services/account_service.dart';
|
import 'package:PiliPlus/services/account_service.dart';
|
||||||
|
import 'package:PiliPlus/utils/global_data.dart';
|
||||||
import 'package:PiliPlus/utils/page_utils.dart';
|
import 'package:PiliPlus/utils/page_utils.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/utils/storage_key.dart';
|
import 'package:PiliPlus/utils/storage_key.dart';
|
||||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -29,9 +35,119 @@ abstract class CommonIntroController extends GetxController {
|
|||||||
|
|
||||||
AccountService accountService = Get.find<AccountService>();
|
AccountService accountService = Get.find<AccountService>();
|
||||||
|
|
||||||
Future queryVideoInFolder();
|
(Object, int) getFavRidType();
|
||||||
|
|
||||||
Future<void> actionFavVideo({bool isQuick = false});
|
StatDetail? getStat();
|
||||||
|
|
||||||
|
Future<LoadingState<FavFolderData>> queryVideoInFolder() async {
|
||||||
|
favIds = null;
|
||||||
|
final (rid, type) = getFavRidType();
|
||||||
|
final result = await FavHttp.videoInFolder(
|
||||||
|
mid: accountService.mid,
|
||||||
|
rid: rid,
|
||||||
|
type: type,
|
||||||
|
);
|
||||||
|
if (result.isSuccess) {
|
||||||
|
favFolderData.value = result.data;
|
||||||
|
favIds = result.data.list
|
||||||
|
?.where((item) => item.favState == 1)
|
||||||
|
.map((item) => item.id)
|
||||||
|
.toSet();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> actionFavVideo({bool isQuick = false}) async {
|
||||||
|
final (rid, type) = getFavRidType();
|
||||||
|
// 收藏至默认文件夹
|
||||||
|
if (isQuick) {
|
||||||
|
SmartDialog.showLoading(msg: '请求中');
|
||||||
|
queryVideoInFolder().then((res) async {
|
||||||
|
if (res.isSuccess) {
|
||||||
|
final hasFav = this.hasFav.value;
|
||||||
|
var result = hasFav
|
||||||
|
? await FavHttp.unfavAll(rid: rid, type: type)
|
||||||
|
: await FavHttp.favVideo(
|
||||||
|
resources: '$rid:$type',
|
||||||
|
addIds: favFolderId.toString(),
|
||||||
|
);
|
||||||
|
SmartDialog.dismiss();
|
||||||
|
if (result['status']) {
|
||||||
|
getStat()!.favorite += hasFav ? -1 : 1;
|
||||||
|
this.hasFav.value = !hasFav;
|
||||||
|
SmartDialog.showToast('✅ 快速收藏/取消收藏成功');
|
||||||
|
} else {
|
||||||
|
SmartDialog.showToast(result['msg']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SmartDialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int?> addMediaIdsNew = [];
|
||||||
|
List<int?> delMediaIdsNew = [];
|
||||||
|
try {
|
||||||
|
for (var i in favFolderData.value.list!) {
|
||||||
|
bool isFaved = favIds?.contains(i.id) == true;
|
||||||
|
if (i.favState == 1) {
|
||||||
|
if (!isFaved) {
|
||||||
|
addMediaIdsNew.add(i.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isFaved) {
|
||||||
|
delMediaIdsNew.add(i.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (kDebugMode) debugPrint(e.toString());
|
||||||
|
}
|
||||||
|
SmartDialog.showLoading(msg: '请求中');
|
||||||
|
var result = await FavHttp.favVideo(
|
||||||
|
resources: '$rid:$type',
|
||||||
|
addIds: addMediaIdsNew.join(','),
|
||||||
|
delIds: delMediaIdsNew.join(','),
|
||||||
|
);
|
||||||
|
SmartDialog.dismiss();
|
||||||
|
if (result['status']) {
|
||||||
|
Get.back();
|
||||||
|
final newVal =
|
||||||
|
addMediaIdsNew.isNotEmpty || favIds?.length != delMediaIdsNew.length;
|
||||||
|
if (hasFav.value != newVal) {
|
||||||
|
getStat()!.favorite += newVal ? 1 : -1;
|
||||||
|
hasFav.value = newVal;
|
||||||
|
}
|
||||||
|
SmartDialog.showToast('操作成功');
|
||||||
|
} else {
|
||||||
|
SmartDialog.showToast(result['msg']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> coinVideo(int coin, [bool selectLike = false]) async {
|
||||||
|
final stat = getStat();
|
||||||
|
if (stat == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var res = await VideoHttp.coinVideo(
|
||||||
|
bvid: bvid,
|
||||||
|
multiply: coin,
|
||||||
|
selectLike: selectLike ? 1 : 0,
|
||||||
|
);
|
||||||
|
if (res['status']) {
|
||||||
|
SmartDialog.showToast('投币成功');
|
||||||
|
coinNum.value += coin;
|
||||||
|
GlobalData().afterCoin(coin);
|
||||||
|
stat.coin += coin;
|
||||||
|
if (selectLike && !hasLike.value) {
|
||||||
|
stat.like++;
|
||||||
|
hasLike.value = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SmartDialog.showToast(res['msg']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
late final enableQuickFav = Pref.enableQuickFav;
|
late final enableQuickFav = Pref.enableQuickFav;
|
||||||
int? quickFavId;
|
int? quickFavId;
|
||||||
|
|||||||
@@ -33,11 +33,7 @@ class _FavPanelState extends State<FavPanel> {
|
|||||||
Future<void> _query() async {
|
Future<void> _query() async {
|
||||||
var res = await widget.ctr.queryVideoInFolder();
|
var res = await widget.ctr.queryVideoInFolder();
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
if (res['status']) {
|
loadingState = res;
|
||||||
loadingState = const Success(null);
|
|
||||||
} else {
|
|
||||||
loadingState = Error(res['msg']);
|
|
||||||
}
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import 'package:PiliPlus/grpc/bilibili/app/viewunite/pgcanymodel.pb.dart'
|
|||||||
show ViewPgcAny;
|
show ViewPgcAny;
|
||||||
import 'package:PiliPlus/grpc/view.dart';
|
import 'package:PiliPlus/grpc/view.dart';
|
||||||
import 'package:PiliPlus/http/constants.dart';
|
import 'package:PiliPlus/http/constants.dart';
|
||||||
import 'package:PiliPlus/http/fav.dart';
|
|
||||||
import 'package:PiliPlus/http/video.dart';
|
import 'package:PiliPlus/http/video.dart';
|
||||||
import 'package:PiliPlus/models/pgc_lcf.dart';
|
import 'package:PiliPlus/models/pgc_lcf.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.dart';
|
import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart';
|
import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart';
|
||||||
import 'package:PiliPlus/models_new/triple/pgc_triple.dart';
|
import 'package:PiliPlus/models_new/triple/pgc_triple.dart';
|
||||||
|
import 'package:PiliPlus/models_new/video/video_detail/stat_detail.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_intro_controller.dart';
|
import 'package:PiliPlus/pages/common/common_intro_controller.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_repost/view.dart';
|
import 'package:PiliPlus/pages/dynamics_repost/view.dart';
|
||||||
import 'package:PiliPlus/pages/video/controller.dart';
|
import 'package:PiliPlus/pages/video/controller.dart';
|
||||||
@@ -64,7 +64,7 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
final hasFav = data.favorite == 1;
|
final hasFav = data.favorite == 1;
|
||||||
late final stat = pgcItem.stat!;
|
late final stat = pgcItem.stat!;
|
||||||
if (hasLike) {
|
if (hasLike) {
|
||||||
stat.likes = max(1, stat.likes);
|
stat.like = max(1, stat.like);
|
||||||
}
|
}
|
||||||
if (hasFav) {
|
if (hasFav) {
|
||||||
stat.favorite = max(1, stat.favorite);
|
stat.favorite = max(1, stat.favorite);
|
||||||
@@ -87,33 +87,13 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
var result = await VideoHttp.likeVideo(bvid: bvid, type: newVal);
|
var result = await VideoHttp.likeVideo(bvid: bvid, type: newVal);
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
SmartDialog.showToast(newVal ? result['data']['toast'] : '取消赞');
|
SmartDialog.showToast(newVal ? result['data']['toast'] : '取消赞');
|
||||||
pgcItem.stat!.likes += newVal ? 1 : -1;
|
pgcItem.stat!.like += newVal ? 1 : -1;
|
||||||
hasLike.value = newVal;
|
hasLike.value = newVal;
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast(result['msg']);
|
SmartDialog.showToast(result['msg']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> coinVideo(int coin, [bool selectLike = false]) async {
|
|
||||||
var res = await VideoHttp.coinVideo(
|
|
||||||
bvid: bvid,
|
|
||||||
multiply: coin,
|
|
||||||
selectLike: selectLike ? 1 : 0,
|
|
||||||
);
|
|
||||||
if (res['status']) {
|
|
||||||
SmartDialog.showToast('投币成功');
|
|
||||||
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']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 投币
|
// 投币
|
||||||
void actionCoinVideo() {
|
void actionCoinVideo() {
|
||||||
if (!accountService.isLogin.value) {
|
if (!accountService.isLogin.value) {
|
||||||
@@ -137,70 +117,11 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (取消)收藏 pgc
|
|
||||||
@override
|
@override
|
||||||
Future<void> actionFavVideo({bool isQuick = false}) async {
|
(Object, int) getFavRidType() => (epId!, 24);
|
||||||
// 收藏至默认文件夹
|
|
||||||
if (isQuick) {
|
|
||||||
SmartDialog.showLoading(msg: '请求中');
|
|
||||||
queryVideoInFolder().then((res) async {
|
|
||||||
if (res['status']) {
|
|
||||||
final hasFav = this.hasFav.value;
|
|
||||||
var result = hasFav
|
|
||||||
? await FavHttp.unfavAll(rid: epId, type: 24)
|
|
||||||
: await FavHttp.favVideo(
|
|
||||||
resources: '$epId:24',
|
|
||||||
addIds: favFolderId.toString(),
|
|
||||||
);
|
|
||||||
SmartDialog.dismiss();
|
|
||||||
if (result['status']) {
|
|
||||||
pgcItem.stat!.favorite += hasFav ? -1 : 1;
|
|
||||||
this.hasFav.value = !hasFav;
|
|
||||||
SmartDialog.showToast('✅ 快速收藏/取消收藏成功');
|
|
||||||
} else {
|
|
||||||
SmartDialog.showToast(result['msg']);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SmartDialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<int?> addMediaIdsNew = [];
|
@override
|
||||||
List<int?> delMediaIdsNew = [];
|
StatDetail? getStat() => pgcItem.stat;
|
||||||
try {
|
|
||||||
for (var i in favFolderData.value.list!.toList()) {
|
|
||||||
bool isFaved = favIds?.contains(i.id) == true;
|
|
||||||
if (i.favState == 1) {
|
|
||||||
if (!isFaved) {
|
|
||||||
addMediaIdsNew.add(i.id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isFaved) {
|
|
||||||
delMediaIdsNew.add(i.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (_) {}
|
|
||||||
var result = await FavHttp.favVideo(
|
|
||||||
resources: '$epId:24',
|
|
||||||
addIds: addMediaIdsNew.join(','),
|
|
||||||
delIds: delMediaIdsNew.join(','),
|
|
||||||
);
|
|
||||||
if (result['status']) {
|
|
||||||
SmartDialog.showToast('操作成功');
|
|
||||||
Get.back();
|
|
||||||
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']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分享视频
|
// 分享视频
|
||||||
void actionShareVideo(BuildContext context) {
|
void actionShareVideo(BuildContext context) {
|
||||||
@@ -407,24 +328,6 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
SmartDialog.showToast(result['msg']);
|
SmartDialog.showToast(result['msg']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future queryVideoInFolder() async {
|
|
||||||
favIds = null;
|
|
||||||
var result = await FavHttp.videoInFolder(
|
|
||||||
mid: accountService.mid,
|
|
||||||
rid: epId, // pgc
|
|
||||||
type: 24, // pgc
|
|
||||||
);
|
|
||||||
if (result['status']) {
|
|
||||||
favFolderData.value = result['data'];
|
|
||||||
favIds = favFolderData.value.list
|
|
||||||
?.where((item) => item.favState == 1)
|
|
||||||
.map((item) => item.id)
|
|
||||||
.toSet();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool prevPlay() {
|
bool prevPlay() {
|
||||||
List episodes = pgcItem.episodes!;
|
List episodes = pgcItem.episodes!;
|
||||||
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
|
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
|
||||||
@@ -503,11 +406,11 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
PgcTriple data = result['data'];
|
PgcTriple data = result['data'];
|
||||||
late final stat = pgcItem.stat!;
|
late final stat = pgcItem.stat!;
|
||||||
if ((data.like == 1) != hasLike.value) {
|
if ((data.like == 1) != hasLike.value) {
|
||||||
stat.likes++;
|
stat.like++;
|
||||||
hasLike.value = true;
|
hasLike.value = true;
|
||||||
}
|
}
|
||||||
if ((data.coin == 1) != hasCoin) {
|
if ((data.coin == 1) != hasCoin) {
|
||||||
stat.coins += 2;
|
stat.coin += 2;
|
||||||
coinNum.value = 2;
|
coinNum.value = 2;
|
||||||
GlobalData().afterCoin(2);
|
GlobalData().afterCoin(2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,11 +209,11 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
children: [
|
children: [
|
||||||
StatWidget(
|
StatWidget(
|
||||||
type: StatType.play,
|
type: StatType.play,
|
||||||
value: item.stat!.views,
|
value: item.stat!.view,
|
||||||
),
|
),
|
||||||
StatWidget(
|
StatWidget(
|
||||||
type: StatType.danmaku,
|
type: StatType.danmaku,
|
||||||
value: item.stat!.danmakus,
|
value: item.stat!.danmaku,
|
||||||
),
|
),
|
||||||
if (isLandscape) ...[
|
if (isLandscape) ...[
|
||||||
areasAndPubTime(theme, item),
|
areasAndPubTime(theme, item),
|
||||||
@@ -280,7 +280,7 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
onLongPress: pgcIntroController.actionOneThree,
|
onLongPress: pgcIntroController.actionOneThree,
|
||||||
selectStatus: pgcIntroController.hasLike.value,
|
selectStatus: pgcIntroController.hasLike.value,
|
||||||
semanticsLabel: '点赞',
|
semanticsLabel: '点赞',
|
||||||
text: NumUtil.numFormat(item.stat!.likes),
|
text: NumUtil.numFormat(item.stat!.like),
|
||||||
needAnim: true,
|
needAnim: true,
|
||||||
hasTriple:
|
hasTriple:
|
||||||
pgcIntroController.hasLike.value &&
|
pgcIntroController.hasLike.value &&
|
||||||
@@ -306,7 +306,7 @@ class _PgcIntroPageState extends State<PgcIntroPage>
|
|||||||
onTap: () => handleState(pgcIntroController.actionCoinVideo),
|
onTap: () => handleState(pgcIntroController.actionCoinVideo),
|
||||||
selectStatus: pgcIntroController.hasCoin,
|
selectStatus: pgcIntroController.hasCoin,
|
||||||
semanticsLabel: '投币',
|
semanticsLabel: '投币',
|
||||||
text: NumUtil.numFormat(item.stat!.coins),
|
text: NumUtil.numFormat(item.stat!.coin),
|
||||||
needAnim: true,
|
needAnim: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -114,11 +114,11 @@ class _IntroDetailState extends CommonCollapseSlidePageState<PgcIntroPanel> {
|
|||||||
children: [
|
children: [
|
||||||
StatWidget(
|
StatWidget(
|
||||||
type: StatType.play,
|
type: StatType.play,
|
||||||
value: widget.item.stat!.views,
|
value: widget.item.stat!.view,
|
||||||
),
|
),
|
||||||
StatWidget(
|
StatWidget(
|
||||||
type: StatType.danmaku,
|
type: StatType.danmaku,
|
||||||
value: widget.item.stat!.danmakus,
|
value: widget.item.stat!.danmaku,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,14 +4,12 @@ import 'dart:math';
|
|||||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||||
import 'package:PiliPlus/http/api.dart';
|
import 'package:PiliPlus/http/api.dart';
|
||||||
import 'package:PiliPlus/http/constants.dart';
|
import 'package:PiliPlus/http/constants.dart';
|
||||||
import 'package:PiliPlus/http/fav.dart';
|
|
||||||
import 'package:PiliPlus/http/init.dart';
|
import 'package:PiliPlus/http/init.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/http/member.dart';
|
import 'package:PiliPlus/http/member.dart';
|
||||||
import 'package:PiliPlus/http/search.dart';
|
import 'package:PiliPlus/http/search.dart';
|
||||||
import 'package:PiliPlus/http/user.dart';
|
import 'package:PiliPlus/http/user.dart';
|
||||||
import 'package:PiliPlus/http/video.dart';
|
import 'package:PiliPlus/http/video.dart';
|
||||||
import 'package:PiliPlus/models_new/fav/fav_folder/data.dart';
|
|
||||||
import 'package:PiliPlus/models_new/member_card_info/data.dart';
|
import 'package:PiliPlus/models_new/member_card_info/data.dart';
|
||||||
import 'package:PiliPlus/models_new/triple/ugc_triple.dart';
|
import 'package:PiliPlus/models_new/triple/ugc_triple.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_ai_conclusion/data.dart';
|
import 'package:PiliPlus/models_new/video/video_ai_conclusion/data.dart';
|
||||||
@@ -21,6 +19,7 @@ import 'package:PiliPlus/models_new/video/video_detail/episode.dart';
|
|||||||
import 'package:PiliPlus/models_new/video/video_detail/page.dart';
|
import 'package:PiliPlus/models_new/video/video_detail/page.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_detail/section.dart';
|
import 'package:PiliPlus/models_new/video/video_detail/section.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_detail/staff.dart';
|
import 'package:PiliPlus/models_new/video/video_detail/staff.dart';
|
||||||
|
import 'package:PiliPlus/models_new/video/video_detail/stat_detail.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_detail/ugc_season.dart';
|
import 'package:PiliPlus/models_new/video/video_detail/ugc_season.dart';
|
||||||
import 'package:PiliPlus/models_new/video/video_relation/data.dart';
|
import 'package:PiliPlus/models_new/video/video_relation/data.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_intro_controller.dart';
|
import 'package:PiliPlus/pages/common/common_intro_controller.dart';
|
||||||
@@ -40,7 +39,6 @@ import 'package:PiliPlus/utils/request_utils.dart';
|
|||||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -308,29 +306,6 @@ class VideoIntroController extends CommonIntroController with ReloadMixin {
|
|||||||
SmartDialog.showToast(res['msg']);
|
SmartDialog.showToast(res['msg']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> coinVideo(int coin, [bool selectLike = false]) async {
|
|
||||||
if (videoDetail.value.stat == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var res = await VideoHttp.coinVideo(
|
|
||||||
bvid: bvid,
|
|
||||||
multiply: coin,
|
|
||||||
selectLike: selectLike ? 1 : 0,
|
|
||||||
);
|
|
||||||
if (res['status']) {
|
|
||||||
SmartDialog.showToast('投币成功');
|
|
||||||
coinNum.value += coin;
|
|
||||||
GlobalData().afterCoin(coin);
|
|
||||||
final stat = videoDetail.value.stat!..coin += coin;
|
|
||||||
if (selectLike && !hasLike.value) {
|
|
||||||
stat.like++;
|
|
||||||
hasLike.value = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SmartDialog.showToast(res['msg']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 投币
|
// 投币
|
||||||
Future<void> actionCoinVideo() async {
|
Future<void> actionCoinVideo() async {
|
||||||
if (!accountService.isLogin.value) {
|
if (!accountService.isLogin.value) {
|
||||||
@@ -356,74 +331,11 @@ class VideoIntroController extends CommonIntroController with ReloadMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (取消)收藏
|
|
||||||
@override
|
@override
|
||||||
Future<void> actionFavVideo({bool isQuick = false}) async {
|
(Object, int) getFavRidType() => (IdUtils.bv2av(bvid), 2);
|
||||||
// 收藏至默认文件夹
|
|
||||||
if (isQuick) {
|
|
||||||
SmartDialog.showLoading(msg: '请求中');
|
|
||||||
queryVideoInFolder().then((res) async {
|
|
||||||
if (res['status']) {
|
|
||||||
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: favFolderId.toString(),
|
|
||||||
);
|
|
||||||
SmartDialog.dismiss();
|
|
||||||
if (result['status']) {
|
|
||||||
videoDetail.value.stat!.favorite += hasFav ? -1 : 1;
|
|
||||||
this.hasFav.value = !hasFav;
|
|
||||||
SmartDialog.showToast('✅ 快速收藏/取消收藏成功');
|
|
||||||
} else {
|
|
||||||
SmartDialog.showToast(result['msg']);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SmartDialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<int?> addMediaIdsNew = [];
|
@override
|
||||||
List<int?> delMediaIdsNew = [];
|
StatDetail? getStat() => videoDetail.value.stat;
|
||||||
try {
|
|
||||||
for (var i in favFolderData.value.list!.toList()) {
|
|
||||||
bool isFaved = favIds?.contains(i.id) == true;
|
|
||||||
if (i.favState == 1) {
|
|
||||||
if (!isFaved) {
|
|
||||||
addMediaIdsNew.add(i.id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isFaved) {
|
|
||||||
delMediaIdsNew.add(i.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (kDebugMode) debugPrint(e.toString());
|
|
||||||
}
|
|
||||||
SmartDialog.showLoading(msg: '请求中');
|
|
||||||
var result = await FavHttp.favVideo(
|
|
||||||
resources: '${IdUtils.bv2av(bvid)}:2',
|
|
||||||
addIds: addMediaIdsNew.join(','),
|
|
||||||
delIds: delMediaIdsNew.join(','),
|
|
||||||
);
|
|
||||||
SmartDialog.dismiss();
|
|
||||||
if (result['status']) {
|
|
||||||
Get.back();
|
|
||||||
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']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分享视频
|
// 分享视频
|
||||||
void actionShareVideo(BuildContext context) {
|
void actionShareVideo(BuildContext context) {
|
||||||
@@ -530,24 +442,6 @@ class VideoIntroController extends CommonIntroController with ReloadMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future queryVideoInFolder() async {
|
|
||||||
favIds = null;
|
|
||||||
var result = await FavHttp.videoInFolder(
|
|
||||||
mid: accountService.mid,
|
|
||||||
rid: IdUtils.bv2av(bvid),
|
|
||||||
);
|
|
||||||
if (result['status']) {
|
|
||||||
FavFolderData data = result['data'];
|
|
||||||
favFolderData.value = data;
|
|
||||||
favIds = data.list
|
|
||||||
?.where((item) => item.favState == 1)
|
|
||||||
.map((item) => item.id)
|
|
||||||
.toSet();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询关注状态
|
// 查询关注状态
|
||||||
Future<void> queryFollowStatus() async {
|
Future<void> queryFollowStatus() async {
|
||||||
final videoDetail = this.videoDetail.value;
|
final videoDetail = this.videoDetail.value;
|
||||||
|
|||||||
Reference in New Issue
Block a user