From 009dec1e082c1ce1d62e3fa72942dfa11a290b28 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Wed, 3 Sep 2025 22:29:04 +0530 Subject: [PATCH] Fix card centering and keep file info with image --- .../library_culling/swipe_culling_page.dart | 86 ++++-------- .../widgets/swipeable_photo_card.dart | 124 +++++++++++------- 2 files changed, 106 insertions(+), 104 deletions(-) diff --git a/mobile/apps/photos/lib/ui/pages/library_culling/swipe_culling_page.dart b/mobile/apps/photos/lib/ui/pages/library_culling/swipe_culling_page.dart index 7bea03470c..68e7edee62 100644 --- a/mobile/apps/photos/lib/ui/pages/library_culling/swipe_culling_page.dart +++ b/mobile/apps/photos/lib/ui/pages/library_culling/swipe_culling_page.dart @@ -535,7 +535,6 @@ class _SwipeCullingPageState extends State @override Widget build(BuildContext context) { final theme = getEnteColorScheme(context); - final textTheme = getEnteTextTheme(context); if (groups.isEmpty) { return Scaffold( @@ -621,21 +620,18 @@ class _SwipeCullingPageState extends State ? Column( children: [ Expanded( - child: Column( + child: Stack( + alignment: Alignment.center, children: [ - Expanded( - child: Stack( - alignment: Alignment.center, - children: [ - // Use a unique key for each group to force rebuild - CardSwiper( + // Use a unique key for each group to force rebuild + CardSwiper( key: ValueKey('swiper_${currentGroupIndex}_$currentImageIndex'), controller: controller, cardsCount: currentGroupFiles.length - currentImageIndex, numberOfCardsDisplayed: 1, backCardOffset: const Offset(0, 0), - padding: const EdgeInsets.symmetric(horizontal: 20.0), + padding: const EdgeInsets.all(20.0), cardBuilder: ( context, index, @@ -685,59 +681,29 @@ class _SwipeCullingPageState extends State }, isDisabled: false, threshold: 50, - ), - - // Minimal celebration overlay - if (_showingCelebration) - Container( - color: Colors.black.withValues(alpha: 0.2), - child: Center( - child: Icon( - Icons.check_circle, - size: 48, - color: theme.primary500, - ) - .animate( - controller: _celebrationController, - ) - .scaleXY( - begin: 0.5, - end: 1.2, - curve: Curves.easeOut, - ) - .fadeIn( - duration: 100.ms, - ), - ), - ), - ], - ), ), - // File info display - outside the swipeable area - if (currentFile != null) - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 24, - vertical: 12, - ), - child: Column( - children: [ - Text( - currentFile!.displayName, - style: textTheme.body, - maxLines: 1, - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center, - ), - const SizedBox(height: 4), - Text( - formatBytes(currentFile!.fileSize ?? 0), - style: textTheme.small.copyWith( - color: theme.textMuted, + + // Minimal celebration overlay + if (_showingCelebration) + Container( + color: Colors.black.withValues(alpha: 0.2), + child: Center( + child: Icon( + Icons.check_circle, + size: 48, + color: theme.primary500, + ) + .animate( + controller: _celebrationController, + ) + .scaleXY( + begin: 0.5, + end: 1.2, + curve: Curves.easeOut, + ) + .fadeIn( + duration: 100.ms, ), - textAlign: TextAlign.center, - ), - ], ), ), ], diff --git a/mobile/apps/photos/lib/ui/pages/library_culling/widgets/swipeable_photo_card.dart b/mobile/apps/photos/lib/ui/pages/library_culling/widgets/swipeable_photo_card.dart index 6d212bc49f..d553af2398 100644 --- a/mobile/apps/photos/lib/ui/pages/library_culling/widgets/swipeable_photo_card.dart +++ b/mobile/apps/photos/lib/ui/pages/library_culling/widgets/swipeable_photo_card.dart @@ -7,6 +7,7 @@ import 'package:photos/models/file/file.dart'; import 'package:photos/theme/ente_theme.dart'; import 'package:photos/ui/common/loading_widget.dart'; import 'package:photos/utils/file_util.dart'; +import 'package:photos/utils/standalone/data.dart'; import 'package:photos/utils/thumbnail_util.dart'; class SwipeablePhotoCard extends StatefulWidget { @@ -128,6 +129,7 @@ class _SwipeablePhotoCardState extends State { @override Widget build(BuildContext context) { final theme = getEnteColorScheme(context); + final textTheme = getEnteTextTheme(context); final screenSize = MediaQuery.of(context).size; // Calculate border intensity based on swipe progress @@ -147,53 +149,87 @@ class _SwipeablePhotoCardState extends State { final maxWidth = screenSize.width * 0.85; final maxHeight = screenSize.height * 0.65; - return Container( - constraints: BoxConstraints( - maxWidth: maxWidth, - maxHeight: maxHeight, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.1), - blurRadius: 10, - offset: const Offset(0, 5), + // Get file info + final fileName = widget.file.displayName; + final fileSize = formatBytes(widget.file.fileSize ?? 0); + + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + constraints: BoxConstraints( + maxWidth: maxWidth, + maxHeight: maxHeight, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.1), + blurRadius: 10, + offset: const Offset(0, 5), + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: Stack( + children: [ + // Main photo - progressively load from thumbnail to full image + if (_imageProvider != null) + Image( + image: _imageProvider!, + fit: BoxFit.contain, + gaplessPlayback: true, + ) + else + const Center( + child: EnteLoadingWidget(), + ), + + // Border overlay for swipe feedback + if (borderColor != null && borderWidth > 0) + IgnorePointer( + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: borderColor, + width: borderWidth, + ), + borderRadius: BorderRadius.circular(16), + ), + ), + ), + ], + ), + ), + ), + // File info directly below the image + Container( + width: maxWidth, + padding: const EdgeInsets.only(top: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + fileName, + style: textTheme.body, + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + ), + const SizedBox(height: 2), + Text( + fileSize, + style: textTheme.small.copyWith(color: theme.textMuted), + textAlign: TextAlign.center, + ), + ], + ), ), ], ), - child: ClipRRect( - borderRadius: BorderRadius.circular(16), - child: Stack( - children: [ - // Main photo - progressively load from thumbnail to full image - if (_imageProvider != null) - Image( - image: _imageProvider!, - fit: BoxFit.contain, - gaplessPlayback: true, - ) - else - const Center( - child: EnteLoadingWidget(), - ), - - // Border overlay for swipe feedback - if (borderColor != null && borderWidth > 0) - IgnorePointer( - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: borderColor, - width: borderWidth, - ), - borderRadius: BorderRadius.circular(16), - ), - ), - ), - ], - ), - ), ); } } \ No newline at end of file