mod: 收藏panel抽离
This commit is contained in:
@ -4,6 +4,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.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:get/get.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/common/constants.dart';
|
import 'package:pilipala/common/constants.dart';
|
||||||
import 'package:pilipala/common/widgets/http_error.dart';
|
import 'package:pilipala/common/widgets/http_error.dart';
|
||||||
import 'package:pilipala/pages/fav/index.dart';
|
import 'package:pilipala/pages/fav/index.dart';
|
||||||
@ -18,6 +19,7 @@ import 'package:pilipala/pages/video/detail/introduction/controller.dart';
|
|||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
|
import 'widgets/fav_panel.dart';
|
||||||
import 'widgets/season.dart';
|
import 'widgets/season.dart';
|
||||||
|
|
||||||
class VideoIntroPanel extends StatefulWidget {
|
class VideoIntroPanel extends StatefulWidget {
|
||||||
@ -102,6 +104,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
final FavController _favController = Get.put(FavController());
|
final FavController _favController = Get.put(FavController());
|
||||||
|
|
||||||
late VideoDetailController? videoDetailCtr;
|
late VideoDetailController? videoDetailCtr;
|
||||||
|
Box localCache = GStrorage.localCache;
|
||||||
|
late double sheetHeight;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -115,6 +120,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
Tween<double>(begin: 0.5, end: 1.5).animate(_manualController!);
|
Tween<double>(begin: 0.5, end: 1.5).animate(_manualController!);
|
||||||
videoDetailCtr =
|
videoDetailCtr =
|
||||||
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
|
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
|
||||||
|
sheetHeight = localCache.get('sheetHeight');
|
||||||
}
|
}
|
||||||
|
|
||||||
showFavBottomSheet() {
|
showFavBottomSheet() {
|
||||||
@ -122,109 +128,13 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
SmartDialog.showToast('账号未登录');
|
SmartDialog.showToast('账号未登录');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Get.bottomSheet(
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
Container(
|
builder: (context) {
|
||||||
height: 450,
|
return FavPanel(ctr: videoIntroController);
|
||||||
color: Theme.of(context).colorScheme.background,
|
},
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
AppBar(
|
|
||||||
toolbarHeight: 50,
|
|
||||||
automaticallyImplyLeading: false,
|
|
||||||
centerTitle: false,
|
|
||||||
elevation: 1,
|
|
||||||
title: Text(
|
|
||||||
'选择文件夹',
|
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => videoIntroController.actionFavVideo(),
|
|
||||||
child: const Text('完成'),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 6),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Material(
|
|
||||||
child: FutureBuilder(
|
|
||||||
future: videoIntroController.queryVideoInFolder(),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
|
||||||
Map data = snapshot.data as Map;
|
|
||||||
if (data['status']) {
|
|
||||||
return Obx(
|
|
||||||
() => ListView.builder(
|
|
||||||
itemCount: videoIntroController
|
|
||||||
.favFolderData.value.list!.length +
|
|
||||||
1,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == 0) {
|
|
||||||
return const SizedBox(height: 10);
|
|
||||||
} else {
|
|
||||||
return ListTile(
|
|
||||||
onTap: () => videoIntroController.onChoose(
|
|
||||||
videoIntroController.favFolderData.value
|
|
||||||
.list![index - 1].favState !=
|
|
||||||
1,
|
|
||||||
index - 1),
|
|
||||||
dense: true,
|
|
||||||
leading:
|
|
||||||
const Icon(Icons.folder_special_outlined),
|
|
||||||
minLeadingWidth: 0,
|
|
||||||
title: Text(videoIntroController.favFolderData
|
|
||||||
.value.list![index - 1].title!),
|
|
||||||
subtitle: Text(
|
|
||||||
'${videoIntroController.favFolderData.value.list![index - 1].mediaCount}个内容',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.outline,
|
|
||||||
fontSize: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.labelSmall!
|
|
||||||
.fontSize),
|
|
||||||
),
|
|
||||||
trailing: Transform.scale(
|
|
||||||
scale: 0.9,
|
|
||||||
child: Checkbox(
|
|
||||||
value: videoIntroController
|
|
||||||
.favFolderData
|
|
||||||
.value
|
|
||||||
.list![index - 1]
|
|
||||||
.favState ==
|
|
||||||
1,
|
|
||||||
onChanged: (bool? checkValue) =>
|
|
||||||
videoIntroController.onChoose(
|
|
||||||
checkValue!, index - 1),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return HttpError(
|
|
||||||
errMsg: data['msg'],
|
|
||||||
fn: () => setState(() {}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 骨架屏
|
|
||||||
return Text('请求中');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
persistent: false,
|
|
||||||
backgroundColor: Theme.of(context).bottomSheetTheme.backgroundColor,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +272,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
if (!widget.loadingStatus &&
|
if (!widget.loadingStatus &&
|
||||||
widget.videoDetail!.ugcSeason != null) ...[
|
widget.videoDetail!.ugcSeason != null) ...[
|
||||||
seasonPanel(widget.videoDetail!.ugcSeason!,
|
seasonPanel(widget.videoDetail!.ugcSeason!,
|
||||||
widget.videoDetail!.pages!.first.cid)
|
widget.videoDetail!.pages!.first.cid, sheetHeight)
|
||||||
],
|
],
|
||||||
Divider(
|
Divider(
|
||||||
height: 26,
|
height: 26,
|
||||||
|
123
lib/pages/video/detail/introduction/widgets/fav_panel.dart
Normal file
123
lib/pages/video/detail/introduction/widgets/fav_panel.dart
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:pilipala/common/widgets/http_error.dart';
|
||||||
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
|
class FavPanel extends StatefulWidget {
|
||||||
|
var ctr;
|
||||||
|
FavPanel({this.ctr});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FavPanel> createState() => _FavPanelState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FavPanelState extends State<FavPanel> {
|
||||||
|
Box localCache = GStrorage.localCache;
|
||||||
|
late double sheetHeight;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
sheetHeight = localCache.get('sheetHeight');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: sheetHeight,
|
||||||
|
color: Theme.of(context).colorScheme.background,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
AppBar(
|
||||||
|
toolbarHeight: 50,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
centerTitle: false,
|
||||||
|
elevation: 1,
|
||||||
|
title: Text(
|
||||||
|
'选择文件夹',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await widget.ctr!.actionFavVideo();
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
child: const Text('完成'),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Material(
|
||||||
|
child: FutureBuilder(
|
||||||
|
future: widget.ctr!.queryVideoInFolder(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
Map data = snapshot.data as Map;
|
||||||
|
if (data['status']) {
|
||||||
|
return Obx(
|
||||||
|
() => ListView.builder(
|
||||||
|
itemCount:
|
||||||
|
widget.ctr!.favFolderData.value.list!.length + 1,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index == 0) {
|
||||||
|
return const SizedBox(height: 10);
|
||||||
|
} else {
|
||||||
|
return ListTile(
|
||||||
|
onTap: () => widget.ctr!.onChoose(
|
||||||
|
widget.ctr!.favFolderData.value
|
||||||
|
.list![index - 1].favState !=
|
||||||
|
1,
|
||||||
|
index - 1),
|
||||||
|
dense: true,
|
||||||
|
leading:
|
||||||
|
const Icon(Icons.folder_special_outlined),
|
||||||
|
minLeadingWidth: 0,
|
||||||
|
title: Text(widget.ctr!.favFolderData.value
|
||||||
|
.list![index - 1].title!),
|
||||||
|
subtitle: Text(
|
||||||
|
'${widget.ctr!.favFolderData.value.list![index - 1].mediaCount}个内容',
|
||||||
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.outline,
|
||||||
|
fontSize: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.labelSmall!
|
||||||
|
.fontSize),
|
||||||
|
),
|
||||||
|
trailing: Transform.scale(
|
||||||
|
scale: 0.9,
|
||||||
|
child: Checkbox(
|
||||||
|
value: widget.ctr!.favFolderData.value
|
||||||
|
.list![index - 1].favState ==
|
||||||
|
1,
|
||||||
|
onChanged: (bool? checkValue) => widget.ctr!
|
||||||
|
.onChoose(checkValue!, index - 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return HttpError(
|
||||||
|
errMsg: data['msg'],
|
||||||
|
fn: () => setState(() {}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 骨架屏
|
||||||
|
return Text('请求中');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pilipala/models/video_detail_res.dart';
|
import 'package:pilipala/models/video_detail_res.dart';
|
||||||
|
|
||||||
Widget seasonPanel(UgcSeason ugcSeason, cid) {
|
Widget seasonPanel(UgcSeason ugcSeason, cid, sheetHeight) {
|
||||||
return Builder(builder: (context) {
|
return Builder(builder: (context) {
|
||||||
List<EpisodeItem> episodes = ugcSeason.sections!.first.episodes!;
|
List<EpisodeItem> episodes = ugcSeason.sections!.first.episodes!;
|
||||||
int currentIndex = episodes.indexWhere((e) => e.cid == cid);
|
int currentIndex = episodes.indexWhere((e) => e.cid == cid);
|
||||||
@ -20,7 +20,7 @@ Widget seasonPanel(UgcSeason ugcSeason, cid) {
|
|||||||
onTap: () => showBottomSheet(
|
onTap: () => showBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => Container(
|
builder: (_) => Container(
|
||||||
height: Get.size.height - Get.size.width * 9 / 16 - 45,
|
height: sheetHeight,
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.background,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
Reference in New Issue
Block a user