mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-21 00:20:29 +02:00
improved memory timeline
This commit is contained in:
parent
13ea760cb8
commit
9671e2f578
@ -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) {
|
||||||
|
@ -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']);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -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),
|
||||||
|
@ -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,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user