From b4c0015847250ed652538f84a261787f5515032b Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 01:20:00 +0100 Subject: [PATCH 01/54] added workout widget and workout provider to handle different workout phases and durations --- lib/pages/interval_page.dart | 11 ++++++++- lib/pages/main_page.dart | 2 +- lib/providers/timer_provider.dart | 2 +- lib/providers/workout_provider.dart | 33 +++++++++++++++++++++++++++ lib/widgets/workout_timer_widget.dart | 31 +++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 lib/providers/workout_provider.dart create mode 100644 lib/widgets/workout_timer_widget.dart diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index f6d2fcd..74ccffa 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -3,8 +3,10 @@ import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; +import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/widgets/popup_for_start_and_stop.dart'; import 'package:smoke_cess_app/widgets/timer_widget.dart'; +import 'package:smoke_cess_app/widgets/workout_timer_widget.dart'; import '../providers/input_provider.dart'; @@ -168,7 +170,14 @@ class _IntervalTimerPageState extends State { @override Widget build(BuildContext context) { - return ChangeNotifierProvider( + return MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => TimerProvider()), + ChangeNotifierProvider(create: (context) => WorkoutProvider()) + ], + child: WorkoutTimerWidget(), + ); + ChangeNotifierProvider( create: (context) => TimerProvider(), child: TimerWidget( duration: Duration(seconds: 5), diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 2af4f13..9b6127f 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -15,7 +15,7 @@ class MyHomePage extends StatefulWidget { } class MyHomePageState extends State { - int _selectedIndex = 4; + int _selectedIndex = 2; int? _gruppe; final List _titles = [ diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart index 0601b39..f5a7689 100644 --- a/lib/providers/timer_provider.dart +++ b/lib/providers/timer_provider.dart @@ -9,9 +9,9 @@ class TimerProvider extends ChangeNotifier { void startTimer(Duration duration) { started = true; - print('starting timer'); _timer = Timer.periodic(const Duration(seconds: 1), ((timer) { if (timer.tick >= duration.inSeconds) { + print(elapsedSeconds); timer.cancel(); started = false; } diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart new file mode 100644 index 0000000..0505347 --- /dev/null +++ b/lib/providers/workout_provider.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class WorkoutProvider extends ChangeNotifier { + final List _workoutPhases = [ + 'Warm-Up', + 'High Intensity', + 'Low Intensity', + 'High Intensity', + 'Low Intensity', + 'High Intensity', + 'Low Intensity', + 'High Intensity', + 'Cool-down' + ]; + final Map _phasesDuration = { + 'Warm-Up': const Duration(seconds: 5), + 'High Intensity': const Duration(seconds: 4), + 'Low Intensity': const Duration(seconds: 3), + 'Cool-down': const Duration(seconds: 5) + }; + int _workoutPhaseIndex = 0; + + String get currentPhase => _workoutPhases[_workoutPhaseIndex]; + Duration get currentPhaseDuration => + _phasesDuration[currentPhase] ?? const Duration(seconds: 0); + + void nextPhase() { + _workoutPhaseIndex < _workoutPhases.length + ? _workoutPhaseIndex += 1 + : _workoutPhaseIndex = 0; + //notifyListeners(); + } +} diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart new file mode 100644 index 0000000..1ba501c --- /dev/null +++ b/lib/widgets/workout_timer_widget.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/workout_provider.dart'; +import 'package:smoke_cess_app/widgets/timer_widget.dart'; + +import '../providers/timer_provider.dart'; + +class WorkoutTimerWidget extends StatelessWidget { + const WorkoutTimerWidget({super.key}); + + @override + Widget build(BuildContext context) { + TimerProvider timerProvider = context.watch(); + WorkoutProvider workoutProvider = context.watch(); + + if (timerProvider.elapsedSeconds == + workoutProvider.currentPhaseDuration.inSeconds) { + print('Timer abgelaufen'); + workoutProvider.nextPhase(); + timerProvider.startTimer(workoutProvider.currentPhaseDuration); + } + + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(workoutProvider.currentPhase), + TimerWidget(duration: workoutProvider.currentPhaseDuration) + ], + ); + } +} From b01485f27ab07303512c4b8d5639d6c172032946 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Tue, 28 Feb 2023 13:05:51 +0100 Subject: [PATCH 02/54] playing music and iterating throug workout --- lib/pages/interval_page.dart | 6 ++++-- lib/providers/timer_provider.dart | 1 - lib/providers/workout_provider.dart | 26 ++++++++++++++++++++++---- lib/widgets/workout_timer_widget.dart | 6 +++--- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index 74ccffa..3537f03 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -170,10 +170,12 @@ class _IntervalTimerPageState extends State { @override Widget build(BuildContext context) { + TimerProvider timerProvider = TimerProvider(); return MultiProvider( providers: [ - ChangeNotifierProvider(create: (context) => TimerProvider()), - ChangeNotifierProvider(create: (context) => WorkoutProvider()) + ChangeNotifierProvider(create: (context) => timerProvider), + ChangeNotifierProvider( + create: (context) => WorkoutProvider(timerProvider)) ], child: WorkoutTimerWidget(), ); diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart index f5a7689..8073309 100644 --- a/lib/providers/timer_provider.dart +++ b/lib/providers/timer_provider.dart @@ -11,7 +11,6 @@ class TimerProvider extends ChangeNotifier { started = true; _timer = Timer.periodic(const Duration(seconds: 1), ((timer) { if (timer.tick >= duration.inSeconds) { - print(elapsedSeconds); timer.cancel(); started = false; } diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 0505347..6b38b12 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -1,6 +1,16 @@ +import 'dart:async'; + +import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/providers/timer_provider.dart'; class WorkoutProvider extends ChangeNotifier { + TimerProvider timerProvider; + + final AudioPlayer _audioPlayer = AudioPlayer(); + + WorkoutProvider(this.timerProvider); + final List _workoutPhases = [ 'Warm-Up', 'High Intensity', @@ -18,6 +28,12 @@ class WorkoutProvider extends ChangeNotifier { 'Low Intensity': const Duration(seconds: 3), 'Cool-down': const Duration(seconds: 5) }; + final Map _phaseSongSources = { + 'Warm-Up': AssetSource('warmUp.mp3'), + 'High Intensity': AssetSource('workout.mp3'), + 'Low Intensity': AssetSource('workout.mp3'), + 'Cool-down': AssetSource('cool_down.mp3') + }; int _workoutPhaseIndex = 0; String get currentPhase => _workoutPhases[_workoutPhaseIndex]; @@ -25,9 +41,11 @@ class WorkoutProvider extends ChangeNotifier { _phasesDuration[currentPhase] ?? const Duration(seconds: 0); void nextPhase() { - _workoutPhaseIndex < _workoutPhases.length - ? _workoutPhaseIndex += 1 - : _workoutPhaseIndex = 0; - //notifyListeners(); + _audioPlayer.stop(); + if (_workoutPhaseIndex < _workoutPhases.length - 1) { + _workoutPhaseIndex += 1; + _audioPlayer.play(_phaseSongSources[currentPhase]!); + timerProvider.startTimer(currentPhaseDuration); + } } } diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 1ba501c..bc12bac 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; @@ -15,9 +17,7 @@ class WorkoutTimerWidget extends StatelessWidget { if (timerProvider.elapsedSeconds == workoutProvider.currentPhaseDuration.inSeconds) { - print('Timer abgelaufen'); - workoutProvider.nextPhase(); - timerProvider.startTimer(workoutProvider.currentPhaseDuration); + Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase()); } return Column( From 4144bbaf6966765682019e1638d00717ac458561 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Tue, 28 Feb 2023 14:58:32 +0100 Subject: [PATCH 03/54] wip trying to wrap timerprovider in prokoutprovider --- lib/providers/workout_provider.dart | 23 +++++++++++++++++++---- lib/widgets/timer_widget.dart | 5 ----- lib/widgets/workout_timer_widget.dart | 8 +++++--- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 6b38b12..d2c07cf 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -1,5 +1,3 @@ -import 'dart:async'; - import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; @@ -8,6 +6,8 @@ class WorkoutProvider extends ChangeNotifier { TimerProvider timerProvider; final AudioPlayer _audioPlayer = AudioPlayer(); + final Source _finishedSoundSource = AssetSource('finish.mp3'); + final Source _beepSoundSource = AssetSource('beep.mp3'); WorkoutProvider(this.timerProvider); @@ -39,13 +39,28 @@ class WorkoutProvider extends ChangeNotifier { String get currentPhase => _workoutPhases[_workoutPhaseIndex]; Duration get currentPhaseDuration => _phasesDuration[currentPhase] ?? const Duration(seconds: 0); + bool get isPhaseComplete => + timerProvider.elapsedSeconds - currentPhaseDuration.inSeconds == 0; void nextPhase() { _audioPlayer.stop(); if (_workoutPhaseIndex < _workoutPhases.length - 1) { + _audioPlayer.play(_beepSoundSource); _workoutPhaseIndex += 1; - _audioPlayer.play(_phaseSongSources[currentPhase]!); - timerProvider.startTimer(currentPhaseDuration); + _audioPlayer.onPlayerComplete.listen((event) { + _audioPlayer.play(_phaseSongSources[currentPhase]!); + timerProvider.startTimer(currentPhaseDuration); + }); + } else { + _audioPlayer.play(_finishedSoundSource); } } + + void startWorkout() { + _audioPlayer.play(_beepSoundSource); + _audioPlayer.onPlayerComplete.listen((event) { + _audioPlayer.play(_phaseSongSources[currentPhase]!); + timerProvider.startTimer(currentPhaseDuration); + }); + } } diff --git a/lib/widgets/timer_widget.dart b/lib/widgets/timer_widget.dart index 875697f..4cf1d51 100644 --- a/lib/widgets/timer_widget.dart +++ b/lib/widgets/timer_widget.dart @@ -14,11 +14,6 @@ class TimerWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text(formatTime(duration.inSeconds - timerProvider.elapsedSeconds)), - ElevatedButton( - onPressed: () => timerProvider.started - ? timerProvider.stopTimer() - : timerProvider.startTimer(duration), - child: Text(timerProvider.started ? 'Stop' : 'Start')) ], ); } diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index bc12bac..49baf08 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -15,8 +15,7 @@ class WorkoutTimerWidget extends StatelessWidget { TimerProvider timerProvider = context.watch(); WorkoutProvider workoutProvider = context.watch(); - if (timerProvider.elapsedSeconds == - workoutProvider.currentPhaseDuration.inSeconds) { + if (workoutProvider.isPhaseComplete) { Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase()); } @@ -24,7 +23,10 @@ class WorkoutTimerWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text(workoutProvider.currentPhase), - TimerWidget(duration: workoutProvider.currentPhaseDuration) + TimerWidget(duration: workoutProvider.currentPhaseDuration), + ElevatedButton( + onPressed: () => workoutProvider.startWorkout(), + child: Text(timerProvider.started ? 'Stop' : 'Start')) ], ); } From c1cf3cce30cdc94ceb604b02473e0a762b427f05 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Tue, 28 Feb 2023 15:07:47 +0100 Subject: [PATCH 04/54] handle stop --- lib/providers/timer_provider.dart | 5 ++++- lib/providers/workout_provider.dart | 10 ++++++++++ lib/widgets/workout_timer_widget.dart | 4 +++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart index 8073309..ee34b19 100644 --- a/lib/providers/timer_provider.dart +++ b/lib/providers/timer_provider.dart @@ -18,5 +18,8 @@ class TimerProvider extends ChangeNotifier { })); } - void stopTimer() => _timer?.cancel(); + void stopTimer() { + started = false; + _timer?.cancel(); + } } diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index d2c07cf..2d31dc7 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -8,6 +8,7 @@ class WorkoutProvider extends ChangeNotifier { final AudioPlayer _audioPlayer = AudioPlayer(); final Source _finishedSoundSource = AssetSource('finish.mp3'); final Source _beepSoundSource = AssetSource('beep.mp3'); + bool isWorkoutStarted = false; WorkoutProvider(this.timerProvider); @@ -57,10 +58,19 @@ class WorkoutProvider extends ChangeNotifier { } void startWorkout() { + isWorkoutStarted = true; _audioPlayer.play(_beepSoundSource); _audioPlayer.onPlayerComplete.listen((event) { _audioPlayer.play(_phaseSongSources[currentPhase]!); timerProvider.startTimer(currentPhaseDuration); }); } + + void stopWorkout() { + isWorkoutStarted = false; + _workoutPhaseIndex = 0; + _audioPlayer.stop(); + timerProvider.stopTimer(); + notifyListeners(); + } } diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 49baf08..131229c 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -25,7 +25,9 @@ class WorkoutTimerWidget extends StatelessWidget { Text(workoutProvider.currentPhase), TimerWidget(duration: workoutProvider.currentPhaseDuration), ElevatedButton( - onPressed: () => workoutProvider.startWorkout(), + onPressed: !workoutProvider.isWorkoutStarted + ? () => workoutProvider.startWorkout() + : () => workoutProvider.stopWorkout(), child: Text(timerProvider.started ? 'Stop' : 'Start')) ], ); From 9eff2ad177079caf5320fef3bc13fc3d0e15e177 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Wed, 1 Mar 2023 12:34:35 +0100 Subject: [PATCH 05/54] add circular progress indicator --- lib/pages/interval_page.dart | 228 ++------------------------ lib/providers/workout_provider.dart | 13 ++ lib/widgets/mute_button.dart | 21 +++ lib/widgets/workout_timer_widget.dart | 3 + 4 files changed, 50 insertions(+), 215 deletions(-) create mode 100644 lib/widgets/mute_button.dart diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index 3537f03..5a78b48 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -4,169 +4,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; -import 'package:smoke_cess_app/widgets/popup_for_start_and_stop.dart'; -import 'package:smoke_cess_app/widgets/timer_widget.dart'; +import 'package:smoke_cess_app/widgets/mute_button.dart'; import 'package:smoke_cess_app/widgets/workout_timer_widget.dart'; -import '../providers/input_provider.dart'; - -class IntervalTimerPage extends StatefulWidget { - const IntervalTimerPage({Key? key}) : super(key: key); - - @override - _IntervalTimerPageState createState() => _IntervalTimerPageState(); -} - -class _IntervalTimerPageState extends State { - final Duration _warmupDuration = const Duration(seconds: 5); - final Duration _cooldownDuration = const Duration(seconds: 5); - final Duration _highIntensityDuration = const Duration(seconds: 4); - final Duration _lowIntensityDuration = const Duration(seconds: 3); - late Duration _totalDuration = const Duration(minutes: 35); - AudioPlayer warmUpPlayer = AudioPlayer(); - AudioPlayer workoutPlayer = AudioPlayer(); - AudioPlayer coolDownPlayer = AudioPlayer(); - final AudioCache _audioCache = AudioCache(); - final int _numHighIntensityBlocks = 4; - final int _numLowIntensityBlocks = 3; - - Timer? _timer; - int _currentBlock = 0; - Duration _currentDuration = const Duration(); - bool _isPaused = true; - - @override - void initState() { - _currentDuration = _warmupDuration; - super.initState(); - } - - @override - void dispose() { - _timer?.cancel(); - super.dispose(); - } - - void _startTimer() async { - await showDialog( - context: context, - builder: (BuildContext context) { - return ChangeNotifierProvider( - create: (context) => InputProvider(), - child: const TimerStartStopPopup( - title: 'Motivation vor dem Training', - )); - }, - ); - _isPaused = false; - Source source = AssetSource('go.mp3'); - await AudioPlayer().play(source); - - _timer = Timer.periodic(const Duration(seconds: 1), (_) => _tick()); - Future.delayed(const Duration(seconds: 1)).then((value) { - _playWarmUpMusic(); - }); - } - - void _resetTimer() { - () async { - await coolDownPlayer.stop(); - await warmUpPlayer.stop(); - await workoutPlayer.stop(); - }(); - _isPaused = true; - _timer?.cancel(); - _currentBlock = 0; - _currentDuration = _warmupDuration; - _totalDuration = const Duration(minutes: 35); - setState(() {}); - showDialog( - context: context, - builder: (BuildContext context) { - return const TimerStartStopPopup( - title: 'Motivation nach dem Training', - ); - }, - ); - } - - Future _playWarmUpMusic() async { - Source source = AssetSource('warmUp.mp3'); - await warmUpPlayer.setReleaseMode(ReleaseMode.loop); - await warmUpPlayer.play(source); - } - - Future _playWorkoutMusic() async { - await warmUpPlayer.stop(); - Future.delayed(const Duration(microseconds: 600)).then((value) async { - Source source = AssetSource('workout.mp3'); - await workoutPlayer.setReleaseMode(ReleaseMode.loop); - await workoutPlayer.play(source); - }); - } - - Future _intervalChange() async { - Source source = AssetSource('beep.mp3'); - await AudioPlayer().play(source); - } - - void _tick() { - setState(() { - _currentDuration = Duration( - seconds: _currentDuration.inSeconds - 1, - ); - _totalDuration = Duration( - seconds: _totalDuration.inSeconds - 1, - ); - if (_currentDuration.inSeconds < 1) { - if (_currentBlock < _numHighIntensityBlocks + _numLowIntensityBlocks) { - _intervalChange(); - if (_currentBlock == 0) { - _playWorkoutMusic(); - } - _currentBlock++; - - if (_currentBlock % 2 == 1) { - _currentDuration = _highIntensityDuration; - } else { - _currentDuration = _lowIntensityDuration; - } - } else if (_currentBlock < _numHighIntensityBlocks * 2) { - _intervalChange(); - _currentBlock++; - _currentDuration = _cooldownDuration; - () async { - await workoutPlayer.stop(); - Source source = AssetSource('cool_down.mp3'); - await coolDownPlayer.setReleaseMode(ReleaseMode.loop); - await coolDownPlayer.play(source); - }(); - } else { - () async { - Future.delayed(const Duration(microseconds: 900)) - .then((value) async { - Source source = AssetSource('finish.mp3'); - await AudioPlayer().play(source); - }); - }(); - _resetTimer(); - } - } - }); - } - - String _formatDuration(Duration duration) { - String twoDigits(int n) => n.toString().padLeft(2, '0'); - final minutes = twoDigits(duration.inMinutes.remainder(60)); - final seconds = twoDigits(duration.inSeconds.remainder(60)); - return '$minutes:$seconds'; - } - - String _formatTotalDuration(Duration duration) { - final minutes = duration.inMinutes; - final seconds = duration.inSeconds.remainder(60); - return _formatDuration(Duration(minutes: minutes, seconds: seconds)); - } +class IntervalTimerPage extends StatelessWidget { + const IntervalTimerPage({super.key}); @override Widget build(BuildContext context) { @@ -177,60 +19,16 @@ class _IntervalTimerPageState extends State { ChangeNotifierProvider( create: (context) => WorkoutProvider(timerProvider)) ], - child: WorkoutTimerWidget(), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Align( + alignment: Alignment.topLeft, + child: MuteButton(), + ), + WorkoutTimerWidget() + ], + ), ); - ChangeNotifierProvider( - create: (context) => TimerProvider(), - child: TimerWidget( - duration: Duration(seconds: 5), - )); - return Center( - child: ChangeNotifierProvider( - create: (context) => InputProvider(), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - _currentBlock == 0 - ? 'Warm-up' - : _currentBlock % 2 == 1 - ? 'High Intensity' - : _currentBlock < _numHighIntensityBlocks * 2 - ? 'Low Intensity' - : 'Cool-down', - style: const TextStyle(fontSize: 32.0), - ), - const SizedBox(height: 16.0), - Text( - _formatDuration(_currentDuration), - style: const TextStyle(fontSize: 80.0), - ), - const SizedBox(height: 32.0), - Text( - 'Total: ${_formatTotalDuration(_totalDuration)}', - style: const TextStyle(fontSize: 24.0), - ), - const SizedBox(height: 32.0), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - IconButton( - icon: Icon(_isPaused - ? Icons.play_arrow_rounded - : Icons.stop_rounded), - iconSize: 48.0, - onPressed: () { - if (_isPaused) { - _startTimer(); - } else { - _resetTimer(); - } - }, - ), - // ), - ], - ), - ], - ))); } } diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 2d31dc7..f9fc206 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -9,6 +9,19 @@ class WorkoutProvider extends ChangeNotifier { final Source _finishedSoundSource = AssetSource('finish.mp3'); final Source _beepSoundSource = AssetSource('beep.mp3'); bool isWorkoutStarted = false; + bool isMuted = false; + + void mutePlayer() { + isMuted = true; + _audioPlayer.setVolume(0); + notifyListeners(); + } + + void unMutePlayer() { + isMuted = false; + _audioPlayer.setVolume(1); + notifyListeners(); + } WorkoutProvider(this.timerProvider); diff --git a/lib/widgets/mute_button.dart b/lib/widgets/mute_button.dart new file mode 100644 index 0000000..863bb52 --- /dev/null +++ b/lib/widgets/mute_button.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/workout_provider.dart'; + +class MuteButton extends StatelessWidget { + const MuteButton({super.key}); + + @override + Widget build(BuildContext context) { + WorkoutProvider workoutProvider = context.watch(); + + return IconButton( + onPressed: workoutProvider.isMuted + ? workoutProvider.unMutePlayer + : workoutProvider.mutePlayer, + icon: Icon(workoutProvider.isMuted + ? Icons.volume_off_outlined + : Icons.volume_up_outlined), + ); + } +} diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 131229c..3eb1368 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -23,6 +23,9 @@ class WorkoutTimerWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text(workoutProvider.currentPhase), + CircularProgressIndicator( + value: timerProvider.elapsedSeconds / + workoutProvider.currentPhaseDuration.inSeconds), TimerWidget(duration: workoutProvider.currentPhaseDuration), ElevatedButton( onPressed: !workoutProvider.isWorkoutStarted From da7c820dbd0f744222207d5c191b06e8ffce2e9e Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Wed, 1 Mar 2023 12:57:02 +0100 Subject: [PATCH 06/54] better positioning, fixed endless workout --- lib/providers/workout_provider.dart | 1 + lib/widgets/workout_timer_widget.dart | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index f9fc206..73b32f8 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -67,6 +67,7 @@ class WorkoutProvider extends ChangeNotifier { }); } else { _audioPlayer.play(_finishedSoundSource); + stopWorkout(); } } diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 3eb1368..d789c15 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -23,10 +23,26 @@ class WorkoutTimerWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Text(workoutProvider.currentPhase), - CircularProgressIndicator( - value: timerProvider.elapsedSeconds / - workoutProvider.currentPhaseDuration.inSeconds), - TimerWidget(duration: workoutProvider.currentPhaseDuration), + const SizedBox( + height: 20, + ), + Stack( + alignment: Alignment.center, + children: [ + SizedBox( + height: 100, + width: 100, + child: CircularProgressIndicator( + value: (workoutProvider.currentPhaseDuration.inSeconds + .toDouble() - + timerProvider.elapsedSeconds) / + workoutProvider.currentPhaseDuration.inSeconds)), + TimerWidget(duration: workoutProvider.currentPhaseDuration), + ], + ), + const SizedBox( + height: 20, + ), ElevatedButton( onPressed: !workoutProvider.isWorkoutStarted ? () => workoutProvider.startWorkout() From 556daa9e90af9e1676aa3ab4140559012cbe7a17 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Wed, 1 Mar 2023 13:07:01 +0100 Subject: [PATCH 07/54] show phase colors in circularprogressindi --- lib/providers/workout_provider.dart | 8 ++++++++ lib/widgets/workout_timer_widget.dart | 1 + 2 files changed, 9 insertions(+) diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 73b32f8..4c89b84 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -25,6 +25,7 @@ class WorkoutProvider extends ChangeNotifier { WorkoutProvider(this.timerProvider); + //TODO: outsource all Maps to JSON File! final List _workoutPhases = [ 'Warm-Up', 'High Intensity', @@ -48,6 +49,12 @@ class WorkoutProvider extends ChangeNotifier { 'Low Intensity': AssetSource('workout.mp3'), 'Cool-down': AssetSource('cool_down.mp3') }; + final Map _phaseColors = { + 'Warm-Up': Colors.green, + 'High Intensity': Colors.red, + 'Low Intensity': Colors.orange, + 'Cool-down': Colors.blue + }; int _workoutPhaseIndex = 0; String get currentPhase => _workoutPhases[_workoutPhaseIndex]; @@ -55,6 +62,7 @@ class WorkoutProvider extends ChangeNotifier { _phasesDuration[currentPhase] ?? const Duration(seconds: 0); bool get isPhaseComplete => timerProvider.elapsedSeconds - currentPhaseDuration.inSeconds == 0; + Color get currentPhaseColor => _phaseColors[currentPhase] ?? Colors.blue; void nextPhase() { _audioPlayer.stop(); diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index d789c15..df9fae4 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -33,6 +33,7 @@ class WorkoutTimerWidget extends StatelessWidget { height: 100, width: 100, child: CircularProgressIndicator( + color: workoutProvider.currentPhaseColor, value: (workoutProvider.currentPhaseDuration.inSeconds .toDouble() - timerProvider.elapsedSeconds) / From cd88b483cf0235449448aa1f8339a71879ce37a9 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Wed, 1 Mar 2023 13:30:12 +0100 Subject: [PATCH 08/54] return slider value after popup --- lib/pages/interval_page.dart | 5 ++--- lib/widgets/popup_for_start_and_stop.dart | 18 +++++++++++++----- lib/widgets/workout_timer_widget.dart | 20 +++++++++++++++++++- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index 5a78b48..bf26c40 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -1,7 +1,6 @@ -import 'dart:async'; -import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/input_provider.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/widgets/mute_button.dart'; @@ -17,7 +16,7 @@ class IntervalTimerPage extends StatelessWidget { providers: [ ChangeNotifierProvider(create: (context) => timerProvider), ChangeNotifierProvider( - create: (context) => WorkoutProvider(timerProvider)) + create: (context) => WorkoutProvider(timerProvider)), ], child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/widgets/popup_for_start_and_stop.dart b/lib/widgets/popup_for_start_and_stop.dart index e1af268..d79a83f 100644 --- a/lib/widgets/popup_for_start_and_stop.dart +++ b/lib/widgets/popup_for_start_and_stop.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/input_provider.dart'; import 'package:smoke_cess_app/widgets/slider.dart'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; @@ -9,18 +11,24 @@ class TimerStartStopPopup extends StatelessWidget { @override Widget build(BuildContext context) { + InputProvider inputProvider = context.watch(); + return AlertDialog( title: Text(title), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, - children: const [ - Padding( - padding: const EdgeInsets.only(top: 8), + children: [ + const Padding( + padding: EdgeInsets.only(top: 8), child: MySlider(), ), - SizedBox(height: 16), - MyTextFormField('Beschreibe deinen Motivation'), + const SizedBox(height: 16), + const MyTextFormField('Beschreibe deinen Motivation'), + ElevatedButton( + onPressed: () => + Navigator.pop(context, inputProvider.sliderValue), + child: const Text('Speichern')) ], ), ); diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index df9fae4..5a14911 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -5,11 +5,15 @@ import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/widgets/timer_widget.dart'; +import '../providers/input_provider.dart'; import '../providers/timer_provider.dart'; +import 'popup_for_start_and_stop.dart'; class WorkoutTimerWidget extends StatelessWidget { const WorkoutTimerWidget({super.key}); + void _onStartButtonPressed(BuildContext context) {} + @override Widget build(BuildContext context) { TimerProvider timerProvider = context.watch(); @@ -46,7 +50,21 @@ class WorkoutTimerWidget extends StatelessWidget { ), ElevatedButton( onPressed: !workoutProvider.isWorkoutStarted - ? () => workoutProvider.startWorkout() + ? () async { + double sliderValue = await showDialog( + context: context, + builder: (BuildContext context) { + return ChangeNotifierProvider( + create: (context) => InputProvider(), + child: const TimerStartStopPopup( + title: 'Motivation vor dem Training', + ), + ); + }, + ); + print(sliderValue); + workoutProvider.startWorkout(); + } : () => workoutProvider.stopWorkout(), child: Text(timerProvider.started ? 'Stop' : 'Start')) ], From 5587f049e1c101b834d5a723e88d4a43199a2267 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 13:19:08 +0100 Subject: [PATCH 09/54] wip finishing workout and saving model --- lib/mock/db_mock.dart | 8 ++- lib/models/hiit_workout.dart | 32 ---------- lib/models/workout.dart | 28 +++++++++ lib/providers/workout_provider.dart | 71 ++++++++++++++--------- lib/services/database_service.dart | 9 ++- lib/widgets/popup_for_start_and_stop.dart | 30 ++++++++-- lib/widgets/workout_timer_widget.dart | 43 +++++++------- 7 files changed, 132 insertions(+), 89 deletions(-) delete mode 100644 lib/models/hiit_workout.dart create mode 100644 lib/models/workout.dart diff --git a/lib/mock/db_mock.dart b/lib/mock/db_mock.dart index a06f003..6daa0c4 100644 --- a/lib/mock/db_mock.dart +++ b/lib/mock/db_mock.dart @@ -1,6 +1,7 @@ import 'package:smoke_cess_app/interface/db_record.dart'; import 'package:smoke_cess_app/models/mood.dart'; import 'package:smoke_cess_app/models/sleep.dart'; +import 'package:smoke_cess_app/models/workout.dart'; import 'package:smoke_cess_app/services/database_service.dart'; import 'package:sqflite_common/sqlite_api.dart'; @@ -28,7 +29,12 @@ class DatabaseMock implements DatabaseService { } @override - // TODO: implement database + Future addWorkout(Workout workout) { + _workoutRecords.add(workout); + return Future.value(1); + } + + @override Future get database => DatabaseService.instance.database; @override diff --git a/lib/models/hiit_workout.dart b/lib/models/hiit_workout.dart deleted file mode 100644 index c4ec0da..0000000 --- a/lib/models/hiit_workout.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:smoke_cess_app/interface/db_record.dart'; - -class HIITWorkout implements DatabaseRecord { - Duration _workoutDuration; - String _commentBefore; - String _commentAfter; - DateTime _workoutDate; - - HIITWorkout(this._workoutDuration, this._commentBefore, this._commentAfter, - this._workoutDate); - - //TODO Felder anpassen - @override - factory HIITWorkout.fromMap(Map map) { - return HIITWorkout(map['_workoutDuration'], map['_commentBefore'], - map['_commentAfter'], map['_workoutDate']); - } - - @override - String toCSV() => - "${_workoutDate.toIso8601String()}, $_workoutDuration, $_commentBefore, $_commentAfter"; - - @override - Map toMap() { - return { - 'workoutDuration': _workoutDuration, - 'commentBefore': _commentBefore, - 'commentAfter': _commentAfter, - 'workoutDate': _workoutDate, - }; - } -} diff --git a/lib/models/workout.dart b/lib/models/workout.dart new file mode 100644 index 0000000..0bba86a --- /dev/null +++ b/lib/models/workout.dart @@ -0,0 +1,28 @@ +import 'package:smoke_cess_app/interface/db_record.dart'; + +class Workout implements DatabaseRecord { + int _motivationBefore; + int _motivationAfter; + DateTime _workoutDate; + + Workout(this._motivationBefore, this._motivationAfter, this._workoutDate); + + @override + factory Workout.fromMap(Map map) { + return Workout(map['_workoutDuration'], map['_motivationBefore'], + map['_motivationAfter']); + } + + @override + String toCSV() => + "${_workoutDate.toIso8601String()}, $_motivationBefore, $_motivationAfter"; + + @override + Map toMap() { + return { + 'motivationBefore': _motivationBefore, + 'motivationAfter': _motivationAfter, + 'workoutDate': _workoutDate, + }; + } +} diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 4c89b84..c15c04c 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -1,6 +1,8 @@ import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/models/workout.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; +import '../globals.dart' as globals; class WorkoutProvider extends ChangeNotifier { TimerProvider timerProvider; @@ -10,6 +12,8 @@ class WorkoutProvider extends ChangeNotifier { final Source _beepSoundSource = AssetSource('beep.mp3'); bool isWorkoutStarted = false; bool isMuted = false; + int motivationBefore = 50; + int motivationAfter = 50; void mutePlayer() { isMuted = true; @@ -25,44 +29,29 @@ class WorkoutProvider extends ChangeNotifier { WorkoutProvider(this.timerProvider); - //TODO: outsource all Maps to JSON File! final List _workoutPhases = [ 'Warm-Up', - 'High Intensity', + /*'High Intensity', 'Low Intensity', 'High Intensity', 'Low Intensity', 'High Intensity', 'Low Intensity', - 'High Intensity', + 'High Intensity', */ 'Cool-down' ]; - final Map _phasesDuration = { - 'Warm-Up': const Duration(seconds: 5), - 'High Intensity': const Duration(seconds: 4), - 'Low Intensity': const Duration(seconds: 3), - 'Cool-down': const Duration(seconds: 5) - }; - final Map _phaseSongSources = { - 'Warm-Up': AssetSource('warmUp.mp3'), - 'High Intensity': AssetSource('workout.mp3'), - 'Low Intensity': AssetSource('workout.mp3'), - 'Cool-down': AssetSource('cool_down.mp3') - }; - final Map _phaseColors = { - 'Warm-Up': Colors.green, - 'High Intensity': Colors.red, - 'Low Intensity': Colors.orange, - 'Cool-down': Colors.blue - }; int _workoutPhaseIndex = 0; String get currentPhase => _workoutPhases[_workoutPhaseIndex]; Duration get currentPhaseDuration => - _phasesDuration[currentPhase] ?? const Duration(seconds: 0); + _workoutPhaseSettings[currentPhase]!['duration']; bool get isPhaseComplete => timerProvider.elapsedSeconds - currentPhaseDuration.inSeconds == 0; - Color get currentPhaseColor => _phaseColors[currentPhase] ?? Colors.blue; + Color get currentPhaseColor => _workoutPhaseSettings[currentPhase]!['color']; + AssetSource get currentPhaseSource => + _workoutPhaseSettings[currentPhase]!['source']; + bool get isWorkoutComplete => + _workoutPhaseIndex == _workoutPhases.length - 1 && isPhaseComplete; void nextPhase() { _audioPlayer.stop(); @@ -70,10 +59,11 @@ class WorkoutProvider extends ChangeNotifier { _audioPlayer.play(_beepSoundSource); _workoutPhaseIndex += 1; _audioPlayer.onPlayerComplete.listen((event) { - _audioPlayer.play(_phaseSongSources[currentPhase]!); + _audioPlayer.play(currentPhaseSource); timerProvider.startTimer(currentPhaseDuration); }); } else { + //workout completed _audioPlayer.play(_finishedSoundSource); stopWorkout(); } @@ -83,16 +73,45 @@ class WorkoutProvider extends ChangeNotifier { isWorkoutStarted = true; _audioPlayer.play(_beepSoundSource); _audioPlayer.onPlayerComplete.listen((event) { - _audioPlayer.play(_phaseSongSources[currentPhase]!); + _audioPlayer.play(currentPhaseSource); timerProvider.startTimer(currentPhaseDuration); }); } void stopWorkout() { isWorkoutStarted = false; - _workoutPhaseIndex = 0; + //_workoutPhaseIndex = 0; _audioPlayer.stop(); timerProvider.stopTimer(); notifyListeners(); } + + void saveWorkout() { + Workout workout = + Workout(motivationBefore, motivationAfter, DateTime.now()); + globals.databaseService.addWorkout(workout); + } } + +Map> _workoutPhaseSettings = { + 'Warm-Up': { + 'duration': const Duration(seconds: 5), + 'source': AssetSource('warmUp.mp3'), + 'color': Colors.green + }, + 'High Intensity': { + 'duration': const Duration(seconds: 4), + 'source': AssetSource('workout.mp3'), + 'color': Colors.red + }, + 'Low Intensity': { + 'duration': const Duration(seconds: 3), + 'source': AssetSource('workout.mp3'), + 'color': Colors.orange + }, + 'Cool-down': { + 'duration': const Duration(seconds: 5), + 'source': AssetSource('cool_down.mp3'), + 'color': Colors.blue + } +}; diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart index 8dc8788..3dcc943 100644 --- a/lib/services/database_service.dart +++ b/lib/services/database_service.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:path/path.dart'; import 'package:smoke_cess_app/models/mood.dart'; +import 'package:smoke_cess_app/models/workout.dart'; import 'package:sqflite/sqflite.dart'; // ignore: depend_on_referenced_packages import 'package:path_provider/path_provider.dart'; @@ -62,6 +63,11 @@ class DatabaseService { Database db = await instance.database; return await db.insert('sleep', sleep.toMap()); } + + Future addWorkout(Workout workout) async { + Database db = await instance.database; + return await db.insert('workout', workout.toMap()); + } } String _createMoodTable = ''' @@ -100,9 +106,6 @@ String _createWorkoutTable = ''' id INTEGER PRIMARY KEY, date TEXT, motivationBefore INTEGER, - commentBefore TEXT, motivationAfter INTEGER, - commentAfter TEXT, - completed INTEGER ) '''; diff --git a/lib/widgets/popup_for_start_and_stop.dart b/lib/widgets/popup_for_start_and_stop.dart index d79a83f..4883737 100644 --- a/lib/widgets/popup_for_start_and_stop.dart +++ b/lib/widgets/popup_for_start_and_stop.dart @@ -2,12 +2,29 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/input_provider.dart'; import 'package:smoke_cess_app/widgets/slider.dart'; -import 'package:smoke_cess_app/widgets/text_formfield.dart'; + +Future showMotivationPopup( + BuildContext context, Function onSave, String title) async { + return await showDialog( + context: context, + builder: (BuildContext context) { + return ChangeNotifierProvider( + create: (context) => InputProvider(), + child: TimerStartStopPopup( + title: title, + onSaveAction: onSave, + ), + ); + }, + ); +} class TimerStartStopPopup extends StatelessWidget { final String title; - - const TimerStartStopPopup({Key? key, required this.title}) : super(key: key); + final Function onSaveAction; + const TimerStartStopPopup( + {Key? key, required this.title, required this.onSaveAction}) + : super(key: key); @override Widget build(BuildContext context) { @@ -24,10 +41,11 @@ class TimerStartStopPopup extends StatelessWidget { child: MySlider(), ), const SizedBox(height: 16), - const MyTextFormField('Beschreibe deinen Motivation'), ElevatedButton( - onPressed: () => - Navigator.pop(context, inputProvider.sliderValue), + onPressed: () { + onSaveAction(inputProvider.sliderValue); + Navigator.pop(context); + }, child: const Text('Speichern')) ], ), diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 5a14911..2e39175 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -5,24 +5,41 @@ import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/widgets/timer_widget.dart'; -import '../providers/input_provider.dart'; import '../providers/timer_provider.dart'; import 'popup_for_start_and_stop.dart'; class WorkoutTimerWidget extends StatelessWidget { const WorkoutTimerWidget({super.key}); - void _onStartButtonPressed(BuildContext context) {} - @override Widget build(BuildContext context) { TimerProvider timerProvider = context.watch(); WorkoutProvider workoutProvider = context.watch(); - if (workoutProvider.isPhaseComplete) { + if (workoutProvider.isPhaseComplete && workoutProvider.isWorkoutStarted) { Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase()); } + void handleStartStopWorkout() async { + if (!workoutProvider.isWorkoutStarted) { + await showMotivationPopup( + context, + (double value) => workoutProvider.motivationBefore = value.toInt(), + 'Motivation vor dem Training'); + workoutProvider.startWorkout(); + } else { + workoutProvider.stopWorkout(); + await showMotivationPopup( + context, + (double value) => workoutProvider.motivationAfter = value.toInt(), + 'Motivation nach dem Training'); + } + } + + if (workoutProvider.isWorkoutComplete) { + handleStartStopWorkout(); + } + return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -49,23 +66,7 @@ class WorkoutTimerWidget extends StatelessWidget { height: 20, ), ElevatedButton( - onPressed: !workoutProvider.isWorkoutStarted - ? () async { - double sliderValue = await showDialog( - context: context, - builder: (BuildContext context) { - return ChangeNotifierProvider( - create: (context) => InputProvider(), - child: const TimerStartStopPopup( - title: 'Motivation vor dem Training', - ), - ); - }, - ); - print(sliderValue); - workoutProvider.startWorkout(); - } - : () => workoutProvider.stopWorkout(), + onPressed: handleStartStopWorkout, child: Text(timerProvider.started ? 'Stop' : 'Start')) ], ); From fa8d2f63145da701275044a7992b0c4c23d1b1e0 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 15:08:39 +0100 Subject: [PATCH 10/54] fix onlisten stream error --- lib/providers/workout_provider.dart | 24 +++++++++++++++--------- lib/widgets/workout_timer_widget.dart | 6 +----- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index c15c04c..add88de 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:smoke_cess_app/models/workout.dart'; @@ -8,9 +10,11 @@ class WorkoutProvider extends ChangeNotifier { TimerProvider timerProvider; final AudioPlayer _audioPlayer = AudioPlayer(); + late StreamSubscription _onCompleteSubscription; final Source _finishedSoundSource = AssetSource('finish.mp3'); final Source _beepSoundSource = AssetSource('beep.mp3'); bool isWorkoutStarted = false; + bool isWorkoutComplete = false; bool isMuted = false; int motivationBefore = 50; int motivationAfter = 50; @@ -50,18 +54,19 @@ class WorkoutProvider extends ChangeNotifier { Color get currentPhaseColor => _workoutPhaseSettings[currentPhase]!['color']; AssetSource get currentPhaseSource => _workoutPhaseSettings[currentPhase]!['source']; - bool get isWorkoutComplete => - _workoutPhaseIndex == _workoutPhases.length - 1 && isPhaseComplete; + /* bool get isWorkoutComplete => + _workoutPhaseIndex == _workoutPhases.length - 1 && isPhaseComplete; */ void nextPhase() { + _onCompleteSubscription.cancel(); _audioPlayer.stop(); if (_workoutPhaseIndex < _workoutPhases.length - 1) { _audioPlayer.play(_beepSoundSource); _workoutPhaseIndex += 1; - _audioPlayer.onPlayerComplete.listen((event) { + _onCompleteSubscription = _audioPlayer.onPlayerComplete.listen((event) { _audioPlayer.play(currentPhaseSource); - timerProvider.startTimer(currentPhaseDuration); }); + timerProvider.startTimer(currentPhaseDuration); } else { //workout completed _audioPlayer.play(_finishedSoundSource); @@ -71,19 +76,20 @@ class WorkoutProvider extends ChangeNotifier { void startWorkout() { isWorkoutStarted = true; - _audioPlayer.play(_beepSoundSource); - _audioPlayer.onPlayerComplete.listen((event) { + isWorkoutComplete = false; + _audioPlayer.play(_beepSoundSource).whenComplete(() => null); + _onCompleteSubscription = _audioPlayer.onPlayerComplete.listen((event) { _audioPlayer.play(currentPhaseSource); - timerProvider.startTimer(currentPhaseDuration); }); + timerProvider.startTimer(currentPhaseDuration); } void stopWorkout() { isWorkoutStarted = false; - //_workoutPhaseIndex = 0; + isWorkoutComplete = true; _audioPlayer.stop(); timerProvider.stopTimer(); - notifyListeners(); + //notifyListeners(); } void saveWorkout() { diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 2e39175..8023770 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -16,7 +16,7 @@ class WorkoutTimerWidget extends StatelessWidget { TimerProvider timerProvider = context.watch(); WorkoutProvider workoutProvider = context.watch(); - if (workoutProvider.isPhaseComplete && workoutProvider.isWorkoutStarted) { + if (workoutProvider.isPhaseComplete && !workoutProvider.isWorkoutComplete) { Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase()); } @@ -36,10 +36,6 @@ class WorkoutTimerWidget extends StatelessWidget { } } - if (workoutProvider.isWorkoutComplete) { - handleStartStopWorkout(); - } - return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ From d1600b174ed0f1dfd763a9be61d53742ed203255 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 16:06:24 +0100 Subject: [PATCH 11/54] save workout when completed --- lib/providers/workout_provider.dart | 8 ++++---- lib/widgets/popup_for_start_and_stop.dart | 4 ++-- lib/widgets/workout_timer_widget.dart | 22 +++++++++++++++------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index add88de..5c0a80b 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -35,13 +35,13 @@ class WorkoutProvider extends ChangeNotifier { final List _workoutPhases = [ 'Warm-Up', - /*'High Intensity', - 'Low Intensity', 'High Intensity', 'Low Intensity', 'High Intensity', 'Low Intensity', - 'High Intensity', */ + 'High Intensity', + 'Low Intensity', + 'High Intensity', 'Cool-down' ]; int _workoutPhaseIndex = 0; @@ -89,7 +89,7 @@ class WorkoutProvider extends ChangeNotifier { isWorkoutComplete = true; _audioPlayer.stop(); timerProvider.stopTimer(); - //notifyListeners(); + notifyListeners(); } void saveWorkout() { diff --git a/lib/widgets/popup_for_start_and_stop.dart b/lib/widgets/popup_for_start_and_stop.dart index 4883737..77411a4 100644 --- a/lib/widgets/popup_for_start_and_stop.dart +++ b/lib/widgets/popup_for_start_and_stop.dart @@ -4,8 +4,8 @@ import 'package:smoke_cess_app/providers/input_provider.dart'; import 'package:smoke_cess_app/widgets/slider.dart'; Future showMotivationPopup( - BuildContext context, Function onSave, String title) async { - return await showDialog( + BuildContext context, Function onSave, String title) { + return showDialog( context: context, builder: (BuildContext context) { return ChangeNotifierProvider( diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 8023770..59f67d4 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -20,16 +20,24 @@ class WorkoutTimerWidget extends StatelessWidget { Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase()); } - void handleStartStopWorkout() async { + if (workoutProvider.isWorkoutComplete) { + Timer( + const Duration(milliseconds: 1), + () => showMotivationPopup(context, (double value) { + workoutProvider.motivationAfter = value.toInt(); + workoutProvider.saveWorkout(); + }, 'Motivation nach dem Training')); + } + + void handleStartStopWorkout() { if (!workoutProvider.isWorkoutStarted) { - await showMotivationPopup( - context, - (double value) => workoutProvider.motivationBefore = value.toInt(), - 'Motivation vor dem Training'); - workoutProvider.startWorkout(); + showMotivationPopup(context, (double value) { + workoutProvider.motivationBefore = value.toInt(); + workoutProvider.startWorkout(); + }, 'Motivation vor dem Training'); } else { workoutProvider.stopWorkout(); - await showMotivationPopup( + showMotivationPopup( context, (double value) => workoutProvider.motivationAfter = value.toInt(), 'Motivation nach dem Training'); From 5b3d615c8e24a87e606a1b5a2216ac8939d26616 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 16:12:54 +0100 Subject: [PATCH 12/54] fix flutter analyze problems --- lib/mock/db_mock.dart | 1 + lib/pages/interval_page.dart | 1 - lib/pages/scanner_page.dart | 12 +++--------- lib/services/database_service.dart | 8 ++++---- lib/services/settings_service.dart | 7 ------- lib/widgets/mood_form.dart | 2 -- 6 files changed, 8 insertions(+), 23 deletions(-) diff --git a/lib/mock/db_mock.dart b/lib/mock/db_mock.dart index 68e3b4d..313cece 100644 --- a/lib/mock/db_mock.dart +++ b/lib/mock/db_mock.dart @@ -4,6 +4,7 @@ import 'package:smoke_cess_app/models/relapse.dart'; import 'package:smoke_cess_app/models/sleep.dart'; import 'package:smoke_cess_app/models/workout.dart'; import 'package:smoke_cess_app/services/database_service.dart'; +// ignore: depend_on_referenced_packages import 'package:sqflite_common/sqlite_api.dart'; class DatabaseMock implements DatabaseService { diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index bf26c40..1c0d64f 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/providers/input_provider.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/widgets/mute_button.dart'; diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index 29cf8a7..de394f9 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -17,15 +17,9 @@ class ScannerPage extends StatelessWidget { List moods = await globals.databaseService.getMoodRecords(); List sleeps = await globals.databaseService.getSleepRecords(); List relapses = await globals.databaseService.getRelapseRecords(); - for (Mood mood in moods) { - print(mood.toCSV()); - } - for (Sleep sleep in sleeps) { - print(sleep.toCSV()); - } - for (Relapse relapse in relapses) { - print(relapse.toCSV()); - } + moods; + sleeps; + relapses; } void loadJSON(BuildContext context) async { diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart index 311bf88..3996883 100644 --- a/lib/services/database_service.dart +++ b/lib/services/database_service.dart @@ -83,7 +83,7 @@ class DatabaseService { return await db.insert('relapse', relapse.toMap()); } - String _createMoodTable = ''' + final String _createMoodTable = ''' CREATE TABLE IF NOT EXISTS mood( id INTEGER PRIMARY KEY, value INTEGER, @@ -92,7 +92,7 @@ class DatabaseService { ) '''; - String _createSleepTable = ''' + final String _createSleepTable = ''' CREATE TABLE IF NOT EXISTS sleep( id INTEGER PRIMARY KEY, value INTEGER, @@ -105,7 +105,7 @@ class DatabaseService { ) '''; - String _createRelapseTable = ''' + final String _createRelapseTable = ''' CREATE TABLE IF NOT EXISTS relapse( id INTEGER PRIMARY KEY, date TEXT, @@ -114,7 +114,7 @@ class DatabaseService { ) '''; - String _createWorkoutTable = ''' + final String _createWorkoutTable = ''' CREATE TABLE IF NOT EXISTS workout( id INTEGER PRIMARY KEY, date TEXT, diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 8c7e7a7..f28556a 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -23,13 +23,6 @@ Future getMoodQueryMinutes() => _getIntSetting('mood_query_minutes'); Future getChessHours() => _getIntSetting('chess_hours'); Future getChessMinutes() => _getIntSetting('chess_minutes'); -void _setStringSetting(String settingKey, String settingValue) => - SharedPreferences.getInstance() - .then((pref) => pref.setString(settingKey, settingValue)); - -Future _getStringSetting(String settingKey) => - SharedPreferences.getInstance().then((pref) => pref.getString(settingKey)); - void _setIntSetting(String settingKey, int settingValue) => SharedPreferences.getInstance() .then((pref) => pref.setInt(settingKey, settingValue)); diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index b9a0e05..b461ce7 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/models/mood.dart'; -import 'package:smoke_cess_app/services/database_service.dart'; import 'package:smoke_cess_app/widgets/slider.dart'; import 'package:smoke_cess_app/widgets/submit_form_button.dart'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; From 26504f374e7f2d0ac7720da6a246988bb42cd411 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 17:40:55 +0100 Subject: [PATCH 13/54] trying different flutter version for pipeline --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 562ecfe..a81e822 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: cirrusci/flutter:latest +image: cirrusci/flutter:3.3.5 stages: - analyze From 175735f4b933b8dca568a9f49d013eae78b2286e Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 18:35:03 +0100 Subject: [PATCH 14/54] Added TaskProvider and Pages enum --- lib/main.dart | 8 +++-- lib/mock/db_mock.dart | 8 +++-- lib/models/mood.dart | 2 ++ lib/models/sleep.dart | 2 ++ lib/models/workout.dart | 4 ++- lib/pages/main_page.dart | 6 ++-- lib/providers/task_provider.dart | 56 ++++++++++++++++++++++++++++++ lib/services/database_service.dart | 9 +++++ lib/services/date_service.dart | 20 +++++++++++ lib/services/pages_service.dart | 38 ++++++++++++++------ 10 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 lib/providers/task_provider.dart diff --git a/lib/main.dart b/lib/main.dart index a1cf5ac..e52b7e6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/pages/main_page.dart'; +import 'package:smoke_cess_app/providers/task_provider.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:timezone/data/latest.dart' as tz; import 'globals.dart' as globals; @@ -25,8 +26,11 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: _title, - home: ChangeNotifierProvider( - create: (context) => SettingsProvider(), + home: MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => SettingsProvider()), + ChangeNotifierProvider(create: (context) => TaskProvider()), + ], child: const MyHomePage(), )); } diff --git a/lib/mock/db_mock.dart b/lib/mock/db_mock.dart index 313cece..4e5d0e6 100644 --- a/lib/mock/db_mock.dart +++ b/lib/mock/db_mock.dart @@ -1,4 +1,3 @@ -import 'package:smoke_cess_app/interface/db_record.dart'; import 'package:smoke_cess_app/models/mood.dart'; import 'package:smoke_cess_app/models/relapse.dart'; import 'package:smoke_cess_app/models/sleep.dart'; @@ -17,7 +16,7 @@ class DatabaseMock implements DatabaseService { final List _moodRecords = []; final List _sleepRecords = []; final List _relapseRecords = []; - final List _workoutRecords = []; + final List _workoutRecords = []; @override Future addMood(Mood mood) { @@ -60,4 +59,9 @@ class DatabaseMock implements DatabaseService { Future> getRelapseRecords() { return Future.value(_relapseRecords); } + + @override + Future> getWorkoutRecords() { + return Future.value(_workoutRecords); + } } diff --git a/lib/models/mood.dart b/lib/models/mood.dart index 562b2b4..7f5e7a6 100644 --- a/lib/models/mood.dart +++ b/lib/models/mood.dart @@ -7,6 +7,8 @@ class Mood implements DatabaseRecord { Mood(this._moodValue, this._comment, this._date); + DateTime get date => _date; + @override factory Mood.fromDatabase(Map map) { DateTime date = DateTime.parse(map['date']); diff --git a/lib/models/sleep.dart b/lib/models/sleep.dart index 3474b03..74fd6cb 100644 --- a/lib/models/sleep.dart +++ b/lib/models/sleep.dart @@ -11,6 +11,8 @@ class Sleep implements DatabaseRecord { Sleep(this._sleepQualityValue, this._comment, this._date, this._sleptAt, this._wokeUpAt); + DateTime get date => _date; + @override factory Sleep.fromDatabase(Map map) { DateTime date = DateTime.parse(map['date']); diff --git a/lib/models/workout.dart b/lib/models/workout.dart index 0bba86a..39ef628 100644 --- a/lib/models/workout.dart +++ b/lib/models/workout.dart @@ -7,8 +7,10 @@ class Workout implements DatabaseRecord { Workout(this._motivationBefore, this._motivationAfter, this._workoutDate); + DateTime get date => _workoutDate; + @override - factory Workout.fromMap(Map map) { + factory Workout.fromDatabase(Map map) { return Workout(map['_workoutDuration'], map['_motivationBefore'], map['_motivationAfter']); } diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index b45b479..1d55df5 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -36,7 +36,7 @@ class MyHomePageState extends State { return Scaffold( appBar: AppBar( title: Text( - '${pages.keys.elementAt(_selectedIndex)} ${_isConfigured ? "Gruppe $group" : ""}')), + '${pages.values.elementAt(_selectedIndex)['title']} ${_isConfigured ? "Gruppe $group" : ""}')), body: Center( child: SingleChildScrollView( child: pages.values.elementAt(_selectedIndex)['page'])), @@ -45,9 +45,9 @@ class MyHomePageState extends State { selectedIndex: _selectedIndex, destinations: pages.keys.map((key) { return NavigationDestination( - icon: pages[key]!['icon'] ?? + icon: pages[key]?['icon'] ?? const Icon(Icons.disabled_by_default), - label: key); + label: pages[key]?['title']); }).toList()), ); } diff --git a/lib/providers/task_provider.dart b/lib/providers/task_provider.dart new file mode 100644 index 0000000..cf27964 --- /dev/null +++ b/lib/providers/task_provider.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/models/sleep.dart'; +import 'package:smoke_cess_app/models/workout.dart'; +import 'package:smoke_cess_app/services/date_service.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; +import 'package:timezone/browser.dart'; +import '../globals.dart' as globals; +import '../models/mood.dart'; + +class TaskProvider extends ChangeNotifier { + TaskProvider() { + initTasks(); + } + + void setTaksDone(Pages taskName) { + pages[taskName]?['todo'] = false; + notifyListeners(); + } + + void initTasks() { + pages.forEach((key, value) async { + if (!value['todo']) { + switch (key) { + case Pages.mood: + TZDateTime? moodToday = await getTodayMood(); + if (moodToday != null) { + List moodList = + await globals.databaseService.getMoodRecords(); + Mood mood = moodList.last; + pages[key]?['todo'] = !isSameDay(moodToday, mood.date); + } + break; + case Pages.sleep: + TZDateTime? sleepToday = await getTodayMood(); + if (sleepToday != null) { + List sleepList = + await globals.databaseService.getSleepRecords(); + Sleep sleep = sleepList.last; + pages[key]?['todo'] = !isSameDay(sleepToday, sleep.date); + } + break; + case Pages.timer: + { + List workoutList = + await globals.databaseService.getWorkoutRecords(); + Workout mood = workoutList.last; + pages[key]?['todo'] = !isSameDay(DateTime.now(), mood.date); + break; + } + default: + } + } + }); + notifyListeners(); + } +} diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart index 3996883..acc3ca0 100644 --- a/lib/services/database_service.dart +++ b/lib/services/database_service.dart @@ -63,6 +63,15 @@ class DatabaseService { return relapseList; } + Future> getWorkoutRecords() async { + Database db = await instance.database; + var workoutRecords = await db.query('workout'); + List workoutList = workoutRecords.isNotEmpty + ? workoutRecords.map((e) => Workout.fromDatabase(e)).toList() + : []; + return workoutList; + } + Future addMood(Mood mood) async { Database db = await instance.database; return await db.insert('mood', mood.toMap()); diff --git a/lib/services/date_service.dart b/lib/services/date_service.dart index 0fd108e..b5e254f 100644 --- a/lib/services/date_service.dart +++ b/lib/services/date_service.dart @@ -13,6 +13,12 @@ const weekDays = { "Sonntag": 7, }; +bool isSameDay(DateTime? dateA, DateTime? dateB) { + return dateA?.year == dateB?.year && + dateA?.month == dateB?.month && + dateA?.day == dateB?.day; +} + Future> getDatesforMood() async { final List? selectedDays = await getMoodQueryDaysCategories(); final int? selectedHours = await getMoodQueryHours(); @@ -27,6 +33,20 @@ Future> getDatesforSleep() async { return createTZDateTimes(selectedDays, selectedHours, selectedMinutes); } +Future getTodayMood() async { + List moodDates = await getDatesforMood(); + Iterable today = + moodDates.where((element) => isSameDay(element, DateTime.now())); + return today.isNotEmpty ? today.first : null; +} + +Future getTodaySleep() async { + List sleepDates = await getDatesforSleep(); + Iterable today = + sleepDates.where((element) => isSameDay(element, DateTime.now())); + return today.isNotEmpty ? today.first : null; +} + List createTZDateTimes( List? selectedDays, int? selectedHours, int? selectedMinutes) { final List tzDateTimes = []; diff --git a/lib/services/pages_service.dart b/lib/services/pages_service.dart index 8f3ab37..c29795a 100644 --- a/lib/services/pages_service.dart +++ b/lib/services/pages_service.dart @@ -5,25 +5,43 @@ import '../pages/relapse_page.dart'; import '../pages/scanner_page.dart'; import '../pages/sleep_page.dart'; -const pages = { - 'Stimmung': { +enum Pages { + mood, + sleep, + relapse, + timer, + settings, +} + +const Map> pages = { + Pages.mood: { + 'title': 'Stimmung', 'page': MoodPage(), - 'icon': Icon(Icons.mood_outlined, color: Colors.black) + 'icon': Icon(Icons.mood_outlined, color: Colors.black), + 'todo': false, }, - 'Schlaf': { + Pages.sleep: { + 'title': 'Schlaf', 'page': SleepPage(), - 'icon': Icon(Icons.bedtime_outlined, color: Colors.black) + 'icon': Icon(Icons.bedtime_outlined, color: Colors.black), + 'todo': false, }, - 'Timer': { + Pages.relapse: { + 'title': 'Timer', 'page': IntervalTimerPage(), - 'icon': Icon(Icons.timer_outlined, color: Colors.black) + 'icon': Icon(Icons.timer_outlined, color: Colors.black), + 'todo': false, }, - 'Rückfall': { + Pages.timer: { + 'title': 'Rückfall', 'page': RelapsePage(), 'icon': Icon(Icons.smoke_free_outlined, color: Colors.black), + 'todo': false, }, - 'Scanner': { + Pages.settings: { + 'title': 'Scanner', 'page': ScannerPage(), - 'icon': Icon(Icons.camera_alt_outlined, color: Colors.black) + 'icon': Icon(Icons.camera_alt_outlined, color: Colors.black), + 'todo': false, }, }; From a042933a2dcbc1974107d119767fa215eabab7ea Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 19:04:03 +0100 Subject: [PATCH 15/54] add http package --- android/app/src/main/AndroidManifest.xml | 2 ++ pubspec.lock | 2 +- pubspec.yaml | 9 +++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index bae31ce..c5439ff 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,7 @@ + + Date: Thu, 2 Mar 2023 19:04:40 +0100 Subject: [PATCH 16/54] add workout get db function --- lib/mock/db_mock.dart | 7 ++++++- lib/models/workout.dart | 10 ++++++++-- lib/services/database_service.dart | 9 +++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/mock/db_mock.dart b/lib/mock/db_mock.dart index 313cece..dac8c9f 100644 --- a/lib/mock/db_mock.dart +++ b/lib/mock/db_mock.dart @@ -17,7 +17,7 @@ class DatabaseMock implements DatabaseService { final List _moodRecords = []; final List _sleepRecords = []; final List _relapseRecords = []; - final List _workoutRecords = []; + final List _workoutRecords = []; @override Future addMood(Mood mood) { @@ -60,4 +60,9 @@ class DatabaseMock implements DatabaseService { Future> getRelapseRecords() { return Future.value(_relapseRecords); } + + @override + Future> getWorkoutRecords() { + return Future.value(_workoutRecords); + } } diff --git a/lib/models/workout.dart b/lib/models/workout.dart index 0bba86a..67dd828 100644 --- a/lib/models/workout.dart +++ b/lib/models/workout.dart @@ -7,10 +7,16 @@ class Workout implements DatabaseRecord { Workout(this._motivationBefore, this._motivationAfter, this._workoutDate); + @override + factory Workout.fromDatabase(Map map) { + return Workout(map['motivationBefore'], map['motivationAfter'], + DateTime.parse(map['workoutDate'])); + } + @override factory Workout.fromMap(Map map) { - return Workout(map['_workoutDuration'], map['_motivationBefore'], - map['_motivationAfter']); + return Workout( + map['motivationBefore'], map['motivationAfter'], map['workoutDate']); } @override diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart index 3996883..acc3ca0 100644 --- a/lib/services/database_service.dart +++ b/lib/services/database_service.dart @@ -63,6 +63,15 @@ class DatabaseService { return relapseList; } + Future> getWorkoutRecords() async { + Database db = await instance.database; + var workoutRecords = await db.query('workout'); + List workoutList = workoutRecords.isNotEmpty + ? workoutRecords.map((e) => Workout.fromDatabase(e)).toList() + : []; + return workoutList; + } + Future addMood(Mood mood) async { Database db = await instance.database; return await db.insert('mood', mood.toMap()); From c3fde53bec01c2612f5de33ada7489a79652b3fc Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 19:31:47 +0100 Subject: [PATCH 17/54] added TasksProvider to MainPage --- assets/group3.json | 2 +- lib/main.dart | 4 +-- lib/pages/main_page.dart | 28 +++++++++++++--- lib/providers/task_provider.dart | 56 ------------------------------- lib/providers/tasks_provider.dart | 55 ++++++++++++++++++++++++++++++ lib/services/pages_service.dart | 9 ++--- 6 files changed, 84 insertions(+), 70 deletions(-) delete mode 100644 lib/providers/task_provider.dart create mode 100644 lib/providers/tasks_provider.dart diff --git a/assets/group3.json b/assets/group3.json index 55ce9e0..30e9886 100644 --- a/assets/group3.json +++ b/assets/group3.json @@ -7,7 +7,7 @@ }, "relapse_categories": ["App stresst mich", "langeweile", "lunge braucht es"], "mood_query": { - "days": ["Montag", "Freitag"], + "days": ["Montag", "Donnerstag"], "hours": 10, "minutes": 30 }, diff --git a/lib/main.dart b/lib/main.dart index e52b7e6..0c574ce 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/pages/main_page.dart'; -import 'package:smoke_cess_app/providers/task_provider.dart'; +import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:timezone/data/latest.dart' as tz; import 'globals.dart' as globals; @@ -29,7 +29,7 @@ class MyApp extends StatelessWidget { home: MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => SettingsProvider()), - ChangeNotifierProvider(create: (context) => TaskProvider()), + ChangeNotifierProvider(create: (context) => TasksProvider()), ], child: const MyHomePage(), )); diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 1d55df5..13defdb 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -1,6 +1,7 @@ import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; @@ -31,12 +32,12 @@ class MyHomePageState extends State { @override Widget build(BuildContext context) { var settingsModel = context.watch(); - var group = settingsModel.settings?.group; + var tasksModel = context.watch(); _isConfigured = settingsModel.initialized; return Scaffold( appBar: AppBar( title: Text( - '${pages.values.elementAt(_selectedIndex)['title']} ${_isConfigured ? "Gruppe $group" : ""}')), + '${pages.values.elementAt(_selectedIndex)['title']} + ${_isConfigured ? "Gruppe ${settingsModel.settings?.group}" : ""}')), body: Center( child: SingleChildScrollView( child: pages.values.elementAt(_selectedIndex)['page'])), @@ -45,10 +46,29 @@ class MyHomePageState extends State { selectedIndex: _selectedIndex, destinations: pages.keys.map((key) { return NavigationDestination( - icon: pages[key]?['icon'] ?? - const Icon(Icons.disabled_by_default), + icon: tasksModel.tasks[key] ?? false + ? MyToDoIcon(pages[key]?['icon']) + : pages[key]!['icon'], label: pages[key]?['title']); }).toList()), ); } } + +class MyToDoIcon extends StatelessWidget { + final Icon _icon; + const MyToDoIcon(this._icon, {super.key}); + + @override + Widget build(BuildContext context) { + return Stack(children: [ + _icon, + const Positioned( + // draw a red marble + top: 0.0, + right: 0.0, + child: Icon(Icons.brightness_1, size: 10.0, color: Colors.redAccent), + ) + ]); + } +} diff --git a/lib/providers/task_provider.dart b/lib/providers/task_provider.dart deleted file mode 100644 index cf27964..0000000 --- a/lib/providers/task_provider.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:smoke_cess_app/models/sleep.dart'; -import 'package:smoke_cess_app/models/workout.dart'; -import 'package:smoke_cess_app/services/date_service.dart'; -import 'package:smoke_cess_app/services/pages_service.dart'; -import 'package:timezone/browser.dart'; -import '../globals.dart' as globals; -import '../models/mood.dart'; - -class TaskProvider extends ChangeNotifier { - TaskProvider() { - initTasks(); - } - - void setTaksDone(Pages taskName) { - pages[taskName]?['todo'] = false; - notifyListeners(); - } - - void initTasks() { - pages.forEach((key, value) async { - if (!value['todo']) { - switch (key) { - case Pages.mood: - TZDateTime? moodToday = await getTodayMood(); - if (moodToday != null) { - List moodList = - await globals.databaseService.getMoodRecords(); - Mood mood = moodList.last; - pages[key]?['todo'] = !isSameDay(moodToday, mood.date); - } - break; - case Pages.sleep: - TZDateTime? sleepToday = await getTodayMood(); - if (sleepToday != null) { - List sleepList = - await globals.databaseService.getSleepRecords(); - Sleep sleep = sleepList.last; - pages[key]?['todo'] = !isSameDay(sleepToday, sleep.date); - } - break; - case Pages.timer: - { - List workoutList = - await globals.databaseService.getWorkoutRecords(); - Workout mood = workoutList.last; - pages[key]?['todo'] = !isSameDay(DateTime.now(), mood.date); - break; - } - default: - } - } - }); - notifyListeners(); - } -} diff --git a/lib/providers/tasks_provider.dart b/lib/providers/tasks_provider.dart new file mode 100644 index 0000000..182b8ec --- /dev/null +++ b/lib/providers/tasks_provider.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/models/sleep.dart'; +import 'package:smoke_cess_app/models/workout.dart'; +import 'package:smoke_cess_app/services/date_service.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; +import 'package:timezone/browser.dart'; +import '../globals.dart' as globals; +import '../models/mood.dart'; + +class TasksProvider extends ChangeNotifier { + Map tasks = { + Pages.mood: true, + Pages.sleep: true, + Pages.timer: true, + }; + + TasksProvider() { + initTasks(); + } + + void setTaksDone(Pages taskName) { + tasks[taskName] = false; + notifyListeners(); + } + + void initTasks() async { + TZDateTime? moodToday = await getTodayMood(); + if (moodToday != null) { + List moodList = await globals.databaseService.getMoodRecords(); + if (moodList.isNotEmpty) { + Mood mood = moodList.last; + tasks[Pages.mood] = isSameDay(moodToday, mood.date); + } + } else { + tasks[Pages.mood] = false; + } + TZDateTime? sleepToday = await getTodayMood(); + if (sleepToday != null) { + List sleepList = await globals.databaseService.getSleepRecords(); + if (sleepList.isNotEmpty) { + Sleep sleep = sleepList.last; + tasks[Pages.sleep] = isSameDay(sleepToday, sleep.date); + } + } else { + tasks[Pages.sleep] = false; + } + List workoutList = + await globals.databaseService.getWorkoutRecords(); + if (workoutList.isNotEmpty) { + Workout mood = workoutList.last; + tasks[Pages.timer] = isSameDay(DateTime.now(), mood.date); + } + notifyListeners(); + } +} diff --git a/lib/services/pages_service.dart b/lib/services/pages_service.dart index c29795a..0c19383 100644 --- a/lib/services/pages_service.dart +++ b/lib/services/pages_service.dart @@ -18,30 +18,25 @@ const Map> pages = { 'title': 'Stimmung', 'page': MoodPage(), 'icon': Icon(Icons.mood_outlined, color: Colors.black), - 'todo': false, }, Pages.sleep: { 'title': 'Schlaf', 'page': SleepPage(), 'icon': Icon(Icons.bedtime_outlined, color: Colors.black), - 'todo': false, }, - Pages.relapse: { + Pages.timer: { 'title': 'Timer', 'page': IntervalTimerPage(), 'icon': Icon(Icons.timer_outlined, color: Colors.black), - 'todo': false, }, - Pages.timer: { + Pages.relapse: { 'title': 'Rückfall', 'page': RelapsePage(), 'icon': Icon(Icons.smoke_free_outlined, color: Colors.black), - 'todo': false, }, Pages.settings: { 'title': 'Scanner', 'page': ScannerPage(), 'icon': Icon(Icons.camera_alt_outlined, color: Colors.black), - 'todo': false, }, }; From 1a7f98c5381ec017aeb9d2a784949b2eb1d069e9 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 19:32:13 +0100 Subject: [PATCH 18/54] Fixed wrong title --- lib/pages/main_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 13defdb..82b4990 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -37,7 +37,7 @@ class MyHomePageState extends State { return Scaffold( appBar: AppBar( title: Text( - '${pages.values.elementAt(_selectedIndex)['title']} + ${_isConfigured ? "Gruppe ${settingsModel.settings?.group}" : ""}')), + '${pages.values.elementAt(_selectedIndex)['title']} ${_isConfigured ? "Gruppe ${settingsModel.settings?.group}" : ""}')), body: Center( child: SingleChildScrollView( child: pages.values.elementAt(_selectedIndex)['page'])), From 0e070d73a2a7a6f0f133e67b2c963c740b7fa5bf Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 19:41:13 +0100 Subject: [PATCH 19/54] sending data of records to api --- lib/pages/scanner_page.dart | 13 +++------- lib/services/export_service.dart | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 lib/services/export_service.dart diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index de394f9..d809ff9 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -1,25 +1,18 @@ import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/models/mood.dart'; -import 'package:smoke_cess_app/models/relapse.dart'; +import 'package:smoke_cess_app/services/export_service.dart'; import 'package:smoke_cess_app/services/settings_service.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:smoke_cess_app/widgets/scanner.dart'; -import '../models/sleep.dart'; import '../providers/settings_provider.dart'; -import '../globals.dart' as globals; class ScannerPage extends StatelessWidget { const ScannerPage({super.key}); void export() async { - List moods = await globals.databaseService.getMoodRecords(); - List sleeps = await globals.databaseService.getSleepRecords(); - List relapses = await globals.databaseService.getRelapseRecords(); - moods; - sleeps; - relapses; + ExportService exportService = ExportService(); + exportService.exportData(); } void loadJSON(BuildContext context) async { diff --git a/lib/services/export_service.dart b/lib/services/export_service.dart new file mode 100644 index 0000000..12afa12 --- /dev/null +++ b/lib/services/export_service.dart @@ -0,0 +1,43 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:smoke_cess_app/models/mood.dart'; +import 'package:smoke_cess_app/models/relapse.dart'; +import 'package:smoke_cess_app/models/sleep.dart'; +import 'package:smoke_cess_app/models/workout.dart'; +import 'package:smoke_cess_app/services/database_service.dart'; +import '../globals.dart' as globals; + +class ExportService { + Uri url = Uri.parse('http://localhost:3000/data'); + final DatabaseService _databaseService = globals.databaseService; + + Future>> _loadRecords() async { + List moodRecords = await _databaseService.getMoodRecords(); + List sleepRecords = await _databaseService.getSleepRecords(); + List relapseRecords = await _databaseService.getRelapseRecords(); + List workoutRecords = await _databaseService.getWorkoutRecords(); + return { + 'Stimmung': + moodRecords.map((Mood mood) => jsonEncode(mood.toMap())).toList(), + 'Schlaf': + sleepRecords.map((Sleep sleep) => jsonEncode(sleep.toMap())).toList(), + 'Rückfall': relapseRecords + .map((Relapse relapse) => jsonEncode(relapse.toMap())) + .toList(), + 'Workout': workoutRecords + .map((Workout workout) => jsonEncode(workout.toMap())) + .toList() + }; + } + + void exportData() async { + Map> body = await _loadRecords(); + final response = await http.post(url, + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + body: jsonEncode(body)); + print(response.statusCode); + } +} From 0e49b9cd32a808942328a72f39a4c0120cbbc8c3 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 19:43:05 +0100 Subject: [PATCH 20/54] make date field of workout json encodable --- lib/models/workout.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/workout.dart b/lib/models/workout.dart index 67dd828..671dfc8 100644 --- a/lib/models/workout.dart +++ b/lib/models/workout.dart @@ -28,7 +28,7 @@ class Workout implements DatabaseRecord { return { 'motivationBefore': _motivationBefore, 'motivationAfter': _motivationAfter, - 'workoutDate': _workoutDate, + 'workoutDate': _workoutDate.toIso8601String(), }; } } From 7bc9d4f35d08076036826f26c62d7bdf19b20f4a Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 19:47:28 +0100 Subject: [PATCH 21/54] add minimal errorcheck --- lib/mock/db_mock.dart | 1 - lib/services/export_service.dart | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/mock/db_mock.dart b/lib/mock/db_mock.dart index dac8c9f..4e5d0e6 100644 --- a/lib/mock/db_mock.dart +++ b/lib/mock/db_mock.dart @@ -1,4 +1,3 @@ -import 'package:smoke_cess_app/interface/db_record.dart'; import 'package:smoke_cess_app/models/mood.dart'; import 'package:smoke_cess_app/models/relapse.dart'; import 'package:smoke_cess_app/models/sleep.dart'; diff --git a/lib/services/export_service.dart b/lib/services/export_service.dart index 12afa12..9758270 100644 --- a/lib/services/export_service.dart +++ b/lib/services/export_service.dart @@ -31,13 +31,13 @@ class ExportService { }; } - void exportData() async { + Future exportData() async { Map> body = await _loadRecords(); final response = await http.post(url, headers: { 'Content-Type': 'application/json; charset=UTF-8', }, body: jsonEncode(body)); - print(response.statusCode); + return response.statusCode >= 400 ? 0 : 1; } } From d18bf8f56d372e1c3b19036537c6cedd6a777305 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 19:57:24 +0100 Subject: [PATCH 22/54] Update Tasks when Settings update --- lib/main.dart | 6 +++++- lib/providers/tasks_provider.dart | 11 ++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 0c574ce..c5a19b7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -29,7 +29,11 @@ class MyApp extends StatelessWidget { home: MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => SettingsProvider()), - ChangeNotifierProvider(create: (context) => TasksProvider()), + ChangeNotifierProxyProvider( + create: (context) => TasksProvider(null), + update: (context, value, TasksProvider? previous) => + TasksProvider(value), + ), ], child: const MyHomePage(), )); diff --git a/lib/providers/tasks_provider.dart b/lib/providers/tasks_provider.dart index 182b8ec..8ae2a04 100644 --- a/lib/providers/tasks_provider.dart +++ b/lib/providers/tasks_provider.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:smoke_cess_app/models/sleep.dart'; import 'package:smoke_cess_app/models/workout.dart'; +import 'package:smoke_cess_app/providers/settings_provider.dart'; import 'package:smoke_cess_app/services/date_service.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:timezone/browser.dart'; @@ -14,7 +15,7 @@ class TasksProvider extends ChangeNotifier { Pages.timer: true, }; - TasksProvider() { + TasksProvider(SettingsProvider? settingsProvider) { initTasks(); } @@ -29,17 +30,17 @@ class TasksProvider extends ChangeNotifier { List moodList = await globals.databaseService.getMoodRecords(); if (moodList.isNotEmpty) { Mood mood = moodList.last; - tasks[Pages.mood] = isSameDay(moodToday, mood.date); + tasks[Pages.mood] = !isSameDay(moodToday, mood.date); } } else { tasks[Pages.mood] = false; } - TZDateTime? sleepToday = await getTodayMood(); + TZDateTime? sleepToday = await getTodaySleep(); if (sleepToday != null) { List sleepList = await globals.databaseService.getSleepRecords(); if (sleepList.isNotEmpty) { Sleep sleep = sleepList.last; - tasks[Pages.sleep] = isSameDay(sleepToday, sleep.date); + tasks[Pages.sleep] = !isSameDay(sleepToday, sleep.date); } } else { tasks[Pages.sleep] = false; @@ -48,7 +49,7 @@ class TasksProvider extends ChangeNotifier { await globals.databaseService.getWorkoutRecords(); if (workoutList.isNotEmpty) { Workout mood = workoutList.last; - tasks[Pages.timer] = isSameDay(DateTime.now(), mood.date); + tasks[Pages.timer] = !isSameDay(DateTime.now(), mood.date); } notifyListeners(); } From e8a123413c9959b26f083aaaca20dced75910bba Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 20:16:46 +0100 Subject: [PATCH 23/54] Update when submiting form --- lib/widgets/mood_form.dart | 4 ++++ lib/widgets/relapse_form.dart | 9 ++++++-- lib/widgets/sleep_form.dart | 4 ++++ lib/widgets/submit_form_button.dart | 33 +++++++++++++++++------------ 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index b461ce7..4661678 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/tasks_provider.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/widgets/slider.dart'; import 'package:smoke_cess_app/widgets/submit_form_button.dart'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; @@ -13,6 +15,7 @@ class MoodForm extends StatelessWidget { @override Widget build(BuildContext context) { var inputModel = context.watch(); + var tasksModel = context.watch(); return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -30,6 +33,7 @@ class MoodForm extends StatelessWidget { ), SubmitFormButton( submitCallback: inputModel.saveMood, + updateTasks: () => tasksModel.setTaksDone(Pages.mood), ) ], ); diff --git a/lib/widgets/relapse_form.dart b/lib/widgets/relapse_form.dart index 88e555c..38d3492 100644 --- a/lib/widgets/relapse_form.dart +++ b/lib/widgets/relapse_form.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/widgets/drop_down.dart'; import 'package:smoke_cess_app/widgets/submit_form_button.dart'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; - import '../providers/input_provider.dart'; import '../providers/settings_provider.dart'; +import '../services/pages_service.dart'; import 'elevated_card.dart'; class RelapseForm extends StatelessWidget { @@ -15,6 +16,7 @@ class RelapseForm extends StatelessWidget { Widget build(BuildContext context) { var inputModel = context.watch(); var settingsModel = context.watch(); + var tasksModel = context.watch(); return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -29,7 +31,10 @@ class RelapseForm extends StatelessWidget { const SizedBox( height: 80, ), - SubmitFormButton(submitCallback: inputModel.saveRelapse) + SubmitFormButton( + submitCallback: inputModel.saveRelapse, + updateTasks: () => tasksModel.setTaksDone(Pages.mood), + ) ], ); } diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index 8b4389c..b578e2c 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/widgets/elevated_card.dart'; import 'package:smoke_cess_app/widgets/slider.dart'; import 'package:smoke_cess_app/widgets/submit_form_button.dart'; @@ -7,6 +8,7 @@ import 'package:smoke_cess_app/widgets/text_formfield.dart'; import 'package:smoke_cess_app/widgets/timepicker.dart'; import '../providers/input_provider.dart'; +import '../services/pages_service.dart'; class SleepForm extends StatelessWidget { const SleepForm({Key? key}) : super(key: key); @@ -14,6 +16,7 @@ class SleepForm extends StatelessWidget { @override Widget build(BuildContext context) { InputProvider inputModel = context.watch(); + TasksProvider tasksModel = context.watch(); String wokeUpKey = 'wokeUpAt'; String sleptKey = 'sleptAt'; @@ -44,6 +47,7 @@ class SleepForm extends StatelessWidget { ), SubmitFormButton( submitCallback: () => inputModel.saveSleep(wokeUpKey, sleptKey), + updateTasks: () => tasksModel.setTaksDone(Pages.mood), ) ], ); diff --git a/lib/widgets/submit_form_button.dart b/lib/widgets/submit_form_button.dart index 3242b18..b5bb593 100644 --- a/lib/widgets/submit_form_button.dart +++ b/lib/widgets/submit_form_button.dart @@ -3,7 +3,9 @@ import 'package:flutter/material.dart'; class SubmitFormButton extends StatelessWidget { final Future Function() submitCallback; - const SubmitFormButton({super.key, required this.submitCallback}); + final void Function() updateTasks; + const SubmitFormButton( + {super.key, required this.submitCallback, required this.updateTasks}); @override Widget build(BuildContext context) { @@ -12,19 +14,22 @@ class SubmitFormButton extends StatelessWidget { child: ElevatedButton( onPressed: () async { int success = await submitCallback(); - success != 0 - ? AwesomeDialog( - context: context, - dialogType: DialogType.success, - title: 'Gespeichert', - desc: 'Der Eintrag wurde erfolgreich gespeichert', - ).show() - : AwesomeDialog( - context: context, - dialogType: DialogType.error, - title: 'Fehler', - desc: 'Der Eintrag konnte nicht gespeichert werden', - ).show(); + if (success != 0) { + AwesomeDialog( + context: context, + dialogType: DialogType.success, + title: 'Gespeichert', + desc: 'Der Eintrag wurde erfolgreich gespeichert', + ).show(); + updateTasks(); + } else { + AwesomeDialog( + context: context, + dialogType: DialogType.error, + title: 'Fehler', + desc: 'Der Eintrag konnte nicht gespeichert werden', + ).show(); + } }, child: const Text('Speichern'), ), From c480f83f6d8b98b5d6e7185b9a0f6c4bdcc26d60 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 20:20:17 +0100 Subject: [PATCH 24/54] outsource todoicon --- lib/pages/main_page.dart | 20 ++------------------ lib/widgets/todo_icon.dart | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 lib/widgets/todo_icon.dart diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 82b4990..ce6a1ff 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -5,6 +5,8 @@ import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; +import '../widgets/todo_icon.dart'; + class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @@ -54,21 +56,3 @@ class MyHomePageState extends State { ); } } - -class MyToDoIcon extends StatelessWidget { - final Icon _icon; - const MyToDoIcon(this._icon, {super.key}); - - @override - Widget build(BuildContext context) { - return Stack(children: [ - _icon, - const Positioned( - // draw a red marble - top: 0.0, - right: 0.0, - child: Icon(Icons.brightness_1, size: 10.0, color: Colors.redAccent), - ) - ]); - } -} diff --git a/lib/widgets/todo_icon.dart b/lib/widgets/todo_icon.dart new file mode 100644 index 0000000..e5c82b6 --- /dev/null +++ b/lib/widgets/todo_icon.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class MyToDoIcon extends StatelessWidget { + final Icon _icon; + const MyToDoIcon(this._icon, {super.key}); + + @override + Widget build(BuildContext context) { + return Stack(children: [ + _icon, + const Positioned( + // draw a red marble + top: 0.0, + right: 0.0, + child: Icon(Icons.brightness_1, size: 10.0, color: Colors.redAccent), + ) + ]); + } +} From 7689de73ac39342c1c9fc7dae3bd4fd21acb7bb0 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 20:33:44 +0100 Subject: [PATCH 25/54] Refactor wrong method name --- lib/providers/tasks_provider.dart | 2 +- lib/widgets/mood_form.dart | 2 +- lib/widgets/relapse_form.dart | 2 +- lib/widgets/sleep_form.dart | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/providers/tasks_provider.dart b/lib/providers/tasks_provider.dart index 8ae2a04..f7cd673 100644 --- a/lib/providers/tasks_provider.dart +++ b/lib/providers/tasks_provider.dart @@ -19,7 +19,7 @@ class TasksProvider extends ChangeNotifier { initTasks(); } - void setTaksDone(Pages taskName) { + void setTaskDone(Pages taskName) { tasks[taskName] = false; notifyListeners(); } diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index 4661678..e43e97d 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -33,7 +33,7 @@ class MoodForm extends StatelessWidget { ), SubmitFormButton( submitCallback: inputModel.saveMood, - updateTasks: () => tasksModel.setTaksDone(Pages.mood), + updateTasks: () => tasksModel.setTaskDone(Pages.mood), ) ], ); diff --git a/lib/widgets/relapse_form.dart b/lib/widgets/relapse_form.dart index 38d3492..9451277 100644 --- a/lib/widgets/relapse_form.dart +++ b/lib/widgets/relapse_form.dart @@ -33,7 +33,7 @@ class RelapseForm extends StatelessWidget { ), SubmitFormButton( submitCallback: inputModel.saveRelapse, - updateTasks: () => tasksModel.setTaksDone(Pages.mood), + updateTasks: () => tasksModel.setTaskDone(Pages.mood), ) ], ); diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index b578e2c..ad033ba 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -47,7 +47,7 @@ class SleepForm extends StatelessWidget { ), SubmitFormButton( submitCallback: () => inputModel.saveSleep(wokeUpKey, sleptKey), - updateTasks: () => tasksModel.setTaksDone(Pages.mood), + updateTasks: () => tasksModel.setTaskDone(Pages.mood), ) ], ); From afe481305c11121062b8b7dd9afd5db1f6fe0778 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Thu, 2 Mar 2023 20:35:20 +0100 Subject: [PATCH 26/54] Add TaskProvider to Workout --- lib/widgets/workout_timer_widget.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 59f67d4..a85a09e 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -2,7 +2,9 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/widgets/timer_widget.dart'; import '../providers/timer_provider.dart'; @@ -15,6 +17,7 @@ class WorkoutTimerWidget extends StatelessWidget { Widget build(BuildContext context) { TimerProvider timerProvider = context.watch(); WorkoutProvider workoutProvider = context.watch(); + TasksProvider tasksProvider = context.read(); if (workoutProvider.isPhaseComplete && !workoutProvider.isWorkoutComplete) { Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase()); @@ -26,6 +29,7 @@ class WorkoutTimerWidget extends StatelessWidget { () => showMotivationPopup(context, (double value) { workoutProvider.motivationAfter = value.toInt(); workoutProvider.saveWorkout(); + tasksProvider.setTaskDone(Pages.timer); }, 'Motivation nach dem Training')); } From 1566f5c92aa7e6d4132c64f20ce5cf48f7d37b63 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 12:47:54 +0100 Subject: [PATCH 27/54] Added Getters for Models --- lib/models/mood.dart | 1 + lib/models/relapse.dart | 3 +++ lib/models/sleep.dart | 1 + lib/models/workout.dart | 2 ++ 4 files changed, 7 insertions(+) diff --git a/lib/models/mood.dart b/lib/models/mood.dart index 7f5e7a6..9d34051 100644 --- a/lib/models/mood.dart +++ b/lib/models/mood.dart @@ -8,6 +8,7 @@ class Mood implements DatabaseRecord { Mood(this._moodValue, this._comment, this._date); DateTime get date => _date; + int get moodValue => _moodValue; @override factory Mood.fromDatabase(Map map) { diff --git a/lib/models/relapse.dart b/lib/models/relapse.dart index 0271d31..1507188 100644 --- a/lib/models/relapse.dart +++ b/lib/models/relapse.dart @@ -7,6 +7,9 @@ class Relapse implements DatabaseRecord { Relapse(this._category, this._comment, this._date); + String get category => _category; + DateTime get date => _date; + @override factory Relapse.fromDatabase(Map map) { DateTime date = DateTime.parse(map['date']); diff --git a/lib/models/sleep.dart b/lib/models/sleep.dart index 74fd6cb..4447be4 100644 --- a/lib/models/sleep.dart +++ b/lib/models/sleep.dart @@ -12,6 +12,7 @@ class Sleep implements DatabaseRecord { this._wokeUpAt); DateTime get date => _date; + int get sleepQualitiyValue => _sleepQualityValue; @override factory Sleep.fromDatabase(Map map) { diff --git a/lib/models/workout.dart b/lib/models/workout.dart index 187b7f6..dd27105 100644 --- a/lib/models/workout.dart +++ b/lib/models/workout.dart @@ -8,6 +8,8 @@ class Workout implements DatabaseRecord { Workout(this._motivationBefore, this._motivationAfter, this._workoutDate); DateTime get date => _workoutDate; + int get motivationBefore => _motivationBefore; + int get motivationAfter => _motivationAfter; @override factory Workout.fromDatabase(Map map) { From 6e9f213cdcc4309cfba41192b6243f7213a81749 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 12:48:19 +0100 Subject: [PATCH 28/54] Added PageProvider --- lib/pages/main_page.dart | 9 ++++++--- lib/providers/page_provider.dart | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 lib/providers/page_provider.dart diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index ce6a1ff..338dd75 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -1,6 +1,7 @@ import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/page_provider.dart'; import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; @@ -40,9 +41,11 @@ class MyHomePageState extends State { appBar: AppBar( title: Text( '${pages.values.elementAt(_selectedIndex)['title']} ${_isConfigured ? "Gruppe ${settingsModel.settings?.group}" : ""}')), - body: Center( - child: SingleChildScrollView( - child: pages.values.elementAt(_selectedIndex)['page'])), + body: SingleChildScrollView( + child: ChangeNotifierProvider( + create: (context) => PageProvider(), + child: pages.values.elementAt(_selectedIndex)['page'], + )), bottomNavigationBar: NavigationBar( onDestinationSelected: _onItemTapped, selectedIndex: _selectedIndex, diff --git a/lib/providers/page_provider.dart b/lib/providers/page_provider.dart new file mode 100644 index 0000000..a17ff26 --- /dev/null +++ b/lib/providers/page_provider.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class PageProvider extends ChangeNotifier { + bool showForm = false; + + void swap() { + showForm = !showForm; + notifyListeners(); + } +} From efd38e78d5d713dc799a3380c3310f9214fb3598 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 12:49:42 +0100 Subject: [PATCH 29/54] Added ViewFormPage --- lib/pages/mood_page.dart | 12 ++++---- lib/pages/relapse_page.dart | 11 ++++--- lib/pages/sleep_page.dart | 12 ++++---- lib/widgets/view_form_page.dart | 51 +++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 lib/widgets/view_form_page.dart diff --git a/lib/pages/mood_page.dart b/lib/pages/mood_page.dart index 546c6f1..8c2447d 100644 --- a/lib/pages/mood_page.dart +++ b/lib/pages/mood_page.dart @@ -1,17 +1,15 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/providers/input_provider.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/widgets/mood_form.dart'; +import 'package:smoke_cess_app/widgets/mood_view.dart'; +import 'package:smoke_cess_app/widgets/view_form_page.dart'; class MoodPage extends StatelessWidget { const MoodPage({super.key}); @override Widget build(BuildContext context) { - return Center( - child: ChangeNotifierProvider( - create: (context) => InputProvider(), - child: const MoodForm(), - )); + return const ViewFormPage( + form: MoodForm(), view: MoodView(), page: Pages.mood); } } diff --git a/lib/pages/relapse_page.dart b/lib/pages/relapse_page.dart index 75e007d..b0edf96 100644 --- a/lib/pages/relapse_page.dart +++ b/lib/pages/relapse_page.dart @@ -1,17 +1,16 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/widgets/relapse_form.dart'; -import '../providers/input_provider.dart'; +import 'package:smoke_cess_app/widgets/relapse_view.dart'; +import '../widgets/view_form_page.dart'; class RelapsePage extends StatelessWidget { const RelapsePage({super.key}); @override Widget build(BuildContext context) { - return Center( - child: ChangeNotifierProvider( - create: (context) => InputProvider(), - child: const RelapseForm(), - )); + return const ViewFormPage( + form: RelapseForm(), view: RelapseView(), page: Pages.relapse); } } diff --git a/lib/pages/sleep_page.dart b/lib/pages/sleep_page.dart index 22221f3..3cf3fd5 100644 --- a/lib/pages/sleep_page.dart +++ b/lib/pages/sleep_page.dart @@ -1,17 +1,15 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/providers/input_provider.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/widgets/sleep_form.dart'; +import 'package:smoke_cess_app/widgets/sleep_view.dart'; +import 'package:smoke_cess_app/widgets/view_form_page.dart'; class SleepPage extends StatelessWidget { const SleepPage({super.key}); @override Widget build(BuildContext context) { - return Center( - child: ChangeNotifierProvider( - create: (context) => InputProvider(), - child: const SleepForm(), - )); + return const ViewFormPage( + form: SleepForm(), view: SleepView(), page: Pages.sleep); } } diff --git a/lib/widgets/view_form_page.dart b/lib/widgets/view_form_page.dart new file mode 100644 index 0000000..843f66e --- /dev/null +++ b/lib/widgets/view_form_page.dart @@ -0,0 +1,51 @@ +import 'package:awesome_dialog/awesome_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; + +import '../providers/input_provider.dart'; +import '../providers/page_provider.dart'; +import '../providers/tasks_provider.dart'; + +class ViewFormPage extends StatelessWidget { + final Widget form; + final Widget view; + final Pages page; + const ViewFormPage( + {super.key, required this.form, required this.view, required this.page}); + + void showPopUp(BuildContext context) { + AwesomeDialog( + context: context, + dialogType: DialogType.info, + title: 'Schon gemacht!', + desc: 'Der Eintrag wurde erfolgreich gespeichert', + ).show(); + } + + @override + Widget build(BuildContext context) { + PageProvider pageProvider = context.watch(); + TasksProvider tasksProvider = context.watch(); + return Wrap(children: [ + Align( + alignment: Alignment.topLeft, + child: IconButton( + icon: pageProvider.showForm + ? const Icon(Icons.arrow_back, color: Colors.black) + : const Icon(Icons.add_outlined, color: Colors.black), + onPressed: tasksProvider.tasks[page] ?? true + ? pageProvider.swap + : () => showPopUp(context), + ), + ), + pageProvider.showForm + ? Center( + child: ChangeNotifierProvider( + create: (context) => InputProvider(), + child: form, + )) + : Center(child: view) + ]); + } +} From c9ea73b9b2a2606b83b1db2ea68a53d427098ba1 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 12:50:50 +0100 Subject: [PATCH 30/54] Added Views for Models --- lib/providers/tasks_provider.dart | 15 +++++++++++++ lib/widgets/mood_view.dart | 32 ++++++++++++++++++++++++++ lib/widgets/relapse_view.dart | 20 +++++++++++++++++ lib/widgets/sleep_view.dart | 32 ++++++++++++++++++++++++++ lib/widgets/workout_view.dart | 37 +++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 lib/widgets/mood_view.dart create mode 100644 lib/widgets/relapse_view.dart create mode 100644 lib/widgets/sleep_view.dart create mode 100644 lib/widgets/workout_view.dart diff --git a/lib/providers/tasks_provider.dart b/lib/providers/tasks_provider.dart index f7cd673..590c4fc 100644 --- a/lib/providers/tasks_provider.dart +++ b/lib/providers/tasks_provider.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/models/relapse.dart'; import 'package:smoke_cess_app/models/sleep.dart'; import 'package:smoke_cess_app/models/workout.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; @@ -15,8 +16,14 @@ class TasksProvider extends ChangeNotifier { Pages.timer: true, }; + List moodHistory = []; + List sleepHistory = []; + List workoutHistory = []; + List relapseHistory = []; + TasksProvider(SettingsProvider? settingsProvider) { initTasks(); + initHistories(); } void setTaskDone(Pages taskName) { @@ -24,6 +31,14 @@ class TasksProvider extends ChangeNotifier { notifyListeners(); } + void initHistories() async { + moodHistory = await globals.databaseService.getMoodRecords(); + sleepHistory = await globals.databaseService.getSleepRecords(); + workoutHistory = await globals.databaseService.getWorkoutRecords(); + relapseHistory = await globals.databaseService.getRelapseRecords(); + notifyListeners(); + } + void initTasks() async { TZDateTime? moodToday = await getTodayMood(); if (moodToday != null) { diff --git a/lib/widgets/mood_view.dart b/lib/widgets/mood_view.dart new file mode 100644 index 0000000..14884b9 --- /dev/null +++ b/lib/widgets/mood_view.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import '../models/mood.dart'; +import '../providers/tasks_provider.dart'; + +class MoodView extends StatelessWidget { + const MoodView({super.key}); + + @override + Widget build(BuildContext context) { + var tasksModel = context.watch(); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SfCartesianChart( + primaryXAxis: DateTimeAxis(), + series: [ + LineSeries( + dataSource: tasksModel.moodHistory, + xValueMapper: (Mood value, _) => value.date, + yValueMapper: (Mood value, _) => value.moodValue) + ], + ), + Column( + children: tasksModel.moodHistory.map((mood) { + return Text('${mood.date}: ${mood.moodValue}'); + }).toList()) + ], + ); + } +} diff --git a/lib/widgets/relapse_view.dart b/lib/widgets/relapse_view.dart new file mode 100644 index 0000000..dfa7355 --- /dev/null +++ b/lib/widgets/relapse_view.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/models/relapse.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import '../models/mood.dart'; +import '../providers/tasks_provider.dart'; + +class RelapseView extends StatelessWidget { + const RelapseView({super.key}); + + @override + Widget build(BuildContext context) { + var tasksModel = context.watch(); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: tasksModel.relapseHistory.map((relapse) { + return Text('${relapse.date}: ${relapse.category}'); + }).toList()); + } +} diff --git a/lib/widgets/sleep_view.dart b/lib/widgets/sleep_view.dart new file mode 100644 index 0000000..90a005c --- /dev/null +++ b/lib/widgets/sleep_view.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/models/sleep.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import '../providers/tasks_provider.dart'; + +class SleepView extends StatelessWidget { + const SleepView({super.key}); + + @override + Widget build(BuildContext context) { + var tasksModel = context.watch(); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SfCartesianChart( + primaryXAxis: DateTimeAxis(), + series: [ + LineSeries( + dataSource: tasksModel.sleepHistory, + xValueMapper: (Sleep value, _) => value.date, + yValueMapper: (Sleep value, _) => value.sleepQualitiyValue) + ], + ), + Column( + children: tasksModel.sleepHistory.map((sleep) { + return Text('${sleep.date}: ${sleep.sleepQualitiyValue}'); + }).toList()) + ], + ); + } +} diff --git a/lib/widgets/workout_view.dart b/lib/widgets/workout_view.dart new file mode 100644 index 0000000..7f4f843 --- /dev/null +++ b/lib/widgets/workout_view.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/models/sleep.dart'; +import 'package:smoke_cess_app/models/workout.dart'; +import 'package:syncfusion_flutter_charts/charts.dart'; +import '../providers/tasks_provider.dart'; + +class WorkoutView extends StatelessWidget { + const WorkoutView({super.key}); + + @override + Widget build(BuildContext context) { + var tasksModel = context.watch(); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SfCartesianChart( + primaryXAxis: DateTimeAxis(), + series: [ + LineSeries( + dataSource: tasksModel.workoutHistory, + xValueMapper: (Workout value, _) => value.date, + yValueMapper: (Workout value, _) => value.motivationBefore), + LineSeries( + dataSource: tasksModel.workoutHistory, + xValueMapper: (Workout value, _) => value.date, + yValueMapper: (Workout value, _) => value.motivationAfter) + ], + ), + Column( + children: tasksModel.sleepHistory.map((sleep) { + return Text('${sleep.date}: ${sleep.sleepQualitiyValue}'); + }).toList()) + ], + ); + } +} From 36ef18a4f7fe8871b69d02f33b70f2a72a34ac70 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 12:51:14 +0100 Subject: [PATCH 31/54] Added charts --- pubspec.lock | 21 +++++++++++++++++++++ pubspec.yaml | 1 + 2 files changed, 22 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index 98b299a..c3f17f4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -205,6 +205,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.2" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.18.0" js: dependency: transitive description: @@ -441,6 +448,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + syncfusion_flutter_charts: + dependency: "direct main" + description: + name: syncfusion_flutter_charts + url: "https://pub.dartlang.org" + source: hosted + version: "20.4.52" + syncfusion_flutter_core: + dependency: transitive + description: + name: syncfusion_flutter_core + url: "https://pub.dartlang.org" + source: hosted + version: "20.4.52" synchronized: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 473cf66..b3efde8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,6 +42,7 @@ dependencies: mobile_scanner: ^3.0.0 flutter_local_notifications: ^13.0.0 http: ^0.13.5 + syncfusion_flutter_charts: ^20.4.52 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. From 606e8c3f192ae7acf60631647e5635788f463871 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 12:51:25 +0100 Subject: [PATCH 32/54] Fixed DropDown Bug --- lib/providers/input_provider.dart | 10 ++-------- lib/widgets/drop_down.dart | 1 + 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart index a61514f..3bd473f 100644 --- a/lib/providers/input_provider.dart +++ b/lib/providers/input_provider.dart @@ -11,22 +11,16 @@ class InputProvider extends ChangeNotifier { 'wokeUpAt': const TimeOfDay(hour: 8, minute: 0), 'sleptAt': const TimeOfDay(hour: 22, minute: 0), }; - String _relapseCategory = ''; + String relapseCategory = ''; double get sliderValue => _sliderValue; TextEditingController get textController => _textController; - String get relapseCategory => _relapseCategory; set sliderValue(double newValue) { _sliderValue = newValue; notifyListeners(); } - set relapseCategory(String newValue) { - _relapseCategory = newValue; - notifyListeners(); - } - TimeOfDay getTimeEntry(String key) { return _times[key] ?? const TimeOfDay(hour: 12, minute: 0); } @@ -53,7 +47,7 @@ class InputProvider extends ChangeNotifier { Future saveRelapse() { Relapse relapse = - Relapse(_relapseCategory, _textController.text, DateTime.now()); + Relapse(relapseCategory, _textController.text, DateTime.now()); _resetFields(); return globals.databaseService.addRelapse(relapse); } diff --git a/lib/widgets/drop_down.dart b/lib/widgets/drop_down.dart index 5f06d89..ee704cf 100644 --- a/lib/widgets/drop_down.dart +++ b/lib/widgets/drop_down.dart @@ -9,6 +9,7 @@ class DropDown extends StatelessWidget { @override Widget build(BuildContext context) { var inputModel = context.watch(); + inputModel.relapseCategory = _items.isNotEmpty ? _items[0] : ''; return DropdownButtonFormField( value: _items.isEmpty ? null : _items[0], icon: const Icon(Icons.arrow_downward), From f62cdd254329ff02f886e1ae9065a9bbb86f5f2d Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 12:51:48 +0100 Subject: [PATCH 33/54] On successful submit go back to view page --- lib/widgets/submit_form_button.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/widgets/submit_form_button.dart b/lib/widgets/submit_form_button.dart index b5bb593..4c98c34 100644 --- a/lib/widgets/submit_form_button.dart +++ b/lib/widgets/submit_form_button.dart @@ -1,5 +1,7 @@ import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/page_provider.dart'; class SubmitFormButton extends StatelessWidget { final Future Function() submitCallback; @@ -9,21 +11,23 @@ class SubmitFormButton extends StatelessWidget { @override Widget build(BuildContext context) { + PageProvider pageProvider = context.watch(); return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () async { int success = await submitCallback(); if (success != 0) { - AwesomeDialog( + await AwesomeDialog( context: context, dialogType: DialogType.success, title: 'Gespeichert', desc: 'Der Eintrag wurde erfolgreich gespeichert', ).show(); updateTasks(); + pageProvider.swap(); } else { - AwesomeDialog( + await AwesomeDialog( context: context, dialogType: DialogType.error, title: 'Fehler', From ccf34c07e83bde996f5fb8c5defd02e603f9c03a Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 13:13:33 +0100 Subject: [PATCH 34/54] Fixed Bug when swapping pages --- lib/main.dart | 4 ++++ lib/pages/main_page.dart | 24 +++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index c5a19b7..d94ea15 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:timezone/data/latest.dart' as tz; import 'globals.dart' as globals; +import 'providers/page_provider.dart'; import 'providers/settings_provider.dart'; void main() { @@ -34,6 +35,9 @@ class MyApp extends StatelessWidget { update: (context, value, TasksProvider? previous) => TasksProvider(value), ), + ChangeNotifierProvider( + create: (context) => PageProvider(), + ) ], child: const MyHomePage(), )); diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 338dd75..1caf126 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -20,15 +20,19 @@ class MyHomePageState extends State { bool _isConfigured = false; void _onItemTapped(int index) { + PageProvider pageProvider = context.watch(); setState(() { - _isConfigured - ? _selectedIndex = index - : AwesomeDialog( - context: context, - dialogType: DialogType.info, - title: 'Fehlende Konfiguration', - desc: 'Bitte QR Code Scannen!', - ).show(); + if (_isConfigured) { + pageProvider.showForm = false; + _selectedIndex = index; + return; + } + AwesomeDialog( + context: context, + dialogType: DialogType.info, + title: 'Fehlende Konfiguration', + desc: 'Bitte QR Code Scannen!', + ).show(); }); } @@ -42,10 +46,8 @@ class MyHomePageState extends State { title: Text( '${pages.values.elementAt(_selectedIndex)['title']} ${_isConfigured ? "Gruppe ${settingsModel.settings?.group}" : ""}')), body: SingleChildScrollView( - child: ChangeNotifierProvider( - create: (context) => PageProvider(), child: pages.values.elementAt(_selectedIndex)['page'], - )), + ), bottomNavigationBar: NavigationBar( onDestinationSelected: _onItemTapped, selectedIndex: _selectedIndex, From 4b1eb20ca1fb900c7ad49eddbd60d7b341e611a4 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 13:44:17 +0100 Subject: [PATCH 35/54] extracted workoutform --- lib/pages/interval_page.dart | 25 +++++++------------------ lib/pages/main_page.dart | 2 +- lib/widgets/workout_form.dart | 33 +++++++++++++++++++++++++++++++++ lib/widgets/workout_view.dart | 4 ---- 4 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 lib/widgets/workout_form.dart diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index 1c0d64f..f029f88 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -2,31 +2,20 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/widgets/mute_button.dart'; +import 'package:smoke_cess_app/widgets/workout_form.dart'; import 'package:smoke_cess_app/widgets/workout_timer_widget.dart'; +import 'package:smoke_cess_app/widgets/workout_view.dart'; + +import '../widgets/view_form_page.dart'; class IntervalTimerPage extends StatelessWidget { const IntervalTimerPage({super.key}); @override Widget build(BuildContext context) { - TimerProvider timerProvider = TimerProvider(); - return MultiProvider( - providers: [ - ChangeNotifierProvider(create: (context) => timerProvider), - ChangeNotifierProvider( - create: (context) => WorkoutProvider(timerProvider)), - ], - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - Align( - alignment: Alignment.topLeft, - child: MuteButton(), - ), - WorkoutTimerWidget() - ], - ), - ); + return const ViewFormPage( + form: WorkoutForm(), view: WorkoutView(), page: Pages.timer); } } diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 1caf126..10ff0ec 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -20,7 +20,7 @@ class MyHomePageState extends State { bool _isConfigured = false; void _onItemTapped(int index) { - PageProvider pageProvider = context.watch(); + PageProvider pageProvider = context.read(); setState(() { if (_isConfigured) { pageProvider.showForm = false; diff --git a/lib/widgets/workout_form.dart b/lib/widgets/workout_form.dart new file mode 100644 index 0000000..980c51a --- /dev/null +++ b/lib/widgets/workout_form.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import '../providers/timer_provider.dart'; +import '../providers/workout_provider.dart'; +import 'mute_button.dart'; +import 'workout_timer_widget.dart'; + +class WorkoutForm extends StatelessWidget { + const WorkoutForm({super.key}); + + @override + Widget build(BuildContext context) { + TimerProvider timerProvider = TimerProvider(); + return MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => timerProvider), + ChangeNotifierProvider( + create: (context) => WorkoutProvider(timerProvider)), + ], + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Align( + alignment: Alignment.topLeft, + child: MuteButton(), + ), + WorkoutTimerWidget() + ], + ), + ); + } +} diff --git a/lib/widgets/workout_view.dart b/lib/widgets/workout_view.dart index 7f4f843..fcf88c7 100644 --- a/lib/widgets/workout_view.dart +++ b/lib/widgets/workout_view.dart @@ -27,10 +27,6 @@ class WorkoutView extends StatelessWidget { yValueMapper: (Workout value, _) => value.motivationAfter) ], ), - Column( - children: tasksModel.sleepHistory.map((sleep) { - return Text('${sleep.date}: ${sleep.sleepQualitiyValue}'); - }).toList()) ], ); } From 7dd1a748f21994ad10bf19ac6802eb5d606b45f4 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 15:00:48 +0100 Subject: [PATCH 36/54] Moved Provider to the top level --- lib/main.dart | 8 +++++++- lib/widgets/workout_form.dart | 28 ++++++++-------------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index d94ea15..4e6924d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/pages/main_page.dart'; import 'package:smoke_cess_app/providers/tasks_provider.dart'; +import 'package:smoke_cess_app/providers/timer_provider.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:timezone/data/latest.dart' as tz; import 'globals.dart' as globals; import 'providers/page_provider.dart'; import 'providers/settings_provider.dart'; +import 'providers/workout_provider.dart'; void main() { // to ensure all the widgets are initialized. @@ -25,6 +27,7 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { + TimerProvider timerProvider = TimerProvider(); return MaterialApp( title: _title, home: MultiProvider( @@ -37,7 +40,10 @@ class MyApp extends StatelessWidget { ), ChangeNotifierProvider( create: (context) => PageProvider(), - ) + ), + ChangeNotifierProvider(create: (context) => timerProvider), + ChangeNotifierProvider( + create: (context) => WorkoutProvider(timerProvider)), ], child: const MyHomePage(), )); diff --git a/lib/widgets/workout_form.dart b/lib/widgets/workout_form.dart index 980c51a..e06c4c2 100644 --- a/lib/widgets/workout_form.dart +++ b/lib/widgets/workout_form.dart @@ -1,8 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -import '../providers/timer_provider.dart'; -import '../providers/workout_provider.dart'; import 'mute_button.dart'; import 'workout_timer_widget.dart'; @@ -11,23 +7,15 @@ class WorkoutForm extends StatelessWidget { @override Widget build(BuildContext context) { - TimerProvider timerProvider = TimerProvider(); - return MultiProvider( - providers: [ - ChangeNotifierProvider(create: (context) => timerProvider), - ChangeNotifierProvider( - create: (context) => WorkoutProvider(timerProvider)), + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Align( + alignment: Alignment.topLeft, + child: MuteButton(), + ), + WorkoutTimerWidget() ], - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - Align( - alignment: Alignment.topLeft, - child: MuteButton(), - ), - WorkoutTimerWidget() - ], - ), ); } } From 3b25e12d0862fa8bccd3aba5505c3584991a9a7f Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 15:02:27 +0100 Subject: [PATCH 37/54] Fixed Bug: workout is interruptable now --- lib/pages/main_page.dart | 3 +++ lib/providers/timer_provider.dart | 1 + lib/providers/workout_provider.dart | 8 +++++++ lib/widgets/workout_timer_widget.dart | 34 +++++++++++++++++---------- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 10ff0ec..21049d2 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/page_provider.dart'; import 'package:smoke_cess_app/providers/tasks_provider.dart'; +import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; @@ -21,9 +22,11 @@ class MyHomePageState extends State { void _onItemTapped(int index) { PageProvider pageProvider = context.read(); + WorkoutProvider workoutProvider = context.read(); setState(() { if (_isConfigured) { pageProvider.showForm = false; + workoutProvider.interruptWorkout(); _selectedIndex = index; return; } diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart index ee34b19..acf1a94 100644 --- a/lib/providers/timer_provider.dart +++ b/lib/providers/timer_provider.dart @@ -21,5 +21,6 @@ class TimerProvider extends ChangeNotifier { void stopTimer() { started = false; _timer?.cancel(); + _timer = null; } } diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 5c0a80b..98c3163 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -92,6 +92,14 @@ class WorkoutProvider extends ChangeNotifier { notifyListeners(); } + void interruptWorkout() { + isWorkoutStarted = false; + isWorkoutComplete = false; + _audioPlayer.stop(); + timerProvider.stopTimer(); + notifyListeners(); + } + void saveWorkout() { Workout workout = Workout(motivationBefore, motivationAfter, DateTime.now()); diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index a85a09e..7b2cdb6 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -1,7 +1,10 @@ import 'dart:async'; +import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; +import 'package:http/http.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/page_provider.dart'; import 'package:smoke_cess_app/providers/tasks_provider.dart'; import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; @@ -18,19 +21,29 @@ class WorkoutTimerWidget extends StatelessWidget { TimerProvider timerProvider = context.watch(); WorkoutProvider workoutProvider = context.watch(); TasksProvider tasksProvider = context.read(); + PageProvider pageProvider = context.read(); + + void handleStopWorkout() async { + await showMotivationPopup(context, (double value) { + workoutProvider.motivationAfter = value.toInt(); + workoutProvider.saveWorkout(); + tasksProvider.setTaskDone(Pages.timer); + }, 'Motivation nach dem Training'); + await AwesomeDialog( + context: context, + dialogType: DialogType.success, + title: 'Gespeichert', + desc: 'Der Eintrag wurde erfolgreich gespeichert', + ).show(); + pageProvider.swap(); + } if (workoutProvider.isPhaseComplete && !workoutProvider.isWorkoutComplete) { Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase()); } if (workoutProvider.isWorkoutComplete) { - Timer( - const Duration(milliseconds: 1), - () => showMotivationPopup(context, (double value) { - workoutProvider.motivationAfter = value.toInt(); - workoutProvider.saveWorkout(); - tasksProvider.setTaskDone(Pages.timer); - }, 'Motivation nach dem Training')); + Timer(const Duration(milliseconds: 1), handleStopWorkout); } void handleStartStopWorkout() { @@ -40,11 +53,8 @@ class WorkoutTimerWidget extends StatelessWidget { workoutProvider.startWorkout(); }, 'Motivation vor dem Training'); } else { - workoutProvider.stopWorkout(); - showMotivationPopup( - context, - (double value) => workoutProvider.motivationAfter = value.toInt(), - 'Motivation nach dem Training'); + workoutProvider.interruptWorkout(); + handleStopWorkout(); } } From 0596194ad02e361168a393ee3c961160b2e7d0b0 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 15:04:02 +0100 Subject: [PATCH 38/54] removed unused import --- lib/pages/interval_page.dart | 5 ----- lib/pages/relapse_page.dart | 1 - lib/widgets/relapse_view.dart | 3 --- lib/widgets/workout_timer_widget.dart | 1 - lib/widgets/workout_view.dart | 1 - 5 files changed, 11 deletions(-) diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index f029f88..5117a8d 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -1,11 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/providers/timer_provider.dart'; -import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; -import 'package:smoke_cess_app/widgets/mute_button.dart'; import 'package:smoke_cess_app/widgets/workout_form.dart'; -import 'package:smoke_cess_app/widgets/workout_timer_widget.dart'; import 'package:smoke_cess_app/widgets/workout_view.dart'; import '../widgets/view_form_page.dart'; diff --git a/lib/pages/relapse_page.dart b/lib/pages/relapse_page.dart index b0edf96..e7b6127 100644 --- a/lib/pages/relapse_page.dart +++ b/lib/pages/relapse_page.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/widgets/relapse_form.dart'; import 'package:smoke_cess_app/widgets/relapse_view.dart'; diff --git a/lib/widgets/relapse_view.dart b/lib/widgets/relapse_view.dart index dfa7355..48c9829 100644 --- a/lib/widgets/relapse_view.dart +++ b/lib/widgets/relapse_view.dart @@ -1,8 +1,5 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/models/relapse.dart'; -import 'package:syncfusion_flutter_charts/charts.dart'; -import '../models/mood.dart'; import '../providers/tasks_provider.dart'; class RelapseView extends StatelessWidget { diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 7b2cdb6..10f3033 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; -import 'package:http/http.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/page_provider.dart'; import 'package:smoke_cess_app/providers/tasks_provider.dart'; diff --git a/lib/widgets/workout_view.dart b/lib/widgets/workout_view.dart index fcf88c7..d0deb4d 100644 --- a/lib/widgets/workout_view.dart +++ b/lib/widgets/workout_view.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/models/sleep.dart'; import 'package:smoke_cess_app/models/workout.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; import '../providers/tasks_provider.dart'; From 37a63b00592247b276adeb5f8f53a56698613990 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 16:37:08 +0100 Subject: [PATCH 39/54] Moved Provider to the highest --- lib/main.dart | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 4e6924d..e2d6e90 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -28,24 +28,24 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { TimerProvider timerProvider = TimerProvider(); - return MaterialApp( - title: _title, - home: MultiProvider( - providers: [ - ChangeNotifierProvider(create: (context) => SettingsProvider()), - ChangeNotifierProxyProvider( - create: (context) => TasksProvider(null), - update: (context, value, TasksProvider? previous) => - TasksProvider(value), - ), - ChangeNotifierProvider( - create: (context) => PageProvider(), - ), - ChangeNotifierProvider(create: (context) => timerProvider), - ChangeNotifierProvider( - create: (context) => WorkoutProvider(timerProvider)), - ], - child: const MyHomePage(), + return MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => SettingsProvider()), + ChangeNotifierProxyProvider( + create: (context) => TasksProvider(null), + update: (context, value, TasksProvider? previous) => + TasksProvider(value), + ), + ChangeNotifierProvider( + create: (context) => PageProvider(), + ), + ChangeNotifierProvider(create: (context) => timerProvider), + ChangeNotifierProvider( + create: (context) => WorkoutProvider(timerProvider)), + ], + child: const MaterialApp( + title: _title, + home: MyHomePage(), )); } } From 9d26bdee6015027c098cb4c44e0d8776b4997eae Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 16:38:08 +0100 Subject: [PATCH 40/54] Added Timer to popup if task isnt due --- lib/providers/tasks_provider.dart | 7 ++++-- lib/services/date_service.dart | 41 +++++++++++++++++++++++++++++++ lib/utils/timer_util.dart | 12 ++++++++- lib/widgets/view_form_page.dart | 15 +++++++---- 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/lib/providers/tasks_provider.dart b/lib/providers/tasks_provider.dart index 590c4fc..d3fc042 100644 --- a/lib/providers/tasks_provider.dart +++ b/lib/providers/tasks_provider.dart @@ -40,12 +40,14 @@ class TasksProvider extends ChangeNotifier { } void initTasks() async { + DateTime now = DateTime.now(); TZDateTime? moodToday = await getTodayMood(); if (moodToday != null) { List moodList = await globals.databaseService.getMoodRecords(); if (moodList.isNotEmpty) { Mood mood = moodList.last; - tasks[Pages.mood] = !isSameDay(moodToday, mood.date); + tasks[Pages.mood] = + !isSameDay(moodToday, mood.date) && moodToday.isBefore(now); } } else { tasks[Pages.mood] = false; @@ -55,7 +57,8 @@ class TasksProvider extends ChangeNotifier { List sleepList = await globals.databaseService.getSleepRecords(); if (sleepList.isNotEmpty) { Sleep sleep = sleepList.last; - tasks[Pages.sleep] = !isSameDay(sleepToday, sleep.date); + tasks[Pages.sleep] = + !isSameDay(sleepToday, sleep.date) && sleepToday.isBefore(now); } } else { tasks[Pages.sleep] = false; diff --git a/lib/services/date_service.dart b/lib/services/date_service.dart index b5e254f..79bdd37 100644 --- a/lib/services/date_service.dart +++ b/lib/services/date_service.dart @@ -1,6 +1,8 @@ import 'package:smoke_cess_app/services/settings_service.dart'; import 'package:timezone/timezone.dart'; +import 'pages_service.dart'; + const int trainingTime = 40; const weekDays = { @@ -47,6 +49,45 @@ Future getTodaySleep() async { return today.isNotEmpty ? today.first : null; } +Future getTimeTillNextMood() async { + List moodDates = await getDatesforMood(); + Iterable nextDate = + moodDates.where((element) => element.isAfter(DateTime.now())); + Duration duration = nextDate.isNotEmpty + ? nextDate.first.difference(DateTime.now()) + : const Duration(seconds: 0); + return duration; +} + +Future getTimeTillNextSleep() async { + List sleepDates = await getDatesforSleep(); + Iterable nextDate = + sleepDates.where((element) => element.isAfter(DateTime.now())); + Duration duration = nextDate.isNotEmpty + ? nextDate.first.difference(DateTime.now()) + : const Duration(seconds: 0); + return duration; +} + +Future getTimeTillNextWorkout() async { + DateTime now = DateTime.now(); + DateTime tomorrow = + DateTime(now.year, now.month, now.day).add(const Duration(days: 1)); + Duration duration = tomorrow.difference(now); + return duration; +} + +Future getTimeTill(Pages page) { + switch (page) { + case Pages.mood: + return getTimeTillNextMood(); + case Pages.sleep: + return getTimeTillNextSleep(); + default: + return getTimeTillNextWorkout(); + } +} + List createTZDateTimes( List? selectedDays, int? selectedHours, int? selectedMinutes) { final List tzDateTimes = []; diff --git a/lib/utils/timer_util.dart b/lib/utils/timer_util.dart index 58d9690..a63030f 100644 --- a/lib/utils/timer_util.dart +++ b/lib/utils/timer_util.dart @@ -1,4 +1,14 @@ String formatTime(int seconds) { Duration duration = Duration(seconds: seconds); - return '${duration.inMinutes.remainder(60).toString().padLeft(2, '0')}:${duration.inSeconds.remainder(60).toString().padLeft(2, '0')}'; + String formattedTime = ''; + String twoDigits(int n) => n.toString().padLeft(2, "0"); + String days = duration.inDays.toString(); + String hours = twoDigits(duration.inHours.remainder(24)); + String minutes = twoDigits(duration.inMinutes.remainder(60)); + String formattedSeconds = twoDigits(duration.inSeconds.remainder(60)); + if (duration.inDays != 0) formattedTime += '$days:'; + if (duration.inHours != 0) formattedTime += '$hours:'; + formattedTime += '$minutes:'; + formattedTime += formattedSeconds; + return formattedTime; } diff --git a/lib/widgets/view_form_page.dart b/lib/widgets/view_form_page.dart index 843f66e..a907cfb 100644 --- a/lib/widgets/view_form_page.dart +++ b/lib/widgets/view_form_page.dart @@ -2,10 +2,12 @@ import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; - import '../providers/input_provider.dart'; import '../providers/page_provider.dart'; import '../providers/tasks_provider.dart'; +import '../providers/timer_provider.dart'; +import '../services/date_service.dart'; +import 'timer_widget.dart'; class ViewFormPage extends StatelessWidget { final Widget form; @@ -14,12 +16,15 @@ class ViewFormPage extends StatelessWidget { const ViewFormPage( {super.key, required this.form, required this.view, required this.page}); - void showPopUp(BuildContext context) { + void showPopup(BuildContext context) async { + TimerProvider timerProvider = context.read(); + Duration duration = await getTimeTill(page); + timerProvider.startTimer(duration); AwesomeDialog( context: context, dialogType: DialogType.info, - title: 'Schon gemacht!', - desc: 'Der Eintrag wurde erfolgreich gespeichert', + title: 'Bald erst wieder', + body: TimerWidget(duration: duration), ).show(); } @@ -36,7 +41,7 @@ class ViewFormPage extends StatelessWidget { : const Icon(Icons.add_outlined, color: Colors.black), onPressed: tasksProvider.tasks[page] ?? true ? pageProvider.swap - : () => showPopUp(context), + : () => showPopup(context), ), ), pageProvider.showForm From e22d918a92a8d3556030399e10a1767c22353e3a Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 17:19:58 +0100 Subject: [PATCH 41/54] use dispose function of workout_provider to cleanup instead of high level provider --- lib/main.dart | 6 ------ lib/pages/main_page.dart | 3 --- lib/providers/workout_provider.dart | 6 ++++++ lib/widgets/view_form_page.dart | 8 +------- lib/widgets/workout_form.dart | 30 +++++++++++++++++++---------- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index e2d6e90..4a49cd4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,13 +2,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/pages/main_page.dart'; import 'package:smoke_cess_app/providers/tasks_provider.dart'; -import 'package:smoke_cess_app/providers/timer_provider.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:timezone/data/latest.dart' as tz; import 'globals.dart' as globals; import 'providers/page_provider.dart'; import 'providers/settings_provider.dart'; -import 'providers/workout_provider.dart'; void main() { // to ensure all the widgets are initialized. @@ -27,7 +25,6 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - TimerProvider timerProvider = TimerProvider(); return MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => SettingsProvider()), @@ -39,9 +36,6 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider( create: (context) => PageProvider(), ), - ChangeNotifierProvider(create: (context) => timerProvider), - ChangeNotifierProvider( - create: (context) => WorkoutProvider(timerProvider)), ], child: const MaterialApp( title: _title, diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 21049d2..10ff0ec 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/providers/page_provider.dart'; import 'package:smoke_cess_app/providers/tasks_provider.dart'; -import 'package:smoke_cess_app/providers/workout_provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; @@ -22,11 +21,9 @@ class MyHomePageState extends State { void _onItemTapped(int index) { PageProvider pageProvider = context.read(); - WorkoutProvider workoutProvider = context.read(); setState(() { if (_isConfigured) { pageProvider.showForm = false; - workoutProvider.interruptWorkout(); _selectedIndex = index; return; } diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 98c3163..0cf3804 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -105,6 +105,12 @@ class WorkoutProvider extends ChangeNotifier { Workout(motivationBefore, motivationAfter, DateTime.now()); globals.databaseService.addWorkout(workout); } + + @override + void dispose() { + interruptWorkout(); + super.dispose(); + } } Map> _workoutPhaseSettings = { diff --git a/lib/widgets/view_form_page.dart b/lib/widgets/view_form_page.dart index a907cfb..aa52fd1 100644 --- a/lib/widgets/view_form_page.dart +++ b/lib/widgets/view_form_page.dart @@ -5,9 +5,6 @@ import 'package:smoke_cess_app/services/pages_service.dart'; import '../providers/input_provider.dart'; import '../providers/page_provider.dart'; import '../providers/tasks_provider.dart'; -import '../providers/timer_provider.dart'; -import '../services/date_service.dart'; -import 'timer_widget.dart'; class ViewFormPage extends StatelessWidget { final Widget form; @@ -17,14 +14,11 @@ class ViewFormPage extends StatelessWidget { {super.key, required this.form, required this.view, required this.page}); void showPopup(BuildContext context) async { - TimerProvider timerProvider = context.read(); - Duration duration = await getTimeTill(page); - timerProvider.startTimer(duration); AwesomeDialog( context: context, dialogType: DialogType.info, title: 'Bald erst wieder', - body: TimerWidget(duration: duration), + desc: 'hier kommt ein timer hin', ).show(); } diff --git a/lib/widgets/workout_form.dart b/lib/widgets/workout_form.dart index e06c4c2..a176cd0 100644 --- a/lib/widgets/workout_form.dart +++ b/lib/widgets/workout_form.dart @@ -1,4 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import '../providers/timer_provider.dart'; +import '../providers/workout_provider.dart'; import 'mute_button.dart'; import 'workout_timer_widget.dart'; @@ -7,15 +10,22 @@ class WorkoutForm extends StatelessWidget { @override Widget build(BuildContext context) { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - Align( - alignment: Alignment.topLeft, - child: MuteButton(), - ), - WorkoutTimerWidget() - ], - ); + TimerProvider timerProvider = TimerProvider(); + return MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => timerProvider), + ChangeNotifierProvider( + create: (context) => WorkoutProvider(timerProvider)), + ], + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + Align( + alignment: Alignment.topLeft, + child: MuteButton(), + ), + WorkoutTimerWidget() + ], + )); } } From 3ae9699137757b72c3a6a5356cd0b68dfcf4fc17 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 17:21:27 +0100 Subject: [PATCH 42/54] Add dispose to timerprovider --- lib/providers/timer_provider.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart index acf1a94..54a2679 100644 --- a/lib/providers/timer_provider.dart +++ b/lib/providers/timer_provider.dart @@ -23,4 +23,10 @@ class TimerProvider extends ChangeNotifier { _timer?.cancel(); _timer = null; } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } } From 4279e7961c0ef219c454c08a8e1ac75d81fb9df6 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 18:26:44 +0100 Subject: [PATCH 43/54] Add Timer to Popup --- lib/providers/timer_provider.dart | 4 +++ lib/widgets/popup_for_task_done.dart | 41 ++++++++++++++++++++++++++++ lib/widgets/view_form_page.dart | 13 ++------- 3 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 lib/widgets/popup_for_task_done.dart diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart index 54a2679..f5a75c1 100644 --- a/lib/providers/timer_provider.dart +++ b/lib/providers/timer_provider.dart @@ -8,6 +8,7 @@ class TimerProvider extends ChangeNotifier { int get elapsedSeconds => _timer != null ? _timer!.tick : 0; void startTimer(Duration duration) { + print('started'); started = true; _timer = Timer.periodic(const Duration(seconds: 1), ((timer) { if (timer.tick >= duration.inSeconds) { @@ -26,7 +27,10 @@ class TimerProvider extends ChangeNotifier { @override void dispose() { + print('disposed'); + started = false; _timer?.cancel(); + _timer = null; super.dispose(); } } diff --git a/lib/widgets/popup_for_task_done.dart b/lib/widgets/popup_for_task_done.dart new file mode 100644 index 0000000..fe63907 --- /dev/null +++ b/lib/widgets/popup_for_task_done.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/timer_provider.dart'; +import 'package:smoke_cess_app/widgets/timer_widget.dart'; +import '../services/date_service.dart'; +import '../services/pages_service.dart'; + +void showTaskDonePopup(BuildContext context, Pages page) async { + Duration duration = await getTimeTill(page); + await showDialog( + context: context, + builder: (BuildContext context) { + return ChangeNotifierProvider( + create: (context) => TimerProvider(), + child: TaskDonePopup( + duration: duration, + ), + ); + }, + ); +} + +class TaskDonePopup extends StatelessWidget { + final Duration duration; + const TaskDonePopup({super.key, required this.duration}); + + @override + Widget build(BuildContext context) { + TimerProvider timerProvider = context.read(); + timerProvider.startTimer(duration); + return AlertDialog( + title: const Text('Schon gemacht'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('Nächstes mal wieder:'), + TimerWidget(duration: duration) + ])); + } +} diff --git a/lib/widgets/view_form_page.dart b/lib/widgets/view_form_page.dart index aa52fd1..57b9271 100644 --- a/lib/widgets/view_form_page.dart +++ b/lib/widgets/view_form_page.dart @@ -1,10 +1,10 @@ -import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/services/pages_service.dart'; import '../providers/input_provider.dart'; import '../providers/page_provider.dart'; import '../providers/tasks_provider.dart'; +import 'popup_for_task_done.dart'; class ViewFormPage extends StatelessWidget { final Widget form; @@ -13,15 +13,6 @@ class ViewFormPage extends StatelessWidget { const ViewFormPage( {super.key, required this.form, required this.view, required this.page}); - void showPopup(BuildContext context) async { - AwesomeDialog( - context: context, - dialogType: DialogType.info, - title: 'Bald erst wieder', - desc: 'hier kommt ein timer hin', - ).show(); - } - @override Widget build(BuildContext context) { PageProvider pageProvider = context.watch(); @@ -35,7 +26,7 @@ class ViewFormPage extends StatelessWidget { : const Icon(Icons.add_outlined, color: Colors.black), onPressed: tasksProvider.tasks[page] ?? true ? pageProvider.swap - : () => showPopup(context), + : () => showTaskDonePopup(context, page), ), ), pageProvider.showForm From f7bbac7adce7cc55b99cdd51f107dc6bf5f0b7d7 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 18:27:49 +0100 Subject: [PATCH 44/54] Remove Print calls --- lib/providers/timer_provider.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart index f5a75c1..f355d7d 100644 --- a/lib/providers/timer_provider.dart +++ b/lib/providers/timer_provider.dart @@ -8,7 +8,6 @@ class TimerProvider extends ChangeNotifier { int get elapsedSeconds => _timer != null ? _timer!.tick : 0; void startTimer(Duration duration) { - print('started'); started = true; _timer = Timer.periodic(const Duration(seconds: 1), ((timer) { if (timer.tick >= duration.inSeconds) { @@ -27,7 +26,6 @@ class TimerProvider extends ChangeNotifier { @override void dispose() { - print('disposed'); started = false; _timer?.cancel(); _timer = null; From c56222660d411c08ecc3e65e81cb8d8db6acc9a6 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Fri, 3 Mar 2023 18:34:24 +0100 Subject: [PATCH 45/54] Added try catch with errorhandling --- lib/widgets/scanner.dart | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index 46f8c8a..b635d67 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -37,12 +37,28 @@ class MyScannerState extends State { }); } + void handleError() { + setState(() { + scanning = false; + AwesomeDialog( + context: context, + dialogType: DialogType.error, + title: 'Fehler', + desc: 'Der QR-Code war fehlerhaft!', + ).show(); + }); + } + void onDetect(capture) { - final List barcodes = capture.barcodes; - for (final barcode in barcodes) { - if (barcode.rawValue != null) { - return handleSucces(barcode.rawValue); + try { + final List barcodes = capture.barcodes; + for (final barcode in barcodes) { + if (barcode.rawValue != null) { + return handleSucces(barcode.rawValue); + } } + } catch (e) { + handleError(); } } From 7cc60b180adf42934da60b33efd5cfa889b422e6 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 10:29:13 +0100 Subject: [PATCH 46/54] upgrade flutter version, adjust pipeline flutter version, simplify pubspec --- .gitlab-ci.yml | 2 +- pubspec.lock | 275 +++++++++++++++++++++++++++++++------------------ pubspec.yaml | 67 +----------- 3 files changed, 176 insertions(+), 168 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a81e822..4bb6e7e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: cirrusci/flutter:3.3.5 +image: cirrusci/flutter:3.7.5 stages: - analyze diff --git a/pubspec.lock b/pubspec.lock index c3f17f4..cc89bd1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,140 +5,160 @@ packages: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + url: "https://pub.dev" source: hosted version: "2.4.0" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" audioplayers: dependency: "direct main" description: name: audioplayers - url: "https://pub.dartlang.org" + sha256: "16451eab798b23ad9307aef6f9ca62bb8fb06542af8810eead0d236d3fd40a42" + url: "https://pub.dev" source: hosted version: "3.0.1" audioplayers_android: dependency: transitive description: name: audioplayers_android - url: "https://pub.dartlang.org" + sha256: b2c833e6f718b6b030454e329931229afafe9327fdb002874dd544dc8bf2484d + url: "https://pub.dev" source: hosted version: "2.0.0" audioplayers_darwin: dependency: transitive description: name: audioplayers_darwin - url: "https://pub.dartlang.org" + sha256: e7a3c8759bf11ecfe4b20df338bf9f3d37c7719a5761c46a3833aba0ceeaacff + url: "https://pub.dev" source: hosted version: "3.0.1" audioplayers_linux: dependency: transitive description: name: audioplayers_linux - url: "https://pub.dartlang.org" + sha256: e95b65e1f4d4764601dac5e65f8d8186fc29401043ab020f1dacec483d708707 + url: "https://pub.dev" source: hosted version: "1.0.4" audioplayers_platform_interface: dependency: transitive description: name: audioplayers_platform_interface - url: "https://pub.dartlang.org" + sha256: "178581a44cb685fd798d2108111d2e98cca3400e30b9c3a05546f124fb37f600" + url: "https://pub.dev" source: hosted version: "4.0.0" audioplayers_web: dependency: transitive description: name: audioplayers_web - url: "https://pub.dartlang.org" + sha256: "859ba09be2a57e57a787273f18c8cf0d9b61383870c5ee4b5632fe9adbc37edf" + url: "https://pub.dev" source: hosted version: "2.2.0" audioplayers_windows: dependency: transitive description: name: audioplayers_windows - url: "https://pub.dartlang.org" + sha256: "622e01c4c357c2aaf1b956c3a0f89d97c3cb40315c03f16e3b6c2a31ff9c38bc" + url: "https://pub.dev" source: hosted version: "1.1.3" awesome_dialog: dependency: "direct main" description: name: awesome_dialog - url: "https://pub.dartlang.org" + sha256: ac08268b991f228fc6b8880b68ec030d2941bcc8df8b6a6551fb79f2bd36b7da + url: "https://pub.dev" source: hosted version: "3.0.2" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" source: hosted version: "1.2.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" source: hosted version: "3.0.2" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" source: hosted version: "1.0.5" dbus: dependency: transitive description: name: dbus - url: "https://pub.dartlang.org" + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" source: hosted version: "0.7.8" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" ffi: dependency: transitive description: name: ffi - url: "https://pub.dartlang.org" + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" source: hosted version: "2.0.1" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" source: hosted version: "6.1.4" flutter: @@ -150,28 +170,32 @@ packages: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" source: hosted version: "2.0.1" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - url: "https://pub.dartlang.org" + sha256: "293995f94e120c8afce768981bd1fa9c5d6de67c547568e3b42ae2defdcbb4a0" + url: "https://pub.dev" source: hosted version: "13.0.0" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - url: "https://pub.dartlang.org" + sha256: ccb08b93703aeedb58856e5637450bf3ffec899adb66dc325630b68994734b89 + url: "https://pub.dev" source: hosted version: "3.0.0+1" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - url: "https://pub.dartlang.org" + sha256: "5ec1feac5f7f7d9266759488bc5f76416152baba9aa1b26fe572246caa00d1ab" + url: "https://pub.dev" source: hosted version: "6.0.0" flutter_test: @@ -188,219 +212,250 @@ packages: dependency: transitive description: name: graphs - url: "https://pub.dartlang.org" + sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 + url: "https://pub.dev" source: hosted version: "2.2.0" http: dependency: "direct main" description: name: http - url: "https://pub.dartlang.org" + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" source: hosted version: "0.13.5" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted version: "4.0.2" intl: dependency: transitive description: name: intl - url: "https://pub.dartlang.org" + sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + url: "https://pub.dev" source: hosted version: "0.18.0" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" source: hosted version: "2.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" source: hosted version: "1.8.0" mobile_scanner: dependency: "direct main" description: name: mobile_scanner - url: "https://pub.dartlang.org" + sha256: "4045e8441e21f1fb8998a76fbffd054510dd3a3b1dee55c7c9a2083eee687345" + url: "https://pub.dev" source: hosted version: "3.0.0" nested: dependency: transitive description: name: nested - url: "https://pub.dartlang.org" + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" source: hosted version: "1.0.0" path: dependency: "direct main" description: name: path - url: "https://pub.dartlang.org" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" source: hosted version: "1.8.2" path_provider: dependency: "direct main" description: name: path_provider - url: "https://pub.dartlang.org" + sha256: "04890b994ee89bfa80bf3080bfec40d5a92c5c7a785ebb02c13084a099d2b6f9" + url: "https://pub.dev" source: hosted - version: "2.0.12" + version: "2.0.13" path_provider_android: dependency: transitive description: name: path_provider_android - url: "https://pub.dartlang.org" + sha256: "7623b7d4be0f0f7d9a8b5ee6879fc13e4522d4c875ab86801dee4af32b54b83e" + url: "https://pub.dev" source: hosted - version: "2.0.22" + version: "2.0.23" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - url: "https://pub.dartlang.org" + sha256: eec003594f19fe2456ea965ae36b3fc967bc5005f508890aafe31fa75e41d972 + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_linux: dependency: transitive description: name: path_provider_linux - url: "https://pub.dartlang.org" + sha256: "525ad5e07622d19447ad740b1ed5070031f7a5437f44355ae915ff56e986429a" + url: "https://pub.dev" source: hosted - version: "2.1.8" + version: "2.1.9" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - url: "https://pub.dartlang.org" + sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.0.6" path_provider_windows: dependency: transitive description: name: path_provider_windows - url: "https://pub.dartlang.org" + sha256: "642ddf65fde5404f83267e8459ddb4556316d3ee6d511ed193357e25caa3632d" + url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" petitparser: dependency: transitive description: name: petitparser - url: "https://pub.dartlang.org" + sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + url: "https://pub.dev" source: hosted version: "5.1.0" platform: dependency: transitive description: name: platform - url: "https://pub.dartlang.org" + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" source: hosted version: "3.1.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - url: "https://pub.dartlang.org" + sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" process: dependency: transitive description: name: process - url: "https://pub.dartlang.org" + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" source: hosted version: "4.2.4" provider: dependency: "direct main" description: name: provider - url: "https://pub.dartlang.org" + sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + url: "https://pub.dev" source: hosted version: "6.0.5" rive: dependency: transitive description: name: rive - url: "https://pub.dartlang.org" + sha256: "22e3755b75f4ea4492d2fecf4fc2acf1c8d0073df39781d290a20cbfe74c3760" + url: "https://pub.dev" source: hosted version: "0.9.1" shared_preferences: dependency: "direct main" description: name: shared_preferences - url: "https://pub.dartlang.org" + sha256: ee6257848f822b8481691f20c3e6d2bfee2e9eccb2a3d249907fcfb198c55b41 + url: "https://pub.dev" source: hosted - version: "2.0.17" + version: "2.0.18" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - url: "https://pub.dartlang.org" + sha256: a51a4f9375097f94df1c6e0a49c0374440d31ab026b59d58a7e7660675879db4 + url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.0.16" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - url: "https://pub.dartlang.org" + sha256: "6b84fdf06b32bb336f972d373cd38b63734f3461ba56ac2ba01b56d052796259" + url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - url: "https://pub.dartlang.org" + sha256: d7fb71e6e20cd3dfffcc823a28da3539b392e53ed5fc5c2b90b55fdaa8a7e8fa + url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" + sha256: "824bfd02713e37603b2bdade0842e47d56e7db32b1dcdd1cae533fb88e2913fc" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - url: "https://pub.dartlang.org" + sha256: "6737b757e49ba93de2a233df229d0b6a87728cea1684da828cbc718b65dcf9d7" + url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.0.5" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - url: "https://pub.dartlang.org" + sha256: bd014168e8484837c39ef21065b78f305810ceabc1d4f90be6e3b392ce81b46d + url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" sky_engine: dependency: transitive description: flutter @@ -410,128 +465,146 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" sqflite: dependency: "direct main" description: name: sqflite - url: "https://pub.dartlang.org" + sha256: "851d5040552cf911f4cabda08d003eca76b27da3ed0002978272e27c8fbf8ecc" + url: "https://pub.dev" source: hosted - version: "2.2.4+1" + version: "2.2.5" sqflite_common: dependency: transitive description: name: sqflite_common - url: "https://pub.dartlang.org" + sha256: bfd6973aaeeb93475bc0d875ac9aefddf7965ef22ce09790eb963992ffc5183f + url: "https://pub.dev" source: hosted version: "2.4.2+2" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" syncfusion_flutter_charts: dependency: "direct main" description: name: syncfusion_flutter_charts - url: "https://pub.dartlang.org" + sha256: "6faeb211311559f99f3c816b75aa493e68d1cc263f62dec530d5e8098b71bae4" + url: "https://pub.dev" source: hosted version: "20.4.52" syncfusion_flutter_core: dependency: transitive description: name: syncfusion_flutter_core - url: "https://pub.dartlang.org" + sha256: "4319454a92fe5aea1e90ff68c17703a39517ab05dd3074c34c9553e5f7cbf414" + url: "https://pub.dev" source: hosted version: "20.4.52" synchronized: dependency: transitive description: name: synchronized - url: "https://pub.dartlang.org" + sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b" + url: "https://pub.dev" source: hosted version: "3.0.1" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.4.16" timezone: dependency: "direct main" description: name: timezone - url: "https://pub.dartlang.org" + sha256: "24c8fcdd49a805d95777a39064862133ff816ebfffe0ceff110fb5960e557964" + url: "https://pub.dev" source: hosted version: "0.9.1" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" source: hosted version: "1.3.1" uuid: dependency: transitive description: name: uuid - url: "https://pub.dartlang.org" + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + url: "https://pub.dev" source: hosted version: "3.0.7" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" win32: dependency: transitive description: name: win32 - url: "https://pub.dartlang.org" + sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 + url: "https://pub.dev" source: hosted version: "3.1.3" xdg_directories: dependency: transitive description: name: xdg_directories - url: "https://pub.dartlang.org" + sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 + url: "https://pub.dev" source: hosted version: "0.2.0+3" xml: dependency: transitive description: name: xml - url: "https://pub.dartlang.org" + sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.2.2" sdks: dart: ">=2.18.2 <3.0.0" flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index b3efde8..0c85cc8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,33 +1,13 @@ name: smoke_cess_app description: A new Flutter project. -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: 'none' -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. version: 1.0.0+1 environment: sdk: '>=2.18.2 <3.0.0' -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter @@ -43,33 +23,16 @@ dependencies: flutter_local_notifications: ^13.0.0 http: ^0.13.5 syncfusion_flutter_charts: ^20.4.52 - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. flutter_lints: ^2.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - # To add assets to your application, add an assets section, like this: assets: - assets/beep.mp3 - assets/go.mp3 @@ -79,31 +42,3 @@ flutter: - assets/finish.mp3 - assets/group1.json - assets/group3.json - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages From cd07acc3b5ae313ad7a101d53855cfdb9bd8bab6 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 10:29:35 +0100 Subject: [PATCH 47/54] fixed flutter analyze issues introduced with new flutter version --- lib/pages/scanner_page.dart | 14 ++++++----- lib/widgets/popup_for_task_done.dart | 24 ++++++++++--------- lib/widgets/submit_form_button.dart | 34 ++++++++++++++------------- lib/widgets/workout_timer_widget.dart | 16 +++++++------ 4 files changed, 48 insertions(+), 40 deletions(-) diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index d809ff9..ebba252 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -20,12 +20,14 @@ class ScannerPage extends StatelessWidget { await loadSettingsFromLocalJSON(); settingsModel.initSettings(); NotificationService().setAllNotifications(); - AwesomeDialog( - context: context, - dialogType: DialogType.success, - title: 'Geschafft', - desc: 'Die Einstellung wurden erfolgreich gespeichert', - ).show(); + if (context.mounted) { + AwesomeDialog( + context: context, + dialogType: DialogType.success, + title: 'Geschafft', + desc: 'Die Einstellung wurden erfolgreich gespeichert', + ).show(); + } } @override diff --git a/lib/widgets/popup_for_task_done.dart b/lib/widgets/popup_for_task_done.dart index fe63907..fbaa65d 100644 --- a/lib/widgets/popup_for_task_done.dart +++ b/lib/widgets/popup_for_task_done.dart @@ -7,17 +7,19 @@ import '../services/pages_service.dart'; void showTaskDonePopup(BuildContext context, Pages page) async { Duration duration = await getTimeTill(page); - await showDialog( - context: context, - builder: (BuildContext context) { - return ChangeNotifierProvider( - create: (context) => TimerProvider(), - child: TaskDonePopup( - duration: duration, - ), - ); - }, - ); + if (context.mounted) { + await showDialog( + context: context, + builder: (BuildContext context) { + return ChangeNotifierProvider( + create: (context) => TimerProvider(), + child: TaskDonePopup( + duration: duration, + ), + ); + }, + ); + } } class TaskDonePopup extends StatelessWidget { diff --git a/lib/widgets/submit_form_button.dart b/lib/widgets/submit_form_button.dart index 4c98c34..f9cb784 100644 --- a/lib/widgets/submit_form_button.dart +++ b/lib/widgets/submit_form_button.dart @@ -17,22 +17,24 @@ class SubmitFormButton extends StatelessWidget { child: ElevatedButton( onPressed: () async { int success = await submitCallback(); - if (success != 0) { - await AwesomeDialog( - context: context, - dialogType: DialogType.success, - title: 'Gespeichert', - desc: 'Der Eintrag wurde erfolgreich gespeichert', - ).show(); - updateTasks(); - pageProvider.swap(); - } else { - await AwesomeDialog( - context: context, - dialogType: DialogType.error, - title: 'Fehler', - desc: 'Der Eintrag konnte nicht gespeichert werden', - ).show(); + if (context.mounted) { + if (success != 0) { + await AwesomeDialog( + context: context, + dialogType: DialogType.success, + title: 'Gespeichert', + desc: 'Der Eintrag wurde erfolgreich gespeichert', + ).show(); + updateTasks(); + pageProvider.swap(); + } else { + await AwesomeDialog( + context: context, + dialogType: DialogType.error, + title: 'Fehler', + desc: 'Der Eintrag konnte nicht gespeichert werden', + ).show(); + } } }, child: const Text('Speichern'), diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 10f3033..7312ad1 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -28,13 +28,15 @@ class WorkoutTimerWidget extends StatelessWidget { workoutProvider.saveWorkout(); tasksProvider.setTaskDone(Pages.timer); }, 'Motivation nach dem Training'); - await AwesomeDialog( - context: context, - dialogType: DialogType.success, - title: 'Gespeichert', - desc: 'Der Eintrag wurde erfolgreich gespeichert', - ).show(); - pageProvider.swap(); + if (context.mounted) { + await AwesomeDialog( + context: context, + dialogType: DialogType.success, + title: 'Gespeichert', + desc: 'Der Eintrag wurde erfolgreich gespeichert', + ).show(); + pageProvider.swap(); + } } if (workoutProvider.isPhaseComplete && !workoutProvider.isWorkoutComplete) { From 782dc8664444688308730365d10c58ec770380b4 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 10:32:35 +0100 Subject: [PATCH 48/54] use relative imports --- lib/widgets/workout_timer_widget.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index 7312ad1..c47bbf5 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -3,12 +3,12 @@ import 'dart:async'; import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/providers/page_provider.dart'; -import 'package:smoke_cess_app/providers/tasks_provider.dart'; -import 'package:smoke_cess_app/providers/workout_provider.dart'; -import 'package:smoke_cess_app/services/pages_service.dart'; -import 'package:smoke_cess_app/widgets/timer_widget.dart'; +import '../providers/page_provider.dart'; +import '../providers/tasks_provider.dart'; +import '../providers/workout_provider.dart'; +import '../services/pages_service.dart'; +import '../widgets/timer_widget.dart'; import '../providers/timer_provider.dart'; import 'popup_for_start_and_stop.dart'; From b922a27b9ac391533da3bfaa40e2816dbbe482ad Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 10:40:02 +0100 Subject: [PATCH 49/54] gitignore pubspec --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 24476c5..065dc2c 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ migrate_working_dir/ .pub-cache/ .pub/ /build/ +pubspec.lock # Symbolication related app.*.symbols From 2b92bfa5e9f7a82e3ecee8c056ab6912fa60150a Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 10:40:14 +0100 Subject: [PATCH 50/54] ?? --- pubspec.lock | 243 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 158 insertions(+), 85 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index c3f17f4..f76c458 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,140 +5,160 @@ packages: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + url: "https://pub.dev" source: hosted version: "2.4.0" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" audioplayers: dependency: "direct main" description: name: audioplayers - url: "https://pub.dartlang.org" + sha256: "16451eab798b23ad9307aef6f9ca62bb8fb06542af8810eead0d236d3fd40a42" + url: "https://pub.dev" source: hosted version: "3.0.1" audioplayers_android: dependency: transitive description: name: audioplayers_android - url: "https://pub.dartlang.org" + sha256: b2c833e6f718b6b030454e329931229afafe9327fdb002874dd544dc8bf2484d + url: "https://pub.dev" source: hosted version: "2.0.0" audioplayers_darwin: dependency: transitive description: name: audioplayers_darwin - url: "https://pub.dartlang.org" + sha256: e7a3c8759bf11ecfe4b20df338bf9f3d37c7719a5761c46a3833aba0ceeaacff + url: "https://pub.dev" source: hosted version: "3.0.1" audioplayers_linux: dependency: transitive description: name: audioplayers_linux - url: "https://pub.dartlang.org" + sha256: e95b65e1f4d4764601dac5e65f8d8186fc29401043ab020f1dacec483d708707 + url: "https://pub.dev" source: hosted version: "1.0.4" audioplayers_platform_interface: dependency: transitive description: name: audioplayers_platform_interface - url: "https://pub.dartlang.org" + sha256: "178581a44cb685fd798d2108111d2e98cca3400e30b9c3a05546f124fb37f600" + url: "https://pub.dev" source: hosted version: "4.0.0" audioplayers_web: dependency: transitive description: name: audioplayers_web - url: "https://pub.dartlang.org" + sha256: "859ba09be2a57e57a787273f18c8cf0d9b61383870c5ee4b5632fe9adbc37edf" + url: "https://pub.dev" source: hosted version: "2.2.0" audioplayers_windows: dependency: transitive description: name: audioplayers_windows - url: "https://pub.dartlang.org" + sha256: "622e01c4c357c2aaf1b956c3a0f89d97c3cb40315c03f16e3b6c2a31ff9c38bc" + url: "https://pub.dev" source: hosted version: "1.1.3" awesome_dialog: dependency: "direct main" description: name: awesome_dialog - url: "https://pub.dartlang.org" + sha256: ac08268b991f228fc6b8880b68ec030d2941bcc8df8b6a6551fb79f2bd36b7da + url: "https://pub.dev" source: hosted version: "3.0.2" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" source: hosted version: "1.2.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" source: hosted version: "3.0.2" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.dartlang.org" + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" source: hosted version: "1.0.5" dbus: dependency: transitive description: name: dbus - url: "https://pub.dartlang.org" + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" source: hosted version: "0.7.8" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" ffi: dependency: transitive description: name: ffi - url: "https://pub.dartlang.org" + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" source: hosted version: "2.0.1" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" source: hosted version: "6.1.4" flutter: @@ -150,28 +170,32 @@ packages: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" source: hosted version: "2.0.1" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - url: "https://pub.dartlang.org" + sha256: "293995f94e120c8afce768981bd1fa9c5d6de67c547568e3b42ae2defdcbb4a0" + url: "https://pub.dev" source: hosted version: "13.0.0" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - url: "https://pub.dartlang.org" + sha256: ccb08b93703aeedb58856e5637450bf3ffec899adb66dc325630b68994734b89 + url: "https://pub.dev" source: hosted version: "3.0.0+1" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - url: "https://pub.dartlang.org" + sha256: "5ec1feac5f7f7d9266759488bc5f76416152baba9aa1b26fe572246caa00d1ab" + url: "https://pub.dev" source: hosted version: "6.0.0" flutter_test: @@ -188,217 +212,248 @@ packages: dependency: transitive description: name: graphs - url: "https://pub.dartlang.org" + sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 + url: "https://pub.dev" source: hosted version: "2.2.0" http: dependency: "direct main" description: name: http - url: "https://pub.dartlang.org" + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" source: hosted version: "0.13.5" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted version: "4.0.2" intl: dependency: transitive description: name: intl - url: "https://pub.dartlang.org" + sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + url: "https://pub.dev" source: hosted version: "0.18.0" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" source: hosted version: "2.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.13" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" source: hosted version: "1.8.0" mobile_scanner: dependency: "direct main" description: name: mobile_scanner - url: "https://pub.dartlang.org" + sha256: "4045e8441e21f1fb8998a76fbffd054510dd3a3b1dee55c7c9a2083eee687345" + url: "https://pub.dev" source: hosted version: "3.0.0" nested: dependency: transitive description: name: nested - url: "https://pub.dartlang.org" + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" source: hosted version: "1.0.0" path: dependency: "direct main" description: name: path - url: "https://pub.dartlang.org" + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" source: hosted version: "1.8.2" path_provider: dependency: "direct main" description: name: path_provider - url: "https://pub.dartlang.org" + sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 + url: "https://pub.dev" source: hosted version: "2.0.12" path_provider_android: dependency: transitive description: name: path_provider_android - url: "https://pub.dartlang.org" + sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e + url: "https://pub.dev" source: hosted version: "2.0.22" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - url: "https://pub.dartlang.org" + sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" + url: "https://pub.dev" source: hosted version: "2.1.1" path_provider_linux: dependency: transitive description: name: path_provider_linux - url: "https://pub.dartlang.org" + sha256: "2e32f1640f07caef0d3cb993680f181c79e54a3827b997d5ee221490d131fbd9" + url: "https://pub.dev" source: hosted version: "2.1.8" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - url: "https://pub.dartlang.org" + sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 + url: "https://pub.dev" source: hosted version: "2.0.5" path_provider_windows: dependency: transitive description: name: path_provider_windows - url: "https://pub.dartlang.org" + sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c + url: "https://pub.dev" source: hosted version: "2.1.3" petitparser: dependency: transitive description: name: petitparser - url: "https://pub.dartlang.org" + sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + url: "https://pub.dev" source: hosted version: "5.1.0" platform: dependency: transitive description: name: platform - url: "https://pub.dartlang.org" + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" source: hosted version: "3.1.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - url: "https://pub.dartlang.org" + sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + url: "https://pub.dev" source: hosted version: "2.1.3" process: dependency: transitive description: name: process - url: "https://pub.dartlang.org" + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" source: hosted version: "4.2.4" provider: dependency: "direct main" description: name: provider - url: "https://pub.dartlang.org" + sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + url: "https://pub.dev" source: hosted version: "6.0.5" rive: dependency: transitive description: name: rive - url: "https://pub.dartlang.org" + sha256: "22e3755b75f4ea4492d2fecf4fc2acf1c8d0073df39781d290a20cbfe74c3760" + url: "https://pub.dev" source: hosted version: "0.9.1" shared_preferences: dependency: "direct main" description: name: shared_preferences - url: "https://pub.dartlang.org" + sha256: "5949029e70abe87f75cfe59d17bf5c397619c4b74a099b10116baeb34786fad9" + url: "https://pub.dev" source: hosted version: "2.0.17" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - url: "https://pub.dartlang.org" + sha256: "955e9736a12ba776bdd261cf030232b30eadfcd9c79b32a3250dd4a494e8c8f7" + url: "https://pub.dev" source: hosted version: "2.0.15" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - url: "https://pub.dartlang.org" + sha256: "2b55c18636a4edc529fa5cd44c03d3f3100c00513f518c5127c951978efcccd0" + url: "https://pub.dev" source: hosted version: "2.1.3" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - url: "https://pub.dartlang.org" + sha256: f8ea038aa6da37090093974ebdcf4397010605fd2ff65c37a66f9d28394cb874 + url: "https://pub.dev" source: hosted version: "2.1.3" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" + sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 + url: "https://pub.dev" source: hosted version: "2.1.0" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - url: "https://pub.dartlang.org" + sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 + url: "https://pub.dev" source: hosted version: "2.0.4" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - url: "https://pub.dartlang.org" + sha256: "5eaf05ae77658d3521d0e993ede1af962d4b326cd2153d312df716dc250f00c9" + url: "https://pub.dev" source: hosted version: "2.1.3" sky_engine: @@ -410,126 +465,144 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" sqflite: dependency: "direct main" description: name: sqflite - url: "https://pub.dartlang.org" + sha256: "78324387dc81df14f78df06019175a86a2ee0437624166c382e145d0a7fd9a4f" + url: "https://pub.dev" source: hosted version: "2.2.4+1" sqflite_common: dependency: transitive description: name: sqflite_common - url: "https://pub.dartlang.org" + sha256: bfd6973aaeeb93475bc0d875ac9aefddf7965ef22ce09790eb963992ffc5183f + url: "https://pub.dev" source: hosted version: "2.4.2+2" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" syncfusion_flutter_charts: dependency: "direct main" description: name: syncfusion_flutter_charts - url: "https://pub.dartlang.org" + sha256: "6faeb211311559f99f3c816b75aa493e68d1cc263f62dec530d5e8098b71bae4" + url: "https://pub.dev" source: hosted version: "20.4.52" syncfusion_flutter_core: dependency: transitive description: name: syncfusion_flutter_core - url: "https://pub.dartlang.org" + sha256: "4319454a92fe5aea1e90ff68c17703a39517ab05dd3074c34c9553e5f7cbf414" + url: "https://pub.dev" source: hosted version: "20.4.52" synchronized: dependency: transitive description: name: synchronized - url: "https://pub.dartlang.org" + sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b" + url: "https://pub.dev" source: hosted version: "3.0.1" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.4.16" timezone: dependency: "direct main" description: name: timezone - url: "https://pub.dartlang.org" + sha256: "24c8fcdd49a805d95777a39064862133ff816ebfffe0ceff110fb5960e557964" + url: "https://pub.dev" source: hosted version: "0.9.1" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" source: hosted version: "1.3.1" uuid: dependency: transitive description: name: uuid - url: "https://pub.dartlang.org" + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + url: "https://pub.dev" source: hosted version: "3.0.7" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" win32: dependency: transitive description: name: win32 - url: "https://pub.dartlang.org" + sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 + url: "https://pub.dev" source: hosted version: "3.1.3" xdg_directories: dependency: transitive description: name: xdg_directories - url: "https://pub.dartlang.org" + sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 + url: "https://pub.dev" source: hosted version: "0.2.0+3" xml: dependency: transitive description: name: xml - url: "https://pub.dartlang.org" + sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb + url: "https://pub.dev" source: hosted version: "6.1.0" sdks: From fd362e85313fb132a14498b8012cc8758572316d Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 12:14:29 +0100 Subject: [PATCH 51/54] use dedicated audioprovider --- lib/pages/interval_page.dart | 4 +- lib/providers/audio_provider.dart | 47 +++++++++++++++++++++++ lib/providers/workout_provider.dart | 58 +++++++++-------------------- lib/widgets/mute_button.dart | 5 ++- lib/widgets/workout_form.dart | 11 ++++-- 5 files changed, 77 insertions(+), 48 deletions(-) create mode 100644 lib/providers/audio_provider.dart diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index 5117a8d..2326168 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -10,7 +10,7 @@ class IntervalTimerPage extends StatelessWidget { @override Widget build(BuildContext context) { - return const ViewFormPage( - form: WorkoutForm(), view: WorkoutView(), page: Pages.timer); + return ViewFormPage( + form: WorkoutForm(), view: const WorkoutView(), page: Pages.timer); } } diff --git a/lib/providers/audio_provider.dart b/lib/providers/audio_provider.dart new file mode 100644 index 0000000..a141cb2 --- /dev/null +++ b/lib/providers/audio_provider.dart @@ -0,0 +1,47 @@ +import 'dart:async'; + +import 'package:audioplayers/audioplayers.dart'; +import 'package:flutter/cupertino.dart'; + +class AudioProvider extends ChangeNotifier { + final AudioPlayer _audioPlayer = AudioPlayer(); + bool _isMuted = false; + final Source _finishedSoundSource = AssetSource('finish.mp3'); + final Source _beepSoundSource = AssetSource('beep.mp3'); + StreamSubscription? _onCompleteSubscription; + + bool get isMuted => _isMuted; + + void stop() => _resetPlayer(); + + void playFinishSound() { + _resetPlayer(); + _audioPlayer.play(_finishedSoundSource); + } + + void mutePlayer() { + _isMuted = true; + _audioPlayer.setVolume(0); + notifyListeners(); + } + + void unMutePlayer() { + _isMuted = false; + _audioPlayer.setVolume(1); + notifyListeners(); + } + + //resets player position and delete listening subscription + void _resetPlayer() { + _audioPlayer.stop(); + _onCompleteSubscription?.cancel(); + } + + void playSourceAfterBeep(AssetSource source) { + _resetPlayer(); + _audioPlayer.play(_beepSoundSource); + _onCompleteSubscription = _audioPlayer.onPlayerComplete.listen((event) { + _audioPlayer.play(source); + }); + } +} diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 0cf3804..5d85c18 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -1,38 +1,20 @@ -import 'dart:async'; - import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; import 'package:smoke_cess_app/models/workout.dart'; +import 'package:smoke_cess_app/providers/audio_provider.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; import '../globals.dart' as globals; class WorkoutProvider extends ChangeNotifier { - TimerProvider timerProvider; + final TimerProvider timerProvider; + final AudioProvider audioProvider; - final AudioPlayer _audioPlayer = AudioPlayer(); - late StreamSubscription _onCompleteSubscription; - final Source _finishedSoundSource = AssetSource('finish.mp3'); - final Source _beepSoundSource = AssetSource('beep.mp3'); bool isWorkoutStarted = false; bool isWorkoutComplete = false; - bool isMuted = false; int motivationBefore = 50; int motivationAfter = 50; - void mutePlayer() { - isMuted = true; - _audioPlayer.setVolume(0); - notifyListeners(); - } - - void unMutePlayer() { - isMuted = false; - _audioPlayer.setVolume(1); - notifyListeners(); - } - - WorkoutProvider(this.timerProvider); - + int _workoutPhaseIndex = 0; final List _workoutPhases = [ 'Warm-Up', 'High Intensity', @@ -44,7 +26,8 @@ class WorkoutProvider extends ChangeNotifier { 'High Intensity', 'Cool-down' ]; - int _workoutPhaseIndex = 0; + + WorkoutProvider(this.timerProvider, this.audioProvider); String get currentPhase => _workoutPhases[_workoutPhaseIndex]; Duration get currentPhaseDuration => @@ -54,22 +37,15 @@ class WorkoutProvider extends ChangeNotifier { Color get currentPhaseColor => _workoutPhaseSettings[currentPhase]!['color']; AssetSource get currentPhaseSource => _workoutPhaseSettings[currentPhase]!['source']; - /* bool get isWorkoutComplete => - _workoutPhaseIndex == _workoutPhases.length - 1 && isPhaseComplete; */ void nextPhase() { - _onCompleteSubscription.cancel(); - _audioPlayer.stop(); if (_workoutPhaseIndex < _workoutPhases.length - 1) { - _audioPlayer.play(_beepSoundSource); _workoutPhaseIndex += 1; - _onCompleteSubscription = _audioPlayer.onPlayerComplete.listen((event) { - _audioPlayer.play(currentPhaseSource); - }); + audioProvider.playSourceAfterBeep(currentPhaseSource); timerProvider.startTimer(currentPhaseDuration); } else { //workout completed - _audioPlayer.play(_finishedSoundSource); + audioProvider.playFinishSound; stopWorkout(); } } @@ -77,29 +53,29 @@ class WorkoutProvider extends ChangeNotifier { void startWorkout() { isWorkoutStarted = true; isWorkoutComplete = false; - _audioPlayer.play(_beepSoundSource).whenComplete(() => null); - _onCompleteSubscription = _audioPlayer.onPlayerComplete.listen((event) { - _audioPlayer.play(currentPhaseSource); - }); + audioProvider.playSourceAfterBeep(currentPhaseSource); timerProvider.startTimer(currentPhaseDuration); } void stopWorkout() { isWorkoutStarted = false; isWorkoutComplete = true; - _audioPlayer.stop(); - timerProvider.stopTimer(); + _cleanUp(); notifyListeners(); } void interruptWorkout() { isWorkoutStarted = false; isWorkoutComplete = false; - _audioPlayer.stop(); - timerProvider.stopTimer(); + _cleanUp(); notifyListeners(); } + void _cleanUp() { + audioProvider.stop(); + timerProvider.stopTimer(); + } + void saveWorkout() { Workout workout = Workout(motivationBefore, motivationAfter, DateTime.now()); @@ -108,7 +84,7 @@ class WorkoutProvider extends ChangeNotifier { @override void dispose() { - interruptWorkout(); + _cleanUp(); super.dispose(); } } diff --git a/lib/widgets/mute_button.dart b/lib/widgets/mute_button.dart index 863bb52..29bebf7 100644 --- a/lib/widgets/mute_button.dart +++ b/lib/widgets/mute_button.dart @@ -1,13 +1,14 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/providers/workout_provider.dart'; + +import '../providers/audio_provider.dart'; class MuteButton extends StatelessWidget { const MuteButton({super.key}); @override Widget build(BuildContext context) { - WorkoutProvider workoutProvider = context.watch(); + AudioProvider workoutProvider = context.watch(); return IconButton( onPressed: workoutProvider.isMuted diff --git a/lib/widgets/workout_form.dart b/lib/widgets/workout_form.dart index a176cd0..3e75882 100644 --- a/lib/widgets/workout_form.dart +++ b/lib/widgets/workout_form.dart @@ -1,21 +1,26 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/audio_provider.dart'; import '../providers/timer_provider.dart'; import '../providers/workout_provider.dart'; import 'mute_button.dart'; import 'workout_timer_widget.dart'; class WorkoutForm extends StatelessWidget { - const WorkoutForm({super.key}); + WorkoutForm({super.key}); + + final TimerProvider timerProvider = TimerProvider(); + final AudioProvider audioProvider = AudioProvider(); @override Widget build(BuildContext context) { - TimerProvider timerProvider = TimerProvider(); return MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => timerProvider), + ChangeNotifierProvider(create: (context) => audioProvider), ChangeNotifierProvider( - create: (context) => WorkoutProvider(timerProvider)), + create: (context) => + WorkoutProvider(timerProvider, audioProvider)), ], child: Column( mainAxisAlignment: MainAxisAlignment.center, From 69a84346ca210cce0ab54b66a325579146128d7d Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 12:15:02 +0100 Subject: [PATCH 52/54] remove pubspec lock from repo --- pubspec.lock | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 pubspec.lock diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index e69de29..0000000 From a4a73f3c75d693b1d769b7876b98b9cbdd587cfb Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 12:41:06 +0100 Subject: [PATCH 53/54] add App Icon --- android/app/src/main/AndroidManifest.xml | 4 +- .../main/res/mipmap-hdpi/launcher_icon.png | Bin 0 -> 3646 bytes .../main/res/mipmap-mdpi/launcher_icon.png | Bin 0 -> 2258 bytes .../main/res/mipmap-xhdpi/launcher_icon.png | Bin 0 -> 4874 bytes .../main/res/mipmap-xxhdpi/launcher_icon.png | Bin 0 -> 7368 bytes .../main/res/mipmap-xxxhdpi/launcher_icon.png | Bin 0 -> 10080 bytes assets/ZI_logo.png | Bin 0 -> 36868 bytes .../Icon-App-1024x1024@1x.png | Bin 10932 -> 88661 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 796 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 1796 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 2965 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 1193 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 2818 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 4390 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 1796 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 4111 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 6196 bytes .../AppIcon.appiconset/Icon-App-50x50@1x.png | Bin 0 -> 2380 bytes .../AppIcon.appiconset/Icon-App-50x50@2x.png | Bin 0 -> 5255 bytes .../AppIcon.appiconset/Icon-App-57x57@1x.png | Bin 0 -> 2771 bytes .../AppIcon.appiconset/Icon-App-57x57@2x.png | Bin 0 -> 5815 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 6196 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 9371 bytes .../AppIcon.appiconset/Icon-App-72x72@1x.png | Bin 0 -> 3646 bytes .../AppIcon.appiconset/Icon-App-72x72@2x.png | Bin 0 -> 7368 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 3907 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 7914 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 8651 bytes ios/Runner/Info.plist | 4 +- pubspec.lock | 72 ++++++++++++++++++ pubspec.yaml | 5 ++ 31 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 android/app/src/main/res/mipmap-hdpi/launcher_icon.png create mode 100644 android/app/src/main/res/mipmap-mdpi/launcher_icon.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/launcher_icon.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png create mode 100644 assets/ZI_logo.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c5439ff..752ea03 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -3,9 +3,9 @@ + android:icon="@mipmap/launcher_icon"> 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0959d71786bd051627c7542e23c1246db25d6f33 GIT binary patch literal 4874 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..81b05af68ca268cbc18af2a4de4a84341145208a GIT binary patch literal 7368 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 B>HYu! literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index dc9ada4725e9b0ddb1deab583e5b5102493aa332..e34f3b40d6d15d0cca3a254439748be67402076b 100644 GIT binary patch literal 88661 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

;fO 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 literal 10932 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 D*+_0c delta 540 zcmV+%0^|Lh2DAi_BYyw^b5ch_0Itp)=>Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$W zg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9Hfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH z&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr)C01LsCxk=72-vXmVcK>PAbAwTqj;`=7>HX zM93AwkN~n3*c#^KTQF}AzdqL{zi@>Zh*Ssn#E}f z?2!Tdd=!N|E`LQqfZ!&&jLDjEQ&kRm2Au4n1MK0N35-SfX2&{q-XJr=-ElMh0X1pR zv9tJC^8;Ev)6EqkFe?kk}Ykyy<_4;rt+ya6eQY9b)USk!t)}vP2 zdQ?S4P-q=XZELlywRUWsPFtOhS4TX?vkK}sI^cLxuXf&Q{Ws(Z2N#=)PJZdNXFx9TTqm85MVf` z3QP_swsS+^{Ns?=$x&ULg2Ln-;G0{(#%na>(+?2zEZo^M6Iyj$*8>VfmI#VE4ReV- z?))(UrD>;{#&~9Ca3A>@yvD47U+8wE?wQ^7fF5I(!@{~3Qnn69MNV?FF-EIJ&e?U) z)>q+;_qM^_Z+{=k(oS|AAYWh(mq80qa6QHV?q$orydBQLk#HZrxN8Bs^$dc*!Un}R zW83sCPCW?k@xM}R3ZZLIcMYIe<^lcotS(J!)3>JN9(a5Uh-5CPEzN#;$aH`VujPmK zOftwfrUO)!KcrV4ES>yNk(<)0uceb5I&B?P%Ev8-On(Phk#`FXsxtHl4r>$8F)$R$ zhkrt+(R3Xkqt&3`S`1Z?WhhBKKmgZ_`niQHgr#FJZXO+OY}mAUF#F7EILId>AmSwM zAC5rD?S!T=eH!ZZ))IJ({s{$18==g)Y8@1in4 ziQq(#d4Gs&5AA3cXHfP2VNSUf+UJ_?`ZTrqwH`%GI4*FlRZ+5SapV*@mGN=O}iX~#!k;HOEr zwPP&78chowHonjT0pW*W+j|l!@-O1?-<#Rr9sEC}J62){=saj93zvOvIUb(+rP)~a zxqmenu<$JUPTh*DYy8_hxj<|M9*;*Ss^s+PJ7puO>v6b$B#aXKzJJek_BW#EwYbIf z(PQ+FQ0AO5fYVz;jgqeFRX7j$1VSqr)K$t>;RZ%uLQQD~Wr&$ZeWXr4B>AHVW_dHX zCety^ub{PCFv%nzJV;n%bV2tK(JWlv<$s@Bg)32#32e zG_ls`276^dm9l_6S{h$qL4lsY_J0;B+eVXL()_(@{8n*(D{$a>E`8lcK1fxEB zlRET9zq#?KRVpY1KA-|$->Gy)0bPgAL$6U3OG)dIbDlFlK}4G;@S{Y6s(-}oo#Uw- zR&+L;A)vkQ81^y5)695e9A3&f%ZwCoP*fr*VJjqW9tzddqE|XQLv1FH$8R5?m2)48 zyMw4IPQl&1vuU=DbCytQ3yED{D2_#=x=6w4Cw25jRY5A}xVo~4GKC`qA}KVg8g4+5 zjSB+iouXR%1gSeGL0fP1QGZyI>C0DL`2)J*?<4P`VK1S#p2I(e)INaX_#4i3o<2BD zyMH}ghD0Fu!Y1Q@0&zD4Mx9`9*NvDVsIM$*74C&)pI-%E+P%KhH<3nM)+A;nwytm= zy$mh`7E)Q%Ke0N^xkh!dg4&HZYNl3G8p}jkdZHmE?qlU{Ty7S)9r?OH=qSBV>& zMv%<=n%0?%?!87mA8ygo(a@*|)zwcr4EMsyso^d+-gLLywDq;fI`IR02qaQA**g!I z1D{FjO#h6!qo%2C+|7)ReNNK|=+JKpDdZlnkIINyyARgC3F!9bQyjj{9{)E}Rb>7H Xp>B1Vt4~uG00000NkvXXu0mjfQRiHL delta 1264 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 delta 1004 zcmVU6E9hRDZsKRZ8`ICh6f+zh_Ab z(jRY2a{B+|os<)hT5u?RkVuNN!js0QT$N5qdKbV*dH@&&Vjutv8ARzpRqqL`fs%v3 z_*Hd00YYHFNIC{Q1h^F1P!f5C!xIU|E+^yzaDu?XOc`!nZ+PjJh~`vV%1!_aj2TH& zKwB1AHSp7kgnyx5V{+EJ5gM3@MPI>kpg&?m&MZY^mCPDRTDzYO*c$nehN*{r1;b!} zL~B$N2&udO8tBp-PM4v#VA!7mo$41xCTJ~SU|=SOZ3V-D{)qMzXd9GbL+F1E1Yg28 z1RU&-XuA$zU1(Mh+ag0OA2L@}lJyL@X7yGouP$&$M1OlzM%Nm7TCsNcLSx`u3}=gu zz_8*kvf$vZc1ylSt62f92V^XU?#Y zz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#YwqkoqZx^jlHgV2aMo8z}1PBGB7;Ej|r zUB(UDU}Sw|KG_{Ict^w^3nDNEn{Q#}yRSHTWQ?6}jPTd&B7rp|u4dqtoymH&RdRgj zT#2{N3mqTk(vPPJH*F&>&U5!|8yVTRi>^YB#EGCzC1t+ajDgsRm$x_ZV)O4@I&qfh zrhh)<9J$s!Kq@Bk2*~DAzd+ItgnGi{)g+zGbzBzZYX#nnI#*DSOq^;G=#=I-Jg>aXP1F zlEh^jkE`b1p$afa*ZWyv)#99=s8_FR$dIH^l3o73@CH04X-v{g?RT@=lj`|W(&I~U amdro4`EaZUE<#%!{l98a<_#psEeSffdH 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 UqdUSI@c;k-07*qoM6N<$g3_*ZC;$Ke literal 1716 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 2ccbfd967d9697cd4b83225558af2911e9571c9b..763385e5c4f23cb7736d4d6bb324e7178f7b0d1c 100644 GIT binary patch delta 1781 zcmV;rt+ya6eQY9b)USk!t)}vP2 zdQ?S4P-q=XZELlywRUWsPFtOhS4TX?vkK}sI^cLxuXf&Q{Ws(Z2N#=)PJZdNXFx9TTqm85MVf` z3QP_swsS+^{Ns?=$x&ULg2Ln-;G0{(#%na>(+?2zEZo^M6Iyj$*8>VfmI#VE4ReV- z?))(UrD>;{#&~9Ca3A>@yvD47U+8wE?wQ^7fF5I(!@{~3Qnn69MNV?FF-EIJ&e?U) z)>q+;_qM^_Z+{=k(oS|AAYWh(mq80qa6QHV?q$orydBQLk#HZrxN8Bs^$dc*!Un}R zW83sCPCW?k@xM}R3ZZLIcMYIe<^lcotS(J!)3>JN9(a5Uh-5CPEzN#;$aH`VujPmK zOftwfrUO)!KcrV4ES>yNk(<)0uceb5I&B?P%Ev8-On(Phk#`FXsxtHl4r>$8F)$R$ zhkrt+(R3Xkqt&3`S`1Z?WhhBKKmgZ_`niQHgr#FJZXO+OY}mAUF#F7EILId>AmSwM zAC5rD?S!T=eH!ZZ))IJ({s{$18==g)Y8@1in4 ziQq(#d4Gs&5AA3cXHfP2VNSUf+UJ_?`ZTrqwH`%GI4*FlRZ+5SapV*@mGN=O}iX~#!k;HOEr zwPP&78chowHonjT0pW*W+j|l!@-O1?-<#Rr9sEC}J62){=saj93zvOvIUb(+rP)~a zxqmenu<$JUPTh*DYy8_hxj<|M9*;*Ss^s+PJ7puO>v6b$B#aXKzJJek_BW#EwYbIf z(PQ+FQ0AO5fYVz;jgqeFRX7j$1VSqr)K$t>;RZ%uLQQD~Wr&$ZeWXr4B>AHVW_dHX zCety^ub{PCFv%nzJV;n%bV2tK(JWlv<$s@Bg)32#32e zG_ls`276^dm9l_6S{h$qL4lsY_J0;B+eVXL()_(@{8n*(D{$a>E`8lcK1fxEB zlRET9zq#?KRVpY1KA-|$->Gy)0bPgAL$6U3OG)dIbDlFlK}4G;@S{Y6s(-}oo#Uw- zR&+L;A)vkQ81^y5)695e9A3&f%ZwCoP*fr*VJjqW9tzddqE|XQLv1FH$8R5?m2)48 zyMw4IPQl&1vuU=DbCytQ3yED{D2_#=x=6w4Cw25jRY5A}xVo~4GKC`qA}KVg8g4+5 zjSB+iouXR%1gSeGL0fP1QGZyI>C0DL`2)J*?<4P`VK1S#p2I(e)INaX_#4i3o<2BD zyMH}ghD0Fu!Y1Q@0&zD4Mx9`9*NvDVsIM$*74C&)pI-%E+P%KhH<3nM)+A;nwytm= zy$mh`7E)Q%Ke0N^xkh!dg4&HZYNl3G8p}jkdZHmE?qlU{Ty7S)9r?OH=qSBV>& zMv%<=n%0?%?!87mA8ygo(a@*|)zwcr4EMsyso^d+-gLLywDq;fI`IR02qaQA**g!I z1D{FjO#h6!qo%2C+|7)ReNNK|=+JKpDdZlnkIINyyARgC3F!9bQyjj{9{)E}Rb>7H Xp>B1Vt4~uG00000NkvXXu0mjfQRiHL delta 1264 zcmV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~ahS(%I#+V>J-vjIic7FmrfXn)08SZW zzL?HZgo}SSNcu|m&n`&XRLWEe_q?Rh_`)DQ!Ucc|OZ-XFn511rB_$bP9dH@wh-Ggo zqynVM3)3?_gVf#>E5u8iY)EMfQ#c-AONh%-O{IL)jaDpDp>fGZ;* z&NNa1u7PwxJb%(=S<`N2yPs}=Qd>tT)H6o27G=V5iPc4VS!_#@l|b>qnm9t zrveTdNw3GcyxNRs+YhS;I5HWpo!3ygInT3 zP$EweZn5FmW{(G2OmSWnlaVUrTdi!)jr#2-s*s1Y*W_xKW$+MV)+W zCJONO)jWe^^@a6LPGuFcfUl@%=t@<;i?RwP48wWx&VbMLbZu~j*zqUV3tSiqXmuv* zLdA3PVSjYZn;Sj4Qq`Z+ib)a*a^cJc%E9^JB;4s+K@rARbcBLT5P=@r;IVnBMKvT* z)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$KvMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y z6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nhet(}(@b2R=TnMg(!~JoOB@~U_c{58&x0vLE`&u6Jl1aUEMx=WS<^6F&44hq+zu3- z_YL@*xZ%^Cib8GTu|*xK0`9Mn-Pm>9AUJNoFl&j-KxEN_kAlACY{ z$$uG-fx8)AdpOV5PKzI?;TLyZ)r=v66R`IomuI>x!+GH*&chH~4;$pUapo+qzkiN9 z<5@h%5QL2t?hTdv#T`vf9JrKYa7=W%A%T-Zg*<e+2=O{vx$^4} zFC06^KjT>(Tk|t13k)ZJ8iKTjKw?FACl`;u#Kx8F_~|Syo`Y)*u46%BQD+-het*Bi z?&DuFlF8#(Lxtca1NV%iv%qemMnJ6c{JImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$pt}{a=*RiD2Ikv6o=IM1kgc7zq zpaZ;OB)P!1zz*i3{U()Dq#jG)erW`rGV!8YiTcE;xq_^g1lF2L%K5-fW6V#bE#SS9 zvT+;sezt(~lJ><+Gy2p|Ncw&Opk}j6l6FjiD+x;i=}0=DsM|lR`BgEDeVmu{s-k?D a0{1_&;gnn2jcRKE0000|MNoHPNW-*!Z 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 N002ovPDHLkV1hkB+7AE# delta 1881 zcmV-f2d4OsAmFQtfgmaf zE#=YDCq`qUBt#QpG%*H6QHY765~R=qZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1 zK4#~5?#|rh?sS)(-JQqX*}ciXJ56_Hdw=^s_srbAdqxlvG=BhaYkq$ewHUPpbsRN- z8b*0hBN-yE`ach%PN2R+y^b1xyS^vYaA%P{0B)C}TGSVIY9nx4Q57f`g-BQ=3(v)D zPe=Wtd7%(WQXl0E1}1Cz!nR|m!dOgn!NW%nYBh5}NtNti2g*!8Xk4x|Mj*C>NiaUs%#fyzU5=HSJJNOHlQqY?|vw)nU< z2QMMS`lwSJ2Hx}P6M{KbaT{e*9AT%9eI(=l&SYCYM|Ig4rI}dB5qd~wj*Nx4QJx9# zIBAs8%j_7~&YS~r*CZ9*v7r#G>JGqH=K`>%Cppo5K7Ymi`@M4Hq%TE)WY?~6BEcUM zP<~#WN8ug07J`z4J}B(;!E97f5}JKL(X{rPu)SY0B9!TP_yhs?Hm~6u1@Dj#7NDxT zd{CK$s#MKEfIkjM={PS|7%w9Lck&33!aK^qBS6Xz>sN&;;@I6+q^RQ>aFs$@8v%HZ zxenykd4DOxJ773GmQ_Cic%3JJhC0t2cx>|vJcVusIB!%F90{+}8hG3QU4KNeK zmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u7JyDj7`6d)qVp^R=%j>UIY6f+3`+qz zIc!Y_=+uN^3BYV|o+$vGo-j-Wm<R zS$}xdX~O$Yg=geSue3vW@1PX^2Pqgc;1#9_uPTP~j9w;ZND^rqkiuhAB8Yn75d}l( zInN4shMvYGf|$&hM>@LV6yMG>^v=H@#E$v_c z;k|a$2M;%S5%$e6j53blnKqfwHmE=(;D0K+l7~0B^#+XJeFJ88=!a+rJX5E$s1u7i z^}~Beg*Rc3BE1mpf@k`KYV%(b?7W;BJgR~O5bcC#>Xg1L$DatG2}6PBj|(s2#67Vg z+6~Y250zrAhS%%7L{8)Zp6LKbxe`)?r-it%>n6kA|=8iMUiFYvM zoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS*ZdmT`g5-`BuJs`0LVhz+D9NN za3<=6m;cQLaF?tCv8)zcRSh66*na@qY=&sd0?S|&MDJ}O7BnNgc7XiN=fOQ^B?u*J zL9DI^H_BDH3B*!+A=rxG>mqY4 zM0QLJ!^4D;-*^T*Q{Mn##xf8~RwJw$1h^p#P^_xgK)hf%MBBgS5EEjH3V*NRG`OEE z2jS^OAQmnMao*=3me)q$QMnh|=R_{PXcGmoX#^&90F0|Y3GPY7AWSX;aVEO2bPYO> zfNO|?7lCL~ICJw=F9o6u+b&CRf6WQVn}V*J@g73MF|WE&Q4DY~AzGMNxcahTP(8<~ zYxxy~;u`S0v;|xX8%Kq#E`Nv?IgtPy0ghS(;=XPW=B@(|LUC0$=muzUVhIp{y>Vup z?1QLwwr<}U5az8<4WhY;g|fOr0JhT0Ri2zkJ6pFm4T$E2Gd)NL0r)J0wVqVe+n)AbQCx)yh9;w+J6?NF5LmoecS@ieAKL8%bVd@+-KT{ zyI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^EkL$}tsQt5>QA^;QgjgMV83iI%^s)DX_K`0jg!)|u7T5Zs=Fm=Ip`s2bC17?Wgj52`x{ zF)qCGsQXk_u6PxE^HG=RsaTF(1Rkk+UXZAgubV0N&N?xah2Uh3^Cs#l56?g(R{cTq zPGkefkY@O5Mm?BRZGDI?1^+6lFUF-zrk8pe#~Wb<`OY$8j9japswE9cNS=6@Fj< zS+pu3ir}y)Fep+eg+dG6_l>sclC;h8pBtd`-gHZH6KK8f^W4Jy?#=nmz3)BW*}n4~ zAvo9$_s}RPqo+gWI~Gz^G@M*~iBv)k9gL_)YsGmqmmNpb#l5J@`yce3Mn`2$=qN?Q z4m<(impT&xsn0{=b_*rx|~M-j^M#U>g|uw8JQ5f^;2q%UFdAP2u))dDV1&D zi<}^qs~}NEkrb5JaY%mTXXJmAf$|@}VmsR$!GnQ3GysVUe_H+C(XR6au86!Z6MW-rlpbM~WRBp0Aaa)> zalxKm$k|6V;OPjP@)6OY>b}Mo$T51! zZXEx|ZO}GdX5k4qg8N0t-P?C5q@bhH+iB5UnkNM3P>5PO|u z*MJA$pSqRkvAI6x2<{7!(_V*>=R%W}XT8E2x!2HAUXIgS(viIE1b95jRVk13v)@ML ziLasW)Y+0eM{sYD2S<@oG?ON4tvQT~nSZy7zNY+hC^@(qffLqr%bZ+-;dlFDlpI=T zOVS*{y}|F6C7@ch*IAIY^t4^cdh{~VW5Yzl&x6D}{3-^$C)aRYCHd&5fCKN$Y5IKj_WF?2+ zb%^eYpFTy<#J5OYJfd4RGJXz6Fq`ma@zUm zeaYG+If9vx1>R0OZ^++6%%|h@*I(E}BUr2$4W|(jbhT-$Nsc3!37IOMcHUTU#G(3| zikbREka|awl6}gW+mk0Y24rV|{G)XS9FZgyxcL=rjeyra3*+N3ywdqUevnMTSZEW19zFY}H?Q<38cmU;z)$C$-xue)Sz zavZ@-wA7xa5v&LvkFsN19j4zsbUf|ch!)ayvf71*BbbTif}>D|EbKn_h?owZ;BnJr zfFs};dmrt*t>PGTTC0cBID(mI$onrsdJIPko&BMTz8%#$_8*THdB`C5n@rEorG2&} z$q~#%YsE!$wC2KD8r?1PO?}EC1pC~wpodonG0#RFYO+7GB}tB8CJY9k=InL^jD59R z<`z5)%9v!-pF3$cy#kQ{0b`z~$<$@vKwVyDOR^lny`k!-jfCJo;ktu558*REL{q^y zQXh8OMQ7ObXCRV>^^h1*eE1DpljR8R4J{QVsJ*xmBg0m7%UoPj5Iy^^IJ4#Vtm{*b zz7>9BU!%#?m0zRI_G*D6xGxm!d($2%o;Ghm?na)DOvD5%PAvXR{8s&=@4F*bgDk zn&2g0E3mDmOi&nM&$G@ z;Pc#Ra&_gmDEM|wAHT8~9Krp8a@9G%Z3&Vd@rBs^wjNh_P{pr?EZ`0leDf@7&m4l$ zFt{`+r@oL$FOrYuL6Qu8jj^^l2WK`s#O9z1NAN&sZ)`=@+9^m{c>rQX678CcA_Z~t z4?>fE3YEt`K||gys7ou%(h$4JFfwimd{dTSgo<*aGhaNe>!`$;jnkoRVs+-~3c)@p zlSwP?HxNoj3~>Li7kpvgrAjg)5g}=7$ngPbAXP)#NcCN*sYfRWWh#iAgD_xWGN=(d ze?2RC)#j1%79Q3X*$?~eClMh zlt&8T7C43@cUXcCiR&%IZ1A{xc=$rl7rE4`b*tS(INSgjF@jVO5~kRkU?bEx_D&cy z)wK@E7zcLXqIAcYRe2DIls&~1!Sp6O&sfiqI|R{Qe;FO>8bY)g!5oG$ID&^cID&^c z%(bOgQ+E-~r6HIW-&ukB3tyuuXEPddjtqKU_16NS#0g$WGoXrl2(F91VHdtmbPdg4!~`KXo30(_V+rdDInQzwfhG zOUw?zRAxda{|*6nzG3oLvKB7NR3t9@86}6G#ihOf{MDLn=}1q+%wGqY&wT^m+&^ru zgN0%-5;E4oEqK1InYjuPM&0=?sk@VLYW*_kJGxj(cWA&nDGiacH$vcK`J8euu&o3O zB|;=W@dad_Q+mDL)t-x*Guv^w^f1~=FA&LP)91t&c|+!#0Qb;)p^TjifxtWlg(7$n zV&&_ZfngCDEjZKs6BI_k494|)a9k9_-Qu;;??jUI|l)Gya|j+lqu zhca?SkE=XVw|_`JlznVFquo?c1cf3d{Y&r#^o8FBT@woTKZ;^1gz*3?W^~#vlpNZC z@?#qz@{mGPWeVhCT^%g<9fiO#Z!)9?l9^@X*l2Nj6uLB>$lkCLaZBqkGW_{&IkmDN zXyVg2|M|;SrF*kOD0W87gWJh-(&KVyE@vTU`y8l?iY!Wx+Ewi;xu)c;%2e2l*G>Bi z^h8zGYgUtc4U{?0S^p>8`ot}yj=sJ~SCz0F`MX~s4K9am2?w!4j=%}Og=rDk!S|qT zRNF;Q*p$_fxY6Bl+v`u_mvwiev%%&NPL>la_YY%u`jfA%@dWa|c&(3LSO&_pUpnvt z5*J-3Sm^8nnRhgriX9Vmjw)42E59Y(wkvTf6@ho)_&bwW*CUe2;GOaeO=i&5A$#jg zHpr!5xrrWi*HfT31a!FY#R}*;+3B=WjW@rfht1?t-w=loOzDqX^hr0lCf#0Xka#Ge zX{cva*Qh%mC8pV}hr~!M)e^Lou@+s=vJxzkN}!5eNR!nUZe?}kDf)ru;2Fd08g-$m zD2p{6{pz3l8a%=lF{D%>Fmq_L4I*kq|1z4WrE(w2|F?%tEtV0iN|-^OwdWRXMwA|Y zo3-2oPFf7_1fRjrEO;&!KwMA#wU>U*6 z82ZqertuUmpJ%7^dL^bI^q#foxmN;(s;pN~u+yfEDF%h$i3{OB?jLZJ1B4=g9+w)% zcGR5S%eI=q*TGcXqzITmlhx;b!AdTa(J90-sWT9qMtww% z^KNmLhSJV8^;z}^4>9->Eb|S9KtvxOtuOrE<{T&j0};P)k6E{?ojh>PrWJOdKJ-c) zhlq4)FC@n<-x=Ydpq;lhn6FA?0fQ%4s*0lvj9q9hJ#CwIS1A%Rc9E8(Crxh9RpacA zndFPMDvbT0p$H5ijk+&MxfKt5Gs`gYm_w3wnK~Q1iI%FOXy+X*=b>x1e&=daU-RKF zAaJ37I0k(a&TO6vb+Jw1g9e1$&mRd(_K}Z^<|q!GrUY%R7vSp2e!uqyVDKeaq70;+ zx7A#@1;nj_jT*ey@R|>?^v9kC7`N>_=WGoMR^bXg0U0%yXFzg z;h4>@91MzJ>-t`XF3Z*rD+0sG3nndQ0X+^#W6=&`8duxBI}|hbS$Kp$!jKwKuzxwR z9J}nR{Ki2@Uhom}m>r~)I$Q8Ns*5!E4WlHa&zG=x7h_=k%CuPah77wq*9E1`f>+Yt z%;Z&Be?igrn|k@huz?V*m8CelWh%UrmxH-yQ19qK)yefxmlX_7gLnjz9^D0}5%h6a zohBcr|1+KZYu~=E|M)ZnPuvXiYGDnjcZa7FK@VJMWYuIJFdb}zC*YIr&=yEs>0#;( zy33?HG8ygF)vW963DxKngirs97K52WW6?HJEj&T01;;rM+#uL*ZPK+yjayJU<4PCK zXFf!_BbK?MSPGx0SVYd-W46Hs6@xi@eTKtA^xt6EkKpLJFTgYAF*AALz9)%^w<%2h zfN%}-N6ez{U=+}YKsA?7A#3ey=(N_4zzs3jhv2X&OW~dLs+qhx=PxMyp1n}Ky+J(E z3$e@g!N~Wa$-6Y=q(L`})cIPw>c7drKEYmzlQHTpibQ&&rm1K>azA~Mb$vY{lt_`3 z@hv2Lx_`An*G$av6tq?s+g1Nf2zCjU`%$wqTg`&2QH#n>Z+H|2J9dY70s#^-w!%d@ znts8kL+)quNS%Mye#&oNutzZEW*WaZlk|1z^PHN-9Atf*PE4bH_Bx=z9MAn8W&^9%&qNgu}O`{rgi_PQ( z`&Xgt=%;qoeUrm>f_Z!%VrH+y2<5#rxj}y!Ih&?JQ)L%Vg>Lw#EV~0Oo?Ns;u{rzw6I-)jdRD8^OV8 z^GSE;Ifm3ox4D1BmMzWN8X6-~mDy=DuxTH6mJ``>e6)c;CD1DL})f)#-Y2%nM(9*;gbp)TEy z{B8Cfz?XQakYsYVp$}x}v^hBU{(aEZGk5X+Rl{c|iV80mC zLa`J1urlGI9Lu<(Mc!AlQDf)Ux_!WOVd3|BmyH-4!Bk&2df}&}^rSMbXmNg9I$Da( zv!Asd@Vk8h0WnZb35`QqmpT zw~};+j?k&6Na}T9^UK;duBoFL*pS0Cppq)F*BZ!5RL&I*U zi2e!oNlZaRIu*Cci6*bge;@g~{?2Ab`bAUm35J9R#i+5UZe-s{o?0^Gl|&zzYbrbd zJv~$Ns?pJ$4QJQu)0;kH7ogG+1WPs&~k&nYTy8-8Rylm^L zkLv_S%y<^wu}?Ct8&P`nDU|*Atxa0k!sXm^DEsLJ_>Xy=CRc{6MCu>Mqx{HQC_nvK zzd^)=Vi9@HyWkQ3peaHt({GxBPFst!J0{t6bnY6owGFtm_fcX&s6PGmkIXCaB~sYp zk^9;2NQ2DkrMg!L4w|@t)CGSB^DC~(dXsdA{$*|Ac0vAEZ$LIO4vHXpye`p*Cs^CRXx2{P|H$Yb`s5jM5z;_RnWQGda4PI^={U71fZ zG1Y&d$>n}CG4`p+sLB2qmB&9oLqUGO=}3K4q-#45s>J!|YH!Bbtt*A_xpg8!(x~u7 zbaERCHX(P%AK88un?aeZ)9aTaVNoaPH!khv4rfTcCYlaQ(N=Q+XSXd!OND(`UG#?B z9nX`G&=($I3mI3$q;dIMQx8I?y@=+rlO&&o#PT%5Xyk)0P?$D6k$T6&Ng73MQEmE_ zvmA(eaE%ZV_pKq^(&u&C>%T|Nrlq9%y*YQtpjwzGH!eeH+DQc7@wQq1Ed>=HviRs9 zQM7m64ckV5de_+-GZ4SD1IplKz1%_C*y3>V0Z_-_(v*9T7DC|6h}YD3lC+rTK-X@^ ziCs288b6oztU=w`?+`ZmRVYH{!LsR3Bec!gs64SA5OzCa2WMb0V(N=o` zO@;qO?S)KSKA(F7a@;?th47_6ZbS9yod~@9N%*9!g3#IO{Ts}`cwOg>8OX2|EtTcC zu#2>=$wBQULDfrQ#mKAXTMKPtEjlijprh?3w@g>j*`gs0+&56T|6S5>nhIs?47mD_ zCl)sZ=0P>6F@SRN5B0pXh5W;FYdf7rXIh{>*hT6$GpLcn(qmtl4hmv7(j$=iz{%xG zP}t5kHM&}>O!LdWW2Yl(7HwE{coICEp>1p@$E7~56*EN~!NVLJ!NVLJ!NVLJ!NVNp z1Ph&=dby9oPykTb2<~;~ zXb!^yMj><^1*G0JcP!^H^wC~dBEn SYP0$P0000#h? delta 2657 zcmV-n3ZC_}FzFPKBYz4oNkloFh3q0M zFesq&64WThn3$;G69TfjsAv=f2G9}pgSx99+!YO}2Uveik)GA5ewEg1Va|1@=x;Pyj3t}zC)T-c zzoz+u9TyK|)jteh(` z;D6}gLagCR0hn*76kN#wCv*`b8GyswI1s7kNaT!{fEXv;5ofK|nu3vU_1cRKLBd@TQ@Ei6F6QJ?HM!O!+{x(L<6rNAv)=55QOzlPWhqI{ zjSR5c$#aW1xy}c;$06La(Y*xlX>0w3EDGGn02k}7*%ZplRLFsw%E3MJO@BuPkU#Ja zcbp(_BL!RxGHHe;wff^+2G>u>ah(dq7O)#K0ekx={yBF*$P%aJSOMmjHHmAxvW0cp zt8@K;ETVH`1(=8Ie(Z;Hy+9V#xv>Mxz*+%0w;aeKJ2#eqVJL7nrpksp7|5bKS2)0a zId?FSYb0>4P=MLsl6(J^Q-5;@54jg=+fq2sO~Hz-hVXEO0L<$0j+BKdGX;Npqt{os zJmk~Y_Q1L83|RfW)5G^!;(u>i7{EI*HIqAp9`Cbzna*hHhI2Lm9I{{?%y{Hgdzxli z7Fd?00Ed;L$qk&zI`y$@{Dn;5j(iW`=!aXNV*G=kjb8%Qi`UtJMSq7ZT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah-w13P)xT`>~eFoJC!>{2X zL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw>F+gN+i+VD?gMXwcIhn8 zrz`>e>J^TI3E-MW>VM=sWZual)ns9B%8_$25BcpOz+KP;+J(1(UiAp*Q=dc!FQL}*R43bTaVm7wy#IrC-VD&k-4FWYMd;wg6!1z8a3SP;O>P#-$->_l zEAM2>hI~v3$Y(TlIdJE^0@|6AK_7#uc{~E1^f2gGJ^}i)rGJ>FDPRt4F~}m-WGQZK zw?8N6;NJH#XeW;Webf!0kG=!+v2#G5xX^L14Y#o*Tz9&z7NjOib92f(6aq==Ntoo74a!u6w~r!$mq|FDi7h6+6fTa4$$0Y>@Y*O}J#< z8ic&ucAQ^e_cw)#3uFTLcly|p7IMmPAXha6205mSA%EQja0eR?DV=N%;eS$2zHI*MpiObUuA|j7`m5?j`@^G6SO!-;(G1aCOu{sGli$ zGck~Eqx{gt?U$`9P3JRJO>}Ku- zRew#6AKb$jGi@lro`A;#P%m@cnyJP&(r%f}Zq^V3mIc=hnLfVXHRn=pj;2#4v8WiM zav|%So5|ksmkM-bV7H;F_%f>b72G`eFJ!d@wTC-#ALO^GRCtHl=K|Y}dX%fTm0A$N zzc4;N3AGsYM~OOND&T_#%8wZzWYfL@by`|620=mAU7(LZ-At!cdlWCvu@AK#bt~#< z9;~k^d5}}7VXmK@h?&@_rUHYJ9zD=M%4AFQ`}k8OC$9ssPq=LnkwKG P00000NkvXXu0mjfxH=k) diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c3568a7ed4eac6239f03f259ada8431a9d0e4b9e GIT binary patch literal 2380 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 SYP0$P0000#h? delta 2657 zcmV-n3ZC_}FzFPKBYz4oNkloFh3q0M zFesq&64WThn3$;G69TfjsAv=f2G9}pgSx99+!YO}2Uveik)GA5ewEg1Va|1@=x;Pyj3t}zC)T-c zzoz+u9TyK|)jteh(` z;D6}gLagCR0hn*76kN#wCv*`b8GyswI1s7kNaT!{fEXv;5ofK|nu3vU_1cRKLBd@TQ@Ei6F6QJ?HM!O!+{x(L<6rNAv)=55QOzlPWhqI{ zjSR5c$#aW1xy}c;$06La(Y*xlX>0w3EDGGn02k}7*%ZplRLFsw%E3MJO@BuPkU#Ja zcbp(_BL!RxGHHe;wff^+2G>u>ah(dq7O)#K0ekx={yBF*$P%aJSOMmjHHmAxvW0cp zt8@K;ETVH`1(=8Ie(Z;Hy+9V#xv>Mxz*+%0w;aeKJ2#eqVJL7nrpksp7|5bKS2)0a zId?FSYb0>4P=MLsl6(J^Q-5;@54jg=+fq2sO~Hz-hVXEO0L<$0j+BKdGX;Npqt{os zJmk~Y_Q1L83|RfW)5G^!;(u>i7{EI*HIqAp9`Cbzna*hHhI2Lm9I{{?%y{Hgdzxli z7Fd?00Ed;L$qk&zI`y$@{Dn;5j(iW`=!aXNV*G=kjb8%Qi`UtJMSq7ZT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah-w13P)xT`>~eFoJC!>{2X zL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw>F+gN+i+VD?gMXwcIhn8 zrz`>e>J^TI3E-MW>VM=sWZual)ns9B%8_$25BcpOz+KP;+J(1(UiAp*Q=dc!FQL}*R43bTaVm7wy#IrC-VD&k-4FWYMd;wg6!1z8a3SP;O>P#-$->_l zEAM2>hI~v3$Y(TlIdJE^0@|6AK_7#uc{~E1^f2gGJ^}i)rGJ>FDPRt4F~}m-WGQZK zw?8N6;NJH#XeW;Webf!0kG=!+v2#G5xX^L14Y#o*Tz9&z7NjOib92f(6aq==Ntoo74a!u6w~r!$mq|FDi7h6+6fTa4$$0Y>@Y*O}J#< z8ic&ucAQ^e_cw)#3uFTLcly|p7IMmPAXha6205mSA%EQja0eR?DV=N%;eS$2zHI*MpiObUuA|j7`m5?j`@^G6SO!-;(G1aCOu{sGli$ zGck~Eqx{gt?U$`9P3JRJO>}Ku- zRew#6AKb$jGi@lro`A;#P%m@cnyJP&(r%f}Zq^V3mIc=hnLfVXHRn=pj;2#4v8WiM zav|%So5|ksmkM-bV7H;F_%f>b72G`eFJ!d@wTC-#ALO^GRCtHl=K|Y}dX%fTm0A$N zzc4;N3AGsYM~OOND&T_#%8wZzWYfL@by`|620=mAU7(LZ-At!cdlWCvu@AK#bt~#< z9;~k^d5}}7VXmK@h?&@_rUHYJ9zD=M%4AFQ`}k8OC$9ssPq=LnkwKG P00000NkvXXu0mjfxH=k) diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..00104a42e5626cf611877302bab7a482140f8eb2 100644 GIT binary patch literal 9371 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..200ff50295530f8ed4abb8e69b09d8b84f0c02f5 GIT binary patch literal 3646 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 RXlnof002ovPDHLkV1h&RpFaQq delta 1874 zcmV-Y2d((S9^ej;BYy`cNklx~L`~4d z)Rspd&<9kFh{hn*KP1LP0~$;u(LfAup%fx&qLBcRHx$G|3q(bv@+b;o0*D|jwD-Q9 zuQR(l*ST}s+uPgQ-MeFwZ#GS?b332?&Tk$&_miXn3IGq)Ab;WSyQ!vAt)@Ccb&;xv z%AX@*_j-xyC{+_x1Jy90eS@gHl9`eOYAn?ns>{f~a)oLg)i}Mj8-?Z5uJ>q_5#bAD zs+e{qIS7a(wLvT!sO}RPqyuZB*5&w@L~|675r8qFZOn01hM)stdt z(}AUD*+MA1yMMAWR~H%&a`aj*kR~YHLIk%}CkzB^7}YeC>Z%YF3%$siy4gUWO|iV9 zyS{R3%u=2p$xI}(n6@d|Wn+c7k}2 z((AD!&VxpxR^A?&MN{;FY6cOn>|#gvx^pnz;el1jsvqQz}pGSF<`mq zEXRQ5sC4#BbwnB_4`c5bFE-Gb#JV3tox9fp-vVEN{(tOCpR zse`S+@)?%pz+zVJXSooTrNCUg`R6`hxwb{)D1R`!oJBH}D}dSIti0)xc5KlQ;k&Me z2>uPHr)yMQ5rWI~9($t>0^<$2oJD8x2jY(b@BSK5-ZeHH4q-;SalJr4Uv)5qxyQl^ zKr6bZWCj+~xn6>qN5aY*W~-eg!g}X;SotjbKlUcusA}8P7rC$h7*?ESRri+6cEyu7 zWPjzUS7|qw9as^i(e+yWM&5Yy?_fs@8h;Aox&})oF6feHdx&y#6|KggrRyvPD_!^2 zWf4|JL7&g++36T|jv*B^GqCDS!kUvMSQ$?%`k)a7T4g`bQq8k?qe61#uo|-n%aVy} zDyOB|R_2Xj$C20|!eLEyAuP+5M#)a&(0}Su>}T;t_0TyI3)n+9`|(su5H)S?gk|aC zJK1S$^ei(3izu+}-QvfnodFEr7Qo|sf`$eWJ7ShC+dG|f^kiM?ecBBp2AsuUJ+dQ! zhqedsFjcVuXm&d*>l=s{{6rb?j5v$K;z|Y0DOg$CqV8|;Jdm@J6^FLB5870RVSi=y zB?##U+(6Fi7nno`C<|#PVA%$Y z{}N-?(Gc$1%tr z4Pc}}hm~yY#fTOe!@v9s-ik$dX@ALH?I94Q-n;}RcAsCmWQ^Wv3|h(79tw+~Xv3fI zRWE{f+Db?hm*K^w`_(#S`=Qx-+$ov{v_4qp;j35(scH$l^-UN&qX|;^Qpcd#exS|> zw36>AtbIVy=YPOgHV@LIPvEUx1yAi~@YJorZ8O%Y(3aT`&5r3f6-*VjG1;+h4Tq418njAdPz!-tq zpPUVE>3kJZeKXbCeqnLh*?&D5Fvowz7S-k)Z70s-4mJwbt%Hw3@YJqO3G07OOBg*# zR)F2qStmOO?d(4o(m;x0Wlqr5?09S>x#%Qkt>?(&XjFRY}*L6BeQ3<6XEBh^S7>AbwGm@XP{R zkeEKj6@_o%oV?hDuUpUJ+r#JZO?!IUc;r0R?>mi)*ZpQ)#((dn=A#i+|E(0h@Z5l}YZL#eq00sELYLBA#NZ01}gr6>{OJDZ*4ElXLIz zghey84@Yi6Qy8!^TQ@Hv`Vy{v#0RPZg+>Hei&JH(<4#+s(~k?Gh~a3lkgC*^G94+s zzNW=AUQs^BwwPcH7PH1^@s67{VYS0017bNkluzhUxOa4_RogmtnQ8mA(`jegndve!ww+FO z#(o_g+ge-cxYRDLI6B>2svsbufGkQxP_~3E1ju)8(65Gj!j^k)K<~f5tM;7ao;SHq z&Uw%F9yf^eUc7>Q5fD8EKB0F)=^qDGh#nG2AjxqjmzDfigXV_IsJoI4V@W!UMMqG6 z?j%|*uD1ODadWi+BJFTf$}w>40|-of7~VmX(a|%KAP{n8Ak?~{Zc>~?@Cu-<}H4unrwg0Lxngj^Ed^BYO}Au#e81Vlc8>Vg#HroIAGegRiz zb{A1#y@7z3VTfJ$zmR*5;_RLhDB!1GiqVhELuuMt4 zXgG_;s!~|$t+qVxP$d)|did%_lNxF={B$#k_neGcSKJ83@x?y!*D#+xewDhqQHb^$g*`EimSHfAkKZV2Gxam-M)8|sR0-E z{|m+6e1wP@za+lhAHeuvEF?-q&)p46!vvIPp6qrx-9QwWki^V;4E|xO9OSm*YQ`(b zN_iEn%~q$%X>Mpn&dxV+C3_d*=A{t-YdGsQ65_wbFW81}3loVjO-_~90iwW!!apVn zAtV0==Fze-;rtg1ap}9goR(R2{sNA_I|0MiY=Mu4?e9qxgAlv$Pe|XmhSPFyLKK(~ zFvAgX$$w{_C_B^Ih|C@Lqx{4XUdnDV)#2n@b1`By5n1TZSo!{ukCCP{1%_ka@KL-d zFd+z;I3IG~F_at&Y08p$6W0w|EmmY~UV%|h4kpdz=ythMMBcXvWf^g#X*F|Qv?wsX zaZ`F=&|R-l^NLSAO?qGSk@#M#?b2oP0O;;nf!r_Gaao)wFh0?anogRZ zU{-o{;bv6kpK*ajZRGF$6Eu-4Y!l))6EfxrlDCda;fn&}li*0&R8SKx?Ek&sw%m-# zaM31mKi#8t=`wi)f`$x7Y33=eiV_9J7gD(dzTwkZ>Bf@%__Nmdx3drN7@F4ot>__jwmp`@Cj)@ph>*1+Ow!Fx#9wA=$I~j2e8ak z!z*Y2@zXe2m?#R2FMLDdSZPMX4=%98F-8M@DUi}XLKIkUMoPX`sk@$)URUP2p$Qsw zWlU|#tfWxcrF(0`P|i&eqQLk->CZec_HyR>tA)ZF(*ewQm!;kSxo5O}h9rQiB1D1l zf>q@pqe4(Kx`NqQMFeJ_<`wM2)$K)r@q$E7O|CZyzHO{?Bu(tJR=WK?Kol51(C1n_ zedMST*pkknXh6bQ>;X|={NP{-vXwL6hBK5ZKUP{@nUSm8ivr_=hB~8dr79%$n`u4# z2D->1$4Hg^DXCYvy1ghcK4`54S}X;SDeSk7c?Gh^#$1V4Pyi$nH7mWgjI*FAqQLmV zSd|UGAbWwSb+l#Eu0s_vl$zd9ah|IpM1k>zDfa{s*nGP*h4)ZWYxol%r*{lj`04Io zrCD)}*k|CX2vJ~sQB`ml1ID*cl|nOkGI@Y0t}uy3z>uk|w7Qa`;)27zKt*mk@x#g? zlWXnLLz0ql>3i1;OdUP|?y9k@^s1u6Toxk=j4xU(t)wz z{unCrbGa-^6d0deIkg87$)uTVwr?f_W7ohpd_8K4Toc+-f9JEHO~x0bzQuJ>qQLls z*(rVX$G;*t@eR9li9|t!_XbYBy-;wQG*OYz4rRxpu+-;F zv7CK%@O%s$_YsP}=hWxv5GH)?{CXXNqaT98+kUEu*>#k-@>^tl zI0Kcr=lCqWyO+lZRvI zL;uCO9kWoHc7pS=WlA{`A6gH!{t;^a#qVA~WmXpF-1F}6LkIJ2N|hg1ES*L5gdYJuifhg z54D1bOZX`Zky{&Y-x*M8{oNqfZbc0dy!1;4>l;TJp_O8*$RtF+e-wy#A)`fIfL5LOa#U) zaC8gd1f~iJ#(+E5K%1}(GI?l+uaz*z{YnNwtz)h^7&!h-n2l+;{NqMkO8*E=<#hsC zef#0=qr||84ZC^dR=-HE^a=w!}>-hi>vpgpPTUQ~)8I-4=ZMVA_N+h+Vj?(~St- zK_(9(HQL`0obYpGZe8HA2sO77A&DaqF=r!jUlO>!H9s{NvoCMZj5VZ5e2dgtUD@2w zecXMABWcxf6zp4!;%`%VDdSd$ITtc+@$aCG{~hyxd=$aGz@#cS3|+7R{!uHt@ak5y z$V$*)J36kC)TPXpEDy*$`oY6jM=DqLAptidlLsJT);@UnKaKOBvv*93IL1rskGMsf zp$eVV#dk37NEzvY)uOGpA55N4XD&}Ow@swGj~pY`?1Iwo-VR=6MQzzWTuJ{Jm3aqX zymXEFDk<^v)dORo9eN*v;+H}0>ByUuA?%KKAd$A>+|Kn*e}>xuRmdQWSbYdGMJIbG zEe2dW|1ru=e}(G86KFF1bgq$`hm>@{5)nLXHt9t&9k;M{@4ZGkW*51w!6FyD*`c`V z$`9khf#*@4`D3T|Y9&9I%KRMLmAm^*gil;RdN;3=FNJ*$Bl9B(9rF&Vi_&o=?RzIa z!L5&Kpccbc?d?!pmil}YpL`W1hdw18Dav74gyzOpT+2CSyWEtoK|lEsgp7HG2u;J> z0YyiCN#5JcoxnmSOhZuQ6Ap44QFQnz6dZaVt#o@kggHODATkkU3jf!H}2=r?u)+S~8$ zlR!Ea$>i6w-RZJ!MdB8(B`r)MHIHcybH7*&!|`u>eE+&DRpi=#a}qZ`SakC1kV|My zmkDQ6rW0{xI$g%iWbfJttHu}oquylY^&h=P6c~m6Nn@cI%nm@u(9)EPlbff(bfJjr zVx6zSG=pOh5KU{cfPw>$pe&PHaoynDhi}90nR!t9+n@jA>3DY;wT-w7oCn+O5T?VVo5DnpW)DS}jXC)7Uw5JLGQG3qB+d&g%oY;6eL#P} zSnxjao3=T9e@8HW*@f?3LEP+p?Q*2hM9d-r`v-4jcLxu(50V}^NW?YF_WwSi^NEAK z6c_ey70iZ^(eud9VsNgBWFqJV#w=!~w^)jik@71i?CKgyB|W&B zS~r6CvbzG~R1aUh_y5J!h6Dq~za*Hzq;66Sp7BR&-lgxKM|BQoC#%tLt_IWJvzmNg zN>+ODvDaX(s(0$%ouN%ggnsJ#)Vvl;Ew5#F1*x0~lk^dBs@W%+NfiSGvqPIO5i)rc zE4`uWDDu93kMH7pE-+@GEijH9Shl68#rvc=Om?Xq41q~B8(MK;-{V3I=k&aZ)I^LWz65*L-H`Q;ZCr#e6e>R?tWG6f zAAO*(H0OC-J(JE``CTD);qOUDqbpNo{G$n-%u1`TJd7*p&JP=Pfu7f3nh09tVlxbf zxr>tA9;sYLnw?J|M=UkpSn>&Sw!F<-`CUOjc_D&^zT{FHZr~ZNf!s5am0o&Muwk5@ z3(P-;{mU>K4x+BS(iwvsBKPtj&CWK`>`bTT8%uT~ebWk9xjRg=+vq1RfPTsc=nc!z z8Pq{ZpxIJWAlT}Yo;8uonKw#bc2DhE!5$85V#6%|NnEj+h-)@A-&nE-CpXOJh(?$$Ul7WKp4DJJq4DHTcCg^;oFAODht7~i&yg}0QS%zA zGI4tIgDw?U$msDHH01;ICUG$+{3y$5tVUQGtwNd5Gl6*pQI^hF%`jGEJ82J_h#FUaO@L**m79$yCF6xm`sYpM>aS=ESs~F9+ufiGVt)|(i$rAoj2zum>os23z>NC3QDdOg{do1o|VCAnccx%tt36#ovej+H>fIDhxCn4 zBJ$yv5jyx4L2c_rbX0>m7M{YlKP$~_y2yb&ZKy)}5vTq?tV2B8u)=Wce^7AnQ_jlk zF77_=7_s_G@;7aMkLh%5B|X|F(Ml?GQwI571`BLp@4>Oa{3E8Kj8a2rA|r?o#$HoY zU&+n6HwqsGhArC;nS<$+vW&kYXD8=pOLrM&WkSNT_o4KgM9nuFPmoT>O52KDkq(;3 z{$u`veq&x_qMh5NTj4{}*gi$8rGgWSl2)#VyDxkGj-kH(D`X#dnv-&R0uz)waphm( z8~SrSMSjgeG&s?#Rbeq4cA#oiEGyJ+ij0 z71*kuP>1?s*rVUT%{_*iUzYhNWPRK_)_nDHgclgIoOsys4;+fiShAZq_4G{&Lg4MI z!0?B*L*hVORRtfC9^;DwTh(U~USP2ce*>S;xzxOds&t&*ywtWO%@s%k@xfMAi@ePcJ5*X4RtWq)tZk}8pnzs$0ouZ%oID%A;w$_&tam{wA`1>fr2u!Vu zLhK@Dmp6MAtZfU`!DYm8=6E9D53d2Y2vphaQE>2alxO`{XtQo5_!F3I-PFSy;O;YunqO763)v~p z@m79ks6rx0&3fp1L_Rhp$9_u$_D_MWy5-h)VxOHx5(PEsH3BJd4-up z7`A*jsaXT5`DK~wNX<%LIU&+5_z{?X@=63n)2C5dEG5X;JReQvJ&2{r0aCde5mySS zSse|e?j(K}|B-=i6Sx;x$mq$?Pj%o|S?kHeOC~)s*X#t6y2(hhxD`I3w6F)vKx!)K zF}kj1y#?V`VA_Nv#3X-C{zW@{p$R!VlZn&Zd4y@ch+ViAetP=BO=ejhPH$U)R*Sfp zo7FG97@S5ATIk+K-akf=lU3QF0`Old^h3+~U6waXIj-nlB*xpW{%MS1znkw+GG( zOrcU?`04|YN$H#a$})b3^Pln;tF<%qQ_oGr27hgChu(mLfTO7t- zHcGkV+dIhE!^(`Vpr$ zFLT+_7Hz^Eh?%<+^bSW0iuXSV!w=#{4W8+_z=kY(p7hA*s}Ib^^EkC(I+{$b3C63| z4JJKCMqIRwBuumY0`d=iEv!*4!0P&CYdsU#z)@2XobW0&&x&ef?@vZ!H9wIKJ42~a zU7rF9qUKi@yn{0-u3L^RBrO)&U^YMJcRHZ^0#oZ^pr8E-{k_&YoZC4Ql|Q=9uhAyV zb{N-!2}+W-=~se=*^~+TJngA3uVyDoe94bcfrd&!W>UH*FjYtxsT~fI+QFZa%d9?F z3B&QD+?duw=*xnD#;PMO2}+_KNZU2#+%EX8($Z8yNtHn1qay<2^#Fz&bX{P~iE6fZ zSd`G^3}qQ_@p^PjS1}ulsOkCpUKBhi3DXe@jCz2TZmHzw{HFHQmFJ)>qM>~++9z}v zYKnT1z}!^|jQGXpaQC6_1ga`vh9iE>rC~j$uIvmo-CN5{ZVS6ZTsv$WBnoyI@vC`< z1S#KSs33mWB~q)~yA0ZxyK(6|K?c6NCa|GP*OMA-3N^2x?!QR?baAhlAU2ldli%zW z@|z8|OAku=8S?k@7sH>%fIDadyjGNF33uF}vE(THboK)C3BMn1UTe@?$NMwuTwwYs zj}n9EA(dL1@{ze|K3Z#f&jc|ORj}gxmk5Zmw^`{o5dksLxRxW#^5?KSXOgC94lCVK za}pJ~f;3Mys`65az!uu2$>jZ@oBAN~c5UIi_>Kh@GI}Zz*x#smOh~2lO_O0NxypxO zPH`peW0t@eKO}72(?nqG^Od-UIdna0HhFkf_6&j{P1sek*K)ohVrnLz-u_vK4u2KJ zsXK^Y%Il$Jjs+Gvb{eARFb8L{``N9{Rmk}8UQ`zr^JrVoDbM-_jWbS@W__4lx+Zct z`O)m)bybH-uS4RJeMDUBrP$`CEEImv??GYhF&eJGRP-Tfg;v<5GebF13tmOmCSD^( z(ghYWY7`L{<0sHVDxLXsE-G_R^J$nX)dQ@*iA0_!VD8vjwJ3iY8wY zbBe4tE6<7+Ts*#nJeS(#cq4YvS1?=dM$NfAPRdevyCLG< z=ZU~xX$#~^q3qNjP;uHddq0gOr6|jI4?#oQ*H#h?n)neKjgwJ+oR`zr?7s|!$_Mc? znS%u!#lw0Dc{@Ji!w}ACZm=LPr_f+C+~Qn#eDz_tDcEN$-9RqU6CdRna&c3x@zPeD{@_tG znd-Q?AqOy%{OOxkVZ`cw4$s|`dqyE@_6`i5aT%5Q+fjAlAZfi$!en3{w4n;o5HZC= zts4jbsA<>FCvVe~pMC|Ts$@6lCf$eNp$-DR*_ISD2MahK1K*XH3O;sRQ3ikMSlbidD3<I)~eX!MKK52zqqw3=Dg012kb>J6pW%P!9IN93A1I33DS#r8)J? z(wpVDeEdYWZrIylR#Tk**Hh>>d>dkB{T)(I`d)(W(M){QFHv;-&!nq=oP+xbL#w43 z=^IudVnzlAjQ=zEIPX%@HfF;p1$d$yukT9ZaLQ7LM>dFl;S7f8I_!M#Aze7zi zZ82Zpq^jT&PQ1I6^pamj*tlOHDB&UU+35>6yNPSUnD;gstLtDmvB!4Z&Quo_kn36G zeenX+gPES;U8I*diqvc|q`C{U4Q2d93#rF1qrNO3EtXQKLT8g!fVHb%6qpE`Mw10s z(vR4#8@MSYwhc9HClEKoY%~#{_NVn^gQhKmZW62KEDB7dYcw}lVKO)#u4=3cc#@udI4VA1X?m(VA`mc zG49vXV5xUasBw|Lg;cJ9chG2BmZK(82Bl^klpQVi5fSMe(FYUZ6-Hpp0)H0D6RBYzB~NklQEG_jup^)eW&WUIAp(iaBo#xi!V0Duo>!@LstO;|u#i;%% zpy^J-C4+Sfs(%4>MLKZyVj>w{7?m>>=W7y4S(mFkzT9E9#*Vla-hLJJJn9SSKqLI8 zhRPci<7*}=%*~>o6n}IlTx$jo=`vX4RNi+sQJ=1AJpngwaDGi$JXn#U| zU1p$|a1B9yAO&`6h5i8TKd928KqkRe$%7!I5Kg6biGQ_jL(Q@jG6}99rHmS={C6TC zV$g$@KqkR8S9%g^iF6Xc>gNSPCXFE~CD)=LPbKHFd-8%zf@>%$NX|u-#>tpQ=QP6L zLp7$ps8f`=s4`?SR%}+*4~*e^AQ$)AMrVsuU6e4My;)tql;D~}a8czr!gwfStCU*f z^qTzTgVtQ!#Y7G zxz}stUIm<1;oBQ^Sh2X{F4ibaOOx;5ZGSNK0maF^@(UtV$=p6DXLgRURwF95C=|U8?osGhgOED*b7k})mNly5A_UeT?Em267C0wEf~s zhRVZX_{qC%a3K_TL%SAPY^n^{3h2Cxkt#>Hs*l(!_MAUF6owxoT<3!EA;EKBAOhYhql0`2D*tbz3IvFD8DnhFq$^fe)_sRpV1MYz<>Q1;= z-Om79p7KR1x3|R>S38%?(gp_Dn*^9Q+hWwcfkt%0!wj(F)FLT!6=@!Jh5>eg0zPG~ zB2_B`>?#4495n!fp(KcrSO!>C>F~Owtv&sm|pjT;&K?lS|=p1h6my_Qdh_1YpyTdVjbrl5@Ee zFjnmd*{@Hu!vq^4Qw=V+JD1}btj$KqRLflD9&j$l#}uiM73)mWifzu6xjZ^(Ew+;t zV-(>OT-6?g%N3W3iUpZUaMgGeF2?~Y7Gx@BE-%963c#$+WL7%Y@z1F(Dgl^PPG+TZ zy>mI10BagsY;rE|16Jsq%zugreT4t}qX^fnJA*K&Ihed~O>ijySibGj3g=3~btwh| zb_L-U1nf4v9s1{B@}hDT!R39xa)r!_%#{k)&5c1QX$r#a95g#1QxPuL0+wwiv(&jR zbGQ(wI}k2*pUDo$(taG60?Z82o3I)9fZ088g&^~Va| z=G>KYWr9rJ=tppQ9I#Z#mLgYEKBw*qUbKk{i!m;dvONQ*$ovkngovijffZZ4A6K|CSZ2n)` z;JP^uik*Gp@?rGQ!;~zWeg)^_q@X)Yqk%rz7K8%ZOjtr zQNIDSNe%G*C2zvjus>n5b?ec|WXRfmoz1I8@1S9PUeeikws~j5?psv0r^mTZ?5Jd-It!tfPfiG_p$AY*Vfak%FG4z#;wLtw&E&?}w+ zeKG^=#jF7HQzr8rV0mY<1YAJ_uGz~$E13p?F^fPSzXSn$8UcI$8er9{5w5iv0qf8% z70zV71b-}N$Ry|LJ!2VY-x>#j(gmQG{Q~qKEC#)t0rni|l`9aimpEYS(t_0qvI=#b z%(sAbfGjG_$(k}`E(X_)-vj+Sb3h+?KLWN8^l`rged00$Fm@JMvo!woB2UmkOxEA!`_kuq95p=I74S%o_jD~1Tm0s5&<9QdZBP|xBYuitJ!Q1Q=?K*HSMq`?ZM#$`lM!I)oNPx3 z2JMSL@4Cg<7Ds~q-FrbB`?wM08BjAe8*o_wR@yn40wW9p%ruk55waizYL`P`=xigr zGk=)sw@7Za-g3B7GubEwG8qFbLTJg5#S@<<6>JT{-H*PCZn7GB&e~!ueivhhqC@7v zcF6#1C9F&!!wN>?F!nb)aG_sLEVvzDnPoCB&&e2Im-v19%vLkV+M)Apw>JWXlZ5dO8W2cQTncxPJ=_us!1aB&4!*vYF07Hp&}LCRlop0oK4D zL@ISz{2_BPlezc;xj2|I23RlDNpi9L zgTG_#(w%cMaS)%N`e>~1&a3<{Xy}>?WbF>OOLuO+j&hc^YohQ$4F&ze+hwnrn}4AD zjE&I4Cb8%G^6X8ZOOL8;zNr7wJgh*-#;;5)wl>LTRjvW8 zYy}KlxDC#J_C?~j9AZp7YY=sVfU7&d-I78eRgRD?*mxM~R_uitEBC?l7wuCWYF5L3 znEcc(XlVYIldUo$w@19~X8d717=KPdKhGaq^8D2C#01&A*qs2sJwRD3f5@V-xZ`pV zb`kFX&P+=%r6sM*xE(`)Q5EQ3H8N8&WWvSv5M)$&!u2lWsDpc%xY$4*)}nMqNtGjD zrKav>0@-ppqom5=%#qcGjBxS4)OkSr66&ASDyh1f((v2UsNTFi>RP6fTz_m3DnzZ4 zD&2`QXCu~SYs>)I9LWX=GAg;+`Rzj;W?tDAT$}Jeneq*(s00fy=LMGuWUC1>suTvc z3P!rjU0sEKet#{sOW$WMamKin2l_zXaHWClS?S5>nx((a7R7q6lDH@gt~8L%mu!;e zWa?K$GL?nms*h!GrO9L?P=6no&`qVLYn?`o6BCA_z-0niZz=qPG!vonK3MW_o$V96 zzM!+kJRs{P-5-rQVse0VBH*n6A58)4uc&gfHMa{gIhV2fGf{st>E8sKyP-$8 zzp~wJX^A*@DI&-&Blxm>>9MT3^@I z71VyzBGm1vYw4(KWw9G0kn;5#P*YIPpqjw=kG}MK$?Pk(Y2g(AVSf%)g}O0y!)YU~viV-2LyvJ@;Xz z&s5jcbaj7SXKHGqHPsa`P)Si?U|=wm6am`Mw&K4784-GRCsaL!fuTuJ0!Zt6!=B}# zd`t6q8n+pv zto+lZD^p@TO)hx2a$2zIvIqc7YZLN>VAHo=>oIMJ&o4-O^TF#ew|9VK{+5@O#C2!j zR{aNDJtT<{YWR`(P-jJ!E+l&CT`GhuI+!G8#cB%7+{o@*bT)#~v0J>EjDX09)NmVn zymg>Fz6=@l4q`+m6FmLj`0b%1P2YHWue}WGB*PbJr2umHa9`{jE#|%K*nUA+M>V-h z$!-)6;S(*;4f5>DeH8r+YjWSOqNvwM(Mb!G6tnp$%aaR=EuPW1GSYuOyadohUn|r2 z|3wGH`4IurlLxi;<`g#L?J2XPv+3$fE}Qfe7oB$-x}1`Sm_7GcNKzo((tvCH#IkCf zv`bq5!37tSH9o%OEN`}FB6`;tl6dvlAwNl4y34HYcRB@LeKM?)Wgu=m!R;R6r)%aN zJTO)}kgF>cZ|nlLn|15JxAe`GD&Xnf;*0v#=9CH;pS4<=lzw&%wRUGDpI21hwCVw! zK$xne_0nLKZR%Q<(vD{$QH}m}WsNu~SLqzy^VtUL6M9{{Gb`|Wc@k-JQDXf7J9Hd4 z@dczM5T}p|B?LlVhYi;(Yj3DB^}SS~+WA2;1pN4PSva&5p{(`pc zhm4D2hu=JaQg*=MYHyNjr=+8i#w#(8=6XoMcQwF|_IJxWSg0AgfA_IFC-0&o?wz%` z!(@!b$8+2(6At!vjI6JfQ-K&Py_3TR-9UJKqPRF*2y5b=YiP zLD&V2gh^F4i#ckNG#7*8HdWOJO9_Nc2+tW7)IM+8hjf%><2%8J271MB4*_3TSljvJ za4WtLXWqf=RrfdBp4C>kx(MS~QM3(oDJtZ^J+e~CPME`O6S#NUBPzgvd5q-FMel*O z5%lWZg-g{q**8Lt*@LFT^X$CyL#bSxW^J%YpDoOmbhs~d6J3<DGFe8jEuyOQAfa($jctKj~mv)X$K%Mp`4#LNfh+?9COQ)UKN)tGSQ zfFZ7SFjLfe2}cYzwD&d~GSqyOKs7LD{WGi##>b7HA?oQ+;$z0leKSS5xN{$^5?3L) zOMarhSs!OwyG8gT2h~a`975SM*2s9SjrXaPV9KUAQlGM{Fsy*krH;Nn z9>5k)xC^)~@(?pv5S@X5WS%nXz&HE}q2HE;Ux#R+eh)Do6J~c}E|EXRc^UZ1-Ud$t za+k`nrY-OHt6d(5=@ifON32|-iUX{3XsG*|8P8|6jPshF@-VT!<-`84wHVJucb)wV zYGi!MxChH2UR?a3JzwC0_9Nc=$W3qrZ#!}^PDSFphscx~y(?CO4Ca816? zOADL7A9%a-1L&f4guWdJGM`SMiT#<^J3Q0zUFfA0Od4V)zj3lyKNj(BEve_Ky`3aJ zzb8}59gyxNto>)%jc7)~x!y@}Rzu~R3ROk7?z6n9pc)R*pza2(xLLKvrVKITub|z) zQN`y6EH-{gvdug-2T?Od>oAFs9#+JO-Eu>xQ_w&D=8pe!Lx%`}2HHc)sy?@QkEQ`x zOX=Am05}`Rwnv>6|L5_rE{f1his#kUxV?rUDxZk+fk^ABrjMT#m2}(J@OARMK~L!X zB9uf|iwA}|+Yn&^dH6%{Mt7F(bHW>ckiA5HQ#mbhd-;T>BYbiY1+}R3`cJ$LObcI_A+8thpcl9*(r-+v$q&*{l_d&|`Qf98fr`dK{ zL2|!XQ7Kmj*zlX zVV?z#b}@fAS>ug9&NKtt_tkJHpJ~1MYU6#o`U`Xf=0AQW1<#|x4~aoi2y<@~bO{1N zt{)LTd|8REFbbV(ym2C_J!mbdyTsO$g9dN7;T+@s%!+eHkjU2L`J_d@Vtxyb-=xmG znHA`)LqRM}>LqWo@XB5MWKW7r-61f063pNl6I`B6x|HT0wQZvpn8`!1p9tayX3Us8 zA37$6X&AzQ_FkK9At`|+=g1ZO9rWsrF22uX$O+jBOO+l&&;j)B4Uc+mJ69-(8cnRQJ>tn)6PQVAyYiCZE}FFw3> zAF^`rKtw83*l~bh{BzUN=^(Uj`d!o`^qa(?Q1D?i%zS(789VLLB++{2%&{W57g+4F zgOIK-e6tg+>FafC#7YB?S=@Nsb%34wlHk^pngs(dCjsfIEWyP{Uu)3aOFp50eEr>5 z14y_;r9!Xu`atr{Pyt@)%;sV`di?Ve`5Rhuf6+{=ibH}`W+J6b&ayDWJhOUzpHy6c z10#Mmy*gUPb~g0`iM0r4X~V55KVpKu5=U$PZ}GE5W!J+dzD&$?uNdBcJ%LICY1jy; z9`s=ATG^TT6a3N@-Bg@)_aeuXqz43zTjI)BBqnM-9gwQ62|W#ug+vKG>>II7<=gBBG;DUEX<_hx;77{)xK4eznm0H2P7-j*H*ZR>k$;526X`-6Ms8;- z26ZG;II`LyX<7lq45rF1syQvuQKErw0Cq^v}*f39RQ258U4#yw8rGQ3Jy z9G?fBTo_Xt#Y-xKi{#4lsfjtyI7jn=L;+^R7TG=jd&{8Jw1Qec;S%Lq(9>@C3kgSm zlnm==-<~ZpsW{ma?51A*}WLvZgl4H7W3>y=AiT? zNh9lya=pgMzw@GHkW5fcPVSk$;C@Op*Xm-x`}EwiUrCOFDyzy@T+xl>cuCI@yYo30 zn2xUGwng_EC+VU;Q@qI%F z!MK%#TuzWhVxi;u!&E17qOpU|a&H=rnB}>lB;yy|IG&<{AoX~oa4oc^?W%$WS#>f} z*49GE*hjv!Kr|g&eslG*6}X;}9WL~Os6taOnf;9o=0Gf-FZ!s;mvUb(ZVwm~zlB7~ z1n*4|Sp0P{<^&3s6oq6ft)aVp6?pWYoOg}Z(3(iib6(XX23MF!Eg0^(b*=29cpC8Q zlWDl=xM6l%+a?Y;)I6Xw_UOawpn!rF>YBfbY6iX}U9+s;ARa|+g;b(kNYyEsJfM-_ z92y82cVO{9K0iO8(sMAp^%E6gohW5uW>){+eu$83aL1F31_s!Rd_C<-a1KcIPdJLo zeUQLEZYXeb-(K=cEa`5~1G&mi|00T*Ln2wENRUqpXu`G>m2~})yC``&vIaLEm48Ew zSk|K&|Hl@{j4cY{S7ofD0Yg@Ik3Yq5Te2XAiElaPx1#wlZMGmU`}Lk&Uu(QK#5d;- znvjEtY$-xDjT`Y=+Gi%h3|;N$LU6bt1t!NV&268-V;v}!tQOYbuIcrJff~ViUA-_G zohlc9V1^jW1w8FGl9Gfk(E{$&gF-m1fH`}nhm751N-tgD?R6=0>wRY~VJZQ`A3e|R zX{Q1=oAubj?-WN3Z4?S`6YiOlUlS+eb+(+ttq;k==mS)Z5*8RhePeP$|898}bT9Wb zUs?K~iNIe9`%Hy>i$b@n$VaBFpTVqnt3QNa&A~g87O;-l8=oUWS)FMHYRqc8>hNnf zU=${$!pgh$Q$Fg2(=xfzRs)4lLPt?4_ezkXC=k*=M|Ob8n^DOZe7}q|LD!znk(8ie z`w(KFm6|hJhH@IsEAkp>YtL>6`suw(VX-%o$HfT*PHMx)_Ym1-omhqRW&SHBv<5={ z%qfU(KE~FNKK@uxyg$gKZhasQ#m=3=7oLd-X<3YN%tcKN$+I#f!a*xYB5AfgNa%{G zmVJr)epZXA3woBIU3lA1frv*jBBj1kdqT_snHc~VH*~3&GyA01q-g85gb}Hm)j#(XkIoi%d0T0>u>8d4s!W<>-SM*l5S}toQQt(qD!&Y_^!2iBCwUj z2lL}Uhx$sDU8zMFsG(&)y>uKMb_gtjOo?A(^4t9p66y~e_oqRwc5t8~tlm_C+P&UD zc>|q-Hi}!cdMWl42uSWJBh+>=XS%|tv4j(#o~ab3#7@Z7Vq}DV-##ehEAR?MC(OJ6 zNUGkzdLHZ6SNV0X+arF!q|*i7`riNO?%FSOT_ZaAT2Q8lawM~YCy;=%^@h-Vf*p`c zRYGJi>dnApNqF|!g!Ik<==*U0lq(&5!&zRuUC^Cyy3MhpV;nRR$YcH#-qBL|aA$7h zaD)-;>RMXxh!9pu(m5F09FnGIs^=h-{;JV4?OG36I&3ce+MD&U4B_AoDDdtov9$}<$rSf{E2DpAn^a+;| z43e;sGk>JaXLkkX3%$x5GTNS?wsqY8-NYs)id~IU+hcqp7C)=q7y9+$Wy5VC+*T&2 zsb;m%RiEdlE*Bg6#+K1?E;Jh<MZmoW$}kBE+XOM`KcXCBq~#1G3Vpd0Fqo!-{KKa?`e`z&sEd?;&I2MFUmI?Qcg! z$Vy+)eL5u*zZ>G*^g@;p7ZQbXj@56Tvo^T>XC~(qW~@}}#qUUQAVBqrb1WRZ1yj{W z7}eC%Gj;_RlgHY<*A5s?jpNk;xEE5UfXv||lg#|~sD;RYtcLFNSIdFbEVQx6dvbFT zeveNLcL*z!XPhHxx`2cVh>zg`I`e6(_FjGdDgH+}`;z9_vpB1Qg5itq2k>Oi=u$7zESRYJR| z?I(YfryxXbgQd- zcC$`r6l|oJ-$sDCj2%Hv!L-3m_DNXs((X3_CWHFjN*)EzeFkck(n;x5ptL>ls4gnY zop|&@p21&^SPZe(CF1sNUM9XeG~7JRJBgSD=Z7^3Z-SzrvMX|jm4d>B4qu}~*6+OM z%jjv7smWOvQbft)nH6SR1)6CsOSQmN8MUyim&=1vw1F8u7qAmV(c{g-Ns&5K>GY)?dq5ip&pE`ZN59VeBt=t6AK$T7{&x z7f(L^)d&8#;3!u?I-wosxFcwuAI(*f(qFVUwt^9sSY8wxHF7EZ4r^hz?%sLEccrH; zr;{fHwvVic1MJZstEj$jt~nBn8OznaMVX)9qRM}9JsucL%56sjE=#Su`x#(h)~SZJ z=WgvbssfC2;>NN>=V?l?u+>qT+-?u(XTKY!BQwtACtPXgu3i<|NZ4%f(?n(8@}KgQ zZ^(YeugPN}^{f97hEq{dzaTtbH^)V_FRpik%M$PsqVOYg9ze!*dhXcp2O7;OETq0P zGl!zHVf}Mh`xMUwj?2Fj5WAhy;esqM2(?1wDA~>AOL$F|&N{bkE8b~^$pM*Pd9|{d z@~kK8d>@Fc_rkX5yoY4tj+Wy3`#;4hzQ-$+5GVc6EsfYx?NJ;g0Sal}O@E-Bs`qI* z5&X~#<|{9yG5gR0n_>E#EeDaP5D%46_QKelMUDY)p+?j*1=>AIo|pECV%MLKS37j9hB`>-pI=gM>8 zZRcD|YnV7*dO{Pv1cAk*`^79i76jh1ka86VAtI4z?umshIQQ&KMf4QL63cf`>H;v! zEtl2{G8nSpe3Tkc1;OsV?PK3Ir?rffGXwFVjUnLg>}2Il>Zzvz1!f(&Mh9i2PwS~5 zh9H<+!kQZgA~xc#GpN<$sPD1GjQE{E1; zh)3d2Bd5T*!y84TOMZO2^4nJd{O?<#9sFxu>kK>4*E+;_^5{9;iEjQuEh7bXRLKI` zn367FdI+)`9+Uws0aA6b=!tzYpJrt+?kXPRCp3)i^hYL6lm5nFd7Sd%%@}sZi0`QhAMvf!f(?~PG`ch9A8FUO~H%GJZ34u0^UOFnGe|E{7X01cBP z5R)Q>D||%URa?O)l_w(w;>u#49|MZjYE3QJMi9ply++~r;upic;lw&p#D6_Uld_H2 z>-rb(pi($-kTb+*&(Pi|y0}JfgC&$*W<(XBc#O;S6aic+F`2gD`+WBff0T}u+D3Rs zt8yRw7Q2`UBzpmGny5MpoJswY9BvdIfL0{beDS6R9H6|~RcKoW8x}hAcYQd-q6VsN4U-THo*t}9-q_Ebu`^gmNry3~tV-sslITo$&M*wTa3;3? z0t-HnM&JhsX0Ec`)RFK%DH@$UWc5Vr5K$hZH-4Clgl}wHrU|^opU+!sUC9j(<=d#k zG^D7Mps$hTl2xV0&xX%VQ*K^by0lZ#F~m6o86tx&*%FSrg*;5*lDkZZ_9k2+$Q^|` z-Z(NRW4<=Vsa0m~vmc;slgxQUrlCJwp3Lhu8DMuZAtnZXa1Yo$iSa6ow|4#u`6+hA zxlGX6_34Jx1#Zb#qdD8#5yOvB{a9?8AMH)HBUAN_as2*eiFOJ9)NGP##kO*)1c&jc zd}x+-x`PXR!;Kjt;UM9-{)qR|sao1$#*QH=z3U~LfzOU;$eVY;+`k#^wwk8`L(mip za9jJsWW=0cD6h(wb~YR|H2UqF417TgSAJkxYdK2i=3E4c+U40S!9Y6SsT^JtGgWtA zA#w`mZuub;JV!>=Uv(iMWI&UD_%#;??_A!6w#iG-{>+N}+imHgp6*ORp`C}F$&!ao zj3i>BVblPd)#$fx*m-X-{<4QybIbU3fSi_aJwFa@F9$lD1J*;4vvTdNpkTVu5}wGm z>79-L(BUoqSOb5pwMovyQvm1p<6-0FtNpR5cpKchiJmnkw9+9fHzV?e2dE*LISPhhmElA{}#pS7NZ4?H_!bV|?wst~=THMpbqA=8m@4d%csYvI;-GWByG z!ohN_o)besfIS8Yaia@DLXE!SlmF@MOZ@HvHfWGc)0dGK0)?9{aN|NLo<4y?dp<#q zm^)SkcKb;}F2M&$*@HLcci>nVN=EE;#>S3khmvVX2^_=L-}o4+>tB2^Ix}yVbcn3OQx3e@^#I3niOiIY z)O%YRwQAfVIz3rtvZ&%&V_8u_^ETt*H4-yRhAMFr3x-mIXC zmcnTEY3^U-Ixce0R1qu|xu?*j96NFoj>vR@r=ODPo2x1%=O-bn862EOd$h97i z>^mhJ)BTx`?50$JM!*ZXT4eenib4mmN)-tz3Vh||$?6wo9OvU)<0L=OYPJ<&al8L{ zuZjt+iEa;lN5U2j1rEq>@h2y9((RW7bwvF2B)%Oc({ghsVk3C8Z~%)uLo1mIJ!8L9 zI0oa9Zab% z7B&*4d*`6_3oG@>6lwWoT=$mpQ1=CA1rW^%9ha6)qchcULPF5Lj%O3qZYmabkK*Qn z18Z_Zo}l&MCL{^^*NOVMc}M`CCAUdcP5)+Z8IAANH)4feDV8>ux)?LN0XCt$?$jSL za%!<$dHFl2vl9 z|C?sj>UpLM+sIVv8Jm?U!nE!r{^%NGo-SiELy(?w;(@>8!PG)IcPLYYL8@qnCh6`p zR`xl$lJtuFNHagU>~m%wK*qGGd1pxP0xy|kv@eWooX7|9C9+hyjvQ4!1JJGTa2cY9 z>bQal%%h#o7AhW(j&A)Zs(x_pX@svIO1Qo)bQMmi+A}9z>bIv-EvjsP*6@`~iRztA zUzK6+l`WV9{1H9tjbTGd7q`j+|T$b@55mXUG*kR($DoQ4gXfZ5?% zL9dQ7PaCZx)2s*;v8M6$jw%VRuvdN2+38CZWny1cRtlsl+0_KtW)EU14Ei(F!UtWuj4IK+3{sK@>rh zs1Z;=(DD&U6+tlyL?UnHVN^&g6QhFi2#HS+*qz;(>63G(`|jRtW|nz$Pv7qTovP!^ zP_jES{mr@O-02w%!^a?^1ZP!_KmQiz0L~jZ=W@Qt`8wzOoclQsAS<5YdH;a(4bGLE zk8s}1If(PSIgVi!XE!5kA?~z*sobvNyohr;=Q_@h2@$6Flyej3J)D-6YfheRGl`HEcPk|~huT_2-U?PfL=4BPV)f1o!%rQ!NMt_MYw-5bUSwQ9Z&zC>u zOrl~UJglJNa%f50Ok}?WB{on`Ci`p^Y!xBA?m@rcJXLxtrE0FhRF3d*ir>yzO|BD$ z3V}HpFcCh6bTzY}Nt_(W%QYd3NG)jJ4<`F<1Od) zfQblTdC&h2lCz`>y?>|9o2CdvC8qZeIZt%jN;B7Hdn2l*k4M4MFEtq`q_#5?}c$b$pf_3y{Y!cRDafZBEj-*OD|gz#PBDeu3QoueOesLzB+O zxjf2wvf6Wwz>@AiOo2mO4=TkAV+g~%_n&R;)l#!cBxjuoD$aS-`IIJv7cdX%2{WT7 zOm%5rs(wqyPE^k5SIpUZ!&Lq4<~%{*>_Hu$2|~Xa;iX*tz8~G6O3uFOS?+)tWtdi| zV2b#;zRN!m@H&jd=!$7YY6_}|=!IU@=SjvGDFtL;aCtw06U;-v^0%k0FOyESt z1Wv$={b_H&8FiRV?MrzoHWd>%v6KTRU;-v^Miiz+@q`(BoT!+<37CKhoKb)|8!+RG z6BQFU^@fRW;s8!mOf2QViKQGk0TVER6EG1`#;Nm39Do^PoT!+<37AD!%oJe86(=et zZ~|sLzU>V-qYiU6V8$0GmU7_K8|Fd0B?+9Un1BhKAz#V~Fk^`mJtlCX#{^8^M8!me z8Yg;8-~>!e<-iG;h*0B1kBKm}hItVGY6WnjVpgnTTAC$rqQ^v)4KvOtpY|sIj@WYg zyw##ZZ5AC2IKNC;^hwg9BPk0wLStlmBr;E|$5GoAo$&Ui_;S9WY62n3)i49|T%C#i017z3J=$RF|KyZWnci*@lW4 z=AKhNN6+m`Q!V3Ye68|8y@%=am>YD0nG99M)NWc20%)gwO!96j7muR}Fr&54SxKP2 zP30S~lt=a*qDlbu3+Av57=9v&vr<6g0&`!8E2fq>I|EJGKs}t|{h7+KT@)LfIV-3K zK)r_fr2?}FFyn*MYoLC>oV-J~eavL2ho4a4^r{E-8m2hi>~hA?_vIG4a*KT;2eyl1 zh_hUvUJpNCFwBvRq5BI*srSle>c6%n`#VNsyC|MGa{(P&08p=C9+WUw9Hl<1o9T4M zdD=_C0F7#o8A_bRR?sFNmU0R6tW`ElnF8p53IdHo#S9(JoZCz}fHwJ6F<&?qrpVqE zte|m%89JQD+XwaPU#%#lVs-@-OL);|MdfINd6!XwP2h(eyafTUsoRkA%&@fe?9m@jw-v(yTTiV2(*fthQH9}SqmsRPVnwwbV$1E(_lkmo&S zF-truCU914_$jpqjr(>Ha4HkM4YMT>m~NosUu&UZ>zirfHo%N6PPs9^_o$WqPA0#5 z%tG>qFCL+b*0s?sZ;Sht0nE7Kl>OVXy=gjWxxK;OJ3yGd7-pZf7JYNcZo2*1SF`u6 zHJyRRxGw9mDlOiXqVMsNe#WX`fC`vrtjSQ%KmLcl(lC>ZOQzG^%iql2w-f_K@r?OE zwCICifM#L-HJyc7Gm>Ern?+Sk3&|Khmu4(~3qa$(m6Ub^U0E5RHq49za|XklN#?kP zl;EstdW?(_4D>kwjWy2f!LM)y?F94kyU3`W!6+AyId-89v}sXJpuic^NLL7GJItl~ zsiuB98AI-(#Mnm|=A-R6&2fwJ0JVSY#Q>&3$zFh|@;#%0qeF=j5Ajq@4i0tIIW z&}sk$&fGwoJpe&u-JeGLi^r?dO`m=y(QO{@h zQqAC7$rvz&5+mo3IqE?h=a~6m>%r5Quapvzq;{y~p zJpyXOBgD9VrW7@#p6l7O?o3feml(DtSL>D^R) zZUY%T2b0-vBAFN7VB;M88!~HuOXi4KcI6aRQ&h|XQ0A?m%j2=l1f0cGP}h(oVfJ`N zz#PpmFC*ieab)zJK<4?^k=g%OjPnkANzbAbmGZHoVRk*mTfm75s_cWVa`l*f$B@xu z5E*?&@seIo#*Y~1rBm!7sF9~~u6Wrj5oICUOuz}CS)jdNIznfzCA(stJ(7$c^e5wN z?lt>eYgbA!kvAR7zYSD&*r1$b|(@;9dcZ^67R0 zXAXJKa|5Sdmj!g578Nwt6d$sXuc&MWezA0Whd`94$h{{?1IwXP4)Tx4obDK%xoFZ_Z zjjHJ_P@R_e5blG@yEjnaJb`l;s%Lb2&=8$&Ct-fV`E^4CUs)=jTk!I}2d&n!f@)bm z@ z_4Dc86+3l2*p|~;o-Sb~oXb_RuLmoifDU^&Te$*FevycC0*nE3Xws8gsWp|Rj2>SM zns)qcYj?^2sd8?N!_w~4v+f-HCF|a$TNZDoNl$I1Uq87euoNgKb6&r26TNrfkUa@o zfdiFA@p{K&mH3b8i!lcoz)V{n8Q@g(vR4ns4r6w;K z>1~ecQR0-<^J|Ndg5fvVUM9g;lbu-){#ghGw(fg>L zh)T5Ljb%lWE;V9L!;Cqk>AV1(rULYF07ZBJbGb9qbSoLAd;in9{)95YqX$J43-dY7YU*k~vrM25 zxh5_IqO0LYZW%oxQ5HOzmk4x{atE*vipUk}sh88$b2tn?!ujEHn`tQLe&vo}nMb&{ zio`xzZ&GG6&ZyN3jnaQy#iVqXE9VT(3tWY$n-)uWDQ|tc{`?fq2F`oQ{;d3aWPg4Hp-(iE{ry>MIPWL> iW8CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Smoke Cess App + ZI SmokeFree CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - smoke_cess_app + ZI SmokeFree CFBundlePackageType APPL CFBundleShortVersionString diff --git a/pubspec.lock b/pubspec.lock index cc89bd1..4caa822 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + sha256: d6347d54a2d8028e0437e3c099f66fdb8ae02c4720c1e7534c9f24c10351f85d + url: "https://pub.dev" + source: hosted + version: "3.3.6" args: dependency: transitive description: @@ -97,6 +105,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c" + url: "https://pub.dev" + source: hosted + version: "0.3.5" clock: dependency: transitive description: @@ -113,6 +137,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" crypto: dependency: transitive description: @@ -166,6 +198,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_launcher_icons: + dependency: "direct dev" + description: + name: flutter_launcher_icons + sha256: "02dcaf49d405f652b7160e882bacfc02cb497041bb2eab2a49b1c393cf9aac12" + url: "https://pub.dev" + source: hosted + version: "0.12.0" flutter_lints: dependency: "direct dev" description: @@ -232,6 +272,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image: + dependency: transitive + description: + name: image + sha256: "483a389d6ccb292b570c31b3a193779b1b0178e7eb571986d9a49904b6861227" + url: "https://pub.dev" + source: hosted + version: "4.0.15" intl: dependency: transitive description: @@ -248,6 +296,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.5" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 + url: "https://pub.dev" + source: hosted + version: "4.8.0" lints: dependency: transitive description: @@ -376,6 +432,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 + url: "https://pub.dev" + source: hosted + version: "3.6.2" process: dependency: transitive description: @@ -605,6 +669,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.2.2" + yaml: + dependency: transitive + description: + name: yaml + sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + url: "https://pub.dev" + source: hosted + version: "3.1.1" sdks: dart: ">=2.18.2 <3.0.0" flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 0c85cc8..690527f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,6 +29,11 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 + flutter_launcher_icons: ^0.12.0 +flutter_icons: + android: 'launcher_icon' + ios: true + image_path: 'assets/ZI_logo.png' flutter: uses-material-design: true From 4e6f5e2d8cc1fd291f02df83fad8852ff99afc2c Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Sat, 4 Mar 2023 18:02:27 +0100 Subject: [PATCH 54/54] Enums instead of Strings --- lib/providers/input_provider.dart | 21 ++++++++----- lib/providers/workout_provider.dart | 44 +++++++++++++++++---------- lib/widgets/sleep_form.dart | 13 ++++---- lib/widgets/timepicker.dart | 2 +- lib/widgets/workout_timer_widget.dart | 2 +- 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart index 3bd473f..b8aed63 100644 --- a/lib/providers/input_provider.dart +++ b/lib/providers/input_provider.dart @@ -4,12 +4,17 @@ import 'package:smoke_cess_app/models/relapse.dart'; import 'package:smoke_cess_app/models/sleep.dart'; import '../globals.dart' as globals; +enum SleepTimes { + wokeUpAt, + sleptAt, +} + class InputProvider extends ChangeNotifier { double _sliderValue = 50; final TextEditingController _textController = TextEditingController(text: ''); - final Map _times = { - 'wokeUpAt': const TimeOfDay(hour: 8, minute: 0), - 'sleptAt': const TimeOfDay(hour: 22, minute: 0), + final Map _times = { + SleepTimes.wokeUpAt: const TimeOfDay(hour: 8, minute: 0), + SleepTimes.sleptAt: const TimeOfDay(hour: 22, minute: 0), }; String relapseCategory = ''; @@ -21,11 +26,11 @@ class InputProvider extends ChangeNotifier { notifyListeners(); } - TimeOfDay getTimeEntry(String key) { + TimeOfDay getTimeEntry(SleepTimes key) { return _times[key] ?? const TimeOfDay(hour: 12, minute: 0); } - void setTime(String key, TimeOfDay time) { + void setTime(SleepTimes key, TimeOfDay time) { _times[key] = time; notifyListeners(); } @@ -33,8 +38,8 @@ class InputProvider extends ChangeNotifier { void _resetFields() { _sliderValue = 50; _textController.text = ''; - setTime('wokeUpAt', const TimeOfDay(hour: 8, minute: 0)); - setTime('sleptAt', const TimeOfDay(hour: 22, minute: 0)); + setTime(SleepTimes.wokeUpAt, const TimeOfDay(hour: 8, minute: 0)); + setTime(SleepTimes.sleptAt, const TimeOfDay(hour: 22, minute: 0)); notifyListeners(); } @@ -52,7 +57,7 @@ class InputProvider extends ChangeNotifier { return globals.databaseService.addRelapse(relapse); } - Future saveSleep(String wokeUpKey, String sleptKey) { + Future saveSleep(SleepTimes wokeUpKey, SleepTimes sleptKey) { Sleep sleep = Sleep(_sliderValue.toInt(), _textController.text, DateTime.now(), getTimeEntry(sleptKey), getTimeEntry(wokeUpKey)); _resetFields(); diff --git a/lib/providers/workout_provider.dart b/lib/providers/workout_provider.dart index 5d85c18..ebcaf9c 100644 --- a/lib/providers/workout_provider.dart +++ b/lib/providers/workout_provider.dart @@ -5,6 +5,13 @@ import 'package:smoke_cess_app/providers/audio_provider.dart'; import 'package:smoke_cess_app/providers/timer_provider.dart'; import '../globals.dart' as globals; +enum WorkoutPhases { + warmUp, + highIntensity, + lowIntensity, + coolDown, +} + class WorkoutProvider extends ChangeNotifier { final TimerProvider timerProvider; final AudioProvider audioProvider; @@ -15,21 +22,21 @@ class WorkoutProvider extends ChangeNotifier { int motivationAfter = 50; int _workoutPhaseIndex = 0; - final List _workoutPhases = [ - 'Warm-Up', - 'High Intensity', - 'Low Intensity', - 'High Intensity', - 'Low Intensity', - 'High Intensity', - 'Low Intensity', - 'High Intensity', - 'Cool-down' + final List _workoutPhases = [ + WorkoutPhases.warmUp, + WorkoutPhases.highIntensity, + WorkoutPhases.lowIntensity, + WorkoutPhases.highIntensity, + WorkoutPhases.lowIntensity, + WorkoutPhases.highIntensity, + WorkoutPhases.lowIntensity, + WorkoutPhases.highIntensity, + WorkoutPhases.coolDown, ]; WorkoutProvider(this.timerProvider, this.audioProvider); - String get currentPhase => _workoutPhases[_workoutPhaseIndex]; + WorkoutPhases get currentPhase => _workoutPhases[_workoutPhaseIndex]; Duration get currentPhaseDuration => _workoutPhaseSettings[currentPhase]!['duration']; bool get isPhaseComplete => @@ -37,6 +44,7 @@ class WorkoutProvider extends ChangeNotifier { Color get currentPhaseColor => _workoutPhaseSettings[currentPhase]!['color']; AssetSource get currentPhaseSource => _workoutPhaseSettings[currentPhase]!['source']; + String get currentPhaseTitle => _workoutPhaseSettings[currentPhase]!['title']; void nextPhase() { if (_workoutPhaseIndex < _workoutPhases.length - 1) { @@ -89,23 +97,27 @@ class WorkoutProvider extends ChangeNotifier { } } -Map> _workoutPhaseSettings = { - 'Warm-Up': { +Map> _workoutPhaseSettings = { + WorkoutPhases.warmUp: { + 'title': 'Warm Up', 'duration': const Duration(seconds: 5), 'source': AssetSource('warmUp.mp3'), 'color': Colors.green }, - 'High Intensity': { + WorkoutPhases.highIntensity: { + 'title': 'High Intensity', 'duration': const Duration(seconds: 4), 'source': AssetSource('workout.mp3'), 'color': Colors.red }, - 'Low Intensity': { + WorkoutPhases.lowIntensity: { + 'title': 'Low Intensity', 'duration': const Duration(seconds: 3), 'source': AssetSource('workout.mp3'), 'color': Colors.orange }, - 'Cool-down': { + WorkoutPhases.coolDown: { + 'title': 'Cool Down', 'duration': const Duration(seconds: 5), 'source': AssetSource('cool_down.mp3'), 'color': Colors.blue diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index ad033ba..4996da7 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -17,20 +17,18 @@ class SleepForm extends StatelessWidget { Widget build(BuildContext context) { InputProvider inputModel = context.watch(); TasksProvider tasksModel = context.watch(); - String wokeUpKey = 'wokeUpAt'; - String sleptKey = 'sleptAt'; return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - ElevatedCard( + const ElevatedCard( title: 'Einschlafzeit', - child: TimePicker(sleptKey), + child: TimePicker(SleepTimes.sleptAt), ), const SizedBox(height: 16), - ElevatedCard( + const ElevatedCard( title: 'Aufwachzeit', - child: TimePicker(wokeUpKey), + child: TimePicker(SleepTimes.wokeUpAt), ), const SizedBox(height: 16), const ElevatedCard( @@ -46,7 +44,8 @@ class SleepForm extends StatelessWidget { height: 80, ), SubmitFormButton( - submitCallback: () => inputModel.saveSleep(wokeUpKey, sleptKey), + submitCallback: () => + inputModel.saveSleep(SleepTimes.wokeUpAt, SleepTimes.sleptAt), updateTasks: () => tasksModel.setTaskDone(Pages.mood), ) ], diff --git a/lib/widgets/timepicker.dart b/lib/widgets/timepicker.dart index 0b0926b..d6ab447 100644 --- a/lib/widgets/timepicker.dart +++ b/lib/widgets/timepicker.dart @@ -3,7 +3,7 @@ import 'package:smoke_cess_app/providers/input_provider.dart'; import 'package:provider/provider.dart'; class TimePicker extends StatelessWidget { - final String keyMap; + final SleepTimes keyMap; const TimePicker(this.keyMap, {super.key}); diff --git a/lib/widgets/workout_timer_widget.dart b/lib/widgets/workout_timer_widget.dart index c47bbf5..4f1b64c 100644 --- a/lib/widgets/workout_timer_widget.dart +++ b/lib/widgets/workout_timer_widget.dart @@ -62,7 +62,7 @@ class WorkoutTimerWidget extends StatelessWidget { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(workoutProvider.currentPhase), + Text(workoutProvider.currentPhaseTitle), const SizedBox( height: 20, ),