Fix card centering and keep file info with image
This commit is contained in:
@@ -535,7 +535,6 @@ class _SwipeCullingPageState extends State<SwipeCullingPage>
|
||||
@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<SwipeCullingPage>
|
||||
? 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<SwipeCullingPage>
|
||||
},
|
||||
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,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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<SwipeablePhotoCard> {
|
||||
@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<SwipeablePhotoCard> {
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user