removed TimelineOverlayModel in favor of TimelineModel

This commit is contained in:
Myzel394 2022-08-16 19:52:42 +02:00
parent 518edaff0d
commit c817452d06
5 changed files with 96 additions and 171 deletions

View File

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'package:property_change_notifier/property_change_notifier.dart'; import 'package:property_change_notifier/property_change_notifier.dart';
@ -19,6 +20,8 @@ class TimelineModel extends PropertyChangeNotifier<String> {
int _memoryIndex = 0; int _memoryIndex = 0;
bool _paused = false; bool _paused = false;
bool _isInitializing = false; bool _isInitializing = false;
bool _showOverlay = true;
Timer? _overlayRemoverTimer;
Map<DateTime, List<Memory>> get values => _timeline; Map<DateTime, List<Memory>> get values => _timeline;
int get length => _timeline.length; int get length => _timeline.length;
@ -26,6 +29,7 @@ class TimelineModel extends PropertyChangeNotifier<String> {
int get memoryIndex => _memoryIndex; int get memoryIndex => _memoryIndex;
bool get paused => _paused; bool get paused => _paused;
bool get isInitializing => _isInitializing; bool get isInitializing => _isInitializing;
bool get showOverlay => _showOverlay;
DateTime dateAtIndex(final int index) => _timeline.keys.elementAt(index); DateTime dateAtIndex(final int index) => _timeline.keys.elementAt(index);
@ -42,6 +46,9 @@ class TimelineModel extends PropertyChangeNotifier<String> {
static DateTime createDateKey(final DateTime date) => static DateTime createDateKey(final DateTime date) =>
DateTime(date.year, date.month, date.day); DateTime(date.year, date.month, date.day);
void restoreOverlay() => setShowOverlay(true);
void hideOverlay() => setShowOverlay(false);
static Map<DateTime, List<Memory>> mapFromMemoriesList( static Map<DateTime, List<Memory>> mapFromMemoriesList(
final List<Memory> memories, final List<Memory> memories,
) { ) {
@ -76,19 +83,37 @@ class TimelineModel extends PropertyChangeNotifier<String> {
_timeline.values.elementAt(_currentIndex).length - 1, _timeline.values.elementAt(_currentIndex).length - 1,
max(0, index), max(0, index),
); );
resume();
notifyListeners('memoryIndex'); notifyListeners('memoryIndex');
} }
void setPaused(bool paused) { void setPaused(final bool paused) {
_paused = paused; _paused = paused;
_overlayRemoverTimer?.cancel();
if (paused) {
_overlayRemoverTimer = Timer(
const Duration(milliseconds: 600),
hideOverlay,
);
} else {
restoreOverlay();
}
notifyListeners('paused'); notifyListeners('paused');
} }
void setIsInitializing(bool isInitializing) { void setIsInitializing(final bool isInitializing) {
_isInitializing = isInitializing; _isInitializing = isInitializing;
notifyListeners('isInitializing'); notifyListeners('isInitializing');
} }
void setShowOverlay(final bool showOverlay) {
_showOverlay = showOverlay;
notifyListeners('showOverlay');
}
void pause() => setPaused(true); void pause() => setPaused(true);
void resume() => setPaused(false); void resume() => setPaused(false);

View File

@ -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();
}
}

View File

@ -4,7 +4,6 @@ import 'package:share_location/controllers/status_controller.dart';
import 'package:share_location/enums.dart'; import 'package:share_location/enums.dart';
import 'package:share_location/foreign_types/memory.dart'; import 'package:share_location/foreign_types/memory.dart';
import 'package:share_location/models/timeline.dart'; import 'package:share_location/models/timeline.dart';
import 'package:share_location/models/timeline_overlay.dart';
import 'package:share_location/widgets/status.dart'; import 'package:share_location/widgets/status.dart';
import 'memory.dart'; import 'memory.dart';
@ -34,21 +33,19 @@ class _MemorySlideState extends State<MemorySlide>
void initState() { void initState() {
super.initState(); super.initState();
final timelineOverlay = context.read<TimelineOverlayModel>(); final timeline = context.read<TimelineModel>();
timelineOverlay.addListener(() { timeline.addListener(() {
if (!mounted) { if (!mounted) {
return; return;
} }
switch (timelineOverlay.state) { if (timeline.paused) {
case TimelineState.playing:
controller?.start();
break;
default:
controller?.stop(); controller?.stop();
} else {
controller?.start();
} }
}); }, ['paused']);
} }
@override @override
@ -59,8 +56,6 @@ class _MemorySlideState extends State<MemorySlide>
} }
void initializeAnimation(final Duration newDuration) { void initializeAnimation(final Duration newDuration) {
final timelineOverlay = context.read<TimelineOverlayModel>();
duration = newDuration; duration = newDuration;
controller = StatusController( controller = StatusController(
@ -75,7 +70,6 @@ class _MemorySlideState extends State<MemorySlide>
final timeline = context.read<TimelineModel>(); final timeline = context.read<TimelineModel>();
if (controller!.done) { if (controller!.done) {
timelineOverlay.reset();
timeline.nextMemory(); timeline.nextMemory();
} }
}, ['done']); }, ['done']);
@ -85,12 +79,11 @@ class _MemorySlideState extends State<MemorySlide>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<TimelineOverlayModel>( return Consumer<TimelineModel>(
builder: (_, timelineOverlay, __) => Consumer<TimelineModel>(
builder: (___, timeline, ____) => Status( builder: (___, timeline, ____) => Status(
controller: controller, controller: controller,
paused: timeline.paused, paused: timeline.paused,
hideProgressBar: !timelineOverlay.showOverlay, hideProgressBar: !timeline.showOverlay,
child: MemoryView( child: MemoryView(
memory: widget.memory, memory: widget.memory,
loopVideo: false, loopVideo: false,
@ -118,7 +111,6 @@ class _MemorySlideState extends State<MemorySlide>
}, },
), ),
), ),
),
); );
} }
} }

View File

@ -3,7 +3,6 @@ import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:share_location/constants/spacing.dart'; import 'package:share_location/constants/spacing.dart';
import 'package:share_location/models/timeline.dart'; import 'package:share_location/models/timeline.dart';
import 'package:share_location/models/timeline_overlay.dart';
class TimelineOverlay extends StatelessWidget { class TimelineOverlay extends StatelessWidget {
final DateTime date; final DateTime date;
@ -21,7 +20,6 @@ class TimelineOverlay extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final timeline = context.watch<TimelineModel>(); final timeline = context.watch<TimelineModel>();
final overlayController = context.watch<TimelineOverlayModel>();
return Stack( return Stack(
children: <Widget>[ children: <Widget>[
@ -34,7 +32,7 @@ class TimelineOverlay extends StatelessWidget {
child: AnimatedOpacity( child: AnimatedOpacity(
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
curve: Curves.linearToEaseOut, curve: Curves.linearToEaseOut,
opacity: overlayController.showOverlay ? 1.0 : 0.0, opacity: timeline.showOverlay ? 1.0 : 0.0,
child: Text( child: Text(
DateFormat('dd. MMMM yyyy').format(date), DateFormat('dd. MMMM yyyy').format(date),
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -50,7 +48,7 @@ class TimelineOverlay extends StatelessWidget {
child: AnimatedOpacity( child: AnimatedOpacity(
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
curve: Curves.linearToEaseOut, curve: Curves.linearToEaseOut,
opacity: overlayController.showOverlay ? 1.0 : 0.0, opacity: timeline.showOverlay ? 1.0 : 0.0,
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
AnimatedOpacity( AnimatedOpacity(

View File

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:share_location/foreign_types/memory.dart'; import 'package:share_location/foreign_types/memory.dart';
import 'package:share_location/models/timeline.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_sheet.dart';
import 'package:share_location/widgets/memory_slide.dart'; import 'package:share_location/widgets/memory_slide.dart';
import 'package:share_location/widgets/timeline_overlay.dart'; import 'package:share_location/widgets/timeline_overlay.dart';
@ -24,26 +23,18 @@ class TimelinePage extends StatefulWidget {
} }
class _TimelinePageState extends State<TimelinePage> { class _TimelinePageState extends State<TimelinePage> {
final timelineOverlayController = TimelineOverlayModel();
final pageController = PageController(); final pageController = PageController();
Timer? overlayRemover; Timer? overlayRemover;
void _handleOverlayChangeBasedOnMemoryPack() { @override
if (!mounted) { void initState() {
return; super.initState();
}
final timeline = context.read<TimelineModel>(); final timeline = context.read<TimelineModel>();
if (timeline.paused) { // Jump to correct page
timelineOverlayController.hideOverlay(); timeline.addListener(() {
} else {
timelineOverlayController.restoreOverlay();
}
}
void _jumpToCorrectPage() {
if (!mounted) { if (!mounted) {
return; return;
} }
@ -57,41 +48,13 @@ class _TimelinePageState extends State<TimelinePage> {
curve: Curves.easeOutQuad, curve: Curves.easeOutQuad,
); );
} }
} }, ['memoryIndex']);
@override
void initState() {
super.initState();
final timeline = context.read<TimelineModel>();
timelineOverlayController.addListener(() {
if (!mounted) {
return;
}
// Force update to ensure overlays are up-to-date.
setState(() {});
}, ['showOverlay']);
timelineOverlayController
.addListener(_handleOverlayChangeBasedOnMemoryPack, ['state']);
timeline.addListener(_jumpToCorrectPage, ['memoryIndex']);
} }
@override @override
void dispose() { void dispose() {
pageController.dispose(); pageController.dispose();
try {
final timeline = context.read<TimelineModel>();
timeline.removeListener(_jumpToCorrectPage);
} catch (error) {
// Timeline has been removed completely
}
super.dispose(); super.dispose();
} }
@ -119,24 +82,9 @@ class _TimelinePageState extends State<TimelinePage> {
timeline.resume(); timeline.resume();
}, },
onTapDown: (_) { onTapDown: (_) => timeline.pause(),
timeline.pause(); onTapUp: (_) => timeline.resume(),
onTapCancel: () => timeline.resume(),
overlayRemover = Timer(
const Duration(milliseconds: 600),
timelineOverlayController.hideOverlay,
);
},
onTapUp: (_) {
overlayRemover?.cancel();
timeline.resume();
timelineOverlayController.restoreOverlay();
},
onTapCancel: () {
overlayRemover?.cancel();
timeline.resume();
timelineOverlayController.restoreOverlay();
},
onHorizontalDragEnd: (details) { onHorizontalDragEnd: (details) {
if (details.primaryVelocity! < 0) { if (details.primaryVelocity! < 0) {
timeline.nextMemory(); timeline.nextMemory();
@ -144,8 +92,6 @@ class _TimelinePageState extends State<TimelinePage> {
timeline.previousMemory(); timeline.previousMemory();
} }
}, },
child: ChangeNotifierProvider.value(
value: timelineOverlayController,
child: Stack( child: Stack(
fit: StackFit.expand, fit: StackFit.expand,
children: <Widget>[ children: <Widget>[
@ -166,7 +112,6 @@ class _TimelinePageState extends State<TimelinePage> {
), ),
], ],
), ),
),
); );
} }
} }