improved memory timeline

This commit is contained in:
Myzel394 2022-08-14 22:46:34 +02:00
parent 13ea760cb8
commit 9671e2f578
4 changed files with 94 additions and 73 deletions

View File

@ -7,10 +7,12 @@ import 'package:share_location/widgets/modal_sheet.dart';
class MemorySheet extends StatefulWidget { class MemorySheet extends StatefulWidget {
final Memory memory; final Memory memory;
final VoidCallback onMemoryDeleted;
const MemorySheet({ const MemorySheet({
Key? key, Key? key,
required this.memory, required this.memory,
required this.onMemoryDeleted,
}) : super(key: key); }) : super(key: key);
@override @override
@ -18,7 +20,10 @@ class MemorySheet extends StatefulWidget {
} }
class _MemorySheetState extends State<MemorySheet> with Loadable { class _MemorySheetState extends State<MemorySheet> with Loadable {
Future<void> deleteFile() => FileManager.deleteFile(widget.memory.location); Future<void> deleteFile() async {
await FileManager.deleteFile(widget.memory.location);
widget.onMemoryDeleted();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -84,37 +84,40 @@ class _MemorySlideState extends State<MemorySlide>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<MemoryPack>( return Consumer<TimelineOverlay>(
builder: (context, memoryPack, _) => Status( builder: (_, timelineOverlay, __) => Consumer<MemoryPack>(
controller: controller, builder: (___, memoryPack, ____) => Status(
disabled: memoryPack.paused, controller: controller,
child: MemoryView( paused: memoryPack.paused,
creationDate: widget.memory.creationDate, hideProgressBar: !timelineOverlay.showOverlay,
location: widget.memory.location, child: MemoryView(
filename: widget.memory.filename, creationDate: widget.memory.creationDate,
loopVideo: false, location: widget.memory.location,
onFileDownloaded: () { filename: widget.memory.filename,
if (widget.memory.type == MemoryType.photo) { loopVideo: false,
initializeAnimation(DEFAULT_IMAGE_DURATION); onFileDownloaded: () {
} if (widget.memory.type == MemoryType.photo) {
}, initializeAnimation(DEFAULT_IMAGE_DURATION);
onVideoControllerInitialized: (controller) { }
if (mounted) { },
initializeAnimation(controller.value.duration); onVideoControllerInitialized: (controller) {
if (mounted) {
initializeAnimation(controller.value.duration);
memoryPack.addListener(() { memoryPack.addListener(() {
if (!mounted) { if (!mounted) {
return; return;
} }
if (memoryPack.paused) { if (memoryPack.paused) {
controller.pause(); controller.pause();
} else { } else {
controller.play(); controller.play();
} }
}, ['paused']); }, ['paused']);
} }
}, },
),
), ),
), ),
); );

View File

@ -7,12 +7,14 @@ const BAR_HEIGHT = 4.0;
class Status extends StatefulWidget { class Status extends StatefulWidget {
final StatusController? controller; final StatusController? controller;
final Widget child; final Widget child;
final bool disabled; final bool paused;
final bool hideProgressBar;
const Status({ const Status({
Key? key, Key? key,
required this.child, required this.child,
this.disabled = false, this.paused = false,
this.hideProgressBar = false,
this.controller, this.controller,
}) : super(key: key); }) : super(key: key);
@ -32,7 +34,7 @@ class _StatusState extends State<Status> with TickerProviderStateMixin {
initializeAnimation(); initializeAnimation();
} }
if (widget.disabled) { if (widget.paused) {
animationController?.stop(); animationController?.stop();
} else { } else {
animationController?.forward(); animationController?.forward();
@ -86,7 +88,7 @@ class _StatusState extends State<Status> with TickerProviderStateMixin {
child: AnimatedOpacity( child: AnimatedOpacity(
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
curve: Curves.linearToEaseOut, curve: Curves.linearToEaseOut,
opacity: widget.disabled ? 0.0 : 1.0, opacity: widget.hideProgressBar ? 0.0 : 1.0,
child: (widget.controller == null) child: (widget.controller == null)
? ClipRRect( ? ClipRRect(
borderRadius: BorderRadius.circular(HUGE_SPACE), borderRadius: BorderRadius.circular(HUGE_SPACE),

View File

@ -50,6 +50,15 @@ class _TimelinePageState extends State<TimelinePage> {
} }
}, ['state']); }, ['state']);
timelineOverlayController.addListener(() {
if (!mounted) {
return;
}
// Force update to ensure overlays are up-to-date.
setState(() {});
}, ['showOverlay']);
memoryPack.addListener(() { memoryPack.addListener(() {
if (!mounted) { if (!mounted) {
return; return;
@ -102,6 +111,7 @@ class _TimelinePageState extends State<TimelinePage> {
isScrollControlled: true, isScrollControlled: true,
builder: (_) => MemorySheet( builder: (_) => MemorySheet(
memory: memoryPack.currentMemory, memory: memoryPack.currentMemory,
onMemoryDeleted: widget.onMemoryRemoved,
), ),
); );
@ -109,17 +119,16 @@ class _TimelinePageState extends State<TimelinePage> {
return; return;
} }
memoryPack.removeCurrentMemory();
memoryPack.resume(); memoryPack.resume();
widget.onMemoryRemoved();
}, },
onTapDown: (_) { onTapDown: (_) {
final memoryPack = context.read<MemoryPack>(); final memoryPack = context.read<MemoryPack>();
memoryPack.pause();
overlayRemover = Timer( overlayRemover = Timer(
const Duration(milliseconds: 200), const Duration(milliseconds: 600),
memoryPack.pause, timelineOverlayController.hideOverlay,
); );
}, },
onTapUp: (_) { onTapUp: (_) {
@ -127,12 +136,14 @@ class _TimelinePageState extends State<TimelinePage> {
overlayRemover?.cancel(); overlayRemover?.cancel();
memoryPack.resume(); memoryPack.resume();
timelineOverlayController.restoreOverlay();
}, },
onTapCancel: () { onTapCancel: () {
final memoryPack = context.read<MemoryPack>(); final memoryPack = context.read<MemoryPack>();
overlayRemover?.cancel(); overlayRemover?.cancel();
memoryPack.resume(); memoryPack.resume();
timelineOverlayController.restoreOverlay();
}, },
onHorizontalDragEnd: (details) { onHorizontalDragEnd: (details) {
final memoryPack = context.read<MemoryPack>(); final memoryPack = context.read<MemoryPack>();
@ -155,11 +166,11 @@ class _TimelinePageState extends State<TimelinePage> {
}, },
child: ChangeNotifierProvider<TimelineOverlay>( child: ChangeNotifierProvider<TimelineOverlay>(
create: (_) => timelineOverlayController, create: (_) => timelineOverlayController,
child: Consumer<MemoryPack>( child: Stack(
builder: (_, memoryPack, __) => Stack( fit: StackFit.expand,
fit: StackFit.expand, children: <Widget>[
children: <Widget>[ Consumer<MemoryPack>(
PageView.builder( builder: (_, memoryPack, __) => PageView.builder(
controller: pageController, controller: pageController,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@ -169,43 +180,43 @@ class _TimelinePageState extends State<TimelinePage> {
), ),
itemCount: memoryPack.memories.length, itemCount: memoryPack.memories.length,
), ),
Padding( ),
padding: const EdgeInsets.only( Padding(
top: LARGE_SPACE, padding: const EdgeInsets.only(
left: MEDIUM_SPACE, top: LARGE_SPACE,
right: MEDIUM_SPACE, left: MEDIUM_SPACE,
right: MEDIUM_SPACE,
),
child: AnimatedOpacity(
duration: const Duration(milliseconds: 500),
curve: Curves.linearToEaseOut,
opacity: timelineOverlayController.showOverlay ? 1.0 : 0.0,
child: Text(
DateFormat('dd. MMMM yyyy').format(widget.date),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline1,
), ),
),
),
Positioned(
right: SMALL_SPACE,
bottom: SMALL_SPACE * 2,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: SMALL_SPACE),
child: AnimatedOpacity( child: AnimatedOpacity(
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
curve: Curves.linearToEaseOut, curve: Curves.linearToEaseOut,
opacity: memoryPack.paused ? 0.0 : 1.0, opacity: timelineOverlayController.showOverlay ? 1.0 : 0.0,
child: Text( child: Consumer<MemoryPack>(
DateFormat('dd. MMMM yyyy').format(widget.date), builder: (_, memoryPack, __) => Text(
textAlign: TextAlign.center, '${memoryPack.currentMemoryIndex + 1}/${memoryPack.memories.length}',
style: Theme.of(context).textTheme.headline1, style: Theme.of(context).textTheme.titleSmall,
),
),
),
Positioned(
right: SMALL_SPACE,
bottom: SMALL_SPACE * 2,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: SMALL_SPACE),
child: AnimatedOpacity(
duration: const Duration(milliseconds: 500),
curve: Curves.linearToEaseOut,
opacity: memoryPack.paused ? 0.0 : 1.0,
child: Consumer<MemoryPack>(
builder: (_, memoryPack, __) => Text(
'${memoryPack.currentMemoryIndex + 1}/${memoryPack.memories.length}',
style: Theme.of(context).textTheme.titleSmall,
),
), ),
), ),
), ),
), ),
], ),
), ],
), ),
), ),
); );