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 674cf07bcf..c416f352da 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,6 +535,7 @@ class _SwipeCullingPageState extends State @override Widget build(BuildContext context) { final theme = getEnteColorScheme(context); + final textTheme = getEnteTextTheme(context); if (groups.isEmpty) { return Scaffold( @@ -620,18 +621,21 @@ class _SwipeCullingPageState extends State ? Column( children: [ Expanded( - child: Stack( - alignment: Alignment.center, + child: Column( children: [ - // Use a unique key for each group to force rebuild - CardSwiper( + Expanded( + child: Stack( + alignment: Alignment.center, + children: [ + // 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.all(24.0), + padding: const EdgeInsets.symmetric(horizontal: 20.0), cardBuilder: ( context, index, @@ -681,29 +685,59 @@ 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, + // 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, + ), + 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 ff00a2ee2f..6d212bc49f 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,7 +7,6 @@ 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 { @@ -129,7 +128,6 @@ 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 @@ -149,87 +147,53 @@ class _SwipeablePhotoCardState extends State { final maxWidth = screenSize.width * 0.85; final maxHeight = screenSize.height * 0.65; - // 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: 8), - 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, - ), - ], - ), + 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), ), ], ), + 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