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 '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);

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/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']);
}
},
),
),
);

View File

@ -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(

View File

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