feat: 收藏夹
This commit is contained in:
@ -26,4 +26,8 @@ class Api {
|
|||||||
|
|
||||||
// 获取当前用户状态
|
// 获取当前用户状态
|
||||||
static const String userStatOwner = '/x/web-interface/nav/stat';
|
static const String userStatOwner = '/x/web-interface/nav/stat';
|
||||||
|
|
||||||
|
// 收藏夹
|
||||||
|
// https://api.bilibili.com/x/v3/fav/folder/created/list?pn=1&ps=10&up_mid=17340771
|
||||||
|
static const String userFavFolder = '/x/v3/fav/folder/created/list';
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:pilipala/http/api.dart';
|
import 'package:pilipala/http/api.dart';
|
||||||
import 'package:pilipala/http/init.dart';
|
import 'package:pilipala/http/init.dart';
|
||||||
|
import 'package:pilipala/models/user/fav_folder.dart';
|
||||||
import 'package:pilipala/models/user/info.dart';
|
import 'package:pilipala/models/user/info.dart';
|
||||||
import 'package:pilipala/models/user/stat.dart';
|
import 'package:pilipala/models/user/stat.dart';
|
||||||
|
|
||||||
@ -29,7 +30,26 @@ class UserHttp {
|
|||||||
UserStat data = UserStat.fromJson(res.data['data']);
|
UserStat data = UserStat.fromJson(res.data['data']);
|
||||||
return {'status': true, 'data': data};
|
return {'status': true, 'data': data};
|
||||||
} else {
|
} else {
|
||||||
return {'status': false};
|
return {'status': false, 'data': [], 'msg': res.data['message']};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收藏夹
|
||||||
|
static Future<dynamic> userfavFolder({
|
||||||
|
required int pn,
|
||||||
|
required int ps,
|
||||||
|
required int mid,
|
||||||
|
}) async {
|
||||||
|
var res = await Request().get(Api.userFavFolder, data: {
|
||||||
|
'pn': pn,
|
||||||
|
'ps': ps,
|
||||||
|
'up_mid': mid,
|
||||||
|
});
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
FavFolderData data = FavFolderData.fromJson(res.data['data']);
|
||||||
|
return {'status': true, 'data': data};
|
||||||
|
} else {
|
||||||
|
return {'status': false, 'data': [], 'msg': res.data['message']};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
108
lib/models/user/fav_folder.dart
Normal file
108
lib/models/user/fav_folder.dart
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
class FavFolderData {
|
||||||
|
FavFolderData({
|
||||||
|
this.count,
|
||||||
|
this.list,
|
||||||
|
this.hasMore,
|
||||||
|
});
|
||||||
|
|
||||||
|
int? count;
|
||||||
|
List<FavFolderItemData>? list;
|
||||||
|
bool? hasMore;
|
||||||
|
|
||||||
|
FavFolderData.fromJson(Map<String, dynamic> json) {
|
||||||
|
count = json['count'];
|
||||||
|
list = json['list'] != null
|
||||||
|
? json['list']
|
||||||
|
.map<FavFolderItemData>((e) => FavFolderItemData.fromJson(e))
|
||||||
|
.toList()
|
||||||
|
: [FavFolderItemData()];
|
||||||
|
hasMore = json['has_more'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FavFolderItemData {
|
||||||
|
FavFolderItemData({
|
||||||
|
this.id,
|
||||||
|
this.fid,
|
||||||
|
this.mid,
|
||||||
|
this.attr,
|
||||||
|
this.title,
|
||||||
|
this.cover,
|
||||||
|
this.upper,
|
||||||
|
this.coverType,
|
||||||
|
this.intro,
|
||||||
|
this.ctime,
|
||||||
|
this.mtime,
|
||||||
|
this.state,
|
||||||
|
this.favState,
|
||||||
|
this.mediaCount,
|
||||||
|
this.viewCount,
|
||||||
|
this.vt,
|
||||||
|
this.playSwitch,
|
||||||
|
this.type,
|
||||||
|
this.link,
|
||||||
|
this.bvid,
|
||||||
|
});
|
||||||
|
|
||||||
|
int? id;
|
||||||
|
int? fid;
|
||||||
|
int? mid;
|
||||||
|
int? attr;
|
||||||
|
String? title;
|
||||||
|
String? cover;
|
||||||
|
Upper? upper;
|
||||||
|
int? coverType;
|
||||||
|
String? intro;
|
||||||
|
int? ctime;
|
||||||
|
int? mtime;
|
||||||
|
int? state;
|
||||||
|
int? favState;
|
||||||
|
int? mediaCount;
|
||||||
|
int? viewCount;
|
||||||
|
int? vt;
|
||||||
|
int? playSwitch;
|
||||||
|
int? type;
|
||||||
|
String? link;
|
||||||
|
String? bvid;
|
||||||
|
|
||||||
|
FavFolderItemData.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
fid = json['fid'];
|
||||||
|
mid = json['mid'];
|
||||||
|
attr = json['attr'];
|
||||||
|
title = json['title'];
|
||||||
|
cover = json['cover'];
|
||||||
|
upper = Upper.fromJson(json['upper']);
|
||||||
|
coverType = json['cover_type'];
|
||||||
|
intro = json['intro'];
|
||||||
|
ctime = json['ctime'];
|
||||||
|
mtime = json['mtime'];
|
||||||
|
state = json['state'];
|
||||||
|
favState = json['fav_state'];
|
||||||
|
mediaCount = json['media_count'];
|
||||||
|
viewCount = json['view_count'];
|
||||||
|
vt = json['vt'];
|
||||||
|
playSwitch = json['play_switch'];
|
||||||
|
type = json['type'];
|
||||||
|
link = json['link'];
|
||||||
|
bvid = json['bvid'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Upper {
|
||||||
|
Upper({
|
||||||
|
this.mid,
|
||||||
|
this.name,
|
||||||
|
this.face,
|
||||||
|
});
|
||||||
|
|
||||||
|
int? mid;
|
||||||
|
String? name;
|
||||||
|
String? face;
|
||||||
|
|
||||||
|
Upper.fromJson(Map<String, dynamic> json) {
|
||||||
|
mid = json['mid'];
|
||||||
|
name = json['name'];
|
||||||
|
face = json['face'];
|
||||||
|
}
|
||||||
|
}
|
3
lib/pages/fav/controller.dart
Normal file
3
lib/pages/fav/controller.dart
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class FavController extends GetxController {}
|
4
lib/pages/fav/index.dart
Normal file
4
lib/pages/fav/index.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
library fav;
|
||||||
|
|
||||||
|
export './controller.dart';
|
||||||
|
export './view.dart';
|
20
lib/pages/fav/view.dart
Normal file
20
lib/pages/fav/view.dart
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FavPage extends StatefulWidget {
|
||||||
|
const FavPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FavPage> createState() => _FavPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FavPageState extends State<FavPage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: false,
|
||||||
|
title: Text('我的收藏'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@ import 'dart:io';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/pages/mine/view.dart';
|
||||||
|
|
||||||
class HomeAppBar extends StatelessWidget {
|
class HomeAppBar extends StatelessWidget {
|
||||||
const HomeAppBar({super.key});
|
const HomeAppBar({super.key});
|
||||||
@ -42,6 +44,12 @@ class HomeAppBar extends StatelessWidget {
|
|||||||
// onPressed: () {},
|
// onPressed: () {},
|
||||||
// icon: const Icon(CupertinoIcons.bell, size: 22),
|
// icon: const Icon(CupertinoIcons.bell, size: 22),
|
||||||
// ),
|
// ),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
Get.bottomSheet(const MinePage());
|
||||||
|
},
|
||||||
|
icon: const Icon(CupertinoIcons.person, size: 22),
|
||||||
|
),
|
||||||
const SizedBox(width: 10)
|
const SizedBox(width: 10)
|
||||||
],
|
],
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
@ -5,26 +5,26 @@ import 'package:hive/hive.dart';
|
|||||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||||
import 'package:pilipala/pages/home/view.dart';
|
import 'package:pilipala/pages/home/view.dart';
|
||||||
import 'package:pilipala/pages/hot/view.dart';
|
import 'package:pilipala/pages/hot/view.dart';
|
||||||
import 'package:pilipala/pages/mine/view.dart';
|
import 'package:pilipala/pages/media/index.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
class MainController extends GetxController {
|
class MainController extends GetxController {
|
||||||
List<Widget> pages = <Widget>[
|
List<Widget> pages = <Widget>[
|
||||||
const HomePage(),
|
const HomePage(),
|
||||||
const HotPage(),
|
const HotPage(),
|
||||||
const MinePage(),
|
const MediaPage(),
|
||||||
];
|
];
|
||||||
RxList navigationBars = [
|
RxList navigationBars = [
|
||||||
{
|
{
|
||||||
// 'icon': const Icon(Icons.home_outlined),
|
// 'icon': const Icon(Icons.home_outlined),
|
||||||
// 'selectedIcon': const Icon(Icons.home),
|
// 'selectedIcon': const Icon(Icons.home),
|
||||||
'icon': const Icon(
|
'icon': const Icon(
|
||||||
CupertinoIcons.house,
|
CupertinoIcons.square_favorites_alt,
|
||||||
size: 18,
|
size: 21,
|
||||||
),
|
),
|
||||||
'selectedIcon': const Icon(
|
'selectedIcon': const Icon(
|
||||||
CupertinoIcons.house_fill,
|
CupertinoIcons.square_favorites_alt_fill,
|
||||||
size: 18,
|
size: 21,
|
||||||
),
|
),
|
||||||
'label': "推荐",
|
'label': "推荐",
|
||||||
},
|
},
|
||||||
@ -41,46 +41,57 @@ class MainController extends GetxController {
|
|||||||
),
|
),
|
||||||
'label': "热门",
|
'label': "热门",
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// 'icon': const Icon(
|
||||||
|
// CupertinoIcons.person,
|
||||||
|
// size: 21,
|
||||||
|
// ),
|
||||||
|
// 'selectedIcon': const Icon(
|
||||||
|
// CupertinoIcons.person_fill,
|
||||||
|
// size: 21,
|
||||||
|
// ),
|
||||||
|
// 'label': "我的",
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
// 'icon': const Icon(Icons.person_outline),
|
// 'icon': const Icon(Icons.person_outline),
|
||||||
// 'selectedIcon': const Icon(Icons.person),
|
// 'selectedIcon': const Icon(Icons.person),
|
||||||
'icon': const Icon(
|
'icon': const Icon(
|
||||||
CupertinoIcons.person,
|
CupertinoIcons.tray_full,
|
||||||
size: 21,
|
size: 21,
|
||||||
),
|
),
|
||||||
'selectedIcon': const Icon(
|
'selectedIcon': const Icon(
|
||||||
CupertinoIcons.person_fill,
|
CupertinoIcons.tray_full_fill,
|
||||||
size: 21,
|
size: 21,
|
||||||
),
|
),
|
||||||
'label': "我的",
|
'label': "媒体库",
|
||||||
}
|
}
|
||||||
].obs;
|
].obs;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
readuUserFace();
|
// readuUserFace();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置头像
|
// 设置头像
|
||||||
readuUserFace() async {
|
// readuUserFace() async {
|
||||||
Box user = GStrorage.user;
|
// Box user = GStrorage.user;
|
||||||
if (user.get(UserBoxKey.userFace) != null) {
|
// if (user.get(UserBoxKey.userFace) != null) {
|
||||||
navigationBars.last['icon'] =
|
// navigationBars.last['icon'] =
|
||||||
navigationBars.last['selectedIcon'] = NetworkImgLayer(
|
// navigationBars.last['selectedIcon'] = NetworkImgLayer(
|
||||||
width: 25,
|
// width: 25,
|
||||||
height: 25,
|
// height: 25,
|
||||||
type: 'avatar',
|
// type: 'avatar',
|
||||||
src: user.get(UserBoxKey.userFace),
|
// src: user.get(UserBoxKey.userFace),
|
||||||
);
|
// );
|
||||||
navigationBars.last['label'] = '我';
|
// navigationBars.last['label'] = '我';
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 重置
|
// 重置
|
||||||
resetLast() {
|
// resetLast() {
|
||||||
navigationBars.last['icon'] = const Icon(Icons.person_outline);
|
// navigationBars.last['icon'] = const Icon(Icons.person_outline);
|
||||||
navigationBars.last['selectedIcon'] = const Icon(Icons.person);
|
// navigationBars.last['selectedIcon'] = const Icon(Icons.person);
|
||||||
navigationBars.last['label'] = '我的';
|
// navigationBars.last['label'] = '我的';
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
|
|||||||
late AnimationController? _animationController;
|
late AnimationController? _animationController;
|
||||||
late Animation<double>? _fadeAnimation;
|
late Animation<double>? _fadeAnimation;
|
||||||
late Animation<double>? _slideAnimation;
|
late Animation<double>? _slideAnimation;
|
||||||
int selectedIndex = 2;
|
int selectedIndex = 0;
|
||||||
int? _lastSelectTime; //上次点击时间
|
int? _lastSelectTime; //上次点击时间
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
41
lib/pages/media/controller.dart
Normal file
41
lib/pages/media/controller.dart
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/http/user.dart';
|
||||||
|
import 'package:pilipala/models/user/fav_folder.dart';
|
||||||
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
|
class MediaController extends GetxController {
|
||||||
|
Rx<FavFolderData> favFolderData = FavFolderData().obs;
|
||||||
|
List list = [
|
||||||
|
{
|
||||||
|
'icon': Icons.file_download_outlined,
|
||||||
|
'title': '离线缓存',
|
||||||
|
'onTap': () => Get.toNamed('/fav'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icon': Icons.history,
|
||||||
|
'title': '观看记录',
|
||||||
|
'onTap': () => Get.toNamed('/fav'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icon': Icons.star_border,
|
||||||
|
'title': '我的收藏',
|
||||||
|
'onTap': () => Get.toNamed('/fav'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'icon': Icons.watch_later_outlined,
|
||||||
|
'title': '稍后再看',
|
||||||
|
'onTap': () => Get.toNamed('/fav'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
Future<dynamic> queryFavFolder() async {
|
||||||
|
var res = await await UserHttp.userfavFolder(
|
||||||
|
pn: 1,
|
||||||
|
ps: 5,
|
||||||
|
mid: GStrorage.user.get(UserBoxKey.userMid),
|
||||||
|
);
|
||||||
|
favFolderData.value = res['data'];
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
4
lib/pages/media/index.dart
Normal file
4
lib/pages/media/index.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
library media;
|
||||||
|
|
||||||
|
export './controller.dart';
|
||||||
|
export './view.dart';
|
214
lib/pages/media/view.dart
Normal file
214
lib/pages/media/view.dart
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
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';
|
||||||
|
|
||||||
|
class MediaPage extends StatefulWidget {
|
||||||
|
const MediaPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MediaPage> createState() => _MediaPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MediaPageState extends State<MediaPage>
|
||||||
|
with AutomaticKeepAliveClientMixin {
|
||||||
|
final MediaController _mediaController = Get.put(MediaController());
|
||||||
|
Future? _futureBuilderFuture;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get wantKeepAlive => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_futureBuilderFuture = _mediaController.queryFavFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Color primary = Theme.of(context).colorScheme.primary;
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(toolbarHeight: 30),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
leading: null,
|
||||||
|
title: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 20),
|
||||||
|
child: Text(
|
||||||
|
'媒体库',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: Theme.of(context).textTheme.titleLarge!.fontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
for (var i in _mediaController.list) ...[
|
||||||
|
ListTile(
|
||||||
|
onTap: () => i['onTap'](),
|
||||||
|
leading: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 15),
|
||||||
|
child: Icon(
|
||||||
|
i['icon'],
|
||||||
|
color: primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
minLeadingWidth: 0,
|
||||||
|
title: Text(i['title']),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
favFolder()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget favFolder() {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Divider(
|
||||||
|
height: 35,
|
||||||
|
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
onTap: () {},
|
||||||
|
leading: null,
|
||||||
|
dense: true,
|
||||||
|
title: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: Obx(
|
||||||
|
() => Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '收藏夹 ',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize:
|
||||||
|
Theme.of(context).textTheme.titleMedium!.fontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (_mediaController.favFolderData.value.count != null)
|
||||||
|
TextSpan(
|
||||||
|
text: _mediaController.favFolderData.value.count
|
||||||
|
.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize:
|
||||||
|
Theme.of(context).textTheme.titleSmall!.fontSize,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 10),
|
||||||
|
child: Text(
|
||||||
|
'查看全部',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||||
|
color: Theme.of(context).colorScheme.outline),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// const SizedBox(height: 10),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 170,
|
||||||
|
child: ListView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
children: [
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
FutureBuilder(
|
||||||
|
future: _futureBuilderFuture,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
Map data = snapshot.data;
|
||||||
|
if (data['status']) {
|
||||||
|
return Obx(() => Row(
|
||||||
|
children: [
|
||||||
|
if (_mediaController.favFolderData.value.list !=
|
||||||
|
null) ...[
|
||||||
|
for (FavFolderItemData i in _mediaController
|
||||||
|
.favFolderData.value.list!) ...[
|
||||||
|
FavFolderItem(item: i),
|
||||||
|
const SizedBox(width: 14)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return SizedBox(
|
||||||
|
height: 160,
|
||||||
|
child: Center(child: Text(data['msg'])),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 骨架屏
|
||||||
|
return SizedBox();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
// for (var i in [1, 2, 3]) ...[const FavFolderItem()],
|
||||||
|
const SizedBox(width: 10)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FavFolderItem extends StatelessWidget {
|
||||||
|
FavFolderItem({super.key, this.item});
|
||||||
|
FavFolderItemData? item;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Container(
|
||||||
|
width: 110 * 16 / 9,
|
||||||
|
height: 110,
|
||||||
|
margin: const EdgeInsets.only(bottom: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(14),
|
||||||
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
|
offset: const Offset(4, -12), // 阴影与容器的距离
|
||||||
|
blurRadius: 0.0, // 高斯的标准偏差与盒子的形状卷积。
|
||||||
|
spreadRadius: 0.0, // 在应用模糊之前,框应该膨胀的量。
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, BoxConstraints box) {
|
||||||
|
return NetworkImgLayer(
|
||||||
|
src: item!.cover,
|
||||||
|
width: box.maxWidth,
|
||||||
|
height: box.maxHeight,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
' ${item!.title}',
|
||||||
|
overflow: TextOverflow.fade,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
' 共${item!.mediaCount}条视频',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelSmall!
|
||||||
|
.copyWith(color: Theme.of(context).colorScheme.outline),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ class MineController extends GetxController {
|
|||||||
user.put(UserBoxKey.userMid, res['data'].mid);
|
user.put(UserBoxKey.userMid, res['data'].mid);
|
||||||
user.put(UserBoxKey.userLogin, true);
|
user.put(UserBoxKey.userLogin, true);
|
||||||
userLogin.value = true;
|
userLogin.value = true;
|
||||||
Get.find<MainController>().readuUserFace();
|
// Get.find<MainController>().readuUserFace();
|
||||||
} else {
|
} else {
|
||||||
resetUserInfo();
|
resetUserInfo();
|
||||||
}
|
}
|
||||||
@ -64,6 +64,6 @@ class MineController extends GetxController {
|
|||||||
await user.delete(UserBoxKey.userMid);
|
await user.delete(UserBoxKey.userMid);
|
||||||
await user.delete(UserBoxKey.userLogin);
|
await user.delete(UserBoxKey.userLogin);
|
||||||
userLogin.value = false;
|
userLogin.value = false;
|
||||||
Get.find<MainController>().resetLast();
|
// Get.find<MainController>().resetLast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,11 @@ class _MinePageState extends State<MinePage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
scrolledUnderElevation: 0,
|
||||||
|
elevation: 0,
|
||||||
|
toolbarHeight: kTextTabBarHeight + 20,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
title: null,
|
title: null,
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
@ -54,6 +59,7 @@ class _MinePageState extends State<MinePage> {
|
|||||||
height: constraint.maxHeight,
|
height: constraint.maxHeight,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: _mineController.queryUserInfo(),
|
future: _mineController.queryUserInfo(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
@ -69,45 +75,6 @@ class _MinePageState extends State<MinePage> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 12, right: 12),
|
|
||||||
child: LayoutBuilder(
|
|
||||||
builder: (context, constraints) {
|
|
||||||
return SizedBox(
|
|
||||||
height: constraints.maxWidth / 4 * 0.8,
|
|
||||||
child: GridView.count(
|
|
||||||
primary: false,
|
|
||||||
padding: const EdgeInsets.all(0),
|
|
||||||
crossAxisCount: 4,
|
|
||||||
childAspectRatio: 1.25,
|
|
||||||
children: <Widget>[
|
|
||||||
ActionItem(
|
|
||||||
icon:
|
|
||||||
const Icon(CupertinoIcons.cloud_download),
|
|
||||||
onTap: () => {},
|
|
||||||
text: '离线缓存',
|
|
||||||
),
|
|
||||||
ActionItem(
|
|
||||||
icon: const Icon(CupertinoIcons.time),
|
|
||||||
onTap: () => {},
|
|
||||||
text: '历史记录',
|
|
||||||
),
|
|
||||||
ActionItem(
|
|
||||||
icon: const Icon(CupertinoIcons.star),
|
|
||||||
onTap: () => {},
|
|
||||||
text: '我的收藏',
|
|
||||||
),
|
|
||||||
ActionItem(
|
|
||||||
icon: const Icon(CupertinoIcons.film),
|
|
||||||
onTap: () => {},
|
|
||||||
text: '稍后再看',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/pages/fav/index.dart';
|
||||||
import 'package:pilipala/pages/home/index.dart';
|
import 'package:pilipala/pages/home/index.dart';
|
||||||
import 'package:pilipala/pages/hot/index.dart';
|
import 'package:pilipala/pages/hot/index.dart';
|
||||||
import 'package:pilipala/pages/preview/index.dart';
|
import 'package:pilipala/pages/preview/index.dart';
|
||||||
import 'package:pilipala/pages/video/detail/index.dart';
|
import 'package:pilipala/pages/video/detail/index.dart';
|
||||||
import 'package:pilipala/pages/webview/index.dart';
|
import 'package:pilipala/pages/webview/index.dart';
|
||||||
import 'package:pilipala/pages/setting/index.dart';
|
import 'package:pilipala/pages/setting/index.dart';
|
||||||
|
import 'package:pilipala/pages/media/index.dart';
|
||||||
|
|
||||||
class Routes {
|
class Routes {
|
||||||
static final List<GetPage> getPages = [
|
static final List<GetPage> getPages = [
|
||||||
@ -20,5 +22,9 @@ class Routes {
|
|||||||
GetPage(name: '/webview', page: () => const WebviewPage()),
|
GetPage(name: '/webview', page: () => const WebviewPage()),
|
||||||
// 设置
|
// 设置
|
||||||
GetPage(name: '/setting', page: () => const SettingPage()),
|
GetPage(name: '/setting', page: () => const SettingPage()),
|
||||||
|
//
|
||||||
|
GetPage(name: '/media', page: () => const MediaPage()),
|
||||||
|
//
|
||||||
|
GetPage(name: '/fav', page: () => const FavPage()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user