fix(mobile): better UI for metadata panel (#24428)

* change drag bar and animation position

* ensure bottom bar is below the metadata panel - move the bottom bar from bottomNavigationBar into the Stack

* change some parameters

* add background color for night mode

* background color

* change default position

* minor changes

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
pull/24121/merge
Hai Sullivan 2025-12-17 03:25:01 +11:00 committed by GitHub
parent ded9535434
commit 276d02e12b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 24 additions and 34 deletions

View File

@ -79,7 +79,7 @@ class ActivitiesBottomSheet extends HookConsumerWidget {
expand: false, expand: false,
shouldCloseOnMinExtent: false, shouldCloseOnMinExtent: false,
resizeOnScroll: false, resizeOnScroll: false,
backgroundColor: context.isDarkTheme ? Colors.black : Colors.white, backgroundColor: context.isDarkTheme ? context.colorScheme.surface : Colors.white,
); );
} }
} }

View File

@ -97,7 +97,7 @@ class AssetViewer extends ConsumerStatefulWidget {
} }
const double _kBottomSheetMinimumExtent = 0.4; const double _kBottomSheetMinimumExtent = 0.4;
const double _kBottomSheetSnapExtent = 0.7; const double _kBottomSheetSnapExtent = 0.67;
class _AssetViewerState extends ConsumerState<AssetViewer> { class _AssetViewerState extends ConsumerState<AssetViewer> {
static final _dummyListener = ImageStreamListener((image, _) => image.dispose()); static final _dummyListener = ImageStreamListener((image, _) => image.dispose());
@ -399,10 +399,14 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
final isDraggingDown = currentExtent < previousExtent; final isDraggingDown = currentExtent < previousExtent;
previousExtent = currentExtent; previousExtent = currentExtent;
// Closes the bottom sheet if the user is dragging down // Closes the bottom sheet if the user is dragging down
if (isDraggingDown && delta.extent < 0.55) { if (isDraggingDown && delta.extent < 0.67) {
if (dragInProgress) { if (dragInProgress) {
blockGestures = true; blockGestures = true;
} }
// Jump to a lower position before starting close animation to prevent glitch
if (bottomSheetController.isAttached) {
bottomSheetController.jumpTo(0.67);
}
sheetCloseController?.close(); sheetCloseController?.close();
} }
@ -480,7 +484,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
previousExtent = _kBottomSheetMinimumExtent; previousExtent = _kBottomSheetMinimumExtent;
sheetCloseController = showBottomSheet( sheetCloseController = showBottomSheet(
context: ctx, context: ctx,
sheetAnimationStyle: const AnimationStyle(duration: Durations.short4, reverseDuration: Durations.short2), sheetAnimationStyle: const AnimationStyle(duration: Durations.medium2, reverseDuration: Durations.medium2),
constraints: const BoxConstraints(maxWidth: double.infinity), constraints: const BoxConstraints(maxWidth: double.infinity),
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(20.0))), shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(20.0))),
backgroundColor: ctx.colorScheme.surfaceContainerLowest, backgroundColor: ctx.colorScheme.surfaceContainerLowest,
@ -688,16 +692,20 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
backgroundDecoration: BoxDecoration(color: backgroundColor), backgroundDecoration: BoxDecoration(color: backgroundColor),
enablePanAlways: true, enablePanAlways: true,
), ),
if (!showingBottomSheet)
const Positioned(
bottom: 0,
left: 0,
right: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [AssetStackRow(), ViewerBottomBar()],
),
),
], ],
), ),
bottomNavigationBar: showingBottomSheet
? const SizedBox.shrink()
: const Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [AssetStackRow(), ViewerBottomBar()],
),
), ),
); );
} }

View File

@ -52,7 +52,7 @@ class AssetDetailBottomSheet extends ConsumerWidget {
expand: false, expand: false,
shouldCloseOnMinExtent: false, shouldCloseOnMinExtent: false,
resizeOnScroll: false, resizeOnScroll: false,
backgroundColor: context.isDarkTheme ? Colors.black : Colors.white, backgroundColor: context.isDarkTheme ? context.colorScheme.surface : Colors.white,
); );
} }
} }
@ -299,7 +299,7 @@ class _AssetDetailBottomSheet extends ConsumerWidget {
// Appears in (Albums) // Appears in (Albums)
Padding(padding: const EdgeInsets.only(top: 16.0), child: _buildAppearsInList(ref, context)), Padding(padding: const EdgeInsets.only(top: 16.0), child: _buildAppearsInList(ref, context)),
// padding at the bottom to avoid cut-off // padding at the bottom to avoid cut-off
const SizedBox(height: 100), const SizedBox(height: 30),
], ],
); );
} }

View File

@ -81,7 +81,7 @@ class _BaseDraggableScrollableSheetState extends ConsumerState<BaseBottomSheet>
child: CustomScrollView( child: CustomScrollView(
controller: scrollController, controller: scrollController,
slivers: [ slivers: [
const SliverPersistentHeader(delegate: _DragHandleDelegate(), pinned: true), const SliverToBoxAdapter(child: _DragHandle()),
if (widget.actions.isNotEmpty) if (widget.actions.isNotEmpty)
SliverToBoxAdapter( SliverToBoxAdapter(
child: Column( child: Column(
@ -108,31 +108,13 @@ class _BaseDraggableScrollableSheetState extends ConsumerState<BaseBottomSheet>
} }
} }
class _DragHandleDelegate extends SliverPersistentHeaderDelegate {
const _DragHandleDelegate();
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
return const _DragHandle();
}
@override
bool shouldRebuild(_DragHandleDelegate oldDelegate) => false;
@override
double get minExtent => 50.0;
@override
double get maxExtent => 50.0;
}
class _DragHandle extends StatelessWidget { class _DragHandle extends StatelessWidget {
const _DragHandle(); const _DragHandle();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(
height: 50, height: 38,
child: Center( child: Center(
child: SizedBox( child: SizedBox(
width: 32, width: 32,