Adds ticks to the progress indicator

This commit is contained in:
Marty Fuhry 2024-02-01 13:52:08 -05:00
parent d21964c0cc
commit edba462faf
No known key found for this signature in database
GPG Key ID: E2AB6392D894D900
3 changed files with 142 additions and 76 deletions

View File

@ -16,7 +16,7 @@ class _MemoryEpilogueState extends State<MemoryEpilogue>
late final _animationController = AnimationController( late final _animationController = AnimationController(
vsync: this, vsync: this,
duration: const Duration( duration: const Duration(
seconds: 3, seconds: 2,
), ),
)..repeat( )..repeat(
reverse: true, reverse: true,
@ -29,7 +29,7 @@ class _MemoryEpilogueState extends State<MemoryEpilogue>
super.initState(); super.initState();
_animation = CurvedAnimation( _animation = CurvedAnimation(
parent: _animationController, parent: _animationController,
curve: Curves.easeInOut, curve: Curves.easeIn,
); );
} }
@ -41,74 +41,82 @@ class _MemoryEpilogueState extends State<MemoryEpilogue>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return SafeArea(
crossAxisAlignment: CrossAxisAlignment.center, child: Stack(
mainAxisAlignment: MainAxisAlignment.center, children: [
children: [ Positioned.fill(
Expanded( child: Column(
child: Column( mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, children: [
children: [ const Icon(
const Icon( Icons.check_circle_outline_sharp,
Icons.check_circle_outline_sharp, color: immichDarkThemePrimaryColor,
color: immichDarkThemePrimaryColor, size: 64.0,
size: 64.0, ),
), const SizedBox(height: 16.0),
const SizedBox(height: 16.0), Text(
Text( 'All caught up',
'All caught up', style: Theme.of(context).textTheme.headlineMedium?.copyWith(
style: Theme.of(context).textTheme.headlineMedium?.copyWith( color: Colors.white,
color: Colors.white, ),
),
const SizedBox(height: 16.0),
Text(
'Check back tomorrow for more memories',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
),
const SizedBox(height: 16.0),
TextButton(
onPressed: widget.onStartOver,
child: Text(
'Start Over',
style: context.textTheme.displayMedium?.copyWith(
color: immichDarkThemePrimaryColor,
), ),
),
const SizedBox(height: 16.0),
Text(
'Check back tomorrow for more memories',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
),
const SizedBox(height: 16.0),
TextButton(
onPressed: widget.onStartOver,
child: Text(
'Start Over',
style: context.textTheme.displayMedium?.copyWith(
color: immichDarkThemePrimaryColor,
), ),
), ),
), ],
], ),
), ),
), Positioned(
Column( bottom: 0,
children: [ left: 0,
SizedBox( right: 0,
height: 48, child: Padding(
child: AnimatedBuilder( padding: const EdgeInsets.only(bottom: 16.0),
animation: _animation, child: Column(
builder: (context, child) { children: [
return Transform.translate( SizedBox(
offset: Offset(0, 5 * _animationController.value), height: 48,
child: child, child: AnimatedBuilder(
); animation: _animation,
}, builder: (context, child) {
child: const Icon( return Transform.translate(
size: 32, offset: Offset(0, 8 * _animationController.value),
Icons.expand_less_sharp, child: child,
color: Colors.white, );
), },
child: const Icon(
size: 32,
Icons.expand_less_sharp,
color: Colors.white,
),
),
),
Text(
'Swipe up to close',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.white,
),
),
],
), ),
), ),
Text( ),
'Swipe up to close', ],
style: Theme.of(context).textTheme.bodyMedium?.copyWith( ),
color: Colors.white,
),
),
],
),
],
); );
} }
} }

View File

@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
class MemoryProgressIndicator extends StatelessWidget {
/// The number of ticks in the progress indicator
final int ticks;
/// The current value of the indicator
final double value;
const MemoryProgressIndicator(
{super.key, required this.ticks, required this.value});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final tickWidth = constraints.maxWidth / ticks;
return Stack(
children: [
LinearProgressIndicator(
value: value,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(
ticks,
(i) => Container(
width: tickWidth,
height: 4,
decoration: BoxDecoration(
border: i == 0
? null
: Border(
left: BorderSide(
color: Theme.of(context).scaffoldBackgroundColor,
width: 1,
),
),
),
),
),
),
],
);
},
);
}
}

View File

@ -7,6 +7,7 @@ import 'package:immich_mobile/modules/memories/models/memory.dart';
import 'package:immich_mobile/modules/memories/ui/memory_bottom_info.dart'; import 'package:immich_mobile/modules/memories/ui/memory_bottom_info.dart';
import 'package:immich_mobile/modules/memories/ui/memory_card.dart'; import 'package:immich_mobile/modules/memories/ui/memory_card.dart';
import 'package:immich_mobile/modules/memories/ui/memory_epilogue.dart'; import 'package:immich_mobile/modules/memories/ui/memory_epilogue.dart';
import 'package:immich_mobile/modules/memories/ui/memory_progress_indicator.dart';
import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/ui/immich_image.dart'; import 'package:immich_mobile/shared/ui/immich_image.dart';
import 'package:openapi/api.dart' as api; import 'package:openapi/api.dart' as api;
@ -208,18 +209,27 @@ class MemoryPage extends HookConsumerWidget {
// Build horizontal page // Build horizontal page
return Column( return Column(
children: [ children: [
AnimatedBuilder( Padding(
animation: currentMemoryAssetPageController, padding: const EdgeInsets.only(
builder: (context, child) { left: 24.0,
double value = 0.0; right: 24.0,
if (currentMemoryAssetPageController.hasClients) { top: 8.0,
// We can only access [page] if this has clients bottom: 2.0,
value = currentMemoryAssetPageController.page ?? 0; ),
} child: AnimatedBuilder(
return LinearProgressIndicator( animation: currentMemoryAssetPageController,
value: (value + 1) / memories[mIndex].assets.length, builder: (context, child) {
); double value = 0.0;
}, if (currentMemoryAssetPageController.hasClients) {
// We can only access [page] if this has clients
value = currentMemoryAssetPageController.page ?? 0;
}
return MemoryProgressIndicator(
ticks: memories[mIndex].assets.length,
value: (value + 1) / memories[mIndex].assets.length,
);
},
),
), ),
Expanded( Expanded(
child: Stack( child: Stack(