refa: coin/like arc

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-06-06 21:33:55 +08:00
parent 77e418e4b7
commit db4283af4a
10 changed files with 220 additions and 121 deletions

View File

@@ -876,4 +876,8 @@ class Api {
static const String favFavFolder = '/x/v3/fav/folder/fav'; static const String favFavFolder = '/x/v3/fav/folder/fav';
static const String unfavFavFolder = '/x/v3/fav/folder/unfav'; static const String unfavFavFolder = '/x/v3/fav/folder/unfav';
static const String coinArc = '${HttpString.appBaseUrl}/x/v2/space/coinarc';
static const String likeArc = '${HttpString.appBaseUrl}/x/v2/space/likearc';
} }

View File

@@ -8,11 +8,11 @@ import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/member/contribute_type.dart'; import 'package:PiliPlus/models/common/member/contribute_type.dart';
import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:PiliPlus/models/member/coin.dart';
import 'package:PiliPlus/models/member/info.dart'; import 'package:PiliPlus/models/member/info.dart';
import 'package:PiliPlus/models/member/tags.dart'; import 'package:PiliPlus/models/member/tags.dart';
import 'package:PiliPlus/models_new/follow/data.dart'; import 'package:PiliPlus/models_new/follow/data.dart';
import 'package:PiliPlus/models_new/follow/list.dart'; import 'package:PiliPlus/models_new/follow/list.dart';
import 'package:PiliPlus/models_new/member/coin_like_arc/data.dart';
import 'package:PiliPlus/models_new/member/search_archive/data.dart'; import 'package:PiliPlus/models_new/member/search_archive/data.dart';
import 'package:PiliPlus/models_new/space/space/data.dart'; import 'package:PiliPlus/models_new/space/space/data.dart';
import 'package:PiliPlus/models_new/space/space_archive/data.dart'; import 'package:PiliPlus/models_new/space/space_archive/data.dart';
@@ -605,62 +605,6 @@ class MemberHttp {
} }
} }
// 最近投币
static Future<LoadingState<List<MemberCoinsDataModel>?>> getRecentCoinVideo(
{required int mid}) async {
Map params = await WbiSign.makSign({
'mid': mid,
'gaia_source': 'main_web',
'web_location': 333.999,
});
var res = await Request().get(
Api.getRecentCoinVideoApi,
queryParameters: {
'vmid': mid,
'gaia_source': 'main_web',
'web_location': 333.999,
'w_rid': params['w_rid'],
'wts': params['wts'],
},
);
if (res.data['code'] == 0) {
List<MemberCoinsDataModel>? list = (res.data['data'] as List?)
?.map<MemberCoinsDataModel>((e) => MemberCoinsDataModel.fromJson(e))
.toList();
return Success(list);
} else {
return Error(res.data['message']);
}
}
// 最近点赞
static Future<LoadingState<List<MemberCoinsDataModel>?>> getRecentLikeVideo(
{required int mid}) async {
Map params = await WbiSign.makSign({
'mid': mid,
'gaia_source': 'main_web',
'web_location': 333.999,
});
var res = await Request().get(
Api.getRecentLikeVideoApi,
queryParameters: {
'vmid': mid,
'gaia_source': 'main_web',
'web_location': 333.999,
'w_rid': params['w_rid'],
'wts': params['wts'],
},
);
if (res.data['code'] == 0) {
List<MemberCoinsDataModel>? list = (res.data['data']?['list'] as List?)
?.map<MemberCoinsDataModel>((e) => MemberCoinsDataModel.fromJson(e))
.toList();
return Success(list);
} else {
return Error(res.data['message']);
}
}
// 获取up播放数、点赞数 // 获取up播放数、点赞数
static Future memberView({required int mid}) async { static Future memberView({required int mid}) async {
var res = await Request() var res = await Request()
@@ -748,4 +692,42 @@ class MemberHttp {
return Error(res.data['message']); return Error(res.data['message']);
} }
} }
static Future<LoadingState<CoinLikeArcData>> coinArc({
required int mid,
required int page,
}) async {
var res = await Request().get(
Api.coinArc,
queryParameters: {
'pn': page,
'ps': 20,
'vmid': mid,
},
);
if (res.data['code'] == 0) {
return Success(CoinLikeArcData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<CoinLikeArcData>> likeArc({
required int mid,
required int page,
}) async {
var res = await Request().get(
Api.likeArc,
queryParameters: {
'pn': page,
'ps': 20,
'vmid': mid,
},
);
if (res.data['code'] == 0) {
return Success(CoinLikeArcData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
} }

View File

@@ -1,17 +0,0 @@
import 'package:PiliPlus/models/model_hot_video_item.dart';
class MemberCoinsDataModel extends HotVideoItemModel {
String? subtitle;
int? coins;
int? time;
String? resourceType;
MemberCoinsDataModel.fromJson(Map<String, dynamic> json)
: super.fromJson(json) {
coins = json['coins'];
subtitle = json['subtitle'];
time = json['time'];
resourceType = json['resource_type'];
redirectUrl = json['redirect_url'];
}
}

View File

@@ -0,0 +1,16 @@
import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
class CoinLikeArcData {
int? count;
List<CoinLikeArcItem>? item;
CoinLikeArcData({this.count, this.item});
factory CoinLikeArcData.fromJson(Map<String, dynamic> json) =>
CoinLikeArcData(
count: json['count'] as int?,
item: (json['item'] as List<dynamic>?)
?.map((e) => CoinLikeArcItem.fromJson(e as Map<String, dynamic>))
.toList(),
);
}

View File

@@ -0,0 +1,96 @@
class CoinLikeArcItem {
String? title;
String? subtitle;
String? tname;
String? cover;
String? coverIcon;
String? uri;
String? param;
String? goto;
String? length;
int? duration;
bool? isPopular;
bool? isSteins;
bool? isUgcpay;
bool? isCooperation;
bool? isPgc;
bool? isLivePlayback;
bool? isPugv;
bool? isFold;
bool? isOneself;
int? play;
int? danmaku;
int? ctime;
int? ugcPay;
String? author;
bool? state;
int? videos;
String? viewContent;
int? iconType;
String? publishTimeText;
CoinLikeArcItem({
this.title,
this.subtitle,
this.tname,
this.cover,
this.coverIcon,
this.uri,
this.param,
this.goto,
this.length,
this.duration,
this.isPopular,
this.isSteins,
this.isUgcpay,
this.isCooperation,
this.isPgc,
this.isLivePlayback,
this.isPugv,
this.isFold,
this.isOneself,
this.play,
this.danmaku,
this.ctime,
this.ugcPay,
this.author,
this.state,
this.videos,
this.viewContent,
this.iconType,
this.publishTimeText,
});
factory CoinLikeArcItem.fromJson(Map<String, dynamic> json) =>
CoinLikeArcItem(
title: json['title'] as String?,
subtitle: json['subtitle'] as String?,
tname: json['tname'] as String?,
cover: json['cover'] as String?,
coverIcon: json['cover_icon'] as String?,
uri: json['uri'] as String?,
param: json['param'] as String?,
goto: json['goto'] as String?,
length: json['length'] as String?,
duration: json['duration'] as int?,
isPopular: json['is_popular'] as bool?,
isSteins: json['is_steins'] as bool?,
isUgcpay: json['is_ugcpay'] as bool?,
isCooperation: json['is_cooperation'] as bool?,
isPgc: json['is_pgc'] as bool?,
isLivePlayback: json['is_live_playback'] as bool?,
isPugv: json['is_pugv'] as bool?,
isFold: json['is_fold'] as bool?,
isOneself: json['is_oneself'] as bool?,
play: json['play'] as int?,
danmaku: json['danmaku'] as int?,
ctime: json['ctime'] as int?,
ugcPay: json['ugc_pay'] as int?,
author: json['author'] as String?,
state: json['state'] as bool?,
videos: json['videos'] as int?,
viewContent: json['view_content'] as String?,
iconType: json['icon_type'] as int?,
publishTimeText: json['publish_time_text'] as String?,
);
}

View File

@@ -1,10 +1,11 @@
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/models/member/coin.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/data.dart';
import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
class MemberCoinController extends CommonListController< class MemberCoinController
List<MemberCoinsDataModel>?, MemberCoinsDataModel> { extends CommonListController<CoinLikeArcData, CoinLikeArcItem> {
final dynamic mid; final dynamic mid;
MemberCoinController({this.mid}); MemberCoinController({this.mid});
@@ -15,6 +16,11 @@ class MemberCoinController extends CommonListController<
} }
@override @override
Future<LoadingState<List<MemberCoinsDataModel>?>> customGetData() => List<CoinLikeArcItem>? getDataList(CoinLikeArcData response) {
MemberHttp.getRecentCoinVideo(mid: mid); return response.item;
}
@override
Future<LoadingState<CoinLikeArcData>> customGetData() =>
MemberHttp.coinArc(mid: mid, page: page);
} }

View File

@@ -2,7 +2,7 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/skeleton/video_card_v.dart'; import 'package:PiliPlus/common/skeleton/video_card_v.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/member/coin.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/member_coin/controller.dart'; import 'package:PiliPlus/pages/member_coin/controller.dart';
import 'package:PiliPlus/pages/member_coin/widgets/item.dart'; import 'package:PiliPlus/pages/member_coin/widgets/item.dart';
import 'package:PiliPlus/utils/grid.dart'; import 'package:PiliPlus/utils/grid.dart';
@@ -59,7 +59,7 @@ class _MemberCoinPageState extends State<MemberCoinPage> {
); );
} }
Widget _buildBody(LoadingState<List<MemberCoinsDataModel>?> loadingState) { Widget _buildBody(LoadingState<List<CoinLikeArcItem>?> loadingState) {
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverGrid.builder( Loading() => SliverGrid.builder(
gridDelegate: SliverGridDelegateWithExtentAndRatio( gridDelegate: SliverGridDelegateWithExtentAndRatio(
@@ -85,7 +85,10 @@ class _MemberCoinPageState extends State<MemberCoinPage> {
), ),
itemCount: response!.length, itemCount: response!.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return MemberCoinsItem(coinItem: response[index]); if (index == response.length - 1) {
_ctr.onLoadMore();
}
return MemberCoinLikeItem(item: response[index]);
}, },
) )
: HttpError(onReload: _ctr.onReload), : HttpError(onReload: _ctr.onReload),

View File

@@ -6,18 +6,18 @@ import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/http/search.dart'; import 'package:PiliPlus/http/search.dart';
import 'package:PiliPlus/models/common/badge_type.dart'; import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/models/member/coin.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MemberCoinsItem extends StatelessWidget { class MemberCoinLikeItem extends StatelessWidget {
final MemberCoinsDataModel coinItem; final CoinLikeArcItem item;
const MemberCoinsItem({ const MemberCoinLikeItem({
super.key, super.key,
required this.coinItem, required this.item,
}); });
@override @override
@@ -27,29 +27,29 @@ class MemberCoinsItem extends StatelessWidget {
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
if (coinItem.resourceType != 'ugc') { if (item.isPgc == true) {
if (coinItem.redirectUrl?.isNotEmpty == true) { if (item.uri?.isNotEmpty == true) {
if (await PiliScheme.routePushFromUrl(coinItem.redirectUrl!, PageUtils.viewPgcFromUri(item.uri!);
selfHandle: true)) {
return;
}
} }
return;
} }
int? cid =
await SearchHttp.ab2c(aid: coinItem.aid, bvid: coinItem.bvid); if (item.param != null) {
if (cid != null) { int? cid = await SearchHttp.ab2c(aid: item.param);
PageUtils.toVideoPage( if (cid != null) {
'bvid=${coinItem.bvid}&cid=$cid', PageUtils.toVideoPage(
arguments: { 'bvid=${IdUtils.av2bv(int.parse(item.param!))}&cid=$cid',
'videoItem': coinItem, arguments: {
'heroTag': Utils.makeHeroTag(coinItem.aid) 'videoItem': item,
}, 'heroTag': Utils.makeHeroTag(item.param)
); },
);
}
} }
}, },
onLongPress: () => imageSaveDialog( onLongPress: () => imageSaveDialog(
title: coinItem.title, title: item.title,
cover: coinItem.cover, cover: item.cover,
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -63,16 +63,16 @@ class MemberCoinsItem extends StatelessWidget {
clipBehavior: Clip.none, clipBehavior: Clip.none,
children: [ children: [
NetworkImgLayer( NetworkImgLayer(
src: coinItem.cover, src: item.cover,
width: maxWidth, width: maxWidth,
height: maxHeight, height: maxHeight,
), ),
if (coinItem.duration > 0) if (item.duration != null && item.duration! > 0)
PBadge( PBadge(
bottom: 6, bottom: 6,
right: 6, right: 6,
type: PBadgeType.gray, type: PBadgeType.gray,
text: Utils.timeFormat(coinItem.duration), text: Utils.timeFormat(item.duration),
) )
], ],
); );
@@ -85,7 +85,7 @@ class MemberCoinsItem extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'${coinItem.title}\n', '${item.title}\n',
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -94,17 +94,17 @@ class MemberCoinsItem extends StatelessWidget {
children: [ children: [
StatWidget( StatWidget(
type: StatType.play, type: StatType.play,
value: coinItem.stat.view, value: item.play,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
StatWidget( StatWidget(
type: StatType.danmaku, type: StatType.danmaku,
value: coinItem.stat.danmu, value: item.danmaku,
), ),
const Spacer(), const Spacer(),
Text( Text(
Utils.customStampStr( Utils.customStampStr(
timestamp: coinItem.pubdate, date: 'MM-DD'), timestamp: item.ctime, date: 'MM-DD'),
style: TextStyle( style: TextStyle(
fontSize: 11, fontSize: 11,
color: Theme.of(context).colorScheme.outline, color: Theme.of(context).colorScheme.outline,

View File

@@ -1,10 +1,11 @@
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/models/member/coin.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/data.dart';
import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
class MemberLikeController extends CommonListController< class MemberLikeController
List<MemberCoinsDataModel>?, MemberCoinsDataModel> { extends CommonListController<CoinLikeArcData, CoinLikeArcItem> {
final dynamic mid; final dynamic mid;
MemberLikeController({this.mid}); MemberLikeController({this.mid});
@@ -15,6 +16,11 @@ class MemberLikeController extends CommonListController<
} }
@override @override
Future<LoadingState<List<MemberCoinsDataModel>?>> customGetData() => List<CoinLikeArcItem>? getDataList(CoinLikeArcData response) {
MemberHttp.getRecentLikeVideo(mid: mid); return response.item;
}
@override
Future<LoadingState<CoinLikeArcData>> customGetData() =>
MemberHttp.likeArc(mid: mid, page: page);
} }

View File

@@ -2,7 +2,7 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/skeleton/video_card_v.dart'; import 'package:PiliPlus/common/skeleton/video_card_v.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/member/coin.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/member_coin/widgets/item.dart'; import 'package:PiliPlus/pages/member_coin/widgets/item.dart';
import 'package:PiliPlus/pages/member_like/controller.dart'; import 'package:PiliPlus/pages/member_like/controller.dart';
import 'package:PiliPlus/utils/grid.dart'; import 'package:PiliPlus/utils/grid.dart';
@@ -59,7 +59,7 @@ class _MemberLikePageState extends State<MemberLikePage> {
); );
} }
Widget _buildBody(LoadingState<List<MemberCoinsDataModel>?> loadingState) { Widget _buildBody(LoadingState<List<CoinLikeArcItem>?> loadingState) {
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverGrid.builder( Loading() => SliverGrid.builder(
gridDelegate: SliverGridDelegateWithExtentAndRatio( gridDelegate: SliverGridDelegateWithExtentAndRatio(
@@ -85,7 +85,10 @@ class _MemberLikePageState extends State<MemberLikePage> {
), ),
itemCount: response!.length, itemCount: response!.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return MemberCoinsItem(coinItem: response[index]); if (index == response.length - 1) {
_ctr.onLoadMore();
}
return MemberCoinLikeItem(item: response[index]);
}, },
) )
: HttpError(onReload: _ctr.onReload), : HttpError(onReload: _ctr.onReload),