opt: pages

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-02-21 18:40:39 +08:00
parent 4c56fcd6a8
commit f94cb2a4b5
21 changed files with 728 additions and 748 deletions

View File

@@ -275,174 +275,168 @@ class _ListSheetContentState extends State<ListSheetContent>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ColoredBox( return Column(
color: Theme.of(context).colorScheme.surface, children: [
child: Column( Container(
children: [ height: 45,
Container( padding: EdgeInsets.symmetric(
height: 45, horizontal: widget.showTitle != false ? 14 : 6),
padding: EdgeInsets.symmetric( child: Row(
horizontal: widget.showTitle != false ? 14 : 6), children: [
child: Row( if (widget.showTitle != false)
children: [ Text(
if (widget.showTitle != false) '合集(${_isList ? widget.season.epCount : episodes?.length ?? ''})',
Text( style: Theme.of(context).textTheme.titleMedium,
'合集(${_isList ? widget.season.epCount : episodes?.length ?? ''})',
style: Theme.of(context).textTheme.titleMedium,
),
StreamBuilder(
stream: _favStream?.stream,
builder: (context, snapshot) => snapshot.hasData
? mediumButton(
tooltip: _seasonFav == 1 ? '取消订阅' : '订阅',
icon: _seasonFav == 1
? Icons.notifications_off_outlined
: Icons.notifications_active_outlined,
onPressed: () async {
dynamic result = await VideoHttp.seasonFav(
isFav: _seasonFav == 1,
seasonId: widget.season.id,
);
if (result['status']) {
SmartDialog.showToast(
'${_seasonFav == 1 ? '取消' : ''}订阅成功');
_seasonFav = _seasonFav == 1 ? 0 : 1;
_favStream?.add(_seasonFav);
} else {
SmartDialog.showToast(result['msg']);
}
},
)
: const SizedBox.shrink(),
), ),
mediumButton( StreamBuilder(
tooltip: '跳至顶部', stream: _favStream?.stream,
icon: Icons.vertical_align_top, builder: (context, snapshot) => snapshot.hasData
onPressed: () { ? mediumButton(
try { tooltip: _seasonFav == 1 ? '取消订阅' : '订阅',
itemScrollController[_ctr?.index ?? 0].scrollTo( icon: _seasonFav == 1
index: !reverse[_ctr?.index ?? 0] ? Icons.notifications_off_outlined
? 0 : Icons.notifications_active_outlined,
: _isList onPressed: () async {
? widget.season.sections[_ctr?.index].episodes dynamic result = await VideoHttp.seasonFav(
.length - isFav: _seasonFav == 1,
1 seasonId: widget.season.id,
: episodes.length - 1, );
duration: const Duration(milliseconds: 200), if (result['status']) {
); SmartDialog.showToast(
} catch (_) {} '${_seasonFav == 1 ? '取消' : ''}订阅成功');
}, _seasonFav = _seasonFav == 1 ? 0 : 1;
), _favStream?.add(_seasonFav);
mediumButton( } else {
tooltip: '跳至底部', SmartDialog.showToast(result['msg']);
icon: Icons.vertical_align_bottom, }
onPressed: () { },
try { )
itemScrollController[_ctr?.index ?? 0].scrollTo( : const SizedBox.shrink(),
index: !reverse[_ctr?.index ?? 0] ),
? _isList mediumButton(
? widget.season.sections[_ctr?.index].episodes tooltip: '跳至顶部',
.length - icon: Icons.vertical_align_top,
1 onPressed: () {
: episodes.length - 1 try {
: 0, itemScrollController[_ctr?.index ?? 0].scrollTo(
duration: const Duration(milliseconds: 200), index: !reverse[_ctr?.index ?? 0]
); ? 0
} catch (_) {} : _isList
}, ? widget.season.sections[_ctr?.index].episodes
), .length -
mediumButton( 1
tooltip: '跳至当前', : episodes.length - 1,
icon: Icons.my_location, duration: const Duration(milliseconds: 200),
onPressed: () async { );
if (_ctr != null && _ctr?.index != (_index)) { } catch (_) {}
_ctr?.animateTo(_index); },
await Future.delayed(const Duration(milliseconds: 225)); ),
} mediumButton(
try { tooltip: '跳至底部',
itemScrollController[_ctr?.index ?? 0].scrollTo( icon: Icons.vertical_align_bottom,
index: currentIndex, onPressed: () {
duration: const Duration(milliseconds: 200), try {
); itemScrollController[_ctr?.index ?? 0].scrollTo(
} catch (_) {} index: !reverse[_ctr?.index ?? 0]
}, ? _isList
), ? widget.season.sections[_ctr?.index].episodes
if (widget.isSupportReverse == true) .length -
if (!_isList) 1
_reverseButton : episodes.length - 1
else : 0,
StreamBuilder( duration: const Duration(milliseconds: 200),
stream: _indexStream?.stream, );
initialData: _index, } catch (_) {}
builder: (context, snapshot) { },
return snapshot.data == _index ),
? _reverseButton mediumButton(
: const SizedBox.shrink(); tooltip: '跳至当前',
}, icon: Icons.my_location,
), onPressed: () async {
const Spacer(), if (_ctr != null && _ctr?.index != (_index)) {
StreamBuilder( _ctr?.animateTo(_index);
stream: _indexStream?.stream, await Future.delayed(const Duration(milliseconds: 225));
initialData: _index, }
builder: (context, snapshot) => mediumButton( try {
tooltip: reverse[snapshot.data] ? '顺序' : '倒序', itemScrollController[_ctr?.index ?? 0].scrollTo(
icon: !reverse[snapshot.data] index: currentIndex,
? MdiIcons.sortNumericAscending duration: const Duration(milliseconds: 200),
: MdiIcons.sortNumericDescending, );
onPressed: () { } catch (_) {}
setState(() { },
reverse[_ctr?.index ?? 0] = !reverse[_ctr?.index ?? 0]; ),
}); if (widget.isSupportReverse == true)
if (!_isList)
_reverseButton
else
StreamBuilder(
stream: _indexStream?.stream,
initialData: _index,
builder: (context, snapshot) {
return snapshot.data == _index
? _reverseButton
: const SizedBox.shrink();
}, },
), ),
const Spacer(),
StreamBuilder(
stream: _indexStream?.stream,
initialData: _index,
builder: (context, snapshot) => mediumButton(
tooltip: reverse[snapshot.data] ? '顺序' : '倒序',
icon: !reverse[snapshot.data]
? MdiIcons.sortNumericAscending
: MdiIcons.sortNumericDescending,
onPressed: () {
setState(() {
reverse[_ctr?.index ?? 0] = !reverse[_ctr?.index ?? 0];
});
},
), ),
if (widget.onClose != null)
mediumButton(
tooltip: '关闭',
icon: Icons.close,
onPressed: widget.onClose,
),
],
),
),
Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
if (_isList)
Material(
color: Theme.of(context).colorScheme.surface,
child: TabBar(
controller: _ctr,
padding: const EdgeInsets.only(right: 60),
isScrollable: true,
tabs: (widget.season.sections as List)
.map((item) => Tab(text: item.title))
.toList(),
dividerHeight: 1,
dividerColor: Theme.of(context).dividerColor.withOpacity(0.1),
), ),
), if (widget.onClose != null)
Expanded( mediumButton(
child: _isList tooltip: '关闭',
? Material( icon: Icons.close,
color: Theme.of(context).colorScheme.surface, onPressed: widget.onClose,
child: TabBarView( ),
controller: _ctr, ],
children: List.generate(
widget.season.sections.length,
(index) => _buildBody(
index, widget.season.sections[index].episodes),
),
),
)
: Material(
color: Theme.of(context).colorScheme.surface,
child: _buildBody(null, episodes),
),
), ),
], ),
), Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
if (_isList)
TabBar(
controller: _ctr,
padding: const EdgeInsets.only(right: 60),
isScrollable: true,
tabs: (widget.season.sections as List)
.map((item) => Tab(text: item.title))
.toList(),
dividerHeight: 1,
dividerColor: Theme.of(context).dividerColor.withOpacity(0.1),
),
Expanded(
child: _isList
? Material(
color: Colors.transparent,
child: TabBarView(
controller: _ctr,
children: List.generate(
widget.season.sections.length,
(index) => _buildBody(
index, widget.season.sections[index].episodes),
),
),
)
: Material(
color: Colors.transparent,
child: _buildBody(null, episodes),
),
),
],
); );
} }

View File

@@ -42,133 +42,135 @@ class VideoCardH extends StatelessWidget {
try { try {
type = videoItem.type; type = videoItem.type;
} catch (_) {} } catch (_) {}
return Stack(children: [ return Stack(
Semantics( children: [
label: Utils.videoItemSemantics(videoItem), Semantics(
excludeSemantics: true, label: Utils.videoItemSemantics(videoItem),
// customSemanticsActions: <CustomSemanticsAction, void Function()>{ excludeSemantics: true,
// for (var item in actions) // customSemanticsActions: <CustomSemanticsAction, void Function()>{
// CustomSemanticsAction( // for (var item in actions)
// label: item.title.isEmpty ? 'label' : item.title): item.onTap!, // CustomSemanticsAction(
// }, // label: item.title.isEmpty ? 'label' : item.title): item.onTap!,
child: InkWell( // },
onLongPress: () { child: InkWell(
if (onLongPress != null) { onLongPress: () {
onLongPress!(); if (onLongPress != null) {
} else { onLongPress!();
imageSaveDialog( } else {
context: context, imageSaveDialog(
title: videoItem.title is String context: context,
? videoItem.title title: videoItem.title is String
: videoItem.title is List ? videoItem.title
? (videoItem.title as List) : videoItem.title is List
.map((item) => item['text']) ? (videoItem.title as List)
.join() .map((item) => item['text'])
: '', .join()
cover: videoItem.pic, : '',
); cover: videoItem.pic,
} );
}, }
onTap: () async { },
if (onTap != null) { onTap: () async {
onTap?.call(); if (onTap != null) {
return; onTap?.call();
}
if (type == 'ketang') {
SmartDialog.showToast('课堂视频暂不支持播放');
return;
}
if (videoItem is HotVideoItemModel &&
videoItem.redirectUrl?.isNotEmpty == true) {
if (Utils.viewPgcFromUri(videoItem.redirectUrl!)) {
return; return;
} }
} if (type == 'ketang') {
try { SmartDialog.showToast('课堂视频暂不支持播放');
final int cid = return;
videoItem.cid ?? await SearchHttp.ab2c(aid: aid, bvid: bvid); }
Get.toNamed( if (videoItem is HotVideoItemModel &&
'/video?bvid=$bvid&cid=$cid', videoItem.redirectUrl?.isNotEmpty == true) {
arguments: { if (Utils.viewPgcFromUri(videoItem.redirectUrl!)) {
'videoItem': videoItem, return;
'heroTag': Utils.makeHeroTag(aid) }
}, }
); try {
} catch (err) { final int cid = videoItem.cid ??
SmartDialog.showToast(err.toString()); await SearchHttp.ab2c(aid: aid, bvid: bvid);
} Get.toNamed(
}, '/video?bvid=$bvid&cid=$cid',
child: Padding( arguments: {
padding: const EdgeInsets.symmetric( 'videoItem': videoItem,
horizontal: StyleString.safeSpace, 'heroTag': Utils.makeHeroTag(aid)
vertical: 5, },
), );
child: Row( } catch (err) {
mainAxisAlignment: MainAxisAlignment.start, SmartDialog.showToast(err.toString());
crossAxisAlignment: CrossAxisAlignment.start, }
children: <Widget>[ },
AspectRatio( child: Padding(
aspectRatio: StyleString.aspectRatio, padding: const EdgeInsets.symmetric(
child: LayoutBuilder( horizontal: StyleString.safeSpace,
builder: vertical: 5,
(BuildContext context, BoxConstraints boxConstraints) { ),
final double maxWidth = boxConstraints.maxWidth; child: Row(
final double maxHeight = boxConstraints.maxHeight; mainAxisAlignment: MainAxisAlignment.start,
return Stack( crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
NetworkImgLayer( AspectRatio(
src: videoItem.pic as String, aspectRatio: StyleString.aspectRatio,
width: maxWidth, child: LayoutBuilder(
height: maxHeight, builder: (BuildContext context,
), BoxConstraints boxConstraints) {
if (videoItem is HotVideoItemModel && final double maxWidth = boxConstraints.maxWidth;
videoItem.pgcLabel?.isNotEmpty == true) final double maxHeight = boxConstraints.maxHeight;
PBadge( return Stack(
text: videoItem.pgcLabel, children: [
top: 6.0, NetworkImgLayer(
right: 6.0, src: videoItem.pic as String,
width: maxWidth,
height: maxHeight,
), ),
if (videoItem.duration != 0) if (videoItem is HotVideoItemModel &&
PBadge( videoItem.pgcLabel?.isNotEmpty == true)
text: Utils.timeFormat(videoItem.duration!), PBadge(
right: 6.0, text: videoItem.pgcLabel,
bottom: 6.0, top: 6.0,
type: 'gray', right: 6.0,
), ),
if (type != 'video') if (videoItem.duration != 0)
PBadge( PBadge(
text: type, text: Utils.timeFormat(videoItem.duration!),
left: 6.0, right: 6.0,
bottom: 6.0, bottom: 6.0,
type: 'primary', type: 'gray',
), ),
// if (videoItem.rcmdReason != null && if (type != 'video')
// videoItem.rcmdReason.content != '') PBadge(
// pBadge(videoItem.rcmdReason.content, context, text: type,
// 6.0, 6.0, null, null), left: 6.0,
], bottom: 6.0,
); type: 'primary',
}, ),
// if (videoItem.rcmdReason != null &&
// videoItem.rcmdReason.content != '')
// pBadge(videoItem.rcmdReason.content, context,
// 6.0, 6.0, null, null),
],
);
},
),
), ),
), const SizedBox(width: 10),
const SizedBox(width: 10), videoContent(context),
videoContent(context), ],
], ),
), ),
), ),
), ),
), if (source == 'normal')
if (source == 'normal') Positioned(
Positioned( bottom: 0,
bottom: 0, right: 12,
right: 12, child: VideoPopupMenu(
child: VideoPopupMenu( size: 29,
size: 29, iconSize: 17,
iconSize: 17, videoItem: videoItem,
videoItem: videoItem, ),
), ),
), ],
]); );
} }
Widget videoContent(context) { Widget videoContent(context) {

View File

@@ -53,7 +53,7 @@ void main() async {
], ],
); );
} }
if (GStorage.badCertificateCallback) { if (BuildConfig.isDebug || GStorage.badCertificateCallback) {
HttpOverrides.global = _CustomHttpOverrides(); HttpOverrides.global = _CustomHttpOverrides();
} }
await setupServiceLocator(); await setupServiceLocator();

View File

@@ -22,10 +22,8 @@ class IntroDetail extends StatelessWidget {
fontSize: 12, fontSize: 12,
color: Theme.of(context).colorScheme.onSurface, color: Theme.of(context).colorScheme.onSurface,
); );
return Container( return Padding(
color: Theme.of(context).colorScheme.surface,
padding: const EdgeInsets.only(left: 14, right: 14), padding: const EdgeInsets.only(left: 14, right: 14),
// height: Utils.getSheetHeight(context),
child: Column( child: Column(
children: [ children: [
Container( Container(

View File

@@ -329,7 +329,7 @@ abstract class ReplyController extends CommonController {
dynamic mid, dynamic mid,
}) async { }) async {
// biliSendCommAntifraud // biliSendCommAntifraud
if (_biliSendCommAntifraud && Platform.isAndroid) { if (Platform.isAndroid && _biliSendCommAntifraud) {
try { try {
List<Cookie> cookies = await Request.cookieManager.cookieJar List<Cookie> cookies = await Request.cookieManager.cookieJar
.loadForRequest(Uri.parse(HttpString.apiBaseUrl)); .loadForRequest(Uri.parse(HttpString.apiBaseUrl));

View File

@@ -179,6 +179,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
ScaffoldState? scaffoldState = Scaffold.maybeOf(context); ScaffoldState? scaffoldState = Scaffold.maybeOf(context);
if (scaffoldState != null) { if (scaffoldState != null) {
scaffoldState.showBottomSheet( scaffoldState.showBottomSheet(
backgroundColor: Colors.transparent,
(context) => MediaQuery.removePadding( (context) => MediaQuery.removePadding(
context: context, context: context,
removeLeft: true, removeLeft: true,

View File

@@ -168,6 +168,7 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
ScaffoldState? scaffoldState = Scaffold.maybeOf(context); ScaffoldState? scaffoldState = Scaffold.maybeOf(context);
if (scaffoldState != null) { if (scaffoldState != null) {
scaffoldState.showBottomSheet( scaffoldState.showBottomSheet(
backgroundColor: Colors.transparent,
(context) => MediaQuery.removePadding( (context) => MediaQuery.removePadding(
context: context, context: context,
removeLeft: true, removeLeft: true,

View File

@@ -120,6 +120,7 @@ class MemberController extends GetxController {
await Get.bottomSheet( await Get.bottomSheet(
GroupPanel(mid: mid), GroupPanel(mid: mid),
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Theme.of(context).colorScheme.surface,
); );
Get.back(); Get.back();
}, },

View File

@@ -133,6 +133,7 @@ class _PlaySpeedPageState extends State<PlaySpeedPage> {
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
backgroundColor: Theme.of(context).colorScheme.surface,
builder: (context) { builder: (context) {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

View File

@@ -298,9 +298,10 @@ class VideoDetailController extends GetxController
} }
// 稍后再看面板展开 // 稍后再看面板展开
showMediaListPanel() { showMediaListPanel(context) {
if (mediaList.isNotEmpty) { if (mediaList.isNotEmpty) {
childKey.currentState?.showBottomSheet( childKey.currentState?.showBottomSheet(
backgroundColor: Theme.of(context).colorScheme.surface,
(context) => MediaListPanel( (context) => MediaListPanel(
mediaList: mediaList, mediaList: mediaList,
changeMediaList: (bvid, cid, aid, cover) { changeMediaList: (bvid, cid, aid, cover) {
@@ -1235,6 +1236,7 @@ class VideoDetailController extends GetxController
childKey.currentState?.showBottomSheet( childKey.currentState?.showBottomSheet(
enableDrag: false, enableDrag: false,
(context) => _postPanel(), (context) => _postPanel(),
backgroundColor: Colors.transparent,
); );
} }
} }

View File

@@ -28,7 +28,6 @@ import 'package:share_plus/share_plus.dart';
import '../../../../http/search.dart'; import '../../../../http/search.dart';
import '../../../../models/model_hot_video_item.dart'; import '../../../../models/model_hot_video_item.dart';
import '../related/index.dart'; import '../related/index.dart';
import 'widgets/group_panel.dart';
class VideoIntroController extends GetxController class VideoIntroController extends GetxController
with GetTickerProviderStateMixin { with GetTickerProviderStateMixin {
@@ -852,17 +851,6 @@ class VideoIntroController extends GetxController
return true; return true;
} }
// 设置关注分组
void setFollowGroup() {
if (videoDetail.value.owner == null) {
return;
}
Get.bottomSheet(
GroupPanel(mid: videoDetail.value.owner!.mid!),
isScrollControlled: true,
);
}
// ai总结 // ai总结
Future aiConclusion() async { Future aiConclusion() async {
SmartDialog.showLoading(msg: '正在获取AI总结'); SmartDialog.showLoading(msg: '正在获取AI总结');

View File

@@ -38,184 +38,172 @@ class _FavPanelState extends State<FavPanel> {
} }
return false; return false;
}, },
child: Container( child: Column(
decoration: BoxDecoration( children: [
borderRadius: BorderRadius.circular(18), AppBar(
color: Theme.of(context).colorScheme.surface, backgroundColor: Colors.transparent,
), leading: IconButton(
child: Column( tooltip: '关闭',
children: [ onPressed: Get.back,
AppBar( icon: const Icon(Icons.close_outlined),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(18),
),
),
leading: IconButton(
tooltip: '关闭',
onPressed: Get.back,
icon: const Icon(Icons.close_outlined),
),
title: const Text('添加到收藏夹'),
actions: [
TextButton.icon(
onPressed: () {
Get.toNamed('/createFav')?.then((data) {
if (data != null) {
(widget.ctr?.favFolderData.value as FavFolderData?)
?.list
?.insert(1, data);
widget.ctr?.favFolderData.refresh();
}
});
},
icon: Icon(
Icons.add,
color: Theme.of(context).colorScheme.primary,
),
label: const Text('新建收藏夹'),
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 18, vertical: 14),
visualDensity: const VisualDensity(
horizontal: -2,
vertical: -2,
),
),
),
const SizedBox(width: 16),
],
), ),
Expanded( title: const Text('添加到收藏夹'),
child: Material( actions: [
color: Theme.of(context).colorScheme.surface, TextButton.icon(
child: FutureBuilder( onPressed: () {
future: _futureBuilderFuture, Get.toNamed('/createFav')?.then((data) {
builder: (BuildContext context, AsyncSnapshot snapshot) { if (data != null) {
if (snapshot.connectionState == ConnectionState.done) { (widget.ctr?.favFolderData.value as FavFolderData?)
// TODO: refactor ?.list
if (snapshot.data is! Map) { ?.insert(1, data);
return HttpError( widget.ctr?.favFolderData.refresh();
isSliver: false, }
});
},
icon: Icon(
Icons.add,
color: Theme.of(context).colorScheme.primary,
),
label: const Text('新建收藏夹'),
style: TextButton.styleFrom(
padding:
const EdgeInsets.symmetric(horizontal: 18, vertical: 14),
visualDensity: const VisualDensity(
horizontal: -2,
vertical: -2,
),
),
),
const SizedBox(width: 16),
],
),
Expanded(
child: FutureBuilder(
future: _futureBuilderFuture,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// TODO: refactor
if (snapshot.data is! Map) {
return HttpError(
isSliver: false,
callback: () => setState(() {
_futureBuilderFuture = widget.ctr.queryVideoInFolder();
}),
);
}
Map data = snapshot.data as Map;
if (data['status']) {
return Obx(
() => Material(
color: Colors.transparent,
child: ListView.builder(
controller: widget.scrollController,
itemCount: widget.ctr.favFolderData.value.list.length,
itemBuilder: (context, index) {
return ListTile(
onTap: () => widget.ctr.onChoose(
widget.ctr.favFolderData.value.list[index]
.favState !=
1,
index),
dense: true,
leading: Utils.isPublic(widget
.ctr.favFolderData.value.list[index].attr)
? const Icon(Icons.folder_outlined)
: const Icon(Icons.lock_outline),
minLeadingWidth: 0,
title: Text(widget
.ctr.favFolderData.value.list[index].title!),
subtitle: Text(
'${widget.ctr.favFolderData.value.list[index].mediaCount}个内容 . ${Utils.isPublicText(widget.ctr.favFolderData.value.list[index].attr)}',
),
trailing: Transform.scale(
scale: 0.9,
child: Checkbox(
value: widget.ctr.favFolderData.value
.list[index].favState ==
1,
onChanged: (bool? checkValue) =>
widget.ctr.onChoose(checkValue!, index),
),
),
);
},
),
),
);
} else {
return CustomScrollView(
controller: widget.scrollController,
slivers: [
HttpError(
errMsg: data['msg'],
callback: () => setState(() { callback: () => setState(() {
_futureBuilderFuture = _futureBuilderFuture =
widget.ctr.queryVideoInFolder(); widget.ctr.queryVideoInFolder();
}), }),
); )
} ],
Map data = snapshot.data as Map; );
if (data['status']) { }
return Obx( } else {
() => ListView.builder( // 骨架屏
controller: widget.scrollController, return const Center(
itemCount: child: CircularProgressIndicator(),
widget.ctr.favFolderData.value.list.length, );
itemBuilder: (context, index) { }
return ListTile( },
onTap: () => widget.ctr.onChoose( ),
widget.ctr.favFolderData.value.list[index] ),
.favState != Divider(
1, height: 1,
index), color: Theme.of(context).disabledColor.withOpacity(0.08),
dense: true, ),
leading: Utils.isPublic(widget.ctr.favFolderData Padding(
.value.list[index].attr) padding: EdgeInsets.only(
? const Icon(Icons.folder_outlined) left: 20,
: const Icon(Icons.lock_outline), right: 20,
minLeadingWidth: 0, top: 12,
title: Text(widget.ctr.favFolderData.value bottom: MediaQuery.of(context).padding.bottom + 12,
.list[index].title!), ),
subtitle: Text( child: Row(
'${widget.ctr.favFolderData.value.list[index].mediaCount}个内容 . ${Utils.isPublicText(widget.ctr.favFolderData.value.list[index].attr)}', mainAxisAlignment: MainAxisAlignment.end,
), children: <Widget>[
trailing: Transform.scale( TextButton(
scale: 0.9, onPressed: () => Get.back(),
child: Checkbox( style: TextButton.styleFrom(
value: widget.ctr.favFolderData.value padding: const EdgeInsets.symmetric(
.list[index].favState == horizontal: 20, vertical: 10),
1, visualDensity: const VisualDensity(
onChanged: (bool? checkValue) => horizontal: -1,
widget.ctr.onChoose(checkValue!, index), vertical: -2,
), ),
), foregroundColor: Theme.of(context).colorScheme.outline,
); backgroundColor:
}, Theme.of(context).colorScheme.onInverseSurface,
), ),
); child: const Text('取消'),
} else {
return CustomScrollView(
controller: widget.scrollController,
slivers: [
HttpError(
errMsg: data['msg'],
callback: () => setState(() {
_futureBuilderFuture =
widget.ctr.queryVideoInFolder();
}),
)
],
);
}
} else {
// 骨架屏
return const Center(
child: CircularProgressIndicator(),
);
}
},
), ),
), const SizedBox(width: 25),
), FilledButton.tonal(
Divider( onPressed: () async {
height: 1, feedBack();
color: Theme.of(context).disabledColor.withOpacity(0.08), await widget.ctr.actionFavVideo();
), },
Padding( style: FilledButton.styleFrom(
padding: EdgeInsets.only( padding: const EdgeInsets.symmetric(
left: 20, horizontal: 20, vertical: 10),
right: 20, visualDensity: const VisualDensity(
top: 12, horizontal: -1,
bottom: MediaQuery.of(context).padding.bottom + 12, vertical: -2,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TextButton(
onPressed: () => Get.back(),
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
visualDensity: const VisualDensity(
horizontal: -1,
vertical: -2,
),
foregroundColor: Theme.of(context).colorScheme.outline,
backgroundColor:
Theme.of(context).colorScheme.onInverseSurface,
), ),
child: const Text('取消'),
), ),
const SizedBox(width: 25), child: const Text('完成'),
FilledButton.tonal( ),
onPressed: () async { ],
feedBack();
await widget.ctr.actionFavVideo();
},
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
visualDensity: const VisualDensity(
horizontal: -1,
vertical: -2,
),
),
child: const Text('完成'),
),
],
),
), ),
], ),
), ],
), ),
); );
} }

View File

@@ -77,126 +77,116 @@ class _GroupPanelState extends State<GroupPanel> {
} }
return false; return false;
}, },
child: Container( child: Column(
decoration: BoxDecoration( children: <Widget>[
borderRadius: BorderRadius.circular(18), AppBar(
color: Theme.of(context).colorScheme.surface, backgroundColor: Colors.transparent,
), leading: IconButton(
child: Column( tooltip: '关闭',
children: <Widget>[ onPressed: Get.back,
AppBar( icon: const Icon(Icons.close_outlined)),
shape: const RoundedRectangleBorder( title: const Text('设置关注分组'),
borderRadius: BorderRadius.vertical( ),
top: Radius.circular(18), Expanded(
), child: FutureBuilder(
), future: _futureBuilderFuture,
leading: IconButton( builder: (BuildContext context, AsyncSnapshot snapshot) {
tooltip: '关闭', if (snapshot.connectionState == ConnectionState.done) {
onPressed: Get.back, // TODO: refactor
icon: const Icon(Icons.close_outlined)), if (snapshot.data is! Map) {
title: const Text('设置关注分组'), return HttpError(
), isSliver: false,
Expanded( callback: () => setState(() {
child: Material( _futureBuilderFuture = MemberHttp.followUpTags();
color: Theme.of(context).colorScheme.surface, }),
child: FutureBuilder( );
future: _futureBuilderFuture, }
builder: (BuildContext context, AsyncSnapshot snapshot) { Map data = snapshot.data as Map;
if (snapshot.connectionState == ConnectionState.done) { if (data['status']) {
// TODO: refactor return Material(
if (snapshot.data is! Map) { color: Colors.transparent,
return HttpError( child: ListView.builder(
isSliver: false, controller: widget.scrollController,
callback: () => setState(() { itemCount: tagsList.length,
_futureBuilderFuture = MemberHttp.followUpTags(); itemBuilder: (context, index) {
}), return ListTile(
); onTap: () {
} tagsList[index].checked =
Map data = snapshot.data as Map; !tagsList[index].checked!;
if (data['status']) { showDefaultBtn =
return ListView.builder( !tagsList.any((e) => e.checked == true);
controller: widget.scrollController, setState(() {});
itemCount: tagsList.length, },
itemBuilder: (context, index) { dense: true,
return ListTile( leading: const Icon(Icons.group_outlined),
onTap: () { minLeadingWidth: 0,
tagsList[index].checked = title: Text(tagsList[index].name ?? ''),
!tagsList[index].checked!; subtitle: tagsList[index].tip != ''
showDefaultBtn = ? Text(tagsList[index].tip ?? '')
!tagsList.any((e) => e.checked == true); : null,
setState(() {}); trailing: Transform.scale(
}, scale: 0.9,
dense: true, child: Checkbox(
leading: const Icon(Icons.group_outlined), value: tagsList[index].checked,
minLeadingWidth: 0, onChanged: (bool? checkValue) {
title: Text(tagsList[index].name ?? ''), tagsList[index].checked = checkValue;
subtitle: tagsList[index].tip != '' showDefaultBtn =
? Text(tagsList[index].tip ?? '') !tagsList.any((e) => e.checked == true);
: null, setState(() {});
trailing: Transform.scale( },
scale: 0.9,
child: Checkbox(
value: tagsList[index].checked,
onChanged: (bool? checkValue) {
tagsList[index].checked = checkValue;
showDefaultBtn =
!tagsList.any((e) => e.checked == true);
setState(() {});
},
),
), ),
);
},
);
} else {
return CustomScrollView(
controller: widget.scrollController,
slivers: [
HttpError(
errMsg: data['msg'],
callback: () => setState(() {}),
), ),
], );
); },
} ),
} else { );
// 骨架屏 } else {
return const Center( return CustomScrollView(
child: CircularProgressIndicator(), controller: widget.scrollController,
); slivers: [
} HttpError(
}, errMsg: data['msg'],
), callback: () => setState(() {}),
), ),
],
);
}
} else {
// 骨架屏
return const Center(
child: CircularProgressIndicator(),
);
}
},
), ),
Divider( ),
height: 1, Divider(
color: Theme.of(context).disabledColor.withOpacity(0.08), height: 1,
color: Theme.of(context).disabledColor.withOpacity(0.08),
),
Padding(
padding: EdgeInsets.only(
left: 20,
right: 20,
top: 12,
bottom: MediaQuery.of(context).padding.bottom + 12,
), ),
Padding( child: Row(
padding: EdgeInsets.only( mainAxisAlignment: MainAxisAlignment.end,
left: 20, children: [
right: 20, TextButton(
top: 12, onPressed: () => onSave(),
bottom: MediaQuery.of(context).padding.bottom + 12, style: TextButton.styleFrom(
), padding: const EdgeInsets.only(left: 30, right: 30),
child: Row( foregroundColor: Theme.of(context).colorScheme.onPrimary,
mainAxisAlignment: MainAxisAlignment.end, backgroundColor: Theme.of(context).colorScheme.primary,
children: [
TextButton(
onPressed: () => onSave(),
style: TextButton.styleFrom(
padding: const EdgeInsets.only(left: 30, right: 30),
foregroundColor: Theme.of(context).colorScheme.onPrimary,
backgroundColor: Theme.of(context).colorScheme.primary,
),
child: Text(showDefaultBtn ? '保存至默认分组' : '保存'),
), ),
], child: Text(showDefaultBtn ? '保存至默认分组' : '保存'),
), ),
],
), ),
], ),
), ],
), ),
); );
} }

View File

@@ -19,10 +19,8 @@ class IntroDetail extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Padding(
color: Theme.of(context).colorScheme.surface,
padding: const EdgeInsets.only(left: 14, right: 14), padding: const EdgeInsets.only(left: 14, right: 14),
// height: Utils.getSheetHeight(context),
child: Column( child: Column(
children: [ children: [
InkWell( InkWell(

View File

@@ -64,24 +64,8 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Obx(
appBar: AppBar( () => _buildUserPage(_controller.userState.value),
automaticallyImplyLeading: false,
toolbarHeight: 36,
actions: [
iconButton(
context: context,
onPressed: Get.back,
tooltip: '关闭',
icon: Icons.clear,
size: 28,
),
const SizedBox(width: 16),
],
),
body: Obx(
() => _buildUserPage(_controller.userState.value),
),
); );
} }
@@ -90,11 +74,25 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
Loading() => loadingWidget, Loading() => loadingWidget,
Success() => Column( Success() => Column(
children: [ children: [
const SizedBox(height: 4),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
iconButton(
context: context,
onPressed: Get.back,
tooltip: '关闭',
icon: Icons.clear,
size: 32,
),
const SizedBox(width: 16),
],
),
_buildUserInfo(userState.response), _buildUserInfo(userState.response),
const SizedBox(height: 5), const SizedBox(height: 5),
Expanded( Expanded(
child: Obx(() => _buildVideoList(_controller.loadingState.value)), child: Obx(() => _buildVideoList(_controller.loadingState.value)),
) ),
], ],
), ),
Error() => errorWidget( Error() => errorWidget(
@@ -159,46 +157,49 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
Widget _buildVideoList(LoadingState loadingState) { Widget _buildVideoList(LoadingState loadingState) {
return switch (loadingState) { return switch (loadingState) {
Loading() => loadingWidget, Loading() => loadingWidget,
Success() => CustomScrollView( Success() => Material(
slivers: [ color: Colors.transparent,
_buildSliverHeader, child: CustomScrollView(
SliverPadding( slivers: [
padding: EdgeInsets.only( _buildSliverHeader,
bottom: MediaQuery.of(context).padding.bottom + 80, SliverPadding(
), padding: EdgeInsets.only(
sliver: SliverGrid( bottom: MediaQuery.of(context).padding.bottom + 80,
gridDelegate: SliverGridDelegateWithExtentAndRatio(
mainAxisSpacing: 2,
maxCrossAxisExtent: Grid.mediumCardWidth * 2,
childAspectRatio: StyleString.aspectRatio * 2.2,
), ),
delegate: SliverChildBuilderDelegate( sliver: SliverGrid(
(context, index) { gridDelegate: SliverGridDelegateWithExtentAndRatio(
if (index == loadingState.response.length - 1) { mainAxisSpacing: 2,
_controller.onLoadMore(); maxCrossAxisExtent: Grid.mediumCardWidth * 2,
} childAspectRatio: StyleString.aspectRatio * 2.2,
return VideoCardHMemberVideo( ),
videoItem: loadingState.response[index], delegate: SliverChildBuilderDelegate(
bvid: _bvid, (context, index) {
onTap: () { if (index == loadingState.response.length - 1) {
final Item videoItem = loadingState.response[index]; _controller.onLoadMore();
widget.videoIntroController.changeSeasonOrbangu( }
null, return VideoCardHMemberVideo(
videoItem.bvid, videoItem: loadingState.response[index],
videoItem.firstCid, bvid: _bvid,
IdUtils.bv2av(videoItem.bvid!), onTap: () {
videoItem.cover, final Item videoItem = loadingState.response[index];
); widget.videoIntroController.changeSeasonOrbangu(
_bvid = videoItem.bvid; null,
setState(() {}); videoItem.bvid,
}, videoItem.firstCid,
); IdUtils.bv2av(videoItem.bvid!),
}, videoItem.cover,
childCount: loadingState.response.length, );
_bvid = videoItem.bvid;
setState(() {});
},
);
},
childCount: loadingState.response.length,
),
), ),
), ),
), ],
], ),
), ),
Error() => errorWidget( Error() => errorWidget(
errMsg: loadingState.errMsg, errMsg: loadingState.errMsg,

View File

@@ -1116,7 +1116,7 @@ class MorePanel extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Color errorColor = Theme.of(context).colorScheme.error; Color errorColor = Theme.of(context).colorScheme.error;
return Container( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
bottom: MediaQueryData.fromView( bottom: MediaQueryData.fromView(
WidgetsBinding.instance.platformDispatcher.views.single) WidgetsBinding.instance.platformDispatcher.views.single)

View File

@@ -1159,7 +1159,7 @@ class ReplyItemGrpc extends StatelessWidget {
} }
Color errorColor = Theme.of(context).colorScheme.error; Color errorColor = Theme.of(context).colorScheme.error;
return Container( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
bottom: MediaQueryData.fromView( bottom: MediaQueryData.fromView(
WidgetsBinding.instance.platformDispatcher.views.single) WidgetsBinding.instance.platformDispatcher.views.single)

View File

@@ -497,6 +497,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
upMid: _videoReplyReplyController.upMid, upMid: _videoReplyReplyController.upMid,
showDialogue: () { showDialogue: () {
_key.currentState?.showBottomSheet( _key.currentState?.showBottomSheet(
backgroundColor: Colors.transparent,
(context) => VideoReplyReplyPanel( (context) => VideoReplyReplyPanel(
oid: replyItem.oid.toInt(), oid: replyItem.oid.toInt(),
rpid: replyItem.root.toInt(), rpid: replyItem.root.toInt(),

View File

@@ -887,13 +887,16 @@ class _VideoDetailPageState extends State<VideoDetailPage>
if (videoDetailController.videoType == if (videoDetailController.videoType ==
SearchType.video && SearchType.video &&
videoDetailController.showRelatedVideo) videoDetailController.showRelatedVideo)
CustomScrollView( Material(
controller: _introController, color: Colors.transparent,
slivers: [ child: CustomScrollView(
RelatedVideoPanel( controller: _introController,
key: relatedVideoPanelKey, slivers: [
heroTag: heroTag), RelatedVideoPanel(
], key: relatedVideoPanelKey,
heroTag: heroTag),
],
),
), ),
if (videoDetailController.showReply) if (videoDetailController.showReply)
videoReplyPanel, videoReplyPanel,
@@ -1502,62 +1505,67 @@ class _VideoDetailPageState extends State<VideoDetailPage>
); );
Widget videoIntro([bool needRelated = true]) { Widget videoIntro([bool needRelated = true]) {
Widget introPanel() => CustomScrollView( Widget introPanel() => Material(
key: const PageStorageKey<String>('简介'), color: Colors.transparent,
controller: needRelated ? _introController : null, child: CustomScrollView(
slivers: [ key: const PageStorageKey<String>('简介'),
if (videoDetailController.videoType == SearchType.video) ...[ controller: needRelated ? _introController : null,
VideoIntroPanel( slivers: [
heroTag: heroTag, if (videoDetailController.videoType == SearchType.video) ...[
showAiBottomSheet: showAiBottomSheet, VideoIntroPanel(
showIntroDetail: showIntroDetail, heroTag: heroTag,
showEpisodes: showEpisodes, showAiBottomSheet: showAiBottomSheet,
onShowMemberPage: onShowMemberPage, showIntroDetail: showIntroDetail,
), showEpisodes: showEpisodes,
if (needRelated && videoDetailController.showRelatedVideo) ...[ onShowMemberPage: onShowMemberPage,
SliverToBoxAdapter( ),
child: Padding( if (needRelated && videoDetailController.showRelatedVideo) ...[
padding: const EdgeInsets.only(top: StyleString.safeSpace), SliverToBoxAdapter(
child: Divider( child: Padding(
height: 1, padding:
indent: 12, const EdgeInsets.only(top: StyleString.safeSpace),
endIndent: 12, child: Divider(
color: Theme.of(context) height: 1,
.colorScheme indent: 12,
.outline endIndent: 12,
.withOpacity(0.08), color: Theme.of(context)
.colorScheme
.outline
.withOpacity(0.08),
),
), ),
), ),
), RelatedVideoPanel(
RelatedVideoPanel(key: relatedVideoPanelKey, heroTag: heroTag), key: relatedVideoPanelKey, heroTag: heroTag),
] else ] else
SliverToBoxAdapter( SliverToBoxAdapter(
child: SizedBox( child: SizedBox(
height: MediaQuery.paddingOf(context).bottom + height: MediaQuery.paddingOf(context).bottom +
StyleString.safeSpace, StyleString.safeSpace,
),
),
] else if (videoDetailController.videoType ==
SearchType.media_bangumi)
Obx(
() => BangumiIntroPanel(
heroTag: heroTag,
cid: videoDetailController.cid.value,
showEpisodes: showEpisodes,
showIntroDetail: showIntroDetail,
), ),
), ),
] else if (videoDetailController.videoType == SliverToBoxAdapter(
SearchType.media_bangumi) child: SizedBox(
Obx( height: MediaQuery.paddingOf(context).bottom +
() => BangumiIntroPanel( (videoDetailController.isPlayAll &&
heroTag: heroTag, MediaQuery.orientationOf(context) ==
cid: videoDetailController.cid.value, Orientation.landscape
showEpisodes: showEpisodes, ? 75
showIntroDetail: showIntroDetail, : 0),
), ),
), )
SliverToBoxAdapter( ],
child: SizedBox( ),
height: MediaQuery.paddingOf(context).bottom +
(videoDetailController.isPlayAll &&
MediaQuery.orientationOf(context) ==
Orientation.landscape
? 75
: 0),
),
)
],
); );
if (videoDetailController.isPlayAll) { if (videoDetailController.isPlayAll) {
return Stack( return Stack(
@@ -1570,7 +1578,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: videoDetailController.showMediaListPanel, onTap: () => videoDetailController.showMediaListPanel(context),
borderRadius: const BorderRadius.all(Radius.circular(14)), borderRadius: const BorderRadius.all(Radius.circular(14)),
child: Container( child: Container(
height: 54, height: 54,
@@ -1745,6 +1753,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
int oid = replyItem.oid.toInt(); int oid = replyItem.oid.toInt();
int rpid = GlobalData().grpcReply ? replyItem.id.toInt() : replyItem.rpid; int rpid = GlobalData().grpcReply ? replyItem.id.toInt() : replyItem.rpid;
videoDetailController.childKey.currentState?.showBottomSheet( videoDetailController.childKey.currentState?.showBottomSheet(
backgroundColor: Colors.transparent,
(context) => VideoReplyReplyPanel( (context) => VideoReplyReplyPanel(
id: id, id: id,
oid: oid, oid: oid,
@@ -1764,6 +1773,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
showAiBottomSheet() { showAiBottomSheet() {
videoDetailController.childKey.currentState?.showBottomSheet( videoDetailController.childKey.currentState?.showBottomSheet(
enableDrag: true, enableDrag: true,
backgroundColor: Theme.of(context).colorScheme.surface,
(context) => AiDetail(modelResult: videoIntroController.modelResult), (context) => AiDetail(modelResult: videoIntroController.modelResult),
); );
} }
@@ -1771,6 +1781,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
showIntroDetail(videoDetail, videoTags) { showIntroDetail(videoDetail, videoTags) {
videoDetailController.childKey.currentState?.showBottomSheet( videoDetailController.childKey.currentState?.showBottomSheet(
enableDrag: true, enableDrag: true,
backgroundColor: Theme.of(context).colorScheme.surface,
(context) => videoDetail is BangumiInfoModel (context) => videoDetail is BangumiInfoModel
? bangumi.IntroDetail( ? bangumi.IntroDetail(
bangumiDetail: videoDetail, bangumiDetail: videoDetail,
@@ -1814,9 +1825,16 @@ class _VideoDetailPageState extends State<VideoDetailPage>
}, },
); );
if (isFullScreen) { if (isFullScreen) {
Utils.showFSSheet(child: listSheetContent(), isFullScreen: isFullScreen); Utils.showFSSheet(
child: Material(
color: Theme.of(context).colorScheme.surface,
child: listSheetContent(),
),
isFullScreen: isFullScreen,
);
} else { } else {
videoDetailController.childKey.currentState?.showBottomSheet( videoDetailController.childKey.currentState?.showBottomSheet(
backgroundColor: Theme.of(context).colorScheme.surface,
(context) => listSheetContent(), (context) => listSheetContent(),
); );
} }
@@ -2035,6 +2053,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
Utils.showFSSheet(child: listSheetContent(), isFullScreen: isFullScreen); Utils.showFSSheet(child: listSheetContent(), isFullScreen: isFullScreen);
} else { } else {
videoDetailController.childKey.currentState?.showBottomSheet( videoDetailController.childKey.currentState?.showBottomSheet(
backgroundColor: Colors.transparent,
(context) => listSheetContent(), (context) => listSheetContent(),
); );
} }
@@ -2056,6 +2075,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
void onShowMemberPage(mid) { void onShowMemberPage(mid) {
videoDetailController.childKey.currentState?.showBottomSheet( videoDetailController.childKey.currentState?.showBottomSheet(
backgroundColor: Theme.of(context).colorScheme.surface,
(context) { (context) {
return HorizontalMemberPage( return HorizontalMemberPage(
mid: mid, mid: mid,

View File

@@ -63,53 +63,45 @@ class _MediaListPanelState extends State<MediaListPanel> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DecoratedBox( return Column(
decoration: BoxDecoration( children: [
color: Theme.of(context).colorScheme.surface, AppBar(
), toolbarHeight: 45,
child: Column( automaticallyImplyLeading: false,
children: [ titleSpacing: 16,
AppBar( title: Text(widget.panelTitle ?? '稍后再看'),
toolbarHeight: 45, actions: [
automaticallyImplyLeading: false, Obx(
titleSpacing: 16, () => mediumButton(
title: Text(widget.panelTitle ?? '稍后再看'), tooltip: desc.value ? '顺序播放' : '倒序播放',
actions: [ icon: desc.value
Obx( ? MdiIcons.sortAscending
() => mediumButton( : MdiIcons.sortDescending,
tooltip: desc.value ? '顺序播放' : '倒序播放', onPressed: () {
icon: desc.value widget.onReverse();
? MdiIcons.sortAscending desc.value = !desc.value;
: MdiIcons.sortDescending, },
onPressed: () {
widget.onReverse();
desc.value = !desc.value;
},
),
), ),
mediumButton(
tooltip: '关闭',
icon: Icons.close,
onPressed: Get.back,
),
const SizedBox(width: 14),
],
),
Expanded(
child: Material(
color: Theme.of(context).colorScheme.surface,
child: widget.loadPrevious != null
? refreshIndicator(
onRefresh: () async {
await widget.loadPrevious!();
},
child: _buildList,
)
: _buildList,
), ),
), mediumButton(
], tooltip: '关闭',
), icon: Icons.close,
onPressed: Get.back,
),
const SizedBox(width: 14),
],
),
Expanded(
child: widget.loadPrevious != null
? refreshIndicator(
onRefresh: () async {
await widget.loadPrevious!();
},
child: _buildList,
)
: _buildList,
),
],
); );
} }

View File

@@ -320,6 +320,7 @@ class Utils {
context: context, context: context,
useSafeArea: true, useSafeArea: true,
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Theme.of(context).colorScheme.surface,
sheetAnimationStyle: AnimationStyle(curve: Curves.ease), sheetAnimationStyle: AnimationStyle(curve: Curves.ease),
builder: (BuildContext context) { builder: (BuildContext context) {
return DraggableScrollableSheet( return DraggableScrollableSheet(
@@ -701,6 +702,7 @@ class Utils {
context: context, context: context,
useSafeArea: true, useSafeArea: true,
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Theme.of(context).colorScheme.surface,
sheetAnimationStyle: AnimationStyle(curve: Curves.ease), sheetAnimationStyle: AnimationStyle(curve: Curves.ease),
builder: (BuildContext context) { builder: (BuildContext context) {
return DraggableScrollableSheet( return DraggableScrollableSheet(