mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-19 07:35:26 +02:00
removed TimelineOverlayModel
in favor of TimelineModel
This commit is contained in:
parent
518edaff0d
commit
c817452d06
@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:property_change_notifier/property_change_notifier.dart';
|
||||
@ -19,6 +20,8 @@ class TimelineModel extends PropertyChangeNotifier<String> {
|
||||
int _memoryIndex = 0;
|
||||
bool _paused = false;
|
||||
bool _isInitializing = false;
|
||||
bool _showOverlay = true;
|
||||
Timer? _overlayRemoverTimer;
|
||||
|
||||
Map<DateTime, List<Memory>> get values => _timeline;
|
||||
int get length => _timeline.length;
|
||||
@ -26,6 +29,7 @@ class TimelineModel extends PropertyChangeNotifier<String> {
|
||||
int get memoryIndex => _memoryIndex;
|
||||
bool get paused => _paused;
|
||||
bool get isInitializing => _isInitializing;
|
||||
bool get showOverlay => _showOverlay;
|
||||
|
||||
DateTime dateAtIndex(final int index) => _timeline.keys.elementAt(index);
|
||||
|
||||
@ -42,6 +46,9 @@ class TimelineModel extends PropertyChangeNotifier<String> {
|
||||
static DateTime createDateKey(final DateTime date) =>
|
||||
DateTime(date.year, date.month, date.day);
|
||||
|
||||
void restoreOverlay() => setShowOverlay(true);
|
||||
void hideOverlay() => setShowOverlay(false);
|
||||
|
||||
static Map<DateTime, List<Memory>> mapFromMemoriesList(
|
||||
final List<Memory> memories,
|
||||
) {
|
||||
@ -76,19 +83,37 @@ class TimelineModel extends PropertyChangeNotifier<String> {
|
||||
_timeline.values.elementAt(_currentIndex).length - 1,
|
||||
max(0, index),
|
||||
);
|
||||
resume();
|
||||
notifyListeners('memoryIndex');
|
||||
}
|
||||
|
||||
void setPaused(bool paused) {
|
||||
void setPaused(final bool paused) {
|
||||
_paused = paused;
|
||||
|
||||
_overlayRemoverTimer?.cancel();
|
||||
|
||||
if (paused) {
|
||||
_overlayRemoverTimer = Timer(
|
||||
const Duration(milliseconds: 600),
|
||||
hideOverlay,
|
||||
);
|
||||
} else {
|
||||
restoreOverlay();
|
||||
}
|
||||
|
||||
notifyListeners('paused');
|
||||
}
|
||||
|
||||
void setIsInitializing(bool isInitializing) {
|
||||
void setIsInitializing(final bool isInitializing) {
|
||||
_isInitializing = isInitializing;
|
||||
notifyListeners('isInitializing');
|
||||
}
|
||||
|
||||
void setShowOverlay(final bool showOverlay) {
|
||||
_showOverlay = showOverlay;
|
||||
notifyListeners('showOverlay');
|
||||
}
|
||||
|
||||
void pause() => setPaused(true);
|
||||
void resume() => setPaused(false);
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
import 'package:property_change_notifier/property_change_notifier.dart';
|
||||
|
||||
enum TimelineState {
|
||||
loading,
|
||||
paused,
|
||||
playing,
|
||||
completed,
|
||||
}
|
||||
|
||||
class TimelineOverlayModel extends PropertyChangeNotifier<String> {
|
||||
bool _showOverlay = true;
|
||||
TimelineState _state = TimelineState.loading;
|
||||
|
||||
bool get showOverlay => _showOverlay;
|
||||
TimelineState get state => _state;
|
||||
|
||||
void hideOverlay() => setShowOverlay(false);
|
||||
void restoreOverlay() => setShowOverlay(true);
|
||||
|
||||
void setShowOverlay(bool showOverlay) {
|
||||
_showOverlay = showOverlay;
|
||||
notifyListeners('showOverlay');
|
||||
}
|
||||
|
||||
void setState(TimelineState state) {
|
||||
_state = state;
|
||||
notifyListeners('state');
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_showOverlay = true;
|
||||
_state = TimelineState.loading;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ import 'package:share_location/controllers/status_controller.dart';
|
||||
import 'package:share_location/enums.dart';
|
||||
import 'package:share_location/foreign_types/memory.dart';
|
||||
import 'package:share_location/models/timeline.dart';
|
||||
import 'package:share_location/models/timeline_overlay.dart';
|
||||
import 'package:share_location/widgets/status.dart';
|
||||
|
||||
import 'memory.dart';
|
||||
@ -34,21 +33,19 @@ class _MemorySlideState extends State<MemorySlide>
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
final timelineOverlay = context.read<TimelineOverlayModel>();
|
||||
final timeline = context.read<TimelineModel>();
|
||||
|
||||
timelineOverlay.addListener(() {
|
||||
timeline.addListener(() {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (timelineOverlay.state) {
|
||||
case TimelineState.playing:
|
||||
controller?.start();
|
||||
break;
|
||||
default:
|
||||
controller?.stop();
|
||||
if (timeline.paused) {
|
||||
controller?.stop();
|
||||
} else {
|
||||
controller?.start();
|
||||
}
|
||||
});
|
||||
}, ['paused']);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -59,8 +56,6 @@ class _MemorySlideState extends State<MemorySlide>
|
||||
}
|
||||
|
||||
void initializeAnimation(final Duration newDuration) {
|
||||
final timelineOverlay = context.read<TimelineOverlayModel>();
|
||||
|
||||
duration = newDuration;
|
||||
|
||||
controller = StatusController(
|
||||
@ -75,7 +70,6 @@ class _MemorySlideState extends State<MemorySlide>
|
||||
final timeline = context.read<TimelineModel>();
|
||||
|
||||
if (controller!.done) {
|
||||
timelineOverlay.reset();
|
||||
timeline.nextMemory();
|
||||
}
|
||||
}, ['done']);
|
||||
@ -85,38 +79,36 @@ class _MemorySlideState extends State<MemorySlide>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<TimelineOverlayModel>(
|
||||
builder: (_, timelineOverlay, __) => Consumer<TimelineModel>(
|
||||
builder: (___, timeline, ____) => Status(
|
||||
controller: controller,
|
||||
paused: timeline.paused,
|
||||
hideProgressBar: !timelineOverlay.showOverlay,
|
||||
child: MemoryView(
|
||||
memory: widget.memory,
|
||||
loopVideo: false,
|
||||
onFileDownloaded: () {
|
||||
if (widget.memory.type == MemoryType.photo) {
|
||||
initializeAnimation(DEFAULT_IMAGE_DURATION);
|
||||
}
|
||||
},
|
||||
onVideoControllerInitialized: (controller) {
|
||||
if (mounted) {
|
||||
initializeAnimation(controller.value.duration);
|
||||
return Consumer<TimelineModel>(
|
||||
builder: (___, timeline, ____) => Status(
|
||||
controller: controller,
|
||||
paused: timeline.paused,
|
||||
hideProgressBar: !timeline.showOverlay,
|
||||
child: MemoryView(
|
||||
memory: widget.memory,
|
||||
loopVideo: false,
|
||||
onFileDownloaded: () {
|
||||
if (widget.memory.type == MemoryType.photo) {
|
||||
initializeAnimation(DEFAULT_IMAGE_DURATION);
|
||||
}
|
||||
},
|
||||
onVideoControllerInitialized: (controller) {
|
||||
if (mounted) {
|
||||
initializeAnimation(controller.value.duration);
|
||||
|
||||
timeline.addListener(() {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
timeline.addListener(() {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeline.paused) {
|
||||
controller.pause();
|
||||
} else {
|
||||
controller.play();
|
||||
}
|
||||
}, ['paused']);
|
||||
}
|
||||
},
|
||||
),
|
||||
if (timeline.paused) {
|
||||
controller.pause();
|
||||
} else {
|
||||
controller.play();
|
||||
}
|
||||
}, ['paused']);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -3,7 +3,6 @@ import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:share_location/constants/spacing.dart';
|
||||
import 'package:share_location/models/timeline.dart';
|
||||
import 'package:share_location/models/timeline_overlay.dart';
|
||||
|
||||
class TimelineOverlay extends StatelessWidget {
|
||||
final DateTime date;
|
||||
@ -21,7 +20,6 @@ class TimelineOverlay extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final timeline = context.watch<TimelineModel>();
|
||||
final overlayController = context.watch<TimelineOverlayModel>();
|
||||
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
@ -34,7 +32,7 @@ class TimelineOverlay extends StatelessWidget {
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.linearToEaseOut,
|
||||
opacity: overlayController.showOverlay ? 1.0 : 0.0,
|
||||
opacity: timeline.showOverlay ? 1.0 : 0.0,
|
||||
child: Text(
|
||||
DateFormat('dd. MMMM yyyy').format(date),
|
||||
textAlign: TextAlign.center,
|
||||
@ -50,7 +48,7 @@ class TimelineOverlay extends StatelessWidget {
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.linearToEaseOut,
|
||||
opacity: overlayController.showOverlay ? 1.0 : 0.0,
|
||||
opacity: timeline.showOverlay ? 1.0 : 0.0,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
AnimatedOpacity(
|
||||
|
@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:share_location/foreign_types/memory.dart';
|
||||
import 'package:share_location/models/timeline.dart';
|
||||
import 'package:share_location/models/timeline_overlay.dart';
|
||||
import 'package:share_location/widgets/memory_sheet.dart';
|
||||
import 'package:share_location/widgets/memory_slide.dart';
|
||||
import 'package:share_location/widgets/timeline_overlay.dart';
|
||||
@ -24,74 +23,38 @@ class TimelinePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _TimelinePageState extends State<TimelinePage> {
|
||||
final timelineOverlayController = TimelineOverlayModel();
|
||||
final pageController = PageController();
|
||||
|
||||
Timer? overlayRemover;
|
||||
|
||||
void _handleOverlayChangeBasedOnMemoryPack() {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
final timeline = context.read<TimelineModel>();
|
||||
|
||||
if (timeline.paused) {
|
||||
timelineOverlayController.hideOverlay();
|
||||
} else {
|
||||
timelineOverlayController.restoreOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
void _jumpToCorrectPage() {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
final timeline = context.read<TimelineModel>();
|
||||
|
||||
if (timeline.memoryIndex != pageController.page) {
|
||||
pageController.animateToPage(
|
||||
timeline.memoryIndex,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOutQuad,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
final timeline = context.read<TimelineModel>();
|
||||
|
||||
timelineOverlayController.addListener(() {
|
||||
// Jump to correct page
|
||||
timeline.addListener(() {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force update to ensure overlays are up-to-date.
|
||||
setState(() {});
|
||||
}, ['showOverlay']);
|
||||
final timeline = context.read<TimelineModel>();
|
||||
|
||||
timelineOverlayController
|
||||
.addListener(_handleOverlayChangeBasedOnMemoryPack, ['state']);
|
||||
|
||||
timeline.addListener(_jumpToCorrectPage, ['memoryIndex']);
|
||||
if (timeline.memoryIndex != pageController.page) {
|
||||
pageController.animateToPage(
|
||||
timeline.memoryIndex,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOutQuad,
|
||||
);
|
||||
}
|
||||
}, ['memoryIndex']);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
pageController.dispose();
|
||||
|
||||
try {
|
||||
final timeline = context.read<TimelineModel>();
|
||||
|
||||
timeline.removeListener(_jumpToCorrectPage);
|
||||
} catch (error) {
|
||||
// Timeline has been removed completely
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -119,24 +82,9 @@ class _TimelinePageState extends State<TimelinePage> {
|
||||
|
||||
timeline.resume();
|
||||
},
|
||||
onTapDown: (_) {
|
||||
timeline.pause();
|
||||
|
||||
overlayRemover = Timer(
|
||||
const Duration(milliseconds: 600),
|
||||
timelineOverlayController.hideOverlay,
|
||||
);
|
||||
},
|
||||
onTapUp: (_) {
|
||||
overlayRemover?.cancel();
|
||||
timeline.resume();
|
||||
timelineOverlayController.restoreOverlay();
|
||||
},
|
||||
onTapCancel: () {
|
||||
overlayRemover?.cancel();
|
||||
timeline.resume();
|
||||
timelineOverlayController.restoreOverlay();
|
||||
},
|
||||
onTapDown: (_) => timeline.pause(),
|
||||
onTapUp: (_) => timeline.resume(),
|
||||
onTapCancel: () => timeline.resume(),
|
||||
onHorizontalDragEnd: (details) {
|
||||
if (details.primaryVelocity! < 0) {
|
||||
timeline.nextMemory();
|
||||
@ -144,28 +92,25 @@ class _TimelinePageState extends State<TimelinePage> {
|
||||
timeline.previousMemory();
|
||||
}
|
||||
},
|
||||
child: ChangeNotifierProvider.value(
|
||||
value: timelineOverlayController,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
PageView.builder(
|
||||
controller: pageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (_, index) => MemorySlide(
|
||||
key: Key(widget.memories[index].filename),
|
||||
memory: widget.memories[index],
|
||||
),
|
||||
itemCount: widget.memories.length,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: <Widget>[
|
||||
PageView.builder(
|
||||
controller: pageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (_, index) => MemorySlide(
|
||||
key: Key(widget.memories[index].filename),
|
||||
memory: widget.memories[index],
|
||||
),
|
||||
TimelineOverlay(
|
||||
date: widget.date,
|
||||
memoriesAmount: widget.memories.length,
|
||||
memoryIndex: timeline.memoryIndex + 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
itemCount: widget.memories.length,
|
||||
),
|
||||
TimelineOverlay(
|
||||
date: widget.date,
|
||||
memoriesAmount: widget.memories.length,
|
||||
memoryIndex: timeline.memoryIndex + 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user