diff --git a/lib/widgets/memory_sheet.dart b/lib/widgets/memory_sheet.dart index cac48e7..d475e95 100644 --- a/lib/widgets/memory_sheet.dart +++ b/lib/widgets/memory_sheet.dart @@ -7,10 +7,12 @@ import 'package:share_location/widgets/modal_sheet.dart'; class MemorySheet extends StatefulWidget { final Memory memory; + final VoidCallback onMemoryDeleted; const MemorySheet({ Key? key, required this.memory, + required this.onMemoryDeleted, }) : super(key: key); @override @@ -18,7 +20,10 @@ class MemorySheet extends StatefulWidget { } class _MemorySheetState extends State with Loadable { - Future deleteFile() => FileManager.deleteFile(widget.memory.location); + Future deleteFile() async { + await FileManager.deleteFile(widget.memory.location); + widget.onMemoryDeleted(); + } @override Widget build(BuildContext context) { diff --git a/lib/widgets/memory_slide.dart b/lib/widgets/memory_slide.dart index 7677005..de9bc27 100644 --- a/lib/widgets/memory_slide.dart +++ b/lib/widgets/memory_slide.dart @@ -84,37 +84,40 @@ class _MemorySlideState extends State @override Widget build(BuildContext context) { - return Consumer( - builder: (context, memoryPack, _) => Status( - controller: controller, - disabled: memoryPack.paused, - child: MemoryView( - creationDate: widget.memory.creationDate, - location: widget.memory.location, - filename: widget.memory.filename, - loopVideo: false, - onFileDownloaded: () { - if (widget.memory.type == MemoryType.photo) { - initializeAnimation(DEFAULT_IMAGE_DURATION); - } - }, - onVideoControllerInitialized: (controller) { - if (mounted) { - initializeAnimation(controller.value.duration); + return Consumer( + builder: (_, timelineOverlay, __) => Consumer( + builder: (___, memoryPack, ____) => Status( + controller: controller, + paused: memoryPack.paused, + hideProgressBar: !timelineOverlay.showOverlay, + child: MemoryView( + creationDate: widget.memory.creationDate, + location: widget.memory.location, + filename: widget.memory.filename, + loopVideo: false, + onFileDownloaded: () { + if (widget.memory.type == MemoryType.photo) { + initializeAnimation(DEFAULT_IMAGE_DURATION); + } + }, + onVideoControllerInitialized: (controller) { + if (mounted) { + initializeAnimation(controller.value.duration); - memoryPack.addListener(() { - if (!mounted) { - return; - } + memoryPack.addListener(() { + if (!mounted) { + return; + } - if (memoryPack.paused) { - controller.pause(); - } else { - controller.play(); - } - }, ['paused']); - } - }, + if (memoryPack.paused) { + controller.pause(); + } else { + controller.play(); + } + }, ['paused']); + } + }, + ), ), ), ); diff --git a/lib/widgets/status.dart b/lib/widgets/status.dart index ec4fc61..4d8ce0e 100644 --- a/lib/widgets/status.dart +++ b/lib/widgets/status.dart @@ -7,12 +7,14 @@ const BAR_HEIGHT = 4.0; class Status extends StatefulWidget { final StatusController? controller; final Widget child; - final bool disabled; + final bool paused; + final bool hideProgressBar; const Status({ Key? key, required this.child, - this.disabled = false, + this.paused = false, + this.hideProgressBar = false, this.controller, }) : super(key: key); @@ -32,7 +34,7 @@ class _StatusState extends State with TickerProviderStateMixin { initializeAnimation(); } - if (widget.disabled) { + if (widget.paused) { animationController?.stop(); } else { animationController?.forward(); @@ -86,7 +88,7 @@ class _StatusState extends State with TickerProviderStateMixin { child: AnimatedOpacity( duration: const Duration(milliseconds: 500), curve: Curves.linearToEaseOut, - opacity: widget.disabled ? 0.0 : 1.0, + opacity: widget.hideProgressBar ? 0.0 : 1.0, child: (widget.controller == null) ? ClipRRect( borderRadius: BorderRadius.circular(HUGE_SPACE), diff --git a/lib/widgets/timeline_page.dart b/lib/widgets/timeline_page.dart index 2995e6e..0189d2f 100644 --- a/lib/widgets/timeline_page.dart +++ b/lib/widgets/timeline_page.dart @@ -50,6 +50,15 @@ class _TimelinePageState extends State { } }, ['state']); + timelineOverlayController.addListener(() { + if (!mounted) { + return; + } + + // Force update to ensure overlays are up-to-date. + setState(() {}); + }, ['showOverlay']); + memoryPack.addListener(() { if (!mounted) { return; @@ -102,6 +111,7 @@ class _TimelinePageState extends State { isScrollControlled: true, builder: (_) => MemorySheet( memory: memoryPack.currentMemory, + onMemoryDeleted: widget.onMemoryRemoved, ), ); @@ -109,17 +119,16 @@ class _TimelinePageState extends State { return; } - memoryPack.removeCurrentMemory(); memoryPack.resume(); - - widget.onMemoryRemoved(); }, onTapDown: (_) { final memoryPack = context.read(); + memoryPack.pause(); + overlayRemover = Timer( - const Duration(milliseconds: 200), - memoryPack.pause, + const Duration(milliseconds: 600), + timelineOverlayController.hideOverlay, ); }, onTapUp: (_) { @@ -127,12 +136,14 @@ class _TimelinePageState extends State { overlayRemover?.cancel(); memoryPack.resume(); + timelineOverlayController.restoreOverlay(); }, onTapCancel: () { final memoryPack = context.read(); overlayRemover?.cancel(); memoryPack.resume(); + timelineOverlayController.restoreOverlay(); }, onHorizontalDragEnd: (details) { final memoryPack = context.read(); @@ -155,11 +166,11 @@ class _TimelinePageState extends State { }, child: ChangeNotifierProvider( create: (_) => timelineOverlayController, - child: Consumer( - builder: (_, memoryPack, __) => Stack( - fit: StackFit.expand, - children: [ - PageView.builder( + child: Stack( + fit: StackFit.expand, + children: [ + Consumer( + builder: (_, memoryPack, __) => PageView.builder( controller: pageController, physics: const NeverScrollableScrollPhysics(), scrollDirection: Axis.horizontal, @@ -169,43 +180,43 @@ class _TimelinePageState extends State { ), itemCount: memoryPack.memories.length, ), - Padding( - padding: const EdgeInsets.only( - top: LARGE_SPACE, - left: MEDIUM_SPACE, - right: MEDIUM_SPACE, + ), + Padding( + padding: const EdgeInsets.only( + top: LARGE_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( duration: const Duration(milliseconds: 500), curve: Curves.linearToEaseOut, - opacity: memoryPack.paused ? 0.0 : 1.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( - duration: const Duration(milliseconds: 500), - curve: Curves.linearToEaseOut, - opacity: memoryPack.paused ? 0.0 : 1.0, - child: Consumer( - builder: (_, memoryPack, __) => Text( - '${memoryPack.currentMemoryIndex + 1}/${memoryPack.memories.length}', - style: Theme.of(context).textTheme.titleSmall, - ), + opacity: timelineOverlayController.showOverlay ? 1.0 : 0.0, + child: Consumer( + builder: (_, memoryPack, __) => Text( + '${memoryPack.currentMemoryIndex + 1}/${memoryPack.memories.length}', + style: Theme.of(context).textTheme.titleSmall, ), ), ), ), - ], - ), + ), + ], ), ), );