From 5f7b63d9b5197d0c498414aef892af51bc8e2c05 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 14:08:05 +0100 Subject: [PATCH 01/40] use getter --- lib/widgets/mood_form.dart | 3 +-- lib/widgets/sleep_form.dart | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index 20031df..f6fd0e0 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -22,8 +22,7 @@ class _MoodFormState extends State { void submitForm() { if (_moodFormKey.currentState!.validate()) { _moodFormKey.currentState?.save(); //call every onSave Method - Mood mood = - Mood(slider.getSliderValue().toInt(), _textInput, DateTime.now()); + Mood mood = Mood(slider.sliderValue.toInt(), _textInput, DateTime.now()); DatabaseService.instance.addMood(mood); _moodFormKey.currentState?.reset(); } diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index 732a27a..eb86e89 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -29,7 +29,7 @@ class _SleepFormState extends State { if (_sleepFormKey.currentState!.validate()) { _sleepFormKey.currentState?.save(); //call every onSave Method Sleep sleep = Sleep( - slider.getSliderValue().toInt(), + slider.sliderValue.toInt(), _textInput, DateTime.now(), sleepTimePicker.getCurrentTime, From c87a59a0b6ba0b6b5e602bf147d71ad9efa0c4b3 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 14:10:06 +0100 Subject: [PATCH 02/40] refactor folder names --- lib/main.dart | 4 +- lib/models/settings.dart | 2 +- lib/pages/main_page.dart | 2 +- lib/pages/scanner_page.dart | 8 +- lib/services/database_service.dart | 108 +++++++++++++++++++++++++ lib/services/date_service.dart | 63 +++++++++++++++ lib/services/notification_service.dart | 105 ++++++++++++++++++++++++ lib/services/settings_service.dart | 67 +++++++++++++++ lib/widgets/mood_form.dart | 2 +- lib/widgets/sleep_form.dart | 2 +- 10 files changed, 353 insertions(+), 10 deletions(-) create mode 100644 lib/services/database_service.dart create mode 100644 lib/services/date_service.dart create mode 100644 lib/services/notification_service.dart create mode 100644 lib/services/settings_service.dart diff --git a/lib/main.dart b/lib/main.dart index bf9da73..2fe1f09 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:smoke_cess_app/pages/main_page.dart'; -import 'package:smoke_cess_app/service/database_service.dart'; -import 'package:smoke_cess_app/service/notification_service.dart'; +import 'package:smoke_cess_app/services/database_service.dart'; +import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:timezone/data/latest.dart' as tz; void main() { diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 6691e91..0e7cf30 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -1,4 +1,4 @@ -import 'package:smoke_cess_app/service/json_service.dart'; +import 'package:smoke_cess_app/services/json_service.dart'; class Settings { final int group; diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index ca3c95d..2af4f13 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -4,7 +4,7 @@ import 'package:smoke_cess_app/pages/relapse_page.dart'; import 'package:smoke_cess_app/pages/scanner_page.dart'; import 'package:smoke_cess_app/pages/sleep_page.dart'; import 'package:smoke_cess_app/pages/interval_page.dart'; -import 'package:smoke_cess_app/service/settings_service.dart'; +import 'package:smoke_cess_app/services/settings_service.dart'; import 'package:smoke_cess_app/widgets/missing_config_popup.dart'; class MyHomePage extends StatefulWidget { diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index c382990..7bded71 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:smoke_cess_app/models/mood.dart'; import 'package:smoke_cess_app/models/settings.dart'; -import 'package:smoke_cess_app/service/database_service.dart'; -import 'package:smoke_cess_app/service/json_service.dart'; -import 'package:smoke_cess_app/service/settings_service.dart'; -import 'package:smoke_cess_app/service/notification_service.dart'; +import 'package:smoke_cess_app/services/database_service.dart'; +import 'package:smoke_cess_app/services/json_service.dart'; +import 'package:smoke_cess_app/services/settings_service.dart'; +import 'package:smoke_cess_app/services/notification_service.dart'; import '../models/sleep.dart'; import '../widgets/missing_config_popup.dart'; diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart new file mode 100644 index 0000000..26973f4 --- /dev/null +++ b/lib/services/database_service.dart @@ -0,0 +1,108 @@ +import 'dart:async'; + +import 'package:path/path.dart'; +import 'package:smoke_cess_app/models/mood.dart'; +import 'package:sqflite/sqflite.dart'; +// ignore: depend_on_referenced_packages +import 'package:path_provider/path_provider.dart'; +import 'dart:io'; + +import '../models/sleep.dart'; + +class DatabaseService { + DatabaseService._privateConstructor(); + static final DatabaseService instance = DatabaseService._privateConstructor(); + + static Database? _database; + Future get database async => _database ??= await _initDatabase(); + + Future _initDatabase() async { + Directory documentsDirectory = await getApplicationDocumentsDirectory(); + String path = join(documentsDirectory.path, 'database.db'); + return await openDatabase(path, + version: 1, onCreate: _onCreate, onOpen: _createTablesIfNotExists); + } + + Future _onCreate(Database db, int version) async { + await _createTablesIfNotExists(db); + } + + Future _createTablesIfNotExists(Database db) async { + await db.execute(_createMoodTable); + await db.execute(_createSleepTable); + await db.execute(_createRelapseTable); + await db.execute(_createWorkoutTable); + } + + //TODO use generic function? + Future> getMoodRecords() async { + Database db = await instance.database; + var moodRecords = await db.query('mood'); + List moodList = moodRecords.isNotEmpty + ? moodRecords.map((e) => Mood.fromDatabase(e)).toList() + : []; + return moodList; + } + + Future> getSleepRecords() async { + Database db = await instance.database; + var sleepRecords = await db.query('sleep'); + List sleepList = sleepRecords.isNotEmpty + ? sleepRecords.map((e) => Sleep.fromDatabase(e)).toList() + : []; + return sleepList; + } + + Future addMood(Mood mood) async { + Database db = await instance.database; + return await db.insert('mood', mood.toMap()); + } + + Future addSleep(Sleep sleep) async { + Database db = await instance.database; + return await db.insert('sleep', sleep.toMap()); + } +} + +String _createMoodTable = ''' + CREATE TABLE IF NOT EXISTS mood( + id INTEGER PRIMARY KEY, + value INTEGER, + date TEXT, + comment TEXT + ) + '''; + +String _createSleepTable = ''' + CREATE TABLE IF NOT EXISTS sleep( + id INTEGER PRIMARY KEY, + value INTEGER, + date TEXT, + comment TEXT, + sleepedAtHour INTEGER, + sleepedAtMinute INTEGER, + wokeUpAtHour INTEGER, + wokeUpAtMinute INTEGER + ) + '''; + +String _createRelapseTable = ''' + CREATE TABLE IF NOT EXISTS relapse( + id INTEGER PRIMARY KEY, + date TEXT, + comment TEXT, + reason TEXT + ) + '''; + +String _createWorkoutTable = ''' + CREATE TABLE IF NOT EXISTS workout( + id INTEGER PRIMARY KEY, + date TEXT, + motivationBefore INTEGER, + commentBefore TEXT, + motivationAfter INTEGER, + commentAfter TEXT, + completed INTEGER + ) + '''; diff --git a/lib/services/date_service.dart b/lib/services/date_service.dart new file mode 100644 index 0000000..61e0567 --- /dev/null +++ b/lib/services/date_service.dart @@ -0,0 +1,63 @@ +import 'package:smoke_cess_app/services/settings_service.dart'; +import 'package:timezone/timezone.dart'; + +const int trainingTime = 40; + +const weekDays = { + "Montag": 1, + "Dienstag": 2, + "Mittwoch": 3, + "Donnerstag": 4, + "Freitag": 5, + "Samstag": 6, + "Sonntag": 7, +}; + +Future> getDatesforAll() async { + List allDates = []; + List moodDates = await getDatesforMood(); + List sleepDates = await getDatesforSleep(); + allDates.addAll(moodDates); + allDates.addAll(sleepDates); + return allDates; +} + +Future> getDatesforMood() async { + final List? selectedDays = await getMoodQueryDaysCategories(); + final int? selectedHours = await getMoodQueryHours(); + final int? selectedMinutes = await getMoodQueryMinutes(); + return createTZDateTimes(selectedDays, selectedHours, selectedMinutes); +} + +Future> getDatesforSleep() async { + final List? selectedDays = await getSleepQueryDaysCategories(); + final int? selectedHours = await getSleepQueryHours(); + final int? selectedMinutes = await getSleepQueryMinutes(); + return createTZDateTimes(selectedDays, selectedHours, selectedMinutes); +} + +List createTZDateTimes( + List? selectedDays, int? selectedHours, int? selectedMinutes) { + final List tzDateTimes = []; + final DateTime now = DateTime.now(); + final Duration offset = now.timeZoneOffset; + if (selectedDays == null || + selectedHours == null || + selectedMinutes == null) { + return tzDateTimes; + } + final Iterable selectedDaysInt = + selectedDays.map((day) => weekDays[day]); + for (int i = 0; i < trainingTime; i++) { + final DateTime date = DateTime(now.year, now.month, now.day, selectedHours, + selectedMinutes, 0, 0, 0) + .add(Duration(days: i)); + if (selectedDaysInt.contains(date.weekday) && + date.isAfter(DateTime.now())) { + tzDateTimes.add(TZDateTime.local(date.year, date.month, date.day, + selectedHours, selectedMinutes, 0, 0, 0) + .subtract(offset)); + } + } + return tzDateTimes; +} diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart new file mode 100644 index 0000000..ea65122 --- /dev/null +++ b/lib/services/notification_service.dart @@ -0,0 +1,105 @@ +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:smoke_cess_app/services/date_service.dart'; +import 'package:timezone/timezone.dart'; + +class NotificationService { + static final NotificationService _notificationService = + NotificationService._internal(); + + factory NotificationService() { + return _notificationService; + } + + final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = + FlutterLocalNotificationsPlugin(); + + NotificationService._internal(); + + Future initNotification() async { + // Android initialization + const AndroidInitializationSettings initializationSettingsAndroid = + AndroidInitializationSettings('mipmap/ic_launcher'); + + // ios initialization + const DarwinInitializationSettings initializationSettingsIOS = + DarwinInitializationSettings( + requestAlertPermission: false, + requestBadgePermission: false, + requestSoundPermission: false, + ); + + const InitializationSettings initializationSettings = + InitializationSettings( + android: initializationSettingsAndroid, + iOS: initializationSettingsIOS); + // the initialization settings are initialized after they are setted + await flutterLocalNotificationsPlugin.initialize(initializationSettings); + } + + Future showNotification() async { + await flutterLocalNotificationsPlugin.show( + 0, + 'test', + 'test', +//schedule the notification to show after 2 seconds. + const NotificationDetails( + // Android details + android: AndroidNotificationDetails('main_channel', 'Main Channel', + channelDescription: "ashwin", + importance: Importance.max, + priority: Priority.max), + // iOS details + iOS: DarwinNotificationDetails( + sound: 'default.wav', + presentAlert: true, + presentBadge: true, + presentSound: true, + ), + ), + ); + } + + Future setAllNotifications() async { + List moodDates = await getDatesforMood(); + List sleepDates = await getDatesforSleep(); + int index = 0; + for (var date in moodDates) { + setNotification(index, "Mood", "Evaluate your mood", date); + index++; + } + for (var date in sleepDates) { + setNotification(index, "Sleep", "Evaluate your sleep", date); + index++; + } + } + + Future setNotification( + int id, String title, String body, TZDateTime tzDateTime) async { + await flutterLocalNotificationsPlugin.zonedSchedule( + id, + title, + body, + tzDateTime, //schedule the notification to show after 2 seconds. + const NotificationDetails( + // Android details + android: AndroidNotificationDetails('main_channel', 'Main Channel', + channelDescription: "ashwin", + importance: Importance.max, + priority: Priority.max), + // iOS details + iOS: DarwinNotificationDetails( + sound: 'default.wav', + presentAlert: true, + presentBadge: true, + presentSound: true, + ), + ), + + // Type of time interpretation + uiLocalNotificationDateInterpretation: + UILocalNotificationDateInterpretation.absoluteTime, + androidAllowWhileIdle: + true, // To show notification even when the app is closed + ); + } +} diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart new file mode 100644 index 0000000..52028bd --- /dev/null +++ b/lib/services/settings_service.dart @@ -0,0 +1,67 @@ +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:smoke_cess_app/models/settings.dart'; +import 'package:smoke_cess_app/services/json_service.dart'; + +//access group setting which was saved in local storage +Future getGroup() => _getIntSetting('group'); + +Future?> getRelapseCategories() => + _getStringListSetting('relapse_categories'); + +Future?> getSleepQueryDaysCategories() => + _getStringListSetting('sleep_query_days'); + +Future getSleepQueryHours() => _getIntSetting('sleep_query_hours'); +Future getSleepQueryMinutes() => _getIntSetting('sleep_query_minutes'); + +Future?> getMoodQueryDaysCategories() => + _getStringListSetting('mood_query_days'); + +Future getMoodQueryHours() => _getIntSetting('mood_query_hours'); +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)); + +Future _getIntSetting(String settingKey) => + SharedPreferences.getInstance().then((pref) => pref.getInt(settingKey)); + +void _setStringListSetting(String settingKey, List list) => + SharedPreferences.getInstance() + .then((pref) => pref.setStringList(settingKey, list)); + +Future?> _getStringListSetting(String settingKey) => + SharedPreferences.getInstance() + .then((pref) => pref.getStringList(settingKey)); + +Future loadSettingsFromLocalJSON() async { + Map configJSON = await loadLocalConfigJSON(); + Settings settings = Settings.fromJson(configJSON); + saveSettings(settings); +} + +void saveSettings(Settings settings) { + _setIntSetting('group', settings.group); + _setStringListSetting('relapse_categories', settings.relapseCategories!); + _setStringListSetting('mood_query_days', settings.moodQuery.days!); + _setIntSetting('mood_query_hours', settings.moodQuery.hours); + _setIntSetting('mood_query_minutes', settings.moodQuery.minutes); + _setStringListSetting('sleep_query_days', settings.sleepQuery.days!); + _setIntSetting('sleep_query_hours', settings.sleepQuery.hours); + _setIntSetting('sleep_query_minutes', settings.sleepQuery.minutes); + if (settings.chessTime != null) { + _setIntSetting('chess_hours', settings.chessTime!.hours); + _setIntSetting('chess_minutes', settings.chessTime!.minutes); + } +} diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index f6fd0e0..c859d3f 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:smoke_cess_app/models/mood.dart'; -import 'package:smoke_cess_app/service/database_service.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'; diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index eb86e89..a36318e 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:smoke_cess_app/models/sleep.dart'; -import 'package:smoke_cess_app/service/database_service.dart'; +import 'package:smoke_cess_app/services/database_service.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'; From 8230a66df16214f04505c029bccd12144070fa3c Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 14:10:16 +0100 Subject: [PATCH 03/40] refactor folder names pt2 --- lib/service/database_service.dart | 108 ------------------- lib/service/date_service.dart | 63 ----------- lib/service/notification_service.dart | 105 ------------------ lib/service/settings_service.dart | 67 ------------ lib/{service => services}/json_service.dart | 0 lib/{service => services}/query_service.dart | 0 6 files changed, 343 deletions(-) delete mode 100644 lib/service/database_service.dart delete mode 100644 lib/service/date_service.dart delete mode 100644 lib/service/notification_service.dart delete mode 100644 lib/service/settings_service.dart rename lib/{service => services}/json_service.dart (100%) rename lib/{service => services}/query_service.dart (100%) diff --git a/lib/service/database_service.dart b/lib/service/database_service.dart deleted file mode 100644 index 26973f4..0000000 --- a/lib/service/database_service.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'dart:async'; - -import 'package:path/path.dart'; -import 'package:smoke_cess_app/models/mood.dart'; -import 'package:sqflite/sqflite.dart'; -// ignore: depend_on_referenced_packages -import 'package:path_provider/path_provider.dart'; -import 'dart:io'; - -import '../models/sleep.dart'; - -class DatabaseService { - DatabaseService._privateConstructor(); - static final DatabaseService instance = DatabaseService._privateConstructor(); - - static Database? _database; - Future get database async => _database ??= await _initDatabase(); - - Future _initDatabase() async { - Directory documentsDirectory = await getApplicationDocumentsDirectory(); - String path = join(documentsDirectory.path, 'database.db'); - return await openDatabase(path, - version: 1, onCreate: _onCreate, onOpen: _createTablesIfNotExists); - } - - Future _onCreate(Database db, int version) async { - await _createTablesIfNotExists(db); - } - - Future _createTablesIfNotExists(Database db) async { - await db.execute(_createMoodTable); - await db.execute(_createSleepTable); - await db.execute(_createRelapseTable); - await db.execute(_createWorkoutTable); - } - - //TODO use generic function? - Future> getMoodRecords() async { - Database db = await instance.database; - var moodRecords = await db.query('mood'); - List moodList = moodRecords.isNotEmpty - ? moodRecords.map((e) => Mood.fromDatabase(e)).toList() - : []; - return moodList; - } - - Future> getSleepRecords() async { - Database db = await instance.database; - var sleepRecords = await db.query('sleep'); - List sleepList = sleepRecords.isNotEmpty - ? sleepRecords.map((e) => Sleep.fromDatabase(e)).toList() - : []; - return sleepList; - } - - Future addMood(Mood mood) async { - Database db = await instance.database; - return await db.insert('mood', mood.toMap()); - } - - Future addSleep(Sleep sleep) async { - Database db = await instance.database; - return await db.insert('sleep', sleep.toMap()); - } -} - -String _createMoodTable = ''' - CREATE TABLE IF NOT EXISTS mood( - id INTEGER PRIMARY KEY, - value INTEGER, - date TEXT, - comment TEXT - ) - '''; - -String _createSleepTable = ''' - CREATE TABLE IF NOT EXISTS sleep( - id INTEGER PRIMARY KEY, - value INTEGER, - date TEXT, - comment TEXT, - sleepedAtHour INTEGER, - sleepedAtMinute INTEGER, - wokeUpAtHour INTEGER, - wokeUpAtMinute INTEGER - ) - '''; - -String _createRelapseTable = ''' - CREATE TABLE IF NOT EXISTS relapse( - id INTEGER PRIMARY KEY, - date TEXT, - comment TEXT, - reason TEXT - ) - '''; - -String _createWorkoutTable = ''' - CREATE TABLE IF NOT EXISTS workout( - id INTEGER PRIMARY KEY, - date TEXT, - motivationBefore INTEGER, - commentBefore TEXT, - motivationAfter INTEGER, - commentAfter TEXT, - completed INTEGER - ) - '''; diff --git a/lib/service/date_service.dart b/lib/service/date_service.dart deleted file mode 100644 index b422509..0000000 --- a/lib/service/date_service.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:smoke_cess_app/service/settings_service.dart'; -import 'package:timezone/timezone.dart'; - -const int trainingTime = 40; - -const weekDays = { - "Montag": 1, - "Dienstag": 2, - "Mittwoch": 3, - "Donnerstag": 4, - "Freitag": 5, - "Samstag": 6, - "Sonntag": 7, -}; - -Future> getDatesforAll() async { - List allDates = []; - List moodDates = await getDatesforMood(); - List sleepDates = await getDatesforSleep(); - allDates.addAll(moodDates); - allDates.addAll(sleepDates); - return allDates; -} - -Future> getDatesforMood() async { - final List? selectedDays = await getMoodQueryDaysCategories(); - final int? selectedHours = await getMoodQueryHours(); - final int? selectedMinutes = await getMoodQueryMinutes(); - return createTZDateTimes(selectedDays, selectedHours, selectedMinutes); -} - -Future> getDatesforSleep() async { - final List? selectedDays = await getSleepQueryDaysCategories(); - final int? selectedHours = await getSleepQueryHours(); - final int? selectedMinutes = await getSleepQueryMinutes(); - return createTZDateTimes(selectedDays, selectedHours, selectedMinutes); -} - -List createTZDateTimes( - List? selectedDays, int? selectedHours, int? selectedMinutes) { - final List tzDateTimes = []; - final DateTime now = DateTime.now(); - final Duration offset = now.timeZoneOffset; - if (selectedDays == null || - selectedHours == null || - selectedMinutes == null) { - return tzDateTimes; - } - final Iterable selectedDaysInt = - selectedDays.map((day) => weekDays[day]); - for (int i = 0; i < trainingTime; i++) { - final DateTime date = DateTime(now.year, now.month, now.day, selectedHours, - selectedMinutes, 0, 0, 0) - .add(Duration(days: i)); - if (selectedDaysInt.contains(date.weekday) && - date.isAfter(DateTime.now())) { - tzDateTimes.add(TZDateTime.local(date.year, date.month, date.day, - selectedHours, selectedMinutes, 0, 0, 0) - .subtract(offset)); - } - } - return tzDateTimes; -} diff --git a/lib/service/notification_service.dart b/lib/service/notification_service.dart deleted file mode 100644 index 2f564ce..0000000 --- a/lib/service/notification_service.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:smoke_cess_app/service/date_service.dart'; -import 'package:timezone/timezone.dart'; - -class NotificationService { - static final NotificationService _notificationService = - NotificationService._internal(); - - factory NotificationService() { - return _notificationService; - } - - final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = - FlutterLocalNotificationsPlugin(); - - NotificationService._internal(); - - Future initNotification() async { - // Android initialization - const AndroidInitializationSettings initializationSettingsAndroid = - AndroidInitializationSettings('mipmap/ic_launcher'); - - // ios initialization - const DarwinInitializationSettings initializationSettingsIOS = - DarwinInitializationSettings( - requestAlertPermission: false, - requestBadgePermission: false, - requestSoundPermission: false, - ); - - const InitializationSettings initializationSettings = - InitializationSettings( - android: initializationSettingsAndroid, - iOS: initializationSettingsIOS); - // the initialization settings are initialized after they are setted - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - } - - Future showNotification() async { - await flutterLocalNotificationsPlugin.show( - 0, - 'test', - 'test', -//schedule the notification to show after 2 seconds. - const NotificationDetails( - // Android details - android: AndroidNotificationDetails('main_channel', 'Main Channel', - channelDescription: "ashwin", - importance: Importance.max, - priority: Priority.max), - // iOS details - iOS: DarwinNotificationDetails( - sound: 'default.wav', - presentAlert: true, - presentBadge: true, - presentSound: true, - ), - ), - ); - } - - Future setAllNotifications() async { - List moodDates = await getDatesforMood(); - List sleepDates = await getDatesforSleep(); - int index = 0; - for (var date in moodDates) { - setNotification(index, "Mood", "Evaluate your mood", date); - index++; - } - for (var date in sleepDates) { - setNotification(index, "Sleep", "Evaluate your sleep", date); - index++; - } - } - - Future setNotification( - int id, String title, String body, TZDateTime tzDateTime) async { - await flutterLocalNotificationsPlugin.zonedSchedule( - id, - title, - body, - tzDateTime, //schedule the notification to show after 2 seconds. - const NotificationDetails( - // Android details - android: AndroidNotificationDetails('main_channel', 'Main Channel', - channelDescription: "ashwin", - importance: Importance.max, - priority: Priority.max), - // iOS details - iOS: DarwinNotificationDetails( - sound: 'default.wav', - presentAlert: true, - presentBadge: true, - presentSound: true, - ), - ), - - // Type of time interpretation - uiLocalNotificationDateInterpretation: - UILocalNotificationDateInterpretation.absoluteTime, - androidAllowWhileIdle: - true, // To show notification even when the app is closed - ); - } -} diff --git a/lib/service/settings_service.dart b/lib/service/settings_service.dart deleted file mode 100644 index dca2839..0000000 --- a/lib/service/settings_service.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:smoke_cess_app/models/settings.dart'; -import 'package:smoke_cess_app/service/json_service.dart'; - -//access group setting which was saved in local storage -Future getGroup() => _getIntSetting('group'); - -Future?> getRelapseCategories() => - _getStringListSetting('relapse_categories'); - -Future?> getSleepQueryDaysCategories() => - _getStringListSetting('sleep_query_days'); - -Future getSleepQueryHours() => _getIntSetting('sleep_query_hours'); -Future getSleepQueryMinutes() => _getIntSetting('sleep_query_minutes'); - -Future?> getMoodQueryDaysCategories() => - _getStringListSetting('mood_query_days'); - -Future getMoodQueryHours() => _getIntSetting('mood_query_hours'); -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)); - -Future _getIntSetting(String settingKey) => - SharedPreferences.getInstance().then((pref) => pref.getInt(settingKey)); - -void _setStringListSetting(String settingKey, List list) => - SharedPreferences.getInstance() - .then((pref) => pref.setStringList(settingKey, list)); - -Future?> _getStringListSetting(String settingKey) => - SharedPreferences.getInstance() - .then((pref) => pref.getStringList(settingKey)); - -Future loadSettingsFromLocalJSON() async { - Map configJSON = await loadLocalConfigJSON(); - Settings settings = Settings.fromJson(configJSON); - saveSettings(settings); -} - -void saveSettings(Settings settings) { - _setIntSetting('group', settings.group); - _setStringListSetting('relapse_categories', settings.relapseCategories!); - _setStringListSetting('mood_query_days', settings.moodQuery.days!); - _setIntSetting('mood_query_hours', settings.moodQuery.hours); - _setIntSetting('mood_query_minutes', settings.moodQuery.minutes); - _setStringListSetting('sleep_query_days', settings.sleepQuery.days!); - _setIntSetting('sleep_query_hours', settings.sleepQuery.hours); - _setIntSetting('sleep_query_minutes', settings.sleepQuery.minutes); - if (settings.chessTime != null) { - _setIntSetting('chess_hours', settings.chessTime!.hours); - _setIntSetting('chess_minutes', settings.chessTime!.minutes); - } -} diff --git a/lib/service/json_service.dart b/lib/services/json_service.dart similarity index 100% rename from lib/service/json_service.dart rename to lib/services/json_service.dart diff --git a/lib/service/query_service.dart b/lib/services/query_service.dart similarity index 100% rename from lib/service/query_service.dart rename to lib/services/query_service.dart From c45b38a1df0285a2e5a5103450f21edd583021a4 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 14:59:37 +0100 Subject: [PATCH 04/40] refactor slider to use provider --- lib/pages/mood_page.dart | 10 +++++++--- lib/pages/sleep_page.dart | 8 +++++++- lib/providers/input_provider.dart | 12 ++++++++++++ lib/widgets/mood_form.dart | 11 ++++++++--- lib/widgets/sleep_form.dart | 10 +++++++--- lib/widgets/slider.dart | 32 ++++++++++--------------------- pubspec.lock | 14 ++++++++++++++ pubspec.yaml | 1 + 8 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 lib/providers/input_provider.dart diff --git a/lib/pages/mood_page.dart b/lib/pages/mood_page.dart index bd1b36b..546c6f1 100644 --- a/lib/pages/mood_page.dart +++ b/lib/pages/mood_page.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/mood_form.dart'; class MoodPage extends StatelessWidget { @@ -6,8 +8,10 @@ class MoodPage extends StatelessWidget { @override Widget build(BuildContext context) { - return const Center( - child: MoodForm(), - ); + return Center( + child: ChangeNotifierProvider( + create: (context) => InputProvider(), + child: const MoodForm(), + )); } } diff --git a/lib/pages/sleep_page.dart b/lib/pages/sleep_page.dart index e736f44..22221f3 100644 --- a/lib/pages/sleep_page.dart +++ b/lib/pages/sleep_page.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/sleep_form.dart'; class SleepPage extends StatelessWidget { @@ -6,6 +8,10 @@ class SleepPage extends StatelessWidget { @override Widget build(BuildContext context) { - return const Center(child: SleepForm()); + return Center( + child: ChangeNotifierProvider( + create: (context) => InputProvider(), + child: const SleepForm(), + )); } } diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart new file mode 100644 index 0000000..95bd423 --- /dev/null +++ b/lib/providers/input_provider.dart @@ -0,0 +1,12 @@ +import 'package:flutter/cupertino.dart'; + +class InputProvider extends ChangeNotifier { + double _sliderValue = 50; + + double get sliderValue => _sliderValue; + + set sliderValue(double newValue) { + _sliderValue = newValue; + notifyListeners(); + } +} diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index c859d3f..f52db8c 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -1,10 +1,12 @@ 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'; +import '../providers/input_provider.dart'; import 'elevated_card.dart'; class MoodForm extends StatefulWidget { @@ -19,10 +21,13 @@ class _MoodFormState extends State { MySlider slider = MySlider(); String _textInput = ""; - void submitForm() { + void submitForm(BuildContext context) { + var inputModel = context.watch(); + print(inputModel.sliderValue); if (_moodFormKey.currentState!.validate()) { _moodFormKey.currentState?.save(); //call every onSave Method - Mood mood = Mood(slider.sliderValue.toInt(), _textInput, DateTime.now()); + Mood mood = + Mood(inputModel.sliderValue.toInt(), _textInput, DateTime.now()); DatabaseService.instance.addMood(mood); _moodFormKey.currentState?.reset(); } @@ -47,7 +52,7 @@ class _MoodFormState extends State { child: MyTextFormField('Beschreibe deine Stimmung', onFormFieldSave), ), - SubmitFormButton(submitForm) + SubmitFormButton(() => submitForm(context)) ], )); } diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index a36318e..d9955bc 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -1,4 +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/services/database_service.dart'; import 'package:smoke_cess_app/widgets/elevated_card.dart'; @@ -7,6 +8,8 @@ import 'package:smoke_cess_app/widgets/submit_form_button.dart'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; import 'package:smoke_cess_app/widgets/timepicker.dart'; +import '../providers/input_provider.dart'; + class SleepForm extends StatefulWidget { const SleepForm({Key? key}) : super(key: key); @@ -25,11 +28,12 @@ class _SleepFormState extends State { const TimeOfDay(hour: 8, minute: 00), ); - void submitForm() { + void submitForm(BuildContext context) { + var inputModel = context.watch(); if (_sleepFormKey.currentState!.validate()) { _sleepFormKey.currentState?.save(); //call every onSave Method Sleep sleep = Sleep( - slider.sliderValue.toInt(), + inputModel.sliderValue.toInt(), _textInput, DateTime.now(), sleepTimePicker.getCurrentTime, @@ -84,7 +88,7 @@ class _SleepFormState extends State { child: SizedBox( width: 140, height: 80, - child: SubmitFormButton(submitForm), + child: SubmitFormButton(() => submitForm(context)), ), ), ], diff --git a/lib/widgets/slider.dart b/lib/widgets/slider.dart index b642916..bf7c5b3 100644 --- a/lib/widgets/slider.dart +++ b/lib/widgets/slider.dart @@ -1,25 +1,19 @@ +import 'package:provider/provider.dart'; import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/providers/input_provider.dart'; -// ignore: must_be_immutable -class MySlider extends StatefulWidget { - double _currentSliderValue = 50; +class MySlider extends StatelessWidget { MySlider({Key? key}) : super(key: key); - @override - State createState() => SliderState(); - - double get sliderValue => _currentSliderValue; -} - -class SliderState extends State { @override Widget build(BuildContext context) { + var inputModel = context.watch(); return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const SizedBox(height: 16), - Text('${widget._currentSliderValue.toInt()}', + Text('${inputModel.sliderValue.toInt()}', style: const TextStyle(fontSize: 22)), Row( mainAxisAlignment: MainAxisAlignment.center, @@ -27,31 +21,25 @@ class SliderState extends State { IconButton( icon: const Icon(Icons.remove_outlined), onPressed: () { - setState(() { - widget._currentSliderValue -= 1; - }); + inputModel.sliderValue -= 1; }, ), Expanded( child: Slider( - value: widget._currentSliderValue, + value: inputModel.sliderValue, min: 0, max: 100, divisions: 100, - label: widget._currentSliderValue.round().toString(), + label: '${inputModel.sliderValue.toInt()}', onChanged: (double value) { - setState(() { - widget._currentSliderValue = value; - }); + inputModel.sliderValue = value; }, ), ), IconButton( icon: const Icon(Icons.add_outlined), onPressed: () { - setState(() { - widget._currentSliderValue += 1; - }); + inputModel.sliderValue += 1; }, ), ], diff --git a/pubspec.lock b/pubspec.lock index 04c064a..b899dd9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -233,6 +233,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" path: dependency: "direct main" description: @@ -310,6 +317,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.4" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.5" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index c4a8789..9204ca9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -34,6 +34,7 @@ dependencies: sqflite: path: path_provider: ^2.0.12 + provider: ^6.0.5 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. From b3f22b2c74947beb5e554d123e8ae9d25c052300 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 16:17:57 +0100 Subject: [PATCH 05/40] complete mood form provider setup, use mocked database --- lib/globals.dart | 7 +++ lib/main.dart | 4 +- lib/mock/db_mock.dart | 48 +++++++++++++------ lib/pages/main_page.dart | 2 +- lib/pages/scanner_page.dart | 5 +- lib/providers/input_provider.dart | 27 +++++++++++ lib/widgets/mood_form.dart | 58 ++++++++--------------- lib/widgets/popup_for_start_and_stop.dart | 2 +- lib/widgets/sleep_form.dart | 5 +- lib/widgets/text_formfield.dart | 9 ++-- 10 files changed, 102 insertions(+), 65 deletions(-) create mode 100644 lib/globals.dart diff --git a/lib/globals.dart b/lib/globals.dart new file mode 100644 index 0000000..58229d9 --- /dev/null +++ b/lib/globals.dart @@ -0,0 +1,7 @@ +library app.globals; + +import 'package:smoke_cess_app/mock/db_mock.dart'; +import 'package:smoke_cess_app/services/database_service.dart'; + +DatabaseService databaseService = DatabaseMock(); +// DatabaseService databaseService = DatabaseService.instance; diff --git a/lib/main.dart b/lib/main.dart index 2fe1f09..2c2245d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:smoke_cess_app/pages/main_page.dart'; -import 'package:smoke_cess_app/services/database_service.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import 'package:timezone/data/latest.dart' as tz; +import 'globals.dart' as globals; void main() { // to ensure all the widgets are initialized. WidgetsFlutterBinding.ensureInitialized(); //init database - DatabaseService.instance; + globals.databaseService; tz.initializeTimeZones(); NotificationService().initNotification(); runApp(const MyApp()); diff --git a/lib/mock/db_mock.dart b/lib/mock/db_mock.dart index 1a92cf9..a06f003 100644 --- a/lib/mock/db_mock.dart +++ b/lib/mock/db_mock.dart @@ -1,23 +1,43 @@ 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/services/database_service.dart'; +import 'package:sqflite_common/sqlite_api.dart'; -class DatabaseMock { - final List _moodRecords = []; - final List _sleepRecords = []; +class DatabaseMock implements DatabaseService { + static final DatabaseMock _databaseMock = DatabaseMock._internal(); + factory DatabaseMock() { + return _databaseMock; + } + DatabaseMock._internal(); + + final List _moodRecords = []; + final List _sleepRecords = []; final List _workoutRecords = []; - void saveRecord(DatabaseRecord record) { - if (record is Mood) { - _moodRecords.add(record); - } else if (record is Sleep) { - _sleepRecords.add(record); - } else { - _workoutRecords.add(record); - } + @override + Future addMood(Mood mood) { + _moodRecords.add(mood); + return Future.value(1); } - List getMoodRecords() => _moodRecords; - List getSleepRecords() => _sleepRecords; - List getWorkoutRecords() => _workoutRecords; + @override + Future addSleep(Sleep sleep) { + _sleepRecords.add(sleep); + return Future.value(1); + } + + @override + // TODO: implement database + Future get database => DatabaseService.instance.database; + + @override + Future> getMoodRecords() { + return Future.value(_moodRecords); + } + + @override + Future> getSleepRecords() { + return Future.value(_sleepRecords); + } } diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 2af4f13..0daf3a6 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 = 0; int? _gruppe; final List _titles = [ diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index 7bded71..7159694 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -9,6 +9,7 @@ import 'package:smoke_cess_app/services/notification_service.dart'; import '../models/sleep.dart'; import '../widgets/missing_config_popup.dart'; +import '../globals.dart' as globals; class ScannerPage extends StatefulWidget { const ScannerPage({super.key}); @@ -80,9 +81,9 @@ class ScannerPageState extends State { style: ElevatedButton.styleFrom( textStyle: const TextStyle(fontSize: 20)), onPressed: () async { - List moods = await DatabaseService.instance.getMoodRecords(); + List moods = await globals.databaseService.getMoodRecords(); List sleeps = - await DatabaseService.instance.getSleepRecords(); + await globals.databaseService.getSleepRecords(); for (Mood mood in moods) { print(mood.toCSV()); } diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart index 95bd423..c0a7601 100644 --- a/lib/providers/input_provider.dart +++ b/lib/providers/input_provider.dart @@ -1,12 +1,39 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/models/mood.dart'; +import '../globals.dart' as globals; class InputProvider extends ChangeNotifier { double _sliderValue = 50; + final TextEditingController _textController = TextEditingController(text: ''); + final Map _times = {}; double get sliderValue => _sliderValue; + TextEditingController get textController => _textController; set sliderValue(double newValue) { _sliderValue = newValue; notifyListeners(); } + + TimeOfDay? getTimeEntry(String key) { + return _times[key]; + } + + void setTime(String key, TimeOfDay time) { + _times[key] = time; + } + + void _resetFields() { + _sliderValue = 50; + _textController.text = ''; + notifyListeners(); + } + + void saveMood() { + Mood mood = + Mood(_sliderValue.toInt(), _textController.text, DateTime.now()); + globals.databaseService.addMood(mood); + _resetFields(); + } } diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index f52db8c..9ca1f30 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -9,51 +9,33 @@ import 'package:smoke_cess_app/widgets/text_formfield.dart'; import '../providers/input_provider.dart'; import 'elevated_card.dart'; -class MoodForm extends StatefulWidget { +class MoodForm extends StatelessWidget { const MoodForm({super.key}); - @override - State createState() => _MoodFormState(); -} - -class _MoodFormState extends State { - final GlobalKey _moodFormKey = GlobalKey(); - MySlider slider = MySlider(); - String _textInput = ""; - void submitForm(BuildContext context) { var inputModel = context.watch(); - print(inputModel.sliderValue); - if (_moodFormKey.currentState!.validate()) { - _moodFormKey.currentState?.save(); //call every onSave Method - Mood mood = - Mood(inputModel.sliderValue.toInt(), _textInput, DateTime.now()); - DatabaseService.instance.addMood(mood); - _moodFormKey.currentState?.reset(); - } } - void onFormFieldSave(String? newValue) => _textInput = newValue!; - @override Widget build(BuildContext context) { - return Form( - key: _moodFormKey, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedCard( - title: 'Stimmungsbewertung', - child: slider, - ), - const SizedBox(height: 16), - ElevatedCard( - title: 'Beschreibe deine Stimmung', - child: - MyTextFormField('Beschreibe deine Stimmung', onFormFieldSave), - ), - SubmitFormButton(() => submitForm(context)) - ], - )); + var inputModel = context.watch(); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedCard( + title: 'Stimmungsbewertung', + child: MySlider(), + ), + const SizedBox(height: 16), + const ElevatedCard( + title: 'Beschreibe deine Stimmung', + child: MyTextFormField('Beschreibe deine Stimmung'), + ), + ElevatedButton( + onPressed: () => inputModel.saveMood(), + child: const Text('Speichern'), + ) + ], + ); } } diff --git a/lib/widgets/popup_for_start_and_stop.dart b/lib/widgets/popup_for_start_and_stop.dart index b8ed90a..5221541 100644 --- a/lib/widgets/popup_for_start_and_stop.dart +++ b/lib/widgets/popup_for_start_and_stop.dart @@ -34,7 +34,7 @@ class TimerStartStopPopupState extends State { child: MySlider(), ), const SizedBox(height: 16), - MyTextFormField('Beschreibe deinen Motivation', onFormFieldSave), + MyTextFormField('Beschreibe deinen Motivation'), SubmitFormButton(() => submitForm(context)), ], ), diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index d9955bc..7929367 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -71,10 +71,9 @@ class _SleepFormState extends State { child: slider, ), const SizedBox(height: 16), - ElevatedCard( + const ElevatedCard( title: 'Schlafbeschreibung', - child: MyTextFormField( - 'Beschreibe deinen Schlaf', onFormFieldSave), + child: MyTextFormField('Beschreibe deinen Schlaf'), ), const SizedBox( height: 80, diff --git a/lib/widgets/text_formfield.dart b/lib/widgets/text_formfield.dart index 102a350..1e6e25c 100644 --- a/lib/widgets/text_formfield.dart +++ b/lib/widgets/text_formfield.dart @@ -1,18 +1,19 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/input_provider.dart'; class MyTextFormField extends StatelessWidget { final String _description; - final Function(String?) onSaveAction; const MyTextFormField( - this._description, - this.onSaveAction, { + this._description, { super.key, }); @override Widget build(BuildContext context) { + var inputProvider = context.watch(); return TextFormField( - onSaved: onSaveAction, + controller: inputProvider.textController, decoration: InputDecoration(hintText: _description), validator: (String? value) => value == null || value.isEmpty ? 'Text eingeben' : null, From 646a97926dab33e01466f7f4cefad25622cffa69 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 17:07:38 +0100 Subject: [PATCH 06/40] refactor timepicker and moodform --- lib/models/sleep.dart | 16 ++-- lib/pages/main_page.dart | 2 +- lib/providers/input_provider.dart | 21 +++++- lib/services/database_service.dart | 4 +- lib/services/query_service.dart | 21 ------ lib/widgets/sleep_form.dart | 116 +++++++++-------------------- lib/widgets/slider.dart | 4 +- lib/widgets/timepicker.dart | 27 +++---- 8 files changed, 75 insertions(+), 136 deletions(-) delete mode 100644 lib/services/query_service.dart diff --git a/lib/models/sleep.dart b/lib/models/sleep.dart index d5335a8..3474b03 100644 --- a/lib/models/sleep.dart +++ b/lib/models/sleep.dart @@ -5,25 +5,25 @@ class Sleep implements DatabaseRecord { final int _sleepQualityValue; final String _comment; final DateTime _date; - final TimeOfDay _sleepedAt; + final TimeOfDay _sleptAt; final TimeOfDay _wokeUpAt; - Sleep(this._sleepQualityValue, this._comment, this._date, this._sleepedAt, + Sleep(this._sleepQualityValue, this._comment, this._date, this._sleptAt, this._wokeUpAt); @override factory Sleep.fromDatabase(Map map) { DateTime date = DateTime.parse(map['date']); - TimeOfDay sleepedAt = - TimeOfDay(hour: map['sleepedAtHour'], minute: map['sleepedAtMinute']); + TimeOfDay sleptAt = + TimeOfDay(hour: map['sleptAtHour'], minute: map['sleptAtMinute']); TimeOfDay wokeUpAt = TimeOfDay(hour: map['wokeUpAtHour'], minute: map['wokeUpAtMinute']); - return Sleep(map['value'], map['comment'], date, sleepedAt, wokeUpAt); + return Sleep(map['value'], map['comment'], date, sleptAt, wokeUpAt); } @override String toCSV() { - return "${_date.toIso8601String()}, $_sleepQualityValue, ${_sleepedAt.hour}:${_sleepedAt.minute}, ${_wokeUpAt.hour}:${_wokeUpAt.minute}, $_comment"; + return "${_date.toIso8601String()}, $_sleepQualityValue, ${_sleptAt.hour}:${_sleptAt.minute}, ${_wokeUpAt.hour}:${_wokeUpAt.minute}, $_comment"; } @override @@ -32,8 +32,8 @@ class Sleep implements DatabaseRecord { 'value': _sleepQualityValue, 'comment': _comment, 'date': _date.toIso8601String(), - 'sleepedAtHour': _sleepedAt.hour, - 'sleepedAtMinute': _sleepedAt.minute, + 'sleptAtHour': _sleptAt.hour, + 'sleptAtMinute': _sleptAt.minute, 'wokeUpAtHour': _wokeUpAt.hour, 'wokeUpAtMinute': _wokeUpAt.minute, }; diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 0daf3a6..2af4f13 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 = 0; + int _selectedIndex = 4; int? _gruppe; final List _titles = [ diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart index c0a7601..881ce2c 100644 --- a/lib/providers/input_provider.dart +++ b/lib/providers/input_provider.dart @@ -1,12 +1,15 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:smoke_cess_app/models/mood.dart'; +import 'package:smoke_cess_app/models/sleep.dart'; import '../globals.dart' as globals; class InputProvider extends ChangeNotifier { double _sliderValue = 50; final TextEditingController _textController = TextEditingController(text: ''); - final Map _times = {}; + final Map _times = { + 'wokeUpAt': const TimeOfDay(hour: 8, minute: 0), + 'sleptAt': const TimeOfDay(hour: 22, minute: 0), + }; double get sliderValue => _sliderValue; TextEditingController get textController => _textController; @@ -16,17 +19,20 @@ class InputProvider extends ChangeNotifier { notifyListeners(); } - TimeOfDay? getTimeEntry(String key) { - return _times[key]; + TimeOfDay getTimeEntry(String key) { + return _times[key] ?? const TimeOfDay(hour: 12, minute: 0); } void setTime(String key, TimeOfDay time) { _times[key] = time; + notifyListeners(); } void _resetFields() { _sliderValue = 50; _textController.text = ''; + setTime('wokeUpAt', const TimeOfDay(hour: 8, minute: 0)); + setTime('sleptAt', const TimeOfDay(hour: 22, minute: 0)); notifyListeners(); } @@ -36,4 +42,11 @@ class InputProvider extends ChangeNotifier { globals.databaseService.addMood(mood); _resetFields(); } + + void saveSleep(String wokeUpKey, String sleptKey) { + Sleep sleep = Sleep(_sliderValue.toInt(), _textController.text, + DateTime.now(), getTimeEntry(sleptKey), getTimeEntry(wokeUpKey)); + globals.databaseService.addSleep(sleep); + _resetFields(); + } } diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart index 26973f4..8dc8788 100644 --- a/lib/services/database_service.dart +++ b/lib/services/database_service.dart @@ -79,8 +79,8 @@ String _createSleepTable = ''' value INTEGER, date TEXT, comment TEXT, - sleepedAtHour INTEGER, - sleepedAtMinute INTEGER, + sleptAtHour INTEGER, + sleptAtMinute INTEGER, wokeUpAtHour INTEGER, wokeUpAtMinute INTEGER ) diff --git a/lib/services/query_service.dart b/lib/services/query_service.dart deleted file mode 100644 index fc4f5a3..0000000 --- a/lib/services/query_service.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:smoke_cess_app/interface/db_record.dart'; -import 'package:smoke_cess_app/mock/db_mock.dart'; - -class QueryService { - final DatabaseMock _database; - - QueryService(this._database); - - void addRecord(DatabaseRecord record) => _database.saveRecord(record); - List getWorkoutRecords() => _database.getWorkoutRecords(); - List getMoodRecords() => _database.getMoodRecords(); - List getSleepRecords() => _database.getSleepRecords(); - - String recordsToCSV(List records) { - String csv = ""; - for (DatabaseRecord record in records) { - csv += '${record.toCSV()}\n'; - } - return csv; - } -} diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index 7929367..98d35db 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -1,97 +1,51 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/models/sleep.dart'; -import 'package:smoke_cess_app/services/database_service.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'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; import 'package:smoke_cess_app/widgets/timepicker.dart'; import '../providers/input_provider.dart'; -class SleepForm extends StatefulWidget { +class SleepForm extends StatelessWidget { const SleepForm({Key? key}) : super(key: key); - @override - State createState() => _SleepFormState(); -} - -class _SleepFormState extends State { - final GlobalKey _sleepFormKey = GlobalKey(); - MySlider slider = MySlider(); - String _textInput = ""; - TimePicker sleepTimePicker = TimePicker( - const TimeOfDay(hour: 22, minute: 00), - ); - TimePicker wakeUpTimePicker = TimePicker( - const TimeOfDay(hour: 8, minute: 00), - ); - - void submitForm(BuildContext context) { - var inputModel = context.watch(); - if (_sleepFormKey.currentState!.validate()) { - _sleepFormKey.currentState?.save(); //call every onSave Method - Sleep sleep = Sleep( - inputModel.sliderValue.toInt(), - _textInput, - DateTime.now(), - sleepTimePicker.getCurrentTime, - wakeUpTimePicker.getCurrentTime); - DatabaseService.instance.addSleep(sleep); - _sleepFormKey.currentState?.reset(); - } - } - - void onFormFieldSave(String? newValue) => _textInput = newValue!; - @override Widget build(BuildContext context) { - return Form( - key: _sleepFormKey, - child: Stack( - children: [ - SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ElevatedCard( - title: 'Einschlafzeit', - child: sleepTimePicker, - ), - const SizedBox(height: 16), - ElevatedCard( - title: 'Aufwachzeit', - child: wakeUpTimePicker, - ), - const SizedBox(height: 16), - ElevatedCard( - title: 'Schlafbewertung', - child: slider, - ), - const SizedBox(height: 16), - const ElevatedCard( - title: 'Schlafbeschreibung', - child: MyTextFormField('Beschreibe deinen Schlaf'), - ), - const SizedBox( - height: 80, - ), - ], - ), - ), - Positioned( - bottom: 0, - right: 0, - child: SizedBox( - width: 140, - height: 80, - child: SubmitFormButton(() => submitForm(context)), - ), - ), - ], - ), + InputProvider inputModel = context.watch(); + String wokeUpKey = 'wokeUpAt'; + String sleptKey = 'sleptAt'; + + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ElevatedCard( + title: 'Einschlafzeit', + child: TimePicker(sleptKey), + ), + const SizedBox(height: 16), + ElevatedCard( + title: 'Aufwachzeit', + child: TimePicker(wokeUpKey), + ), + const SizedBox(height: 16), + const ElevatedCard( + title: 'Schlafbewertung', + child: MySlider(), + ), + const SizedBox(height: 16), + const ElevatedCard( + title: 'Schlafbeschreibung', + child: MyTextFormField('Beschreibe deinen Schlaf'), + ), + const SizedBox( + height: 80, + ), + ElevatedButton( + onPressed: () => inputModel.saveSleep(wokeUpKey, sleptKey), + child: const Text('Speichern')) + ], ); } } diff --git a/lib/widgets/slider.dart b/lib/widgets/slider.dart index bf7c5b3..fee5177 100644 --- a/lib/widgets/slider.dart +++ b/lib/widgets/slider.dart @@ -3,11 +3,11 @@ import 'package:flutter/material.dart'; import 'package:smoke_cess_app/providers/input_provider.dart'; class MySlider extends StatelessWidget { - MySlider({Key? key}) : super(key: key); + const MySlider({super.key}); @override Widget build(BuildContext context) { - var inputModel = context.watch(); + InputProvider inputModel = context.watch(); return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/widgets/timepicker.dart b/lib/widgets/timepicker.dart index 5e97af5..19fd528 100644 --- a/lib/widgets/timepicker.dart +++ b/lib/widgets/timepicker.dart @@ -1,25 +1,20 @@ import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/providers/input_provider.dart'; +import 'package:provider/provider.dart'; -class TimePicker extends StatefulWidget { - TimeOfDay _initialTime; - TimePicker(this._initialTime, {Key? key}); +class TimePicker extends StatelessWidget { + final String keyMap; - TimeOfDay get getCurrentTime => _initialTime; - - @override - State createState() => TimePickerState(); -} - - -class TimePickerState extends State { - TimePickerState(); + const TimePicker(this.keyMap, {super.key}); @override Widget build(BuildContext context) { + InputProvider inputModel = context.watch(); + return Center( child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - '${widget._initialTime.hour.toString().padLeft(2, '0')}:${widget._initialTime.minute.toString().padLeft(2, '0')}', + '${inputModel.getTimeEntry(keyMap).hour.toString().padLeft(2, '0')}:${inputModel.getTimeEntry(keyMap).minute.toString().padLeft(2, '0')}', style: const TextStyle(fontSize: 22), ), const SizedBox(width: 16), @@ -28,7 +23,7 @@ class TimePickerState extends State { //TODO auslagern TimeOfDay? newTime = await showTimePicker( context: context, - initialTime: widget._initialTime, + initialTime: inputModel.getTimeEntry(keyMap), builder: (context, child) { return MediaQuery( data: MediaQuery.of(context) @@ -38,9 +33,7 @@ class TimePickerState extends State { }, ); if (newTime == null) return; - setState(() { - widget._initialTime = newTime; - }); + inputModel.setTime(keyMap, newTime); }, child: const Text('Zeit einstellen')) ]), From 68033a64a5d9b6c3c9f57f5cc28dc9b795d1c802 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 17:09:25 +0100 Subject: [PATCH 07/40] layouting --- lib/widgets/mood_form.dart | 5 ++++- lib/widgets/sleep_form.dart | 1 - lib/widgets/timepicker.dart | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index 9ca1f30..0f73c79 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -22,7 +22,7 @@ class MoodForm extends StatelessWidget { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - ElevatedCard( + const ElevatedCard( title: 'Stimmungsbewertung', child: MySlider(), ), @@ -31,6 +31,9 @@ class MoodForm extends StatelessWidget { title: 'Beschreibe deine Stimmung', child: MyTextFormField('Beschreibe deine Stimmung'), ), + const SizedBox( + height: 80, + ), ElevatedButton( onPressed: () => inputModel.saveMood(), child: const Text('Speichern'), diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index 98d35db..5cb7352 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -18,7 +18,6 @@ class SleepForm extends StatelessWidget { return Column( mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, children: [ ElevatedCard( title: 'Einschlafzeit', diff --git a/lib/widgets/timepicker.dart b/lib/widgets/timepicker.dart index 19fd528..0b0926b 100644 --- a/lib/widgets/timepicker.dart +++ b/lib/widgets/timepicker.dart @@ -20,7 +20,6 @@ class TimePicker extends StatelessWidget { const SizedBox(width: 16), ElevatedButton( onPressed: () async { - //TODO auslagern TimeOfDay? newTime = await showTimePicker( context: context, initialTime: inputModel.getTimeEntry(keyMap), From 02ffb9b2f759e8d1bfba55ec1cb386b20851bf17 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 17:33:32 +0100 Subject: [PATCH 08/40] wip refactor timer --- lib/pages/interval_page.dart | 103 ++++++++++++---------- lib/widgets/popup_for_start_and_stop.dart | 23 +---- lib/widgets/timer_widget.dart | 0 3 files changed, 59 insertions(+), 67 deletions(-) create mode 100644 lib/widgets/timer_widget.dart diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index 619d969..98b1c17 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -1,8 +1,11 @@ import 'dart:async'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:smoke_cess_app/widgets/popup_for_start_and_stop.dart'; +import '../providers/input_provider.dart'; + class IntervalTimerPage extends StatefulWidget { const IntervalTimerPage({Key? key}) : super(key: key); @@ -44,9 +47,11 @@ class _IntervalTimerPageState extends State { await showDialog( context: context, builder: (BuildContext context) { - return const TimerStartStopPopup( - title: 'Motivation vor dem Training', - ); + return ChangeNotifierProvider( + create: (context) => InputProvider(), + child: const TimerStartStopPopup( + title: 'Motivation vor dem Training', + )); }, ); _isPaused = false; @@ -161,51 +166,53 @@ class _IntervalTimerPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( - body: Center( + 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(); - } - }, - ), - // ), - ], - ), - ], - ))); + 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/widgets/popup_for_start_and_stop.dart b/lib/widgets/popup_for_start_and_stop.dart index 5221541..e1af268 100644 --- a/lib/widgets/popup_for_start_and_stop.dart +++ b/lib/widgets/popup_for_start_and_stop.dart @@ -1,41 +1,26 @@ import 'package:flutter/material.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'; -class TimerStartStopPopup extends StatefulWidget { +class TimerStartStopPopup extends StatelessWidget { final String title; const TimerStartStopPopup({Key? key, required this.title}) : super(key: key); - @override - TimerStartStopPopupState createState() => TimerStartStopPopupState(); -} - -class TimerStartStopPopupState extends State { - final MySlider slider = MySlider(); - - void submitForm(BuildContext context) { - Navigator.of(context).pop(); - } - - void onFormFieldSave(String? newValue) => newValue!; - @override Widget build(BuildContext context) { return AlertDialog( - title: Text(widget.title), + title: Text(title), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: const [ Padding( padding: const EdgeInsets.only(top: 8), child: MySlider(), ), - const SizedBox(height: 16), + SizedBox(height: 16), MyTextFormField('Beschreibe deinen Motivation'), - SubmitFormButton(() => submitForm(context)), ], ), ); diff --git a/lib/widgets/timer_widget.dart b/lib/widgets/timer_widget.dart new file mode 100644 index 0000000..e69de29 From 20f5c5e42643e71f8bde0344ae73d7c6b8ec7196 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 19:52:45 +0100 Subject: [PATCH 09/40] add timer widget, provider and util (format) --- lib/pages/interval_page.dart | 7 +++++++ lib/providers/timer_provider.dart | 23 +++++++++++++++++++++++ lib/utils/timer_util.dart | 4 ++++ lib/widgets/timer_widget.dart | 25 +++++++++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 lib/providers/timer_provider.dart create mode 100644 lib/utils/timer_util.dart diff --git a/lib/pages/interval_page.dart b/lib/pages/interval_page.dart index 98b1c17..f6d2fcd 100644 --- a/lib/pages/interval_page.dart +++ b/lib/pages/interval_page.dart @@ -2,7 +2,9 @@ import 'dart:async'; 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/widgets/popup_for_start_and_stop.dart'; +import 'package:smoke_cess_app/widgets/timer_widget.dart'; import '../providers/input_provider.dart'; @@ -166,6 +168,11 @@ class _IntervalTimerPageState extends State { @override Widget build(BuildContext context) { + return ChangeNotifierProvider( + create: (context) => TimerProvider(), + child: TimerWidget( + duration: Duration(seconds: 5), + )); return Center( child: ChangeNotifierProvider( create: (context) => InputProvider(), diff --git a/lib/providers/timer_provider.dart b/lib/providers/timer_provider.dart new file mode 100644 index 0000000..0601b39 --- /dev/null +++ b/lib/providers/timer_provider.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +class TimerProvider extends ChangeNotifier { + Timer? _timer; + bool started = false; + int get elapsedSeconds => _timer != null ? _timer!.tick : 0; + + void startTimer(Duration duration) { + started = true; + print('starting timer'); + _timer = Timer.periodic(const Duration(seconds: 1), ((timer) { + if (timer.tick >= duration.inSeconds) { + timer.cancel(); + started = false; + } + notifyListeners(); + })); + } + + void stopTimer() => _timer?.cancel(); +} diff --git a/lib/utils/timer_util.dart b/lib/utils/timer_util.dart new file mode 100644 index 0000000..58d9690 --- /dev/null +++ b/lib/utils/timer_util.dart @@ -0,0 +1,4 @@ +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')}'; +} diff --git a/lib/widgets/timer_widget.dart b/lib/widgets/timer_widget.dart index e69de29..875697f 100644 --- a/lib/widgets/timer_widget.dart +++ b/lib/widgets/timer_widget.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/providers/timer_provider.dart'; +import 'package:smoke_cess_app/utils/timer_util.dart'; + +class TimerWidget extends StatelessWidget { + final Duration duration; + const TimerWidget({super.key, required this.duration}); + + @override + Widget build(BuildContext context) { + TimerProvider timerProvider = context.watch(); + return Column( + 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')) + ], + ); + } +} From 72674a35526425130eee371264729c353ad6d5fd Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 22:49:01 +0100 Subject: [PATCH 10/40] deleted useless code --- lib/services/date_service.dart | 9 --------- lib/services/notification_service.dart | 23 ----------------------- lib/widgets/mood_form.dart | 4 ---- 3 files changed, 36 deletions(-) diff --git a/lib/services/date_service.dart b/lib/services/date_service.dart index 61e0567..0fd108e 100644 --- a/lib/services/date_service.dart +++ b/lib/services/date_service.dart @@ -13,15 +13,6 @@ const weekDays = { "Sonntag": 7, }; -Future> getDatesforAll() async { - List allDates = []; - List moodDates = await getDatesforMood(); - List sleepDates = await getDatesforSleep(); - allDates.addAll(moodDates); - allDates.addAll(sleepDates); - return allDates; -} - Future> getDatesforMood() async { final List? selectedDays = await getMoodQueryDaysCategories(); final int? selectedHours = await getMoodQueryHours(); diff --git a/lib/services/notification_service.dart b/lib/services/notification_service.dart index ea65122..2de386c 100644 --- a/lib/services/notification_service.dart +++ b/lib/services/notification_service.dart @@ -36,29 +36,6 @@ class NotificationService { await flutterLocalNotificationsPlugin.initialize(initializationSettings); } - Future showNotification() async { - await flutterLocalNotificationsPlugin.show( - 0, - 'test', - 'test', -//schedule the notification to show after 2 seconds. - const NotificationDetails( - // Android details - android: AndroidNotificationDetails('main_channel', 'Main Channel', - channelDescription: "ashwin", - importance: Importance.max, - priority: Priority.max), - // iOS details - iOS: DarwinNotificationDetails( - sound: 'default.wav', - presentAlert: true, - presentBadge: true, - presentSound: true, - ), - ), - ); - } - Future setAllNotifications() async { List moodDates = await getDatesforMood(); List sleepDates = await getDatesforSleep(); diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index 0f73c79..a997d01 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -12,10 +12,6 @@ import 'elevated_card.dart'; class MoodForm extends StatelessWidget { const MoodForm({super.key}); - void submitForm(BuildContext context) { - var inputModel = context.watch(); - } - @override Widget build(BuildContext context) { var inputModel = context.watch(); From a0549069704a49fb7b841ce37cac926ae1f40fa8 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 23:24:23 +0100 Subject: [PATCH 11/40] Add relapse model and database --- lib/models/relapse.dart | 27 +++++++++++++++++++++++++++ lib/services/database_service.dart | 15 +++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 lib/models/relapse.dart diff --git a/lib/models/relapse.dart b/lib/models/relapse.dart new file mode 100644 index 0000000..78eeb12 --- /dev/null +++ b/lib/models/relapse.dart @@ -0,0 +1,27 @@ +import 'package:smoke_cess_app/interface/db_record.dart'; + +class Relapse implements DatabaseRecord { + final String _comment; + final DateTime _date; + + Relapse(this._comment, this._date); + + @override + factory Relapse.fromDatabase(Map map) { + DateTime date = DateTime.parse(map['date']); + return Relapse(map['comment'], date); + } + + @override + String toCSV() { + return "${_date.toIso8601String()}, {_wokeUpAt.minute}, $_comment"; + } + + @override + Map toMap() { + return { + 'comment': _comment, + 'date': _date.toIso8601String(), + }; + } +} diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart index 8dc8788..030a5af 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/relapse.dart'; import 'package:sqflite/sqflite.dart'; // ignore: depend_on_referenced_packages import 'package:path_provider/path_provider.dart'; @@ -53,6 +54,15 @@ class DatabaseService { return sleepList; } + Future> getRelapseRecords() async { + Database db = await instance.database; + var relapseRecords = await db.query('relapse'); + List relapseList = relapseRecords.isNotEmpty + ? relapseRecords.map((e) => Relapse.fromDatabase(e)).toList() + : []; + return relapseList; + } + Future addMood(Mood mood) async { Database db = await instance.database; return await db.insert('mood', mood.toMap()); @@ -62,6 +72,11 @@ class DatabaseService { Database db = await instance.database; return await db.insert('sleep', sleep.toMap()); } + + Future addRelapse(Relapse relapse) async { + Database db = await instance.database; + return await db.insert('relapse', relapse.toMap()); + } } String _createMoodTable = ''' From 0b57c14e05365544a294dcab9cbf9128b7022f59 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 23:29:47 +0100 Subject: [PATCH 12/40] Add relapse db part2 --- lib/mock/db_mock.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/mock/db_mock.dart b/lib/mock/db_mock.dart index a06f003..e7c60c3 100644 --- a/lib/mock/db_mock.dart +++ b/lib/mock/db_mock.dart @@ -1,5 +1,6 @@ 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'; import 'package:smoke_cess_app/services/database_service.dart'; import 'package:sqflite_common/sqlite_api.dart'; @@ -13,6 +14,7 @@ class DatabaseMock implements DatabaseService { final List _moodRecords = []; final List _sleepRecords = []; + final List _relapseRecords = []; final List _workoutRecords = []; @override @@ -27,6 +29,12 @@ class DatabaseMock implements DatabaseService { return Future.value(1); } + @override + Future addRelapse(Relapse relapse) { + _relapseRecords.add(relapse); + return Future.value(1); + } + @override // TODO: implement database Future get database => DatabaseService.instance.database; @@ -40,4 +48,9 @@ class DatabaseMock implements DatabaseService { Future> getSleepRecords() { return Future.value(_sleepRecords); } + + @override + Future> getRelapseRecords() { + return Future.value(_relapseRecords); + } } From a574e7f718f2fd94e064664b47d744898fa6abbb Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Sun, 26 Feb 2023 23:30:00 +0100 Subject: [PATCH 13/40] Add relapse form --- lib/pages/relapse_page.dart | 9 ++++++++- lib/widgets/relapse_form.dart | 31 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 lib/widgets/relapse_form.dart diff --git a/lib/pages/relapse_page.dart b/lib/pages/relapse_page.dart index 7710e10..75e007d 100644 --- a/lib/pages/relapse_page.dart +++ b/lib/pages/relapse_page.dart @@ -1,10 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/widgets/relapse_form.dart'; +import '../providers/input_provider.dart'; class RelapsePage extends StatelessWidget { const RelapsePage({super.key}); @override Widget build(BuildContext context) { - return const Center(child: Text('Hier werden Rückfälle dokumentiert')); + return Center( + child: ChangeNotifierProvider( + create: (context) => InputProvider(), + child: const RelapseForm(), + )); } } diff --git a/lib/widgets/relapse_form.dart b/lib/widgets/relapse_form.dart new file mode 100644 index 0000000..825e303 --- /dev/null +++ b/lib/widgets/relapse_form.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/widgets/text_formfield.dart'; + +import '../providers/input_provider.dart'; +import 'elevated_card.dart'; + +class RelapseForm extends StatelessWidget { + const RelapseForm({super.key}); + + @override + Widget build(BuildContext context) { + var inputModel = context.watch(); + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const ElevatedCard( + title: 'Beschreibe deinen Rückfall', + child: MyTextFormField('Beschreibe deinen Rückfall'), + ), + const SizedBox( + height: 80, + ), + ElevatedButton( + onPressed: () {}, + child: const Text('Speichern'), + ) + ], + ); + } +} From a2ed17fd5cb3babf9bf01a01c04c443612550fe9 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 02:27:42 +0100 Subject: [PATCH 14/40] Added SettingsProvider around MyApp --- lib/main.dart | 9 ++++++- lib/pages/main_page.dart | 2 ++ lib/pages/scanner_page.dart | 14 ++++++++++- lib/providers/settings_provider.dart | 35 ++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 lib/providers/settings_provider.dart diff --git a/lib/main.dart b/lib/main.dart index 2c2245d..a1cf5ac 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:smoke_cess_app/pages/main_page.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/settings_provider.dart'; void main() { // to ensure all the widgets are initialized. @@ -21,6 +23,11 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return const MaterialApp(title: _title, home: MyHomePage()); + return MaterialApp( + title: _title, + home: ChangeNotifierProvider( + create: (context) => SettingsProvider(), + child: const MyHomePage(), + )); } } diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 2af4f13..739f0d1 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:smoke_cess_app/pages/mood_page.dart'; import 'package:smoke_cess_app/pages/relapse_page.dart'; import 'package:smoke_cess_app/pages/scanner_page.dart'; import 'package:smoke_cess_app/pages/sleep_page.dart'; import 'package:smoke_cess_app/pages/interval_page.dart'; +import 'package:smoke_cess_app/providers/settings_provider.dart'; import 'package:smoke_cess_app/services/settings_service.dart'; import 'package:smoke_cess_app/widgets/missing_config_popup.dart'; diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index 7159694..82485f8 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.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/models/settings.dart'; import 'package:smoke_cess_app/services/database_service.dart'; import 'package:smoke_cess_app/services/json_service.dart'; @@ -8,6 +10,7 @@ import 'package:smoke_cess_app/services/settings_service.dart'; import 'package:smoke_cess_app/services/notification_service.dart'; import '../models/sleep.dart'; +import '../providers/settings_provider.dart'; import '../widgets/missing_config_popup.dart'; import '../globals.dart' as globals; @@ -23,6 +26,7 @@ class ScannerPageState extends State { @override Widget build(BuildContext context) { + var settings = context.watch(); return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -72,7 +76,10 @@ class ScannerPageState extends State { textStyle: const TextStyle(fontSize: 20)), onPressed: () { loadSettingsFromLocalJSON(); - NotificationService().setAllNotifications(); + Future.delayed(Duration(milliseconds: 100), () { + settings.initSettings(); + NotificationService().setAllNotifications(); + }); }, child: const Text('Read JSON'), ), @@ -84,12 +91,17 @@ class ScannerPageState extends State { 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()); + } }, child: const Text('Export'), ) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart new file mode 100644 index 0000000..71efb11 --- /dev/null +++ b/lib/providers/settings_provider.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:smoke_cess_app/services/settings_service.dart'; + +import '../models/settings.dart'; + +class SettingsProvider extends ChangeNotifier { + Settings? _settings; + + Settings? get settings => _settings; + + SettingsProvider() { + initSettings(); + } + + void initSettings() async { + int? group = await getGroup(); + List? relapseCategories = await getRelapseCategories(); + int? moodHours = await getMoodQueryHours(); + int? moodMinutes = await getMoodQueryMinutes(); + List? moodDays = await getMoodQueryDaysCategories(); + int? sleepHours = await getSleepQueryHours(); + int? sleepMinutes = await getSleepQueryMinutes(); + List? sleepDays = await getSleepQueryDaysCategories(); + int? chessHours = await getChessHours(); + int? chessMinutes = await getChessMinutes(); + + _settings = Settings( + group ?? 0, + relapseCategories, + QueryConfig(moodHours ?? 0, moodMinutes ?? 0, moodDays), + QueryConfig(sleepHours ?? 0, sleepMinutes ?? 0, sleepDays), + TimeConfig(chessHours ?? 0, chessMinutes ?? 0)); + notifyListeners(); + } +} From 63fdda819544f0cdf5f03f8514d5f1ae1dcee6f4 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 02:28:26 +0100 Subject: [PATCH 15/40] Added DropDown for Relapse --- lib/models/relapse.dart | 7 ++++--- lib/providers/input_provider.dart | 15 +++++++++++++++ lib/widgets/drop_down.dart | 30 ++++++++++++++++++++++++++++++ lib/widgets/relapse_form.dart | 7 ++++++- 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 lib/widgets/drop_down.dart diff --git a/lib/models/relapse.dart b/lib/models/relapse.dart index 78eeb12..2e65f51 100644 --- a/lib/models/relapse.dart +++ b/lib/models/relapse.dart @@ -1,20 +1,21 @@ import 'package:smoke_cess_app/interface/db_record.dart'; class Relapse implements DatabaseRecord { + final String _category; final String _comment; final DateTime _date; - Relapse(this._comment, this._date); + Relapse(this._category, this._comment, this._date); @override factory Relapse.fromDatabase(Map map) { DateTime date = DateTime.parse(map['date']); - return Relapse(map['comment'], date); + return Relapse(map['_category'], map['comment'], date); } @override String toCSV() { - return "${_date.toIso8601String()}, {_wokeUpAt.minute}, $_comment"; + return "${_date.toIso8601String()}, $_category, $_comment"; } @override diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart index 881ce2c..5fec37c 100644 --- a/lib/providers/input_provider.dart +++ b/lib/providers/input_provider.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.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'; import '../globals.dart' as globals; @@ -10,15 +11,22 @@ class InputProvider extends ChangeNotifier { 'wokeUpAt': const TimeOfDay(hour: 8, minute: 0), 'sleptAt': const TimeOfDay(hour: 22, minute: 0), }; + 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); } @@ -43,6 +51,13 @@ class InputProvider extends ChangeNotifier { _resetFields(); } + void saveRelapse() { + Relapse relapse = + Relapse(_relapseCategory, _textController.text, DateTime.now()); + globals.databaseService.addRelapse(relapse); + _resetFields(); + } + void saveSleep(String wokeUpKey, String sleptKey) { Sleep sleep = Sleep(_sliderValue.toInt(), _textController.text, DateTime.now(), getTimeEntry(sleptKey), getTimeEntry(wokeUpKey)); diff --git a/lib/widgets/drop_down.dart b/lib/widgets/drop_down.dart new file mode 100644 index 0000000..2df8b07 --- /dev/null +++ b/lib/widgets/drop_down.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import '../providers/input_provider.dart'; +import '../providers/settings_provider.dart'; + +class DropDown extends StatelessWidget { + const DropDown({super.key}); + + @override + Widget build(BuildContext context) { + var inputModel = context.watch(); + var settings = context.watch(); + return DropdownButtonFormField( + value: settings.settings?.relapseCategories?[0] ?? '', + icon: const Icon(Icons.arrow_downward), + elevation: 16, + style: const TextStyle(color: Colors.deepPurple), + onChanged: (String? value) { + inputModel.relapseCategory = value ?? ''; + }, + items: settings.settings?.relapseCategories + ?.map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ); + } +} diff --git a/lib/widgets/relapse_form.dart b/lib/widgets/relapse_form.dart index 825e303..b80fcba 100644 --- a/lib/widgets/relapse_form.dart +++ b/lib/widgets/relapse_form.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:smoke_cess_app/widgets/drop_down.dart'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; import '../providers/input_provider.dart'; @@ -14,6 +15,10 @@ class RelapseForm extends StatelessWidget { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ + const ElevatedCard( + title: 'Rückfallkategorie', + child: DropDown(), + ), const ElevatedCard( title: 'Beschreibe deinen Rückfall', child: MyTextFormField('Beschreibe deinen Rückfall'), @@ -22,7 +27,7 @@ class RelapseForm extends StatelessWidget { height: 80, ), ElevatedButton( - onPressed: () {}, + onPressed: () => inputModel.saveRelapse(), child: const Text('Speichern'), ) ], From cbf384f9e9851aa5e7907136aae9fc22a1aa7c17 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 02:35:17 +0100 Subject: [PATCH 16/40] Refactoring: DropDown more modular --- lib/widgets/drop_down.dart | 10 ++++------ lib/widgets/relapse_form.dart | 6 ++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/widgets/drop_down.dart b/lib/widgets/drop_down.dart index 2df8b07..ae4dec9 100644 --- a/lib/widgets/drop_down.dart +++ b/lib/widgets/drop_down.dart @@ -1,25 +1,23 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/input_provider.dart'; -import '../providers/settings_provider.dart'; class DropDown extends StatelessWidget { - const DropDown({super.key}); + final List _items; + const DropDown(this._items, {super.key}); @override Widget build(BuildContext context) { var inputModel = context.watch(); - var settings = context.watch(); return DropdownButtonFormField( - value: settings.settings?.relapseCategories?[0] ?? '', + value: _items[0], icon: const Icon(Icons.arrow_downward), elevation: 16, style: const TextStyle(color: Colors.deepPurple), onChanged: (String? value) { inputModel.relapseCategory = value ?? ''; }, - items: settings.settings?.relapseCategories - ?.map>((String value) { + items: _items.map>((String value) { return DropdownMenuItem( value: value, child: Text(value), diff --git a/lib/widgets/relapse_form.dart b/lib/widgets/relapse_form.dart index b80fcba..cc53a53 100644 --- a/lib/widgets/relapse_form.dart +++ b/lib/widgets/relapse_form.dart @@ -4,6 +4,7 @@ import 'package:smoke_cess_app/widgets/drop_down.dart'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; import '../providers/input_provider.dart'; +import '../providers/settings_provider.dart'; import 'elevated_card.dart'; class RelapseForm extends StatelessWidget { @@ -12,12 +13,13 @@ class RelapseForm extends StatelessWidget { @override Widget build(BuildContext context) { var inputModel = context.watch(); + var settings = context.watch(); return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const ElevatedCard( + ElevatedCard( title: 'Rückfallkategorie', - child: DropDown(), + child: DropDown(settings.settings?.relapseCategories ?? []), ), const ElevatedCard( title: 'Beschreibe deinen Rückfall', From ba558adecbe398b7989da9c3b97923308307efaa Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:07:46 +0100 Subject: [PATCH 17/40] Check for empty list --- lib/widgets/drop_down.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/drop_down.dart b/lib/widgets/drop_down.dart index ae4dec9..845c42c 100644 --- a/lib/widgets/drop_down.dart +++ b/lib/widgets/drop_down.dart @@ -10,7 +10,7 @@ class DropDown extends StatelessWidget { Widget build(BuildContext context) { var inputModel = context.watch(); return DropdownButtonFormField( - value: _items[0], + value: _items.isEmpty ? null : _items[0], icon: const Icon(Icons.arrow_downward), elevation: 16, style: const TextStyle(color: Colors.deepPurple), From b1c6288b2b296401174bc360731a7bf3a9248138 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:08:38 +0100 Subject: [PATCH 18/40] Add initilized field for Settingsprovider --- lib/providers/settings_provider.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 71efb11..d7a2e0f 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -5,8 +5,10 @@ import '../models/settings.dart'; class SettingsProvider extends ChangeNotifier { Settings? _settings; + bool _initialized = false; Settings? get settings => _settings; + bool get initialized => _initialized; SettingsProvider() { initSettings(); @@ -30,6 +32,7 @@ class SettingsProvider extends ChangeNotifier { QueryConfig(moodHours ?? 0, moodMinutes ?? 0, moodDays), QueryConfig(sleepHours ?? 0, sleepMinutes ?? 0, sleepDays), TimeConfig(chessHours ?? 0, chessMinutes ?? 0)); + _initialized = group != 0 ? true : false; notifyListeners(); } } From 28e46d1806a978ea27ab6b4cb80d841e17cf47ee Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:19:56 +0100 Subject: [PATCH 19/40] Settingsfields nullable --- lib/models/settings.dart | 14 +++++++------- lib/providers/settings_provider.dart | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 0e7cf30..7dea33f 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -1,10 +1,10 @@ import 'package:smoke_cess_app/services/json_service.dart'; class Settings { - final int group; + final int? group; final List? relapseCategories; - final QueryConfig moodQuery; - final QueryConfig sleepQuery; + final QueryConfig? moodQuery; + final QueryConfig? sleepQuery; final TimeConfig? chessTime; Settings(this.group, this.relapseCategories, this.moodQuery, this.sleepQuery, @@ -21,8 +21,8 @@ class Settings { } class QueryConfig { - final int hours; - final int minutes; + final int? hours; + final int? minutes; final List? days; QueryConfig(this.hours, this.minutes, this.days); @@ -34,8 +34,8 @@ class QueryConfig { } class TimeConfig { - final int hours; - final int minutes; + final int? hours; + final int? minutes; TimeConfig(this.hours, this.minutes); diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index d7a2e0f..5283808 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -27,12 +27,12 @@ class SettingsProvider extends ChangeNotifier { int? chessMinutes = await getChessMinutes(); _settings = Settings( - group ?? 0, + group, relapseCategories, - QueryConfig(moodHours ?? 0, moodMinutes ?? 0, moodDays), - QueryConfig(sleepHours ?? 0, sleepMinutes ?? 0, sleepDays), - TimeConfig(chessHours ?? 0, chessMinutes ?? 0)); - _initialized = group != 0 ? true : false; + QueryConfig(moodHours, moodMinutes, moodDays), + QueryConfig(sleepHours, sleepMinutes, sleepDays), + TimeConfig(chessHours, chessMinutes)); + _initialized = group != null ? true : false; notifyListeners(); } } From d46dd3ff7b31637f7bfb45df3059c460ac4f884e Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:21:57 +0100 Subject: [PATCH 20/40] Make Settingsfields nullable part 2 --- lib/services/settings_service.dart | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 52028bd..c046cd2 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -52,16 +52,16 @@ Future loadSettingsFromLocalJSON() async { } void saveSettings(Settings settings) { - _setIntSetting('group', settings.group); + _setIntSetting('group', settings.group!); _setStringListSetting('relapse_categories', settings.relapseCategories!); - _setStringListSetting('mood_query_days', settings.moodQuery.days!); - _setIntSetting('mood_query_hours', settings.moodQuery.hours); - _setIntSetting('mood_query_minutes', settings.moodQuery.minutes); - _setStringListSetting('sleep_query_days', settings.sleepQuery.days!); - _setIntSetting('sleep_query_hours', settings.sleepQuery.hours); - _setIntSetting('sleep_query_minutes', settings.sleepQuery.minutes); + _setStringListSetting('mood_query_days', settings.moodQuery!.days!); + _setIntSetting('mood_query_hours', settings.moodQuery!.hours!); + _setIntSetting('mood_query_minutes', settings.moodQuery!.minutes!); + _setStringListSetting('sleep_query_days', settings.sleepQuery!.days!); + _setIntSetting('sleep_query_hours', settings.sleepQuery!.hours!); + _setIntSetting('sleep_query_minutes', settings.sleepQuery!.minutes!); if (settings.chessTime != null) { - _setIntSetting('chess_hours', settings.chessTime!.hours); - _setIntSetting('chess_minutes', settings.chessTime!.minutes); + _setIntSetting('chess_hours', settings.chessTime!.hours!); + _setIntSetting('chess_minutes', settings.chessTime!.minutes!); } } From 21470da038398f4184aeaa90d632f4654f02024b Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:27:45 +0100 Subject: [PATCH 21/40] outsource loadsettings to settings_service --- lib/providers/settings_provider.dart | 20 ++------------------ lib/services/settings_service.dart | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 5283808..f51c5e1 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -15,24 +15,8 @@ class SettingsProvider extends ChangeNotifier { } void initSettings() async { - int? group = await getGroup(); - List? relapseCategories = await getRelapseCategories(); - int? moodHours = await getMoodQueryHours(); - int? moodMinutes = await getMoodQueryMinutes(); - List? moodDays = await getMoodQueryDaysCategories(); - int? sleepHours = await getSleepQueryHours(); - int? sleepMinutes = await getSleepQueryMinutes(); - List? sleepDays = await getSleepQueryDaysCategories(); - int? chessHours = await getChessHours(); - int? chessMinutes = await getChessMinutes(); - - _settings = Settings( - group, - relapseCategories, - QueryConfig(moodHours, moodMinutes, moodDays), - QueryConfig(sleepHours, sleepMinutes, sleepDays), - TimeConfig(chessHours, chessMinutes)); - _initialized = group != null ? true : false; + _settings = await loadSettings(); + _initialized = _settings != null ? true : false; notifyListeners(); } } diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index c046cd2..d72c245 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -65,3 +65,23 @@ void saveSettings(Settings settings) { _setIntSetting('chess_minutes', settings.chessTime!.minutes!); } } + +Future loadSettings() async { + int? group = await getGroup(); + List? relapseCategories = await getRelapseCategories(); + int? moodHours = await getMoodQueryHours(); + int? moodMinutes = await getMoodQueryMinutes(); + List? moodDays = await getMoodQueryDaysCategories(); + int? sleepHours = await getSleepQueryHours(); + int? sleepMinutes = await getSleepQueryMinutes(); + List? sleepDays = await getSleepQueryDaysCategories(); + int? chessHours = await getChessHours(); + int? chessMinutes = await getChessMinutes(); + + return Settings( + group, + relapseCategories, + QueryConfig(moodHours, moodMinutes, moodDays), + QueryConfig(sleepHours, sleepMinutes, sleepDays), + TimeConfig(chessHours, chessMinutes)); +} From 9c4a5e0fbb69921a967f92037a4891642ce5b2ab Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:39:42 +0100 Subject: [PATCH 22/40] return null if settings cant be correctly loaded --- lib/models/settings.dart | 2 +- lib/services/settings_service.dart | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 7dea33f..83fad43 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -1,7 +1,7 @@ import 'package:smoke_cess_app/services/json_service.dart'; class Settings { - final int? group; + final int group; final List? relapseCategories; final QueryConfig? moodQuery; final QueryConfig? sleepQuery; diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index d72c245..13de7f6 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -66,7 +66,7 @@ void saveSettings(Settings settings) { } } -Future loadSettings() async { +Future loadSettings() async { int? group = await getGroup(); List? relapseCategories = await getRelapseCategories(); int? moodHours = await getMoodQueryHours(); @@ -78,10 +78,13 @@ Future loadSettings() async { int? chessHours = await getChessHours(); int? chessMinutes = await getChessMinutes(); - return Settings( - group, - relapseCategories, - QueryConfig(moodHours, moodMinutes, moodDays), - QueryConfig(sleepHours, sleepMinutes, sleepDays), - TimeConfig(chessHours, chessMinutes)); + if (group != null) { + return Settings( + group, + relapseCategories, + QueryConfig(moodHours, moodMinutes, moodDays), + QueryConfig(sleepHours, sleepMinutes, sleepDays), + TimeConfig(chessHours, chessMinutes)); + } + return null; } From 395749618b47da83d7e0f20e482a96e57fda5fbf Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:40:24 +0100 Subject: [PATCH 23/40] quickfix --- lib/services/settings_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 13de7f6..8c7e7a7 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -52,7 +52,7 @@ Future loadSettingsFromLocalJSON() async { } void saveSettings(Settings settings) { - _setIntSetting('group', settings.group!); + _setIntSetting('group', settings.group); _setStringListSetting('relapse_categories', settings.relapseCategories!); _setStringListSetting('mood_query_days', settings.moodQuery!.days!); _setIntSetting('mood_query_hours', settings.moodQuery!.hours!); From 95915e759bd008638c54942f9e6875eba604a2a2 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 11:57:55 +0100 Subject: [PATCH 24/40] Start Refactoring mainpage using Settingsprovider --- lib/pages/main_page.dart | 13 +++++++------ lib/widgets/relapse_form.dart | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 739f0d1..2e6a9f8 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -18,7 +18,7 @@ class MyHomePage extends StatefulWidget { class MyHomePageState extends State { int _selectedIndex = 4; - int? _gruppe; + bool _isConfigured = false; final List _titles = [ 'Stimmung', @@ -35,11 +35,9 @@ class MyHomePageState extends State { ScannerPage(), ]; - Future _onItemTapped(int index) async { - _gruppe = await getGroup(); - bool isConfigured = _gruppe != null; + void _onItemTapped(int index) { setState(() { - isConfigured + _isConfigured ? _selectedIndex = index : showDialog( context: context, @@ -54,10 +52,13 @@ class MyHomePageState extends State { @override Widget build(BuildContext context) { + var settingsModel = context.watch(); + var group = settingsModel.settings?.group; + _isConfigured = settingsModel.initialized; return Scaffold( appBar: AppBar( title: Text( - '${_titles[_selectedIndex]} ${_gruppe != null ? "Gruppe $_gruppe" : ""}')), + '${_titles[_selectedIndex]} ${_isConfigured ? "Gruppe $group" : ""}')), body: _widgetOptions.elementAt(_selectedIndex), bottomNavigationBar: NavigationBar( onDestinationSelected: _onItemTapped, diff --git a/lib/widgets/relapse_form.dart b/lib/widgets/relapse_form.dart index cc53a53..a00ab31 100644 --- a/lib/widgets/relapse_form.dart +++ b/lib/widgets/relapse_form.dart @@ -13,13 +13,13 @@ class RelapseForm extends StatelessWidget { @override Widget build(BuildContext context) { var inputModel = context.watch(); - var settings = context.watch(); + var settingsModel = context.watch(); return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedCard( title: 'Rückfallkategorie', - child: DropDown(settings.settings?.relapseCategories ?? []), + child: DropDown(settingsModel.settings?.relapseCategories ?? []), ), const ElevatedCard( title: 'Beschreibe deinen Rückfall', From 01d62a291c7929846b0fea08bddadf4e264e7ae6 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 14:57:56 +0100 Subject: [PATCH 25/40] refactoring mainpage --- lib/pages/main_page.dart | 59 +++++++----------------------------- lib/pages/pages_service.dart | 32 +++++++++++++++++++ 2 files changed, 43 insertions(+), 48 deletions(-) create mode 100644 lib/pages/pages_service.dart diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 2e6a9f8..5a2af86 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -1,12 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/pages/mood_page.dart'; -import 'package:smoke_cess_app/pages/relapse_page.dart'; -import 'package:smoke_cess_app/pages/scanner_page.dart'; -import 'package:smoke_cess_app/pages/sleep_page.dart'; -import 'package:smoke_cess_app/pages/interval_page.dart'; +import 'package:smoke_cess_app/pages/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; -import 'package:smoke_cess_app/services/settings_service.dart'; import 'package:smoke_cess_app/widgets/missing_config_popup.dart'; class MyHomePage extends StatefulWidget { @@ -20,21 +15,6 @@ class MyHomePageState extends State { int _selectedIndex = 4; bool _isConfigured = false; - final List _titles = [ - 'Stimmung', - 'Schlaf', - 'Timer', - 'Rückfall', - 'Scanner' - ]; - static const List _widgetOptions = [ - MoodPage(), - SleepPage(), - IntervalTimerPage(), - RelapsePage(), - ScannerPage(), - ]; - void _onItemTapped(int index) { setState(() { _isConfigured @@ -58,34 +38,17 @@ class MyHomePageState extends State { return Scaffold( appBar: AppBar( title: Text( - '${_titles[_selectedIndex]} ${_isConfigured ? "Gruppe $group" : ""}')), - body: _widgetOptions.elementAt(_selectedIndex), + '${pages.keys.elementAt(_selectedIndex)} ${_isConfigured ? "Gruppe $group" : ""}')), + body: pages.values.elementAt(_selectedIndex)['page'], bottomNavigationBar: NavigationBar( - onDestinationSelected: _onItemTapped, - selectedIndex: _selectedIndex, - destinations: const [ - NavigationDestination( - icon: Icon(Icons.mood_outlined, color: Colors.black), - label: 'Stimmung'), - NavigationDestination( - icon: Icon(Icons.bedtime_outlined, color: Colors.black), - label: 'Schlaf'), - NavigationDestination( - icon: Icon( - Icons.timer_outlined, - color: Colors.black, - ), - label: 'Timer'), - NavigationDestination( - icon: Icon(Icons.smoke_free_outlined, color: Colors.black), - label: 'Rückfall'), - NavigationDestination( - icon: Icon(Icons.camera_alt_outlined, color: Colors.black), - label: 'Settings'), - ], - - //onTap: _onItemTapped, - ), + onDestinationSelected: _onItemTapped, + selectedIndex: _selectedIndex, + destinations: pages.keys.map((key) { + return NavigationDestination( + icon: pages[key]!['icon'] ?? + const Icon(Icons.disabled_by_default), + label: key); + }).toList()), ); } } diff --git a/lib/pages/pages_service.dart b/lib/pages/pages_service.dart new file mode 100644 index 0000000..e530550 --- /dev/null +++ b/lib/pages/pages_service.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'interval_page.dart'; +import 'mood_page.dart'; +import 'relapse_page.dart'; +import 'scanner_page.dart'; +import 'sleep_page.dart'; + +const pages = { + 'Stimmung': { + 'page': MoodPage(), + 'icon': Icon(Icons.mood_outlined, color: Colors.black) + }, + 'Schlaf': { + 'page': SleepPage(), + 'icon': Icon(Icons.bedtime_outlined, color: Colors.black) + }, + 'Timer': { + 'page': IntervalTimerPage(), + 'icon': Icon(Icons.smoke_free_outlined, color: Colors.black) + }, + 'Rückfall': { + 'page': RelapsePage(), + 'icon': Icon( + Icons.timer_outlined, + color: Colors.black, + ) + }, + 'Scanner': { + 'page': ScannerPage(), + 'icon': Icon(Icons.camera_alt_outlined, color: Colors.black) + }, +}; From 7a402e464cfab04be24f5f8ff223b648a81950ac Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 15:19:03 +0100 Subject: [PATCH 26/40] quickfix relapse model --- lib/models/relapse.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/models/relapse.dart b/lib/models/relapse.dart index 2e65f51..0271d31 100644 --- a/lib/models/relapse.dart +++ b/lib/models/relapse.dart @@ -10,7 +10,7 @@ class Relapse implements DatabaseRecord { @override factory Relapse.fromDatabase(Map map) { DateTime date = DateTime.parse(map['date']); - return Relapse(map['_category'], map['comment'], date); + return Relapse(map['category'], map['comment'], date); } @override @@ -21,6 +21,7 @@ class Relapse implements DatabaseRecord { @override Map toMap() { return { + 'category': _category, 'comment': _comment, 'date': _date.toIso8601String(), }; From d4018826719b2ec8cd040470ed772854bec4f3d6 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 17:00:28 +0100 Subject: [PATCH 27/40] Refactoring ScannerPage --- lib/pages/scanner_page.dart | 100 +++++++++--------------------------- lib/widgets/scanner.dart | 82 +++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 75 deletions(-) create mode 100644 lib/widgets/scanner.dart diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index 82485f8..7e9df8f 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -1,108 +1,58 @@ import 'package:flutter/material.dart'; -import 'package:mobile_scanner/mobile_scanner.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/models/settings.dart'; -import 'package:smoke_cess_app/services/database_service.dart'; -import 'package:smoke_cess_app/services/json_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 '../widgets/missing_config_popup.dart'; import '../globals.dart' as globals; -class ScannerPage extends StatefulWidget { +class ScannerPage extends StatelessWidget { const ScannerPage({super.key}); - @override - State createState() => ScannerPageState(); -} + void export() async { + 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()); + } + } -class ScannerPageState extends State { - bool scanning = false; + void loadJSON(BuildContext context) async { + var settingsModel = context.read(); + await loadSettingsFromLocalJSON(); + settingsModel.initSettings(); + NotificationService().setAllNotifications(); + } @override Widget build(BuildContext context) { - var settings = context.watch(); return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - scanning - ? Expanded( - child: MobileScanner( - fit: BoxFit.contain, - controller: MobileScannerController( - detectionTimeoutMs: 2000, - ), - onDetect: (capture) { - //TODO Errorhandling!! - final List barcodes = capture.barcodes; - for (final barcode in barcodes) { - if (barcode.rawValue != null) { - String qrText = barcode.rawValue!; - Map json = stringToJSON(qrText); - Settings settings = Settings.fromJson(json); - saveSettings(settings); - setState(() { - scanning = false; - showDialog( - context: context, - builder: (BuildContext context) { - return MissingConfigPopup( - title: 'Konfiguration erfolgreich', - text: 'Du gehörst zu Gruppe ${settings.group}', - ); - }); - }); - } - } - }, - )) - : ElevatedButton( - style: ElevatedButton.styleFrom( - textStyle: const TextStyle(fontSize: 20)), - onPressed: () { - setState(() => scanning = true); - }, - child: const Text('Scan QR Code'), - ), + const MyScanner(), const SizedBox(height: 30), ElevatedButton( style: ElevatedButton.styleFrom( textStyle: const TextStyle(fontSize: 20)), - onPressed: () { - loadSettingsFromLocalJSON(); - Future.delayed(Duration(milliseconds: 100), () { - settings.initSettings(); - NotificationService().setAllNotifications(); - }); - }, + onPressed: () => loadJSON(context), child: const Text('Read JSON'), ), const SizedBox(height: 30), ElevatedButton( style: ElevatedButton.styleFrom( textStyle: const TextStyle(fontSize: 20)), - onPressed: () async { - 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()); - } - }, + onPressed: export, child: const Text('Export'), ) ], diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart new file mode 100644 index 0000000..f8e22d1 --- /dev/null +++ b/lib/widgets/scanner.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; +import 'package:smoke_cess_app/models/settings.dart'; +import 'package:smoke_cess_app/services/json_service.dart'; +import 'package:smoke_cess_app/services/settings_service.dart'; +import '../widgets/missing_config_popup.dart'; + +class MyScanner extends StatefulWidget { + const MyScanner({super.key}); + + @override + State createState() => MyScannerState(); +} + +class MyScannerState extends State { + bool scanning = false; + + void handleError(String error) { + setState(() { + scanning = false; + showDialog( + context: context, + builder: (BuildContext context) { + return MissingConfigPopup( + title: 'Scanfehler', + text: + 'Beim Scanen gab es folgende Meldung: $error. Bitte erneut versuchen', + ); + }); + }); + } + + void handleSucces(String group) { + setState(() { + scanning = false; + showDialog( + context: context, + builder: (BuildContext context) { + return MissingConfigPopup( + title: 'Konfiguration erfolgreich', + text: 'Du gehörst zu Gruppe $group', + ); + }); + }); + } + + void onDetect(capture) { + try { + final List barcodes = capture.barcodes; + for (final barcode in barcodes) { + if (barcode.rawValue != null) { + String qrText = barcode.rawValue!; + Map json = stringToJSON(qrText); + Settings settings = Settings.fromJson(json); + saveSettings(settings); + } + } + } catch (e) { + handleError(e.toString()); + } + } + + @override + Widget build(BuildContext context) { + return scanning + ? Expanded( + child: MobileScanner( + fit: BoxFit.contain, + controller: MobileScannerController( + detectionTimeoutMs: 2000, + ), + onDetect: onDetect)) + : ElevatedButton( + style: ElevatedButton.styleFrom( + textStyle: const TextStyle(fontSize: 20)), + onPressed: () { + setState(() => scanning = true); + }, + child: const Text('Scan QR Code'), + ); + } +} From 3909bfd66cfc53ea2d4ffcdaeab38b486065bbe1 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 17:01:44 +0100 Subject: [PATCH 28/40] forgot to add handlesuccess --- lib/widgets/scanner.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index f8e22d1..76ec40a 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -30,7 +30,7 @@ class MyScannerState extends State { }); } - void handleSucces(String group) { + void handleSucces(int group) { setState(() { scanning = false; showDialog( @@ -53,6 +53,7 @@ class MyScannerState extends State { Map json = stringToJSON(qrText); Settings settings = Settings.fromJson(json); saveSettings(settings); + handleSucces(settings.group); } } } catch (e) { From 074ebb1871d2ed0306542567eeb9570f9fc99002 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 17:09:58 +0100 Subject: [PATCH 29/40] finally instead of catch to secure if nothing is found an message is deplayed --- lib/widgets/scanner.dart | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index 76ec40a..b1aff7d 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -15,22 +15,26 @@ class MyScanner extends StatefulWidget { class MyScannerState extends State { bool scanning = false; - void handleError(String error) { + void handleError() { setState(() { scanning = false; showDialog( context: context, builder: (BuildContext context) { - return MissingConfigPopup( + return const MissingConfigPopup( title: 'Scanfehler', text: - 'Beim Scanen gab es folgende Meldung: $error. Bitte erneut versuchen', + 'Beim Scanen gab es wohl einen Fehler. Bitte erneut versuchen', ); }); }); } - void handleSucces(int group) { + void handleSucces(String? rawValue) { + String qrText = rawValue!; + Map json = stringToJSON(qrText); + Settings settings = Settings.fromJson(json); + saveSettings(settings); setState(() { scanning = false; showDialog( @@ -38,7 +42,7 @@ class MyScannerState extends State { builder: (BuildContext context) { return MissingConfigPopup( title: 'Konfiguration erfolgreich', - text: 'Du gehörst zu Gruppe $group', + text: 'Du gehörst zu Gruppe ${settings.group}', ); }); }); @@ -49,15 +53,11 @@ class MyScannerState extends State { final List barcodes = capture.barcodes; for (final barcode in barcodes) { if (barcode.rawValue != null) { - String qrText = barcode.rawValue!; - Map json = stringToJSON(qrText); - Settings settings = Settings.fromJson(json); - saveSettings(settings); - handleSucces(settings.group); + handleSucces(barcode.rawValue); } } - } catch (e) { - handleError(e.toString()); + } finally { + handleError(); } } From b96604103d4855c4c305d0d7c27067f45a48daca Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 17:15:34 +0100 Subject: [PATCH 30/40] Added initating Settings from QR-Code --- lib/widgets/scanner.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index b1aff7d..a97e14d 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -1,8 +1,11 @@ import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; +import 'package:provider/provider.dart'; import 'package:smoke_cess_app/models/settings.dart'; import 'package:smoke_cess_app/services/json_service.dart'; import 'package:smoke_cess_app/services/settings_service.dart'; +import '../providers/settings_provider.dart'; +import '../services/notification_service.dart'; import '../widgets/missing_config_popup.dart'; class MyScanner extends StatefulWidget { @@ -35,6 +38,9 @@ class MyScannerState extends State { Map json = stringToJSON(qrText); Settings settings = Settings.fromJson(json); saveSettings(settings); + var settingsModel = context.read(); + settingsModel.initSettings(); + NotificationService().setAllNotifications(); setState(() { scanning = false; showDialog( From 6a6b44a5557f5870ee13632dca422dd16a24a960 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 17:27:01 +0100 Subject: [PATCH 31/40] Moved pageservice to service folder --- lib/pages/main_page.dart | 2 +- lib/{pages => services}/pages_service.dart | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) rename lib/{pages => services}/pages_service.dart (77%) diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 5a2af86..48897d0 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smoke_cess_app/pages/pages_service.dart'; +import 'package:smoke_cess_app/services/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; import 'package:smoke_cess_app/widgets/missing_config_popup.dart'; diff --git a/lib/pages/pages_service.dart b/lib/services/pages_service.dart similarity index 77% rename from lib/pages/pages_service.dart rename to lib/services/pages_service.dart index e530550..c3b1bd8 100644 --- a/lib/pages/pages_service.dart +++ b/lib/services/pages_service.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import 'interval_page.dart'; -import 'mood_page.dart'; -import 'relapse_page.dart'; -import 'scanner_page.dart'; -import 'sleep_page.dart'; +import '../pages/interval_page.dart'; +import '../pages/mood_page.dart'; +import '../pages/relapse_page.dart'; +import '../pages/scanner_page.dart'; +import '../pages/sleep_page.dart'; const pages = { 'Stimmung': { From 2c96f711b64e4b15a3caeded35a8a1c24d2c9f85 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 19:29:22 +0100 Subject: [PATCH 32/40] Add SingleChildScrollView --- lib/pages/main_page.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 5a2af86..65024a9 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -39,7 +39,8 @@ class MyHomePageState extends State { appBar: AppBar( title: Text( '${pages.keys.elementAt(_selectedIndex)} ${_isConfigured ? "Gruppe $group" : ""}')), - body: pages.values.elementAt(_selectedIndex)['page'], + body: SingleChildScrollView( + child: pages.values.elementAt(_selectedIndex)['page']), bottomNavigationBar: NavigationBar( onDestinationSelected: _onItemTapped, selectedIndex: _selectedIndex, From d18d48493259c78533ed002dffeb0eb5e2908eb1 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 19:34:11 +0100 Subject: [PATCH 33/40] Center every page --- lib/pages/main_page.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 65024a9..f373582 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -39,8 +39,9 @@ class MyHomePageState extends State { appBar: AppBar( title: Text( '${pages.keys.elementAt(_selectedIndex)} ${_isConfigured ? "Gruppe $group" : ""}')), - body: SingleChildScrollView( - child: pages.values.elementAt(_selectedIndex)['page']), + body: Center( + child: SingleChildScrollView( + child: pages.values.elementAt(_selectedIndex)['page'])), bottomNavigationBar: NavigationBar( onDestinationSelected: _onItemTapped, selectedIndex: _selectedIndex, From 5b411ef6bf02f7a4deb1a6abf0c480c6baa8cf12 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 20:02:15 +0100 Subject: [PATCH 34/40] Add AwesomeDialog --- lib/pages/main_page.dart | 14 ++++++-------- lib/providers/input_provider.dart | 4 ++-- lib/widgets/mood_form.dart | 5 ++--- lib/widgets/submit_form_button.dart | 22 +++++++++++++++++++--- pubspec.lock | 21 +++++++++++++++++++++ pubspec.yaml | 1 + 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index f373582..7a5df4a 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -1,8 +1,8 @@ +import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smoke_cess_app/pages/pages_service.dart'; import 'package:smoke_cess_app/providers/settings_provider.dart'; -import 'package:smoke_cess_app/widgets/missing_config_popup.dart'; class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @@ -19,14 +19,12 @@ class MyHomePageState extends State { setState(() { _isConfigured ? _selectedIndex = index - : showDialog( + : AwesomeDialog( context: context, - builder: (BuildContext context) { - return const MissingConfigPopup( - title: 'Fehlende Konfiguration', - text: 'Bitte QR Code Scannen!', - ); - }); + dialogType: DialogType.info, + title: 'Fehlende Konfiguration', + desc: 'Bitte QR Code Scannen!', + ).show(); }); } diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart index 5fec37c..1f4fefd 100644 --- a/lib/providers/input_provider.dart +++ b/lib/providers/input_provider.dart @@ -44,11 +44,11 @@ class InputProvider extends ChangeNotifier { notifyListeners(); } - void saveMood() { + Future saveMood() { Mood mood = Mood(_sliderValue.toInt(), _textController.text, DateTime.now()); - globals.databaseService.addMood(mood); _resetFields(); + return globals.databaseService.addMood(mood); } void saveRelapse() { diff --git a/lib/widgets/mood_form.dart b/lib/widgets/mood_form.dart index a997d01..b9a0e05 100644 --- a/lib/widgets/mood_form.dart +++ b/lib/widgets/mood_form.dart @@ -30,9 +30,8 @@ class MoodForm extends StatelessWidget { const SizedBox( height: 80, ), - ElevatedButton( - onPressed: () => inputModel.saveMood(), - child: const Text('Speichern'), + SubmitFormButton( + submitCallback: inputModel.saveMood, ) ], ); diff --git a/lib/widgets/submit_form_button.dart b/lib/widgets/submit_form_button.dart index 58f28c8..3242b18 100644 --- a/lib/widgets/submit_form_button.dart +++ b/lib/widgets/submit_form_button.dart @@ -1,15 +1,31 @@ +import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; class SubmitFormButton extends StatelessWidget { - final VoidCallback submitCallback; - const SubmitFormButton(this.submitCallback, {super.key}); + final Future Function() submitCallback; + const SubmitFormButton({super.key, required this.submitCallback}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( - onPressed: submitCallback, + 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(); + }, child: const Text('Speichern'), ), ); diff --git a/pubspec.lock b/pubspec.lock index b899dd9..08b0b74 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -64,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.3" + awesome_dialog: + dependency: "direct main" + description: + name: awesome_dialog + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" boolean_selector: dependency: transitive description: @@ -177,6 +184,13 @@ packages: description: flutter source: sdk version: "0.0.0" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" http: dependency: transitive description: @@ -324,6 +338,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.0.5" + rive: + dependency: transitive + description: + name: rive + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.1" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 9204ca9..5c61553 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ dependencies: path: path_provider: ^2.0.12 provider: ^6.0.5 + awesome_dialog: ^3.0.2 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. From 591317df260fdef4ed67f3637f657b0f061db176 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 20:09:11 +0100 Subject: [PATCH 35/40] Added Submitformbutton to sleep and relapse --- lib/providers/input_provider.dart | 8 ++++---- lib/widgets/relapse_form.dart | 6 ++---- lib/widgets/sleep_form.dart | 7 ++++--- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/providers/input_provider.dart b/lib/providers/input_provider.dart index 1f4fefd..a61514f 100644 --- a/lib/providers/input_provider.dart +++ b/lib/providers/input_provider.dart @@ -51,17 +51,17 @@ class InputProvider extends ChangeNotifier { return globals.databaseService.addMood(mood); } - void saveRelapse() { + Future saveRelapse() { Relapse relapse = Relapse(_relapseCategory, _textController.text, DateTime.now()); - globals.databaseService.addRelapse(relapse); _resetFields(); + return globals.databaseService.addRelapse(relapse); } - void saveSleep(String wokeUpKey, String sleptKey) { + Future saveSleep(String wokeUpKey, String sleptKey) { Sleep sleep = Sleep(_sliderValue.toInt(), _textController.text, DateTime.now(), getTimeEntry(sleptKey), getTimeEntry(wokeUpKey)); - globals.databaseService.addSleep(sleep); _resetFields(); + return globals.databaseService.addSleep(sleep); } } diff --git a/lib/widgets/relapse_form.dart b/lib/widgets/relapse_form.dart index a00ab31..88e555c 100644 --- a/lib/widgets/relapse_form.dart +++ b/lib/widgets/relapse_form.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/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'; @@ -28,10 +29,7 @@ class RelapseForm extends StatelessWidget { const SizedBox( height: 80, ), - ElevatedButton( - onPressed: () => inputModel.saveRelapse(), - child: const Text('Speichern'), - ) + SubmitFormButton(submitCallback: inputModel.saveRelapse) ], ); } diff --git a/lib/widgets/sleep_form.dart b/lib/widgets/sleep_form.dart index 5cb7352..8b4389c 100644 --- a/lib/widgets/sleep_form.dart +++ b/lib/widgets/sleep_form.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/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'; import 'package:smoke_cess_app/widgets/text_formfield.dart'; import 'package:smoke_cess_app/widgets/timepicker.dart'; @@ -41,9 +42,9 @@ class SleepForm extends StatelessWidget { const SizedBox( height: 80, ), - ElevatedButton( - onPressed: () => inputModel.saveSleep(wokeUpKey, sleptKey), - child: const Text('Speichern')) + SubmitFormButton( + submitCallback: () => inputModel.saveSleep(wokeUpKey, sleptKey), + ) ], ); } From bb96aaeef9544f78a354bcad9b927703dbc89423 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 20:30:24 +0100 Subject: [PATCH 36/40] Added new alerts to scanner page --- lib/pages/scanner_page.dart | 7 +++++++ lib/widgets/scanner.dart | 30 +++++++++++++----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/pages/scanner_page.dart b/lib/pages/scanner_page.dart index 7e9df8f..29cf8a7 100644 --- a/lib/pages/scanner_page.dart +++ b/lib/pages/scanner_page.dart @@ -1,3 +1,4 @@ +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'; @@ -32,6 +33,12 @@ 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(); } @override diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index a97e14d..0f65b74 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -1,3 +1,4 @@ +import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:provider/provider.dart'; @@ -21,15 +22,12 @@ class MyScannerState extends State { void handleError() { setState(() { scanning = false; - showDialog( - context: context, - builder: (BuildContext context) { - return const MissingConfigPopup( - title: 'Scanfehler', - text: - 'Beim Scanen gab es wohl einen Fehler. Bitte erneut versuchen', - ); - }); + AwesomeDialog( + context: context, + dialogType: DialogType.error, + title: 'Upss', + desc: 'Da muss etwas schiefgelaufen sein!', + ).show(); }); } @@ -43,14 +41,12 @@ class MyScannerState extends State { NotificationService().setAllNotifications(); setState(() { scanning = false; - showDialog( - context: context, - builder: (BuildContext context) { - return MissingConfigPopup( - title: 'Konfiguration erfolgreich', - text: 'Du gehörst zu Gruppe ${settings.group}', - ); - }); + AwesomeDialog( + context: context, + dialogType: DialogType.success, + title: 'Geschafft', + desc: 'Der Code wurde erfolgreich gescannt!', + ).show(); }); } From afb63adb5c4e58727a78302bbdde1e03bff952be Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 20:34:14 +0100 Subject: [PATCH 37/40] Make sure to leave onDetect when successful --- lib/widgets/scanner.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index 0f65b74..a8b1b2b 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -55,7 +55,7 @@ class MyScannerState extends State { final List barcodes = capture.barcodes; for (final barcode in barcodes) { if (barcode.rawValue != null) { - handleSucces(barcode.rawValue); + return handleSucces(barcode.rawValue); } } } finally { From 88ec309f555e6c12c02cde416212aa8889ff48ff Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 20:36:59 +0100 Subject: [PATCH 38/40] Remove Errorhandling from scanner --- lib/widgets/scanner.dart | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index a8b1b2b..f7a5089 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -19,18 +19,6 @@ class MyScanner extends StatefulWidget { class MyScannerState extends State { bool scanning = false; - void handleError() { - setState(() { - scanning = false; - AwesomeDialog( - context: context, - dialogType: DialogType.error, - title: 'Upss', - desc: 'Da muss etwas schiefgelaufen sein!', - ).show(); - }); - } - void handleSucces(String? rawValue) { String qrText = rawValue!; Map json = stringToJSON(qrText); @@ -51,15 +39,11 @@ class MyScannerState extends State { } void onDetect(capture) { - try { - final List barcodes = capture.barcodes; - for (final barcode in barcodes) { - if (barcode.rawValue != null) { - return handleSucces(barcode.rawValue); - } + final List barcodes = capture.barcodes; + for (final barcode in barcodes) { + if (barcode.rawValue != null) { + return handleSucces(barcode.rawValue); } - } finally { - handleError(); } } From 2d88553ee8bf0be0228ae4b4fe1c3b41bf40ba06 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Mon, 27 Feb 2023 20:37:39 +0100 Subject: [PATCH 39/40] Remove unnessecary import --- lib/widgets/scanner.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/widgets/scanner.dart b/lib/widgets/scanner.dart index f7a5089..46f8c8a 100644 --- a/lib/widgets/scanner.dart +++ b/lib/widgets/scanner.dart @@ -7,7 +7,6 @@ import 'package:smoke_cess_app/services/json_service.dart'; import 'package:smoke_cess_app/services/settings_service.dart'; import '../providers/settings_provider.dart'; import '../services/notification_service.dart'; -import '../widgets/missing_config_popup.dart'; class MyScanner extends StatefulWidget { const MyScanner({super.key}); From 4fc602806c276e0e89fc1c4d5c80c2b109ab44b1 Mon Sep 17 00:00:00 2001 From: "k.mannweiler" <2012491@stud.hs-mannheim.de> Date: Wed, 1 Mar 2023 20:45:00 +0100 Subject: [PATCH 40/40] Fixed Visuals --- lib/services/pages_service.dart | 7 ++----- lib/widgets/drop_down.dart | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/services/pages_service.dart b/lib/services/pages_service.dart index c3b1bd8..8f3ab37 100644 --- a/lib/services/pages_service.dart +++ b/lib/services/pages_service.dart @@ -16,14 +16,11 @@ const pages = { }, 'Timer': { 'page': IntervalTimerPage(), - 'icon': Icon(Icons.smoke_free_outlined, color: Colors.black) + 'icon': Icon(Icons.timer_outlined, color: Colors.black) }, 'Rückfall': { 'page': RelapsePage(), - 'icon': Icon( - Icons.timer_outlined, - color: Colors.black, - ) + 'icon': Icon(Icons.smoke_free_outlined, color: Colors.black), }, 'Scanner': { 'page': ScannerPage(), diff --git a/lib/widgets/drop_down.dart b/lib/widgets/drop_down.dart index 845c42c..5f06d89 100644 --- a/lib/widgets/drop_down.dart +++ b/lib/widgets/drop_down.dart @@ -13,7 +13,6 @@ class DropDown extends StatelessWidget { value: _items.isEmpty ? null : _items[0], icon: const Icon(Icons.arrow_downward), elevation: 16, - style: const TextStyle(color: Colors.deepPurple), onChanged: (String? value) { inputModel.relapseCategory = value ?? ''; },