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 01/18] 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 02/18] 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 03/18] 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 04/18] 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 05/18] 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 06/18] 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 07/18] 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 08/18] 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 09/18] 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 10/18] 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 11/18] 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 12/18] 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 13/18] 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 14/18] 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 15/18] 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 16/18] 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 17/18] 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 18/18] 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;