feat: 最近点赞的视频
This commit is contained in:
@ -8,6 +8,7 @@ import 'package:pilipala/http/video.dart';
|
||||
import 'package:pilipala/models/member/archive.dart';
|
||||
import 'package:pilipala/models/member/coin.dart';
|
||||
import 'package:pilipala/models/member/info.dart';
|
||||
import 'package:pilipala/models/member/like.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
@ -25,6 +26,7 @@ class MemberController extends GetxController {
|
||||
RxInt attribute = (-1).obs;
|
||||
RxString attributeText = '关注'.obs;
|
||||
RxList<MemberCoinsDataModel> recentCoinsList = <MemberCoinsDataModel>[].obs;
|
||||
RxList<MemberLikeDataModel> recentLikeList = <MemberLikeDataModel>[].obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
@ -208,6 +210,14 @@ class MemberController extends GetxController {
|
||||
return res;
|
||||
}
|
||||
|
||||
// 请求点赞视频
|
||||
Future getRecentLikeVideo() async {
|
||||
if (userInfo == null) return;
|
||||
var res = await MemberHttp.getRecentLikeVideo(mid: mid);
|
||||
recentLikeList.value = res['data'];
|
||||
return res;
|
||||
}
|
||||
|
||||
// 跳转查看动态
|
||||
void pushDynamicsPage() => Get.toNamed('/memberDynamics?mid=$mid');
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import 'package:pilipala/pages/member/index.dart';
|
||||
import 'package:pilipala/utils/utils.dart';
|
||||
|
||||
import 'widgets/conis.dart';
|
||||
import 'widgets/like.dart';
|
||||
import 'widgets/profile.dart';
|
||||
import 'widgets/seasons.dart';
|
||||
|
||||
@ -26,6 +27,7 @@ class _MemberPageState extends State<MemberPage>
|
||||
late Future _futureBuilderFuture;
|
||||
late Future _memberSeasonsFuture;
|
||||
late Future _memberCoinsFuture;
|
||||
late Future _memberLikeFuture;
|
||||
final ScrollController _extendNestCtr = ScrollController();
|
||||
final StreamController<bool> appbarStream = StreamController<bool>();
|
||||
late int mid;
|
||||
@ -39,6 +41,7 @@ class _MemberPageState extends State<MemberPage>
|
||||
_futureBuilderFuture = _memberController.getInfo();
|
||||
_memberSeasonsFuture = _memberController.getMemberSeasons();
|
||||
_memberCoinsFuture = _memberController.getRecentCoinVideo();
|
||||
_memberLikeFuture = _memberController.getRecentLikeVideo();
|
||||
_extendNestCtr.addListener(
|
||||
() {
|
||||
final double offset = _extendNestCtr.position.pixels;
|
||||
@ -162,6 +165,7 @@ class _MemberPageState extends State<MemberPage>
|
||||
trailing:
|
||||
const Icon(Icons.arrow_forward_outlined, size: 19),
|
||||
),
|
||||
const Divider(height: 1, thickness: 0.1),
|
||||
|
||||
/// 视频
|
||||
ListTile(
|
||||
@ -170,12 +174,10 @@ class _MemberPageState extends State<MemberPage>
|
||||
trailing:
|
||||
const Icon(Icons.arrow_forward_outlined, size: 19),
|
||||
),
|
||||
const Divider(height: 1, thickness: 0.1),
|
||||
|
||||
/// 专栏
|
||||
ListTile(
|
||||
onTap: () {},
|
||||
title: const Text('Ta的专栏'),
|
||||
),
|
||||
const ListTile(title: Text('Ta的专栏')),
|
||||
MediaQuery.removePadding(
|
||||
removeTop: true,
|
||||
removeBottom: true,
|
||||
@ -218,12 +220,7 @@ class _MemberPageState extends State<MemberPage>
|
||||
/// 最近投币
|
||||
Obx(
|
||||
() => _memberController.recentCoinsList.isNotEmpty
|
||||
? ListTile(
|
||||
onTap: () {},
|
||||
title: const Text('最近投币的视频'),
|
||||
// trailing: const Icon(Icons.arrow_forward_outlined,
|
||||
// size: 19),
|
||||
)
|
||||
? const ListTile(title: Text('最近投币的视频'))
|
||||
: const SizedBox(),
|
||||
),
|
||||
MediaQuery.removePadding(
|
||||
@ -257,13 +254,44 @@ class _MemberPageState extends State<MemberPage>
|
||||
),
|
||||
),
|
||||
),
|
||||
// 最近点赞
|
||||
// ListTile(
|
||||
// onTap: () {},
|
||||
// title: const Text('最近点赞的视频'),
|
||||
// trailing:
|
||||
// const Icon(Icons.arrow_forward_outlined, size: 19),
|
||||
// ),
|
||||
|
||||
/// 最近点赞
|
||||
Obx(
|
||||
() => _memberController.recentLikeList.isNotEmpty
|
||||
? const ListTile(title: Text('最近点赞的视频'))
|
||||
: const SizedBox(),
|
||||
),
|
||||
MediaQuery.removePadding(
|
||||
removeTop: true,
|
||||
removeBottom: true,
|
||||
context: context,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: StyleString.safeSpace,
|
||||
right: StyleString.safeSpace,
|
||||
),
|
||||
child: FutureBuilder(
|
||||
future: _memberLikeFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState ==
|
||||
ConnectionState.done) {
|
||||
if (snapshot.data == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
if (snapshot.data['status']) {
|
||||
Map data = snapshot.data as Map;
|
||||
return MemberLikePanel(data: data['data']);
|
||||
} else {
|
||||
// 请求错误
|
||||
return const SizedBox();
|
||||
}
|
||||
} else {
|
||||
return const SizedBox();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -4,8 +4,8 @@ import 'package:pilipala/models/member/coin.dart';
|
||||
import 'package:pilipala/pages/member_coin/widgets/item.dart';
|
||||
|
||||
class MemberCoinsPanel extends StatelessWidget {
|
||||
final List<MemberCoinsDataModel>? data;
|
||||
const MemberCoinsPanel({super.key, this.data});
|
||||
final List<MemberCoinsDataModel> data;
|
||||
const MemberCoinsPanel({super.key, required this.data});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -20,9 +20,9 @@ class MemberCoinsPanel extends StatelessWidget {
|
||||
),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: data!.length,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, i) {
|
||||
return MemberCoinsItem(coinItem: data![i]);
|
||||
return MemberCoinsItem(coinItem: data[i]);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
31
lib/pages/member/widgets/like.dart
Normal file
31
lib/pages/member/widgets/like.dart
Normal file
@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:pilipala/common/constants.dart';
|
||||
import 'package:pilipala/models/member/like.dart';
|
||||
import 'package:pilipala/pages/member_like/widgets/item.dart';
|
||||
|
||||
class MemberLikePanel extends StatelessWidget {
|
||||
final List<MemberLikeDataModel> data;
|
||||
const MemberLikePanel({super.key, required this.data});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, boxConstraints) {
|
||||
return GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2, // Use a fixed count for GridView
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
mainAxisSpacing: StyleString.safeSpace,
|
||||
childAspectRatio: 0.94,
|
||||
),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, i) {
|
||||
return MemberLikeItem(likeItem: data[i]);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
96
lib/pages/member_like/widgets/item.dart
Normal file
96
lib/pages/member_like/widgets/item.dart
Normal file
@ -0,0 +1,96 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/common/constants.dart';
|
||||
import 'package:pilipala/common/widgets/badge.dart';
|
||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||
import 'package:pilipala/common/widgets/stat/view.dart';
|
||||
import 'package:pilipala/http/search.dart';
|
||||
import 'package:pilipala/models/member/like.dart';
|
||||
import 'package:pilipala/utils/utils.dart';
|
||||
|
||||
class MemberLikeItem extends StatelessWidget {
|
||||
final MemberLikeDataModel likeItem;
|
||||
|
||||
const MemberLikeItem({
|
||||
Key? key,
|
||||
required this.likeItem,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String heroTag = Utils.makeHeroTag(likeItem.aid);
|
||||
return Card(
|
||||
elevation: 0,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
margin: EdgeInsets.zero,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
int cid =
|
||||
await SearchHttp.ab2c(aid: likeItem.aid, bvid: likeItem.bvid);
|
||||
Get.toNamed('/video?bvid=${likeItem.bvid}&cid=$cid',
|
||||
arguments: {'videoItem': likeItem, 'heroTag': heroTag});
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: StyleString.aspectRatio,
|
||||
child: LayoutBuilder(builder: (context, boxConstraints) {
|
||||
double maxWidth = boxConstraints.maxWidth;
|
||||
double maxHeight = boxConstraints.maxHeight;
|
||||
return Stack(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: likeItem.pic,
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
),
|
||||
if (likeItem.duration != null)
|
||||
PBadge(
|
||||
bottom: 6,
|
||||
right: 6,
|
||||
type: 'gray',
|
||||
text: Utils.timeFormat(likeItem.duration),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(5, 6, 0, 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
likeItem.title!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
StatView(
|
||||
view: likeItem.stat!.view,
|
||||
theme: 'gray',
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
Utils.CustomStamp_str(
|
||||
timestamp: likeItem.pubdate, date: 'MM-DD'),
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user