mod: 我的收藏

This commit is contained in:
guozhigq
2023-07-23 23:43:51 +08:00
parent dbfe85e781
commit bafda1f0bd
5 changed files with 153 additions and 48 deletions

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/common/widgets/http_error.dart';
import 'package:pilipala/pages/fav/index.dart';
import 'package:pilipala/pages/fav/widgets/item.dart';
class FavPage extends StatefulWidget {
const FavPage({super.key});
@ -18,7 +19,11 @@ class _FavPageState extends State<FavPage> {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: const Text('我的收藏'),
titleSpacing: 0,
title: Text(
'我的收藏',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: FutureBuilder(
future: _favController.queryFavFolder(),
@ -30,31 +35,9 @@ class _FavPageState extends State<FavPage> {
() => ListView.builder(
itemCount: _favController.favFolderData.value.list!.length,
itemBuilder: (context, index) {
return ListTile(
onTap: () => Get.toNamed(
'/favDetail',
arguments:
_favController.favFolderData.value.list![index],
parameters: {
'mediaId': _favController
.favFolderData.value.list![index].id
.toString(),
},
),
leading: const Icon(Icons.folder_special_outlined),
minLeadingWidth: 0,
title: Text(_favController
.favFolderData.value.list![index].title!),
subtitle: Text(
'${_favController.favFolderData.value.list![index].mediaCount}个内容',
style: TextStyle(
color: Theme.of(context).colorScheme.outline,
fontSize: Theme.of(context)
.textTheme
.labelSmall!
.fontSize),
),
);
return FavItem(
favFolderItem:
_favController.favFolderData.value.list![index]);
},
),
);

View 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/network_img_layer.dart';
import 'package:pilipala/utils/utils.dart';
class FavItem extends StatelessWidget {
var favFolderItem;
FavItem({super.key, required this.favFolderItem});
@override
Widget build(BuildContext context) {
String heroTag = Utils.makeHeroTag(favFolderItem.fid);
return InkWell(
onTap: () => Get.toNamed(
'/favDetail',
arguments: favFolderItem,
parameters: {
'heroTag': heroTag,
'mediaId': favFolderItem.id.toString(),
},
),
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 7, 12, 7),
child: LayoutBuilder(
builder: (context, boxConstraints) {
double width =
(boxConstraints.maxWidth - StyleString.cardSpace * 6) / 2;
return SizedBox(
height: width / StyleString.aspectRatio,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: StyleString.aspectRatio,
child: LayoutBuilder(
builder: (context, boxConstraints) {
double maxWidth = boxConstraints.maxWidth;
double maxHeight = boxConstraints.maxHeight;
double PR = MediaQuery.of(context).devicePixelRatio;
return Hero(
tag: heroTag,
child: NetworkImgLayer(
src: favFolderItem.cover + '@.webp',
width: maxWidth,
height: maxHeight,
),
);
},
),
),
VideoContent(favFolderItem: favFolderItem)
],
),
);
},
),
),
);
}
}
class VideoContent extends StatelessWidget {
final favFolderItem;
const VideoContent({super.key, required this.favFolderItem});
@override
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 2, 6, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
favFolderItem.title,
textAlign: TextAlign.start,
style: TextStyle(
fontSize: Theme.of(context).textTheme.titleSmall!.fontSize,
fontWeight: FontWeight.w500),
),
Text(
'${favFolderItem.mediaCount}个内容',
textAlign: TextAlign.start,
style: TextStyle(
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
color: Theme.of(context).colorScheme.outline,
),
),
],
),
),
);
}
}

View File

@ -4,30 +4,42 @@ import 'package:pilipala/http/user.dart';
import 'package:pilipala/http/video.dart';
import 'package:pilipala/models/user/fav_detail.dart';
import 'package:pilipala/models/user/fav_folder.dart';
import 'package:pilipala/utils/id_utils.dart';
class FavDetailController extends GetxController {
FavFolderItemData? item;
Rx<FavDetailData> favDetailData = FavDetailData().obs;
int? mediaId;
late String heroTag;
int currentPage = 1;
bool isLoadingMore = false;
RxMap favInfo = {}.obs;
RxList<FavDetailItemData> favList = [FavDetailItemData()].obs;
@override
void onInit() {
item = Get.arguments;
if (Get.parameters.keys.isNotEmpty) {
mediaId = int.parse(Get.parameters['mediaId']!);
heroTag = Get.parameters['heroTag']!;
}
super.onInit();
}
Future<dynamic> queryUserFavFolderDetail() async {
print('🐯🐯虎');
Future<dynamic> queryUserFavFolderDetail({type = 'init'}) async {
var res = await await UserHttp.userFavFolderDetail(
pn: 1,
ps: 15,
pn: currentPage,
ps: 20,
mediaId: mediaId!,
);
favDetailData.value = res['data'];
if (res['status']) {
favInfo.value = res['data'].info;
if (currentPage == 1 && type == 'init') {
favList.value = res['data'].medias;
} else if (type == 'onload') {
favList.addAll(res['data'].medias);
}
}
return res;
}
@ -49,4 +61,8 @@ class FavDetailController extends GetxController {
}
}
}
onLoad() {
queryUserFavFolderDetail(type: 'onload');
}
}

View File

@ -34,6 +34,14 @@ class _FavDetailPageState extends State<FavDetailPage> {
} else if (_controller.offset <= 160) {
titleStreamC.add(false);
}
if (_controller.position.pixels >=
_controller.position.maxScrollExtent - 200) {
if (!_favDetailController.isLoadingMore) {
_favDetailController.isLoadingMore = true;
_favDetailController.onLoad();
}
}
},
);
}
@ -109,9 +117,8 @@ class _FavDetailPageState extends State<FavDetailPage> {
// mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 180,
height: 110,
Hero(
tag: _favDetailController.heroTag,
child: NetworkImgLayer(
width: 180,
height: 110,
@ -156,7 +163,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
padding: const EdgeInsets.only(top: 15, bottom: 8, left: 14),
child: Obx(
() => Text(
'${_favDetailController.favDetailData.value.medias != null ? _favDetailController.favDetailData.value.medias!.length : '-'}条视频',
'${_favDetailController.favInfo['media_count'] ?? '-'}条视频',
style: TextStyle(
fontSize:
Theme.of(context).textTheme.labelMedium!.fontSize,
@ -184,12 +191,9 @@ class _FavDetailPageState extends State<FavDetailPage> {
() => SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return FavVideoCardH(
videoItem: _favDetailController
.favDetailData.value.medias![index],
videoItem: _favDetailController.favList[index],
);
},
childCount: _favDetailController
.favDetailData.value.medias!.length),
}, childCount: _favDetailController.favList.length),
),
);
}

View File

@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/models/user/fav_folder.dart';
import 'package:pilipala/pages/media/index.dart';
import 'package:pilipala/utils/utils.dart';
class MediaPage extends StatelessWidget {
const MediaPage({super.key});
@ -169,12 +170,14 @@ class FavFolderItem extends StatelessWidget {
int? index;
@override
Widget build(BuildContext context) {
String heroTag = Utils.makeHeroTag(item!.fid);
return Container(
margin: EdgeInsets.only(left: index == 0 ? 20 : 0, right: 14),
child: GestureDetector(
onTap: () => Get.toNamed('/favDetail', arguments: item, parameters: {
'mediaId': item!.id.toString(),
}),
onTap: () => Get.toNamed('/favDetail',
arguments: item,
parameters: {'mediaId': item!.id.toString(), 'heroTag': heroTag}),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
@ -199,10 +202,13 @@ class FavFolderItem extends StatelessWidget {
),
child: LayoutBuilder(
builder: (context, BoxConstraints box) {
return NetworkImgLayer(
src: item!.cover,
width: box.maxWidth,
height: box.maxHeight,
return Hero(
tag: heroTag,
child: NetworkImgLayer(
src: item!.cover,
width: box.maxWidth,
height: box.maxHeight,
),
);
},
),