opt: fav follow bottomSheet
This commit is contained in:
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:bottom_sheet/bottom_sheet.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||||
@ -47,9 +48,21 @@ class FollowItem extends StatelessWidget {
|
|||||||
height: 34,
|
height: 34,
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Get.bottomSheet(
|
await showFlexibleBottomSheet(
|
||||||
GroupPanel(mid: item.mid!),
|
bottomSheetColor: Colors.transparent,
|
||||||
isScrollControlled: true,
|
minHeight: 1,
|
||||||
|
initHeight: 1,
|
||||||
|
maxHeight: 1,
|
||||||
|
context: Get.context!,
|
||||||
|
builder: (BuildContext context,
|
||||||
|
ScrollController scrollController, double offset) {
|
||||||
|
return GroupPanel(
|
||||||
|
mid: item.mid!,
|
||||||
|
scrollController: scrollController,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
anchors: [1],
|
||||||
|
isSafeArea: true,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:bottom_sheet/bottom_sheet.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
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';
|
||||||
@ -517,9 +518,21 @@ class VideoIntroController extends GetxController {
|
|||||||
|
|
||||||
// 设置关注分组
|
// 设置关注分组
|
||||||
void setFollowGroup() {
|
void setFollowGroup() {
|
||||||
Get.bottomSheet(
|
showFlexibleBottomSheet(
|
||||||
GroupPanel(mid: videoDetail.value.owner!.mid!),
|
bottomSheetColor: Colors.transparent,
|
||||||
isScrollControlled: true,
|
minHeight: 0.6,
|
||||||
|
initHeight: 0.6,
|
||||||
|
maxHeight: 1,
|
||||||
|
context: Get.context!,
|
||||||
|
builder: (BuildContext context, ScrollController scrollController,
|
||||||
|
double offset) {
|
||||||
|
return GroupPanel(
|
||||||
|
mid: videoDetail.value.owner!.mid!,
|
||||||
|
scrollController: scrollController,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
anchors: [0.6, 1],
|
||||||
|
isSafeArea: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:bottom_sheet/bottom_sheet.dart';
|
||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
import 'package:expandable/expandable.dart';
|
import 'package:expandable/expandable.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -215,37 +218,35 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
if (!videoIntroController.hasFav.value) {
|
if (!videoIntroController.hasFav.value) {
|
||||||
videoIntroController.actionFavVideo(type: 'default');
|
videoIntroController.actionFavVideo(type: 'default');
|
||||||
} else {
|
} else {
|
||||||
showModalBottomSheet(
|
_showFavPanel();
|
||||||
context: context,
|
|
||||||
useRootNavigator: true,
|
|
||||||
isScrollControlled: true,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return FavPanel(ctr: videoIntroController);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showModalBottomSheet(
|
_showFavPanel();
|
||||||
context: context,
|
|
||||||
useRootNavigator: true,
|
|
||||||
isScrollControlled: true,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return FavPanel(ctr: videoIntroController);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (type != 'longPress') {
|
} else if (type != 'longPress') {
|
||||||
showModalBottomSheet(
|
_showFavPanel();
|
||||||
context: context,
|
|
||||||
useRootNavigator: true,
|
|
||||||
isScrollControlled: true,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return FavPanel(ctr: videoIntroController);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showFavPanel() {
|
||||||
|
showFlexibleBottomSheet(
|
||||||
|
bottomSheetColor: Colors.transparent,
|
||||||
|
minHeight: 0.6,
|
||||||
|
initHeight: 0.6,
|
||||||
|
maxHeight: 1,
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context, ScrollController scrollController,
|
||||||
|
double offset) {
|
||||||
|
return FavPanel(
|
||||||
|
ctr: videoIntroController,
|
||||||
|
scrollController: scrollController,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
anchors: [0.6, 1],
|
||||||
|
isSafeArea: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 视频介绍
|
// 视频介绍
|
||||||
showIntroDetail() {
|
showIntroDetail() {
|
||||||
feedBack();
|
feedBack();
|
||||||
|
|||||||
@ -6,8 +6,9 @@ import 'package:pilipala/utils/feed_back.dart';
|
|||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
class FavPanel extends StatefulWidget {
|
class FavPanel extends StatefulWidget {
|
||||||
const FavPanel({super.key, this.ctr});
|
const FavPanel({super.key, this.ctr, this.scrollController});
|
||||||
final dynamic ctr;
|
final dynamic ctr;
|
||||||
|
final ScrollController? scrollController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<FavPanel> createState() => _FavPanelState();
|
State<FavPanel> createState() => _FavPanelState();
|
||||||
@ -15,31 +16,39 @@ class FavPanel extends StatefulWidget {
|
|||||||
|
|
||||||
class _FavPanelState extends State<FavPanel> {
|
class _FavPanelState extends State<FavPanel> {
|
||||||
final Box<dynamic> localCache = GStrorage.localCache;
|
final Box<dynamic> localCache = GStrorage.localCache;
|
||||||
late double sheetHeight;
|
|
||||||
late Future _futureBuilderFuture;
|
late Future _futureBuilderFuture;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
sheetHeight = localCache.get('sheetHeight');
|
|
||||||
_futureBuilderFuture = widget.ctr!.queryVideoInFolder();
|
_futureBuilderFuture = widget.ctr!.queryVideoInFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
height: sheetHeight,
|
clipBehavior: Clip.hardEdge,
|
||||||
color: Theme.of(context).colorScheme.surface,
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(16),
|
||||||
|
topRight: Radius.circular(16),
|
||||||
|
),
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
AppBar(
|
AppBar(
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
leading: IconButton(
|
automaticallyImplyLeading: false,
|
||||||
onPressed: () => Get.back(),
|
leadingWidth: 0,
|
||||||
icon: const Icon(Icons.close_outlined)),
|
title: Text(
|
||||||
title:
|
'选择收藏夹',
|
||||||
Text('添加到收藏夹', style: Theme.of(context).textTheme.titleMedium),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium!
|
||||||
|
.copyWith(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Material(
|
child: Material(
|
||||||
@ -51,22 +60,22 @@ class _FavPanelState extends State<FavPanel> {
|
|||||||
if (data['status']) {
|
if (data['status']) {
|
||||||
return Obx(
|
return Obx(
|
||||||
() => ListView.builder(
|
() => ListView.builder(
|
||||||
|
controller: widget.scrollController,
|
||||||
itemCount:
|
itemCount:
|
||||||
widget.ctr!.favFolderData.value.list!.length,
|
widget.ctr!.favFolderData.value.list!.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
final item =
|
||||||
|
widget.ctr!.favFolderData.value.list![index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
onTap: () => widget.ctr!.onChoose(
|
onTap: () => widget.ctr!
|
||||||
widget.ctr!.favFolderData.value.list![index]
|
.onChoose(item.favState != 1, index),
|
||||||
.favState !=
|
|
||||||
1,
|
|
||||||
index),
|
|
||||||
dense: true,
|
dense: true,
|
||||||
leading: const Icon(Icons.folder_outlined),
|
leading: const Icon(Icons.folder_outlined),
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
title: Text(widget.ctr!.favFolderData.value
|
title: Text(widget.ctr!.favFolderData.value
|
||||||
.list![index].title!),
|
.list![index].title!),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'${widget.ctr!.favFolderData.value.list![index].mediaCount}个内容',
|
'${item.mediaCount}个内容 ',
|
||||||
),
|
),
|
||||||
trailing: Transform.scale(
|
trailing: Transform.scale(
|
||||||
scale: 0.9,
|
scale: 0.9,
|
||||||
@ -132,7 +141,7 @@ class _FavPanelState extends State<FavPanel> {
|
|||||||
backgroundColor:
|
backgroundColor:
|
||||||
Theme.of(context).colorScheme.primary, // 设置按钮背景色
|
Theme.of(context).colorScheme.primary, // 设置按钮背景色
|
||||||
),
|
),
|
||||||
child: const Text('完成'),
|
child: const Text('确认选择'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import 'package:pilipala/utils/storage.dart';
|
|||||||
|
|
||||||
class GroupPanel extends StatefulWidget {
|
class GroupPanel extends StatefulWidget {
|
||||||
final int? mid;
|
final int? mid;
|
||||||
const GroupPanel({super.key, this.mid});
|
final ScrollController scrollController;
|
||||||
|
const GroupPanel({super.key, this.mid, required this.scrollController});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<GroupPanel> createState() => _GroupPanelState();
|
State<GroupPanel> createState() => _GroupPanelState();
|
||||||
@ -18,7 +19,6 @@ class GroupPanel extends StatefulWidget {
|
|||||||
|
|
||||||
class _GroupPanelState extends State<GroupPanel> {
|
class _GroupPanelState extends State<GroupPanel> {
|
||||||
final Box<dynamic> localCache = GStrorage.localCache;
|
final Box<dynamic> localCache = GStrorage.localCache;
|
||||||
late double sheetHeight;
|
|
||||||
late Future _futureBuilderFuture;
|
late Future _futureBuilderFuture;
|
||||||
late List<MemberTagItemModel> tagsList;
|
late List<MemberTagItemModel> tagsList;
|
||||||
bool showDefault = true;
|
bool showDefault = true;
|
||||||
@ -26,7 +26,6 @@ class _GroupPanelState extends State<GroupPanel> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
sheetHeight = localCache.get('sheetHeight');
|
|
||||||
_futureBuilderFuture = MemberHttp.followUpTags();
|
_futureBuilderFuture = MemberHttp.followUpTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +55,14 @@ class _GroupPanelState extends State<GroupPanel> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
height: sheetHeight,
|
clipBehavior: Clip.hardEdge,
|
||||||
color: Theme.of(context).colorScheme.surface,
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(16),
|
||||||
|
topRight: Radius.circular(16),
|
||||||
|
),
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
AppBar(
|
AppBar(
|
||||||
@ -79,6 +84,7 @@ class _GroupPanelState extends State<GroupPanel> {
|
|||||||
if (data['status']) {
|
if (data['status']) {
|
||||||
tagsList = data['data'];
|
tagsList = data['data'];
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
|
controller: widget.scrollController,
|
||||||
itemCount: data['data'].length,
|
itemCount: data['data'].length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
|||||||
16
pubspec.lock
16
pubspec.lock
@ -113,6 +113,22 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
bottom_inset_observer:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bottom_inset_observer
|
||||||
|
sha256: cbfb01e0e07cc4922052701786d5e607765a6f54e1844f41061abf8744519a7d
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0"
|
||||||
|
bottom_sheet:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: bottom_sheet
|
||||||
|
sha256: efd28f52357d23e1c01eaeb45466b407f1e29318305bd6d10baf814fda18bd7e
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.4"
|
||||||
build:
|
build:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -146,6 +146,7 @@ dependencies:
|
|||||||
lottie: ^3.1.2
|
lottie: ^3.1.2
|
||||||
# 二维码
|
# 二维码
|
||||||
qr_flutter: ^4.1.0
|
qr_flutter: ^4.1.0
|
||||||
|
bottom_sheet: ^4.0.4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user