From e7d4e42ab81bb99e9feab34493fa48897f79b59d Mon Sep 17 00:00:00 2001 From: Leptopoda Date: Fri, 7 Oct 2022 10:20:23 +0200 Subject: [PATCH 01/37] migrate ios_app_group to the maintained app_group_directory --- lib/common/data/database_path_provider.dart | 4 +- pubspec.lock | 42 ++++++++++----------- pubspec.yaml | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/common/data/database_path_provider.dart b/lib/common/data/database_path_provider.dart index 6d78badc..d6765ed8 100644 --- a/lib/common/data/database_path_provider.dart +++ b/lib/common/data/database_path_provider.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart'; -import 'package:ios_app_group/ios_app_group.dart'; +import 'package:app_group_directory/app_group_directory.dart'; Future getDatabasePath(String databaseName) async { Directory documentsDirectory = await getApplicationDocumentsDirectory(); @@ -25,7 +25,7 @@ Future _getiOSDatabasePathAndMigrate( // module. "Migration" means that the database at the old path gets // copied to the new path - var groupDirectory = await IosAppGroup.getAppGroupDirectory( + var groupDirectory = await AppGroupDirectory.getAppGroupDirectory( 'group.de.bennik2000.dhbwstudentapp', ); diff --git a/pubspec.lock b/pubspec.lock index f05222ab..0ffd0453 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.2" + app_group_directory: + dependency: "direct main" + description: + name: app_group_directory + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" archive: dependency: transitive description: @@ -42,7 +49,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" boolean_selector: dependency: transitive description: @@ -56,7 +63,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" charcode: dependency: transitive description: @@ -70,7 +77,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: @@ -126,7 +133,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" ffi: dependency: transitive description: @@ -378,13 +385,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.3" - ios_app_group: - dependency: "direct main" - description: - name: ios_app_group - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" js: dependency: transitive description: @@ -426,21 +426,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" mime: dependency: transitive description: @@ -482,7 +482,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" path_provider: dependency: "direct main" description: @@ -697,7 +697,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" sprintf: dependency: transitive description: @@ -739,7 +739,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" synchronized: dependency: transitive description: @@ -753,28 +753,28 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test: dependency: "direct dev" description: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.21.1" + version: "1.21.4" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.4.13" + version: "0.4.16" timezone: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 18ed687b..14563867 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,7 +48,7 @@ dependencies: device_calendar: ^4.2.0 flutter_inapp_purchase: ^5.1.2 flutter_widgetkit: ^1.0.3 - ios_app_group: ^1.0.0 + app_group_directory: ^2.0.0 timezone: ^0.8.0 dev_dependencies: From aa02417eec10cf465f75a9c5dad87d61141b3cd5 Mon Sep 17 00:00:00 2001 From: Leptopoda Date: Fri, 7 Oct 2022 10:21:08 +0200 Subject: [PATCH 02/37] mirate snackbar to ScaffoldMessenger --- lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index baa28690..1e3a81ef 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -29,7 +29,7 @@ class _WeeklySchedulePageState extends State { } void _showQueryFailedSnackBar() { - Scaffold.of(context).showSnackBar( + ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Column( crossAxisAlignment: CrossAxisAlignment.end, From 61c51755158fb7ede3a3443e697abb5e014e479d Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 7 Oct 2022 14:03:07 +0200 Subject: [PATCH 03/37] upgrade workmanager for flutter 3 --- pubspec.lock | 4 ++-- pubspec.yaml | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 0ffd0453..c0c493ac 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -907,7 +907,7 @@ packages: name: workmanager url: "https://pub.dartlang.org" source: hosted - version: "0.4.1" + version: "0.5.0" xdg_directories: dependency: transitive description: @@ -930,5 +930,5 @@ packages: source: hosted version: "3.1.0" sdks: - dart: ">=2.17.0-0 <3.0.0" + dart: ">=2.17.0 <3.0.0" flutter: ">=2.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index 14563867..a7c391fd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,7 +35,7 @@ dependencies: url_launcher: ^6.1.0 kiwi: ^4.0.2 flutter_local_notifications: ^9.4.1 # BREAKING CHANGES HERE! - workmanager: ^0.4.1 + workmanager: ^0.5.0 universal_html: ^2.0.8 firebase_core: ^1.15.0 firebase_analytics: ^9.1.6 @@ -57,13 +57,11 @@ dev_dependencies: test: any - # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. @@ -81,6 +79,6 @@ flutter: - assets/schedule_empty_state_dark.png fonts: - - family: CustomIcons + - family: CustomIcons fonts: - asset: fonts/CustomIcons.ttf From 56d1d8b05a842af85f75726ef41e7d8685c7c28b Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sun, 16 Oct 2022 13:13:30 +0200 Subject: [PATCH 04/37] null safety migration --- .../appstart/localization_initialize.dart | 4 +- lib/common/data/database_access.dart | 40 +++--- lib/common/data/database_entity.dart | 2 +- lib/common/data/database_path_provider.dart | 5 +- .../data/preferences/app_theme_enum.dart | 7 +- .../data/preferences/preferences_access.dart | 24 ++-- .../preferences/preferences_provider.dart | 118 ++++++++++-------- .../preferences/secure_storage_access.dart | 2 +- lib/common/i18n/localization_strings_de.dart | 6 +- lib/common/i18n/localizations.dart | 17 +-- lib/common/iap/in_app_purchase_helper.dart | 91 +++++++------- lib/common/iap/in_app_purchase_manager.dart | 28 ++--- lib/common/logging/crash_reporting.dart | 2 +- lib/common/ui/colors.dart | 8 +- lib/common/ui/custom_icons_icons.dart | 7 +- lib/common/ui/notification_api.dart | 16 +-- .../ui/schedule_entry_type_mappings.dart | 8 +- lib/common/ui/text_styles.dart | 30 ++--- lib/common/ui/viewmodels/root_view_model.dart | 12 +- lib/common/ui/widgets/dots_indicator.dart | 3 +- lib/common/ui/widgets/error_display.dart | 4 +- lib/common/ui/widgets/title_list_tile.dart | 2 +- lib/common/util/cancelable_mutex.dart | 4 +- lib/common/util/cancellation_token.dart | 6 +- lib/common/util/date_utils.dart | 43 +++---- lib/common/util/platform_util.dart | 2 +- lib/common/util/string_utils.dart | 8 +- .../business/date_entry_provider.dart | 19 +-- lib/date_management/data/calendar_access.dart | 30 +++-- .../data/date_entry_entity.dart | 29 ++--- .../data/date_entry_repository.dart | 18 +-- lib/date_management/model/date_entry.dart | 23 ++-- .../model/date_search_parameters.dart | 8 +- .../service/date_management_service.dart | 4 +- .../service/parsing/all_dates_extract.dart | 13 +- .../ui/calendar_export_page.dart | 56 ++++----- .../ui/date_management_navigation_entry.dart | 43 +++---- .../ui/date_management_page.dart | 38 +++--- .../calendar_export_view_model.dart | 17 +-- .../date_management_view_model.dart | 58 ++++----- .../ui/widgets/date_detail_bottom_sheet.dart | 14 +-- .../ui/widgets/date_filter_options.dart | 51 +++----- lib/dualis/model/credentials.dart | 42 ++++++- lib/dualis/model/exam.dart | 4 +- lib/dualis/model/exam_grade.dart | 4 +- lib/dualis/model/module.dart | 10 +- lib/dualis/model/semester.dart | 2 +- lib/dualis/model/study_grades.dart | 8 +- .../cache_dualis_service_decorator.dart | 28 ++--- lib/dualis/service/dualis_authentication.dart | 90 +++++++------ lib/dualis/service/dualis_scraper.dart | 36 +++--- lib/dualis/service/dualis_service.dart | 40 +++--- lib/dualis/service/dualis_website_model.dart | 34 ++--- ...fake_account_dualis_scraper_decorator.dart | 41 +++--- .../service/fake_data_dualis_scraper.dart | 22 ++-- .../service/parsing/all_modules_extract.dart | 6 +- .../exams_from_module_details_extract.dart | 8 +- .../parsing/login_redirect_url_extract.dart | 6 +- ...dules_from_course_result_page_extract.dart | 20 +-- .../parsing/monthly_schedule_extract.dart | 12 +- lib/dualis/service/parsing/parsing_utils.dart | 10 +- ...sters_from_course_result_page_extract.dart | 12 +- ...des_from_student_results_page_extract.dart | 20 +-- .../parsing/urls_from_main_page_extract.dart | 12 +- lib/dualis/service/session.dart | 37 +++--- lib/dualis/ui/dualis_navigation_entry.dart | 59 ++++----- lib/dualis/ui/dualis_page.dart | 3 +- .../exam_results_page/exam_results_page.dart | 26 ++-- lib/dualis/ui/login/dualis_login_page.dart | 3 +- .../study_overview/study_overview_page.dart | 26 ++-- .../viewmodels/study_grades_view_model.dart | 43 +++---- lib/dualis/ui/widgets/grade_state_icon.dart | 9 +- lib/dualis/ui/widgets/login_form_widget.dart | 113 +++++++---------- .../useful_information_navigation_entry.dart | 13 +- .../useful_information_page.dart | 3 +- lib/native/widget/android_widget_helper.dart | 2 +- lib/native/widget/ios_widget_helper.dart | 2 +- lib/native/widget/widget_helper.dart | 12 +- .../background_schedule_update.dart | 4 +- .../background/calendar_synchronizer.dart | 3 +- .../business/schedule_diff_calculator.dart | 15 ++- lib/schedule/business/schedule_provider.dart | 10 +- .../business/schedule_source_provider.dart | 25 ++-- lib/schedule/data/schedule_entry_entity.dart | 30 ++--- .../data/schedule_entry_repository.dart | 13 +- .../data/schedule_filter_repository.dart | 6 +- .../schedule_query_information_entity.dart | 18 +-- ...schedule_query_information_repository.dart | 8 +- lib/schedule/model/schedule.dart | 30 ++--- lib/schedule/model/schedule_entry.dart | 46 ++++--- .../model/schedule_query_information.dart | 9 +- lib/schedule/model/schedule_query_result.dart | 8 +- .../dualis/dualis_schedule_source.dart | 15 +-- ...rror_report_schedule_source_decorator.dart | 4 +- lib/schedule/service/ical/ical_parser.dart | 26 ++-- .../service/ical/ical_schedule_source.dart | 19 +-- .../service/invalid_schedule_source.dart | 6 +- .../isolate_schedule_source_decorator.dart | 34 ++--- .../mannheim_course_response_parser.dart | 2 +- .../mannheim/mannheim_course_scraper.dart | 7 +- .../rapla/rapla_monthly_response_parser.dart | 6 +- .../service/rapla/rapla_parsing_utils.dart | 21 ++-- .../service/rapla/rapla_response_parser.dart | 2 +- .../service/rapla/rapla_schedule_source.dart | 74 ++++++----- .../rapla_several_months_response_parser.dart | 7 +- .../rapla/rapla_week_response_parser.dart | 4 +- lib/schedule/service/schedule_prettifier.dart | 20 ++- lib/schedule/service/schedule_source.dart | 10 +- .../ui/dailyschedule/daily_schedule_page.dart | 16 +-- .../widgets/daily_schedule_entry_widget.dart | 6 +- .../next_day_information_notification.dart | 45 +++---- .../ui/schedule_navigation_entry.dart | 47 +++---- lib/schedule/ui/schedule_page.dart | 10 +- .../viewmodels/daily_schedule_view_model.dart | 34 +++-- .../weekly_schedule_view_model.dart | 52 ++++---- .../filter/filter_view_model.dart | 8 +- .../filter/schedule_filter_page.dart | 10 +- .../schedule_entry_detail_bottom_sheet.dart | 24 ++-- .../weeklyschedule/weekly_schedule_page.dart | 31 ++--- .../widgets/schedule_entry_alignment.dart | 6 +- .../widgets/schedule_entry_widget.dart | 8 +- .../weeklyschedule/widgets/schedule_grid.dart | 10 +- .../widgets/schedule_past_overlay.dart | 30 ++--- .../widgets/schedule_widget.dart | 42 +++---- .../enter_dualis_credentials_dialog.dart | 29 ++--- lib/schedule/ui/widgets/enter_ical_url.dart | 8 +- .../ui/widgets/enter_rapla_url_dialog.dart | 6 +- lib/schedule/ui/widgets/enter_url_dialog.dart | 18 +-- .../ui/widgets/schedule_empty_state.dart | 2 +- .../select_mannheim_course_dialog.dart | 2 +- .../ui/widgets/select_source_dialog.dart | 13 +- lib/ui/banner_widget.dart | 34 ++--- lib/ui/login_credentials_widget.dart | 35 ++---- lib/ui/main_page.dart | 24 ++-- lib/ui/navigation/navigation_entry.dart | 32 ++--- lib/ui/navigation/router.dart | 8 +- lib/ui/navigation_drawer.dart | 18 +-- lib/ui/onboarding/onboardin_step.dart | 18 ++- lib/ui/onboarding/onboarding_page.dart | 30 +++-- .../viewmodels/dualis_login_view_model.dart | 29 +++-- .../viewmodels/ical_url_view_model.dart | 12 +- .../viewmodels/mannheim_view_model.dart | 8 +- .../viewmodels/onboarding_view_model.dart | 12 +- .../onboarding_view_model_base.dart | 1 + .../viewmodels/rapla_url_view_model.dart | 12 +- .../viewmodels/select_source_view_model.dart | 12 +- .../onboarding/widgets/dualis_login_page.dart | 44 ++++--- lib/ui/onboarding/widgets/ical_url_page.dart | 21 ++-- lib/ui/onboarding/widgets/mannheim_page.dart | 29 +++-- .../widgets/onboarding_button_bar.dart | 12 +- .../widgets/onboarding_page_background.dart | 8 +- lib/ui/onboarding/widgets/rapla_url_page.dart | 21 ++-- .../widgets/select_source_page.dart | 14 +-- lib/ui/pager_widget.dart | 62 ++++----- lib/ui/root_page.dart | 20 ++- lib/ui/settings/donate_list_tile.dart | 13 +- .../settings/purchase_widget_list_tile.dart | 13 +- lib/ui/settings/select_theme_dialog.dart | 9 +- lib/ui/settings/settings_page.dart | 28 +++-- .../viewmodels/settings_view_model.dart | 19 ++- pubspec.lock | 7 ++ pubspec.yaml | 3 +- ..._from_course_result_page_extract_test.dart | 12 +- .../rapla/rapla_response_parser_test.dart | 45 ++++--- 164 files changed, 1637 insertions(+), 1705 deletions(-) diff --git a/lib/common/appstart/localization_initialize.dart b/lib/common/appstart/localization_initialize.dart index c773fd90..37d772b1 100644 --- a/lib/common/appstart/localization_initialize.dart +++ b/lib/common/appstart/localization_initialize.dart @@ -9,8 +9,8 @@ import 'package:kiwi/kiwi.dart'; /// correct language /// class LocalizationInitialize { - PreferencesProvider _preferencesProvider; - String _languageCode; + PreferencesProvider? _preferencesProvider; + String? _languageCode; /// /// Initialize the localization using the provided language code diff --git a/lib/common/data/database_access.dart b/lib/common/data/database_access.dart index 8dfd9819..6b8a3851 100644 --- a/lib/common/data/database_access.dart +++ b/lib/common/data/database_access.dart @@ -4,15 +4,12 @@ import 'package:sqflite/sqflite.dart'; class DatabaseAccess { static const String _databaseName = "Database.db"; - static Database _databaseInstance; + static Database? _databaseInstance; static const String idColumnName = "id"; Future get _database async { - if (_databaseInstance != null) return _databaseInstance; - - _databaseInstance = await _initDatabase(); - return _databaseInstance; + return _databaseInstance ??= await _initDatabase(); } Future _initDatabase() async { @@ -60,19 +57,20 @@ class DatabaseAccess { } Future>> queryRows(String table, - {bool distinct, - List columns, - String where, - List whereArgs, - String groupBy, - String having, - String orderBy, - int limit, - int offset}) async { + {bool? distinct, + List? columns, + String? where, + List? whereArgs, + String? groupBy, + String? having, + String? orderBy, + int? limit, + int? offset}) async { Database db = await _database; + // TODO: [Leptopoda] is there a reason this is done? or at maybe use whereArgs.removeWhere() for (int i = 0; i < (whereArgs?.length ?? 0); i++) { - whereArgs[i] = whereArgs[i] ?? ""; + whereArgs![i] = whereArgs[i] ?? ""; } return await db.query( @@ -89,33 +87,33 @@ class DatabaseAccess { ); } - Future queryRowCount(String table) async { + Future queryRowCount(String table) async { Database db = await _database; return Sqflite.firstIntValue( await db.rawQuery('SELECT COUNT(*) FROM $table')); } - Future queryAggregator(String query, List arguments) async { + Future queryAggregator(String query, List arguments) async { Database db = await _database; return Sqflite.firstIntValue(await db.rawQuery(query, arguments)); } Future update(String table, Map row) async { Database db = await _database; - int id = row[idColumnName]; + int? id = row[idColumnName]; return await db .update(table, row, where: '$idColumnName = ?', whereArgs: [id]); } - Future delete(String table, int id) async { + Future delete(String table, int? id) async { Database db = await _database; return await db.delete(table, where: '$idColumnName = ?', whereArgs: [id]); } Future deleteWhere( String table, { - String where, - List whereArgs, + String? where, + List? whereArgs, }) async { Database db = await _database; return await db.delete( diff --git a/lib/common/data/database_entity.dart b/lib/common/data/database_entity.dart index 121892b8..65967e9e 100644 --- a/lib/common/data/database_entity.dart +++ b/lib/common/data/database_entity.dart @@ -1,4 +1,4 @@ abstract class DatabaseEntity { Map toMap(); - void fromMap(Map map); + fromMap(Map map); } diff --git a/lib/common/data/database_path_provider.dart b/lib/common/data/database_path_provider.dart index d6765ed8..e5a5be00 100644 --- a/lib/common/data/database_path_provider.dart +++ b/lib/common/data/database_path_provider.dart @@ -24,12 +24,13 @@ Future _getiOSDatabasePathAndMigrate( // it must be saved in a group shared between the app module and the widget // module. "Migration" means that the database at the old path gets // copied to the new path + assert(Platform.isIOS); - var groupDirectory = await AppGroupDirectory.getAppGroupDirectory( + Directory? groupDirectory = await AppGroupDirectory.getAppGroupDirectory( 'group.de.bennik2000.dhbwstudentapp', ); - var newPath = join(groupDirectory.path, databaseName); + var newPath = join(groupDirectory!.path, databaseName); var migrateSuccess = await _migrateOldDatabase(oldPath, newPath); diff --git a/lib/common/data/preferences/app_theme_enum.dart b/lib/common/data/preferences/app_theme_enum.dart index 01aab80e..0c8be05f 100644 --- a/lib/common/data/preferences/app_theme_enum.dart +++ b/lib/common/data/preferences/app_theme_enum.dart @@ -1,9 +1,4 @@ - /// /// Enum which holds the possible themes the app can be displayed in /// -enum AppTheme { - Dark, - Light, - System -} \ No newline at end of file +enum AppTheme { Dark, Light, System } diff --git a/lib/common/data/preferences/preferences_access.dart b/lib/common/data/preferences/preferences_access.dart index 20cc4c9c..ea183eae 100644 --- a/lib/common/data/preferences/preferences_access.dart +++ b/lib/common/data/preferences/preferences_access.dart @@ -17,32 +17,26 @@ class PreferencesAccess { case int: await prefs.setInt(key, value as int); return; + default: + throw InvalidValueTypeException(T); } - - throw InvalidValueTypeException(T); } - Future get(String key) async { + Future get(String key) async { final SharedPreferences prefs = await SharedPreferences.getInstance(); - T value; - switch (T) { case bool: - value = prefs.getBool(key) as T; - break; + return prefs.getBool(key) as T?; case String: - value = prefs.getString(key) as T; - break; + return prefs.getString(key) as T?; case double: - value = prefs.getDouble(key) as T; - break; + return prefs.getDouble(key) as T?; case int: - value = prefs.getInt(key) as T; - break; + return prefs.getInt(key) as T?; + default: + return null; } - - return value; } } diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index 5c6beaf5..61533ddd 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -51,23 +51,23 @@ class PreferencesProvider { } Future setIsCalendarSyncEnabled(bool value) async { - await _preferencesAccess.set('isCalendarSyncEnabled', value); + await _preferencesAccess.set('isCalendarSyncEnabled', value); } Future isCalendarSyncEnabled() async { - return await _preferencesAccess.get('isCalendarSyncEnabled') ?? false; + return await _preferencesAccess.get('isCalendarSyncEnabled') ?? false; } - Future setSelectedCalendar(Calendar selectedCalendar) async { - String selectedCalendarId = selectedCalendar?.id; - await _preferencesAccess.set( - 'SelectedCalendarId', selectedCalendarId ?? ''); + Future setSelectedCalendar(Calendar? selectedCalendar) async { + final selectedCalendarId = selectedCalendar?.id ?? ""; + await _preferencesAccess.set( + 'SelectedCalendarId', selectedCalendarId); } - Future getSelectedCalendar() async { - Calendar selectedCalendar; - String selectedCalendarId = - await _preferencesAccess.get('SelectedCalendarId') ?? null; + Future getSelectedCalendar() async { + Calendar? selectedCalendar; + String? selectedCalendarId = + await _preferencesAccess.get('SelectedCalendarId'); if (selectedCalendarId == null) return null; List availableCalendars = await CalendarAccess().queryWriteableCalendars(); @@ -78,27 +78,27 @@ class PreferencesProvider { } Future getRaplaUrl() async { - return await _preferencesAccess.get(RaplaUrlKey) ?? ""; + return await _preferencesAccess.get(RaplaUrlKey) ?? ""; } Future setRaplaUrl(String url) async { - await _preferencesAccess.set(RaplaUrlKey, url); + await _preferencesAccess.set(RaplaUrlKey, url); } Future isFirstStart() async { - return await _preferencesAccess.get(IsFirstStartKey) ?? true; + return await _preferencesAccess.get(IsFirstStartKey) ?? true; } Future setIsFirstStart(bool isFirstStart) async { - await _preferencesAccess.set(IsFirstStartKey, isFirstStart); + await _preferencesAccess.set(IsFirstStartKey, isFirstStart); } - Future getLastUsedLanguageCode() async { + Future getLastUsedLanguageCode() async { return await _preferencesAccess.get(LastUsedLanguageCode); } Future setLastUsedLanguageCode(String languageCode) async { - await _preferencesAccess.set(LastUsedLanguageCode, languageCode); + await _preferencesAccess.set(LastUsedLanguageCode, languageCode); } Future getNotifyAboutNextDay() async { @@ -106,7 +106,7 @@ class PreferencesProvider { } Future setNotifyAboutNextDay(bool value) async { - await _preferencesAccess.set(NotifyAboutNextDay, value); + await _preferencesAccess.set(NotifyAboutNextDay, value); } Future getNotifyAboutScheduleChanges() async { @@ -115,7 +115,7 @@ class PreferencesProvider { } Future setNotifyAboutScheduleChanges(bool value) async { - await _preferencesAccess.set(NotifyAboutScheduleChanges, value); + await _preferencesAccess.set(NotifyAboutScheduleChanges, value); } Future getDontShowRateNowDialog() async { @@ -123,17 +123,22 @@ class PreferencesProvider { } Future setDontShowRateNowDialog(bool value) async { - await _preferencesAccess.set(DontShowRateNowDialog, value); + await _preferencesAccess.set(DontShowRateNowDialog, value); } Future storeDualisCredentials(Credentials credentials) async { - await _secureStorageAccess.set(DualisUsername, credentials.username ?? ""); - await _secureStorageAccess.set(DualisPassword, credentials.password ?? ""); + await _secureStorageAccess.set(DualisUsername, credentials.username); + await _secureStorageAccess.set(DualisPassword, credentials.password); } - Future loadDualisCredentials() async { + Future loadDualisCredentials() async { var username = await _secureStorageAccess.get(DualisUsername); var password = await _secureStorageAccess.get(DualisPassword); + + if (username == null || + password == null || + username.isEmpty || + password.isEmpty) return null; return Credentials(username, password); } @@ -147,30 +152,34 @@ class PreferencesProvider { } Future setStoreDualisCredentials(bool value) async { - await _preferencesAccess.set(DualisStoreCredentials, value ?? false); + await _preferencesAccess.set(DualisStoreCredentials, value); } - Future getLastViewedSemester() async { + Future getLastViewedSemester() async { return await _preferencesAccess.get(LastViewedSemester); } - Future setLastViewedSemester(String lastViewedSemester) async { - await _preferencesAccess.set(LastViewedSemester, lastViewedSemester); + Future setLastViewedSemester(String? lastViewedSemester) async { + if (lastViewedSemester == null) return; + await _preferencesAccess.set( + LastViewedSemester, lastViewedSemester); } - Future getLastViewedDateEntryDatabase() async { + Future getLastViewedDateEntryDatabase() async { return await _preferencesAccess.get(LastViewedDateEntryDatabase); } - Future setLastViewedDateEntryDatabase(String value) async { - await _preferencesAccess.set(LastViewedDateEntryDatabase, value); + Future setLastViewedDateEntryDatabase(String? value) async { + await _preferencesAccess.set( + LastViewedDateEntryDatabase, value ?? ""); } - Future getLastViewedDateEntryYear() async { + Future getLastViewedDateEntryYear() async { return await _preferencesAccess.get(LastViewedDateEntryYear); } - Future setLastViewedDateEntryYear(String value) async { + Future setLastViewedDateEntryYear(String? value) async { + if (value == null) return; await _preferencesAccess.set(LastViewedDateEntryYear, value); } @@ -182,85 +191,88 @@ class PreferencesProvider { await _preferencesAccess.set(ScheduleSourceType, value); } - Future getIcalUrl() { - return _preferencesAccess.get(ScheduleIcalUrl); + Future getIcalUrl() { + return _preferencesAccess.get(ScheduleIcalUrl); } Future setIcalUrl(String url) { - return _preferencesAccess.set(ScheduleIcalUrl, url); + return _preferencesAccess.set(ScheduleIcalUrl, url); } - Future getMannheimScheduleId() { - return _preferencesAccess.get(MannheimScheduleId); + Future getMannheimScheduleId() { + return _preferencesAccess.get(MannheimScheduleId); } Future setMannheimScheduleId(String url) { - return _preferencesAccess.set(MannheimScheduleId, url); + return _preferencesAccess.set(MannheimScheduleId, url); } Future getPrettifySchedule() async { - return await _preferencesAccess.get(PrettifySchedule) ?? true; + return await _preferencesAccess.get(PrettifySchedule) ?? true; } Future setPrettifySchedule(bool value) { - return _preferencesAccess.set(PrettifySchedule, value); + return _preferencesAccess.set(PrettifySchedule, value); } Future getSynchronizeScheduleWithCalendar() async { - return await _preferencesAccess.get(SynchronizeScheduleWithCalendar) ?? + return await _preferencesAccess + .get(SynchronizeScheduleWithCalendar) ?? true; } Future setSynchronizeScheduleWithCalendar(bool value) { - return _preferencesAccess.set(SynchronizeScheduleWithCalendar, value); + return _preferencesAccess.set(SynchronizeScheduleWithCalendar, value); } Future getDidShowWidgetHelpDialog() async { - return await _preferencesAccess.get(DidShowWidgetHelpDialog) ?? false; + return await _preferencesAccess.get(DidShowWidgetHelpDialog) ?? false; } Future setDidShowWidgetHelpDialog(bool value) { - return _preferencesAccess.set(DidShowWidgetHelpDialog, value); + return _preferencesAccess.set(DidShowWidgetHelpDialog, value); } Future set(String key, T value) async { + if (value == null) return; return _preferencesAccess.set(key, value); } - Future get(String key) async { - return _preferencesAccess.get(key); + Future get(String key) async { + return _preferencesAccess.get(key); } Future getAppLaunchCounter() async { - return await _preferencesAccess.get("AppLaunchCount") ?? 0; + return await _preferencesAccess.get("AppLaunchCount") ?? 0; } Future setAppLaunchCounter(int value) async { - return await _preferencesAccess.set("AppLaunchCount", value); + return await _preferencesAccess.set("AppLaunchCount", value); } Future getNextRateInStoreLaunchCount() async { - return await _preferencesAccess.get("NextRateInStoreLaunchCount") ?? + return await _preferencesAccess.get("NextRateInStoreLaunchCount") ?? RateInStoreLaunchAfter; } Future setNextRateInStoreLaunchCount(int value) async { - return await _preferencesAccess.set("NextRateInStoreLaunchCount", value); + return await _preferencesAccess.set( + "NextRateInStoreLaunchCount", value); } Future getDidShowDonateDialog() async { - return await _preferencesAccess.get("DidShowDonateDialog") ?? false; + return await _preferencesAccess.get("DidShowDonateDialog") ?? false; } Future setDidShowDonateDialog(bool value) { - return _preferencesAccess.set("DidShowDonateDialog", value); + return _preferencesAccess.set("DidShowDonateDialog", value); } Future getHasPurchasedSomething() async { - return await _preferencesAccess.get("HasPurchasedSomething") ?? false; + return await _preferencesAccess.get("HasPurchasedSomething") ?? false; } Future setHasPurchasedSomething(bool value) { - return _preferencesAccess.set("HasPurchasedSomething", value); + return _preferencesAccess.set("HasPurchasedSomething", value); } } diff --git a/lib/common/data/preferences/secure_storage_access.dart b/lib/common/data/preferences/secure_storage_access.dart index ec8e7442..76745504 100644 --- a/lib/common/data/preferences/secure_storage_access.dart +++ b/lib/common/data/preferences/secure_storage_access.dart @@ -7,7 +7,7 @@ class SecureStorageAccess { await _secureStorage.write(key: key, value: value); } - Future get(String key) async { + Future get(String key) async { return await _secureStorage.read(key: key); } } diff --git a/lib/common/i18n/localization_strings_de.dart b/lib/common/i18n/localization_strings_de.dart index 252116e8..753959be 100644 --- a/lib/common/i18n/localization_strings_de.dart +++ b/lib/common/i18n/localization_strings_de.dart @@ -5,7 +5,8 @@ final de = { "settingsViewSourceCode": "Source code auf GitHub ansehen", "settingsCalendarSync": "Kalendersynchronisation", "calendarSyncPageTitle": "Kalender synchronisieren", - "calendarSyncPageSubtitle": "Wähle den Kalender aus, in den der Vorlesungsplan übertragen werden soll:", + "calendarSyncPageSubtitle": + "Wähle den Kalender aus, in den der Vorlesungsplan übertragen werden soll:", "calendarSyncPageEndSync": "Synchronisation beenden", "calendarSyncPageBeginSync": "Kalender synchronisieren", "applicationName": "DHBW Studenten App", @@ -114,7 +115,8 @@ final de = { "dialogOk": "Ok", "dialogCancel": "Cancel", "dialogSetRaplaUrlTitle": "Rapla Url festlegen", - "dialogCalendarAccessNotGranted": "Wenn du den Vorlesungsplan mit deinem nativen Kalender synchronisieren möchtest, musst du in den Einstellungen den Kalenderzugriff erlauben.", + "dialogCalendarAccessNotGranted": + "Wenn du den Vorlesungsplan mit deinem nativen Kalender synchronisieren möchtest, musst du in den Einstellungen den Kalenderzugriff erlauben.", "dialogTitleCalendarAccessNotGranted": "Keine Zugriffsrechte", "scheduleEmptyStateSetUrl": "Konfigurieren", "scheduleEmptyStateBannerMessage": diff --git a/lib/common/i18n/localizations.dart b/lib/common/i18n/localizations.dart index c43f5842..fb82fdbc 100644 --- a/lib/common/i18n/localizations.dart +++ b/lib/common/i18n/localizations.dart @@ -6,10 +6,10 @@ import 'package:flutter/widgets.dart'; class L { final Locale locale; - String _language; + late String _language; L(this.locale) { - _language = locale?.languageCode?.substring(0, 2); + _language = locale.languageCode.substring(0, 2); if (!_localizedValues.containsKey(_language)) { _language = "en"; @@ -84,7 +84,8 @@ class L { String get calendarSyncPageEndSync => _getValue("calendarSyncPageEndSync"); - String get calendarSyncPageBeginSync => _getValue("calendarSyncPageBeginSync"); + String get calendarSyncPageBeginSync => + _getValue("calendarSyncPageBeginSync"); String get notificationScheduleChangedNewClass => _getValue("notificationScheduleChangedNewClass"); @@ -283,9 +284,11 @@ class L { String get dialogSetRaplaUrlTitle => _getValue("dialogSetRaplaUrlTitle"); - String get dialogCalendarAccessNotGranted => _getValue("dialogCalendarAccessNotGranted"); + String get dialogCalendarAccessNotGranted => + _getValue("dialogCalendarAccessNotGranted"); - String get dialogTitleCalendarAccessNotGranted => _getValue("dialogTitleCalendarAccessNotGranted"); + String get dialogTitleCalendarAccessNotGranted => + _getValue("dialogTitleCalendarAccessNotGranted"); String get scheduleEmptyStateSetUrl => _getValue("scheduleEmptyStateSetUrl"); @@ -403,7 +406,7 @@ class L { String get filterTitle => _getValue("filterTitle"); static L of(BuildContext context) { - return Localizations.of(context, L); + return Localizations.of(context, L)!; } static final Map> _localizedValues = { @@ -412,7 +415,7 @@ class L { }; String _getValue(String key) { - return _localizedValues[_language][key] ?? ""; + return _localizedValues[_language]![key] ?? ""; } String getValue(String key) => _getValue(key); diff --git a/lib/common/iap/in_app_purchase_helper.dart b/lib/common/iap/in_app_purchase_helper.dart index efe60867..3d9d50cd 100644 --- a/lib/common/iap/in_app_purchase_helper.dart +++ b/lib/common/iap/in_app_purchase_helper.dart @@ -20,7 +20,7 @@ enum PurchaseResultEnum { } typedef PurchaseCompletedCallback = Function( - String productId, + String? productId, PurchaseResultEnum result, ); @@ -33,10 +33,10 @@ class InAppPurchaseHelper { final PreferencesProvider _preferencesProvider; - StreamSubscription _purchaseUpdatedSubscription; - StreamSubscription _purchaseErrorSubscription; + StreamSubscription? _purchaseUpdatedSubscription; + StreamSubscription? _purchaseErrorSubscription; - PurchaseCompletedCallback _purchaseCallback; + PurchaseCompletedCallback? _purchaseCallback; InAppPurchaseHelper(this._preferencesProvider); @@ -77,7 +77,7 @@ class InAppPurchaseHelper { return PurchaseResultEnum.Success; } on PlatformException catch (_) { if (_purchaseCallback != null) { - _purchaseCallback(id, PurchaseResultEnum.Error); + _purchaseCallback!(id, PurchaseResultEnum.Error); } return PurchaseResultEnum.Error; @@ -95,25 +95,23 @@ class InAppPurchaseHelper { return PurchaseStateEnum.NotPurchased; } - var allPurchases = []; - try { - allPurchases = + var allPurchases = await FlutterInappPurchase.instance.getAvailablePurchases(); - } on Exception catch (_) { - return PurchaseStateEnum.Unknown; - } - var productIdPurchases = - allPurchases.where((element) => element.productId == id); + var productIdPurchases = + allPurchases?.where((element) => element.productId == id); + + if (productIdPurchases?.isNotEmpty ?? false) { + return productIdPurchases!.any((element) => _isPurchased(element)) + ? PurchaseStateEnum.Purchased + : PurchaseStateEnum.NotPurchased; + } - if (productIdPurchases.isEmpty) { return PurchaseStateEnum.NotPurchased; + } on Exception catch (_) { + return PurchaseStateEnum.Unknown; } - - return productIdPurchases.any((element) => _isPurchased(element)) - ? PurchaseStateEnum.Purchased - : PurchaseStateEnum.NotPurchased; } /// @@ -124,7 +122,9 @@ class InAppPurchaseHelper { _purchaseCallback = callback; } - Future _completePurchase(PurchasedItem item) async { + Future _completePurchase(PurchasedItem? item) async { + if (item == null) return; + var purchaseResult = _purchaseResultFromItem(item); _purchaseCallback?.call(item.productId, purchaseResult); @@ -152,48 +152,40 @@ class InAppPurchaseHelper { } PurchaseResultEnum _purchaseResultFromItem(PurchasedItem item) { - var purchaseResult = PurchaseResultEnum.Error; - if (Platform.isAndroid) { switch (item.purchaseStateAndroid) { case PurchaseState.pending: - purchaseResult = PurchaseResultEnum.Pending; - break; + return PurchaseResultEnum.Pending; + case PurchaseState.purchased: - purchaseResult = PurchaseResultEnum.Success; - break; + return PurchaseResultEnum.Success; case PurchaseState.unspecified: - purchaseResult = PurchaseResultEnum.Error; - break; + default: + return PurchaseResultEnum.Error; } } else if (Platform.isIOS) { switch (item.transactionStateIOS) { case TransactionState.purchasing: - purchaseResult = PurchaseResultEnum.Pending; - break; + return PurchaseResultEnum.Pending; case TransactionState.purchased: - purchaseResult = PurchaseResultEnum.Success; - break; - case TransactionState.failed: - purchaseResult = PurchaseResultEnum.Error; - break; + return PurchaseResultEnum.Success; case TransactionState.restored: - purchaseResult = PurchaseResultEnum.Success; - break; + return PurchaseResultEnum.Success; case TransactionState.deferred: - purchaseResult = PurchaseResultEnum.Pending; - break; + return PurchaseResultEnum.Pending; + case TransactionState.failed: + default: + return PurchaseResultEnum.Error; } } - - return purchaseResult; + return PurchaseResultEnum.Error; } Future _hasFinishedTransaction(PurchasedItem item) async { if (item.isAcknowledgedAndroid ?? false) return true; return await _preferencesProvider - .get("purchase_${item.productId}_finished") ?? + .get("purchase_${item.productId}_finished") ?? false; } @@ -206,7 +198,7 @@ class InAppPurchaseHelper { return; } - List purchasedItems = []; + List? purchasedItems; if (Platform.isAndroid) { purchasedItems = @@ -216,20 +208,23 @@ class InAppPurchaseHelper { await FlutterInappPurchase.instance.getPendingTransactionsIOS(); } - print("Found ${purchasedItems.length} pending purchases"); + if (purchasedItems != null) { + print("Found ${purchasedItems.length} pending purchases"); - purchasedItems.forEach(_completePurchase); + purchasedItems.forEach(_completePurchase); + } } - void _onPurchaseError(PurchaseResult event) { + void _onPurchaseError(PurchaseResult? event) { print("Failed to purchase:"); - print(event.message); - print(event.debugMessage); + print(event?.message); + print(event?.debugMessage); _purchaseCallback?.call(null, PurchaseResultEnum.Error); } - bool _isConsumable(String id) { + // TODO: [Leptopdoa] remove this¿? + bool _isConsumable(String? id) { return false; } diff --git a/lib/common/iap/in_app_purchase_manager.dart b/lib/common/iap/in_app_purchase_manager.dart index c56b8f96..75b7d540 100644 --- a/lib/common/iap/in_app_purchase_manager.dart +++ b/lib/common/iap/in_app_purchase_manager.dart @@ -22,7 +22,7 @@ class InAppPurchaseManager { void _initialize() async { addPurchaseCallback( InAppPurchaseHelper.WidgetProductId, - (String productId, PurchaseResultEnum result) => + (String? productId, PurchaseResultEnum result) => _setWidgetEnabled(result == PurchaseResultEnum.Success), ); @@ -32,8 +32,8 @@ class InAppPurchaseManager { try { await _inAppPurchaseHelper.initialize(); await _restorePurchases(); - } - catch (ex) { + } catch (ex) { + // TODO: [Leptopoda] disable purchases or show error message in settings when initialization was not sucessfull (i.e. no play services) print("Failed to initialize in app purchase!"); } } @@ -61,19 +61,21 @@ class InAppPurchaseManager { await buyWidget(); } - void _purchaseCompletedCallback(String productId, PurchaseResultEnum result) { + // TODO: [Leptopoda] better nullseafety + void _purchaseCompletedCallback( + String? productId, PurchaseResultEnum result) { if (purchaseCallbacks.containsKey(productId)) { - var callback = purchaseCallbacks[productId] ?? []; + var callback = purchaseCallbacks[productId!]; - callback.forEach((element) { + callback?.forEach((element) { element(productId, result); }); } if (purchaseCallbacks.containsKey("*")) { - var callback = purchaseCallbacks["*"] ?? []; + var callback = purchaseCallbacks["*"]; - callback.forEach((element) { + callback?.forEach((element) { element(productId, result); }); } @@ -91,25 +93,21 @@ class InAppPurchaseManager { /// for all product ids, pass null or "*" as productId /// void addPurchaseCallback( - String productId, + String? productId, PurchaseCompletedCallback callback, ) { if (productId == null) { productId = "*"; } - if (!purchaseCallbacks.containsKey(productId)) { - purchaseCallbacks[productId] = []; - } - - purchaseCallbacks[productId].add(callback); + purchaseCallbacks[productId]?.add(callback); } /// /// Removes a callback which was registered using [addPurchaseCallback] /// void removePurchaseCallback( - String productId, + String? productId, PurchaseCompletedCallback callback, ) { if (productId == null) { diff --git a/lib/common/logging/crash_reporting.dart b/lib/common/logging/crash_reporting.dart index ad0dde6b..0e863cfa 100644 --- a/lib/common/logging/crash_reporting.dart +++ b/lib/common/logging/crash_reporting.dart @@ -1,7 +1,7 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; -Future reportException(ex, StackTrace trace) async { +Future reportException(ex, StackTrace? trace) async { if (kReleaseMode) { print("Reporting exception to crashlytics: $ex with stack trace $trace"); await FirebaseCrashlytics.instance.recordError(ex, trace); diff --git a/lib/common/ui/colors.dart b/lib/common/ui/colors.dart index 181b7c65..1cea4e06 100644 --- a/lib/common/ui/colors.dart +++ b/lib/common/ui/colors.dart @@ -68,7 +68,7 @@ Color colorNoConnectionForeground() => Colors.white; class ColorPalettes { ColorPalettes._(); - static ThemeData buildTheme(AppTheme theme) { + static ThemeData buildTheme(AppTheme? theme) { if (theme == AppTheme.System) { theme = PlatformUtil.platformBrightness() == Brightness.light ? AppTheme.Light @@ -93,14 +93,14 @@ class ColorPalettes { return themeData.copyWith( snackBarTheme: themeData.snackBarTheme.copyWith( backgroundColor: isDark ? Color(0xff363635) : Color(0xfffafafa), - contentTextStyle: themeData.textTheme.bodyText1.copyWith( + contentTextStyle: themeData.textTheme.bodyText1!.copyWith( color: - isDark ? Color(0xffe4e4e4) : themeData.textTheme.bodyText1.color, + isDark ? Color(0xffe4e4e4) : themeData.textTheme.bodyText1!.color, ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( - primary: ColorPalettes.main, + foregroundColor: ColorPalettes.main, padding: EdgeInsets.symmetric(horizontal: 16.0), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(4.0)), diff --git a/lib/common/ui/custom_icons_icons.dart b/lib/common/ui/custom_icons_icons.dart index 759832fb..39da89d1 100644 --- a/lib/common/ui/custom_icons_icons.dart +++ b/lib/common/ui/custom_icons_icons.dart @@ -11,7 +11,7 @@ /// fonts: /// - asset: fonts/CustomIcons.ttf /// -/// +/// /// * Font Awesome 4, Copyright (C) 2016 by Dave Gandy /// Author: Dave Gandy /// License: SIL () @@ -23,7 +23,8 @@ class CustomIcons { CustomIcons._(); static const _kFontFam = 'CustomIcons'; - static const _kFontPkg = null; + static const dynamic _kFontPkg = null; - static const IconData logout = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData logout = + IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); } diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index 9810bf1e..ae714d84 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -20,6 +20,7 @@ class NotificationApi { ); var initializationSettingsIOS = IOSInitializationSettings( + // TODO: [Leptopoda] the below always returns null so why register it? onDidReceiveLocalNotification: onDidReceiveLocalNotification, ); @@ -37,7 +38,7 @@ class NotificationApi { /// /// Show a notification with the given title and message /// - Future showNotification(String title, String message, [int id]) async { + Future showNotification(String title, String? message, [int? id]) async { var androidPlatformChannelSpecifics = AndroidNotificationDetails( 'Notifications', 'Notifications', @@ -72,10 +73,10 @@ class NotificationApi { } Future onDidReceiveLocalNotification( - int id, String title, String body, String payload) => + int id, String? title, String? body, String? payload) => Future.value(); - Future selectNotification(String payload) => Future.value(); + Future selectNotification(String? payload) => Future.value(); } /// @@ -83,7 +84,8 @@ class NotificationApi { /// class VoidNotificationApi implements NotificationApi { @override - FlutterLocalNotificationsPlugin get _localNotificationsPlugin => null; + FlutterLocalNotificationsPlugin get _localNotificationsPlugin => + throw UnimplementedError(); @override Future initialize() { @@ -92,17 +94,17 @@ class VoidNotificationApi implements NotificationApi { @override Future onDidReceiveLocalNotification( - int id, String title, String body, String payload) { + int id, String? title, String? body, String? payload) { return Future.value(); } @override - Future selectNotification(String payload) { + Future selectNotification(String? payload) { return Future.value(); } @override - Future showNotification(String title, String message, [int id]) { + Future showNotification(String title, String? message, [int? id]) { return Future.value(); } } diff --git a/lib/common/ui/schedule_entry_type_mappings.dart b/lib/common/ui/schedule_entry_type_mappings.dart index 9c162016..f934ce95 100644 --- a/lib/common/ui/schedule_entry_type_mappings.dart +++ b/lib/common/ui/schedule_entry_type_mappings.dart @@ -25,14 +25,14 @@ final Map scheduleEntryTypeTextMapping = { Color scheduleEntryTypeToColor( BuildContext context, - ScheduleEntryType type, + ScheduleEntryType? type, ) { - return scheduleEntryTypeColorMapping[type](context); + return scheduleEntryTypeColorMapping[type!]!(context); } String scheduleEntryTypeToReadableString( BuildContext context, - ScheduleEntryType type, + ScheduleEntryType? type, ) { - return scheduleEntryTypeTextMapping[type](context); + return scheduleEntryTypeTextMapping[type!]!(context); } diff --git a/lib/common/ui/text_styles.dart b/lib/common/ui/text_styles.dart index f4ec8f22..94b731db 100644 --- a/lib/common/ui/text_styles.dart +++ b/lib/common/ui/text_styles.dart @@ -1,56 +1,56 @@ import 'package:flutter/material.dart'; -TextStyle textStyleDailyScheduleEntryWidgetProfessor(BuildContext context) => +TextStyle? textStyleDailyScheduleEntryWidgetProfessor(BuildContext context) => Theme.of(context).textTheme.subtitle2; TextStyle textStyleDailyScheduleEntryWidgetTitle(BuildContext context) => Theme.of(context) .textTheme - .headline4 - .copyWith(color: Theme.of(context).textTheme.headline6.color); + .headline4! + .copyWith(color: Theme.of(context).textTheme.headline6!.color); TextStyle textStyleDailyScheduleEntryWidgetType(BuildContext context) => - Theme.of(context).textTheme.bodyText2.copyWith( + Theme.of(context).textTheme.bodyText2!.copyWith( fontWeight: FontWeight.w300, letterSpacing: 0.15, ); TextStyle textStyleDailyScheduleEntryWidgetTimeStart(BuildContext context) => - Theme.of(context).textTheme.headline5.copyWith( + Theme.of(context).textTheme.headline5!.copyWith( fontWeight: FontWeight.w600, letterSpacing: 0.15, ); -TextStyle textStyleDailyScheduleEntryWidgetTimeEnd(BuildContext context) => +TextStyle? textStyleDailyScheduleEntryWidgetTimeEnd(BuildContext context) => Theme.of(context).textTheme.subtitle2; TextStyle textStyleDailyScheduleCurrentDate(BuildContext context) => - Theme.of(context).textTheme.headline4.copyWith( - color: Theme.of(context).textTheme.headline5.color, + Theme.of(context).textTheme.headline4!.copyWith( + color: Theme.of(context).textTheme.headline5!.color, ); -TextStyle textStyleDailyScheduleNoEntries(BuildContext context) => +TextStyle? textStyleDailyScheduleNoEntries(BuildContext context) => Theme.of(context).textTheme.headline5; TextStyle textStyleScheduleEntryWidgetTitle(BuildContext context) => - Theme.of(context).textTheme.bodyText1.copyWith( + Theme.of(context).textTheme.bodyText1!.copyWith( fontWeight: FontWeight.normal, ); -TextStyle textStyleScheduleEntryBottomPageTitle(BuildContext context) => +TextStyle? textStyleScheduleEntryBottomPageTitle(BuildContext context) => Theme.of(context).textTheme.subtitle2; -TextStyle textStyleScheduleEntryBottomPageTimeFromTo(BuildContext context) => +TextStyle? textStyleScheduleEntryBottomPageTimeFromTo(BuildContext context) => Theme.of(context).textTheme.caption; -TextStyle textStyleScheduleEntryBottomPageTime(BuildContext context) => +TextStyle? textStyleScheduleEntryBottomPageTime(BuildContext context) => Theme.of(context).textTheme.headline5; TextStyle textStyleScheduleEntryBottomPageType(BuildContext context) => - Theme.of(context).textTheme.bodyText1.copyWith( + Theme.of(context).textTheme.bodyText1!.copyWith( fontWeight: FontWeight.w300, ); TextStyle textStyleScheduleWidgetColumnTitleDay(BuildContext context) => - Theme.of(context).textTheme.subtitle2.copyWith( + Theme.of(context).textTheme.subtitle2!.copyWith( fontWeight: FontWeight.w300, ); diff --git a/lib/common/ui/viewmodels/root_view_model.dart b/lib/common/ui/viewmodels/root_view_model.dart index dd2a360a..f976bcb2 100644 --- a/lib/common/ui/viewmodels/root_view_model.dart +++ b/lib/common/ui/viewmodels/root_view_model.dart @@ -5,25 +5,25 @@ import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; class RootViewModel extends BaseViewModel { final PreferencesProvider _preferencesProvider; - AppTheme _appTheme; + late AppTheme _appTheme; AppTheme get appTheme => _appTheme; - bool _isOnboarding; + late bool _isOnboarding; bool get isOnboarding => _isOnboarding; RootViewModel(this._preferencesProvider); Future loadFromPreferences() async { - var darkMode = await _preferencesProvider.appTheme(); - - _appTheme = darkMode; + _appTheme = await _preferencesProvider.appTheme(); _isOnboarding = await _preferencesProvider.isFirstStart(); notifyListeners("appTheme"); notifyListeners("isOnboarding"); } - Future setAppTheme(AppTheme value) async { + Future setAppTheme(AppTheme? value) async { + if (value == null) return; + await _preferencesProvider.setAppTheme(value); _appTheme = value; notifyListeners("appTheme"); diff --git a/lib/common/ui/widgets/dots_indicator.dart b/lib/common/ui/widgets/dots_indicator.dart index 816e3c79..abcf6f5f 100644 --- a/lib/common/ui/widgets/dots_indicator.dart +++ b/lib/common/ui/widgets/dots_indicator.dart @@ -4,7 +4,8 @@ class DotsIndicator extends StatelessWidget { final int numberSteps; final int currentStep; - const DotsIndicator({Key key, this.numberSteps, this.currentStep}) + const DotsIndicator( + {Key? key, required this.numberSteps, required this.currentStep}) : super(key: key); @override diff --git a/lib/common/ui/widgets/error_display.dart b/lib/common/ui/widgets/error_display.dart index 6cefef8f..6be52a66 100644 --- a/lib/common/ui/widgets/error_display.dart +++ b/lib/common/ui/widgets/error_display.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; class ErrorDisplay extends StatelessWidget { final bool show; - const ErrorDisplay({Key key, this.show}) : super(key: key); + const ErrorDisplay({Key? key, required this.show}) : super(key: key); @override Widget build(BuildContext context) { @@ -24,7 +24,7 @@ class ErrorDisplay extends StatelessWidget { child: Text( L.of(context).noConnectionMessage, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.subtitle2.copyWith( + style: Theme.of(context).textTheme.subtitle2!.copyWith( color: colorNoConnectionForeground(), ), ), diff --git a/lib/common/ui/widgets/title_list_tile.dart b/lib/common/ui/widgets/title_list_tile.dart index c3576a63..82de6d27 100644 --- a/lib/common/ui/widgets/title_list_tile.dart +++ b/lib/common/ui/widgets/title_list_tile.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; class TitleListTile extends StatelessWidget { final String title; - const TitleListTile({Key key, this.title}) : super(key: key); + const TitleListTile({Key? key, required this.title}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/common/util/cancelable_mutex.dart b/lib/common/util/cancelable_mutex.dart index 5335981a..3160b39c 100644 --- a/lib/common/util/cancelable_mutex.dart +++ b/lib/common/util/cancelable_mutex.dart @@ -3,8 +3,8 @@ import 'cancellation_token.dart'; class CancelableMutex { final Mutex _mutex = Mutex(); - CancellationToken _token; - CancellationToken get token => _token; + CancellationToken? _token; + CancellationToken? get token => _token; void cancel() { _token?.cancel(); diff --git a/lib/common/util/cancellation_token.dart b/lib/common/util/cancellation_token.dart index 59f097cc..36c5e604 100644 --- a/lib/common/util/cancellation_token.dart +++ b/lib/common/util/cancellation_token.dart @@ -2,7 +2,7 @@ typedef CancellationCallback = void Function(); class CancellationToken { bool _isCancelled = false; - CancellationCallback _callback; + CancellationCallback? _callback; bool isCancelled() { return _isCancelled; @@ -17,10 +17,10 @@ class CancellationToken { void cancel() { _isCancelled = true; - if (_callback != null) _callback(); + _callback?.call(); } - void setCancellationCallback(CancellationCallback callback) { + void setCancellationCallback(CancellationCallback? callback) { _callback = callback; } } diff --git a/lib/common/util/date_utils.dart b/lib/common/util/date_utils.dart index 57b54605..19903804 100644 --- a/lib/common/util/date_utils.dart +++ b/lib/common/util/date_utils.dart @@ -1,20 +1,22 @@ -DateTime toStartOfDay(DateTime dateTime) { +// TODO: [Leptopoda] write extension methods directly on [DateTime] + +DateTime? toStartOfDay(DateTime? dateTime) { return dateTime == null ? null : DateTime(dateTime.year, dateTime.month, dateTime.day, 0, 0, 0); } -DateTime toStartOfMonth(DateTime dateTime) { +DateTime? toStartOfMonth(DateTime? dateTime) { return dateTime == null ? null : DateTime(dateTime.year, dateTime.month, 1, 0, 0, 0); } -DateTime tomorrow(DateTime dateTime) { +DateTime? tomorrow(DateTime? dateTime) { return addDays(dateTime, 1); } -DateTime addDays(DateTime dateTime, int days) { +DateTime? addDays(DateTime? dateTime, int days) { return dateTime == null ? null : DateTime( @@ -28,12 +30,10 @@ DateTime addDays(DateTime dateTime, int days) { } DateTime toMonday(DateTime dateTime) { - return dateTime == null - ? null - : dateTime.subtract(Duration(days: dateTime.weekday - 1)); + return dateTime.subtract(Duration(days: dateTime.weekday - 1)); } -DateTime toPreviousWeek(DateTime dateTime) { +DateTime? toPreviousWeek(DateTime? dateTime) { return dateTime == null ? null : DateTime( @@ -46,7 +46,7 @@ DateTime toPreviousWeek(DateTime dateTime) { ); } -DateTime toNextWeek(DateTime dateTime) { +DateTime? toNextWeek(DateTime? dateTime) { return dateTime == null ? null : DateTime( @@ -60,20 +60,17 @@ DateTime toNextWeek(DateTime dateTime) { } DateTime toNextMonth(DateTime dateTime) { - return dateTime == null - ? null - : DateTime( - dateTime.year, - dateTime.month + 1, - dateTime.day, - dateTime.hour, - dateTime.minute, - dateTime.second, - ); + return DateTime( + dateTime.year, + dateTime.month + 1, + dateTime.day, + dateTime.hour, + dateTime.minute, + dateTime.second, + ); } DateTime toTimeOfDay(DateTime dateTime, int hour, int minute) { - if (dateTime == null) return null; return DateTime( dateTime.year, dateTime.month, @@ -84,8 +81,6 @@ DateTime toTimeOfDay(DateTime dateTime, int hour, int minute) { } DateTime toTimeOfDayInFuture(DateTime dateTime, int hour, int minute) { - if (dateTime == null) return null; - var newDateTime = DateTime( dateTime.year, dateTime.month, @@ -94,7 +89,7 @@ DateTime toTimeOfDayInFuture(DateTime dateTime, int hour, int minute) { minute, ); - if (dateTime.isAfter(newDateTime)) newDateTime = tomorrow(newDateTime); + if (dateTime.isAfter(newDateTime)) newDateTime = tomorrow(newDateTime)!; return newDateTime; } @@ -105,7 +100,7 @@ bool isAtSameDay(DateTime date1, DateTime date2) { date1.day == date2.day; } -DateTime toDayOfWeek(DateTime dateTime, int weekday) { +DateTime? toDayOfWeek(DateTime? dateTime, int weekday) { if (dateTime == null) return null; var startOfWeek = addDays(dateTime, -dateTime.weekday); diff --git a/lib/common/util/platform_util.dart b/lib/common/util/platform_util.dart index a602f6c6..a015d709 100644 --- a/lib/common/util/platform_util.dart +++ b/lib/common/util/platform_util.dart @@ -19,7 +19,7 @@ class PlatformUtil { static Brightness platformBrightness() { final data = MediaQueryData.fromWindow(WidgetsBinding.instance.window); - return data.platformBrightness ?? Brightness.light; + return data.platformBrightness; } static Future initializePortraitLandscapeMode() async { diff --git a/lib/common/util/string_utils.dart b/lib/common/util/string_utils.dart index f308d63b..d910d0e5 100644 --- a/lib/common/util/string_utils.dart +++ b/lib/common/util/string_utils.dart @@ -1,7 +1,9 @@ +// TODO: [Leptopoda] deprecate as dart has it's own function (at least for the above) + String concatStringList(List list, String separator) { var result = ""; - for (var element in list ?? []) { + for (var element in list) { result += element + separator; } @@ -12,10 +14,10 @@ String concatStringList(List list, String separator) { return result; } -String interpolate(String string, List params) { +String interpolate(String string, List params) { String result = string; for (int i = 0; i < params.length; i++) { - result = result.replaceAll('%$i', params[i]); + result = result.replaceAll('%$i', params[i]!); } return result; diff --git a/lib/date_management/business/date_entry_provider.dart b/lib/date_management/business/date_entry_provider.dart index 714d453d..05807f28 100644 --- a/lib/date_management/business/date_entry_provider.dart +++ b/lib/date_management/business/date_entry_provider.dart @@ -13,16 +13,16 @@ class DateEntryProvider { Future> getCachedDateEntries( DateSearchParameters parameters, ) async { - var cachedEntries = []; + List cachedEntries = []; - if (parameters.includeFuture && parameters.includePast) { + if (parameters.includeFuture! && parameters.includePast!) { cachedEntries = await _dateEntryRepository.queryAllDateEntries( parameters.databaseName, parameters.year, ); } else { var now = DateTime.now(); - if (parameters.includeFuture) { + if (parameters.includeFuture!) { var datesAfter = await _dateEntryRepository.queryDateEntriesAfter( parameters.databaseName, parameters.year, @@ -31,7 +31,7 @@ class DateEntryProvider { cachedEntries.addAll(datesAfter); } - if (parameters.includePast) { + if (parameters.includePast!) { var datesBefore = await _dateEntryRepository.queryDateEntriesBefore( parameters.databaseName, parameters.year, @@ -41,8 +41,9 @@ class DateEntryProvider { } } - cachedEntries.sort((DateEntry a1, DateEntry a2) => - a1?.start?.compareTo(a2?.start)); + cachedEntries.sort( + (DateEntry a1, DateEntry a2) => a1.start.compareTo(a2.start), + ); print("Read cached ${cachedEntries.length} date entries"); @@ -51,7 +52,7 @@ class DateEntryProvider { Future> getDateEntries( DateSearchParameters parameters, - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ) async { var updatedEntries = await _dateEntryService.queryAllDates( parameters, @@ -82,11 +83,11 @@ class DateEntryProvider { continue; } - if (dateEntry.start.isBefore(now) && !parameters.includePast) { + if (dateEntry.start.isBefore(now) && !parameters.includePast!) { continue; } - if (dateEntry.end.isAfter(now) && !parameters.includeFuture) { + if (dateEntry.end.isAfter(now) && !parameters.includeFuture!) { continue; } diff --git a/lib/date_management/data/calendar_access.dart b/lib/date_management/data/calendar_access.dart index d57bdec7..cf6c852c 100644 --- a/lib/date_management/data/calendar_access.dart +++ b/lib/date_management/data/calendar_access.dart @@ -5,8 +5,6 @@ import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; import 'package:flutter/services.dart'; import 'package:timezone/timezone.dart' as tz; - - enum CalendarPermission { PermissionGranted, PermissionDenied, @@ -19,14 +17,13 @@ enum CalendarPermission { class CalendarAccess { final DeviceCalendarPlugin _deviceCalendarPlugin = DeviceCalendarPlugin(); - Future requestCalendarPermission() async { try { var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); - if (permissionsGranted.isSuccess && !permissionsGranted.data) { + if (permissionsGranted.isSuccess && !permissionsGranted.data!) { permissionsGranted = await _deviceCalendarPlugin.requestPermissions(); - if (!permissionsGranted.isSuccess || !permissionsGranted.data) { + if (!permissionsGranted.isSuccess || !permissionsGranted.data!) { return CalendarPermission.PermissionDenied; } } @@ -42,8 +39,8 @@ class CalendarAccess { Future> queryWriteableCalendars() async { final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); var writeableCalendars = []; - for (var calendar in calendarsResult?.data ?? []) { - if (!calendar.isReadOnly) { + for (var calendar in calendarsResult.data ?? []) { + if (!calendar.isReadOnly!) { writeableCalendars.add(calendar); } } @@ -53,12 +50,12 @@ class CalendarAccess { Future addOrUpdateDates( List dateEntries, - Calendar calendar, + Calendar? calendar, ) async { - if ((dateEntries ?? []).isEmpty) return; + if (dateEntries.isEmpty) return; var existingEvents = - await _getExistingEventsFromCalendar(dateEntries, calendar); + await _getExistingEventsFromCalendar(dateEntries, calendar!); for (var entry in dateEntries) { await _addOrUpdateEntry(existingEvents, entry, calendar); @@ -82,7 +79,6 @@ class CalendarAccess { end = entry.end; } - return await _deviceCalendarPlugin.createOrUpdateEvent(Event( calendar.id, location: entry.room, @@ -95,11 +91,13 @@ class CalendarAccess { )); } - String _getIdOfExistingEvent(List existingEvents, DateEntry entry) { + String? _getIdOfExistingEvent(List existingEvents, DateEntry entry) { var existingEvent = existingEvents - .where((element) => (element.title == entry.description && element.start.toUtc().isAtSameMomentAs(entry.start.toUtc()))) + .where((element) => (element.title == entry.description && + (element.start?.toUtc().isAtSameMomentAs(entry.start.toUtc()) ?? + false))) .toList(); - String id; + String? id; if (existingEvent.isNotEmpty) { id = existingEvent[0].eventId; @@ -122,7 +120,7 @@ class CalendarAccess { var existingEvents = []; if (existingEventsResult.isSuccess) { - existingEvents = existingEventsResult.data.toList(); + existingEvents = existingEventsResult.data!.toList(); } return existingEvents; } @@ -131,7 +129,7 @@ class CalendarAccess { var firstEntry = entries[0]; for (var entry in entries) { - if (entry.end.isBefore(firstEntry?.end)) { + if (entry.end.isBefore(firstEntry.end)) { firstEntry = entry; } } diff --git a/lib/date_management/data/date_entry_entity.dart b/lib/date_management/data/date_entry_entity.dart index 20302338..b3b23a75 100644 --- a/lib/date_management/data/date_entry_entity.dart +++ b/lib/date_management/data/date_entry_entity.dart @@ -2,22 +2,17 @@ import 'package:dhbwstudentapp/common/data/database_entity.dart'; import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; class DateEntryEntity extends DatabaseEntity { - DateEntry _dateEntry; + // TODO: [Leptopoda] make non null + DateEntry? _dateEntry; - DateEntryEntity.fromModel(DateEntry dateEntry) { - _dateEntry = dateEntry; - } + DateEntryEntity.fromModel(DateEntry dateEntry) : _dateEntry = dateEntry; DateEntryEntity.fromMap(Map map) { fromMap(map); } - @override void fromMap(Map map) { - DateTime date; - if (map["date"] != null) { - date = DateTime.fromMillisecondsSinceEpoch(map["date"]); - } + var date = DateTime.fromMillisecondsSinceEpoch(map["date"]); _dateEntry = DateEntry( comment: map["comment"], @@ -26,22 +21,24 @@ class DateEntryEntity extends DatabaseEntity { databaseName: map["databaseName"], start: date, end: date, - room: map["room"] + room: map["room"], ); } @override Map toMap() { + assert(_dateEntry != null); return { - "date": _dateEntry.start?.millisecondsSinceEpoch ?? 0, - "comment": _dateEntry.comment ?? "", - "description": _dateEntry.description ?? "", - "year": _dateEntry.year ?? "", - "databaseName": _dateEntry.databaseName ?? "" + "date": _dateEntry!.start.millisecondsSinceEpoch, + "comment": _dateEntry!.comment, + "description": _dateEntry!.description, + "year": _dateEntry!.year, + "databaseName": _dateEntry!.databaseName, }; } - DateEntry asDateEntry() => _dateEntry; + DateEntry asDateEntry() => _dateEntry!; + // TODO: [Leptopoda] make getter or even constant. static String tableName() => "DateEntries"; } diff --git a/lib/date_management/data/date_entry_repository.dart b/lib/date_management/data/date_entry_repository.dart index 7a4f675b..7fc21c7b 100644 --- a/lib/date_management/data/date_entry_repository.dart +++ b/lib/date_management/data/date_entry_repository.dart @@ -8,8 +8,8 @@ class DateEntryRepository { DateEntryRepository(this._database); Future> queryAllDateEntries( - String databaseName, - String year, + String? databaseName, + String? year, ) async { var rows = await _database.queryRows( DateEntryEntity.tableName(), @@ -20,7 +20,7 @@ class DateEntryRepository { return _rowsToDateEntries(rows); } - Future> queryDateEntriesBetween( + Future> queryDateEntriesBetween( String databaseName, String year, DateTime start, @@ -41,8 +41,8 @@ class DateEntryRepository { } Future> queryDateEntriesAfter( - String databaseName, - String year, + String? databaseName, + String? year, DateTime date, ) async { var rows = await _database.queryRows( @@ -59,8 +59,8 @@ class DateEntryRepository { } Future> queryDateEntriesBefore( - String databaseName, - String year, + String? databaseName, + String? year, DateTime date, ) async { var rows = await _database.queryRows( @@ -88,8 +88,8 @@ class DateEntryRepository { } Future deleteAllDateEntries( - String databaseName, - String year, + String? databaseName, + String? year, ) async { await _database.deleteWhere(DateEntryEntity.tableName(), where: "databaseName=? AND year=?", diff --git a/lib/date_management/model/date_entry.dart b/lib/date_management/model/date_entry.dart index 02ba7271..17e4ce98 100644 --- a/lib/date_management/model/date_entry.dart +++ b/lib/date_management/model/date_entry.dart @@ -5,15 +5,20 @@ class DateEntry { final String databaseName; final DateTime start; final DateTime end; - final String room; + final String? room; DateEntry({ - this.description, - this.year, - this.comment, - this.databaseName, - this.start, - this.end, - this.room - }); + String? description, + String? year, + String? comment, + String? databaseName, + DateTime? start, + DateTime? end, + this.room, + }) : this.start = start ?? DateTime.fromMicrosecondsSinceEpoch(0), + this.end = end ?? DateTime.fromMicrosecondsSinceEpoch(0), + this.comment = comment ?? "", + this.description = description ?? "", + this.year = year ?? "", + this.databaseName = databaseName ?? ""; } diff --git a/lib/date_management/model/date_search_parameters.dart b/lib/date_management/model/date_search_parameters.dart index a6a1dfc5..f686fc9f 100644 --- a/lib/date_management/model/date_search_parameters.dart +++ b/lib/date_management/model/date_search_parameters.dart @@ -1,8 +1,8 @@ class DateSearchParameters { - bool includePast; - bool includeFuture; - String year; - String databaseName; + bool? includePast; + bool? includeFuture; + String? year; + String? databaseName; DateSearchParameters( this.includePast, diff --git a/lib/date_management/service/date_management_service.dart b/lib/date_management/service/date_management_service.dart index a192677a..0e5d11fa 100644 --- a/lib/date_management/service/date_management_service.dart +++ b/lib/date_management/service/date_management_service.dart @@ -7,7 +7,7 @@ import 'package:dhbwstudentapp/dualis/service/session.dart'; class DateManagementService { Future> queryAllDates( DateSearchParameters parameters, - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ) async { var queryResult = await Session().get( _buildRequestUrl(parameters), @@ -28,7 +28,7 @@ class DateManagementService { url += "&sel_typ=pub"; url += "&sel_jahrgang= ${parameters.year ?? "*"}"; url += "&sel_bezeichnung=*"; - url += "&selection=${parameters.includePast ? "**" : "*"}"; + url += "&selection=${parameters.includePast! ? "**" : "*"}"; url += "&permission=show"; url += "&sessionid="; url += "&user=nobody"; diff --git a/lib/date_management/service/parsing/all_dates_extract.dart b/lib/date_management/service/parsing/all_dates_extract.dart index 3db64a4f..828c75bb 100644 --- a/lib/date_management/service/parsing/all_dates_extract.dart +++ b/lib/date_management/service/parsing/all_dates_extract.dart @@ -5,7 +5,8 @@ import 'package:intl/intl.dart'; // TODO: Parse exception to common module class AllDatesExtract { - List extractAllDates(String body, String databaseName) { + List extractAllDates(String? body, String? databaseName) { + if (body == null) return []; try { return _extractAllDates(body, databaseName); } catch (e, trace) { @@ -14,7 +15,7 @@ class AllDatesExtract { } } - List _extractAllDates(String body, String databaseName) { + List _extractAllDates(String body, String? databaseName) { body = body.replaceAll(new RegExp("<(br|BR)[ /]*>"), "\n"); var document = parse(body); @@ -24,7 +25,7 @@ class AllDatesExtract { var dateEntries = []; for (var a in dateContainingElement.nodes.sublist(0)) { - var text = a.text; + var text = a.text!; var lines = text.split("\n"); @@ -38,12 +39,12 @@ class AllDatesExtract { } dateEntries - .sort((DateEntry e1, DateEntry e2) => e1.start?.compareTo(e2.start)); + .sort((DateEntry e1, DateEntry e2) => e1.start.compareTo(e2.start)); return dateEntries; } - DateEntry _parseDateEntryLine(String line, String databaseName) { + DateEntry? _parseDateEntryLine(String line, String? databaseName) { var parts = line.split(';'); if (parts.length != 5) { @@ -64,7 +65,7 @@ class AllDatesExtract { end: date); } - DateTime _parseDateTime(String date, String time) { + DateTime? _parseDateTime(String date, String time) { if (time == "24:00") { time = "00:00"; } diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 6ee2188d..9a439d32 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -15,32 +15,25 @@ class CalendarExportPage extends StatefulWidget { final bool isCalendarSyncEnabled; const CalendarExportPage( - {Key key, - this.entriesToExport, + {Key? key, + required this.entriesToExport, this.isCalendarSyncWidget = false, this.isCalendarSyncEnabled = false}) : super(key: key); @override - _CalendarExportPageState createState() => _CalendarExportPageState( - entriesToExport, isCalendarSyncWidget, isCalendarSyncEnabled); + _CalendarExportPageState createState() => _CalendarExportPageState(); } class _CalendarExportPageState extends State { - final List entriesToExport; - final bool isCalendarSyncWidget; - final bool isCalendarSyncEnabled; - CalendarExportViewModel viewModel; - - _CalendarExportPageState(this.entriesToExport, this.isCalendarSyncWidget, - this.isCalendarSyncEnabled); + late CalendarExportViewModel viewModel; @override void initState() { super.initState(); - viewModel = CalendarExportViewModel(entriesToExport, CalendarAccess(), - KiwiContainer().resolve()); + viewModel = CalendarExportViewModel(widget.entriesToExport, + CalendarAccess(), KiwiContainer().resolve()); viewModel.setOnPermissionDeniedCallback(() { Navigator.of(context).pop(); }); @@ -57,7 +50,7 @@ class _CalendarExportPageState extends State { actionsIconTheme: Theme.of(context).iconTheme, elevation: 0, iconTheme: Theme.of(context).iconTheme, - title: Text(this.isCalendarSyncWidget + title: Text(widget.isCalendarSyncWidget ? L.of(context).calendarSyncPageTitle : L.of(context).dateManagementExportToCalendar), toolbarTextStyle: Theme.of(context).textTheme.bodyText2, @@ -69,7 +62,7 @@ class _CalendarExportPageState extends State { padding: const EdgeInsets.all(24), child: Align( alignment: Alignment.centerLeft, - child: Text(this.isCalendarSyncWidget + child: Text(widget.isCalendarSyncWidget ? L.of(context).calendarSyncPageSubtitle : L.of(context).dateManagementExportToCalendarDescription), ), @@ -89,12 +82,13 @@ class _CalendarExportPageState extends State { Widget _buildCalendarList() { return Expanded( child: PropertyChangeConsumer( - builder: (BuildContext context, CalendarExportViewModel viewModel, _) => - ListView.builder( - itemCount: viewModel.calendars.length, + builder: + (BuildContext context, CalendarExportViewModel? viewModel, _) => + ListView.builder( + itemCount: viewModel!.calendars.length, itemBuilder: (BuildContext context, int index) { - var isSelected = viewModel.selectedCalendar?.id == - viewModel.calendars[index]?.id; + var isSelected = + viewModel.selectedCalendar?.id == viewModel.calendars[index].id; return _buildCalendarListEntry( viewModel.calendars[index], @@ -109,21 +103,21 @@ class _CalendarExportPageState extends State { Widget _buildStopCalendarSyncBtn() { // Dont display the "Synchronisation beenden" button, //if synchronization is not enabled or if it is not the right page - if (!this.isCalendarSyncWidget) return SizedBox(); + if (!widget.isCalendarSyncWidget) return SizedBox(); return PropertyChangeProvider( value: viewModel, child: Column( children: [ Container( - decoration: this.isCalendarSyncEnabled ? null : null, + decoration: widget.isCalendarSyncEnabled ? null : null, child: ListTile( - enabled: this.isCalendarSyncEnabled ? true : false, + enabled: widget.isCalendarSyncEnabled ? true : false, title: Text( L.of(context).calendarSyncPageEndSync.toUpperCase(), textAlign: TextAlign.center, style: TextStyle( - color: this.isCalendarSyncEnabled + color: widget.isCalendarSyncEnabled ? ColorPalettes.main : Theme.of(context).disabledColor, fontSize: 14), @@ -163,9 +157,9 @@ class _CalendarExportPageState extends State { height: 24, decoration: BoxDecoration( shape: BoxShape.circle, - color: isSelected ? Color(calendar.color) : Colors.transparent, + color: isSelected ? Color(calendar.color!) : Colors.transparent, border: Border.all( - color: Color(calendar.color), + color: Color(calendar.color!), width: 4, ), ), @@ -181,7 +175,7 @@ class _CalendarExportPageState extends State { ), Padding( padding: const EdgeInsets.fromLTRB(16, 0, 0, 0), - child: Text(calendar.name), + child: Text(calendar.name!), ), ], ), @@ -191,8 +185,8 @@ class _CalendarExportPageState extends State { Widget _buildExportButton() { return PropertyChangeConsumer( - builder: (BuildContext context, CalendarExportViewModel viewModel, _) => - viewModel.isExporting + builder: (BuildContext context, CalendarExportViewModel? viewModel, _) => + viewModel!.isExporting ? const Padding( padding: EdgeInsets.fromLTRB(8, 8, 8, 15), child: SizedBox( @@ -214,7 +208,7 @@ class _CalendarExportPageState extends State { borderRadius: BorderRadius.all(Radius.circular(4.0)), ), title: Text( - this.isCalendarSyncWidget + widget.isCalendarSyncWidget ? L .of(context) .calendarSyncPageBeginSync @@ -231,7 +225,7 @@ class _CalendarExportPageState extends State { ), onTap: viewModel.canExport ? () async { - if (this.isCalendarSyncWidget) { + if (widget.isCalendarSyncWidget) { var preferencesProvider = KiwiContainer() .resolve(); preferencesProvider.setSelectedCalendar( diff --git a/lib/date_management/ui/date_management_navigation_entry.dart b/lib/date_management/ui/date_management_navigation_entry.dart index 57856113..04806a09 100644 --- a/lib/date_management/ui/date_management_navigation_entry.dart +++ b/lib/date_management/ui/date_management_navigation_entry.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/date_management/ui/calendar_export_page.dart'; import 'package:dhbwstudentapp/date_management/ui/date_management_page.dart'; import 'package:dhbwstudentapp/date_management/ui/viewmodels/date_management_view_model.dart'; @@ -10,13 +9,10 @@ import 'package:flutter/material.dart'; import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; -class DateManagementNavigationEntry extends NavigationEntry { - DateManagementViewModel _viewModel; - +class DateManagementNavigationEntry + extends NavigationEntry { @override - Widget icon(BuildContext context) { - return Icon(Icons.date_range); - } + Icon icon = Icon(Icons.date_range); @override String title(BuildContext context) { @@ -24,20 +20,15 @@ class DateManagementNavigationEntry extends NavigationEntry { } @override - BaseViewModel initViewModel() { - if (_viewModel == null) { - _viewModel = DateManagementViewModel( - KiwiContainer().resolve(), - KiwiContainer().resolve(), - ); - } - - return _viewModel; + DateManagementViewModel initViewModel() { + return DateManagementViewModel( + KiwiContainer().resolve(), + KiwiContainer().resolve(), + ); } @override List appBarActions(BuildContext context) { - initViewModel(); return [ IconButton( icon: Icon(Icons.help_outline), @@ -47,17 +38,19 @@ class DateManagementNavigationEntry extends NavigationEntry { tooltip: L.of(context).helpButtonTooltip, ), PropertyChangeProvider( - value: _viewModel, + value: model, child: PropertyChangeConsumer( - builder: - (BuildContext context, DateManagementViewModel viewModel, _) => - PopupMenuButton( + builder: (BuildContext context, DateManagementViewModel? _, __) => + PopupMenuButton( onSelected: (i) async { - await NavigatorKey.rootKey.currentState.push(MaterialPageRoute( + await NavigatorKey.rootKey.currentState!.push( + MaterialPageRoute( builder: (BuildContext context) => CalendarExportPage( - entriesToExport: viewModel.allDates, - ), - settings: RouteSettings(name: "settings"))); + entriesToExport: model.allDates!, + ), + settings: RouteSettings(name: "settings"), + ), + ); }, itemBuilder: (BuildContext context) { return [ diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index 5ace61e4..3e2d124a 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/common/ui/widgets/error_display.dart'; import 'package:dhbwstudentapp/common/util/date_utils.dart'; import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; @@ -14,7 +13,8 @@ import 'package:provider/provider.dart'; class DateManagementPage extends StatelessWidget { @override Widget build(BuildContext context) { - DateManagementViewModel viewModel = Provider.of(context); + DateManagementViewModel viewModel = + Provider.of(context); return PropertyChangeProvider( value: viewModel, @@ -47,17 +47,17 @@ class DateManagementPage extends StatelessWidget { child: PropertyChangeConsumer( builder: ( BuildContext context, - DateManagementViewModel model, + DateManagementViewModel? model, _, ) => AnimatedSwitcher( duration: const Duration(milliseconds: 200), child: Column( - key: ValueKey( - viewModel?.dateSearchParameters?.toString() ?? ""), + key: + ValueKey(viewModel.dateSearchParameters.toString()), crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildAllDatesDataTable(model, context), + _buildAllDatesDataTable(model!, context), ], )), ), @@ -94,17 +94,21 @@ class DateManagementPage extends StatelessWidget { BuildContext context, ) { var dataRows = []; - for (DateEntry dateEntry in model?.allDates ?? []) { + for (DateEntry dateEntry in model.allDates ?? []) { dataRows.add( DataRow( cells: [ DataCell( - Text(dateEntry.description, - style: dateEntry.end.isBefore(DateTime.now()) - ? TextStyle(decoration: TextDecoration.lineThrough) - : null), onTap: () { - showDateEntryDetailBottomSheet(context, dateEntry); - }), + Text( + dateEntry.description, + style: dateEntry.end.isBefore(DateTime.now()) + ? TextStyle(decoration: TextDecoration.lineThrough) + : null, + ), + onTap: () { + showDateEntryDetailBottomSheet(context, dateEntry); + }, + ), DataCell( Column( mainAxisAlignment: MainAxisAlignment.center, @@ -138,7 +142,7 @@ class DateManagementPage extends StatelessWidget { return dataRows; } - void showDateEntryDetailBottomSheet(BuildContext context, DateEntry entry) { + void showDateEntryDetailBottomSheet(BuildContext context, DateEntry? entry) { showModalBottomSheet( useRootNavigator: true, context: context, @@ -156,10 +160,10 @@ class DateManagementPage extends StatelessWidget { properties: const [ "updateFailed", ], - builder: (BuildContext context, DateManagementViewModel model, - Set properties) => + builder: (BuildContext context, DateManagementViewModel? model, + Set? properties) => ErrorDisplay( - show: model.updateFailed, + show: model!.updateFailed, ), ); } diff --git a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart index 7bbf6d6a..b4f9a78a 100644 --- a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart +++ b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart @@ -11,20 +11,21 @@ class CalendarExportViewModel extends BaseViewModel { final PreferencesProvider preferencesProvider; final List _entriesToExport; - OnPermissionDenied _onPermissionDenied; + OnPermissionDenied? _onPermissionDenied; - List _calendars; - List get calendars => _calendars ?? []; + List? _calendars; + List get calendars => _calendars ??= []; - Calendar _selectedCalendar; - Calendar get selectedCalendar => _selectedCalendar; + Calendar? _selectedCalendar; + Calendar? get selectedCalendar => _selectedCalendar; bool get canExport => _selectedCalendar != null; bool _isExporting = false; bool get isExporting => _isExporting; - CalendarExportViewModel(this._entriesToExport, this.calendarAccess, this.preferencesProvider) { + CalendarExportViewModel( + this._entriesToExport, this.calendarAccess, this.preferencesProvider) { loadCalendars(); } @@ -41,12 +42,12 @@ class CalendarExportViewModel extends BaseViewModel { notifyListeners("_calendars"); } - void loadSelectedCalendar() async{ + void loadSelectedCalendar() async { _selectedCalendar = await preferencesProvider.getSelectedCalendar(); notifyListeners("selectedCalendar"); } - void resetSelectedCalendar() async{ + void resetSelectedCalendar() async { await preferencesProvider.setSelectedCalendar(null); this.loadCalendars(); } diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index 2c4b1765..87c1437c 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -33,16 +33,16 @@ class DateManagementViewModel extends BaseViewModel { final CancelableMutex _updateMutex = CancelableMutex(); - Timer _errorResetTimer; + Timer? _errorResetTimer; - List _years; + List _years = []; List get years => _years; - String _currentSelectedYear; - String get currentSelectedYear => _currentSelectedYear; + String? _currentSelectedYear; + String? get currentSelectedYear => _currentSelectedYear; - List _allDates; - List get allDates => _allDates; + List? _allDates; + List? get allDates => _allDates; bool _showPassedDates = false; bool get showPassedDates => _showPassedDates; @@ -53,8 +53,8 @@ class DateManagementViewModel extends BaseViewModel { bool _isLoading = false; bool get isLoading => _isLoading; - DateDatabase _currentDateDatabase; - DateDatabase get currentDateDatabase => _currentDateDatabase; + DateDatabase? _currentDateDatabase; + DateDatabase? get currentDateDatabase => _currentDateDatabase; int _dateEntriesKeyIndex = 0; int get dateEntriesKeyIndex => _dateEntriesKeyIndex; @@ -75,8 +75,6 @@ class DateManagementViewModel extends BaseViewModel { } void _buildYearsArray() { - _years = []; - for (var i = 2017; i < DateTime.now().year + 3; i++) { _years.add(i.toString()); } @@ -90,7 +88,8 @@ class DateManagementViewModel extends BaseViewModel { notifyListeners("isLoading"); await _doUpdateDates(); - } catch (_) {} finally { + } catch (_) { + } finally { _isLoading = false; _updateMutex.release(); notifyListeners("isLoading"); @@ -99,11 +98,11 @@ class DateManagementViewModel extends BaseViewModel { Future _doUpdateDates() async { var cachedDateEntries = await _readCachedDateEntries(); - _updateMutex.token.throwIfCancelled(); + _updateMutex.token!.throwIfCancelled(); _setAllDates(cachedDateEntries); var loadedDateEntries = await _readUpdatedDateEntries(); - _updateMutex.token.throwIfCancelled(); + _updateMutex.token!.throwIfCancelled(); if (loadedDateEntries != null) { _setAllDates(loadedDateEntries); @@ -117,23 +116,23 @@ class DateManagementViewModel extends BaseViewModel { notifyListeners("updateFailed"); } - Future> _readUpdatedDateEntries() async { + Future?> _readUpdatedDateEntries() async { try { var loadedDateEntries = await _dateEntryProvider.getDateEntries( dateSearchParameters, _updateMutex.token, ); return loadedDateEntries; - } on OperationCancelledException {} on ServiceRequestFailed {} + } on OperationCancelledException { + } on ServiceRequestFailed {} return null; } Future> _readCachedDateEntries() async { - var cachedDateEntries = await _dateEntryProvider.getCachedDateEntries( + return _dateEntryProvider.getCachedDateEntries( dateSearchParameters, ); - return cachedDateEntries; } void _setAllDates(List dateEntries) { @@ -143,24 +142,31 @@ class DateManagementViewModel extends BaseViewModel { notifyListeners("allDates"); } - void setShowPassedDates(bool value) { + // TODO [Leptopoda]: use setters + void setShowPassedDates(bool? value) { + if (value == null) return; + _showPassedDates = value; notifyListeners("showPassedDates"); } - void setShowFutureDates(bool value) { + void setShowFutureDates(bool? value) { + if (value == null) return; + _showFutureDates = value; notifyListeners("showFutureDates"); } - void setCurrentDateDatabase(DateDatabase database) { + void setCurrentDateDatabase(DateDatabase? database) { _currentDateDatabase = database; notifyListeners("currentDateDatabase"); _preferencesProvider.setLastViewedDateEntryDatabase(database?.id); } - void setCurrentSelectedYear(String year) { + void setCurrentSelectedYear(String? year) { + if (year == null) return; + _currentSelectedYear = year; notifyListeners("currentSelectedYear"); @@ -183,19 +189,13 @@ class DateManagementViewModel extends BaseViewModel { } var year = await _preferencesProvider.getLastViewedDateEntryYear(); - if (year != null) { - setCurrentSelectedYear(year); - } else { - setCurrentSelectedYear(years[0]); - } + setCurrentSelectedYear(year ?? years[0]); await updateDates(); } void _cancelErrorInFuture() async { - if (_errorResetTimer != null) { - _errorResetTimer.cancel(); - } + _errorResetTimer?.cancel(); _errorResetTimer = Timer( const Duration(seconds: 5), diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index 679eba0e..981ab641 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -6,16 +6,16 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class DateDetailBottomSheet extends StatelessWidget { - final DateEntry dateEntry; + final DateEntry? dateEntry; - const DateDetailBottomSheet({Key key, this.dateEntry}) : super(key: key); + const DateDetailBottomSheet({Key? key, this.dateEntry}) : super(key: key); @override Widget build(BuildContext context) { var date = DateFormat.yMd(L.of(context).locale.languageCode) - .format(dateEntry.start); + .format(dateEntry!.start); var time = DateFormat.Hm(L.of(context).locale.languageCode) - .format(dateEntry.start); + .format(dateEntry!.start); return Container( height: 400, @@ -46,7 +46,7 @@ class DateDetailBottomSheet extends StatelessWidget { children: [ Expanded( child: Text( - dateEntry.description, + dateEntry!.description, style: Theme.of(context).textTheme.headline5, ), ), @@ -60,7 +60,7 @@ class DateDetailBottomSheet extends StatelessWidget { softWrap: true, style: Theme.of(context).textTheme.subtitle2, ), - isAtMidnight(dateEntry.start) + isAtMidnight(dateEntry!.start) ? Container() : Text( time, @@ -75,7 +75,7 @@ class DateDetailBottomSheet extends StatelessWidget { Padding( padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), child: Text( - dateEntry.comment, + dateEntry!.comment, ), ), ], diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index de063007..1eaf161a 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -6,19 +6,16 @@ import 'package:flutter/material.dart'; class DateFilterOptions extends StatefulWidget { final DateManagementViewModel viewModel; - const DateFilterOptions({Key key, this.viewModel}) : super(key: key); + const DateFilterOptions({Key? key, required this.viewModel}) + : super(key: key); @override - _DateFilterOptionsState createState() => _DateFilterOptionsState(viewModel); + _DateFilterOptionsState createState() => _DateFilterOptionsState(); } class _DateFilterOptionsState extends State { - final DateManagementViewModel viewModel; - bool _isExpanded = false; - _DateFilterOptionsState(this.viewModel); - @override Widget build(BuildContext context) { return AnimatedCrossFade( @@ -81,31 +78,31 @@ class _DateFilterOptionsState extends State { Widget _buildCollapsedChips() { var chips = []; - if (viewModel.showPassedDates && viewModel.showFutureDates) { + if (widget.viewModel.showPassedDates && widget.viewModel.showFutureDates) { chips.add(Chip( label: Text(L.of(context).dateManagementChipFutureAndPast), visualDensity: VisualDensity.compact, )); - } else if (viewModel.showFutureDates) { + } else if (widget.viewModel.showFutureDates) { chips.add(Chip( label: Text(L.of(context).dateManagementChipOnlyFuture), visualDensity: VisualDensity.compact, )); - } else if (viewModel.showPassedDates) { + } else if (widget.viewModel.showPassedDates) { chips.add(Chip( label: Text(L.of(context).dateManagementChipOnlyPassed), visualDensity: VisualDensity.compact, )); } - if (viewModel.currentSelectedYear != null) { + if (widget.viewModel.currentSelectedYear != null) { chips.add(Chip( - label: Text(viewModel.currentSelectedYear), + label: Text(widget.viewModel.currentSelectedYear!), visualDensity: VisualDensity.compact, )); } - var database = viewModel.currentDateDatabase?.displayName ?? ""; + var database = widget.viewModel.currentDateDatabase?.displayName ?? ""; if (database != "") { chips.add(Chip( label: Text(database), @@ -147,10 +144,8 @@ class _DateFilterOptionsState extends State { flex: 1, child: DropdownButton( isExpanded: true, - value: viewModel.currentDateDatabase, - onChanged: (value) { - viewModel.setCurrentDateDatabase(value); - }, + value: widget.viewModel.currentDateDatabase, + onChanged: widget.viewModel.setCurrentDateDatabase, items: _buildDatabaseMenuItems(), ), ), @@ -171,10 +166,8 @@ class _DateFilterOptionsState extends State { flex: 1, child: DropdownButton( isExpanded: true, - value: viewModel.currentSelectedYear, - onChanged: (value) { - viewModel.setCurrentSelectedYear(value); - }, + value: widget.viewModel.currentSelectedYear, + onChanged: widget.viewModel.setCurrentSelectedYear, items: _buildYearsMenuItems(), ), ), @@ -182,19 +175,15 @@ class _DateFilterOptionsState extends State { ), CheckboxListTile( title: Text(L.of(context).dateManagementCheckBoxFutureDates), - value: viewModel.showFutureDates, + value: widget.viewModel.showFutureDates, dense: true, - onChanged: (bool value) { - viewModel.setShowFutureDates(value); - }, + onChanged: widget.viewModel.setShowFutureDates, ), CheckboxListTile( title: Text(L.of(context).dateManagementCheckBoxPassedDates), - value: viewModel.showPassedDates, + value: widget.viewModel.showPassedDates, dense: true, - onChanged: (bool value) { - viewModel.setShowPassedDates(value); - }, + onChanged: widget.viewModel.setShowPassedDates, ), ], ), @@ -211,7 +200,7 @@ class _DateFilterOptionsState extends State { _isExpanded = false; }); - viewModel.updateDates(); + widget.viewModel.updateDates(); }, ), ), @@ -223,7 +212,7 @@ class _DateFilterOptionsState extends State { List> _buildYearsMenuItems() { var yearMenuItems = >[]; - for (var year in viewModel.years) { + for (var year in widget.viewModel.years) { yearMenuItems.add(DropdownMenuItem( child: Text(year), value: year, @@ -235,7 +224,7 @@ class _DateFilterOptionsState extends State { List> _buildDatabaseMenuItems() { var databaseMenuItems = >[]; - for (var database in viewModel.allDateDatabases) { + for (var database in widget.viewModel.allDateDatabases) { databaseMenuItems.add(DropdownMenuItem( child: Text(database.displayName), value: database, diff --git a/lib/dualis/model/credentials.dart b/lib/dualis/model/credentials.dart index 81eb7831..d409e54f 100644 --- a/lib/dualis/model/credentials.dart +++ b/lib/dualis/model/credentials.dart @@ -1,10 +1,42 @@ -class Credentials { - final String password; +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; + +class Credentials extends Equatable { final String username; + final String password; + + const Credentials(this.username, this.password); + + @override + List get props => [username, password]; +} - Credentials(this.username, this.password); +class CredentialsEditingController { + final _usernameController = TextEditingController(); + final _passwordController = TextEditingController(); - bool allFieldsFilled() { - return password != null && username != null; + CredentialsEditingController([Credentials? credentials]) { + if (credentials != null) { + _usernameController.text = credentials.username; + _passwordController.text = credentials.password; + } } + + set credentials(Credentials credentials) { + _usernameController.text = credentials.username; + _passwordController.text = credentials.password; + } + + void dispose() { + _usernameController.dispose(); + _passwordController.dispose(); + } + + TextEditingController get username => _usernameController; + TextEditingController get password => _passwordController; + + Credentials get credentials => Credentials( + _usernameController.text, + _passwordController.text, + ); } diff --git a/lib/dualis/model/exam.dart b/lib/dualis/model/exam.dart index e8947ddb..22cf8f93 100644 --- a/lib/dualis/model/exam.dart +++ b/lib/dualis/model/exam.dart @@ -7,9 +7,9 @@ enum ExamState { } class Exam { - final String name; + final String? name; final ExamGrade grade; - final String semester; + final String? semester; final ExamState state; Exam( diff --git a/lib/dualis/model/exam_grade.dart b/lib/dualis/model/exam_grade.dart index a494edac..0759ddd1 100644 --- a/lib/dualis/model/exam_grade.dart +++ b/lib/dualis/model/exam_grade.dart @@ -7,7 +7,7 @@ enum ExamGradeState { class ExamGrade { ExamGradeState state; - String gradeValue; + String? gradeValue; ExamGrade.failed() : state = ExamGradeState.Failed, @@ -23,7 +23,7 @@ class ExamGrade { ExamGrade.graded(this.gradeValue) : state = ExamGradeState.Graded; - static ExamGrade fromString(String grade) { + static ExamGrade fromString(String? grade) { if (grade == "noch nicht gesetzt" || grade == "") { return ExamGrade.notGraded(); } diff --git a/lib/dualis/model/module.dart b/lib/dualis/model/module.dart index d6e4dc56..c2d1d879 100644 --- a/lib/dualis/model/module.dart +++ b/lib/dualis/model/module.dart @@ -2,11 +2,11 @@ import 'package:dhbwstudentapp/dualis/model/exam.dart'; class Module { final List exams; - final String id; - final String name; - final String credits; - final String grade; - final ExamState state; + final String? id; + final String? name; + final String? credits; + final String? grade; + final ExamState? state; Module( this.exams, diff --git a/lib/dualis/model/semester.dart b/lib/dualis/model/semester.dart index 84eecc90..db30676b 100644 --- a/lib/dualis/model/semester.dart +++ b/lib/dualis/model/semester.dart @@ -1,7 +1,7 @@ import 'package:dhbwstudentapp/dualis/model/module.dart'; class Semester { - final String name; + final String? name; final List modules; Semester( diff --git a/lib/dualis/model/study_grades.dart b/lib/dualis/model/study_grades.dart index d57266b2..e5b25ab4 100644 --- a/lib/dualis/model/study_grades.dart +++ b/lib/dualis/model/study_grades.dart @@ -1,8 +1,8 @@ class StudyGrades { - final double gpaTotal; - final double gpaMainModules; - final double creditsTotal; - final double creditsGained; + final double? gpaTotal; + final double? gpaMainModules; + final double? creditsTotal; + final double? creditsGained; StudyGrades( this.gpaTotal, diff --git a/lib/dualis/service/cache_dualis_service_decorator.dart b/lib/dualis/service/cache_dualis_service_decorator.dart index 95a2ec9c..d182de36 100644 --- a/lib/dualis/service/cache_dualis_service_decorator.dart +++ b/lib/dualis/service/cache_dualis_service_decorator.dart @@ -1,4 +1,5 @@ import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/dualis/model/module.dart'; import 'package:dhbwstudentapp/dualis/model/semester.dart'; import 'package:dhbwstudentapp/dualis/model/study_grades.dart'; @@ -10,25 +11,24 @@ import 'package:dhbwstudentapp/dualis/service/dualis_service.dart'; class CacheDualisServiceDecorator extends DualisService { final DualisService _service; - List _allModulesCached; - List _allSemesterNamesCached; - Map _semestersCached = {}; - StudyGrades _studyGradesCached; + List? _allModulesCached; + List? _allSemesterNamesCached; + Map _semestersCached = {}; + StudyGrades? _studyGradesCached; CacheDualisServiceDecorator(this._service); @override Future login( - String username, - String password, [ - CancellationToken cancellationToken, + Credentials credentials, [ + CancellationToken? cancellationToken, ]) { - return _service.login(username, password, cancellationToken); + return _service.login(credentials, cancellationToken); } @override Future> queryAllModules([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { if (_allModulesCached != null) { return Future.value(_allModulesCached); @@ -43,8 +43,8 @@ class CacheDualisServiceDecorator extends DualisService { @override Future querySemester( - String name, [ - CancellationToken cancellationToken, + String? name, [ + CancellationToken? cancellationToken, ]) async { if (_semestersCached.containsKey(name)) { return Future.value(_semestersCached[name]); @@ -58,7 +58,7 @@ class CacheDualisServiceDecorator extends DualisService { @override Future> querySemesterNames([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { if (_allSemesterNamesCached != null) { return Future.value(_allSemesterNamesCached); @@ -73,7 +73,7 @@ class CacheDualisServiceDecorator extends DualisService { @override Future queryStudyGrades([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { if (_studyGradesCached != null) { return Future.value(_studyGradesCached); @@ -95,7 +95,7 @@ class CacheDualisServiceDecorator extends DualisService { @override Future logout([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { await _service.logout(cancellationToken); clearCache(); diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index 193b0c1b..b7d681ac 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -1,4 +1,5 @@ import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_service.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_website_model.dart'; import 'package:dhbwstudentapp/dualis/service/parsing/access_denied_extract.dart'; @@ -16,36 +17,28 @@ import 'package:http/http.dart'; class DualisAuthentication { final RegExp _tokenRegex = RegExp("ARGUMENTS=-N([0-9]{15})"); - String _username; - String _password; + Credentials? _credentials; - DualisUrls _dualisUrls; - DualisUrls get dualisUrls => _dualisUrls; + // TODO: [Leptopoda] make singletons :) - String _authToken; - Session _session; + DualisUrls? _dualisUrls; + DualisUrls get dualisUrls => _dualisUrls ??= DualisUrls(); - LoginResult _loginState = LoginResult.LoggedOut; - LoginResult get loginState => _loginState; + String? _authToken; + Session? _session; + Session get session => _session ??= Session(); + + LoginResult? _loginState; + LoginResult get loginState => _loginState ??= LoginResult.LoggedOut; Future login( - String username, - String password, - CancellationToken cancellationToken, + Credentials credentials, + CancellationToken? cancellationToken, ) async { - username = username ?? this._username; - password = password ?? this._password; - - _dualisUrls = dualisUrls ?? DualisUrls(); - - this._username = username; - this._password = password; - - _session = Session(); + _credentials = credentials; var loginResponse = await _makeLoginRequest( - username, - password, + credentials, cancellationToken, ); @@ -68,7 +61,7 @@ class DualisAuthentication { return loginState; } - var redirectPage = await _session.get( + var redirectPage = await session.get( redirectUrl, cancellationToken, ); @@ -83,10 +76,10 @@ class DualisAuthentication { return loginState; } - _updateAccessToken(dualisUrls.mainPageUrl); + _updateAccessToken(dualisUrls.mainPageUrl!); - var mainPage = await _session.get( - dualisUrls.mainPageUrl, + var mainPage = await session.get( + dualisUrls.mainPageUrl!, cancellationToken, ); @@ -100,16 +93,15 @@ class DualisAuthentication { return loginState; } - Future _makeLoginRequest( - String user, - String password, [ - CancellationToken cancellationToken, + Future _makeLoginRequest( + Credentials credentials, [ + CancellationToken? cancellationToken, ]) async { var loginUrl = dualisEndpoint + "/scripts/mgrqispi.dll"; var data = { - "usrname": user, - "pass": password, + "usrname": credentials.username, + "pass": credentials.password, "APPNAME": "CampusNet", "PRGNAME": "LOGINCHECK", "ARGUMENTS": "clino,usrname,pass,menuno,menu_type,browser,platform", @@ -121,7 +113,7 @@ class DualisAuthentication { }; try { - var loginResponse = await _session.rawPost( + var loginResponse = await session.rawPost( loginUrl, data, cancellationToken, @@ -138,15 +130,19 @@ class DualisAuthentication { /// This method handles the authentication cookie and token. If the session /// timed out, it will renew the session by logging in again /// - Future authenticatedGet( + Future authenticatedGet( String url, - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ) async { - var result = await _session.get( + assert(_credentials != null); + + var result = await session.get( _fillUrlWithAuthToken(url), cancellationToken, ); + if (result == null) return null; + cancellationToken?.throwIfCancelled(); if (!TimeoutExtract().isTimeoutErrorPage(result) && @@ -154,10 +150,10 @@ class DualisAuthentication { return result; } - var loginResult = await login(_username, _password, cancellationToken); + var loginResult = await login(_credentials!, cancellationToken); if (loginResult == LoginResult.LoggedIn) { - return await _session.get( + return await session.get( _fillUrlWithAuthToken(url), cancellationToken, ); @@ -167,9 +163,9 @@ class DualisAuthentication { } Future logout([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { - var logoutRequest = _session.get(dualisUrls.logoutUrl, cancellationToken); + var logoutRequest = session.get(dualisUrls.logoutUrl, cancellationToken); _session = null; _dualisUrls = null; @@ -186,9 +182,9 @@ class DualisAuthentication { void _updateAccessToken(String urlWithNewToken) { var tokenMatch = _tokenRegex.firstMatch(urlWithNewToken); - if (tokenMatch == null) return; - - _authToken = tokenMatch.group(1); + if (tokenMatch != null) { + _authToken = tokenMatch.group(1); + } } /// @@ -207,13 +203,13 @@ class DualisAuthentication { return url; } - void setLoginCredentials(String username, String password) { - _username = username; - _password = password; + void setLoginCredentials(Credentials credentials) { + _credentials = credentials; } Future loginWithPreviousCredentials( CancellationToken cancellationToken) async { - return await login(_username, _password, cancellationToken); + assert(_credentials != null); + return await login(_credentials!, cancellationToken); } } diff --git a/lib/dualis/service/dualis_scraper.dart b/lib/dualis/service/dualis_scraper.dart index 7c9c65fd..b217200b 100644 --- a/lib/dualis/service/dualis_scraper.dart +++ b/lib/dualis/service/dualis_scraper.dart @@ -1,4 +1,5 @@ import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/dualis/model/study_grades.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_authentication.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_service.dart'; @@ -19,10 +20,10 @@ class DualisScraper { DualisUrls get _dualisUrls => _dualisAuthentication.dualisUrls; Future> loadAllModules([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { var allModulesPageResponse = await _dualisAuthentication.authenticatedGet( - _dualisUrls.studentResultsUrl, + _dualisUrls.studentResultsUrl!, cancellationToken, ); @@ -31,7 +32,7 @@ class DualisScraper { Future> loadModuleExams( String moduleDetailsUrl, [ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { var detailsResponse = await _dualisAuthentication.authenticatedGet( moduleDetailsUrl, @@ -44,10 +45,10 @@ class DualisScraper { } Future> loadSemesters([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { var courseResultsResponse = await _dualisAuthentication.authenticatedGet( - _dualisUrls.courseResultUrl, + _dualisUrls.courseResultUrl!, cancellationToken, ); @@ -65,12 +66,12 @@ class DualisScraper { return semesters; } - Future> loadSemesterModules( - String semesterName, [ - CancellationToken cancellationToken, + Future> loadSemesterModules( + String? semesterName, [ + CancellationToken? cancellationToken, ]) async { var coursePage = await _dualisAuthentication.authenticatedGet( - _dualisUrls.semesterCourseResultUrls[semesterName], + _dualisUrls.semesterCourseResultUrls[semesterName!]!, cancellationToken, ); @@ -79,10 +80,10 @@ class DualisScraper { } Future loadStudyGrades( - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ) async { var studentsResultsPage = await _dualisAuthentication.authenticatedGet( - _dualisUrls.studentResultsUrl, + _dualisUrls.studentResultsUrl!, cancellationToken, ); @@ -108,11 +109,10 @@ class DualisScraper { } Future login( - String username, - String password, - CancellationToken cancellationToken, + Credentials credentials, + CancellationToken? cancellationToken, ) { - return _dualisAuthentication.login(username, password, cancellationToken); + return _dualisAuthentication.login(credentials, cancellationToken); } Future loginWithPreviousCredentials( @@ -122,7 +122,7 @@ class DualisScraper { .loginWithPreviousCredentials(cancellationToken); } - Future logout(CancellationToken cancellationToken) { + Future logout(CancellationToken? cancellationToken) { return _dualisAuthentication.logout(cancellationToken); } @@ -130,7 +130,7 @@ class DualisScraper { return _dualisAuthentication.loginState == LoginResult.LoggedIn; } - void setLoginCredentials(String username, String password) { - _dualisAuthentication.setLoginCredentials(username, password); + void setLoginCredentials(Credentials credentials) { + _dualisAuthentication.setLoginCredentials(credentials); } } diff --git a/lib/dualis/service/dualis_service.dart b/lib/dualis/service/dualis_service.dart index ddbd93fd..a830cbf9 100644 --- a/lib/dualis/service/dualis_service.dart +++ b/lib/dualis/service/dualis_service.dart @@ -1,4 +1,5 @@ import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/dualis/model/exam.dart'; import 'package:dhbwstudentapp/dualis/model/module.dart'; import 'package:dhbwstudentapp/dualis/model/semester.dart'; @@ -7,30 +8,29 @@ import 'package:dhbwstudentapp/dualis/service/dualis_scraper.dart'; abstract class DualisService { Future login( - String username, - String password, [ - CancellationToken cancellationToken, + Credentials credentials, [ + CancellationToken? cancellationToken, ]); Future queryStudyGrades([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]); Future> querySemesterNames([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]); Future> queryAllModules([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]); Future querySemester( - String name, [ - CancellationToken cancellationToken, + String? name, [ + CancellationToken? cancellationToken, ]); Future logout([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]); } @@ -48,27 +48,25 @@ class DualisServiceImpl extends DualisService { @override Future login( - String username, - String password, [ - CancellationToken cancellationToken, + Credentials credentials, [ + CancellationToken? cancellationToken, ]) async { return await _dualisScraper.login( - username, - password, + credentials, cancellationToken, ); } @override Future queryStudyGrades([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { return await _dualisScraper.loadStudyGrades(cancellationToken); } @override Future> querySemesterNames([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { var semesters = await _dualisScraper.loadSemesters(cancellationToken); @@ -83,7 +81,7 @@ class DualisServiceImpl extends DualisService { @override Future> queryAllModules([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { var dualisModules = await _dualisScraper.loadAllModules(cancellationToken); @@ -103,8 +101,8 @@ class DualisServiceImpl extends DualisService { @override Future querySemester( - String name, [ - CancellationToken cancellationToken, + String? name, [ + CancellationToken? cancellationToken, ]) async { var semesterModules = await _dualisScraper.loadSemesterModules( name, @@ -115,7 +113,7 @@ class DualisServiceImpl extends DualisService { for (var dualisModule in semesterModules) { var moduleExams = await _dualisScraper.loadModuleExams( - dualisModule.detailsUrl, + dualisModule!.detailsUrl!, cancellationToken, ); @@ -145,7 +143,7 @@ class DualisServiceImpl extends DualisService { @override Future logout([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { await _dualisScraper.logout(cancellationToken); } diff --git a/lib/dualis/service/dualis_website_model.dart b/lib/dualis/service/dualis_website_model.dart index 8e7bdf60..dc234e45 100644 --- a/lib/dualis/service/dualis_website_model.dart +++ b/lib/dualis/service/dualis_website_model.dart @@ -8,18 +8,18 @@ const String dualisEndpoint = "https://dualis.dhbw.de"; /// access token contained within the urls. /// class DualisUrls { - String courseResultUrl; - String studentResultsUrl; - String logoutUrl; - String mainPageUrl; - String monthlyScheduleUrl; + String? courseResultUrl; + String? studentResultsUrl; + late String logoutUrl; + String? mainPageUrl; + String? monthlyScheduleUrl; - Map semesterCourseResultUrls = {}; + Map semesterCourseResultUrls = {}; } class DualisSemester { final String semesterName; - final String semesterCourseResultsUrl; + final String? semesterCourseResultsUrl; final List modules; DualisSemester( @@ -30,12 +30,12 @@ class DualisSemester { } class DualisModule { - final String id; - final String name; - final String finalGrade; - final String credits; - final String detailsUrl; - final ExamState state; + final String? id; + final String? name; + final String? finalGrade; + final String? credits; + final String? detailsUrl; + final ExamState? state; DualisModule( this.id, @@ -48,11 +48,11 @@ class DualisModule { } class DualisExam { - final String tryNr; - final String moduleName; - final String name; + final String? tryNr; + final String? moduleName; + final String? name; final ExamGrade grade; - final String semester; + final String? semester; DualisExam( this.name, diff --git a/lib/dualis/service/fake_account_dualis_scraper_decorator.dart b/lib/dualis/service/fake_account_dualis_scraper_decorator.dart index 54a0e3c0..fddbbce8 100644 --- a/lib/dualis/service/fake_account_dualis_scraper_decorator.dart +++ b/lib/dualis/service/fake_account_dualis_scraper_decorator.dart @@ -1,4 +1,5 @@ import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/dualis/model/study_grades.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_scraper.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_service.dart'; @@ -14,13 +15,12 @@ import 'package:dhbwstudentapp/schedule/model/schedule.dart'; /// area of the app. /// class FakeAccountDualisScraperDecorator implements DualisScraper { - final fakeUsername = "fakeAccount@domain.de"; - final fakePassword = "Passw0rd"; + static const _credentials = Credentials("fakeAccount@domain.de", "Passw0rd"); final DualisScraper _fakeDualisScraper = FakeDataDualisScraper(); final DualisScraper _originalDualisScraper; - DualisScraper _currentDualisScraper; + late DualisScraper _currentDualisScraper; FakeAccountDualisScraperDecorator( this._originalDualisScraper, @@ -33,14 +33,14 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { @override Future> loadAllModules( - [CancellationToken cancellationToken]) { + [CancellationToken? cancellationToken]) { return _currentDualisScraper.loadAllModules(); } @override Future> loadModuleExams( String moduleDetailsUrl, [ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) { return _currentDualisScraper.loadModuleExams( moduleDetailsUrl, @@ -60,9 +60,9 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { } @override - Future> loadSemesterModules( - String semesterName, [ - CancellationToken cancellationToken, + Future> loadSemesterModules( + String? semesterName, [ + CancellationToken? cancellationToken, ]) { return _currentDualisScraper.loadSemesterModules( semesterName, @@ -72,29 +72,27 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { @override Future> loadSemesters( - [CancellationToken cancellationToken]) { + [CancellationToken? cancellationToken]) { return _currentDualisScraper.loadSemesters(cancellationToken); } @override - Future loadStudyGrades(CancellationToken cancellationToken) { + Future loadStudyGrades(CancellationToken? cancellationToken) { return _currentDualisScraper.loadStudyGrades(cancellationToken); } @override Future login( - String username, - String password, - CancellationToken cancellationToken, + Credentials credentials, + CancellationToken? cancellationToken, ) { - if (username == fakeUsername && password == fakePassword) { + if (credentials == _credentials) { _currentDualisScraper = _fakeDualisScraper; } else { _currentDualisScraper = _originalDualisScraper; } return _currentDualisScraper.login( - username, - password, + credentials, cancellationToken, ); } @@ -108,23 +106,20 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { } @override - Future logout(CancellationToken cancellationToken) { + Future logout(CancellationToken? cancellationToken) { return _currentDualisScraper.logout( cancellationToken, ); } @override - void setLoginCredentials(String username, String password) { - if (username == fakeUsername && password == fakePassword) { + void setLoginCredentials(Credentials credentials) { + if (credentials == _credentials) { _currentDualisScraper = _fakeDualisScraper; } else { _currentDualisScraper = _originalDualisScraper; } - return _currentDualisScraper.setLoginCredentials( - username, - password, - ); + return _currentDualisScraper.setLoginCredentials(credentials); } } diff --git a/lib/dualis/service/fake_data_dualis_scraper.dart b/lib/dualis/service/fake_data_dualis_scraper.dart index fe7a90b0..56de36b8 100644 --- a/lib/dualis/service/fake_data_dualis_scraper.dart +++ b/lib/dualis/service/fake_data_dualis_scraper.dart @@ -1,4 +1,5 @@ import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/dualis/model/exam.dart'; import 'package:dhbwstudentapp/dualis/model/exam_grade.dart'; import 'package:dhbwstudentapp/dualis/model/study_grades.dart'; @@ -20,7 +21,7 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadAllModules( - [CancellationToken cancellationToken]) async { + [CancellationToken? cancellationToken]) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value([ @@ -38,7 +39,7 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadModuleExams( String moduleDetailsUrl, [ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value([ @@ -63,8 +64,8 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadSemesterModules( - String semesterName, [ - CancellationToken cancellationToken, + String? semesterName, [ + CancellationToken? cancellationToken, ]) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value([ @@ -81,14 +82,14 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadSemesters( - [CancellationToken cancellationToken]) async { + [CancellationToken? cancellationToken]) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value([DualisSemester("SoSe2020", "", [])]); } @override Future loadStudyGrades( - CancellationToken cancellationToken) async { + CancellationToken? cancellationToken) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value( StudyGrades( @@ -102,9 +103,8 @@ class FakeDataDualisScraper implements DualisScraper { @override Future login( - String username, - String password, - CancellationToken cancellationToken, + Credentials credentials, + CancellationToken? cancellationToken, ) async { await Future.delayed(Duration(milliseconds: 200)); _isLoggedIn = true; @@ -120,13 +120,13 @@ class FakeDataDualisScraper implements DualisScraper { } @override - Future logout(CancellationToken cancellationToken) async { + Future logout(CancellationToken? cancellationToken) async { await Future.delayed(Duration(milliseconds: 200)); _isLoggedIn = false; } @override - void setLoginCredentials(String username, String password) { + void setLoginCredentials(Credentials? credentials) { // TODO: implement setLoginCredentials } } diff --git a/lib/dualis/service/parsing/all_modules_extract.dart b/lib/dualis/service/parsing/all_modules_extract.dart index 02e76db6..cca84728 100644 --- a/lib/dualis/service/parsing/all_modules_extract.dart +++ b/lib/dualis/service/parsing/all_modules_extract.dart @@ -5,7 +5,7 @@ import 'package:html/dom.dart'; import 'package:html/parser.dart'; class AllModulesExtract { - List extractAllModules(String body) { + List extractAllModules(String? body) { try { return _extractAllModules(body); } catch (e, trace) { @@ -14,7 +14,7 @@ class AllModulesExtract { } } - List _extractAllModules(String body) { + List _extractAllModules(String? body) { var document = parse(body); var modulesTable = getElementByTagName(document, "tbody"); @@ -49,7 +49,7 @@ class AllModulesExtract { var grade = cells[4].innerHtml; var state = cells[5].children[0].attributes["alt"]; - ExamState stateEnum; + ExamState? stateEnum; if (state == "Bestanden") { stateEnum = ExamState.Passed; diff --git a/lib/dualis/service/parsing/exams_from_module_details_extract.dart b/lib/dualis/service/parsing/exams_from_module_details_extract.dart index 769c92be..d90f79e0 100644 --- a/lib/dualis/service/parsing/exams_from_module_details_extract.dart +++ b/lib/dualis/service/parsing/exams_from_module_details_extract.dart @@ -4,7 +4,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:html/parser.dart'; class ExamsFromModuleDetailsExtract { - List extractExamsFromModuleDetails(String body) { + List extractExamsFromModuleDetails(String? body) { try { return _extractExamsFromModuleDetails(body); } on ParseException catch (e, trace) { @@ -13,14 +13,14 @@ class ExamsFromModuleDetailsExtract { } } - List _extractExamsFromModuleDetails(String body) { + List _extractExamsFromModuleDetails(String? body) { var document = parse(body); var tableExams = getElementByTagName(document, "tbody"); var tableExamsRows = tableExams.getElementsByTagName("tr"); - String currentTry; - String currentModule; + String? currentTry; + String? currentModule; var exams = []; diff --git a/lib/dualis/service/parsing/login_redirect_url_extract.dart b/lib/dualis/service/parsing/login_redirect_url_extract.dart index 847edff5..ea2f2463 100644 --- a/lib/dualis/service/parsing/login_redirect_url_extract.dart +++ b/lib/dualis/service/parsing/login_redirect_url_extract.dart @@ -1,12 +1,12 @@ import 'package:html/parser.dart'; class LoginRedirectUrlExtract { - String readRedirectUrl(String body, String redirectUrl) { + String? readRedirectUrl(String? body, String redirectUrl) { var document = parse(body); var metaTags = document.getElementsByTagName("meta"); - String redirectContent; + String? redirectContent; for (var metaTag in metaTags) { if (!metaTag.attributes.containsKey("http-equiv")) continue; @@ -23,7 +23,7 @@ class LoginRedirectUrlExtract { return getUrlFromHeader(redirectContent, redirectUrl); } - String getUrlFromHeader(String refreshHeader, String endpointUrl) { + String? getUrlFromHeader(String? refreshHeader, String endpointUrl) { if (refreshHeader == null || !refreshHeader.contains("URL=")) return null; var refreshHeaderUrlIndex = refreshHeader.indexOf("URL=") + "URL=".length; diff --git a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart index f903a77f..baa53cb0 100644 --- a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart @@ -7,8 +7,8 @@ import 'package:html/parser.dart'; class ModulesFromCourseResultPageExtract { final RegExp _extractUrlRegex = RegExp('dl_popUp\\("(.+?)"'); - List extractModulesFromCourseResultPage( - String body, + List extractModulesFromCourseResultPage( + String? body, String endpointUrl, ) { try { @@ -19,27 +19,27 @@ class ModulesFromCourseResultPageExtract { } } - List _extractModulesFromCourseResultPage( - String body, String endpointUrl) { + List _extractModulesFromCourseResultPage( + String? body, String endpointUrl) { var document = parse(body); var tableBodies = getElementByTagName(document, "tbody"); var rows = tableBodies.getElementsByTagName("tr"); - var modulesOfSemester = []; + var modulesOfSemester = []; for (var row in rows) { // Only rows with tds as child are modules if (row.children[0].localName != "td") continue; - DualisModule module = _extractModuleFromRow(row, endpointUrl); + DualisModule? module = _extractModuleFromRow(row, endpointUrl); modulesOfSemester.add(module); } return modulesOfSemester; } - DualisModule _extractModuleFromRow( + DualisModule? _extractModuleFromRow( Element row, String endpointUrl, ) { @@ -49,13 +49,13 @@ class ModulesFromCourseResultPageExtract { var name = row.children[1].innerHtml; var grade = row.children[2].innerHtml; var credits = row.children[3].innerHtml; - var status = row.children[4].innerHtml; + String? status = row.children[4].innerHtml; var detailsButton = row.children[5]; var url = _extractDetailsUrlFromButton(detailsButton, endpointUrl); status = trimAndEscapeString(status); - ExamState statusEnum; + ExamState? statusEnum; if (status == "bestanden") { statusEnum = ExamState.Passed; @@ -76,7 +76,7 @@ class ModulesFromCourseResultPageExtract { return module; } - String _extractDetailsUrlFromButton( + String? _extractDetailsUrlFromButton( Element detailsButton, String endpointUrl, ) { diff --git a/lib/dualis/service/parsing/monthly_schedule_extract.dart b/lib/dualis/service/parsing/monthly_schedule_extract.dart index d0f8e22a..019a879b 100644 --- a/lib/dualis/service/parsing/monthly_schedule_extract.dart +++ b/lib/dualis/service/parsing/monthly_schedule_extract.dart @@ -6,7 +6,7 @@ import 'package:html/parser.dart'; import 'package:intl/intl.dart'; class MonthlyScheduleExtract { - Schedule extractScheduleFromMonthly(String body) { + Schedule extractScheduleFromMonthly(String? body) { try { return _extractScheduleFromMonthly(body); } catch (e, trace) { @@ -15,7 +15,7 @@ class MonthlyScheduleExtract { } } - Schedule _extractScheduleFromMonthly(String body) { + Schedule _extractScheduleFromMonthly(String? body) { var document = parse(body); var appointments = document.getElementsByClassName("apmntLink"); @@ -29,18 +29,18 @@ class MonthlyScheduleExtract { } allEntries.sort( - (ScheduleEntry e1, ScheduleEntry e2) => e1?.start?.compareTo(e2?.start), + (ScheduleEntry e1, ScheduleEntry e2) => e1.start.compareTo(e2.start), ); return Schedule.fromList(allEntries); } ScheduleEntry _extractEntry(Element appointment) { - var date = appointment.parent.parent - .querySelector(".tbsubhead a") + var date = appointment.parent!.parent! + .querySelector(".tbsubhead a")! .attributes["title"]; - var information = appointment.attributes["title"]; + var information = appointment.attributes["title"]!; var informationParts = information.split(" / "); var startAndEnd = informationParts[0].split(" - "); diff --git a/lib/dualis/service/parsing/parsing_utils.dart b/lib/dualis/service/parsing/parsing_utils.dart index 4091c44a..e192cca9 100644 --- a/lib/dualis/service/parsing/parsing_utils.dart +++ b/lib/dualis/service/parsing/parsing_utils.dart @@ -2,7 +2,7 @@ import 'package:html/dom.dart'; import 'package:universal_html/html.dart' as html; -String trimAndEscapeString(String htmlString) { +String? trimAndEscapeString(String? htmlString) { if (htmlString == null) return null; var text = html.Element.span()..appendHtml(htmlString); @@ -45,8 +45,8 @@ Element getElementById( } class ParseException implements Exception { - Object innerException; - StackTrace trace; + Object? innerException; + StackTrace? trace; ParseException.withInner(this.innerException, this.trace); @@ -58,10 +58,10 @@ class ParseException implements Exception { class ElementNotFoundParseException implements ParseException { @override - Object innerException; + Object? innerException; @override - StackTrace trace; + StackTrace? trace; final String elementDescription; diff --git a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart index c6ae1853..2ce424b7 100644 --- a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart @@ -5,7 +5,7 @@ import 'package:html/parser.dart'; class SemestersFromCourseResultPageExtract { List extractSemestersFromCourseResults( - String body, + String? body, String endpointUrl, ) { try { @@ -17,7 +17,7 @@ class SemestersFromCourseResultPageExtract { } List _extractSemestersFromCourseResults( - String body, String endpointUrl) { + String? body, String endpointUrl) { var page = parse(body); var semesterSelector = page.getElementById("semester"); @@ -33,10 +33,10 @@ class SemestersFromCourseResultPageExtract { var id = option.attributes["value"]; var name = option.innerHtml; - String detailsUrl; + String? detailsUrl; if (url != null) { - detailsUrl = url + id; + detailsUrl = url + id!; } semesters.add(DualisSemester( @@ -49,11 +49,11 @@ class SemestersFromCourseResultPageExtract { return semesters; } - String _extractSemesterDetailUrlPart( + String? _extractSemesterDetailUrlPart( Element semesterSelector, String endpointUrl, ) { - var dropDownSemesterSelector = semesterSelector.attributes["onchange"]; + var dropDownSemesterSelector = semesterSelector.attributes["onchange"]!; var regExp = RegExp("'([A-z0-9]*)'"); diff --git a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart index 8b6ff079..3af3e401 100644 --- a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart +++ b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart @@ -4,7 +4,7 @@ import 'package:html/dom.dart'; import 'package:html/parser.dart'; class StudyGradesFromStudentResultsPageExtract { - StudyGrades extractStudyGradesFromStudentsResultsPage(String body) { + StudyGrades extractStudyGradesFromStudentsResultsPage(String? body) { try { return _extractStudyGradesFromStudentsResultsPage(body); } catch (e, trace) { @@ -13,7 +13,7 @@ class StudyGradesFromStudentResultsPageExtract { } } - StudyGrades _extractStudyGradesFromStudentsResultsPage(String body) { + StudyGrades _extractStudyGradesFromStudentsResultsPage(String? body) { var document = parse(body); var creditsTable = getElementByTagName(document, "tbody", 0); @@ -40,12 +40,12 @@ class StudyGradesFromStudentResultsPageExtract { var neededCredits = neededCreditsRow.children[0].innerHtml; // Only take the number after the colon - neededCredits = trimAndEscapeString(neededCredits.split(":")[1]); + neededCredits = trimAndEscapeString(neededCredits.split(":")[1])!; var gainedCreditsRow = rows[rows.length - 2]; var gainedCredits = trimAndEscapeString( gainedCreditsRow.children[2].innerHtml, - ); + )!; neededCredits = neededCredits.replaceAll(",", "."); gainedCredits = gainedCredits.replaceAll(",", "."); @@ -65,12 +65,12 @@ class StudyGradesFromStudentResultsPageExtract { var totalGpaRowCells = rows[0].getElementsByTagName("th"); var totalGpa = trimAndEscapeString( totalGpaRowCells[1].innerHtml, - ); + )!; var mainCoursesGpaRowCells = rows[1].getElementsByTagName("th"); var mainModulesGpa = trimAndEscapeString( mainCoursesGpaRowCells[1].innerHtml, - ); + )!; _Gpa gpa = _Gpa(); gpa.totalGpa = double.tryParse(totalGpa.replaceAll(",", ".")); @@ -81,11 +81,11 @@ class StudyGradesFromStudentResultsPageExtract { } class _Credits { - double totalCredits; - double gainedCredits; + double? totalCredits; + double? gainedCredits; } class _Gpa { - double totalGpa; - double mainModulesGpa; + double? totalGpa; + double? mainModulesGpa; } diff --git a/lib/dualis/service/parsing/urls_from_main_page_extract.dart b/lib/dualis/service/parsing/urls_from_main_page_extract.dart index 1cea8a03..d8638001 100644 --- a/lib/dualis/service/parsing/urls_from_main_page_extract.dart +++ b/lib/dualis/service/parsing/urls_from_main_page_extract.dart @@ -4,7 +4,7 @@ import 'package:html/parser.dart'; class UrlsFromMainPageExtract { void parseMainPage( - String body, + String? body, DualisUrls dualsUrls, String endpointUrl, ) { @@ -17,7 +17,7 @@ class UrlsFromMainPageExtract { } void _parseMainPage( - String body, + String? body, DualisUrls dualisUrls, String endpointUrl, ) { @@ -29,14 +29,14 @@ class UrlsFromMainPageExtract { var logoutElement = getElementById(document, "logoutButton"); dualisUrls.courseResultUrl = - endpointUrl + courseResultsElement.attributes['href']; + endpointUrl + courseResultsElement.attributes['href']!; dualisUrls.studentResultsUrl = - endpointUrl + studentResultsElement.attributes['href']; + endpointUrl + studentResultsElement.attributes['href']!; dualisUrls.monthlyScheduleUrl = - endpointUrl + monthlyScheduleElement.attributes["href"]; + endpointUrl + monthlyScheduleElement.attributes["href"]!; - dualisUrls.logoutUrl = endpointUrl + logoutElement.attributes['href']; + dualisUrls.logoutUrl = endpointUrl + logoutElement.attributes['href']!; } } diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index a1563f8d..01d14088 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -5,19 +5,22 @@ import 'package:dhbwstudentapp/schedule/service/schedule_source.dart'; import 'package:http/http.dart'; import 'package:http_client_helper/http_client_helper.dart' as http; +// TODO: [Leptopoda] requestCancellationToken and Cancellation token cleanup +// TODO: [Leptopoda] Pass Uri objects and not strings + /// /// Handles cookies and provides a session. Execute your api calls with the /// provided get and set methods. /// class Session { - Map cookies = {}; + Map _cookies = {}; /// /// Execute a GET request and return the result body as string /// - Future get( + Future get( String url, [ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { var response = await rawGet(url, cancellationToken); @@ -32,9 +35,9 @@ class Session { } } - Future rawGet( + Future rawGet( String url, [ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); @@ -50,13 +53,13 @@ class Session { var response = await http.HttpClientHelper.get( requestUri, cancelToken: requestCancellationToken, - headers: cookies, + headers: _cookies, ); if (response == null && !requestCancellationToken.isCanceled) throw ServiceRequestFailed("Http request failed!"); - _updateCookie(response); + _updateCookie(response!); return response; } on http.OperationCanceledError catch (_) { @@ -73,10 +76,10 @@ class Session { /// /// Execute a POST request and return the result body as string /// - Future post( + Future post( String url, - dynamic data, [ - CancellationToken cancellationToken, + Map data, [ + CancellationToken? cancellationToken, ]) async { var response = await rawPost(url, data, cancellationToken); @@ -91,10 +94,10 @@ class Session { } } - Future rawPost( + Future rawPost( String url, - dynamic data, [ - CancellationToken cancellationToken, + Map data, [ + CancellationToken? cancellationToken, ]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); var requestCancellationToken = http.CancellationToken(); @@ -107,14 +110,14 @@ class Session { var response = await http.HttpClientHelper.post( Uri.parse(url), body: data, - headers: cookies, + headers: _cookies, cancelToken: requestCancellationToken, ); if (response == null && !requestCancellationToken.isCanceled) throw ServiceRequestFailed("Http request failed!"); - _updateCookie(response); + _updateCookie(response!); return response; } on http.OperationCanceledError catch (_) { @@ -129,7 +132,7 @@ class Session { } void _updateCookie(Response response) { - String rawCookie = response.headers['set-cookie']; + String? rawCookie = response.headers['set-cookie']; if (rawCookie != null) { int index = rawCookie.indexOf(';'); @@ -137,7 +140,7 @@ class Session { cookie = cookie.replaceAll(" ", ""); - cookies['cookie'] = cookie; + _cookies['cookie'] = cookie; } } } diff --git a/lib/dualis/ui/dualis_navigation_entry.dart b/lib/dualis/ui/dualis_navigation_entry.dart index 95e2097f..3fc5eea4 100644 --- a/lib/dualis/ui/dualis_navigation_entry.dart +++ b/lib/dualis/ui/dualis_navigation_entry.dart @@ -1,6 +1,5 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/common/ui/custom_icons_icons.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/dualis/ui/dualis_page.dart'; import 'package:dhbwstudentapp/dualis/ui/viewmodels/study_grades_view_model.dart'; import 'package:dhbwstudentapp/dualis/ui/widgets/dualis_help_dialog.dart'; @@ -9,13 +8,9 @@ import 'package:flutter/material.dart'; import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; -class DualisNavigationEntry extends NavigationEntry { - StudyGradesViewModel _viewModel; - +class DualisNavigationEntry extends NavigationEntry { @override - Widget icon(BuildContext context) { - return Icon(Icons.data_usage); - } + Icon icon = Icon(Icons.data_usage); @override String title(BuildContext context) { @@ -23,15 +18,11 @@ class DualisNavigationEntry extends NavigationEntry { } @override - BaseViewModel initViewModel() { - if (_viewModel == null) { - _viewModel = StudyGradesViewModel( - KiwiContainer().resolve(), - KiwiContainer().resolve(), - ); - } - - return _viewModel; + StudyGradesViewModel initViewModel() { + return StudyGradesViewModel( + KiwiContainer().resolve(), + KiwiContainer().resolve(), + ); } @override @@ -41,27 +32,27 @@ class DualisNavigationEntry extends NavigationEntry { @override List appBarActions(BuildContext context) { - initViewModel(); return [ PropertyChangeProvider( - value: _viewModel, + value: model, child: PropertyChangeConsumer( - builder: (BuildContext _, StudyGradesViewModel __, Set ___) => - _viewModel.loginState != LoginState.LoggedIn - ? IconButton( - icon: Icon(Icons.help_outline), - onPressed: () async { - await DualisHelpDialog().show(context); - }, - tooltip: L.of(context).helpButtonTooltip, - ) - : IconButton( - icon: const Icon(CustomIcons.logout), - onPressed: () async { - await _viewModel.logout(); - }, - tooltip: L.of(context).logoutButtonTooltip, - ), + builder: + (BuildContext _, StudyGradesViewModel? __, Set? ___) => + model.loginState != LoginState.LoggedIn + ? IconButton( + icon: Icon(Icons.help_outline), + onPressed: () async { + await DualisHelpDialog().show(context); + }, + tooltip: L.of(context).helpButtonTooltip, + ) + : IconButton( + icon: const Icon(CustomIcons.logout), + onPressed: () async { + await model.logout(); + }, + tooltip: L.of(context).logoutButtonTooltip, + ), ), ), ]; diff --git a/lib/dualis/ui/dualis_page.dart b/lib/dualis/ui/dualis_page.dart index 5f866d55..cd9e017c 100644 --- a/lib/dualis/ui/dualis_page.dart +++ b/lib/dualis/ui/dualis_page.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/dualis/ui/exam_results_page/exam_results_page.dart'; import 'package:dhbwstudentapp/dualis/ui/login/dualis_login_page.dart'; import 'package:dhbwstudentapp/dualis/ui/study_overview/study_overview_page.dart'; @@ -12,7 +11,7 @@ import 'package:provider/provider.dart'; class DualisPage extends StatelessWidget { @override Widget build(BuildContext context) { - StudyGradesViewModel viewModel = Provider.of(context); + StudyGradesViewModel viewModel = Provider.of(context); Widget widget; diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index 315dc141..25f09e4f 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -38,14 +38,14 @@ class ExamResultsPage extends StatelessWidget { ], builder: ( BuildContext context, - StudyGradesViewModel model, - Set properties, + StudyGradesViewModel? model, + Set? properties, ) => DropdownButton( - onChanged: (value) => model.loadSemester(value), - value: model.currentSemesterName, - items: (model.allSemesterNames ?? []) - .map( + onChanged: model?.loadSemester, + value: model?.currentSemesterName, + items: model?.allSemesterNames + ?.map( (n) => DropdownMenuItem( child: Text(n), value: n, @@ -62,10 +62,10 @@ class ExamResultsPage extends StatelessWidget { properties: const ["currentSemester"], builder: ( BuildContext context, - StudyGradesViewModel model, - Set properties, + StudyGradesViewModel? model, + Set? properties, ) => - model.currentSemester != null + model!.currentSemester != null ? buildModulesColumn(context, model) : const Padding( padding: EdgeInsets.fromLTRB(0, 16, 0, 0), @@ -81,7 +81,7 @@ class ExamResultsPage extends StatelessWidget { Widget buildModulesColumn( BuildContext context, StudyGradesViewModel viewModel) { return AnimatedSwitcher( - layoutBuilder: (Widget currentChild, List previousChildren) { + layoutBuilder: (Widget? currentChild, List previousChildren) { List children = previousChildren; if (currentChild != null) children = children.toList()..add(currentChild); @@ -103,7 +103,7 @@ class ExamResultsPage extends StatelessWidget { var dataTables = []; var isFirstModule = true; - for (var module in viewModel.currentSemester.modules) { + for (var module in viewModel.currentSemester!.modules) { dataTables.add(DataTable( horizontalMargin: 24, columnSpacing: 0, @@ -157,14 +157,12 @@ class ExamResultsPage extends StatelessWidget { case ExamGradeState.NotGraded: return Text(""); case ExamGradeState.Graded: - return Text(grade.gradeValue); + return Text(grade.gradeValue!); case ExamGradeState.Passed: return Text(L.of(context).examPassed); case ExamGradeState.Failed: return Text(L.of(context).examNotPassed); } - - return Text(""); } List buildModuleColumns(BuildContext context, var module, diff --git a/lib/dualis/ui/login/dualis_login_page.dart b/lib/dualis/ui/login/dualis_login_page.dart index 204dd8a2..3fd8ff86 100644 --- a/lib/dualis/ui/login/dualis_login_page.dart +++ b/lib/dualis/ui/login/dualis_login_page.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/dualis/ui/viewmodels/study_grades_view_model.dart'; import 'package:dhbwstudentapp/dualis/ui/widgets/login_form_widget.dart'; import 'package:flutter/material.dart'; @@ -8,7 +7,7 @@ import 'package:provider/provider.dart'; class DualisLoginPage extends StatelessWidget { @override Widget build(BuildContext context) { - StudyGradesViewModel viewModel = Provider.of(context); + StudyGradesViewModel viewModel = Provider.of(context); return buildLoginPage(context, viewModel); } diff --git a/lib/dualis/ui/study_overview/study_overview_page.dart b/lib/dualis/ui/study_overview/study_overview_page.dart index 1cd0f267..fd6a8a4c 100644 --- a/lib/dualis/ui/study_overview/study_overview_page.dart +++ b/lib/dualis/ui/study_overview/study_overview_page.dart @@ -39,10 +39,10 @@ class StudyOverviewPage extends StatelessWidget { properties: const ["studyGrades"], builder: ( BuildContext context, - StudyGradesViewModel model, - Set properties, + StudyGradesViewModel? model, + Set? properties, ) => - model.studyGrades != null + model!.studyGrades != null ? Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -54,7 +54,7 @@ class StudyOverviewPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.baseline, children: [ Text( - model.studyGrades.gpaTotal.toString(), + model.studyGrades!.gpaTotal.toString(), style: Theme.of(context).textTheme.headline3, ), Padding( @@ -72,7 +72,7 @@ class StudyOverviewPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.baseline, children: [ Text( - model.studyGrades.gpaMainModules.toString(), + model.studyGrades!.gpaMainModules.toString(), style: Theme.of(context).textTheme.headline3, ), Padding( @@ -90,7 +90,7 @@ class StudyOverviewPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.baseline, children: [ Text( - "${model.studyGrades.creditsGained} / ${model.studyGrades.creditsTotal}", + "${model.studyGrades!.creditsGained} / ${model.studyGrades!.creditsTotal}", style: Theme.of(context).textTheme.headline3, ), Padding( @@ -129,10 +129,10 @@ class StudyOverviewPage extends StatelessWidget { properties: const ["allModules"], builder: ( BuildContext context, - StudyGradesViewModel model, - Set properties, + StudyGradesViewModel? model, + Set? properties, ) => - model.allModules != null + model!.allModules != null ? buildModulesDataTable(context, model) : buildProgressIndicator(), ), @@ -154,13 +154,13 @@ class StudyOverviewPage extends StatelessWidget { ) { var dataRows = []; - for (var module in model.allModules) { + for (var module in model.allModules!) { dataRows.add( DataRow( cells: [ - DataCell(Text(module.name)), - DataCell(Text(module.credits)), - DataCell(Text(module.grade)), + DataCell(Text(module.name!)), + DataCell(Text(module.credits!)), + DataCell(Text(module.grade!)), DataCell(GradeStateIcon(state: module.state)), ], ), diff --git a/lib/dualis/ui/viewmodels/study_grades_view_model.dart b/lib/dualis/ui/viewmodels/study_grades_view_model.dart index 2b7305b1..32251a4f 100644 --- a/lib/dualis/ui/viewmodels/study_grades_view_model.dart +++ b/lib/dualis/ui/viewmodels/study_grades_view_model.dart @@ -25,26 +25,26 @@ class StudyGradesViewModel extends BaseViewModel { LoginState _loginState = LoginState.LoggedOut; LoginState get loginState => _loginState; - StudyGrades _studyGrades; - StudyGrades get studyGrades => _studyGrades; + StudyGrades? _studyGrades; + StudyGrades? get studyGrades => _studyGrades; final CancelableMutex _studyGradesCancellationToken = CancelableMutex(); - List _allModules; - List get allModules => _allModules; + List? _allModules; + List? get allModules => _allModules; final CancelableMutex _allModulesCancellationToken = CancelableMutex(); - List _semesterNames; - List get allSemesterNames => _semesterNames; + List? _semesterNames; + List? get allSemesterNames => _semesterNames; final CancelableMutex _semesterNamesCancellationToken = CancelableMutex(); - Semester _currentSemester; - Semester get currentSemester => _currentSemester; + Semester? _currentSemester; + Semester? get currentSemester => _currentSemester; final CancelableMutex _currentSemesterCancellationToken = CancelableMutex(); - String _currentSemesterName; - String get currentSemesterName => _currentSemesterName; + String? _currentSemesterName; + String? get currentSemesterName => _currentSemesterName; - String _currentLoadingSemesterName; + String? _currentLoadingSemesterName; StudyGradesViewModel(this._preferencesProvider, this._dualisService); @@ -54,10 +54,7 @@ class StudyGradesViewModel extends BaseViewModel { bool success; try { - var result = await _dualisService.login( - credentials.username, - credentials.password, - ); + var result = await _dualisService.login(credentials); success = result == LoginResult.LoggedIn; } on OperationCancelledException catch (_) { @@ -95,7 +92,7 @@ class StudyGradesViewModel extends BaseViewModel { await _preferencesProvider.clearDualisCredentials(); } - Future loadCredentials() async { + Future loadCredentials() async { return await _preferencesProvider.loadDualisCredentials(); } @@ -109,7 +106,7 @@ class StudyGradesViewModel extends BaseViewModel { } Future loadStudyGrades() async { - if (_studyGrades != null) return Future.value(); + if (_studyGrades != null) return; print("Loading study grades..."); @@ -130,7 +127,7 @@ class StudyGradesViewModel extends BaseViewModel { } Future loadAllModules() async { - if (_allModules != null) return Future.value(); + if (_allModules != null) return; print("Loading all modules..."); @@ -151,7 +148,7 @@ class StudyGradesViewModel extends BaseViewModel { notifyListeners("allModules"); } - Future loadSemester(String semesterName) async { + Future loadSemester(String? semesterName) async { if (_currentSemester != null && _currentSemesterName == semesterName) return Future.value(); @@ -186,7 +183,7 @@ class StudyGradesViewModel extends BaseViewModel { } Future loadSemesterNames() async { - if (_semesterNames != null) return Future.value(); + if (_semesterNames != null) return; print("Loading semester names..."); @@ -211,14 +208,14 @@ class StudyGradesViewModel extends BaseViewModel { Future _loadInitialSemester() async { if (_semesterNames == null) return; - if (_semesterNames.isEmpty) return; + if (_semesterNames!.isEmpty) return; var lastViewedSemester = await _preferencesProvider.getLastViewedSemester(); - if (_semesterNames.contains(lastViewedSemester)) { + if (_semesterNames!.contains(lastViewedSemester)) { loadSemester(lastViewedSemester); } else { - loadSemester(_semesterNames.first); + loadSemester(_semesterNames!.first); } } diff --git a/lib/dualis/ui/widgets/grade_state_icon.dart b/lib/dualis/ui/widgets/grade_state_icon.dart index 8c3e1236..5984b6e4 100644 --- a/lib/dualis/ui/widgets/grade_state_icon.dart +++ b/lib/dualis/ui/widgets/grade_state_icon.dart @@ -2,11 +2,11 @@ import 'package:dhbwstudentapp/dualis/model/exam.dart'; import 'package:flutter/material.dart'; class GradeStateIcon extends StatelessWidget { - final ExamState state; + final ExamState? state; const GradeStateIcon({ - Key key, - this.state, + Key? key, + required this.state, }) : super(key: key); @override @@ -17,9 +17,8 @@ class GradeStateIcon extends StatelessWidget { case ExamState.Failed: return const Icon(Icons.close, color: Colors.red); case ExamState.Pending: + default: return Container(); } - - return Container(); } } diff --git a/lib/dualis/ui/widgets/login_form_widget.dart b/lib/dualis/ui/widgets/login_form_widget.dart index 2e71236e..7d061a64 100644 --- a/lib/dualis/ui/widgets/login_form_widget.dart +++ b/lib/dualis/ui/widgets/login_form_widget.dart @@ -3,7 +3,7 @@ import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:flutter/material.dart'; typedef OnLogin = Future Function(Credentials credentials); -typedef OnLoadCredentials = Future Function(); +typedef OnLoadCredentials = Future Function(); typedef OnSaveCredentials = Future Function(Credentials credentials); typedef OnClearCredentials = Future Function(); typedef GetDoSaveCredentials = Future Function(); @@ -19,77 +19,52 @@ class LoginForm extends StatefulWidget { final String loginFailedText; const LoginForm({ - Key key, - this.onLogin, - this.title, - this.loginFailedText, - this.onLoadCredentials, - this.onSaveCredentials, - this.onClearCredentials, - this.getDoSaveCredentials, + Key? key, + required this.onLogin, + required this.title, + required this.loginFailedText, + required this.onLoadCredentials, + required this.onSaveCredentials, + required this.onClearCredentials, + required this.getDoSaveCredentials, }) : super(key: key); @override - _LoginFormState createState() => _LoginFormState( - onLogin, - title, - loginFailedText, - onLoadCredentials, - onSaveCredentials, - onClearCredentials, - getDoSaveCredentials, - ); + _LoginFormState createState() => _LoginFormState(); } class _LoginFormState extends State { - final OnLogin _onLogin; - final OnLoadCredentials _onLoadCredentials; - final OnSaveCredentials _onSaveCredentials; - final OnClearCredentials _onClearCredentials; - final GetDoSaveCredentials _getDoSaveCredentials; - final Widget _title; - - final String _loginFailedText; - bool _storeCredentials = false; bool _loginFailed = false; bool _isLoading = false; - final TextEditingController _usernameEditingController = - TextEditingController(); - final TextEditingController _passwordEditingController = - TextEditingController(); - - _LoginFormState( - this._onLogin, - this._title, - this._loginFailedText, - this._onLoadCredentials, - this._onSaveCredentials, - this._onClearCredentials, - this._getDoSaveCredentials, - ); + final CredentialsEditingController _controller = + CredentialsEditingController(); @override void initState() { super.initState(); - if (_onLoadCredentials != null && _getDoSaveCredentials != null) { - _getDoSaveCredentials().then((value) { - setState(() { - _storeCredentials = value; - }); - - _onLoadCredentials().then((value) { - _usernameEditingController.text = value.username; - _passwordEditingController.text = value.password; + widget.getDoSaveCredentials().then((value) { + setState(() { + _storeCredentials = value; + }); + widget.onLoadCredentials().then((credentials) { + if (credentials != null) { + _controller.credentials = credentials; if (mounted) { setState(() {}); } - }); + } }); - } + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); } @override @@ -98,14 +73,12 @@ class _LoginFormState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - _title != null - ? Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 24), - child: _title, - ) - : Container(), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 24), + child: widget.title, + ), TextField( - controller: _usernameEditingController, + controller: _controller.username, decoration: InputDecoration( enabled: !_isLoading, hintText: L.of(context).loginUsername, @@ -113,13 +86,13 @@ class _LoginFormState extends State { ), ), TextField( - controller: _passwordEditingController, + controller: _controller.password, obscureText: true, decoration: InputDecoration( enabled: !_isLoading, hintText: L.of(context).loginPassword, icon: Icon(Icons.lock_outline), - errorText: _loginFailed ? _loginFailedText : null, + errorText: _loginFailed ? widget.loginFailedText : null, ), ), Padding( @@ -130,7 +103,8 @@ class _LoginFormState extends State { title: Text( L.of(context).dualisStoreCredentials, ), - onChanged: (bool value) { + onChanged: (bool? value) { + if (value == null) return; setState(() { _storeCredentials = value; }); @@ -165,19 +139,16 @@ class _LoginFormState extends State { _isLoading = true; }); - if (!_storeCredentials && _onClearCredentials != null) { - await _onClearCredentials(); + if (!_storeCredentials) { + await widget.onClearCredentials(); } - var credentials = Credentials( - _usernameEditingController.text, - _passwordEditingController.text, - ); + var credentials = _controller.credentials; - bool loginSuccess = await _onLogin(credentials); + bool loginSuccess = await widget.onLogin(credentials); - if (loginSuccess && _storeCredentials && _onSaveCredentials != null) { - await _onSaveCredentials(credentials); + if (loginSuccess && _storeCredentials) { + await widget.onSaveCredentials(credentials); } setState(() { diff --git a/lib/information/ui/useful_information_navigation_entry.dart b/lib/information/ui/useful_information_navigation_entry.dart index 14271bf5..08713249 100644 --- a/lib/information/ui/useful_information_navigation_entry.dart +++ b/lib/information/ui/useful_information_navigation_entry.dart @@ -1,18 +1,17 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; +import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/information/ui/usefulinformation/useful_information_page.dart'; import 'package:dhbwstudentapp/ui/navigation/navigation_entry.dart'; import 'package:flutter/material.dart'; -class UsefulInformationNavigationEntry extends NavigationEntry { +class UsefulInformationNavigationEntry extends NavigationEntry { @override Widget build(BuildContext context) { return UsefulInformationPage(); } @override - Widget icon(BuildContext context) { - return Icon(Icons.info_outline); - } + Icon icon = Icon(Icons.info_outline); @override String title(BuildContext context) { @@ -21,4 +20,10 @@ class UsefulInformationNavigationEntry extends NavigationEntry { @override String get route => "usefulInformation"; + + @override + BaseViewModel initViewModel() => BaseViewModel(); + + @override + List appBarActions(BuildContext context) => []; } diff --git a/lib/information/ui/usefulinformation/useful_information_page.dart b/lib/information/ui/usefulinformation/useful_information_page.dart index 903db7af..d480dd32 100644 --- a/lib/information/ui/usefulinformation/useful_information_page.dart +++ b/lib/information/ui/usefulinformation/useful_information_page.dart @@ -26,7 +26,8 @@ class UsefulInformationPage extends StatelessWidget { leading: Icon(Icons.email), title: Text(L.of(context).informationPageRoundcube), onTap: () { - openLink("https://lehre-webmail.dhbw-stuttgart.de/roundcubemail/"); + openLink( + "https://lehre-webmail.dhbw-stuttgart.de/roundcubemail/"); }, ), ListTile( diff --git a/lib/native/widget/android_widget_helper.dart b/lib/native/widget/android_widget_helper.dart index 464d69de..a193aac1 100644 --- a/lib/native/widget/android_widget_helper.dart +++ b/lib/native/widget/android_widget_helper.dart @@ -30,7 +30,7 @@ class AndroidWidgetHelper implements WidgetHelper { } @override - Future areWidgetsSupported() async { + Future areWidgetsSupported() async { try { return await platform.invokeMethod('areWidgetsSupported'); } on Exception catch (_) { diff --git a/lib/native/widget/ios_widget_helper.dart b/lib/native/widget/ios_widget_helper.dart index 7e4a2b2e..0aa61fb8 100644 --- a/lib/native/widget/ios_widget_helper.dart +++ b/lib/native/widget/ios_widget_helper.dart @@ -32,7 +32,7 @@ class IOSWidgetHelper implements WidgetHelper { } @override - Future areWidgetsSupported() async { + Future areWidgetsSupported() async { try { return await platform.invokeMethod('areWidgetsSupported'); } on PlatformException catch (_) { diff --git a/lib/native/widget/widget_helper.dart b/lib/native/widget/widget_helper.dart index 8b8e98ad..e0f03028 100644 --- a/lib/native/widget/widget_helper.dart +++ b/lib/native/widget/widget_helper.dart @@ -8,7 +8,7 @@ import 'package:dhbwstudentapp/native/widget/ios_widget_helper.dart'; /// methods to enable/disable or update the widget /// class WidgetHelper { - static WidgetHelper _instance; + static WidgetHelper? _instance; WidgetHelper() { if (_instance != null) return; @@ -27,14 +27,14 @@ class WidgetHelper { /// scheduled and will happen soon. /// Future requestWidgetRefresh() { - return _instance.requestWidgetRefresh(); + return _instance!.requestWidgetRefresh(); } /// /// Checks if widgets are supported by the device /// - Future areWidgetsSupported() { - return _instance.areWidgetsSupported(); + Future areWidgetsSupported() { + return _instance!.areWidgetsSupported(); } /// @@ -42,7 +42,7 @@ class WidgetHelper { /// its full functionality. /// Future enableWidget() { - return _instance.enableWidget(); + return _instance!.enableWidget(); } /// @@ -50,7 +50,7 @@ class WidgetHelper { /// only provide placeholder content or limited functionality. /// Future disableWidget() { - return _instance.disableWidget(); + return _instance!.disableWidget(); } } diff --git a/lib/schedule/background/background_schedule_update.dart b/lib/schedule/background/background_schedule_update.dart index 7c63d1a6..c8106b8b 100644 --- a/lib/schedule/background/background_schedule_update.dart +++ b/lib/schedule/background/background_schedule_update.dart @@ -22,8 +22,8 @@ class BackgroundScheduleUpdate extends TaskCallback { return; } - var today = toDayOfWeek(toStartOfDay(DateTime.now()), DateTime.monday); - var end = addDays(today, 7 * 3); + var today = toDayOfWeek(toStartOfDay(DateTime.now()), DateTime.monday)!; + var end = addDays(today, 7 * 3)!; var cancellationToken = CancellationToken(); diff --git a/lib/schedule/background/calendar_synchronizer.dart b/lib/schedule/background/calendar_synchronizer.dart index 158f89d2..f67ef0b4 100644 --- a/lib/schedule/background/calendar_synchronizer.dart +++ b/lib/schedule/background/calendar_synchronizer.dart @@ -35,7 +35,7 @@ class CalendarSynchronizer { listDateEntries; if (await preferencesProvider.isCalendarSyncEnabled()) { - Calendar selectedCalendar = + Calendar? selectedCalendar = await preferencesProvider.getSelectedCalendar(); if (selectedCalendar == null) return; CalendarAccess().addOrUpdateDates(listDateEntries, selectedCalendar); @@ -47,7 +47,6 @@ class CalendarSynchronizer { Future.delayed(Duration(seconds: 10), () { if (!scheduleSourceProvider.didSetupCorrectly()) return; scheduleProvider.getUpdatedSchedule( - DateTime.now(), DateTime.now().add(Duration(days: 30)), CancellationToken(), diff --git a/lib/schedule/business/schedule_diff_calculator.dart b/lib/schedule/business/schedule_diff_calculator.dart index 077bdc17..c8be9661 100644 --- a/lib/schedule/business/schedule_diff_calculator.dart +++ b/lib/schedule/business/schedule_diff_calculator.dart @@ -39,17 +39,17 @@ class ScheduleDiffCalculator { return entry1.start.isAtSameMomentAs(entry2.start) && entry1.end.isAtSameMomentAs(entry2.end) && entry1.type == entry2.type && - (entry1.room ?? "") == (entry2.room ?? "") && - (entry1.details ?? "") == (entry2.details ?? "") && - (entry1.title ?? "") == (entry2.title ?? "") && - (entry1.professor ?? "") == (entry2.professor ?? ""); + entry1.room == entry2.room && + entry1.details == entry2.details && + entry1.title == entry2.title && + entry1.professor == entry2.professor; } ScheduleDiff _tryConnectNewAndOldEntries( List addedEntries, List removedEntries, ) { - var allDistinctTitles = []; + var allDistinctTitles = []; allDistinctTitles.addAll(addedEntries.map((ScheduleEntry e) => e.title)); allDistinctTitles.addAll(removedEntries.map((ScheduleEntry e) => e.title)); @@ -166,7 +166,10 @@ class ScheduleDiff { final List removedEntries; final List updatedEntries; - ScheduleDiff({this.addedEntries, this.removedEntries, this.updatedEntries}); + ScheduleDiff( + {required this.addedEntries, + required this.removedEntries, + required this.updatedEntries}); bool didSomethingChange() { return addedEntries.isNotEmpty || diff --git a/lib/schedule/business/schedule_provider.dart b/lib/schedule/business/schedule_provider.dart index 69d7b426..0dee19a6 100644 --- a/lib/schedule/business/schedule_provider.dart +++ b/lib/schedule/business/schedule_provider.dart @@ -33,7 +33,7 @@ class ScheduleProvider { final List _scheduleUpdatedCallbacks = []; - ScheduleFilter _scheduleFilter; + late ScheduleFilter _scheduleFilter; final List _scheduleEntryChangedCallbacks = []; @@ -73,7 +73,7 @@ class ScheduleProvider { var updatedSchedule = await _scheduleSource.currentScheduleSource .querySchedule(start, end, cancellationToken); - var schedule = updatedSchedule.schedule; + var schedule = updatedSchedule?.schedule; if (schedule == null) { print("No schedule returned!"); @@ -97,10 +97,10 @@ class ScheduleProvider { } for (var c in _scheduleUpdatedCallbacks) { - await c(schedule, start, end); + await c(schedule!, start, end); } - updatedSchedule = ScheduleQueryResult(schedule, updatedSchedule.errors); + updatedSchedule = ScheduleQueryResult(schedule!, updatedSchedule!.errors); return updatedSchedule; } on ScheduleQueryFailedException catch (e, trace) { @@ -162,7 +162,7 @@ class ScheduleProvider { for (var addedEntry in diff.addedEntries) { if (queryInformation.any((i) => - addedEntry.end.isAfter(i.start) && + addedEntry.end.isAfter(i!.start) && addedEntry.start.isBefore(i.end))) { cleanedAddedEntries.add(addedEntry); } diff --git a/lib/schedule/business/schedule_source_provider.dart b/lib/schedule/business/schedule_source_provider.dart index 06e244b9..4b0a1ff4 100644 --- a/lib/schedule/business/schedule_source_provider.dart +++ b/lib/schedule/business/schedule_source_provider.dart @@ -55,7 +55,7 @@ class ScheduleSourceProvider { }; if (initializer.containsKey(scheduleSourceType)) { - scheduleSource = await initializer[scheduleSourceType](); + scheduleSource = await initializer[scheduleSourceType]!(); } _currentScheduleSource = scheduleSource; @@ -72,11 +72,7 @@ class ScheduleSourceProvider { Future _getScheduleSourceType() async { var type = await _preferencesProvider.getScheduleSourceType(); - var scheduleSourceType = type != null - ? ScheduleSourceType.values[type] - : ScheduleSourceType.None; - - return scheduleSourceType; + return ScheduleSourceType.values[type]; } Future _dualisScheduleSource() async { @@ -84,7 +80,7 @@ class ScheduleSourceProvider { var credentials = await _preferencesProvider.loadDualisCredentials(); - if (credentials.allFieldsFilled()) { + if (credentials != null) { dualis.setLoginCredentials(credentials); return ErrorReportScheduleSourceDecorator(dualis); } else { @@ -130,7 +126,9 @@ class ScheduleSourceProvider { return InvalidScheduleSource(); } - Future setupForRapla(String url) async { + Future setupForRapla(String? url) async { + if (url == null) return; + await _preferencesProvider.setRaplaUrl(url); await _preferencesProvider .setScheduleSourceType(ScheduleSourceType.Rapla.index); @@ -157,7 +155,9 @@ class ScheduleSourceProvider { ); } - Future setupForIcal(String url) async { + Future setupForIcal(String? url) async { + if (url == null) return; + await _preferencesProvider.setIcalUrl(url); await _preferencesProvider .setScheduleSourceType(ScheduleSourceType.Ical.index); @@ -171,8 +171,8 @@ class ScheduleSourceProvider { ); } - Future setupForMannheim(Course selectedCourse) async { - if(selectedCourse == null) return; + Future setupForMannheim(Course? selectedCourse) async { + if (selectedCourse == null) return; await _preferencesProvider.setMannheimScheduleId(selectedCourse.scheduleId); await _preferencesProvider.setIcalUrl(selectedCourse.icalUrl); await _preferencesProvider @@ -188,8 +188,7 @@ class ScheduleSourceProvider { } bool didSetupCorrectly() { - return _currentScheduleSource != null && - !(_currentScheduleSource is InvalidScheduleSource); + return !(_currentScheduleSource is InvalidScheduleSource); } void addDidChangeScheduleSourceCallback(OnDidChangeScheduleSource callback) { diff --git a/lib/schedule/data/schedule_entry_entity.dart b/lib/schedule/data/schedule_entry_entity.dart index 2f532d8f..8a5ae1bc 100644 --- a/lib/schedule/data/schedule_entry_entity.dart +++ b/lib/schedule/data/schedule_entry_entity.dart @@ -2,7 +2,7 @@ import 'package:dhbwstudentapp/common/data/database_entity.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class ScheduleEntryEntity extends DatabaseEntity { - ScheduleEntry _scheduleEntry; + ScheduleEntry? _scheduleEntry; ScheduleEntryEntity.fromModel(ScheduleEntry scheduleEntry) { _scheduleEntry = scheduleEntry; @@ -14,15 +14,9 @@ class ScheduleEntryEntity extends DatabaseEntity { @override void fromMap(Map map) { - DateTime startDate; - if (map["start"] != null) { - startDate = DateTime.fromMillisecondsSinceEpoch(map["start"]); - } + var startDate = DateTime.fromMillisecondsSinceEpoch(map["start"]); - DateTime endDate; - if (map["end"] != null) { - endDate = DateTime.fromMillisecondsSinceEpoch(map["end"]); - } + var endDate = DateTime.fromMillisecondsSinceEpoch(map["end"]); _scheduleEntry = ScheduleEntry( id: map["id"], @@ -38,18 +32,18 @@ class ScheduleEntryEntity extends DatabaseEntity { @override Map toMap() { return { - "id": _scheduleEntry.id, - "start": _scheduleEntry.start?.millisecondsSinceEpoch ?? 0, - "end": _scheduleEntry.end?.millisecondsSinceEpoch ?? 0, - "details": _scheduleEntry.details ?? "", - "professor": _scheduleEntry.professor ?? "", - "room": _scheduleEntry.room ?? "", - "title": _scheduleEntry.title ?? "", - "type": _scheduleEntry.type?.index + "id": _scheduleEntry!.id, + "start": _scheduleEntry!.start.millisecondsSinceEpoch, + "end": _scheduleEntry!.end.millisecondsSinceEpoch, + "details": _scheduleEntry!.details, + "professor": _scheduleEntry!.professor, + "room": _scheduleEntry!.room, + "title": _scheduleEntry!.title, + "type": _scheduleEntry!.type.index }; } - ScheduleEntry asScheduleEntry() => _scheduleEntry; + ScheduleEntry asScheduleEntry() => _scheduleEntry!; static String tableName() => "ScheduleEntries"; } diff --git a/lib/schedule/data/schedule_entry_repository.dart b/lib/schedule/data/schedule_entry_repository.dart index 0f72149f..e46ed5db 100644 --- a/lib/schedule/data/schedule_entry_repository.dart +++ b/lib/schedule/data/schedule_entry_repository.dart @@ -34,7 +34,7 @@ class ScheduleEntryRepository { return schedule; } - Future queryExistingScheduleEntry(ScheduleEntry entry) async { + Future queryExistingScheduleEntry(ScheduleEntry entry) async { var rows = await _database.queryRows( ScheduleEntryEntity.tableName(), where: "start=? AND end=? AND title=? AND details=? AND professor=?", @@ -52,7 +52,7 @@ class ScheduleEntryRepository { return ScheduleEntryEntity.fromMap(rows[0]).asScheduleEntry(); } - Future queryNextScheduleEntry(DateTime dateTime) async { + Future queryNextScheduleEntry(DateTime dateTime) async { var nextScheduleEntry = await _database.queryRows( ScheduleEntryEntity.tableName(), where: "start>?", @@ -70,18 +70,16 @@ class ScheduleEntryRepository { return null; } - Future> queryAllNamesOfScheduleEntries() async { + Future> queryAllNamesOfScheduleEntries() async { var allNames = await _database.rawQuery( "SELECT DISTINCT title FROM ScheduleEntries", [], ); - return allNames.map((e) => e["title"] as String).toList(); + return allNames.map((e) => e["title"] as String?).toList(); } Future saveScheduleEntry(ScheduleEntry entry) async { - var row = ScheduleEntryEntity.fromModel(entry).toMap(); - var existingEntry = await queryExistingScheduleEntry(entry); if (existingEntry != null) { @@ -89,6 +87,7 @@ class ScheduleEntryRepository { return; } + var row = ScheduleEntryEntity.fromModel(entry).toMap(); if (entry.id == null) { var id = await _database.insert(ScheduleEntryEntity.tableName(), row); entry.id = id; @@ -98,7 +97,7 @@ class ScheduleEntryRepository { } Future saveSchedule(Schedule schedule) async { - for (var entry in schedule.entries ?? []) { + for (var entry in schedule.entries) { saveScheduleEntry(entry); } } diff --git a/lib/schedule/data/schedule_filter_repository.dart b/lib/schedule/data/schedule_filter_repository.dart index 39e41480..651bc270 100644 --- a/lib/schedule/data/schedule_filter_repository.dart +++ b/lib/schedule/data/schedule_filter_repository.dart @@ -5,14 +5,14 @@ class ScheduleFilterRepository { ScheduleFilterRepository(this._database); - Future> queryAllHiddenNames() async { + Future> queryAllHiddenNames() async { var rows = await _database.queryRows("ScheduleEntryFilters"); - var names = rows.map((e) => e['title'] as String).toList(); + var names = rows.map((e) => e['title'] as String?).toList(); return names; } - Future saveAllHiddenNames(List hiddenNames) async { + Future saveAllHiddenNames(List hiddenNames) async { await _database.deleteWhere("ScheduleEntryFilters"); for (var name in hiddenNames) { diff --git a/lib/schedule/data/schedule_query_information_entity.dart b/lib/schedule/data/schedule_query_information_entity.dart index abd0d5e2..b8bc4e1d 100644 --- a/lib/schedule/data/schedule_query_information_entity.dart +++ b/lib/schedule/data/schedule_query_information_entity.dart @@ -2,7 +2,7 @@ import 'package:dhbwstudentapp/common/data/database_entity.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_query_information.dart'; class ScheduleQueryInformationEntity extends DatabaseEntity { - ScheduleQueryInformation _scheduleQueryInformation; + ScheduleQueryInformation? _scheduleQueryInformation; ScheduleQueryInformationEntity.fromModel( ScheduleQueryInformation scheduleQueryInformation, @@ -16,18 +16,18 @@ class ScheduleQueryInformationEntity extends DatabaseEntity { @override void fromMap(Map map) { - DateTime startDate; + DateTime? startDate; if (map["start"] != null) { startDate = DateTime.fromMillisecondsSinceEpoch(map["start"]); } - DateTime endDate; + DateTime? endDate; if (map["end"] != null) { endDate = DateTime.fromMillisecondsSinceEpoch(map["end"]); } - DateTime queryTimeDate; - if (map["end"] != null) { + DateTime? queryTimeDate; + if (map["queryTime"] != null) { queryTimeDate = DateTime.fromMillisecondsSinceEpoch(map["queryTime"]); } @@ -38,13 +38,13 @@ class ScheduleQueryInformationEntity extends DatabaseEntity { @override Map toMap() { return { - "start": _scheduleQueryInformation.start?.millisecondsSinceEpoch ?? 0, - "end": _scheduleQueryInformation.end?.millisecondsSinceEpoch ?? 0, - "queryTime": _scheduleQueryInformation.queryTime?.millisecondsSinceEpoch, + "start": _scheduleQueryInformation!.start.millisecondsSinceEpoch, + "end": _scheduleQueryInformation!.end.millisecondsSinceEpoch, + "queryTime": _scheduleQueryInformation!.queryTime?.millisecondsSinceEpoch, }; } - ScheduleQueryInformation asScheduleQueryInformation() => + ScheduleQueryInformation? asScheduleQueryInformation() => _scheduleQueryInformation; static String tableName() => "ScheduleQueryInformation"; diff --git a/lib/schedule/data/schedule_query_information_repository.dart b/lib/schedule/data/schedule_query_information_repository.dart index 669d300e..e43d8fcf 100644 --- a/lib/schedule/data/schedule_query_information_repository.dart +++ b/lib/schedule/data/schedule_query_information_repository.dart @@ -7,7 +7,7 @@ class ScheduleQueryInformationRepository { ScheduleQueryInformationRepository(this._database); - Future getOldestQueryTimeBetweenDates( + Future getOldestQueryTimeBetweenDates( DateTime start, DateTime end) async { var oldestQueryTimeDate = await _database.queryAggregator( "SELECT MIN(queryTime) FROM ScheduleQueryInformation WHERE start<=? AND end>=?", @@ -17,10 +17,12 @@ class ScheduleQueryInformationRepository { ], ); + if (oldestQueryTimeDate == null) return null; + return DateTime.fromMillisecondsSinceEpoch(oldestQueryTimeDate); } - Future> getQueryInformationBetweenDates( + Future> getQueryInformationBetweenDates( DateTime start, DateTime end) async { var rows = await _database.queryRows( ScheduleQueryInformationEntity.tableName(), @@ -31,7 +33,7 @@ class ScheduleQueryInformationRepository { ], ); - var scheduleQueryInformation = []; + var scheduleQueryInformation = []; for (var row in rows) { scheduleQueryInformation.add( diff --git a/lib/schedule/model/schedule.dart b/lib/schedule/model/schedule.dart index 7a948471..3d4aeac4 100644 --- a/lib/schedule/model/schedule.dart +++ b/lib/schedule/model/schedule.dart @@ -25,11 +25,11 @@ class Schedule { } } - Schedule trim(DateTime startDate, DateTime endDate) { + Schedule trim(DateTime? startDate, DateTime? endDate) { var newList = []; for (var entry in entries) { - if (startDate.isBefore(entry.end) && endDate.isAfter(entry.start)) { + if (startDate!.isBefore(entry.end) && endDate!.isAfter(entry.start)) { newList.add(entry); } } @@ -40,28 +40,28 @@ class Schedule { return schedule; } - DateTime getStartDate() { + DateTime? getStartDate() { if (entries.isEmpty) return null; - var date = entries?.reduce((ScheduleEntry a, ScheduleEntry b) { - return a.start.isBefore(b.start) ? a : b; - })?.start; + var date = entries.reduce((ScheduleEntry? a, ScheduleEntry? b) { + return a!.start.isBefore(b!.start) ? a : b; + }).start; return date; } - DateTime getEndDate() { + DateTime? getEndDate() { if (entries.isEmpty) return null; - var date = entries?.reduce((ScheduleEntry a, ScheduleEntry b) { - return a.end.isAfter(b.end) ? a : b; - })?.end; + var date = entries.reduce((ScheduleEntry? a, ScheduleEntry? b) { + return a!.end.isAfter(b!.end) ? a : b; + }).end; return date; } - DateTime getStartTime() { - DateTime earliestTime; + DateTime? getStartTime() { + DateTime? earliestTime; for (var entry in entries) { var entryTime = DateTime( @@ -83,8 +83,8 @@ class Schedule { return earliestTime; } - DateTime getEndTime() { - DateTime latestTime; + DateTime? getEndTime() { + DateTime? latestTime; for (var entry in entries) { var entryTime = DateTime( @@ -106,7 +106,7 @@ class Schedule { return latestTime; } - Schedule copyWith({List entries}) { + Schedule copyWith({required List entries}) { var schedule = Schedule.fromList(entries); schedule.urls.addAll(urls); diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index 619df572..d925d5b0 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -7,7 +7,7 @@ enum ScheduleEntryType { } class ScheduleEntry { - int id; + int? id; final DateTime start; final DateTime end; final String title; @@ -18,14 +18,19 @@ class ScheduleEntry { ScheduleEntry({ this.id, - this.start, - this.end, - this.title, - this.details, - this.professor, - this.room, - this.type, - }); + DateTime? start, + DateTime? end, + String? title, + String? details, + String? professor, + String? room, + required this.type, + }) : this.start = start ?? DateTime.fromMicrosecondsSinceEpoch(0), + this.end = end ?? DateTime.fromMicrosecondsSinceEpoch(0), + this.details = details ?? "", + this.professor = professor ?? "", + this.room = room ?? "", + this.title = title ?? ""; bool equalsWithIdIgnored(ScheduleEntry other) { return this.start == other.start && @@ -40,7 +45,7 @@ class ScheduleEntry { List getDifferentProperties(ScheduleEntry entry) { var changedProperties = []; - if ((title ?? "") != (entry.title ?? "")) { + if (title != entry.title) { changedProperties.add("title"); } if (start != entry.start) { @@ -49,13 +54,13 @@ class ScheduleEntry { if (end != entry.end) { changedProperties.add("end"); } - if ((details ?? "") != (entry.details ?? "")) { + if (details != entry.details) { changedProperties.add("details"); } - if ((professor ?? "") != (entry.professor ?? "")) { + if (professor != entry.professor) { changedProperties.add("professor"); } - if ((room ?? "") != (entry.room ?? "")) { + if (room != entry.room) { changedProperties.add("room"); } if (type != entry.type) { @@ -65,14 +70,15 @@ class ScheduleEntry { return changedProperties; } + // TODO: [Leptopoda] use buildrunner ScheduleEntry copyWith( - {DateTime start, - DateTime end, - String title, - String details, - String professor, - String room, - ScheduleEntryType type}) { + {DateTime? start, + DateTime? end, + String? title, + String? details, + String? professor, + String? room, + ScheduleEntryType? type}) { return ScheduleEntry( id: id, start: start ?? this.start, diff --git a/lib/schedule/model/schedule_query_information.dart b/lib/schedule/model/schedule_query_information.dart index e527f01a..b9e124b8 100644 --- a/lib/schedule/model/schedule_query_information.dart +++ b/lib/schedule/model/schedule_query_information.dart @@ -1,7 +1,12 @@ class ScheduleQueryInformation { final DateTime start; final DateTime end; - final DateTime queryTime; + final DateTime? queryTime; - ScheduleQueryInformation(this.start, this.end, this.queryTime); + ScheduleQueryInformation( + DateTime? start, + DateTime? end, + this.queryTime, + ) : this.start = start ?? DateTime.fromMillisecondsSinceEpoch(0), + this.end = end ?? DateTime.fromMillisecondsSinceEpoch(0); } diff --git a/lib/schedule/model/schedule_query_result.dart b/lib/schedule/model/schedule_query_result.dart index 26382398..421807bc 100644 --- a/lib/schedule/model/schedule_query_result.dart +++ b/lib/schedule/model/schedule_query_result.dart @@ -4,16 +4,16 @@ class ScheduleQueryResult { final Schedule schedule; final List errors; - bool get hasError => errors?.isNotEmpty ?? false; + bool get hasError => errors.isNotEmpty; ScheduleQueryResult(this.schedule, this.errors); } class ParseError { final String object; - final String trace; + final String? trace; - ParseError(Object object, StackTrace trace) - : object = object?.toString(), + ParseError(Object object, [StackTrace? trace]) + : object = object.toString(), trace = trace?.toString(); } diff --git a/lib/schedule/service/dualis/dualis_schedule_source.dart b/lib/schedule/service/dualis/dualis_schedule_source.dart index f515f501..9863689f 100644 --- a/lib/schedule/service/dualis/dualis_schedule_source.dart +++ b/lib/schedule/service/dualis/dualis_schedule_source.dart @@ -13,11 +13,11 @@ class DualisScheduleSource extends ScheduleSource { DualisScheduleSource(this._dualisScraper); @override - Future querySchedule(DateTime from, DateTime to, - [CancellationToken cancellationToken]) async { + Future querySchedule(DateTime? from, DateTime? to, + [CancellationToken? cancellationToken]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); - DateTime current = toStartOfMonth(from); + DateTime current = toStartOfMonth(from)!; var schedule = Schedule(); var allErrors = []; @@ -25,12 +25,12 @@ class DualisScheduleSource extends ScheduleSource { if (!_dualisScraper.isLoggedIn()) await _dualisScraper.loginWithPreviousCredentials(cancellationToken); - while (to.isAfter(current) && !cancellationToken.isCancelled()) { + while (to!.isAfter(current) && !cancellationToken.isCancelled()) { try { var monthSchedule = await _dualisScraper.loadMonthlySchedule( current, cancellationToken); - if (monthSchedule != null) schedule.merge(monthSchedule); + schedule.merge(monthSchedule); } on OperationCancelledException { rethrow; } on ParseException catch (ex, trace) { @@ -51,10 +51,7 @@ class DualisScheduleSource extends ScheduleSource { } Future setLoginCredentials(Credentials credentials) async { - _dualisScraper.setLoginCredentials( - credentials.username, - credentials.password, - ); + _dualisScraper.setLoginCredentials(credentials); } @override diff --git a/lib/schedule/service/error_report_schedule_source_decorator.dart b/lib/schedule/service/error_report_schedule_source_decorator.dart index 15c5e88b..d1930b98 100644 --- a/lib/schedule/service/error_report_schedule_source_decorator.dart +++ b/lib/schedule/service/error_report_schedule_source_decorator.dart @@ -9,8 +9,8 @@ class ErrorReportScheduleSourceDecorator extends ScheduleSource { ErrorReportScheduleSourceDecorator(this._scheduleSource); @override - Future querySchedule(DateTime from, DateTime to, - [CancellationToken cancellationToken]) async { + Future querySchedule(DateTime? from, DateTime? to, + [CancellationToken? cancellationToken]) async { try { var schedule = await _scheduleSource.querySchedule( from, diff --git a/lib/schedule/service/ical/ical_parser.dart b/lib/schedule/service/ical/ical_parser.dart index 60435489..5042a245 100644 --- a/lib/schedule/service/ical/ical_parser.dart +++ b/lib/schedule/service/ical/ical_parser.dart @@ -34,7 +34,7 @@ class IcalParser { List entries = []; for (var match in matches) { - var entry = _parseEntry(match.group(1)); + var entry = _parseEntry(match.group(1)!); entries.add(entry); } @@ -50,7 +50,7 @@ class IcalParser { unicode: true, ).allMatches(entryData); - Map properties = {}; + Map properties = {}; for (var property in allProperties) { properties[property.group(1)] = property.group(3); @@ -67,23 +67,23 @@ class IcalParser { ); } - DateTime _parseDate(String date) { + DateTime? _parseDate(String? date) { + if (date == null) return null; + var match = RegExp( dateTimeRegex, unicode: true, - ).firstMatch(date ?? ""); + ).firstMatch(date); - if (match == null) { - return null; - } + if (match == null) return null; return DateTime( - int.tryParse(match.group(1)), - int.tryParse(match.group(2)), - int.tryParse(match.group(3)), - int.tryParse(match.group(4)), - int.tryParse(match.group(5)), - int.tryParse(match.group(6)), + int.tryParse(match.group(1)!)!, + int.tryParse(match.group(2)!)!, + int.tryParse(match.group(3)!)!, + int.tryParse(match.group(4)!)!, + int.tryParse(match.group(5)!)!, + int.tryParse(match.group(6)!)!, ); } } diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index 495ada39..2bf3112a 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -10,9 +10,9 @@ import 'package:http_client_helper/http_client_helper.dart' as http; class IcalScheduleSource extends ScheduleSource { final IcalParser _icalParser = IcalParser(); - String _url; + String? _url; - void setIcalUrl(String url) { + void setIcalUrl(String? url) { _url = url; } @@ -22,12 +22,12 @@ class IcalScheduleSource extends ScheduleSource { } @override - Future querySchedule( - DateTime from, - DateTime to, [ - CancellationToken cancellationToken, + Future querySchedule( + DateTime? from, + DateTime? to, [ + CancellationToken? cancellationToken, ]) async { - var response = await _makeRequest(_url, cancellationToken); + var response = await _makeRequest(_url!, cancellationToken!); if (response == null) return null; try { @@ -45,7 +45,7 @@ class IcalScheduleSource extends ScheduleSource { } } - Future _makeRequest( + Future _makeRequest( String url, CancellationToken cancellationToken) async { url = url.replaceAll("webcal://", "https://"); @@ -76,8 +76,9 @@ class IcalScheduleSource extends ScheduleSource { return null; } - static bool isValidUrl(String url) { + static bool isValidUrl(String? url) { try { + if (url == null) return false; Uri.parse(url); } catch (e) { return false; diff --git a/lib/schedule/service/invalid_schedule_source.dart b/lib/schedule/service/invalid_schedule_source.dart index 0dcd0030..7f55936b 100644 --- a/lib/schedule/service/invalid_schedule_source.dart +++ b/lib/schedule/service/invalid_schedule_source.dart @@ -5,9 +5,9 @@ import 'package:dhbwstudentapp/schedule/service/schedule_source.dart'; class InvalidScheduleSource extends ScheduleSource { @override Future querySchedule( - DateTime from, - DateTime to, [ - CancellationToken cancellationToken, + DateTime? from, + DateTime? to, [ + CancellationToken? cancellationToken, ]) { throw StateError("Schedule source not properly configured"); } diff --git a/lib/schedule/service/isolate_schedule_source_decorator.dart b/lib/schedule/service/isolate_schedule_source_decorator.dart index 02ea3a96..5071aed6 100644 --- a/lib/schedule/service/isolate_schedule_source_decorator.dart +++ b/lib/schedule/service/isolate_schedule_source_decorator.dart @@ -11,35 +11,35 @@ import 'package:dhbwstudentapp/schedule/service/schedule_source.dart'; class IsolateScheduleSourceDecorator extends ScheduleSource { final ScheduleSource _scheduleSource; - Stream _isolateToMain; - Isolate _isolate; - SendPort _sendPort; + Stream? _isolateToMain; + Isolate? _isolate; + SendPort? _sendPort; IsolateScheduleSourceDecorator(this._scheduleSource); @override - Future querySchedule(DateTime from, DateTime to, - [CancellationToken cancellationToken]) async { + Future querySchedule(DateTime? from, DateTime? to, + [CancellationToken? cancellationToken]) async { await _initializeIsolate(); // Use the cancellation token to send a cancel message. // The isolate then uses a new instance to cancel the request - cancellationToken.setCancellationCallback(() { - _sendPort.send({"type": "cancel"}); + cancellationToken!.setCancellationCallback(() { + _sendPort!.send({"type": "cancel"}); }); - _sendPort.send({ + _sendPort!.send({ "type": "execute", "source": _scheduleSource, "from": from, "to": to, }); - final completer = Completer(); + final completer = Completer(); - ScheduleQueryFailedException potentialException; + ScheduleQueryFailedException? potentialException; - final subscription = _isolateToMain.listen((result) { + final subscription = _isolateToMain!.listen((result) { cancellationToken.setCancellationCallback(null); if (result != null && !(result is ScheduleQueryResult)) { @@ -55,7 +55,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { subscription.cancel(); if (potentialException != null) { - throw potentialException; + throw potentialException!; } return result; @@ -70,7 +70,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { _isolateToMain = isolateToMain.asBroadcastStream(); _isolate = await Isolate.spawn( scheduleSourceIsolateEntryPoint, isolateToMain.sendPort); - _sendPort = await _isolateToMain.first; + _sendPort = await _isolateToMain!.first as SendPort?; } @override @@ -84,7 +84,7 @@ void scheduleSourceIsolateEntryPoint(SendPort sendPort) async { var port = ReceivePort(); sendPort.send(port.sendPort); - CancellationToken token; + CancellationToken? token; await for (var message in port) { if (message["type"] == "execute") { @@ -99,12 +99,12 @@ void scheduleSourceIsolateEntryPoint(SendPort sendPort) async { Future executeQueryScheduleMessage( Map map, SendPort sendPort, - CancellationToken token, + CancellationToken? token, ) async { try { ScheduleSource source = map["source"]; - DateTime from = map["from"]; - DateTime to = map["to"]; + DateTime? from = map["from"]; + DateTime? to = map["to"]; var result = await source.querySchedule(from, to, token); diff --git a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart index 0cb543f0..9912082b 100644 --- a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart +++ b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart @@ -14,7 +14,7 @@ class MannheimCourseResponseParser { for (var e in options) { var label = e.attributes["label"] ?? ""; var value = e.attributes["value"] ?? ""; - var title = e.parent.attributes["label"] ?? ""; + var title = e.parent!.attributes["label"] ?? ""; if (label == "" || value == "") continue; if (label.trim() == "Kurs auswählen") continue; diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index 7ca27aa0..ecd3b732 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -15,7 +15,7 @@ class Course { class MannheimCourseScraper { Future> loadCourses([ - CancellationToken cancellationToken, + CancellationToken? cancellationToken, ]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); @@ -42,15 +42,14 @@ class MannheimCourseScraper { if (response == null && !requestCancellationToken.isCanceled) throw ServiceRequestFailed("Http request failed!"); - return response; + return response!; } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { if (!requestCancellationToken.isCanceled) rethrow; + throw ServiceRequestFailed("Http request failed!"); } finally { cancellationToken.setCancellationCallback(null); } - - return null; } } diff --git a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart index 5886f610..2a2f6bd3 100644 --- a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart @@ -12,7 +12,7 @@ class RaplaMonthlyResponseParser { static ScheduleQueryResult parseMonthlyTable( Element monthTable, ) { - var title = monthTable.parent.getElementsByClassName("title"); + var title = monthTable.parent!.getElementsByClassName("title"); var monthAndYear = title[0].text; var yearString = monthAndYear.split(" ")[1]; @@ -37,7 +37,7 @@ class RaplaMonthlyResponseParser { try { var entry = RaplaParsingUtils.extractScheduleEntryOrThrow( dayEntry, - DateTime(year, month, day), + DateTime(year!, month!, day!), ); allEntries.add(entry); @@ -50,7 +50,7 @@ class RaplaMonthlyResponseParser { return ScheduleQueryResult(Schedule.fromList(allEntries), parseErrors); } - static int _monthStringToDateTime(String monthAndYear) { + static int? _monthStringToDateTime(String monthAndYear) { var monthString = monthAndYear.split(" ")[0]; var monthNames = { "Januar": DateTime.january, diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index 90cc3aec..51830201 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -46,7 +46,7 @@ class RaplaParsingUtils { if (start == null || end == null) throw ElementNotFoundParseException("start and end date container"); - ScheduleEntry scheduleEntry; + ScheduleEntry? scheduleEntry; // The important information is stored in a html element called tooltip. // Depending on the Rapla configuration the tooltip is available or not. @@ -66,12 +66,12 @@ class RaplaParsingUtils { } static ScheduleEntry improveScheduleEntry(ScheduleEntry scheduleEntry) { - if (scheduleEntry.title == null) { + if (scheduleEntry.title == "") { throw ElementNotFoundParseException("title"); } var professor = scheduleEntry.professor; - if (professor?.endsWith(",") ?? false) { + if (professor.endsWith(",")) { scheduleEntry = scheduleEntry.copyWith( professor: professor.substring(0, professor.length - 1)); } @@ -87,7 +87,7 @@ class RaplaParsingUtils { static ScheduleEntry extractScheduleFromTooltip( List tooltip, Element value, - ScheduleEntry scheduleEntry, + ScheduleEntry? scheduleEntry, DateTime start, DateTime end) { var infotable = tooltip[0].getElementsByClassName(INFOTABLE_CLASS); @@ -120,7 +120,7 @@ class RaplaParsingUtils { static ScheduleEntry extractScheduleDetailsFromCell( List timeAndClassName, - ScheduleEntry scheduleEntry, + ScheduleEntry? scheduleEntry, DateTime start, DateTime end) { var descriptionHtml = timeAndClassName[0].innerHtml.substring(12); @@ -156,12 +156,11 @@ class RaplaParsingUtils { var typeString = strongTag[0].innerHtml; - var type = ScheduleEntryType.Unknown; if (entryTypeMapping.containsKey(typeString)) { - type = entryTypeMapping[typeString]; + return entryTypeMapping[typeString]!; + } else { + return ScheduleEntryType.Unknown; } - - return type; } static Map _parsePropertiesTable(Element infotable) { @@ -175,7 +174,7 @@ class RaplaParsingUtils { return map; } - static DateTime _parseTime(String timeString, DateTime date) { + static DateTime? _parseTime(String timeString, DateTime date) { try { var time = DateFormat("HH:mm").parse(timeString.substring(0, 5)); return DateTime(date.year, date.month, date.day, time.hour, time.minute); @@ -200,7 +199,7 @@ class RaplaParsingUtils { // selected year in the date selector var comboBoxes = document.getElementsByTagName("select"); - String year; + String? year; for (var box in comboBoxes) { if (box.attributes.containsKey("name") && box.attributes["name"] == "year") { diff --git a/lib/schedule/service/rapla/rapla_response_parser.dart b/lib/schedule/service/rapla/rapla_response_parser.dart index f0a7e353..cc37efff 100644 --- a/lib/schedule/service/rapla/rapla_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_response_parser.dart @@ -27,7 +27,7 @@ class RaplaResponseParser { } return ScheduleQueryResult(Schedule(), [ - ParseError("Did not find a week_table and month_table class", null), + ParseError("Did not find a week_table and month_table class"), ]); } } diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index fac25cf4..02082dbe 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -11,7 +11,7 @@ import 'package:http_client_helper/http_client_helper.dart' as http; class RaplaScheduleSource extends ScheduleSource { final RaplaResponseParser responseParser = RaplaResponseParser(); - String raplaUrl; + String? raplaUrl; RaplaScheduleSource({this.raplaUrl}); @@ -20,9 +20,9 @@ class RaplaScheduleSource extends ScheduleSource { } @override - Future querySchedule(DateTime from, DateTime to, - [CancellationToken cancellationToken]) async { - DateTime current = toDayOfWeek(from, DateTime.monday); + Future querySchedule(DateTime? from, DateTime? to, + [CancellationToken? cancellationToken]) async { + DateTime current = toDayOfWeek(from, DateTime.monday)!; if (cancellationToken == null) cancellationToken = CancellationToken(); @@ -31,16 +31,18 @@ class RaplaScheduleSource extends ScheduleSource { var didChangeMonth = false; - while ((to.isAfter(current) && !cancellationToken.isCancelled()) || + while ((to!.isAfter(current) && !cancellationToken.isCancelled()) || didChangeMonth) { try { var weekSchedule = await _fetchRaplaSource(current, cancellationToken); - if (weekSchedule.schedule != null) { - schedule.merge(weekSchedule.schedule); + if (weekSchedule?.schedule != null) { + schedule.merge(weekSchedule!.schedule); } - allErrors.addAll(weekSchedule.errors ?? []); + if (weekSchedule != null) { + allErrors.addAll(weekSchedule.errors); + } } on OperationCancelledException { rethrow; } on ParseException catch (ex, trace) { @@ -50,7 +52,7 @@ class RaplaScheduleSource extends ScheduleSource { } var currentMonth = current.month; - current = toNextWeek(current); + current = toNextWeek(current)!; var nextMonth = current.month; // Some rapla instances only return the dates in the current month. @@ -67,7 +69,7 @@ class RaplaScheduleSource extends ScheduleSource { return ScheduleQueryResult(schedule, allErrors); } - Future _fetchRaplaSource( + Future _fetchRaplaSource( DateTime date, CancellationToken cancellationToken, ) async { @@ -79,9 +81,7 @@ class RaplaScheduleSource extends ScheduleSource { try { var schedule = responseParser.parseSchedule(response.body); - if (schedule?.schedule?.urls != null) { - schedule.schedule.urls.add(requestUri.toString()); - } + schedule.schedule.urls.add(requestUri.toString()); return schedule; } on ParseException catch (_) { @@ -100,11 +100,11 @@ class RaplaScheduleSource extends ScheduleSource { /// - ?user=XXXXXXXXXX&file=XXXXX&page=XXXXXX /// Uri _buildRequestUri(DateTime date) { - if (!raplaUrl.startsWith("http://") && !raplaUrl.startsWith("https://")) { + if (!raplaUrl!.startsWith("http://") && !raplaUrl!.startsWith("https://")) { raplaUrl = "http://$raplaUrl"; } - var uri = Uri.parse(raplaUrl); + var uri = Uri.parse(raplaUrl!); bool hasKeyParameter = uri.queryParameters.containsKey("key"); bool hasUserParameter = uri.queryParameters.containsKey("user"); @@ -114,7 +114,7 @@ class RaplaScheduleSource extends ScheduleSource { bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); bool hasSalt = uri.queryParameters.containsKey("salt"); - Map parameters = {}; + Map parameters = {}; if (hasKeyParameter) { parameters["key"] = uri.queryParameters["key"]; @@ -133,14 +133,14 @@ class RaplaScheduleSource extends ScheduleSource { parameters["month"] = date.month.toString(); parameters["year"] = date.year.toString(); - if (raplaUrl.startsWith("https")) { + if (raplaUrl!.startsWith("https")) { return Uri.https(uri.authority, uri.path, parameters); } else { return Uri.http(uri.authority, uri.path, parameters); } } - Future _makeRequest( + Future _makeRequest( Uri uri, CancellationToken cancellationToken) async { var requestCancellationToken = http.CancellationToken(); @@ -169,7 +169,7 @@ class RaplaScheduleSource extends ScheduleSource { @override bool canQuery() { - return isValidUrl(raplaUrl); + return isValidUrl(raplaUrl!); } static bool isValidUrl(String url) { @@ -181,26 +181,24 @@ class RaplaScheduleSource extends ScheduleSource { return false; } - if (uri != null) { - bool hasKeyParameter = uri.queryParameters.containsKey("key"); - bool hasUserParameter = uri.queryParameters.containsKey("user"); - bool hasFileParameter = uri.queryParameters.containsKey("file"); - bool hasPageParameter = uri.queryParameters.containsKey("page"); + bool hasKeyParameter = uri.queryParameters.containsKey("key"); + bool hasUserParameter = uri.queryParameters.containsKey("user"); + bool hasFileParameter = uri.queryParameters.containsKey("file"); + bool hasPageParameter = uri.queryParameters.containsKey("page"); - bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); - bool hasSalt = uri.queryParameters.containsKey("salt"); + bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); + bool hasSalt = uri.queryParameters.containsKey("salt"); - if (hasUserParameter && hasFileParameter && hasPageParameter) { - return true; - } + if (hasUserParameter && hasFileParameter && hasPageParameter) { + return true; + } - if (hasSalt && hasAllocatableId && hasKeyParameter) { - return true; - } + if (hasSalt && hasAllocatableId && hasKeyParameter) { + return true; + } - if (hasKeyParameter) { - return true; - } + if (hasKeyParameter) { + return true; } return false; @@ -215,9 +213,9 @@ enum FailureReason { class ScheduleOrFailure { final FailureReason reason; - final Schedule schedule; - final Object exception; - final StackTrace trace; + final Schedule? schedule; + final Object? exception; + final StackTrace? trace; bool get success => reason == FailureReason.Success; diff --git a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart index dad3b018..96bab905 100644 --- a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart @@ -9,14 +9,11 @@ class RaplaSeveralMonthsResponseParser { Document document, List monthTables, ) { - var parseErrors = []; var allEntries = []; - for(var monthTable in monthTables) { - var result = RaplaMonthlyResponseParser.parseMonthlyTable( - monthTable - ); + for (var monthTable in monthTables) { + var result = RaplaMonthlyResponseParser.parseMonthlyTable(monthTable); parseErrors.addAll(result.errors); allEntries.addAll(result.schedule.entries); diff --git a/lib/schedule/service/rapla/rapla_week_response_parser.dart b/lib/schedule/service/rapla/rapla_week_response_parser.dart index 6d27a811..46fae222 100644 --- a/lib/schedule/service/rapla/rapla_week_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_week_response_parser.dart @@ -63,7 +63,7 @@ class RaplaWeekResponseParser { } allEntries.sort( - (ScheduleEntry e1, ScheduleEntry e2) => e1?.start?.compareTo(e2?.start), + (ScheduleEntry e1, ScheduleEntry e2) => e1.start.compareTo(e2.start), ); return ScheduleQueryResult( @@ -100,7 +100,7 @@ class RaplaWeekResponseParser { // selected year in the date selector var comboBoxes = document.getElementsByTagName("select"); - String year; + String? year; for (var box in comboBoxes) { if (box.attributes.containsKey("name") && box.attributes["name"] == "year") { diff --git a/lib/schedule/service/schedule_prettifier.dart b/lib/schedule/service/schedule_prettifier.dart index a5f9d00e..258bd9cf 100644 --- a/lib/schedule/service/schedule_prettifier.dart +++ b/lib/schedule/service/schedule_prettifier.dart @@ -2,8 +2,10 @@ import 'package:dhbwstudentapp/schedule/model/schedule.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class SchedulePrettifier { - final RegExp onlinePrefixRegExp = RegExp(r'\(?online\)?([ -]*)', caseSensitive: false); - final RegExp onlineSuffixRegExp = RegExp(r'([ -]*)\(?online\)?', caseSensitive: false); + final RegExp onlinePrefixRegExp = + RegExp(r'\(?online\)?([ -]*)', caseSensitive: false); + final RegExp onlineSuffixRegExp = + RegExp(r'([ -]*)\(?online\)?', caseSensitive: false); Schedule prettifySchedule(Schedule schedule) { var allEntries = []; @@ -41,20 +43,18 @@ class SchedulePrettifier { } ScheduleEntry _removeCourseFromTitle(ScheduleEntry entry) { - var title = entry.title ?? ""; - var details = entry.details ?? ""; + var title = entry.title; + var details = entry.details; var titleRegex = - RegExp("[A-Z]{3,}-?[A-Z]+[0-9]*[A-Z]*[0-9]*[\/]?[A-Z]*[0-9]*[ ]*-?"); + RegExp("[A-Z]{3,}-?[A-Z]+[0-9]*[A-Z]*[0-9]*[\/]?[A-Z]*[0-9]*[ ]*-?"); var match = titleRegex.firstMatch(entry.title); if (match != null && match.start == 0) { details = title.substring(0, match.end) + " - $details"; title = title.substring(match.end).trim(); } else { - var first = title - .split(" ") - .first; + var first = title.split(" ").first; // Prettify titles: T3MB9025 Fluidmechanik -> Fluidmechanik @@ -62,9 +62,7 @@ class SchedulePrettifier { // or less than 2 charcters long if (!(first == first.toUpperCase() && first.length >= 3)) return entry; - var numberCount = first - .split(new RegExp("[0-9]")) - .length; + var numberCount = first.split(new RegExp("[0-9]")).length; // If there are less thant two numbers in the title, do not prettify it if (numberCount < 2) return entry; diff --git a/lib/schedule/service/schedule_source.dart b/lib/schedule/service/schedule_source.dart index 87f08c7c..6bd044b3 100644 --- a/lib/schedule/service/schedule_source.dart +++ b/lib/schedule/service/schedule_source.dart @@ -9,21 +9,21 @@ abstract class ScheduleSource { /// Returns a future which gives the updated schedule or throws an exception /// if an error happened or the operation was cancelled /// - Future querySchedule(DateTime from, DateTime to, - [CancellationToken cancellationToken]); + Future querySchedule(DateTime? from, DateTime? to, + [CancellationToken? cancellationToken]); bool canQuery(); } class ScheduleQueryFailedException implements Exception { - final dynamic innerException; - final StackTrace trace; + final Object innerException; + final StackTrace? trace; ScheduleQueryFailedException(this.innerException, [this.trace]); @override String toString() { - return (innerException?.toString() ?? "") + "\n" + trace?.toString(); + return innerException.toString() + "\n" + (trace?.toString() ?? ""); } } diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index 8f4342e2..b0f19659 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/common/ui/text_styles.dart'; import 'package:dhbwstudentapp/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart'; import 'package:dhbwstudentapp/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart'; @@ -11,16 +10,17 @@ import 'package:property_change_notifier/property_change_notifier.dart'; import 'package:provider/provider.dart'; class DailySchedulePage extends StatefulWidget { + const DailySchedulePage({Key? key}) : super(key: key); @override _DailySchedulePageState createState() => _DailySchedulePageState(); } class _DailySchedulePageState extends State { - DailyScheduleViewModel viewModel; + late DailyScheduleViewModel viewModel; @override Widget build(BuildContext context) { - viewModel = Provider.of(context); + viewModel = Provider.of(context); return PropertyChangeProvider( value: viewModel, @@ -34,18 +34,18 @@ class _DailySchedulePageState extends State { Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), child: PropertyChangeConsumer( - builder: (BuildContext context, DailyScheduleViewModel model, - Set properties) { + builder: (BuildContext context, DailyScheduleViewModel? model, + Set? properties) { var dateFormat = DateFormat.yMMMMEEEEd( L.of(context).locale.languageCode); return Text( - dateFormat.format(model.currentDate), + dateFormat.format(model!.currentDate!), style: textStyleDailyScheduleCurrentDate(context), ); }, ), ), - (viewModel.daySchedule?.entries?.length ?? 0) == 0 + viewModel.daySchedule.entries.isEmpty ? Padding( padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: Column( @@ -93,7 +93,7 @@ class _DailySchedulePageState extends State { var now = DateTime.now(); var nowIndicatorInserted = false; - for (var entry in viewModel.daySchedule?.entries) { + for (var entry in viewModel.daySchedule.entries) { if (!nowIndicatorInserted && (entry.end.isAfter(now))) { entryWidgets.add(CurrentTimeIndicatorWidget()); nowIndicatorInserted = true; diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index 9c0fe1e1..474c02cd 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -9,13 +9,11 @@ import 'package:intl/intl.dart'; class DailyScheduleEntryWidget extends StatelessWidget { final ScheduleEntry scheduleEntry; - const DailyScheduleEntryWidget({Key key, this.scheduleEntry}) + const DailyScheduleEntryWidget({Key? key, required this.scheduleEntry}) : super(key: key); @override Widget build(BuildContext context) { - if (scheduleEntry == null) return Container(); - var timeFormatter = DateFormat.Hm(L.of(context).locale.languageCode); var startTime = timeFormatter.format(scheduleEntry.start); @@ -96,7 +94,7 @@ class DailyScheduleEntryWidget extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(32, 0, 0, 0), child: Text( - scheduleEntry.room ?? "", + scheduleEntry.room, softWrap: true, textAlign: TextAlign.end, ), diff --git a/lib/schedule/ui/notification/next_day_information_notification.dart b/lib/schedule/ui/notification/next_day_information_notification.dart index d70ad2ce..d477ae87 100644 --- a/lib/schedule/ui/notification/next_day_information_notification.dart +++ b/lib/schedule/ui/notification/next_day_information_notification.dart @@ -40,8 +40,8 @@ class NextDayInformationNotification extends TaskCallback { if (nextScheduleEntry == null) return; var format = DateFormat.Hm(); - var daysToNextEntry = toStartOfDay(nextScheduleEntry.start) - .difference(toStartOfDay(now)) + var daysToNextEntry = toStartOfDay(nextScheduleEntry.start)! + .difference(toStartOfDay(now)!) .inDays; if (daysToNextEntry > 1) return; @@ -58,27 +58,30 @@ class NextDayInformationNotification extends TaskCallback { ); } - String _getNotificationMessage( + String? _getNotificationMessage( int daysToNextEntry, ScheduleEntry nextScheduleEntry, DateFormat format) { - String message; - if (daysToNextEntry == 0) { - message = interpolate( - _localization.notificationNextClassNextClassAtMessage, - [ - nextScheduleEntry.title, - format.format(nextScheduleEntry.start), - ], - ); - } else if (daysToNextEntry == 1) { - message = interpolate( - _localization.notificationNextClassTomorrow, - [ - nextScheduleEntry.title, - format.format(nextScheduleEntry.start), - ], - ); + switch (daysToNextEntry) { + case 0: + return interpolate( + _localization.notificationNextClassNextClassAtMessage, + [ + nextScheduleEntry.title, + format.format(nextScheduleEntry.start), + ], + ); + + case 1: + return interpolate( + _localization.notificationNextClassTomorrow, + [ + nextScheduleEntry.title, + format.format(nextScheduleEntry.start), + ], + ); + + default: + return null; } - return message; } @override diff --git a/lib/schedule/ui/schedule_navigation_entry.dart b/lib/schedule/ui/schedule_navigation_entry.dart index 096dc47f..bfb542a7 100644 --- a/lib/schedule/ui/schedule_navigation_entry.dart +++ b/lib/schedule/ui/schedule_navigation_entry.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/schedule/ui/schedule_page.dart'; import 'package:dhbwstudentapp/schedule/ui/viewmodels/schedule_view_model.dart'; import 'package:dhbwstudentapp/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart'; @@ -9,23 +8,15 @@ import 'package:flutter/material.dart'; import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; -class ScheduleNavigationEntry extends NavigationEntry { - ScheduleViewModel _viewModel; - +class ScheduleNavigationEntry extends NavigationEntry { @override - Widget icon(BuildContext context) { - return Icon(Icons.calendar_today); - } + Icon icon = Icon(Icons.calendar_today); @override - BaseViewModel initViewModel() { - if (_viewModel != null) return _viewModel; - - _viewModel = ScheduleViewModel( + ScheduleViewModel initViewModel() { + return ScheduleViewModel( KiwiContainer().resolve(), ); - - return _viewModel; } @override @@ -40,29 +31,29 @@ class ScheduleNavigationEntry extends NavigationEntry { @override List appBarActions(BuildContext context) { - initViewModel(); return [ PropertyChangeProvider( - value: _viewModel, + value: model, child: PropertyChangeConsumer( properties: const ["didSetupProperly"], - builder: (BuildContext _, ScheduleViewModel __, Set ___) => - _viewModel.didSetupProperly - ? Container() - : IconButton( - icon: Icon(Icons.help_outline), - onPressed: () async { - await ScheduleHelpDialog().show(context); - }, - tooltip: L.of(context).helpButtonTooltip, - )), + builder: + (BuildContext _, ScheduleViewModel? __, Set? ___) => + model.didSetupProperly + ? Container() + : IconButton( + icon: Icon(Icons.help_outline), + onPressed: () async { + await ScheduleHelpDialog().show(context); + }, + tooltip: L.of(context).helpButtonTooltip, + )), ), PropertyChangeProvider( - value: _viewModel, + value: model, child: PropertyChangeConsumer( properties: const ["didSetupProperly"], - builder: (BuildContext _, ScheduleViewModel __, Set ___) => - _viewModel.didSetupProperly + builder: (BuildContext _, ScheduleViewModel? __, Set? ___) => + model.didSetupProperly ? IconButton( icon: Icon(Icons.filter_alt), onPressed: () async { diff --git a/lib/schedule/ui/schedule_page.dart b/lib/schedule/ui/schedule_page.dart index 3da65712..531a0687 100644 --- a/lib/schedule/ui/schedule_page.dart +++ b/lib/schedule/ui/schedule_page.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/schedule/ui/dailyschedule/daily_schedule_page.dart'; import 'package:dhbwstudentapp/schedule/ui/viewmodels/daily_schedule_view_model.dart'; import 'package:dhbwstudentapp/schedule/ui/viewmodels/schedule_view_model.dart'; @@ -12,6 +11,7 @@ import 'package:kiwi/kiwi.dart'; import 'package:provider/provider.dart'; class SchedulePage extends StatefulWidget { + const SchedulePage({Key? key}) : super(key: key); @override _SchedulePageState createState() => _SchedulePageState(); } @@ -29,20 +29,20 @@ class _SchedulePageState extends State { @override Widget build(BuildContext context) { - ScheduleViewModel viewModel = Provider.of(context); + ScheduleViewModel viewModel = Provider.of(context); if (!viewModel.didSetupProperly) { return ScheduleEmptyState(); } else { return PagerWidget( - pages: [ - PageDefinition( + pages: [ + PageDefinition( icon: Icon(Icons.view_week), text: L.of(context).pageWeekOverviewTitle, builder: (_) => WeeklySchedulePage(), viewModel: weeklyScheduleViewModel, ), - PageDefinition( + PageDefinition( icon: Icon(Icons.view_day), text: L.of(context).pageDayOverviewTitle, builder: (_) => DailySchedulePage(), diff --git a/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart b/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart index 793b76ab..0183aa0d 100644 --- a/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart @@ -8,9 +8,9 @@ class DailyScheduleViewModel extends BaseViewModel { final ScheduleProvider scheduleProvider; - DateTime currentDate; + DateTime? currentDate; - Schedule daySchedule; + Schedule? _daySchedule; DailyScheduleViewModel(this.scheduleProvider) { scheduleProvider.addScheduleUpdatedCallback(_scheduleUpdatedCallback); @@ -18,11 +18,13 @@ class DailyScheduleViewModel extends BaseViewModel { loadScheduleForToday(); } - Future setSchedule(Schedule schedule) async { - daySchedule = schedule; + set schedule(Schedule schedule) { + _daySchedule = schedule; notifyListeners("daySchedule"); } + Schedule get daySchedule => _daySchedule ??= Schedule(); + Future loadScheduleForToday() async { var now = DateTime.now(); currentDate = toStartOfDay(now); @@ -35,30 +37,24 @@ class DailyScheduleViewModel extends BaseViewModel { } Future _updateScheduleFromCache() async { - setSchedule( - await scheduleProvider.getCachedSchedule( - currentDate, - tomorrow(currentDate), - ), + schedule = await scheduleProvider.getCachedSchedule( + currentDate!, + tomorrow(currentDate)!, ); } Future _scheduleUpdatedCallback( Schedule schedule, - DateTime start, - DateTime end, + DateTime? start, + DateTime? end, ) async { - if (schedule == null) return; - start = toStartOfDay(start); end = toStartOfDay(tomorrow(end)); - if (!(start.isAfter(currentDate) || end.isBefore(currentDate))) { - setSchedule( - schedule.trim( - toStartOfDay(currentDate), - toStartOfDay(tomorrow(currentDate)), - ), + if (!(start!.isAfter(currentDate!) || end!.isBefore(currentDate!))) { + schedule = schedule.trim( + toStartOfDay(currentDate), + toStartOfDay(tomorrow(currentDate)), ); } } diff --git a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart index af98bb16..076eef85 100644 --- a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart @@ -18,11 +18,11 @@ class WeeklyScheduleViewModel extends BaseViewModel { final ScheduleProvider scheduleProvider; final ScheduleSourceProvider scheduleSourceProvider; - DateTime currentDateStart; - DateTime currentDateEnd; + DateTime? currentDateStart; + DateTime? currentDateEnd; - DateTime clippedDateStart; - DateTime clippedDateEnd; + DateTime? clippedDateStart; + DateTime? clippedDateEnd; bool didUpdateScheduleIntoFuture = true; @@ -33,24 +33,24 @@ class WeeklyScheduleViewModel extends BaseViewModel { bool get hasQueryErrors => _hasQueryErrors; - VoidCallback _queryFailedCallback; + VoidCallback? _queryFailedCallback; bool updateFailed = false; bool isUpdating = false; - Schedule weekSchedule; + Schedule? weekSchedule; - String scheduleUrl; + String? scheduleUrl; DateTime get now => DateTime.now(); - Timer _errorResetTimer; - Timer _updateNowTimer; + Timer? _errorResetTimer; + Timer? _updateNowTimer; final CancelableMutex _updateMutex = CancelableMutex(); - DateTime lastRequestedStart; - DateTime lastRequestedEnd; + DateTime? lastRequestedStart; + DateTime? lastRequestedEnd; WeeklyScheduleViewModel( this.scheduleProvider, @@ -62,7 +62,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { Future _initViewModel() async { _setSchedule( null, - toDayOfWeek(DateTime.now(), DateTime.monday), + toDayOfWeek(DateTime.now(), DateTime.monday)!, toDayOfWeek(DateTime.now(), DateTime.friday), ); @@ -80,15 +80,15 @@ class WeeklyScheduleViewModel extends BaseViewModel { if (setupSuccess) await updateSchedule(currentDateStart, currentDateEnd); } - void _setSchedule(Schedule schedule, DateTime start, DateTime end) { + void _setSchedule(Schedule? schedule, DateTime start, DateTime? end) { weekSchedule = schedule; didUpdateScheduleIntoFuture = currentDateStart?.isBefore(start) ?? true; currentDateStart = start; currentDateEnd = end; if (weekSchedule != null) { - var scheduleStart = weekSchedule.getStartDate(); - var scheduleEnd = weekSchedule.getEndDate(); + var scheduleStart = weekSchedule!.getStartDate(); + var scheduleEnd = weekSchedule!.getEndDate(); if (scheduleStart == null && scheduleEnd == null) { clippedDateStart = toDayOfWeek(start, DateTime.monday); @@ -98,7 +98,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { clippedDateEnd = toDayOfWeek(scheduleEnd, DateTime.friday); } - if (scheduleEnd?.isAfter(clippedDateEnd) ?? false) + if (scheduleEnd?.isAfter(clippedDateEnd!) ?? false) clippedDateEnd = scheduleEnd; displayStartHour = weekSchedule?.getStartTime()?.hour ?? 23; @@ -136,7 +136,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { await updateSchedule(currentDateStart, currentDateEnd); } - Future updateSchedule(DateTime start, DateTime end) async { + Future updateSchedule(DateTime? start, DateTime? end) async { lastRequestedEnd = end; lastRequestedStart = start; @@ -151,8 +151,9 @@ class WeeklyScheduleViewModel extends BaseViewModel { isUpdating = true; notifyListeners("isUpdating"); - await _doUpdateSchedule(start, end); - } catch (_) {} finally { + await _doUpdateSchedule(start!, end!); + } catch (_) { + } finally { isUpdating = false; _updateMutex.release(); notifyListeners("isUpdating"); @@ -162,7 +163,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { Future _doUpdateSchedule(DateTime start, DateTime end) async { print("Refreshing schedule..."); - var cancellationToken = _updateMutex.token; + var cancellationToken = _updateMutex.token!; scheduleUrl = null; @@ -178,7 +179,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { cancellationToken.throwIfCancelled(); if (updatedSchedule?.schedule != null) { - var schedule = updatedSchedule.schedule; + var schedule = updatedSchedule!.schedule; _setSchedule(schedule, start, end); @@ -202,7 +203,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { print("Refreshing done"); } - Future _readScheduleFromService( + Future _readScheduleFromService( DateTime start, DateTime end, CancellationToken token, @@ -213,14 +214,15 @@ class WeeklyScheduleViewModel extends BaseViewModel { end, token, ); - } on OperationCancelledException {} on ScheduleQueryFailedException {} + } on OperationCancelledException { + } on ScheduleQueryFailedException {} return null; } void _cancelErrorInFuture() { if (_errorResetTimer != null) { - _errorResetTimer.cancel(); + _errorResetTimer!.cancel(); } _errorResetTimer = Timer( @@ -233,7 +235,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { } void ensureUpdateNowTimerRunning() { - if (_updateNowTimer == null || !_updateNowTimer.isActive) { + if (_updateNowTimer == null || !_updateNowTimer!.isActive) { _updateNowTimer = Timer.periodic(const Duration(minutes: 1), (_) { notifyListeners("now"); }); diff --git a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart index d2555c59..29fa0433 100644 --- a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart +++ b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart @@ -21,7 +21,7 @@ class FilterViewModel extends BaseViewModel { var filteredNames = await _scheduleFilterRepository.queryAllHiddenNames(); - allNames.sort((s1, s2) => s1.compareTo(s2)); + allNames.sort((s1, s2) => s1!.compareTo(s2!)); filterStates = allNames.map((e) { var isFiltered = filteredNames.contains(e); @@ -33,7 +33,7 @@ class FilterViewModel extends BaseViewModel { void applyFilter() async { var allFilteredNames = filterStates - .where((element) => !element.isDisplayed) + .where((element) => !element.isDisplayed!) .map((e) => e.entryName) .toList(); @@ -44,8 +44,8 @@ class FilterViewModel extends BaseViewModel { } class ScheduleEntryFilterState { - bool isDisplayed; - String entryName; + bool? isDisplayed; + String? entryName; ScheduleEntryFilterState(this.isDisplayed, this.entryName); } diff --git a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart index 735392eb..3d5229b6 100644 --- a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart +++ b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart @@ -46,11 +46,11 @@ class ScheduleFilterPage extends StatelessWidget { child: PropertyChangeProvider( value: _viewModel, child: PropertyChangeConsumer( - builder: (BuildContext _, FilterViewModel viewModel, - Set ___) => + builder: (BuildContext _, FilterViewModel? viewModel, + Set? ___) => ListView.builder( shrinkWrap: true, - itemCount: viewModel.filterStates.length, + itemCount: viewModel!.filterStates.length, itemBuilder: (context, index) => FilterStateRow(viewModel.filterStates[index]), )), @@ -74,7 +74,7 @@ class FilterStateRow extends StatefulWidget { } class _FilterStateRowState extends State { - bool isChecked = false; + bool? isChecked = false; @override void initState() { @@ -94,7 +94,7 @@ class _FilterStateRowState extends State { }); }, controlAffinity: ListTileControlAffinity.leading, - title: Text(widget.filterState.entryName), + title: Text(widget.filterState.entryName!), ); } } diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index a5ad1ea1..377906fd 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -8,19 +8,19 @@ import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; class ScheduleEntryDetailBottomSheet extends StatelessWidget { - final ScheduleEntry scheduleEntry; + final ScheduleEntry? scheduleEntry; - const ScheduleEntryDetailBottomSheet({Key key, this.scheduleEntry}) + const ScheduleEntryDetailBottomSheet({Key? key, this.scheduleEntry}) : super(key: key); @override Widget build(BuildContext context) { var formatter = DateFormat.Hm(L.of(context).locale.languageCode); - var timeStart = formatter.format(scheduleEntry.start); - var timeEnd = formatter.format(scheduleEntry.end); + var timeStart = formatter.format(scheduleEntry!.start); + var timeEnd = formatter.format(scheduleEntry!.end); var typeString = - scheduleEntryTypeToReadableString(context, scheduleEntry.type); + scheduleEntryTypeToReadableString(context, scheduleEntry!.type); return Container( height: 400, @@ -90,7 +90,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(16, 0, 0, 0), child: Text( - scheduleEntry.title ?? "", + scheduleEntry!.title, softWrap: true, style: textStyleScheduleEntryBottomPageTitle(context), ), @@ -106,7 +106,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { children: [ Expanded( child: Text( - scheduleEntry.professor ?? "", + scheduleEntry!.professor, ), ), Text( @@ -116,13 +116,13 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { ], ), ), - scheduleEntry.room?.isEmpty ?? true + scheduleEntry!.room.isEmpty ? Container() : Padding( padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), - child: Text(scheduleEntry.room.replaceAll(",", "\n")), + child: Text(scheduleEntry!.room.replaceAll(",", "\n")), ), - scheduleEntry.details?.isEmpty ?? true + scheduleEntry!.details.isEmpty ? Container() : Padding( padding: const EdgeInsets.fromLTRB(0, 16, 0, 16), @@ -131,9 +131,9 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { height: 1, ), ), - scheduleEntry.details?.isEmpty ?? true + scheduleEntry!.details.isEmpty ? Container() - : Text(scheduleEntry.details), + : Text(scheduleEntry!.details), ], ), ), diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index 1e3a81ef..4e7f77e5 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -13,13 +13,15 @@ import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; class WeeklySchedulePage extends StatefulWidget { + const WeeklySchedulePage({Key? key}) : super(key: key); + @override _WeeklySchedulePageState createState() => _WeeklySchedulePageState(); } class _WeeklySchedulePageState extends State { - WeeklyScheduleViewModel viewModel; - Schedule schedule; + late WeeklyScheduleViewModel viewModel; + Schedule? schedule; _WeeklySchedulePageState(); @@ -40,7 +42,7 @@ class _WeeklySchedulePageState extends State { child: Text( L.of(context).scheduleQueryFailedOpenInBrowser.toUpperCase()), onPressed: () { - launchUrl(Uri.parse(viewModel.scheduleUrl)); + launchUrl(Uri.parse(viewModel.scheduleUrl!)); }, ) ], @@ -51,15 +53,15 @@ class _WeeklySchedulePageState extends State { } void _previousWeek() async { - await viewModel?.previousWeek(); + await viewModel.previousWeek(); } void _nextWeek() async { - await viewModel?.nextWeek(); + await viewModel.nextWeek(); } void _goToToday() async { - await viewModel?.goToToday(); + await viewModel.goToToday(); } void _onScheduleEntryTap(BuildContext context, ScheduleEntry entry) { @@ -77,7 +79,7 @@ class _WeeklySchedulePageState extends State { @override Widget build(BuildContext context) { - viewModel = Provider.of(context); + viewModel = Provider.of(context); viewModel.ensureUpdateNowTimerRunning(); viewModel.setQueryFailedCallback(_showQueryFailedSnackBar); @@ -109,9 +111,9 @@ class _WeeklySchedulePageState extends State { child: PropertyChangeConsumer( properties: const ["weekSchedule", "now"], builder: (BuildContext context, - WeeklyScheduleViewModel model, Set properties) { + WeeklyScheduleViewModel? model, Set? _) { return PageTransitionSwitcher( - reverse: !model.didUpdateScheduleIntoFuture, + reverse: !model!.didUpdateScheduleIntoFuture, duration: const Duration(milliseconds: 300), transitionBuilder: (Widget child, Animation animation, @@ -125,7 +127,7 @@ class _WeeklySchedulePageState extends State { ), child: ScheduleWidget( key: ValueKey( - model.currentDateStart.toIso8601String(), + model.currentDateStart!.toIso8601String(), ), schedule: model.weekSchedule, displayStart: model.clippedDateStart ?? @@ -146,8 +148,8 @@ class _WeeklySchedulePageState extends State { PropertyChangeConsumer( properties: const ["isUpdating"], builder: (BuildContext context, - WeeklyScheduleViewModel model, Set properties) { - return model.isUpdating + WeeklyScheduleViewModel? model, Set? _) { + return model!.isUpdating ? const LinearProgressIndicator() : Container(); }, @@ -189,10 +191,9 @@ class _WeeklySchedulePageState extends State { properties: const [ "updateFailed", ], - builder: (BuildContext context, WeeklyScheduleViewModel model, - Set properties) => + builder: (BuildContext context, WeeklyScheduleViewModel? model, Set? _) => ErrorDisplay( - show: model.updateFailed, + show: model!.updateFailed, ), ); } diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart index f1748038..4a753c55 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart @@ -3,8 +3,8 @@ import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class ScheduleEntryAlignmentInformation { final ScheduleEntry entry; - double leftColumn; - double rightColumn; + late double leftColumn; + late double rightColumn; ScheduleEntryAlignmentInformation(this.entry); } @@ -34,7 +34,7 @@ class ScheduleEntryAlignmentAlgorithm { List> columns = [[]]; - DateTime lastEventEnd; + DateTime? lastEventEnd; for (var event in events) { if (!event.entry.start diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart index 8511ad5c..db798f14 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart @@ -7,11 +7,11 @@ typedef ScheduleEntryTapCallback = Function(ScheduleEntry entry); class ScheduleEntryWidget extends StatelessWidget { final ScheduleEntry scheduleEntry; - final ScheduleEntryTapCallback onScheduleEntryTap; + final ScheduleEntryTapCallback? onScheduleEntryTap; const ScheduleEntryWidget({ - Key key, - this.scheduleEntry, + Key? key, + required this.scheduleEntry, this.onScheduleEntryTap, }) : super(key: key); @@ -25,7 +25,7 @@ class ScheduleEntryWidget extends StatelessWidget { margin: const EdgeInsets.fromLTRB(1, 0, 1, 0), child: InkWell( onTap: () { - if (onScheduleEntryTap != null) onScheduleEntryTap(scheduleEntry); + if (onScheduleEntryTap != null) onScheduleEntryTap!(scheduleEntry); }, child: Padding( padding: const EdgeInsets.fromLTRB(4, 4, 4, 4), diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart index c306466c..361e9249 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; class ScheduleGrid extends CustomPaint { - final int fromHour; - final int toHour; + final int? fromHour; + final int? toHour; final double timeLabelsWidth; final double dateLabelsHeight; final int columns; @@ -23,8 +23,8 @@ class ScheduleGrid extends CustomPaint { } class ScheduleGridCustomPaint extends CustomPainter { - final int fromHour; - final int toHour; + final int? fromHour; + final int? toHour; final double timeLabelsWidth; final double dateLabelsHeight; final int columns; @@ -45,7 +45,7 @@ class ScheduleGridCustomPaint extends CustomPainter { ..color = gridLineColor ..strokeWidth = 1; - var lines = toHour - fromHour; + var lines = toHour! - fromHour!; drawHorizontalLines(lines, size, canvas, secondaryPaint); drawVerticalLines(size, canvas, secondaryPaint); diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart index 94234607..ae98def9 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart @@ -5,11 +5,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; class SchedulePastOverlay extends CustomPaint { - final DateTime fromDate; - final DateTime toDate; - final DateTime now; - final int fromHour; - final int toHour; + final DateTime? fromDate; + final DateTime? toDate; + final DateTime? now; + final int? fromHour; + final int? toHour; final int columns; final Color overlayColor; @@ -35,11 +35,11 @@ class SchedulePastOverlay extends CustomPaint { } class SchedulePastOverlayCustomPaint extends CustomPainter { - final DateTime fromDate; - final DateTime toDate; - final DateTime now; - final int fromHour; - final int toHour; + final DateTime? fromDate; + final DateTime? toDate; + final DateTime? now; + final int? fromHour; + final int? toHour; final int columns; final Color overlayColor; @@ -59,9 +59,9 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { ..color = overlayColor ..strokeWidth = 1; - if (now.isBefore(toDate) && now.isAfter(fromDate)) { + if (now!.isBefore(toDate!) && now!.isAfter(fromDate!)) { drawPartialPastOverlay(canvas, size, overlayPaint); - } else if (now.isAfter(toDate)) { + } else if (now!.isAfter(toDate!)) { drawCompletePastOverlay(canvas, size, overlayPaint); } } @@ -78,7 +78,7 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { } void drawPartialPastOverlay(Canvas canvas, Size size, Paint overlayPaint) { - var difference = now.difference(fromDate); + var difference = now!.difference(fromDate!); var differenceInDays = (difference.inHours / 24).floor(); var dayWidth = size.width / columns; @@ -93,9 +93,9 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { ); var leftoverMinutes = - difference.inMinutes - (differenceInDays * 24 * 60) - (60 * fromHour); + difference.inMinutes - (differenceInDays * 24 * 60) - (60 * fromHour!); - var displayedMinutes = (toHour - fromHour) * 60; + var displayedMinutes = (toHour! - fromHour!) * 60; var leftoverHeight = leftoverMinutes * (size.height / displayedMinutes); if (leftoverHeight > 0) { diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 59fcaeef..748b3290 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -13,16 +13,16 @@ import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; class ScheduleWidget extends StatelessWidget { - final Schedule schedule; - final DateTime displayStart; - final DateTime displayEnd; - final DateTime now; - final int displayStartHour; - final int displayEndHour; - final ScheduleEntryTapCallback onScheduleEntryTap; + final Schedule? schedule; + final DateTime? displayStart; + final DateTime? displayEnd; + final DateTime? now; + final int? displayStartHour; + final int? displayEndHour; + final ScheduleEntryTapCallback? onScheduleEntryTap; const ScheduleWidget({ - Key key, + Key? key, this.schedule, this.displayStart, this.displayEnd, @@ -48,7 +48,7 @@ class ScheduleWidget extends StatelessWidget { var timeLabelsWidth = 50.0; var hourHeight = - (height - dayLabelsHeight) / (displayEndHour - displayStartHour); + (height - dayLabelsHeight) / (displayEndHour! - displayStartHour!); var minuteHeight = hourHeight / 60; var days = calculateDisplayedDays(); @@ -112,7 +112,7 @@ class ScheduleWidget extends StatelessWidget { int calculateDisplayedDays() { var startEndDifference = - toStartOfDay(displayEnd)?.difference(toStartOfDay(displayStart)); + toStartOfDay(displayEnd)?.difference(toStartOfDay(displayStart)!); var days = (startEndDifference?.inDays ?? 0) + 1; @@ -135,12 +135,12 @@ class ScheduleWidget extends StatelessWidget { ) { var labelWidgets = []; - for (var i = displayStartHour; i < displayEndHour; i++) { + for (var i = displayStartHour!; i < displayEndHour!; i++) { var hourLabelText = i.toString() + ":00"; labelWidgets.add( Positioned( - top: rowHeight * (i - displayStartHour) + dayLabelHeight, + top: rowHeight * (i - displayStartHour!) + dayLabelHeight, left: 0, child: Padding( padding: const EdgeInsets.fromLTRB(4, 4, 4, 8), @@ -155,11 +155,11 @@ class ScheduleWidget extends StatelessWidget { var dayFormatter = DateFormat("E", L.of(context).locale.languageCode); var dateFormatter = DateFormat("d. MMM", L.of(context).locale.languageCode); - var loopEnd = toStartOfDay(tomorrow(displayEnd)); + var loopEnd = toStartOfDay(tomorrow(displayEnd))!; - for (var columnDate = toStartOfDay(displayStart); + for (var columnDate = toStartOfDay(displayStart)!; columnDate.isBefore(loopEnd); - columnDate = tomorrow(columnDate)) { + columnDate = tomorrow(columnDate)!) { labelWidgets.add( Positioned( top: 0, @@ -192,20 +192,20 @@ class ScheduleWidget extends StatelessWidget { List buildEntryWidgets( double hourHeight, double minuteHeight, double width, int columns) { if (schedule == null) return []; - if (schedule.entries.isEmpty) return []; + if (schedule!.entries.isEmpty) return []; var entryWidgets = []; var columnWidth = width / columns; - DateTime columnStartDate = toStartOfDay(displayStart); - DateTime columnEndDate = tomorrow(columnStartDate); + DateTime? columnStartDate = toStartOfDay(displayStart); + DateTime? columnEndDate = tomorrow(columnStartDate); for (int i = 0; i < columns; i++) { var xPosition = columnWidth * i; var maxWidth = columnWidth; - var columnSchedule = schedule.trim(columnStartDate, columnEndDate); + var columnSchedule = schedule!.trim(columnStartDate, columnEndDate); entryWidgets.addAll(buildEntryWidgetsForColumn( maxWidth, @@ -237,10 +237,10 @@ class ScheduleWidget extends StatelessWidget { for (var value in laidOutEntries) { var entry = value.entry; - var yStart = hourHeight * (entry.start.hour - displayStartHour) + + var yStart = hourHeight * (entry.start.hour - displayStartHour!) + minuteHeight * entry.start.minute; - var yEnd = hourHeight * (entry.end.hour - displayStartHour) + + var yEnd = hourHeight * (entry.end.hour - displayStartHour!) + minuteHeight * entry.end.minute; var entryLeft = maxWidth * value.leftColumn; diff --git a/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart b/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart index cca38e58..eec5214e 100644 --- a/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart +++ b/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart @@ -9,13 +9,9 @@ class EnterDualisCredentialsDialog { final PreferencesProvider _preferencesProvider; final ScheduleSourceProvider _scheduleSourceProvider; - final TextEditingController _usernameEditingController = - TextEditingController(); - final TextEditingController _passwordEditingController = - TextEditingController(); + final _controller = CredentialsEditingController(); - String username; - String password; + Credentials? _credentials; EnterDualisCredentialsDialog( this._preferencesProvider, @@ -23,9 +19,7 @@ class EnterDualisCredentialsDialog { ); Future show(BuildContext context) async { - var credentials = await _preferencesProvider.loadDualisCredentials(); - username = credentials.username; - password = credentials.password; + _credentials = await _preferencesProvider.loadDualisCredentials(); await showDialog( context: context, @@ -34,11 +28,9 @@ class EnterDualisCredentialsDialog { } AlertDialog _buildDialog(BuildContext context) { - if (_usernameEditingController.text != username) { - _usernameEditingController.text = username; - } - if (_passwordEditingController.text != password) { - _passwordEditingController.text = password; + final credentials = _credentials; + if (credentials != null) { + _controller.credentials = credentials; } return AlertDialog( @@ -55,8 +47,7 @@ class EnterDualisCredentialsDialog { ), ), LoginCredentialsWidget( - usernameEditingController: _usernameEditingController, - passwordEditingController: _passwordEditingController, + controller: _controller, onSubmitted: () async {}, ), ], @@ -70,11 +61,9 @@ class EnterDualisCredentialsDialog { TextButton( child: Text(L.of(context).dialogOk.toUpperCase()), onPressed: () async { + // TODO: [Leptopoda] validate credentials like [DualisLoginViewModel] await _preferencesProvider.storeDualisCredentials( - Credentials( - _usernameEditingController.text, - _passwordEditingController.text, - ), + _controller.credentials, ); await _scheduleSourceProvider.setupForDualis(); diff --git a/lib/schedule/ui/widgets/enter_ical_url.dart b/lib/schedule/ui/widgets/enter_ical_url.dart index 25cc1d17..b563d723 100644 --- a/lib/schedule/ui/widgets/enter_ical_url.dart +++ b/lib/schedule/ui/widgets/enter_ical_url.dart @@ -12,18 +12,18 @@ class EnterIcalDialog extends EnterUrlDialog { EnterIcalDialog(this._preferencesProvider, this._scheduleSource); @override - Future loadUrl() { + Future loadUrl() { return _preferencesProvider.getIcalUrl(); } @override - Future saveUrl(String url) async { + Future saveUrl(String? url) async { await _scheduleSource.setupForIcal(url); } @override - bool isValidUrl(String url) { - return IcalScheduleSource.isValidUrl(url); + bool isValidUrl(String? url) { + return IcalScheduleSource.isValidUrl(url!); } @override diff --git a/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart b/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart index 0bc5167b..c2ed49b2 100644 --- a/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart @@ -15,7 +15,7 @@ class EnterRaplaUrlDialog extends EnterUrlDialog { EnterRaplaUrlDialog(this._preferencesProvider, this._scheduleSource); @override - Future saveUrl(String url) async { + Future saveUrl(String? url) async { await _scheduleSource.setupForRapla(url); } @@ -25,8 +25,8 @@ class EnterRaplaUrlDialog extends EnterUrlDialog { } @override - bool isValidUrl(String url) { - return RaplaScheduleSource.isValidUrl(url); + bool isValidUrl(String? url) { + return RaplaScheduleSource.isValidUrl(url!); } @override diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index 58a65dc4..fc09625a 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -49,7 +49,7 @@ abstract class EnterUrlDialog { builder: ( BuildContext context, ValueNotifier url, - Widget child, + Widget? child, ) { if (_urlTextController.text != url.value) _urlTextController.text = url.value; @@ -58,7 +58,7 @@ abstract class EnterUrlDialog { builder: ( BuildContext context, ValueNotifier hasUrlError, - Widget child, + Widget? child, ) => TextField( controller: _urlTextController, @@ -103,7 +103,7 @@ abstract class EnterUrlDialog { value: _hasUrlError, child: Consumer( builder: (BuildContext context, ValueNotifier hasUrlError, - Widget child) => + Widget? child) => TextButton( child: Text(L.of(context).dialogOk.toUpperCase()), onPressed: hasUrlError.value @@ -120,15 +120,15 @@ abstract class EnterUrlDialog { } Future _pasteUrl() async { - ClipboardData data = await Clipboard.getData('text/plain'); + ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text != null) { - _setUrl(data.text); + _setUrl(data!.text!); } } Future _loadUrl() async { - _url.value = await loadUrl(); + _url.value = await loadUrl() ?? ""; } void _setUrl(String url) { @@ -140,9 +140,9 @@ abstract class EnterUrlDialog { _hasUrlError.value = !isValidUrl(_url.value); } - bool isValidUrl(String url); - Future saveUrl(String url); - Future loadUrl(); + bool isValidUrl(String? url); + Future saveUrl(String? url); + Future loadUrl(); String title(BuildContext context); String message(BuildContext context); diff --git a/lib/schedule/ui/widgets/schedule_empty_state.dart b/lib/schedule/ui/widgets/schedule_empty_state.dart index c52a1e59..37c846cc 100644 --- a/lib/schedule/ui/widgets/schedule_empty_state.dart +++ b/lib/schedule/ui/widgets/schedule_empty_state.dart @@ -32,7 +32,7 @@ class ScheduleEmptyState extends StatelessWidget { child: ClipRRect( child: Padding( padding: const EdgeInsets.all(32), - child: Image.asset(image[Theme.of(context).brightness]), + child: Image.asset(image[Theme.of(context).brightness]!), ), ), ) diff --git a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart index 70943bb4..e828b847 100644 --- a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart +++ b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart @@ -9,7 +9,7 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class SelectMannheimCourseDialog { final ScheduleSourceProvider _scheduleSourceProvider; - MannheimViewModel _mannheimViewModel; + late MannheimViewModel _mannheimViewModel; SelectMannheimCourseDialog( this._scheduleSourceProvider, diff --git a/lib/schedule/ui/widgets/select_source_dialog.dart b/lib/schedule/ui/widgets/select_source_dialog.dart index 83d03fd7..5ec9f9cd 100644 --- a/lib/schedule/ui/widgets/select_source_dialog.dart +++ b/lib/schedule/ui/widgets/select_source_dialog.dart @@ -13,7 +13,7 @@ class SelectSourceDialog { final PreferencesProvider _preferencesProvider; final ScheduleSourceProvider _scheduleSourceProvider; - ScheduleSourceType _currentScheduleSource; + ScheduleSourceType? _currentScheduleSource; SelectSourceDialog(this._preferencesProvider, this._scheduleSourceProvider); @@ -41,31 +41,31 @@ class SelectSourceDialog { RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Rapla, - onChanged: (v) => sourceSelected(v, context), + onChanged: (dynamic v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeRapla), ), RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Dualis, - onChanged: (v) => sourceSelected(v, context), + onChanged: (dynamic v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeDualis), ), RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Mannheim, - onChanged: (v) => sourceSelected(v, context), + onChanged: (dynamic v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeMannheim), ), RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Ical, - onChanged: (v) => sourceSelected(v, context), + onChanged: (dynamic v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeIcal), ), RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.None, - onChanged: (v) => sourceSelected(v, context), + onChanged: (dynamic v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeNone), ) ], @@ -76,6 +76,7 @@ class SelectSourceDialog { ScheduleSourceType type, BuildContext context, ) async { + // TODO: [Leptopoda] only switch the type when the setup is completed. _preferencesProvider.setScheduleSourceType(type.index); Navigator.of(context).pop(); diff --git a/lib/ui/banner_widget.dart b/lib/ui/banner_widget.dart index 7700d6e2..f993f420 100644 --- a/lib/ui/banner_widget.dart +++ b/lib/ui/banner_widget.dart @@ -5,7 +5,11 @@ class BannerWidget extends StatelessWidget { final String buttonText; final VoidCallback onButtonTap; - const BannerWidget({Key key, this.message, this.buttonText, this.onButtonTap}) + const BannerWidget( + {Key? key, + required this.message, + required this.buttonText, + required this.onButtonTap}) : super(key: key); @override @@ -27,23 +31,19 @@ class BannerWidget extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Text( - message, + Text(message), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 12, 0, 0), + child: TextButton( + child: Text(buttonText), + onPressed: onButtonTap, + ), + ), + ], ), - buttonText != null - ? Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(0, 12, 0, 0), - child: TextButton( - child: Text(buttonText), - onPressed: onButtonTap, - ), - ), - ], - ) - : Container(), ], ), ), diff --git a/lib/ui/login_credentials_widget.dart b/lib/ui/login_credentials_widget.dart index b8ee1134..c3e70936 100644 --- a/lib/ui/login_credentials_widget.dart +++ b/lib/ui/login_credentials_widget.dart @@ -1,45 +1,30 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:flutter/material.dart'; class LoginCredentialsWidget extends StatefulWidget { - final TextEditingController usernameEditingController; - final TextEditingController passwordEditingController; + final CredentialsEditingController controller; final Function onSubmitted; const LoginCredentialsWidget({ - Key key, - this.usernameEditingController, - this.passwordEditingController, - this.onSubmitted, + Key? key, + required this.controller, + required this.onSubmitted, }) : super(key: key); @override - _LoginCredentialsWidgetState createState() => _LoginCredentialsWidgetState( - usernameEditingController, - passwordEditingController, - onSubmitted, - ); + _LoginCredentialsWidgetState createState() => _LoginCredentialsWidgetState(); } class _LoginCredentialsWidgetState extends State { - final TextEditingController _usernameEditingController; - final TextEditingController _passwordEditingController; - final Function _onSubmitted; - final _focus = FocusNode(); - _LoginCredentialsWidgetState( - this._usernameEditingController, - this._passwordEditingController, - this._onSubmitted, - ); - @override Widget build(BuildContext context) { return Column( children: [ TextField( - controller: _usernameEditingController, + controller: widget.controller.username, decoration: InputDecoration( hintText: L.of(context).loginUsername, icon: Icon(Icons.alternate_email), @@ -50,7 +35,7 @@ class _LoginCredentialsWidgetState extends State { textInputAction: TextInputAction.next, ), TextField( - controller: _passwordEditingController, + controller: widget.controller.password, obscureText: true, decoration: InputDecoration( hintText: L.of(context).loginPassword, @@ -58,9 +43,7 @@ class _LoginCredentialsWidgetState extends State { ), focusNode: _focus, onSubmitted: (v) { - if (_onSubmitted != null) { - _onSubmitted(); - } + widget.onSubmitted(); }, ), ], diff --git a/lib/ui/main_page.dart b/lib/ui/main_page.dart index 9584c87c..47cfa706 100644 --- a/lib/ui/main_page.dart +++ b/lib/ui/main_page.dart @@ -15,6 +15,8 @@ import 'package:provider/provider.dart'; /// To navigate to a new route inside this widget use the [NavigatorKey.mainKey] /// class MainPage extends StatefulWidget { + const MainPage({Key? key}) : super(key: key); + @override _MainPageState createState() => _MainPageState(); } @@ -46,7 +48,7 @@ class _MainPageState extends State with NavigatorObserver { return ChangeNotifierProvider.value( value: _currentEntryIndex, child: Consumer>( - builder: (BuildContext context, value, Widget child) { + builder: (BuildContext context, value, Widget? child) { Widget content; if (PlatformUtil.isPhone() || PlatformUtil.isPortrait(context)) { @@ -64,11 +66,11 @@ class _MainPageState extends State with NavigatorObserver { Widget buildPhoneLayout(BuildContext context, Navigator navigator) { return WillPopScope( onWillPop: () async { - var canPop = NavigatorKey.mainKey.currentState.canPop(); + var canPop = NavigatorKey.mainKey.currentState!.canPop(); if (!canPop) return true; - NavigatorKey.mainKey.currentState.pop(); + NavigatorKey.mainKey.currentState!.pop(); return false; }, @@ -135,7 +137,7 @@ class _MainPageState extends State with NavigatorObserver { for (var entry in navigationEntries) { drawerEntries.add(DrawerNavigationEntry( - entry.icon(context), + entry.icon, entry.title(context), )); } @@ -146,7 +148,7 @@ class _MainPageState extends State with NavigatorObserver { void _onNavigationTapped(int index) { _currentEntryIndex.value = index; - NavigatorKey.mainKey.currentState + NavigatorKey.mainKey.currentState! .pushNamedAndRemoveUntil(currentEntry.route, (route) { return route.settings.name == navigationEntries[0].route; }); @@ -160,7 +162,7 @@ class _MainPageState extends State with NavigatorObserver { } } - void updateNavigationDrawer(String routeName) { + void updateNavigationDrawer(String? routeName) { for (int i = 0; i < navigationEntries.length; i++) { if (navigationEntries[i].route == routeName) { _currentEntryIndex.value = i; @@ -170,17 +172,17 @@ class _MainPageState extends State with NavigatorObserver { } @override - void didPop(Route route, Route previousRoute) { - updateNavigationDrawer(previousRoute.settings.name); + void didPop(Route route, Route? previousRoute) { + updateNavigationDrawer(previousRoute!.settings.name); } @override - void didPush(Route route, Route previousRoute) { + void didPush(Route route, Route? previousRoute) { updateNavigationDrawer(route.settings.name); } @override - void didReplace({Route newRoute, Route oldRoute}) { - updateNavigationDrawer(newRoute.settings.name); + void didReplace({Route? newRoute, Route? oldRoute}) { + updateNavigationDrawer(newRoute!.settings.name); } } diff --git a/lib/ui/navigation/navigation_entry.dart b/lib/ui/navigation/navigation_entry.dart index dedbf575..4c123c22 100644 --- a/lib/ui/navigation/navigation_entry.dart +++ b/lib/ui/navigation/navigation_entry.dart @@ -2,38 +2,30 @@ import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -abstract class NavigationEntry { - BaseViewModel _viewModel; +abstract class NavigationEntry { + T? _viewModel; String get route; String title(BuildContext context); - Widget icon(BuildContext context); + Icon get icon; Widget buildRoute(BuildContext context) { - var model = viewModel(); - if (model != null) { - return ChangeNotifierProvider.value( - value: model, - child: build(context), - ); - } else { - return build(context); - } + return ChangeNotifierProvider.value( + value: model, + child: build(context), + ); } Widget build(BuildContext context); - BaseViewModel viewModel() { - if (_viewModel == null) { - _viewModel = initViewModel(); - } - - return _viewModel; + T get model { + return _viewModel ??= initViewModel(); } - BaseViewModel initViewModel() => null; + T initViewModel(); - List appBarActions(BuildContext context) => []; + // TODO: [Leptopoda] clean up but not null related so something for later + List appBarActions(BuildContext context); } diff --git a/lib/ui/navigation/router.dart b/lib/ui/navigation/router.dart index 72c5fe58..f17e4cd7 100644 --- a/lib/ui/navigation/router.dart +++ b/lib/ui/navigation/router.dart @@ -18,7 +18,7 @@ final List navigationEntries = [ Route generateDrawerRoute(RouteSettings settings) { print("=== === === === === === Navigating to: ${settings.name}"); - WidgetBuilder widget; + WidgetBuilder? widget; for (var route in navigationEntries) { if (route.route == settings.name) { @@ -28,14 +28,14 @@ Route generateDrawerRoute(RouteSettings settings) { } if (widget == null) { - print("Failed to navigate to: " + settings.name); + print("Failed to navigate to: " + settings.name!); widget = (BuildContext context) => Container(); } return PageRouteBuilder( settings: settings, transitionDuration: const Duration(milliseconds: 200), - pageBuilder: (context, animation, secondaryAnimation) => widget(context), + pageBuilder: (context, animation, secondaryAnimation) => widget!(context), transitionsBuilder: (context, animation, secondaryAnimation, child) { const offsetBegin = Offset(0.0, 0.005); final offsetEnd = Offset.zero; @@ -76,7 +76,7 @@ Route generateRoute(RouteSettings settings) { target = SettingsPage(); break; default: - print("Failed to navigate to: " + settings.name); + print("Failed to navigate to: " + settings.name!); target = Container(); } diff --git a/lib/ui/navigation_drawer.dart b/lib/ui/navigation_drawer.dart index 6266b583..abc21d8a 100644 --- a/lib/ui/navigation_drawer.dart +++ b/lib/ui/navigation_drawer.dart @@ -16,10 +16,10 @@ class NavigationDrawer extends StatelessWidget { final bool isInDrawer; const NavigationDrawer({ - Key key, - this.selectedIndex, - this.onTap, - this.entries, + Key? key, + required this.selectedIndex, + required this.onTap, + required this.entries, this.isInDrawer = true, }) : super(key: key); @@ -81,10 +81,10 @@ class NavigationDrawer extends StatelessWidget { Widget _createDrawerItem( BuildContext context, { - Widget icon, - String text, - bool isSelected, - int index, + required Widget icon, + required String text, + required bool isSelected, + required int index, }) { return Padding( padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), @@ -169,7 +169,7 @@ class NavigationDrawer extends StatelessWidget { } class DrawerNavigationEntry { - final Widget icon; + final Icon icon; final String title; DrawerNavigationEntry(this.icon, this.title); diff --git a/lib/ui/onboarding/onboardin_step.dart b/lib/ui/onboarding/onboardin_step.dart index 37ee31aa..c800089f 100644 --- a/lib/ui/onboarding/onboardin_step.dart +++ b/lib/ui/onboarding/onboardin_step.dart @@ -17,7 +17,7 @@ abstract class OnboardingStep { OnboardingStepViewModel viewModel(); - String nextStep(); + String? nextStep(); } class SelectSourceOnboardingStep extends OnboardingStep { @@ -31,7 +31,7 @@ class SelectSourceOnboardingStep extends OnboardingStep { } @override - String nextStep() { + String? nextStep() { return _viewModel.nextStep(); } @@ -53,7 +53,7 @@ class DualisCredentialsOnboardingStep extends OnboardingStep { } @override - String nextStep() { + String? nextStep() { return null; } @@ -108,7 +108,7 @@ class IcalOnboardingStep extends OnboardingStep { } class MannheimOnboardingStep extends OnboardingStep { - MannheimViewModel _viewModel; + MannheimViewModel? _viewModel; @override Widget buildContent(BuildContext context) { @@ -122,12 +122,8 @@ class MannheimOnboardingStep extends OnboardingStep { @override OnboardingStepViewModel viewModel() { - if (_viewModel == null) { - _viewModel = MannheimViewModel( - KiwiContainer().resolve(), - ); - } - - return _viewModel; + return _viewModel ??= MannheimViewModel( + KiwiContainer().resolve(), + ); } } diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index 58a9f086..651f2bbe 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -1,5 +1,4 @@ import 'package:animations/animations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/root_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/onboarding_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/onboarding_view_model_base.dart'; @@ -10,7 +9,7 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class OnboardingPage extends StatefulWidget { - const OnboardingPage({Key key}) : super(key: key); + const OnboardingPage({Key? key}) : super(key: key); @override _OnboardingPageState createState() => _OnboardingPageState(); @@ -18,8 +17,8 @@ class OnboardingPage extends StatefulWidget { class _OnboardingPageState extends State with TickerProviderStateMixin { - AnimationController _controller; - OnboardingViewModel viewModel; + late AnimationController _controller; + late OnboardingViewModel viewModel; _OnboardingPageState(); @@ -35,7 +34,7 @@ class _OnboardingPageState extends State viewModel.addListener( () async { await _controller.animateTo( - viewModel.stepIndex / viewModel.onboardingSteps, + viewModel.stepIndex! / viewModel.onboardingSteps, curve: Curves.ease, duration: const Duration(milliseconds: 300)); }, @@ -75,12 +74,12 @@ class _OnboardingPageState extends State child: Padding( padding: const EdgeInsets.fromLTRB(0, 120, 0, 90), child: PropertyChangeConsumer( - builder: (BuildContext context, BaseViewModel model, _) { + builder: (BuildContext context, OnboardingViewModel? model, _) { return Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [ - Expanded(child: _buildActiveOnboardingPage(model)), + Expanded(child: _buildActiveOnboardingPage(model!)), OnboardingButtonBar( onPrevious: () { _navigateBack(context); @@ -101,7 +100,7 @@ class _OnboardingPageState extends State } Widget _buildActiveOnboardingPage(OnboardingViewModel model) { - var currentStep = model.pages[model.currentStep]; + var currentStep = model.pages[model.currentStep]!; var contentWidget = currentStep.buildContent(context); Widget body = Padding( @@ -109,13 +108,11 @@ class _OnboardingPageState extends State child: contentWidget, ); - if (currentStep != null) { - body = PropertyChangeProvider( - key: ValueKey(model.currentStep), - value: currentStep.viewModel(), - child: body, - ); - } + body = PropertyChangeProvider( + key: ValueKey(model.currentStep), + value: currentStep.viewModel(), + child: body, + ); return IntrinsicHeight( child: PageTransitionSwitcher( @@ -146,7 +143,8 @@ class _OnboardingPageState extends State } void _onboardingFinished() { - var rootViewModel = PropertyChangeProvider.of(context).value; + var rootViewModel = + PropertyChangeProvider.of(context)!.value; rootViewModel.setIsOnboarding(false); Navigator.of(context).pushReplacementNamed("main"); diff --git a/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart b/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart index d040074b..25e74c15 100644 --- a/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart +++ b/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart @@ -7,8 +7,7 @@ class DualisLoginViewModel extends OnboardingStepViewModel { final PreferencesProvider preferencesProvider; final DualisService dualisService; - String username; - String password; + Credentials? credentials; bool _isLoading = false; bool get isLoading => _isLoading; @@ -16,27 +15,28 @@ class DualisLoginViewModel extends OnboardingStepViewModel { bool _loginSuccess = false; bool get loginSuccess => _loginSuccess; - bool _passwordOrUsernameWrong = false; - bool get passwordOrUsernameWrong => _passwordOrUsernameWrong; - DualisLoginViewModel(this.preferencesProvider, this.dualisService); - Future testCredentials(String username, String password) async { - this.username = username; - this.password = password; + @override + void setIsValid(bool isValid) { + if (credentials == null) { + super.setIsValid(false); + } else { + super.setIsValid(isValid); + } + } + Future testCredentials(Credentials credentials) async { try { _isLoading = true; notifyListeners("isLoading"); _loginSuccess = - await dualisService.login(username, password) == LoginResult.LoggedIn; - _passwordOrUsernameWrong = !_loginSuccess; + await dualisService.login(credentials) == LoginResult.LoggedIn; setIsValid(_loginSuccess); } catch (ex) { setIsValid(false); - _passwordOrUsernameWrong = true; } finally { _isLoading = false; } @@ -46,13 +46,12 @@ class DualisLoginViewModel extends OnboardingStepViewModel { @override Future save() async { + if (!isValid) return; + await preferencesProvider.setStoreDualisCredentials(true); // To improve the onboarding experience we do not await this call because // it may take a few seconds - preferencesProvider.storeDualisCredentials(Credentials( - username, - password, - )); + preferencesProvider.storeDualisCredentials(credentials!); } } diff --git a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart index 78ed03e6..346f6648 100644 --- a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart +++ b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart @@ -8,14 +8,14 @@ class IcalUrlViewModel extends OnboardingStepViewModel { final PreferencesProvider preferencesProvider; final ScheduleSourceProvider scheduleSourceProvider; - String _url; - String get url => _url; + String? _url; + String? get url => _url; bool urlHasError = false; IcalUrlViewModel(this.preferencesProvider, this.scheduleSourceProvider); - void setUrl(String url) { + void setUrl(String? url) { _url = url; notifyListeners("url"); @@ -24,7 +24,7 @@ class IcalUrlViewModel extends OnboardingStepViewModel { } void _validateUrl() { - urlHasError = !IcalScheduleSource.isValidUrl(_url); + urlHasError = !IcalScheduleSource.isValidUrl(_url!); setIsValid(!urlHasError); @@ -32,10 +32,10 @@ class IcalUrlViewModel extends OnboardingStepViewModel { } Future pasteUrl() async { - ClipboardData data = await Clipboard.getData('text/plain'); + ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text != null) { - setUrl(data.text); + setUrl(data!.text); } } diff --git a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart index 757125fa..3ae7a468 100644 --- a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart +++ b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart @@ -14,11 +14,11 @@ class MannheimViewModel extends OnboardingStepViewModel { LoadCoursesState _loadingState = LoadCoursesState.Loading; LoadCoursesState get loadingState => _loadingState; - Course _selectedCourse; - Course get selectedCourse => _selectedCourse; + Course? _selectedCourse; + Course? get selectedCourse => _selectedCourse; - List _courses; - List get courses => _courses; + List? _courses; + List? get courses => _courses; MannheimViewModel(this._scheduleSourceProvider) { setIsValid(false); diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart index 9128e541..b9749d75 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart @@ -28,11 +28,11 @@ class OnboardingViewModel extends BaseViewModel { final Map stepsBackstack = {}; int _stepIndex = 0; - int get stepIndex => _stepIndex; + int? get stepIndex => _stepIndex; String get currentStep => steps[_stepIndex]; - bool get currentPageValid => pages[currentStep].viewModel().isValid; + bool get currentPageValid => pages[currentStep]!.viewModel().isValid; bool get isLastStep => _stepIndex >= steps.length - 1; get onboardingSteps => steps.length; @@ -61,7 +61,7 @@ class OnboardingViewModel extends BaseViewModel { var lastPage = stepsBackstack.keys.last; - _stepIndex = stepsBackstack[lastPage]; + _stepIndex = stepsBackstack[lastPage]!; stepsBackstack.remove(lastPage); @@ -77,7 +77,7 @@ class OnboardingViewModel extends BaseViewModel { return; } - var nextDesiredStep = pages[currentStep].nextStep(); + var nextDesiredStep = pages[currentStep]!.nextStep(); stepsBackstack[currentStep] = _stepIndex; @@ -96,10 +96,10 @@ class OnboardingViewModel extends BaseViewModel { Future finishOnboarding() async { for (var step in stepsBackstack.keys) { - await pages[step].viewModel().save(); + await pages[step]!.viewModel().save(); } - _onboardingFinished?.call(); + _onboardingFinished.call(); await analytics.logTutorialComplete(); await analytics.setUserProperty(name: "onboarding_finished", value: "true"); diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart index 26ebd7da..fba1ca43 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart @@ -4,6 +4,7 @@ abstract class OnboardingStepViewModel extends BaseViewModel { bool _isValid = false; bool get isValid => _isValid; + // TODO: [Leptopoda] kinda redundant now that we have null safety?¿ void setIsValid(bool isValid) { _isValid = isValid; notifyListeners("isValid"); diff --git a/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart b/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart index 76fbf4c1..6511643b 100644 --- a/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart +++ b/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart @@ -8,8 +8,8 @@ class RaplaUrlViewModel extends OnboardingStepViewModel { final PreferencesProvider preferencesProvider; final ScheduleSourceProvider scheduleSourceProvider; - String _raplaUrl; - String get raplaUrl => _raplaUrl; + String? _raplaUrl; + String? get raplaUrl => _raplaUrl; bool urlHasError = false; @@ -18,7 +18,7 @@ class RaplaUrlViewModel extends OnboardingStepViewModel { this.scheduleSourceProvider, ); - void setRaplaUrl(String url) { + void setRaplaUrl(String? url) { _raplaUrl = url; notifyListeners("raplaUrl"); @@ -27,7 +27,7 @@ class RaplaUrlViewModel extends OnboardingStepViewModel { } void _validateUrl() { - urlHasError = !RaplaScheduleSource.isValidUrl(_raplaUrl); + urlHasError = !RaplaScheduleSource.isValidUrl(_raplaUrl!); setIsValid(!urlHasError); @@ -35,10 +35,10 @@ class RaplaUrlViewModel extends OnboardingStepViewModel { } Future pasteUrl() async { - ClipboardData data = await Clipboard.getData('text/plain'); + ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text != null) { - setRaplaUrl(data.text); + setRaplaUrl(data!.text); } } diff --git a/lib/ui/onboarding/viewmodels/select_source_view_model.dart b/lib/ui/onboarding/viewmodels/select_source_view_model.dart index ec95f6fa..8310a6f3 100644 --- a/lib/ui/onboarding/viewmodels/select_source_view_model.dart +++ b/lib/ui/onboarding/viewmodels/select_source_view_model.dart @@ -12,9 +12,11 @@ class SelectSourceViewModel extends OnboardingStepViewModel { setIsValid(true); } - void setScheduleSourceType(ScheduleSourceType type) { + void setScheduleSourceType(ScheduleSourceType? type) { + if (type == null) return; + _scheduleSourceType = type; - setIsValid(_scheduleSourceType != null); + setIsValid(true); notifyListeners("scheduleSourceType"); } @@ -24,7 +26,7 @@ class SelectSourceViewModel extends OnboardingStepViewModel { await _preferencesProvider.setScheduleSourceType(scheduleSourceType.index); } - String nextStep() { + String? nextStep() { switch (_scheduleSourceType) { case ScheduleSourceType.Rapla: return "rapla"; @@ -36,8 +38,8 @@ class SelectSourceViewModel extends OnboardingStepViewModel { return "mannheim"; case ScheduleSourceType.Ical: return "ical"; + default: + return null; } - - return null; } } diff --git a/lib/ui/onboarding/widgets/dualis_login_page.dart b/lib/ui/onboarding/widgets/dualis_login_page.dart index 52630741..f4faf068 100644 --- a/lib/ui/onboarding/widgets/dualis_login_page.dart +++ b/lib/ui/onboarding/widgets/dualis_login_page.dart @@ -1,4 +1,5 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; +import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/ui/login_credentials_widget.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/dualis_login_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/onboarding_view_model_base.dart'; @@ -10,6 +11,8 @@ import 'package:property_change_notifier/property_change_notifier.dart'; /// credentials. /// class DualisLoginCredentialsPage extends StatefulWidget { + const DualisLoginCredentialsPage({Key? key}) : super(key: key); + @override _DualisLoginCredentialsPageState createState() => _DualisLoginCredentialsPageState(); @@ -17,31 +20,27 @@ class DualisLoginCredentialsPage extends StatefulWidget { class _DualisLoginCredentialsPageState extends State { - final TextEditingController _usernameEditingController = - TextEditingController(); - final TextEditingController _passwordEditingController = - TextEditingController(); + final CredentialsEditingController _controller = + CredentialsEditingController(); @override Widget build(BuildContext context) { return PropertyChangeConsumer( - builder: - (BuildContext context, OnboardingStepViewModel base, Set _) { - var viewModel = base as DualisLoginViewModel; + builder: (BuildContext context, OnboardingStepViewModel? base, + Set? _) { + final viewModel = base as DualisLoginViewModel?; - if (_usernameEditingController.text != viewModel.username) { - _usernameEditingController.text = viewModel.username; - } - if (_passwordEditingController.text != viewModel.password) { - _passwordEditingController.text = viewModel.password; + final credentials = viewModel?.credentials; + + if (credentials != null) { + _controller.credentials = credentials; } var widgets = []; widgets.addAll(_buildHeader()); widgets.add(LoginCredentialsWidget( - usernameEditingController: _usernameEditingController, - passwordEditingController: _passwordEditingController, + controller: _controller, onSubmitted: () async { await _testCredentials(viewModel); }, @@ -57,7 +56,7 @@ class _DualisLoginCredentialsPageState ); } - Widget _buildTestCredentialsButton(DualisLoginViewModel viewModel) { + Widget _buildTestCredentialsButton(DualisLoginViewModel? viewModel) { return Expanded( child: SizedBox( height: 64, @@ -69,7 +68,7 @@ class _DualisLoginCredentialsPageState crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( - child: viewModel.passwordOrUsernameWrong + child: viewModel?.isValid ?? false ? Text( L.of(context).onboardingDualisWrongCredentials, textAlign: TextAlign.start, @@ -77,7 +76,7 @@ class _DualisLoginCredentialsPageState ) : Container(), ), - viewModel.isLoading + viewModel?.isLoading ?? false ? const SizedBox( width: 16, height: 16, @@ -85,7 +84,7 @@ class _DualisLoginCredentialsPageState strokeWidth: 1, ), ) - : viewModel.loginSuccess + : viewModel?.loginSuccess ?? false ? const Icon( Icons.check, color: Colors.green, @@ -106,11 +105,10 @@ class _DualisLoginCredentialsPageState ); } - Future _testCredentials(DualisLoginViewModel viewModel) async { - await viewModel.testCredentials( - _usernameEditingController.text, - _passwordEditingController.text, - ); + Future _testCredentials(DualisLoginViewModel? viewModel) async { + if (viewModel == null) return; + + await viewModel.testCredentials(_controller.credentials); } List _buildHeader() { diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index dfd690bc..cdb6316f 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -5,6 +5,8 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class IcalUrlPage extends StatefulWidget { + const IcalUrlPage({Key? key}) : super(key: key); + @override _IcalUrlPageState createState() => _IcalUrlPageState(); } @@ -40,12 +42,13 @@ class _IcalUrlPageState extends State { child: Padding( padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: PropertyChangeConsumer( - builder: (BuildContext context, OnboardingStepViewModel model, - Set _) { - var viewModel = model as IcalUrlViewModel; + builder: (BuildContext context, OnboardingStepViewModel? model, + Set? _) { + final viewModel = model as IcalUrlViewModel?; - if (_urlTextController.text != viewModel.url) - _urlTextController.text = viewModel.url; + if (viewModel?.url != null && + _urlTextController.text != viewModel!.url) + _urlTextController.text = viewModel.url!; return Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), @@ -56,19 +59,17 @@ class _IcalUrlPageState extends State { child: TextField( controller: _urlTextController, decoration: InputDecoration( - errorText: (viewModel.urlHasError ?? false) + errorText: (viewModel?.urlHasError == true) ? L.of(context).onboardingRaplaUrlInvalid : null, hintText: L.of(context).onboardingIcalUrlHint, ), - onChanged: (value) { - viewModel.setUrl(value); - }, + onChanged: viewModel?.setUrl, ), ), TextButton.icon( onPressed: () async { - await viewModel.pasteUrl(); + await viewModel?.pasteUrl(); }, icon: Icon(Icons.content_paste), label: Text( diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index 83495596..ff9c0890 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -5,6 +5,8 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class MannheimPage extends StatefulWidget { + const MannheimPage({Key? key}) : super(key: key); + @override _MannheimPageState createState() => _MannheimPageState(); } @@ -50,20 +52,19 @@ class SelectMannheimCourseWidget extends StatelessWidget { @override Widget build(BuildContext context) { return PropertyChangeConsumer( - builder: - (BuildContext context, OnboardingStepViewModel model, Set _) { - var viewModel = model as MannheimViewModel; + builder: (BuildContext context, OnboardingStepViewModel? model, + Set? _) { + final viewModel = model as MannheimViewModel?; - switch (viewModel.loadingState) { + switch (viewModel?.loadingState) { case LoadCoursesState.Loading: return _buildLoadingIndicator(); case LoadCoursesState.Loaded: - return _buildCourseList(context, viewModel); + return _buildCourseList(context, viewModel!); case LoadCoursesState.Failed: + default: return _buildLoadingError(context, viewModel); } - - return Container(); }, ); } @@ -89,7 +90,8 @@ class SelectMannheimCourseWidget extends StatelessWidget { int index, BuildContext context, ) { - var isSelected = viewModel.selectedCourse == viewModel.courses[index]; + // TODO: [Leptopoda] why is nullsafety garanttueed here but checked above ¿? + var isSelected = viewModel.selectedCourse == viewModel.courses![index]; return ListTile( trailing: isSelected @@ -99,19 +101,20 @@ class SelectMannheimCourseWidget extends StatelessWidget { ) : null, title: Text( - viewModel.courses[index].name, + viewModel.courses![index].name, style: isSelected ? TextStyle( color: Theme.of(context).colorScheme.secondary, ) : null, ), - subtitle: Text(viewModel.courses[index].title), - onTap: () => viewModel.setSelectedCourse(viewModel.courses[index]), + subtitle: Text(viewModel.courses![index].title), + onTap: () => viewModel.setSelectedCourse(viewModel.courses![index]), ); } - Widget _buildLoadingError(BuildContext context, MannheimViewModel viewModel) { + Widget _buildLoadingError( + BuildContext context, MannheimViewModel? viewModel) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -120,7 +123,7 @@ class SelectMannheimCourseWidget extends StatelessWidget { Padding( padding: const EdgeInsets.all(16), child: MaterialButton( - onPressed: viewModel.loadCourses, + onPressed: viewModel?.loadCourses, child: Icon(Icons.refresh), ), ), diff --git a/lib/ui/onboarding/widgets/onboarding_button_bar.dart b/lib/ui/onboarding/widgets/onboarding_button_bar.dart index 41f4deb6..f95cc7ab 100644 --- a/lib/ui/onboarding/widgets/onboarding_button_bar.dart +++ b/lib/ui/onboarding/widgets/onboarding_button_bar.dart @@ -4,14 +4,14 @@ import 'package:flutter/material.dart'; class OnboardingButtonBar extends StatelessWidget { final OnboardingViewModel viewModel; - final Function onNext; - final Function onPrevious; + final VoidCallback onNext; + final VoidCallback onPrevious; const OnboardingButtonBar({ - Key key, - @required this.viewModel, - @required this.onNext, - @required this.onPrevious, + Key? key, + required this.viewModel, + required this.onNext, + required this.onPrevious, }) : super(key: key); @override diff --git a/lib/ui/onboarding/widgets/onboarding_page_background.dart b/lib/ui/onboarding/widgets/onboarding_page_background.dart index 715b0747..b31b0242 100644 --- a/lib/ui/onboarding/widgets/onboarding_page_background.dart +++ b/lib/ui/onboarding/widgets/onboarding_page_background.dart @@ -20,7 +20,7 @@ class OnboardingPageBackground extends StatelessWidget { Brightness.dark: "assets/onboarding_bottom_background_dark.png", }; - OnboardingPageBackground({Key key, this.controller}) + OnboardingPageBackground({Key? key, required this.controller}) : angleTopBackground = Tween( begin: PlatformUtil.isPhone() ? -32 : -10, end: PlatformUtil.isPhone() ? -10 : -5, @@ -75,7 +75,7 @@ class OnboardingPageBackground extends StatelessWidget { ), super(key: key); - Widget _buildAnimation(BuildContext context, Widget child) { + Widget _buildAnimation(BuildContext context, Widget? child) { return Stack( children: [ Transform.rotate( @@ -111,7 +111,7 @@ class OnboardingPageBackground extends StatelessWidget { child: Transform.scale( scale: 1.5, child: Image.asset( - background[Theme.of(context).brightness], + background[Theme.of(context).brightness]!, ), ), ), @@ -129,7 +129,7 @@ class OnboardingPageBackground extends StatelessWidget { child: Transform.scale( scale: 1.5, child: Image.asset( - foreground[Theme.of(context).brightness], + foreground[Theme.of(context).brightness]!, ), ), ), diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index 2e5b5f3e..512b5d12 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -5,6 +5,8 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class RaplaUrlPage extends StatefulWidget { + const RaplaUrlPage({Key? key}) : super(key: key); + @override _RaplaUrlPageState createState() => _RaplaUrlPageState(); } @@ -40,12 +42,13 @@ class _RaplaUrlPageState extends State { child: Padding( padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: PropertyChangeConsumer( - builder: (BuildContext context, OnboardingStepViewModel model, - Set _) { - var viewModel = model as RaplaUrlViewModel; + builder: (BuildContext context, OnboardingStepViewModel? model, + Set? _) { + final viewModel = model as RaplaUrlViewModel?; - if (_urlTextController.text != viewModel.raplaUrl) - _urlTextController.text = viewModel.raplaUrl; + if (viewModel?.raplaUrl != null && + _urlTextController.text != viewModel!.raplaUrl) + _urlTextController.text = viewModel.raplaUrl!; return Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), @@ -56,19 +59,17 @@ class _RaplaUrlPageState extends State { child: TextField( controller: _urlTextController, decoration: InputDecoration( - errorText: (viewModel.urlHasError ?? false) + errorText: viewModel?.urlHasError == true ? L.of(context).onboardingRaplaUrlInvalid : null, hintText: L.of(context).onboardingRaplaUrlHint, ), - onChanged: (value) { - viewModel.setRaplaUrl(value); - }, + onChanged: viewModel?.setRaplaUrl, ), ), TextButton.icon( onPressed: () async { - await viewModel.pasteUrl(); + await viewModel?.pasteUrl(); }, icon: Icon(Icons.content_paste), label: Text( diff --git a/lib/ui/onboarding/widgets/select_source_page.dart b/lib/ui/onboarding/widgets/select_source_page.dart index e10eb9e5..b420a366 100644 --- a/lib/ui/onboarding/widgets/select_source_page.dart +++ b/lib/ui/onboarding/widgets/select_source_page.dart @@ -6,17 +6,17 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class SelectSourcePage extends StatelessWidget { - const SelectSourcePage({Key key}) : super(key: key); + const SelectSourcePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return PropertyChangeConsumer( builder: ( BuildContext context, - OnboardingStepViewModel model, - Set _, + OnboardingStepViewModel? model, + Set? _, ) { - var viewModel = model as SelectSourceViewModel; + final viewModel = model as SelectSourceViewModel?; return Column( mainAxisAlignment: MainAxisAlignment.start, children: [ @@ -92,15 +92,15 @@ class SelectSourcePage extends StatelessWidget { } RadioListTile buildScheduleTypeRadio( - SelectSourceViewModel viewModel, + SelectSourceViewModel? viewModel, BuildContext context, ScheduleSourceType type, String title) { return RadioListTile( value: type, //model.useDualis, - onChanged: viewModel.setScheduleSourceType, + onChanged: viewModel?.setScheduleSourceType, title: Text(title), - groupValue: viewModel.scheduleSourceType, + groupValue: viewModel?.scheduleSourceType, ); } } diff --git a/lib/ui/pager_widget.dart b/lib/ui/pager_widget.dart index 96cbc68f..7d2dc3ed 100644 --- a/lib/ui/pager_widget.dart +++ b/lib/ui/pager_widget.dart @@ -15,24 +15,20 @@ import 'package:provider/provider.dart'; /// class PagerWidget extends StatefulWidget { final List pages; - final String pagesId; + final String? pagesId; - const PagerWidget({Key key, @required this.pages, this.pagesId}) + const PagerWidget({Key? key, required this.pages, this.pagesId}) : super(key: key); @override - _PagerWidgetState createState() => _PagerWidgetState(pages, pagesId); + _PagerWidgetState createState() => _PagerWidgetState(); } class _PagerWidgetState extends State { final PreferencesProvider preferencesProvider = KiwiContainer().resolve(); - final String pagesId; - final List pages; int _currentPage = 0; - _PagerWidgetState(this.pages, this.pagesId); - @override void initState() { super.initState(); @@ -49,37 +45,23 @@ class _PagerWidgetState extends State { key: ValueKey(_currentPage), children: [ Expanded( - child: _wrapWithChangeNotifierProvider( - pages[_currentPage].builder(context), - pages[_currentPage].viewModel, - ), + child: widget.pages[_currentPage].widget(context), ), ], ), ), bottomNavigationBar: BottomNavigationBar( currentIndex: _currentPage, - onTap: (int index) async { - await setActivePage(index); - }, + onTap: setActivePage, items: buildBottomNavigationBarItems(), ), ); } - Widget _wrapWithChangeNotifierProvider(Widget child, BaseViewModel value) { - if (value == null) return child; - - return ChangeNotifierProvider.value( - child: child, - value: value, - ); - } - List buildBottomNavigationBarItems() { var bottomNavigationBarItems = []; - for (var page in pages) { + for (var page in widget.pages) { bottomNavigationBarItems.add( BottomNavigationBarItem( icon: page.icon, @@ -91,7 +73,7 @@ class _PagerWidgetState extends State { } Future setActivePage(int page) async { - if (page < 0 || page >= pages.length) { + if (page < 0 || page >= widget.pages.length) { return; } @@ -99,20 +81,20 @@ class _PagerWidgetState extends State { _currentPage = page; }); - if (pagesId == null) return; - await preferencesProvider.set("${pagesId}_active_page", page); + if (widget.pagesId == null) return; + await preferencesProvider.set("${widget.pagesId}_active_page", page); } Future loadActivePage() async { - if (pagesId == null) return; + if (widget.pagesId == null) return; var selectedPage = await preferencesProvider.get( - "${pagesId}_active_page", + "${widget.pagesId}_active_page", ); if (selectedPage == null) return; - if (selectedPage > 0 && selectedPage < pages.length) { + if (selectedPage > 0 && selectedPage < widget.pages.length) { setState(() { _currentPage = selectedPage; }); @@ -120,16 +102,26 @@ class _PagerWidgetState extends State { } } -class PageDefinition { +class PageDefinition { final Widget icon; final String text; final WidgetBuilder builder; - final BaseViewModel viewModel; + final T? viewModel; PageDefinition({ - @required this.icon, - @required this.text, - @required this.builder, + required this.icon, + required this.text, + required this.builder, this.viewModel, }); + + /// Wraps the Widget with a [ChangeNotifierProvider] if [viewModel] is specified. + Widget widget(BuildContext context) { + if (viewModel == null) return builder(context); + + return ChangeNotifierProvider.value( + child: builder(context), + value: viewModel, + ); + } } diff --git a/lib/ui/root_page.dart b/lib/ui/root_page.dart index 82397d57..cb6c2027 100644 --- a/lib/ui/root_page.dart +++ b/lib/ui/root_page.dart @@ -16,17 +16,13 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class RootPage extends StatefulWidget { final RootViewModel rootViewModel; - const RootPage({Key key, this.rootViewModel}) : super(key: key); + const RootPage({Key? key, required this.rootViewModel}) : super(key: key); @override - _RootPageState createState() => _RootPageState(rootViewModel); + _RootPageState createState() => _RootPageState(); } class _RootPageState extends State { - final RootViewModel rootViewModel; - - _RootPageState(this.rootViewModel); - @override void initState() { super.initState(); @@ -37,10 +33,12 @@ class _RootPageState extends State { return PropertyChangeProvider( child: PropertyChangeConsumer( properties: const ["appTheme", "isOnboarding"], - builder: (BuildContext context, RootViewModel model, Set properties) => - MaterialApp( - theme: ColorPalettes.buildTheme(model.appTheme), - initialRoute: rootViewModel.isOnboarding ? "onboarding" : "main", + builder: + (BuildContext context, RootViewModel? model, Set? properties) => + MaterialApp( + theme: ColorPalettes.buildTheme(model!.appTheme), + initialRoute: + widget.rootViewModel.isOnboarding ? "onboarding" : "main", navigatorKey: NavigatorKey.rootKey, navigatorObservers: [rootNavigationObserver], localizationsDelegates: [ @@ -57,7 +55,7 @@ class _RootPageState extends State { onGenerateRoute: generateRoute, ), ), - value: rootViewModel, + value: widget.rootViewModel, ); } } diff --git a/lib/ui/settings/donate_list_tile.dart b/lib/ui/settings/donate_list_tile.dart index 9562b533..4b17d511 100644 --- a/lib/ui/settings/donate_list_tile.dart +++ b/lib/ui/settings/donate_list_tile.dart @@ -7,6 +7,8 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class DonateListTile extends StatefulWidget { + const DonateListTile({Key? key}) : super(key: key); + @override _DonateListTileState createState() => _DonateListTileState(); } @@ -14,7 +16,7 @@ class DonateListTile extends StatefulWidget { class _DonateListTileState extends State { final InAppPurchaseManager inAppPurchaseManager; - SettingsViewModel model; + late SettingsViewModel model; bool isPurchasing = false; @@ -34,7 +36,7 @@ class _DonateListTileState extends State { inAppPurchaseManager.removePurchaseCallback(null, purchaseCallback); } - void purchaseCallback(String productId, PurchaseResultEnum result) { + void purchaseCallback(String? productId, PurchaseResultEnum result) { if (!mounted) return; setState(() { @@ -49,7 +51,8 @@ class _DonateListTileState extends State { properties: const [ "didPurchaseWidget", ], - ).value; + )! + .value; if (model.widgetPurchaseState == null) { return Padding( @@ -91,8 +94,8 @@ class _DonateListTileState extends State { } void _purchaseClicked() async { - if (isPurchasing || model.widgetPurchaseState == PurchaseStateEnum.Purchased) - return; + if (isPurchasing || + model.widgetPurchaseState == PurchaseStateEnum.Purchased) return; setState(() { isPurchasing = true; diff --git a/lib/ui/settings/purchase_widget_list_tile.dart b/lib/ui/settings/purchase_widget_list_tile.dart index 8f8d9438..5cbd5594 100644 --- a/lib/ui/settings/purchase_widget_list_tile.dart +++ b/lib/ui/settings/purchase_widget_list_tile.dart @@ -7,13 +7,15 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class PurchaseWidgetListTile extends StatefulWidget { + const PurchaseWidgetListTile({Key? key}) : super(key: key); + @override _PurchaseWidgetListTileState createState() => _PurchaseWidgetListTileState(); } class _PurchaseWidgetListTileState extends State { final InAppPurchaseManager inAppPurchaseManager; - SettingsViewModel model; + late SettingsViewModel model; bool isPurchasing = false; @@ -34,7 +36,7 @@ class _PurchaseWidgetListTileState extends State { inAppPurchaseManager.removePurchaseCallback(null, purchaseCallback); } - void purchaseCallback(String productId, PurchaseResultEnum result) { + void purchaseCallback(String? productId, PurchaseResultEnum result) { if (!mounted) return; setState(() { @@ -50,9 +52,10 @@ class _PurchaseWidgetListTileState extends State { "didPurchaseWidget", "areWidgetsSupported", ], - ).value; + )! + .value; - if (!model.areWidgetsSupported || + if (!model.areWidgetsSupported! || model.widgetPurchaseState == PurchaseStateEnum.Unknown || model.widgetPurchaseState == null) { return Container(); @@ -66,7 +69,7 @@ class _PurchaseWidgetListTileState extends State { ); } - Widget _buildWidgetSubtitle() { + Widget? _buildWidgetSubtitle() { if (isPurchasing) { return Align( alignment: Alignment.centerLeft, diff --git a/lib/ui/settings/select_theme_dialog.dart b/lib/ui/settings/select_theme_dialog.dart index c6a337c1..340711b9 100644 --- a/lib/ui/settings/select_theme_dialog.dart +++ b/lib/ui/settings/select_theme_dialog.dart @@ -28,7 +28,8 @@ class SelectThemeDialog { properties: const [ "appTheme", ], - builder: (BuildContext context, RootViewModel model, Set properties) { + builder: + (BuildContext context, RootViewModel? model, Set? properties) { return Column( mainAxisSize: MainAxisSize.min, children: [ @@ -36,19 +37,19 @@ class SelectThemeDialog { title: Text(L.of(context).selectThemeLight), value: AppTheme.Light, groupValue: _rootViewModel.appTheme, - onChanged: (v) => _rootViewModel.setAppTheme(v), + onChanged: _rootViewModel.setAppTheme, ), RadioListTile( title: Text(L.of(context).selectThemeDark), value: AppTheme.Dark, groupValue: _rootViewModel.appTheme, - onChanged: (v) => _rootViewModel.setAppTheme(v), + onChanged: _rootViewModel.setAppTheme, ), RadioListTile( title: Text(L.of(context).selectThemeSystem), value: AppTheme.System, groupValue: _rootViewModel.appTheme, - onChanged: (v) => _rootViewModel.setAppTheme(v), + onChanged: _rootViewModel.setAppTheme, ), ], ); diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 7c7c173a..4d966bda 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -30,6 +30,8 @@ import 'package:url_launcher/url_launcher.dart'; /// of the app /// class SettingsPage extends StatefulWidget { + const SettingsPage({Key? key}) : super(key: key); + @override _SettingsPageState createState() => _SettingsPageState(); } @@ -128,10 +130,10 @@ class _SettingsPageState extends State { "prettifySchedule", ], builder: - (BuildContext context, SettingsViewModel model, Set properties) { + (BuildContext context, SettingsViewModel? model, Set? properties) { return SwitchListTile( title: Text(L.of(context).settingsPrettifySchedule), - onChanged: model.setPrettifySchedule, + onChanged: model!.setPrettifySchedule, value: model.prettifySchedule, ); }, @@ -162,7 +164,7 @@ class _SettingsPageState extends State { .isCalendarSyncEnabled(); List entriesToExport = KiwiContainer().resolve().listDateEntries; - await NavigatorKey.rootKey.currentState.push(MaterialPageRoute( + await NavigatorKey.rootKey.currentState!.push(MaterialPageRoute( builder: (BuildContext context) => CalendarExportPage( entriesToExport: entriesToExport, isCalendarSyncWidget: true, @@ -177,18 +179,18 @@ class _SettingsPageState extends State { List buildNotificationSettings(BuildContext context) { WorkSchedulerService service = KiwiContainer().resolve(); - if (service?.isSchedulingAvailable() ?? false) { + if (service.isSchedulingAvailable()) { return [ TitleListTile(title: L.of(context).settingsNotificationsTitle), PropertyChangeConsumer( properties: const [ "notifyAboutNextDay", ], - builder: - (BuildContext context, SettingsViewModel model, Set properties) { + builder: (BuildContext context, SettingsViewModel? model, + Set? properties) { return SwitchListTile( title: Text(L.of(context).settingsNotificationsNextDay), - onChanged: model.setNotifyAboutNextDay, + onChanged: model!.setNotifyAboutNextDay, value: model.notifyAboutNextDay, ); }, @@ -197,11 +199,11 @@ class _SettingsPageState extends State { properties: const [ "notifyAboutScheduleChanges", ], - builder: - (BuildContext context, SettingsViewModel model, Set properties) { + builder: (BuildContext context, SettingsViewModel? model, + Set? properties) { return SwitchListTile( title: Text(L.of(context).settingsNotificationsScheduleChange), - onChanged: model.setNotifyAboutScheduleChanges, + onChanged: model!.setNotifyAboutScheduleChanges, value: model.notifyAboutScheduleChanges, ); }, @@ -220,17 +222,17 @@ class _SettingsPageState extends State { properties: const [ "appTheme", ], - builder: (BuildContext context, RootViewModel model, Set properties) { + builder: (BuildContext context, RootViewModel? model, Set? properties) { return ListTile( title: Text(L.of(context).settingsDarkMode), onTap: () async { - await SelectThemeDialog(model).show(context); + await SelectThemeDialog(model!).show(context); }, subtitle: Text({ AppTheme.Dark: L.of(context).selectThemeDark, AppTheme.Light: L.of(context).selectThemeLight, AppTheme.System: L.of(context).selectThemeSystem, - }[model.appTheme]), + }[model!.appTheme]!), ); }, ), diff --git a/lib/ui/settings/viewmodels/settings_view_model.dart b/lib/ui/settings/viewmodels/settings_view_model.dart index 9db30d99..7bffb54c 100644 --- a/lib/ui/settings/viewmodels/settings_view_model.dart +++ b/lib/ui/settings/viewmodels/settings_view_model.dart @@ -34,20 +34,19 @@ class SettingsViewModel extends BaseViewModel { bool get isCalendarSyncEnabled => _isCalendarSyncEnabled; - PurchaseStateEnum _widgetPurchaseState; + PurchaseStateEnum? _widgetPurchaseState; - PurchaseStateEnum get widgetPurchaseState => _widgetPurchaseState; + PurchaseStateEnum? get widgetPurchaseState => _widgetPurchaseState; - bool _areWidgetsSupported = false; + bool? _areWidgetsSupported = false; - bool get areWidgetsSupported => _areWidgetsSupported; + bool? get areWidgetsSupported => _areWidgetsSupported; SettingsViewModel( - this._preferencesProvider, - this._nextDayInformationNotification, - this._widgetHelper, - this._inAppPurchaseManager - ) { + this._preferencesProvider, + this._nextDayInformationNotification, + this._widgetHelper, + this._inAppPurchaseManager) { _loadPreferences(); _inAppPurchaseManager.addPurchaseCallback( @@ -71,7 +70,7 @@ class SettingsViewModel extends BaseViewModel { ); } - void _widgetPurchaseCallback(String id, PurchaseResultEnum result) { + void _widgetPurchaseCallback(String? id, PurchaseResultEnum result) { if (result == PurchaseResultEnum.Success) { _widgetPurchaseState = PurchaseStateEnum.Purchased; } diff --git a/pubspec.lock b/pubspec.lock index c0c493ac..7a882907 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -127,6 +127,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.0" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a7c391fd..3f04227c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ description: An app for the DHBW Stuttgart version: 1.0.1+1 environment: - sdk: ">=2.10.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: @@ -50,6 +50,7 @@ dependencies: flutter_widgetkit: ^1.0.3 app_group_directory: ^2.0.0 timezone: ^0.8.0 + equatable: ^2.0.0 dev_dependencies: flutter_test: diff --git a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart index 28bcc7d9..fd347f36 100644 --- a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart @@ -17,12 +17,12 @@ Future main() async { expect(modules.length, 3); - expect(modules[1].id, "T3INF1001"); - expect(modules[1].name, "Mathematik I"); - expect(modules[1].state, null); - expect(modules[1].credits, "8,0"); - expect(modules[1].finalGrade, "4,0"); - expect(modules[1].detailsUrl, + expect(modules[1]!.id, "T3INF1001"); + expect(modules[1]!.name, "Mathematik I"); + expect(modules[1]!.state, null); + expect(modules[1]!.credits, "8,0"); + expect(modules[1]!.finalGrade, "4,0"); + expect(modules[1]!.detailsUrl, "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=RESULTDETAILS&ARGUMENTS=-N123456789876543,-N000307,-N121212121212121"); }); diff --git a/test/schedule/service/rapla/rapla_response_parser_test.dart b/test/schedule/service/rapla/rapla_response_parser_test.dart index ced0b81d..deda5af1 100644 --- a/test/schedule/service/rapla/rapla_response_parser_test.dart +++ b/test/schedule/service/rapla/rapla_response_parser_test.dart @@ -114,7 +114,8 @@ Future main() async { expect(schedule.entries[0].end, DateTime(2021, 09, 22, 15, 00)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "A"); - expect(schedule.entries[0].room, "MOS-TINF19A,A 1.380 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00),A 1.390 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00)"); + expect(schedule.entries[0].room, + "MOS-TINF19A,A 1.380 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00),A 1.390 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00)"); expect(schedule.entries[2].title, "Tag der Deutschen Einheit"); expect(schedule.entries[2].start, DateTime(2021, 10, 03, 08, 00)); @@ -165,8 +166,7 @@ Future main() async { expect(schedule.entries.length, 20); }); - test('Rapla correctly read all classes of several months view 3', - () async { + test('Rapla correctly read all classes of several months view 3', () async { var parser = RaplaResponseParser(); var schedule = parser.parseSchedule(severalMonthsPage2).schedule; @@ -179,8 +179,7 @@ Future main() async { expect(schedule.entries.length, 36); }); - test('Rapla correctly read the day of a class in week view', - () async { + test('Rapla correctly read the day of a class in week view', () async { var parser = RaplaResponseParser(); var schedule = parser.parseSchedule(raplaPage1).schedule; @@ -190,55 +189,63 @@ Future main() async { expect(schedule.entries[0].end, DateTime(2021, 11, 02, 12, 15)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "Fr, Ta"); - expect(schedule.entries[0].room, "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)"); + expect(schedule.entries[0].room, + "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)"); - expect(schedule.entries[1].title, "Einführung in die Volkswirtschaftslehre und Mikroökonomik"); + expect(schedule.entries[1].title, + "Einführung in die Volkswirtschaftslehre und Mikroökonomik"); expect(schedule.entries[1].start, DateTime(2021, 11, 02, 13, 45)); expect(schedule.entries[1].end, DateTime(2021, 11, 02, 17, 00)); expect(schedule.entries[1].type, ScheduleEntryType.Class); expect(schedule.entries[1].professor, "Le, An"); - expect(schedule.entries[1].room, "WDCM21B,D221 W Hörsaal (Mo 11.10.21 09:00),G086 W Hörsaal (Mo 25.10.21 09:00, Mo 15.11.21 09:00),F218_1 PA Hörsaal (Mo 22.11.21 09:00, Mo 06.12.21 09:00),A167 W Hörsaal (Mo 29.11.21 09:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 13:45)"); + expect(schedule.entries[1].room, + "WDCM21B,D221 W Hörsaal (Mo 11.10.21 09:00),G086 W Hörsaal (Mo 25.10.21 09:00, Mo 15.11.21 09:00),F218_1 PA Hörsaal (Mo 22.11.21 09:00, Mo 06.12.21 09:00),A167 W Hörsaal (Mo 29.11.21 09:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 13:45)"); expect(schedule.entries[2].title, "Grundlagen des Bürgerlichen Rechts"); expect(schedule.entries[2].start, DateTime(2021, 11, 03, 09, 00)); expect(schedule.entries[2].end, DateTime(2021, 11, 03, 11, 30)); expect(schedule.entries[2].type, ScheduleEntryType.Class); expect(schedule.entries[2].professor, "Ei, An"); - expect(schedule.entries[2].room, "WDCM21B,XOnline-Veranstaltung A Virtueller Raum (Mi 13.10.21 09:00, Mi 27.10.21 09:00, Mi 10.11.21 09:00, Mi 24.11.21 09:00, Fr 03.12.21 10:00),D221 W Hörsaal (Mi 20.10.21 13:00, Mi 17.11.21 09:00),G086 W Hörsaal (Di 26.10.21 09:00, Mi 03.11.21 09:00),B354 W Hörsaal (Fr 03.12.21 10:00),F218_1 PA Hörsaal (Mi 08.12.21 09:00)"); + expect(schedule.entries[2].room, + "WDCM21B,XOnline-Veranstaltung A Virtueller Raum (Mi 13.10.21 09:00, Mi 27.10.21 09:00, Mi 10.11.21 09:00, Mi 24.11.21 09:00, Fr 03.12.21 10:00),D221 W Hörsaal (Mi 20.10.21 13:00, Mi 17.11.21 09:00),G086 W Hörsaal (Di 26.10.21 09:00, Mi 03.11.21 09:00),B354 W Hörsaal (Fr 03.12.21 10:00),F218_1 PA Hörsaal (Mi 08.12.21 09:00)"); expect(schedule.entries[3].title, "Technik der Finanzbuchführung I"); expect(schedule.entries[3].start, DateTime(2021, 11, 03, 13, 00)); expect(schedule.entries[3].end, DateTime(2021, 11, 03, 16, 15)); expect(schedule.entries[3].type, ScheduleEntryType.Class); expect(schedule.entries[3].professor, "Se, Ka"); - expect(schedule.entries[3].room, "WDCM21B,D221 W Hörsaal (Mi 17.11.21 13:00, Mi 06.10.21 13:00, Mi 13.10.21 13:00),G086 W Hörsaal (Mi 27.10.21 13:00, Mi 03.11.21 13:00, Mi 10.11.21 13:00),A167 W Hörsaal (Mi 24.11.21 13:00, Mi 01.12.21 14:00)"); + expect(schedule.entries[3].room, + "WDCM21B,D221 W Hörsaal (Mi 17.11.21 13:00, Mi 06.10.21 13:00, Mi 13.10.21 13:00),G086 W Hörsaal (Mi 27.10.21 13:00, Mi 03.11.21 13:00, Mi 10.11.21 13:00),A167 W Hörsaal (Mi 24.11.21 13:00, Mi 01.12.21 14:00)"); - expect(schedule.entries[4].title, "Grundlagen des wissenschaftlichen Arbeitens"); + expect(schedule.entries[4].title, + "Grundlagen des wissenschaftlichen Arbeitens"); expect(schedule.entries[4].start, DateTime(2021, 11, 04, 09, 00)); expect(schedule.entries[4].end, DateTime(2021, 11, 04, 12, 15)); expect(schedule.entries[4].type, ScheduleEntryType.Class); expect(schedule.entries[4].professor, "He, Be"); - expect(schedule.entries[4].room, "WDCM21B,D221 W Hörsaal (Di 05.10.21 09:00, Di 12.10.21 09:00),A167 W Hörsaal (Di 23.11.21 09:00),G086 W Hörsaal (Do 04.11.21 09:00)"); + expect(schedule.entries[4].room, + "WDCM21B,D221 W Hörsaal (Di 05.10.21 09:00, Di 12.10.21 09:00),A167 W Hörsaal (Di 23.11.21 09:00),G086 W Hörsaal (Do 04.11.21 09:00)"); expect(schedule.entries[5].title, "Grundlagen der Handelsbetriebslehre"); expect(schedule.entries[5].start, DateTime(2021, 11, 04, 12, 45)); expect(schedule.entries[5].end, DateTime(2021, 11, 04, 16, 00)); expect(schedule.entries[5].type, ScheduleEntryType.Class); expect(schedule.entries[5].professor, "Fr, Ta"); - expect(schedule.entries[5].room, "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)"); + expect(schedule.entries[5].room, + "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)"); expect(schedule.entries[6].title, "Einführung in die Programmierung"); expect(schedule.entries[6].start, DateTime(2021, 11, 05, 13, 00)); expect(schedule.entries[6].end, DateTime(2021, 11, 05, 16, 15)); expect(schedule.entries[6].type, ScheduleEntryType.Class); expect(schedule.entries[6].professor, "He, Ma"); - expect(schedule.entries[6].room, "WDCM21B,C348 PC Raum,D221 W Hörsaal (Fr 08.10.21 13:00, Fr 15.10.21 13:00, Fr 22.10.21 13:00),G086 W Hörsaal (Fr 29.10.21 13:00, Fr 05.11.21 13:00, Fr 12.11.21 13:00, Do 18.11.21 13:00),A167 W Hörsaal (Fr 26.11.21 13:00, Do 02.12.21 13:00)"); + expect(schedule.entries[6].room, + "WDCM21B,C348 PC Raum,D221 W Hörsaal (Fr 08.10.21 13:00, Fr 15.10.21 13:00, Fr 22.10.21 13:00),G086 W Hörsaal (Fr 29.10.21 13:00, Fr 05.11.21 13:00, Fr 12.11.21 13:00, Do 18.11.21 13:00),A167 W Hörsaal (Fr 26.11.21 13:00, Do 02.12.21 13:00)"); expect(schedule.entries.length, 7); }); - test('Rapla correctly read the week response', - () async { + test('Rapla correctly read the week response', () async { var parser = RaplaResponseParser(); var schedule = parser.parseSchedule(raplaWeekResponse).schedule; @@ -253,8 +260,7 @@ Future main() async { expect(schedule.entries.length, 6); }); - test('Rapla correctly read the week response 1', - () async { + test('Rapla correctly read the week response 1', () async { var parser = RaplaResponseParser(); var schedule = parser.parseSchedule(raplaWeekResponse1).schedule; @@ -264,7 +270,8 @@ Future main() async { expect(schedule.entries[0].end, DateTime(2021, 12, 13, 10, 00)); expect(schedule.entries[0].type, ScheduleEntryType.Exam); expect(schedule.entries[0].professor, "Man, R."); - expect(schedule.entries[0].room, "TEA20,H031, Hörsaal,N003, Hörsaal,N004, Hörsaal"); + expect(schedule.entries[0].room, + "TEA20,H031, Hörsaal,N003, Hörsaal,N004, Hörsaal"); expect(schedule.entries.length, 7); }); From 6f55f4670c8d9f6e267f813ebfbbca65f67c205f Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:40:37 +0200 Subject: [PATCH 05/37] add linting --- analysis_options.yaml | 27 +++++++++++++++++++++++++++ pubspec.lock | 4 ++-- pubspec.yaml | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 analysis_options.yaml diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 00000000..ba2dd286 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,27 @@ +# This file configures the analyzer to use the lint rule set from `package:lint` + +# For apps, use the default set +include: package:lint/analysis_options.yaml + +# Packages, that may be distributed (i.e. via pub.dev) should use the package +# version, resulting in a better pub score. +# include: package:lint/analysis_options_package.yaml + +# You might want to exclude auto-generated files from dart analysis +analyzer: + exclude: + #- '**.freezed.dart' + +# You can customize the lint rules set to your own liking. A list of all rules +# can be found at https://dart-lang.github.io/linter/lints/options/options.html +linter: + rules: + # Util classes are awesome! + # avoid_classes_with_only_static_members: false + + # Make constructors the first thing in every class + # sort_constructors_first: true + + # Choose wisely, but you don't have to + # prefer_double_quotes: true + # prefer_single_quotes: true \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 7a882907..117d42d7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -414,12 +414,12 @@ packages: source: hosted version: "3.0.1" lint: - dependency: transitive + dependency: "direct dev" description: name: lint url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.10.0" logging: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 3f04227c..3d070581 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,6 +55,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + lint: ^1.10.0 test: any From f99fddb3778c67c0bf8a936b031272142d0230b8 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:14:14 +0200 Subject: [PATCH 06/37] fix require_trailing_commas --- analysis_options.yaml | 12 +----- lib/common/appstart/app_initializer.dart | 2 +- .../appstart/localization_initialize.dart | 2 +- lib/common/appstart/service_injector.dart | 16 ++++---- .../background/background_work_scheduler.dart | 2 +- lib/common/data/database_access.dart | 8 ++-- .../preferences/preferences_provider.dart | 8 ++-- lib/common/iap/in_app_purchase_helper.dart | 2 +- lib/common/iap/in_app_purchase_manager.dart | 2 +- lib/common/logging/crash_reporting.dart | 2 +- lib/common/ui/donate_to_developer_dialog.dart | 2 +- lib/common/ui/notification_api.dart | 4 +- lib/common/ui/rate_in_store_dialog.dart | 2 +- lib/common/ui/widget_help_dialog.dart | 2 +- lib/common/ui/widgets/dots_indicator.dart | 2 +- lib/common/util/platform_util.dart | 2 +- .../business/date_entry_provider.dart | 2 +- lib/date_management/data/calendar_access.dart | 10 ++--- .../data/date_entry_repository.dart | 2 +- .../service/parsing/all_dates_extract.dart | 2 +- .../ui/calendar_export_page.dart | 16 ++++---- .../ui/date_management_page.dart | 8 ++-- .../calendar_export_view_model.dart | 2 +- .../date_management_view_model.dart | 4 +- .../ui/widgets/date_detail_bottom_sheet.dart | 2 +- .../ui/widgets/date_filter_options.dart | 14 +++---- lib/dualis/service/dualis_authentication.dart | 4 +- lib/dualis/service/dualis_scraper.dart | 2 +- lib/dualis/service/dualis_service.dart | 2 +- ...fake_account_dualis_scraper_decorator.dart | 6 +-- .../service/fake_data_dualis_scraper.dart | 8 ++-- .../exams_from_module_details_extract.dart | 2 +- ...dules_from_course_result_page_extract.dart | 2 +- ...sters_from_course_result_page_extract.dart | 4 +- .../exam_results_page/exam_results_page.dart | 16 ++++---- .../useful_information_page.dart | 8 ++-- lib/main.dart | 2 +- .../background/calendar_synchronizer.dart | 4 +- .../business/schedule_diff_calculator.dart | 12 +++--- lib/schedule/business/schedule_provider.dart | 12 +++--- lib/schedule/data/schedule_entry_entity.dart | 2 +- .../data/schedule_entry_repository.dart | 4 +- ...schedule_query_information_repository.dart | 6 +-- lib/schedule/model/schedule_entry.dart | 2 +- .../dualis/dualis_schedule_source.dart | 4 +- ...rror_report_schedule_source_decorator.dart | 2 +- .../service/ical/ical_schedule_source.dart | 2 +- .../isolate_schedule_source_decorator.dart | 4 +- .../mannheim_course_response_parser.dart | 2 +- .../mannheim/mannheim_course_scraper.dart | 4 +- .../service/rapla/rapla_parsing_utils.dart | 10 ++--- .../service/rapla/rapla_schedule_source.dart | 6 +-- lib/schedule/service/schedule_source.dart | 2 +- .../ui/dailyschedule/daily_schedule_page.dart | 4 +- .../widgets/daily_schedule_entry_widget.dart | 6 +-- .../next_day_information_notification.dart | 2 +- .../ui/schedule_navigation_entry.dart | 4 +- .../filter/filter_view_model.dart | 2 +- .../filter/schedule_filter_page.dart | 4 +- .../schedule_entry_detail_bottom_sheet.dart | 4 +- .../weeklyschedule/weekly_schedule_page.dart | 9 ++--- .../weeklyschedule/widgets/schedule_grid.dart | 4 +- .../widgets/schedule_past_overlay.dart | 2 +- .../widgets/schedule_widget.dart | 8 ++-- lib/schedule/ui/widgets/enter_url_dialog.dart | 2 +- lib/ui/banner_widget.dart | 2 +- lib/ui/main_page.dart | 2 +- lib/ui/navigation_drawer.dart | 2 +- lib/ui/onboarding/onboarding_page.dart | 2 +- .../viewmodels/onboarding_view_model.dart | 2 +- .../onboarding/widgets/dualis_login_page.dart | 6 +-- lib/ui/onboarding/widgets/ical_url_page.dart | 2 +- lib/ui/onboarding/widgets/mannheim_page.dart | 4 +- lib/ui/onboarding/widgets/rapla_url_page.dart | 2 +- .../widgets/select_source_page.dart | 2 +- lib/ui/settings/settings_page.dart | 14 +++---- .../viewmodels/settings_view_model.dart | 2 +- .../parsing/all_dates_extract_test.dart | 2 +- .../parsing/all_modules_extract_test.dart | 2 +- .../parsing/dualis_timeout_extract_test.dart | 4 +- ...xams_from_module_details_extract_test.dart | 2 +- ..._from_course_result_page_extract_test.dart | 6 +-- .../monthly_schedule_extract_test.dart | 2 +- ..._from_course_result_page_extract_test.dart | 6 +-- ...rom_student_results_page_extract_test.dart | 2 +- .../urls_from_main_page_extract_test.dart | 8 ++-- test/rapla_service_test.dart | 2 +- .../service/ical/ical_parser_test.dart | 2 +- .../mannheim_course_response_parser_test.dart | 2 +- .../rapla/rapla_response_parser_test.dart | 40 +++++++++---------- 90 files changed, 215 insertions(+), 224 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index ba2dd286..113936f3 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,7 +1,7 @@ # This file configures the analyzer to use the lint rule set from `package:lint` # For apps, use the default set -include: package:lint/analysis_options.yaml +#include: package:lint/analysis_options.yaml # Packages, that may be distributed (i.e. via pub.dev) should use the package # version, resulting in a better pub score. @@ -16,12 +16,4 @@ analyzer: # can be found at https://dart-lang.github.io/linter/lints/options/options.html linter: rules: - # Util classes are awesome! - # avoid_classes_with_only_static_members: false - - # Make constructors the first thing in every class - # sort_constructors_first: true - - # Choose wisely, but you don't have to - # prefer_double_quotes: true - # prefer_single_quotes: true \ No newline at end of file + require_trailing_commas: true diff --git a/lib/common/appstart/app_initializer.dart b/lib/common/appstart/app_initializer.dart index 98cebdd0..8de25aeb 100644 --- a/lib/common/appstart/app_initializer.dart +++ b/lib/common/appstart/app_initializer.dart @@ -65,7 +65,7 @@ Future initializeApp(bool isBackground) async { CalendarSynchronizer calendarSynchronizer = new CalendarSynchronizer( KiwiContainer().resolve(), KiwiContainer().resolve(), - KiwiContainer().resolve()); + KiwiContainer().resolve(),); calendarSynchronizer.registerSynchronizationCallback(); calendarSynchronizer.scheduleSyncInAFewSeconds(); diff --git a/lib/common/appstart/localization_initialize.dart b/lib/common/appstart/localization_initialize.dart index 37d772b1..2a35404a 100644 --- a/lib/common/appstart/localization_initialize.dart +++ b/lib/common/appstart/localization_initialize.dart @@ -26,7 +26,7 @@ class LocalizationInitialize { var localization = L(Locale( _languageCode ?? (await _preferencesProvider?.getLastUsedLanguageCode() ?? "en"), - )); + ),); KiwiContainer().registerInstance(localization); } } diff --git a/lib/common/appstart/service_injector.dart b/lib/common/appstart/service_injector.dart index 3d3f6bc9..a6c73883 100644 --- a/lib/common/appstart/service_injector.dart +++ b/lib/common/appstart/service_injector.dart @@ -32,30 +32,30 @@ void injectServices(bool isBackground) { c.registerInstance(PreferencesProvider( PreferencesAccess(), SecureStorageAccess(), - )); + ),); c.registerInstance(DatabaseAccess()); c.registerInstance(ScheduleEntryRepository( c.resolve(), - )); + ),); c.registerInstance(ScheduleFilterRepository( c.resolve(), - )); + ),); c.registerInstance(ScheduleQueryInformationRepository( c.resolve(), - )); + ),); c.registerInstance(ScheduleSourceProvider( c.resolve(), isBackground, c.resolve(), c.resolve(), - )); + ),); c.registerInstance(ScheduleProvider( c.resolve(), c.resolve(), c.resolve(), c.resolve(), c.resolve(), - )); + ),); c.registerInstance( FakeAccountDualisScraperDecorator(DualisScraper()), ); @@ -63,11 +63,11 @@ void injectServices(bool isBackground) { DualisServiceImpl( c.resolve(), ), - )); + ),); c.registerInstance(DateEntryProvider( DateManagementService(), DateEntryRepository(c.resolve()), - )); + ),); c.registerInstance(WidgetHelper()); c.registerInstance(ListDateEntries30d(List.empty(growable: true))); diff --git a/lib/common/background/background_work_scheduler.dart b/lib/common/background/background_work_scheduler.dart index 76f6e14f..482e5f83 100644 --- a/lib/common/background/background_work_scheduler.dart +++ b/lib/common/background/background_work_scheduler.dart @@ -23,7 +23,7 @@ class BackgroundWorkScheduler extends WorkSchedulerService { /// @override Future scheduleOneShotTaskIn( - Duration delay, String id, String name) async { + Duration delay, String id, String name,) async { print( "Scheduling one shot task: $id. With a delay of ${delay.inMinutes} minutes.", ); diff --git a/lib/common/data/database_access.dart b/lib/common/data/database_access.dart index 6b8a3851..73161621 100644 --- a/lib/common/data/database_access.dart +++ b/lib/common/data/database_access.dart @@ -18,7 +18,7 @@ class DatabaseAccess { return await openDatabase(path, version: SqlScripts.databaseMigrationScripts.length, onCreate: _onCreate, - onUpgrade: _onUpgrade); + onUpgrade: _onUpgrade,); } Future _onCreate(Database db, int version) async { @@ -51,7 +51,7 @@ class DatabaseAccess { } Future>> rawQuery( - String sql, List parameters) async { + String sql, List parameters,) async { Database db = await _database; return await db.rawQuery(sql, parameters); } @@ -65,7 +65,7 @@ class DatabaseAccess { String? having, String? orderBy, int? limit, - int? offset}) async { + int? offset,}) async { Database db = await _database; // TODO: [Leptopoda] is there a reason this is done? or at maybe use whereArgs.removeWhere() @@ -90,7 +90,7 @@ class DatabaseAccess { Future queryRowCount(String table) async { Database db = await _database; return Sqflite.firstIntValue( - await db.rawQuery('SELECT COUNT(*) FROM $table')); + await db.rawQuery('SELECT COUNT(*) FROM $table'),); } Future queryAggregator(String query, List arguments) async { diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index 61533ddd..5a551ca6 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -61,7 +61,7 @@ class PreferencesProvider { Future setSelectedCalendar(Calendar? selectedCalendar) async { final selectedCalendarId = selectedCalendar?.id ?? ""; await _preferencesAccess.set( - 'SelectedCalendarId', selectedCalendarId); + 'SelectedCalendarId', selectedCalendarId,); } Future getSelectedCalendar() async { @@ -73,7 +73,7 @@ class PreferencesProvider { await CalendarAccess().queryWriteableCalendars(); availableCalendars.forEach((cal) => { if (cal.id == selectedCalendarId) {selectedCalendar = cal} - }); + },); return selectedCalendar; } @@ -162,7 +162,7 @@ class PreferencesProvider { Future setLastViewedSemester(String? lastViewedSemester) async { if (lastViewedSemester == null) return; await _preferencesAccess.set( - LastViewedSemester, lastViewedSemester); + LastViewedSemester, lastViewedSemester,); } Future getLastViewedDateEntryDatabase() async { @@ -171,7 +171,7 @@ class PreferencesProvider { Future setLastViewedDateEntryDatabase(String? value) async { await _preferencesAccess.set( - LastViewedDateEntryDatabase, value ?? ""); + LastViewedDateEntryDatabase, value ?? "",); } Future getLastViewedDateEntryYear() async { diff --git a/lib/common/iap/in_app_purchase_helper.dart b/lib/common/iap/in_app_purchase_helper.dart index 3d9d50cd..631c168a 100644 --- a/lib/common/iap/in_app_purchase_helper.dart +++ b/lib/common/iap/in_app_purchase_helper.dart @@ -194,7 +194,7 @@ class InAppPurchaseHelper { if (!await _preferencesProvider.getHasPurchasedSomething()) { print( - "Abort complete pending purchases, the user did not buy something in the past"); + "Abort complete pending purchases, the user did not buy something in the past",); return; } diff --git a/lib/common/iap/in_app_purchase_manager.dart b/lib/common/iap/in_app_purchase_manager.dart index 75b7d540..af6781ae 100644 --- a/lib/common/iap/in_app_purchase_manager.dart +++ b/lib/common/iap/in_app_purchase_manager.dart @@ -63,7 +63,7 @@ class InAppPurchaseManager { // TODO: [Leptopoda] better nullseafety void _purchaseCompletedCallback( - String? productId, PurchaseResultEnum result) { + String? productId, PurchaseResultEnum result,) { if (purchaseCallbacks.containsKey(productId)) { var callback = purchaseCallbacks[productId!]; diff --git a/lib/common/logging/crash_reporting.dart b/lib/common/logging/crash_reporting.dart index 0e863cfa..b3d7d1f3 100644 --- a/lib/common/logging/crash_reporting.dart +++ b/lib/common/logging/crash_reporting.dart @@ -7,6 +7,6 @@ Future reportException(ex, StackTrace? trace) async { await FirebaseCrashlytics.instance.recordError(ex, trace); } else { print( - "Did not report exception (not in release mode) to crashlytics: $ex with stack trace $trace"); + "Did not report exception (not in release mode) to crashlytics: $ex with stack trace $trace",); } } diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index f38ee705..541a2a32 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -53,7 +53,7 @@ class DonateToDeveloperDialog { ), ), ], - )), + ),), Padding( padding: const EdgeInsets.fromLTRB(24, 0, 24, 0), child: _buildButtonBar(context), diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index ae714d84..88a8201e 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -73,7 +73,7 @@ class NotificationApi { } Future onDidReceiveLocalNotification( - int id, String? title, String? body, String? payload) => + int id, String? title, String? body, String? payload,) => Future.value(); Future selectNotification(String? payload) => Future.value(); @@ -94,7 +94,7 @@ class VoidNotificationApi implements NotificationApi { @override Future onDidReceiveLocalNotification( - int id, String? title, String? body, String? payload) { + int id, String? title, String? body, String? payload,) { return Future.value(); } diff --git a/lib/common/ui/rate_in_store_dialog.dart b/lib/common/ui/rate_in_store_dialog.dart index 76f66cb5..cbdff89e 100644 --- a/lib/common/ui/rate_in_store_dialog.dart +++ b/lib/common/ui/rate_in_store_dialog.dart @@ -89,7 +89,7 @@ class RateInStoreDialog { await analytics.logEvent(name: "rateLater"); await _preferencesProvider.setNextRateInStoreLaunchCount( - RateInStoreLaunchAfter + _appLaunchCounter); + RateInStoreLaunchAfter + _appLaunchCounter,); } Future _rateNow() async { diff --git a/lib/common/ui/widget_help_dialog.dart b/lib/common/ui/widget_help_dialog.dart index 085c9ee7..06acfe48 100644 --- a/lib/common/ui/widget_help_dialog.dart +++ b/lib/common/ui/widget_help_dialog.dart @@ -38,7 +38,7 @@ class WidgetHelpDialog { children: [ Padding( padding: const EdgeInsets.all(24), - child: Text(L.of(context).widgetHelpDialogMessage)), + child: Text(L.of(context).widgetHelpDialogMessage),), Padding( padding: const EdgeInsets.fromLTRB(24, 0, 24, 0), child: _buildButtonBar(context), diff --git a/lib/common/ui/widgets/dots_indicator.dart b/lib/common/ui/widgets/dots_indicator.dart index abcf6f5f..d7171f7f 100644 --- a/lib/common/ui/widgets/dots_indicator.dart +++ b/lib/common/ui/widgets/dots_indicator.dart @@ -5,7 +5,7 @@ class DotsIndicator extends StatelessWidget { final int currentStep; const DotsIndicator( - {Key? key, required this.numberSteps, required this.currentStep}) + {Key? key, required this.numberSteps, required this.currentStep,}) : super(key: key); @override diff --git a/lib/common/util/platform_util.dart b/lib/common/util/platform_util.dart index a015d709..f55954bf 100644 --- a/lib/common/util/platform_util.dart +++ b/lib/common/util/platform_util.dart @@ -25,7 +25,7 @@ class PlatformUtil { static Future initializePortraitLandscapeMode() async { if (isPhone()) { await SystemChrome.setPreferredOrientations( - [DeviceOrientation.portraitUp]); + [DeviceOrientation.portraitUp],); } else { await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, diff --git a/lib/date_management/business/date_entry_provider.dart b/lib/date_management/business/date_entry_provider.dart index 05807f28..d5dc3e81 100644 --- a/lib/date_management/business/date_entry_provider.dart +++ b/lib/date_management/business/date_entry_provider.dart @@ -73,7 +73,7 @@ class DateEntryProvider { } List _filterDates( - List updatedEntries, DateSearchParameters parameters) { + List updatedEntries, DateSearchParameters parameters,) { var filteredDateEntries = []; var now = DateTime.now(); diff --git a/lib/date_management/data/calendar_access.dart b/lib/date_management/data/calendar_access.dart index cf6c852c..150cf779 100644 --- a/lib/date_management/data/calendar_access.dart +++ b/lib/date_management/data/calendar_access.dart @@ -63,7 +63,7 @@ class CalendarAccess { } Future _addOrUpdateEntry( - List existingEvents, DateEntry entry, Calendar calendar) async { + List existingEvents, DateEntry entry, Calendar calendar,) async { // Find the id in the existing events in order that the "update" part of // createOrUpdateEvent(...) works var id = _getIdOfExistingEvent(existingEvents, entry); @@ -88,14 +88,14 @@ class CalendarAccess { allDay: isAllDay, start: tz.TZDateTime.from(start, tz.getLocation('Europe/Berlin')), end: tz.TZDateTime.from(end, tz.getLocation('Europe/Berlin')), - )); + ),); } String? _getIdOfExistingEvent(List existingEvents, DateEntry entry) { var existingEvent = existingEvents .where((element) => (element.title == entry.description && (element.start?.toUtc().isAtSameMomentAs(entry.start.toUtc()) ?? - false))) + false)),) .toList(); String? id; @@ -106,7 +106,7 @@ class CalendarAccess { } Future> _getExistingEventsFromCalendar( - List dateEntries, Calendar calendar) async { + List dateEntries, Calendar calendar,) async { var firstEntry = _findFirstEntry(dateEntries); var lastEntry = _findLastEntry(dateEntries); @@ -115,7 +115,7 @@ class CalendarAccess { RetrieveEventsParams( startDate: firstEntry.start, endDate: lastEntry.end, - )); + ),); var existingEvents = []; diff --git a/lib/date_management/data/date_entry_repository.dart b/lib/date_management/data/date_entry_repository.dart index 7fc21c7b..37f279bb 100644 --- a/lib/date_management/data/date_entry_repository.dart +++ b/lib/date_management/data/date_entry_repository.dart @@ -96,7 +96,7 @@ class DateEntryRepository { whereArgs: [ databaseName, year, - ]); + ],); } List _rowsToDateEntries(List> rows) { diff --git a/lib/date_management/service/parsing/all_dates_extract.dart b/lib/date_management/service/parsing/all_dates_extract.dart index 828c75bb..7bf71014 100644 --- a/lib/date_management/service/parsing/all_dates_extract.dart +++ b/lib/date_management/service/parsing/all_dates_extract.dart @@ -62,7 +62,7 @@ class AllDatesExtract { year: parts[1].trim(), databaseName: databaseName, start: date, - end: date); + end: date,); } DateTime? _parseDateTime(String date, String time) { diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 9a439d32..3783fbe6 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -18,7 +18,7 @@ class CalendarExportPage extends StatefulWidget { {Key? key, required this.entriesToExport, this.isCalendarSyncWidget = false, - this.isCalendarSyncEnabled = false}) + this.isCalendarSyncEnabled = false,}) : super(key: key); @override @@ -33,7 +33,7 @@ class _CalendarExportPageState extends State { super.initState(); viewModel = CalendarExportViewModel(widget.entriesToExport, - CalendarAccess(), KiwiContainer().resolve()); + CalendarAccess(), KiwiContainer().resolve(),); viewModel.setOnPermissionDeniedCallback(() { Navigator.of(context).pop(); }); @@ -52,7 +52,7 @@ class _CalendarExportPageState extends State { iconTheme: Theme.of(context).iconTheme, title: Text(widget.isCalendarSyncWidget ? L.of(context).calendarSyncPageTitle - : L.of(context).dateManagementExportToCalendar), + : L.of(context).dateManagementExportToCalendar,), toolbarTextStyle: Theme.of(context).textTheme.bodyText2, titleTextStyle: Theme.of(context).textTheme.headline6, ), @@ -64,7 +64,7 @@ class _CalendarExportPageState extends State { alignment: Alignment.centerLeft, child: Text(widget.isCalendarSyncWidget ? L.of(context).calendarSyncPageSubtitle - : L.of(context).dateManagementExportToCalendarDescription), + : L.of(context).dateManagementExportToCalendarDescription,), ), ), _buildCalendarList(), @@ -120,7 +120,7 @@ class _CalendarExportPageState extends State { color: widget.isCalendarSyncEnabled ? ColorPalettes.main : Theme.of(context).disabledColor, - fontSize: 14), + fontSize: 14,), ), onTap: () async { KiwiContainer() @@ -192,12 +192,12 @@ class _CalendarExportPageState extends State { child: SizedBox( height: 32, width: 32, - child: CircularProgressIndicator()), + child: CircularProgressIndicator(),), ) : Container( decoration: !viewModel.canExport ? new BoxDecoration( - color: Theme.of(context).colorScheme.background) + color: Theme.of(context).colorScheme.background,) : new BoxDecoration( color: Theme.of(context).colorScheme.primary, ), @@ -229,7 +229,7 @@ class _CalendarExportPageState extends State { var preferencesProvider = KiwiContainer() .resolve(); preferencesProvider.setSelectedCalendar( - viewModel.selectedCalendar); + viewModel.selectedCalendar,); preferencesProvider .setIsCalendarSyncEnabled(true); } diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index 3e2d124a..13f5cb38 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -29,7 +29,7 @@ class DateManagementPage extends StatelessWidget { duration: const Duration(milliseconds: 200), child: viewModel.isLoading ? const LinearProgressIndicator() - : Container()), + : Container(),), ], ), _buildBody(viewModel, context), @@ -59,7 +59,7 @@ class DateManagementPage extends StatelessWidget { children: [ _buildAllDatesDataTable(model!, context), ], - )), + ),), ), ), Align( @@ -133,7 +133,7 @@ class DateManagementPage extends StatelessWidget { ], ), onTap: () { showDateEntryDetailBottomSheet(context, dateEntry); - }), + },), ], ), ); @@ -161,7 +161,7 @@ class DateManagementPage extends StatelessWidget { "updateFailed", ], builder: (BuildContext context, DateManagementViewModel? model, - Set? properties) => + Set? properties,) => ErrorDisplay( show: model!.updateFailed, ), diff --git a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart index b4f9a78a..912f6321 100644 --- a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart +++ b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart @@ -25,7 +25,7 @@ class CalendarExportViewModel extends BaseViewModel { bool get isExporting => _isExporting; CalendarExportViewModel( - this._entriesToExport, this.calendarAccess, this.preferencesProvider) { + this._entriesToExport, this.calendarAccess, this.preferencesProvider,) { loadCalendars(); } diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index 87c1437c..83e24adb 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -18,7 +18,7 @@ class DateManagementViewModel extends BaseViewModel { DateDatabase("BWL-Bank", "Termine_BWL_Bank"), DateDatabase("Immobilienwirtschaft", "Termine_BWL_Immo"), DateDatabase( - "Dienstleistungsmanagement Consulting & Sales", "Termine_DLM_Consult"), + "Dienstleistungsmanagement Consulting & Sales", "Termine_DLM_Consult",), DateDatabase("Dienstleistungsmanagement Logistik", "Termine_DLM_Logistik"), DateDatabase("Campus Horb Informatik", "Termine_Horb_INF"), DateDatabase("Campus Horb Maschinenbau", "Termine_Horb_MB"), @@ -26,7 +26,7 @@ class DateManagementViewModel extends BaseViewModel { DateDatabase("Informatik", "Termine_Informatik"), DateDatabase("MUK (DLM - C&S, LogM, MUK)", "Termine_MUK"), DateDatabase("SO_GuO (Abweichungen und Ergänzungen zum Vorlesungsplan)", - "Termine_SO_GuO"), + "Termine_SO_GuO",), DateDatabase("Wirtschaftsingenieurwesen", "Termine_WIW"), ]; List get allDateDatabases => _allDateDatabases; diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index 981ab641..a7d8daca 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -33,7 +33,7 @@ class DateDetailBottomSheet extends StatelessWidget { width: 30, decoration: BoxDecoration( color: colorSeparator(), - borderRadius: const BorderRadius.all(Radius.circular(4))), + borderRadius: const BorderRadius.all(Radius.circular(4)),), child: null, ), ), diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index 1eaf161a..3710648f 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -82,24 +82,24 @@ class _DateFilterOptionsState extends State { chips.add(Chip( label: Text(L.of(context).dateManagementChipFutureAndPast), visualDensity: VisualDensity.compact, - )); + ),); } else if (widget.viewModel.showFutureDates) { chips.add(Chip( label: Text(L.of(context).dateManagementChipOnlyFuture), visualDensity: VisualDensity.compact, - )); + ),); } else if (widget.viewModel.showPassedDates) { chips.add(Chip( label: Text(L.of(context).dateManagementChipOnlyPassed), visualDensity: VisualDensity.compact, - )); + ),); } if (widget.viewModel.currentSelectedYear != null) { chips.add(Chip( label: Text(widget.viewModel.currentSelectedYear!), visualDensity: VisualDensity.compact, - )); + ),); } var database = widget.viewModel.currentDateDatabase?.displayName ?? ""; @@ -107,7 +107,7 @@ class _DateFilterOptionsState extends State { chips.add(Chip( label: Text(database), visualDensity: VisualDensity.compact, - )); + ),); } return Padding( @@ -216,7 +216,7 @@ class _DateFilterOptionsState extends State { yearMenuItems.add(DropdownMenuItem( child: Text(year), value: year, - )); + ),); } return yearMenuItems; } @@ -228,7 +228,7 @@ class _DateFilterOptionsState extends State { databaseMenuItems.add(DropdownMenuItem( child: Text(database.displayName), value: database, - )); + ),); } return databaseMenuItems; } diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index b7d681ac..be8a0569 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -197,7 +197,7 @@ class DualisAuthentication { var match = _tokenRegex.firstMatch(url); if (match != null) { return url.replaceRange( - match.start, match.end, "ARGUMENTS=-N$_authToken"); + match.start, match.end, "ARGUMENTS=-N$_authToken",); } return url; @@ -208,7 +208,7 @@ class DualisAuthentication { } Future loginWithPreviousCredentials( - CancellationToken cancellationToken) async { + CancellationToken cancellationToken,) async { assert(_credentials != null); return await login(_credentials!, cancellationToken); } diff --git a/lib/dualis/service/dualis_scraper.dart b/lib/dualis/service/dualis_scraper.dart index b217200b..0f10b538 100644 --- a/lib/dualis/service/dualis_scraper.dart +++ b/lib/dualis/service/dualis_scraper.dart @@ -99,7 +99,7 @@ class DualisScraper { "${_dualisUrls.monthlyScheduleUrl}01.${dateInMonth.month}.${dateInMonth.year}"; var result = await _dualisAuthentication.authenticatedGet( - requestUrl, cancellationToken); + requestUrl, cancellationToken,); var schedule = MonthlyScheduleExtract().extractScheduleFromMonthly(result); diff --git a/lib/dualis/service/dualis_service.dart b/lib/dualis/service/dualis_service.dart index a830cbf9..c9ae673b 100644 --- a/lib/dualis/service/dualis_service.dart +++ b/lib/dualis/service/dualis_service.dart @@ -94,7 +94,7 @@ class DualisServiceImpl extends DualisService { module.credits, module.finalGrade, module.state, - )); + ),); } return modules; } diff --git a/lib/dualis/service/fake_account_dualis_scraper_decorator.dart b/lib/dualis/service/fake_account_dualis_scraper_decorator.dart index fddbbce8..a493ce0d 100644 --- a/lib/dualis/service/fake_account_dualis_scraper_decorator.dart +++ b/lib/dualis/service/fake_account_dualis_scraper_decorator.dart @@ -33,7 +33,7 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { @override Future> loadAllModules( - [CancellationToken? cancellationToken]) { + [CancellationToken? cancellationToken,]) { return _currentDualisScraper.loadAllModules(); } @@ -72,7 +72,7 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { @override Future> loadSemesters( - [CancellationToken? cancellationToken]) { + [CancellationToken? cancellationToken,]) { return _currentDualisScraper.loadSemesters(cancellationToken); } @@ -99,7 +99,7 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { @override Future loginWithPreviousCredentials( - CancellationToken cancellationToken) { + CancellationToken cancellationToken,) { return _currentDualisScraper.loginWithPreviousCredentials( cancellationToken, ); diff --git a/lib/dualis/service/fake_data_dualis_scraper.dart b/lib/dualis/service/fake_data_dualis_scraper.dart index 56de36b8..acc20f69 100644 --- a/lib/dualis/service/fake_data_dualis_scraper.dart +++ b/lib/dualis/service/fake_data_dualis_scraper.dart @@ -21,7 +21,7 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadAllModules( - [CancellationToken? cancellationToken]) async { + [CancellationToken? cancellationToken,]) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value([ @@ -82,14 +82,14 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadSemesters( - [CancellationToken? cancellationToken]) async { + [CancellationToken? cancellationToken,]) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value([DualisSemester("SoSe2020", "", [])]); } @override Future loadStudyGrades( - CancellationToken? cancellationToken) async { + CancellationToken? cancellationToken,) async { await Future.delayed(Duration(milliseconds: 200)); return Future.value( StudyGrades( @@ -113,7 +113,7 @@ class FakeDataDualisScraper implements DualisScraper { @override Future loginWithPreviousCredentials( - CancellationToken cancellationToken) async { + CancellationToken cancellationToken,) async { await Future.delayed(Duration(milliseconds: 200)); _isLoggedIn = true; return Future.value(LoginResult.LoggedIn); diff --git a/lib/dualis/service/parsing/exams_from_module_details_extract.dart b/lib/dualis/service/parsing/exams_from_module_details_extract.dart index d90f79e0..3c269d37 100644 --- a/lib/dualis/service/parsing/exams_from_module_details_extract.dart +++ b/lib/dualis/service/parsing/exams_from_module_details_extract.dart @@ -54,7 +54,7 @@ class ExamsFromModuleDetailsExtract { ExamGrade.fromString(grade), trimAndEscapeString(currentTry), trimAndEscapeString(semester), - )); + ),); } return exams; diff --git a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart index baa53cb0..ce6dc8ba 100644 --- a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart @@ -20,7 +20,7 @@ class ModulesFromCourseResultPageExtract { } List _extractModulesFromCourseResultPage( - String? body, String endpointUrl) { + String? body, String endpointUrl,) { var document = parse(body); var tableBodies = getElementByTagName(document, "tbody"); diff --git a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart index 2ce424b7..ee3b277e 100644 --- a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart @@ -17,7 +17,7 @@ class SemestersFromCourseResultPageExtract { } List _extractSemestersFromCourseResults( - String? body, String endpointUrl) { + String? body, String endpointUrl,) { var page = parse(body); var semesterSelector = page.getElementById("semester"); @@ -43,7 +43,7 @@ class SemestersFromCourseResultPageExtract { name, detailsUrl, [], - )); + ),); } return semesters; diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index 25f09e4f..4cccde67 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -79,7 +79,7 @@ class ExamResultsPage extends StatelessWidget { } Widget buildModulesColumn( - BuildContext context, StudyGradesViewModel viewModel) { + BuildContext context, StudyGradesViewModel viewModel,) { return AnimatedSwitcher( layoutBuilder: (Widget? currentChild, List previousChildren) { List children = previousChildren; @@ -99,7 +99,7 @@ class ExamResultsPage extends StatelessWidget { } List buildModulesDataTables( - BuildContext context, StudyGradesViewModel viewModel) { + BuildContext context, StudyGradesViewModel viewModel,) { var dataTables = []; var isFirstModule = true; @@ -111,8 +111,8 @@ class ExamResultsPage extends StatelessWidget { headingRowHeight: 65, rows: buildModuleDataRows(context, module), columns: buildModuleColumns(context, module, - displayGradeHeader: isFirstModule), - )); + displayGradeHeader: isFirstModule,), + ),); isFirstModule = false; } return dataTables; @@ -139,12 +139,12 @@ class ExamResultsPage extends StatelessWidget { textScaleFactor: exam.semester == "" ? 0 : 1, ), ], - )), + ),), DataCell.empty, DataCell(Padding( padding: const EdgeInsets.fromLTRB(0, 0, 16, 0), child: _examGradeToWidget(context, exam.grade), - )), + ),), ], ), ); @@ -166,7 +166,7 @@ class ExamResultsPage extends StatelessWidget { } List buildModuleColumns(BuildContext context, var module, - {var displayGradeHeader = false}) { + {var displayGradeHeader = false,}) { var displayWidth = MediaQuery.of(context).size.width; if (!PlatformUtil.isPortrait(context) && PlatformUtil.isTablet()) { @@ -205,7 +205,7 @@ class ExamResultsPage extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(0, 0, 10, 16), child: Text( - "${L.of(context).dualisExamResultsCreditsColumnHeader}: ${module.credits}"), + "${L.of(context).dualisExamResultsCreditsColumnHeader}: ${module.credits}",), ), ), ), diff --git a/lib/information/ui/usefulinformation/useful_information_page.dart b/lib/information/ui/usefulinformation/useful_information_page.dart index d480dd32..316d5b3b 100644 --- a/lib/information/ui/usefulinformation/useful_information_page.dart +++ b/lib/information/ui/usefulinformation/useful_information_page.dart @@ -27,7 +27,7 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageRoundcube), onTap: () { openLink( - "https://lehre-webmail.dhbw-stuttgart.de/roundcubemail/"); + "https://lehre-webmail.dhbw-stuttgart.de/roundcubemail/",); }, ), ListTile( @@ -42,7 +42,7 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageLocation), onTap: () { openLink( - "https://www.dhbw-stuttgart.de/themen/hochschule/standorte/"); + "https://www.dhbw-stuttgart.de/themen/hochschule/standorte/",); }, ), ListTile( @@ -50,7 +50,7 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageEduroam), onTap: () { openLink( - "https://www.dhbw-stuttgart.de/themen/einrichtungen/itservice-center/informationen-fuer-studierende/wlan-vpn-zugang/"); + "https://www.dhbw-stuttgart.de/themen/einrichtungen/itservice-center/informationen-fuer-studierende/wlan-vpn-zugang/",); }, ), ListTile( @@ -65,7 +65,7 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageDHBWSports), onTap: () { openLink( - "https://www.dhbw-stuttgart.de/themen/einrichtungen/hochschulsport/"); + "https://www.dhbw-stuttgart.de/themen/einrichtungen/hochschulsport/",); }, ), ], diff --git a/lib/main.dart b/lib/main.dart index 592e5ad7..f82cfb57 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -28,7 +28,7 @@ void main() async { runApp(RootPage( rootViewModel: await loadRootViewModel(), - )); + ),); } /// diff --git a/lib/schedule/background/calendar_synchronizer.dart b/lib/schedule/background/calendar_synchronizer.dart index f67ef0b4..c3a7e590 100644 --- a/lib/schedule/background/calendar_synchronizer.dart +++ b/lib/schedule/background/calendar_synchronizer.dart @@ -13,7 +13,7 @@ class CalendarSynchronizer { final PreferencesProvider preferencesProvider; CalendarSynchronizer(this.scheduleProvider, this.scheduleSourceProvider, - this.preferencesProvider); + this.preferencesProvider,); void registerSynchronizationCallback() { scheduleProvider.addScheduleUpdatedCallback((schedule, start, end) async { @@ -27,7 +27,7 @@ class CalendarSynchronizer { description: element.title, year: element.start.year.toString(), start: element.start, - end: element.end); + end: element.end,); listDateEntries.add(date); }, ); diff --git a/lib/schedule/business/schedule_diff_calculator.dart b/lib/schedule/business/schedule_diff_calculator.dart index c8be9661..6c4d8fa2 100644 --- a/lib/schedule/business/schedule_diff_calculator.dart +++ b/lib/schedule/business/schedule_diff_calculator.dart @@ -14,14 +14,14 @@ class ScheduleDiffCalculator { for (var entry in oldEntries) { if (!newEntries.any((ScheduleEntry element) => - _areScheduleEntriesEqual(element, entry))) { + _areScheduleEntriesEqual(element, entry),)) { removedEntries.add(entry); } } for (var entry in newEntries) { if (!oldEntries.any((ScheduleEntry element) => - _areScheduleEntriesEqual(element, entry))) { + _areScheduleEntriesEqual(element, entry),)) { addedEntries.add(entry); } } @@ -89,7 +89,7 @@ class ScheduleDiffCalculator { updatedEntries.add(UpdatedEntry( newElementsWithName[0], newElementsWithName[0].getDifferentProperties(oldElementsWithName[0]), - )); + ),); continue; } @@ -117,7 +117,7 @@ class ScheduleDiffCalculator { List newElementsWithName, List updatedEntries, List oldEntries, - List newEntries) { + List newEntries,) { if (oldElementsWithName.length == newElementsWithName.length) { for (var oldElement in oldElementsWithName) { ScheduleEntry nearestElement = @@ -144,7 +144,7 @@ class ScheduleDiffCalculator { } ScheduleEntry _findNearestElementByStart( - List elements, ScheduleEntry reference) { + List elements, ScheduleEntry reference,) { ScheduleEntry nearestElement = elements[0]; Duration minimalDifference = reference.start.difference(nearestElement.start).abs(); @@ -169,7 +169,7 @@ class ScheduleDiff { ScheduleDiff( {required this.addedEntries, required this.removedEntries, - required this.updatedEntries}); + required this.updatedEntries,}); bool didSomethingChange() { return addedEntries.isNotEmpty || diff --git a/lib/schedule/business/schedule_provider.dart b/lib/schedule/business/schedule_provider.dart index 0dee19a6..56ac7161 100644 --- a/lib/schedule/business/schedule_provider.dart +++ b/lib/schedule/business/schedule_provider.dart @@ -43,7 +43,7 @@ class ScheduleProvider { this._scheduleEntryRepository, this._scheduleQueryInformationRepository, this._preferencesProvider, - this._scheduleFilterRepository) { + this._scheduleFilterRepository,) { _scheduleFilter = ScheduleFilter(_scheduleFilterRepository); } @@ -52,12 +52,12 @@ class ScheduleProvider { await _scheduleEntryRepository.queryScheduleBetweenDates(start, end); print( - "Read chached schedule with ${cachedSchedule.entries.length.toString()} entries"); + "Read chached schedule with ${cachedSchedule.entries.length.toString()} entries",); cachedSchedule = await _scheduleFilter.filter(cachedSchedule); print( - "Filtered cached schedule has ${cachedSchedule.entries.length} entries"); + "Filtered cached schedule has ${cachedSchedule.entries.length} entries",); return cachedSchedule; } @@ -68,7 +68,7 @@ class ScheduleProvider { CancellationToken cancellationToken, ) async { print( - "Fetching schedule for ${DateFormat.yMd().format(start)} - ${DateFormat.yMd().format(end)}"); + "Fetching schedule for ${DateFormat.yMd().format(start)} - ${DateFormat.yMd().format(end)}",); try { var updatedSchedule = await _scheduleSource.currentScheduleSource .querySchedule(start, end, cancellationToken); @@ -145,7 +145,7 @@ class ScheduleProvider { } void removeScheduleEntryChangedCallback( - ScheduleEntryChangedCallback callback) { + ScheduleEntryChangedCallback callback,) { if (_scheduleUpdatedCallbacks.contains(callback)) _scheduleEntryChangedCallbacks.remove(callback); } @@ -163,7 +163,7 @@ class ScheduleProvider { for (var addedEntry in diff.addedEntries) { if (queryInformation.any((i) => addedEntry.end.isAfter(i!.start) && - addedEntry.start.isBefore(i.end))) { + addedEntry.start.isBefore(i.end),)) { cleanedAddedEntries.add(addedEntry); } } diff --git a/lib/schedule/data/schedule_entry_entity.dart b/lib/schedule/data/schedule_entry_entity.dart index 8a5ae1bc..6f58146e 100644 --- a/lib/schedule/data/schedule_entry_entity.dart +++ b/lib/schedule/data/schedule_entry_entity.dart @@ -26,7 +26,7 @@ class ScheduleEntryEntity extends DatabaseEntity { professor: map["professor"], title: map["title"], room: map["room"], - type: ScheduleEntryType.values[map["type"]]); + type: ScheduleEntryType.values[map["type"]],); } @override diff --git a/lib/schedule/data/schedule_entry_repository.dart b/lib/schedule/data/schedule_entry_repository.dart index e46ed5db..6ca00324 100644 --- a/lib/schedule/data/schedule_entry_repository.dart +++ b/lib/schedule/data/schedule_entry_repository.dart @@ -13,7 +13,7 @@ class ScheduleEntryRepository { } Future queryScheduleBetweenDates( - DateTime start, DateTime end) async { + DateTime start, DateTime end,) async { var rows = await _database.queryRows( ScheduleEntryEntity.tableName(), where: "end>? AND start deleteScheduleEntriesBetween( - DateTime start, DateTime end) async { + DateTime start, DateTime end,) async { await _database.deleteWhere( ScheduleEntryEntity.tableName(), where: "start>=? AND end<=?", diff --git a/lib/schedule/data/schedule_query_information_repository.dart b/lib/schedule/data/schedule_query_information_repository.dart index e43d8fcf..6054fe90 100644 --- a/lib/schedule/data/schedule_query_information_repository.dart +++ b/lib/schedule/data/schedule_query_information_repository.dart @@ -7,8 +7,8 @@ class ScheduleQueryInformationRepository { ScheduleQueryInformationRepository(this._database); + DateTime start, DateTime end,) async { Future getOldestQueryTimeBetweenDates( - DateTime start, DateTime end) async { var oldestQueryTimeDate = await _database.queryAggregator( "SELECT MIN(queryTime) FROM ScheduleQueryInformation WHERE start<=? AND end>=?", [ @@ -23,7 +23,7 @@ class ScheduleQueryInformationRepository { } Future> getQueryInformationBetweenDates( - DateTime start, DateTime end) async { + DateTime start, DateTime end,) async { var rows = await _database.queryRows( ScheduleQueryInformationEntity.tableName(), where: "start<=? AND end>=?", @@ -46,7 +46,7 @@ class ScheduleQueryInformationRepository { } Future saveScheduleQueryInformation( - ScheduleQueryInformation queryInformation) async { + ScheduleQueryInformation queryInformation,) async { await _database.deleteWhere( ScheduleQueryInformationEntity.tableName(), where: "start=? AND end=?", diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index d925d5b0..cb52e4e6 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -78,7 +78,7 @@ class ScheduleEntry { String? details, String? professor, String? room, - ScheduleEntryType? type}) { + ScheduleEntryType? type,}) { return ScheduleEntry( id: id, start: start ?? this.start, diff --git a/lib/schedule/service/dualis/dualis_schedule_source.dart b/lib/schedule/service/dualis/dualis_schedule_source.dart index 9863689f..46580416 100644 --- a/lib/schedule/service/dualis/dualis_schedule_source.dart +++ b/lib/schedule/service/dualis/dualis_schedule_source.dart @@ -14,7 +14,7 @@ class DualisScheduleSource extends ScheduleSource { @override Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken]) async { + [CancellationToken? cancellationToken,]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); DateTime current = toStartOfMonth(from)!; @@ -28,7 +28,7 @@ class DualisScheduleSource extends ScheduleSource { while (to!.isAfter(current) && !cancellationToken.isCancelled()) { try { var monthSchedule = await _dualisScraper.loadMonthlySchedule( - current, cancellationToken); + current, cancellationToken,); schedule.merge(monthSchedule); } on OperationCancelledException { diff --git a/lib/schedule/service/error_report_schedule_source_decorator.dart b/lib/schedule/service/error_report_schedule_source_decorator.dart index d1930b98..9a4264cd 100644 --- a/lib/schedule/service/error_report_schedule_source_decorator.dart +++ b/lib/schedule/service/error_report_schedule_source_decorator.dart @@ -10,7 +10,7 @@ class ErrorReportScheduleSourceDecorator extends ScheduleSource { @override Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken]) async { + [CancellationToken? cancellationToken,]) async { try { var schedule = await _scheduleSource.querySchedule( from, diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index 2bf3112a..174dce6f 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -46,7 +46,7 @@ class IcalScheduleSource extends ScheduleSource { } Future _makeRequest( - String url, CancellationToken cancellationToken) async { + String url, CancellationToken cancellationToken,) async { url = url.replaceAll("webcal://", "https://"); var requestCancellationToken = http.CancellationToken(); diff --git a/lib/schedule/service/isolate_schedule_source_decorator.dart b/lib/schedule/service/isolate_schedule_source_decorator.dart index 5071aed6..027c6712 100644 --- a/lib/schedule/service/isolate_schedule_source_decorator.dart +++ b/lib/schedule/service/isolate_schedule_source_decorator.dart @@ -19,7 +19,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { @override Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken]) async { + [CancellationToken? cancellationToken,]) async { await _initializeIsolate(); // Use the cancellation token to send a cancel message. @@ -69,7 +69,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { // Use a broadcast stream. The normal ReceivePort closes after one subscription _isolateToMain = isolateToMain.asBroadcastStream(); _isolate = await Isolate.spawn( - scheduleSourceIsolateEntryPoint, isolateToMain.sendPort); + scheduleSourceIsolateEntryPoint, isolateToMain.sendPort,); _sendPort = await _isolateToMain!.first as SendPort?; } diff --git a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart index 9912082b..24b7ac2c 100644 --- a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart +++ b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart @@ -24,7 +24,7 @@ class MannheimCourseResponseParser { "http://vorlesungsplan.dhbw-mannheim.de/ical.php?uid=$value", title, value, - )); + ),); } courses.sort((c1, c2) => c1.name.compareTo(c2.name)); diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index ecd3b732..66458c21 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -28,7 +28,7 @@ class MannheimCourseScraper { } Future _makeRequest( - Uri uri, CancellationToken cancellationToken) async { + Uri uri, CancellationToken cancellationToken,) async { var requestCancellationToken = http.CancellationToken(); try { @@ -37,7 +37,7 @@ class MannheimCourseScraper { }); var response = await http.HttpClientHelper.get(uri, - cancelToken: requestCancellationToken); + cancelToken: requestCancellationToken,); if (response == null && !requestCancellationToken.isCanceled) throw ServiceRequestFailed("Http request failed!"); diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index 51830201..7db01adf 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -28,7 +28,7 @@ class RaplaParsingUtils { }; static ScheduleEntry extractScheduleEntryOrThrow( - Element value, DateTime date) { + Element value, DateTime date,) { // The tooltip tag contains the most relevant information var tooltip = value.getElementsByClassName(TOOLTIP_CLASS); @@ -56,7 +56,7 @@ class RaplaParsingUtils { // tooltip. Then provide a link with a manual to activate it in Rapla if (tooltip.isEmpty) { scheduleEntry = extractScheduleDetailsFromCell( - timeAndClassName, scheduleEntry, start, end); + timeAndClassName, scheduleEntry, start, end,); } else { scheduleEntry = extractScheduleFromTooltip(tooltip, value, scheduleEntry, start, end); @@ -73,7 +73,7 @@ class RaplaParsingUtils { var professor = scheduleEntry.professor; if (professor.endsWith(",")) { scheduleEntry = scheduleEntry.copyWith( - professor: professor.substring(0, professor.length - 1)); + professor: professor.substring(0, professor.length - 1),); } return scheduleEntry.copyWith( @@ -89,7 +89,7 @@ class RaplaParsingUtils { Element value, ScheduleEntry? scheduleEntry, DateTime start, - DateTime end) { + DateTime end,) { var infotable = tooltip[0].getElementsByClassName(INFOTABLE_CLASS); if (infotable.isEmpty) { @@ -122,7 +122,7 @@ class RaplaParsingUtils { List timeAndClassName, ScheduleEntry? scheduleEntry, DateTime start, - DateTime end) { + DateTime end,) { var descriptionHtml = timeAndClassName[0].innerHtml.substring(12); var descriptionParts = descriptionHtml.split("
"); diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index 02082dbe..9a28a1ce 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -21,7 +21,7 @@ class RaplaScheduleSource extends ScheduleSource { @override Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken]) async { + [CancellationToken? cancellationToken,]) async { DateTime current = toDayOfWeek(from, DateTime.monday)!; if (cancellationToken == null) cancellationToken = CancellationToken(); @@ -141,7 +141,7 @@ class RaplaScheduleSource extends ScheduleSource { } Future _makeRequest( - Uri uri, CancellationToken cancellationToken) async { + Uri uri, CancellationToken cancellationToken,) async { var requestCancellationToken = http.CancellationToken(); try { @@ -150,7 +150,7 @@ class RaplaScheduleSource extends ScheduleSource { }); var response = await http.HttpClientHelper.get(uri, - cancelToken: requestCancellationToken); + cancelToken: requestCancellationToken,); if (response == null && !requestCancellationToken.isCanceled) throw ServiceRequestFailed("Http request failed!"); diff --git a/lib/schedule/service/schedule_source.dart b/lib/schedule/service/schedule_source.dart index 6bd044b3..4785b8eb 100644 --- a/lib/schedule/service/schedule_source.dart +++ b/lib/schedule/service/schedule_source.dart @@ -10,7 +10,7 @@ abstract class ScheduleSource { /// if an error happened or the operation was cancelled /// Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken]); + [CancellationToken? cancellationToken,]); bool canQuery(); } diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index b0f19659..93d30aa0 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -35,9 +35,9 @@ class _DailySchedulePageState extends State { padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), child: PropertyChangeConsumer( builder: (BuildContext context, DailyScheduleViewModel? model, - Set? properties) { + Set? properties,) { var dateFormat = DateFormat.yMMMMEEEEd( - L.of(context).locale.languageCode); + L.of(context).locale.languageCode,); return Text( dateFormat.format(model!.currentDate!), style: textStyleDailyScheduleCurrentDate(context), diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index 474c02cd..d4e82ccd 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -80,13 +80,13 @@ class DailyScheduleEntryWidget extends StatelessWidget { Text( scheduleEntry.professor, style: textStyleDailyScheduleEntryWidgetProfessor( - context), + context,), ), Text( scheduleEntryTypeToReadableString( - context, scheduleEntry.type), + context, scheduleEntry.type,), style: textStyleDailyScheduleEntryWidgetType( - context), + context,), ), ], ), diff --git a/lib/schedule/ui/notification/next_day_information_notification.dart b/lib/schedule/ui/notification/next_day_information_notification.dart index d477ae87..33d8c63c 100644 --- a/lib/schedule/ui/notification/next_day_information_notification.dart +++ b/lib/schedule/ui/notification/next_day_information_notification.dart @@ -59,7 +59,7 @@ class NextDayInformationNotification extends TaskCallback { } String? _getNotificationMessage( - int daysToNextEntry, ScheduleEntry nextScheduleEntry, DateFormat format) { + int daysToNextEntry, ScheduleEntry nextScheduleEntry, DateFormat format,) { switch (daysToNextEntry) { case 0: return interpolate( diff --git a/lib/schedule/ui/schedule_navigation_entry.dart b/lib/schedule/ui/schedule_navigation_entry.dart index bfb542a7..160f4689 100644 --- a/lib/schedule/ui/schedule_navigation_entry.dart +++ b/lib/schedule/ui/schedule_navigation_entry.dart @@ -46,7 +46,7 @@ class ScheduleNavigationEntry extends NavigationEntry { await ScheduleHelpDialog().show(context); }, tooltip: L.of(context).helpButtonTooltip, - )), + ),), ), PropertyChangeProvider( value: model, @@ -59,7 +59,7 @@ class ScheduleNavigationEntry extends NavigationEntry { onPressed: () async { Navigator.of(context).push(MaterialPageRoute( builder: (context) => ScheduleFilterPage(), - )); + ),); }, ) : Container(), diff --git a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart index 29fa0433..539c6b97 100644 --- a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart +++ b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart @@ -11,7 +11,7 @@ class FilterViewModel extends BaseViewModel { List filterStates = []; FilterViewModel(this._scheduleEntryRepository, this._scheduleFilterRepository, - this._scheduleSource) { + this._scheduleSource,) { loadFilterStates(); } diff --git a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart index 3d5229b6..52de5863 100644 --- a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart +++ b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart @@ -47,13 +47,13 @@ class ScheduleFilterPage extends StatelessWidget { value: _viewModel, child: PropertyChangeConsumer( builder: (BuildContext _, FilterViewModel? viewModel, - Set? ___) => + Set? ___,) => ListView.builder( shrinkWrap: true, itemCount: viewModel!.filterStates.length, itemBuilder: (context, index) => FilterStateRow(viewModel.filterStates[index]), - )), + ),), ), ) ], diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index 377906fd..d2218a73 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -38,7 +38,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { width: 30, decoration: BoxDecoration( color: colorSeparator(), - borderRadius: const BorderRadius.all(Radius.circular(4))), + borderRadius: const BorderRadius.all(Radius.circular(4)),), child: null, ), ), @@ -58,7 +58,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { Text( L.of(context).scheduleEntryDetailFrom, style: textStyleScheduleEntryBottomPageTimeFromTo( - context), + context,), ), Text( timeStart, diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index 4e7f77e5..c12da6ad 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -1,6 +1,5 @@ import 'package:animations/animations.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/common/ui/widgets/error_display.dart'; import 'package:dhbwstudentapp/schedule/model/schedule.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; @@ -40,7 +39,7 @@ class _WeeklySchedulePageState extends State { Text(L.of(context).scheduleQueryFailedMessage), TextButton( child: Text( - L.of(context).scheduleQueryFailedOpenInBrowser.toUpperCase()), + L.of(context).scheduleQueryFailedOpenInBrowser.toUpperCase(),), onPressed: () { launchUrl(Uri.parse(viewModel.scheduleUrl!)); }, @@ -111,13 +110,13 @@ class _WeeklySchedulePageState extends State { child: PropertyChangeConsumer( properties: const ["weekSchedule", "now"], builder: (BuildContext context, - WeeklyScheduleViewModel? model, Set? _) { + WeeklyScheduleViewModel? model, Set? _,) { return PageTransitionSwitcher( reverse: !model!.didUpdateScheduleIntoFuture, duration: const Duration(milliseconds: 300), transitionBuilder: (Widget child, Animation animation, - Animation secondaryAnimation) => + Animation secondaryAnimation,) => SharedAxisTransition( child: child, animation: animation, @@ -148,7 +147,7 @@ class _WeeklySchedulePageState extends State { PropertyChangeConsumer( properties: const ["isUpdating"], builder: (BuildContext context, - WeeklyScheduleViewModel? model, Set? _) { + WeeklyScheduleViewModel? model, Set? _,) { return model!.isUpdating ? const LinearProgressIndicator() : Container(); diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart index 361e9249..b4bc7f65 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart @@ -10,7 +10,7 @@ class ScheduleGrid extends CustomPaint { final Color gridLinesColor; ScheduleGrid(this.fromHour, this.toHour, this.timeLabelsWidth, - this.dateLabelsHeight, this.columns, this.gridLinesColor) + this.dateLabelsHeight, this.columns, this.gridLinesColor,) : super( painter: ScheduleGridCustomPaint( fromHour, @@ -19,7 +19,7 @@ class ScheduleGrid extends CustomPaint { dateLabelsHeight, columns, gridLinesColor, - )); + ),); } class ScheduleGridCustomPaint extends CustomPainter { diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart index ae98def9..753db464 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart @@ -74,7 +74,7 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { size.width, size.height, ), - overlayPaint); + overlayPaint,); } void drawPartialPastOverlay(Canvas canvas, Size size, Paint overlayPaint) { diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 748b3290..5064dba8 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -38,8 +38,8 @@ class ScheduleWidget extends StatelessWidget { child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return buildWithSize( - context, constraints.biggest.width, constraints.biggest.height); - }), + context, constraints.biggest.width, constraints.biggest.height,); + },), ); } @@ -190,7 +190,7 @@ class ScheduleWidget extends StatelessWidget { } List buildEntryWidgets( - double hourHeight, double minuteHeight, double width, int columns) { + double hourHeight, double minuteHeight, double width, int columns,) { if (schedule == null) return []; if (schedule!.entries.isEmpty) return []; @@ -213,7 +213,7 @@ class ScheduleWidget extends StatelessWidget { minuteHeight, xPosition, columnSchedule.entries, - )); + ),); columnStartDate = columnEndDate; columnEndDate = tomorrow(columnEndDate); diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index fc09625a..7b7407fa 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -103,7 +103,7 @@ abstract class EnterUrlDialog { value: _hasUrlError, child: Consumer( builder: (BuildContext context, ValueNotifier hasUrlError, - Widget? child) => + Widget? child,) => TextButton( child: Text(L.of(context).dialogOk.toUpperCase()), onPressed: hasUrlError.value diff --git a/lib/ui/banner_widget.dart b/lib/ui/banner_widget.dart index f993f420..26f1bc47 100644 --- a/lib/ui/banner_widget.dart +++ b/lib/ui/banner_widget.dart @@ -9,7 +9,7 @@ class BannerWidget extends StatelessWidget { {Key? key, required this.message, required this.buttonText, - required this.onButtonTap}) + required this.onButtonTap,}) : super(key: key); @override diff --git a/lib/ui/main_page.dart b/lib/ui/main_page.dart index 47cfa706..ce2b915f 100644 --- a/lib/ui/main_page.dart +++ b/lib/ui/main_page.dart @@ -139,7 +139,7 @@ class _MainPageState extends State with NavigatorObserver { drawerEntries.add(DrawerNavigationEntry( entry.icon, entry.title(context), - )); + ),); } return drawerEntries; diff --git a/lib/ui/navigation_drawer.dart b/lib/ui/navigation_drawer.dart index abc21d8a..c368ef35 100644 --- a/lib/ui/navigation_drawer.dart +++ b/lib/ui/navigation_drawer.dart @@ -37,7 +37,7 @@ class NavigationDrawer extends StatelessWidget { icon: entry.icon, text: entry.title, index: i, - isSelected: i == selectedIndex)); + isSelected: i == selectedIndex,),); i++; } diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index 651f2bbe..83f92b22 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -36,7 +36,7 @@ class _OnboardingPageState extends State await _controller.animateTo( viewModel.stepIndex! / viewModel.onboardingSteps, curve: Curves.ease, - duration: const Duration(milliseconds: 300)); + duration: const Duration(milliseconds: 300),); }, ); diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart index b9749d75..8126ca8d 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart @@ -47,7 +47,7 @@ class OnboardingViewModel extends BaseViewModel { for (var page in pages.values) { page.viewModel().addListener(() { notifyListeners("currentPageValid"); - }, ["isValid"]); + }, ["isValid"],); } analytics.logTutorialBegin(); diff --git a/lib/ui/onboarding/widgets/dualis_login_page.dart b/lib/ui/onboarding/widgets/dualis_login_page.dart index f4faf068..1fd4f60e 100644 --- a/lib/ui/onboarding/widgets/dualis_login_page.dart +++ b/lib/ui/onboarding/widgets/dualis_login_page.dart @@ -27,7 +27,7 @@ class _DualisLoginCredentialsPageState Widget build(BuildContext context) { return PropertyChangeConsumer( builder: (BuildContext context, OnboardingStepViewModel? base, - Set? _) { + Set? _,) { final viewModel = base as DualisLoginViewModel?; final credentials = viewModel?.credentials; @@ -44,7 +44,7 @@ class _DualisLoginCredentialsPageState onSubmitted: () async { await _testCredentials(viewModel); }, - )); + ),); widgets.add(_buildTestCredentialsButton(viewModel)); return Column( @@ -96,7 +96,7 @@ class _DualisLoginCredentialsPageState child: Text(L .of(context) .onboardingDualisTestButton - .toUpperCase()), + .toUpperCase(),), ), ], ), diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index cdb6316f..b9159317 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -43,7 +43,7 @@ class _IcalUrlPageState extends State { padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: PropertyChangeConsumer( builder: (BuildContext context, OnboardingStepViewModel? model, - Set? _) { + Set? _,) { final viewModel = model as IcalUrlViewModel?; if (viewModel?.url != null && diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index ff9c0890..ba40b86e 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -53,7 +53,7 @@ class SelectMannheimCourseWidget extends StatelessWidget { Widget build(BuildContext context) { return PropertyChangeConsumer( builder: (BuildContext context, OnboardingStepViewModel? model, - Set? _) { + Set? _,) { final viewModel = model as MannheimViewModel?; switch (viewModel?.loadingState) { @@ -114,7 +114,7 @@ class SelectMannheimCourseWidget extends StatelessWidget { } Widget _buildLoadingError( - BuildContext context, MannheimViewModel? viewModel) { + BuildContext context, MannheimViewModel? viewModel,) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index 512b5d12..60dc2245 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -43,7 +43,7 @@ class _RaplaUrlPageState extends State { padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: PropertyChangeConsumer( builder: (BuildContext context, OnboardingStepViewModel? model, - Set? _) { + Set? _,) { final viewModel = model as RaplaUrlViewModel?; if (viewModel?.raplaUrl != null && diff --git a/lib/ui/onboarding/widgets/select_source_page.dart b/lib/ui/onboarding/widgets/select_source_page.dart index b420a366..53e3a68f 100644 --- a/lib/ui/onboarding/widgets/select_source_page.dart +++ b/lib/ui/onboarding/widgets/select_source_page.dart @@ -95,7 +95,7 @@ class SelectSourcePage extends StatelessWidget { SelectSourceViewModel? viewModel, BuildContext context, ScheduleSourceType type, - String title) { + String title,) { return RadioListTile( value: type, //model.useDualis, onChanged: viewModel?.setScheduleSourceType, diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 4d966bda..c72c2e5e 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -42,7 +42,7 @@ class _SettingsPageState extends State { KiwiContainer().resolve(NextDayInformationNotification.name) as NextDayInformationNotification, KiwiContainer().resolve(), - KiwiContainer().resolve()); + KiwiContainer().resolve(),); @override Widget build(BuildContext context) { @@ -147,7 +147,7 @@ class _SettingsPageState extends State { context: context, builder: (BuildContext context) => AlertDialog( title: Text( - L.of(context).dialogTitleCalendarAccessNotGranted), + L.of(context).dialogTitleCalendarAccessNotGranted,), content: Text(L.of(context).dialogCalendarAccessNotGranted), actions: [ @@ -156,7 +156,7 @@ class _SettingsPageState extends State { child: Text(L.of(context).dialogOk), ) ], - )); + ),); return; } var isCalendarSyncEnabled = await KiwiContainer() @@ -170,7 +170,7 @@ class _SettingsPageState extends State { isCalendarSyncWidget: true, isCalendarSyncEnabled: isCalendarSyncEnabled, ), - settings: RouteSettings(name: "settings"))); + settings: RouteSettings(name: "settings"),),); }, ), const Divider(), @@ -187,7 +187,7 @@ class _SettingsPageState extends State { "notifyAboutNextDay", ], builder: (BuildContext context, SettingsViewModel? model, - Set? properties) { + Set? properties,) { return SwitchListTile( title: Text(L.of(context).settingsNotificationsNextDay), onChanged: model!.setNotifyAboutNextDay, @@ -200,7 +200,7 @@ class _SettingsPageState extends State { "notifyAboutScheduleChanges", ], builder: (BuildContext context, SettingsViewModel? model, - Set? properties) { + Set? properties,) { return SwitchListTile( title: Text(L.of(context).settingsNotificationsScheduleChange), onChanged: model!.setNotifyAboutScheduleChanges, @@ -232,7 +232,7 @@ class _SettingsPageState extends State { AppTheme.Dark: L.of(context).selectThemeDark, AppTheme.Light: L.of(context).selectThemeLight, AppTheme.System: L.of(context).selectThemeSystem, - }[model!.appTheme]!), + }[model!.appTheme]!,), ); }, ), diff --git a/lib/ui/settings/viewmodels/settings_view_model.dart b/lib/ui/settings/viewmodels/settings_view_model.dart index 7bffb54c..c554371b 100644 --- a/lib/ui/settings/viewmodels/settings_view_model.dart +++ b/lib/ui/settings/viewmodels/settings_view_model.dart @@ -46,7 +46,7 @@ class SettingsViewModel extends BaseViewModel { this._preferencesProvider, this._nextDayInformationNotification, this._widgetHelper, - this._inAppPurchaseManager) { + this._inAppPurchaseManager,) { _loadPreferences(); _inAppPurchaseManager.addPurchaseCallback( diff --git a/test/date_management/service/parsing/all_dates_extract_test.dart b/test/date_management/service/parsing/all_dates_extract_test.dart index 0d885eb4..3657e0be 100644 --- a/test/date_management/service/parsing/all_dates_extract_test.dart +++ b/test/date_management/service/parsing/all_dates_extract_test.dart @@ -5,7 +5,7 @@ import 'package:test/test.dart'; Future main() async { var allDatesPage = await File(Directory.current.absolute.path + - '/test/date_management/service/parsing/html_resources/all_dates.html') + '/test/date_management/service/parsing/html_resources/all_dates.html',) .readAsString(); test('AllDatesExtract extract all dates', () async { diff --git a/test/dualis/service/parsing/all_modules_extract_test.dart b/test/dualis/service/parsing/all_modules_extract_test.dart index faf73b78..f143a451 100644 --- a/test/dualis/service/parsing/all_modules_extract_test.dart +++ b/test/dualis/service/parsing/all_modules_extract_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; Future main() async { var studentResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/student_results.html') + '/test/dualis/service/parsing/html_resources/student_results.html',) .readAsString(); test('AllModulesExtract extract all modules', () async { diff --git a/test/dualis/service/parsing/dualis_timeout_extract_test.dart b/test/dualis/service/parsing/dualis_timeout_extract_test.dart index 79e477d5..855addca 100644 --- a/test/dualis/service/parsing/dualis_timeout_extract_test.dart +++ b/test/dualis/service/parsing/dualis_timeout_extract_test.dart @@ -5,11 +5,11 @@ import 'package:test/test.dart'; Future main() async { var monthlySchedulePage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/monthly_schedule.html') + '/test/dualis/service/parsing/html_resources/monthly_schedule.html',) .readAsString(); var timeoutPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/dualis_timeout.html') + '/test/dualis/service/parsing/html_resources/dualis_timeout.html',) .readAsString(); test('DualisTimeoutExtract detect timeout page', () async { diff --git a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart index 55e997c9..af079e5b 100644 --- a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart +++ b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart @@ -6,7 +6,7 @@ import 'package:test/test.dart'; Future main() async { var moduleDetailsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/module_details.html') + '/test/dualis/service/parsing/html_resources/module_details.html',) .readAsString(); test('ExamsFromModuleDetailsExtract', () async { diff --git a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart index fd347f36..7b3e143c 100644 --- a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart @@ -6,14 +6,14 @@ import 'package:test/test.dart'; Future main() async { var courseResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/course_results.html') + '/test/dualis/service/parsing/html_resources/course_results.html',) .readAsString(); test('ModulesFromCourseResultPageExtract', () async { var extract = ModulesFromCourseResultPageExtract(); var modules = extract.extractModulesFromCourseResultPage( - courseResultsPage, "www.endpoint.com"); + courseResultsPage, "www.endpoint.com",); expect(modules.length, 3); @@ -23,7 +23,7 @@ Future main() async { expect(modules[1]!.credits, "8,0"); expect(modules[1]!.finalGrade, "4,0"); expect(modules[1]!.detailsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=RESULTDETAILS&ARGUMENTS=-N123456789876543,-N000307,-N121212121212121"); + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=RESULTDETAILS&ARGUMENTS=-N123456789876543,-N000307,-N121212121212121",); }); test('ModulesFromCourseResultPageExtract invalid html throws exception', diff --git a/test/dualis/service/parsing/monthly_schedule_extract_test.dart b/test/dualis/service/parsing/monthly_schedule_extract_test.dart index 60c6d073..a3ae447b 100644 --- a/test/dualis/service/parsing/monthly_schedule_extract_test.dart +++ b/test/dualis/service/parsing/monthly_schedule_extract_test.dart @@ -5,7 +5,7 @@ import 'package:test/test.dart'; Future main() async { var monthlySchedulePage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/monthly_schedule.html') + '/test/dualis/service/parsing/html_resources/monthly_schedule.html',) .readAsString(); test('MonthlyScheduleExtract extract all appointments', () async { diff --git a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart index 261c3692..fb443111 100644 --- a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart @@ -6,7 +6,7 @@ import 'package:test/test.dart'; Future main() async { var courseResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/course_results.html') + '/test/dualis/service/parsing/html_resources/course_results.html',) .readAsString(); test('SemestersFromCourseResultPageExtract', () async { @@ -21,11 +21,11 @@ Future main() async { expect(semesters[0].semesterName, "SoSe yyyy"); expect(semesters[0].semesterCourseResultsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000012345000"); + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000012345000",); expect(semesters[1].semesterName, "WiSe xx/yy"); expect(semesters[1].semesterCourseResultsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000015048000"); + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000015048000",); }); test('SemestersFromCourseResultPageExtract invalid html throws exception', diff --git a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart index 660e0747..47c33165 100644 --- a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart +++ b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart @@ -6,7 +6,7 @@ import 'package:test/test.dart'; Future main() async { var studentResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/student_results.html') + '/test/dualis/service/parsing/html_resources/student_results.html',) .readAsString(); test('StudyGradesFromStudentResultsPageExtract', () async { diff --git a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart index eaeaff6b..7de7c4a6 100644 --- a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart +++ b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart @@ -7,7 +7,7 @@ import 'package:test/test.dart'; Future main() async { var mainPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/main_page.html') + '/test/dualis/service/parsing/html_resources/main_page.html',) .readAsString(); test('UrlsFromMainPageExtract', () async { @@ -18,11 +18,11 @@ Future main() async { extract.parseMainPage(mainPage, mainPageUrls, "www.endpoint.com"); expect(mainPageUrls.studentResultsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=STUDENT_RESULT&ARGUMENTS=-N123456789876543,-N000310,-N0,-N000000000000000,-N000000000000000,-N000000000000000,-N0,-N000000000000000"); + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=STUDENT_RESULT&ARGUMENTS=-N123456789876543,-N000310,-N0,-N000000000000000,-N000000000000000,-N000000000000000,-N0,-N000000000000000",); expect(mainPageUrls.courseResultUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,"); + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,",); expect(mainPageUrls.monthlyScheduleUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=MONTH&ARGUMENTS=-N123456789876543,-N000031,-A"); + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=MONTH&ARGUMENTS=-N123456789876543,-N000031,-A",); expect(mainPageUrls.semesterCourseResultUrls, {}); }); diff --git a/test/rapla_service_test.dart b/test/rapla_service_test.dart index 76bfee08..00963a46 100644 --- a/test/rapla_service_test.dart +++ b/test/rapla_service_test.dart @@ -5,7 +5,7 @@ void main() { test('debugging', () async { var source = RaplaScheduleSource(); source.setEndpointUrl( - "https://rapla.dhbw-stuttgart.de/rapla?key=txB1FOi5xd1wUJBWuX8lJhGDUgtMSFmnKLgAG_NVMhCn4AzVqTBQM-yMcTKkIDCa"); + "https://rapla.dhbw-stuttgart.de/rapla?key=txB1FOi5xd1wUJBWuX8lJhGDUgtMSFmnKLgAG_NVMhCn4AzVqTBQM-yMcTKkIDCa",); //var schedule = await source.querySchedule( // DateTime(2020, 01, 20), DateTime(2020, 01, 25)); //print(schedule); diff --git a/test/schedule/service/ical/ical_parser_test.dart b/test/schedule/service/ical/ical_parser_test.dart index 0af71462..586b61ed 100644 --- a/test/schedule/service/ical/ical_parser_test.dart +++ b/test/schedule/service/ical/ical_parser_test.dart @@ -6,7 +6,7 @@ import 'package:test/test.dart'; Future main() async { var icalFile = await File(Directory.current.absolute.path + - '/test/schedule/service/ical/file_resources/ical_test.ics') + '/test/schedule/service/ical/file_resources/ical_test.ics',) .readAsString(); test('ical correctly read all entries', () async { diff --git a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart index 9ad88b9a..4a70c620 100644 --- a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart +++ b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart @@ -5,7 +5,7 @@ import 'package:test/test.dart'; Future main() async { var coursePage = await File(Directory.current.absolute.path + - '/test/schedule/service/mannheim/html_resources/mannheim_ical.html') + '/test/schedule/service/mannheim/html_resources/mannheim_ical.html',) .readAsString(); test('Mannheim course parser parses correctly', () async { diff --git a/test/schedule/service/rapla/rapla_response_parser_test.dart b/test/schedule/service/rapla/rapla_response_parser_test.dart index deda5af1..70b81d19 100644 --- a/test/schedule/service/rapla/rapla_response_parser_test.dart +++ b/test/schedule/service/rapla/rapla_response_parser_test.dart @@ -6,39 +6,39 @@ import 'package:test/test.dart'; Future main() async { var monthlyRaplaPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_monthly_response.html') + '/test/schedule/service/rapla/html_resources/rapla_monthly_response.html',) .readAsString(); var raplaPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_response.html') + '/test/schedule/service/rapla/html_resources/rapla_response.html',) .readAsString(); var raplaPage1 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_response_1.html') + '/test/schedule/service/rapla/html_resources/rapla_response_1.html',) .readAsString(); var severalMonthsPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_several_months_response.html') + '/test/schedule/service/rapla/html_resources/rapla_several_months_response.html',) .readAsString(); var severalMonthsPage1 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_several_months_response_1.html') + '/test/schedule/service/rapla/html_resources/rapla_several_months_response_1.html',) .readAsString(); var severalMonthsPage2 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_several_months_response_2.html') + '/test/schedule/service/rapla/html_resources/rapla_several_months_response_2.html',) .readAsString(); var invalidRaplaPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/invalid_rapla_response.html') + '/test/schedule/service/rapla/html_resources/invalid_rapla_response.html',) .readAsString(); var raplaWeekResponse = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_week_response.html') + '/test/schedule/service/rapla/html_resources/rapla_week_response.html',) .readAsString(); var raplaWeekResponse1 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_week_response_1.html') + '/test/schedule/service/rapla/html_resources/rapla_week_response_1.html',) .readAsString(); test('Rapla correctly read all classes of weekly view', () async { @@ -115,7 +115,7 @@ Future main() async { expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "A"); expect(schedule.entries[0].room, - "MOS-TINF19A,A 1.380 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00),A 1.390 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00)"); + "MOS-TINF19A,A 1.380 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00),A 1.390 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00)",); expect(schedule.entries[2].title, "Tag der Deutschen Einheit"); expect(schedule.entries[2].start, DateTime(2021, 10, 03, 08, 00)); @@ -190,16 +190,16 @@ Future main() async { expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "Fr, Ta"); expect(schedule.entries[0].room, - "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)"); + "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)",); expect(schedule.entries[1].title, - "Einführung in die Volkswirtschaftslehre und Mikroökonomik"); + "Einführung in die Volkswirtschaftslehre und Mikroökonomik",); expect(schedule.entries[1].start, DateTime(2021, 11, 02, 13, 45)); expect(schedule.entries[1].end, DateTime(2021, 11, 02, 17, 00)); expect(schedule.entries[1].type, ScheduleEntryType.Class); expect(schedule.entries[1].professor, "Le, An"); expect(schedule.entries[1].room, - "WDCM21B,D221 W Hörsaal (Mo 11.10.21 09:00),G086 W Hörsaal (Mo 25.10.21 09:00, Mo 15.11.21 09:00),F218_1 PA Hörsaal (Mo 22.11.21 09:00, Mo 06.12.21 09:00),A167 W Hörsaal (Mo 29.11.21 09:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 13:45)"); + "WDCM21B,D221 W Hörsaal (Mo 11.10.21 09:00),G086 W Hörsaal (Mo 25.10.21 09:00, Mo 15.11.21 09:00),F218_1 PA Hörsaal (Mo 22.11.21 09:00, Mo 06.12.21 09:00),A167 W Hörsaal (Mo 29.11.21 09:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 13:45)",); expect(schedule.entries[2].title, "Grundlagen des Bürgerlichen Rechts"); expect(schedule.entries[2].start, DateTime(2021, 11, 03, 09, 00)); @@ -207,7 +207,7 @@ Future main() async { expect(schedule.entries[2].type, ScheduleEntryType.Class); expect(schedule.entries[2].professor, "Ei, An"); expect(schedule.entries[2].room, - "WDCM21B,XOnline-Veranstaltung A Virtueller Raum (Mi 13.10.21 09:00, Mi 27.10.21 09:00, Mi 10.11.21 09:00, Mi 24.11.21 09:00, Fr 03.12.21 10:00),D221 W Hörsaal (Mi 20.10.21 13:00, Mi 17.11.21 09:00),G086 W Hörsaal (Di 26.10.21 09:00, Mi 03.11.21 09:00),B354 W Hörsaal (Fr 03.12.21 10:00),F218_1 PA Hörsaal (Mi 08.12.21 09:00)"); + "WDCM21B,XOnline-Veranstaltung A Virtueller Raum (Mi 13.10.21 09:00, Mi 27.10.21 09:00, Mi 10.11.21 09:00, Mi 24.11.21 09:00, Fr 03.12.21 10:00),D221 W Hörsaal (Mi 20.10.21 13:00, Mi 17.11.21 09:00),G086 W Hörsaal (Di 26.10.21 09:00, Mi 03.11.21 09:00),B354 W Hörsaal (Fr 03.12.21 10:00),F218_1 PA Hörsaal (Mi 08.12.21 09:00)",); expect(schedule.entries[3].title, "Technik der Finanzbuchführung I"); expect(schedule.entries[3].start, DateTime(2021, 11, 03, 13, 00)); @@ -215,16 +215,16 @@ Future main() async { expect(schedule.entries[3].type, ScheduleEntryType.Class); expect(schedule.entries[3].professor, "Se, Ka"); expect(schedule.entries[3].room, - "WDCM21B,D221 W Hörsaal (Mi 17.11.21 13:00, Mi 06.10.21 13:00, Mi 13.10.21 13:00),G086 W Hörsaal (Mi 27.10.21 13:00, Mi 03.11.21 13:00, Mi 10.11.21 13:00),A167 W Hörsaal (Mi 24.11.21 13:00, Mi 01.12.21 14:00)"); + "WDCM21B,D221 W Hörsaal (Mi 17.11.21 13:00, Mi 06.10.21 13:00, Mi 13.10.21 13:00),G086 W Hörsaal (Mi 27.10.21 13:00, Mi 03.11.21 13:00, Mi 10.11.21 13:00),A167 W Hörsaal (Mi 24.11.21 13:00, Mi 01.12.21 14:00)",); expect(schedule.entries[4].title, - "Grundlagen des wissenschaftlichen Arbeitens"); + "Grundlagen des wissenschaftlichen Arbeitens",); expect(schedule.entries[4].start, DateTime(2021, 11, 04, 09, 00)); expect(schedule.entries[4].end, DateTime(2021, 11, 04, 12, 15)); expect(schedule.entries[4].type, ScheduleEntryType.Class); expect(schedule.entries[4].professor, "He, Be"); expect(schedule.entries[4].room, - "WDCM21B,D221 W Hörsaal (Di 05.10.21 09:00, Di 12.10.21 09:00),A167 W Hörsaal (Di 23.11.21 09:00),G086 W Hörsaal (Do 04.11.21 09:00)"); + "WDCM21B,D221 W Hörsaal (Di 05.10.21 09:00, Di 12.10.21 09:00),A167 W Hörsaal (Di 23.11.21 09:00),G086 W Hörsaal (Do 04.11.21 09:00)",); expect(schedule.entries[5].title, "Grundlagen der Handelsbetriebslehre"); expect(schedule.entries[5].start, DateTime(2021, 11, 04, 12, 45)); @@ -232,7 +232,7 @@ Future main() async { expect(schedule.entries[5].type, ScheduleEntryType.Class); expect(schedule.entries[5].professor, "Fr, Ta"); expect(schedule.entries[5].room, - "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)"); + "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)",); expect(schedule.entries[6].title, "Einführung in die Programmierung"); expect(schedule.entries[6].start, DateTime(2021, 11, 05, 13, 00)); @@ -240,7 +240,7 @@ Future main() async { expect(schedule.entries[6].type, ScheduleEntryType.Class); expect(schedule.entries[6].professor, "He, Ma"); expect(schedule.entries[6].room, - "WDCM21B,C348 PC Raum,D221 W Hörsaal (Fr 08.10.21 13:00, Fr 15.10.21 13:00, Fr 22.10.21 13:00),G086 W Hörsaal (Fr 29.10.21 13:00, Fr 05.11.21 13:00, Fr 12.11.21 13:00, Do 18.11.21 13:00),A167 W Hörsaal (Fr 26.11.21 13:00, Do 02.12.21 13:00)"); + "WDCM21B,C348 PC Raum,D221 W Hörsaal (Fr 08.10.21 13:00, Fr 15.10.21 13:00, Fr 22.10.21 13:00),G086 W Hörsaal (Fr 29.10.21 13:00, Fr 05.11.21 13:00, Fr 12.11.21 13:00, Do 18.11.21 13:00),A167 W Hörsaal (Fr 26.11.21 13:00, Do 02.12.21 13:00)",); expect(schedule.entries.length, 7); }); @@ -271,7 +271,7 @@ Future main() async { expect(schedule.entries[0].type, ScheduleEntryType.Exam); expect(schedule.entries[0].professor, "Man, R."); expect(schedule.entries[0].room, - "TEA20,H031, Hörsaal,N003, Hörsaal,N004, Hörsaal"); + "TEA20,H031, Hörsaal,N003, Hörsaal,N004, Hörsaal",); expect(schedule.entries.length, 7); }); From 5cd37b09fab3fd28f1b5828f7fdb11b0ece20bdd Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:16:38 +0200 Subject: [PATCH 07/37] fix avoid_redundant_argument_values --- analysis_options.yaml | 1 + .../background/background_work_scheduler.dart | 1 - lib/common/ui/custom_icons_icons.dart | 2 +- lib/common/ui/notification_api.dart | 3 - lib/common/util/date_utils.dart | 4 +- .../ui/calendar_export_page.dart | 1 - .../ui/date_management_page.dart | 1 - .../ui/widgets/date_detail_bottom_sheet.dart | 2 - .../ui/widgets/date_filter_options.dart | 9 --- ...des_from_student_results_page_extract.dart | 2 +- .../exam_results_page/exam_results_page.dart | 4 -- .../study_overview/study_overview_page.dart | 4 -- ...schedule_query_information_repository.dart | 2 +- .../ui/dailyschedule/daily_schedule_page.dart | 6 +- .../widgets/daily_schedule_entry_widget.dart | 4 -- .../schedule_entry_detail_bottom_sheet.dart | 3 - .../weeklyschedule/weekly_schedule_page.dart | 1 - .../select_mannheim_course_dialog.dart | 1 - lib/ui/navigation_drawer.dart | 3 - lib/ui/onboarding/onboarding_page.dart | 3 - .../onboarding/widgets/dualis_login_page.dart | 2 - lib/ui/onboarding/widgets/ical_url_page.dart | 1 - lib/ui/onboarding/widgets/mannheim_page.dart | 2 - .../widgets/onboarding_button_bar.dart | 1 - .../widgets/onboarding_page_background.dart | 4 -- lib/ui/onboarding/widgets/rapla_url_page.dart | 1 - .../widgets/select_source_page.dart | 1 - .../parsing/all_dates_extract_test.dart | 6 +- .../monthly_schedule_extract_test.dart | 4 +- .../schedule_diff_calculator_test.dart | 20 +++---- .../service/ical/ical_parser_test.dart | 12 ++-- .../rapla/rapla_response_parser_test.dart | 60 +++++++++---------- 32 files changed, 59 insertions(+), 112 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 113936f3..73419ee3 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -17,3 +17,4 @@ analyzer: linter: rules: require_trailing_commas: true + avoid_redundant_argument_values: true diff --git a/lib/common/background/background_work_scheduler.dart b/lib/common/background/background_work_scheduler.dart index 482e5f83..61efc6a8 100644 --- a/lib/common/background/background_work_scheduler.dart +++ b/lib/common/background/background_work_scheduler.dart @@ -129,7 +129,6 @@ class BackgroundWorkScheduler extends WorkSchedulerService { await workmanager.initialize( callbackDispatcher, - isInDebugMode: false, ); } diff --git a/lib/common/ui/custom_icons_icons.dart b/lib/common/ui/custom_icons_icons.dart index 39da89d1..5ea374e7 100644 --- a/lib/common/ui/custom_icons_icons.dart +++ b/lib/common/ui/custom_icons_icons.dart @@ -26,5 +26,5 @@ class CustomIcons { static const dynamic _kFontPkg = null; static const IconData logout = - IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); + IconData(0xe800, fontFamily: _kFontFam); } diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index 88a8201e..719e8e80 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -44,12 +44,9 @@ class NotificationApi { 'Notifications', channelDescription: 'This is the main notification channel', icon: 'outline_event_note_24', - channelAction: AndroidNotificationChannelAction.createIfNotExists, - autoCancel: true, channelShowBadge: false, color: Colors.red, enableLights: true, - enableVibration: true, importance: Importance.high, priority: Priority.high, ticker: 'ticker', diff --git a/lib/common/util/date_utils.dart b/lib/common/util/date_utils.dart index 19903804..48109a27 100644 --- a/lib/common/util/date_utils.dart +++ b/lib/common/util/date_utils.dart @@ -3,13 +3,13 @@ DateTime? toStartOfDay(DateTime? dateTime) { return dateTime == null ? null - : DateTime(dateTime.year, dateTime.month, dateTime.day, 0, 0, 0); + : DateTime(dateTime.year, dateTime.month, dateTime.day); } DateTime? toStartOfMonth(DateTime? dateTime) { return dateTime == null ? null - : DateTime(dateTime.year, dateTime.month, 1, 0, 0, 0); + : DateTime(dateTime.year, dateTime.month); } DateTime? tomorrow(DateTime? dateTime) { diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 3783fbe6..98f775f2 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -150,7 +150,6 @@ class _CalendarExportPageState extends State { child: Padding( padding: const EdgeInsets.fromLTRB(32, 16, 32, 16), child: Row( - crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( width: 24, diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index 13f5cb38..fbab8350 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -43,7 +43,6 @@ class DateManagementPage extends StatelessWidget { child: Stack( children: [ SingleChildScrollView( - scrollDirection: Axis.vertical, child: PropertyChangeConsumer( builder: ( BuildContext context, diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index a7d8daca..50d9d3fc 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -22,7 +22,6 @@ class DateDetailBottomSheet extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(24, 12, 24, 24), child: Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( @@ -34,7 +33,6 @@ class DateDetailBottomSheet extends StatelessWidget { decoration: BoxDecoration( color: colorSeparator(), borderRadius: const BorderRadius.all(Radius.circular(4)),), - child: null, ), ), ), diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index 3710648f..b79c5233 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -50,7 +50,6 @@ class _DateFilterOptionsState extends State { }, child: Row( mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.max, children: [ Expanded( child: _buildCollapsedChips(), @@ -59,7 +58,6 @@ class _DateFilterOptionsState extends State { padding: const EdgeInsets.fromLTRB(0, 0, 16, 0), child: ButtonTheme( minWidth: 36, - height: 36, child: IconButton( icon: Icon(Icons.tune), onPressed: () { @@ -121,18 +119,15 @@ class _DateFilterOptionsState extends State { Widget _buildExpanded() { return Row( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( - flex: 1, child: Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 0), child: Text( @@ -141,7 +136,6 @@ class _DateFilterOptionsState extends State { ), ), Expanded( - flex: 1, child: DropdownButton( isExpanded: true, value: widget.viewModel.currentDateDatabase, @@ -154,7 +148,6 @@ class _DateFilterOptionsState extends State { Row( children: [ Expanded( - flex: 1, child: Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 0), child: Text( @@ -163,7 +156,6 @@ class _DateFilterOptionsState extends State { ), ), Expanded( - flex: 1, child: DropdownButton( isExpanded: true, value: widget.viewModel.currentSelectedYear, @@ -192,7 +184,6 @@ class _DateFilterOptionsState extends State { padding: const EdgeInsets.fromLTRB(0, 0, 16, 8), child: ButtonTheme( minWidth: 36, - height: 36, child: IconButton( icon: const Icon(Icons.check), onPressed: () { diff --git a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart index 3af3e401..1729eb08 100644 --- a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart +++ b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart @@ -16,7 +16,7 @@ class StudyGradesFromStudentResultsPageExtract { StudyGrades _extractStudyGradesFromStudentsResultsPage(String? body) { var document = parse(body); - var creditsTable = getElementByTagName(document, "tbody", 0); + var creditsTable = getElementByTagName(document, "tbody"); var gpaTable = getElementByTagName(document, "tbody", 1); var credits = _extractCredits(creditsTable); diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index 4cccde67..acf78318 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -11,9 +11,7 @@ class ExamResultsPage extends StatelessWidget { return Container( height: double.infinity, child: SingleChildScrollView( - scrollDirection: Axis.vertical, child: Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( @@ -26,7 +24,6 @@ class ExamResultsPage extends StatelessWidget { Padding( padding: const EdgeInsets.fromLTRB(24, 8, 24, 0), child: Row( - mainAxisAlignment: MainAxisAlignment.start, children: [ Text(L.of(context).dualisExamResultsSemesterSelect), Padding( @@ -193,7 +190,6 @@ class ExamResultsPage extends StatelessWidget { ), ), ), - numeric: false, ), DataColumn( label: ConstrainedBox( diff --git a/lib/dualis/ui/study_overview/study_overview_page.dart b/lib/dualis/ui/study_overview/study_overview_page.dart index fd6a8a4c..1f78cc99 100644 --- a/lib/dualis/ui/study_overview/study_overview_page.dart +++ b/lib/dualis/ui/study_overview/study_overview_page.dart @@ -10,9 +10,7 @@ class StudyOverviewPage extends StatelessWidget { return Container( height: double.infinity, child: SingleChildScrollView( - scrollDirection: Axis.vertical, child: Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ buildGpaCredits(context), @@ -44,7 +42,6 @@ class StudyOverviewPage extends StatelessWidget { ) => model!.studyGrades != null ? Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Padding( @@ -179,7 +176,6 @@ class StudyOverviewPage extends StatelessWidget { return [ DataColumn( label: Text(L.of(context).dualisOverviewModuleColumnHeader), - numeric: false, ), DataColumn( label: Text(L.of(context).dualisOverviewCreditsColumnHeader), diff --git a/lib/schedule/data/schedule_query_information_repository.dart b/lib/schedule/data/schedule_query_information_repository.dart index 6054fe90..9dc2e75d 100644 --- a/lib/schedule/data/schedule_query_information_repository.dart +++ b/lib/schedule/data/schedule_query_information_repository.dart @@ -7,8 +7,8 @@ class ScheduleQueryInformationRepository { ScheduleQueryInformationRepository(this._database); - DateTime start, DateTime end,) async { Future getOldestQueryTimeBetweenDates( + DateTime start, DateTime end,) async { var oldestQueryTimeDate = await _database.queryAggregator( "SELECT MIN(queryTime) FROM ScheduleQueryInformation WHERE start<=? AND end>=?", [ diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index 93d30aa0..76ee2161 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -29,7 +29,6 @@ class _DailySchedulePageState extends State { padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), @@ -52,9 +51,8 @@ class _DailySchedulePageState extends State { children: [ Row( mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, children: [ - Expanded(flex: 1, child: Container()), + Expanded(child: Container()), Expanded( flex: 8, child: Text( @@ -65,7 +63,7 @@ class _DailySchedulePageState extends State { textStyleDailyScheduleNoEntries(context), ), ), - Expanded(flex: 1, child: Container()), + Expanded(child: Container()), ], ), Padding( diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index d4e82ccd..e0ebc1d4 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -21,8 +21,6 @@ class DailyScheduleEntryWidget extends StatelessWidget { return IntrinsicHeight( child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( @@ -30,7 +28,6 @@ class DailyScheduleEntryWidget extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(0, 8, 8, 8), child: Column( - crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( startTime, @@ -62,7 +59,6 @@ class DailyScheduleEntryWidget extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(8), child: Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index d2218a73..be272c40 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -27,7 +27,6 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(24, 12, 24, 24), child: Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( @@ -39,14 +38,12 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { decoration: BoxDecoration( color: colorSeparator(), borderRadius: const BorderRadius.all(Radius.circular(4)),), - child: null, ), ), ), Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16.0), child: Row( - crossAxisAlignment: CrossAxisAlignment.center, children: [ Column( crossAxisAlignment: CrossAxisAlignment.end, diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index c12da6ad..46ff4f49 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -113,7 +113,6 @@ class _WeeklySchedulePageState extends State { WeeklyScheduleViewModel? model, Set? _,) { return PageTransitionSwitcher( reverse: !model!.didUpdateScheduleIntoFuture, - duration: const Duration(milliseconds: 300), transitionBuilder: (Widget child, Animation animation, Animation secondaryAnimation,) => diff --git a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart index e828b847..cad41b7b 100644 --- a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart +++ b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart @@ -34,7 +34,6 @@ class SelectMannheimCourseDialog { height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, child: Column( - mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Padding( diff --git a/lib/ui/navigation_drawer.dart b/lib/ui/navigation_drawer.dart index c368ef35..b7cf56c9 100644 --- a/lib/ui/navigation_drawer.dart +++ b/lib/ui/navigation_drawer.dart @@ -45,7 +45,6 @@ class NavigationDrawer extends StatelessWidget { widgets.add(_createSettingsItem(context)); var widget = Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: widgets, ); @@ -100,7 +99,6 @@ class NavigationDrawer extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 0, 0), child: Row( - crossAxisAlignment: CrossAxisAlignment.center, children: [ icon, Padding( @@ -135,7 +133,6 @@ class NavigationDrawer extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(20, 15, 0, 10), child: Row( - crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon( Icons.settings, diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index 83f92b22..3f812c20 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -76,8 +76,6 @@ class _OnboardingPageState extends State child: PropertyChangeConsumer( builder: (BuildContext context, OnboardingViewModel? model, _) { return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded(child: _buildActiveOnboardingPage(model!)), OnboardingButtonBar( @@ -117,7 +115,6 @@ class _OnboardingPageState extends State return IntrinsicHeight( child: PageTransitionSwitcher( reverse: !model.didStepForward, - duration: const Duration(milliseconds: 300), transitionBuilder: ( Widget child, Animation animation, diff --git a/lib/ui/onboarding/widgets/dualis_login_page.dart b/lib/ui/onboarding/widgets/dualis_login_page.dart index 1fd4f60e..8c0613c2 100644 --- a/lib/ui/onboarding/widgets/dualis_login_page.dart +++ b/lib/ui/onboarding/widgets/dualis_login_page.dart @@ -48,7 +48,6 @@ class _DualisLoginCredentialsPageState widgets.add(_buildTestCredentialsButton(viewModel)); return Column( - mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: widgets, ); @@ -65,7 +64,6 @@ class _DualisLoginCredentialsPageState child: Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: viewModel?.isValid ?? false diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index b9159317..88ec56db 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -17,7 +17,6 @@ class _IcalUrlPageState extends State { @override Widget build(BuildContext context) { return Column( - mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(32, 0, 32, 0), diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index ba40b86e..b0301957 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -15,8 +15,6 @@ class _MannheimPageState extends State { @override Widget build(BuildContext context) { return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(32, 0, 32, 0), diff --git a/lib/ui/onboarding/widgets/onboarding_button_bar.dart b/lib/ui/onboarding/widgets/onboarding_button_bar.dart index f95cc7ab..9bacbf46 100644 --- a/lib/ui/onboarding/widgets/onboarding_button_bar.dart +++ b/lib/ui/onboarding/widgets/onboarding_button_bar.dart @@ -19,7 +19,6 @@ class OnboardingButtonBar extends StatelessWidget { return Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 0), child: Row( - crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildPreviousButton(context), diff --git a/lib/ui/onboarding/widgets/onboarding_page_background.dart b/lib/ui/onboarding/widgets/onboarding_page_background.dart index b31b0242..f37a41d1 100644 --- a/lib/ui/onboarding/widgets/onboarding_page_background.dart +++ b/lib/ui/onboarding/widgets/onboarding_page_background.dart @@ -30,7 +30,6 @@ class OnboardingPageBackground extends StatelessWidget { curve: const Interval( 0.0, 1, - curve: Curves.linear, ), ), ), @@ -43,7 +42,6 @@ class OnboardingPageBackground extends StatelessWidget { curve: const Interval( 0.0, 1, - curve: Curves.linear, ), ), ), @@ -56,7 +54,6 @@ class OnboardingPageBackground extends StatelessWidget { curve: const Interval( 0.0, 1, - curve: Curves.linear, ), ), ), @@ -69,7 +66,6 @@ class OnboardingPageBackground extends StatelessWidget { curve: const Interval( 0.0, 1, - curve: Curves.linear, ), ), ), diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index 60dc2245..af2e7f4a 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -17,7 +17,6 @@ class _RaplaUrlPageState extends State { @override Widget build(BuildContext context) { return Column( - mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(32, 0, 32, 0), diff --git a/lib/ui/onboarding/widgets/select_source_page.dart b/lib/ui/onboarding/widgets/select_source_page.dart index 53e3a68f..0f3c273a 100644 --- a/lib/ui/onboarding/widgets/select_source_page.dart +++ b/lib/ui/onboarding/widgets/select_source_page.dart @@ -18,7 +18,6 @@ class SelectSourcePage extends StatelessWidget { ) { final viewModel = model as SelectSourceViewModel?; return Column( - mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(32, 0, 32, 0), diff --git a/test/date_management/service/parsing/all_dates_extract_test.dart b/test/date_management/service/parsing/all_dates_extract_test.dart index 3657e0be..6ee47bab 100644 --- a/test/date_management/service/parsing/all_dates_extract_test.dart +++ b/test/date_management/service/parsing/all_dates_extract_test.dart @@ -18,12 +18,12 @@ Future main() async { expect(dateEntries[0].description, "Termin 1"); expect(dateEntries[0].year, "2020"); expect(dateEntries[0].comment, "bis 22.12.21"); - expect(dateEntries[0].start, DateTime(2020, 11, 10, 08, 00)); + expect(dateEntries[0].start, DateTime(2020, 11, 10, 08)); expect(dateEntries[1].description, "Abgabe Studienarbeit"); expect(dateEntries[1].year, "2021"); expect(dateEntries[1].comment, "Abgabesystem"); - expect(dateEntries[1].start, DateTime(2021, 03, 04, 00, 00)); + expect(dateEntries[1].start, DateTime(2021, 03, 04)); expect(dateEntries[2].description, "Abgabe Bachelorarbeit"); expect(dateEntries[2].year, "2019"); @@ -33,6 +33,6 @@ Future main() async { expect(dateEntries[3].description, "Abgabe Bericht Praxis 1"); expect(dateEntries[3].year, "2021"); expect(dateEntries[3].comment, "Elektronisches Abgabesystem"); - expect(dateEntries[3].start, DateTime(2022, 09, 05, 00, 00)); + expect(dateEntries[3].start, DateTime(2022, 09, 05)); }); } diff --git a/test/dualis/service/parsing/monthly_schedule_extract_test.dart b/test/dualis/service/parsing/monthly_schedule_extract_test.dart index a3ae447b..1dc638ba 100644 --- a/test/dualis/service/parsing/monthly_schedule_extract_test.dart +++ b/test/dualis/service/parsing/monthly_schedule_extract_test.dart @@ -26,10 +26,10 @@ Future main() async { ]; var startAndEndTime = [ - [DateTime(2020, 09, 08, 08, 00), DateTime(2020, 09, 08, 12, 15)], + [DateTime(2020, 09, 08, 08), DateTime(2020, 09, 08, 12, 15)], [DateTime(2020, 09, 10, 08, 30), DateTime(2020, 09, 10, 12, 45)], [DateTime(2020, 09, 10, 13, 30), DateTime(2020, 09, 10, 16, 45)], - [DateTime(2020, 09, 14, 09, 00), DateTime(2020, 09, 14, 11, 30)], + [DateTime(2020, 09, 14, 09), DateTime(2020, 09, 14, 11, 30)], [DateTime(2020, 09, 18, 08, 15), DateTime(2020, 09, 18, 11, 15)], [DateTime(2020, 09, 21, 08, 30), DateTime(2020, 09, 21, 11, 45)], [DateTime(2020, 09, 21, 13, 30), DateTime(2020, 09, 21, 16, 45)], diff --git a/test/schedule/business/schedule_diff_calculator_test.dart b/test/schedule/business/schedule_diff_calculator_test.dart index 89b834d7..e8332cb6 100644 --- a/test/schedule/business/schedule_diff_calculator_test.dart +++ b/test/schedule/business/schedule_diff_calculator_test.dart @@ -46,8 +46,8 @@ void main() { title: "Project management", professor: "Sam", details: "ipsum", - start: DateTime(2020, 06, 09, 17, 00), - end: DateTime(2020, 06, 09, 18, 00), + start: DateTime(2020, 06, 09, 17), + end: DateTime(2020, 06, 09, 18), ); newSchedule.addEntry(newEntry); @@ -165,8 +165,8 @@ Schedule generateSchedule() { title: "Chemistry", professor: "Mr. White", details: "We will make breaks", - start: DateTime(2020, 06, 09, 10, 00), - end: DateTime(2020, 06, 09, 12, 00), + start: DateTime(2020, 06, 09, 10), + end: DateTime(2020, 06, 09, 12), ), ScheduleEntry( room: "Room2", @@ -174,8 +174,8 @@ Schedule generateSchedule() { title: "Computer Science", professor: "Mr. Turing", details: "Lorem", - start: DateTime(2020, 06, 09, 13, 00), - end: DateTime(2020, 06, 09, 14, 00), + start: DateTime(2020, 06, 09, 13), + end: DateTime(2020, 06, 09, 14), ), ScheduleEntry( room: "Room3", @@ -183,8 +183,8 @@ Schedule generateSchedule() { title: "Physics", professor: "Mr. Hawking", details: "ipsum", - start: DateTime(2020, 06, 09, 15, 00), - end: DateTime(2020, 06, 09, 16, 00), + start: DateTime(2020, 06, 09, 15), + end: DateTime(2020, 06, 09, 16), ), ScheduleEntry( room: "Room3", @@ -192,8 +192,8 @@ Schedule generateSchedule() { title: "Physics", professor: "Mr. Hawking", details: "ipsum", - start: DateTime(2020, 06, 09, 17, 00), - end: DateTime(2020, 06, 09, 18, 00), + start: DateTime(2020, 06, 09, 17), + end: DateTime(2020, 06, 09, 18), ), ]; diff --git a/test/schedule/service/ical/ical_parser_test.dart b/test/schedule/service/ical/ical_parser_test.dart index 586b61ed..12968c70 100644 --- a/test/schedule/service/ical/ical_parser_test.dart +++ b/test/schedule/service/ical/ical_parser_test.dart @@ -17,20 +17,20 @@ Future main() async { expect(schedule.entries.length, 3); expect(schedule.entries[0].title, "Angewandte Mathematik"); - expect(schedule.entries[0].start, DateTime(2019, 04, 01, 10, 00, 00)); - expect(schedule.entries[0].end, DateTime(2019, 04, 01, 14, 30, 00)); + expect(schedule.entries[0].start, DateTime(2019, 04, 01, 10)); + expect(schedule.entries[0].end, DateTime(2019, 04, 01, 14, 30)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].room, "Raum 035B"); expect(schedule.entries[1].title, "Elektronik"); - expect(schedule.entries[1].start, DateTime(2019, 04, 02, 08, 00, 00)); - expect(schedule.entries[1].end, DateTime(2019, 04, 02, 14, 00, 00)); + expect(schedule.entries[1].start, DateTime(2019, 04, 02, 08)); + expect(schedule.entries[1].end, DateTime(2019, 04, 02, 14)); expect(schedule.entries[1].type, ScheduleEntryType.Class); expect(schedule.entries[1].room, "Raum 035B"); expect(schedule.entries[2].title, "Informatik"); - expect(schedule.entries[2].start, DateTime(2019, 04, 03, 09, 00, 00)); - expect(schedule.entries[2].end, DateTime(2019, 04, 03, 12, 15, 00)); + expect(schedule.entries[2].start, DateTime(2019, 04, 03, 09)); + expect(schedule.entries[2].end, DateTime(2019, 04, 03, 12, 15)); expect(schedule.entries[2].type, ScheduleEntryType.Class); expect(schedule.entries[2].room, "Raum 035B"); }); diff --git a/test/schedule/service/rapla/rapla_response_parser_test.dart b/test/schedule/service/rapla/rapla_response_parser_test.dart index 70b81d19..be0e5d63 100644 --- a/test/schedule/service/rapla/rapla_response_parser_test.dart +++ b/test/schedule/service/rapla/rapla_response_parser_test.dart @@ -55,12 +55,12 @@ Future main() async { expect(schedule.entries[0].professor, "Müller, Georg"); expect(schedule.entries[1].title, "Semestereinführung"); - expect(schedule.entries[1].start, DateTime(2020, 09, 07, 12, 00)); + expect(schedule.entries[1].start, DateTime(2020, 09, 07, 12)); expect(schedule.entries[1].end, DateTime(2020, 09, 07, 12, 30)); expect(schedule.entries[1].type, ScheduleEntryType.Class); expect(schedule.entries[2].title, "Messdatenerfassung"); - expect(schedule.entries[2].start, DateTime(2020, 09, 07, 13, 00)); + expect(schedule.entries[2].start, DateTime(2020, 09, 07, 13)); expect(schedule.entries[2].end, DateTime(2020, 09, 07, 14, 30)); expect(schedule.entries[2].type, ScheduleEntryType.Class); @@ -70,22 +70,22 @@ Future main() async { expect(schedule.entries[3].type, ScheduleEntryType.Class); expect(schedule.entries[4].title, "Signale & Systeme I"); - expect(schedule.entries[4].start, DateTime(2020, 09, 08, 13, 00)); - expect(schedule.entries[4].end, DateTime(2020, 09, 08, 15, 00)); + expect(schedule.entries[4].start, DateTime(2020, 09, 08, 13)); + expect(schedule.entries[4].end, DateTime(2020, 09, 08, 15)); expect(schedule.entries[4].type, ScheduleEntryType.Class); expect(schedule.entries[5].title, "Angewandte Mathematik"); - expect(schedule.entries[5].start, DateTime(2020, 09, 09, 09, 00)); + expect(schedule.entries[5].start, DateTime(2020, 09, 09, 09)); expect(schedule.entries[5].end, DateTime(2020, 09, 09, 11, 45)); expect(schedule.entries[5].type, ScheduleEntryType.Class); expect(schedule.entries[6].title, "SWE"); expect(schedule.entries[6].start, DateTime(2020, 09, 10, 09, 15)); - expect(schedule.entries[6].end, DateTime(2020, 09, 10, 12, 00)); + expect(schedule.entries[6].end, DateTime(2020, 09, 10, 12)); expect(schedule.entries[6].type, ScheduleEntryType.Class); expect(schedule.entries[7].title, "Messdatenerfassung"); - expect(schedule.entries[7].start, DateTime(2020, 09, 10, 13, 00)); + expect(schedule.entries[7].start, DateTime(2020, 09, 10, 13)); expect(schedule.entries[7].end, DateTime(2020, 09, 10, 14, 30)); expect(schedule.entries[7].type, ScheduleEntryType.Class); }); @@ -98,8 +98,8 @@ Future main() async { expect(schedule.entries.length, 9); expect(schedule.entries[0].title, "Mikrocontroller ONLINE"); - expect(schedule.entries[0].start, DateTime(2020, 10, 01, 13, 00)); - expect(schedule.entries[0].end, DateTime(2020, 10, 01, 18, 00)); + expect(schedule.entries[0].start, DateTime(2020, 10, 01, 13)); + expect(schedule.entries[0].end, DateTime(2020, 10, 01, 18)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "Schmitt, Tobias"); }); @@ -110,26 +110,26 @@ Future main() async { var schedule = parser.parseSchedule(severalMonthsPage).schedule; expect(schedule.entries[0].title, "Modulprüfung T3_2000"); - expect(schedule.entries[0].start, DateTime(2021, 09, 22, 08, 00)); - expect(schedule.entries[0].end, DateTime(2021, 09, 22, 15, 00)); + expect(schedule.entries[0].start, DateTime(2021, 09, 22, 08)); + expect(schedule.entries[0].end, DateTime(2021, 09, 22, 15)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "A"); expect(schedule.entries[0].room, "MOS-TINF19A,A 1.380 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00),A 1.390 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00)",); expect(schedule.entries[2].title, "Tag der Deutschen Einheit"); - expect(schedule.entries[2].start, DateTime(2021, 10, 03, 08, 00)); - expect(schedule.entries[2].end, DateTime(2021, 10, 03, 18, 00)); + expect(schedule.entries[2].start, DateTime(2021, 10, 03, 08)); + expect(schedule.entries[2].end, DateTime(2021, 10, 03, 18)); expect(schedule.entries[2].type, ScheduleEntryType.Unknown); expect(schedule.entries[8].title, "Ausgewählte Themen der Informatik"); expect(schedule.entries[8].start, DateTime(2021, 10, 06, 13, 45)); - expect(schedule.entries[8].end, DateTime(2021, 10, 06, 17, 00)); + expect(schedule.entries[8].end, DateTime(2021, 10, 06, 17)); expect(schedule.entries[8].type, ScheduleEntryType.Class); expect(schedule.entries[84].title, "Silvester"); - expect(schedule.entries[84].start, DateTime(2021, 12, 31, 08, 00)); - expect(schedule.entries[84].end, DateTime(2021, 12, 31, 18, 00)); + expect(schedule.entries[84].start, DateTime(2021, 12, 31, 08)); + expect(schedule.entries[84].end, DateTime(2021, 12, 31, 18)); expect(schedule.entries[84].type, ScheduleEntryType.Unknown); expect(schedule.entries.length, 85); @@ -148,19 +148,19 @@ Future main() async { expect(schedule.entries[0].professor, "Müller"); expect(schedule.entries[3].title, "Marketing und Unternehmensstrategie"); - expect(schedule.entries[3].start, DateTime(2021, 12, 03, 13, 00)); + expect(schedule.entries[3].start, DateTime(2021, 12, 03, 13)); expect(schedule.entries[3].end, DateTime(2021, 12, 03, 16, 15)); expect(schedule.entries[3].type, ScheduleEntryType.Class); expect(schedule.entries[3].professor, "Mayer"); expect(schedule.entries[11].title, "Stahlbetonbau"); - expect(schedule.entries[11].start, DateTime(2021, 12, 17, 09, 00)); + expect(schedule.entries[11].start, DateTime(2021, 12, 17, 09)); expect(schedule.entries[11].end, DateTime(2021, 12, 17, 10, 30)); expect(schedule.entries[11].type, ScheduleEntryType.Exam); expect(schedule.entries[17].title, "Silvester"); - expect(schedule.entries[17].start, DateTime(2021, 12, 31, 08, 00)); - expect(schedule.entries[17].end, DateTime(2021, 12, 31, 18, 00)); + expect(schedule.entries[17].start, DateTime(2021, 12, 31, 08)); + expect(schedule.entries[17].end, DateTime(2021, 12, 31, 18)); expect(schedule.entries[17].type, ScheduleEntryType.Unknown); expect(schedule.entries.length, 20); @@ -172,7 +172,7 @@ Future main() async { var schedule = parser.parseSchedule(severalMonthsPage2).schedule; expect(schedule.entries[0].title, "Marketing und Unternehmensstrategie"); - expect(schedule.entries[0].start, DateTime(2021, 12, 01, 10, 00)); + expect(schedule.entries[0].start, DateTime(2021, 12, 01, 10)); expect(schedule.entries[0].end, DateTime(2021, 12, 01, 13, 30)); expect(schedule.entries[0].type, ScheduleEntryType.Unknown); @@ -185,7 +185,7 @@ Future main() async { var schedule = parser.parseSchedule(raplaPage1).schedule; expect(schedule.entries[0].title, "Grundlagen der Handelsbetriebslehre"); - expect(schedule.entries[0].start, DateTime(2021, 11, 02, 09, 00)); + expect(schedule.entries[0].start, DateTime(2021, 11, 02, 09)); expect(schedule.entries[0].end, DateTime(2021, 11, 02, 12, 15)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "Fr, Ta"); @@ -195,14 +195,14 @@ Future main() async { expect(schedule.entries[1].title, "Einführung in die Volkswirtschaftslehre und Mikroökonomik",); expect(schedule.entries[1].start, DateTime(2021, 11, 02, 13, 45)); - expect(schedule.entries[1].end, DateTime(2021, 11, 02, 17, 00)); + expect(schedule.entries[1].end, DateTime(2021, 11, 02, 17)); expect(schedule.entries[1].type, ScheduleEntryType.Class); expect(schedule.entries[1].professor, "Le, An"); expect(schedule.entries[1].room, "WDCM21B,D221 W Hörsaal (Mo 11.10.21 09:00),G086 W Hörsaal (Mo 25.10.21 09:00, Mo 15.11.21 09:00),F218_1 PA Hörsaal (Mo 22.11.21 09:00, Mo 06.12.21 09:00),A167 W Hörsaal (Mo 29.11.21 09:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 13:45)",); expect(schedule.entries[2].title, "Grundlagen des Bürgerlichen Rechts"); - expect(schedule.entries[2].start, DateTime(2021, 11, 03, 09, 00)); + expect(schedule.entries[2].start, DateTime(2021, 11, 03, 09)); expect(schedule.entries[2].end, DateTime(2021, 11, 03, 11, 30)); expect(schedule.entries[2].type, ScheduleEntryType.Class); expect(schedule.entries[2].professor, "Ei, An"); @@ -210,7 +210,7 @@ Future main() async { "WDCM21B,XOnline-Veranstaltung A Virtueller Raum (Mi 13.10.21 09:00, Mi 27.10.21 09:00, Mi 10.11.21 09:00, Mi 24.11.21 09:00, Fr 03.12.21 10:00),D221 W Hörsaal (Mi 20.10.21 13:00, Mi 17.11.21 09:00),G086 W Hörsaal (Di 26.10.21 09:00, Mi 03.11.21 09:00),B354 W Hörsaal (Fr 03.12.21 10:00),F218_1 PA Hörsaal (Mi 08.12.21 09:00)",); expect(schedule.entries[3].title, "Technik der Finanzbuchführung I"); - expect(schedule.entries[3].start, DateTime(2021, 11, 03, 13, 00)); + expect(schedule.entries[3].start, DateTime(2021, 11, 03, 13)); expect(schedule.entries[3].end, DateTime(2021, 11, 03, 16, 15)); expect(schedule.entries[3].type, ScheduleEntryType.Class); expect(schedule.entries[3].professor, "Se, Ka"); @@ -219,7 +219,7 @@ Future main() async { expect(schedule.entries[4].title, "Grundlagen des wissenschaftlichen Arbeitens",); - expect(schedule.entries[4].start, DateTime(2021, 11, 04, 09, 00)); + expect(schedule.entries[4].start, DateTime(2021, 11, 04, 09)); expect(schedule.entries[4].end, DateTime(2021, 11, 04, 12, 15)); expect(schedule.entries[4].type, ScheduleEntryType.Class); expect(schedule.entries[4].professor, "He, Be"); @@ -228,14 +228,14 @@ Future main() async { expect(schedule.entries[5].title, "Grundlagen der Handelsbetriebslehre"); expect(schedule.entries[5].start, DateTime(2021, 11, 04, 12, 45)); - expect(schedule.entries[5].end, DateTime(2021, 11, 04, 16, 00)); + expect(schedule.entries[5].end, DateTime(2021, 11, 04, 16)); expect(schedule.entries[5].type, ScheduleEntryType.Class); expect(schedule.entries[5].professor, "Fr, Ta"); expect(schedule.entries[5].room, "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)",); expect(schedule.entries[6].title, "Einführung in die Programmierung"); - expect(schedule.entries[6].start, DateTime(2021, 11, 05, 13, 00)); + expect(schedule.entries[6].start, DateTime(2021, 11, 05, 13)); expect(schedule.entries[6].end, DateTime(2021, 11, 05, 16, 15)); expect(schedule.entries[6].type, ScheduleEntryType.Class); expect(schedule.entries[6].professor, "He, Ma"); @@ -266,8 +266,8 @@ Future main() async { var schedule = parser.parseSchedule(raplaWeekResponse1).schedule; expect(schedule.entries[0].title, "Klausur Elektronik und Messtechnik"); - expect(schedule.entries[0].start, DateTime(2021, 12, 13, 08, 00)); - expect(schedule.entries[0].end, DateTime(2021, 12, 13, 10, 00)); + expect(schedule.entries[0].start, DateTime(2021, 12, 13, 08)); + expect(schedule.entries[0].end, DateTime(2021, 12, 13, 10)); expect(schedule.entries[0].type, ScheduleEntryType.Exam); expect(schedule.entries[0].professor, "Man, R."); expect(schedule.entries[0].room, From 0b9168bb005365dfd4b9c1ad1f0ffd6612ba5eb3 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:17:37 +0200 Subject: [PATCH 08/37] fix prefer_final lints --- analysis_options.yaml | 5 +- lib/common/appstart/app_initializer.dart | 4 +- .../appstart/background_initialize.dart | 4 +- .../appstart/localization_initialize.dart | 2 +- ...ification_schedule_changed_initialize.dart | 8 +-- .../appstart/notifications_initialize.dart | 2 +- lib/common/appstart/service_injector.dart | 2 +- .../background/background_work_scheduler.dart | 2 +- lib/common/data/database_access.dart | 22 +++---- lib/common/data/database_path_provider.dart | 12 ++-- .../preferences/preferences_provider.dart | 10 ++-- lib/common/iap/in_app_purchase_helper.dart | 6 +- lib/common/iap/in_app_purchase_manager.dart | 8 +-- lib/common/ui/colors.dart | 6 +- lib/common/ui/donate_to_developer_dialog.dart | 4 +- lib/common/ui/notification_api.dart | 12 ++-- lib/common/ui/widgets/dots_indicator.dart | 2 +- lib/common/util/date_utils.dart | 2 +- lib/common/util/string_utils.dart | 2 +- .../business/date_entry_provider.dart | 16 ++--- lib/date_management/data/calendar_access.dart | 22 +++---- .../data/date_entry_entity.dart | 2 +- .../data/date_entry_repository.dart | 16 ++--- .../service/date_management_service.dart | 4 +- .../service/parsing/all_dates_extract.dart | 24 ++++---- .../ui/calendar_export_page.dart | 4 +- .../ui/date_management_page.dart | 6 +- .../calendar_export_view_model.dart | 2 +- .../date_management_view_model.dart | 14 ++--- .../ui/widgets/date_detail_bottom_sheet.dart | 4 +- .../ui/widgets/date_filter_options.dart | 12 ++-- .../cache_dualis_service_decorator.dart | 8 +-- lib/dualis/service/dualis_authentication.dart | 24 ++++---- lib/dualis/service/dualis_scraper.dart | 22 +++---- lib/dualis/service/dualis_service.dart | 22 +++---- .../service/parsing/all_modules_extract.dart | 24 ++++---- .../exams_from_module_details_extract.dart | 22 +++---- .../parsing/login_redirect_url_extract.dart | 10 ++-- ...dules_from_course_result_page_extract.dart | 26 ++++----- .../parsing/monthly_schedule_extract.dart | 34 +++++------ lib/dualis/service/parsing/parsing_utils.dart | 8 +-- ...sters_from_course_result_page_extract.dart | 28 ++++----- ...des_from_student_results_page_extract.dart | 30 +++++----- .../parsing/urls_from_main_page_extract.dart | 10 ++-- lib/dualis/service/session.dart | 18 +++--- lib/dualis/ui/dualis_page.dart | 2 +- .../exam_results_page/exam_results_page.dart | 8 +-- lib/dualis/ui/login/dualis_login_page.dart | 2 +- .../study_overview/study_overview_page.dart | 4 +- .../viewmodels/study_grades_view_model.dart | 4 +- lib/dualis/ui/widgets/login_form_widget.dart | 4 +- lib/main.dart | 4 +- .../background_schedule_update.dart | 6 +- .../background/calendar_synchronizer.dart | 6 +- .../business/schedule_diff_calculator.dart | 38 ++++++------ lib/schedule/business/schedule_filter.dart | 6 +- lib/schedule/business/schedule_provider.dart | 16 ++--- .../business/schedule_source_provider.dart | 26 ++++----- lib/schedule/data/schedule_entry_entity.dart | 4 +- .../data/schedule_entry_repository.dart | 22 +++---- .../data/schedule_filter_repository.dart | 6 +- ...schedule_query_information_repository.dart | 8 +-- lib/schedule/model/schedule.dart | 22 +++---- lib/schedule/model/schedule_entry.dart | 2 +- .../dualis/dualis_schedule_source.dart | 4 +- ...rror_report_schedule_source_decorator.dart | 2 +- lib/schedule/service/ical/ical_parser.dart | 18 +++--- .../service/ical/ical_schedule_source.dart | 10 ++-- .../isolate_schedule_source_decorator.dart | 14 ++--- .../mannheim_course_response_parser.dart | 16 ++--- .../mannheim/mannheim_course_scraper.dart | 6 +- .../rapla/rapla_monthly_response_parser.dart | 36 ++++++------ .../service/rapla/rapla_parsing_utils.dart | 56 +++++++++--------- .../service/rapla/rapla_response_parser.dart | 6 +- .../service/rapla/rapla_schedule_source.dart | 46 +++++++-------- .../rapla_several_months_response_parser.dart | 8 +-- .../rapla/rapla_week_response_parser.dart | 32 +++++----- lib/schedule/service/schedule_prettifier.dart | 14 ++--- .../ui/dailyschedule/daily_schedule_page.dart | 8 +-- .../widgets/daily_schedule_entry_widget.dart | 6 +- .../next_day_information_notification.dart | 14 ++--- .../schedule_changed_notification.dart | 12 ++-- .../viewmodels/daily_schedule_view_model.dart | 2 +- .../weekly_schedule_view_model.dart | 12 ++-- .../filter/filter_view_model.dart | 8 +-- .../schedule_entry_detail_bottom_sheet.dart | 8 +-- .../widgets/schedule_entry_alignment.dart | 18 +++--- .../widgets/schedule_entry_widget.dart | 2 +- .../weeklyschedule/widgets/schedule_grid.dart | 6 +- .../widgets/schedule_past_overlay.dart | 12 ++-- .../widgets/schedule_widget.dart | 52 ++++++++--------- lib/schedule/ui/widgets/enter_url_dialog.dart | 2 +- .../ui/widgets/select_source_dialog.dart | 2 +- lib/ui/main_page.dart | 8 +-- lib/ui/navigation/router.dart | 2 +- lib/ui/navigation_drawer.dart | 6 +- lib/ui/onboarding/onboardin_step.dart | 4 +- lib/ui/onboarding/onboarding_page.dart | 6 +- .../viewmodels/ical_url_view_model.dart | 2 +- .../viewmodels/onboarding_view_model.dart | 6 +- .../viewmodels/rapla_url_view_model.dart | 2 +- .../onboarding/widgets/dualis_login_page.dart | 2 +- lib/ui/onboarding/widgets/mannheim_page.dart | 2 +- .../widgets/onboarding_button_bar.dart | 2 +- lib/ui/pager_widget.dart | 6 +- lib/ui/settings/settings_page.dart | 8 +-- .../viewmodels/settings_view_model.dart | 2 +- test/common/util/string_utils_test.dart | 4 +- .../parsing/all_dates_extract_test.dart | 6 +- .../parsing/all_modules_extract_test.dart | 8 +-- .../parsing/dualis_timeout_extract_test.dart | 4 +- ...xams_from_module_details_extract_test.dart | 8 +-- ..._from_course_result_page_extract_test.dart | 8 +-- .../monthly_schedule_extract_test.dart | 10 ++-- ..._from_course_result_page_extract_test.dart | 8 +-- ...rom_student_results_page_extract_test.dart | 8 +-- .../urls_from_main_page_extract_test.dart | 8 +-- test/rapla_service_test.dart | 2 +- .../schedule_diff_calculator_test.dart | 52 ++++++++--------- .../service/ical/ical_parser_test.dart | 6 +- .../mannheim_course_response_parser_test.dart | 6 +- .../rapla/rapla_response_parser_test.dart | 58 +++++++++---------- 122 files changed, 703 insertions(+), 700 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 73419ee3..e1f9ffff 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,7 +3,7 @@ # For apps, use the default set #include: package:lint/analysis_options.yaml -# Packages, that may be distributed (i.e. via pub.dev) should use the package +# Packages, that may be distributed (i.e. via pub.dev) should use the package # version, resulting in a better pub score. # include: package:lint/analysis_options_package.yaml @@ -18,3 +18,6 @@ linter: rules: require_trailing_commas: true avoid_redundant_argument_values: true + prefer_final_locals: true + prefer_final_in_for_each: true + prefer_final_fields: true diff --git a/lib/common/appstart/app_initializer.dart b/lib/common/appstart/app_initializer.dart index 8de25aeb..d3ad9e6a 100644 --- a/lib/common/appstart/app_initializer.dart +++ b/lib/common/appstart/app_initializer.dart @@ -57,12 +57,12 @@ Future initializeApp(bool isBackground) async { NotificationScheduleChangedInitialize().setupNotification(); if (isBackground) { - var setup = KiwiContainer().resolve(); + final setup = KiwiContainer().resolve(); setup.setupScheduleSource(); } // Callback-Function for synchronizing the device calendar with the schedule, when schedule is updated - CalendarSynchronizer calendarSynchronizer = new CalendarSynchronizer( + final CalendarSynchronizer calendarSynchronizer = new CalendarSynchronizer( KiwiContainer().resolve(), KiwiContainer().resolve(), KiwiContainer().resolve(),); diff --git a/lib/common/appstart/background_initialize.dart b/lib/common/appstart/background_initialize.dart index 0b3dbb31..1fe025e2 100644 --- a/lib/common/appstart/background_initialize.dart +++ b/lib/common/appstart/background_initialize.dart @@ -22,7 +22,7 @@ class BackgroundInitialize { KiwiContainer().registerInstance(scheduler); - var tasks = [ + final tasks = [ BackgroundScheduleUpdate( KiwiContainer().resolve(), KiwiContainer().resolve(), @@ -37,7 +37,7 @@ class BackgroundInitialize { ), ]; - for (var task in tasks) { + for (final task in tasks) { scheduler.registerTask(task); KiwiContainer().registerInstance( diff --git a/lib/common/appstart/localization_initialize.dart b/lib/common/appstart/localization_initialize.dart index 2a35404a..f091c5d2 100644 --- a/lib/common/appstart/localization_initialize.dart +++ b/lib/common/appstart/localization_initialize.dart @@ -23,7 +23,7 @@ class LocalizationInitialize { LocalizationInitialize.fromPreferences(this._preferencesProvider); Future setupLocalizations() async { - var localization = L(Locale( + final localization = L(Locale( _languageCode ?? (await _preferencesProvider?.getLastUsedLanguageCode() ?? "en"), ),); diff --git a/lib/common/appstart/notification_schedule_changed_initialize.dart b/lib/common/appstart/notification_schedule_changed_initialize.dart index 4d1728f5..c5c0209d 100644 --- a/lib/common/appstart/notification_schedule_changed_initialize.dart +++ b/lib/common/appstart/notification_schedule_changed_initialize.dart @@ -9,18 +9,18 @@ import 'package:kiwi/kiwi.dart'; /// class NotificationScheduleChangedInitialize { void setupNotification() { - var provider = KiwiContainer().resolve(); + final provider = KiwiContainer().resolve(); provider.addScheduleEntryChangedCallback(_scheduleChangedCallback); } Future _scheduleChangedCallback(ScheduleDiff scheduleDiff) async { - PreferencesProvider preferences = KiwiContainer().resolve(); - var doNotify = await preferences.getNotifyAboutScheduleChanges(); + final PreferencesProvider preferences = KiwiContainer().resolve(); + final doNotify = await preferences.getNotifyAboutScheduleChanges(); if (!doNotify) return; - var notification = ScheduleChangedNotification( + final notification = ScheduleChangedNotification( KiwiContainer().resolve(), KiwiContainer().resolve(), ); diff --git a/lib/common/appstart/notifications_initialize.dart b/lib/common/appstart/notifications_initialize.dart index 2fce4c9f..ec9a664d 100644 --- a/lib/common/appstart/notifications_initialize.dart +++ b/lib/common/appstart/notifications_initialize.dart @@ -11,7 +11,7 @@ import 'package:kiwi/kiwi.dart'; class NotificationsInitialize { Future setupNotifications() async { if (Platform.isAndroid) { - var notificationApi = NotificationApi(); + final notificationApi = NotificationApi(); KiwiContainer().registerInstance(notificationApi); diff --git a/lib/common/appstart/service_injector.dart b/lib/common/appstart/service_injector.dart index a6c73883..2980bdf2 100644 --- a/lib/common/appstart/service_injector.dart +++ b/lib/common/appstart/service_injector.dart @@ -28,7 +28,7 @@ bool _isInjected = false; void injectServices(bool isBackground) { if (_isInjected) return; - KiwiContainer c = KiwiContainer(); + final KiwiContainer c = KiwiContainer(); c.registerInstance(PreferencesProvider( PreferencesAccess(), SecureStorageAccess(), diff --git a/lib/common/background/background_work_scheduler.dart b/lib/common/background/background_work_scheduler.dart index 61efc6a8..d746dd75 100644 --- a/lib/common/background/background_work_scheduler.dart +++ b/lib/common/background/background_work_scheduler.dart @@ -109,7 +109,7 @@ class BackgroundWorkScheduler extends WorkSchedulerService { await initializeApp(true); - WorkSchedulerService scheduler = KiwiContainer().resolve(); + final WorkSchedulerService scheduler = KiwiContainer().resolve(); await scheduler.executeTask(taskId); } catch (e, trace) { diff --git a/lib/common/data/database_access.dart b/lib/common/data/database_access.dart index 73161621..f1ca87ab 100644 --- a/lib/common/data/database_access.dart +++ b/lib/common/data/database_access.dart @@ -33,7 +33,7 @@ class DatabaseAccess { for (var i = oldVersion; i <= newVersion; i++) { print(" -> Execute migration to $i"); - for (var s in SqlScripts.databaseMigrationScripts[i - 1]) { + for (final s in SqlScripts.databaseMigrationScripts[i - 1]) { print(" -> $s"); await db.execute(s); } @@ -41,18 +41,18 @@ class DatabaseAccess { } Future insert(String table, Map row) async { - Database db = await _database; + final Database db = await _database; return await db.insert(table, row); } Future>> queryAllRows(String table) async { - Database db = await _database; + final Database db = await _database; return await db.query(table); } Future>> rawQuery( String sql, List parameters,) async { - Database db = await _database; + final Database db = await _database; return await db.rawQuery(sql, parameters); } @@ -66,7 +66,7 @@ class DatabaseAccess { String? orderBy, int? limit, int? offset,}) async { - Database db = await _database; + final Database db = await _database; // TODO: [Leptopoda] is there a reason this is done? or at maybe use whereArgs.removeWhere() for (int i = 0; i < (whereArgs?.length ?? 0); i++) { @@ -88,25 +88,25 @@ class DatabaseAccess { } Future queryRowCount(String table) async { - Database db = await _database; + final Database db = await _database; return Sqflite.firstIntValue( await db.rawQuery('SELECT COUNT(*) FROM $table'),); } Future queryAggregator(String query, List arguments) async { - Database db = await _database; + final Database db = await _database; return Sqflite.firstIntValue(await db.rawQuery(query, arguments)); } Future update(String table, Map row) async { - Database db = await _database; - int? id = row[idColumnName]; + final Database db = await _database; + final int? id = row[idColumnName]; return await db .update(table, row, where: '$idColumnName = ?', whereArgs: [id]); } Future delete(String table, int? id) async { - Database db = await _database; + final Database db = await _database; return await db.delete(table, where: '$idColumnName = ?', whereArgs: [id]); } @@ -115,7 +115,7 @@ class DatabaseAccess { String? where, List? whereArgs, }) async { - Database db = await _database; + final Database db = await _database; return await db.delete( table, where: where, diff --git a/lib/common/data/database_path_provider.dart b/lib/common/data/database_path_provider.dart index e5a5be00..0900fe2d 100644 --- a/lib/common/data/database_path_provider.dart +++ b/lib/common/data/database_path_provider.dart @@ -5,7 +5,7 @@ import 'package:path/path.dart'; import 'package:app_group_directory/app_group_directory.dart'; Future getDatabasePath(String databaseName) async { - Directory documentsDirectory = await getApplicationDocumentsDirectory(); + final Directory documentsDirectory = await getApplicationDocumentsDirectory(); var path = join(documentsDirectory.path, databaseName); @@ -26,13 +26,13 @@ Future _getiOSDatabasePathAndMigrate( // copied to the new path assert(Platform.isIOS); - Directory? groupDirectory = await AppGroupDirectory.getAppGroupDirectory( + final Directory? groupDirectory = await AppGroupDirectory.getAppGroupDirectory( 'group.de.bennik2000.dhbwstudentapp', ); - var newPath = join(groupDirectory!.path, databaseName); + final newPath = join(groupDirectory!.path, databaseName); - var migrateSuccess = await _migrateOldDatabase(oldPath, newPath); + final migrateSuccess = await _migrateOldDatabase(oldPath, newPath); if (!migrateSuccess) { print("Failed to migrate database"); @@ -43,8 +43,8 @@ Future _getiOSDatabasePathAndMigrate( Future _migrateOldDatabase(String oldPath, String newPath) async { try { - var newFile = File(newPath); - var oldFile = File(oldPath); + final newFile = File(newPath); + final oldFile = File(oldPath); if (await oldFile.exists() && !(await newFile.exists())) { print("Migrating database..."); diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index 5a551ca6..af10e3e8 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -36,7 +36,7 @@ class PreferencesProvider { PreferencesProvider(this._preferencesAccess, this._secureStorageAccess); Future appTheme() async { - var theme = await _preferencesAccess.get(AppThemeKey); + final theme = await _preferencesAccess.get(AppThemeKey); return AppTheme.values.firstWhere( (element) => element.name == theme, @@ -66,10 +66,10 @@ class PreferencesProvider { Future getSelectedCalendar() async { Calendar? selectedCalendar; - String? selectedCalendarId = + final String? selectedCalendarId = await _preferencesAccess.get('SelectedCalendarId'); if (selectedCalendarId == null) return null; - List availableCalendars = + final List availableCalendars = await CalendarAccess().queryWriteableCalendars(); availableCalendars.forEach((cal) => { if (cal.id == selectedCalendarId) {selectedCalendar = cal} @@ -132,8 +132,8 @@ class PreferencesProvider { } Future loadDualisCredentials() async { - var username = await _secureStorageAccess.get(DualisUsername); - var password = await _secureStorageAccess.get(DualisPassword); + final username = await _secureStorageAccess.get(DualisUsername); + final password = await _secureStorageAccess.get(DualisPassword); if (username == null || password == null || diff --git a/lib/common/iap/in_app_purchase_helper.dart b/lib/common/iap/in_app_purchase_helper.dart index 631c168a..67360b6f 100644 --- a/lib/common/iap/in_app_purchase_helper.dart +++ b/lib/common/iap/in_app_purchase_helper.dart @@ -96,10 +96,10 @@ class InAppPurchaseHelper { } try { - var allPurchases = + final allPurchases = await FlutterInappPurchase.instance.getAvailablePurchases(); - var productIdPurchases = + final productIdPurchases = allPurchases?.where((element) => element.productId == id); if (productIdPurchases?.isNotEmpty ?? false) { @@ -125,7 +125,7 @@ class InAppPurchaseHelper { Future _completePurchase(PurchasedItem? item) async { if (item == null) return; - var purchaseResult = _purchaseResultFromItem(item); + final purchaseResult = _purchaseResultFromItem(item); _purchaseCallback?.call(item.productId, purchaseResult); diff --git a/lib/common/iap/in_app_purchase_manager.dart b/lib/common/iap/in_app_purchase_manager.dart index af6781ae..54b5c76d 100644 --- a/lib/common/iap/in_app_purchase_manager.dart +++ b/lib/common/iap/in_app_purchase_manager.dart @@ -39,7 +39,7 @@ class InAppPurchaseManager { } Future _restorePurchases() async { - var didPurchaseWidget = await didBuyWidget() == PurchaseStateEnum.Purchased; + final didPurchaseWidget = await didBuyWidget() == PurchaseStateEnum.Purchased; await _setWidgetEnabled(didPurchaseWidget); } @@ -65,7 +65,7 @@ class InAppPurchaseManager { void _purchaseCompletedCallback( String? productId, PurchaseResultEnum result,) { if (purchaseCallbacks.containsKey(productId)) { - var callback = purchaseCallbacks[productId!]; + final callback = purchaseCallbacks[productId!]; callback?.forEach((element) { element(productId, result); @@ -73,14 +73,14 @@ class InAppPurchaseManager { } if (purchaseCallbacks.containsKey("*")) { - var callback = purchaseCallbacks["*"]; + final callback = purchaseCallbacks["*"]; callback?.forEach((element) { element(productId, result); }); } - for (var pair in purchaseCallbacks.entries) { + for (final pair in purchaseCallbacks.entries) { pair.value.forEach((element) { element(null, result); }); diff --git a/lib/common/ui/colors.dart b/lib/common/ui/colors.dart index 1cea4e06..832d3d2a 100644 --- a/lib/common/ui/colors.dart +++ b/lib/common/ui/colors.dart @@ -75,11 +75,11 @@ class ColorPalettes { : AppTheme.Dark; } - var isDark = theme == AppTheme.Dark; + final isDark = theme == AppTheme.Dark; - var brightness = isDark ? Brightness.dark : Brightness.light; + final brightness = isDark ? Brightness.dark : Brightness.light; - var themeData = ThemeData( + final themeData = ThemeData( brightness: brightness, toggleableActiveColor: isDark ? ColorPalettes.main[700] : ColorPalettes.main[600], diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index 541a2a32..5dc4d432 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -11,8 +11,8 @@ import 'package:kiwi/kiwi.dart'; /// developer /// class DonateToDeveloperDialog { - PreferencesProvider _preferencesProvider; - int _appLaunchCounter; + final PreferencesProvider _preferencesProvider; + final int _appLaunchCounter; DonateToDeveloperDialog(this._preferencesProvider, this._appLaunchCounter); diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index 719e8e80..a302c7a3 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -15,16 +15,16 @@ class NotificationApi { /// call this method /// Future initialize() async { - var initializationSettingsAndroid = const AndroidInitializationSettings( + final initializationSettingsAndroid = const AndroidInitializationSettings( 'outline_event_note_24', ); - var initializationSettingsIOS = IOSInitializationSettings( + final initializationSettingsIOS = IOSInitializationSettings( // TODO: [Leptopoda] the below always returns null so why register it? onDidReceiveLocalNotification: onDidReceiveLocalNotification, ); - var initializationSettings = InitializationSettings( + final initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsIOS, ); @@ -39,7 +39,7 @@ class NotificationApi { /// Show a notification with the given title and message /// Future showNotification(String title, String? message, [int? id]) async { - var androidPlatformChannelSpecifics = AndroidNotificationDetails( + final androidPlatformChannelSpecifics = AndroidNotificationDetails( 'Notifications', 'Notifications', channelDescription: 'This is the main notification channel', @@ -52,9 +52,9 @@ class NotificationApi { ticker: 'ticker', ); - var iOSPlatformChannelSpecifics = const IOSNotificationDetails(); + final iOSPlatformChannelSpecifics = const IOSNotificationDetails(); - var platformChannelSpecifics = NotificationDetails( + final platformChannelSpecifics = NotificationDetails( android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics, ); diff --git a/lib/common/ui/widgets/dots_indicator.dart b/lib/common/ui/widgets/dots_indicator.dart index d7171f7f..20b33f46 100644 --- a/lib/common/ui/widgets/dots_indicator.dart +++ b/lib/common/ui/widgets/dots_indicator.dart @@ -10,7 +10,7 @@ class DotsIndicator extends StatelessWidget { @override Widget build(BuildContext context) { - var dots = []; + final dots = []; for (int i = 0; i < numberSteps; i++) { dots.add( diff --git a/lib/common/util/date_utils.dart b/lib/common/util/date_utils.dart index 48109a27..f1530e48 100644 --- a/lib/common/util/date_utils.dart +++ b/lib/common/util/date_utils.dart @@ -103,7 +103,7 @@ bool isAtSameDay(DateTime date1, DateTime date2) { DateTime? toDayOfWeek(DateTime? dateTime, int weekday) { if (dateTime == null) return null; - var startOfWeek = addDays(dateTime, -dateTime.weekday); + final startOfWeek = addDays(dateTime, -dateTime.weekday); return addDays(startOfWeek, weekday); } diff --git a/lib/common/util/string_utils.dart b/lib/common/util/string_utils.dart index d910d0e5..e67cf3e8 100644 --- a/lib/common/util/string_utils.dart +++ b/lib/common/util/string_utils.dart @@ -3,7 +3,7 @@ String concatStringList(List list, String separator) { var result = ""; - for (var element in list) { + for (final element in list) { result += element + separator; } diff --git a/lib/date_management/business/date_entry_provider.dart b/lib/date_management/business/date_entry_provider.dart index d5dc3e81..4737e5c0 100644 --- a/lib/date_management/business/date_entry_provider.dart +++ b/lib/date_management/business/date_entry_provider.dart @@ -21,9 +21,9 @@ class DateEntryProvider { parameters.year, ); } else { - var now = DateTime.now(); + final now = DateTime.now(); if (parameters.includeFuture!) { - var datesAfter = await _dateEntryRepository.queryDateEntriesAfter( + final datesAfter = await _dateEntryRepository.queryDateEntriesAfter( parameters.databaseName, parameters.year, now, @@ -32,7 +32,7 @@ class DateEntryProvider { } if (parameters.includePast!) { - var datesBefore = await _dateEntryRepository.queryDateEntriesBefore( + final datesBefore = await _dateEntryRepository.queryDateEntriesBefore( parameters.databaseName, parameters.year, now, @@ -54,7 +54,7 @@ class DateEntryProvider { DateSearchParameters parameters, CancellationToken? cancellationToken, ) async { - var updatedEntries = await _dateEntryService.queryAllDates( + final updatedEntries = await _dateEntryService.queryAllDates( parameters, cancellationToken, ); @@ -65,7 +65,7 @@ class DateEntryProvider { ); await _dateEntryRepository.saveDateEntries(updatedEntries); - var filteredDates = _filterDates(updatedEntries, parameters); + final filteredDates = _filterDates(updatedEntries, parameters); print("Read ${filteredDates.length} date entries"); @@ -74,11 +74,11 @@ class DateEntryProvider { List _filterDates( List updatedEntries, DateSearchParameters parameters,) { - var filteredDateEntries = []; + final filteredDateEntries = []; - var now = DateTime.now(); + final now = DateTime.now(); - for (var dateEntry in updatedEntries) { + for (final dateEntry in updatedEntries) { if (dateEntry.databaseName != parameters.databaseName) { continue; } diff --git a/lib/date_management/data/calendar_access.dart b/lib/date_management/data/calendar_access.dart index 150cf779..6f14f970 100644 --- a/lib/date_management/data/calendar_access.dart +++ b/lib/date_management/data/calendar_access.dart @@ -38,8 +38,8 @@ class CalendarAccess { Future> queryWriteableCalendars() async { final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); - var writeableCalendars = []; - for (var calendar in calendarsResult.data ?? []) { + final writeableCalendars = []; + for (final calendar in calendarsResult.data ?? []) { if (!calendar.isReadOnly!) { writeableCalendars.add(calendar); } @@ -54,10 +54,10 @@ class CalendarAccess { ) async { if (dateEntries.isEmpty) return; - var existingEvents = + final existingEvents = await _getExistingEventsFromCalendar(dateEntries, calendar!); - for (var entry in dateEntries) { + for (final entry in dateEntries) { await _addOrUpdateEntry(existingEvents, entry, calendar); } } @@ -66,7 +66,7 @@ class CalendarAccess { List existingEvents, DateEntry entry, Calendar calendar,) async { // Find the id in the existing events in order that the "update" part of // createOrUpdateEvent(...) works - var id = _getIdOfExistingEvent(existingEvents, entry); + final id = _getIdOfExistingEvent(existingEvents, entry); var isAllDay, start, end; if (entry.start.isAtSameMomentAs(entry.end)) { @@ -92,7 +92,7 @@ class CalendarAccess { } String? _getIdOfExistingEvent(List existingEvents, DateEntry entry) { - var existingEvent = existingEvents + final existingEvent = existingEvents .where((element) => (element.title == entry.description && (element.start?.toUtc().isAtSameMomentAs(entry.start.toUtc()) ?? false)),) @@ -107,10 +107,10 @@ class CalendarAccess { Future> _getExistingEventsFromCalendar( List dateEntries, Calendar calendar,) async { - var firstEntry = _findFirstEntry(dateEntries); - var lastEntry = _findLastEntry(dateEntries); + final firstEntry = _findFirstEntry(dateEntries); + final lastEntry = _findLastEntry(dateEntries); - var existingEventsResult = await _deviceCalendarPlugin.retrieveEvents( + final existingEventsResult = await _deviceCalendarPlugin.retrieveEvents( calendar.id, RetrieveEventsParams( startDate: firstEntry.start, @@ -128,7 +128,7 @@ class CalendarAccess { DateEntry _findFirstEntry(List entries) { var firstEntry = entries[0]; - for (var entry in entries) { + for (final entry in entries) { if (entry.end.isBefore(firstEntry.end)) { firstEntry = entry; } @@ -140,7 +140,7 @@ class CalendarAccess { DateEntry _findLastEntry(List entries) { var lastEntry = entries[0]; - for (var entry in entries) { + for (final entry in entries) { if (entry.end.isAfter(lastEntry.end)) { lastEntry = entry; } diff --git a/lib/date_management/data/date_entry_entity.dart b/lib/date_management/data/date_entry_entity.dart index b3b23a75..cc5a2af7 100644 --- a/lib/date_management/data/date_entry_entity.dart +++ b/lib/date_management/data/date_entry_entity.dart @@ -12,7 +12,7 @@ class DateEntryEntity extends DatabaseEntity { } void fromMap(Map map) { - var date = DateTime.fromMillisecondsSinceEpoch(map["date"]); + final date = DateTime.fromMillisecondsSinceEpoch(map["date"]); _dateEntry = DateEntry( comment: map["comment"], diff --git a/lib/date_management/data/date_entry_repository.dart b/lib/date_management/data/date_entry_repository.dart index 37f279bb..a3a81968 100644 --- a/lib/date_management/data/date_entry_repository.dart +++ b/lib/date_management/data/date_entry_repository.dart @@ -11,7 +11,7 @@ class DateEntryRepository { String? databaseName, String? year, ) async { - var rows = await _database.queryRows( + final rows = await _database.queryRows( DateEntryEntity.tableName(), where: "databaseName=? AND year=?", whereArgs: [databaseName, year], @@ -26,7 +26,7 @@ class DateEntryRepository { DateTime start, DateTime end, ) async { - var rows = await _database.queryRows( + final rows = await _database.queryRows( DateEntryEntity.tableName(), where: "date>=? AND date<=? AND databaseName=? AND year=?", whereArgs: [ @@ -45,7 +45,7 @@ class DateEntryRepository { String? year, DateTime date, ) async { - var rows = await _database.queryRows( + final rows = await _database.queryRows( DateEntryEntity.tableName(), where: "date>=? AND databaseName=? AND year=?", whereArgs: [ @@ -63,7 +63,7 @@ class DateEntryRepository { String? year, DateTime date, ) async { - var rows = await _database.queryRows( + final rows = await _database.queryRows( DateEntryEntity.tableName(), where: "date<=? AND databaseName=? AND year=?", whereArgs: [ @@ -77,12 +77,12 @@ class DateEntryRepository { } Future saveDateEntry(DateEntry entry) async { - var row = DateEntryEntity.fromModel(entry).toMap(); + final row = DateEntryEntity.fromModel(entry).toMap(); await _database.insert(DateEntryEntity.tableName(), row); } Future saveDateEntries(List entries) async { - for (var entry in entries) { + for (final entry in entries) { await saveDateEntry(entry); } } @@ -100,9 +100,9 @@ class DateEntryRepository { } List _rowsToDateEntries(List> rows) { - var dateEntries = []; + final dateEntries = []; - for (var row in rows) { + for (final row in rows) { dateEntries.add( DateEntryEntity.fromMap(row).asDateEntry(), ); diff --git a/lib/date_management/service/date_management_service.dart b/lib/date_management/service/date_management_service.dart index 0e5d11fa..3a2e26dd 100644 --- a/lib/date_management/service/date_management_service.dart +++ b/lib/date_management/service/date_management_service.dart @@ -9,12 +9,12 @@ class DateManagementService { DateSearchParameters parameters, CancellationToken? cancellationToken, ) async { - var queryResult = await Session().get( + final queryResult = await Session().get( _buildRequestUrl(parameters), cancellationToken, ); - var allDates = AllDatesExtract().extractAllDates( + final allDates = AllDatesExtract().extractAllDates( queryResult, parameters.databaseName, ); diff --git a/lib/date_management/service/parsing/all_dates_extract.dart b/lib/date_management/service/parsing/all_dates_extract.dart index 7bf71014..1d1bdfe7 100644 --- a/lib/date_management/service/parsing/all_dates_extract.dart +++ b/lib/date_management/service/parsing/all_dates_extract.dart @@ -17,20 +17,20 @@ class AllDatesExtract { List _extractAllDates(String body, String? databaseName) { body = body.replaceAll(new RegExp("<(br|BR)[ /]*>"), "\n"); - var document = parse(body); + final document = parse(body); // The dates are located in the first

element of the page - var dateContainingElement = document.getElementsByTagName("p")[0]; + final dateContainingElement = document.getElementsByTagName("p")[0]; - var dateEntries = []; + final dateEntries = []; - for (var a in dateContainingElement.nodes.sublist(0)) { - var text = a.text!; + for (final a in dateContainingElement.nodes.sublist(0)) { + final text = a.text!; - var lines = text.split("\n"); + final lines = text.split("\n"); - for (var line in lines) { - var dateEntry = _parseDateEntryLine(line, databaseName); + for (final line in lines) { + final dateEntry = _parseDateEntryLine(line, databaseName); if (dateEntry != null) { dateEntries.add(dateEntry); @@ -45,13 +45,13 @@ class AllDatesExtract { } DateEntry? _parseDateEntryLine(String line, String? databaseName) { - var parts = line.split(';'); + final parts = line.split(';'); if (parts.length != 5) { return null; } - var date = _parseDateTime( + final date = _parseDateTime( parts[2].trim(), parts[3].trim(), ); @@ -70,10 +70,10 @@ class AllDatesExtract { time = "00:00"; } - var dateAndTimeString = date + " " + time; + final dateAndTimeString = date + " " + time; try { - var date = DateFormat("dd.MM.yyyy hh:mm").parse(dateAndTimeString); + final date = DateFormat("dd.MM.yyyy hh:mm").parse(dateAndTimeString); return date; } on FormatException catch (_) { return null; diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 98f775f2..62122f05 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -87,7 +87,7 @@ class _CalendarExportPageState extends State { ListView.builder( itemCount: viewModel!.calendars.length, itemBuilder: (BuildContext context, int index) { - var isSelected = + final isSelected = viewModel.selectedCalendar?.id == viewModel.calendars[index].id; return _buildCalendarListEntry( @@ -225,7 +225,7 @@ class _CalendarExportPageState extends State { onTap: viewModel.canExport ? () async { if (widget.isCalendarSyncWidget) { - var preferencesProvider = KiwiContainer() + final preferencesProvider = KiwiContainer() .resolve(); preferencesProvider.setSelectedCalendar( viewModel.selectedCalendar,); diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index fbab8350..ab09e551 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -13,7 +13,7 @@ import 'package:provider/provider.dart'; class DateManagementPage extends StatelessWidget { @override Widget build(BuildContext context) { - DateManagementViewModel viewModel = + final DateManagementViewModel viewModel = Provider.of(context); return PropertyChangeProvider( @@ -92,8 +92,8 @@ class DateManagementPage extends StatelessWidget { DateManagementViewModel model, BuildContext context, ) { - var dataRows = []; - for (DateEntry dateEntry in model.allDates ?? []) { + final dataRows = []; + for (final DateEntry dateEntry in model.allDates ?? []) { dataRows.add( DataRow( cells: [ diff --git a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart index 912f6321..c372549e 100644 --- a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart +++ b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart @@ -30,7 +30,7 @@ class CalendarExportViewModel extends BaseViewModel { } Future loadCalendars() async { - var access = await calendarAccess.requestCalendarPermission(); + final access = await calendarAccess.requestCalendarPermission(); if (access == CalendarPermission.PermissionDenied) { _onPermissionDenied?.call(); diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index 83e24adb..e1441c32 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -35,7 +35,7 @@ class DateManagementViewModel extends BaseViewModel { Timer? _errorResetTimer; - List _years = []; + final List _years = []; List get years => _years; String? _currentSelectedYear; @@ -97,11 +97,11 @@ class DateManagementViewModel extends BaseViewModel { } Future _doUpdateDates() async { - var cachedDateEntries = await _readCachedDateEntries(); + final cachedDateEntries = await _readCachedDateEntries(); _updateMutex.token!.throwIfCancelled(); _setAllDates(cachedDateEntries); - var loadedDateEntries = await _readUpdatedDateEntries(); + final loadedDateEntries = await _readUpdatedDateEntries(); _updateMutex.token!.throwIfCancelled(); if (loadedDateEntries != null) { @@ -118,7 +118,7 @@ class DateManagementViewModel extends BaseViewModel { Future?> _readUpdatedDateEntries() async { try { - var loadedDateEntries = await _dateEntryProvider.getDateEntries( + final loadedDateEntries = await _dateEntryProvider.getDateEntries( dateSearchParameters, _updateMutex.token, ); @@ -174,10 +174,10 @@ class DateManagementViewModel extends BaseViewModel { } void _loadDefaultSelection() async { - var database = await _preferencesProvider.getLastViewedDateEntryDatabase(); + final database = await _preferencesProvider.getLastViewedDateEntryDatabase(); bool didSetDatabase = false; - for (var db in allDateDatabases) { + for (final db in allDateDatabases) { if (db.id == database) { setCurrentDateDatabase(db); didSetDatabase = true; @@ -188,7 +188,7 @@ class DateManagementViewModel extends BaseViewModel { setCurrentDateDatabase(allDateDatabases[0]); } - var year = await _preferencesProvider.getLastViewedDateEntryYear(); + final year = await _preferencesProvider.getLastViewedDateEntryYear(); setCurrentSelectedYear(year ?? years[0]); await updateDates(); diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index 50d9d3fc..2593be92 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -12,9 +12,9 @@ class DateDetailBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - var date = DateFormat.yMd(L.of(context).locale.languageCode) + final date = DateFormat.yMd(L.of(context).locale.languageCode) .format(dateEntry!.start); - var time = DateFormat.Hm(L.of(context).locale.languageCode) + final time = DateFormat.Hm(L.of(context).locale.languageCode) .format(dateEntry!.start); return Container( diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index b79c5233..1d89b5fa 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -74,7 +74,7 @@ class _DateFilterOptionsState extends State { } Widget _buildCollapsedChips() { - var chips = []; + final chips = []; if (widget.viewModel.showPassedDates && widget.viewModel.showFutureDates) { chips.add(Chip( @@ -100,7 +100,7 @@ class _DateFilterOptionsState extends State { ),); } - var database = widget.viewModel.currentDateDatabase?.displayName ?? ""; + final database = widget.viewModel.currentDateDatabase?.displayName ?? ""; if (database != "") { chips.add(Chip( label: Text(database), @@ -201,9 +201,9 @@ class _DateFilterOptionsState extends State { } List> _buildYearsMenuItems() { - var yearMenuItems = >[]; + final yearMenuItems = >[]; - for (var year in widget.viewModel.years) { + for (final year in widget.viewModel.years) { yearMenuItems.add(DropdownMenuItem( child: Text(year), value: year, @@ -213,9 +213,9 @@ class _DateFilterOptionsState extends State { } List> _buildDatabaseMenuItems() { - var databaseMenuItems = >[]; + final databaseMenuItems = >[]; - for (var database in widget.viewModel.allDateDatabases) { + for (final database in widget.viewModel.allDateDatabases) { databaseMenuItems.add(DropdownMenuItem( child: Text(database.displayName), value: database, diff --git a/lib/dualis/service/cache_dualis_service_decorator.dart b/lib/dualis/service/cache_dualis_service_decorator.dart index d182de36..0931f1f6 100644 --- a/lib/dualis/service/cache_dualis_service_decorator.dart +++ b/lib/dualis/service/cache_dualis_service_decorator.dart @@ -34,7 +34,7 @@ class CacheDualisServiceDecorator extends DualisService { return Future.value(_allModulesCached); } - var allModules = await _service.queryAllModules(cancellationToken); + final allModules = await _service.queryAllModules(cancellationToken); _allModulesCached = allModules; @@ -49,7 +49,7 @@ class CacheDualisServiceDecorator extends DualisService { if (_semestersCached.containsKey(name)) { return Future.value(_semestersCached[name]); } - var semester = await _service.querySemester(name, cancellationToken); + final semester = await _service.querySemester(name, cancellationToken); _semestersCached[name] = semester; @@ -64,7 +64,7 @@ class CacheDualisServiceDecorator extends DualisService { return Future.value(_allSemesterNamesCached); } - var allSemesterNames = await _service.querySemesterNames(cancellationToken); + final allSemesterNames = await _service.querySemesterNames(cancellationToken); _allSemesterNamesCached = allSemesterNames; @@ -79,7 +79,7 @@ class CacheDualisServiceDecorator extends DualisService { return Future.value(_studyGradesCached); } - var studyGrades = await _service.queryStudyGrades(cancellationToken); + final studyGrades = await _service.queryStudyGrades(cancellationToken); _studyGradesCached = studyGrades; diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index be8a0569..821b0b73 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -37,7 +37,7 @@ class DualisAuthentication { ) async { _credentials = credentials; - var loginResponse = await _makeLoginRequest( + final loginResponse = await _makeLoginRequest( credentials, cancellationToken, ); @@ -51,7 +51,7 @@ class DualisAuthentication { // TODO: Test for login failed page - var redirectUrl = LoginRedirectUrlExtract().getUrlFromHeader( + final redirectUrl = LoginRedirectUrlExtract().getUrlFromHeader( loginResponse.headers['refresh'], dualisEndpoint, ); @@ -61,7 +61,7 @@ class DualisAuthentication { return loginState; } - var redirectPage = await session.get( + final redirectPage = await session.get( redirectUrl, cancellationToken, ); @@ -78,7 +78,7 @@ class DualisAuthentication { _updateAccessToken(dualisUrls.mainPageUrl!); - var mainPage = await session.get( + final mainPage = await session.get( dualisUrls.mainPageUrl!, cancellationToken, ); @@ -97,9 +97,9 @@ class DualisAuthentication { Credentials credentials, [ CancellationToken? cancellationToken, ]) async { - var loginUrl = dualisEndpoint + "/scripts/mgrqispi.dll"; + final loginUrl = dualisEndpoint + "/scripts/mgrqispi.dll"; - var data = { + final data = { "usrname": credentials.username, "pass": credentials.password, "APPNAME": "CampusNet", @@ -113,7 +113,7 @@ class DualisAuthentication { }; try { - var loginResponse = await session.rawPost( + final loginResponse = await session.rawPost( loginUrl, data, cancellationToken, @@ -136,7 +136,7 @@ class DualisAuthentication { ) async { assert(_credentials != null); - var result = await session.get( + final result = await session.get( _fillUrlWithAuthToken(url), cancellationToken, ); @@ -150,7 +150,7 @@ class DualisAuthentication { return result; } - var loginResult = await login(_credentials!, cancellationToken); + final loginResult = await login(_credentials!, cancellationToken); if (loginResult == LoginResult.LoggedIn) { return await session.get( @@ -165,7 +165,7 @@ class DualisAuthentication { Future logout([ CancellationToken? cancellationToken, ]) async { - var logoutRequest = session.get(dualisUrls.logoutUrl, cancellationToken); + final logoutRequest = session.get(dualisUrls.logoutUrl, cancellationToken); _session = null; _dualisUrls = null; @@ -180,7 +180,7 @@ class DualisAuthentication { /// wrapped in a [fillUrlWithAuthToken()] call /// void _updateAccessToken(String urlWithNewToken) { - var tokenMatch = _tokenRegex.firstMatch(urlWithNewToken); + final tokenMatch = _tokenRegex.firstMatch(urlWithNewToken); if (tokenMatch != null) { _authToken = tokenMatch.group(1); @@ -194,7 +194,7 @@ class DualisAuthentication { /// updated api token /// String _fillUrlWithAuthToken(String url) { - var match = _tokenRegex.firstMatch(url); + final match = _tokenRegex.firstMatch(url); if (match != null) { return url.replaceRange( match.start, match.end, "ARGUMENTS=-N$_authToken",); diff --git a/lib/dualis/service/dualis_scraper.dart b/lib/dualis/service/dualis_scraper.dart index 0f10b538..224ecd52 100644 --- a/lib/dualis/service/dualis_scraper.dart +++ b/lib/dualis/service/dualis_scraper.dart @@ -16,13 +16,13 @@ import 'package:dhbwstudentapp/schedule/model/schedule.dart'; /// Provides one single class to access the dualis api. /// class DualisScraper { - DualisAuthentication _dualisAuthentication = DualisAuthentication(); + final DualisAuthentication _dualisAuthentication = DualisAuthentication(); DualisUrls get _dualisUrls => _dualisAuthentication.dualisUrls; Future> loadAllModules([ CancellationToken? cancellationToken, ]) async { - var allModulesPageResponse = await _dualisAuthentication.authenticatedGet( + final allModulesPageResponse = await _dualisAuthentication.authenticatedGet( _dualisUrls.studentResultsUrl!, cancellationToken, ); @@ -34,7 +34,7 @@ class DualisScraper { String moduleDetailsUrl, [ CancellationToken? cancellationToken, ]) async { - var detailsResponse = await _dualisAuthentication.authenticatedGet( + final detailsResponse = await _dualisAuthentication.authenticatedGet( moduleDetailsUrl, cancellationToken, ); @@ -47,18 +47,18 @@ class DualisScraper { Future> loadSemesters([ CancellationToken? cancellationToken, ]) async { - var courseResultsResponse = await _dualisAuthentication.authenticatedGet( + final courseResultsResponse = await _dualisAuthentication.authenticatedGet( _dualisUrls.courseResultUrl!, cancellationToken, ); - var semesters = SemestersFromCourseResultPageExtract() + final semesters = SemestersFromCourseResultPageExtract() .extractSemestersFromCourseResults( courseResultsResponse, dualisEndpoint, ); - for (var semester in semesters) { + for (final semester in semesters) { _dualisUrls.semesterCourseResultUrls[semester.semesterName] = semester.semesterCourseResultsUrl; } @@ -70,7 +70,7 @@ class DualisScraper { String? semesterName, [ CancellationToken? cancellationToken, ]) async { - var coursePage = await _dualisAuthentication.authenticatedGet( + final coursePage = await _dualisAuthentication.authenticatedGet( _dualisUrls.semesterCourseResultUrls[semesterName!]!, cancellationToken, ); @@ -82,7 +82,7 @@ class DualisScraper { Future loadStudyGrades( CancellationToken? cancellationToken, ) async { - var studentsResultsPage = await _dualisAuthentication.authenticatedGet( + final studentsResultsPage = await _dualisAuthentication.authenticatedGet( _dualisUrls.studentResultsUrl!, cancellationToken, ); @@ -95,13 +95,13 @@ class DualisScraper { DateTime dateInMonth, CancellationToken cancellationToken, ) async { - var requestUrl = + final requestUrl = "${_dualisUrls.monthlyScheduleUrl}01.${dateInMonth.month}.${dateInMonth.year}"; - var result = await _dualisAuthentication.authenticatedGet( + final result = await _dualisAuthentication.authenticatedGet( requestUrl, cancellationToken,); - var schedule = MonthlyScheduleExtract().extractScheduleFromMonthly(result); + final schedule = MonthlyScheduleExtract().extractScheduleFromMonthly(result); schedule.urls.add(dualisEndpoint); diff --git a/lib/dualis/service/dualis_service.dart b/lib/dualis/service/dualis_service.dart index c9ae673b..f74d1005 100644 --- a/lib/dualis/service/dualis_service.dart +++ b/lib/dualis/service/dualis_service.dart @@ -68,11 +68,11 @@ class DualisServiceImpl extends DualisService { Future> querySemesterNames([ CancellationToken? cancellationToken, ]) async { - var semesters = await _dualisScraper.loadSemesters(cancellationToken); + final semesters = await _dualisScraper.loadSemesters(cancellationToken); - var names = []; + final names = []; - for (var semester in semesters) { + for (final semester in semesters) { names.add(semester.semesterName); } @@ -83,10 +83,10 @@ class DualisServiceImpl extends DualisService { Future> queryAllModules([ CancellationToken? cancellationToken, ]) async { - var dualisModules = await _dualisScraper.loadAllModules(cancellationToken); + final dualisModules = await _dualisScraper.loadAllModules(cancellationToken); - var modules = []; - for (var module in dualisModules) { + final modules = []; + for (final module in dualisModules) { modules.add(Module( [], module.id, @@ -104,20 +104,20 @@ class DualisServiceImpl extends DualisService { String? name, [ CancellationToken? cancellationToken, ]) async { - var semesterModules = await _dualisScraper.loadSemesterModules( + final semesterModules = await _dualisScraper.loadSemesterModules( name, cancellationToken, ); - var modules = []; + final modules = []; - for (var dualisModule in semesterModules) { - var moduleExams = await _dualisScraper.loadModuleExams( + for (final dualisModule in semesterModules) { + final moduleExams = await _dualisScraper.loadModuleExams( dualisModule!.detailsUrl!, cancellationToken, ); - var module = Module( + final module = Module( moduleExams .map( (exam) => Exam( diff --git a/lib/dualis/service/parsing/all_modules_extract.dart b/lib/dualis/service/parsing/all_modules_extract.dart index cca84728..2196b904 100644 --- a/lib/dualis/service/parsing/all_modules_extract.dart +++ b/lib/dualis/service/parsing/all_modules_extract.dart @@ -15,19 +15,19 @@ class AllModulesExtract { } List _extractAllModules(String? body) { - var document = parse(body); + final document = parse(body); - var modulesTable = getElementByTagName(document, "tbody"); - var rows = modulesTable.getElementsByTagName("tr"); + final modulesTable = getElementByTagName(document, "tbody"); + final rows = modulesTable.getElementsByTagName("tr"); - var modules = []; + final modules = []; - for (var row in rows) { + for (final row in rows) { // Rows with the subhead class do not contain any modules if (row.classes.contains("subhead")) continue; // When there are not 6 cells the row is not a module - var cells = row.getElementsByClassName("tbdata"); + final cells = row.getElementsByClassName("tbdata"); if (cells.length != 6) continue; modules.add(_extractModuleFromCells(cells)); @@ -38,16 +38,16 @@ class AllModulesExtract { DualisModule _extractModuleFromCells(List cells) { var name = cells[1].innerHtml.trim(); - var nameHyperlink = cells[1].getElementsByTagName("a"); + final nameHyperlink = cells[1].getElementsByTagName("a"); if (nameHyperlink.isNotEmpty) { name = nameHyperlink[0].innerHtml; } - var id = cells[0].innerHtml; - var credits = cells[3].innerHtml; - var grade = cells[4].innerHtml; - var state = cells[5].children[0].attributes["alt"]; + final id = cells[0].innerHtml; + final credits = cells[3].innerHtml; + final grade = cells[4].innerHtml; + final state = cells[5].children[0].attributes["alt"]; ExamState? stateEnum; @@ -58,7 +58,7 @@ class AllModulesExtract { stateEnum = ExamState.Pending; } - var module = DualisModule( + final module = DualisModule( trimAndEscapeString(id), trimAndEscapeString(name), trimAndEscapeString(grade), diff --git a/lib/dualis/service/parsing/exams_from_module_details_extract.dart b/lib/dualis/service/parsing/exams_from_module_details_extract.dart index 3c269d37..5f8fb636 100644 --- a/lib/dualis/service/parsing/exams_from_module_details_extract.dart +++ b/lib/dualis/service/parsing/exams_from_module_details_extract.dart @@ -14,26 +14,26 @@ class ExamsFromModuleDetailsExtract { } List _extractExamsFromModuleDetails(String? body) { - var document = parse(body); + final document = parse(body); - var tableExams = getElementByTagName(document, "tbody"); - var tableExamsRows = tableExams.getElementsByTagName("tr"); + final tableExams = getElementByTagName(document, "tbody"); + final tableExamsRows = tableExams.getElementsByTagName("tr"); String? currentTry; String? currentModule; - var exams = []; + final exams = []; - for (var row in tableExamsRows) { + for (final row in tableExamsRows) { // Save the try for all following exams - var level01s = row.getElementsByClassName("level01"); + final level01s = row.getElementsByClassName("level01"); if (level01s.isNotEmpty) { currentTry = level01s[0].innerHtml; continue; } // Save the module for all following exams - var level02s = row.getElementsByClassName("level02"); + final level02s = row.getElementsByClassName("level02"); if (level02s.isNotEmpty) { currentModule = level02s[0].innerHtml; continue; @@ -41,12 +41,12 @@ class ExamsFromModuleDetailsExtract { // All exam rows contain cells with the tbdata class. // If there are none continue with the next row - var tbdata = row.getElementsByClassName("tbdata"); + final tbdata = row.getElementsByClassName("tbdata"); if (tbdata.length < 4) continue; - var semester = tbdata[0].innerHtml; - var name = tbdata[1].innerHtml; - var grade = trimAndEscapeString(tbdata[3].innerHtml); + final semester = tbdata[0].innerHtml; + final name = tbdata[1].innerHtml; + final grade = trimAndEscapeString(tbdata[3].innerHtml); exams.add(DualisExam( trimAndEscapeString(name), diff --git a/lib/dualis/service/parsing/login_redirect_url_extract.dart b/lib/dualis/service/parsing/login_redirect_url_extract.dart index ea2f2463..7d1d4811 100644 --- a/lib/dualis/service/parsing/login_redirect_url_extract.dart +++ b/lib/dualis/service/parsing/login_redirect_url_extract.dart @@ -2,16 +2,16 @@ import 'package:html/parser.dart'; class LoginRedirectUrlExtract { String? readRedirectUrl(String? body, String redirectUrl) { - var document = parse(body); + final document = parse(body); - var metaTags = document.getElementsByTagName("meta"); + final metaTags = document.getElementsByTagName("meta"); String? redirectContent; - for (var metaTag in metaTags) { + for (final metaTag in metaTags) { if (!metaTag.attributes.containsKey("http-equiv")) continue; - var httpEquiv = metaTag.attributes["http-equiv"]; + final httpEquiv = metaTag.attributes["http-equiv"]; if (httpEquiv != "refresh") continue; if (!metaTag.attributes.containsKey("content")) continue; @@ -26,7 +26,7 @@ class LoginRedirectUrlExtract { String? getUrlFromHeader(String? refreshHeader, String endpointUrl) { if (refreshHeader == null || !refreshHeader.contains("URL=")) return null; - var refreshHeaderUrlIndex = refreshHeader.indexOf("URL=") + "URL=".length; + final refreshHeaderUrlIndex = refreshHeader.indexOf("URL=") + "URL=".length; return endpointUrl + refreshHeader.substring(refreshHeaderUrlIndex); } } diff --git a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart index ce6dc8ba..280ede50 100644 --- a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart @@ -21,18 +21,18 @@ class ModulesFromCourseResultPageExtract { List _extractModulesFromCourseResultPage( String? body, String endpointUrl,) { - var document = parse(body); + final document = parse(body); - var tableBodies = getElementByTagName(document, "tbody"); - var rows = tableBodies.getElementsByTagName("tr"); + final tableBodies = getElementByTagName(document, "tbody"); + final rows = tableBodies.getElementsByTagName("tr"); - var modulesOfSemester = []; + final modulesOfSemester = []; - for (var row in rows) { + for (final row in rows) { // Only rows with tds as child are modules if (row.children[0].localName != "td") continue; - DualisModule? module = _extractModuleFromRow(row, endpointUrl); + final DualisModule? module = _extractModuleFromRow(row, endpointUrl); modulesOfSemester.add(module); } @@ -45,13 +45,13 @@ class ModulesFromCourseResultPageExtract { ) { if (row.children.length < 6) return null; - var id = row.children[0].innerHtml; - var name = row.children[1].innerHtml; + final id = row.children[0].innerHtml; + final name = row.children[1].innerHtml; var grade = row.children[2].innerHtml; - var credits = row.children[3].innerHtml; + final credits = row.children[3].innerHtml; String? status = row.children[4].innerHtml; - var detailsButton = row.children[5]; - var url = _extractDetailsUrlFromButton(detailsButton, endpointUrl); + final detailsButton = row.children[5]; + final url = _extractDetailsUrlFromButton(detailsButton, endpointUrl); status = trimAndEscapeString(status); @@ -65,7 +65,7 @@ class ModulesFromCourseResultPageExtract { grade = ""; } - var module = DualisModule( + final module = DualisModule( trimAndEscapeString(id), trimAndEscapeString(name), trimAndEscapeString(grade), @@ -80,7 +80,7 @@ class ModulesFromCourseResultPageExtract { Element detailsButton, String endpointUrl, ) { - var firstMatch = _extractUrlRegex.firstMatch(detailsButton.innerHtml); + final firstMatch = _extractUrlRegex.firstMatch(detailsButton.innerHtml); var url = firstMatch?.group(1); if (url != null) { diff --git a/lib/dualis/service/parsing/monthly_schedule_extract.dart b/lib/dualis/service/parsing/monthly_schedule_extract.dart index 019a879b..d9cff9be 100644 --- a/lib/dualis/service/parsing/monthly_schedule_extract.dart +++ b/lib/dualis/service/parsing/monthly_schedule_extract.dart @@ -16,14 +16,14 @@ class MonthlyScheduleExtract { } Schedule _extractScheduleFromMonthly(String? body) { - var document = parse(body); + final document = parse(body); - var appointments = document.getElementsByClassName("apmntLink"); + final appointments = document.getElementsByClassName("apmntLink"); - var allEntries = []; + final allEntries = []; - for (var appointment in appointments) { - var entry = _extractEntry(appointment); + for (final appointment in appointments) { + final entry = _extractEntry(appointment); allEntries.add(entry); } @@ -36,24 +36,24 @@ class MonthlyScheduleExtract { } ScheduleEntry _extractEntry(Element appointment) { - var date = appointment.parent!.parent! + final date = appointment.parent!.parent! .querySelector(".tbsubhead a")! .attributes["title"]; - var information = appointment.attributes["title"]!; - var informationParts = information.split(" / "); + final information = appointment.attributes["title"]!; + final informationParts = information.split(" / "); - var startAndEnd = informationParts[0].split(" - "); - var start = "$date ${startAndEnd[0]}"; - var end = "$date ${startAndEnd[1]}"; - var room = informationParts[1]; - var title = informationParts[2]; + final startAndEnd = informationParts[0].split(" - "); + final start = "$date ${startAndEnd[0]}"; + final end = "$date ${startAndEnd[1]}"; + final room = informationParts[1]; + final title = informationParts[2]; - var dateFormat = DateFormat("dd.MM.yyyy HH:mm"); - var startDate = dateFormat.parse(start); - var endDate = dateFormat.parse(end); + final dateFormat = DateFormat("dd.MM.yyyy HH:mm"); + final startDate = dateFormat.parse(start); + final endDate = dateFormat.parse(end); - var entry = ScheduleEntry( + final entry = ScheduleEntry( title: title, professor: "", details: "", diff --git a/lib/dualis/service/parsing/parsing_utils.dart b/lib/dualis/service/parsing/parsing_utils.dart index e192cca9..9e4caa18 100644 --- a/lib/dualis/service/parsing/parsing_utils.dart +++ b/lib/dualis/service/parsing/parsing_utils.dart @@ -5,7 +5,7 @@ import 'package:universal_html/html.dart' as html; String? trimAndEscapeString(String? htmlString) { if (htmlString == null) return null; - var text = html.Element.span()..appendHtml(htmlString); + final text = html.Element.span()..appendHtml(htmlString); return text.innerText.trim(); } @@ -14,7 +14,7 @@ Element getElementByTagName( String localName, [ int index = 0, ]) { - var list = document.getElementsByTagName(localName); + final list = document.getElementsByTagName(localName); if (index >= list.length) throw ElementNotFoundParseException(localName); @@ -26,7 +26,7 @@ Element getElementByClassName( String className, [ int index = 0, ]) { - var list = document.getElementsByClassName(className); + final list = document.getElementsByClassName(className); if (index >= list.length) throw ElementNotFoundParseException(className); @@ -37,7 +37,7 @@ Element getElementById( Document document, String id, ) { - var element = document.getElementById(id); + final element = document.getElementById(id); if (element == null) throw ElementNotFoundParseException(id); diff --git a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart index ee3b277e..73a56b6f 100644 --- a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart @@ -18,20 +18,20 @@ class SemestersFromCourseResultPageExtract { List _extractSemestersFromCourseResults( String? body, String endpointUrl,) { - var page = parse(body); + final page = parse(body); - var semesterSelector = page.getElementById("semester"); + final semesterSelector = page.getElementById("semester"); if (semesterSelector == null) throw ElementNotFoundParseException("semester selector container"); - var url = _extractSemesterDetailUrlPart(semesterSelector, endpointUrl); + final url = _extractSemesterDetailUrlPart(semesterSelector, endpointUrl); - var semesters = []; + final semesters = []; - for (var option in semesterSelector.getElementsByTagName("option")) { - var id = option.attributes["value"]; - var name = option.innerHtml; + for (final option in semesterSelector.getElementsByTagName("option")) { + final id = option.attributes["value"]; + final name = option.innerHtml; String? detailsUrl; @@ -53,18 +53,18 @@ class SemestersFromCourseResultPageExtract { Element semesterSelector, String endpointUrl, ) { - var dropDownSemesterSelector = semesterSelector.attributes["onchange"]!; + final dropDownSemesterSelector = semesterSelector.attributes["onchange"]!; - var regExp = RegExp("'([A-z0-9]*)'"); + final regExp = RegExp("'([A-z0-9]*)'"); - var matches = regExp.allMatches(dropDownSemesterSelector).toList(); + final matches = regExp.allMatches(dropDownSemesterSelector).toList(); if (matches.length != 4) return null; - var applicationName = matches[0].group(1); - var programName = matches[1].group(1); - var sessionNo = matches[2].group(1); - var menuId = matches[3].group(1); + final applicationName = matches[0].group(1); + final programName = matches[1].group(1); + final sessionNo = matches[2].group(1); + final menuId = matches[3].group(1); var url = endpointUrl + "/scripts/mgrqispi.dll"; url += "?APPNAME=$applicationName"; diff --git a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart index 1729eb08..7ca64c3b 100644 --- a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart +++ b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart @@ -14,13 +14,13 @@ class StudyGradesFromStudentResultsPageExtract { } StudyGrades _extractStudyGradesFromStudentsResultsPage(String? body) { - var document = parse(body); + final document = parse(body); - var creditsTable = getElementByTagName(document, "tbody"); - var gpaTable = getElementByTagName(document, "tbody", 1); + final creditsTable = getElementByTagName(document, "tbody"); + final gpaTable = getElementByTagName(document, "tbody", 1); - var credits = _extractCredits(creditsTable); - var gpa = _extractGpa(gpaTable); + final credits = _extractCredits(creditsTable); + final gpa = _extractGpa(gpaTable); return StudyGrades( gpa.totalGpa, @@ -31,18 +31,18 @@ class StudyGradesFromStudentResultsPageExtract { } _Credits _extractCredits(Element table) { - var rows = table.getElementsByTagName("tr"); + final rows = table.getElementsByTagName("tr"); if (rows.length < 2) throw ElementNotFoundParseException("credits container"); - var neededCreditsRow = rows[rows.length - 1]; + final neededCreditsRow = rows[rows.length - 1]; var neededCredits = neededCreditsRow.children[0].innerHtml; // Only take the number after the colon neededCredits = trimAndEscapeString(neededCredits.split(":")[1])!; - var gainedCreditsRow = rows[rows.length - 2]; + final gainedCreditsRow = rows[rows.length - 2]; var gainedCredits = trimAndEscapeString( gainedCreditsRow.children[2].innerHtml, )!; @@ -50,7 +50,7 @@ class StudyGradesFromStudentResultsPageExtract { neededCredits = neededCredits.replaceAll(",", "."); gainedCredits = gainedCredits.replaceAll(",", "."); - var credits = _Credits(); + final credits = _Credits(); credits.gainedCredits = double.tryParse(gainedCredits); credits.totalCredits = double.tryParse(neededCredits); @@ -58,21 +58,21 @@ class StudyGradesFromStudentResultsPageExtract { } _Gpa _extractGpa(Element table) { - var rows = table.getElementsByTagName("tr"); + final rows = table.getElementsByTagName("tr"); if (rows.length < 2) throw ElementNotFoundParseException("gpa container"); - var totalGpaRowCells = rows[0].getElementsByTagName("th"); - var totalGpa = trimAndEscapeString( + final totalGpaRowCells = rows[0].getElementsByTagName("th"); + final totalGpa = trimAndEscapeString( totalGpaRowCells[1].innerHtml, )!; - var mainCoursesGpaRowCells = rows[1].getElementsByTagName("th"); - var mainModulesGpa = trimAndEscapeString( + final mainCoursesGpaRowCells = rows[1].getElementsByTagName("th"); + final mainModulesGpa = trimAndEscapeString( mainCoursesGpaRowCells[1].innerHtml, )!; - _Gpa gpa = _Gpa(); + final _Gpa gpa = _Gpa(); gpa.totalGpa = double.tryParse(totalGpa.replaceAll(",", ".")); gpa.mainModulesGpa = double.tryParse(mainModulesGpa.replaceAll(",", ".")); diff --git a/lib/dualis/service/parsing/urls_from_main_page_extract.dart b/lib/dualis/service/parsing/urls_from_main_page_extract.dart index d8638001..c707dcd5 100644 --- a/lib/dualis/service/parsing/urls_from_main_page_extract.dart +++ b/lib/dualis/service/parsing/urls_from_main_page_extract.dart @@ -21,12 +21,12 @@ class UrlsFromMainPageExtract { DualisUrls dualisUrls, String endpointUrl, ) { - var document = parse(body); + final document = parse(body); - var courseResultsElement = getElementByClassName(document, "link000307"); - var studentResultsElement = getElementByClassName(document, "link000310"); - var monthlyScheduleElement = getElementByClassName(document, "link000031"); - var logoutElement = getElementById(document, "logoutButton"); + final courseResultsElement = getElementByClassName(document, "link000307"); + final studentResultsElement = getElementByClassName(document, "link000310"); + final monthlyScheduleElement = getElementByClassName(document, "link000031"); + final logoutElement = getElementById(document, "logoutButton"); dualisUrls.courseResultUrl = endpointUrl + courseResultsElement.attributes['href']!; diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index 01d14088..07381755 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -22,7 +22,7 @@ class Session { String url, [ CancellationToken? cancellationToken, ]) async { - var response = await rawGet(url, cancellationToken); + final response = await rawGet(url, cancellationToken); if (response == null) { return null; @@ -41,16 +41,16 @@ class Session { ]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); - var requestCancellationToken = http.CancellationToken(); + final requestCancellationToken = http.CancellationToken(); try { cancellationToken.setCancellationCallback(() { requestCancellationToken.cancel(); }); - var requestUri = Uri.parse(url); + final requestUri = Uri.parse(url); - var response = await http.HttpClientHelper.get( + final response = await http.HttpClientHelper.get( requestUri, cancelToken: requestCancellationToken, headers: _cookies, @@ -81,7 +81,7 @@ class Session { Map data, [ CancellationToken? cancellationToken, ]) async { - var response = await rawPost(url, data, cancellationToken); + final response = await rawPost(url, data, cancellationToken); if (response == null) { return null; @@ -100,14 +100,14 @@ class Session { CancellationToken? cancellationToken, ]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); - var requestCancellationToken = http.CancellationToken(); + final requestCancellationToken = http.CancellationToken(); try { cancellationToken.setCancellationCallback(() { requestCancellationToken.cancel(); }); - var response = await http.HttpClientHelper.post( + final response = await http.HttpClientHelper.post( Uri.parse(url), body: data, headers: _cookies, @@ -132,9 +132,9 @@ class Session { } void _updateCookie(Response response) { - String? rawCookie = response.headers['set-cookie']; + final String? rawCookie = response.headers['set-cookie']; if (rawCookie != null) { - int index = rawCookie.indexOf(';'); + final int index = rawCookie.indexOf(';'); var cookie = (index == -1) ? rawCookie : rawCookie.substring(0, index); diff --git a/lib/dualis/ui/dualis_page.dart b/lib/dualis/ui/dualis_page.dart index cd9e017c..0ea8203c 100644 --- a/lib/dualis/ui/dualis_page.dart +++ b/lib/dualis/ui/dualis_page.dart @@ -11,7 +11,7 @@ import 'package:provider/provider.dart'; class DualisPage extends StatelessWidget { @override Widget build(BuildContext context) { - StudyGradesViewModel viewModel = Provider.of(context); + final StudyGradesViewModel viewModel = Provider.of(context); Widget widget; diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index acf78318..d5e8ab0c 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -97,10 +97,10 @@ class ExamResultsPage extends StatelessWidget { List buildModulesDataTables( BuildContext context, StudyGradesViewModel viewModel,) { - var dataTables = []; + final dataTables = []; var isFirstModule = true; - for (var module in viewModel.currentSemester!.modules) { + for (final module in viewModel.currentSemester!.modules) { dataTables.add(DataTable( horizontalMargin: 24, columnSpacing: 0, @@ -116,9 +116,9 @@ class ExamResultsPage extends StatelessWidget { } List buildModuleDataRows(BuildContext context, var module) { - var dataRows = []; + final dataRows = []; - for (var exam in module.exams) { + for (final exam in module.exams) { dataRows.add( DataRow( cells: [ diff --git a/lib/dualis/ui/login/dualis_login_page.dart b/lib/dualis/ui/login/dualis_login_page.dart index 3fd8ff86..98c7776b 100644 --- a/lib/dualis/ui/login/dualis_login_page.dart +++ b/lib/dualis/ui/login/dualis_login_page.dart @@ -7,7 +7,7 @@ import 'package:provider/provider.dart'; class DualisLoginPage extends StatelessWidget { @override Widget build(BuildContext context) { - StudyGradesViewModel viewModel = Provider.of(context); + final StudyGradesViewModel viewModel = Provider.of(context); return buildLoginPage(context, viewModel); } diff --git a/lib/dualis/ui/study_overview/study_overview_page.dart b/lib/dualis/ui/study_overview/study_overview_page.dart index 1f78cc99..80addc71 100644 --- a/lib/dualis/ui/study_overview/study_overview_page.dart +++ b/lib/dualis/ui/study_overview/study_overview_page.dart @@ -149,9 +149,9 @@ class StudyOverviewPage extends StatelessWidget { BuildContext context, StudyGradesViewModel model, ) { - var dataRows = []; + final dataRows = []; - for (var module in model.allModules!) { + for (final module in model.allModules!) { dataRows.add( DataRow( cells: [ diff --git a/lib/dualis/ui/viewmodels/study_grades_view_model.dart b/lib/dualis/ui/viewmodels/study_grades_view_model.dart index 32251a4f..7e3281a9 100644 --- a/lib/dualis/ui/viewmodels/study_grades_view_model.dart +++ b/lib/dualis/ui/viewmodels/study_grades_view_model.dart @@ -54,7 +54,7 @@ class StudyGradesViewModel extends BaseViewModel { bool success; try { - var result = await _dualisService.login(credentials); + final result = await _dualisService.login(credentials); success = result == LoginResult.LoggedIn; } on OperationCancelledException catch (_) { @@ -210,7 +210,7 @@ class StudyGradesViewModel extends BaseViewModel { if (_semesterNames == null) return; if (_semesterNames!.isEmpty) return; - var lastViewedSemester = await _preferencesProvider.getLastViewedSemester(); + final lastViewedSemester = await _preferencesProvider.getLastViewedSemester(); if (_semesterNames!.contains(lastViewedSemester)) { loadSemester(lastViewedSemester); diff --git a/lib/dualis/ui/widgets/login_form_widget.dart b/lib/dualis/ui/widgets/login_form_widget.dart index 7d061a64..154e08c1 100644 --- a/lib/dualis/ui/widgets/login_form_widget.dart +++ b/lib/dualis/ui/widgets/login_form_widget.dart @@ -143,9 +143,9 @@ class _LoginFormState extends State { await widget.onClearCredentials(); } - var credentials = _controller.credentials; + final credentials = _controller.credentials; - bool loginSuccess = await widget.onLogin(credentials); + final bool loginSuccess = await widget.onLogin(credentials); if (loginSuccess && _storeCredentials) { await widget.onSaveCredentials(credentials); diff --git a/lib/main.dart b/lib/main.dart index f82cfb57..d64dc6a8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -38,12 +38,12 @@ void main() async { /// used language /// Future saveLastStartLanguage() async { - PreferencesProvider preferencesProvider = KiwiContainer().resolve(); + final PreferencesProvider preferencesProvider = KiwiContainer().resolve(); await preferencesProvider.setLastUsedLanguageCode(Platform.localeName); } Future loadRootViewModel() async { - var rootViewModel = RootViewModel( + final rootViewModel = RootViewModel( KiwiContainer().resolve(), ); diff --git a/lib/schedule/background/background_schedule_update.dart b/lib/schedule/background/background_schedule_update.dart index c8106b8b..bf7a9f6f 100644 --- a/lib/schedule/background/background_schedule_update.dart +++ b/lib/schedule/background/background_schedule_update.dart @@ -22,10 +22,10 @@ class BackgroundScheduleUpdate extends TaskCallback { return; } - var today = toDayOfWeek(toStartOfDay(DateTime.now()), DateTime.monday)!; - var end = addDays(today, 7 * 3)!; + final today = toDayOfWeek(toStartOfDay(DateTime.now()), DateTime.monday)!; + final end = addDays(today, 7 * 3)!; - var cancellationToken = CancellationToken(); + final cancellationToken = CancellationToken(); await scheduleProvider.getUpdatedSchedule( today, diff --git a/lib/schedule/background/calendar_synchronizer.dart b/lib/schedule/background/calendar_synchronizer.dart index c3a7e590..d3236b96 100644 --- a/lib/schedule/background/calendar_synchronizer.dart +++ b/lib/schedule/background/calendar_synchronizer.dart @@ -17,10 +17,10 @@ class CalendarSynchronizer { void registerSynchronizationCallback() { scheduleProvider.addScheduleUpdatedCallback((schedule, start, end) async { - List listDateEntries = List.empty(growable: true); + final List listDateEntries = List.empty(growable: true); schedule.entries.forEach( (element) { - DateEntry date = DateEntry( + final DateEntry date = DateEntry( room: element.room, comment: element.details, databaseName: 'DHBW', @@ -35,7 +35,7 @@ class CalendarSynchronizer { listDateEntries; if (await preferencesProvider.isCalendarSyncEnabled()) { - Calendar? selectedCalendar = + final Calendar? selectedCalendar = await preferencesProvider.getSelectedCalendar(); if (selectedCalendar == null) return; CalendarAccess().addOrUpdateDates(listDateEntries, selectedCalendar); diff --git a/lib/schedule/business/schedule_diff_calculator.dart b/lib/schedule/business/schedule_diff_calculator.dart index 6c4d8fa2..baae2205 100644 --- a/lib/schedule/business/schedule_diff_calculator.dart +++ b/lib/schedule/business/schedule_diff_calculator.dart @@ -6,27 +6,27 @@ class ScheduleDiffCalculator { Schedule oldSchedule, Schedule newSchedule, ) { - var oldEntries = List.from(oldSchedule.entries); - var newEntries = List.from(newSchedule.entries); + final oldEntries = List.from(oldSchedule.entries); + final newEntries = List.from(newSchedule.entries); - var removedEntries = []; - var addedEntries = []; + final removedEntries = []; + final addedEntries = []; - for (var entry in oldEntries) { + for (final entry in oldEntries) { if (!newEntries.any((ScheduleEntry element) => _areScheduleEntriesEqual(element, entry),)) { removedEntries.add(entry); } } - for (var entry in newEntries) { + for (final entry in newEntries) { if (!oldEntries.any((ScheduleEntry element) => _areScheduleEntriesEqual(element, entry),)) { addedEntries.add(entry); } } - var scheduleDiff = + final scheduleDiff = _tryConnectNewAndOldEntries(addedEntries, removedEntries); return scheduleDiff; @@ -55,16 +55,16 @@ class ScheduleDiffCalculator { allDistinctTitles.addAll(removedEntries.map((ScheduleEntry e) => e.title)); allDistinctTitles = allDistinctTitles.toSet().toList(); - var updatedEntries = []; - var newEntries = []; - var oldEntries = []; + final updatedEntries = []; + final newEntries = []; + final oldEntries = []; - for (var intersectingTitle in allDistinctTitles) { - var oldElementsWithName = removedEntries + for (final intersectingTitle in allDistinctTitles) { + final oldElementsWithName = removedEntries .where((ScheduleEntry e) => e.title == intersectingTitle) .toList(); - var newElementsWithName = addedEntries + final newElementsWithName = addedEntries .where((ScheduleEntry e) => e.title == intersectingTitle) .toList(); @@ -119,8 +119,8 @@ class ScheduleDiffCalculator { List oldEntries, List newEntries,) { if (oldElementsWithName.length == newElementsWithName.length) { - for (var oldElement in oldElementsWithName) { - ScheduleEntry nearestElement = + for (final oldElement in oldElementsWithName) { + final ScheduleEntry nearestElement = _findNearestElementByStart(newElementsWithName, oldElement); newElementsWithName.remove(nearestElement); @@ -133,11 +133,11 @@ class ScheduleDiffCalculator { ); } } else { - for (var oldElement in oldElementsWithName) { + for (final oldElement in oldElementsWithName) { oldEntries.add(oldElement); } - for (var newElement in newElementsWithName) { + for (final newElement in newElementsWithName) { newEntries.add(newElement); } } @@ -149,8 +149,8 @@ class ScheduleDiffCalculator { Duration minimalDifference = reference.start.difference(nearestElement.start).abs(); - for (var newElement in elements) { - var difference = reference.start.difference(newElement.start).abs(); + for (final newElement in elements) { + final difference = reference.start.difference(newElement.start).abs(); if (difference < minimalDifference) { nearestElement = newElement; diff --git a/lib/schedule/business/schedule_filter.dart b/lib/schedule/business/schedule_filter.dart index 4520e82e..ca90dce8 100644 --- a/lib/schedule/business/schedule_filter.dart +++ b/lib/schedule/business/schedule_filter.dart @@ -8,11 +8,11 @@ class ScheduleFilter { ScheduleFilter(this._scheduleFilterRepository); Future filter(Schedule original) async { - var allHiddenNames = await _scheduleFilterRepository.queryAllHiddenNames(); + final allHiddenNames = await _scheduleFilterRepository.queryAllHiddenNames(); - var allEntries = []; + final allEntries = []; - for (var entry in original.entries) { + for (final entry in original.entries) { if (allHiddenNames.contains(entry.title)) { continue; } diff --git a/lib/schedule/business/schedule_provider.dart b/lib/schedule/business/schedule_provider.dart index 56ac7161..24bf2eb2 100644 --- a/lib/schedule/business/schedule_provider.dart +++ b/lib/schedule/business/schedule_provider.dart @@ -96,7 +96,7 @@ class ScheduleProvider { print("Filtered schedule has ${schedule.entries.length} entries"); } - for (var c in _scheduleUpdatedCallbacks) { + for (final c in _scheduleUpdatedCallbacks) { await c(schedule!, start, end); } @@ -116,16 +116,16 @@ class ScheduleProvider { DateTime end, Schedule updatedSchedule, ) async { - var oldSchedule = + final oldSchedule = await _scheduleEntryRepository.queryScheduleBetweenDates(start, end); - var diff = + final diff = ScheduleDiffCalculator().calculateDiff(oldSchedule, updatedSchedule); - var cleanedDiff = await _cleanDiffFromNewlyQueriedEntries(start, end, diff); + final cleanedDiff = await _cleanDiffFromNewlyQueriedEntries(start, end, diff); if (cleanedDiff.didSomethingChange()) { - for (var c in _scheduleEntryChangedCallbacks) { + for (final c in _scheduleEntryChangedCallbacks) { await c(cleanedDiff); } } @@ -155,12 +155,12 @@ class ScheduleProvider { DateTime end, ScheduleDiff diff, ) async { - var queryInformation = await _scheduleQueryInformationRepository + final queryInformation = await _scheduleQueryInformationRepository .getQueryInformationBetweenDates(start, end); - var cleanedAddedEntries = []; + final cleanedAddedEntries = []; - for (var addedEntry in diff.addedEntries) { + for (final addedEntry in diff.addedEntries) { if (queryInformation.any((i) => addedEntry.end.isAfter(i!.start) && addedEntry.start.isBefore(i.end),)) { diff --git a/lib/schedule/business/schedule_source_provider.dart b/lib/schedule/business/schedule_source_provider.dart index 4b0a1ff4..d104a0e0 100644 --- a/lib/schedule/business/schedule_source_provider.dart +++ b/lib/schedule/business/schedule_source_provider.dart @@ -33,7 +33,7 @@ class ScheduleSourceProvider { ScheduleSource get currentScheduleSource => _currentScheduleSource; - List _onDidChangeScheduleSourceCallbacks = []; + final List _onDidChangeScheduleSourceCallbacks = []; ScheduleSourceProvider( this._preferencesProvider, @@ -43,7 +43,7 @@ class ScheduleSourceProvider { ); Future setupScheduleSource() async { - var scheduleSourceType = await _getScheduleSourceType(); + final scheduleSourceType = await _getScheduleSourceType(); ScheduleSource scheduleSource = InvalidScheduleSource(); @@ -60,7 +60,7 @@ class ScheduleSourceProvider { _currentScheduleSource = scheduleSource; - var success = didSetupCorrectly(); + final success = didSetupCorrectly(); _onDidChangeScheduleSourceCallbacks.forEach((element) { element(scheduleSource, success); @@ -70,15 +70,15 @@ class ScheduleSourceProvider { } Future _getScheduleSourceType() async { - var type = await _preferencesProvider.getScheduleSourceType(); + final type = await _preferencesProvider.getScheduleSourceType(); return ScheduleSourceType.values[type]; } Future _dualisScheduleSource() async { - var dualis = DualisScheduleSource(KiwiContainer().resolve()); + final dualis = DualisScheduleSource(KiwiContainer().resolve()); - var credentials = await _preferencesProvider.loadDualisCredentials(); + final credentials = await _preferencesProvider.loadDualisCredentials(); if (credentials != null) { dualis.setLoginCredentials(credentials); @@ -89,10 +89,10 @@ class ScheduleSourceProvider { } Future _raplaScheduleSource() async { - var raplaUrl = await _preferencesProvider.getRaplaUrl(); + final raplaUrl = await _preferencesProvider.getRaplaUrl(); - var rapla = RaplaScheduleSource(); - var urlValid = RaplaScheduleSource.isValidUrl(raplaUrl); + final rapla = RaplaScheduleSource(); + final urlValid = RaplaScheduleSource.isValidUrl(raplaUrl); if (urlValid) { rapla.setEndpointUrl(raplaUrl); @@ -109,9 +109,9 @@ class ScheduleSourceProvider { } Future _icalScheduleSource() async { - var url = await _preferencesProvider.getIcalUrl(); + final url = await _preferencesProvider.getIcalUrl(); - var ical = IcalScheduleSource(); + final ical = IcalScheduleSource(); ical.setIcalUrl(url); if (ical.canQuery()) { @@ -196,8 +196,8 @@ class ScheduleSourceProvider { } Future _clearEntryCache() async { - var scheduleEntries = _scheduleEntryRepository.deleteAllScheduleEntries(); - var queryInformation = + final scheduleEntries = _scheduleEntryRepository.deleteAllScheduleEntries(); + final queryInformation = _scheduleQueryInformationRepository.deleteAllQueryInformation(); await Future.wait([scheduleEntries, queryInformation]); diff --git a/lib/schedule/data/schedule_entry_entity.dart b/lib/schedule/data/schedule_entry_entity.dart index 6f58146e..844e4980 100644 --- a/lib/schedule/data/schedule_entry_entity.dart +++ b/lib/schedule/data/schedule_entry_entity.dart @@ -14,9 +14,9 @@ class ScheduleEntryEntity extends DatabaseEntity { @override void fromMap(Map map) { - var startDate = DateTime.fromMillisecondsSinceEpoch(map["start"]); + final startDate = DateTime.fromMillisecondsSinceEpoch(map["start"]); - var endDate = DateTime.fromMillisecondsSinceEpoch(map["end"]); + final endDate = DateTime.fromMillisecondsSinceEpoch(map["end"]); _scheduleEntry = ScheduleEntry( id: map["id"], diff --git a/lib/schedule/data/schedule_entry_repository.dart b/lib/schedule/data/schedule_entry_repository.dart index 6ca00324..463f59b6 100644 --- a/lib/schedule/data/schedule_entry_repository.dart +++ b/lib/schedule/data/schedule_entry_repository.dart @@ -14,7 +14,7 @@ class ScheduleEntryRepository { Future queryScheduleBetweenDates( DateTime start, DateTime end,) async { - var rows = await _database.queryRows( + final rows = await _database.queryRows( ScheduleEntryEntity.tableName(), where: "end>? AND start queryExistingScheduleEntry(ScheduleEntry entry) async { - var rows = await _database.queryRows( + final rows = await _database.queryRows( ScheduleEntryEntity.tableName(), where: "start=? AND end=? AND title=? AND details=? AND professor=?", whereArgs: [ @@ -53,7 +53,7 @@ class ScheduleEntryRepository { } Future queryNextScheduleEntry(DateTime dateTime) async { - var nextScheduleEntry = await _database.queryRows( + final nextScheduleEntry = await _database.queryRows( ScheduleEntryEntity.tableName(), where: "start>?", whereArgs: [dateTime.millisecondsSinceEpoch], @@ -61,7 +61,7 @@ class ScheduleEntryRepository { orderBy: "start ASC", ); - var entriesList = nextScheduleEntry.toList(); + final entriesList = nextScheduleEntry.toList(); if (entriesList.length == 1) { return ScheduleEntryEntity.fromMap(entriesList[0]).asScheduleEntry(); @@ -71,7 +71,7 @@ class ScheduleEntryRepository { } Future> queryAllNamesOfScheduleEntries() async { - var allNames = await _database.rawQuery( + final allNames = await _database.rawQuery( "SELECT DISTINCT title FROM ScheduleEntries", [], ); @@ -80,16 +80,16 @@ class ScheduleEntryRepository { } Future saveScheduleEntry(ScheduleEntry entry) async { - var existingEntry = await queryExistingScheduleEntry(entry); + final existingEntry = await queryExistingScheduleEntry(entry); if (existingEntry != null) { entry.id = existingEntry.id; return; } - var row = ScheduleEntryEntity.fromModel(entry).toMap(); + final row = ScheduleEntryEntity.fromModel(entry).toMap(); if (entry.id == null) { - var id = await _database.insert(ScheduleEntryEntity.tableName(), row); + final id = await _database.insert(ScheduleEntryEntity.tableName(), row); entry.id = id; } else { await _database.update(ScheduleEntryEntity.tableName(), row); @@ -97,7 +97,7 @@ class ScheduleEntryRepository { } Future saveSchedule(Schedule schedule) async { - for (var entry in schedule.entries) { + for (final entry in schedule.entries) { saveScheduleEntry(entry); } } diff --git a/lib/schedule/data/schedule_filter_repository.dart b/lib/schedule/data/schedule_filter_repository.dart index 651bc270..1ef9e7c3 100644 --- a/lib/schedule/data/schedule_filter_repository.dart +++ b/lib/schedule/data/schedule_filter_repository.dart @@ -6,16 +6,16 @@ class ScheduleFilterRepository { ScheduleFilterRepository(this._database); Future> queryAllHiddenNames() async { - var rows = await _database.queryRows("ScheduleEntryFilters"); + final rows = await _database.queryRows("ScheduleEntryFilters"); - var names = rows.map((e) => e['title'] as String?).toList(); + final names = rows.map((e) => e['title'] as String?).toList(); return names; } Future saveAllHiddenNames(List hiddenNames) async { await _database.deleteWhere("ScheduleEntryFilters"); - for (var name in hiddenNames) { + for (final name in hiddenNames) { await _database.insert("ScheduleEntryFilters", {'title': name}); } } diff --git a/lib/schedule/data/schedule_query_information_repository.dart b/lib/schedule/data/schedule_query_information_repository.dart index 9dc2e75d..6de9285a 100644 --- a/lib/schedule/data/schedule_query_information_repository.dart +++ b/lib/schedule/data/schedule_query_information_repository.dart @@ -9,7 +9,7 @@ class ScheduleQueryInformationRepository { Future getOldestQueryTimeBetweenDates( DateTime start, DateTime end,) async { - var oldestQueryTimeDate = await _database.queryAggregator( + final oldestQueryTimeDate = await _database.queryAggregator( "SELECT MIN(queryTime) FROM ScheduleQueryInformation WHERE start<=? AND end>=?", [ start.millisecondsSinceEpoch, @@ -24,7 +24,7 @@ class ScheduleQueryInformationRepository { Future> getQueryInformationBetweenDates( DateTime start, DateTime end,) async { - var rows = await _database.queryRows( + final rows = await _database.queryRows( ScheduleQueryInformationEntity.tableName(), where: "start<=? AND end>=?", whereArgs: [ @@ -33,9 +33,9 @@ class ScheduleQueryInformationRepository { ], ); - var scheduleQueryInformation = []; + final scheduleQueryInformation = []; - for (var row in rows) { + for (final row in rows) { scheduleQueryInformation.add( ScheduleQueryInformationEntity.fromMap(row) .asScheduleQueryInformation(), diff --git a/lib/schedule/model/schedule.dart b/lib/schedule/model/schedule.dart index 3d4aeac4..4d4291c2 100644 --- a/lib/schedule/model/schedule.dart +++ b/lib/schedule/model/schedule.dart @@ -16,7 +16,7 @@ class Schedule { // TODO: Return new schedule instead of adding it to the list urls.addAll(schedule.urls); - for (var newEntry in schedule.entries) { + for (final newEntry in schedule.entries) { if (entries.any((element) => element.equalsWithIdIgnored(newEntry))) { continue; } @@ -26,15 +26,15 @@ class Schedule { } Schedule trim(DateTime? startDate, DateTime? endDate) { - var newList = []; + final newList = []; - for (var entry in entries) { + for (final entry in entries) { if (startDate!.isBefore(entry.end) && endDate!.isAfter(entry.start)) { newList.add(entry); } } - var schedule = Schedule.fromList(newList); + final schedule = Schedule.fromList(newList); schedule.urls.addAll(urls); return schedule; @@ -43,7 +43,7 @@ class Schedule { DateTime? getStartDate() { if (entries.isEmpty) return null; - var date = entries.reduce((ScheduleEntry? a, ScheduleEntry? b) { + final date = entries.reduce((ScheduleEntry? a, ScheduleEntry? b) { return a!.start.isBefore(b!.start) ? a : b; }).start; @@ -53,7 +53,7 @@ class Schedule { DateTime? getEndDate() { if (entries.isEmpty) return null; - var date = entries.reduce((ScheduleEntry? a, ScheduleEntry? b) { + final date = entries.reduce((ScheduleEntry? a, ScheduleEntry? b) { return a!.end.isAfter(b!.end) ? a : b; }).end; @@ -63,8 +63,8 @@ class Schedule { DateTime? getStartTime() { DateTime? earliestTime; - for (var entry in entries) { - var entryTime = DateTime( + for (final entry in entries) { + final entryTime = DateTime( 0, 1, 1, @@ -86,8 +86,8 @@ class Schedule { DateTime? getEndTime() { DateTime? latestTime; - for (var entry in entries) { - var entryTime = DateTime( + for (final entry in entries) { + final entryTime = DateTime( 0, 1, 1, @@ -107,7 +107,7 @@ class Schedule { } Schedule copyWith({required List entries}) { - var schedule = Schedule.fromList(entries); + final schedule = Schedule.fromList(entries); schedule.urls.addAll(urls); diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index cb52e4e6..69d5f4eb 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -43,7 +43,7 @@ class ScheduleEntry { } List getDifferentProperties(ScheduleEntry entry) { - var changedProperties = []; + final changedProperties = []; if (title != entry.title) { changedProperties.add("title"); diff --git a/lib/schedule/service/dualis/dualis_schedule_source.dart b/lib/schedule/service/dualis/dualis_schedule_source.dart index 46580416..19d7c16f 100644 --- a/lib/schedule/service/dualis/dualis_schedule_source.dart +++ b/lib/schedule/service/dualis/dualis_schedule_source.dart @@ -20,14 +20,14 @@ class DualisScheduleSource extends ScheduleSource { DateTime current = toStartOfMonth(from)!; var schedule = Schedule(); - var allErrors = []; + final allErrors = []; if (!_dualisScraper.isLoggedIn()) await _dualisScraper.loginWithPreviousCredentials(cancellationToken); while (to!.isAfter(current) && !cancellationToken.isCancelled()) { try { - var monthSchedule = await _dualisScraper.loadMonthlySchedule( + final monthSchedule = await _dualisScraper.loadMonthlySchedule( current, cancellationToken,); schedule.merge(monthSchedule); diff --git a/lib/schedule/service/error_report_schedule_source_decorator.dart b/lib/schedule/service/error_report_schedule_source_decorator.dart index 9a4264cd..1e368447 100644 --- a/lib/schedule/service/error_report_schedule_source_decorator.dart +++ b/lib/schedule/service/error_report_schedule_source_decorator.dart @@ -12,7 +12,7 @@ class ErrorReportScheduleSourceDecorator extends ScheduleSource { Future querySchedule(DateTime? from, DateTime? to, [CancellationToken? cancellationToken,]) async { try { - var schedule = await _scheduleSource.querySchedule( + final schedule = await _scheduleSource.querySchedule( from, to, cancellationToken, diff --git a/lib/schedule/service/ical/ical_parser.dart b/lib/schedule/service/ical/ical_parser.dart index 5042a245..a3587c2f 100644 --- a/lib/schedule/service/ical/ical_parser.dart +++ b/lib/schedule/service/ical/ical_parser.dart @@ -22,19 +22,19 @@ class IcalParser { "([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})(Z?)"; ScheduleQueryResult parseIcal(String icalData) { - var regex = RegExp( + final regex = RegExp( calendarEntryRegex, multiLine: true, unicode: true, dotAll: true, ); - var matches = regex.allMatches(icalData); + final matches = regex.allMatches(icalData); - List entries = []; + final List entries = []; - for (var match in matches) { - var entry = _parseEntry(match.group(1)!); + for (final match in matches) { + final entry = _parseEntry(match.group(1)!); entries.add(entry); } @@ -45,14 +45,14 @@ class IcalParser { } ScheduleEntry _parseEntry(String entryData) { - var allProperties = RegExp( + final allProperties = RegExp( propertyRegex, unicode: true, ).allMatches(entryData); - Map properties = {}; + final Map properties = {}; - for (var property in allProperties) { + for (final property in allProperties) { properties[property.group(1)] = property.group(3); } @@ -70,7 +70,7 @@ class IcalParser { DateTime? _parseDate(String? date) { if (date == null) return null; - var match = RegExp( + final match = RegExp( dateTimeRegex, unicode: true, ).firstMatch(date); diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index 174dce6f..60d3a8a4 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -27,12 +27,12 @@ class IcalScheduleSource extends ScheduleSource { DateTime? to, [ CancellationToken? cancellationToken, ]) async { - var response = await _makeRequest(_url!, cancellationToken!); + final response = await _makeRequest(_url!, cancellationToken!); if (response == null) return null; try { - var body = utf8.decode(response.bodyBytes); - var schedule = _icalParser.parseIcal(body); + final body = utf8.decode(response.bodyBytes); + final schedule = _icalParser.parseIcal(body); return ScheduleQueryResult( schedule.schedule.trim(from, to), @@ -49,14 +49,14 @@ class IcalScheduleSource extends ScheduleSource { String url, CancellationToken cancellationToken,) async { url = url.replaceAll("webcal://", "https://"); - var requestCancellationToken = http.CancellationToken(); + final requestCancellationToken = http.CancellationToken(); try { cancellationToken.setCancellationCallback(() { requestCancellationToken.cancel(); }); - var response = await http.HttpClientHelper.get( + final response = await http.HttpClientHelper.get( Uri.parse(url), cancelToken: requestCancellationToken, ); diff --git a/lib/schedule/service/isolate_schedule_source_decorator.dart b/lib/schedule/service/isolate_schedule_source_decorator.dart index 027c6712..f4c833a1 100644 --- a/lib/schedule/service/isolate_schedule_source_decorator.dart +++ b/lib/schedule/service/isolate_schedule_source_decorator.dart @@ -64,7 +64,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { Future _initializeIsolate() async { if (_isolate != null && _isolateToMain != null && _sendPort != null) return; - var isolateToMain = ReceivePort(); + final isolateToMain = ReceivePort(); // Use a broadcast stream. The normal ReceivePort closes after one subscription _isolateToMain = isolateToMain.asBroadcastStream(); @@ -81,12 +81,12 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { void scheduleSourceIsolateEntryPoint(SendPort sendPort) async { // Using the given send port, send back a send port for two way communication - var port = ReceivePort(); + final port = ReceivePort(); sendPort.send(port.sendPort); CancellationToken? token; - await for (var message in port) { + await for (final message in port) { if (message["type"] == "execute") { token = CancellationToken(); executeQueryScheduleMessage(message, sendPort, token); @@ -102,11 +102,11 @@ Future executeQueryScheduleMessage( CancellationToken? token, ) async { try { - ScheduleSource source = map["source"]; - DateTime? from = map["from"]; - DateTime? to = map["to"]; + final ScheduleSource source = map["source"]; + final DateTime? from = map["from"]; + final DateTime? to = map["to"]; - var result = await source.querySchedule(from, to, token); + final result = await source.querySchedule(from, to, token); sendPort.send(result); } on OperationCancelledException catch (_) { diff --git a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart index 24b7ac2c..d3710cce 100644 --- a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart +++ b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart @@ -4,17 +4,17 @@ import 'package:html/parser.dart'; class MannheimCourseResponseParser { List parseCoursePage(String body) { - var document = parse(body); + final document = parse(body); - var selectElement = getElementById(document, "class_select"); - var options = selectElement.getElementsByTagName("option"); + final selectElement = getElementById(document, "class_select"); + final options = selectElement.getElementsByTagName("option"); - var courses = []; + final courses = []; - for (var e in options) { - var label = e.attributes["label"] ?? ""; - var value = e.attributes["value"] ?? ""; - var title = e.parent!.attributes["label"] ?? ""; + for (final e in options) { + final label = e.attributes["label"] ?? ""; + final value = e.attributes["value"] ?? ""; + final title = e.parent!.attributes["label"] ?? ""; if (label == "" || value == "") continue; if (label.trim() == "Kurs auswählen") continue; diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index 66458c21..f21d2319 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -19,7 +19,7 @@ class MannheimCourseScraper { ]) async { if (cancellationToken == null) cancellationToken = CancellationToken(); - var coursesPage = await _makeRequest( + final coursesPage = await _makeRequest( Uri.parse("https://vorlesungsplan.dhbw-mannheim.de/ical.php"), cancellationToken, ); @@ -29,14 +29,14 @@ class MannheimCourseScraper { Future _makeRequest( Uri uri, CancellationToken cancellationToken,) async { - var requestCancellationToken = http.CancellationToken(); + final requestCancellationToken = http.CancellationToken(); try { cancellationToken.setCancellationCallback(() { requestCancellationToken.cancel(); }); - var response = await http.HttpClientHelper.get(uri, + final response = await http.HttpClientHelper.get(uri, cancelToken: requestCancellationToken,); if (response == null && !requestCancellationToken.isCanceled) diff --git a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart index 2a2f6bd3..db8f54b2 100644 --- a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart @@ -12,30 +12,30 @@ class RaplaMonthlyResponseParser { static ScheduleQueryResult parseMonthlyTable( Element monthTable, ) { - var title = monthTable.parent!.getElementsByClassName("title"); + final title = monthTable.parent!.getElementsByClassName("title"); - var monthAndYear = title[0].text; - var yearString = monthAndYear.split(" ")[1]; - var year = int.tryParse(yearString); - var month = _monthStringToDateTime(monthAndYear); + final monthAndYear = title[0].text; + final yearString = monthAndYear.split(" ")[1]; + final year = int.tryParse(yearString); + final month = _monthStringToDateTime(monthAndYear); - var dayCells = monthTable.getElementsByClassName("month_cell"); + final dayCells = monthTable.getElementsByClassName("month_cell"); - var allEntries = []; - var parseErrors = []; + final allEntries = []; + final parseErrors = []; - for (var dayCell in dayCells) { - var dayNumber = dayCell.getElementsByTagName("div"); - var dayEntries = dayCell.getElementsByClassName("month_block"); + for (final dayCell in dayCells) { + final dayNumber = dayCell.getElementsByTagName("div"); + final dayEntries = dayCell.getElementsByClassName("month_block"); if (dayNumber.isEmpty || dayEntries.isEmpty) continue; - var dayNumberString = dayNumber[0].text; - var day = int.tryParse(dayNumberString); + final dayNumberString = dayNumber[0].text; + final day = int.tryParse(dayNumberString); - for (var dayEntry in dayEntries) { + for (final dayEntry in dayEntries) { try { - var entry = RaplaParsingUtils.extractScheduleEntryOrThrow( + final entry = RaplaParsingUtils.extractScheduleEntryOrThrow( dayEntry, DateTime(year!, month!, day!), ); @@ -51,8 +51,8 @@ class RaplaMonthlyResponseParser { } static int? _monthStringToDateTime(String monthAndYear) { - var monthString = monthAndYear.split(" ")[0]; - var monthNames = { + final monthString = monthAndYear.split(" ")[0]; + final monthNames = { "Januar": DateTime.january, "Februar": DateTime.february, "März": DateTime.march, @@ -67,7 +67,7 @@ class RaplaMonthlyResponseParser { "Dezember": DateTime.december, }; - var month = monthNames[monthString]; + final month = monthNames[monthString]; return month; } } diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index 7db01adf..b2000082 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -30,18 +30,18 @@ class RaplaParsingUtils { static ScheduleEntry extractScheduleEntryOrThrow( Element value, DateTime date,) { // The tooltip tag contains the most relevant information - var tooltip = value.getElementsByClassName(TOOLTIP_CLASS); + final tooltip = value.getElementsByClassName(TOOLTIP_CLASS); // The only reliable way to extract the time - var timeAndClassName = value.getElementsByTagName("a"); + final timeAndClassName = value.getElementsByTagName("a"); if (timeAndClassName.isEmpty) throw ElementNotFoundParseException("time and date container"); - var descriptionInCell = timeAndClassName[0].text; + final descriptionInCell = timeAndClassName[0].text; - var start = _parseTime(descriptionInCell.substring(0, 5), date); - var end = _parseTime(descriptionInCell.substring(7, 12), date); + final start = _parseTime(descriptionInCell.substring(0, 5), date); + final end = _parseTime(descriptionInCell.substring(7, 12), date); if (start == null || end == null) throw ElementNotFoundParseException("start and end date container"); @@ -70,7 +70,7 @@ class RaplaParsingUtils { throw ElementNotFoundParseException("title"); } - var professor = scheduleEntry.professor; + final professor = scheduleEntry.professor; if (professor.endsWith(",")) { scheduleEntry = scheduleEntry.copyWith( professor: professor.substring(0, professor.length - 1),); @@ -90,21 +90,21 @@ class RaplaParsingUtils { ScheduleEntry? scheduleEntry, DateTime start, DateTime end,) { - var infotable = tooltip[0].getElementsByClassName(INFOTABLE_CLASS); + final infotable = tooltip[0].getElementsByClassName(INFOTABLE_CLASS); if (infotable.isEmpty) { throw ElementNotFoundParseException("infotable container"); } - Map properties = _parsePropertiesTable(infotable[0]); - var type = _extractEntryType(tooltip); - var title = properties[CLASS_NAME_LABEL] ?? + final Map properties = _parsePropertiesTable(infotable[0]); + final type = _extractEntryType(tooltip); + final title = properties[CLASS_NAME_LABEL] ?? properties[CLASS_TITLE_LABEL] ?? properties[CLASS_NAME_LABEL_ALTERNATIVE]; - var professor = properties[PROFESSOR_NAME_LABEL]; - var details = properties[DETAILS_LABEL]; - var resource = properties[RESOURCES_LABEL] ?? _extractResources(value); + final professor = properties[PROFESSOR_NAME_LABEL]; + final details = properties[DETAILS_LABEL]; + final resource = properties[RESOURCES_LABEL] ?? _extractResources(value); scheduleEntry = ScheduleEntry( start: start, @@ -123,8 +123,8 @@ class RaplaParsingUtils { ScheduleEntry? scheduleEntry, DateTime start, DateTime end,) { - var descriptionHtml = timeAndClassName[0].innerHtml.substring(12); - var descriptionParts = descriptionHtml.split("
"); + final descriptionHtml = timeAndClassName[0].innerHtml.substring(12); + final descriptionParts = descriptionHtml.split("
"); var title = ""; var details = ""; @@ -151,10 +151,10 @@ class RaplaParsingUtils { static ScheduleEntryType _extractEntryType(List tooltip) { if (tooltip.isEmpty) return ScheduleEntryType.Unknown; - var strongTag = tooltip[0].getElementsByTagName("strong"); + final strongTag = tooltip[0].getElementsByTagName("strong"); if (strongTag.isEmpty) return ScheduleEntryType.Unknown; - var typeString = strongTag[0].innerHtml; + final typeString = strongTag[0].innerHtml; if (entryTypeMapping.containsKey(typeString)) { return entryTypeMapping[typeString]!; @@ -164,9 +164,9 @@ class RaplaParsingUtils { } static Map _parsePropertiesTable(Element infotable) { - var map = {}; - var labels = infotable.getElementsByClassName(LABEL_CLASS); - var values = infotable.getElementsByClassName(VALUE_CLASS); + final map = {}; + final labels = infotable.getElementsByClassName(LABEL_CLASS); + final values = infotable.getElementsByClassName(VALUE_CLASS); for (var i = 0; i < labels.length; i++) { map[labels[i].innerHtml] = values[i].innerHtml; @@ -176,7 +176,7 @@ class RaplaParsingUtils { static DateTime? _parseTime(String timeString, DateTime date) { try { - var time = DateFormat("HH:mm").parse(timeString.substring(0, 5)); + final time = DateFormat("HH:mm").parse(timeString.substring(0, 5)); return DateTime(date.year, date.month, date.day, time.hour, time.minute); } catch (e) { return null; @@ -184,10 +184,10 @@ class RaplaParsingUtils { } static String _extractResources(Element value) { - var resources = value.getElementsByClassName(RESOURCE_CLASS); + final resources = value.getElementsByClassName(RESOURCE_CLASS); - var resourcesList = []; - for (var resource in resources) { + final resourcesList = []; + for (final resource in resources) { resourcesList.add(resource.innerHtml); } @@ -197,15 +197,15 @@ class RaplaParsingUtils { static String readYearOrThrow(Document document) { // The only reliable way to read the year of this schedule is to parse the // selected year in the date selector - var comboBoxes = document.getElementsByTagName("select"); + final comboBoxes = document.getElementsByTagName("select"); String? year; - for (var box in comboBoxes) { + for (final box in comboBoxes) { if (box.attributes.containsKey("name") && box.attributes["name"] == "year") { - var entries = box.getElementsByTagName("option"); + final entries = box.getElementsByTagName("option"); - for (var entry in entries) { + for (final entry in entries) { if (entry.attributes.containsKey("selected") && entry.attributes["selected"] == "") { year = entry.text; diff --git a/lib/schedule/service/rapla/rapla_response_parser.dart b/lib/schedule/service/rapla/rapla_response_parser.dart index cc37efff..f051c537 100644 --- a/lib/schedule/service/rapla/rapla_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_response_parser.dart @@ -9,10 +9,10 @@ import 'package:html/parser.dart' show parse; /// class RaplaResponseParser { ScheduleQueryResult parseSchedule(String responseBody) { - var document = parse(responseBody); + final document = parse(responseBody); - var weekTable = document.getElementsByClassName("week_table"); - var monthTable = document.getElementsByClassName("month_table"); + final weekTable = document.getElementsByClassName("week_table"); + final monthTable = document.getElementsByClassName("month_table"); if (weekTable.isNotEmpty) { return RaplaWeekResponseParser.parseWeeklyTable( diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index 9a28a1ce..c7de956f 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -27,14 +27,14 @@ class RaplaScheduleSource extends ScheduleSource { if (cancellationToken == null) cancellationToken = CancellationToken(); var schedule = Schedule(); - var allErrors = []; + final allErrors = []; var didChangeMonth = false; while ((to!.isAfter(current) && !cancellationToken.isCancelled()) || didChangeMonth) { try { - var weekSchedule = await _fetchRaplaSource(current, cancellationToken); + final weekSchedule = await _fetchRaplaSource(current, cancellationToken); if (weekSchedule?.schedule != null) { schedule.merge(weekSchedule!.schedule); @@ -51,9 +51,9 @@ class RaplaScheduleSource extends ScheduleSource { throw ScheduleQueryFailedException(e, trace); } - var currentMonth = current.month; + final currentMonth = current.month; current = toNextWeek(current)!; - var nextMonth = current.month; + final nextMonth = current.month; // Some rapla instances only return the dates in the current month. // If the month changes in the middle of a week only half the week is @@ -73,13 +73,13 @@ class RaplaScheduleSource extends ScheduleSource { DateTime date, CancellationToken cancellationToken, ) async { - var requestUri = _buildRequestUri(date); + final requestUri = _buildRequestUri(date); - var response = await _makeRequest(requestUri, cancellationToken); + final response = await _makeRequest(requestUri, cancellationToken); if (response == null) return null; try { - var schedule = responseParser.parseSchedule(response.body); + final schedule = responseParser.parseSchedule(response.body); schedule.schedule.urls.add(requestUri.toString()); @@ -104,17 +104,17 @@ class RaplaScheduleSource extends ScheduleSource { raplaUrl = "http://$raplaUrl"; } - var uri = Uri.parse(raplaUrl!); + final uri = Uri.parse(raplaUrl!); - bool hasKeyParameter = uri.queryParameters.containsKey("key"); - bool hasUserParameter = uri.queryParameters.containsKey("user"); - bool hasFileParameter = uri.queryParameters.containsKey("file"); - bool hasPageParameter = uri.queryParameters.containsKey("page"); + final bool hasKeyParameter = uri.queryParameters.containsKey("key"); + final bool hasUserParameter = uri.queryParameters.containsKey("user"); + final bool hasFileParameter = uri.queryParameters.containsKey("file"); + final bool hasPageParameter = uri.queryParameters.containsKey("page"); - bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); - bool hasSalt = uri.queryParameters.containsKey("salt"); + final bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); + final bool hasSalt = uri.queryParameters.containsKey("salt"); - Map parameters = {}; + final Map parameters = {}; if (hasKeyParameter) { parameters["key"] = uri.queryParameters["key"]; @@ -142,14 +142,14 @@ class RaplaScheduleSource extends ScheduleSource { Future _makeRequest( Uri uri, CancellationToken cancellationToken,) async { - var requestCancellationToken = http.CancellationToken(); + final requestCancellationToken = http.CancellationToken(); try { cancellationToken.setCancellationCallback(() { requestCancellationToken.cancel(); }); - var response = await http.HttpClientHelper.get(uri, + final response = await http.HttpClientHelper.get(uri, cancelToken: requestCancellationToken,); if (response == null && !requestCancellationToken.isCanceled) @@ -181,13 +181,13 @@ class RaplaScheduleSource extends ScheduleSource { return false; } - bool hasKeyParameter = uri.queryParameters.containsKey("key"); - bool hasUserParameter = uri.queryParameters.containsKey("user"); - bool hasFileParameter = uri.queryParameters.containsKey("file"); - bool hasPageParameter = uri.queryParameters.containsKey("page"); + final bool hasKeyParameter = uri.queryParameters.containsKey("key"); + final bool hasUserParameter = uri.queryParameters.containsKey("user"); + final bool hasFileParameter = uri.queryParameters.containsKey("file"); + final bool hasPageParameter = uri.queryParameters.containsKey("page"); - bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); - bool hasSalt = uri.queryParameters.containsKey("salt"); + final bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); + final bool hasSalt = uri.queryParameters.containsKey("salt"); if (hasUserParameter && hasFileParameter && hasPageParameter) { return true; diff --git a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart index 96bab905..a721db42 100644 --- a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart @@ -9,11 +9,11 @@ class RaplaSeveralMonthsResponseParser { Document document, List monthTables, ) { - var parseErrors = []; - var allEntries = []; + final parseErrors = []; + final allEntries = []; - for (var monthTable in monthTables) { - var result = RaplaMonthlyResponseParser.parseMonthlyTable(monthTable); + for (final monthTable in monthTables) { + final result = RaplaMonthlyResponseParser.parseMonthlyTable(monthTable); parseErrors.addAll(result.errors); allEntries.addAll(result.schedule.entries); diff --git a/lib/schedule/service/rapla/rapla_week_response_parser.dart b/lib/schedule/service/rapla/rapla_week_response_parser.dart index 46fae222..569f2c98 100644 --- a/lib/schedule/service/rapla/rapla_week_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_week_response_parser.dart @@ -15,15 +15,15 @@ class RaplaWeekResponseParser { Document document, Element weekTable, ) { - var dates = _readDatesFromHeadersOrThrow(document); - var allRows = weekTable.getElementsByTagName("tr"); + final dates = _readDatesFromHeadersOrThrow(document); + final allRows = weekTable.getElementsByTagName("tr"); - var allEntries = []; - var parseErrors = []; + final allEntries = []; + final parseErrors = []; - for (var row in allRows) { + for (final row in allRows) { var currentDayInWeekIndex = 0; - for (var cell in row.children) { + for (final cell in row.children) { if (cell.localName != "td") continue; // Skip all spacer cells. They are only used for the alignment in the html page @@ -49,7 +49,7 @@ class RaplaWeekResponseParser { // The important information is inside a week_block cell if (cell.classes.contains("week_block")) { try { - var entry = RaplaParsingUtils.extractScheduleEntryOrThrow( + final entry = RaplaParsingUtils.extractScheduleEntryOrThrow( cell, dates[currentDayInWeekIndex], ); @@ -73,20 +73,20 @@ class RaplaWeekResponseParser { } static List _readDatesFromHeadersOrThrow(Document document) { - var year = _readYearOrThrow(document); + final year = _readYearOrThrow(document); // The only reliable way to read the dates is the table header. // Some schedule entries contain the dates in the description but not // in every case. - var weekHeaders = document.getElementsByClassName("week_header"); - var dates = []; + final weekHeaders = document.getElementsByClassName("week_header"); + final dates = []; - for (var header in weekHeaders) { + for (final header in weekHeaders) { var dateString = header.text + year; dateString = dateString.replaceAll(RegExp(r"\s+\b|\b\s"), ""); try { - var date = DateFormat("dd.MM.yyyy").parse(dateString.substring(2)); + final date = DateFormat("dd.MM.yyyy").parse(dateString.substring(2)); dates.add(date); } catch (exception, trace) { throw ParseException.withInner(exception, trace); @@ -98,15 +98,15 @@ class RaplaWeekResponseParser { static String _readYearOrThrow(Document document) { // The only reliable way to read the year of this schedule is to parse the // selected year in the date selector - var comboBoxes = document.getElementsByTagName("select"); + final comboBoxes = document.getElementsByTagName("select"); String? year; - for (var box in comboBoxes) { + for (final box in comboBoxes) { if (box.attributes.containsKey("name") && box.attributes["name"] == "year") { - var entries = box.getElementsByTagName("option"); + final entries = box.getElementsByTagName("option"); - for (var entry in entries) { + for (final entry in entries) { if (entry.attributes.containsKey("selected") && (entry.attributes["selected"] == "" || entry.attributes["selected"] == "selected")) { diff --git a/lib/schedule/service/schedule_prettifier.dart b/lib/schedule/service/schedule_prettifier.dart index 258bd9cf..a6eb944c 100644 --- a/lib/schedule/service/schedule_prettifier.dart +++ b/lib/schedule/service/schedule_prettifier.dart @@ -8,9 +8,9 @@ class SchedulePrettifier { RegExp(r'([ -]*)\(?online\)?', caseSensitive: false); Schedule prettifySchedule(Schedule schedule) { - var allEntries = []; + final allEntries = []; - for (var entry in schedule.entries) { + for (final entry in schedule.entries) { allEntries.add(prettifyScheduleEntry(entry)); } @@ -37,7 +37,7 @@ class SchedulePrettifier { return entry; } - var type = ScheduleEntryType.Online; + final type = ScheduleEntryType.Online; return entry.copyWith(title: newTitle, type: type); } @@ -46,15 +46,15 @@ class SchedulePrettifier { var title = entry.title; var details = entry.details; - var titleRegex = + final titleRegex = RegExp("[A-Z]{3,}-?[A-Z]+[0-9]*[A-Z]*[0-9]*[\/]?[A-Z]*[0-9]*[ ]*-?"); - var match = titleRegex.firstMatch(entry.title); + final match = titleRegex.firstMatch(entry.title); if (match != null && match.start == 0) { details = title.substring(0, match.end) + " - $details"; title = title.substring(match.end).trim(); } else { - var first = title.split(" ").first; + final first = title.split(" ").first; // Prettify titles: T3MB9025 Fluidmechanik -> Fluidmechanik @@ -62,7 +62,7 @@ class SchedulePrettifier { // or less than 2 charcters long if (!(first == first.toUpperCase() && first.length >= 3)) return entry; - var numberCount = first.split(new RegExp("[0-9]")).length; + final numberCount = first.split(new RegExp("[0-9]")).length; // If there are less thant two numbers in the title, do not prettify it if (numberCount < 2) return entry; diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index 76ee2161..727cac15 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -35,7 +35,7 @@ class _DailySchedulePageState extends State { child: PropertyChangeConsumer( builder: (BuildContext context, DailyScheduleViewModel? model, Set? properties,) { - var dateFormat = DateFormat.yMMMMEEEEd( + final dateFormat = DateFormat.yMMMMEEEEd( L.of(context).locale.languageCode,); return Text( dateFormat.format(model!.currentDate!), @@ -87,11 +87,11 @@ class _DailySchedulePageState extends State { } List buildEntryWidgets() { - var entryWidgets = []; - var now = DateTime.now(); + final entryWidgets = []; + final now = DateTime.now(); var nowIndicatorInserted = false; - for (var entry in viewModel.daySchedule.entries) { + for (final entry in viewModel.daySchedule.entries) { if (!nowIndicatorInserted && (entry.end.isAfter(now))) { entryWidgets.add(CurrentTimeIndicatorWidget()); nowIndicatorInserted = true; diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index e0ebc1d4..13e4d452 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -14,10 +14,10 @@ class DailyScheduleEntryWidget extends StatelessWidget { @override Widget build(BuildContext context) { - var timeFormatter = DateFormat.Hm(L.of(context).locale.languageCode); + final timeFormatter = DateFormat.Hm(L.of(context).locale.languageCode); - var startTime = timeFormatter.format(scheduleEntry.start); - var endTime = timeFormatter.format(scheduleEntry.end); + final startTime = timeFormatter.format(scheduleEntry.start); + final endTime = timeFormatter.format(scheduleEntry.end); return IntrinsicHeight( child: Row( diff --git a/lib/schedule/ui/notification/next_day_information_notification.dart b/lib/schedule/ui/notification/next_day_information_notification.dart index 33d8c63c..81629d95 100644 --- a/lib/schedule/ui/notification/next_day_information_notification.dart +++ b/lib/schedule/ui/notification/next_day_information_notification.dart @@ -32,21 +32,21 @@ class NextDayInformationNotification extends TaskCallback { return; } - var now = DateTime.now(); + final now = DateTime.now(); - var nextScheduleEntry = + final nextScheduleEntry = await _scheduleEntryRepository.queryNextScheduleEntry(now); if (nextScheduleEntry == null) return; - var format = DateFormat.Hm(); - var daysToNextEntry = toStartOfDay(nextScheduleEntry.start)! + final format = DateFormat.Hm(); + final daysToNextEntry = toStartOfDay(nextScheduleEntry.start)! .difference(toStartOfDay(now)!) .inDays; if (daysToNextEntry > 1) return; - var message = _getNotificationMessage( + final message = _getNotificationMessage( daysToNextEntry, nextScheduleEntry, format, @@ -86,7 +86,7 @@ class NextDayInformationNotification extends TaskCallback { @override Future schedule() async { - var nextSchedule = toTimeOfDayInFuture(DateTime.now(), 20, 00); + final nextSchedule = toTimeOfDayInFuture(DateTime.now(), 20, 00); await _scheduler.scheduleOneShotTaskAt( nextSchedule, "NextDayInformationNotification" + DateFormat.yMd().format(nextSchedule), @@ -96,7 +96,7 @@ class NextDayInformationNotification extends TaskCallback { @override Future cancel() async { - var nextSchedule = toTimeOfDayInFuture(DateTime.now(), 20, 00); + final nextSchedule = toTimeOfDayInFuture(DateTime.now(), 20, 00); await _scheduler.cancelTask( "NextDayInformationNotification" + DateFormat.yMd().format(nextSchedule), ); diff --git a/lib/schedule/ui/notification/schedule_changed_notification.dart b/lib/schedule/ui/notification/schedule_changed_notification.dart index 7c6443eb..9c57960c 100644 --- a/lib/schedule/ui/notification/schedule_changed_notification.dart +++ b/lib/schedule/ui/notification/schedule_changed_notification.dart @@ -21,8 +21,8 @@ class ScheduleChangedNotification { return; } - for (var entry in scheduleDiff.updatedEntries) { - var message = interpolate( + for (final entry in scheduleDiff.updatedEntries) { + final message = interpolate( _localization.notificationScheduleChangedClass, [ entry.entry.title, @@ -42,8 +42,8 @@ class ScheduleChangedNotification { return; } - for (var entry in scheduleDiff.removedEntries) { - var message = interpolate( + for (final entry in scheduleDiff.removedEntries) { + final message = interpolate( _localization.notificationScheduleChangedRemovedClass, [ entry.title, @@ -64,8 +64,8 @@ class ScheduleChangedNotification { return; } - for (var entry in scheduleDiff.addedEntries) { - var message = interpolate( + for (final entry in scheduleDiff.addedEntries) { + final message = interpolate( _localization.notificationScheduleChangedNewClass, [ entry.title, diff --git a/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart b/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart index 0183aa0d..f81ae6fc 100644 --- a/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart @@ -26,7 +26,7 @@ class DailyScheduleViewModel extends BaseViewModel { Schedule get daySchedule => _daySchedule ??= Schedule(); Future loadScheduleForToday() async { - var now = DateTime.now(); + final now = DateTime.now(); currentDate = toStartOfDay(now); await updateSchedule(); diff --git a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart index 076eef85..e5276b64 100644 --- a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart @@ -87,8 +87,8 @@ class WeeklyScheduleViewModel extends BaseViewModel { currentDateEnd = end; if (weekSchedule != null) { - var scheduleStart = weekSchedule!.getStartDate(); - var scheduleEnd = weekSchedule!.getEndDate(); + final scheduleStart = weekSchedule!.getStartDate(); + final scheduleEnd = weekSchedule!.getEndDate(); if (scheduleStart == null && scheduleEnd == null) { clippedDateStart = toDayOfWeek(start, DateTime.monday); @@ -163,15 +163,15 @@ class WeeklyScheduleViewModel extends BaseViewModel { Future _doUpdateSchedule(DateTime start, DateTime end) async { print("Refreshing schedule..."); - var cancellationToken = _updateMutex.token!; + final cancellationToken = _updateMutex.token!; scheduleUrl = null; - var cachedSchedule = await scheduleProvider.getCachedSchedule(start, end); + final cachedSchedule = await scheduleProvider.getCachedSchedule(start, end); cancellationToken.throwIfCancelled(); _setSchedule(cachedSchedule, start, end); - var updatedSchedule = await _readScheduleFromService( + final updatedSchedule = await _readScheduleFromService( start, end, cancellationToken, @@ -179,7 +179,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { cancellationToken.throwIfCancelled(); if (updatedSchedule?.schedule != null) { - var schedule = updatedSchedule!.schedule; + final schedule = updatedSchedule!.schedule; _setSchedule(schedule, start, end); diff --git a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart index 539c6b97..4d06a1cb 100644 --- a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart +++ b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart @@ -16,15 +16,15 @@ class FilterViewModel extends BaseViewModel { } void loadFilterStates() async { - var allNames = + final allNames = await _scheduleEntryRepository.queryAllNamesOfScheduleEntries(); - var filteredNames = await _scheduleFilterRepository.queryAllHiddenNames(); + final filteredNames = await _scheduleFilterRepository.queryAllHiddenNames(); allNames.sort((s1, s2) => s1!.compareTo(s2!)); filterStates = allNames.map((e) { - var isFiltered = filteredNames.contains(e); + final isFiltered = filteredNames.contains(e); return ScheduleEntryFilterState(!isFiltered, e); }).toList(); @@ -32,7 +32,7 @@ class FilterViewModel extends BaseViewModel { } void applyFilter() async { - var allFilteredNames = filterStates + final allFilteredNames = filterStates .where((element) => !element.isDisplayed!) .map((e) => e.entryName) .toList(); diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index be272c40..c1178307 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -15,11 +15,11 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - var formatter = DateFormat.Hm(L.of(context).locale.languageCode); - var timeStart = formatter.format(scheduleEntry!.start); - var timeEnd = formatter.format(scheduleEntry!.end); + final formatter = DateFormat.Hm(L.of(context).locale.languageCode); + final timeStart = formatter.format(scheduleEntry!.start); + final timeEnd = formatter.format(scheduleEntry!.end); - var typeString = + final typeString = scheduleEntryTypeToReadableString(context, scheduleEntry!.type); return Container( diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart index 4a753c55..f51b27d1 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart @@ -17,7 +17,7 @@ class ScheduleEntryAlignmentAlgorithm { List layoutEntries( List entries, ) { - var events = entries + final events = entries .map( (e) => ScheduleEntryAlignmentInformation(e), ) @@ -32,11 +32,11 @@ class ScheduleEntryAlignmentAlgorithm { return result; }); - List> columns = [[]]; + final List> columns = [[]]; DateTime? lastEventEnd; - for (var event in events) { + for (final event in events) { if (!event.entry.start .isBefore(lastEventEnd ?? DateTime.fromMillisecondsSinceEpoch(0))) { _packEvents(columns); @@ -47,7 +47,7 @@ class ScheduleEntryAlignmentAlgorithm { bool placed = false; // Try to put the event in one existing column. - for (var column in columns) { + for (final column in columns) { if (!_entriesCollide(column.last.entry, event.entry)) { column.add(event); placed = true; @@ -77,9 +77,9 @@ class ScheduleEntryAlignmentAlgorithm { void _packEvents(List> columns) { int columnIndex = 0; - for (var column in columns) { - for (var event in column) { - var span = _expandEvent(event, columnIndex, columns); + for (final column in columns) { + for (final event in column) { + final span = _expandEvent(event, columnIndex, columns); event.leftColumn = columnIndex / columns.length; event.rightColumn = (columnIndex + span) / columns.length; } @@ -93,8 +93,8 @@ class ScheduleEntryAlignmentAlgorithm { List> columns, ) { var span = 1; - for (var column in columns.skip(columnIndex + 1)) { - for (var ev in column) { + for (final column in columns.skip(columnIndex + 1)) { + for (final ev in column) { if (_entriesCollide(ev.entry, event.entry)) { return span; } diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart index db798f14..0a15e826 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart @@ -17,7 +17,7 @@ class ScheduleEntryWidget extends StatelessWidget { @override Widget build(BuildContext context) { - Color color = scheduleEntryTypeToColor(context, scheduleEntry.type); + final Color color = scheduleEntryTypeToColor(context, scheduleEntry.type); return Card( color: color, diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart index b4bc7f65..8a8b8f7a 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart @@ -45,7 +45,7 @@ class ScheduleGridCustomPaint extends CustomPainter { ..color = gridLineColor ..strokeWidth = 1; - var lines = toHour! - fromHour!; + final lines = toHour! - fromHour!; drawHorizontalLines(lines, size, canvas, secondaryPaint); drawVerticalLines(size, canvas, secondaryPaint); @@ -58,7 +58,7 @@ class ScheduleGridCustomPaint extends CustomPainter { Paint secondaryPaint, ) { for (var i = 0; i < lines; i++) { - var y = ((size.height - dateLabelsHeight) / lines) * i + dateLabelsHeight; + final y = ((size.height - dateLabelsHeight) / lines) * i + dateLabelsHeight; canvas.drawLine(Offset(0, y), Offset(size.width, y), secondaryPaint); } @@ -66,7 +66,7 @@ class ScheduleGridCustomPaint extends CustomPainter { void drawVerticalLines(Size size, Canvas canvas, Paint secondaryPaint) { for (var i = 0; i < columns; i++) { - var x = ((size.width - timeLabelsWidth) / columns) * i + timeLabelsWidth; + final x = ((size.width - timeLabelsWidth) / columns) * i + timeLabelsWidth; canvas.drawLine(Offset(x, 0), Offset(x, size.height), secondaryPaint); } diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart index 753db464..421495c6 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart @@ -78,9 +78,9 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { } void drawPartialPastOverlay(Canvas canvas, Size size, Paint overlayPaint) { - var difference = now!.difference(fromDate!); - var differenceInDays = (difference.inHours / 24).floor(); - var dayWidth = size.width / columns; + final difference = now!.difference(fromDate!); + final differenceInDays = (difference.inHours / 24).floor(); + final dayWidth = size.width / columns; canvas.drawRect( Rect.fromLTWH( @@ -92,11 +92,11 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { overlayPaint, ); - var leftoverMinutes = + final leftoverMinutes = difference.inMinutes - (differenceInDays * 24 * 60) - (60 * fromHour!); - var displayedMinutes = (toHour! - fromHour!) * 60; - var leftoverHeight = leftoverMinutes * (size.height / displayedMinutes); + final displayedMinutes = (toHour! - fromHour!) * 60; + final leftoverHeight = leftoverMinutes * (size.height / displayedMinutes); if (leftoverHeight > 0) { canvas.drawRect( diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 5064dba8..6ea5b266 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -44,16 +44,16 @@ class ScheduleWidget extends StatelessWidget { } Widget buildWithSize(BuildContext context, double width, double height) { - var dayLabelsHeight = 40.0; - var timeLabelsWidth = 50.0; + final dayLabelsHeight = 40.0; + final timeLabelsWidth = 50.0; - var hourHeight = + final hourHeight = (height - dayLabelsHeight) / (displayEndHour! - displayStartHour!); - var minuteHeight = hourHeight / 60; + final minuteHeight = hourHeight / 60; - var days = calculateDisplayedDays(); + final days = calculateDisplayedDays(); - var labelWidgets = buildLabelWidgets( + final labelWidgets = buildLabelWidgets( context, hourHeight, (width - timeLabelsWidth) / days, @@ -111,7 +111,7 @@ class ScheduleWidget extends StatelessWidget { } int calculateDisplayedDays() { - var startEndDifference = + final startEndDifference = toStartOfDay(displayEnd)?.difference(toStartOfDay(displayStart)!); var days = (startEndDifference?.inDays ?? 0) + 1; @@ -133,10 +133,10 @@ class ScheduleWidget extends StatelessWidget { double hourHeight, double minuteHeight, ) { - var labelWidgets = []; + final labelWidgets = []; for (var i = displayStartHour!; i < displayEndHour!; i++) { - var hourLabelText = i.toString() + ":00"; + final hourLabelText = i.toString() + ":00"; labelWidgets.add( Positioned( @@ -152,10 +152,10 @@ class ScheduleWidget extends StatelessWidget { var i = 0; - var dayFormatter = DateFormat("E", L.of(context).locale.languageCode); - var dateFormatter = DateFormat("d. MMM", L.of(context).locale.languageCode); + final dayFormatter = DateFormat("E", L.of(context).locale.languageCode); + final dateFormatter = DateFormat("d. MMM", L.of(context).locale.languageCode); - var loopEnd = toStartOfDay(tomorrow(displayEnd))!; + final loopEnd = toStartOfDay(tomorrow(displayEnd))!; for (var columnDate = toStartOfDay(displayStart)!; columnDate.isBefore(loopEnd); @@ -194,18 +194,18 @@ class ScheduleWidget extends StatelessWidget { if (schedule == null) return []; if (schedule!.entries.isEmpty) return []; - var entryWidgets = []; + final entryWidgets = []; - var columnWidth = width / columns; + final columnWidth = width / columns; DateTime? columnStartDate = toStartOfDay(displayStart); DateTime? columnEndDate = tomorrow(columnStartDate); for (int i = 0; i < columns; i++) { - var xPosition = columnWidth * i; - var maxWidth = columnWidth; + final xPosition = columnWidth * i; + final maxWidth = columnWidth; - var columnSchedule = schedule!.trim(columnStartDate, columnEndDate); + final columnSchedule = schedule!.trim(columnStartDate, columnEndDate); entryWidgets.addAll(buildEntryWidgetsForColumn( maxWidth, @@ -229,24 +229,24 @@ class ScheduleWidget extends StatelessWidget { double xPosition, List entries, ) { - var entryWidgets = []; + final entryWidgets = []; - var laidOutEntries = + final laidOutEntries = ScheduleEntryAlignmentAlgorithm().layoutEntries(entries); - for (var value in laidOutEntries) { - var entry = value.entry; + for (final value in laidOutEntries) { + final entry = value.entry; - var yStart = hourHeight * (entry.start.hour - displayStartHour!) + + final yStart = hourHeight * (entry.start.hour - displayStartHour!) + minuteHeight * entry.start.minute; - var yEnd = hourHeight * (entry.end.hour - displayStartHour!) + + final yEnd = hourHeight * (entry.end.hour - displayStartHour!) + minuteHeight * entry.end.minute; - var entryLeft = maxWidth * value.leftColumn; - var entryWidth = maxWidth * (value.rightColumn - value.leftColumn); + final entryLeft = maxWidth * value.leftColumn; + final entryWidth = maxWidth * (value.rightColumn - value.leftColumn); - var widget = Positioned( + final widget = Positioned( top: yStart, left: entryLeft + xPosition, height: yEnd - yStart, diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index 7b7407fa..e9310551 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -120,7 +120,7 @@ abstract class EnterUrlDialog { } Future _pasteUrl() async { - ClipboardData? data = await Clipboard.getData('text/plain'); + final ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text != null) { _setUrl(data!.text!); diff --git a/lib/schedule/ui/widgets/select_source_dialog.dart b/lib/schedule/ui/widgets/select_source_dialog.dart index 5ec9f9cd..e7acf8b8 100644 --- a/lib/schedule/ui/widgets/select_source_dialog.dart +++ b/lib/schedule/ui/widgets/select_source_dialog.dart @@ -18,7 +18,7 @@ class SelectSourceDialog { SelectSourceDialog(this._preferencesProvider, this._scheduleSourceProvider); Future show(BuildContext context) async { - var type = await _preferencesProvider.getScheduleSourceType(); + final type = await _preferencesProvider.getScheduleSourceType(); _currentScheduleSource = ScheduleSourceType.values[type]; await showDialog( diff --git a/lib/ui/main_page.dart b/lib/ui/main_page.dart index ce2b915f..f158ee82 100644 --- a/lib/ui/main_page.dart +++ b/lib/ui/main_page.dart @@ -38,7 +38,7 @@ class _MainPageState extends State with NavigatorObserver { Widget build(BuildContext context) { _showAppLaunchDialogsIfNeeded(context); - var navigator = Navigator( + final navigator = Navigator( key: NavigatorKey.mainKey, onGenerateRoute: generateDrawerRoute, initialRoute: "schedule", @@ -66,7 +66,7 @@ class _MainPageState extends State with NavigatorObserver { Widget buildPhoneLayout(BuildContext context, Navigator navigator) { return WillPopScope( onWillPop: () async { - var canPop = NavigatorKey.mainKey.currentState!.canPop(); + final canPop = NavigatorKey.mainKey.currentState!.canPop(); if (!canPop) return true; @@ -133,9 +133,9 @@ class _MainPageState extends State with NavigatorObserver { } List _buildDrawerEntries() { - var drawerEntries = []; + final drawerEntries = []; - for (var entry in navigationEntries) { + for (final entry in navigationEntries) { drawerEntries.add(DrawerNavigationEntry( entry.icon, entry.title(context), diff --git a/lib/ui/navigation/router.dart b/lib/ui/navigation/router.dart index f17e4cd7..6bc7ff67 100644 --- a/lib/ui/navigation/router.dart +++ b/lib/ui/navigation/router.dart @@ -20,7 +20,7 @@ Route generateDrawerRoute(RouteSettings settings) { WidgetBuilder? widget; - for (var route in navigationEntries) { + for (final route in navigationEntries) { if (route.route == settings.name) { widget = route.buildRoute; break; diff --git a/lib/ui/navigation_drawer.dart b/lib/ui/navigation_drawer.dart index b7cf56c9..a48f8e46 100644 --- a/lib/ui/navigation_drawer.dart +++ b/lib/ui/navigation_drawer.dart @@ -25,14 +25,14 @@ class NavigationDrawer extends StatelessWidget { @override Widget build(BuildContext context) { - var widgets = []; + final widgets = []; if (isInDrawer) { widgets.add(_createHeader(context)); } int i = 0; - for (var entry in entries) { + for (final entry in entries) { widgets.add(_createDrawerItem(context, icon: entry.icon, text: entry.title, @@ -44,7 +44,7 @@ class NavigationDrawer extends StatelessWidget { widgets.add(_createSettingsItem(context)); - var widget = Column( + final widget = Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: widgets, ); diff --git a/lib/ui/onboarding/onboardin_step.dart b/lib/ui/onboarding/onboardin_step.dart index c800089f..7d26be55 100644 --- a/lib/ui/onboarding/onboardin_step.dart +++ b/lib/ui/onboarding/onboardin_step.dart @@ -64,7 +64,7 @@ class DualisCredentialsOnboardingStep extends OnboardingStep { } class RaplaOnboardingStep extends OnboardingStep { - RaplaUrlViewModel _viewModel = RaplaUrlViewModel( + final RaplaUrlViewModel _viewModel = RaplaUrlViewModel( KiwiContainer().resolve(), KiwiContainer().resolve(), ); @@ -86,7 +86,7 @@ class RaplaOnboardingStep extends OnboardingStep { } class IcalOnboardingStep extends OnboardingStep { - IcalUrlViewModel _viewModel = IcalUrlViewModel( + final IcalUrlViewModel _viewModel = IcalUrlViewModel( KiwiContainer().resolve(), KiwiContainer().resolve(), ); diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index 3f812c20..fc548819 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -98,8 +98,8 @@ class _OnboardingPageState extends State } Widget _buildActiveOnboardingPage(OnboardingViewModel model) { - var currentStep = model.pages[model.currentStep]!; - var contentWidget = currentStep.buildContent(context); + final currentStep = model.pages[model.currentStep]!; + final contentWidget = currentStep.buildContent(context); Widget body = Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 0), @@ -140,7 +140,7 @@ class _OnboardingPageState extends State } void _onboardingFinished() { - var rootViewModel = + final rootViewModel = PropertyChangeProvider.of(context)!.value; rootViewModel.setIsOnboarding(false); diff --git a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart index 346f6648..76552dc3 100644 --- a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart +++ b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart @@ -32,7 +32,7 @@ class IcalUrlViewModel extends OnboardingStepViewModel { } Future pasteUrl() async { - ClipboardData? data = await Clipboard.getData('text/plain'); + final ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text != null) { setUrl(data!.text); diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart index 8126ca8d..5ccf7757 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart @@ -44,7 +44,7 @@ class OnboardingViewModel extends BaseViewModel { this.preferencesProvider, this._onboardingFinished, ) { - for (var page in pages.values) { + for (final page in pages.values) { page.viewModel().addListener(() { notifyListeners("currentPageValid"); }, ["isValid"],); @@ -59,7 +59,7 @@ class OnboardingViewModel extends BaseViewModel { return; } - var lastPage = stepsBackstack.keys.last; + final lastPage = stepsBackstack.keys.last; _stepIndex = stepsBackstack[lastPage]!; @@ -95,7 +95,7 @@ class OnboardingViewModel extends BaseViewModel { } Future finishOnboarding() async { - for (var step in stepsBackstack.keys) { + for (final step in stepsBackstack.keys) { await pages[step]!.viewModel().save(); } diff --git a/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart b/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart index 6511643b..bb15520d 100644 --- a/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart +++ b/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart @@ -35,7 +35,7 @@ class RaplaUrlViewModel extends OnboardingStepViewModel { } Future pasteUrl() async { - ClipboardData? data = await Clipboard.getData('text/plain'); + final ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text != null) { setRaplaUrl(data!.text); diff --git a/lib/ui/onboarding/widgets/dualis_login_page.dart b/lib/ui/onboarding/widgets/dualis_login_page.dart index 8c0613c2..8b6e6e48 100644 --- a/lib/ui/onboarding/widgets/dualis_login_page.dart +++ b/lib/ui/onboarding/widgets/dualis_login_page.dart @@ -36,7 +36,7 @@ class _DualisLoginCredentialsPageState _controller.credentials = credentials; } - var widgets = []; + final widgets = []; widgets.addAll(_buildHeader()); widgets.add(LoginCredentialsWidget( diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index b0301957..81c3ce75 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -89,7 +89,7 @@ class SelectMannheimCourseWidget extends StatelessWidget { BuildContext context, ) { // TODO: [Leptopoda] why is nullsafety garanttueed here but checked above ¿? - var isSelected = viewModel.selectedCourse == viewModel.courses![index]; + final isSelected = viewModel.selectedCourse == viewModel.courses![index]; return ListTile( trailing: isSelected diff --git a/lib/ui/onboarding/widgets/onboarding_button_bar.dart b/lib/ui/onboarding/widgets/onboarding_button_bar.dart index 9bacbf46..0dad178e 100644 --- a/lib/ui/onboarding/widgets/onboarding_button_bar.dart +++ b/lib/ui/onboarding/widgets/onboarding_button_bar.dart @@ -29,7 +29,7 @@ class OnboardingButtonBar extends StatelessWidget { } Widget _buildPreviousButton(BuildContext context) { - bool isFirstPage = viewModel.stepIndex == 0; + final bool isFirstPage = viewModel.stepIndex == 0; return AnimatedSwitcher( duration: const Duration(milliseconds: 100), diff --git a/lib/ui/pager_widget.dart b/lib/ui/pager_widget.dart index 7d2dc3ed..7c72224c 100644 --- a/lib/ui/pager_widget.dart +++ b/lib/ui/pager_widget.dart @@ -59,9 +59,9 @@ class _PagerWidgetState extends State { } List buildBottomNavigationBarItems() { - var bottomNavigationBarItems = []; + final bottomNavigationBarItems = []; - for (var page in widget.pages) { + for (final page in widget.pages) { bottomNavigationBarItems.add( BottomNavigationBarItem( icon: page.icon, @@ -88,7 +88,7 @@ class _PagerWidgetState extends State { Future loadActivePage() async { if (widget.pagesId == null) return; - var selectedPage = await preferencesProvider.get( + final selectedPage = await preferencesProvider.get( "${widget.pagesId}_active_page", ); diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index c72c2e5e..a9962fde 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -46,7 +46,7 @@ class _SettingsPageState extends State { @override Widget build(BuildContext context) { - var widgets = []; + final widgets = []; widgets.addAll(buildScheduleSourceSettings(context)); widgets.addAll(buildDesignSettings(context)); @@ -159,10 +159,10 @@ class _SettingsPageState extends State { ),); return; } - var isCalendarSyncEnabled = await KiwiContainer() + final isCalendarSyncEnabled = await KiwiContainer() .resolve() .isCalendarSyncEnabled(); - List entriesToExport = + final List entriesToExport = KiwiContainer().resolve().listDateEntries; await NavigatorKey.rootKey.currentState!.push(MaterialPageRoute( builder: (BuildContext context) => CalendarExportPage( @@ -178,7 +178,7 @@ class _SettingsPageState extends State { } List buildNotificationSettings(BuildContext context) { - WorkSchedulerService service = KiwiContainer().resolve(); + final WorkSchedulerService service = KiwiContainer().resolve(); if (service.isSchedulingAvailable()) { return [ TitleListTile(title: L.of(context).settingsNotificationsTitle), diff --git a/lib/ui/settings/viewmodels/settings_view_model.dart b/lib/ui/settings/viewmodels/settings_view_model.dart index c554371b..033aef8a 100644 --- a/lib/ui/settings/viewmodels/settings_view_model.dart +++ b/lib/ui/settings/viewmodels/settings_view_model.dart @@ -62,7 +62,7 @@ class SettingsViewModel extends BaseViewModel { await _preferencesProvider.setIsCalendarSyncEnabled(value); - var scheduleProvider = KiwiContainer().resolve(); + final scheduleProvider = KiwiContainer().resolve(); scheduleProvider.getUpdatedSchedule( DateTime.now(), DateTime.now().add(Duration(days: 30)), diff --git a/test/common/util/string_utils_test.dart b/test/common/util/string_utils_test.dart index c076c7da..c566465f 100644 --- a/test/common/util/string_utils_test.dart +++ b/test/common/util/string_utils_test.dart @@ -3,8 +3,8 @@ import 'package:test/test.dart'; void main() { test('String interpolation', () async { - var format = "%0 %1!"; - var result = interpolate(format, ["Hello", "world"]); + final format = "%0 %1!"; + final result = interpolate(format, ["Hello", "world"]); expect(result, "Hello world!"); }); diff --git a/test/date_management/service/parsing/all_dates_extract_test.dart b/test/date_management/service/parsing/all_dates_extract_test.dart index 6ee47bab..ac02e2e8 100644 --- a/test/date_management/service/parsing/all_dates_extract_test.dart +++ b/test/date_management/service/parsing/all_dates_extract_test.dart @@ -4,14 +4,14 @@ import 'package:dhbwstudentapp/date_management/service/parsing/all_dates_extract import 'package:test/test.dart'; Future main() async { - var allDatesPage = await File(Directory.current.absolute.path + + final allDatesPage = await File(Directory.current.absolute.path + '/test/date_management/service/parsing/html_resources/all_dates.html',) .readAsString(); test('AllDatesExtract extract all dates', () async { - var extract = AllDatesExtract(); + final extract = AllDatesExtract(); - var dateEntries = extract.extractAllDates(allDatesPage, ""); + final dateEntries = extract.extractAllDates(allDatesPage, ""); expect(dateEntries.length, 4); diff --git a/test/dualis/service/parsing/all_modules_extract_test.dart b/test/dualis/service/parsing/all_modules_extract_test.dart index f143a451..caaad15b 100644 --- a/test/dualis/service/parsing/all_modules_extract_test.dart +++ b/test/dualis/service/parsing/all_modules_extract_test.dart @@ -6,14 +6,14 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - var studentResultsPage = await File(Directory.current.absolute.path + + final studentResultsPage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/student_results.html',) .readAsString(); test('AllModulesExtract extract all modules', () async { - var extract = AllModulesExtract(); + final extract = AllModulesExtract(); - var modules = extract.extractAllModules(studentResultsPage); + final modules = extract.extractAllModules(studentResultsPage); expect(modules.length, 6); @@ -27,7 +27,7 @@ Future main() async { }); test('AllModulesExtract invalid html throws exception', () async { - var extract = AllModulesExtract(); + final extract = AllModulesExtract(); try { extract.extractAllModules("Lorem ipsum"); diff --git a/test/dualis/service/parsing/dualis_timeout_extract_test.dart b/test/dualis/service/parsing/dualis_timeout_extract_test.dart index 855addca..60888b80 100644 --- a/test/dualis/service/parsing/dualis_timeout_extract_test.dart +++ b/test/dualis/service/parsing/dualis_timeout_extract_test.dart @@ -4,11 +4,11 @@ import 'package:dhbwstudentapp/dualis/service/parsing/timeout_extract.dart'; import 'package:test/test.dart'; Future main() async { - var monthlySchedulePage = await File(Directory.current.absolute.path + + final monthlySchedulePage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/monthly_schedule.html',) .readAsString(); - var timeoutPage = await File(Directory.current.absolute.path + + final timeoutPage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/dualis_timeout.html',) .readAsString(); diff --git a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart index af079e5b..fd3fd2d1 100644 --- a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart +++ b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart @@ -5,14 +5,14 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - var moduleDetailsPage = await File(Directory.current.absolute.path + + final moduleDetailsPage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/module_details.html',) .readAsString(); test('ExamsFromModuleDetailsExtract', () async { - var extract = ExamsFromModuleDetailsExtract(); + final extract = ExamsFromModuleDetailsExtract(); - var exams = extract.extractExamsFromModuleDetails(moduleDetailsPage); + final exams = extract.extractExamsFromModuleDetails(moduleDetailsPage); expect(exams.length, 2); @@ -26,7 +26,7 @@ Future main() async { }); test('ExamsFromModuleDetailsExtract invalid html throws exception', () async { - var extract = ExamsFromModuleDetailsExtract(); + final extract = ExamsFromModuleDetailsExtract(); try { extract.extractExamsFromModuleDetails("Lorem ipsum"); diff --git a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart index 7b3e143c..e30c9810 100644 --- a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart @@ -5,14 +5,14 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - var courseResultsPage = await File(Directory.current.absolute.path + + final courseResultsPage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/course_results.html',) .readAsString(); test('ModulesFromCourseResultPageExtract', () async { - var extract = ModulesFromCourseResultPageExtract(); + final extract = ModulesFromCourseResultPageExtract(); - var modules = extract.extractModulesFromCourseResultPage( + final modules = extract.extractModulesFromCourseResultPage( courseResultsPage, "www.endpoint.com",); expect(modules.length, 3); @@ -28,7 +28,7 @@ Future main() async { test('ModulesFromCourseResultPageExtract invalid html throws exception', () async { - var extract = ModulesFromCourseResultPageExtract(); + final extract = ModulesFromCourseResultPageExtract(); try { extract.extractModulesFromCourseResultPage("Lorem ipsum", ""); diff --git a/test/dualis/service/parsing/monthly_schedule_extract_test.dart b/test/dualis/service/parsing/monthly_schedule_extract_test.dart index 1dc638ba..8cc68446 100644 --- a/test/dualis/service/parsing/monthly_schedule_extract_test.dart +++ b/test/dualis/service/parsing/monthly_schedule_extract_test.dart @@ -4,18 +4,18 @@ import 'package:dhbwstudentapp/dualis/service/parsing/monthly_schedule_extract.d import 'package:test/test.dart'; Future main() async { - var monthlySchedulePage = await File(Directory.current.absolute.path + + final monthlySchedulePage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/monthly_schedule.html',) .readAsString(); test('MonthlyScheduleExtract extract all appointments', () async { - var extract = MonthlyScheduleExtract(); + final extract = MonthlyScheduleExtract(); - var modules = extract.extractScheduleFromMonthly(monthlySchedulePage); + final modules = extract.extractScheduleFromMonthly(monthlySchedulePage); expect(modules.entries.length, 7); - var entryTitles = [ + final entryTitles = [ "HOR-TMB20xxKE1 - 3. Sem. Antriebstechnik", "HOR-TMB20xxKE1/KE2 - 3. Sem. Konstruktion III", "HOR-TMB20xxKE1/KE2 3 . Sem. Thermodynamik Grundlagen 1", @@ -25,7 +25,7 @@ Future main() async { "HOR-TMB20xxKE1 3. Sem. Managementsysteme -Projektmanagement", ]; - var startAndEndTime = [ + final startAndEndTime = [ [DateTime(2020, 09, 08, 08), DateTime(2020, 09, 08, 12, 15)], [DateTime(2020, 09, 10, 08, 30), DateTime(2020, 09, 10, 12, 45)], [DateTime(2020, 09, 10, 13, 30), DateTime(2020, 09, 10, 16, 45)], diff --git a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart index fb443111..e2f550f8 100644 --- a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart @@ -5,14 +5,14 @@ import 'package:dhbwstudentapp/dualis/service/parsing/semesters_from_course_resu import 'package:test/test.dart'; Future main() async { - var courseResultsPage = await File(Directory.current.absolute.path + + final courseResultsPage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/course_results.html',) .readAsString(); test('SemestersFromCourseResultPageExtract', () async { - var extract = SemestersFromCourseResultPageExtract(); + final extract = SemestersFromCourseResultPageExtract(); - var semesters = extract.extractSemestersFromCourseResults( + final semesters = extract.extractSemestersFromCourseResults( courseResultsPage, "www.endpoint.com", ); @@ -30,7 +30,7 @@ Future main() async { test('SemestersFromCourseResultPageExtract invalid html throws exception', () async { - var extract = SemestersFromCourseResultPageExtract(); + final extract = SemestersFromCourseResultPageExtract(); try { extract.extractSemestersFromCourseResults("Lorem ipsum", ""); diff --git a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart index 47c33165..e56fbd5a 100644 --- a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart +++ b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart @@ -5,14 +5,14 @@ import 'package:dhbwstudentapp/dualis/service/parsing/study_grades_from_student_ import 'package:test/test.dart'; Future main() async { - var studentResultsPage = await File(Directory.current.absolute.path + + final studentResultsPage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/student_results.html',) .readAsString(); test('StudyGradesFromStudentResultsPageExtract', () async { - var extract = StudyGradesFromStudentResultsPageExtract(); + final extract = StudyGradesFromStudentResultsPageExtract(); - var studyGrades = + final studyGrades = extract.extractStudyGradesFromStudentsResultsPage(studentResultsPage); expect(studyGrades.creditsGained, 13); @@ -24,7 +24,7 @@ Future main() async { test('StudyGradesFromStudentResultsPageExtract invalid html throws exception', () async { - var extract = StudyGradesFromStudentResultsPageExtract(); + final extract = StudyGradesFromStudentResultsPageExtract(); try { extract.extractStudyGradesFromStudentsResultsPage("Lorem ipsum"); diff --git a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart index 7de7c4a6..d5d5ae75 100644 --- a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart +++ b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart @@ -6,14 +6,14 @@ import 'package:dhbwstudentapp/dualis/service/parsing/urls_from_main_page_extrac import 'package:test/test.dart'; Future main() async { - var mainPage = await File(Directory.current.absolute.path + + final mainPage = await File(Directory.current.absolute.path + '/test/dualis/service/parsing/html_resources/main_page.html',) .readAsString(); test('UrlsFromMainPageExtract', () async { - var extract = UrlsFromMainPageExtract(); + final extract = UrlsFromMainPageExtract(); - var mainPageUrls = DualisUrls(); + final mainPageUrls = DualisUrls(); extract.parseMainPage(mainPage, mainPageUrls, "www.endpoint.com"); @@ -27,7 +27,7 @@ Future main() async { }); test('UrlsFromMainPageExtract invalid html throws exception', () async { - var extract = UrlsFromMainPageExtract(); + final extract = UrlsFromMainPageExtract(); try { extract.parseMainPage("Lorem ipsum", DualisUrls(), ""); diff --git a/test/rapla_service_test.dart b/test/rapla_service_test.dart index 00963a46..870a66ee 100644 --- a/test/rapla_service_test.dart +++ b/test/rapla_service_test.dart @@ -3,7 +3,7 @@ import 'package:test/test.dart'; void main() { test('debugging', () async { - var source = RaplaScheduleSource(); + final source = RaplaScheduleSource(); source.setEndpointUrl( "https://rapla.dhbw-stuttgart.de/rapla?key=txB1FOi5xd1wUJBWuX8lJhGDUgtMSFmnKLgAG_NVMhCn4AzVqTBQM-yMcTKkIDCa",); //var schedule = await source.querySchedule( diff --git a/test/schedule/business/schedule_diff_calculator_test.dart b/test/schedule/business/schedule_diff_calculator_test.dart index e8332cb6..057644e6 100644 --- a/test/schedule/business/schedule_diff_calculator_test.dart +++ b/test/schedule/business/schedule_diff_calculator_test.dart @@ -5,12 +5,12 @@ import 'package:test/test.dart'; void main() { test('Diff detect identical schedules', () async { - var calculator = ScheduleDiffCalculator(); + final calculator = ScheduleDiffCalculator(); - var oldSchedule = generateSchedule(); - var newSchedule = generateSchedule(); + final oldSchedule = generateSchedule(); + final newSchedule = generateSchedule(); - var diff = calculator.calculateDiff(oldSchedule, newSchedule); + final diff = calculator.calculateDiff(oldSchedule, newSchedule); expect(diff.addedEntries.length, 0); expect(diff.removedEntries.length, 0); @@ -35,12 +35,12 @@ void main() { }); test('Diff detect new entry', () async { - var calculator = ScheduleDiffCalculator(); + final calculator = ScheduleDiffCalculator(); - var oldSchedule = generateSchedule(); - var newSchedule = generateSchedule(); + final oldSchedule = generateSchedule(); + final newSchedule = generateSchedule(); - var newEntry = ScheduleEntry( + final newEntry = ScheduleEntry( room: "Room3", type: ScheduleEntryType.Class, title: "Project management", @@ -52,7 +52,7 @@ void main() { newSchedule.addEntry(newEntry); - var diff = calculator.calculateDiff(oldSchedule, newSchedule); + final diff = calculator.calculateDiff(oldSchedule, newSchedule); expect(diff.addedEntries.length, 1); expect(diff.addedEntries[0], newEntry); @@ -61,12 +61,12 @@ void main() { }); test('Diff detect changed entry (time)', () async { - var calculator = ScheduleDiffCalculator(); + final calculator = ScheduleDiffCalculator(); - var oldSchedule = generateSchedule(); - var newSchedule = generateSchedule(); + final oldSchedule = generateSchedule(); + final newSchedule = generateSchedule(); - var updatedEntry = ScheduleEntry( + final updatedEntry = ScheduleEntry( room: newSchedule.entries[0].room, type: newSchedule.entries[0].type, title: newSchedule.entries[0].title, @@ -77,7 +77,7 @@ void main() { ); newSchedule.entries[0] = updatedEntry; - var diff = calculator.calculateDiff(oldSchedule, newSchedule); + final diff = calculator.calculateDiff(oldSchedule, newSchedule); expect(diff.addedEntries.length, 0); expect(diff.removedEntries.length, 0); @@ -88,12 +88,12 @@ void main() { }); test('Diff detect changed entry (start and room)', () async { - var calculator = ScheduleDiffCalculator(); + final calculator = ScheduleDiffCalculator(); - var oldSchedule = generateSchedule(); - var newSchedule = generateSchedule(); + final oldSchedule = generateSchedule(); + final newSchedule = generateSchedule(); - var updatedEntry = ScheduleEntry( + final updatedEntry = ScheduleEntry( room: "Changed room", type: newSchedule.entries[0].type, title: newSchedule.entries[0].title, @@ -104,7 +104,7 @@ void main() { ); newSchedule.entries[0] = updatedEntry; - var diff = calculator.calculateDiff(oldSchedule, newSchedule); + final diff = calculator.calculateDiff(oldSchedule, newSchedule); expect(diff.addedEntries.length, 0); expect(diff.removedEntries.length, 0); @@ -116,12 +116,12 @@ void main() { }); test('Diff detect two changed entries of same name (start)', () async { - var calculator = ScheduleDiffCalculator(); + final calculator = ScheduleDiffCalculator(); - var oldSchedule = generateSchedule(); - var newSchedule = generateSchedule(); + final oldSchedule = generateSchedule(); + final newSchedule = generateSchedule(); - var updatedEntry1 = ScheduleEntry( + final updatedEntry1 = ScheduleEntry( room: newSchedule.entries[2].room, type: newSchedule.entries[2].type, title: newSchedule.entries[2].title, @@ -132,7 +132,7 @@ void main() { ); newSchedule.entries[2] = updatedEntry1; - var updatedEntry2 = ScheduleEntry( + final updatedEntry2 = ScheduleEntry( room: newSchedule.entries[3].room, type: newSchedule.entries[3].type, title: newSchedule.entries[3].title, @@ -143,7 +143,7 @@ void main() { ); newSchedule.entries[3] = updatedEntry2; - var diff = calculator.calculateDiff(oldSchedule, newSchedule); + final diff = calculator.calculateDiff(oldSchedule, newSchedule); expect(diff.addedEntries.length, 0); expect(diff.removedEntries.length, 0); @@ -158,7 +158,7 @@ void main() { } Schedule generateSchedule() { - var scheduleEntries = [ + final scheduleEntries = [ ScheduleEntry( room: "Room1", type: ScheduleEntryType.Class, diff --git a/test/schedule/service/ical/ical_parser_test.dart b/test/schedule/service/ical/ical_parser_test.dart index 12968c70..6221637f 100644 --- a/test/schedule/service/ical/ical_parser_test.dart +++ b/test/schedule/service/ical/ical_parser_test.dart @@ -5,14 +5,14 @@ import 'package:dhbwstudentapp/schedule/service/ical/ical_parser.dart'; import 'package:test/test.dart'; Future main() async { - var icalFile = await File(Directory.current.absolute.path + + final icalFile = await File(Directory.current.absolute.path + '/test/schedule/service/ical/file_resources/ical_test.ics',) .readAsString(); test('ical correctly read all entries', () async { - var parser = IcalParser(); + final parser = IcalParser(); - var schedule = parser.parseIcal(icalFile).schedule; + final schedule = parser.parseIcal(icalFile).schedule; expect(schedule.entries.length, 3); diff --git a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart index 4a70c620..1aa4adaa 100644 --- a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart +++ b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart @@ -4,14 +4,14 @@ import 'package:dhbwstudentapp/schedule/service/mannheim/mannheim_course_respons import 'package:test/test.dart'; Future main() async { - var coursePage = await File(Directory.current.absolute.path + + final coursePage = await File(Directory.current.absolute.path + '/test/schedule/service/mannheim/html_resources/mannheim_ical.html',) .readAsString(); test('Mannheim course parser parses correctly', () async { - var parser = MannheimCourseResponseParser(); + final parser = MannheimCourseResponseParser(); - var courses = parser.parseCoursePage(coursePage); + final courses = parser.parseCoursePage(coursePage); expect(courses.length, 8); diff --git a/test/schedule/service/rapla/rapla_response_parser_test.dart b/test/schedule/service/rapla/rapla_response_parser_test.dart index be0e5d63..14ab8831 100644 --- a/test/schedule/service/rapla/rapla_response_parser_test.dart +++ b/test/schedule/service/rapla/rapla_response_parser_test.dart @@ -5,46 +5,46 @@ import 'package:dhbwstudentapp/schedule/service/rapla/rapla_response_parser.dart import 'package:test/test.dart'; Future main() async { - var monthlyRaplaPage = await File(Directory.current.absolute.path + + final monthlyRaplaPage = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_monthly_response.html',) .readAsString(); - var raplaPage = await File(Directory.current.absolute.path + + final raplaPage = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_response.html',) .readAsString(); - var raplaPage1 = await File(Directory.current.absolute.path + + final raplaPage1 = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_response_1.html',) .readAsString(); - var severalMonthsPage = await File(Directory.current.absolute.path + + final severalMonthsPage = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_several_months_response.html',) .readAsString(); - var severalMonthsPage1 = await File(Directory.current.absolute.path + + final severalMonthsPage1 = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_several_months_response_1.html',) .readAsString(); - var severalMonthsPage2 = await File(Directory.current.absolute.path + + final severalMonthsPage2 = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_several_months_response_2.html',) .readAsString(); - var invalidRaplaPage = await File(Directory.current.absolute.path + + final invalidRaplaPage = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/invalid_rapla_response.html',) .readAsString(); - var raplaWeekResponse = await File(Directory.current.absolute.path + + final raplaWeekResponse = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_week_response.html',) .readAsString(); - var raplaWeekResponse1 = await File(Directory.current.absolute.path + + final raplaWeekResponse1 = await File(Directory.current.absolute.path + '/test/schedule/service/rapla/html_resources/rapla_week_response_1.html',) .readAsString(); test('Rapla correctly read all classes of weekly view', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(raplaPage).schedule; + final schedule = parser.parseSchedule(raplaPage).schedule; expect(schedule.entries.length, 8); @@ -91,9 +91,9 @@ Future main() async { }); test('Rapla correctly read all classes of monthly view', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(monthlyRaplaPage).schedule; + final schedule = parser.parseSchedule(monthlyRaplaPage).schedule; expect(schedule.entries.length, 9); @@ -105,9 +105,9 @@ Future main() async { }); test('Rapla correctly read all classes of several months view', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(severalMonthsPage).schedule; + final schedule = parser.parseSchedule(severalMonthsPage).schedule; expect(schedule.entries[0].title, "Modulprüfung T3_2000"); expect(schedule.entries[0].start, DateTime(2021, 09, 22, 08)); @@ -137,9 +137,9 @@ Future main() async { test('Rapla correctly read all classes of problematic several months view', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(severalMonthsPage1).schedule; + final schedule = parser.parseSchedule(severalMonthsPage1).schedule; expect(schedule.entries[0].title, "Verkehrswegebau und Straßenwesen"); expect(schedule.entries[0].start, DateTime(2021, 12, 01, 08, 15)); @@ -167,9 +167,9 @@ Future main() async { }); test('Rapla correctly read all classes of several months view 3', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(severalMonthsPage2).schedule; + final schedule = parser.parseSchedule(severalMonthsPage2).schedule; expect(schedule.entries[0].title, "Marketing und Unternehmensstrategie"); expect(schedule.entries[0].start, DateTime(2021, 12, 01, 10)); @@ -180,9 +180,9 @@ Future main() async { }); test('Rapla correctly read the day of a class in week view', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(raplaPage1).schedule; + final schedule = parser.parseSchedule(raplaPage1).schedule; expect(schedule.entries[0].title, "Grundlagen der Handelsbetriebslehre"); expect(schedule.entries[0].start, DateTime(2021, 11, 02, 09)); @@ -246,9 +246,9 @@ Future main() async { }); test('Rapla correctly read the week response', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(raplaWeekResponse).schedule; + final schedule = parser.parseSchedule(raplaWeekResponse).schedule; expect(schedule.entries[0].title, "Geschäftsprozesse, T3ELG1010"); expect(schedule.entries[0].start, DateTime(2022, 02, 21, 08, 30)); @@ -261,9 +261,9 @@ Future main() async { }); test('Rapla correctly read the week response 1', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var schedule = parser.parseSchedule(raplaWeekResponse1).schedule; + final schedule = parser.parseSchedule(raplaWeekResponse1).schedule; expect(schedule.entries[0].title, "Klausur Elektronik und Messtechnik"); expect(schedule.entries[0].start, DateTime(2021, 12, 13, 08)); @@ -277,11 +277,11 @@ Future main() async { }); test('Rapla robust parse', () async { - var parser = RaplaResponseParser(); + final parser = RaplaResponseParser(); - var result = parser.parseSchedule(invalidRaplaPage); - var schedule = result.schedule; - var errors = result.errors; + final result = parser.parseSchedule(invalidRaplaPage); + final schedule = result.schedule; + final errors = result.errors; expect(errors.length, 3); expect(schedule.entries.length, 5); From e6497cd22a185e93a81465dd078468ebaec75a7a Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:18:02 +0200 Subject: [PATCH 09/37] fix prefer_const_constructors --- analysis_options.yaml | 1 + lib/common/ui/colors.dart | 6 +++--- lib/common/ui/donate_to_developer_dialog.dart | 4 ++-- lib/common/ui/notification_api.dart | 2 +- .../ui/calendar_export_page.dart | 6 +++--- .../ui/date_management_navigation_entry.dart | 6 +++--- .../ui/date_management_page.dart | 2 +- .../ui/widgets/date_filter_options.dart | 2 +- .../service/fake_data_dualis_scraper.dart | 18 +++++++++--------- lib/dualis/ui/dualis_navigation_entry.dart | 4 ++-- lib/dualis/ui/dualis_page.dart | 4 ++-- .../exam_results_page/exam_results_page.dart | 2 +- lib/dualis/ui/login/dualis_login_page.dart | 2 +- lib/dualis/ui/widgets/login_form_widget.dart | 6 +++--- .../useful_information_navigation_entry.dart | 2 +- .../useful_information_page.dart | 16 ++++++++-------- .../background/calendar_synchronizer.dart | 4 ++-- lib/schedule/ui/schedule_navigation_entry.dart | 8 ++++---- lib/schedule/ui/schedule_page.dart | 8 ++++---- .../weeklyschedule/weekly_schedule_page.dart | 8 ++++---- lib/schedule/ui/widgets/enter_url_dialog.dart | 2 +- .../widgets/select_mannheim_course_dialog.dart | 2 +- lib/ui/login_credentials_widget.dart | 4 ++-- lib/ui/navigation/router.dart | 4 ++-- lib/ui/onboarding/onboardin_step.dart | 10 +++++----- lib/ui/onboarding/onboarding_page.dart | 2 +- .../viewmodels/mannheim_view_model.dart | 2 +- lib/ui/onboarding/widgets/ical_url_page.dart | 2 +- lib/ui/onboarding/widgets/mannheim_page.dart | 6 +++--- .../widgets/onboarding_button_bar.dart | 6 +++--- lib/ui/onboarding/widgets/rapla_url_page.dart | 2 +- lib/ui/settings/donate_list_tile.dart | 10 +++++----- lib/ui/settings/purchase_widget_list_tile.dart | 12 ++++++------ lib/ui/settings/settings_page.dart | 6 +++--- .../viewmodels/settings_view_model.dart | 2 +- 35 files changed, 92 insertions(+), 91 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index e1f9ffff..00540b5c 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -21,3 +21,4 @@ linter: prefer_final_locals: true prefer_final_in_for_each: true prefer_final_fields: true + prefer_const_constructors: true diff --git a/lib/common/ui/colors.dart b/lib/common/ui/colors.dart index 832d3d2a..831b9ea0 100644 --- a/lib/common/ui/colors.dart +++ b/lib/common/ui/colors.dart @@ -92,16 +92,16 @@ class ColorPalettes { return themeData.copyWith( snackBarTheme: themeData.snackBarTheme.copyWith( - backgroundColor: isDark ? Color(0xff363635) : Color(0xfffafafa), + backgroundColor: isDark ? const Color(0xff363635) : const Color(0xfffafafa), contentTextStyle: themeData.textTheme.bodyText1!.copyWith( color: - isDark ? Color(0xffe4e4e4) : themeData.textTheme.bodyText1!.color, + isDark ? const Color(0xffe4e4e4) : themeData.textTheme.bodyText1!.color, ), ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: ColorPalettes.main, - padding: EdgeInsets.symmetric(horizontal: 16.0), + padding: const EdgeInsets.symmetric(horizontal: 16.0), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(4.0)), ), diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index 5dc4d432..a80908bb 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -45,8 +45,8 @@ class DonateToDeveloperDialog { child: Column( children: [ Text(L.of(context).donateDialogMessage), - Padding( - padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), + const Padding( + padding: EdgeInsets.fromLTRB(0, 32, 0, 0), child: Icon( Icons.free_breakfast_outlined, size: 60, diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index a302c7a3..c2f9471b 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -39,7 +39,7 @@ class NotificationApi { /// Show a notification with the given title and message /// Future showNotification(String title, String? message, [int? id]) async { - final androidPlatformChannelSpecifics = AndroidNotificationDetails( + final androidPlatformChannelSpecifics = const AndroidNotificationDetails( 'Notifications', 'Notifications', channelDescription: 'This is the main notification channel', diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 62122f05..f3e426ae 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -103,7 +103,7 @@ class _CalendarExportPageState extends State { Widget _buildStopCalendarSyncBtn() { // Dont display the "Synchronisation beenden" button, //if synchronization is not enabled or if it is not the right page - if (!widget.isCalendarSyncWidget) return SizedBox(); + if (!widget.isCalendarSyncWidget) return const SizedBox(); return PropertyChangeProvider( value: viewModel, @@ -163,7 +163,7 @@ class _CalendarExportPageState extends State { ), ), child: isSelected - ? Center( + ? const Center( child: Icon( Icons.check, size: 16, @@ -217,7 +217,7 @@ class _CalendarExportPageState extends State { .dateManagementExportToCalendarConfirm .toUpperCase(), textAlign: TextAlign.center, - style: TextStyle( + style: const TextStyle( fontSize: 14, color: Colors.white, ), diff --git a/lib/date_management/ui/date_management_navigation_entry.dart b/lib/date_management/ui/date_management_navigation_entry.dart index 04806a09..76340b64 100644 --- a/lib/date_management/ui/date_management_navigation_entry.dart +++ b/lib/date_management/ui/date_management_navigation_entry.dart @@ -12,7 +12,7 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class DateManagementNavigationEntry extends NavigationEntry { @override - Icon icon = Icon(Icons.date_range); + Icon icon = const Icon(Icons.date_range); @override String title(BuildContext context) { @@ -31,7 +31,7 @@ class DateManagementNavigationEntry List appBarActions(BuildContext context) { return [ IconButton( - icon: Icon(Icons.help_outline), + icon: const Icon(Icons.help_outline), onPressed: () async { await DateManagementHelpDialog().show(context); }, @@ -48,7 +48,7 @@ class DateManagementNavigationEntry builder: (BuildContext context) => CalendarExportPage( entriesToExport: model.allDates!, ), - settings: RouteSettings(name: "settings"), + settings: const RouteSettings(name: "settings"), ), ); }, diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index ab09e551..e6e2dfe0 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -101,7 +101,7 @@ class DateManagementPage extends StatelessWidget { Text( dateEntry.description, style: dateEntry.end.isBefore(DateTime.now()) - ? TextStyle(decoration: TextDecoration.lineThrough) + ? const TextStyle(decoration: TextDecoration.lineThrough) : null, ), onTap: () { diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index 1d89b5fa..e0f58d2b 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -59,7 +59,7 @@ class _DateFilterOptionsState extends State { child: ButtonTheme( minWidth: 36, child: IconButton( - icon: Icon(Icons.tune), + icon: const Icon(Icons.tune), onPressed: () { setState(() { _isExpanded = true; diff --git a/lib/dualis/service/fake_data_dualis_scraper.dart b/lib/dualis/service/fake_data_dualis_scraper.dart index acc20f69..1c3a150b 100644 --- a/lib/dualis/service/fake_data_dualis_scraper.dart +++ b/lib/dualis/service/fake_data_dualis_scraper.dart @@ -22,7 +22,7 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadAllModules( [CancellationToken? cancellationToken,]) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); return Future.value([ DualisModule( @@ -41,7 +41,7 @@ class FakeDataDualisScraper implements DualisScraper { String moduleDetailsUrl, [ CancellationToken? cancellationToken, ]) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); return Future.value([ DualisExam( "Klausur", @@ -58,7 +58,7 @@ class FakeDataDualisScraper implements DualisScraper { DateTime dateInMonth, CancellationToken cancellationToken, ) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); return Future.value(Schedule.fromList([])); } @@ -67,7 +67,7 @@ class FakeDataDualisScraper implements DualisScraper { String? semesterName, [ CancellationToken? cancellationToken, ]) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); return Future.value([ DualisModule( "Module1", @@ -83,14 +83,14 @@ class FakeDataDualisScraper implements DualisScraper { @override Future> loadSemesters( [CancellationToken? cancellationToken,]) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); return Future.value([DualisSemester("SoSe2020", "", [])]); } @override Future loadStudyGrades( CancellationToken? cancellationToken,) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); return Future.value( StudyGrades( 1.5, @@ -106,7 +106,7 @@ class FakeDataDualisScraper implements DualisScraper { Credentials credentials, CancellationToken? cancellationToken, ) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); _isLoggedIn = true; return Future.value(LoginResult.LoggedIn); } @@ -114,14 +114,14 @@ class FakeDataDualisScraper implements DualisScraper { @override Future loginWithPreviousCredentials( CancellationToken cancellationToken,) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); _isLoggedIn = true; return Future.value(LoginResult.LoggedIn); } @override Future logout(CancellationToken? cancellationToken) async { - await Future.delayed(Duration(milliseconds: 200)); + await Future.delayed(const Duration(milliseconds: 200)); _isLoggedIn = false; } diff --git a/lib/dualis/ui/dualis_navigation_entry.dart b/lib/dualis/ui/dualis_navigation_entry.dart index 3fc5eea4..1435aef5 100644 --- a/lib/dualis/ui/dualis_navigation_entry.dart +++ b/lib/dualis/ui/dualis_navigation_entry.dart @@ -10,7 +10,7 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class DualisNavigationEntry extends NavigationEntry { @override - Icon icon = Icon(Icons.data_usage); + Icon icon = const Icon(Icons.data_usage); @override String title(BuildContext context) { @@ -40,7 +40,7 @@ class DualisNavigationEntry extends NavigationEntry { (BuildContext _, StudyGradesViewModel? __, Set? ___) => model.loginState != LoginState.LoggedIn ? IconButton( - icon: Icon(Icons.help_outline), + icon: const Icon(Icons.help_outline), onPressed: () async { await DualisHelpDialog().show(context); }, diff --git a/lib/dualis/ui/dualis_page.dart b/lib/dualis/ui/dualis_page.dart index 0ea8203c..3491caa7 100644 --- a/lib/dualis/ui/dualis_page.dart +++ b/lib/dualis/ui/dualis_page.dart @@ -25,12 +25,12 @@ class DualisPage extends StatelessWidget { pages: [ PageDefinition( text: L.of(context).pageDualisOverview, - icon: Icon(Icons.dashboard), + icon: const Icon(Icons.dashboard), builder: (BuildContext context) => StudyOverviewPage(), ), PageDefinition( text: L.of(context).pageDualisExams, - icon: Icon(Icons.book), + icon: const Icon(Icons.book), builder: (BuildContext context) => ExamResultsPage(), ), ], diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index d5e8ab0c..45f6dcf8 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -152,7 +152,7 @@ class ExamResultsPage extends StatelessWidget { Widget _examGradeToWidget(BuildContext context, ExamGrade grade) { switch (grade.state) { case ExamGradeState.NotGraded: - return Text(""); + return const Text(""); case ExamGradeState.Graded: return Text(grade.gradeValue!); case ExamGradeState.Passed: diff --git a/lib/dualis/ui/login/dualis_login_page.dart b/lib/dualis/ui/login/dualis_login_page.dart index 98c7776b..8638e32a 100644 --- a/lib/dualis/ui/login/dualis_login_page.dart +++ b/lib/dualis/ui/login/dualis_login_page.dart @@ -19,7 +19,7 @@ class DualisLoginPage extends StatelessWidget { Padding( padding: const EdgeInsets.all(32), child: Container( - constraints: BoxConstraints(maxWidth: 500), + constraints: const BoxConstraints(maxWidth: 500), child: LoginForm( loginFailedText: L.of(context).dualisLoginFailed, title: Text( diff --git a/lib/dualis/ui/widgets/login_form_widget.dart b/lib/dualis/ui/widgets/login_form_widget.dart index 154e08c1..65b9a613 100644 --- a/lib/dualis/ui/widgets/login_form_widget.dart +++ b/lib/dualis/ui/widgets/login_form_widget.dart @@ -82,7 +82,7 @@ class _LoginFormState extends State { decoration: InputDecoration( enabled: !_isLoading, hintText: L.of(context).loginUsername, - icon: Icon(Icons.alternate_email), + icon: const Icon(Icons.alternate_email), ), ), TextField( @@ -91,7 +91,7 @@ class _LoginFormState extends State { decoration: InputDecoration( enabled: !_isLoading, hintText: L.of(context).loginPassword, - icon: Icon(Icons.lock_outline), + icon: const Icon(Icons.lock_outline), errorText: _loginFailed ? widget.loginFailedText : null, ), ), @@ -124,7 +124,7 @@ class _LoginFormState extends State { onPressed: () async { await loginButtonPressed(); }, - icon: Icon(Icons.chevron_right), + icon: const Icon(Icons.chevron_right), label: Text(L.of(context).loginButton.toUpperCase()), ), ), diff --git a/lib/information/ui/useful_information_navigation_entry.dart b/lib/information/ui/useful_information_navigation_entry.dart index 08713249..2b05e8b8 100644 --- a/lib/information/ui/useful_information_navigation_entry.dart +++ b/lib/information/ui/useful_information_navigation_entry.dart @@ -11,7 +11,7 @@ class UsefulInformationNavigationEntry extends NavigationEntry { } @override - Icon icon = Icon(Icons.info_outline); + Icon icon = const Icon(Icons.info_outline); @override String title(BuildContext context) { diff --git a/lib/information/ui/usefulinformation/useful_information_page.dart b/lib/information/ui/usefulinformation/useful_information_page.dart index 316d5b3b..a06c03d1 100644 --- a/lib/information/ui/usefulinformation/useful_information_page.dart +++ b/lib/information/ui/usefulinformation/useful_information_page.dart @@ -9,21 +9,21 @@ class UsefulInformationPage extends StatelessWidget { body: ListView( children: [ ListTile( - leading: Icon(Icons.language), + leading: const Icon(Icons.language), title: Text(L.of(context).informationPageDHBWHomepage), onTap: () { openLink("https://www.dhbw-stuttgart.de/home/"); }, ), ListTile( - leading: Icon(Icons.data_usage), + leading: const Icon(Icons.data_usage), title: Text(L.of(context).informationPageDualis), onTap: () { openLink("https://dualis.dhbw.de/"); }, ), ListTile( - leading: Icon(Icons.email), + leading: const Icon(Icons.email), title: Text(L.of(context).informationPageRoundcube), onTap: () { openLink( @@ -31,14 +31,14 @@ class UsefulInformationPage extends StatelessWidget { }, ), ListTile( - leading: Icon(Icons.room_service), + leading: const Icon(Icons.room_service), title: Text(L.of(context).informationPageMoodle), onTap: () { openLink("http://elearning.dhbw-stuttgart.de/"); }, ), ListTile( - leading: Icon(Icons.location_on), + leading: const Icon(Icons.location_on), title: Text(L.of(context).informationPageLocation), onTap: () { openLink( @@ -46,7 +46,7 @@ class UsefulInformationPage extends StatelessWidget { }, ), ListTile( - leading: Icon(Icons.wifi), + leading: const Icon(Icons.wifi), title: Text(L.of(context).informationPageEduroam), onTap: () { openLink( @@ -54,14 +54,14 @@ class UsefulInformationPage extends StatelessWidget { }, ), ListTile( - leading: Icon(Icons.person_outline), + leading: const Icon(Icons.person_outline), title: Text(L.of(context).informationPageStuV), onTap: () { openLink("https://stuv-stuttgart.de/"); }, ), ListTile( - leading: Icon(Icons.pool), + leading: const Icon(Icons.pool), title: Text(L.of(context).informationPageDHBWSports), onTap: () { openLink( diff --git a/lib/schedule/background/calendar_synchronizer.dart b/lib/schedule/background/calendar_synchronizer.dart index d3236b96..bfaab7dd 100644 --- a/lib/schedule/background/calendar_synchronizer.dart +++ b/lib/schedule/background/calendar_synchronizer.dart @@ -44,11 +44,11 @@ class CalendarSynchronizer { } void scheduleSyncInAFewSeconds() { - Future.delayed(Duration(seconds: 10), () { + Future.delayed(const Duration(seconds: 10), () { if (!scheduleSourceProvider.didSetupCorrectly()) return; scheduleProvider.getUpdatedSchedule( DateTime.now(), - DateTime.now().add(Duration(days: 30)), + DateTime.now().add(const Duration(days: 30)), CancellationToken(), ); }); diff --git a/lib/schedule/ui/schedule_navigation_entry.dart b/lib/schedule/ui/schedule_navigation_entry.dart index 160f4689..2be1d9f6 100644 --- a/lib/schedule/ui/schedule_navigation_entry.dart +++ b/lib/schedule/ui/schedule_navigation_entry.dart @@ -10,7 +10,7 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class ScheduleNavigationEntry extends NavigationEntry { @override - Icon icon = Icon(Icons.calendar_today); + Icon icon = const Icon(Icons.calendar_today); @override ScheduleViewModel initViewModel() { @@ -26,7 +26,7 @@ class ScheduleNavigationEntry extends NavigationEntry { @override Widget build(BuildContext context) { - return SchedulePage(); + return const SchedulePage(); } @override @@ -41,7 +41,7 @@ class ScheduleNavigationEntry extends NavigationEntry { model.didSetupProperly ? Container() : IconButton( - icon: Icon(Icons.help_outline), + icon: const Icon(Icons.help_outline), onPressed: () async { await ScheduleHelpDialog().show(context); }, @@ -55,7 +55,7 @@ class ScheduleNavigationEntry extends NavigationEntry { builder: (BuildContext _, ScheduleViewModel? __, Set? ___) => model.didSetupProperly ? IconButton( - icon: Icon(Icons.filter_alt), + icon: const Icon(Icons.filter_alt), onPressed: () async { Navigator.of(context).push(MaterialPageRoute( builder: (context) => ScheduleFilterPage(), diff --git a/lib/schedule/ui/schedule_page.dart b/lib/schedule/ui/schedule_page.dart index 531a0687..c4693f54 100644 --- a/lib/schedule/ui/schedule_page.dart +++ b/lib/schedule/ui/schedule_page.dart @@ -37,15 +37,15 @@ class _SchedulePageState extends State { return PagerWidget( pages: [ PageDefinition( - icon: Icon(Icons.view_week), + icon: const Icon(Icons.view_week), text: L.of(context).pageWeekOverviewTitle, - builder: (_) => WeeklySchedulePage(), + builder: (_) => const WeeklySchedulePage(), viewModel: weeklyScheduleViewModel, ), PageDefinition( - icon: Icon(Icons.view_day), + icon: const Icon(Icons.view_day), text: L.of(context).pageDayOverviewTitle, - builder: (_) => DailySchedulePage(), + builder: (_) => const DailySchedulePage(), viewModel: dailyScheduleViewModel, ), ], diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index 46ff4f49..57942a27 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -46,7 +46,7 @@ class _WeeklySchedulePageState extends State { ) ], ), - duration: Duration(seconds: 15), + duration: const Duration(seconds: 15), ), ); } @@ -169,15 +169,15 @@ class _WeeklySchedulePageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( - icon: Icon(Icons.chevron_left), + icon: const Icon(Icons.chevron_left), onPressed: _previousWeek, ), IconButton( - icon: Icon(Icons.today), + icon: const Icon(Icons.today), onPressed: _goToToday, ), IconButton( - icon: Icon(Icons.chevron_right), + icon: const Icon(Icons.chevron_right), onPressed: _nextWeek, ), ], diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index e9310551..ee1610a7 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -81,7 +81,7 @@ abstract class EnterUrlDialog { await _pasteUrl(); }, tooltip: L.of(context).onboardingRaplaUrlPaste, - icon: Icon(Icons.content_paste), + icon: const Icon(Icons.content_paste), ), ], ), diff --git a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart index cad41b7b..be20b53b 100644 --- a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart +++ b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart @@ -27,7 +27,7 @@ class SelectMannheimCourseDialog { AlertDialog _buildDialog(BuildContext context) { return AlertDialog( title: Text(L.of(context).onboardingMannheimTitle), - contentPadding: EdgeInsets.all(0), + contentPadding: const EdgeInsets.all(0), content: PropertyChangeProvider( value: _mannheimViewModel, child: Container( diff --git a/lib/ui/login_credentials_widget.dart b/lib/ui/login_credentials_widget.dart index c3e70936..71bf0e90 100644 --- a/lib/ui/login_credentials_widget.dart +++ b/lib/ui/login_credentials_widget.dart @@ -27,7 +27,7 @@ class _LoginCredentialsWidgetState extends State { controller: widget.controller.username, decoration: InputDecoration( hintText: L.of(context).loginUsername, - icon: Icon(Icons.alternate_email), + icon: const Icon(Icons.alternate_email), ), onSubmitted: (v) { FocusScope.of(context).requestFocus(_focus); @@ -39,7 +39,7 @@ class _LoginCredentialsWidgetState extends State { obscureText: true, decoration: InputDecoration( hintText: L.of(context).loginPassword, - icon: Icon(Icons.lock_outline), + icon: const Icon(Icons.lock_outline), ), focusNode: _focus, onSubmitted: (v) { diff --git a/lib/ui/navigation/router.dart b/lib/ui/navigation/router.dart index 6bc7ff67..633a61a1 100644 --- a/lib/ui/navigation/router.dart +++ b/lib/ui/navigation/router.dart @@ -70,10 +70,10 @@ Route generateRoute(RouteSettings settings) { target = const OnboardingPage(); break; case "main": - target = MainPage(); + target = const MainPage(); break; case "settings": - target = SettingsPage(); + target = const SettingsPage(); break; default: print("Failed to navigate to: " + settings.name!); diff --git a/lib/ui/onboarding/onboardin_step.dart b/lib/ui/onboarding/onboardin_step.dart index 7d26be55..0f7221fd 100644 --- a/lib/ui/onboarding/onboardin_step.dart +++ b/lib/ui/onboarding/onboardin_step.dart @@ -27,7 +27,7 @@ class SelectSourceOnboardingStep extends OnboardingStep { @override Widget buildContent(BuildContext context) { - return SelectSourcePage(); + return const SelectSourcePage(); } @override @@ -49,7 +49,7 @@ class DualisCredentialsOnboardingStep extends OnboardingStep { @override Widget buildContent(BuildContext context) { - return DualisLoginCredentialsPage(); + return const DualisLoginCredentialsPage(); } @override @@ -71,7 +71,7 @@ class RaplaOnboardingStep extends OnboardingStep { @override Widget buildContent(BuildContext context) { - return RaplaUrlPage(); + return const RaplaUrlPage(); } @override @@ -93,7 +93,7 @@ class IcalOnboardingStep extends OnboardingStep { @override Widget buildContent(BuildContext context) { - return IcalUrlPage(); + return const IcalUrlPage(); } @override @@ -112,7 +112,7 @@ class MannheimOnboardingStep extends OnboardingStep { @override Widget buildContent(BuildContext context) { - return MannheimPage(); + return const MannheimPage(); } @override diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index fc548819..cf5a5044 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -70,7 +70,7 @@ class _OnboardingPageState extends State behavior: HitTestBehavior.translucent, child: Center( child: Container( - constraints: BoxConstraints(maxWidth: 500), + constraints: const BoxConstraints(maxWidth: 500), child: Padding( padding: const EdgeInsets.fromLTRB(0, 120, 0, 90), child: PropertyChangeConsumer( diff --git a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart index 3ae7a468..809e0992 100644 --- a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart +++ b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart @@ -30,7 +30,7 @@ class MannheimViewModel extends OnboardingStepViewModel { notifyListeners("loadingState"); try { - await Future.delayed(Duration(seconds: 1)); + await Future.delayed(const Duration(seconds: 1)); _courses = await MannheimCourseScraper().loadCourses(); _loadingState = LoadCoursesState.Loaded; } catch (ex) { diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index 88ec56db..1494741b 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -70,7 +70,7 @@ class _IcalUrlPageState extends State { onPressed: () async { await viewModel?.pasteUrl(); }, - icon: Icon(Icons.content_paste), + icon: const Icon(Icons.content_paste), label: Text( L.of(context).onboardingRaplaUrlPaste.toUpperCase(), ), diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index 81c3ce75..3e968d71 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -68,14 +68,14 @@ class SelectMannheimCourseWidget extends StatelessWidget { } Widget _buildLoadingIndicator() { - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); } Widget _buildCourseList(BuildContext context, MannheimViewModel viewModel) { return Material( color: Colors.transparent, child: ListView.builder( - padding: EdgeInsets.all(0), + padding: const EdgeInsets.all(0), itemCount: viewModel.courses?.length ?? 0, itemBuilder: (BuildContext context, int index) => _buildCourseListTile(viewModel, index, context), @@ -122,7 +122,7 @@ class SelectMannheimCourseWidget extends StatelessWidget { padding: const EdgeInsets.all(16), child: MaterialButton( onPressed: viewModel?.loadCourses, - child: Icon(Icons.refresh), + child: const Icon(Icons.refresh), ), ), ], diff --git a/lib/ui/onboarding/widgets/onboarding_button_bar.dart b/lib/ui/onboarding/widgets/onboarding_button_bar.dart index 0dad178e..44fc6a9d 100644 --- a/lib/ui/onboarding/widgets/onboarding_button_bar.dart +++ b/lib/ui/onboarding/widgets/onboarding_button_bar.dart @@ -37,7 +37,7 @@ class OnboardingButtonBar extends StatelessWidget { ? Container() : TextButton.icon( onPressed: onPrevious, - icon: Icon(Icons.navigate_before), + icon: const Icon(Icons.navigate_before), label: Text(L.of(context).onboardingBackButton.toUpperCase()), ), ); @@ -60,8 +60,8 @@ class OnboardingButtonBar extends StatelessWidget { key: ValueKey(buttonText), onPressed: onNext, icon: viewModel.isLastStep - ? Icon(Icons.arrow_forward) - : Icon(Icons.navigate_next), + ? const Icon(Icons.arrow_forward) + : const Icon(Icons.navigate_next), label: Text(buttonText.toUpperCase()), ), ); diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index af2e7f4a..e7c31c76 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -70,7 +70,7 @@ class _RaplaUrlPageState extends State { onPressed: () async { await viewModel?.pasteUrl(); }, - icon: Icon(Icons.content_paste), + icon: const Icon(Icons.content_paste), label: Text( L.of(context).onboardingRaplaUrlPaste.toUpperCase(), ), diff --git a/lib/ui/settings/donate_list_tile.dart b/lib/ui/settings/donate_list_tile.dart index 4b17d511..254cdc11 100644 --- a/lib/ui/settings/donate_list_tile.dart +++ b/lib/ui/settings/donate_list_tile.dart @@ -55,8 +55,8 @@ class _DonateListTileState extends State { .value; if (model.widgetPurchaseState == null) { - return Padding( - padding: const EdgeInsets.all(8.0), + return const Padding( + padding: EdgeInsets.all(8.0), child: Center( child: SizedBox( child: CircularProgressIndicator( @@ -71,10 +71,10 @@ class _DonateListTileState extends State { return ListTile( title: Text(L.of(context).donateButtonTitle), subtitle: isPurchasing - ? Align( + ? const Align( alignment: Alignment.centerLeft, child: Padding( - padding: const EdgeInsets.all(8.0), + padding: EdgeInsets.all(8.0), child: SizedBox( child: CircularProgressIndicator( strokeWidth: 2, @@ -85,7 +85,7 @@ class _DonateListTileState extends State { ), ) : Text(L.of(context).donateButtonSubtitle), - trailing: Icon(Icons.free_breakfast), + trailing: const Icon(Icons.free_breakfast), onTap: _purchaseClicked, ); } diff --git a/lib/ui/settings/purchase_widget_list_tile.dart b/lib/ui/settings/purchase_widget_list_tile.dart index 5cbd5594..df1d5693 100644 --- a/lib/ui/settings/purchase_widget_list_tile.dart +++ b/lib/ui/settings/purchase_widget_list_tile.dart @@ -63,7 +63,7 @@ class _PurchaseWidgetListTileState extends State { return ListTile( title: Text(L.of(context).settingsWidgetPurchase), - trailing: Icon(Icons.add_to_home_screen_outlined), + trailing: const Icon(Icons.add_to_home_screen_outlined), subtitle: _buildWidgetSubtitle(), onTap: _purchaseClicked, ); @@ -71,10 +71,10 @@ class _PurchaseWidgetListTileState extends State { Widget? _buildWidgetSubtitle() { if (isPurchasing) { - return Align( + return const Align( alignment: Alignment.centerLeft, child: Padding( - padding: const EdgeInsets.all(8.0), + padding: EdgeInsets.all(8.0), child: SizedBox( child: CircularProgressIndicator( strokeWidth: 2, @@ -89,8 +89,8 @@ class _PurchaseWidgetListTileState extends State { if (model.widgetPurchaseState == PurchaseStateEnum.Purchased) { return Row( children: [ - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 8, 0), + const Padding( + padding: EdgeInsets.fromLTRB(0, 0, 8, 0), child: Icon( Icons.check, color: Colors.green, @@ -99,7 +99,7 @@ class _PurchaseWidgetListTileState extends State { ), Text( L.of(context).settingsWidgetDidPurchase, - style: TextStyle(color: Colors.green), + style: const TextStyle(color: Colors.green), ), ], ); diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index a9962fde..527905c7 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -86,8 +86,8 @@ class _SettingsPageState extends State { List buildAboutSettings(BuildContext context) { return [ TitleListTile(title: L.of(context).settingsAboutTitle), - PurchaseWidgetListTile(), - DonateListTile(), + const PurchaseWidgetListTile(), + const DonateListTile(), ListTile( title: Text(L.of(context).settingsAbout), onTap: () { @@ -170,7 +170,7 @@ class _SettingsPageState extends State { isCalendarSyncWidget: true, isCalendarSyncEnabled: isCalendarSyncEnabled, ), - settings: RouteSettings(name: "settings"),),); + settings: const RouteSettings(name: "settings"),),); }, ), const Divider(), diff --git a/lib/ui/settings/viewmodels/settings_view_model.dart b/lib/ui/settings/viewmodels/settings_view_model.dart index 033aef8a..7afb106a 100644 --- a/lib/ui/settings/viewmodels/settings_view_model.dart +++ b/lib/ui/settings/viewmodels/settings_view_model.dart @@ -65,7 +65,7 @@ class SettingsViewModel extends BaseViewModel { final scheduleProvider = KiwiContainer().resolve(); scheduleProvider.getUpdatedSchedule( DateTime.now(), - DateTime.now().add(Duration(days: 30)), + DateTime.now().add(const Duration(days: 30)), CancellationToken(), ); } From 730a17f4df1b4b0ec38ca32fa249078cfe09560d Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:19:34 +0200 Subject: [PATCH 10/37] unnecessary_await_in_return --- analysis_options.yaml | 1 + lib/common/data/database_access.dart | 16 ++++++++-------- .../data/preferences/preferences_provider.dart | 10 +++++----- .../data/preferences/secure_storage_access.dart | 2 +- lib/common/ui/donate_to_developer_dialog.dart | 2 +- lib/common/ui/rate_in_store_dialog.dart | 2 +- lib/common/ui/widget_help_dialog.dart | 2 +- lib/date_management/data/calendar_access.dart | 2 +- lib/dualis/service/dualis_authentication.dart | 4 ++-- lib/dualis/service/dualis_service.dart | 4 ++-- .../ui/viewmodels/study_grades_view_model.dart | 2 +- .../business/schedule_source_provider.dart | 8 ++++---- .../ui/widgets/enter_rapla_url_dialog.dart | 2 +- 13 files changed, 29 insertions(+), 28 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 00540b5c..98864dfa 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -22,3 +22,4 @@ linter: prefer_final_in_for_each: true prefer_final_fields: true prefer_const_constructors: true + unnecessary_await_in_return: true diff --git a/lib/common/data/database_access.dart b/lib/common/data/database_access.dart index f1ca87ab..bb094a2c 100644 --- a/lib/common/data/database_access.dart +++ b/lib/common/data/database_access.dart @@ -15,7 +15,7 @@ class DatabaseAccess { Future _initDatabase() async { final String path = await getDatabasePath(_databaseName); - return await openDatabase(path, + return openDatabase(path, version: SqlScripts.databaseMigrationScripts.length, onCreate: _onCreate, onUpgrade: _onUpgrade,); @@ -42,18 +42,18 @@ class DatabaseAccess { Future insert(String table, Map row) async { final Database db = await _database; - return await db.insert(table, row); + return db.insert(table, row); } Future>> queryAllRows(String table) async { final Database db = await _database; - return await db.query(table); + return db.query(table); } Future>> rawQuery( String sql, List parameters,) async { final Database db = await _database; - return await db.rawQuery(sql, parameters); + return db.rawQuery(sql, parameters); } Future>> queryRows(String table, @@ -73,7 +73,7 @@ class DatabaseAccess { whereArgs![i] = whereArgs[i] ?? ""; } - return await db.query( + return db.query( table, distinct: distinct, columns: columns, @@ -101,13 +101,13 @@ class DatabaseAccess { Future update(String table, Map row) async { final Database db = await _database; final int? id = row[idColumnName]; - return await db + return db .update(table, row, where: '$idColumnName = ?', whereArgs: [id]); } Future delete(String table, int? id) async { final Database db = await _database; - return await db.delete(table, where: '$idColumnName = ?', whereArgs: [id]); + return db.delete(table, where: '$idColumnName = ?', whereArgs: [id]); } Future deleteWhere( @@ -116,7 +116,7 @@ class DatabaseAccess { List? whereArgs, }) async { final Database db = await _database; - return await db.delete( + return db.delete( table, where: where, whereArgs: whereArgs, diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index af10e3e8..e2984a31 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -94,7 +94,7 @@ class PreferencesProvider { } Future getLastUsedLanguageCode() async { - return await _preferencesAccess.get(LastUsedLanguageCode); + return _preferencesAccess.get(LastUsedLanguageCode); } Future setLastUsedLanguageCode(String languageCode) async { @@ -156,7 +156,7 @@ class PreferencesProvider { } Future getLastViewedSemester() async { - return await _preferencesAccess.get(LastViewedSemester); + return _preferencesAccess.get(LastViewedSemester); } Future setLastViewedSemester(String? lastViewedSemester) async { @@ -166,7 +166,7 @@ class PreferencesProvider { } Future getLastViewedDateEntryDatabase() async { - return await _preferencesAccess.get(LastViewedDateEntryDatabase); + return _preferencesAccess.get(LastViewedDateEntryDatabase); } Future setLastViewedDateEntryDatabase(String? value) async { @@ -175,7 +175,7 @@ class PreferencesProvider { } Future getLastViewedDateEntryYear() async { - return await _preferencesAccess.get(LastViewedDateEntryYear); + return _preferencesAccess.get(LastViewedDateEntryYear); } Future setLastViewedDateEntryYear(String? value) async { @@ -247,7 +247,7 @@ class PreferencesProvider { } Future setAppLaunchCounter(int value) async { - return await _preferencesAccess.set("AppLaunchCount", value); + return _preferencesAccess.set("AppLaunchCount", value); } Future getNextRateInStoreLaunchCount() async { diff --git a/lib/common/data/preferences/secure_storage_access.dart b/lib/common/data/preferences/secure_storage_access.dart index 76745504..d5d871f6 100644 --- a/lib/common/data/preferences/secure_storage_access.dart +++ b/lib/common/data/preferences/secure_storage_access.dart @@ -8,6 +8,6 @@ class SecureStorageAccess { } Future get(String key) async { - return await _secureStorage.read(key: key); + return _secureStorage.read(key: key); } } diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index a80908bb..40e91b62 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -28,7 +28,7 @@ class DonateToDeveloperDialog { } Future _showDialog(BuildContext context) async { - return await showDialog( + return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { diff --git a/lib/common/ui/rate_in_store_dialog.dart b/lib/common/ui/rate_in_store_dialog.dart index cbdff89e..80ce26bd 100644 --- a/lib/common/ui/rate_in_store_dialog.dart +++ b/lib/common/ui/rate_in_store_dialog.dart @@ -28,7 +28,7 @@ class RateInStoreDialog { Future _showRateDialog(BuildContext context) async { await analytics.logEvent(name: "rateRequestShown"); - return await showDialog( + return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { diff --git a/lib/common/ui/widget_help_dialog.dart b/lib/common/ui/widget_help_dialog.dart index 06acfe48..663c1c3f 100644 --- a/lib/common/ui/widget_help_dialog.dart +++ b/lib/common/ui/widget_help_dialog.dart @@ -24,7 +24,7 @@ class WidgetHelpDialog { } Future _showDialog(BuildContext context) async { - return await showDialog( + return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { diff --git a/lib/date_management/data/calendar_access.dart b/lib/date_management/data/calendar_access.dart index 6f14f970..3a269165 100644 --- a/lib/date_management/data/calendar_access.dart +++ b/lib/date_management/data/calendar_access.dart @@ -79,7 +79,7 @@ class CalendarAccess { end = entry.end; } - return await _deviceCalendarPlugin.createOrUpdateEvent(Event( + return _deviceCalendarPlugin.createOrUpdateEvent(Event( calendar.id, location: entry.room, title: entry.description, diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index 821b0b73..0bf541e5 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -153,7 +153,7 @@ class DualisAuthentication { final loginResult = await login(_credentials!, cancellationToken); if (loginResult == LoginResult.LoggedIn) { - return await session.get( + return session.get( _fillUrlWithAuthToken(url), cancellationToken, ); @@ -210,6 +210,6 @@ class DualisAuthentication { Future loginWithPreviousCredentials( CancellationToken cancellationToken,) async { assert(_credentials != null); - return await login(_credentials!, cancellationToken); + return login(_credentials!, cancellationToken); } } diff --git a/lib/dualis/service/dualis_service.dart b/lib/dualis/service/dualis_service.dart index f74d1005..1603f2c0 100644 --- a/lib/dualis/service/dualis_service.dart +++ b/lib/dualis/service/dualis_service.dart @@ -51,7 +51,7 @@ class DualisServiceImpl extends DualisService { Credentials credentials, [ CancellationToken? cancellationToken, ]) async { - return await _dualisScraper.login( + return _dualisScraper.login( credentials, cancellationToken, ); @@ -61,7 +61,7 @@ class DualisServiceImpl extends DualisService { Future queryStudyGrades([ CancellationToken? cancellationToken, ]) async { - return await _dualisScraper.loadStudyGrades(cancellationToken); + return _dualisScraper.loadStudyGrades(cancellationToken); } @override diff --git a/lib/dualis/ui/viewmodels/study_grades_view_model.dart b/lib/dualis/ui/viewmodels/study_grades_view_model.dart index 7e3281a9..97f23baa 100644 --- a/lib/dualis/ui/viewmodels/study_grades_view_model.dart +++ b/lib/dualis/ui/viewmodels/study_grades_view_model.dart @@ -93,7 +93,7 @@ class StudyGradesViewModel extends BaseViewModel { } Future loadCredentials() async { - return await _preferencesProvider.loadDualisCredentials(); + return _preferencesProvider.loadDualisCredentials(); } Future saveCredentials(Credentials credentials) async { diff --git a/lib/schedule/business/schedule_source_provider.dart b/lib/schedule/business/schedule_source_provider.dart index d104a0e0..ab67f74c 100644 --- a/lib/schedule/business/schedule_source_provider.dart +++ b/lib/schedule/business/schedule_source_provider.dart @@ -48,10 +48,10 @@ class ScheduleSourceProvider { ScheduleSource scheduleSource = InvalidScheduleSource(); final initializer = { - ScheduleSourceType.Dualis: () async => await _dualisScheduleSource(), - ScheduleSourceType.Rapla: () async => await _raplaScheduleSource(), - ScheduleSourceType.Ical: () async => await _icalScheduleSource(), - ScheduleSourceType.Mannheim: () async => await _icalScheduleSource(), + ScheduleSourceType.Dualis: () async => _dualisScheduleSource(), + ScheduleSourceType.Rapla: () async => _raplaScheduleSource(), + ScheduleSourceType.Ical: () async => _icalScheduleSource(), + ScheduleSourceType.Mannheim: () async => _icalScheduleSource(), }; if (initializer.containsKey(scheduleSourceType)) { diff --git a/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart b/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart index c2ed49b2..e2baea2c 100644 --- a/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart @@ -21,7 +21,7 @@ class EnterRaplaUrlDialog extends EnterUrlDialog { @override Future loadUrl() async { - return await _preferencesProvider.getRaplaUrl(); + return _preferencesProvider.getRaplaUrl(); } @override From 395fc59a87a90b87d5dac7415b661d1261154687 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:21:07 +0200 Subject: [PATCH 11/37] fix curly_braces_in_flow_control_structures --- analysis_options.yaml | 1 + .../parsing/semesters_from_course_result_page_extract.dart | 3 ++- .../study_grades_from_student_results_page_extract.dart | 3 ++- lib/dualis/service/session.dart | 6 ++++-- lib/dualis/ui/exam_results_page/exam_results_page.dart | 3 ++- lib/dualis/ui/viewmodels/study_grades_view_model.dart | 3 ++- lib/schedule/business/schedule_provider.dart | 6 ++++-- lib/schedule/service/dualis/dualis_schedule_source.dart | 3 ++- lib/schedule/service/ical/ical_schedule_source.dart | 3 ++- lib/schedule/service/mannheim/mannheim_course_scraper.dart | 3 ++- lib/schedule/service/rapla/rapla_parsing_utils.dart | 6 ++++-- lib/schedule/service/rapla/rapla_schedule_source.dart | 3 ++- lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart | 3 ++- lib/schedule/ui/widgets/enter_url_dialog.dart | 3 ++- lib/ui/onboarding/widgets/ical_url_page.dart | 3 ++- lib/ui/onboarding/widgets/rapla_url_page.dart | 3 ++- lib/ui/settings/viewmodels/settings_view_model.dart | 5 +++-- 17 files changed, 40 insertions(+), 20 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 98864dfa..414a8a50 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -23,3 +23,4 @@ linter: prefer_final_fields: true prefer_const_constructors: true unnecessary_await_in_return: true + curly_braces_in_flow_control_structures: true diff --git a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart index 73a56b6f..e2a82417 100644 --- a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart @@ -22,8 +22,9 @@ class SemestersFromCourseResultPageExtract { final semesterSelector = page.getElementById("semester"); - if (semesterSelector == null) + if (semesterSelector == null) { throw ElementNotFoundParseException("semester selector container"); + } final url = _extractSemesterDetailUrlPart(semesterSelector, endpointUrl); diff --git a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart index 7ca64c3b..0da8da5d 100644 --- a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart +++ b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart @@ -33,8 +33,9 @@ class StudyGradesFromStudentResultsPageExtract { _Credits _extractCredits(Element table) { final rows = table.getElementsByTagName("tr"); - if (rows.length < 2) + if (rows.length < 2) { throw ElementNotFoundParseException("credits container"); + } final neededCreditsRow = rows[rows.length - 1]; var neededCredits = neededCreditsRow.children[0].innerHtml; diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index 07381755..5fdd7090 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -56,8 +56,9 @@ class Session { headers: _cookies, ); - if (response == null && !requestCancellationToken.isCanceled) + if (response == null && !requestCancellationToken.isCanceled) { throw ServiceRequestFailed("Http request failed!"); + } _updateCookie(response!); @@ -114,8 +115,9 @@ class Session { cancelToken: requestCancellationToken, ); - if (response == null && !requestCancellationToken.isCanceled) + if (response == null && !requestCancellationToken.isCanceled) { throw ServiceRequestFailed("Http request failed!"); + } _updateCookie(response!); diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index 45f6dcf8..39545a7b 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -80,8 +80,9 @@ class ExamResultsPage extends StatelessWidget { return AnimatedSwitcher( layoutBuilder: (Widget? currentChild, List previousChildren) { List children = previousChildren; - if (currentChild != null) + if (currentChild != null) { children = children.toList()..add(currentChild); + } return Stack( children: children, alignment: Alignment.topCenter, diff --git a/lib/dualis/ui/viewmodels/study_grades_view_model.dart b/lib/dualis/ui/viewmodels/study_grades_view_model.dart index 97f23baa..e65d1b09 100644 --- a/lib/dualis/ui/viewmodels/study_grades_view_model.dart +++ b/lib/dualis/ui/viewmodels/study_grades_view_model.dart @@ -149,8 +149,9 @@ class StudyGradesViewModel extends BaseViewModel { } Future loadSemester(String? semesterName) async { - if (_currentSemester != null && _currentSemesterName == semesterName) + if (_currentSemester != null && _currentSemesterName == semesterName) { return Future.value(); + } if (_currentLoadingSemesterName == semesterName) return Future.value(); diff --git a/lib/schedule/business/schedule_provider.dart b/lib/schedule/business/schedule_provider.dart index 24bf2eb2..3de9599c 100644 --- a/lib/schedule/business/schedule_provider.dart +++ b/lib/schedule/business/schedule_provider.dart @@ -136,8 +136,9 @@ class ScheduleProvider { } void removeScheduleUpdatedCallback(ScheduleUpdatedCallback callback) { - if (_scheduleUpdatedCallbacks.contains(callback)) + if (_scheduleUpdatedCallbacks.contains(callback)) { _scheduleUpdatedCallbacks.remove(callback); + } } void addScheduleEntryChangedCallback(ScheduleEntryChangedCallback callback) { @@ -146,8 +147,9 @@ class ScheduleProvider { void removeScheduleEntryChangedCallback( ScheduleEntryChangedCallback callback,) { - if (_scheduleUpdatedCallbacks.contains(callback)) + if (_scheduleUpdatedCallbacks.contains(callback)) { _scheduleEntryChangedCallbacks.remove(callback); + } } Future _cleanDiffFromNewlyQueriedEntries( diff --git a/lib/schedule/service/dualis/dualis_schedule_source.dart b/lib/schedule/service/dualis/dualis_schedule_source.dart index 19d7c16f..fd08e80d 100644 --- a/lib/schedule/service/dualis/dualis_schedule_source.dart +++ b/lib/schedule/service/dualis/dualis_schedule_source.dart @@ -22,8 +22,9 @@ class DualisScheduleSource extends ScheduleSource { var schedule = Schedule(); final allErrors = []; - if (!_dualisScraper.isLoggedIn()) + if (!_dualisScraper.isLoggedIn()) { await _dualisScraper.loginWithPreviousCredentials(cancellationToken); + } while (to!.isAfter(current) && !cancellationToken.isCancelled()) { try { diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index 60d3a8a4..da1ffede 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -61,8 +61,9 @@ class IcalScheduleSource extends ScheduleSource { cancelToken: requestCancellationToken, ); - if (response == null && !requestCancellationToken.isCanceled) + if (response == null && !requestCancellationToken.isCanceled) { throw ServiceRequestFailed("Http request failed!"); + } return response; } on http.OperationCanceledError catch (_) { diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index f21d2319..2eecc7d8 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -39,8 +39,9 @@ class MannheimCourseScraper { final response = await http.HttpClientHelper.get(uri, cancelToken: requestCancellationToken,); - if (response == null && !requestCancellationToken.isCanceled) + if (response == null && !requestCancellationToken.isCanceled) { throw ServiceRequestFailed("Http request failed!"); + } return response!; } on http.OperationCanceledError catch (_) { diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index b2000082..316ba5c8 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -35,16 +35,18 @@ class RaplaParsingUtils { // The only reliable way to extract the time final timeAndClassName = value.getElementsByTagName("a"); - if (timeAndClassName.isEmpty) + if (timeAndClassName.isEmpty) { throw ElementNotFoundParseException("time and date container"); + } final descriptionInCell = timeAndClassName[0].text; final start = _parseTime(descriptionInCell.substring(0, 5), date); final end = _parseTime(descriptionInCell.substring(7, 12), date); - if (start == null || end == null) + if (start == null || end == null) { throw ElementNotFoundParseException("start and end date container"); + } ScheduleEntry? scheduleEntry; diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index c7de956f..dc21be72 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -152,8 +152,9 @@ class RaplaScheduleSource extends ScheduleSource { final response = await http.HttpClientHelper.get(uri, cancelToken: requestCancellationToken,); - if (response == null && !requestCancellationToken.isCanceled) + if (response == null && !requestCancellationToken.isCanceled) { throw ServiceRequestFailed("Http request failed!"); + } return response; } on http.OperationCanceledError catch (_) { diff --git a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart index e5276b64..cb183ce6 100644 --- a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart @@ -98,8 +98,9 @@ class WeeklyScheduleViewModel extends BaseViewModel { clippedDateEnd = toDayOfWeek(scheduleEnd, DateTime.friday); } - if (scheduleEnd?.isAfter(clippedDateEnd!) ?? false) + if (scheduleEnd?.isAfter(clippedDateEnd!) ?? false) { clippedDateEnd = scheduleEnd; + } displayStartHour = weekSchedule?.getStartTime()?.hour ?? 23; displayStartHour = min(7, displayStartHour); diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index ee1610a7..2f38dbc4 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -51,8 +51,9 @@ abstract class EnterUrlDialog { ValueNotifier url, Widget? child, ) { - if (_urlTextController.text != url.value) + if (_urlTextController.text != url.value) { _urlTextController.text = url.value; + } return Consumer( builder: ( diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index 1494741b..d7707fee 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -46,8 +46,9 @@ class _IcalUrlPageState extends State { final viewModel = model as IcalUrlViewModel?; if (viewModel?.url != null && - _urlTextController.text != viewModel!.url) + _urlTextController.text != viewModel!.url){ _urlTextController.text = viewModel.url!; + } return Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index e7c31c76..88171428 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -46,8 +46,9 @@ class _RaplaUrlPageState extends State { final viewModel = model as RaplaUrlViewModel?; if (viewModel?.raplaUrl != null && - _urlTextController.text != viewModel!.raplaUrl) + _urlTextController.text != viewModel!.raplaUrl){ _urlTextController.text = viewModel.raplaUrl!; + } return Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), diff --git a/lib/ui/settings/viewmodels/settings_view_model.dart b/lib/ui/settings/viewmodels/settings_view_model.dart index 7afb106a..9377935d 100644 --- a/lib/ui/settings/viewmodels/settings_view_model.dart +++ b/lib/ui/settings/viewmodels/settings_view_model.dart @@ -100,10 +100,11 @@ class SettingsViewModel extends BaseViewModel { await _preferencesProvider.setNotifyAboutNextDay(value); - if (value) + if (value) { await _nextDayInformationNotification.schedule(); - else + } else { await _nextDayInformationNotification.cancel(); + } } Future _loadPreferences() async { From 3b647baef7ae6e8ce145d01629bafcd988573af8 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:24:38 +0200 Subject: [PATCH 12/37] fix various lints (using dart fix) --- analysis_options.yaml | 2 +- lib/common/appstart/app_initializer.dart | 6 ++--- lib/common/data/database_path_provider.dart | 4 +-- .../preferences/preferences_provider.dart | 6 +++-- lib/common/iap/in_app_purchase_manager.dart | 14 ++++------ lib/common/ui/donate_to_developer_dialog.dart | 2 +- lib/common/ui/notification_api.dart | 8 +++--- lib/common/ui/widgets/error_display.dart | 2 +- lib/common/util/cancelable_mutex.dart | 2 +- lib/date_management/data/calendar_access.dart | 6 ++--- .../data/date_entry_entity.dart | 1 + lib/date_management/model/date_entry.dart | 12 ++++----- .../service/parsing/all_dates_extract.dart | 4 +-- .../ui/calendar_export_page.dart | 4 +-- .../ui/date_management_page.dart | 6 ++--- .../calendar_export_view_model.dart | 6 ++--- .../date_management_view_model.dart | 9 +++---- .../ui/widgets/date_detail_bottom_sheet.dart | 6 ++--- .../ui/widgets/date_filter_options.dart | 4 +-- lib/dualis/service/dualis_authentication.dart | 2 +- lib/dualis/service/dualis_scraper.dart | 2 +- ...sters_from_course_result_page_extract.dart | 2 +- lib/dualis/service/session.dart | 4 +-- .../exam_results_page/exam_results_page.dart | 10 +++---- .../study_overview/study_overview_page.dart | 2 +- lib/dualis/ui/widgets/login_form_widget.dart | 2 +- lib/main.dart | 11 ++++---- lib/native/widget/android_widget_helper.dart | 2 +- lib/native/widget/ios_widget_helper.dart | 2 +- .../background/calendar_synchronizer.dart | 6 ++--- .../business/schedule_source_provider.dart | 10 +++---- lib/schedule/model/schedule_entry.dart | 26 +++++++++--------- .../model/schedule_query_information.dart | 4 +-- .../dualis/dualis_schedule_source.dart | 2 +- .../isolate_schedule_source_decorator.dart | 4 +-- .../mannheim/mannheim_course_scraper.dart | 2 +- .../service/rapla/rapla_parsing_utils.dart | 2 +- .../service/rapla/rapla_schedule_source.dart | 2 +- lib/schedule/service/schedule_prettifier.dart | 10 +++---- lib/schedule/service/schedule_source.dart | 2 +- .../ui/dailyschedule/daily_schedule_page.dart | 8 +++--- .../next_day_information_notification.dart | 4 +-- .../weekly_schedule_view_model.dart | 3 +-- .../filter/filter_view_model.dart | 4 +-- .../schedule_entry_detail_bottom_sheet.dart | 14 +++------- .../weeklyschedule/weekly_schedule_page.dart | 8 +++--- .../widgets/schedule_widget.dart | 10 +++---- lib/schedule/ui/widgets/enter_url_dialog.dart | 2 +- .../select_mannheim_course_dialog.dart | 2 +- lib/ui/banner_widget.dart | 2 +- lib/ui/main_page.dart | 2 +- lib/ui/navigation/router.dart | 8 +++--- lib/ui/navigation_drawer.dart | 2 +- lib/ui/onboarding/onboardin_step.dart | 2 +- lib/ui/onboarding/onboarding_page.dart | 2 +- .../viewmodels/onboarding_view_model.dart | 8 +++--- .../onboarding/widgets/dualis_login_page.dart | 6 ++--- .../widgets/onboarding_page_background.dart | 20 ++++++-------- lib/ui/onboarding/widgets/rapla_url_page.dart | 2 +- lib/ui/pager_widget.dart | 2 +- lib/ui/root_page.dart | 6 ++--- lib/ui/settings/donate_list_tile.dart | 10 +++---- .../settings/purchase_widget_list_tile.dart | 6 ++--- lib/ui/settings/settings_page.dart | 2 +- .../viewmodels/settings_view_model.dart | 6 ++--- test/common/util/string_utils_test.dart | 2 +- .../parsing/all_dates_extract_test.dart | 3 +-- .../parsing/all_modules_extract_test.dart | 3 +-- .../parsing/dualis_timeout_extract_test.dart | 6 ++--- ...xams_from_module_details_extract_test.dart | 3 +-- ..._from_course_result_page_extract_test.dart | 3 +-- .../monthly_schedule_extract_test.dart | 3 +-- ..._from_course_result_page_extract_test.dart | 3 +-- ...rom_student_results_page_extract_test.dart | 3 +-- .../urls_from_main_page_extract_test.dart | 3 +-- .../service/ical/ical_parser_test.dart | 3 +-- .../mannheim_course_response_parser_test.dart | 3 +-- .../rapla/rapla_response_parser_test.dart | 27 +++++++------------ 78 files changed, 185 insertions(+), 234 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 414a8a50..b47820e0 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,7 +1,7 @@ # This file configures the analyzer to use the lint rule set from `package:lint` # For apps, use the default set -#include: package:lint/analysis_options.yaml +include: package:lint/analysis_options.yaml # Packages, that may be distributed (i.e. via pub.dev) should use the package # version, resulting in a better pub score. diff --git a/lib/common/appstart/app_initializer.dart b/lib/common/appstart/app_initializer.dart index d3ad9e6a..fe5d9581 100644 --- a/lib/common/appstart/app_initializer.dart +++ b/lib/common/appstart/app_initializer.dart @@ -5,13 +5,13 @@ import 'package:dhbwstudentapp/common/appstart/localization_initialize.dart'; import 'package:dhbwstudentapp/common/appstart/notification_schedule_changed_initialize.dart'; import 'package:dhbwstudentapp/common/appstart/notifications_initialize.dart'; import 'package:dhbwstudentapp/common/appstart/service_injector.dart'; +import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart'; import 'package:dhbwstudentapp/common/iap/in_app_purchase_manager.dart'; import 'package:dhbwstudentapp/native/widget/widget_update_callback.dart'; import 'package:dhbwstudentapp/schedule/background/calendar_synchronizer.dart'; +import 'package:dhbwstudentapp/schedule/business/schedule_provider.dart'; import 'package:dhbwstudentapp/schedule/business/schedule_source_provider.dart'; import 'package:kiwi/kiwi.dart'; -import 'package:dhbwstudentapp/schedule/business/schedule_provider.dart'; -import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart'; import 'package:timezone/data/latest.dart' as tz; bool isInitialized = false; @@ -62,7 +62,7 @@ Future initializeApp(bool isBackground) async { } // Callback-Function for synchronizing the device calendar with the schedule, when schedule is updated - final CalendarSynchronizer calendarSynchronizer = new CalendarSynchronizer( + final CalendarSynchronizer calendarSynchronizer = CalendarSynchronizer( KiwiContainer().resolve(), KiwiContainer().resolve(), KiwiContainer().resolve(),); diff --git a/lib/common/data/database_path_provider.dart b/lib/common/data/database_path_provider.dart index 0900fe2d..f6ba715e 100644 --- a/lib/common/data/database_path_provider.dart +++ b/lib/common/data/database_path_provider.dart @@ -1,8 +1,8 @@ import 'dart:io'; -import 'package:path_provider/path_provider.dart'; -import 'package:path/path.dart'; import 'package:app_group_directory/app_group_directory.dart'; +import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; Future getDatabasePath(String databaseName) async { final Directory documentsDirectory = await getApplicationDocumentsDirectory(); diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index e2984a31..c5ab496c 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -71,9 +71,11 @@ class PreferencesProvider { if (selectedCalendarId == null) return null; final List availableCalendars = await CalendarAccess().queryWriteableCalendars(); - availableCalendars.forEach((cal) => { + for (final cal in availableCalendars) { + { if (cal.id == selectedCalendarId) {selectedCalendar = cal} - },); + } + } return selectedCalendar; } diff --git a/lib/common/iap/in_app_purchase_manager.dart b/lib/common/iap/in_app_purchase_manager.dart index 54b5c76d..b504271b 100644 --- a/lib/common/iap/in_app_purchase_manager.dart +++ b/lib/common/iap/in_app_purchase_manager.dart @@ -19,7 +19,7 @@ class InAppPurchaseManager { _initialize(); } - void _initialize() async { + Future _initialize() async { addPurchaseCallback( InAppPurchaseHelper.WidgetProductId, (String? productId, PurchaseResultEnum result) => @@ -81,9 +81,9 @@ class InAppPurchaseManager { } for (final pair in purchaseCallbacks.entries) { - pair.value.forEach((element) { + for (final element in pair.value) { element(null, result); - }); + } } } @@ -96,9 +96,7 @@ class InAppPurchaseManager { String? productId, PurchaseCompletedCallback callback, ) { - if (productId == null) { - productId = "*"; - } + productId ??= "*"; purchaseCallbacks[productId]?.add(callback); } @@ -110,9 +108,7 @@ class InAppPurchaseManager { String? productId, PurchaseCompletedCallback callback, ) { - if (productId == null) { - productId = "*"; - } + productId ??= "*"; purchaseCallbacks[productId]?.remove(callback); } diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index 40e91b62..43866132 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -16,7 +16,7 @@ class DonateToDeveloperDialog { DonateToDeveloperDialog(this._preferencesProvider, this._appLaunchCounter); - void showIfNeeded(BuildContext context) async { + Future showIfNeeded(BuildContext context) async { if (await _preferencesProvider.getDidShowDonateDialog()) return; if (_appLaunchCounter >= DonateLaunchAfter) { diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index c2f9471b..9f9d5a17 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -15,7 +15,7 @@ class NotificationApi { /// call this method /// Future initialize() async { - final initializationSettingsAndroid = const AndroidInitializationSettings( + const initializationSettingsAndroid = AndroidInitializationSettings( 'outline_event_note_24', ); @@ -39,7 +39,7 @@ class NotificationApi { /// Show a notification with the given title and message /// Future showNotification(String title, String? message, [int? id]) async { - final androidPlatformChannelSpecifics = const AndroidNotificationDetails( + const androidPlatformChannelSpecifics = AndroidNotificationDetails( 'Notifications', 'Notifications', channelDescription: 'This is the main notification channel', @@ -52,9 +52,9 @@ class NotificationApi { ticker: 'ticker', ); - final iOSPlatformChannelSpecifics = const IOSNotificationDetails(); + const iOSPlatformChannelSpecifics = IOSNotificationDetails(); - final platformChannelSpecifics = NotificationDetails( + const platformChannelSpecifics = NotificationDetails( android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics, ); diff --git a/lib/common/ui/widgets/error_display.dart b/lib/common/ui/widgets/error_display.dart index 6be52a66..306b0926 100644 --- a/lib/common/ui/widgets/error_display.dart +++ b/lib/common/ui/widgets/error_display.dart @@ -13,6 +13,7 @@ class ErrorDisplay extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ AnimatedSwitcher( + duration: const Duration(milliseconds: 300), child: show ? Padding( padding: const EdgeInsets.all(0), @@ -34,7 +35,6 @@ class ErrorDisplay extends StatelessWidget { : Container( width: double.infinity, ), - duration: const Duration(milliseconds: 300), ), ], ); diff --git a/lib/common/util/cancelable_mutex.dart b/lib/common/util/cancelable_mutex.dart index 3160b39c..cf53898a 100644 --- a/lib/common/util/cancelable_mutex.dart +++ b/lib/common/util/cancelable_mutex.dart @@ -1,5 +1,5 @@ +import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; import 'package:mutex/mutex.dart'; -import 'cancellation_token.dart'; class CancelableMutex { final Mutex _mutex = Mutex(); diff --git a/lib/date_management/data/calendar_access.dart b/lib/date_management/data/calendar_access.dart index 3a269165..bd25b3d3 100644 --- a/lib/date_management/data/calendar_access.dart +++ b/lib/date_management/data/calendar_access.dart @@ -83,7 +83,7 @@ class CalendarAccess { calendar.id, location: entry.room, title: entry.description, - description: "${entry.comment}", + description: entry.comment, eventId: id, allDay: isAllDay, start: tz.TZDateTime.from(start, tz.getLocation('Europe/Berlin')), @@ -93,9 +93,9 @@ class CalendarAccess { String? _getIdOfExistingEvent(List existingEvents, DateEntry entry) { final existingEvent = existingEvents - .where((element) => (element.title == entry.description && + .where((element) => element.title == entry.description && (element.start?.toUtc().isAtSameMomentAs(entry.start.toUtc()) ?? - false)),) + false),) .toList(); String? id; diff --git a/lib/date_management/data/date_entry_entity.dart b/lib/date_management/data/date_entry_entity.dart index cc5a2af7..26ff8414 100644 --- a/lib/date_management/data/date_entry_entity.dart +++ b/lib/date_management/data/date_entry_entity.dart @@ -11,6 +11,7 @@ class DateEntryEntity extends DatabaseEntity { fromMap(map); } + @override void fromMap(Map map) { final date = DateTime.fromMillisecondsSinceEpoch(map["date"]); diff --git a/lib/date_management/model/date_entry.dart b/lib/date_management/model/date_entry.dart index 17e4ce98..3a146e56 100644 --- a/lib/date_management/model/date_entry.dart +++ b/lib/date_management/model/date_entry.dart @@ -15,10 +15,10 @@ class DateEntry { DateTime? start, DateTime? end, this.room, - }) : this.start = start ?? DateTime.fromMicrosecondsSinceEpoch(0), - this.end = end ?? DateTime.fromMicrosecondsSinceEpoch(0), - this.comment = comment ?? "", - this.description = description ?? "", - this.year = year ?? "", - this.databaseName = databaseName ?? ""; + }) : start = start ?? DateTime.fromMicrosecondsSinceEpoch(0), + end = end ?? DateTime.fromMicrosecondsSinceEpoch(0), + comment = comment ?? "", + description = description ?? "", + year = year ?? "", + databaseName = databaseName ?? ""; } diff --git a/lib/date_management/service/parsing/all_dates_extract.dart b/lib/date_management/service/parsing/all_dates_extract.dart index 1d1bdfe7..ca538104 100644 --- a/lib/date_management/service/parsing/all_dates_extract.dart +++ b/lib/date_management/service/parsing/all_dates_extract.dart @@ -16,7 +16,7 @@ class AllDatesExtract { } List _extractAllDates(String body, String? databaseName) { - body = body.replaceAll(new RegExp("<(br|BR)[ /]*>"), "\n"); + body = body.replaceAll(RegExp("<(br|BR)[ /]*>"), "\n"); final document = parse(body); // The dates are located in the first

element of the page @@ -70,7 +70,7 @@ class AllDatesExtract { time = "00:00"; } - final dateAndTimeString = date + " " + time; + final dateAndTimeString = "$date $time"; try { final date = DateFormat("dd.MM.yyyy hh:mm").parse(dateAndTimeString); diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index f3e426ae..59eb5877 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -195,9 +195,9 @@ class _CalendarExportPageState extends State { ) : Container( decoration: !viewModel.canExport - ? new BoxDecoration( + ? BoxDecoration( color: Theme.of(context).colorScheme.background,) - : new BoxDecoration( + : BoxDecoration( color: Theme.of(context).colorScheme.primary, ), child: Padding( diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index e6e2dfe0..3ce0f407 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -62,8 +62,8 @@ class DateManagementPage extends StatelessWidget { ), ), Align( - child: buildErrorDisplay(context), alignment: Alignment.bottomCenter, + child: buildErrorDisplay(context), ), ], ), @@ -120,9 +120,7 @@ class DateManagementPage extends StatelessWidget { ), // When the date entry has a time of 00:00 don't show it. // It means the date entry is for the whole day - isAtMidnight(dateEntry.start) - ? Container() - : Padding( + if (isAtMidnight(dateEntry.start)) Container() else Padding( padding: const EdgeInsets.fromLTRB(0, 4, 0, 0), child: Text( DateFormat.Hm(L.of(context).locale.languageCode) diff --git a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart index c372549e..74bb61e9 100644 --- a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart +++ b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart @@ -42,14 +42,14 @@ class CalendarExportViewModel extends BaseViewModel { notifyListeners("_calendars"); } - void loadSelectedCalendar() async { + Future loadSelectedCalendar() async { _selectedCalendar = await preferencesProvider.getSelectedCalendar(); notifyListeners("selectedCalendar"); } - void resetSelectedCalendar() async { + Future resetSelectedCalendar() async { await preferencesProvider.setSelectedCalendar(null); - this.loadCalendars(); + loadCalendars(); } void toggleSelection(Calendar calendar) { diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index e1441c32..6f8f9bd5 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -3,12 +3,10 @@ import 'dart:async'; import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; import 'package:dhbwstudentapp/common/util/cancelable_mutex.dart'; -import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; import 'package:dhbwstudentapp/date_management/business/date_entry_provider.dart'; import 'package:dhbwstudentapp/date_management/model/date_database.dart'; import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; import 'package:dhbwstudentapp/date_management/model/date_search_parameters.dart'; -import 'package:dhbwstudentapp/schedule/service/schedule_source.dart'; class DateManagementViewModel extends BaseViewModel { final DateEntryProvider _dateEntryProvider; @@ -123,8 +121,7 @@ class DateManagementViewModel extends BaseViewModel { _updateMutex.token, ); return loadedDateEntries; - } on OperationCancelledException { - } on ServiceRequestFailed {} + } return null; } @@ -173,7 +170,7 @@ class DateManagementViewModel extends BaseViewModel { _preferencesProvider.setLastViewedDateEntryYear(year); } - void _loadDefaultSelection() async { + Future _loadDefaultSelection() async { final database = await _preferencesProvider.getLastViewedDateEntryDatabase(); bool didSetDatabase = false; @@ -194,7 +191,7 @@ class DateManagementViewModel extends BaseViewModel { await updateDates(); } - void _cancelErrorInFuture() async { + Future _cancelErrorInFuture() async { _errorResetTimer?.cancel(); _errorResetTimer = Timer( diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index 2593be92..36813cce 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -17,7 +17,7 @@ class DateDetailBottomSheet extends StatelessWidget { final time = DateFormat.Hm(L.of(context).locale.languageCode) .format(dateEntry!.start); - return Container( + return SizedBox( height: 400, child: Padding( padding: const EdgeInsets.fromLTRB(24, 12, 24, 24), @@ -58,9 +58,7 @@ class DateDetailBottomSheet extends StatelessWidget { softWrap: true, style: Theme.of(context).textTheme.subtitle2, ), - isAtMidnight(dateEntry!.start) - ? Container() - : Text( + if (isAtMidnight(dateEntry!.start)) Container() else Text( time, softWrap: true, ), diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index e0f58d2b..c2b38a55 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -205,8 +205,8 @@ class _DateFilterOptionsState extends State { for (final year in widget.viewModel.years) { yearMenuItems.add(DropdownMenuItem( - child: Text(year), value: year, + child: Text(year), ),); } return yearMenuItems; @@ -217,8 +217,8 @@ class _DateFilterOptionsState extends State { for (final database in widget.viewModel.allDateDatabases) { databaseMenuItems.add(DropdownMenuItem( - child: Text(database.displayName), value: database, + child: Text(database.displayName), ),); } return databaseMenuItems; diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index 0bf541e5..217cd4b6 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -97,7 +97,7 @@ class DualisAuthentication { Credentials credentials, [ CancellationToken? cancellationToken, ]) async { - final loginUrl = dualisEndpoint + "/scripts/mgrqispi.dll"; + const loginUrl = "$dualisEndpoint/scripts/mgrqispi.dll"; final data = { "usrname": credentials.username, diff --git a/lib/dualis/service/dualis_scraper.dart b/lib/dualis/service/dualis_scraper.dart index 224ecd52..0a1e6927 100644 --- a/lib/dualis/service/dualis_scraper.dart +++ b/lib/dualis/service/dualis_scraper.dart @@ -3,11 +3,11 @@ import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:dhbwstudentapp/dualis/model/study_grades.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_authentication.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_service.dart'; -import 'package:dhbwstudentapp/dualis/service/parsing/monthly_schedule_extract.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_website_model.dart'; import 'package:dhbwstudentapp/dualis/service/parsing/all_modules_extract.dart'; import 'package:dhbwstudentapp/dualis/service/parsing/exams_from_module_details_extract.dart'; import 'package:dhbwstudentapp/dualis/service/parsing/modules_from_course_result_page_extract.dart'; +import 'package:dhbwstudentapp/dualis/service/parsing/monthly_schedule_extract.dart'; import 'package:dhbwstudentapp/dualis/service/parsing/semesters_from_course_result_page_extract.dart'; import 'package:dhbwstudentapp/dualis/service/parsing/study_grades_from_student_results_page_extract.dart'; import 'package:dhbwstudentapp/schedule/model/schedule.dart'; diff --git a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart index e2a82417..49f4df2a 100644 --- a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart @@ -67,7 +67,7 @@ class SemestersFromCourseResultPageExtract { final sessionNo = matches[2].group(1); final menuId = matches[3].group(1); - var url = endpointUrl + "/scripts/mgrqispi.dll"; + var url = "$endpointUrl/scripts/mgrqispi.dll"; url += "?APPNAME=$applicationName"; url += "&PRGNAME=$programName"; url += "&ARGUMENTS=-N$sessionNo,-N$menuId,-N"; diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index 5fdd7090..5c90dc37 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -39,7 +39,7 @@ class Session { String url, [ CancellationToken? cancellationToken, ]) async { - if (cancellationToken == null) cancellationToken = CancellationToken(); + cancellationToken ??= CancellationToken(); final requestCancellationToken = http.CancellationToken(); @@ -100,7 +100,7 @@ class Session { Map data, [ CancellationToken? cancellationToken, ]) async { - if (cancellationToken == null) cancellationToken = CancellationToken(); + cancellationToken ??= CancellationToken(); final requestCancellationToken = http.CancellationToken(); try { diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index 39545a7b..98af8de0 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -8,7 +8,7 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class ExamResultsPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( + return SizedBox( height: double.infinity, child: SingleChildScrollView( child: Column( @@ -44,8 +44,8 @@ class ExamResultsPage extends StatelessWidget { items: model?.allSemesterNames ?.map( (n) => DropdownMenuItem( - child: Text(n), value: n, + child: Text(n), ), ) .toList(), @@ -84,15 +84,15 @@ class ExamResultsPage extends StatelessWidget { children = children.toList()..add(currentChild); } return Stack( - children: children, alignment: Alignment.topCenter, + children: children, ); }, + duration: const Duration(milliseconds: 200), child: Column( key: ValueKey("semester_${viewModel.currentSemester?.name}"), children: buildModulesDataTables(context, viewModel), ), - duration: const Duration(milliseconds: 200), ); } @@ -184,7 +184,7 @@ class ExamResultsPage extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(0, 0, 10, 16), child: Text( - (module.name ?? ""), + module.name ?? "", style: Theme.of(context).textTheme.subtitle2, softWrap: true, ), diff --git a/lib/dualis/ui/study_overview/study_overview_page.dart b/lib/dualis/ui/study_overview/study_overview_page.dart index 80addc71..679aa187 100644 --- a/lib/dualis/ui/study_overview/study_overview_page.dart +++ b/lib/dualis/ui/study_overview/study_overview_page.dart @@ -7,7 +7,7 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class StudyOverviewPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( + return SizedBox( height: double.infinity, child: SingleChildScrollView( child: Column( diff --git a/lib/dualis/ui/widgets/login_form_widget.dart b/lib/dualis/ui/widgets/login_form_widget.dart index 65b9a613..0beb44a7 100644 --- a/lib/dualis/ui/widgets/login_form_widget.dart +++ b/lib/dualis/ui/widgets/login_form_widget.dart @@ -112,7 +112,7 @@ class _LoginFormState extends State { value: _storeCredentials, ), ), - Container( + SizedBox( height: 80, child: Align( alignment: Alignment.topRight, diff --git a/lib/main.dart b/lib/main.dart index d64dc6a8..8f674049 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,15 +1,14 @@ import 'dart:io'; -import 'package:dhbwstudentapp/ui/root_page.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:dhbwstudentapp/common/appstart/app_initializer.dart'; import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/root_view_model.dart'; -import 'package:kiwi/kiwi.dart'; +import 'package:dhbwstudentapp/common/util/platform_util.dart'; +import 'package:dhbwstudentapp/ui/root_page.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/material.dart'; - -import 'common/util/platform_util.dart'; +import 'package:kiwi/kiwi.dart'; /// /// Main entry point for the app diff --git a/lib/native/widget/android_widget_helper.dart b/lib/native/widget/android_widget_helper.dart index a193aac1..f49b4ca5 100644 --- a/lib/native/widget/android_widget_helper.dart +++ b/lib/native/widget/android_widget_helper.dart @@ -6,7 +6,7 @@ import 'package:flutter/services.dart'; /// class AndroidWidgetHelper implements WidgetHelper { static const platform = - const MethodChannel('de.bennik2000.dhbwstudentapp/widget'); + MethodChannel('de.bennik2000.dhbwstudentapp/widget'); @override Future disableWidget() async { diff --git a/lib/native/widget/ios_widget_helper.dart b/lib/native/widget/ios_widget_helper.dart index 0aa61fb8..e12386e0 100644 --- a/lib/native/widget/ios_widget_helper.dart +++ b/lib/native/widget/ios_widget_helper.dart @@ -7,7 +7,7 @@ import 'package:flutter_widgetkit/flutter_widgetkit.dart'; /// class IOSWidgetHelper implements WidgetHelper { static const platform = - const MethodChannel('de.bennik2000.dhbwstudentapp/widget'); + MethodChannel('de.bennik2000.dhbwstudentapp/widget'); @override Future disableWidget() async { diff --git a/lib/schedule/background/calendar_synchronizer.dart b/lib/schedule/background/calendar_synchronizer.dart index bfaab7dd..3573f4ca 100644 --- a/lib/schedule/background/calendar_synchronizer.dart +++ b/lib/schedule/background/calendar_synchronizer.dart @@ -18,8 +18,7 @@ class CalendarSynchronizer { void registerSynchronizationCallback() { scheduleProvider.addScheduleUpdatedCallback((schedule, start, end) async { final List listDateEntries = List.empty(growable: true); - schedule.entries.forEach( - (element) { + for (final element in schedule.entries) { final DateEntry date = DateEntry( room: element.room, comment: element.details, @@ -29,8 +28,7 @@ class CalendarSynchronizer { start: element.start, end: element.end,); listDateEntries.add(date); - }, - ); + } KiwiContainer().resolve().listDateEntries = listDateEntries; diff --git a/lib/schedule/business/schedule_source_provider.dart b/lib/schedule/business/schedule_source_provider.dart index ab67f74c..3aa34b37 100644 --- a/lib/schedule/business/schedule_source_provider.dart +++ b/lib/schedule/business/schedule_source_provider.dart @@ -62,9 +62,9 @@ class ScheduleSourceProvider { final success = didSetupCorrectly(); - _onDidChangeScheduleSourceCallbacks.forEach((element) { + for (final element in _onDidChangeScheduleSourceCallbacks) { element(scheduleSource, success); - }); + } return success; } @@ -188,7 +188,7 @@ class ScheduleSourceProvider { } bool didSetupCorrectly() { - return !(_currentScheduleSource is InvalidScheduleSource); + return _currentScheduleSource is! InvalidScheduleSource; } void addDidChangeScheduleSourceCallback(OnDidChangeScheduleSource callback) { @@ -204,8 +204,8 @@ class ScheduleSourceProvider { } void fireScheduleSourceChanged() { - _onDidChangeScheduleSourceCallbacks.forEach((element) { + for (final element in _onDidChangeScheduleSourceCallbacks) { element(currentScheduleSource, true); - }); + } } } diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index 69d5f4eb..877b6ad1 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -25,21 +25,21 @@ class ScheduleEntry { String? professor, String? room, required this.type, - }) : this.start = start ?? DateTime.fromMicrosecondsSinceEpoch(0), - this.end = end ?? DateTime.fromMicrosecondsSinceEpoch(0), - this.details = details ?? "", - this.professor = professor ?? "", - this.room = room ?? "", - this.title = title ?? ""; + }) : start = start ?? DateTime.fromMicrosecondsSinceEpoch(0), + end = end ?? DateTime.fromMicrosecondsSinceEpoch(0), + details = details ?? "", + professor = professor ?? "", + room = room ?? "", + title = title ?? ""; bool equalsWithIdIgnored(ScheduleEntry other) { - return this.start == other.start && - this.end == other.end && - this.title == other.title && - this.details == other.details && - this.professor == other.professor && - this.room == other.room && - this.type == other.type; + return start == other.start && + end == other.end && + title == other.title && + details == other.details && + professor == other.professor && + room == other.room && + type == other.type; } List getDifferentProperties(ScheduleEntry entry) { diff --git a/lib/schedule/model/schedule_query_information.dart b/lib/schedule/model/schedule_query_information.dart index b9e124b8..f2d5091c 100644 --- a/lib/schedule/model/schedule_query_information.dart +++ b/lib/schedule/model/schedule_query_information.dart @@ -7,6 +7,6 @@ class ScheduleQueryInformation { DateTime? start, DateTime? end, this.queryTime, - ) : this.start = start ?? DateTime.fromMillisecondsSinceEpoch(0), - this.end = end ?? DateTime.fromMillisecondsSinceEpoch(0); + ) : start = start ?? DateTime.fromMillisecondsSinceEpoch(0), + end = end ?? DateTime.fromMillisecondsSinceEpoch(0); } diff --git a/lib/schedule/service/dualis/dualis_schedule_source.dart b/lib/schedule/service/dualis/dualis_schedule_source.dart index fd08e80d..b8738a7d 100644 --- a/lib/schedule/service/dualis/dualis_schedule_source.dart +++ b/lib/schedule/service/dualis/dualis_schedule_source.dart @@ -15,7 +15,7 @@ class DualisScheduleSource extends ScheduleSource { @override Future querySchedule(DateTime? from, DateTime? to, [CancellationToken? cancellationToken,]) async { - if (cancellationToken == null) cancellationToken = CancellationToken(); + cancellationToken ??= CancellationToken(); DateTime current = toStartOfMonth(from)!; diff --git a/lib/schedule/service/isolate_schedule_source_decorator.dart b/lib/schedule/service/isolate_schedule_source_decorator.dart index f4c833a1..a5f29d32 100644 --- a/lib/schedule/service/isolate_schedule_source_decorator.dart +++ b/lib/schedule/service/isolate_schedule_source_decorator.dart @@ -42,7 +42,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { final subscription = _isolateToMain!.listen((result) { cancellationToken.setCancellationCallback(null); - if (result != null && !(result is ScheduleQueryResult)) { + if (result != null && result is! ScheduleQueryResult) { potentialException = ScheduleQueryFailedException(result); completer.complete(null); } else { @@ -79,7 +79,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { } } -void scheduleSourceIsolateEntryPoint(SendPort sendPort) async { +Future scheduleSourceIsolateEntryPoint(SendPort sendPort) async { // Using the given send port, send back a send port for two way communication final port = ReceivePort(); sendPort.send(port.sendPort); diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index 2eecc7d8..42e1c199 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -17,7 +17,7 @@ class MannheimCourseScraper { Future> loadCourses([ CancellationToken? cancellationToken, ]) async { - if (cancellationToken == null) cancellationToken = CancellationToken(); + cancellationToken ??= CancellationToken(); final coursesPage = await _makeRequest( Uri.parse("https://vorlesungsplan.dhbw-mannheim.de/ical.php"), diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index 316ba5c8..2b911246 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -133,7 +133,7 @@ class RaplaParsingUtils { if (descriptionParts.length == 1) { title = descriptionParts[0]; - } else if (descriptionParts.length > 0) { + } else if (descriptionParts.isNotEmpty) { title = descriptionParts[1]; details = descriptionParts.join("\n"); } diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index dc21be72..4a848ebe 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -24,7 +24,7 @@ class RaplaScheduleSource extends ScheduleSource { [CancellationToken? cancellationToken,]) async { DateTime current = toDayOfWeek(from, DateTime.monday)!; - if (cancellationToken == null) cancellationToken = CancellationToken(); + cancellationToken ??= CancellationToken(); var schedule = Schedule(); final allErrors = []; diff --git a/lib/schedule/service/schedule_prettifier.dart b/lib/schedule/service/schedule_prettifier.dart index a6eb944c..37cad3ed 100644 --- a/lib/schedule/service/schedule_prettifier.dart +++ b/lib/schedule/service/schedule_prettifier.dart @@ -37,7 +37,7 @@ class SchedulePrettifier { return entry; } - final type = ScheduleEntryType.Online; + const type = ScheduleEntryType.Online; return entry.copyWith(title: newTitle, type: type); } @@ -47,11 +47,11 @@ class SchedulePrettifier { var details = entry.details; final titleRegex = - RegExp("[A-Z]{3,}-?[A-Z]+[0-9]*[A-Z]*[0-9]*[\/]?[A-Z]*[0-9]*[ ]*-?"); + RegExp("[A-Z]{3,}-?[A-Z]+[0-9]*[A-Z]*[0-9]*[/]?[A-Z]*[0-9]*[ ]*-?"); final match = titleRegex.firstMatch(entry.title); if (match != null && match.start == 0) { - details = title.substring(0, match.end) + " - $details"; + details = "${title.substring(0, match.end)} - $details"; title = title.substring(match.end).trim(); } else { final first = title.split(" ").first; @@ -62,12 +62,12 @@ class SchedulePrettifier { // or less than 2 charcters long if (!(first == first.toUpperCase() && first.length >= 3)) return entry; - final numberCount = first.split(new RegExp("[0-9]")).length; + final numberCount = first.split(RegExp("[0-9]")).length; // If there are less thant two numbers in the title, do not prettify it if (numberCount < 2) return entry; - details = title.substring(0, first.length) + " - $details"; + details = "${title.substring(0, first.length)} - $details"; title = title.substring(first.length).trim(); } diff --git a/lib/schedule/service/schedule_source.dart b/lib/schedule/service/schedule_source.dart index 4785b8eb..25694b1b 100644 --- a/lib/schedule/service/schedule_source.dart +++ b/lib/schedule/service/schedule_source.dart @@ -23,7 +23,7 @@ class ScheduleQueryFailedException implements Exception { @override String toString() { - return innerException.toString() + "\n" + (trace?.toString() ?? ""); + return "${innerException.toString()}\n${trace?.toString() ?? ""}"; } } diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index 727cac15..d42c5d42 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -44,8 +44,7 @@ class _DailySchedulePageState extends State { }, ), ), - viewModel.daySchedule.entries.isEmpty - ? Padding( + if (viewModel.daySchedule.entries.isEmpty) Padding( padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: Column( children: [ @@ -69,14 +68,13 @@ class _DailySchedulePageState extends State { Padding( padding: const EdgeInsets.fromLTRB(32, 64, 32, 32), child: Opacity( - child: Image.asset("assets/empty_state.png"), opacity: 0.9, + child: Image.asset("assets/empty_state.png"), ), ) ], ), - ) - : Column( + ) else Column( children: buildEntryWidgets(), ) ], diff --git a/lib/schedule/ui/notification/next_day_information_notification.dart b/lib/schedule/ui/notification/next_day_information_notification.dart index 81629d95..349e6e5a 100644 --- a/lib/schedule/ui/notification/next_day_information_notification.dart +++ b/lib/schedule/ui/notification/next_day_information_notification.dart @@ -89,7 +89,7 @@ class NextDayInformationNotification extends TaskCallback { final nextSchedule = toTimeOfDayInFuture(DateTime.now(), 20, 00); await _scheduler.scheduleOneShotTaskAt( nextSchedule, - "NextDayInformationNotification" + DateFormat.yMd().format(nextSchedule), + "NextDayInformationNotification${DateFormat.yMd().format(nextSchedule)}", "NextDayInformationNotification", ); } @@ -98,7 +98,7 @@ class NextDayInformationNotification extends TaskCallback { Future cancel() async { final nextSchedule = toTimeOfDayInFuture(DateTime.now(), 20, 00); await _scheduler.cancelTask( - "NextDayInformationNotification" + DateFormat.yMd().format(nextSchedule), + "NextDayInformationNotification${DateFormat.yMd().format(nextSchedule)}", ); } diff --git a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart index cb183ce6..43da4f28 100644 --- a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart @@ -215,8 +215,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { end, token, ); - } on OperationCancelledException { - } on ScheduleQueryFailedException {} + } return null; } diff --git a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart index 4d06a1cb..4057c3b2 100644 --- a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart +++ b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart @@ -15,7 +15,7 @@ class FilterViewModel extends BaseViewModel { loadFilterStates(); } - void loadFilterStates() async { + Future loadFilterStates() async { final allNames = await _scheduleEntryRepository.queryAllNamesOfScheduleEntries(); @@ -31,7 +31,7 @@ class FilterViewModel extends BaseViewModel { notifyListeners(); } - void applyFilter() async { + Future applyFilter() async { final allFilteredNames = filterStates .where((element) => !element.isDisplayed!) .map((e) => e.entryName) diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index c1178307..37209097 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -22,7 +22,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { final typeString = scheduleEntryTypeToReadableString(context, scheduleEntry!.type); - return Container( + return SizedBox( height: 400, child: Padding( padding: const EdgeInsets.fromLTRB(24, 12, 24, 24), @@ -113,24 +113,18 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { ], ), ), - scheduleEntry!.room.isEmpty - ? Container() - : Padding( + if (scheduleEntry!.room.isEmpty) Container() else Padding( padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), child: Text(scheduleEntry!.room.replaceAll(",", "\n")), ), - scheduleEntry!.details.isEmpty - ? Container() - : Padding( + if (scheduleEntry!.details.isEmpty) Container() else Padding( padding: const EdgeInsets.fromLTRB(0, 16, 0, 16), child: Container( color: colorSeparator(), height: 1, ), ), - scheduleEntry!.details.isEmpty - ? Container() - : Text(scheduleEntry!.details), + if (scheduleEntry!.details.isEmpty) Container() else Text(scheduleEntry!.details), ], ), ), diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index 57942a27..27be2db3 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -51,15 +51,15 @@ class _WeeklySchedulePageState extends State { ); } - void _previousWeek() async { + Future _previousWeek() async { await viewModel.previousWeek(); } - void _nextWeek() async { + Future _nextWeek() async { await viewModel.nextWeek(); } - void _goToToday() async { + Future _goToToday() async { await viewModel.goToToday(); } @@ -117,11 +117,11 @@ class _WeeklySchedulePageState extends State { Animation animation, Animation secondaryAnimation,) => SharedAxisTransition( - child: child, animation: animation, secondaryAnimation: secondaryAnimation, transitionType: SharedAxisTransitionType.horizontal, + child: child, ), child: ScheduleWidget( key: ValueKey( diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 6ea5b266..480a506a 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -44,8 +44,8 @@ class ScheduleWidget extends StatelessWidget { } Widget buildWithSize(BuildContext context, double width, double height) { - final dayLabelsHeight = 40.0; - final timeLabelsWidth = 50.0; + const dayLabelsHeight = 40.0; + const timeLabelsWidth = 50.0; final hourHeight = (height - dayLabelsHeight) / (displayEndHour! - displayStartHour!); @@ -86,7 +86,7 @@ class ScheduleWidget extends StatelessWidget { colorScheduleGridGridLines(context), ), Padding( - padding: EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), + padding: const EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), child: Stack( children: entryWidgets, ), @@ -95,7 +95,7 @@ class ScheduleWidget extends StatelessWidget { children: labelWidgets, ), Padding( - padding: EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), + padding: const EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), child: SchedulePastOverlay( displayStartHour, displayEndHour, @@ -136,7 +136,7 @@ class ScheduleWidget extends StatelessWidget { final labelWidgets = []; for (var i = displayStartHour!; i < displayEndHour!; i++) { - final hourLabelText = i.toString() + ":00"; + final hourLabelText = "$i:00"; labelWidgets.add( Positioned( diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index 2f38dbc4..1d440d93 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -106,7 +106,6 @@ abstract class EnterUrlDialog { builder: (BuildContext context, ValueNotifier hasUrlError, Widget? child,) => TextButton( - child: Text(L.of(context).dialogOk.toUpperCase()), onPressed: hasUrlError.value ? null : () async { @@ -114,6 +113,7 @@ abstract class EnterUrlDialog { await saveUrl(_url.value); }, + child: Text(L.of(context).dialogOk.toUpperCase()), ), ), ), diff --git a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart index be20b53b..c9120790 100644 --- a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart +++ b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart @@ -30,7 +30,7 @@ class SelectMannheimCourseDialog { contentPadding: const EdgeInsets.all(0), content: PropertyChangeProvider( value: _mannheimViewModel, - child: Container( + child: SizedBox( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, child: Column( diff --git a/lib/ui/banner_widget.dart b/lib/ui/banner_widget.dart index 26f1bc47..1e19f31e 100644 --- a/lib/ui/banner_widget.dart +++ b/lib/ui/banner_widget.dart @@ -38,8 +38,8 @@ class BannerWidget extends StatelessWidget { Padding( padding: const EdgeInsets.fromLTRB(0, 12, 0, 0), child: TextButton( - child: Text(buttonText), onPressed: onButtonTap, + child: Text(buttonText), ), ), ], diff --git a/lib/ui/main_page.dart b/lib/ui/main_page.dart index f158ee82..c57202b1 100644 --- a/lib/ui/main_page.dart +++ b/lib/ui/main_page.dart @@ -124,8 +124,8 @@ class _MainPageState extends State with NavigatorObserver { width: 1, ), Expanded( - child: navigator, flex: 3, + child: navigator, ), ], ), diff --git a/lib/ui/navigation/router.dart b/lib/ui/navigation/router.dart index 633a61a1..5f616524 100644 --- a/lib/ui/navigation/router.dart +++ b/lib/ui/navigation/router.dart @@ -28,7 +28,7 @@ Route generateDrawerRoute(RouteSettings settings) { } if (widget == null) { - print("Failed to navigate to: " + settings.name!); + print("Failed to navigate to: ${settings.name!}"); widget = (BuildContext context) => Container(); } @@ -38,7 +38,7 @@ Route generateDrawerRoute(RouteSettings settings) { pageBuilder: (context, animation, secondaryAnimation) => widget!(context), transitionsBuilder: (context, animation, secondaryAnimation, child) { const offsetBegin = Offset(0.0, 0.005); - final offsetEnd = Offset.zero; + const offsetEnd = Offset.zero; final offsetTween = Tween(begin: offsetBegin, end: offsetEnd) .chain(CurveTween(curve: Curves.fastOutSlowIn)); @@ -52,8 +52,8 @@ Route generateDrawerRoute(RouteSettings settings) { child: FadeTransition( opacity: animation.drive(opacityTween), child: Container( - child: child, color: Theme.of(context).scaffoldBackgroundColor, + child: child, ), ), ); @@ -76,7 +76,7 @@ Route generateRoute(RouteSettings settings) { target = const SettingsPage(); break; default: - print("Failed to navigate to: " + settings.name!); + print("Failed to navigate to: ${settings.name!}"); target = Container(); } diff --git a/lib/ui/navigation_drawer.dart b/lib/ui/navigation_drawer.dart index a48f8e46..2ea6680b 100644 --- a/lib/ui/navigation_drawer.dart +++ b/lib/ui/navigation_drawer.dart @@ -94,7 +94,7 @@ class NavigationDrawer extends StatelessWidget { borderRadius: BorderRadius.circular(8), ), child: InkWell( - child: Container( + child: SizedBox( height: 48, child: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 0, 0), diff --git a/lib/ui/onboarding/onboardin_step.dart b/lib/ui/onboarding/onboardin_step.dart index 0f7221fd..5d8c03f9 100644 --- a/lib/ui/onboarding/onboardin_step.dart +++ b/lib/ui/onboarding/onboardin_step.dart @@ -1,8 +1,8 @@ import 'package:dhbwstudentapp/ui/onboarding/viewmodels/dualis_login_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/ical_url_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/mannheim_view_model.dart'; -import 'package:dhbwstudentapp/ui/onboarding/viewmodels/rapla_url_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/onboarding_view_model_base.dart'; +import 'package:dhbwstudentapp/ui/onboarding/viewmodels/rapla_url_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/select_source_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/widgets/dualis_login_page.dart'; import 'package:dhbwstudentapp/ui/onboarding/widgets/ical_url_page.dart'; diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index cf5a5044..fe898934 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -121,10 +121,10 @@ class _OnboardingPageState extends State Animation secondaryAnimation, ) => SharedAxisTransition( - child: child, animation: animation, secondaryAnimation: secondaryAnimation, transitionType: SharedAxisTransitionType.horizontal, + child: child, ), child: body, ), diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart index 5ccf7757..6892320e 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart @@ -35,7 +35,7 @@ class OnboardingViewModel extends BaseViewModel { bool get currentPageValid => pages[currentStep]!.viewModel().isValid; bool get isLastStep => _stepIndex >= steps.length - 1; - get onboardingSteps => steps.length; + int get onboardingSteps => steps.length; bool _didStepForward = true; bool get didStepForward => _didStepForward; @@ -55,7 +55,7 @@ class OnboardingViewModel extends BaseViewModel { } void previousPage() { - if (stepsBackstack.length == 0) { + if (stepsBackstack.isEmpty) { return; } @@ -81,9 +81,7 @@ class OnboardingViewModel extends BaseViewModel { stepsBackstack[currentStep] = _stepIndex; - if (nextDesiredStep == null) { - nextDesiredStep = steps[_stepIndex + 1]; - } + nextDesiredStep ??= steps[_stepIndex + 1]; while (nextDesiredStep != currentStep) { _stepIndex++; diff --git a/lib/ui/onboarding/widgets/dualis_login_page.dart b/lib/ui/onboarding/widgets/dualis_login_page.dart index 8b6e6e48..4944c673 100644 --- a/lib/ui/onboarding/widgets/dualis_login_page.dart +++ b/lib/ui/onboarding/widgets/dualis_login_page.dart @@ -74,15 +74,13 @@ class _DualisLoginCredentialsPageState ) : Container(), ), - viewModel?.isLoading ?? false - ? const SizedBox( + if (viewModel?.isLoading ?? false) const SizedBox( width: 16, height: 16, child: CircularProgressIndicator( strokeWidth: 1, ), - ) - : viewModel?.loginSuccess ?? false + ) else viewModel?.loginSuccess ?? false ? const Icon( Icons.check, color: Colors.green, diff --git a/lib/ui/onboarding/widgets/onboarding_page_background.dart b/lib/ui/onboarding/widgets/onboarding_page_background.dart index f37a41d1..9147294c 100644 --- a/lib/ui/onboarding/widgets/onboarding_page_background.dart +++ b/lib/ui/onboarding/widgets/onboarding_page_background.dart @@ -75,29 +75,28 @@ class OnboardingPageBackground extends StatelessWidget { return Stack( children: [ Transform.rotate( + angle: toRadian(angleTopForeground.value), child: Transform.translate( + offset: const Offset(20, -450), child: Container( width: 15000, height: 500, color: colorOnboardingDecorationForeground(context), ), - offset: const Offset(20, -450), ), - angle: toRadian(angleTopForeground.value), ), Transform.rotate( + angle: toRadian(angleTopBackground.value), child: Transform.translate( + offset: const Offset(20, -480), child: Container( width: 1500, height: 500, color: colorOnboardingDecorationBackground(context), ), - offset: const Offset(20, -480), ), - angle: toRadian(angleTopBackground.value), ), - PlatformUtil.isPhone() - ? Align( + if (PlatformUtil.isPhone()) Align( alignment: Alignment.bottomCenter, child: SizedBox( height: 90, @@ -112,10 +111,8 @@ class OnboardingPageBackground extends StatelessWidget { ), ), ), - ) - : Container(), - PlatformUtil.isPhone() - ? Align( + ) else Container(), + if (PlatformUtil.isPhone()) Align( alignment: Alignment.bottomCenter, child: SizedBox( height: 90, @@ -130,8 +127,7 @@ class OnboardingPageBackground extends StatelessWidget { ), ), ), - ) - : Container(), + ) else Container(), ], ); } diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index 88171428..6055e088 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -1,6 +1,6 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/ui/onboarding/viewmodels/rapla_url_view_model.dart'; import 'package:dhbwstudentapp/ui/onboarding/viewmodels/onboarding_view_model_base.dart'; +import 'package:dhbwstudentapp/ui/onboarding/viewmodels/rapla_url_view_model.dart'; import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; diff --git a/lib/ui/pager_widget.dart b/lib/ui/pager_widget.dart index 7c72224c..3c2286ed 100644 --- a/lib/ui/pager_widget.dart +++ b/lib/ui/pager_widget.dart @@ -120,8 +120,8 @@ class PageDefinition { if (viewModel == null) return builder(context); return ChangeNotifierProvider.value( - child: builder(context), value: viewModel, + child: builder(context), ); } } diff --git a/lib/ui/root_page.dart b/lib/ui/root_page.dart index cb6c2027..a7505f32 100644 --- a/lib/ui/root_page.dart +++ b/lib/ui/root_page.dart @@ -31,6 +31,7 @@ class _RootPageState extends State { @override Widget build(BuildContext context) { return PropertyChangeProvider( + value: widget.rootViewModel, child: PropertyChangeConsumer( properties: const ["appTheme", "isOnboarding"], builder: @@ -41,8 +42,8 @@ class _RootPageState extends State { widget.rootViewModel.isOnboarding ? "onboarding" : "main", navigatorKey: NavigatorKey.rootKey, navigatorObservers: [rootNavigationObserver], - localizationsDelegates: [ - const LocalizationDelegate(), + localizationsDelegates: const [ + LocalizationDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, @@ -55,7 +56,6 @@ class _RootPageState extends State { onGenerateRoute: generateRoute, ), ), - value: widget.rootViewModel, ); } } diff --git a/lib/ui/settings/donate_list_tile.dart b/lib/ui/settings/donate_list_tile.dart index 254cdc11..7b1fea9f 100644 --- a/lib/ui/settings/donate_list_tile.dart +++ b/lib/ui/settings/donate_list_tile.dart @@ -59,11 +59,11 @@ class _DonateListTileState extends State { padding: EdgeInsets.all(8.0), child: Center( child: SizedBox( + width: 16, + height: 16, child: CircularProgressIndicator( strokeWidth: 2, ), - width: 16, - height: 16, ), ), ); @@ -76,11 +76,11 @@ class _DonateListTileState extends State { child: Padding( padding: EdgeInsets.all(8.0), child: SizedBox( + width: 16, + height: 16, child: CircularProgressIndicator( strokeWidth: 2, ), - width: 16, - height: 16, ), ), ) @@ -93,7 +93,7 @@ class _DonateListTileState extends State { return Container(); } - void _purchaseClicked() async { + Future _purchaseClicked() async { if (isPurchasing || model.widgetPurchaseState == PurchaseStateEnum.Purchased) return; diff --git a/lib/ui/settings/purchase_widget_list_tile.dart b/lib/ui/settings/purchase_widget_list_tile.dart index df1d5693..691d9cdb 100644 --- a/lib/ui/settings/purchase_widget_list_tile.dart +++ b/lib/ui/settings/purchase_widget_list_tile.dart @@ -76,11 +76,11 @@ class _PurchaseWidgetListTileState extends State { child: Padding( padding: EdgeInsets.all(8.0), child: SizedBox( + width: 16, + height: 16, child: CircularProgressIndicator( strokeWidth: 2, ), - width: 16, - height: 16, ), ), ); @@ -107,7 +107,7 @@ class _PurchaseWidgetListTileState extends State { return null; } - void _purchaseClicked() async { + Future _purchaseClicked() async { if (isPurchasing || model.widgetPurchaseState == PurchaseStateEnum.Purchased) return; diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 527905c7..60c02697 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -13,9 +13,9 @@ import 'package:dhbwstudentapp/schedule/background/calendar_synchronizer.dart'; import 'package:dhbwstudentapp/schedule/ui/notification/next_day_information_notification.dart'; import 'package:dhbwstudentapp/schedule/ui/widgets/select_source_dialog.dart'; import 'package:dhbwstudentapp/ui/navigation/navigator_key.dart'; -import 'package:dhbwstudentapp/ui/settings/select_theme_dialog.dart'; import 'package:dhbwstudentapp/ui/settings/donate_list_tile.dart'; import 'package:dhbwstudentapp/ui/settings/purchase_widget_list_tile.dart'; +import 'package:dhbwstudentapp/ui/settings/select_theme_dialog.dart'; import 'package:dhbwstudentapp/ui/settings/viewmodels/settings_view_model.dart'; import 'package:flutter/material.dart'; import 'package:kiwi/kiwi.dart'; diff --git a/lib/ui/settings/viewmodels/settings_view_model.dart b/lib/ui/settings/viewmodels/settings_view_model.dart index 9377935d..98895818 100644 --- a/lib/ui/settings/viewmodels/settings_view_model.dart +++ b/lib/ui/settings/viewmodels/settings_view_model.dart @@ -2,13 +2,12 @@ import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart import 'package:dhbwstudentapp/common/iap/in_app_purchase_helper.dart'; import 'package:dhbwstudentapp/common/iap/in_app_purchase_manager.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; +import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; import 'package:dhbwstudentapp/native/widget/widget_helper.dart'; +import 'package:dhbwstudentapp/schedule/business/schedule_provider.dart'; import 'package:dhbwstudentapp/schedule/ui/notification/next_day_information_notification.dart'; import 'package:kiwi/kiwi.dart'; -import '../../../common/util/cancellation_token.dart'; -import '../../../schedule/business/schedule_provider.dart'; - /// /// The view model for the settings page. /// @@ -136,6 +135,7 @@ class SettingsViewModel extends BaseViewModel { await _inAppPurchaseManager.donate(); } + @override void dispose() { super.dispose(); diff --git a/test/common/util/string_utils_test.dart b/test/common/util/string_utils_test.dart index c566465f..cf32d9d2 100644 --- a/test/common/util/string_utils_test.dart +++ b/test/common/util/string_utils_test.dart @@ -3,7 +3,7 @@ import 'package:test/test.dart'; void main() { test('String interpolation', () async { - final format = "%0 %1!"; + const format = "%0 %1!"; final result = interpolate(format, ["Hello", "world"]); expect(result, "Hello world!"); diff --git a/test/date_management/service/parsing/all_dates_extract_test.dart b/test/date_management/service/parsing/all_dates_extract_test.dart index ac02e2e8..34b32e1d 100644 --- a/test/date_management/service/parsing/all_dates_extract_test.dart +++ b/test/date_management/service/parsing/all_dates_extract_test.dart @@ -4,8 +4,7 @@ import 'package:dhbwstudentapp/date_management/service/parsing/all_dates_extract import 'package:test/test.dart'; Future main() async { - final allDatesPage = await File(Directory.current.absolute.path + - '/test/date_management/service/parsing/html_resources/all_dates.html',) + final allDatesPage = await File('${Directory.current.absolute.path}/test/date_management/service/parsing/html_resources/all_dates.html',) .readAsString(); test('AllDatesExtract extract all dates', () async { diff --git a/test/dualis/service/parsing/all_modules_extract_test.dart b/test/dualis/service/parsing/all_modules_extract_test.dart index caaad15b..eef65992 100644 --- a/test/dualis/service/parsing/all_modules_extract_test.dart +++ b/test/dualis/service/parsing/all_modules_extract_test.dart @@ -6,8 +6,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - final studentResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/student_results.html',) + final studentResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/student_results.html',) .readAsString(); test('AllModulesExtract extract all modules', () async { diff --git a/test/dualis/service/parsing/dualis_timeout_extract_test.dart b/test/dualis/service/parsing/dualis_timeout_extract_test.dart index 60888b80..1203c50e 100644 --- a/test/dualis/service/parsing/dualis_timeout_extract_test.dart +++ b/test/dualis/service/parsing/dualis_timeout_extract_test.dart @@ -4,12 +4,10 @@ import 'package:dhbwstudentapp/dualis/service/parsing/timeout_extract.dart'; import 'package:test/test.dart'; Future main() async { - final monthlySchedulePage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/monthly_schedule.html',) + final monthlySchedulePage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/monthly_schedule.html',) .readAsString(); - final timeoutPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/dualis_timeout.html',) + final timeoutPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/dualis_timeout.html',) .readAsString(); test('DualisTimeoutExtract detect timeout page', () async { diff --git a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart index fd3fd2d1..7f0f6d72 100644 --- a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart +++ b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart @@ -5,8 +5,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - final moduleDetailsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/module_details.html',) + final moduleDetailsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/module_details.html',) .readAsString(); test('ExamsFromModuleDetailsExtract', () async { diff --git a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart index e30c9810..eddbdcde 100644 --- a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart @@ -5,8 +5,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - final courseResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/course_results.html',) + final courseResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/course_results.html',) .readAsString(); test('ModulesFromCourseResultPageExtract', () async { diff --git a/test/dualis/service/parsing/monthly_schedule_extract_test.dart b/test/dualis/service/parsing/monthly_schedule_extract_test.dart index 8cc68446..479ea917 100644 --- a/test/dualis/service/parsing/monthly_schedule_extract_test.dart +++ b/test/dualis/service/parsing/monthly_schedule_extract_test.dart @@ -4,8 +4,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/monthly_schedule_extract.d import 'package:test/test.dart'; Future main() async { - final monthlySchedulePage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/monthly_schedule.html',) + final monthlySchedulePage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/monthly_schedule.html',) .readAsString(); test('MonthlyScheduleExtract extract all appointments', () async { diff --git a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart index e2f550f8..7e932791 100644 --- a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart @@ -5,8 +5,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/semesters_from_course_resu import 'package:test/test.dart'; Future main() async { - final courseResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/course_results.html',) + final courseResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/course_results.html',) .readAsString(); test('SemestersFromCourseResultPageExtract', () async { diff --git a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart index e56fbd5a..cf23408d 100644 --- a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart +++ b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart @@ -5,8 +5,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/study_grades_from_student_ import 'package:test/test.dart'; Future main() async { - final studentResultsPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/student_results.html',) + final studentResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/student_results.html',) .readAsString(); test('StudyGradesFromStudentResultsPageExtract', () async { diff --git a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart index d5d5ae75..7a4e2095 100644 --- a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart +++ b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart @@ -6,8 +6,7 @@ import 'package:dhbwstudentapp/dualis/service/parsing/urls_from_main_page_extrac import 'package:test/test.dart'; Future main() async { - final mainPage = await File(Directory.current.absolute.path + - '/test/dualis/service/parsing/html_resources/main_page.html',) + final mainPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/main_page.html',) .readAsString(); test('UrlsFromMainPageExtract', () async { diff --git a/test/schedule/service/ical/ical_parser_test.dart b/test/schedule/service/ical/ical_parser_test.dart index 6221637f..b256e8f9 100644 --- a/test/schedule/service/ical/ical_parser_test.dart +++ b/test/schedule/service/ical/ical_parser_test.dart @@ -5,8 +5,7 @@ import 'package:dhbwstudentapp/schedule/service/ical/ical_parser.dart'; import 'package:test/test.dart'; Future main() async { - final icalFile = await File(Directory.current.absolute.path + - '/test/schedule/service/ical/file_resources/ical_test.ics',) + final icalFile = await File('${Directory.current.absolute.path}/test/schedule/service/ical/file_resources/ical_test.ics',) .readAsString(); test('ical correctly read all entries', () async { diff --git a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart index 1aa4adaa..55296130 100644 --- a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart +++ b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart @@ -4,8 +4,7 @@ import 'package:dhbwstudentapp/schedule/service/mannheim/mannheim_course_respons import 'package:test/test.dart'; Future main() async { - final coursePage = await File(Directory.current.absolute.path + - '/test/schedule/service/mannheim/html_resources/mannheim_ical.html',) + final coursePage = await File('${Directory.current.absolute.path}/test/schedule/service/mannheim/html_resources/mannheim_ical.html',) .readAsString(); test('Mannheim course parser parses correctly', () async { diff --git a/test/schedule/service/rapla/rapla_response_parser_test.dart b/test/schedule/service/rapla/rapla_response_parser_test.dart index 14ab8831..f2b6dc3b 100644 --- a/test/schedule/service/rapla/rapla_response_parser_test.dart +++ b/test/schedule/service/rapla/rapla_response_parser_test.dart @@ -5,40 +5,31 @@ import 'package:dhbwstudentapp/schedule/service/rapla/rapla_response_parser.dart import 'package:test/test.dart'; Future main() async { - final monthlyRaplaPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_monthly_response.html',) + final monthlyRaplaPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_monthly_response.html',) .readAsString(); - final raplaPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_response.html',) + final raplaPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_response.html',) .readAsString(); - final raplaPage1 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_response_1.html',) + final raplaPage1 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_response_1.html',) .readAsString(); - final severalMonthsPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_several_months_response.html',) + final severalMonthsPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response.html',) .readAsString(); - final severalMonthsPage1 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_several_months_response_1.html',) + final severalMonthsPage1 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response_1.html',) .readAsString(); - final severalMonthsPage2 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_several_months_response_2.html',) + final severalMonthsPage2 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response_2.html',) .readAsString(); - final invalidRaplaPage = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/invalid_rapla_response.html',) + final invalidRaplaPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/invalid_rapla_response.html',) .readAsString(); - final raplaWeekResponse = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_week_response.html',) + final raplaWeekResponse = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_week_response.html',) .readAsString(); - final raplaWeekResponse1 = await File(Directory.current.absolute.path + - '/test/schedule/service/rapla/html_resources/rapla_week_response_1.html',) + final raplaWeekResponse1 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_week_response_1.html',) .readAsString(); test('Rapla correctly read all classes of weekly view', () async { From f86e2e7b12ee3e6483f7220ccdb938b316cb8149 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:26:40 +0200 Subject: [PATCH 13/37] Sort pub dependencies --- pubspec.yaml | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 3d070581..08124d8e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,40 +17,38 @@ environment: sdk: ">=2.12.0 <3.0.0" dependencies: + animations: ^2.0.2 + app_group_directory: ^2.0.0 + device_calendar: ^4.2.0 + equatable: ^2.0.0 + firebase_analytics: ^9.1.6 + firebase_core: ^1.15.0 + firebase_crashlytics: ^2.6.3 # BREAKING CHANGES: iOS Min Plaform has to be updated flutter: sdk: flutter + flutter_inapp_purchase: ^5.1.2 + flutter_local_notifications: ^9.4.1 # BREAKING CHANGES HERE! flutter_localizations: sdk: flutter - - # cupertino_icons: ^1.0.0 - intl: ^0.17.0 + flutter_native_splash: ^2.1.6 + flutter_secure_storage: ^5.0.2 + flutter_widgetkit: ^1.0.3 html: ^0.15.0 http: ^0.13.4 - sqflite: ^2.0.2+1 - path_provider: ^2.0.9 - provider: ^6.0.2 - property_change_notifier: ^0.3.0 http_client_helper: ^2.0.2 - shared_preferences: ^2.0.13 - url_launcher: ^6.1.0 + intl: ^0.17.0 kiwi: ^4.0.2 - flutter_local_notifications: ^9.4.1 # BREAKING CHANGES HERE! - workmanager: ^0.5.0 - universal_html: ^2.0.8 - firebase_core: ^1.15.0 - firebase_analytics: ^9.1.6 - firebase_crashlytics: ^2.6.3 # BREAKING CHANGES: iOS Min Plaform has to be updated launch_review: ^3.0.1 - flutter_secure_storage: ^5.0.2 - animations: ^2.0.2 - flutter_native_splash: ^2.1.6 mutex: ^3.0.0 - device_calendar: ^4.2.0 - flutter_inapp_purchase: ^5.1.2 - flutter_widgetkit: ^1.0.3 - app_group_directory: ^2.0.0 + path_provider: ^2.0.9 + property_change_notifier: ^0.3.0 + provider: ^6.0.2 + shared_preferences: ^2.0.13 + sqflite: ^2.0.2+1 timezone: ^0.8.0 - equatable: ^2.0.0 + universal_html: ^2.0.8 + url_launcher: ^6.1.0 + workmanager: ^0.5.0 dev_dependencies: flutter_test: From a79bec94e3b5921787ab2d8b1ec53011ec04fac0 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 11:13:20 +0200 Subject: [PATCH 14/37] disable lints that require deeper code changes --- analysis_options.yaml | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index b47820e0..8c7dd194 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,10 +3,6 @@ # For apps, use the default set include: package:lint/analysis_options.yaml -# Packages, that may be distributed (i.e. via pub.dev) should use the package -# version, resulting in a better pub score. -# include: package:lint/analysis_options_package.yaml - # You might want to exclude auto-generated files from dart analysis analyzer: exclude: @@ -16,11 +12,9 @@ analyzer: # can be found at https://dart-lang.github.io/linter/lints/options/options.html linter: rules: - require_trailing_commas: true - avoid_redundant_argument_values: true - prefer_final_locals: true - prefer_final_in_for_each: true - prefer_final_fields: true - prefer_const_constructors: true - unnecessary_await_in_return: true - curly_braces_in_flow_control_structures: true + constant_identifier_names: false + avoid_print: false + avoid_positional_boolean_parameters: false + use_build_context_synchronously: false + parameter_assignments: false + avoid_setters_without_getters: false From a069ba2074bd4a1bb65c92c347f36be830863a78 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 13 Oct 2022 11:50:43 +0200 Subject: [PATCH 15/37] manually fix some lints --- lib/schedule/data/schedule_entry_entity.dart | 20 +++++++++---------- .../weekly_schedule_view_model.dart | 2 -- .../widgets/schedule_widget.dart | 12 +++++------ lib/schedule/ui/widgets/enter_ical_url.dart | 2 +- lib/ui/banner_widget.dart | 2 +- lib/ui/navigation/router.dart | 2 +- .../viewmodels/ical_url_view_model.dart | 2 +- 7 files changed, 19 insertions(+), 23 deletions(-) diff --git a/lib/schedule/data/schedule_entry_entity.dart b/lib/schedule/data/schedule_entry_entity.dart index 844e4980..c161732e 100644 --- a/lib/schedule/data/schedule_entry_entity.dart +++ b/lib/schedule/data/schedule_entry_entity.dart @@ -2,7 +2,7 @@ import 'package:dhbwstudentapp/common/data/database_entity.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class ScheduleEntryEntity extends DatabaseEntity { - ScheduleEntry? _scheduleEntry; + late ScheduleEntry _scheduleEntry; ScheduleEntryEntity.fromModel(ScheduleEntry scheduleEntry) { _scheduleEntry = scheduleEntry; @@ -32,18 +32,18 @@ class ScheduleEntryEntity extends DatabaseEntity { @override Map toMap() { return { - "id": _scheduleEntry!.id, - "start": _scheduleEntry!.start.millisecondsSinceEpoch, - "end": _scheduleEntry!.end.millisecondsSinceEpoch, - "details": _scheduleEntry!.details, - "professor": _scheduleEntry!.professor, - "room": _scheduleEntry!.room, - "title": _scheduleEntry!.title, - "type": _scheduleEntry!.type.index + "id": _scheduleEntry.id, + "start": _scheduleEntry.start.millisecondsSinceEpoch, + "end": _scheduleEntry.end.millisecondsSinceEpoch, + "details": _scheduleEntry.details, + "professor": _scheduleEntry.professor, + "room": _scheduleEntry.room, + "title": _scheduleEntry.title, + "type": _scheduleEntry.type.index }; } - ScheduleEntry asScheduleEntry() => _scheduleEntry!; + ScheduleEntry asScheduleEntry() => _scheduleEntry; static String tableName() => "ScheduleEntries"; } diff --git a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart index 43da4f28..f4ad1dcf 100644 --- a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart @@ -216,8 +216,6 @@ class WeeklyScheduleViewModel extends BaseViewModel { token, ); } - - return null; } void _cancelErrorInFuture() { diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 480a506a..1160cad5 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -34,13 +34,11 @@ class ScheduleWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - child: LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return buildWithSize( - context, constraints.biggest.width, constraints.biggest.height,); - },), - ); + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return buildWithSize( + context, constraints.biggest.width, constraints.biggest.height,); + },); } Widget buildWithSize(BuildContext context, double width, double height) { diff --git a/lib/schedule/ui/widgets/enter_ical_url.dart b/lib/schedule/ui/widgets/enter_ical_url.dart index b563d723..8cef7432 100644 --- a/lib/schedule/ui/widgets/enter_ical_url.dart +++ b/lib/schedule/ui/widgets/enter_ical_url.dart @@ -23,7 +23,7 @@ class EnterIcalDialog extends EnterUrlDialog { @override bool isValidUrl(String? url) { - return IcalScheduleSource.isValidUrl(url!); + return IcalScheduleSource.isValidUrl(url); } @override diff --git a/lib/ui/banner_widget.dart b/lib/ui/banner_widget.dart index 1e19f31e..2c0dbe91 100644 --- a/lib/ui/banner_widget.dart +++ b/lib/ui/banner_widget.dart @@ -14,7 +14,7 @@ class BannerWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( + return DecoratedBox( decoration: BoxDecoration( color: Theme.of(context).scaffoldBackgroundColor, boxShadow: [ diff --git a/lib/ui/navigation/router.dart b/lib/ui/navigation/router.dart index 5f616524..160effe3 100644 --- a/lib/ui/navigation/router.dart +++ b/lib/ui/navigation/router.dart @@ -51,7 +51,7 @@ Route generateDrawerRoute(RouteSettings settings) { position: animation.drive(offsetTween), child: FadeTransition( opacity: animation.drive(opacityTween), - child: Container( + child: ColoredBox( color: Theme.of(context).scaffoldBackgroundColor, child: child, ), diff --git a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart index 76552dc3..ea3b3d7b 100644 --- a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart +++ b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart @@ -24,7 +24,7 @@ class IcalUrlViewModel extends OnboardingStepViewModel { } void _validateUrl() { - urlHasError = !IcalScheduleSource.isValidUrl(_url!); + urlHasError = !IcalScheduleSource.isValidUrl(_url); setIsValid(!urlHasError); From eec0f482b06691bea5da4905f42fd8f2731aac5f Mon Sep 17 00:00:00 2001 From: Leptopoda Date: Wed, 12 Oct 2022 16:41:02 +0200 Subject: [PATCH 16/37] fix use_named_constants --- lib/common/ui/donate_to_developer_dialog.dart | 6 +++--- lib/common/ui/rate_in_store_dialog.dart | 6 +++--- lib/common/ui/widget_help_dialog.dart | 6 +++--- lib/common/ui/widgets/error_display.dart | 2 +- .../dailyschedule/widgets/daily_schedule_entry_widget.dart | 2 +- lib/schedule/ui/widgets/select_mannheim_course_dialog.dart | 2 +- lib/ui/onboarding/widgets/mannheim_page.dart | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index 43866132..0d7ebf76 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -33,9 +33,9 @@ class DonateToDeveloperDialog { barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( - buttonPadding: const EdgeInsets.all(0), - actionsPadding: const EdgeInsets.all(0), - contentPadding: const EdgeInsets.all(0), + buttonPadding: EdgeInsets.zero, + actionsPadding: EdgeInsets.zero, + contentPadding: EdgeInsets.zero, title: Text(L.of(context).donateDialogTitle), content: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/common/ui/rate_in_store_dialog.dart b/lib/common/ui/rate_in_store_dialog.dart index 80ce26bd..d4f1dfc3 100644 --- a/lib/common/ui/rate_in_store_dialog.dart +++ b/lib/common/ui/rate_in_store_dialog.dart @@ -33,9 +33,9 @@ class RateInStoreDialog { barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( - buttonPadding: const EdgeInsets.all(0), - actionsPadding: const EdgeInsets.all(0), - contentPadding: const EdgeInsets.all(0), + buttonPadding: EdgeInsets.zero, + actionsPadding: EdgeInsets.zero, + contentPadding: EdgeInsets.zero, title: Text(L.of(context).rateDialogTitle), content: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/common/ui/widget_help_dialog.dart b/lib/common/ui/widget_help_dialog.dart index 663c1c3f..bd70a063 100644 --- a/lib/common/ui/widget_help_dialog.dart +++ b/lib/common/ui/widget_help_dialog.dart @@ -29,9 +29,9 @@ class WidgetHelpDialog { barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( - buttonPadding: const EdgeInsets.all(0), - actionsPadding: const EdgeInsets.all(0), - contentPadding: const EdgeInsets.all(0), + buttonPadding: EdgeInsets.zero, + actionsPadding: EdgeInsets.zero, + contentPadding: EdgeInsets.zero, title: Text(L.of(context).widgetHelpDialogTitle), content: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/common/ui/widgets/error_display.dart b/lib/common/ui/widgets/error_display.dart index 306b0926..fb31b656 100644 --- a/lib/common/ui/widgets/error_display.dart +++ b/lib/common/ui/widgets/error_display.dart @@ -16,7 +16,7 @@ class ErrorDisplay extends StatelessWidget { duration: const Duration(milliseconds: 300), child: show ? Padding( - padding: const EdgeInsets.all(0), + padding: EdgeInsets.zero, child: Container( width: double.infinity, color: colorNoConnectionBackground(), diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index 13e4d452..79b70410 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -53,7 +53,7 @@ class DailyScheduleEntryWidget extends StatelessWidget { Expanded( flex: 7, child: Card( - margin: const EdgeInsets.all(0), + margin: EdgeInsets.zero, elevation: 8, color: scheduleEntryTypeToColor(context, scheduleEntry.type), child: Padding( diff --git a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart index c9120790..94dfdf5f 100644 --- a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart +++ b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart @@ -27,7 +27,7 @@ class SelectMannheimCourseDialog { AlertDialog _buildDialog(BuildContext context) { return AlertDialog( title: Text(L.of(context).onboardingMannheimTitle), - contentPadding: const EdgeInsets.all(0), + contentPadding: EdgeInsets.zero, content: PropertyChangeProvider( value: _mannheimViewModel, child: SizedBox( diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index 3e968d71..ddedefce 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -75,7 +75,7 @@ class SelectMannheimCourseWidget extends StatelessWidget { return Material( color: Colors.transparent, child: ListView.builder( - padding: const EdgeInsets.all(0), + padding: EdgeInsets.zero, itemCount: viewModel.courses?.length ?? 0, itemBuilder: (BuildContext context, int index) => _buildCourseListTile(viewModel, index, context), From 3a472ee5a3b473a6515c94ca6c993e275243ae19 Mon Sep 17 00:00:00 2001 From: Leptopoda Date: Wed, 12 Oct 2022 16:58:42 +0200 Subject: [PATCH 17/37] fix avoid_classes_with_only_static_members --- lib/common/data/sql_scripts.dart | 1 + lib/common/util/platform_util.dart | 5 ++- .../rapla/rapla_monthly_response_parser.dart | 2 ++ .../service/rapla/rapla_parsing_utils.dart | 35 ++++++++++++------- .../rapla_several_months_response_parser.dart | 2 ++ .../rapla/rapla_week_response_parser.dart | 2 ++ lib/ui/navigation/navigator_key.dart | 1 + 7 files changed, 35 insertions(+), 13 deletions(-) diff --git a/lib/common/data/sql_scripts.dart b/lib/common/data/sql_scripts.dart index 108a991e..52100970 100644 --- a/lib/common/data/sql_scripts.dart +++ b/lib/common/data/sql_scripts.dart @@ -1,6 +1,7 @@ import 'dart:core'; class SqlScripts { + const SqlScripts(); static final databaseMigrationScripts = [ // Version 1 - init database [ diff --git a/lib/common/util/platform_util.dart b/lib/common/util/platform_util.dart index f55954bf..21030e96 100644 --- a/lib/common/util/platform_util.dart +++ b/lib/common/util/platform_util.dart @@ -4,6 +4,8 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; class PlatformUtil { + const PlatformUtil(); + static bool isPhone() { final data = MediaQueryData.fromWindow(WidgetsBinding.instance.window); return data.size.shortestSide < 600; @@ -25,7 +27,8 @@ class PlatformUtil { static Future initializePortraitLandscapeMode() async { if (isPhone()) { await SystemChrome.setPreferredOrientations( - [DeviceOrientation.portraitUp],); + [DeviceOrientation.portraitUp], + ); } else { await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, diff --git a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart index db8f54b2..d5e20c52 100644 --- a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart @@ -9,6 +9,8 @@ import 'package:html/dom.dart'; /// table /// class RaplaMonthlyResponseParser { + const RaplaMonthlyResponseParser(); + static ScheduleQueryResult parseMonthlyTable( Element monthTable, ) { diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index 2b911246..effc8ef4 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -5,6 +5,8 @@ import 'package:html/dom.dart'; import 'package:intl/intl.dart'; class RaplaParsingUtils { + const RaplaParsingUtils(); + static const String WEEK_BLOCK_CLASS = "week_block"; static const String TOOLTIP_CLASS = "tooltip"; static const String INFOTABLE_CLASS = "infotable"; @@ -28,7 +30,9 @@ class RaplaParsingUtils { }; static ScheduleEntry extractScheduleEntryOrThrow( - Element value, DateTime date,) { + Element value, + DateTime date, + ) { // The tooltip tag contains the most relevant information final tooltip = value.getElementsByClassName(TOOLTIP_CLASS); @@ -58,7 +62,11 @@ class RaplaParsingUtils { // tooltip. Then provide a link with a manual to activate it in Rapla if (tooltip.isEmpty) { scheduleEntry = extractScheduleDetailsFromCell( - timeAndClassName, scheduleEntry, start, end,); + timeAndClassName, + scheduleEntry, + start, + end, + ); } else { scheduleEntry = extractScheduleFromTooltip(tooltip, value, scheduleEntry, start, end); @@ -75,7 +83,8 @@ class RaplaParsingUtils { final professor = scheduleEntry.professor; if (professor.endsWith(",")) { scheduleEntry = scheduleEntry.copyWith( - professor: professor.substring(0, professor.length - 1),); + professor: professor.substring(0, professor.length - 1), + ); } return scheduleEntry.copyWith( @@ -87,11 +96,12 @@ class RaplaParsingUtils { } static ScheduleEntry extractScheduleFromTooltip( - List tooltip, - Element value, - ScheduleEntry? scheduleEntry, - DateTime start, - DateTime end,) { + List tooltip, + Element value, + ScheduleEntry? scheduleEntry, + DateTime start, + DateTime end, + ) { final infotable = tooltip[0].getElementsByClassName(INFOTABLE_CLASS); if (infotable.isEmpty) { @@ -121,10 +131,11 @@ class RaplaParsingUtils { } static ScheduleEntry extractScheduleDetailsFromCell( - List timeAndClassName, - ScheduleEntry? scheduleEntry, - DateTime start, - DateTime end,) { + List timeAndClassName, + ScheduleEntry? scheduleEntry, + DateTime start, + DateTime end, + ) { final descriptionHtml = timeAndClassName[0].innerHtml.substring(12); final descriptionParts = descriptionHtml.split("
"); diff --git a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart index a721db42..5a18d583 100644 --- a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart @@ -5,6 +5,8 @@ import 'package:dhbwstudentapp/schedule/service/rapla/rapla_monthly_response_par import 'package:html/dom.dart'; class RaplaSeveralMonthsResponseParser { + const RaplaSeveralMonthsResponseParser(); + static ScheduleQueryResult parseSeveralMonthlyTables( Document document, List monthTables, diff --git a/lib/schedule/service/rapla/rapla_week_response_parser.dart b/lib/schedule/service/rapla/rapla_week_response_parser.dart index 569f2c98..d4bdbe4c 100644 --- a/lib/schedule/service/rapla/rapla_week_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_week_response_parser.dart @@ -11,6 +11,8 @@ import 'package:intl/intl.dart'; /// table /// class RaplaWeekResponseParser { + const RaplaWeekResponseParser(); + static ScheduleQueryResult parseWeeklyTable( Document document, Element weekTable, diff --git a/lib/ui/navigation/navigator_key.dart b/lib/ui/navigation/navigator_key.dart index 1dee2eef..86556a16 100644 --- a/lib/ui/navigation/navigator_key.dart +++ b/lib/ui/navigation/navigator_key.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; class NavigatorKey { + const NavigatorKey(); static final mainKey = GlobalKey(); static final rootKey = GlobalKey(); } From e5729bc9212d027afb1d2b53f3960e4772fe41a1 Mon Sep 17 00:00:00 2001 From: Leptopoda Date: Wed, 12 Oct 2022 17:13:59 +0200 Subject: [PATCH 18/37] prefer_null_aware_method_calls --- lib/common/iap/in_app_purchase_helper.dart | 7 +++---- .../ui/weeklyschedule/widgets/schedule_entry_widget.dart | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/common/iap/in_app_purchase_helper.dart b/lib/common/iap/in_app_purchase_helper.dart index 67360b6f..37bf6c6f 100644 --- a/lib/common/iap/in_app_purchase_helper.dart +++ b/lib/common/iap/in_app_purchase_helper.dart @@ -76,9 +76,7 @@ class InAppPurchaseHelper { return PurchaseResultEnum.Success; } on PlatformException catch (_) { - if (_purchaseCallback != null) { - _purchaseCallback!(id, PurchaseResultEnum.Error); - } + _purchaseCallback?.call(id, PurchaseResultEnum.Error); return PurchaseResultEnum.Error; } @@ -194,7 +192,8 @@ class InAppPurchaseHelper { if (!await _preferencesProvider.getHasPurchasedSomething()) { print( - "Abort complete pending purchases, the user did not buy something in the past",); + "Abort complete pending purchases, the user did not buy something in the past", + ); return; } diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart index 0a15e826..d4c9b20e 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart @@ -25,7 +25,7 @@ class ScheduleEntryWidget extends StatelessWidget { margin: const EdgeInsets.fromLTRB(1, 0, 1, 0), child: InkWell( onTap: () { - if (onScheduleEntryTap != null) onScheduleEntryTap!(scheduleEntry); + onScheduleEntryTap?.call(scheduleEntry); }, child: Padding( padding: const EdgeInsets.fromLTRB(4, 4, 4, 4), From f126dfb2dfd4f24659f316019af8c75c7ae6aa65 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:53:16 +0200 Subject: [PATCH 19/37] fix errors --- .../background/background_work_scheduler.dart | 2 +- lib/common/data/database_access.dart | 56 ++++++------ .../preferences/preferences_provider.dart | 20 +++-- lib/common/ui/viewmodels/root_view_model.dart | 1 - lib/date_management/data/calendar_access.dart | 73 ++++++++++------ .../data/date_entry_entity.dart | 20 +++-- .../date_management_view_model.dart | 17 ++-- .../ui/widgets/date_filter_options.dart | 74 +++++++++------- .../exam_results_page/exam_results_page.dart | 86 +++++++++++-------- lib/schedule/business/schedule_provider.dart | 38 ++++---- lib/schedule/data/schedule_entry_entity.dart | 31 ++++--- .../schedule_query_information_entity.dart | 7 +- .../isolate_schedule_source_decorator.dart | 29 ++++--- .../weekly_schedule_view_model.dart | 12 ++- .../ui/widgets/select_source_dialog.dart | 23 ++--- lib/ui/login_credentials_widget.dart | 4 +- lib/ui/onboarding/widgets/mannheim_page.dart | 4 +- lib/ui/settings/select_theme_dialog.dart | 6 +- 18 files changed, 298 insertions(+), 205 deletions(-) diff --git a/lib/common/background/background_work_scheduler.dart b/lib/common/background/background_work_scheduler.dart index d746dd75..b551428e 100644 --- a/lib/common/background/background_work_scheduler.dart +++ b/lib/common/background/background_work_scheduler.dart @@ -103,7 +103,7 @@ class BackgroundWorkScheduler extends WorkSchedulerService { /// /// Entry point for when a background task is executed /// - static Future backgroundTaskMain(taskId, inputData) async { + static Future backgroundTaskMain(String taskId, Map? inputData) async { try { print("Background task started: $taskId with data: $inputData"); diff --git a/lib/common/data/database_access.dart b/lib/common/data/database_access.dart index bb094a2c..d03bf55f 100644 --- a/lib/common/data/database_access.dart +++ b/lib/common/data/database_access.dart @@ -15,10 +15,12 @@ class DatabaseAccess { Future _initDatabase() async { final String path = await getDatabasePath(_databaseName); - return openDatabase(path, - version: SqlScripts.databaseMigrationScripts.length, - onCreate: _onCreate, - onUpgrade: _onUpgrade,); + return openDatabase( + path, + version: SqlScripts.databaseMigrationScripts.length, + onCreate: _onCreate, + onUpgrade: _onUpgrade, + ); } Future _onCreate(Database db, int version) async { @@ -42,30 +44,34 @@ class DatabaseAccess { Future insert(String table, Map row) async { final Database db = await _database; - return db.insert(table, row); + return db.insert(table, row); } Future>> queryAllRows(String table) async { final Database db = await _database; - return db.query(table); + return db.query(table); } Future>> rawQuery( - String sql, List parameters,) async { + String sql, + List parameters, + ) async { final Database db = await _database; - return db.rawQuery(sql, parameters); + return db.rawQuery(sql, parameters); } - Future>> queryRows(String table, - {bool? distinct, - List? columns, - String? where, - List? whereArgs, - String? groupBy, - String? having, - String? orderBy, - int? limit, - int? offset,}) async { + Future>> queryRows( + String table, { + bool? distinct, + List? columns, + String? where, + List? whereArgs, + String? groupBy, + String? having, + String? orderBy, + int? limit, + int? offset, + }) async { final Database db = await _database; // TODO: [Leptopoda] is there a reason this is done? or at maybe use whereArgs.removeWhere() @@ -73,7 +79,7 @@ class DatabaseAccess { whereArgs![i] = whereArgs[i] ?? ""; } - return db.query( + return db.query( table, distinct: distinct, columns: columns, @@ -90,7 +96,8 @@ class DatabaseAccess { Future queryRowCount(String table) async { final Database db = await _database; return Sqflite.firstIntValue( - await db.rawQuery('SELECT COUNT(*) FROM $table'),); + await db.rawQuery('SELECT COUNT(*) FROM $table'), + ); } Future queryAggregator(String query, List arguments) async { @@ -100,14 +107,13 @@ class DatabaseAccess { Future update(String table, Map row) async { final Database db = await _database; - final int? id = row[idColumnName]; - return db - .update(table, row, where: '$idColumnName = ?', whereArgs: [id]); + final id = row[idColumnName]; + return db.update(table, row, where: '$idColumnName = ?', whereArgs: [id]); } Future delete(String table, int? id) async { final Database db = await _database; - return db.delete(table, where: '$idColumnName = ?', whereArgs: [id]); + return db.delete(table, where: '$idColumnName = ?', whereArgs: [id]); } Future deleteWhere( @@ -116,7 +122,7 @@ class DatabaseAccess { List? whereArgs, }) async { final Database db = await _database; - return db.delete( + return db.delete( table, where: where, whereArgs: whereArgs, diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index c5ab496c..c060facd 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -68,13 +68,15 @@ class PreferencesProvider { Calendar? selectedCalendar; final String? selectedCalendarId = await _preferencesAccess.get('SelectedCalendarId'); - if (selectedCalendarId == null) return null; - final List availableCalendars = + final List? availableCalendars = await CalendarAccess().queryWriteableCalendars(); + if (selectedCalendarId == null || availableCalendars == null) return null; for (final cal in availableCalendars) { { - if (cal.id == selectedCalendarId) {selectedCalendar = cal} + if (cal.id == selectedCalendarId) { + selectedCalendar = cal; } + } } return selectedCalendar; } @@ -96,7 +98,7 @@ class PreferencesProvider { } Future getLastUsedLanguageCode() async { - return _preferencesAccess.get(LastUsedLanguageCode); + return _preferencesAccess.get(LastUsedLanguageCode); } Future setLastUsedLanguageCode(String languageCode) async { @@ -158,7 +160,7 @@ class PreferencesProvider { } Future getLastViewedSemester() async { - return _preferencesAccess.get(LastViewedSemester); + return _preferencesAccess.get(LastViewedSemester); } Future setLastViewedSemester(String? lastViewedSemester) async { @@ -168,16 +170,18 @@ class PreferencesProvider { } Future getLastViewedDateEntryDatabase() async { - return _preferencesAccess.get(LastViewedDateEntryDatabase); + return _preferencesAccess.get(LastViewedDateEntryDatabase); } Future setLastViewedDateEntryDatabase(String? value) async { await _preferencesAccess.set( - LastViewedDateEntryDatabase, value ?? "",); + LastViewedDateEntryDatabase, + value ?? "", + ); } Future getLastViewedDateEntryYear() async { - return _preferencesAccess.get(LastViewedDateEntryYear); + return _preferencesAccess.get(LastViewedDateEntryYear); } Future setLastViewedDateEntryYear(String? value) async { diff --git a/lib/common/ui/viewmodels/root_view_model.dart b/lib/common/ui/viewmodels/root_view_model.dart index f976bcb2..2d8acb30 100644 --- a/lib/common/ui/viewmodels/root_view_model.dart +++ b/lib/common/ui/viewmodels/root_view_model.dart @@ -23,7 +23,6 @@ class RootViewModel extends BaseViewModel { Future setAppTheme(AppTheme? value) async { if (value == null) return; - await _preferencesProvider.setAppTheme(value); _appTheme = value; notifyListeners("appTheme"); diff --git a/lib/date_management/data/calendar_access.dart b/lib/date_management/data/calendar_access.dart index bd25b3d3..5c410cc3 100644 --- a/lib/date_management/data/calendar_access.dart +++ b/lib/date_management/data/calendar_access.dart @@ -36,16 +36,20 @@ class CalendarAccess { return CalendarPermission.PermissionDenied; } - Future> queryWriteableCalendars() async { + Future?> queryWriteableCalendars() async { final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars(); - final writeableCalendars = []; - for (final calendar in calendarsResult.data ?? []) { - if (!calendar.isReadOnly!) { - writeableCalendars.add(calendar); + final calendars = calendarsResult.data; + + if (calendars != null) { + final writeableCalendars = []; + for (final calendar in calendars) { + if (!calendar.isReadOnly!) { + writeableCalendars.add(calendar); + } } + return writeableCalendars; } - - return writeableCalendars; + return null; } Future addOrUpdateDates( @@ -63,12 +67,17 @@ class CalendarAccess { } Future _addOrUpdateEntry( - List existingEvents, DateEntry entry, Calendar calendar,) async { + List existingEvents, + DateEntry entry, + Calendar calendar, + ) async { // Find the id in the existing events in order that the "update" part of // createOrUpdateEvent(...) works final id = _getIdOfExistingEvent(existingEvents, entry); - var isAllDay, start, end; + bool isAllDay; + DateTime start; + DateTime end; if (entry.start.isAtSameMomentAs(entry.end)) { isAllDay = isAtMidnight(entry.start); start = entry.start; @@ -79,23 +88,28 @@ class CalendarAccess { end = entry.end; } - return _deviceCalendarPlugin.createOrUpdateEvent(Event( - calendar.id, - location: entry.room, - title: entry.description, - description: entry.comment, - eventId: id, - allDay: isAllDay, - start: tz.TZDateTime.from(start, tz.getLocation('Europe/Berlin')), - end: tz.TZDateTime.from(end, tz.getLocation('Europe/Berlin')), - ),); + return _deviceCalendarPlugin.createOrUpdateEvent( + Event( + calendar.id, + location: entry.room, + title: entry.description, + description: entry.comment, + eventId: id, + allDay: isAllDay, + start: tz.TZDateTime.from(start, tz.getLocation('Europe/Berlin')), + end: tz.TZDateTime.from(end, tz.getLocation('Europe/Berlin')), + ), + ); } String? _getIdOfExistingEvent(List existingEvents, DateEntry entry) { final existingEvent = existingEvents - .where((element) => element.title == entry.description && - (element.start?.toUtc().isAtSameMomentAs(entry.start.toUtc()) ?? - false),) + .where( + (element) => + element.title == entry.description && + (element.start?.toUtc().isAtSameMomentAs(entry.start.toUtc()) ?? + false), + ) .toList(); String? id; @@ -106,16 +120,19 @@ class CalendarAccess { } Future> _getExistingEventsFromCalendar( - List dateEntries, Calendar calendar,) async { + List dateEntries, + Calendar calendar, + ) async { final firstEntry = _findFirstEntry(dateEntries); final lastEntry = _findLastEntry(dateEntries); final existingEventsResult = await _deviceCalendarPlugin.retrieveEvents( - calendar.id, - RetrieveEventsParams( - startDate: firstEntry.start, - endDate: lastEntry.end, - ),); + calendar.id, + RetrieveEventsParams( + startDate: firstEntry.start, + endDate: lastEntry.end, + ), + ); var existingEvents = []; diff --git a/lib/date_management/data/date_entry_entity.dart b/lib/date_management/data/date_entry_entity.dart index 26ff8414..593637d7 100644 --- a/lib/date_management/data/date_entry_entity.dart +++ b/lib/date_management/data/date_entry_entity.dart @@ -13,16 +13,20 @@ class DateEntryEntity extends DatabaseEntity { @override void fromMap(Map map) { - final date = DateTime.fromMillisecondsSinceEpoch(map["date"]); + final date = map["date"] as int?; + DateTime? dateTime; + if (date != null) { + dateTime = DateTime.fromMillisecondsSinceEpoch(date); + } _dateEntry = DateEntry( - comment: map["comment"], - description: map["description"], - year: map["year"], - databaseName: map["databaseName"], - start: date, - end: date, - room: map["room"], + comment: map["comment"] as String?, + description: map["description"] as String?, + year: map["year"] as String?, + databaseName: map["databaseName"] as String?, + start: dateTime, + end: dateTime, + room: map["room"] as String?, ); } diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index 6f8f9bd5..fbb9549a 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -16,15 +16,19 @@ class DateManagementViewModel extends BaseViewModel { DateDatabase("BWL-Bank", "Termine_BWL_Bank"), DateDatabase("Immobilienwirtschaft", "Termine_BWL_Immo"), DateDatabase( - "Dienstleistungsmanagement Consulting & Sales", "Termine_DLM_Consult",), + "Dienstleistungsmanagement Consulting & Sales", + "Termine_DLM_Consult", + ), DateDatabase("Dienstleistungsmanagement Logistik", "Termine_DLM_Logistik"), DateDatabase("Campus Horb Informatik", "Termine_Horb_INF"), DateDatabase("Campus Horb Maschinenbau", "Termine_Horb_MB"), DateDatabase("International Business", "Termine_IB"), DateDatabase("Informatik", "Termine_Informatik"), DateDatabase("MUK (DLM - C&S, LogM, MUK)", "Termine_MUK"), - DateDatabase("SO_GuO (Abweichungen und Ergänzungen zum Vorlesungsplan)", - "Termine_SO_GuO",), + DateDatabase( + "SO_GuO (Abweichungen und Ergänzungen zum Vorlesungsplan)", + "Termine_SO_GuO", + ), DateDatabase("Wirtschaftsingenieurwesen", "Termine_WIW"), ]; List get allDateDatabases => _allDateDatabases; @@ -121,9 +125,9 @@ class DateManagementViewModel extends BaseViewModel { _updateMutex.token, ); return loadedDateEntries; + } catch (_) { + return null; } - - return null; } Future> _readCachedDateEntries() async { @@ -171,7 +175,8 @@ class DateManagementViewModel extends BaseViewModel { } Future _loadDefaultSelection() async { - final database = await _preferencesProvider.getLastViewedDateEntryDatabase(); + final database = + await _preferencesProvider.getLastViewedDateEntryDatabase(); bool didSetDatabase = false; for (final db in allDateDatabases) { diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index c2b38a55..af212393 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -77,35 +77,45 @@ class _DateFilterOptionsState extends State { final chips = []; if (widget.viewModel.showPassedDates && widget.viewModel.showFutureDates) { - chips.add(Chip( - label: Text(L.of(context).dateManagementChipFutureAndPast), - visualDensity: VisualDensity.compact, - ),); + chips.add( + Chip( + label: Text(L.of(context).dateManagementChipFutureAndPast), + visualDensity: VisualDensity.compact, + ), + ); } else if (widget.viewModel.showFutureDates) { - chips.add(Chip( - label: Text(L.of(context).dateManagementChipOnlyFuture), - visualDensity: VisualDensity.compact, - ),); + chips.add( + Chip( + label: Text(L.of(context).dateManagementChipOnlyFuture), + visualDensity: VisualDensity.compact, + ), + ); } else if (widget.viewModel.showPassedDates) { - chips.add(Chip( - label: Text(L.of(context).dateManagementChipOnlyPassed), - visualDensity: VisualDensity.compact, - ),); + chips.add( + Chip( + label: Text(L.of(context).dateManagementChipOnlyPassed), + visualDensity: VisualDensity.compact, + ), + ); } if (widget.viewModel.currentSelectedYear != null) { - chips.add(Chip( - label: Text(widget.viewModel.currentSelectedYear!), - visualDensity: VisualDensity.compact, - ),); + chips.add( + Chip( + label: Text(widget.viewModel.currentSelectedYear!), + visualDensity: VisualDensity.compact, + ), + ); } final database = widget.viewModel.currentDateDatabase?.displayName ?? ""; if (database != "") { - chips.add(Chip( - label: Text(database), - visualDensity: VisualDensity.compact, - ),); + chips.add( + Chip( + label: Text(database), + visualDensity: VisualDensity.compact, + ), + ); } return Padding( @@ -136,7 +146,7 @@ class _DateFilterOptionsState extends State { ), ), Expanded( - child: DropdownButton( + child: DropdownButton( isExpanded: true, value: widget.viewModel.currentDateDatabase, onChanged: widget.viewModel.setCurrentDateDatabase, @@ -156,7 +166,7 @@ class _DateFilterOptionsState extends State { ), ), Expanded( - child: DropdownButton( + child: DropdownButton( isExpanded: true, value: widget.viewModel.currentSelectedYear, onChanged: widget.viewModel.setCurrentSelectedYear, @@ -204,10 +214,12 @@ class _DateFilterOptionsState extends State { final yearMenuItems = >[]; for (final year in widget.viewModel.years) { - yearMenuItems.add(DropdownMenuItem( - value: year, - child: Text(year), - ),); + yearMenuItems.add( + DropdownMenuItem( + value: year, + child: Text(year), + ), + ); } return yearMenuItems; } @@ -216,10 +228,12 @@ class _DateFilterOptionsState extends State { final databaseMenuItems = >[]; for (final database in widget.viewModel.allDateDatabases) { - databaseMenuItems.add(DropdownMenuItem( - value: database, - child: Text(database.displayName), - ),); + databaseMenuItems.add( + DropdownMenuItem( + value: database, + child: Text(database.displayName), + ), + ); } return databaseMenuItems; } diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index 98af8de0..1281b9dd 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -1,6 +1,7 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/common/util/platform_util.dart'; import 'package:dhbwstudentapp/dualis/model/exam_grade.dart'; +import 'package:dhbwstudentapp/dualis/model/module.dart'; import 'package:dhbwstudentapp/dualis/ui/viewmodels/study_grades_view_model.dart'; import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; @@ -76,7 +77,9 @@ class ExamResultsPage extends StatelessWidget { } Widget buildModulesColumn( - BuildContext context, StudyGradesViewModel viewModel,) { + BuildContext context, + StudyGradesViewModel viewModel, + ) { return AnimatedSwitcher( layoutBuilder: (Widget? currentChild, List previousChildren) { List children = previousChildren; @@ -97,52 +100,63 @@ class ExamResultsPage extends StatelessWidget { } List buildModulesDataTables( - BuildContext context, StudyGradesViewModel viewModel,) { + BuildContext context, + StudyGradesViewModel viewModel, + ) { final dataTables = []; var isFirstModule = true; for (final module in viewModel.currentSemester!.modules) { - dataTables.add(DataTable( - horizontalMargin: 24, - columnSpacing: 0, - dataRowHeight: 45, - headingRowHeight: 65, - rows: buildModuleDataRows(context, module), - columns: buildModuleColumns(context, module, - displayGradeHeader: isFirstModule,), - ),); + dataTables.add( + DataTable( + horizontalMargin: 24, + columnSpacing: 0, + dataRowHeight: 45, + headingRowHeight: 65, + rows: buildModuleDataRows(context, module), + columns: buildModuleColumns( + context, + module, + displayGradeHeader: isFirstModule, + ), + ), + ); isFirstModule = false; } return dataTables; } - List buildModuleDataRows(BuildContext context, var module) { + List buildModuleDataRows(BuildContext context, Module module) { final dataRows = []; for (final exam in module.exams) { dataRows.add( DataRow( cells: [ - DataCell(Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - exam.name ?? "", - style: Theme.of(context).textTheme.caption, - ), - Text( - exam.semester ?? "", - style: Theme.of(context).textTheme.caption, - textScaleFactor: exam.semester == "" ? 0 : 1, - ), - ], - ),), + DataCell( + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + exam.name ?? "", + style: Theme.of(context).textTheme.caption, + ), + Text( + exam.semester ?? "", + style: Theme.of(context).textTheme.caption, + textScaleFactor: exam.semester == "" ? 0 : 1, + ), + ], + ), + ), DataCell.empty, - DataCell(Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 16, 0), - child: _examGradeToWidget(context, exam.grade), - ),), + DataCell( + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 16, 0), + child: _examGradeToWidget(context, exam.grade), + ), + ), ], ), ); @@ -163,8 +177,11 @@ class ExamResultsPage extends StatelessWidget { } } - List buildModuleColumns(BuildContext context, var module, - {var displayGradeHeader = false,}) { + List buildModuleColumns( + BuildContext context, + Module module, { + bool displayGradeHeader = false, + }) { var displayWidth = MediaQuery.of(context).size.width; if (!PlatformUtil.isPortrait(context) && PlatformUtil.isTablet()) { @@ -202,7 +219,8 @@ class ExamResultsPage extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(0, 0, 10, 16), child: Text( - "${L.of(context).dualisExamResultsCreditsColumnHeader}: ${module.credits}",), + "${L.of(context).dualisExamResultsCreditsColumnHeader}: ${module.credits}", + ), ), ), ), diff --git a/lib/schedule/business/schedule_provider.dart b/lib/schedule/business/schedule_provider.dart index 3de9599c..199f13f2 100644 --- a/lib/schedule/business/schedule_provider.dart +++ b/lib/schedule/business/schedule_provider.dart @@ -39,11 +39,12 @@ class ScheduleProvider { []; ScheduleProvider( - this._scheduleSource, - this._scheduleEntryRepository, - this._scheduleQueryInformationRepository, - this._preferencesProvider, - this._scheduleFilterRepository,) { + this._scheduleSource, + this._scheduleEntryRepository, + this._scheduleQueryInformationRepository, + this._preferencesProvider, + this._scheduleFilterRepository, + ) { _scheduleFilter = ScheduleFilter(_scheduleFilterRepository); } @@ -52,23 +53,26 @@ class ScheduleProvider { await _scheduleEntryRepository.queryScheduleBetweenDates(start, end); print( - "Read chached schedule with ${cachedSchedule.entries.length.toString()} entries",); + "Read chached schedule with ${cachedSchedule.entries.length.toString()} entries", + ); cachedSchedule = await _scheduleFilter.filter(cachedSchedule); print( - "Filtered cached schedule has ${cachedSchedule.entries.length} entries",); + "Filtered cached schedule has ${cachedSchedule.entries.length} entries", + ); return cachedSchedule; } - Future getUpdatedSchedule( + Future getUpdatedSchedule( DateTime start, DateTime end, CancellationToken cancellationToken, ) async { print( - "Fetching schedule for ${DateFormat.yMd().format(start)} - ${DateFormat.yMd().format(end)}",); + "Fetching schedule for ${DateFormat.yMd().format(start)} - ${DateFormat.yMd().format(end)}", + ); try { var updatedSchedule = await _scheduleSource.currentScheduleSource .querySchedule(start, end, cancellationToken); @@ -107,7 +111,7 @@ class ScheduleProvider { print("Failed to fetch schedule!"); print(e.innerException.toString()); print(trace); - rethrow; + return null; } } @@ -122,7 +126,8 @@ class ScheduleProvider { final diff = ScheduleDiffCalculator().calculateDiff(oldSchedule, updatedSchedule); - final cleanedDiff = await _cleanDiffFromNewlyQueriedEntries(start, end, diff); + final cleanedDiff = + await _cleanDiffFromNewlyQueriedEntries(start, end, diff); if (cleanedDiff.didSomethingChange()) { for (final c in _scheduleEntryChangedCallbacks) { @@ -146,7 +151,8 @@ class ScheduleProvider { } void removeScheduleEntryChangedCallback( - ScheduleEntryChangedCallback callback,) { + ScheduleEntryChangedCallback callback, + ) { if (_scheduleUpdatedCallbacks.contains(callback)) { _scheduleEntryChangedCallbacks.remove(callback); } @@ -163,9 +169,11 @@ class ScheduleProvider { final cleanedAddedEntries = []; for (final addedEntry in diff.addedEntries) { - if (queryInformation.any((i) => - addedEntry.end.isAfter(i!.start) && - addedEntry.start.isBefore(i.end),)) { + if (queryInformation.any( + (i) => + addedEntry.end.isAfter(i!.start) && + addedEntry.start.isBefore(i.end), + )) { cleanedAddedEntries.add(addedEntry); } } diff --git a/lib/schedule/data/schedule_entry_entity.dart b/lib/schedule/data/schedule_entry_entity.dart index c161732e..43b16d09 100644 --- a/lib/schedule/data/schedule_entry_entity.dart +++ b/lib/schedule/data/schedule_entry_entity.dart @@ -14,19 +14,28 @@ class ScheduleEntryEntity extends DatabaseEntity { @override void fromMap(Map map) { - final startDate = DateTime.fromMillisecondsSinceEpoch(map["start"]); - - final endDate = DateTime.fromMillisecondsSinceEpoch(map["end"]); + final start = map["start"] as int?; + DateTime? startDate; + if (start != null) { + startDate = DateTime.fromMillisecondsSinceEpoch(start); + } + + final end = map["end"] as int?; + DateTime? endDate; + if (end != null) { + endDate = DateTime.fromMillisecondsSinceEpoch(end); + } _scheduleEntry = ScheduleEntry( - id: map["id"], - start: startDate, - end: endDate, - details: map["details"], - professor: map["professor"], - title: map["title"], - room: map["room"], - type: ScheduleEntryType.values[map["type"]],); + id: map["id"] as int?, + start: startDate, + end: endDate, + details: map["details"] as String?, + professor: map["professor"] as String?, + title: map["title"] as String?, + room: map["room"] as String?, + type: ScheduleEntryType.values[map["type"] as int], + ); } @override diff --git a/lib/schedule/data/schedule_query_information_entity.dart b/lib/schedule/data/schedule_query_information_entity.dart index b8bc4e1d..fa1f9068 100644 --- a/lib/schedule/data/schedule_query_information_entity.dart +++ b/lib/schedule/data/schedule_query_information_entity.dart @@ -18,17 +18,18 @@ class ScheduleQueryInformationEntity extends DatabaseEntity { void fromMap(Map map) { DateTime? startDate; if (map["start"] != null) { - startDate = DateTime.fromMillisecondsSinceEpoch(map["start"]); + startDate = DateTime.fromMillisecondsSinceEpoch(map["start"] as int); } DateTime? endDate; if (map["end"] != null) { - endDate = DateTime.fromMillisecondsSinceEpoch(map["end"]); + endDate = DateTime.fromMillisecondsSinceEpoch(map["end"] as int); } DateTime? queryTimeDate; if (map["queryTime"] != null) { - queryTimeDate = DateTime.fromMillisecondsSinceEpoch(map["queryTime"]); + queryTimeDate = + DateTime.fromMillisecondsSinceEpoch(map["queryTime"] as int); } _scheduleQueryInformation = diff --git a/lib/schedule/service/isolate_schedule_source_decorator.dart b/lib/schedule/service/isolate_schedule_source_decorator.dart index a5f29d32..14e97f87 100644 --- a/lib/schedule/service/isolate_schedule_source_decorator.dart +++ b/lib/schedule/service/isolate_schedule_source_decorator.dart @@ -18,8 +18,11 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { IsolateScheduleSourceDecorator(this._scheduleSource); @override - Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken,]) async { + Future querySchedule( + DateTime? from, + DateTime? to, [ + CancellationToken? cancellationToken, + ]) async { await _initializeIsolate(); // Use the cancellation token to send a cancel message. @@ -42,9 +45,10 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { final subscription = _isolateToMain!.listen((result) { cancellationToken.setCancellationCallback(null); - if (result != null && result is! ScheduleQueryResult) { + // TODO: [Leptopoda] validate changes + if (result == null || result is! ScheduleQueryResult) { potentialException = ScheduleQueryFailedException(result); - completer.complete(null); + completer.complete(); } else { completer.complete(result); } @@ -69,7 +73,9 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { // Use a broadcast stream. The normal ReceivePort closes after one subscription _isolateToMain = isolateToMain.asBroadcastStream(); _isolate = await Isolate.spawn( - scheduleSourceIsolateEntryPoint, isolateToMain.sendPort,); + _scheduleSourceIsolateEntryPoint, + isolateToMain.sendPort, + ); _sendPort = await _isolateToMain!.first as SendPort?; } @@ -79,7 +85,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { } } -Future scheduleSourceIsolateEntryPoint(SendPort sendPort) async { +Future _scheduleSourceIsolateEntryPoint(SendPort sendPort) async { // Using the given send port, send back a send port for two way communication final port = ReceivePort(); sendPort.send(port.sendPort); @@ -87,24 +93,25 @@ Future scheduleSourceIsolateEntryPoint(SendPort sendPort) async { CancellationToken? token; await for (final message in port) { + message as Map; if (message["type"] == "execute") { token = CancellationToken(); - executeQueryScheduleMessage(message, sendPort, token); + _executeQueryScheduleMessage(message, sendPort, token); } else if (message["type"] == "cancel") { token?.cancel(); } } } -Future executeQueryScheduleMessage( +Future _executeQueryScheduleMessage( Map map, SendPort sendPort, CancellationToken? token, ) async { try { - final ScheduleSource source = map["source"]; - final DateTime? from = map["from"]; - final DateTime? to = map["to"]; + final ScheduleSource source = map["source"] as ScheduleSource; + final DateTime? from = map["from"] as DateTime?; + final DateTime? to = map["to"] as DateTime?; final result = await source.querySchedule(from, to, token); diff --git a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart index f4ad1dcf..0aa53ff5 100644 --- a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart @@ -209,13 +209,11 @@ class WeeklyScheduleViewModel extends BaseViewModel { DateTime end, CancellationToken token, ) async { - try { - return await scheduleProvider.getUpdatedSchedule( - start, - end, - token, - ); - } + return scheduleProvider.getUpdatedSchedule( + start, + end, + token, + ); } void _cancelErrorInFuture() { diff --git a/lib/schedule/ui/widgets/select_source_dialog.dart b/lib/schedule/ui/widgets/select_source_dialog.dart index e7acf8b8..bb43eb3c 100644 --- a/lib/schedule/ui/widgets/select_source_dialog.dart +++ b/lib/schedule/ui/widgets/select_source_dialog.dart @@ -38,34 +38,34 @@ class SelectSourceDialog { style: Theme.of(context).textTheme.bodyText2, ), ), - RadioListTile( + RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Rapla, - onChanged: (dynamic v) => sourceSelected(v, context), + onChanged: (v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeRapla), ), - RadioListTile( + RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Dualis, - onChanged: (dynamic v) => sourceSelected(v, context), + onChanged: (v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeDualis), ), - RadioListTile( + RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Mannheim, - onChanged: (dynamic v) => sourceSelected(v, context), + onChanged: (v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeMannheim), ), - RadioListTile( + RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.Ical, - onChanged: (dynamic v) => sourceSelected(v, context), + onChanged: (v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeIcal), ), - RadioListTile( + RadioListTile( groupValue: _currentScheduleSource, value: ScheduleSourceType.None, - onChanged: (dynamic v) => sourceSelected(v, context), + onChanged: (v) => sourceSelected(v, context), title: Text(L.of(context).scheduleSourceTypeNone), ) ], @@ -73,9 +73,10 @@ class SelectSourceDialog { } Future sourceSelected( - ScheduleSourceType type, + ScheduleSourceType? type, BuildContext context, ) async { + if (type == null) return; // TODO: [Leptopoda] only switch the type when the setup is completed. _preferencesProvider.setScheduleSourceType(type.index); diff --git a/lib/ui/login_credentials_widget.dart b/lib/ui/login_credentials_widget.dart index 71bf0e90..70670b9a 100644 --- a/lib/ui/login_credentials_widget.dart +++ b/lib/ui/login_credentials_widget.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; class LoginCredentialsWidget extends StatefulWidget { final CredentialsEditingController controller; - final Function onSubmitted; + final VoidCallback onSubmitted; const LoginCredentialsWidget({ Key? key, @@ -42,7 +42,7 @@ class _LoginCredentialsWidgetState extends State { icon: const Icon(Icons.lock_outline), ), focusNode: _focus, - onSubmitted: (v) { + onSubmitted: (_) { widget.onSubmitted(); }, ), diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index ddedefce..9e14c61d 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -112,7 +112,9 @@ class SelectMannheimCourseWidget extends StatelessWidget { } Widget _buildLoadingError( - BuildContext context, MannheimViewModel? viewModel,) { + BuildContext context, + MannheimViewModel? viewModel, + ) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/ui/settings/select_theme_dialog.dart b/lib/ui/settings/select_theme_dialog.dart index 340711b9..a30d85f4 100644 --- a/lib/ui/settings/select_theme_dialog.dart +++ b/lib/ui/settings/select_theme_dialog.dart @@ -33,19 +33,19 @@ class SelectThemeDialog { return Column( mainAxisSize: MainAxisSize.min, children: [ - RadioListTile( + RadioListTile( title: Text(L.of(context).selectThemeLight), value: AppTheme.Light, groupValue: _rootViewModel.appTheme, onChanged: _rootViewModel.setAppTheme, ), - RadioListTile( + RadioListTile( title: Text(L.of(context).selectThemeDark), value: AppTheme.Dark, groupValue: _rootViewModel.appTheme, onChanged: _rootViewModel.setAppTheme, ), - RadioListTile( + RadioListTile( title: Text(L.of(context).selectThemeSystem), value: AppTheme.System, groupValue: _rootViewModel.appTheme, From 60a2d8626d06849a2d940fcdbe161e391fca2548 Mon Sep 17 00:00:00 2001 From: Leptopoda Date: Thu, 13 Oct 2022 11:38:44 +0200 Subject: [PATCH 20/37] fix join_return_with_assignment --- lib/schedule/business/schedule_provider.dart | 6 ++---- lib/schedule/service/rapla/rapla_parsing_utils.dart | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/schedule/business/schedule_provider.dart b/lib/schedule/business/schedule_provider.dart index 199f13f2..d15e1bc5 100644 --- a/lib/schedule/business/schedule_provider.dart +++ b/lib/schedule/business/schedule_provider.dart @@ -74,7 +74,7 @@ class ScheduleProvider { "Fetching schedule for ${DateFormat.yMd().format(start)} - ${DateFormat.yMd().format(end)}", ); try { - var updatedSchedule = await _scheduleSource.currentScheduleSource + final updatedSchedule = await _scheduleSource.currentScheduleSource .querySchedule(start, end, cancellationToken); var schedule = updatedSchedule?.schedule; @@ -104,9 +104,7 @@ class ScheduleProvider { await c(schedule!, start, end); } - updatedSchedule = ScheduleQueryResult(schedule!, updatedSchedule!.errors); - - return updatedSchedule; + return ScheduleQueryResult(schedule!, updatedSchedule!.errors); } on ScheduleQueryFailedException catch (e, trace) { print("Failed to fetch schedule!"); print(e.innerException.toString()); diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index effc8ef4..ff17aaaa 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -118,7 +118,7 @@ class RaplaParsingUtils { final details = properties[DETAILS_LABEL]; final resource = properties[RESOURCES_LABEL] ?? _extractResources(value); - scheduleEntry = ScheduleEntry( + return ScheduleEntry( start: start, end: end, title: title, @@ -127,7 +127,6 @@ class RaplaParsingUtils { type: type, room: resource, ); - return scheduleEntry; } static ScheduleEntry extractScheduleDetailsFromCell( @@ -149,7 +148,7 @@ class RaplaParsingUtils { details = descriptionParts.join("\n"); } - scheduleEntry = ScheduleEntry( + return ScheduleEntry( start: start, end: end, title: title, @@ -158,7 +157,6 @@ class RaplaParsingUtils { type: ScheduleEntryType.Unknown, room: "", ); - return scheduleEntry; } static ScheduleEntryType _extractEntryType(List tooltip) { From 8ebc4f69786b9a6a282895ce55c8b4081736beb7 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 13 Oct 2022 11:49:48 +0200 Subject: [PATCH 21/37] fix type_annotate_public_apis --- lib/common/logging/crash_reporting.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/logging/crash_reporting.dart b/lib/common/logging/crash_reporting.dart index b3d7d1f3..8aada3c5 100644 --- a/lib/common/logging/crash_reporting.dart +++ b/lib/common/logging/crash_reporting.dart @@ -1,7 +1,7 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; -Future reportException(ex, StackTrace? trace) async { +Future reportException(dynamic ex, StackTrace? trace) async { if (kReleaseMode) { print("Reporting exception to crashlytics: $ex with stack trace $trace"); await FirebaseCrashlytics.instance.recordError(ex, trace); From 155d1d6c1e0531f5128952fe8bb2fb32e90321d5 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 13 Oct 2022 11:46:46 +0200 Subject: [PATCH 22/37] fix avoid_setters_without_getters --- .../ui/dailyschedule/daily_schedule_page.dart | 72 ++++++++++--------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index d42c5d42..baccc30f 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -33,10 +33,14 @@ class _DailySchedulePageState extends State { Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 16), child: PropertyChangeConsumer( - builder: (BuildContext context, DailyScheduleViewModel? model, - Set? properties,) { + builder: ( + BuildContext context, + DailyScheduleViewModel? model, + Set? properties, + ) { final dateFormat = DateFormat.yMMMMEEEEd( - L.of(context).locale.languageCode,); + L.of(context).locale.languageCode, + ); return Text( dateFormat.format(model!.currentDate!), style: textStyleDailyScheduleCurrentDate(context), @@ -44,39 +48,41 @@ class _DailySchedulePageState extends State { }, ), ), - if (viewModel.daySchedule.entries.isEmpty) Padding( - padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), - child: Column( + if (viewModel.schedule.entries.isEmpty) + Padding( + padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded(child: Container()), - Expanded( - flex: 8, - child: Text( - L.of(context).dailyScheduleNoEntriesToday, - softWrap: true, - textAlign: TextAlign.center, - style: - textStyleDailyScheduleNoEntries(context), - ), - ), - Expanded(child: Container()), - ], - ), - Padding( - padding: const EdgeInsets.fromLTRB(32, 64, 32, 32), - child: Opacity( - opacity: 0.9, - child: Image.asset("assets/empty_state.png"), + Expanded(child: Container()), + Expanded( + flex: 8, + child: Text( + L.of(context).dailyScheduleNoEntriesToday, + softWrap: true, + textAlign: TextAlign.center, + style: textStyleDailyScheduleNoEntries(context), ), - ) + ), + Expanded(child: Container()), ], ), - ) else Column( - children: buildEntryWidgets(), - ) + Padding( + padding: const EdgeInsets.fromLTRB(32, 64, 32, 32), + child: Opacity( + opacity: 0.9, + child: Image.asset("assets/empty_state.png"), + ), + ) + ], + ), + ) + else + Column( + children: buildEntryWidgets(), + ) ], ), ), @@ -89,7 +95,7 @@ class _DailySchedulePageState extends State { final now = DateTime.now(); var nowIndicatorInserted = false; - for (final entry in viewModel.daySchedule.entries) { + for (final entry in viewModel.schedule.entries) { if (!nowIndicatorInserted && (entry.end.isAfter(now))) { entryWidgets.add(CurrentTimeIndicatorWidget()); nowIndicatorInserted = true; From 519f0e94c282da8a423bee4b19463c92da6c7deb Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 09:33:24 +0200 Subject: [PATCH 23/37] fix use_setters_to_change_properties --- lib/common/iap/in_app_purchase_helper.dart | 2 +- lib/common/iap/in_app_purchase_manager.dart | 10 +-- lib/common/util/cancelable_mutex.dart | 2 +- lib/common/util/cancellation_token.dart | 8 +-- .../business/date_entry_provider.dart | 4 +- .../ui/calendar_export_page.dart | 61 ++++++++++-------- .../calendar_export_view_model.dart | 7 ++- .../date_management_view_model.dart | 19 +++--- .../ui/widgets/date_filter_options.dart | 10 +-- lib/dualis/service/dualis_authentication.dart | 2 +- lib/dualis/service/dualis_scraper.dart | 13 ++-- ...fake_account_dualis_scraper_decorator.dart | 17 ++--- .../service/fake_data_dualis_scraper.dart | 2 +- lib/dualis/service/session.dart | 15 ++--- .../business/schedule_source_provider.dart | 26 ++++---- .../dualis/dualis_schedule_source.dart | 23 ++++--- .../service/ical/ical_schedule_source.dart | 18 +++--- .../isolate_schedule_source_decorator.dart | 7 +-- .../mannheim/mannheim_course_scraper.dart | 16 ++--- .../service/rapla/rapla_schedule_source.dart | 52 +++++++++------- .../weekly_schedule_view_model.dart | 2 +- .../weeklyschedule/weekly_schedule_page.dart | 2 +- .../viewmodels/dualis_login_view_model.dart | 10 +-- .../viewmodels/ical_url_view_model.dart | 6 +- .../viewmodels/mannheim_view_model.dart | 4 +- .../onboarding_view_model_base.dart | 3 +- .../viewmodels/rapla_url_view_model.dart | 2 +- .../viewmodels/select_source_view_model.dart | 4 +- .../onboarding/widgets/dualis_login_page.dart | 62 +++++++++++-------- lib/ui/onboarding/widgets/ical_url_page.dart | 2 +- test/rapla_service_test.dart | 9 ++- 31 files changed, 229 insertions(+), 191 deletions(-) diff --git a/lib/common/iap/in_app_purchase_helper.dart b/lib/common/iap/in_app_purchase_helper.dart index 37bf6c6f..d469490e 100644 --- a/lib/common/iap/in_app_purchase_helper.dart +++ b/lib/common/iap/in_app_purchase_helper.dart @@ -116,7 +116,7 @@ class InAppPurchaseHelper { /// Sets the callback function that gets executed when a purchase succeeded /// or failed /// - void setPurchaseCompleteCallback(PurchaseCompletedCallback callback) { + set purchaseCompleteCallback(PurchaseCompletedCallback callback) { _purchaseCallback = callback; } diff --git a/lib/common/iap/in_app_purchase_manager.dart b/lib/common/iap/in_app_purchase_manager.dart index b504271b..87c59283 100644 --- a/lib/common/iap/in_app_purchase_manager.dart +++ b/lib/common/iap/in_app_purchase_manager.dart @@ -26,8 +26,7 @@ class InAppPurchaseManager { _setWidgetEnabled(result == PurchaseResultEnum.Success), ); - _inAppPurchaseHelper - .setPurchaseCompleteCallback(_purchaseCompletedCallback); + _inAppPurchaseHelper.purchaseCompleteCallback = _purchaseCompletedCallback; try { await _inAppPurchaseHelper.initialize(); @@ -39,7 +38,8 @@ class InAppPurchaseManager { } Future _restorePurchases() async { - final didPurchaseWidget = await didBuyWidget() == PurchaseStateEnum.Purchased; + final didPurchaseWidget = + await didBuyWidget() == PurchaseStateEnum.Purchased; await _setWidgetEnabled(didPurchaseWidget); } @@ -63,7 +63,9 @@ class InAppPurchaseManager { // TODO: [Leptopoda] better nullseafety void _purchaseCompletedCallback( - String? productId, PurchaseResultEnum result,) { + String? productId, + PurchaseResultEnum result, + ) { if (purchaseCallbacks.containsKey(productId)) { final callback = purchaseCallbacks[productId!]; diff --git a/lib/common/util/cancelable_mutex.dart b/lib/common/util/cancelable_mutex.dart index cf53898a..4d79d6fb 100644 --- a/lib/common/util/cancelable_mutex.dart +++ b/lib/common/util/cancelable_mutex.dart @@ -11,7 +11,7 @@ class CancelableMutex { } Future acquireAndCancelOther() async { - if (!(token?.isCancelled() ?? false)) { + if (!(token?.isCancelled ?? false)) { token?.cancel(); } diff --git a/lib/common/util/cancellation_token.dart b/lib/common/util/cancellation_token.dart index 36c5e604..27fc3c2e 100644 --- a/lib/common/util/cancellation_token.dart +++ b/lib/common/util/cancellation_token.dart @@ -4,9 +4,9 @@ class CancellationToken { bool _isCancelled = false; CancellationCallback? _callback; - bool isCancelled() { - return _isCancelled; - } + CancellationToken([this._callback]); + + bool get isCancelled => _isCancelled; void throwIfCancelled() { if (_isCancelled) { @@ -20,7 +20,7 @@ class CancellationToken { _callback?.call(); } - void setCancellationCallback(CancellationCallback? callback) { + set cancellationCallback(CancellationCallback? callback) { _callback = callback; } } diff --git a/lib/date_management/business/date_entry_provider.dart b/lib/date_management/business/date_entry_provider.dart index 4737e5c0..ad8d762f 100644 --- a/lib/date_management/business/date_entry_provider.dart +++ b/lib/date_management/business/date_entry_provider.dart @@ -73,7 +73,9 @@ class DateEntryProvider { } List _filterDates( - List updatedEntries, DateSearchParameters parameters,) { + List updatedEntries, + DateSearchParameters parameters, + ) { final filteredDateEntries = []; final now = DateTime.now(); diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 59eb5877..a6017258 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -14,12 +14,12 @@ class CalendarExportPage extends StatefulWidget { final bool isCalendarSyncWidget; final bool isCalendarSyncEnabled; - const CalendarExportPage( - {Key? key, - required this.entriesToExport, - this.isCalendarSyncWidget = false, - this.isCalendarSyncEnabled = false,}) - : super(key: key); + const CalendarExportPage({ + Key? key, + required this.entriesToExport, + this.isCalendarSyncWidget = false, + this.isCalendarSyncEnabled = false, + }) : super(key: key); @override _CalendarExportPageState createState() => _CalendarExportPageState(); @@ -32,11 +32,12 @@ class _CalendarExportPageState extends State { void initState() { super.initState(); - viewModel = CalendarExportViewModel(widget.entriesToExport, - CalendarAccess(), KiwiContainer().resolve(),); - viewModel.setOnPermissionDeniedCallback(() { - Navigator.of(context).pop(); - }); + viewModel = CalendarExportViewModel( + widget.entriesToExport, + CalendarAccess(), + KiwiContainer().resolve(), + ); + viewModel.onPermissionDeniedCallback = Navigator.of(context).pop; viewModel.loadSelectedCalendar(); } @@ -50,9 +51,11 @@ class _CalendarExportPageState extends State { actionsIconTheme: Theme.of(context).iconTheme, elevation: 0, iconTheme: Theme.of(context).iconTheme, - title: Text(widget.isCalendarSyncWidget - ? L.of(context).calendarSyncPageTitle - : L.of(context).dateManagementExportToCalendar,), + title: Text( + widget.isCalendarSyncWidget + ? L.of(context).calendarSyncPageTitle + : L.of(context).dateManagementExportToCalendar, + ), toolbarTextStyle: Theme.of(context).textTheme.bodyText2, titleTextStyle: Theme.of(context).textTheme.headline6, ), @@ -62,9 +65,11 @@ class _CalendarExportPageState extends State { padding: const EdgeInsets.all(24), child: Align( alignment: Alignment.centerLeft, - child: Text(widget.isCalendarSyncWidget - ? L.of(context).calendarSyncPageSubtitle - : L.of(context).dateManagementExportToCalendarDescription,), + child: Text( + widget.isCalendarSyncWidget + ? L.of(context).calendarSyncPageSubtitle + : L.of(context).dateManagementExportToCalendarDescription, + ), ), ), _buildCalendarList(), @@ -117,10 +122,11 @@ class _CalendarExportPageState extends State { L.of(context).calendarSyncPageEndSync.toUpperCase(), textAlign: TextAlign.center, style: TextStyle( - color: widget.isCalendarSyncEnabled - ? ColorPalettes.main - : Theme.of(context).disabledColor, - fontSize: 14,), + color: widget.isCalendarSyncEnabled + ? ColorPalettes.main + : Theme.of(context).disabledColor, + fontSize: 14, + ), ), onTap: () async { KiwiContainer() @@ -189,14 +195,16 @@ class _CalendarExportPageState extends State { ? const Padding( padding: EdgeInsets.fromLTRB(8, 8, 8, 15), child: SizedBox( - height: 32, - width: 32, - child: CircularProgressIndicator(),), + height: 32, + width: 32, + child: CircularProgressIndicator(), + ), ) : Container( decoration: !viewModel.canExport ? BoxDecoration( - color: Theme.of(context).colorScheme.background,) + color: Theme.of(context).colorScheme.background, + ) : BoxDecoration( color: Theme.of(context).colorScheme.primary, ), @@ -228,7 +236,8 @@ class _CalendarExportPageState extends State { final preferencesProvider = KiwiContainer() .resolve(); preferencesProvider.setSelectedCalendar( - viewModel.selectedCalendar,); + viewModel.selectedCalendar, + ); preferencesProvider .setIsCalendarSyncEnabled(true); } diff --git a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart index 74bb61e9..4070663f 100644 --- a/lib/date_management/ui/viewmodels/calendar_export_view_model.dart +++ b/lib/date_management/ui/viewmodels/calendar_export_view_model.dart @@ -25,7 +25,10 @@ class CalendarExportViewModel extends BaseViewModel { bool get isExporting => _isExporting; CalendarExportViewModel( - this._entriesToExport, this.calendarAccess, this.preferencesProvider,) { + this._entriesToExport, + this.calendarAccess, + this.preferencesProvider, + ) { loadCalendars(); } @@ -78,7 +81,7 @@ class CalendarExportViewModel extends BaseViewModel { } } - void setOnPermissionDeniedCallback(OnPermissionDenied function) { + set onPermissionDeniedCallback(OnPermissionDenied function) { _onPermissionDenied = function; } } diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index fbb9549a..4b16334f 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -100,11 +100,11 @@ class DateManagementViewModel extends BaseViewModel { Future _doUpdateDates() async { final cachedDateEntries = await _readCachedDateEntries(); - _updateMutex.token!.throwIfCancelled(); + _updateMutex.token?.throwIfCancelled(); _setAllDates(cachedDateEntries); final loadedDateEntries = await _readUpdatedDateEntries(); - _updateMutex.token!.throwIfCancelled(); + _updateMutex.token?.throwIfCancelled(); if (loadedDateEntries != null) { _setAllDates(loadedDateEntries); @@ -143,29 +143,28 @@ class DateManagementViewModel extends BaseViewModel { notifyListeners("allDates"); } - // TODO [Leptopoda]: use setters - void setShowPassedDates(bool? value) { + set showPassedDates(bool? value) { if (value == null) return; _showPassedDates = value; notifyListeners("showPassedDates"); } - void setShowFutureDates(bool? value) { + set showFutureDates(bool? value) { if (value == null) return; _showFutureDates = value; notifyListeners("showFutureDates"); } - void setCurrentDateDatabase(DateDatabase? database) { + set currentDateDatabase(DateDatabase? database) { _currentDateDatabase = database; notifyListeners("currentDateDatabase"); _preferencesProvider.setLastViewedDateEntryDatabase(database?.id); } - void setCurrentSelectedYear(String? year) { + set currentSelectedYear(String? year) { if (year == null) return; _currentSelectedYear = year; @@ -181,17 +180,17 @@ class DateManagementViewModel extends BaseViewModel { bool didSetDatabase = false; for (final db in allDateDatabases) { if (db.id == database) { - setCurrentDateDatabase(db); + currentDateDatabase = db; didSetDatabase = true; } } if (!didSetDatabase) { - setCurrentDateDatabase(allDateDatabases[0]); + currentDateDatabase = allDateDatabases[0]; } final year = await _preferencesProvider.getLastViewedDateEntryYear(); - setCurrentSelectedYear(year ?? years[0]); + currentSelectedYear = year ?? years[0]; await updateDates(); } diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index af212393..2624293d 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -149,7 +149,8 @@ class _DateFilterOptionsState extends State { child: DropdownButton( isExpanded: true, value: widget.viewModel.currentDateDatabase, - onChanged: widget.viewModel.setCurrentDateDatabase, + onChanged: (v) => + widget.viewModel.currentDateDatabase = v, items: _buildDatabaseMenuItems(), ), ), @@ -169,7 +170,8 @@ class _DateFilterOptionsState extends State { child: DropdownButton( isExpanded: true, value: widget.viewModel.currentSelectedYear, - onChanged: widget.viewModel.setCurrentSelectedYear, + onChanged: (v) => + widget.viewModel.currentSelectedYear = v, items: _buildYearsMenuItems(), ), ), @@ -179,13 +181,13 @@ class _DateFilterOptionsState extends State { title: Text(L.of(context).dateManagementCheckBoxFutureDates), value: widget.viewModel.showFutureDates, dense: true, - onChanged: widget.viewModel.setShowFutureDates, + onChanged: (v) => widget.viewModel.showFutureDates = v, ), CheckboxListTile( title: Text(L.of(context).dateManagementCheckBoxPassedDates), value: widget.viewModel.showPassedDates, dense: true, - onChanged: widget.viewModel.setShowPassedDates, + onChanged: (v) => widget.viewModel.showPassedDates = v, ), ], ), diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index 217cd4b6..a4a80b62 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -203,7 +203,7 @@ class DualisAuthentication { return url; } - void setLoginCredentials(Credentials credentials) { + set loginCredentials(Credentials credentials) { _credentials = credentials; } diff --git a/lib/dualis/service/dualis_scraper.dart b/lib/dualis/service/dualis_scraper.dart index 0a1e6927..dcd2ff83 100644 --- a/lib/dualis/service/dualis_scraper.dart +++ b/lib/dualis/service/dualis_scraper.dart @@ -19,6 +19,8 @@ class DualisScraper { final DualisAuthentication _dualisAuthentication = DualisAuthentication(); DualisUrls get _dualisUrls => _dualisAuthentication.dualisUrls; + DualisScraper(); + Future> loadAllModules([ CancellationToken? cancellationToken, ]) async { @@ -99,9 +101,12 @@ class DualisScraper { "${_dualisUrls.monthlyScheduleUrl}01.${dateInMonth.month}.${dateInMonth.year}"; final result = await _dualisAuthentication.authenticatedGet( - requestUrl, cancellationToken,); + requestUrl, + cancellationToken, + ); - final schedule = MonthlyScheduleExtract().extractScheduleFromMonthly(result); + final schedule = + MonthlyScheduleExtract().extractScheduleFromMonthly(result); schedule.urls.add(dualisEndpoint); @@ -130,7 +135,7 @@ class DualisScraper { return _dualisAuthentication.loginState == LoginResult.LoggedIn; } - void setLoginCredentials(Credentials credentials) { - _dualisAuthentication.setLoginCredentials(credentials); + set loginCredentials(Credentials credentials) { + _dualisAuthentication.loginCredentials = credentials; } } diff --git a/lib/dualis/service/fake_account_dualis_scraper_decorator.dart b/lib/dualis/service/fake_account_dualis_scraper_decorator.dart index a493ce0d..8b05ed09 100644 --- a/lib/dualis/service/fake_account_dualis_scraper_decorator.dart +++ b/lib/dualis/service/fake_account_dualis_scraper_decorator.dart @@ -32,8 +32,9 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { } @override - Future> loadAllModules( - [CancellationToken? cancellationToken,]) { + Future> loadAllModules([ + CancellationToken? cancellationToken, + ]) { return _currentDualisScraper.loadAllModules(); } @@ -71,8 +72,9 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { } @override - Future> loadSemesters( - [CancellationToken? cancellationToken,]) { + Future> loadSemesters([ + CancellationToken? cancellationToken, + ]) { return _currentDualisScraper.loadSemesters(cancellationToken); } @@ -99,7 +101,8 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { @override Future loginWithPreviousCredentials( - CancellationToken cancellationToken,) { + CancellationToken cancellationToken, + ) { return _currentDualisScraper.loginWithPreviousCredentials( cancellationToken, ); @@ -113,13 +116,13 @@ class FakeAccountDualisScraperDecorator implements DualisScraper { } @override - void setLoginCredentials(Credentials credentials) { + set loginCredentials(Credentials credentials) { if (credentials == _credentials) { _currentDualisScraper = _fakeDualisScraper; } else { _currentDualisScraper = _originalDualisScraper; } - return _currentDualisScraper.setLoginCredentials(credentials); + _currentDualisScraper.loginCredentials = credentials; } } diff --git a/lib/dualis/service/fake_data_dualis_scraper.dart b/lib/dualis/service/fake_data_dualis_scraper.dart index 1c3a150b..0435e044 100644 --- a/lib/dualis/service/fake_data_dualis_scraper.dart +++ b/lib/dualis/service/fake_data_dualis_scraper.dart @@ -126,7 +126,7 @@ class FakeDataDualisScraper implements DualisScraper { } @override - void setLoginCredentials(Credentials? credentials) { + set loginCredentials(Credentials? credentials) { // TODO: implement setLoginCredentials } } diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index 5c90dc37..146ac27c 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -39,14 +39,11 @@ class Session { String url, [ CancellationToken? cancellationToken, ]) async { - cancellationToken ??= CancellationToken(); - final requestCancellationToken = http.CancellationToken(); + cancellationToken ??= CancellationToken(); try { - cancellationToken.setCancellationCallback(() { - requestCancellationToken.cancel(); - }); + cancellationToken.cancellationCallback = requestCancellationToken.cancel; final requestUri = Uri.parse(url); @@ -68,7 +65,7 @@ class Session { } catch (ex) { if (!requestCancellationToken.isCanceled) rethrow; } finally { - cancellationToken.setCancellationCallback(null); + cancellationToken.cancellationCallback = null; } return null; @@ -104,9 +101,7 @@ class Session { final requestCancellationToken = http.CancellationToken(); try { - cancellationToken.setCancellationCallback(() { - requestCancellationToken.cancel(); - }); + cancellationToken.cancellationCallback = requestCancellationToken.cancel; final response = await http.HttpClientHelper.post( Uri.parse(url), @@ -127,7 +122,7 @@ class Session { } catch (ex) { if (!requestCancellationToken.isCanceled) rethrow; } finally { - cancellationToken.setCancellationCallback(null); + cancellationToken.cancellationCallback = null; } return null; diff --git a/lib/schedule/business/schedule_source_provider.dart b/lib/schedule/business/schedule_source_provider.dart index 3aa34b37..996b2312 100644 --- a/lib/schedule/business/schedule_source_provider.dart +++ b/lib/schedule/business/schedule_source_provider.dart @@ -33,7 +33,8 @@ class ScheduleSourceProvider { ScheduleSource get currentScheduleSource => _currentScheduleSource; - final List _onDidChangeScheduleSourceCallbacks = []; + final List _onDidChangeScheduleSourceCallbacks = + []; ScheduleSourceProvider( this._preferencesProvider, @@ -76,12 +77,11 @@ class ScheduleSourceProvider { } Future _dualisScheduleSource() async { - final dualis = DualisScheduleSource(KiwiContainer().resolve()); - final credentials = await _preferencesProvider.loadDualisCredentials(); if (credentials != null) { - dualis.setLoginCredentials(credentials); + final dualis = + DualisScheduleSource(KiwiContainer().resolve(), credentials); return ErrorReportScheduleSourceDecorator(dualis); } else { return InvalidScheduleSource(); @@ -91,11 +91,10 @@ class ScheduleSourceProvider { Future _raplaScheduleSource() async { final raplaUrl = await _preferencesProvider.getRaplaUrl(); - final rapla = RaplaScheduleSource(); final urlValid = RaplaScheduleSource.isValidUrl(raplaUrl); if (urlValid) { - rapla.setEndpointUrl(raplaUrl); + final rapla = RaplaScheduleSource(raplaUrl: raplaUrl); ScheduleSource source = ErrorReportScheduleSourceDecorator(rapla); @@ -111,16 +110,17 @@ class ScheduleSourceProvider { Future _icalScheduleSource() async { final url = await _preferencesProvider.getIcalUrl(); - final ical = IcalScheduleSource(); - ical.setIcalUrl(url); + if (url != null) { + final ical = IcalScheduleSource(url); - if (ical.canQuery()) { - ScheduleSource source = ErrorReportScheduleSourceDecorator(ical); + if (ical.canQuery()) { + ScheduleSource source = ErrorReportScheduleSourceDecorator(ical); - if (!_appRunningInBackground) { - source = IsolateScheduleSourceDecorator(source); + if (!_appRunningInBackground) { + source = IsolateScheduleSourceDecorator(source); + } + return source; } - return source; } return InvalidScheduleSource(); diff --git a/lib/schedule/service/dualis/dualis_schedule_source.dart b/lib/schedule/service/dualis/dualis_schedule_source.dart index b8738a7d..ecdf3663 100644 --- a/lib/schedule/service/dualis/dualis_schedule_source.dart +++ b/lib/schedule/service/dualis/dualis_schedule_source.dart @@ -10,11 +10,16 @@ import 'package:dhbwstudentapp/schedule/service/schedule_source.dart'; class DualisScheduleSource extends ScheduleSource { final DualisScraper _dualisScraper; - DualisScheduleSource(this._dualisScraper); + DualisScheduleSource(this._dualisScraper, Credentials credentials) { + _dualisScraper.loginCredentials = credentials; + } @override - Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken,]) async { + Future querySchedule( + DateTime? from, + DateTime? to, [ + CancellationToken? cancellationToken, + ]) async { cancellationToken ??= CancellationToken(); DateTime current = toStartOfMonth(from)!; @@ -26,10 +31,12 @@ class DualisScheduleSource extends ScheduleSource { await _dualisScraper.loginWithPreviousCredentials(cancellationToken); } - while (to!.isAfter(current) && !cancellationToken.isCancelled()) { + while (to!.isAfter(current) && !cancellationToken.isCancelled) { try { final monthSchedule = await _dualisScraper.loadMonthlySchedule( - current, cancellationToken,); + current, + cancellationToken, + ); schedule.merge(monthSchedule); } on OperationCancelledException { @@ -44,17 +51,13 @@ class DualisScheduleSource extends ScheduleSource { current = toNextMonth(current); } - if (cancellationToken.isCancelled()) throw OperationCancelledException(); + cancellationToken.throwIfCancelled(); schedule = schedule.trim(from, to); return ScheduleQueryResult(schedule, allErrors); } - Future setLoginCredentials(Credentials credentials) async { - _dualisScraper.setLoginCredentials(credentials); - } - @override bool canQuery() { return _dualisScraper.isLoggedIn(); diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index da1ffede..8229e0fb 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -10,11 +10,9 @@ import 'package:http_client_helper/http_client_helper.dart' as http; class IcalScheduleSource extends ScheduleSource { final IcalParser _icalParser = IcalParser(); - String? _url; + final String _url; - void setIcalUrl(String? url) { - _url = url; - } + IcalScheduleSource(this._url); @override bool canQuery() { @@ -27,7 +25,7 @@ class IcalScheduleSource extends ScheduleSource { DateTime? to, [ CancellationToken? cancellationToken, ]) async { - final response = await _makeRequest(_url!, cancellationToken!); + final response = await _makeRequest(_url, cancellationToken!); if (response == null) return null; try { @@ -46,15 +44,15 @@ class IcalScheduleSource extends ScheduleSource { } Future _makeRequest( - String url, CancellationToken cancellationToken,) async { + String url, + CancellationToken cancellationToken, + ) async { url = url.replaceAll("webcal://", "https://"); final requestCancellationToken = http.CancellationToken(); try { - cancellationToken.setCancellationCallback(() { - requestCancellationToken.cancel(); - }); + cancellationToken.cancellationCallback = requestCancellationToken.cancel; final response = await http.HttpClientHelper.get( Uri.parse(url), @@ -71,7 +69,7 @@ class IcalScheduleSource extends ScheduleSource { } catch (ex) { if (!requestCancellationToken.isCanceled) rethrow; } finally { - cancellationToken.setCancellationCallback(null); + cancellationToken.cancellationCallback = null; } return null; diff --git a/lib/schedule/service/isolate_schedule_source_decorator.dart b/lib/schedule/service/isolate_schedule_source_decorator.dart index 14e97f87..8b62bf85 100644 --- a/lib/schedule/service/isolate_schedule_source_decorator.dart +++ b/lib/schedule/service/isolate_schedule_source_decorator.dart @@ -27,9 +27,8 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { // Use the cancellation token to send a cancel message. // The isolate then uses a new instance to cancel the request - cancellationToken!.setCancellationCallback(() { - _sendPort!.send({"type": "cancel"}); - }); + cancellationToken!.cancellationCallback = + () => _sendPort!.send({"type": "cancel"}); _sendPort!.send({ "type": "execute", @@ -43,7 +42,7 @@ class IsolateScheduleSourceDecorator extends ScheduleSource { ScheduleQueryFailedException? potentialException; final subscription = _isolateToMain!.listen((result) { - cancellationToken.setCancellationCallback(null); + cancellationToken.cancellationCallback = null; // TODO: [Leptopoda] validate changes if (result == null || result is! ScheduleQueryResult) { diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index 42e1c199..8e1103bb 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -28,16 +28,18 @@ class MannheimCourseScraper { } Future _makeRequest( - Uri uri, CancellationToken cancellationToken,) async { + Uri uri, + CancellationToken cancellationToken, + ) async { final requestCancellationToken = http.CancellationToken(); try { - cancellationToken.setCancellationCallback(() { - requestCancellationToken.cancel(); - }); + cancellationToken.cancellationCallback = requestCancellationToken.cancel; - final response = await http.HttpClientHelper.get(uri, - cancelToken: requestCancellationToken,); + final response = await http.HttpClientHelper.get( + uri, + cancelToken: requestCancellationToken, + ); if (response == null && !requestCancellationToken.isCanceled) { throw ServiceRequestFailed("Http request failed!"); @@ -50,7 +52,7 @@ class MannheimCourseScraper { if (!requestCancellationToken.isCanceled) rethrow; throw ServiceRequestFailed("Http request failed!"); } finally { - cancellationToken.setCancellationCallback(null); + cancellationToken.cancellationCallback = null; } } } diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index 4a848ebe..5b3a0062 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -11,17 +11,16 @@ import 'package:http_client_helper/http_client_helper.dart' as http; class RaplaScheduleSource extends ScheduleSource { final RaplaResponseParser responseParser = RaplaResponseParser(); - String? raplaUrl; + String raplaUrl; - RaplaScheduleSource({this.raplaUrl}); - - void setEndpointUrl(String url) { - raplaUrl = url; - } + RaplaScheduleSource({required this.raplaUrl}); @override - Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken,]) async { + Future querySchedule( + DateTime? from, + DateTime? to, [ + CancellationToken? cancellationToken, + ]) async { DateTime current = toDayOfWeek(from, DateTime.monday)!; cancellationToken ??= CancellationToken(); @@ -31,10 +30,11 @@ class RaplaScheduleSource extends ScheduleSource { var didChangeMonth = false; - while ((to!.isAfter(current) && !cancellationToken.isCancelled()) || + while ((to!.isAfter(current) && !cancellationToken.isCancelled) || didChangeMonth) { try { - final weekSchedule = await _fetchRaplaSource(current, cancellationToken); + final weekSchedule = + await _fetchRaplaSource(current, cancellationToken); if (weekSchedule?.schedule != null) { schedule.merge(weekSchedule!.schedule); @@ -62,7 +62,7 @@ class RaplaScheduleSource extends ScheduleSource { didChangeMonth = currentMonth != nextMonth; } - if (cancellationToken.isCancelled()) throw OperationCancelledException(); + cancellationToken.throwIfCancelled(); schedule = schedule.trim(from, to); @@ -100,18 +100,19 @@ class RaplaScheduleSource extends ScheduleSource { /// - ?user=XXXXXXXXXX&file=XXXXX&page=XXXXXX /// Uri _buildRequestUri(DateTime date) { - if (!raplaUrl!.startsWith("http://") && !raplaUrl!.startsWith("https://")) { + if (!raplaUrl.startsWith("http://") && !raplaUrl.startsWith("https://")) { raplaUrl = "http://$raplaUrl"; } - final uri = Uri.parse(raplaUrl!); + final uri = Uri.parse(raplaUrl); final bool hasKeyParameter = uri.queryParameters.containsKey("key"); final bool hasUserParameter = uri.queryParameters.containsKey("user"); final bool hasFileParameter = uri.queryParameters.containsKey("file"); final bool hasPageParameter = uri.queryParameters.containsKey("page"); - final bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); + final bool hasAllocatableId = + uri.queryParameters.containsKey("allocatable_id"); final bool hasSalt = uri.queryParameters.containsKey("salt"); final Map parameters = {}; @@ -133,7 +134,7 @@ class RaplaScheduleSource extends ScheduleSource { parameters["month"] = date.month.toString(); parameters["year"] = date.year.toString(); - if (raplaUrl!.startsWith("https")) { + if (raplaUrl.startsWith("https")) { return Uri.https(uri.authority, uri.path, parameters); } else { return Uri.http(uri.authority, uri.path, parameters); @@ -141,16 +142,18 @@ class RaplaScheduleSource extends ScheduleSource { } Future _makeRequest( - Uri uri, CancellationToken cancellationToken,) async { + Uri uri, + CancellationToken cancellationToken, + ) async { final requestCancellationToken = http.CancellationToken(); try { - cancellationToken.setCancellationCallback(() { - requestCancellationToken.cancel(); - }); + cancellationToken.cancellationCallback = requestCancellationToken.cancel; - final response = await http.HttpClientHelper.get(uri, - cancelToken: requestCancellationToken,); + final response = await http.HttpClientHelper.get( + uri, + cancelToken: requestCancellationToken, + ); if (response == null && !requestCancellationToken.isCanceled) { throw ServiceRequestFailed("Http request failed!"); @@ -162,7 +165,7 @@ class RaplaScheduleSource extends ScheduleSource { } catch (ex) { if (!requestCancellationToken.isCanceled) rethrow; } finally { - cancellationToken.setCancellationCallback(null); + cancellationToken.cancellationCallback = null; } return null; @@ -170,7 +173,7 @@ class RaplaScheduleSource extends ScheduleSource { @override bool canQuery() { - return isValidUrl(raplaUrl!); + return isValidUrl(raplaUrl); } static bool isValidUrl(String url) { @@ -187,7 +190,8 @@ class RaplaScheduleSource extends ScheduleSource { final bool hasFileParameter = uri.queryParameters.containsKey("file"); final bool hasPageParameter = uri.queryParameters.containsKey("page"); - final bool hasAllocatableId = uri.queryParameters.containsKey("allocatable_id"); + final bool hasAllocatableId = + uri.queryParameters.containsKey("allocatable_id"); final bool hasSalt = uri.queryParameters.containsKey("salt"); if (hasUserParameter && hasFileParameter && hasPageParameter) { diff --git a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart index 0aa53ff5..03e79420 100644 --- a/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/weekly_schedule_view_model.dart @@ -249,7 +249,7 @@ class WeeklyScheduleViewModel extends BaseViewModel { _errorResetTimer = null; } - void setQueryFailedCallback(VoidCallback callback) { + set queryFailedCallback(VoidCallback callback) { _queryFailedCallback = callback; } } diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index 27be2db3..b1501086 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -81,7 +81,7 @@ class _WeeklySchedulePageState extends State { viewModel = Provider.of(context); viewModel.ensureUpdateNowTimerRunning(); - viewModel.setQueryFailedCallback(_showQueryFailedSnackBar); + viewModel.queryFailedCallback =_showQueryFailedSnackBar; return PropertyChangeProvider( value: viewModel, diff --git a/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart b/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart index 25e74c15..ab609ca8 100644 --- a/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart +++ b/lib/ui/onboarding/viewmodels/dualis_login_view_model.dart @@ -18,11 +18,11 @@ class DualisLoginViewModel extends OnboardingStepViewModel { DualisLoginViewModel(this.preferencesProvider, this.dualisService); @override - void setIsValid(bool isValid) { + set isValid(bool value) { if (credentials == null) { - super.setIsValid(false); + super.isValid = false; } else { - super.setIsValid(isValid); + super.isValid = value; } } @@ -34,9 +34,9 @@ class DualisLoginViewModel extends OnboardingStepViewModel { _loginSuccess = await dualisService.login(credentials) == LoginResult.LoggedIn; - setIsValid(_loginSuccess); + isValid = _loginSuccess; } catch (ex) { - setIsValid(false); + isValid = false; } finally { _isLoading = false; } diff --git a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart index ea3b3d7b..dda3d155 100644 --- a/lib/ui/onboarding/viewmodels/ical_url_view_model.dart +++ b/lib/ui/onboarding/viewmodels/ical_url_view_model.dart @@ -15,7 +15,7 @@ class IcalUrlViewModel extends OnboardingStepViewModel { IcalUrlViewModel(this.preferencesProvider, this.scheduleSourceProvider); - void setUrl(String? url) { + set url(String? url) { _url = url; notifyListeners("url"); @@ -26,7 +26,7 @@ class IcalUrlViewModel extends OnboardingStepViewModel { void _validateUrl() { urlHasError = !IcalScheduleSource.isValidUrl(_url); - setIsValid(!urlHasError); + isValid = !urlHasError; notifyListeners("urlHasError"); } @@ -35,7 +35,7 @@ class IcalUrlViewModel extends OnboardingStepViewModel { final ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text != null) { - setUrl(data!.text); + url = data!.text; } } diff --git a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart index 809e0992..30f17349 100644 --- a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart +++ b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart @@ -21,7 +21,7 @@ class MannheimViewModel extends OnboardingStepViewModel { List? get courses => _courses; MannheimViewModel(this._scheduleSourceProvider) { - setIsValid(false); + isValid = false; loadCourses(); } @@ -49,7 +49,7 @@ class MannheimViewModel extends OnboardingStepViewModel { _selectedCourse = course; } - setIsValid(_selectedCourse != null); + isValid = _selectedCourse != null; } @override diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart index fba1ca43..c6be6b65 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart @@ -4,8 +4,7 @@ abstract class OnboardingStepViewModel extends BaseViewModel { bool _isValid = false; bool get isValid => _isValid; - // TODO: [Leptopoda] kinda redundant now that we have null safety?¿ - void setIsValid(bool isValid) { + set isValid(bool isValid) { _isValid = isValid; notifyListeners("isValid"); } diff --git a/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart b/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart index bb15520d..cd4072af 100644 --- a/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart +++ b/lib/ui/onboarding/viewmodels/rapla_url_view_model.dart @@ -29,7 +29,7 @@ class RaplaUrlViewModel extends OnboardingStepViewModel { void _validateUrl() { urlHasError = !RaplaScheduleSource.isValidUrl(_raplaUrl!); - setIsValid(!urlHasError); + isValid = !urlHasError; notifyListeners("urlHasError"); } diff --git a/lib/ui/onboarding/viewmodels/select_source_view_model.dart b/lib/ui/onboarding/viewmodels/select_source_view_model.dart index 8310a6f3..ad94586d 100644 --- a/lib/ui/onboarding/viewmodels/select_source_view_model.dart +++ b/lib/ui/onboarding/viewmodels/select_source_view_model.dart @@ -9,14 +9,14 @@ class SelectSourceViewModel extends OnboardingStepViewModel { ScheduleSourceType get scheduleSourceType => _scheduleSourceType; SelectSourceViewModel(this._preferencesProvider) { - setIsValid(true); + isValid = true; } void setScheduleSourceType(ScheduleSourceType? type) { if (type == null) return; _scheduleSourceType = type; - setIsValid(true); + isValid = true; notifyListeners("scheduleSourceType"); } diff --git a/lib/ui/onboarding/widgets/dualis_login_page.dart b/lib/ui/onboarding/widgets/dualis_login_page.dart index 4944c673..8b0d2477 100644 --- a/lib/ui/onboarding/widgets/dualis_login_page.dart +++ b/lib/ui/onboarding/widgets/dualis_login_page.dart @@ -26,8 +26,11 @@ class _DualisLoginCredentialsPageState @override Widget build(BuildContext context) { return PropertyChangeConsumer( - builder: (BuildContext context, OnboardingStepViewModel? base, - Set? _,) { + builder: ( + BuildContext context, + OnboardingStepViewModel? base, + Set? _, + ) { final viewModel = base as DualisLoginViewModel?; final credentials = viewModel?.credentials; @@ -39,12 +42,14 @@ class _DualisLoginCredentialsPageState final widgets = []; widgets.addAll(_buildHeader()); - widgets.add(LoginCredentialsWidget( - controller: _controller, - onSubmitted: () async { - await _testCredentials(viewModel); - }, - ),); + widgets.add( + LoginCredentialsWidget( + controller: _controller, + onSubmitted: () async { + await _testCredentials(viewModel); + }, + ), + ); widgets.add(_buildTestCredentialsButton(viewModel)); return Column( @@ -66,7 +71,7 @@ class _DualisLoginCredentialsPageState mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( - child: viewModel?.isValid ?? false + child: viewModel?.isValid == false ? Text( L.of(context).onboardingDualisWrongCredentials, textAlign: TextAlign.start, @@ -74,26 +79,31 @@ class _DualisLoginCredentialsPageState ) : Container(), ), - if (viewModel?.isLoading ?? false) const SizedBox( - width: 16, - height: 16, - child: CircularProgressIndicator( - strokeWidth: 1, - ), - ) else viewModel?.loginSuccess ?? false - ? const Icon( - Icons.check, - color: Colors.green, - ) - : TextButton( - onPressed: () async { - await _testCredentials(viewModel); - }, - child: Text(L + if (viewModel?.isLoading ?? false) + const SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator( + strokeWidth: 1, + ), + ) + else + viewModel?.loginSuccess ?? false + ? const Icon( + Icons.check, + color: Colors.green, + ) + : TextButton( + onPressed: () async { + await _testCredentials(viewModel); + }, + child: Text( + L .of(context) .onboardingDualisTestButton - .toUpperCase(),), + .toUpperCase(), ), + ), ], ), ), diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index d7707fee..9a22ddd8 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -64,7 +64,7 @@ class _IcalUrlPageState extends State { : null, hintText: L.of(context).onboardingIcalUrlHint, ), - onChanged: viewModel?.setUrl, + onChanged: (v) => viewModel?.url = v, ), ), TextButton.icon( diff --git a/test/rapla_service_test.dart b/test/rapla_service_test.dart index 870a66ee..2fa06c74 100644 --- a/test/rapla_service_test.dart +++ b/test/rapla_service_test.dart @@ -3,9 +3,12 @@ import 'package:test/test.dart'; void main() { test('debugging', () async { - final source = RaplaScheduleSource(); - source.setEndpointUrl( - "https://rapla.dhbw-stuttgart.de/rapla?key=txB1FOi5xd1wUJBWuX8lJhGDUgtMSFmnKLgAG_NVMhCn4AzVqTBQM-yMcTKkIDCa",); + // ignore: unused_local_variable + final source = RaplaScheduleSource( + raplaUrl: + "https://rapla.dhbw-stuttgart.de/rapla?key=txB1FOi5xd1wUJBWuX8lJhGDUgtMSFmnKLgAG_NVMhCn4AzVqTBQM-yMcTKkIDCa", + ); + //var schedule = await source.querySchedule( // DateTime(2020, 01, 20), DateTime(2020, 01, 25)); //print(schedule); From 9e5429a51a0afc7e6950e591d2c182fc1f328e7a Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 10:18:18 +0200 Subject: [PATCH 24/37] removed unused variable --- lib/common/ui/custom_icons_icons.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/common/ui/custom_icons_icons.dart b/lib/common/ui/custom_icons_icons.dart index 5ea374e7..72be9796 100644 --- a/lib/common/ui/custom_icons_icons.dart +++ b/lib/common/ui/custom_icons_icons.dart @@ -20,11 +20,9 @@ import 'package:flutter/widgets.dart'; class CustomIcons { - CustomIcons._(); + const CustomIcons._(); static const _kFontFam = 'CustomIcons'; - static const dynamic _kFontPkg = null; - static const IconData logout = - IconData(0xe800, fontFamily: _kFontFam); + static const IconData logout = IconData(0xe800, fontFamily: _kFontFam); } From 26d91600075fde1fe365fc498399fc1e6dbe3977 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 10:47:18 +0200 Subject: [PATCH 25/37] fix use_string_buffers --- lib/common/util/string_utils.dart | 17 +---------------- .../service/rapla/rapla_parsing_utils.dart | 6 ++++-- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/lib/common/util/string_utils.dart b/lib/common/util/string_utils.dart index e67cf3e8..e55a777b 100644 --- a/lib/common/util/string_utils.dart +++ b/lib/common/util/string_utils.dart @@ -1,19 +1,4 @@ -// TODO: [Leptopoda] deprecate as dart has it's own function (at least for the above) - -String concatStringList(List list, String separator) { - var result = ""; - - for (final element in list) { - result += element + separator; - } - - if (result != "") { - result = result.substring(0, result.length - separator.length); - } - - return result; -} - +// TODO: [Leptopoda] deprecate this as propper localization does already have interpolation String interpolate(String string, List params) { String result = string; for (int i = 0; i < params.length; i++) { diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index ff17aaaa..fc502465 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -1,4 +1,3 @@ -import 'package:dhbwstudentapp/common/util/string_utils.dart'; import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; import 'package:html/dom.dart'; @@ -202,7 +201,10 @@ class RaplaParsingUtils { resourcesList.add(resource.innerHtml); } - return concatStringList(resourcesList, ", "); + final buffer = StringBuffer(); + buffer.writeAll(resourcesList, ", "); + + return buffer.toString(); } static String readYearOrThrow(Document document) { From 8f4ee2676445f776b4150f46a6aec1c0f19386d3 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 10:43:01 +0200 Subject: [PATCH 26/37] fix leading_newlines_in_multiline_strings --- lib/common/data/sql_scripts.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/common/data/sql_scripts.dart b/lib/common/data/sql_scripts.dart index 52100970..22c79fa9 100644 --- a/lib/common/data/sql_scripts.dart +++ b/lib/common/data/sql_scripts.dart @@ -1,3 +1,5 @@ +// ignore_for_file: leading_newlines_in_multiline_strings + import 'dart:core'; class SqlScripts { From 6cbc25511497397167b532545a63212ba16cc8f7 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 10:44:36 +0200 Subject: [PATCH 27/37] fix use_decorated_box --- .../ui/calendar_export_page.dart | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index a6017258..1f20edbd 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -114,28 +114,25 @@ class _CalendarExportPageState extends State { value: viewModel, child: Column( children: [ - Container( - decoration: widget.isCalendarSyncEnabled ? null : null, - child: ListTile( - enabled: widget.isCalendarSyncEnabled ? true : false, - title: Text( - L.of(context).calendarSyncPageEndSync.toUpperCase(), - textAlign: TextAlign.center, - style: TextStyle( - color: widget.isCalendarSyncEnabled - ? ColorPalettes.main - : Theme.of(context).disabledColor, - fontSize: 14, - ), + ListTile( + enabled: widget.isCalendarSyncEnabled, + title: Text( + L.of(context).calendarSyncPageEndSync.toUpperCase(), + textAlign: TextAlign.center, + style: TextStyle( + color: widget.isCalendarSyncEnabled + ? ColorPalettes.main + : Theme.of(context).disabledColor, + fontSize: 14, ), - onTap: () async { - KiwiContainer() - .resolve() - .setIsCalendarSyncEnabled(false); - viewModel.resetSelectedCalendar(); - Navigator.of(context).pop(); - }, ), + onTap: () async { + KiwiContainer() + .resolve() + .setIsCalendarSyncEnabled(false); + viewModel.resetSelectedCalendar(); + Navigator.of(context).pop(); + }, ), const Divider( height: 1, @@ -200,7 +197,7 @@ class _CalendarExportPageState extends State { child: CircularProgressIndicator(), ), ) - : Container( + : DecoratedBox( decoration: !viewModel.canExport ? BoxDecoration( color: Theme.of(context).colorScheme.background, From 421f678ad3a89695d2209fa9bfef70322b300932 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 10:46:22 +0200 Subject: [PATCH 28/37] fix no_leading_underscores_for_local_identifiers --- lib/common/iap/in_app_purchase_manager.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/iap/in_app_purchase_manager.dart b/lib/common/iap/in_app_purchase_manager.dart index 87c59283..cfefe765 100644 --- a/lib/common/iap/in_app_purchase_manager.dart +++ b/lib/common/iap/in_app_purchase_manager.dart @@ -13,9 +13,9 @@ class InAppPurchaseManager { final Map> purchaseCallbacks = {}; InAppPurchaseManager( - PreferencesProvider _preferencesProvider, + PreferencesProvider preferencesProvider, this._widgetHelper, - ) : _inAppPurchaseHelper = InAppPurchaseHelper(_preferencesProvider) { + ) : _inAppPurchaseHelper = InAppPurchaseHelper(preferencesProvider) { _initialize(); } From eb7fd666fdca4f1c0227deeb8c9bb2e5e5e67db3 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 10:48:34 +0200 Subject: [PATCH 29/37] fix prefer_constructors_over_static_methods --- lib/dualis/model/exam_grade.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dualis/model/exam_grade.dart b/lib/dualis/model/exam_grade.dart index 0759ddd1..f3ba7598 100644 --- a/lib/dualis/model/exam_grade.dart +++ b/lib/dualis/model/exam_grade.dart @@ -23,7 +23,7 @@ class ExamGrade { ExamGrade.graded(this.gradeValue) : state = ExamGradeState.Graded; - static ExamGrade fromString(String? grade) { + factory ExamGrade.fromString(String? grade) { if (grade == "noch nicht gesetzt" || grade == "") { return ExamGrade.notGraded(); } From b68400206c8f03717d438a14a8d7c6b74a9e5694 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Fri, 14 Oct 2022 10:55:46 +0200 Subject: [PATCH 30/37] fix error catching stuff --- lib/dualis/service/session.dart | 2 ++ lib/native/widget/android_widget_helper.dart | 5 ++--- lib/schedule/service/ical/ical_schedule_source.dart | 1 + lib/schedule/service/mannheim/mannheim_course_scraper.dart | 1 + lib/schedule/service/rapla/rapla_schedule_source.dart | 1 + 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index 146ac27c..8885881b 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -60,6 +60,7 @@ class Session { _updateCookie(response!); return response; + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { @@ -117,6 +118,7 @@ class Session { _updateCookie(response!); return response; + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { diff --git a/lib/native/widget/android_widget_helper.dart b/lib/native/widget/android_widget_helper.dart index f49b4ca5..68ebf490 100644 --- a/lib/native/widget/android_widget_helper.dart +++ b/lib/native/widget/android_widget_helper.dart @@ -5,8 +5,7 @@ import 'package:flutter/services.dart'; /// WidgetHelper which calls native code to control the widget on android /// class AndroidWidgetHelper implements WidgetHelper { - static const platform = - MethodChannel('de.bennik2000.dhbwstudentapp/widget'); + static const platform = MethodChannel('de.bennik2000.dhbwstudentapp/widget'); @override Future disableWidget() async { @@ -26,7 +25,7 @@ class AndroidWidgetHelper implements WidgetHelper { Future requestWidgetRefresh() async { try { await platform.invokeMethod('requestWidgetRefresh'); - } on PlatformException {} + } on PlatformException catch (_) {} } @override diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index 8229e0fb..faf6ecab 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -64,6 +64,7 @@ class IcalScheduleSource extends ScheduleSource { } return response; + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index 8e1103bb..8a8455c5 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -46,6 +46,7 @@ class MannheimCourseScraper { } return response!; + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index 5b3a0062..36465459 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -160,6 +160,7 @@ class RaplaScheduleSource extends ScheduleSource { } return response; + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { From bfe0250aabd28caab22a99c7f437fbd8895f8c3a Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sun, 16 Oct 2022 13:32:04 +0200 Subject: [PATCH 31/37] format code --- lib/common/appstart/app_initializer.dart | 7 +- .../appstart/localization_initialize.dart | 10 +- lib/common/appstart/service_injector.dart | 84 +++++++------ .../background/background_work_scheduler.dart | 10 +- lib/common/data/database_path_provider.dart | 3 +- .../preferences/preferences_provider.dart | 8 +- .../preferences/secure_storage_access.dart | 2 +- lib/common/logging/crash_reporting.dart | 3 +- lib/common/ui/colors.dart | 8 +- lib/common/ui/donate_to_developer_dialog.dart | 27 ++-- lib/common/ui/notification_api.dart | 12 +- lib/common/ui/rate_in_store_dialog.dart | 5 +- lib/common/ui/widget_help_dialog.dart | 7 +- lib/common/ui/widgets/dots_indicator.dart | 8 +- lib/common/util/date_utils.dart | 4 +- .../data/date_entry_repository.dart | 14 ++- .../service/parsing/all_dates_extract.dart | 13 +- .../ui/date_management_page.dart | 81 ++++++------ .../date_management_view_model.dart | 8 +- .../ui/widgets/date_detail_bottom_sheet.dart | 16 ++- .../cache_dualis_service_decorator.dart | 3 +- lib/dualis/service/dualis_authentication.dart | 12 +- lib/dualis/service/dualis_service.dart | 25 ++-- .../service/fake_data_dualis_scraper.dart | 16 ++- .../exams_from_module_details_extract.dart | 16 +-- ...dules_from_course_result_page_extract.dart | 4 +- ...sters_from_course_result_page_extract.dart | 16 ++- .../parsing/urls_from_main_page_extract.dart | 3 +- lib/dualis/service/session.dart | 4 +- lib/dualis/ui/dualis_page.dart | 3 +- lib/dualis/ui/login/dualis_login_page.dart | 3 +- .../viewmodels/study_grades_view_model.dart | 5 +- .../useful_information_page.dart | 12 +- lib/main.dart | 8 +- lib/native/widget/ios_widget_helper.dart | 3 +- .../background/calendar_synchronizer.dart | 31 +++-- .../business/schedule_diff_calculator.dart | 45 ++++--- lib/schedule/business/schedule_filter.dart | 3 +- .../data/schedule_entry_repository.dart | 8 +- ...schedule_query_information_repository.dart | 11 +- lib/schedule/model/schedule_entry.dart | 17 +-- ...rror_report_schedule_source_decorator.dart | 7 +- .../service/ical/ical_schedule_source.dart | 2 +- .../mannheim_course_response_parser.dart | 14 ++- .../mannheim/mannheim_course_scraper.dart | 2 +- .../service/rapla/rapla_schedule_source.dart | 2 +- lib/schedule/service/schedule_source.dart | 9 +- .../widgets/daily_schedule_entry_widget.dart | 10 +- .../next_day_information_notification.dart | 5 +- .../ui/schedule_navigation_entry.dart | 32 ++--- lib/schedule/ui/schedule_page.dart | 2 +- .../filter/filter_view_model.dart | 7 +- .../filter/schedule_filter_page.dart | 20 +-- .../schedule_entry_detail_bottom_sheet.dart | 41 ++++--- .../weeklyschedule/weekly_schedule_page.dart | 27 ++-- .../weeklyschedule/widgets/schedule_grid.dart | 34 ++++-- .../widgets/schedule_past_overlay.dart | 15 +-- .../widgets/schedule_widget.dart | 43 ++++--- .../ui/widgets/enter_rapla_url_dialog.dart | 2 +- lib/schedule/ui/widgets/enter_url_dialog.dart | 7 +- lib/ui/banner_widget.dart | 12 +- lib/ui/main_page.dart | 10 +- lib/ui/navigation_drawer.dart | 8 +- lib/ui/onboarding/onboarding_page.dart | 7 +- .../viewmodels/onboarding_view_model.dart | 9 +- lib/ui/onboarding/widgets/ical_url_page.dart | 9 +- lib/ui/onboarding/widgets/mannheim_page.dart | 7 +- .../widgets/onboarding_page_background.dart | 62 +++++----- lib/ui/onboarding/widgets/rapla_url_page.dart | 9 +- .../widgets/select_source_page.dart | 9 +- lib/ui/settings/settings_page.dart | 79 +++++++----- .../viewmodels/settings_view_model.dart | 9 +- .../parsing/all_dates_extract_test.dart | 5 +- .../parsing/all_modules_extract_test.dart | 5 +- .../parsing/dualis_timeout_extract_test.dart | 10 +- ...xams_from_module_details_extract_test.dart | 5 +- ..._from_course_result_page_extract_test.dart | 15 ++- .../monthly_schedule_extract_test.dart | 5 +- ..._from_course_result_page_extract_test.dart | 17 ++- ...rom_student_results_page_extract_test.dart | 5 +- .../urls_from_main_page_extract_test.dart | 23 ++-- .../service/ical/ical_parser_test.dart | 5 +- .../mannheim_course_response_parser_test.dart | 5 +- .../rapla/rapla_response_parser_test.dart | 115 +++++++++++------- 84 files changed, 792 insertions(+), 512 deletions(-) diff --git a/lib/common/appstart/app_initializer.dart b/lib/common/appstart/app_initializer.dart index fe5d9581..7968c307 100644 --- a/lib/common/appstart/app_initializer.dart +++ b/lib/common/appstart/app_initializer.dart @@ -63,9 +63,10 @@ Future initializeApp(bool isBackground) async { // Callback-Function for synchronizing the device calendar with the schedule, when schedule is updated final CalendarSynchronizer calendarSynchronizer = CalendarSynchronizer( - KiwiContainer().resolve(), - KiwiContainer().resolve(), - KiwiContainer().resolve(),); + KiwiContainer().resolve(), + KiwiContainer().resolve(), + KiwiContainer().resolve(), + ); calendarSynchronizer.registerSynchronizationCallback(); calendarSynchronizer.scheduleSyncInAFewSeconds(); diff --git a/lib/common/appstart/localization_initialize.dart b/lib/common/appstart/localization_initialize.dart index f091c5d2..133cde4f 100644 --- a/lib/common/appstart/localization_initialize.dart +++ b/lib/common/appstart/localization_initialize.dart @@ -23,10 +23,12 @@ class LocalizationInitialize { LocalizationInitialize.fromPreferences(this._preferencesProvider); Future setupLocalizations() async { - final localization = L(Locale( - _languageCode ?? - (await _preferencesProvider?.getLastUsedLanguageCode() ?? "en"), - ),); + final localization = L( + Locale( + _languageCode ?? + (await _preferencesProvider?.getLastUsedLanguageCode() ?? "en"), + ), + ); KiwiContainer().registerInstance(localization); } } diff --git a/lib/common/appstart/service_injector.dart b/lib/common/appstart/service_injector.dart index 2980bdf2..77adf9a3 100644 --- a/lib/common/appstart/service_injector.dart +++ b/lib/common/appstart/service_injector.dart @@ -29,45 +29,61 @@ void injectServices(bool isBackground) { if (_isInjected) return; final KiwiContainer c = KiwiContainer(); - c.registerInstance(PreferencesProvider( - PreferencesAccess(), - SecureStorageAccess(), - ),); + c.registerInstance( + PreferencesProvider( + PreferencesAccess(), + SecureStorageAccess(), + ), + ); c.registerInstance(DatabaseAccess()); - c.registerInstance(ScheduleEntryRepository( - c.resolve(), - ),); - c.registerInstance(ScheduleFilterRepository( - c.resolve(), - ),); - c.registerInstance(ScheduleQueryInformationRepository( - c.resolve(), - ),); - c.registerInstance(ScheduleSourceProvider( - c.resolve(), - isBackground, - c.resolve(), - c.resolve(), - ),); - c.registerInstance(ScheduleProvider( - c.resolve(), - c.resolve(), - c.resolve(), - c.resolve(), - c.resolve(), - ),); + c.registerInstance( + ScheduleEntryRepository( + c.resolve(), + ), + ); + c.registerInstance( + ScheduleFilterRepository( + c.resolve(), + ), + ); + c.registerInstance( + ScheduleQueryInformationRepository( + c.resolve(), + ), + ); + c.registerInstance( + ScheduleSourceProvider( + c.resolve(), + isBackground, + c.resolve(), + c.resolve(), + ), + ); + c.registerInstance( + ScheduleProvider( + c.resolve(), + c.resolve(), + c.resolve(), + c.resolve(), + c.resolve(), + ), + ); c.registerInstance( FakeAccountDualisScraperDecorator(DualisScraper()), ); - c.registerInstance(CacheDualisServiceDecorator( - DualisServiceImpl( - c.resolve(), + c.registerInstance( + CacheDualisServiceDecorator( + DualisServiceImpl( + c.resolve(), + ), ), - ),); - c.registerInstance(DateEntryProvider( - DateManagementService(), - DateEntryRepository(c.resolve()), - ),); + ); + c.registerInstance( + DateEntryProvider( + DateManagementService(), + DateEntryRepository(c.resolve()), + ), + ); c.registerInstance(WidgetHelper()); c.registerInstance(ListDateEntries30d(List.empty(growable: true))); diff --git a/lib/common/background/background_work_scheduler.dart b/lib/common/background/background_work_scheduler.dart index b551428e..f84c0312 100644 --- a/lib/common/background/background_work_scheduler.dart +++ b/lib/common/background/background_work_scheduler.dart @@ -23,7 +23,10 @@ class BackgroundWorkScheduler extends WorkSchedulerService { /// @override Future scheduleOneShotTaskIn( - Duration delay, String id, String name,) async { + Duration delay, + String id, + String name, + ) async { print( "Scheduling one shot task: $id. With a delay of ${delay.inMinutes} minutes.", ); @@ -103,7 +106,10 @@ class BackgroundWorkScheduler extends WorkSchedulerService { /// /// Entry point for when a background task is executed /// - static Future backgroundTaskMain(String taskId, Map? inputData) async { + static Future backgroundTaskMain( + String taskId, + Map? inputData, + ) async { try { print("Background task started: $taskId with data: $inputData"); diff --git a/lib/common/data/database_path_provider.dart b/lib/common/data/database_path_provider.dart index f6ba715e..d89ca77a 100644 --- a/lib/common/data/database_path_provider.dart +++ b/lib/common/data/database_path_provider.dart @@ -26,7 +26,8 @@ Future _getiOSDatabasePathAndMigrate( // copied to the new path assert(Platform.isIOS); - final Directory? groupDirectory = await AppGroupDirectory.getAppGroupDirectory( + final Directory? groupDirectory = + await AppGroupDirectory.getAppGroupDirectory( 'group.de.bennik2000.dhbwstudentapp', ); diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index c060facd..821d375b 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -61,7 +61,9 @@ class PreferencesProvider { Future setSelectedCalendar(Calendar? selectedCalendar) async { final selectedCalendarId = selectedCalendar?.id ?? ""; await _preferencesAccess.set( - 'SelectedCalendarId', selectedCalendarId,); + 'SelectedCalendarId', + selectedCalendarId, + ); } Future getSelectedCalendar() async { @@ -166,7 +168,9 @@ class PreferencesProvider { Future setLastViewedSemester(String? lastViewedSemester) async { if (lastViewedSemester == null) return; await _preferencesAccess.set( - LastViewedSemester, lastViewedSemester,); + LastViewedSemester, + lastViewedSemester, + ); } Future getLastViewedDateEntryDatabase() async { diff --git a/lib/common/data/preferences/secure_storage_access.dart b/lib/common/data/preferences/secure_storage_access.dart index d5d871f6..2f616d2e 100644 --- a/lib/common/data/preferences/secure_storage_access.dart +++ b/lib/common/data/preferences/secure_storage_access.dart @@ -8,6 +8,6 @@ class SecureStorageAccess { } Future get(String key) async { - return _secureStorage.read(key: key); + return _secureStorage.read(key: key); } } diff --git a/lib/common/logging/crash_reporting.dart b/lib/common/logging/crash_reporting.dart index 8aada3c5..901f6b27 100644 --- a/lib/common/logging/crash_reporting.dart +++ b/lib/common/logging/crash_reporting.dart @@ -7,6 +7,7 @@ Future reportException(dynamic ex, StackTrace? trace) async { await FirebaseCrashlytics.instance.recordError(ex, trace); } else { print( - "Did not report exception (not in release mode) to crashlytics: $ex with stack trace $trace",); + "Did not report exception (not in release mode) to crashlytics: $ex with stack trace $trace", + ); } } diff --git a/lib/common/ui/colors.dart b/lib/common/ui/colors.dart index 831b9ea0..5f870035 100644 --- a/lib/common/ui/colors.dart +++ b/lib/common/ui/colors.dart @@ -92,10 +92,12 @@ class ColorPalettes { return themeData.copyWith( snackBarTheme: themeData.snackBarTheme.copyWith( - backgroundColor: isDark ? const Color(0xff363635) : const Color(0xfffafafa), + backgroundColor: + isDark ? const Color(0xff363635) : const Color(0xfffafafa), contentTextStyle: themeData.textTheme.bodyText1!.copyWith( - color: - isDark ? const Color(0xffe4e4e4) : themeData.textTheme.bodyText1!.color, + color: isDark + ? const Color(0xffe4e4e4) + : themeData.textTheme.bodyText1!.color, ), ), textButtonTheme: TextButtonThemeData( diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index 0d7ebf76..dca41ffc 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -28,7 +28,7 @@ class DonateToDeveloperDialog { } Future _showDialog(BuildContext context) async { - return showDialog( + return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { @@ -41,19 +41,20 @@ class DonateToDeveloperDialog { mainAxisSize: MainAxisSize.min, children: [ Padding( - padding: const EdgeInsets.all(24), - child: Column( - children: [ - Text(L.of(context).donateDialogMessage), - const Padding( - padding: EdgeInsets.fromLTRB(0, 32, 0, 0), - child: Icon( - Icons.free_breakfast_outlined, - size: 60, - ), + padding: const EdgeInsets.all(24), + child: Column( + children: [ + Text(L.of(context).donateDialogMessage), + const Padding( + padding: EdgeInsets.fromLTRB(0, 32, 0, 0), + child: Icon( + Icons.free_breakfast_outlined, + size: 60, ), - ], - ),), + ), + ], + ), + ), Padding( padding: const EdgeInsets.fromLTRB(24, 0, 24, 0), child: _buildButtonBar(context), diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index 9f9d5a17..d2338919 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -70,7 +70,11 @@ class NotificationApi { } Future onDidReceiveLocalNotification( - int id, String? title, String? body, String? payload,) => + int id, + String? title, + String? body, + String? payload, + ) => Future.value(); Future selectNotification(String? payload) => Future.value(); @@ -91,7 +95,11 @@ class VoidNotificationApi implements NotificationApi { @override Future onDidReceiveLocalNotification( - int id, String? title, String? body, String? payload,) { + int id, + String? title, + String? body, + String? payload, + ) { return Future.value(); } diff --git a/lib/common/ui/rate_in_store_dialog.dart b/lib/common/ui/rate_in_store_dialog.dart index d4f1dfc3..936b7612 100644 --- a/lib/common/ui/rate_in_store_dialog.dart +++ b/lib/common/ui/rate_in_store_dialog.dart @@ -28,7 +28,7 @@ class RateInStoreDialog { Future _showRateDialog(BuildContext context) async { await analytics.logEvent(name: "rateRequestShown"); - return showDialog( + return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { @@ -89,7 +89,8 @@ class RateInStoreDialog { await analytics.logEvent(name: "rateLater"); await _preferencesProvider.setNextRateInStoreLaunchCount( - RateInStoreLaunchAfter + _appLaunchCounter,); + RateInStoreLaunchAfter + _appLaunchCounter, + ); } Future _rateNow() async { diff --git a/lib/common/ui/widget_help_dialog.dart b/lib/common/ui/widget_help_dialog.dart index bd70a063..060428e0 100644 --- a/lib/common/ui/widget_help_dialog.dart +++ b/lib/common/ui/widget_help_dialog.dart @@ -24,7 +24,7 @@ class WidgetHelpDialog { } Future _showDialog(BuildContext context) async { - return showDialog( + return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { @@ -37,8 +37,9 @@ class WidgetHelpDialog { mainAxisSize: MainAxisSize.min, children: [ Padding( - padding: const EdgeInsets.all(24), - child: Text(L.of(context).widgetHelpDialogMessage),), + padding: const EdgeInsets.all(24), + child: Text(L.of(context).widgetHelpDialogMessage), + ), Padding( padding: const EdgeInsets.fromLTRB(24, 0, 24, 0), child: _buildButtonBar(context), diff --git a/lib/common/ui/widgets/dots_indicator.dart b/lib/common/ui/widgets/dots_indicator.dart index 20b33f46..8a89bd4c 100644 --- a/lib/common/ui/widgets/dots_indicator.dart +++ b/lib/common/ui/widgets/dots_indicator.dart @@ -4,9 +4,11 @@ class DotsIndicator extends StatelessWidget { final int numberSteps; final int currentStep; - const DotsIndicator( - {Key? key, required this.numberSteps, required this.currentStep,}) - : super(key: key); + const DotsIndicator({ + Key? key, + required this.numberSteps, + required this.currentStep, + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/common/util/date_utils.dart b/lib/common/util/date_utils.dart index f1530e48..7a8e2679 100644 --- a/lib/common/util/date_utils.dart +++ b/lib/common/util/date_utils.dart @@ -7,9 +7,7 @@ DateTime? toStartOfDay(DateTime? dateTime) { } DateTime? toStartOfMonth(DateTime? dateTime) { - return dateTime == null - ? null - : DateTime(dateTime.year, dateTime.month); + return dateTime == null ? null : DateTime(dateTime.year, dateTime.month); } DateTime? tomorrow(DateTime? dateTime) { diff --git a/lib/date_management/data/date_entry_repository.dart b/lib/date_management/data/date_entry_repository.dart index a3a81968..46c9c177 100644 --- a/lib/date_management/data/date_entry_repository.dart +++ b/lib/date_management/data/date_entry_repository.dart @@ -91,12 +91,14 @@ class DateEntryRepository { String? databaseName, String? year, ) async { - await _database.deleteWhere(DateEntryEntity.tableName(), - where: "databaseName=? AND year=?", - whereArgs: [ - databaseName, - year, - ],); + await _database.deleteWhere( + DateEntryEntity.tableName(), + where: "databaseName=? AND year=?", + whereArgs: [ + databaseName, + year, + ], + ); } List _rowsToDateEntries(List> rows) { diff --git a/lib/date_management/service/parsing/all_dates_extract.dart b/lib/date_management/service/parsing/all_dates_extract.dart index ca538104..bc48b192 100644 --- a/lib/date_management/service/parsing/all_dates_extract.dart +++ b/lib/date_management/service/parsing/all_dates_extract.dart @@ -57,12 +57,13 @@ class AllDatesExtract { ); return DateEntry( - comment: parts[4].trim(), - description: parts[0].trim(), - year: parts[1].trim(), - databaseName: databaseName, - start: date, - end: date,); + comment: parts[4].trim(), + description: parts[0].trim(), + year: parts[1].trim(), + databaseName: databaseName, + start: date, + end: date, + ); } DateTime? _parseDateTime(String date, String time) { diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index 3ce0f407..8ceb65cc 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -26,10 +26,11 @@ class DateManagementPage extends StatelessWidget { children: [ const Divider(), AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - child: viewModel.isLoading - ? const LinearProgressIndicator() - : Container(),), + duration: const Duration(milliseconds: 200), + child: viewModel.isLoading + ? const LinearProgressIndicator() + : Container(), + ), ], ), _buildBody(viewModel, context), @@ -50,15 +51,15 @@ class DateManagementPage extends StatelessWidget { _, ) => AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - child: Column( - key: - ValueKey(viewModel.dateSearchParameters.toString()), - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _buildAllDatesDataTable(model!, context), - ], - ),), + duration: const Duration(milliseconds: 200), + child: Column( + key: ValueKey(viewModel.dateSearchParameters.toString()), + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildAllDatesDataTable(model!, context), + ], + ), + ), ), ), Align( @@ -109,28 +110,33 @@ class DateManagementPage extends StatelessWidget { }, ), DataCell( - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - DateFormat.yMd(L.of(context).locale.languageCode) - .format(dateEntry.start), - style: Theme.of(context).textTheme.bodyText1, + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + DateFormat.yMd(L.of(context).locale.languageCode) + .format(dateEntry.start), + style: Theme.of(context).textTheme.bodyText1, + ), + // When the date entry has a time of 00:00 don't show it. + // It means the date entry is for the whole day + if (isAtMidnight(dateEntry.start)) + Container() + else + Padding( + padding: const EdgeInsets.fromLTRB(0, 4, 0, 0), + child: Text( + DateFormat.Hm(L.of(context).locale.languageCode) + .format(dateEntry.start), + ), ), - // When the date entry has a time of 00:00 don't show it. - // It means the date entry is for the whole day - if (isAtMidnight(dateEntry.start)) Container() else Padding( - padding: const EdgeInsets.fromLTRB(0, 4, 0, 0), - child: Text( - DateFormat.Hm(L.of(context).locale.languageCode) - .format(dateEntry.start), - ), - ), - ], - ), onTap: () { - showDateEntryDetailBottomSheet(context, dateEntry); - },), + ], + ), + onTap: () { + showDateEntryDetailBottomSheet(context, dateEntry); + }, + ), ], ), ); @@ -157,8 +163,11 @@ class DateManagementPage extends StatelessWidget { properties: const [ "updateFailed", ], - builder: (BuildContext context, DateManagementViewModel? model, - Set? properties,) => + builder: ( + BuildContext context, + DateManagementViewModel? model, + Set? properties, + ) => ErrorDisplay( show: model!.updateFailed, ), diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index 4b16334f..32296b9f 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -143,28 +143,28 @@ class DateManagementViewModel extends BaseViewModel { notifyListeners("allDates"); } - set showPassedDates(bool? value) { + set showPassedDates(bool? value) { if (value == null) return; _showPassedDates = value; notifyListeners("showPassedDates"); } - set showFutureDates(bool? value) { + set showFutureDates(bool? value) { if (value == null) return; _showFutureDates = value; notifyListeners("showFutureDates"); } - set currentDateDatabase(DateDatabase? database) { + set currentDateDatabase(DateDatabase? database) { _currentDateDatabase = database; notifyListeners("currentDateDatabase"); _preferencesProvider.setLastViewedDateEntryDatabase(database?.id); } - set currentSelectedYear(String? year) { + set currentSelectedYear(String? year) { if (year == null) return; _currentSelectedYear = year; diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index 36813cce..a883b54b 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -31,8 +31,9 @@ class DateDetailBottomSheet extends StatelessWidget { height: 8, width: 30, decoration: BoxDecoration( - color: colorSeparator(), - borderRadius: const BorderRadius.all(Radius.circular(4)),), + color: colorSeparator(), + borderRadius: const BorderRadius.all(Radius.circular(4)), + ), ), ), ), @@ -58,10 +59,13 @@ class DateDetailBottomSheet extends StatelessWidget { softWrap: true, style: Theme.of(context).textTheme.subtitle2, ), - if (isAtMidnight(dateEntry!.start)) Container() else Text( - time, - softWrap: true, - ), + if (isAtMidnight(dateEntry!.start)) + Container() + else + Text( + time, + softWrap: true, + ), ], ), ), diff --git a/lib/dualis/service/cache_dualis_service_decorator.dart b/lib/dualis/service/cache_dualis_service_decorator.dart index 0931f1f6..a0e4a178 100644 --- a/lib/dualis/service/cache_dualis_service_decorator.dart +++ b/lib/dualis/service/cache_dualis_service_decorator.dart @@ -64,7 +64,8 @@ class CacheDualisServiceDecorator extends DualisService { return Future.value(_allSemesterNamesCached); } - final allSemesterNames = await _service.querySemesterNames(cancellationToken); + final allSemesterNames = + await _service.querySemesterNames(cancellationToken); _allSemesterNamesCached = allSemesterNames; diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index a4a80b62..c1697443 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -153,7 +153,7 @@ class DualisAuthentication { final loginResult = await login(_credentials!, cancellationToken); if (loginResult == LoginResult.LoggedIn) { - return session.get( + return session.get( _fillUrlWithAuthToken(url), cancellationToken, ); @@ -197,7 +197,10 @@ class DualisAuthentication { final match = _tokenRegex.firstMatch(url); if (match != null) { return url.replaceRange( - match.start, match.end, "ARGUMENTS=-N$_authToken",); + match.start, + match.end, + "ARGUMENTS=-N$_authToken", + ); } return url; @@ -208,8 +211,9 @@ class DualisAuthentication { } Future loginWithPreviousCredentials( - CancellationToken cancellationToken,) async { + CancellationToken cancellationToken, + ) async { assert(_credentials != null); - return login(_credentials!, cancellationToken); + return login(_credentials!, cancellationToken); } } diff --git a/lib/dualis/service/dualis_service.dart b/lib/dualis/service/dualis_service.dart index 1603f2c0..22311637 100644 --- a/lib/dualis/service/dualis_service.dart +++ b/lib/dualis/service/dualis_service.dart @@ -51,7 +51,7 @@ class DualisServiceImpl extends DualisService { Credentials credentials, [ CancellationToken? cancellationToken, ]) async { - return _dualisScraper.login( + return _dualisScraper.login( credentials, cancellationToken, ); @@ -61,7 +61,7 @@ class DualisServiceImpl extends DualisService { Future queryStudyGrades([ CancellationToken? cancellationToken, ]) async { - return _dualisScraper.loadStudyGrades(cancellationToken); + return _dualisScraper.loadStudyGrades(cancellationToken); } @override @@ -83,18 +83,21 @@ class DualisServiceImpl extends DualisService { Future> queryAllModules([ CancellationToken? cancellationToken, ]) async { - final dualisModules = await _dualisScraper.loadAllModules(cancellationToken); + final dualisModules = + await _dualisScraper.loadAllModules(cancellationToken); final modules = []; for (final module in dualisModules) { - modules.add(Module( - [], - module.id, - module.name, - module.credits, - module.finalGrade, - module.state, - ),); + modules.add( + Module( + [], + module.id, + module.name, + module.credits, + module.finalGrade, + module.state, + ), + ); } return modules; } diff --git a/lib/dualis/service/fake_data_dualis_scraper.dart b/lib/dualis/service/fake_data_dualis_scraper.dart index 0435e044..90337eb9 100644 --- a/lib/dualis/service/fake_data_dualis_scraper.dart +++ b/lib/dualis/service/fake_data_dualis_scraper.dart @@ -20,8 +20,9 @@ class FakeDataDualisScraper implements DualisScraper { } @override - Future> loadAllModules( - [CancellationToken? cancellationToken,]) async { + Future> loadAllModules([ + CancellationToken? cancellationToken, + ]) async { await Future.delayed(const Duration(milliseconds: 200)); return Future.value([ @@ -81,15 +82,17 @@ class FakeDataDualisScraper implements DualisScraper { } @override - Future> loadSemesters( - [CancellationToken? cancellationToken,]) async { + Future> loadSemesters([ + CancellationToken? cancellationToken, + ]) async { await Future.delayed(const Duration(milliseconds: 200)); return Future.value([DualisSemester("SoSe2020", "", [])]); } @override Future loadStudyGrades( - CancellationToken? cancellationToken,) async { + CancellationToken? cancellationToken, + ) async { await Future.delayed(const Duration(milliseconds: 200)); return Future.value( StudyGrades( @@ -113,7 +116,8 @@ class FakeDataDualisScraper implements DualisScraper { @override Future loginWithPreviousCredentials( - CancellationToken cancellationToken,) async { + CancellationToken cancellationToken, + ) async { await Future.delayed(const Duration(milliseconds: 200)); _isLoggedIn = true; return Future.value(LoginResult.LoggedIn); diff --git a/lib/dualis/service/parsing/exams_from_module_details_extract.dart b/lib/dualis/service/parsing/exams_from_module_details_extract.dart index 5f8fb636..5e4abb4f 100644 --- a/lib/dualis/service/parsing/exams_from_module_details_extract.dart +++ b/lib/dualis/service/parsing/exams_from_module_details_extract.dart @@ -48,13 +48,15 @@ class ExamsFromModuleDetailsExtract { final name = tbdata[1].innerHtml; final grade = trimAndEscapeString(tbdata[3].innerHtml); - exams.add(DualisExam( - trimAndEscapeString(name), - trimAndEscapeString(currentModule), - ExamGrade.fromString(grade), - trimAndEscapeString(currentTry), - trimAndEscapeString(semester), - ),); + exams.add( + DualisExam( + trimAndEscapeString(name), + trimAndEscapeString(currentModule), + ExamGrade.fromString(grade), + trimAndEscapeString(currentTry), + trimAndEscapeString(semester), + ), + ); } return exams; diff --git a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart index 280ede50..3a540183 100644 --- a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart @@ -20,7 +20,9 @@ class ModulesFromCourseResultPageExtract { } List _extractModulesFromCourseResultPage( - String? body, String endpointUrl,) { + String? body, + String endpointUrl, + ) { final document = parse(body); final tableBodies = getElementByTagName(document, "tbody"); diff --git a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart index 49f4df2a..278d4e24 100644 --- a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart @@ -17,7 +17,9 @@ class SemestersFromCourseResultPageExtract { } List _extractSemestersFromCourseResults( - String? body, String endpointUrl,) { + String? body, + String endpointUrl, + ) { final page = parse(body); final semesterSelector = page.getElementById("semester"); @@ -40,11 +42,13 @@ class SemestersFromCourseResultPageExtract { detailsUrl = url + id!; } - semesters.add(DualisSemester( - name, - detailsUrl, - [], - ),); + semesters.add( + DualisSemester( + name, + detailsUrl, + [], + ), + ); } return semesters; diff --git a/lib/dualis/service/parsing/urls_from_main_page_extract.dart b/lib/dualis/service/parsing/urls_from_main_page_extract.dart index c707dcd5..9dad754f 100644 --- a/lib/dualis/service/parsing/urls_from_main_page_extract.dart +++ b/lib/dualis/service/parsing/urls_from_main_page_extract.dart @@ -25,7 +25,8 @@ class UrlsFromMainPageExtract { final courseResultsElement = getElementByClassName(document, "link000307"); final studentResultsElement = getElementByClassName(document, "link000310"); - final monthlyScheduleElement = getElementByClassName(document, "link000031"); + final monthlyScheduleElement = + getElementByClassName(document, "link000031"); final logoutElement = getElementById(document, "logoutButton"); dualisUrls.courseResultUrl = diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index 8885881b..a60f2e89 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -60,7 +60,7 @@ class Session { _updateCookie(response!); return response; - // ignore: avoid_catching_errors + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { @@ -118,7 +118,7 @@ class Session { _updateCookie(response!); return response; - // ignore: avoid_catching_errors + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { diff --git a/lib/dualis/ui/dualis_page.dart b/lib/dualis/ui/dualis_page.dart index 3491caa7..a5ddbf59 100644 --- a/lib/dualis/ui/dualis_page.dart +++ b/lib/dualis/ui/dualis_page.dart @@ -11,7 +11,8 @@ import 'package:provider/provider.dart'; class DualisPage extends StatelessWidget { @override Widget build(BuildContext context) { - final StudyGradesViewModel viewModel = Provider.of(context); + final StudyGradesViewModel viewModel = + Provider.of(context); Widget widget; diff --git a/lib/dualis/ui/login/dualis_login_page.dart b/lib/dualis/ui/login/dualis_login_page.dart index 8638e32a..3d684232 100644 --- a/lib/dualis/ui/login/dualis_login_page.dart +++ b/lib/dualis/ui/login/dualis_login_page.dart @@ -7,7 +7,8 @@ import 'package:provider/provider.dart'; class DualisLoginPage extends StatelessWidget { @override Widget build(BuildContext context) { - final StudyGradesViewModel viewModel = Provider.of(context); + final StudyGradesViewModel viewModel = + Provider.of(context); return buildLoginPage(context, viewModel); } diff --git a/lib/dualis/ui/viewmodels/study_grades_view_model.dart b/lib/dualis/ui/viewmodels/study_grades_view_model.dart index e65d1b09..e61aa5c0 100644 --- a/lib/dualis/ui/viewmodels/study_grades_view_model.dart +++ b/lib/dualis/ui/viewmodels/study_grades_view_model.dart @@ -93,7 +93,7 @@ class StudyGradesViewModel extends BaseViewModel { } Future loadCredentials() async { - return _preferencesProvider.loadDualisCredentials(); + return _preferencesProvider.loadDualisCredentials(); } Future saveCredentials(Credentials credentials) async { @@ -211,7 +211,8 @@ class StudyGradesViewModel extends BaseViewModel { if (_semesterNames == null) return; if (_semesterNames!.isEmpty) return; - final lastViewedSemester = await _preferencesProvider.getLastViewedSemester(); + final lastViewedSemester = + await _preferencesProvider.getLastViewedSemester(); if (_semesterNames!.contains(lastViewedSemester)) { loadSemester(lastViewedSemester); diff --git a/lib/information/ui/usefulinformation/useful_information_page.dart b/lib/information/ui/usefulinformation/useful_information_page.dart index a06c03d1..61a61a5f 100644 --- a/lib/information/ui/usefulinformation/useful_information_page.dart +++ b/lib/information/ui/usefulinformation/useful_information_page.dart @@ -27,7 +27,8 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageRoundcube), onTap: () { openLink( - "https://lehre-webmail.dhbw-stuttgart.de/roundcubemail/",); + "https://lehre-webmail.dhbw-stuttgart.de/roundcubemail/", + ); }, ), ListTile( @@ -42,7 +43,8 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageLocation), onTap: () { openLink( - "https://www.dhbw-stuttgart.de/themen/hochschule/standorte/",); + "https://www.dhbw-stuttgart.de/themen/hochschule/standorte/", + ); }, ), ListTile( @@ -50,7 +52,8 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageEduroam), onTap: () { openLink( - "https://www.dhbw-stuttgart.de/themen/einrichtungen/itservice-center/informationen-fuer-studierende/wlan-vpn-zugang/",); + "https://www.dhbw-stuttgart.de/themen/einrichtungen/itservice-center/informationen-fuer-studierende/wlan-vpn-zugang/", + ); }, ), ListTile( @@ -65,7 +68,8 @@ class UsefulInformationPage extends StatelessWidget { title: Text(L.of(context).informationPageDHBWSports), onTap: () { openLink( - "https://www.dhbw-stuttgart.de/themen/einrichtungen/hochschulsport/",); + "https://www.dhbw-stuttgart.de/themen/einrichtungen/hochschulsport/", + ); }, ), ], diff --git a/lib/main.dart b/lib/main.dart index 8f674049..bad7cf00 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -25,9 +25,11 @@ void main() async { await PlatformUtil.initializePortraitLandscapeMode(); - runApp(RootPage( - rootViewModel: await loadRootViewModel(), - ),); + runApp( + RootPage( + rootViewModel: await loadRootViewModel(), + ), + ); } /// diff --git a/lib/native/widget/ios_widget_helper.dart b/lib/native/widget/ios_widget_helper.dart index e12386e0..d9a55ab7 100644 --- a/lib/native/widget/ios_widget_helper.dart +++ b/lib/native/widget/ios_widget_helper.dart @@ -6,8 +6,7 @@ import 'package:flutter_widgetkit/flutter_widgetkit.dart'; /// WidgetHelper which calls native code to control the widget on iOS /// class IOSWidgetHelper implements WidgetHelper { - static const platform = - MethodChannel('de.bennik2000.dhbwstudentapp/widget'); + static const platform = MethodChannel('de.bennik2000.dhbwstudentapp/widget'); @override Future disableWidget() async { diff --git a/lib/schedule/background/calendar_synchronizer.dart b/lib/schedule/background/calendar_synchronizer.dart index 3573f4ca..6d04fe49 100644 --- a/lib/schedule/background/calendar_synchronizer.dart +++ b/lib/schedule/background/calendar_synchronizer.dart @@ -12,23 +12,28 @@ class CalendarSynchronizer { final ScheduleSourceProvider scheduleSourceProvider; final PreferencesProvider preferencesProvider; - CalendarSynchronizer(this.scheduleProvider, this.scheduleSourceProvider, - this.preferencesProvider,); + CalendarSynchronizer( + this.scheduleProvider, + this.scheduleSourceProvider, + this.preferencesProvider, + ); void registerSynchronizationCallback() { scheduleProvider.addScheduleUpdatedCallback((schedule, start, end) async { - final List listDateEntries = List.empty(growable: true); + final List listDateEntries = + List.empty(growable: true); for (final element in schedule.entries) { - final DateEntry date = DateEntry( - room: element.room, - comment: element.details, - databaseName: 'DHBW', - description: element.title, - year: element.start.year.toString(), - start: element.start, - end: element.end,); - listDateEntries.add(date); - } + final DateEntry date = DateEntry( + room: element.room, + comment: element.details, + databaseName: 'DHBW', + description: element.title, + year: element.start.year.toString(), + start: element.start, + end: element.end, + ); + listDateEntries.add(date); + } KiwiContainer().resolve().listDateEntries = listDateEntries; diff --git a/lib/schedule/business/schedule_diff_calculator.dart b/lib/schedule/business/schedule_diff_calculator.dart index baae2205..80e87cf0 100644 --- a/lib/schedule/business/schedule_diff_calculator.dart +++ b/lib/schedule/business/schedule_diff_calculator.dart @@ -13,15 +13,17 @@ class ScheduleDiffCalculator { final addedEntries = []; for (final entry in oldEntries) { - if (!newEntries.any((ScheduleEntry element) => - _areScheduleEntriesEqual(element, entry),)) { + if (!newEntries.any( + (ScheduleEntry element) => _areScheduleEntriesEqual(element, entry), + )) { removedEntries.add(entry); } } for (final entry in newEntries) { - if (!oldEntries.any((ScheduleEntry element) => - _areScheduleEntriesEqual(element, entry),)) { + if (!oldEntries.any( + (ScheduleEntry element) => _areScheduleEntriesEqual(element, entry), + )) { addedEntries.add(entry); } } @@ -86,10 +88,13 @@ class ScheduleDiffCalculator { } if (oldElementsWithName.length == 1 && newElementsWithName.length == 1) { - updatedEntries.add(UpdatedEntry( - newElementsWithName[0], - newElementsWithName[0].getDifferentProperties(oldElementsWithName[0]), - ),); + updatedEntries.add( + UpdatedEntry( + newElementsWithName[0], + newElementsWithName[0] + .getDifferentProperties(oldElementsWithName[0]), + ), + ); continue; } @@ -113,11 +118,12 @@ class ScheduleDiffCalculator { } void _matchMNChangedElements( - List oldElementsWithName, - List newElementsWithName, - List updatedEntries, - List oldEntries, - List newEntries,) { + List oldElementsWithName, + List newElementsWithName, + List updatedEntries, + List oldEntries, + List newEntries, + ) { if (oldElementsWithName.length == newElementsWithName.length) { for (final oldElement in oldElementsWithName) { final ScheduleEntry nearestElement = @@ -144,7 +150,9 @@ class ScheduleDiffCalculator { } ScheduleEntry _findNearestElementByStart( - List elements, ScheduleEntry reference,) { + List elements, + ScheduleEntry reference, + ) { ScheduleEntry nearestElement = elements[0]; Duration minimalDifference = reference.start.difference(nearestElement.start).abs(); @@ -166,10 +174,11 @@ class ScheduleDiff { final List removedEntries; final List updatedEntries; - ScheduleDiff( - {required this.addedEntries, - required this.removedEntries, - required this.updatedEntries,}); + ScheduleDiff({ + required this.addedEntries, + required this.removedEntries, + required this.updatedEntries, + }); bool didSomethingChange() { return addedEntries.isNotEmpty || diff --git a/lib/schedule/business/schedule_filter.dart b/lib/schedule/business/schedule_filter.dart index ca90dce8..286a03f9 100644 --- a/lib/schedule/business/schedule_filter.dart +++ b/lib/schedule/business/schedule_filter.dart @@ -8,7 +8,8 @@ class ScheduleFilter { ScheduleFilter(this._scheduleFilterRepository); Future filter(Schedule original) async { - final allHiddenNames = await _scheduleFilterRepository.queryAllHiddenNames(); + final allHiddenNames = + await _scheduleFilterRepository.queryAllHiddenNames(); final allEntries = []; diff --git a/lib/schedule/data/schedule_entry_repository.dart b/lib/schedule/data/schedule_entry_repository.dart index 463f59b6..0ee313cf 100644 --- a/lib/schedule/data/schedule_entry_repository.dart +++ b/lib/schedule/data/schedule_entry_repository.dart @@ -13,7 +13,9 @@ class ScheduleEntryRepository { } Future queryScheduleBetweenDates( - DateTime start, DateTime end,) async { + DateTime start, + DateTime end, + ) async { final rows = await _database.queryRows( ScheduleEntryEntity.tableName(), where: "end>? AND start deleteScheduleEntriesBetween( - DateTime start, DateTime end,) async { + DateTime start, + DateTime end, + ) async { await _database.deleteWhere( ScheduleEntryEntity.tableName(), where: "start>=? AND end<=?", diff --git a/lib/schedule/data/schedule_query_information_repository.dart b/lib/schedule/data/schedule_query_information_repository.dart index 6de9285a..524103ca 100644 --- a/lib/schedule/data/schedule_query_information_repository.dart +++ b/lib/schedule/data/schedule_query_information_repository.dart @@ -8,7 +8,9 @@ class ScheduleQueryInformationRepository { ScheduleQueryInformationRepository(this._database); Future getOldestQueryTimeBetweenDates( - DateTime start, DateTime end,) async { + DateTime start, + DateTime end, + ) async { final oldestQueryTimeDate = await _database.queryAggregator( "SELECT MIN(queryTime) FROM ScheduleQueryInformation WHERE start<=? AND end>=?", [ @@ -23,7 +25,9 @@ class ScheduleQueryInformationRepository { } Future> getQueryInformationBetweenDates( - DateTime start, DateTime end,) async { + DateTime start, + DateTime end, + ) async { final rows = await _database.queryRows( ScheduleQueryInformationEntity.tableName(), where: "start<=? AND end>=?", @@ -46,7 +50,8 @@ class ScheduleQueryInformationRepository { } Future saveScheduleQueryInformation( - ScheduleQueryInformation queryInformation,) async { + ScheduleQueryInformation queryInformation, + ) async { await _database.deleteWhere( ScheduleQueryInformationEntity.tableName(), where: "start=? AND end=?", diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index 877b6ad1..503945a6 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -71,14 +71,15 @@ class ScheduleEntry { } // TODO: [Leptopoda] use buildrunner - ScheduleEntry copyWith( - {DateTime? start, - DateTime? end, - String? title, - String? details, - String? professor, - String? room, - ScheduleEntryType? type,}) { + ScheduleEntry copyWith({ + DateTime? start, + DateTime? end, + String? title, + String? details, + String? professor, + String? room, + ScheduleEntryType? type, + }) { return ScheduleEntry( id: id, start: start ?? this.start, diff --git a/lib/schedule/service/error_report_schedule_source_decorator.dart b/lib/schedule/service/error_report_schedule_source_decorator.dart index 1e368447..24739d2a 100644 --- a/lib/schedule/service/error_report_schedule_source_decorator.dart +++ b/lib/schedule/service/error_report_schedule_source_decorator.dart @@ -9,8 +9,11 @@ class ErrorReportScheduleSourceDecorator extends ScheduleSource { ErrorReportScheduleSourceDecorator(this._scheduleSource); @override - Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken,]) async { + Future querySchedule( + DateTime? from, + DateTime? to, [ + CancellationToken? cancellationToken, + ]) async { try { final schedule = await _scheduleSource.querySchedule( from, diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index faf6ecab..6242a8cb 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -64,7 +64,7 @@ class IcalScheduleSource extends ScheduleSource { } return response; - // ignore: avoid_catching_errors + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { diff --git a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart index d3710cce..779fe485 100644 --- a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart +++ b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart @@ -19,12 +19,14 @@ class MannheimCourseResponseParser { if (label == "" || value == "") continue; if (label.trim() == "Kurs auswählen") continue; - courses.add(Course( - label, - "http://vorlesungsplan.dhbw-mannheim.de/ical.php?uid=$value", - title, - value, - ),); + courses.add( + Course( + label, + "http://vorlesungsplan.dhbw-mannheim.de/ical.php?uid=$value", + title, + value, + ), + ); } courses.sort((c1, c2) => c1.name.compareTo(c2.name)); diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index 8a8455c5..b463a118 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -46,7 +46,7 @@ class MannheimCourseScraper { } return response!; - // ignore: avoid_catching_errors + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index 36465459..10b4550d 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -160,7 +160,7 @@ class RaplaScheduleSource extends ScheduleSource { } return response; - // ignore: avoid_catching_errors + // ignore: avoid_catching_errors } on http.OperationCanceledError catch (_) { throw OperationCancelledException(); } catch (ex) { diff --git a/lib/schedule/service/schedule_source.dart b/lib/schedule/service/schedule_source.dart index 25694b1b..f0109365 100644 --- a/lib/schedule/service/schedule_source.dart +++ b/lib/schedule/service/schedule_source.dart @@ -9,14 +9,17 @@ abstract class ScheduleSource { /// Returns a future which gives the updated schedule or throws an exception /// if an error happened or the operation was cancelled /// - Future querySchedule(DateTime? from, DateTime? to, - [CancellationToken? cancellationToken,]); + Future querySchedule( + DateTime? from, + DateTime? to, [ + CancellationToken? cancellationToken, + ]); bool canQuery(); } class ScheduleQueryFailedException implements Exception { - final Object innerException; + final dynamic innerException; final StackTrace? trace; ScheduleQueryFailedException(this.innerException, [this.trace]); diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index 79b70410..3557d0dc 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -76,13 +76,17 @@ class DailyScheduleEntryWidget extends StatelessWidget { Text( scheduleEntry.professor, style: textStyleDailyScheduleEntryWidgetProfessor( - context,), + context, + ), ), Text( scheduleEntryTypeToReadableString( - context, scheduleEntry.type,), + context, + scheduleEntry.type, + ), style: textStyleDailyScheduleEntryWidgetType( - context,), + context, + ), ), ], ), diff --git a/lib/schedule/ui/notification/next_day_information_notification.dart b/lib/schedule/ui/notification/next_day_information_notification.dart index 349e6e5a..4eea6189 100644 --- a/lib/schedule/ui/notification/next_day_information_notification.dart +++ b/lib/schedule/ui/notification/next_day_information_notification.dart @@ -59,7 +59,10 @@ class NextDayInformationNotification extends TaskCallback { } String? _getNotificationMessage( - int daysToNextEntry, ScheduleEntry nextScheduleEntry, DateFormat format,) { + int daysToNextEntry, + ScheduleEntry nextScheduleEntry, + DateFormat format, + ) { switch (daysToNextEntry) { case 0: return interpolate( diff --git a/lib/schedule/ui/schedule_navigation_entry.dart b/lib/schedule/ui/schedule_navigation_entry.dart index 2be1d9f6..19e29b99 100644 --- a/lib/schedule/ui/schedule_navigation_entry.dart +++ b/lib/schedule/ui/schedule_navigation_entry.dart @@ -35,18 +35,18 @@ class ScheduleNavigationEntry extends NavigationEntry { PropertyChangeProvider( value: model, child: PropertyChangeConsumer( - properties: const ["didSetupProperly"], - builder: - (BuildContext _, ScheduleViewModel? __, Set? ___) => - model.didSetupProperly - ? Container() - : IconButton( - icon: const Icon(Icons.help_outline), - onPressed: () async { - await ScheduleHelpDialog().show(context); - }, - tooltip: L.of(context).helpButtonTooltip, - ),), + properties: const ["didSetupProperly"], + builder: (BuildContext _, ScheduleViewModel? __, Set? ___) => + model.didSetupProperly + ? Container() + : IconButton( + icon: const Icon(Icons.help_outline), + onPressed: () async { + await ScheduleHelpDialog().show(context); + }, + tooltip: L.of(context).helpButtonTooltip, + ), + ), ), PropertyChangeProvider( value: model, @@ -57,9 +57,11 @@ class ScheduleNavigationEntry extends NavigationEntry { ? IconButton( icon: const Icon(Icons.filter_alt), onPressed: () async { - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => ScheduleFilterPage(), - ),); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ScheduleFilterPage(), + ), + ); }, ) : Container(), diff --git a/lib/schedule/ui/schedule_page.dart b/lib/schedule/ui/schedule_page.dart index c4693f54..d8ded79b 100644 --- a/lib/schedule/ui/schedule_page.dart +++ b/lib/schedule/ui/schedule_page.dart @@ -29,7 +29,7 @@ class _SchedulePageState extends State { @override Widget build(BuildContext context) { - ScheduleViewModel viewModel = Provider.of(context); + final ScheduleViewModel viewModel = Provider.of(context); if (!viewModel.didSetupProperly) { return ScheduleEmptyState(); diff --git a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart index 4057c3b2..fb111d83 100644 --- a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart +++ b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart @@ -10,8 +10,11 @@ class FilterViewModel extends BaseViewModel { List filterStates = []; - FilterViewModel(this._scheduleEntryRepository, this._scheduleFilterRepository, - this._scheduleSource,) { + FilterViewModel( + this._scheduleEntryRepository, + this._scheduleFilterRepository, + this._scheduleSource, + ) { loadFilterStates(); } diff --git a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart index 52de5863..dbe1ad5b 100644 --- a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart +++ b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart @@ -46,14 +46,18 @@ class ScheduleFilterPage extends StatelessWidget { child: PropertyChangeProvider( value: _viewModel, child: PropertyChangeConsumer( - builder: (BuildContext _, FilterViewModel? viewModel, - Set? ___,) => - ListView.builder( - shrinkWrap: true, - itemCount: viewModel!.filterStates.length, - itemBuilder: (context, index) => - FilterStateRow(viewModel.filterStates[index]), - ),), + builder: ( + BuildContext _, + FilterViewModel? viewModel, + Set? ___, + ) => + ListView.builder( + shrinkWrap: true, + itemCount: viewModel!.filterStates.length, + itemBuilder: (context, index) => + FilterStateRow(viewModel.filterStates[index]), + ), + ), ), ) ], diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index 37209097..3d0b13ce 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -36,8 +36,9 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { height: 8, width: 30, decoration: BoxDecoration( - color: colorSeparator(), - borderRadius: const BorderRadius.all(Radius.circular(4)),), + color: colorSeparator(), + borderRadius: const BorderRadius.all(Radius.circular(4)), + ), ), ), ), @@ -55,7 +56,8 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { Text( L.of(context).scheduleEntryDetailFrom, style: textStyleScheduleEntryBottomPageTimeFromTo( - context,), + context, + ), ), Text( timeStart, @@ -113,18 +115,27 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { ], ), ), - if (scheduleEntry!.room.isEmpty) Container() else Padding( - padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), - child: Text(scheduleEntry!.room.replaceAll(",", "\n")), - ), - if (scheduleEntry!.details.isEmpty) Container() else Padding( - padding: const EdgeInsets.fromLTRB(0, 16, 0, 16), - child: Container( - color: colorSeparator(), - height: 1, - ), - ), - if (scheduleEntry!.details.isEmpty) Container() else Text(scheduleEntry!.details), + if (scheduleEntry!.room.isEmpty) + Container() + else + Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), + child: Text(scheduleEntry!.room.replaceAll(",", "\n")), + ), + if (scheduleEntry!.details.isEmpty) + Container() + else + Padding( + padding: const EdgeInsets.fromLTRB(0, 16, 0, 16), + child: Container( + color: colorSeparator(), + height: 1, + ), + ), + if (scheduleEntry!.details.isEmpty) + Container() + else + Text(scheduleEntry!.details), ], ), ), diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index b1501086..f83f499c 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -39,7 +39,8 @@ class _WeeklySchedulePageState extends State { Text(L.of(context).scheduleQueryFailedMessage), TextButton( child: Text( - L.of(context).scheduleQueryFailedOpenInBrowser.toUpperCase(),), + L.of(context).scheduleQueryFailedOpenInBrowser.toUpperCase(), + ), onPressed: () { launchUrl(Uri.parse(viewModel.scheduleUrl!)); }, @@ -81,7 +82,7 @@ class _WeeklySchedulePageState extends State { viewModel = Provider.of(context); viewModel.ensureUpdateNowTimerRunning(); - viewModel.queryFailedCallback =_showQueryFailedSnackBar; + viewModel.queryFailedCallback = _showQueryFailedSnackBar; return PropertyChangeProvider( value: viewModel, @@ -109,13 +110,18 @@ class _WeeklySchedulePageState extends State { padding: const EdgeInsets.all(8.0), child: PropertyChangeConsumer( properties: const ["weekSchedule", "now"], - builder: (BuildContext context, - WeeklyScheduleViewModel? model, Set? _,) { + builder: ( + BuildContext context, + WeeklyScheduleViewModel? model, + Set? _, + ) { return PageTransitionSwitcher( reverse: !model!.didUpdateScheduleIntoFuture, - transitionBuilder: (Widget child, - Animation animation, - Animation secondaryAnimation,) => + transitionBuilder: ( + Widget child, + Animation animation, + Animation secondaryAnimation, + ) => SharedAxisTransition( animation: animation, secondaryAnimation: secondaryAnimation, @@ -145,8 +151,11 @@ class _WeeklySchedulePageState extends State { ), PropertyChangeConsumer( properties: const ["isUpdating"], - builder: (BuildContext context, - WeeklyScheduleViewModel? model, Set? _,) { + builder: ( + BuildContext context, + WeeklyScheduleViewModel? model, + Set? _, + ) { return model!.isUpdating ? const LinearProgressIndicator() : Container(); diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart index 8a8b8f7a..509b2f5e 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart @@ -9,17 +9,23 @@ class ScheduleGrid extends CustomPaint { final int columns; final Color gridLinesColor; - ScheduleGrid(this.fromHour, this.toHour, this.timeLabelsWidth, - this.dateLabelsHeight, this.columns, this.gridLinesColor,) - : super( - painter: ScheduleGridCustomPaint( - fromHour, - toHour, - timeLabelsWidth, - dateLabelsHeight, - columns, - gridLinesColor, - ),); + ScheduleGrid( + this.fromHour, + this.toHour, + this.timeLabelsWidth, + this.dateLabelsHeight, + this.columns, + this.gridLinesColor, + ) : super( + painter: ScheduleGridCustomPaint( + fromHour, + toHour, + timeLabelsWidth, + dateLabelsHeight, + columns, + gridLinesColor, + ), + ); } class ScheduleGridCustomPaint extends CustomPainter { @@ -58,7 +64,8 @@ class ScheduleGridCustomPaint extends CustomPainter { Paint secondaryPaint, ) { for (var i = 0; i < lines; i++) { - final y = ((size.height - dateLabelsHeight) / lines) * i + dateLabelsHeight; + final y = + ((size.height - dateLabelsHeight) / lines) * i + dateLabelsHeight; canvas.drawLine(Offset(0, y), Offset(size.width, y), secondaryPaint); } @@ -66,7 +73,8 @@ class ScheduleGridCustomPaint extends CustomPainter { void drawVerticalLines(Size size, Canvas canvas, Paint secondaryPaint) { for (var i = 0; i < columns; i++) { - final x = ((size.width - timeLabelsWidth) / columns) * i + timeLabelsWidth; + final x = + ((size.width - timeLabelsWidth) / columns) * i + timeLabelsWidth; canvas.drawLine(Offset(x, 0), Offset(x, size.height), secondaryPaint); } diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart index 421495c6..96eec88b 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart @@ -68,13 +68,14 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { void drawCompletePastOverlay(Canvas canvas, Size size, Paint overlayPaint) { canvas.drawRect( - Rect.fromLTRB( - 0, - 0, - size.width, - size.height, - ), - overlayPaint,); + Rect.fromLTRB( + 0, + 0, + size.width, + size.height, + ), + overlayPaint, + ); } void drawPartialPastOverlay(Canvas canvas, Size size, Paint overlayPaint) { diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 1160cad5..88b99403 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -35,10 +35,14 @@ class ScheduleWidget extends StatelessWidget { @override Widget build(BuildContext context) { return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return buildWithSize( - context, constraints.biggest.width, constraints.biggest.height,); - },); + builder: (BuildContext context, BoxConstraints constraints) { + return buildWithSize( + context, + constraints.biggest.width, + constraints.biggest.height, + ); + }, + ); } Widget buildWithSize(BuildContext context, double width, double height) { @@ -84,7 +88,8 @@ class ScheduleWidget extends StatelessWidget { colorScheduleGridGridLines(context), ), Padding( - padding: const EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), + padding: + const EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), child: Stack( children: entryWidgets, ), @@ -93,7 +98,8 @@ class ScheduleWidget extends StatelessWidget { children: labelWidgets, ), Padding( - padding: const EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), + padding: + const EdgeInsets.fromLTRB(timeLabelsWidth, dayLabelsHeight, 0, 0), child: SchedulePastOverlay( displayStartHour, displayEndHour, @@ -151,7 +157,8 @@ class ScheduleWidget extends StatelessWidget { var i = 0; final dayFormatter = DateFormat("E", L.of(context).locale.languageCode); - final dateFormatter = DateFormat("d. MMM", L.of(context).locale.languageCode); + final dateFormatter = + DateFormat("d. MMM", L.of(context).locale.languageCode); final loopEnd = toStartOfDay(tomorrow(displayEnd))!; @@ -188,7 +195,11 @@ class ScheduleWidget extends StatelessWidget { } List buildEntryWidgets( - double hourHeight, double minuteHeight, double width, int columns,) { + double hourHeight, + double minuteHeight, + double width, + int columns, + ) { if (schedule == null) return []; if (schedule!.entries.isEmpty) return []; @@ -205,13 +216,15 @@ class ScheduleWidget extends StatelessWidget { final columnSchedule = schedule!.trim(columnStartDate, columnEndDate); - entryWidgets.addAll(buildEntryWidgetsForColumn( - maxWidth, - hourHeight, - minuteHeight, - xPosition, - columnSchedule.entries, - ),); + entryWidgets.addAll( + buildEntryWidgetsForColumn( + maxWidth, + hourHeight, + minuteHeight, + xPosition, + columnSchedule.entries, + ), + ); columnStartDate = columnEndDate; columnEndDate = tomorrow(columnEndDate); diff --git a/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart b/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart index e2baea2c..f74ad99a 100644 --- a/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_rapla_url_dialog.dart @@ -21,7 +21,7 @@ class EnterRaplaUrlDialog extends EnterUrlDialog { @override Future loadUrl() async { - return _preferencesProvider.getRaplaUrl(); + return _preferencesProvider.getRaplaUrl(); } @override diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index 1d440d93..f266fb3b 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -103,8 +103,11 @@ abstract class EnterUrlDialog { ListenableProvider.value( value: _hasUrlError, child: Consumer( - builder: (BuildContext context, ValueNotifier hasUrlError, - Widget? child,) => + builder: ( + BuildContext context, + ValueNotifier hasUrlError, + Widget? child, + ) => TextButton( onPressed: hasUrlError.value ? null diff --git a/lib/ui/banner_widget.dart b/lib/ui/banner_widget.dart index 2c0dbe91..fd1c08c8 100644 --- a/lib/ui/banner_widget.dart +++ b/lib/ui/banner_widget.dart @@ -5,12 +5,12 @@ class BannerWidget extends StatelessWidget { final String buttonText; final VoidCallback onButtonTap; - const BannerWidget( - {Key? key, - required this.message, - required this.buttonText, - required this.onButtonTap,}) - : super(key: key); + const BannerWidget({ + Key? key, + required this.message, + required this.buttonText, + required this.onButtonTap, + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/ui/main_page.dart b/lib/ui/main_page.dart index c57202b1..ed435d30 100644 --- a/lib/ui/main_page.dart +++ b/lib/ui/main_page.dart @@ -136,10 +136,12 @@ class _MainPageState extends State with NavigatorObserver { final drawerEntries = []; for (final entry in navigationEntries) { - drawerEntries.add(DrawerNavigationEntry( - entry.icon, - entry.title(context), - ),); + drawerEntries.add( + DrawerNavigationEntry( + entry.icon, + entry.title(context), + ), + ); } return drawerEntries; diff --git a/lib/ui/navigation_drawer.dart b/lib/ui/navigation_drawer.dart index 2ea6680b..0a0e25dd 100644 --- a/lib/ui/navigation_drawer.dart +++ b/lib/ui/navigation_drawer.dart @@ -33,11 +33,15 @@ class NavigationDrawer extends StatelessWidget { int i = 0; for (final entry in entries) { - widgets.add(_createDrawerItem(context, + widgets.add( + _createDrawerItem( + context, icon: entry.icon, text: entry.title, index: i, - isSelected: i == selectedIndex,),); + isSelected: i == selectedIndex, + ), + ); i++; } diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index fe898934..35aa2aed 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -34,9 +34,10 @@ class _OnboardingPageState extends State viewModel.addListener( () async { await _controller.animateTo( - viewModel.stepIndex! / viewModel.onboardingSteps, - curve: Curves.ease, - duration: const Duration(milliseconds: 300),); + viewModel.stepIndex! / viewModel.onboardingSteps, + curve: Curves.ease, + duration: const Duration(milliseconds: 300), + ); }, ); diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart index 6892320e..2460615d 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model.dart @@ -45,9 +45,12 @@ class OnboardingViewModel extends BaseViewModel { this._onboardingFinished, ) { for (final page in pages.values) { - page.viewModel().addListener(() { - notifyListeners("currentPageValid"); - }, ["isValid"],); + page.viewModel().addListener( + () { + notifyListeners("currentPageValid"); + }, + ["isValid"], + ); } analytics.logTutorialBegin(); diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index 9a22ddd8..93ebce5f 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -41,12 +41,15 @@ class _IcalUrlPageState extends State { child: Padding( padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: PropertyChangeConsumer( - builder: (BuildContext context, OnboardingStepViewModel? model, - Set? _,) { + builder: ( + BuildContext context, + OnboardingStepViewModel? model, + Set? _, + ) { final viewModel = model as IcalUrlViewModel?; if (viewModel?.url != null && - _urlTextController.text != viewModel!.url){ + _urlTextController.text != viewModel!.url) { _urlTextController.text = viewModel.url!; } diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index 9e14c61d..75d2bfac 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -50,8 +50,11 @@ class SelectMannheimCourseWidget extends StatelessWidget { @override Widget build(BuildContext context) { return PropertyChangeConsumer( - builder: (BuildContext context, OnboardingStepViewModel? model, - Set? _,) { + builder: ( + BuildContext context, + OnboardingStepViewModel? model, + Set? _, + ) { final viewModel = model as MannheimViewModel?; switch (viewModel?.loadingState) { diff --git a/lib/ui/onboarding/widgets/onboarding_page_background.dart b/lib/ui/onboarding/widgets/onboarding_page_background.dart index 9147294c..f0f91a24 100644 --- a/lib/ui/onboarding/widgets/onboarding_page_background.dart +++ b/lib/ui/onboarding/widgets/onboarding_page_background.dart @@ -96,38 +96,44 @@ class OnboardingPageBackground extends StatelessWidget { ), ), ), - if (PlatformUtil.isPhone()) Align( - alignment: Alignment.bottomCenter, - child: SizedBox( - height: 90, - width: double.infinity, - child: Transform.translate( - offset: Offset(bottomBackground.value, 20), - child: Transform.scale( - scale: 1.5, - child: Image.asset( - background[Theme.of(context).brightness]!, - ), - ), + if (PlatformUtil.isPhone()) + Align( + alignment: Alignment.bottomCenter, + child: SizedBox( + height: 90, + width: double.infinity, + child: Transform.translate( + offset: Offset(bottomBackground.value, 20), + child: Transform.scale( + scale: 1.5, + child: Image.asset( + background[Theme.of(context).brightness]!, ), ), - ) else Container(), - if (PlatformUtil.isPhone()) Align( - alignment: Alignment.bottomCenter, - child: SizedBox( - height: 90, - width: double.infinity, - child: Transform.translate( - offset: Offset(bottomForeground.value, 20), - child: Transform.scale( - scale: 1.5, - child: Image.asset( - foreground[Theme.of(context).brightness]!, - ), - ), + ), + ), + ) + else + Container(), + if (PlatformUtil.isPhone()) + Align( + alignment: Alignment.bottomCenter, + child: SizedBox( + height: 90, + width: double.infinity, + child: Transform.translate( + offset: Offset(bottomForeground.value, 20), + child: Transform.scale( + scale: 1.5, + child: Image.asset( + foreground[Theme.of(context).brightness]!, ), ), - ) else Container(), + ), + ), + ) + else + Container(), ], ); } diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index 6055e088..db2df414 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -41,12 +41,15 @@ class _RaplaUrlPageState extends State { child: Padding( padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), child: PropertyChangeConsumer( - builder: (BuildContext context, OnboardingStepViewModel? model, - Set? _,) { + builder: ( + BuildContext context, + OnboardingStepViewModel? model, + Set? _, + ) { final viewModel = model as RaplaUrlViewModel?; if (viewModel?.raplaUrl != null && - _urlTextController.text != viewModel!.raplaUrl){ + _urlTextController.text != viewModel!.raplaUrl) { _urlTextController.text = viewModel.raplaUrl!; } diff --git a/lib/ui/onboarding/widgets/select_source_page.dart b/lib/ui/onboarding/widgets/select_source_page.dart index 0f3c273a..4036d051 100644 --- a/lib/ui/onboarding/widgets/select_source_page.dart +++ b/lib/ui/onboarding/widgets/select_source_page.dart @@ -91,10 +91,11 @@ class SelectSourcePage extends StatelessWidget { } RadioListTile buildScheduleTypeRadio( - SelectSourceViewModel? viewModel, - BuildContext context, - ScheduleSourceType type, - String title,) { + SelectSourceViewModel? viewModel, + BuildContext context, + ScheduleSourceType type, + String title, + ) { return RadioListTile( value: type, //model.useDualis, onChanged: viewModel?.setScheduleSourceType, diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 60c02697..0f1f69bf 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -38,11 +38,12 @@ class SettingsPage extends StatefulWidget { class _SettingsPageState extends State { final SettingsViewModel settingsViewModel = SettingsViewModel( - KiwiContainer().resolve(), - KiwiContainer().resolve(NextDayInformationNotification.name) - as NextDayInformationNotification, - KiwiContainer().resolve(), - KiwiContainer().resolve(),); + KiwiContainer().resolve(), + KiwiContainer().resolve(NextDayInformationNotification.name) + as NextDayInformationNotification, + KiwiContainer().resolve(), + KiwiContainer().resolve(), + ); @override Widget build(BuildContext context) { @@ -144,19 +145,20 @@ class _SettingsPageState extends State { if (await CalendarAccess().requestCalendarPermission() == CalendarPermission.PermissionDenied) { await showDialog( - context: context, - builder: (BuildContext context) => AlertDialog( - title: Text( - L.of(context).dialogTitleCalendarAccessNotGranted,), - content: - Text(L.of(context).dialogCalendarAccessNotGranted), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(L.of(context).dialogOk), - ) - ], - ),); + context: context, + builder: (BuildContext context) => AlertDialog( + title: Text( + L.of(context).dialogTitleCalendarAccessNotGranted, + ), + content: Text(L.of(context).dialogCalendarAccessNotGranted), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(L.of(context).dialogOk), + ) + ], + ), + ); return; } final isCalendarSyncEnabled = await KiwiContainer() @@ -164,13 +166,16 @@ class _SettingsPageState extends State { .isCalendarSyncEnabled(); final List entriesToExport = KiwiContainer().resolve().listDateEntries; - await NavigatorKey.rootKey.currentState!.push(MaterialPageRoute( + await NavigatorKey.rootKey.currentState!.push( + MaterialPageRoute( builder: (BuildContext context) => CalendarExportPage( - entriesToExport: entriesToExport, - isCalendarSyncWidget: true, - isCalendarSyncEnabled: isCalendarSyncEnabled, - ), - settings: const RouteSettings(name: "settings"),),); + entriesToExport: entriesToExport, + isCalendarSyncWidget: true, + isCalendarSyncEnabled: isCalendarSyncEnabled, + ), + settings: const RouteSettings(name: "settings"), + ), + ); }, ), const Divider(), @@ -186,8 +191,11 @@ class _SettingsPageState extends State { properties: const [ "notifyAboutNextDay", ], - builder: (BuildContext context, SettingsViewModel? model, - Set? properties,) { + builder: ( + BuildContext context, + SettingsViewModel? model, + Set? properties, + ) { return SwitchListTile( title: Text(L.of(context).settingsNotificationsNextDay), onChanged: model!.setNotifyAboutNextDay, @@ -199,8 +207,11 @@ class _SettingsPageState extends State { properties: const [ "notifyAboutScheduleChanges", ], - builder: (BuildContext context, SettingsViewModel? model, - Set? properties,) { + builder: ( + BuildContext context, + SettingsViewModel? model, + Set? properties, + ) { return SwitchListTile( title: Text(L.of(context).settingsNotificationsScheduleChange), onChanged: model!.setNotifyAboutScheduleChanges, @@ -228,11 +239,13 @@ class _SettingsPageState extends State { onTap: () async { await SelectThemeDialog(model!).show(context); }, - subtitle: Text({ - AppTheme.Dark: L.of(context).selectThemeDark, - AppTheme.Light: L.of(context).selectThemeLight, - AppTheme.System: L.of(context).selectThemeSystem, - }[model!.appTheme]!,), + subtitle: Text( + { + AppTheme.Dark: L.of(context).selectThemeDark, + AppTheme.Light: L.of(context).selectThemeLight, + AppTheme.System: L.of(context).selectThemeSystem, + }[model!.appTheme]!, + ), ); }, ), diff --git a/lib/ui/settings/viewmodels/settings_view_model.dart b/lib/ui/settings/viewmodels/settings_view_model.dart index 98895818..26daf18e 100644 --- a/lib/ui/settings/viewmodels/settings_view_model.dart +++ b/lib/ui/settings/viewmodels/settings_view_model.dart @@ -42,10 +42,11 @@ class SettingsViewModel extends BaseViewModel { bool? get areWidgetsSupported => _areWidgetsSupported; SettingsViewModel( - this._preferencesProvider, - this._nextDayInformationNotification, - this._widgetHelper, - this._inAppPurchaseManager,) { + this._preferencesProvider, + this._nextDayInformationNotification, + this._widgetHelper, + this._inAppPurchaseManager, + ) { _loadPreferences(); _inAppPurchaseManager.addPurchaseCallback( diff --git a/test/date_management/service/parsing/all_dates_extract_test.dart b/test/date_management/service/parsing/all_dates_extract_test.dart index 34b32e1d..88e72642 100644 --- a/test/date_management/service/parsing/all_dates_extract_test.dart +++ b/test/date_management/service/parsing/all_dates_extract_test.dart @@ -4,8 +4,9 @@ import 'package:dhbwstudentapp/date_management/service/parsing/all_dates_extract import 'package:test/test.dart'; Future main() async { - final allDatesPage = await File('${Directory.current.absolute.path}/test/date_management/service/parsing/html_resources/all_dates.html',) - .readAsString(); + final allDatesPage = await File( + '${Directory.current.absolute.path}/test/date_management/service/parsing/html_resources/all_dates.html', + ).readAsString(); test('AllDatesExtract extract all dates', () async { final extract = AllDatesExtract(); diff --git a/test/dualis/service/parsing/all_modules_extract_test.dart b/test/dualis/service/parsing/all_modules_extract_test.dart index eef65992..e637ca0a 100644 --- a/test/dualis/service/parsing/all_modules_extract_test.dart +++ b/test/dualis/service/parsing/all_modules_extract_test.dart @@ -6,8 +6,9 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - final studentResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/student_results.html',) - .readAsString(); + final studentResultsPage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/student_results.html', + ).readAsString(); test('AllModulesExtract extract all modules', () async { final extract = AllModulesExtract(); diff --git a/test/dualis/service/parsing/dualis_timeout_extract_test.dart b/test/dualis/service/parsing/dualis_timeout_extract_test.dart index 1203c50e..d3cfed2b 100644 --- a/test/dualis/service/parsing/dualis_timeout_extract_test.dart +++ b/test/dualis/service/parsing/dualis_timeout_extract_test.dart @@ -4,11 +4,13 @@ import 'package:dhbwstudentapp/dualis/service/parsing/timeout_extract.dart'; import 'package:test/test.dart'; Future main() async { - final monthlySchedulePage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/monthly_schedule.html',) - .readAsString(); + final monthlySchedulePage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/monthly_schedule.html', + ).readAsString(); - final timeoutPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/dualis_timeout.html',) - .readAsString(); + final timeoutPage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/dualis_timeout.html', + ).readAsString(); test('DualisTimeoutExtract detect timeout page', () async { expect(TimeoutExtract().isTimeoutErrorPage(timeoutPage), isTrue); diff --git a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart index 7f0f6d72..6023bf56 100644 --- a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart +++ b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart @@ -5,8 +5,9 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - final moduleDetailsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/module_details.html',) - .readAsString(); + final moduleDetailsPage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/module_details.html', + ).readAsString(); test('ExamsFromModuleDetailsExtract', () async { final extract = ExamsFromModuleDetailsExtract(); diff --git a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart index eddbdcde..79f18a43 100644 --- a/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/modules_from_course_result_page_extract_test.dart @@ -5,14 +5,17 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:test/test.dart'; Future main() async { - final courseResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/course_results.html',) - .readAsString(); + final courseResultsPage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/course_results.html', + ).readAsString(); test('ModulesFromCourseResultPageExtract', () async { final extract = ModulesFromCourseResultPageExtract(); final modules = extract.extractModulesFromCourseResultPage( - courseResultsPage, "www.endpoint.com",); + courseResultsPage, + "www.endpoint.com", + ); expect(modules.length, 3); @@ -21,8 +24,10 @@ Future main() async { expect(modules[1]!.state, null); expect(modules[1]!.credits, "8,0"); expect(modules[1]!.finalGrade, "4,0"); - expect(modules[1]!.detailsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=RESULTDETAILS&ARGUMENTS=-N123456789876543,-N000307,-N121212121212121",); + expect( + modules[1]!.detailsUrl, + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=RESULTDETAILS&ARGUMENTS=-N123456789876543,-N000307,-N121212121212121", + ); }); test('ModulesFromCourseResultPageExtract invalid html throws exception', diff --git a/test/dualis/service/parsing/monthly_schedule_extract_test.dart b/test/dualis/service/parsing/monthly_schedule_extract_test.dart index 479ea917..425a8b25 100644 --- a/test/dualis/service/parsing/monthly_schedule_extract_test.dart +++ b/test/dualis/service/parsing/monthly_schedule_extract_test.dart @@ -4,8 +4,9 @@ import 'package:dhbwstudentapp/dualis/service/parsing/monthly_schedule_extract.d import 'package:test/test.dart'; Future main() async { - final monthlySchedulePage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/monthly_schedule.html',) - .readAsString(); + final monthlySchedulePage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/monthly_schedule.html', + ).readAsString(); test('MonthlyScheduleExtract extract all appointments', () async { final extract = MonthlyScheduleExtract(); diff --git a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart index 7e932791..abafc0ea 100644 --- a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart @@ -5,8 +5,9 @@ import 'package:dhbwstudentapp/dualis/service/parsing/semesters_from_course_resu import 'package:test/test.dart'; Future main() async { - final courseResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/course_results.html',) - .readAsString(); + final courseResultsPage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/course_results.html', + ).readAsString(); test('SemestersFromCourseResultPageExtract', () async { final extract = SemestersFromCourseResultPageExtract(); @@ -19,12 +20,16 @@ Future main() async { expect(semesters.length, 2); expect(semesters[0].semesterName, "SoSe yyyy"); - expect(semesters[0].semesterCourseResultsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000012345000",); + expect( + semesters[0].semesterCourseResultsUrl, + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000012345000", + ); expect(semesters[1].semesterName, "WiSe xx/yy"); - expect(semesters[1].semesterCourseResultsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000015048000",); + expect( + semesters[1].semesterCourseResultsUrl, + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,-N000000015048000", + ); }); test('SemestersFromCourseResultPageExtract invalid html throws exception', diff --git a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart index cf23408d..374142d4 100644 --- a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart +++ b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart @@ -5,8 +5,9 @@ import 'package:dhbwstudentapp/dualis/service/parsing/study_grades_from_student_ import 'package:test/test.dart'; Future main() async { - final studentResultsPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/student_results.html',) - .readAsString(); + final studentResultsPage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/student_results.html', + ).readAsString(); test('StudyGradesFromStudentResultsPageExtract', () async { final extract = StudyGradesFromStudentResultsPageExtract(); diff --git a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart index 7a4e2095..12365b16 100644 --- a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart +++ b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart @@ -6,8 +6,9 @@ import 'package:dhbwstudentapp/dualis/service/parsing/urls_from_main_page_extrac import 'package:test/test.dart'; Future main() async { - final mainPage = await File('${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/main_page.html',) - .readAsString(); + final mainPage = await File( + '${Directory.current.absolute.path}/test/dualis/service/parsing/html_resources/main_page.html', + ).readAsString(); test('UrlsFromMainPageExtract', () async { final extract = UrlsFromMainPageExtract(); @@ -16,12 +17,18 @@ Future main() async { extract.parseMainPage(mainPage, mainPageUrls, "www.endpoint.com"); - expect(mainPageUrls.studentResultsUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=STUDENT_RESULT&ARGUMENTS=-N123456789876543,-N000310,-N0,-N000000000000000,-N000000000000000,-N000000000000000,-N0,-N000000000000000",); - expect(mainPageUrls.courseResultUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,",); - expect(mainPageUrls.monthlyScheduleUrl, - "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=MONTH&ARGUMENTS=-N123456789876543,-N000031,-A",); + expect( + mainPageUrls.studentResultsUrl, + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=STUDENT_RESULT&ARGUMENTS=-N123456789876543,-N000310,-N0,-N000000000000000,-N000000000000000,-N000000000000000,-N0,-N000000000000000", + ); + expect( + mainPageUrls.courseResultUrl, + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N123456789876543,-N000307,", + ); + expect( + mainPageUrls.monthlyScheduleUrl, + "www.endpoint.com/scripts/mgrqispi.dll?APPNAME=CampusNet&PRGNAME=MONTH&ARGUMENTS=-N123456789876543,-N000031,-A", + ); expect(mainPageUrls.semesterCourseResultUrls, {}); }); diff --git a/test/schedule/service/ical/ical_parser_test.dart b/test/schedule/service/ical/ical_parser_test.dart index b256e8f9..b736358b 100644 --- a/test/schedule/service/ical/ical_parser_test.dart +++ b/test/schedule/service/ical/ical_parser_test.dart @@ -5,8 +5,9 @@ import 'package:dhbwstudentapp/schedule/service/ical/ical_parser.dart'; import 'package:test/test.dart'; Future main() async { - final icalFile = await File('${Directory.current.absolute.path}/test/schedule/service/ical/file_resources/ical_test.ics',) - .readAsString(); + final icalFile = await File( + '${Directory.current.absolute.path}/test/schedule/service/ical/file_resources/ical_test.ics', + ).readAsString(); test('ical correctly read all entries', () async { final parser = IcalParser(); diff --git a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart index 55296130..9a906026 100644 --- a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart +++ b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart @@ -4,8 +4,9 @@ import 'package:dhbwstudentapp/schedule/service/mannheim/mannheim_course_respons import 'package:test/test.dart'; Future main() async { - final coursePage = await File('${Directory.current.absolute.path}/test/schedule/service/mannheim/html_resources/mannheim_ical.html',) - .readAsString(); + final coursePage = await File( + '${Directory.current.absolute.path}/test/schedule/service/mannheim/html_resources/mannheim_ical.html', + ).readAsString(); test('Mannheim course parser parses correctly', () async { final parser = MannheimCourseResponseParser(); diff --git a/test/schedule/service/rapla/rapla_response_parser_test.dart b/test/schedule/service/rapla/rapla_response_parser_test.dart index f2b6dc3b..ca4b95bf 100644 --- a/test/schedule/service/rapla/rapla_response_parser_test.dart +++ b/test/schedule/service/rapla/rapla_response_parser_test.dart @@ -5,32 +5,41 @@ import 'package:dhbwstudentapp/schedule/service/rapla/rapla_response_parser.dart import 'package:test/test.dart'; Future main() async { - final monthlyRaplaPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_monthly_response.html',) - .readAsString(); + final monthlyRaplaPage = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_monthly_response.html', + ).readAsString(); - final raplaPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_response.html',) - .readAsString(); + final raplaPage = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_response.html', + ).readAsString(); - final raplaPage1 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_response_1.html',) - .readAsString(); + final raplaPage1 = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_response_1.html', + ).readAsString(); - final severalMonthsPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response.html',) - .readAsString(); + final severalMonthsPage = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response.html', + ).readAsString(); - final severalMonthsPage1 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response_1.html',) - .readAsString(); + final severalMonthsPage1 = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response_1.html', + ).readAsString(); - final severalMonthsPage2 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response_2.html',) - .readAsString(); + final severalMonthsPage2 = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_several_months_response_2.html', + ).readAsString(); - final invalidRaplaPage = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/invalid_rapla_response.html',) - .readAsString(); + final invalidRaplaPage = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/invalid_rapla_response.html', + ).readAsString(); - final raplaWeekResponse = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_week_response.html',) - .readAsString(); + final raplaWeekResponse = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_week_response.html', + ).readAsString(); - final raplaWeekResponse1 = await File('${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_week_response_1.html',) - .readAsString(); + final raplaWeekResponse1 = await File( + '${Directory.current.absolute.path}/test/schedule/service/rapla/html_resources/rapla_week_response_1.html', + ).readAsString(); test('Rapla correctly read all classes of weekly view', () async { final parser = RaplaResponseParser(); @@ -105,8 +114,10 @@ Future main() async { expect(schedule.entries[0].end, DateTime(2021, 09, 22, 15)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "A"); - expect(schedule.entries[0].room, - "MOS-TINF19A,A 1.380 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00),A 1.390 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00)",); + expect( + schedule.entries[0].room, + "MOS-TINF19A,A 1.380 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00),A 1.390 Vorlesungsraum (Mi 22.09.21 08:00, Do 23.09.21 08:00)", + ); expect(schedule.entries[2].title, "Tag der Deutschen Einheit"); expect(schedule.entries[2].start, DateTime(2021, 10, 03, 08)); @@ -180,58 +191,76 @@ Future main() async { expect(schedule.entries[0].end, DateTime(2021, 11, 02, 12, 15)); expect(schedule.entries[0].type, ScheduleEntryType.Class); expect(schedule.entries[0].professor, "Fr, Ta"); - expect(schedule.entries[0].room, - "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)",); - - expect(schedule.entries[1].title, - "Einführung in die Volkswirtschaftslehre und Mikroökonomik",); + expect( + schedule.entries[0].room, + "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)", + ); + + expect( + schedule.entries[1].title, + "Einführung in die Volkswirtschaftslehre und Mikroökonomik", + ); expect(schedule.entries[1].start, DateTime(2021, 11, 02, 13, 45)); expect(schedule.entries[1].end, DateTime(2021, 11, 02, 17)); expect(schedule.entries[1].type, ScheduleEntryType.Class); expect(schedule.entries[1].professor, "Le, An"); - expect(schedule.entries[1].room, - "WDCM21B,D221 W Hörsaal (Mo 11.10.21 09:00),G086 W Hörsaal (Mo 25.10.21 09:00, Mo 15.11.21 09:00),F218_1 PA Hörsaal (Mo 22.11.21 09:00, Mo 06.12.21 09:00),A167 W Hörsaal (Mo 29.11.21 09:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 13:45)",); + expect( + schedule.entries[1].room, + "WDCM21B,D221 W Hörsaal (Mo 11.10.21 09:00),G086 W Hörsaal (Mo 25.10.21 09:00, Mo 15.11.21 09:00),F218_1 PA Hörsaal (Mo 22.11.21 09:00, Mo 06.12.21 09:00),A167 W Hörsaal (Mo 29.11.21 09:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 13:45)", + ); expect(schedule.entries[2].title, "Grundlagen des Bürgerlichen Rechts"); expect(schedule.entries[2].start, DateTime(2021, 11, 03, 09)); expect(schedule.entries[2].end, DateTime(2021, 11, 03, 11, 30)); expect(schedule.entries[2].type, ScheduleEntryType.Class); expect(schedule.entries[2].professor, "Ei, An"); - expect(schedule.entries[2].room, - "WDCM21B,XOnline-Veranstaltung A Virtueller Raum (Mi 13.10.21 09:00, Mi 27.10.21 09:00, Mi 10.11.21 09:00, Mi 24.11.21 09:00, Fr 03.12.21 10:00),D221 W Hörsaal (Mi 20.10.21 13:00, Mi 17.11.21 09:00),G086 W Hörsaal (Di 26.10.21 09:00, Mi 03.11.21 09:00),B354 W Hörsaal (Fr 03.12.21 10:00),F218_1 PA Hörsaal (Mi 08.12.21 09:00)",); + expect( + schedule.entries[2].room, + "WDCM21B,XOnline-Veranstaltung A Virtueller Raum (Mi 13.10.21 09:00, Mi 27.10.21 09:00, Mi 10.11.21 09:00, Mi 24.11.21 09:00, Fr 03.12.21 10:00),D221 W Hörsaal (Mi 20.10.21 13:00, Mi 17.11.21 09:00),G086 W Hörsaal (Di 26.10.21 09:00, Mi 03.11.21 09:00),B354 W Hörsaal (Fr 03.12.21 10:00),F218_1 PA Hörsaal (Mi 08.12.21 09:00)", + ); expect(schedule.entries[3].title, "Technik der Finanzbuchführung I"); expect(schedule.entries[3].start, DateTime(2021, 11, 03, 13)); expect(schedule.entries[3].end, DateTime(2021, 11, 03, 16, 15)); expect(schedule.entries[3].type, ScheduleEntryType.Class); expect(schedule.entries[3].professor, "Se, Ka"); - expect(schedule.entries[3].room, - "WDCM21B,D221 W Hörsaal (Mi 17.11.21 13:00, Mi 06.10.21 13:00, Mi 13.10.21 13:00),G086 W Hörsaal (Mi 27.10.21 13:00, Mi 03.11.21 13:00, Mi 10.11.21 13:00),A167 W Hörsaal (Mi 24.11.21 13:00, Mi 01.12.21 14:00)",); - - expect(schedule.entries[4].title, - "Grundlagen des wissenschaftlichen Arbeitens",); + expect( + schedule.entries[3].room, + "WDCM21B,D221 W Hörsaal (Mi 17.11.21 13:00, Mi 06.10.21 13:00, Mi 13.10.21 13:00),G086 W Hörsaal (Mi 27.10.21 13:00, Mi 03.11.21 13:00, Mi 10.11.21 13:00),A167 W Hörsaal (Mi 24.11.21 13:00, Mi 01.12.21 14:00)", + ); + + expect( + schedule.entries[4].title, + "Grundlagen des wissenschaftlichen Arbeitens", + ); expect(schedule.entries[4].start, DateTime(2021, 11, 04, 09)); expect(schedule.entries[4].end, DateTime(2021, 11, 04, 12, 15)); expect(schedule.entries[4].type, ScheduleEntryType.Class); expect(schedule.entries[4].professor, "He, Be"); - expect(schedule.entries[4].room, - "WDCM21B,D221 W Hörsaal (Di 05.10.21 09:00, Di 12.10.21 09:00),A167 W Hörsaal (Di 23.11.21 09:00),G086 W Hörsaal (Do 04.11.21 09:00)",); + expect( + schedule.entries[4].room, + "WDCM21B,D221 W Hörsaal (Di 05.10.21 09:00, Di 12.10.21 09:00),A167 W Hörsaal (Di 23.11.21 09:00),G086 W Hörsaal (Do 04.11.21 09:00)", + ); expect(schedule.entries[5].title, "Grundlagen der Handelsbetriebslehre"); expect(schedule.entries[5].start, DateTime(2021, 11, 04, 12, 45)); expect(schedule.entries[5].end, DateTime(2021, 11, 04, 16)); expect(schedule.entries[5].type, ScheduleEntryType.Class); expect(schedule.entries[5].professor, "Fr, Ta"); - expect(schedule.entries[5].room, - "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)",); + expect( + schedule.entries[5].room, + "WDCM21B,G086 W Hörsaal (Di 26.10.21 13:00, Do 04.11.21 12:45, Di 16.11.21 10:00),A167 W Hörsaal (Di 30.11.21 10:00),F218_1 PA Hörsaal (Di 07.12.21 10:00, Mi 08.12.21 13:00),XOnline-Veranstaltung A Virtueller Raum (Di 02.11.21 09:00, Do 11.11.21 09:00)", + ); expect(schedule.entries[6].title, "Einführung in die Programmierung"); expect(schedule.entries[6].start, DateTime(2021, 11, 05, 13)); expect(schedule.entries[6].end, DateTime(2021, 11, 05, 16, 15)); expect(schedule.entries[6].type, ScheduleEntryType.Class); expect(schedule.entries[6].professor, "He, Ma"); - expect(schedule.entries[6].room, - "WDCM21B,C348 PC Raum,D221 W Hörsaal (Fr 08.10.21 13:00, Fr 15.10.21 13:00, Fr 22.10.21 13:00),G086 W Hörsaal (Fr 29.10.21 13:00, Fr 05.11.21 13:00, Fr 12.11.21 13:00, Do 18.11.21 13:00),A167 W Hörsaal (Fr 26.11.21 13:00, Do 02.12.21 13:00)",); + expect( + schedule.entries[6].room, + "WDCM21B,C348 PC Raum,D221 W Hörsaal (Fr 08.10.21 13:00, Fr 15.10.21 13:00, Fr 22.10.21 13:00),G086 W Hörsaal (Fr 29.10.21 13:00, Fr 05.11.21 13:00, Fr 12.11.21 13:00, Do 18.11.21 13:00),A167 W Hörsaal (Fr 26.11.21 13:00, Do 02.12.21 13:00)", + ); expect(schedule.entries.length, 7); }); @@ -261,8 +290,10 @@ Future main() async { expect(schedule.entries[0].end, DateTime(2021, 12, 13, 10)); expect(schedule.entries[0].type, ScheduleEntryType.Exam); expect(schedule.entries[0].professor, "Man, R."); - expect(schedule.entries[0].room, - "TEA20,H031, Hörsaal,N003, Hörsaal,N004, Hörsaal",); + expect( + schedule.entries[0].room, + "TEA20,H031, Hörsaal,N003, Hörsaal,N004, Hörsaal", + ); expect(schedule.entries.length, 7); }); From 1c6bf85c22c877abcb2edeeb264836194a9e01f2 Mon Sep 17 00:00:00 2001 From: Leptopoda Date: Fri, 14 Oct 2022 13:37:08 +0200 Subject: [PATCH 32/37] fix depend_on_referenced_packages --- pubspec.lock | 2 +- pubspec.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pubspec.lock b/pubspec.lock index 117d42d7..a6f46ecb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -484,7 +484,7 @@ packages: source: hosted version: "2.0.2" path: - dependency: transitive + dependency: "direct main" description: name: path url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index 08124d8e..260ec5e8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: kiwi: ^4.0.2 launch_review: ^3.0.1 mutex: ^3.0.0 + path: ^1.8.0 path_provider: ^2.0.9 property_change_notifier: ^0.3.0 provider: ^6.0.2 From ee4903ec8503c37f889c30a6421d6825e5b66c75 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sun, 16 Oct 2022 14:11:41 +0200 Subject: [PATCH 33/37] use copy_with_gen --- .../service/fake_data_dualis_scraper.dart | 2 +- .../parsing/monthly_schedule_extract.dart | 2 +- .../data/schedule_entry_repository.dart | 13 +- lib/schedule/model/schedule.dart | 31 ++-- lib/schedule/model/schedule.g.dart | 67 ++++++++ lib/schedule/model/schedule_entry.dart | 44 ++---- lib/schedule/model/schedule_entry.g.dart | 133 ++++++++++++++++ .../dualis/dualis_schedule_source.dart | 2 +- lib/schedule/service/ical/ical_parser.dart | 2 +- .../rapla/rapla_monthly_response_parser.dart | 2 +- .../service/rapla/rapla_parsing_utils.dart | 2 +- .../service/rapla/rapla_response_parser.dart | 2 +- .../service/rapla/rapla_schedule_source.dart | 2 +- .../rapla_several_months_response_parser.dart | 2 +- .../rapla/rapla_week_response_parser.dart | 2 +- .../viewmodels/daily_schedule_view_model.dart | 2 +- pubspec.lock | 144 +++++++++++++++++- pubspec.yaml | 3 + .../schedule_diff_calculator_test.dart | 4 +- 19 files changed, 386 insertions(+), 75 deletions(-) create mode 100644 lib/schedule/model/schedule.g.dart create mode 100644 lib/schedule/model/schedule_entry.g.dart diff --git a/lib/dualis/service/fake_data_dualis_scraper.dart b/lib/dualis/service/fake_data_dualis_scraper.dart index 90337eb9..27466fca 100644 --- a/lib/dualis/service/fake_data_dualis_scraper.dart +++ b/lib/dualis/service/fake_data_dualis_scraper.dart @@ -60,7 +60,7 @@ class FakeDataDualisScraper implements DualisScraper { CancellationToken cancellationToken, ) async { await Future.delayed(const Duration(milliseconds: 200)); - return Future.value(Schedule.fromList([])); + return Future.value(const Schedule()); } @override diff --git a/lib/dualis/service/parsing/monthly_schedule_extract.dart b/lib/dualis/service/parsing/monthly_schedule_extract.dart index d9cff9be..9448e3a8 100644 --- a/lib/dualis/service/parsing/monthly_schedule_extract.dart +++ b/lib/dualis/service/parsing/monthly_schedule_extract.dart @@ -32,7 +32,7 @@ class MonthlyScheduleExtract { (ScheduleEntry e1, ScheduleEntry e2) => e1.start.compareTo(e2.start), ); - return Schedule.fromList(allEntries); + return Schedule(entries: allEntries); } ScheduleEntry _extractEntry(Element appointment) { diff --git a/lib/schedule/data/schedule_entry_repository.dart b/lib/schedule/data/schedule_entry_repository.dart index 0ee313cf..502db21b 100644 --- a/lib/schedule/data/schedule_entry_repository.dart +++ b/lib/schedule/data/schedule_entry_repository.dart @@ -25,15 +25,12 @@ class ScheduleEntryRepository { ], ); - final schedule = Schedule(); - + final entries = []; for (final row in rows) { - schedule.addEntry( - ScheduleEntryEntity.fromMap(row).asScheduleEntry(), - ); + entries.add(ScheduleEntryEntity.fromMap(row).asScheduleEntry()); } - return schedule; + return Schedule(entries: entries); } Future queryExistingScheduleEntry(ScheduleEntry entry) async { @@ -85,14 +82,14 @@ class ScheduleEntryRepository { final existingEntry = await queryExistingScheduleEntry(entry); if (existingEntry != null) { - entry.id = existingEntry.id; + entry = entry.copyWith.id(existingEntry.id); return; } final row = ScheduleEntryEntity.fromModel(entry).toMap(); if (entry.id == null) { final id = await _database.insert(ScheduleEntryEntity.tableName(), row); - entry.id = id; + entry = entry.copyWith.id(id); } else { await _database.update(ScheduleEntryEntity.tableName(), row); } diff --git a/lib/schedule/model/schedule.dart b/lib/schedule/model/schedule.dart index 4d4291c2..cb425db5 100644 --- a/lib/schedule/model/schedule.dart +++ b/lib/schedule/model/schedule.dart @@ -1,23 +1,24 @@ +import 'package:copy_with_extension/copy_with_extension.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; +part 'schedule.g.dart'; + +@CopyWith() class Schedule { final List entries; - final List urls = []; - - Schedule() : entries = []; + final List urls; - Schedule.fromList(this.entries); - - void addEntry(ScheduleEntry entry) { - entries.add(entry); - } + const Schedule({ + this.entries = const [], + this.urls = const [], + }); void merge(Schedule schedule) { // TODO: Return new schedule instead of adding it to the list urls.addAll(schedule.urls); for (final newEntry in schedule.entries) { - if (entries.any((element) => element.equalsWithIdIgnored(newEntry))) { + if (entries.any((element) => element == newEntry)) { continue; } @@ -25,6 +26,7 @@ class Schedule { } } + // TODO: [Leptopoda] improve nullability Schedule trim(DateTime? startDate, DateTime? endDate) { final newList = []; @@ -34,8 +36,7 @@ class Schedule { } } - final schedule = Schedule.fromList(newList); - schedule.urls.addAll(urls); + final schedule = Schedule(entries: newList, urls: urls); return schedule; } @@ -105,12 +106,4 @@ class Schedule { return latestTime; } - - Schedule copyWith({required List entries}) { - final schedule = Schedule.fromList(entries); - - schedule.urls.addAll(urls); - - return schedule; - } } diff --git a/lib/schedule/model/schedule.g.dart b/lib/schedule/model/schedule.g.dart new file mode 100644 index 00000000..2694f159 --- /dev/null +++ b/lib/schedule/model/schedule.g.dart @@ -0,0 +1,67 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'schedule.dart'; + +// ************************************************************************** +// CopyWithGenerator +// ************************************************************************** + +abstract class _$ScheduleCWProxy { + Schedule entries(List entries); + + Schedule urls(List urls); + + /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `Schedule(...).copyWith.fieldName(...)` to override fields one at a time with nullification support. + /// + /// Usage + /// ```dart + /// Schedule(...).copyWith(id: 12, name: "My name") + /// ```` + Schedule call({ + List? entries, + List? urls, + }); +} + +/// Proxy class for `copyWith` functionality. This is a callable class and can be used as follows: `instanceOfSchedule.copyWith(...)`. Additionally contains functions for specific fields e.g. `instanceOfSchedule.copyWith.fieldName(...)` +class _$ScheduleCWProxyImpl implements _$ScheduleCWProxy { + final Schedule _value; + + const _$ScheduleCWProxyImpl(this._value); + + @override + Schedule entries(List entries) => this(entries: entries); + + @override + Schedule urls(List urls) => this(urls: urls); + + @override + + /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `Schedule(...).copyWith.fieldName(...)` to override fields one at a time with nullification support. + /// + /// Usage + /// ```dart + /// Schedule(...).copyWith(id: 12, name: "My name") + /// ```` + Schedule call({ + Object? entries = const $CopyWithPlaceholder(), + Object? urls = const $CopyWithPlaceholder(), + }) { + return Schedule( + entries: entries == const $CopyWithPlaceholder() || entries == null + ? _value.entries + // ignore: cast_nullable_to_non_nullable + : entries as List, + urls: urls == const $CopyWithPlaceholder() || urls == null + ? _value.urls + // ignore: cast_nullable_to_non_nullable + : urls as List, + ); + } +} + +extension $ScheduleCopyWith on Schedule { + /// Returns a callable class that can be used as follows: `instanceOfSchedule.copyWith(...)` or like so:`instanceOfSchedule.copyWith.fieldName(...)`. + // ignore: library_private_types_in_public_api + _$ScheduleCWProxy get copyWith => _$ScheduleCWProxyImpl(this); +} diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index 503945a6..c590d535 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -1,3 +1,8 @@ +import 'package:copy_with_extension/copy_with_extension.dart'; +import 'package:equatable/equatable.dart'; + +part 'schedule_entry.g.dart'; + enum ScheduleEntryType { Unknown, Class, @@ -6,8 +11,9 @@ enum ScheduleEntryType { Exam, } -class ScheduleEntry { - int? id; +@CopyWith() +class ScheduleEntry extends Equatable { + final int? id; final DateTime start; final DateTime end; final String title; @@ -32,16 +38,6 @@ class ScheduleEntry { room = room ?? "", title = title ?? ""; - bool equalsWithIdIgnored(ScheduleEntry other) { - return start == other.start && - end == other.end && - title == other.title && - details == other.details && - professor == other.professor && - room == other.room && - type == other.type; - } - List getDifferentProperties(ScheduleEntry entry) { final changedProperties = []; @@ -70,25 +66,7 @@ class ScheduleEntry { return changedProperties; } - // TODO: [Leptopoda] use buildrunner - ScheduleEntry copyWith({ - DateTime? start, - DateTime? end, - String? title, - String? details, - String? professor, - String? room, - ScheduleEntryType? type, - }) { - return ScheduleEntry( - id: id, - start: start ?? this.start, - end: end ?? this.end, - title: title ?? this.title, - details: details ?? this.details, - professor: professor ?? this.professor, - room: room ?? this.room, - type: type ?? this.type, - ); - } + @override + List get props => + [start, end, title, details, professor, room, type]; } diff --git a/lib/schedule/model/schedule_entry.g.dart b/lib/schedule/model/schedule_entry.g.dart new file mode 100644 index 00000000..9992d7ab --- /dev/null +++ b/lib/schedule/model/schedule_entry.g.dart @@ -0,0 +1,133 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'schedule_entry.dart'; + +// ************************************************************************** +// CopyWithGenerator +// ************************************************************************** + +abstract class _$ScheduleEntryCWProxy { + ScheduleEntry details(String? details); + + ScheduleEntry end(DateTime? end); + + ScheduleEntry id(int? id); + + ScheduleEntry professor(String? professor); + + ScheduleEntry room(String? room); + + ScheduleEntry start(DateTime? start); + + ScheduleEntry title(String? title); + + ScheduleEntry type(ScheduleEntryType type); + + /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `ScheduleEntry(...).copyWith.fieldName(...)` to override fields one at a time with nullification support. + /// + /// Usage + /// ```dart + /// ScheduleEntry(...).copyWith(id: 12, name: "My name") + /// ```` + ScheduleEntry call({ + String? details, + DateTime? end, + int? id, + String? professor, + String? room, + DateTime? start, + String? title, + ScheduleEntryType? type, + }); +} + +/// Proxy class for `copyWith` functionality. This is a callable class and can be used as follows: `instanceOfScheduleEntry.copyWith(...)`. Additionally contains functions for specific fields e.g. `instanceOfScheduleEntry.copyWith.fieldName(...)` +class _$ScheduleEntryCWProxyImpl implements _$ScheduleEntryCWProxy { + final ScheduleEntry _value; + + const _$ScheduleEntryCWProxyImpl(this._value); + + @override + ScheduleEntry details(String? details) => this(details: details); + + @override + ScheduleEntry end(DateTime? end) => this(end: end); + + @override + ScheduleEntry id(int? id) => this(id: id); + + @override + ScheduleEntry professor(String? professor) => this(professor: professor); + + @override + ScheduleEntry room(String? room) => this(room: room); + + @override + ScheduleEntry start(DateTime? start) => this(start: start); + + @override + ScheduleEntry title(String? title) => this(title: title); + + @override + ScheduleEntry type(ScheduleEntryType type) => this(type: type); + + @override + + /// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `ScheduleEntry(...).copyWith.fieldName(...)` to override fields one at a time with nullification support. + /// + /// Usage + /// ```dart + /// ScheduleEntry(...).copyWith(id: 12, name: "My name") + /// ```` + ScheduleEntry call({ + Object? details = const $CopyWithPlaceholder(), + Object? end = const $CopyWithPlaceholder(), + Object? id = const $CopyWithPlaceholder(), + Object? professor = const $CopyWithPlaceholder(), + Object? room = const $CopyWithPlaceholder(), + Object? start = const $CopyWithPlaceholder(), + Object? title = const $CopyWithPlaceholder(), + Object? type = const $CopyWithPlaceholder(), + }) { + return ScheduleEntry( + details: details == const $CopyWithPlaceholder() + ? _value.details + // ignore: cast_nullable_to_non_nullable + : details as String?, + end: end == const $CopyWithPlaceholder() + ? _value.end + // ignore: cast_nullable_to_non_nullable + : end as DateTime?, + id: id == const $CopyWithPlaceholder() + ? _value.id + // ignore: cast_nullable_to_non_nullable + : id as int?, + professor: professor == const $CopyWithPlaceholder() + ? _value.professor + // ignore: cast_nullable_to_non_nullable + : professor as String?, + room: room == const $CopyWithPlaceholder() + ? _value.room + // ignore: cast_nullable_to_non_nullable + : room as String?, + start: start == const $CopyWithPlaceholder() + ? _value.start + // ignore: cast_nullable_to_non_nullable + : start as DateTime?, + title: title == const $CopyWithPlaceholder() + ? _value.title + // ignore: cast_nullable_to_non_nullable + : title as String?, + type: type == const $CopyWithPlaceholder() || type == null + ? _value.type + // ignore: cast_nullable_to_non_nullable + : type as ScheduleEntryType, + ); + } +} + +extension $ScheduleEntryCopyWith on ScheduleEntry { + /// Returns a callable class that can be used as follows: `instanceOfScheduleEntry.copyWith(...)` or like so:`instanceOfScheduleEntry.copyWith.fieldName(...)`. + // ignore: library_private_types_in_public_api + _$ScheduleEntryCWProxy get copyWith => _$ScheduleEntryCWProxyImpl(this); +} diff --git a/lib/schedule/service/dualis/dualis_schedule_source.dart b/lib/schedule/service/dualis/dualis_schedule_source.dart index ecdf3663..c479e87f 100644 --- a/lib/schedule/service/dualis/dualis_schedule_source.dart +++ b/lib/schedule/service/dualis/dualis_schedule_source.dart @@ -24,7 +24,7 @@ class DualisScheduleSource extends ScheduleSource { DateTime current = toStartOfMonth(from)!; - var schedule = Schedule(); + var schedule = const Schedule(); final allErrors = []; if (!_dualisScraper.isLoggedIn()) { diff --git a/lib/schedule/service/ical/ical_parser.dart b/lib/schedule/service/ical/ical_parser.dart index a3587c2f..3a1a22d0 100644 --- a/lib/schedule/service/ical/ical_parser.dart +++ b/lib/schedule/service/ical/ical_parser.dart @@ -39,7 +39,7 @@ class IcalParser { } return ScheduleQueryResult( - Schedule.fromList(entries), + Schedule(entries: entries), [], ); } diff --git a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart index d5e20c52..d78f6fa8 100644 --- a/lib/schedule/service/rapla/rapla_monthly_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_monthly_response_parser.dart @@ -49,7 +49,7 @@ class RaplaMonthlyResponseParser { } } - return ScheduleQueryResult(Schedule.fromList(allEntries), parseErrors); + return ScheduleQueryResult(Schedule(entries: allEntries), parseErrors); } static int? _monthStringToDateTime(String monthAndYear) { diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index fc502465..5ea96056 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -75,7 +75,7 @@ class RaplaParsingUtils { } static ScheduleEntry improveScheduleEntry(ScheduleEntry scheduleEntry) { - if (scheduleEntry.title == "") { + if (scheduleEntry.title.isEmpty) { throw ElementNotFoundParseException("title"); } diff --git a/lib/schedule/service/rapla/rapla_response_parser.dart b/lib/schedule/service/rapla/rapla_response_parser.dart index f051c537..a8c6ac06 100644 --- a/lib/schedule/service/rapla/rapla_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_response_parser.dart @@ -26,7 +26,7 @@ class RaplaResponseParser { ); } - return ScheduleQueryResult(Schedule(), [ + return ScheduleQueryResult(const Schedule(), [ ParseError("Did not find a week_table and month_table class"), ]); } diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index 10b4550d..9b870fa2 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -25,7 +25,7 @@ class RaplaScheduleSource extends ScheduleSource { cancellationToken ??= CancellationToken(); - var schedule = Schedule(); + var schedule = const Schedule(); final allErrors = []; var didChangeMonth = false; diff --git a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart index 5a18d583..6d427a8d 100644 --- a/lib/schedule/service/rapla/rapla_several_months_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_several_months_response_parser.dart @@ -21,6 +21,6 @@ class RaplaSeveralMonthsResponseParser { allEntries.addAll(result.schedule.entries); } - return ScheduleQueryResult(Schedule.fromList(allEntries), parseErrors); + return ScheduleQueryResult(Schedule(entries: allEntries), parseErrors); } } diff --git a/lib/schedule/service/rapla/rapla_week_response_parser.dart b/lib/schedule/service/rapla/rapla_week_response_parser.dart index d4bdbe4c..54de3087 100644 --- a/lib/schedule/service/rapla/rapla_week_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_week_response_parser.dart @@ -69,7 +69,7 @@ class RaplaWeekResponseParser { ); return ScheduleQueryResult( - Schedule.fromList(allEntries), + Schedule(entries: allEntries), parseErrors, ); } diff --git a/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart b/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart index f81ae6fc..25113a59 100644 --- a/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart +++ b/lib/schedule/ui/viewmodels/daily_schedule_view_model.dart @@ -23,7 +23,7 @@ class DailyScheduleViewModel extends BaseViewModel { notifyListeners("daySchedule"); } - Schedule get daySchedule => _daySchedule ??= Schedule(); + Schedule get schedule => _daySchedule ??= const Schedule(); Future loadScheduleForToday() async { final now = DateTime.now(); diff --git a/pubspec.lock b/pubspec.lock index a6f46ecb..048ff0bb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "40.0.0" + version: "47.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.7.0" animations: dependency: "direct main" description: @@ -57,6 +57,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.10" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.4" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.4.1" characters: dependency: transitive description: @@ -71,6 +127,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" clock: dependency: transitive description: @@ -78,6 +141,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.0" collection: dependency: transitive description: @@ -92,6 +162,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" + copy_with_extension: + dependency: "direct main" + description: + name: copy_with_extension + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.4" + copy_with_extension_gen: + dependency: "direct dev" + description: + name: copy_with_extension_gen + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.4" coverage: dependency: transitive description: @@ -113,6 +197,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.17.1" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" dbus: dependency: transitive description: @@ -211,6 +302,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.4" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" flutter: dependency: "direct main" description: flutter @@ -336,6 +434,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.2" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" html: dependency: "direct main" description: @@ -399,6 +504,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.4" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.7.0" kiwi: dependency: "direct main" description: @@ -595,6 +707,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" shared_preferences: dependency: "direct main" description: @@ -684,6 +803,13 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.2" source_map_stack_trace: dependency: transitive description: @@ -740,6 +866,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" string_scanner: dependency: transitive description: @@ -789,6 +922,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.8.0" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 260ec5e8..290c8e39 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -19,6 +19,7 @@ environment: dependencies: animations: ^2.0.2 app_group_directory: ^2.0.0 + copy_with_extension: ^4.0.0 device_calendar: ^4.2.0 equatable: ^2.0.0 firebase_analytics: ^9.1.6 @@ -52,6 +53,8 @@ dependencies: workmanager: ^0.5.0 dev_dependencies: + build_runner: ^2.3.0 + copy_with_extension_gen: ^4.0.0 flutter_test: sdk: flutter lint: ^1.10.0 diff --git a/test/schedule/business/schedule_diff_calculator_test.dart b/test/schedule/business/schedule_diff_calculator_test.dart index 057644e6..b8323b05 100644 --- a/test/schedule/business/schedule_diff_calculator_test.dart +++ b/test/schedule/business/schedule_diff_calculator_test.dart @@ -50,7 +50,7 @@ void main() { end: DateTime(2020, 06, 09, 18), ); - newSchedule.addEntry(newEntry); + newSchedule.entries.add(newEntry); final diff = calculator.calculateDiff(oldSchedule, newSchedule); @@ -197,5 +197,5 @@ Schedule generateSchedule() { ), ]; - return Schedule.fromList(scheduleEntries); + return Schedule(entries: scheduleEntries); } From 5e7cdd8472127970ef66aff16b8516db0d03b7d0 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sat, 15 Oct 2022 12:08:17 +0200 Subject: [PATCH 34/37] use json_serialisable --- analysis_options.yaml | 2 +- lib/common/data/database_entity.dart | 4 -- .../data/epoch_date_time_converter.dart | 11 ++++ .../data/date_entry_entity.dart | 49 ---------------- .../data/date_entry_repository.dart | 17 +++--- lib/date_management/model/date_entry.dart | 18 +++++- lib/date_management/model/date_entry.g.dart | 35 +++++++++++ lib/schedule/data/schedule_entry_entity.dart | 58 ------------------- .../data/schedule_entry_repository.dart | 25 ++++---- .../schedule_query_information_entity.dart | 52 ----------------- ...schedule_query_information_repository.dart | 14 ++--- lib/schedule/model/schedule_entry.dart | 20 +++++++ lib/schedule/model/schedule_entry.g.dart | 36 ++++++++++++ .../model/schedule_query_information.dart | 16 +++++ .../model/schedule_query_information.g.dart | 39 +++++++++++++ pubspec.lock | 16 ++++- pubspec.yaml | 2 + 17 files changed, 218 insertions(+), 196 deletions(-) delete mode 100644 lib/common/data/database_entity.dart create mode 100644 lib/common/data/epoch_date_time_converter.dart delete mode 100644 lib/date_management/data/date_entry_entity.dart create mode 100644 lib/date_management/model/date_entry.g.dart delete mode 100644 lib/schedule/data/schedule_entry_entity.dart delete mode 100644 lib/schedule/data/schedule_query_information_entity.dart create mode 100644 lib/schedule/model/schedule_query_information.g.dart diff --git a/analysis_options.yaml b/analysis_options.yaml index 8c7dd194..3566b291 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -6,7 +6,7 @@ include: package:lint/analysis_options.yaml # You might want to exclude auto-generated files from dart analysis analyzer: exclude: - #- '**.freezed.dart' + - "**.g.dart" # You can customize the lint rules set to your own liking. A list of all rules # can be found at https://dart-lang.github.io/linter/lints/options/options.html diff --git a/lib/common/data/database_entity.dart b/lib/common/data/database_entity.dart deleted file mode 100644 index 65967e9e..00000000 --- a/lib/common/data/database_entity.dart +++ /dev/null @@ -1,4 +0,0 @@ -abstract class DatabaseEntity { - Map toMap(); - fromMap(Map map); -} diff --git a/lib/common/data/epoch_date_time_converter.dart b/lib/common/data/epoch_date_time_converter.dart new file mode 100644 index 00000000..555731ba --- /dev/null +++ b/lib/common/data/epoch_date_time_converter.dart @@ -0,0 +1,11 @@ +import 'package:json_annotation/json_annotation.dart'; + +class EpochDateTimeConverter implements JsonConverter { + const EpochDateTimeConverter(); + + @override + DateTime fromJson(int json) => DateTime.fromMillisecondsSinceEpoch(json); + + @override + int toJson(DateTime object) => object.millisecondsSinceEpoch; +} diff --git a/lib/date_management/data/date_entry_entity.dart b/lib/date_management/data/date_entry_entity.dart deleted file mode 100644 index 593637d7..00000000 --- a/lib/date_management/data/date_entry_entity.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:dhbwstudentapp/common/data/database_entity.dart'; -import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; - -class DateEntryEntity extends DatabaseEntity { - // TODO: [Leptopoda] make non null - DateEntry? _dateEntry; - - DateEntryEntity.fromModel(DateEntry dateEntry) : _dateEntry = dateEntry; - - DateEntryEntity.fromMap(Map map) { - fromMap(map); - } - - @override - void fromMap(Map map) { - final date = map["date"] as int?; - DateTime? dateTime; - if (date != null) { - dateTime = DateTime.fromMillisecondsSinceEpoch(date); - } - - _dateEntry = DateEntry( - comment: map["comment"] as String?, - description: map["description"] as String?, - year: map["year"] as String?, - databaseName: map["databaseName"] as String?, - start: dateTime, - end: dateTime, - room: map["room"] as String?, - ); - } - - @override - Map toMap() { - assert(_dateEntry != null); - return { - "date": _dateEntry!.start.millisecondsSinceEpoch, - "comment": _dateEntry!.comment, - "description": _dateEntry!.description, - "year": _dateEntry!.year, - "databaseName": _dateEntry!.databaseName, - }; - } - - DateEntry asDateEntry() => _dateEntry!; - - // TODO: [Leptopoda] make getter or even constant. - static String tableName() => "DateEntries"; -} diff --git a/lib/date_management/data/date_entry_repository.dart b/lib/date_management/data/date_entry_repository.dart index 46c9c177..986e6366 100644 --- a/lib/date_management/data/date_entry_repository.dart +++ b/lib/date_management/data/date_entry_repository.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/data/database_access.dart'; -import 'package:dhbwstudentapp/date_management/data/date_entry_entity.dart'; import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; class DateEntryRepository { @@ -12,7 +11,7 @@ class DateEntryRepository { String? year, ) async { final rows = await _database.queryRows( - DateEntryEntity.tableName(), + DateEntry.tableName, where: "databaseName=? AND year=?", whereArgs: [databaseName, year], ); @@ -27,7 +26,7 @@ class DateEntryRepository { DateTime end, ) async { final rows = await _database.queryRows( - DateEntryEntity.tableName(), + DateEntry.tableName, where: "date>=? AND date<=? AND databaseName=? AND year=?", whereArgs: [ start.millisecondsSinceEpoch, @@ -46,7 +45,7 @@ class DateEntryRepository { DateTime date, ) async { final rows = await _database.queryRows( - DateEntryEntity.tableName(), + DateEntry.tableName, where: "date>=? AND databaseName=? AND year=?", whereArgs: [ date.millisecondsSinceEpoch, @@ -64,7 +63,7 @@ class DateEntryRepository { DateTime date, ) async { final rows = await _database.queryRows( - DateEntryEntity.tableName(), + DateEntry.tableName, where: "date<=? AND databaseName=? AND year=?", whereArgs: [ date.millisecondsSinceEpoch, @@ -77,8 +76,8 @@ class DateEntryRepository { } Future saveDateEntry(DateEntry entry) async { - final row = DateEntryEntity.fromModel(entry).toMap(); - await _database.insert(DateEntryEntity.tableName(), row); + final row = entry.toJson(); + await _database.insert(DateEntry.tableName, row); } Future saveDateEntries(List entries) async { @@ -92,7 +91,7 @@ class DateEntryRepository { String? year, ) async { await _database.deleteWhere( - DateEntryEntity.tableName(), + DateEntry.tableName, where: "databaseName=? AND year=?", whereArgs: [ databaseName, @@ -106,7 +105,7 @@ class DateEntryRepository { for (final row in rows) { dateEntries.add( - DateEntryEntity.fromMap(row).asDateEntry(), + DateEntry.fromJson(row), ); } diff --git a/lib/date_management/model/date_entry.dart b/lib/date_management/model/date_entry.dart index 3a146e56..52252419 100644 --- a/lib/date_management/model/date_entry.dart +++ b/lib/date_management/model/date_entry.dart @@ -1,9 +1,18 @@ +import 'package:dhbwstudentapp/common/data/epoch_date_time_converter.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'date_entry.g.dart'; + +@JsonSerializable() class DateEntry { final String description; final String year; final String comment; final String databaseName; + @JsonKey(name: "date") + @EpochDateTimeConverter() final DateTime start; + @EpochDateTimeConverter() final DateTime end; final String? room; @@ -16,9 +25,16 @@ class DateEntry { DateTime? end, this.room, }) : start = start ?? DateTime.fromMicrosecondsSinceEpoch(0), - end = end ?? DateTime.fromMicrosecondsSinceEpoch(0), + end = end ?? start ?? DateTime.fromMicrosecondsSinceEpoch(0), comment = comment ?? "", description = description ?? "", year = year ?? "", databaseName = databaseName ?? ""; + + factory DateEntry.fromJson(Map json) => + _$DateEntryFromJson(json); + + Map toJson() => _$DateEntryToJson(this); + + static const tableName = "DateEntries"; } diff --git a/lib/date_management/model/date_entry.g.dart b/lib/date_management/model/date_entry.g.dart new file mode 100644 index 00000000..b7c6130d --- /dev/null +++ b/lib/date_management/model/date_entry.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'date_entry.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DateEntry _$DateEntryFromJson(Map json) => DateEntry( + description: json['description'] as String?, + year: json['year'] as String?, + comment: json['comment'] as String?, + databaseName: json['databaseName'] as String?, + start: _$JsonConverterFromJson( + json['date'], const EpochDateTimeConverter().fromJson), + end: _$JsonConverterFromJson( + json['end'], const EpochDateTimeConverter().fromJson), + room: json['room'] as String?, + ); + +Map _$DateEntryToJson(DateEntry instance) => { + 'description': instance.description, + 'year': instance.year, + 'comment': instance.comment, + 'databaseName': instance.databaseName, + 'date': const EpochDateTimeConverter().toJson(instance.start), + 'end': const EpochDateTimeConverter().toJson(instance.end), + 'room': instance.room, + }; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); diff --git a/lib/schedule/data/schedule_entry_entity.dart b/lib/schedule/data/schedule_entry_entity.dart deleted file mode 100644 index 43b16d09..00000000 --- a/lib/schedule/data/schedule_entry_entity.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:dhbwstudentapp/common/data/database_entity.dart'; -import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; - -class ScheduleEntryEntity extends DatabaseEntity { - late ScheduleEntry _scheduleEntry; - - ScheduleEntryEntity.fromModel(ScheduleEntry scheduleEntry) { - _scheduleEntry = scheduleEntry; - } - - ScheduleEntryEntity.fromMap(Map map) { - fromMap(map); - } - - @override - void fromMap(Map map) { - final start = map["start"] as int?; - DateTime? startDate; - if (start != null) { - startDate = DateTime.fromMillisecondsSinceEpoch(start); - } - - final end = map["end"] as int?; - DateTime? endDate; - if (end != null) { - endDate = DateTime.fromMillisecondsSinceEpoch(end); - } - - _scheduleEntry = ScheduleEntry( - id: map["id"] as int?, - start: startDate, - end: endDate, - details: map["details"] as String?, - professor: map["professor"] as String?, - title: map["title"] as String?, - room: map["room"] as String?, - type: ScheduleEntryType.values[map["type"] as int], - ); - } - - @override - Map toMap() { - return { - "id": _scheduleEntry.id, - "start": _scheduleEntry.start.millisecondsSinceEpoch, - "end": _scheduleEntry.end.millisecondsSinceEpoch, - "details": _scheduleEntry.details, - "professor": _scheduleEntry.professor, - "room": _scheduleEntry.room, - "title": _scheduleEntry.title, - "type": _scheduleEntry.type.index - }; - } - - ScheduleEntry asScheduleEntry() => _scheduleEntry; - - static String tableName() => "ScheduleEntries"; -} diff --git a/lib/schedule/data/schedule_entry_repository.dart b/lib/schedule/data/schedule_entry_repository.dart index 502db21b..039f260d 100644 --- a/lib/schedule/data/schedule_entry_repository.dart +++ b/lib/schedule/data/schedule_entry_repository.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/data/database_access.dart'; -import 'package:dhbwstudentapp/schedule/data/schedule_entry_entity.dart'; import 'package:dhbwstudentapp/schedule/model/schedule.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; @@ -17,7 +16,7 @@ class ScheduleEntryRepository { DateTime end, ) async { final rows = await _database.queryRows( - ScheduleEntryEntity.tableName(), + ScheduleEntry.tableName, where: "end>? AND start[]; for (final row in rows) { - entries.add(ScheduleEntryEntity.fromMap(row).asScheduleEntry()); + entries.add(ScheduleEntry.fromJson(row)); } return Schedule(entries: entries); @@ -35,7 +34,7 @@ class ScheduleEntryRepository { Future queryExistingScheduleEntry(ScheduleEntry entry) async { final rows = await _database.queryRows( - ScheduleEntryEntity.tableName(), + ScheduleEntry.tableName, where: "start=? AND end=? AND title=? AND details=? AND professor=?", whereArgs: [ entry.start.millisecondsSinceEpoch, @@ -48,12 +47,12 @@ class ScheduleEntryRepository { if (rows.isEmpty) return null; - return ScheduleEntryEntity.fromMap(rows[0]).asScheduleEntry(); + return ScheduleEntry.fromJson(rows[0]); } Future queryNextScheduleEntry(DateTime dateTime) async { final nextScheduleEntry = await _database.queryRows( - ScheduleEntryEntity.tableName(), + ScheduleEntry.tableName, where: "start>?", whereArgs: [dateTime.millisecondsSinceEpoch], limit: 1, @@ -63,7 +62,7 @@ class ScheduleEntryRepository { final entriesList = nextScheduleEntry.toList(); if (entriesList.length == 1) { - return ScheduleEntryEntity.fromMap(entriesList[0]).asScheduleEntry(); + return ScheduleEntry.fromJson(entriesList[0]); } return null; @@ -86,12 +85,12 @@ class ScheduleEntryRepository { return; } - final row = ScheduleEntryEntity.fromModel(entry).toMap(); + final row = entry.toJson(); if (entry.id == null) { - final id = await _database.insert(ScheduleEntryEntity.tableName(), row); + final id = await _database.insert(ScheduleEntry.tableName, row); entry = entry.copyWith.id(id); } else { - await _database.update(ScheduleEntryEntity.tableName(), row); + await _database.update(ScheduleEntry.tableName, row); } } @@ -102,7 +101,7 @@ class ScheduleEntryRepository { } Future deleteScheduleEntry(ScheduleEntry entry) async { - await _database.delete(ScheduleEntryEntity.tableName(), entry.id); + await _database.delete(ScheduleEntry.tableName, entry.id); } Future deleteScheduleEntriesBetween( @@ -110,7 +109,7 @@ class ScheduleEntryRepository { DateTime end, ) async { await _database.deleteWhere( - ScheduleEntryEntity.tableName(), + ScheduleEntry.tableName, where: "start>=? AND end<=?", whereArgs: [ start.millisecondsSinceEpoch, @@ -121,7 +120,7 @@ class ScheduleEntryRepository { Future deleteAllScheduleEntries() async { await _database.deleteWhere( - ScheduleEntryEntity.tableName(), + ScheduleEntry.tableName, where: "1=1", whereArgs: [], ); diff --git a/lib/schedule/data/schedule_query_information_entity.dart b/lib/schedule/data/schedule_query_information_entity.dart deleted file mode 100644 index fa1f9068..00000000 --- a/lib/schedule/data/schedule_query_information_entity.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:dhbwstudentapp/common/data/database_entity.dart'; -import 'package:dhbwstudentapp/schedule/model/schedule_query_information.dart'; - -class ScheduleQueryInformationEntity extends DatabaseEntity { - ScheduleQueryInformation? _scheduleQueryInformation; - - ScheduleQueryInformationEntity.fromModel( - ScheduleQueryInformation scheduleQueryInformation, - ) { - _scheduleQueryInformation = scheduleQueryInformation; - } - - ScheduleQueryInformationEntity.fromMap(Map map) { - fromMap(map); - } - - @override - void fromMap(Map map) { - DateTime? startDate; - if (map["start"] != null) { - startDate = DateTime.fromMillisecondsSinceEpoch(map["start"] as int); - } - - DateTime? endDate; - if (map["end"] != null) { - endDate = DateTime.fromMillisecondsSinceEpoch(map["end"] as int); - } - - DateTime? queryTimeDate; - if (map["queryTime"] != null) { - queryTimeDate = - DateTime.fromMillisecondsSinceEpoch(map["queryTime"] as int); - } - - _scheduleQueryInformation = - ScheduleQueryInformation(startDate, endDate, queryTimeDate); - } - - @override - Map toMap() { - return { - "start": _scheduleQueryInformation!.start.millisecondsSinceEpoch, - "end": _scheduleQueryInformation!.end.millisecondsSinceEpoch, - "queryTime": _scheduleQueryInformation!.queryTime?.millisecondsSinceEpoch, - }; - } - - ScheduleQueryInformation? asScheduleQueryInformation() => - _scheduleQueryInformation; - - static String tableName() => "ScheduleQueryInformation"; -} diff --git a/lib/schedule/data/schedule_query_information_repository.dart b/lib/schedule/data/schedule_query_information_repository.dart index 524103ca..c76df96d 100644 --- a/lib/schedule/data/schedule_query_information_repository.dart +++ b/lib/schedule/data/schedule_query_information_repository.dart @@ -1,5 +1,4 @@ import 'package:dhbwstudentapp/common/data/database_access.dart'; -import 'package:dhbwstudentapp/schedule/data/schedule_query_information_entity.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_query_information.dart'; class ScheduleQueryInformationRepository { @@ -29,7 +28,7 @@ class ScheduleQueryInformationRepository { DateTime end, ) async { final rows = await _database.queryRows( - ScheduleQueryInformationEntity.tableName(), + ScheduleQueryInformation.tableName, where: "start<=? AND end>=?", whereArgs: [ start.millisecondsSinceEpoch, @@ -41,8 +40,7 @@ class ScheduleQueryInformationRepository { for (final row in rows) { scheduleQueryInformation.add( - ScheduleQueryInformationEntity.fromMap(row) - .asScheduleQueryInformation(), + ScheduleQueryInformation.fromJson(row), ); } @@ -53,7 +51,7 @@ class ScheduleQueryInformationRepository { ScheduleQueryInformation queryInformation, ) async { await _database.deleteWhere( - ScheduleQueryInformationEntity.tableName(), + ScheduleQueryInformation.tableName, where: "start=? AND end=?", whereArgs: [ queryInformation.start.millisecondsSinceEpoch, @@ -62,14 +60,14 @@ class ScheduleQueryInformationRepository { ); await _database.insert( - ScheduleQueryInformationEntity.tableName(), - ScheduleQueryInformationEntity.fromModel(queryInformation).toMap(), + ScheduleQueryInformation.tableName, + queryInformation.toJson(), ); } Future deleteAllQueryInformation() async { await _database.deleteWhere( - ScheduleQueryInformationEntity.tableName(), + ScheduleQueryInformation.tableName, where: "1=1", whereArgs: [], ); diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index c590d535..b99de2e3 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -1,5 +1,7 @@ import 'package:copy_with_extension/copy_with_extension.dart'; +import 'package:dhbwstudentapp/common/data/epoch_date_time_converter.dart'; import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; part 'schedule_entry.g.dart'; @@ -12,14 +14,21 @@ enum ScheduleEntryType { } @CopyWith() +@JsonSerializable() class ScheduleEntry extends Equatable { final int? id; + @EpochDateTimeConverter() final DateTime start; + @EpochDateTimeConverter() final DateTime end; final String title; final String details; final String professor; final String room; + @JsonKey( + toJson: _typeToJson, + fromJson: _typeFromJson, + ) final ScheduleEntryType type; ScheduleEntry({ @@ -66,6 +75,17 @@ class ScheduleEntry extends Equatable { return changedProperties; } + factory ScheduleEntry.fromJson(Map json) => + _$ScheduleEntryFromJson(json); + + Map toJson() => _$ScheduleEntryToJson(this); + + static const tableName = "ScheduleEntries"; + + static int _typeToJson(ScheduleEntryType value) => value.index; + static ScheduleEntryType _typeFromJson(int value) => + ScheduleEntryType.values[value]; + @override List get props => [start, end, title, details, professor, room, type]; diff --git a/lib/schedule/model/schedule_entry.g.dart b/lib/schedule/model/schedule_entry.g.dart index 9992d7ab..03d213e9 100644 --- a/lib/schedule/model/schedule_entry.g.dart +++ b/lib/schedule/model/schedule_entry.g.dart @@ -131,3 +131,39 @@ extension $ScheduleEntryCopyWith on ScheduleEntry { // ignore: library_private_types_in_public_api _$ScheduleEntryCWProxy get copyWith => _$ScheduleEntryCWProxyImpl(this); } + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ScheduleEntry _$ScheduleEntryFromJson(Map json) => + ScheduleEntry( + id: json['id'] as int?, + start: _$JsonConverterFromJson( + json['start'], const EpochDateTimeConverter().fromJson), + end: _$JsonConverterFromJson( + json['end'], const EpochDateTimeConverter().fromJson), + title: json['title'] as String?, + details: json['details'] as String?, + professor: json['professor'] as String?, + room: json['room'] as String?, + type: ScheduleEntry._typeFromJson(json['type'] as int), + ); + +Map _$ScheduleEntryToJson(ScheduleEntry instance) => + { + 'id': instance.id, + 'start': const EpochDateTimeConverter().toJson(instance.start), + 'end': const EpochDateTimeConverter().toJson(instance.end), + 'title': instance.title, + 'details': instance.details, + 'professor': instance.professor, + 'room': instance.room, + 'type': ScheduleEntry._typeToJson(instance.type), + }; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); diff --git a/lib/schedule/model/schedule_query_information.dart b/lib/schedule/model/schedule_query_information.dart index f2d5091c..ec5be49a 100644 --- a/lib/schedule/model/schedule_query_information.dart +++ b/lib/schedule/model/schedule_query_information.dart @@ -1,6 +1,15 @@ +import 'package:dhbwstudentapp/common/data/epoch_date_time_converter.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'schedule_query_information.g.dart'; + +@JsonSerializable() class ScheduleQueryInformation { + @EpochDateTimeConverter() final DateTime start; + @EpochDateTimeConverter() final DateTime end; + @EpochDateTimeConverter() final DateTime? queryTime; ScheduleQueryInformation( @@ -9,4 +18,11 @@ class ScheduleQueryInformation { this.queryTime, ) : start = start ?? DateTime.fromMillisecondsSinceEpoch(0), end = end ?? DateTime.fromMillisecondsSinceEpoch(0); + + factory ScheduleQueryInformation.fromJson(Map json) => + _$ScheduleQueryInformationFromJson(json); + + Map toJson() => _$ScheduleQueryInformationToJson(this); + + static const tableName = "ScheduleQueryInformation"; } diff --git a/lib/schedule/model/schedule_query_information.g.dart b/lib/schedule/model/schedule_query_information.g.dart new file mode 100644 index 00000000..a0492ffc --- /dev/null +++ b/lib/schedule/model/schedule_query_information.g.dart @@ -0,0 +1,39 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'schedule_query_information.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ScheduleQueryInformation _$ScheduleQueryInformationFromJson( + Map json) => + ScheduleQueryInformation( + _$JsonConverterFromJson( + json['start'], const EpochDateTimeConverter().fromJson), + _$JsonConverterFromJson( + json['end'], const EpochDateTimeConverter().fromJson), + _$JsonConverterFromJson( + json['queryTime'], const EpochDateTimeConverter().fromJson), + ); + +Map _$ScheduleQueryInformationToJson( + ScheduleQueryInformation instance) => + { + 'start': const EpochDateTimeConverter().toJson(instance.start), + 'end': const EpochDateTimeConverter().toJson(instance.end), + 'queryTime': _$JsonConverterToJson( + instance.queryTime, const EpochDateTimeConverter().toJson), + }; + +Value? _$JsonConverterFromJson( + Object? json, + Value? Function(Json json) fromJson, +) => + json == null ? null : fromJson(json as Json); + +Json? _$JsonConverterToJson( + Value? value, + Json? Function(Value value) toJson, +) => + value == null ? null : toJson(value); diff --git a/pubspec.lock b/pubspec.lock index 048ff0bb..544208eb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -505,12 +505,19 @@ packages: source: hosted version: "0.6.4" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation url: "https://pub.dartlang.org" source: hosted version: "4.7.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "6.5.1" kiwi: dependency: "direct main" description: @@ -810,6 +817,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.2" + source_helper: + dependency: transitive + description: + name: source_helper + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.3" source_map_stack_trace: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 290c8e39..8d2b8f3f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: http: ^0.13.4 http_client_helper: ^2.0.2 intl: ^0.17.0 + json_annotation: ^4.7.0 kiwi: ^4.0.2 launch_review: ^3.0.1 mutex: ^3.0.0 @@ -57,6 +58,7 @@ dev_dependencies: copy_with_extension_gen: ^4.0.0 flutter_test: sdk: flutter + json_serializable: ^6.5.0 lint: ^1.10.0 test: any From 6af1c044f458a96d266c7fe5a6326049bc86c53a Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sat, 15 Oct 2022 13:10:18 +0200 Subject: [PATCH 35/37] use assets_gen --- lib/assets.dart | 36 +++++++++++++++++++ .../ui/dailyschedule/daily_schedule_page.dart | 3 +- .../ui/widgets/schedule_empty_state.dart | 5 +-- .../widgets/onboarding_page_background.dart | 9 ++--- lib/ui/settings/settings_page.dart | 3 +- pubspec.lock | 14 ++++++++ pubspec.yaml | 1 + 7 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 lib/assets.dart diff --git a/lib/assets.dart b/lib/assets.dart new file mode 100644 index 00000000..bfec560e --- /dev/null +++ b/lib/assets.dart @@ -0,0 +1,36 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// Total assets: 9. +// Generated by https://pub.dev/packages/assets_gen. +// ************************************************************************** +class Assets { + static const String package = 'dhbwstudentapp'; + + static const String assets_app_icon_png = 'assets/app_icon.png'; + static const String dhbwstudentapp$assets_app_icon_png = 'packages/dhbwstudentapp/assets/app_icon.png'; + + static const String assets_empty_state_png = 'assets/empty_state.png'; + static const String dhbwstudentapp$assets_empty_state_png = 'packages/dhbwstudentapp/assets/empty_state.png'; + + static const String assets_onboarding_bottom_background_png = 'assets/onboarding_bottom_background.png'; + static const String dhbwstudentapp$assets_onboarding_bottom_background_png = 'packages/dhbwstudentapp/assets/onboarding_bottom_background.png'; + + static const String assets_onboarding_bottom_background_dark_png = 'assets/onboarding_bottom_background_dark.png'; + static const String dhbwstudentapp$assets_onboarding_bottom_background_dark_png = 'packages/dhbwstudentapp/assets/onboarding_bottom_background_dark.png'; + + static const String assets_onboarding_bottom_foreground_png = 'assets/onboarding_bottom_foreground.png'; + static const String dhbwstudentapp$assets_onboarding_bottom_foreground_png = 'packages/dhbwstudentapp/assets/onboarding_bottom_foreground.png'; + + static const String assets_onboarding_bottom_foreground_dark_png = 'assets/onboarding_bottom_foreground_dark.png'; + static const String dhbwstudentapp$assets_onboarding_bottom_foreground_dark_png = 'packages/dhbwstudentapp/assets/onboarding_bottom_foreground_dark.png'; + + static const String assets_schedule_empty_state_png = 'assets/schedule_empty_state.png'; + static const String dhbwstudentapp$assets_schedule_empty_state_png = 'packages/dhbwstudentapp/assets/schedule_empty_state.png'; + + static const String assets_schedule_empty_state_dark_png = 'assets/schedule_empty_state_dark.png'; + static const String dhbwstudentapp$assets_schedule_empty_state_dark_png = 'packages/dhbwstudentapp/assets/schedule_empty_state_dark.png'; + + static const String assets_splash_png = 'assets/splash.png'; + static const String dhbwstudentapp$assets_splash_png = 'packages/dhbwstudentapp/assets/splash.png'; +} diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index baccc30f..e12a9673 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -1,3 +1,4 @@ +import 'package:dhbwstudentapp/assets.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/common/ui/text_styles.dart'; import 'package:dhbwstudentapp/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart'; @@ -73,7 +74,7 @@ class _DailySchedulePageState extends State { padding: const EdgeInsets.fromLTRB(32, 64, 32, 32), child: Opacity( opacity: 0.9, - child: Image.asset("assets/empty_state.png"), + child: Image.asset(Assets.assets_empty_state_png), ), ) ], diff --git a/lib/schedule/ui/widgets/schedule_empty_state.dart b/lib/schedule/ui/widgets/schedule_empty_state.dart index 37c846cc..436d26f1 100644 --- a/lib/schedule/ui/widgets/schedule_empty_state.dart +++ b/lib/schedule/ui/widgets/schedule_empty_state.dart @@ -1,3 +1,4 @@ +import 'package:dhbwstudentapp/assets.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/schedule/ui/widgets/select_source_dialog.dart'; import 'package:dhbwstudentapp/ui/banner_widget.dart'; @@ -6,8 +7,8 @@ import 'package:kiwi/kiwi.dart'; class ScheduleEmptyState extends StatelessWidget { final Map image = { - Brightness.dark: "assets/schedule_empty_state_dark.png", - Brightness.light: "assets/schedule_empty_state.png", + Brightness.dark: Assets.assets_schedule_empty_state_dark_png, + Brightness.light: Assets.assets_schedule_empty_state_png, }; @override diff --git a/lib/ui/onboarding/widgets/onboarding_page_background.dart b/lib/ui/onboarding/widgets/onboarding_page_background.dart index f0f91a24..0e676561 100644 --- a/lib/ui/onboarding/widgets/onboarding_page_background.dart +++ b/lib/ui/onboarding/widgets/onboarding_page_background.dart @@ -1,3 +1,4 @@ +import 'package:dhbwstudentapp/assets.dart'; import 'package:dhbwstudentapp/common/math/math.dart'; import 'package:dhbwstudentapp/common/ui/colors.dart'; import 'package:dhbwstudentapp/common/util/platform_util.dart'; @@ -11,13 +12,13 @@ class OnboardingPageBackground extends StatelessWidget { final Animation bottomBackground; final Map foreground = { - Brightness.light: "assets/onboarding_bottom_foreground.png", - Brightness.dark: "assets/onboarding_bottom_foreground_dark.png", + Brightness.light: Assets.assets_onboarding_bottom_foreground_png, + Brightness.dark: Assets.assets_onboarding_bottom_foreground_dark_png, }; final Map background = { - Brightness.light: "assets/onboarding_bottom_background.png", - Brightness.dark: "assets/onboarding_bottom_background_dark.png", + Brightness.light: Assets.assets_onboarding_bottom_background_png, + Brightness.dark: Assets.assets_onboarding_bottom_background_dark_png, }; OnboardingPageBackground({Key? key, required this.controller}) diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 0f1f69bf..3e6371e7 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -1,3 +1,4 @@ +import 'package:dhbwstudentapp/assets.dart'; import 'package:dhbwstudentapp/common/application_constants.dart'; import 'package:dhbwstudentapp/common/background/task_callback.dart'; import 'package:dhbwstudentapp/common/background/work_scheduler_service.dart'; @@ -95,7 +96,7 @@ class _SettingsPageState extends State { showAboutDialog( context: context, applicationIcon: Image.asset( - "assets/app_icon.png", + Assets.assets_app_icon_png, width: 75, ), applicationLegalese: L.of(context).applicationLegalese, diff --git a/pubspec.lock b/pubspec.lock index 544208eb..40dc89d2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.2" + ansicolor: + dependency: transitive + description: + name: ansicolor + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" app_group_directory: dependency: "direct main" description: @@ -43,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.3.0" + assets_gen: + dependency: "direct dev" + description: + name: assets_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" async: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8d2b8f3f..a8a1cda1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,6 +54,7 @@ dependencies: workmanager: ^0.5.0 dev_dependencies: + assets_gen: ^1.2.0 build_runner: ^2.3.0 copy_with_extension_gen: ^4.0.0 flutter_test: From e52dfa62bef322005846bb2abb9500f125516473 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sat, 15 Oct 2022 16:18:29 +0200 Subject: [PATCH 36/37] cleanup Theme --- .../data/preferences/app_theme_enum.dart | 4 - .../preferences/preferences_provider.dart | 13 +- lib/common/ui/app_theme.dart | 154 ++++++++++++++++++ lib/common/ui/colors.dart | 148 ----------------- lib/common/ui/schedule_entry_theme.dart | 49 ++++++ .../ui/schedule_entry_type_mappings.dart | 22 +-- lib/common/ui/schedule_theme.dart | 44 +++++ lib/common/ui/text_styles.dart | 56 ------- lib/common/ui/text_theme.dart | 74 +++++++++ lib/common/ui/viewmodels/root_view_model.dart | 8 +- lib/common/ui/widgets/error_display.dart | 6 +- .../ui/calendar_export_page.dart | 4 +- .../ui/widgets/date_detail_bottom_sheet.dart | 8 +- .../parsing/monthly_schedule_extract.dart | 2 +- lib/schedule/model/schedule_entry.dart | 24 ++- lib/schedule/service/ical/ical_parser.dart | 2 +- .../service/rapla/rapla_parsing_utils.dart | 4 +- .../ui/dailyschedule/daily_schedule_page.dart | 10 +- .../current_time_indicator_widget.dart | 8 +- .../widgets/daily_schedule_entry_widget.dart | 35 ++-- .../schedule_entry_detail_bottom_sheet.dart | 36 ++-- .../widgets/schedule_entry_widget.dart | 15 +- .../widgets/schedule_widget.dart | 18 +- .../widgets/onboarding_page_background.dart | 6 +- lib/ui/root_page.dart | 6 +- lib/ui/settings/select_theme_dialog.dart | 13 +- lib/ui/settings/settings_page.dart | 7 +- pubspec.yaml | 2 +- .../schedule_diff_calculator_test.dart | 10 +- .../service/ical/ical_parser_test.dart | 6 +- .../rapla/rapla_response_parser_test.dart | 40 ++--- 31 files changed, 484 insertions(+), 350 deletions(-) delete mode 100644 lib/common/data/preferences/app_theme_enum.dart create mode 100644 lib/common/ui/app_theme.dart delete mode 100644 lib/common/ui/colors.dart create mode 100644 lib/common/ui/schedule_entry_theme.dart create mode 100644 lib/common/ui/schedule_theme.dart delete mode 100644 lib/common/ui/text_styles.dart create mode 100644 lib/common/ui/text_theme.dart diff --git a/lib/common/data/preferences/app_theme_enum.dart b/lib/common/data/preferences/app_theme_enum.dart deleted file mode 100644 index 0c8be05f..00000000 --- a/lib/common/data/preferences/app_theme_enum.dart +++ /dev/null @@ -1,4 +0,0 @@ -/// -/// Enum which holds the possible themes the app can be displayed in -/// -enum AppTheme { Dark, Light, System } diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index 821d375b..86a4ff4e 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -1,10 +1,10 @@ import 'package:device_calendar/device_calendar.dart'; import 'package:dhbwstudentapp/common/application_constants.dart'; -import 'package:dhbwstudentapp/common/data/preferences/app_theme_enum.dart'; import 'package:dhbwstudentapp/common/data/preferences/preferences_access.dart'; import 'package:dhbwstudentapp/common/data/preferences/secure_storage_access.dart'; import 'package:dhbwstudentapp/date_management/data/calendar_access.dart'; import 'package:dhbwstudentapp/dualis/model/credentials.dart'; +import 'package:flutter/material.dart'; class PreferencesProvider { static const String AppThemeKey = "AppTheme"; @@ -35,18 +35,19 @@ class PreferencesProvider { PreferencesProvider(this._preferencesAccess, this._secureStorageAccess); - Future appTheme() async { + Future appTheme() async { final theme = await _preferencesAccess.get(AppThemeKey); + final themeName = theme?.toLowerCase(); - return AppTheme.values.firstWhere( - (element) => element.name == theme, + return ThemeMode.values.firstWhere( + (element) => element.name == themeName, orElse: () { - return AppTheme.System; + return ThemeMode.system; }, ); } - Future setAppTheme(AppTheme value) async { + Future setAppTheme(ThemeMode value) async { await _preferencesAccess.set(AppThemeKey, value.name); } diff --git a/lib/common/ui/app_theme.dart b/lib/common/ui/app_theme.dart new file mode 100644 index 00000000..b9f89f43 --- /dev/null +++ b/lib/common/ui/app_theme.dart @@ -0,0 +1,154 @@ +import 'package:dhbwstudentapp/common/ui/schedule_entry_theme.dart'; +import 'package:dhbwstudentapp/common/ui/schedule_theme.dart'; +import 'package:dhbwstudentapp/common/ui/text_theme.dart'; +import 'package:flutter/material.dart'; + +class AppTheme { + AppTheme._(); + + /// Light theme + static final lightThemeData = ThemeData( + brightness: Brightness.light, + toggleableActiveColor: AppTheme.main[600], + colorScheme: ColorScheme.fromSwatch(primarySwatch: main).copyWith( + secondary: AppTheme.main[500], + brightness: Brightness.light, + ), + textButtonTheme: textButtonTheme, + snackBarTheme: const SnackBarThemeData( + backgroundColor: Color(0xfffafafa), + ), + extensions: const >[ + scheduleEntryThemeLight, + scheduleThemeLight, + textTheme, + ], + ); + + /// Dark theme + static final darkThemeData = ThemeData( + brightness: Brightness.dark, + toggleableActiveColor: AppTheme.main[700], + colorScheme: ColorScheme.fromSwatch(primarySwatch: main).copyWith( + secondary: AppTheme.main[500], + brightness: Brightness.dark, + ), + textButtonTheme: textButtonTheme, + snackBarTheme: const SnackBarThemeData( + backgroundColor: Color(0xff363635), + contentTextStyle: TextStyle( + color: Color(0xffe4e4e4), + ), + ), + extensions: const >[ + scheduleEntryThemeDark, + scheduleThemeDark, + textTheme, + ], + ); + + static final textButtonTheme = TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: AppTheme.main, + padding: const EdgeInsets.symmetric(horizontal: 16.0), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(4.0)), + ), + ), + ); + + static const scheduleEntryThemeLight = ScheduleEntryTheme( + unknown: Color(0xffcbcbcb), + lesson: Color(0xffe63f3b), + online: Color(0xffAFC7EA), + publicHoliday: Color(0xffcbcbcb), + exam: Color(0xfffdb531), + ); + + static const scheduleEntryThemeDark = ScheduleEntryTheme( + unknown: Color(0xff515151), + lesson: Color(0xffa52632), + online: Color(0xff2659A6), + publicHoliday: Color(0xff515151), + exam: Color(0xffb17f22), + ); + + static const scheduleThemeLight = ScheduleTheme( + scheduleGridGridLines: Color(0xffe0e0e0), + scheduleInPastOverlay: Color(0x1F000000), + currentTimeIndicator: Color(0xffffa500), + ); + + static const scheduleThemeDark = ScheduleTheme( + scheduleGridGridLines: Color(0xff515151), + scheduleInPastOverlay: Color(0x3F000000), + currentTimeIndicator: Color(0xffb37300), + ); + + static const textTheme = CustomTextTheme( + dailyScheduleEntryType: TextStyle( + inherit: false, + fontWeight: FontWeight.w300, + letterSpacing: 0.15, + ), + dailyScheduleEntryTimeStart: TextStyle( + inherit: false, + fontWeight: FontWeight.w600, + letterSpacing: 0.15, + ), + scheduleEntryWidgetTitle: TextStyle( + inherit: false, + fontWeight: FontWeight.normal, + ), + scheduleEntryBottomPageType: TextStyle( + inherit: false, + fontWeight: FontWeight.w300, + ), + scheduleWidgetColumnTitleDay: TextStyle( + inherit: false, + fontWeight: FontWeight.w300, + ), + ); + + static const onboardingDecorationForeground = Color(0xFFA62828); + static const onboardingDecorationBackground = Color(0xFFC91A1A); + static const success = Color(0xFFC91A1A); + static const dailyScheduleTimeVerticalConnector = Colors.grey; + static const separator = Colors.grey; + static const noConnectionBackground = Colors.black87; + static const noConnectionForeground = Colors.white; + + static const MaterialColor main = MaterialColor(0xffff061c, { + 050: Color(0xFFff838e), + 100: Color(0xFFff6a77), + 200: Color(0xFFff5160), + 300: Color(0xFFff3849), + 400: Color(0xFFff1f33), + 500: Color(0xffff061c), + 600: Color(0xFFe60519), + 700: Color(0xFFcc0516), + 800: Color(0xFFb30414), + 900: Color(0xFF990411), + }); + + static const MaterialColor secondary = MaterialColor(0xFFCECED0, { + 050: Color(0xFFF9F9F9), + 100: Color(0xFFF0F0F1), + 200: Color(0xFFE7E7E8), + 300: Color(0xFFDDDDDE), + 400: Color(0xFFD5D5D7), + 500: Color(0xFFCECED0), + 600: Color(0xFFC9C9CB), + 700: Color(0xFFC2C2C4), + 800: Color(0xFFBCBCBE), + 900: Color(0xFFB0B0B3), + }); + + static const MaterialColor secondaryAccent = + MaterialColor(0xFFFFFFFF, { + 100: Color(0xFFFFFFFF), + 200: Color(0xFFFFFFFF), + 400: Color(0xFFFFFFFF), + 700: Color(0xFFEAEAFF), + }); +} diff --git a/lib/common/ui/colors.dart b/lib/common/ui/colors.dart deleted file mode 100644 index 5f870035..00000000 --- a/lib/common/ui/colors.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:dhbwstudentapp/common/data/preferences/app_theme_enum.dart'; -import 'package:dhbwstudentapp/common/util/platform_util.dart'; -import 'package:flutter/material.dart'; - -Color colorScheduleEntryPublicHoliday(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xffcbcbcb) - : const Color(0xff515151); - -Color colorScheduleEntryClass(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xffe63f3b) - : const Color(0xffa52632); - -Color colorScheduleEntryExam(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xfffdb531) - : const Color(0xffb17f22); - -Color colorScheduleEntryOnline(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xffAFC7EA) - : const Color(0xff2659A6); - -Color colorScheduleEntryUnknown(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xffcbcbcb) - : const Color(0xff515151); - -Color colorScheduleGridGridLines(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xffe0e0e0) - : const Color(0xff515151); - -Color colorScheduleInPastOverlay(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0x1F000000) - : const Color(0x3F000000); - -Color colorCurrentTimeIndicator(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xffffa500) - : const Color(0xffb37300); - -Color colorOnboardingDecorationForeground(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xFFA62828) - : const Color(0xFFA62828); - -Color colorOnboardingDecorationBackground(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xFFC91A1A) - : const Color(0xFFC91A1A); - -Color colorSuccess(BuildContext context) => - Theme.of(context).brightness == Brightness.light - ? const Color(0xFFC91A1A) - : const Color(0xFFC91A1A); - -Color colorDailyScheduleTimeVerticalConnector() => Colors.grey; - -Color colorSeparator() => Colors.grey; - -Color colorNoConnectionBackground() => Colors.black87; - -Color colorNoConnectionForeground() => Colors.white; - -class ColorPalettes { - ColorPalettes._(); - - static ThemeData buildTheme(AppTheme? theme) { - if (theme == AppTheme.System) { - theme = PlatformUtil.platformBrightness() == Brightness.light - ? AppTheme.Light - : AppTheme.Dark; - } - - final isDark = theme == AppTheme.Dark; - - final brightness = isDark ? Brightness.dark : Brightness.light; - - final themeData = ThemeData( - brightness: brightness, - toggleableActiveColor: - isDark ? ColorPalettes.main[700] : ColorPalettes.main[600], - colorScheme: - ColorScheme.fromSwatch(primarySwatch: ColorPalettes.main).copyWith( - secondary: ColorPalettes.main[500], - brightness: brightness, - ), - ); - - return themeData.copyWith( - snackBarTheme: themeData.snackBarTheme.copyWith( - backgroundColor: - isDark ? const Color(0xff363635) : const Color(0xfffafafa), - contentTextStyle: themeData.textTheme.bodyText1!.copyWith( - color: isDark - ? const Color(0xffe4e4e4) - : themeData.textTheme.bodyText1!.color, - ), - ), - textButtonTheme: TextButtonThemeData( - style: TextButton.styleFrom( - foregroundColor: ColorPalettes.main, - padding: const EdgeInsets.symmetric(horizontal: 16.0), - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(4.0)), - ), - ), - ), - ); - } - - static const MaterialColor main = MaterialColor(0xffff061c, { - 050: Color(0xFFff838e), - 100: Color(0xFFff6a77), - 200: Color(0xFFff5160), - 300: Color(0xFFff3849), - 400: Color(0xFFff1f33), - 500: Color(0xffff061c), - 600: Color(0xFFe60519), - 700: Color(0xFFcc0516), - 800: Color(0xFFb30414), - 900: Color(0xFF990411), - }); - - static const MaterialColor secondary = MaterialColor(0xFFCECED0, { - 050: Color(0xFFF9F9F9), - 100: Color(0xFFF0F0F1), - 200: Color(0xFFE7E7E8), - 300: Color(0xFFDDDDDE), - 400: Color(0xFFD5D5D7), - 500: Color(0xFFCECED0), - 600: Color(0xFFC9C9CB), - 700: Color(0xFFC2C2C4), - 800: Color(0xFFBCBCBE), - 900: Color(0xFFB0B0B3), - }); - - static const MaterialColor secondaryAccent = - MaterialColor(0xFFFFFFFF, { - 100: Color(0xFFFFFFFF), - 200: Color(0xFFFFFFFF), - 400: Color(0xFFFFFFFF), - 700: Color(0xFFEAEAFF), - }); -} diff --git a/lib/common/ui/schedule_entry_theme.dart b/lib/common/ui/schedule_entry_theme.dart new file mode 100644 index 00000000..2cea0ff8 --- /dev/null +++ b/lib/common/ui/schedule_entry_theme.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +@immutable +class ScheduleEntryTheme extends ThemeExtension { + const ScheduleEntryTheme({ + required this.unknown, + required this.lesson, + required this.online, + required this.publicHoliday, + required this.exam, + }); + + final Color unknown; + final Color lesson; + final Color online; + final Color publicHoliday; + final Color exam; + + @override + ScheduleEntryTheme copyWith({ + Color? unknown, + Color? lesson, + Color? online, + Color? publicHoliday, + Color? exam, + }) { + return ScheduleEntryTheme( + unknown: unknown ?? this.unknown, + lesson: lesson ?? this.lesson, + online: online ?? this.online, + publicHoliday: publicHoliday ?? this.publicHoliday, + exam: exam ?? this.exam, + ); + } + + @override + ScheduleEntryTheme lerp(ThemeExtension? other, double t) { + if (other is! ScheduleEntryTheme) { + return this; + } + return copyWith( + unknown: Color.lerp(unknown, other.unknown, t), + lesson: Color.lerp(lesson, other.lesson, t), + online: Color.lerp(online, other.online, t), + publicHoliday: Color.lerp(publicHoliday, other.publicHoliday, t), + exam: Color.lerp(exam, other.exam, t), + ); + } +} diff --git a/lib/common/ui/schedule_entry_type_mappings.dart b/lib/common/ui/schedule_entry_type_mappings.dart index f934ce95..fc41e3df 100644 --- a/lib/common/ui/schedule_entry_type_mappings.dart +++ b/lib/common/ui/schedule_entry_type_mappings.dart @@ -1,38 +1,22 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; import 'package:flutter/material.dart'; typedef ColorDelegate = Color Function(BuildContext context); typedef TextDelegate = String Function(BuildContext context); -final Map scheduleEntryTypeColorMapping = { - ScheduleEntryType.PublicHoliday: colorScheduleEntryPublicHoliday, - ScheduleEntryType.Class: colorScheduleEntryClass, - ScheduleEntryType.Exam: colorScheduleEntryExam, - ScheduleEntryType.Online: colorScheduleEntryOnline, - ScheduleEntryType.Unknown: colorScheduleEntryUnknown, -}; - final Map scheduleEntryTypeTextMapping = { ScheduleEntryType.PublicHoliday: (c) => L.of(c).scheduleEntryTypePublicHoliday, - ScheduleEntryType.Class: (c) => L.of(c).scheduleEntryTypeClass, + ScheduleEntryType.Lesson: (c) => L.of(c).scheduleEntryTypeClass, ScheduleEntryType.Exam: (c) => L.of(c).scheduleEntryTypeExam, ScheduleEntryType.Online: (c) => L.of(c).scheduleEntryTypeOnline, ScheduleEntryType.Unknown: (c) => L.of(c).scheduleEntryTypeUnknown, }; -Color scheduleEntryTypeToColor( - BuildContext context, - ScheduleEntryType? type, -) { - return scheduleEntryTypeColorMapping[type!]!(context); -} - String scheduleEntryTypeToReadableString( BuildContext context, - ScheduleEntryType? type, + ScheduleEntryType type, ) { - return scheduleEntryTypeTextMapping[type!]!(context); + return scheduleEntryTypeTextMapping[type]!(context); } diff --git a/lib/common/ui/schedule_theme.dart b/lib/common/ui/schedule_theme.dart new file mode 100644 index 00000000..763bfe5b --- /dev/null +++ b/lib/common/ui/schedule_theme.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; + +@immutable +class ScheduleTheme extends ThemeExtension { + const ScheduleTheme({ + required this.scheduleGridGridLines, + required this.scheduleInPastOverlay, + required this.currentTimeIndicator, + }); + + final Color scheduleGridGridLines; + final Color scheduleInPastOverlay; + final Color currentTimeIndicator; + + @override + ScheduleTheme copyWith({ + Color? scheduleGridGridLines, + Color? scheduleInPastOverlay, + Color? currentTimeIndicator, + }) { + return ScheduleTheme( + scheduleGridGridLines: + scheduleGridGridLines ?? this.scheduleGridGridLines, + scheduleInPastOverlay: + scheduleInPastOverlay ?? this.scheduleInPastOverlay, + currentTimeIndicator: currentTimeIndicator ?? this.currentTimeIndicator, + ); + } + + @override + ScheduleTheme lerp(ThemeExtension? other, double t) { + if (other is! ScheduleTheme) { + return this; + } + return copyWith( + scheduleGridGridLines: + Color.lerp(scheduleGridGridLines, other.scheduleGridGridLines, t), + scheduleInPastOverlay: + Color.lerp(scheduleInPastOverlay, other.scheduleInPastOverlay, t), + currentTimeIndicator: + Color.lerp(currentTimeIndicator, other.currentTimeIndicator, t), + ); + } +} diff --git a/lib/common/ui/text_styles.dart b/lib/common/ui/text_styles.dart deleted file mode 100644 index 94b731db..00000000 --- a/lib/common/ui/text_styles.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; - -TextStyle? textStyleDailyScheduleEntryWidgetProfessor(BuildContext context) => - Theme.of(context).textTheme.subtitle2; - -TextStyle textStyleDailyScheduleEntryWidgetTitle(BuildContext context) => - Theme.of(context) - .textTheme - .headline4! - .copyWith(color: Theme.of(context).textTheme.headline6!.color); - -TextStyle textStyleDailyScheduleEntryWidgetType(BuildContext context) => - Theme.of(context).textTheme.bodyText2!.copyWith( - fontWeight: FontWeight.w300, - letterSpacing: 0.15, - ); - -TextStyle textStyleDailyScheduleEntryWidgetTimeStart(BuildContext context) => - Theme.of(context).textTheme.headline5!.copyWith( - fontWeight: FontWeight.w600, - letterSpacing: 0.15, - ); - -TextStyle? textStyleDailyScheduleEntryWidgetTimeEnd(BuildContext context) => - Theme.of(context).textTheme.subtitle2; - -TextStyle textStyleDailyScheduleCurrentDate(BuildContext context) => - Theme.of(context).textTheme.headline4!.copyWith( - color: Theme.of(context).textTheme.headline5!.color, - ); -TextStyle? textStyleDailyScheduleNoEntries(BuildContext context) => - Theme.of(context).textTheme.headline5; - -TextStyle textStyleScheduleEntryWidgetTitle(BuildContext context) => - Theme.of(context).textTheme.bodyText1!.copyWith( - fontWeight: FontWeight.normal, - ); - -TextStyle? textStyleScheduleEntryBottomPageTitle(BuildContext context) => - Theme.of(context).textTheme.subtitle2; - -TextStyle? textStyleScheduleEntryBottomPageTimeFromTo(BuildContext context) => - Theme.of(context).textTheme.caption; - -TextStyle? textStyleScheduleEntryBottomPageTime(BuildContext context) => - Theme.of(context).textTheme.headline5; - -TextStyle textStyleScheduleEntryBottomPageType(BuildContext context) => - Theme.of(context).textTheme.bodyText1!.copyWith( - fontWeight: FontWeight.w300, - ); - -TextStyle textStyleScheduleWidgetColumnTitleDay(BuildContext context) => - Theme.of(context).textTheme.subtitle2!.copyWith( - fontWeight: FontWeight.w300, - ); diff --git a/lib/common/ui/text_theme.dart b/lib/common/ui/text_theme.dart new file mode 100644 index 00000000..ecbceb34 --- /dev/null +++ b/lib/common/ui/text_theme.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +@immutable +class CustomTextTheme extends ThemeExtension { + const CustomTextTheme({ + required this.dailyScheduleEntryType, + required this.dailyScheduleEntryTimeStart, + required this.scheduleEntryWidgetTitle, + required this.scheduleEntryBottomPageType, + required this.scheduleWidgetColumnTitleDay, + }); + + final TextStyle dailyScheduleEntryType; + final TextStyle dailyScheduleEntryTimeStart; + final TextStyle scheduleEntryWidgetTitle; + final TextStyle scheduleEntryBottomPageType; + final TextStyle scheduleWidgetColumnTitleDay; + + @override + CustomTextTheme copyWith({ + TextStyle? dailyScheduleEntryType, + TextStyle? dailyScheduleEntryTimeStart, + TextStyle? scheduleEntryWidgetTitle, + TextStyle? scheduleEntryBottomPageType, + TextStyle? scheduleWidgetColumnTitleDay, + }) { + return CustomTextTheme( + dailyScheduleEntryType: + dailyScheduleEntryType ?? this.dailyScheduleEntryType, + dailyScheduleEntryTimeStart: + dailyScheduleEntryTimeStart ?? this.dailyScheduleEntryTimeStart, + scheduleEntryWidgetTitle: + scheduleEntryWidgetTitle ?? this.scheduleEntryWidgetTitle, + scheduleEntryBottomPageType: + scheduleEntryBottomPageType ?? this.scheduleEntryBottomPageType, + scheduleWidgetColumnTitleDay: + scheduleWidgetColumnTitleDay ?? this.scheduleWidgetColumnTitleDay, + ); + } + + @override + CustomTextTheme lerp(ThemeExtension? other, double t) { + if (other is! CustomTextTheme) { + return this; + } + return copyWith( + dailyScheduleEntryType: TextStyle.lerp( + dailyScheduleEntryType, + other.dailyScheduleEntryType, + t, + ), + dailyScheduleEntryTimeStart: TextStyle.lerp( + dailyScheduleEntryTimeStart, + other.dailyScheduleEntryTimeStart, + t, + ), + scheduleEntryWidgetTitle: TextStyle.lerp( + scheduleEntryWidgetTitle, + other.scheduleEntryWidgetTitle, + t, + ), + scheduleEntryBottomPageType: TextStyle.lerp( + scheduleEntryBottomPageType, + other.scheduleEntryBottomPageType, + t, + ), + scheduleWidgetColumnTitleDay: TextStyle.lerp( + scheduleWidgetColumnTitleDay, + other.scheduleWidgetColumnTitleDay, + t, + ), + ); + } +} diff --git a/lib/common/ui/viewmodels/root_view_model.dart b/lib/common/ui/viewmodels/root_view_model.dart index 2d8acb30..05555242 100644 --- a/lib/common/ui/viewmodels/root_view_model.dart +++ b/lib/common/ui/viewmodels/root_view_model.dart @@ -1,12 +1,12 @@ -import 'package:dhbwstudentapp/common/data/preferences/app_theme_enum.dart'; import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; +import 'package:flutter/material.dart'; class RootViewModel extends BaseViewModel { final PreferencesProvider _preferencesProvider; - late AppTheme _appTheme; - AppTheme get appTheme => _appTheme; + late ThemeMode _appTheme; + ThemeMode get appTheme => _appTheme; late bool _isOnboarding; bool get isOnboarding => _isOnboarding; @@ -21,7 +21,7 @@ class RootViewModel extends BaseViewModel { notifyListeners("isOnboarding"); } - Future setAppTheme(AppTheme? value) async { + Future setAppTheme(ThemeMode? value) async { if (value == null) return; await _preferencesProvider.setAppTheme(value); _appTheme = value; diff --git a/lib/common/ui/widgets/error_display.dart b/lib/common/ui/widgets/error_display.dart index fb31b656..c254574a 100644 --- a/lib/common/ui/widgets/error_display.dart +++ b/lib/common/ui/widgets/error_display.dart @@ -1,5 +1,5 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/app_theme.dart'; import 'package:flutter/material.dart'; class ErrorDisplay extends StatelessWidget { @@ -19,14 +19,14 @@ class ErrorDisplay extends StatelessWidget { padding: EdgeInsets.zero, child: Container( width: double.infinity, - color: colorNoConnectionBackground(), + color: AppTheme.noConnectionBackground, child: Padding( padding: const EdgeInsets.fromLTRB(24, 4, 24, 4), child: Text( L.of(context).noConnectionMessage, textAlign: TextAlign.center, style: Theme.of(context).textTheme.subtitle2!.copyWith( - color: colorNoConnectionForeground(), + color: AppTheme.noConnectionForeground, ), ), ), diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 1f20edbd..749c3fe5 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -1,7 +1,7 @@ import 'package:device_calendar/device_calendar.dart'; import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/app_theme.dart'; import 'package:dhbwstudentapp/date_management/data/calendar_access.dart'; import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; import 'package:dhbwstudentapp/date_management/ui/viewmodels/calendar_export_view_model.dart'; @@ -121,7 +121,7 @@ class _CalendarExportPageState extends State { textAlign: TextAlign.center, style: TextStyle( color: widget.isCalendarSyncEnabled - ? ColorPalettes.main + ? AppTheme.main : Theme.of(context).disabledColor, fontSize: 14, ), diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index a883b54b..a715e3ee 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -1,5 +1,5 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/app_theme.dart'; import 'package:dhbwstudentapp/common/util/date_utils.dart'; import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; import 'package:flutter/material.dart'; @@ -30,9 +30,9 @@ class DateDetailBottomSheet extends StatelessWidget { child: Container( height: 8, width: 30, - decoration: BoxDecoration( - color: colorSeparator(), - borderRadius: const BorderRadius.all(Radius.circular(4)), + decoration: const BoxDecoration( + color: AppTheme.separator, + borderRadius: BorderRadius.all(Radius.circular(4)), ), ), ), diff --git a/lib/dualis/service/parsing/monthly_schedule_extract.dart b/lib/dualis/service/parsing/monthly_schedule_extract.dart index 9448e3a8..4b17151b 100644 --- a/lib/dualis/service/parsing/monthly_schedule_extract.dart +++ b/lib/dualis/service/parsing/monthly_schedule_extract.dart @@ -58,7 +58,7 @@ class MonthlyScheduleExtract { professor: "", details: "", room: room, - type: ScheduleEntryType.Class, + type: ScheduleEntryType.Lesson, start: startDate, end: endDate, ); diff --git a/lib/schedule/model/schedule_entry.dart b/lib/schedule/model/schedule_entry.dart index b99de2e3..5442e36f 100644 --- a/lib/schedule/model/schedule_entry.dart +++ b/lib/schedule/model/schedule_entry.dart @@ -1,16 +1,36 @@ import 'package:copy_with_extension/copy_with_extension.dart'; import 'package:dhbwstudentapp/common/data/epoch_date_time_converter.dart'; +import 'package:dhbwstudentapp/common/ui/schedule_entry_theme.dart'; import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; import 'package:json_annotation/json_annotation.dart'; part 'schedule_entry.g.dart'; enum ScheduleEntryType { Unknown, - Class, + Lesson, Online, PublicHoliday, - Exam, + Exam; + + Color color(BuildContext context) { + final scheduleEntryTheme = + Theme.of(context).extension()!; + + switch (this) { + case ScheduleEntryType.PublicHoliday: + return scheduleEntryTheme.publicHoliday; + case ScheduleEntryType.Lesson: + return scheduleEntryTheme.lesson; + case ScheduleEntryType.Exam: + return scheduleEntryTheme.exam; + case ScheduleEntryType.Online: + return scheduleEntryTheme.online; + case ScheduleEntryType.Unknown: + return scheduleEntryTheme.unknown; + } + } } @CopyWith() diff --git a/lib/schedule/service/ical/ical_parser.dart b/lib/schedule/service/ical/ical_parser.dart index 3a1a22d0..48fb90e0 100644 --- a/lib/schedule/service/ical/ical_parser.dart +++ b/lib/schedule/service/ical/ical_parser.dart @@ -61,7 +61,7 @@ class IcalParser { end: _parseDate(properties["DTEND"]), room: properties["LOCATION"], title: properties["SUMMARY"], - type: ScheduleEntryType.Class, + type: ScheduleEntryType.Lesson, details: properties["DESCRIPTION"] ?? "", professor: "", ); diff --git a/lib/schedule/service/rapla/rapla_parsing_utils.dart b/lib/schedule/service/rapla/rapla_parsing_utils.dart index 5ea96056..e164bb48 100644 --- a/lib/schedule/service/rapla/rapla_parsing_utils.dart +++ b/lib/schedule/service/rapla/rapla_parsing_utils.dart @@ -22,8 +22,8 @@ class RaplaParsingUtils { static const Map entryTypeMapping = { "Feiertag": ScheduleEntryType.PublicHoliday, "Online-Format (ohne Raumbelegung)": ScheduleEntryType.Online, - "Vorlesung / Lehrbetrieb": ScheduleEntryType.Class, - "Lehrveranstaltung": ScheduleEntryType.Class, + "Vorlesung / Lehrbetrieb": ScheduleEntryType.Lesson, + "Lehrveranstaltung": ScheduleEntryType.Lesson, "Klausur / Prüfung": ScheduleEntryType.Exam, "Prüfung": ScheduleEntryType.Exam }; diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index e12a9673..0bbcb4c7 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -1,11 +1,9 @@ import 'package:dhbwstudentapp/assets.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/text_styles.dart'; import 'package:dhbwstudentapp/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart'; import 'package:dhbwstudentapp/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart'; import 'package:dhbwstudentapp/schedule/ui/viewmodels/daily_schedule_view_model.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; import 'package:provider/provider.dart'; @@ -23,6 +21,10 @@ class _DailySchedulePageState extends State { Widget build(BuildContext context) { viewModel = Provider.of(context); + final textTheme = Theme.of(context).textTheme; + final dailyScheduleEntryTitle = + textTheme.headline4?.copyWith(color: textTheme.headline5?.color); + return PropertyChangeProvider( value: viewModel, child: SingleChildScrollView( @@ -44,7 +46,7 @@ class _DailySchedulePageState extends State { ); return Text( dateFormat.format(model!.currentDate!), - style: textStyleDailyScheduleCurrentDate(context), + style: dailyScheduleEntryTitle, ); }, ), @@ -64,7 +66,7 @@ class _DailySchedulePageState extends State { L.of(context).dailyScheduleNoEntriesToday, softWrap: true, textAlign: TextAlign.center, - style: textStyleDailyScheduleNoEntries(context), + style: Theme.of(context).textTheme.headline5, ), ), Expanded(child: Container()), diff --git a/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart b/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart index 902507bd..25124812 100644 --- a/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart @@ -1,23 +1,25 @@ -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/schedule_theme.dart'; import 'package:flutter/material.dart'; class CurrentTimeIndicatorWidget extends StatelessWidget { @override Widget build(BuildContext context) { + final scheduleTheme = Theme.of(context).extension()!; + return Row( children: [ Container( height: 10, width: 10, decoration: BoxDecoration( - color: colorCurrentTimeIndicator(context), + color: scheduleTheme.currentTimeIndicator, shape: BoxShape.circle, ), ), Expanded( child: Container( height: 1, - color: colorCurrentTimeIndicator(context), + color: scheduleTheme.currentTimeIndicator, ), ) ], diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index 3557d0dc..569b7906 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -1,7 +1,7 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/app_theme.dart'; import 'package:dhbwstudentapp/common/ui/schedule_entry_type_mappings.dart'; -import 'package:dhbwstudentapp/common/ui/text_styles.dart'; +import 'package:dhbwstudentapp/common/ui/text_theme.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; @@ -19,6 +19,11 @@ class DailyScheduleEntryWidget extends StatelessWidget { final startTime = timeFormatter.format(scheduleEntry.start); final endTime = timeFormatter.format(scheduleEntry.end); + final textTheme = Theme.of(context).textTheme; + final customTextThme = Theme.of(context).extension()!; + final dailyScheduleEntryTitle = + textTheme.headline4?.copyWith(color: textTheme.headline6?.color); + return IntrinsicHeight( child: Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -31,20 +36,19 @@ class DailyScheduleEntryWidget extends StatelessWidget { children: [ Text( startTime, - style: textStyleDailyScheduleEntryWidgetTimeStart(context), + style: textTheme.headline5 + ?.merge(customTextThme.dailyScheduleEntryTimeStart), ), Expanded( - child: Padding( + child: Container( padding: const EdgeInsets.all(4), - child: Container( - width: 1, - color: colorDailyScheduleTimeVerticalConnector(), - ), + width: 1, + color: AppTheme.dailyScheduleTimeVerticalConnector, ), ), Text( endTime, - style: textStyleDailyScheduleEntryWidgetTimeEnd(context), + style: Theme.of(context).textTheme.subtitle2, ), ], ), @@ -55,7 +59,7 @@ class DailyScheduleEntryWidget extends StatelessWidget { child: Card( margin: EdgeInsets.zero, elevation: 8, - color: scheduleEntryTypeToColor(context, scheduleEntry.type), + color: scheduleEntry.type.color(context), child: Padding( padding: const EdgeInsets.all(8), child: Column( @@ -65,7 +69,7 @@ class DailyScheduleEntryWidget extends StatelessWidget { padding: const EdgeInsets.fromLTRB(0, 0, 0, 8), child: Text( scheduleEntry.title, - style: textStyleDailyScheduleEntryWidgetTitle(context), + style: dailyScheduleEntryTitle, ), ), Row( @@ -75,18 +79,15 @@ class DailyScheduleEntryWidget extends StatelessWidget { children: [ Text( scheduleEntry.professor, - style: textStyleDailyScheduleEntryWidgetProfessor( - context, - ), + style: Theme.of(context).textTheme.subtitle2, ), Text( scheduleEntryTypeToReadableString( context, scheduleEntry.type, ), - style: textStyleDailyScheduleEntryWidgetType( - context, - ), + style: textTheme.bodyText2?.merge( + customTextThme.dailyScheduleEntryType,), ), ], ), diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index 3d0b13ce..a056484c 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -1,10 +1,9 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/app_theme.dart'; import 'package:dhbwstudentapp/common/ui/schedule_entry_type_mappings.dart'; -import 'package:dhbwstudentapp/common/ui/text_styles.dart'; +import 'package:dhbwstudentapp/common/ui/text_theme.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; class ScheduleEntryDetailBottomSheet extends StatelessWidget { @@ -22,6 +21,11 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { final typeString = scheduleEntryTypeToReadableString(context, scheduleEntry!.type); + final textTheme = Theme.of(context).textTheme; + final customTextThme = Theme.of(context).extension(); + final scheduleEntryBottomPageType = + textTheme.bodyText1?.merge(customTextThme?.scheduleEntryBottomPageType); + return SizedBox( height: 400, child: Padding( @@ -35,9 +39,9 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { child: Container( height: 8, width: 30, - decoration: BoxDecoration( - color: colorSeparator(), - borderRadius: const BorderRadius.all(Radius.circular(4)), + decoration: const BoxDecoration( + color: AppTheme.separator, + borderRadius: BorderRadius.all(Radius.circular(4)), ), ), ), @@ -55,14 +59,11 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { children: [ Text( L.of(context).scheduleEntryDetailFrom, - style: textStyleScheduleEntryBottomPageTimeFromTo( - context, - ), + style: Theme.of(context).textTheme.caption, ), Text( timeStart, - style: - textStyleScheduleEntryBottomPageTime(context), + style: Theme.of(context).textTheme.caption, ), ], ), @@ -72,14 +73,11 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { children: [ Text( L.of(context).scheduleEntryDetailTo, - style: textStyleScheduleEntryBottomPageTimeFromTo( - context, - ), + style: Theme.of(context).textTheme.caption, ), Text( timeEnd, - style: - textStyleScheduleEntryBottomPageTime(context), + style: Theme.of(context).textTheme.headline5, ), ], ), @@ -91,7 +89,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { child: Text( scheduleEntry!.title, softWrap: true, - style: textStyleScheduleEntryBottomPageTitle(context), + style: Theme.of(context).textTheme.subtitle2, ), ), ), @@ -110,7 +108,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { ), Text( typeString, - style: textStyleScheduleEntryBottomPageType(context), + style: scheduleEntryBottomPageType, ), ], ), @@ -128,7 +126,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { Padding( padding: const EdgeInsets.fromLTRB(0, 16, 0, 16), child: Container( - color: colorSeparator(), + color: AppTheme.separator, height: 1, ), ), diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart index d4c9b20e..5ad83b3e 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart @@ -1,5 +1,4 @@ -import 'package:dhbwstudentapp/common/ui/schedule_entry_type_mappings.dart'; -import 'package:dhbwstudentapp/common/ui/text_styles.dart'; +import 'package:dhbwstudentapp/common/ui/text_theme.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; import 'package:flutter/material.dart'; @@ -17,7 +16,15 @@ class ScheduleEntryWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final Color color = scheduleEntryTypeToColor(context, scheduleEntry.type); + final Color color = scheduleEntry.type.color(context); + + Theme.of(context).textTheme.bodyText1!.copyWith(); + + final theme = Theme.of(context); + final textTheme = theme.textTheme; + final customTextThme = theme.extension()!; + final textStyle = + textTheme.headline1?.merge(customTextThme.scheduleEntryWidgetTitle); return Card( color: color, @@ -34,7 +41,7 @@ class ScheduleEntryWidget extends StatelessWidget { softWrap: true, overflow: TextOverflow.clip, textAlign: TextAlign.left, - style: textStyleScheduleEntryWidgetTitle(context), + style: textStyle, ), ), ), diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 88b99403..52e0ad10 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -1,6 +1,6 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; -import 'package:dhbwstudentapp/common/ui/text_styles.dart'; +import 'package:dhbwstudentapp/common/ui/schedule_theme.dart'; +import 'package:dhbwstudentapp/common/ui/text_theme.dart'; import 'package:dhbwstudentapp/common/util/date_utils.dart'; import 'package:dhbwstudentapp/schedule/model/schedule.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; @@ -9,7 +9,6 @@ import 'package:dhbwstudentapp/schedule/ui/weeklyschedule/widgets/schedule_entry import 'package:dhbwstudentapp/schedule/ui/weeklyschedule/widgets/schedule_grid.dart'; import 'package:dhbwstudentapp/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; class ScheduleWidget extends StatelessWidget { @@ -46,6 +45,8 @@ class ScheduleWidget extends StatelessWidget { } Widget buildWithSize(BuildContext context, double width, double height) { + final scheduleTheme = Theme.of(context).extension()!; + const dayLabelsHeight = 40.0; const timeLabelsWidth = 50.0; @@ -85,7 +86,7 @@ class ScheduleWidget extends StatelessWidget { timeLabelsWidth, dayLabelsHeight, days, - colorScheduleGridGridLines(context), + scheduleTheme.scheduleGridGridLines, ), Padding( padding: @@ -103,7 +104,7 @@ class ScheduleWidget extends StatelessWidget { child: SchedulePastOverlay( displayStartHour, displayEndHour, - colorScheduleInPastOverlay(context), + scheduleTheme.scheduleInPastOverlay, displayStart, displayEnd, now, @@ -162,6 +163,11 @@ class ScheduleWidget extends StatelessWidget { final loopEnd = toStartOfDay(tomorrow(displayEnd))!; + final textTheme = Theme.of(context).textTheme; + final customTextThme = Theme.of(context).extension(); + final scheduleWidgetColumnTitleDay = textTheme.subtitle2 + ?.merge(customTextThme?.scheduleWidgetColumnTitleDay); + for (var columnDate = toStartOfDay(displayStart)!; columnDate.isBefore(loopEnd); columnDate = tomorrow(columnDate)!) { @@ -179,7 +185,7 @@ class ScheduleWidget extends StatelessWidget { children: [ Text( dayFormatter.format(columnDate), - style: textStyleScheduleWidgetColumnTitleDay(context), + style: scheduleWidgetColumnTitleDay, ), Text(dateFormatter.format(columnDate)), ], diff --git a/lib/ui/onboarding/widgets/onboarding_page_background.dart b/lib/ui/onboarding/widgets/onboarding_page_background.dart index 0e676561..e4bf9fad 100644 --- a/lib/ui/onboarding/widgets/onboarding_page_background.dart +++ b/lib/ui/onboarding/widgets/onboarding_page_background.dart @@ -1,6 +1,6 @@ import 'package:dhbwstudentapp/assets.dart'; import 'package:dhbwstudentapp/common/math/math.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/app_theme.dart'; import 'package:dhbwstudentapp/common/util/platform_util.dart'; import 'package:flutter/material.dart'; @@ -82,7 +82,7 @@ class OnboardingPageBackground extends StatelessWidget { child: Container( width: 15000, height: 500, - color: colorOnboardingDecorationForeground(context), + color: AppTheme.onboardingDecorationForeground, ), ), ), @@ -93,7 +93,7 @@ class OnboardingPageBackground extends StatelessWidget { child: Container( width: 1500, height: 500, - color: colorOnboardingDecorationBackground(context), + color: AppTheme.onboardingDecorationBackground, ), ), ), diff --git a/lib/ui/root_page.dart b/lib/ui/root_page.dart index a7505f32..c3521653 100644 --- a/lib/ui/root_page.dart +++ b/lib/ui/root_page.dart @@ -1,6 +1,6 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/common/logging/analytics.dart'; -import 'package:dhbwstudentapp/common/ui/colors.dart'; +import 'package:dhbwstudentapp/common/ui/app_theme.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/root_view_model.dart'; import 'package:dhbwstudentapp/ui/navigation/navigator_key.dart'; import 'package:dhbwstudentapp/ui/navigation/router.dart'; @@ -37,7 +37,9 @@ class _RootPageState extends State { builder: (BuildContext context, RootViewModel? model, Set? properties) => MaterialApp( - theme: ColorPalettes.buildTheme(model!.appTheme), + theme: AppTheme.lightThemeData, + darkTheme: AppTheme.darkThemeData, + themeMode: model?.appTheme, initialRoute: widget.rootViewModel.isOnboarding ? "onboarding" : "main", navigatorKey: NavigatorKey.rootKey, diff --git a/lib/ui/settings/select_theme_dialog.dart b/lib/ui/settings/select_theme_dialog.dart index a30d85f4..f3eb3dd9 100644 --- a/lib/ui/settings/select_theme_dialog.dart +++ b/lib/ui/settings/select_theme_dialog.dart @@ -1,4 +1,3 @@ -import 'package:dhbwstudentapp/common/data/preferences/app_theme_enum.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/root_view_model.dart'; import 'package:flutter/material.dart'; @@ -33,21 +32,21 @@ class SelectThemeDialog { return Column( mainAxisSize: MainAxisSize.min, children: [ - RadioListTile( + RadioListTile( title: Text(L.of(context).selectThemeLight), - value: AppTheme.Light, + value: ThemeMode.light, groupValue: _rootViewModel.appTheme, onChanged: _rootViewModel.setAppTheme, ), - RadioListTile( + RadioListTile( title: Text(L.of(context).selectThemeDark), - value: AppTheme.Dark, + value: ThemeMode.dark, groupValue: _rootViewModel.appTheme, onChanged: _rootViewModel.setAppTheme, ), - RadioListTile( + RadioListTile( title: Text(L.of(context).selectThemeSystem), - value: AppTheme.System, + value: ThemeMode.system, groupValue: _rootViewModel.appTheme, onChanged: _rootViewModel.setAppTheme, ), diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 3e6371e7..0650f4f1 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -2,7 +2,6 @@ import 'package:dhbwstudentapp/assets.dart'; import 'package:dhbwstudentapp/common/application_constants.dart'; import 'package:dhbwstudentapp/common/background/task_callback.dart'; import 'package:dhbwstudentapp/common/background/work_scheduler_service.dart'; -import 'package:dhbwstudentapp/common/data/preferences/app_theme_enum.dart'; import 'package:dhbwstudentapp/common/data/preferences/preferences_provider.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/common/ui/viewmodels/root_view_model.dart'; @@ -242,9 +241,9 @@ class _SettingsPageState extends State { }, subtitle: Text( { - AppTheme.Dark: L.of(context).selectThemeDark, - AppTheme.Light: L.of(context).selectThemeLight, - AppTheme.System: L.of(context).selectThemeSystem, + ThemeMode.dark: L.of(context).selectThemeDark, + ThemeMode.light: L.of(context).selectThemeLight, + ThemeMode.system: L.of(context).selectThemeSystem, }[model!.appTheme]!, ), ); diff --git a/pubspec.yaml b/pubspec.yaml index a8a1cda1..393a9ee4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ description: An app for the DHBW Stuttgart version: 1.0.1+1 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.17.0 <3.0.0" dependencies: animations: ^2.0.2 diff --git a/test/schedule/business/schedule_diff_calculator_test.dart b/test/schedule/business/schedule_diff_calculator_test.dart index b8323b05..c832c658 100644 --- a/test/schedule/business/schedule_diff_calculator_test.dart +++ b/test/schedule/business/schedule_diff_calculator_test.dart @@ -42,7 +42,7 @@ void main() { final newEntry = ScheduleEntry( room: "Room3", - type: ScheduleEntryType.Class, + type: ScheduleEntryType.Lesson, title: "Project management", professor: "Sam", details: "ipsum", @@ -161,7 +161,7 @@ Schedule generateSchedule() { final scheduleEntries = [ ScheduleEntry( room: "Room1", - type: ScheduleEntryType.Class, + type: ScheduleEntryType.Lesson, title: "Chemistry", professor: "Mr. White", details: "We will make breaks", @@ -170,7 +170,7 @@ Schedule generateSchedule() { ), ScheduleEntry( room: "Room2", - type: ScheduleEntryType.Class, + type: ScheduleEntryType.Lesson, title: "Computer Science", professor: "Mr. Turing", details: "Lorem", @@ -179,7 +179,7 @@ Schedule generateSchedule() { ), ScheduleEntry( room: "Room3", - type: ScheduleEntryType.Class, + type: ScheduleEntryType.Lesson, title: "Physics", professor: "Mr. Hawking", details: "ipsum", @@ -188,7 +188,7 @@ Schedule generateSchedule() { ), ScheduleEntry( room: "Room3", - type: ScheduleEntryType.Class, + type: ScheduleEntryType.Lesson, title: "Physics", professor: "Mr. Hawking", details: "ipsum", diff --git a/test/schedule/service/ical/ical_parser_test.dart b/test/schedule/service/ical/ical_parser_test.dart index b736358b..bcc4a0cd 100644 --- a/test/schedule/service/ical/ical_parser_test.dart +++ b/test/schedule/service/ical/ical_parser_test.dart @@ -19,19 +19,19 @@ Future main() async { expect(schedule.entries[0].title, "Angewandte Mathematik"); expect(schedule.entries[0].start, DateTime(2019, 04, 01, 10)); expect(schedule.entries[0].end, DateTime(2019, 04, 01, 14, 30)); - expect(schedule.entries[0].type, ScheduleEntryType.Class); + expect(schedule.entries[0].type, ScheduleEntryType.Lesson); expect(schedule.entries[0].room, "Raum 035B"); expect(schedule.entries[1].title, "Elektronik"); expect(schedule.entries[1].start, DateTime(2019, 04, 02, 08)); expect(schedule.entries[1].end, DateTime(2019, 04, 02, 14)); - expect(schedule.entries[1].type, ScheduleEntryType.Class); + expect(schedule.entries[1].type, ScheduleEntryType.Lesson); expect(schedule.entries[1].room, "Raum 035B"); expect(schedule.entries[2].title, "Informatik"); expect(schedule.entries[2].start, DateTime(2019, 04, 03, 09)); expect(schedule.entries[2].end, DateTime(2019, 04, 03, 12, 15)); - expect(schedule.entries[2].type, ScheduleEntryType.Class); + expect(schedule.entries[2].type, ScheduleEntryType.Lesson); expect(schedule.entries[2].room, "Raum 035B"); }); } diff --git a/test/schedule/service/rapla/rapla_response_parser_test.dart b/test/schedule/service/rapla/rapla_response_parser_test.dart index ca4b95bf..a6a80616 100644 --- a/test/schedule/service/rapla/rapla_response_parser_test.dart +++ b/test/schedule/service/rapla/rapla_response_parser_test.dart @@ -51,43 +51,43 @@ Future main() async { expect(schedule.entries[0].title, "Netztechnik I"); expect(schedule.entries[0].start, DateTime(2020, 09, 07, 09, 15)); expect(schedule.entries[0].end, DateTime(2020, 09, 07, 11, 45)); - expect(schedule.entries[0].type, ScheduleEntryType.Class); + expect(schedule.entries[0].type, ScheduleEntryType.Lesson); expect(schedule.entries[0].professor, "Müller, Georg"); expect(schedule.entries[1].title, "Semestereinführung"); expect(schedule.entries[1].start, DateTime(2020, 09, 07, 12)); expect(schedule.entries[1].end, DateTime(2020, 09, 07, 12, 30)); - expect(schedule.entries[1].type, ScheduleEntryType.Class); + expect(schedule.entries[1].type, ScheduleEntryType.Lesson); expect(schedule.entries[2].title, "Messdatenerfassung"); expect(schedule.entries[2].start, DateTime(2020, 09, 07, 13)); expect(schedule.entries[2].end, DateTime(2020, 09, 07, 14, 30)); - expect(schedule.entries[2].type, ScheduleEntryType.Class); + expect(schedule.entries[2].type, ScheduleEntryType.Lesson); expect(schedule.entries[3].title, "Formale Sprachen & Automaten"); expect(schedule.entries[3].start, DateTime(2020, 09, 08, 08, 15)); expect(schedule.entries[3].end, DateTime(2020, 09, 08, 11, 45)); - expect(schedule.entries[3].type, ScheduleEntryType.Class); + expect(schedule.entries[3].type, ScheduleEntryType.Lesson); expect(schedule.entries[4].title, "Signale & Systeme I"); expect(schedule.entries[4].start, DateTime(2020, 09, 08, 13)); expect(schedule.entries[4].end, DateTime(2020, 09, 08, 15)); - expect(schedule.entries[4].type, ScheduleEntryType.Class); + expect(schedule.entries[4].type, ScheduleEntryType.Lesson); expect(schedule.entries[5].title, "Angewandte Mathematik"); expect(schedule.entries[5].start, DateTime(2020, 09, 09, 09)); expect(schedule.entries[5].end, DateTime(2020, 09, 09, 11, 45)); - expect(schedule.entries[5].type, ScheduleEntryType.Class); + expect(schedule.entries[5].type, ScheduleEntryType.Lesson); expect(schedule.entries[6].title, "SWE"); expect(schedule.entries[6].start, DateTime(2020, 09, 10, 09, 15)); expect(schedule.entries[6].end, DateTime(2020, 09, 10, 12)); - expect(schedule.entries[6].type, ScheduleEntryType.Class); + expect(schedule.entries[6].type, ScheduleEntryType.Lesson); expect(schedule.entries[7].title, "Messdatenerfassung"); expect(schedule.entries[7].start, DateTime(2020, 09, 10, 13)); expect(schedule.entries[7].end, DateTime(2020, 09, 10, 14, 30)); - expect(schedule.entries[7].type, ScheduleEntryType.Class); + expect(schedule.entries[7].type, ScheduleEntryType.Lesson); }); test('Rapla correctly read all classes of monthly view', () async { @@ -100,7 +100,7 @@ Future main() async { expect(schedule.entries[0].title, "Mikrocontroller ONLINE"); expect(schedule.entries[0].start, DateTime(2020, 10, 01, 13)); expect(schedule.entries[0].end, DateTime(2020, 10, 01, 18)); - expect(schedule.entries[0].type, ScheduleEntryType.Class); + expect(schedule.entries[0].type, ScheduleEntryType.Lesson); expect(schedule.entries[0].professor, "Schmitt, Tobias"); }); @@ -112,7 +112,7 @@ Future main() async { expect(schedule.entries[0].title, "Modulprüfung T3_2000"); expect(schedule.entries[0].start, DateTime(2021, 09, 22, 08)); expect(schedule.entries[0].end, DateTime(2021, 09, 22, 15)); - expect(schedule.entries[0].type, ScheduleEntryType.Class); + expect(schedule.entries[0].type, ScheduleEntryType.Lesson); expect(schedule.entries[0].professor, "A"); expect( schedule.entries[0].room, @@ -127,7 +127,7 @@ Future main() async { expect(schedule.entries[8].title, "Ausgewählte Themen der Informatik"); expect(schedule.entries[8].start, DateTime(2021, 10, 06, 13, 45)); expect(schedule.entries[8].end, DateTime(2021, 10, 06, 17)); - expect(schedule.entries[8].type, ScheduleEntryType.Class); + expect(schedule.entries[8].type, ScheduleEntryType.Lesson); expect(schedule.entries[84].title, "Silvester"); expect(schedule.entries[84].start, DateTime(2021, 12, 31, 08)); @@ -146,13 +146,13 @@ Future main() async { expect(schedule.entries[0].title, "Verkehrswegebau und Straßenwesen"); expect(schedule.entries[0].start, DateTime(2021, 12, 01, 08, 15)); expect(schedule.entries[0].end, DateTime(2021, 12, 01, 12, 15)); - expect(schedule.entries[0].type, ScheduleEntryType.Class); + expect(schedule.entries[0].type, ScheduleEntryType.Lesson); expect(schedule.entries[0].professor, "Müller"); expect(schedule.entries[3].title, "Marketing und Unternehmensstrategie"); expect(schedule.entries[3].start, DateTime(2021, 12, 03, 13)); expect(schedule.entries[3].end, DateTime(2021, 12, 03, 16, 15)); - expect(schedule.entries[3].type, ScheduleEntryType.Class); + expect(schedule.entries[3].type, ScheduleEntryType.Lesson); expect(schedule.entries[3].professor, "Mayer"); expect(schedule.entries[11].title, "Stahlbetonbau"); @@ -189,7 +189,7 @@ Future main() async { expect(schedule.entries[0].title, "Grundlagen der Handelsbetriebslehre"); expect(schedule.entries[0].start, DateTime(2021, 11, 02, 09)); expect(schedule.entries[0].end, DateTime(2021, 11, 02, 12, 15)); - expect(schedule.entries[0].type, ScheduleEntryType.Class); + expect(schedule.entries[0].type, ScheduleEntryType.Lesson); expect(schedule.entries[0].professor, "Fr, Ta"); expect( schedule.entries[0].room, @@ -202,7 +202,7 @@ Future main() async { ); expect(schedule.entries[1].start, DateTime(2021, 11, 02, 13, 45)); expect(schedule.entries[1].end, DateTime(2021, 11, 02, 17)); - expect(schedule.entries[1].type, ScheduleEntryType.Class); + expect(schedule.entries[1].type, ScheduleEntryType.Lesson); expect(schedule.entries[1].professor, "Le, An"); expect( schedule.entries[1].room, @@ -212,7 +212,7 @@ Future main() async { expect(schedule.entries[2].title, "Grundlagen des Bürgerlichen Rechts"); expect(schedule.entries[2].start, DateTime(2021, 11, 03, 09)); expect(schedule.entries[2].end, DateTime(2021, 11, 03, 11, 30)); - expect(schedule.entries[2].type, ScheduleEntryType.Class); + expect(schedule.entries[2].type, ScheduleEntryType.Lesson); expect(schedule.entries[2].professor, "Ei, An"); expect( schedule.entries[2].room, @@ -222,7 +222,7 @@ Future main() async { expect(schedule.entries[3].title, "Technik der Finanzbuchführung I"); expect(schedule.entries[3].start, DateTime(2021, 11, 03, 13)); expect(schedule.entries[3].end, DateTime(2021, 11, 03, 16, 15)); - expect(schedule.entries[3].type, ScheduleEntryType.Class); + expect(schedule.entries[3].type, ScheduleEntryType.Lesson); expect(schedule.entries[3].professor, "Se, Ka"); expect( schedule.entries[3].room, @@ -235,7 +235,7 @@ Future main() async { ); expect(schedule.entries[4].start, DateTime(2021, 11, 04, 09)); expect(schedule.entries[4].end, DateTime(2021, 11, 04, 12, 15)); - expect(schedule.entries[4].type, ScheduleEntryType.Class); + expect(schedule.entries[4].type, ScheduleEntryType.Lesson); expect(schedule.entries[4].professor, "He, Be"); expect( schedule.entries[4].room, @@ -245,7 +245,7 @@ Future main() async { expect(schedule.entries[5].title, "Grundlagen der Handelsbetriebslehre"); expect(schedule.entries[5].start, DateTime(2021, 11, 04, 12, 45)); expect(schedule.entries[5].end, DateTime(2021, 11, 04, 16)); - expect(schedule.entries[5].type, ScheduleEntryType.Class); + expect(schedule.entries[5].type, ScheduleEntryType.Lesson); expect(schedule.entries[5].professor, "Fr, Ta"); expect( schedule.entries[5].room, @@ -255,7 +255,7 @@ Future main() async { expect(schedule.entries[6].title, "Einführung in die Programmierung"); expect(schedule.entries[6].start, DateTime(2021, 11, 05, 13)); expect(schedule.entries[6].end, DateTime(2021, 11, 05, 16, 15)); - expect(schedule.entries[6].type, ScheduleEntryType.Class); + expect(schedule.entries[6].type, ScheduleEntryType.Lesson); expect(schedule.entries[6].professor, "He, Ma"); expect( schedule.entries[6].room, From 4b266a678e6acb4390ec31e2e8d0388f93346371 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Sun, 16 Oct 2022 14:56:56 +0200 Subject: [PATCH 37/37] upgrade to dart 2.17 now that we use features of dart 2.17 for the theme upgrading everything to it. This also adds default constructors to every widget potentially improving the performance. Nuallybility got a boost aswel. --- lib/common/appstart/app_initializer.dart | 6 +- .../appstart/background_initialize.dart | 2 + .../appstart/localization_initialize.dart | 10 +- ...ification_schedule_changed_initialize.dart | 2 + .../appstart/notifications_initialize.dart | 5 +- lib/common/appstart/service_injector.dart | 6 +- lib/common/background/task_callback.dart | 2 + .../background/work_scheduler_service.dart | 2 + lib/common/data/database_access.dart | 2 + .../data/preferences/preferences_access.dart | 4 +- .../preferences/preferences_provider.dart | 5 +- .../preferences/secure_storage_access.dart | 4 +- lib/common/iap/in_app_purchase_helper.dart | 4 +- lib/common/ui/app_launch_dialogs.dart | 2 +- lib/common/ui/app_theme.dart | 2 +- lib/common/ui/donate_to_developer_dialog.dart | 5 +- lib/common/ui/notification_api.dart | 4 + lib/common/ui/rate_in_store_dialog.dart | 2 +- lib/common/ui/widget_help_dialog.dart | 2 +- lib/common/ui/widgets/dots_indicator.dart | 4 +- lib/common/ui/widgets/error_display.dart | 8 +- lib/common/ui/widgets/help_dialog.dart | 2 + lib/common/ui/widgets/title_list_tile.dart | 2 +- lib/common/util/cancelable_mutex.dart | 2 + .../business/date_entry_provider.dart | 12 +-- lib/date_management/data/calendar_access.dart | 8 +- .../data/date_entry_repository.dart | 2 +- lib/date_management/model/date_database.dart | 2 +- .../model/date_search_parameters.dart | 10 +- .../service/date_management_service.dart | 6 +- .../service/parsing/all_dates_extract.dart | 2 + .../ui/calendar_export_page.dart | 6 +- .../ui/date_management_navigation_entry.dart | 8 +- .../ui/date_management_page.dart | 8 +- .../date_management_view_model.dart | 25 +++-- .../ui/widgets/date_detail_bottom_sheet.dart | 16 ++- .../ui/widgets/date_filter_options.dart | 13 ++- .../widgets/date_management_help_dialog.dart | 2 + lib/dualis/model/exam.dart | 2 +- lib/dualis/model/exam_grade.dart | 15 +-- lib/dualis/model/module.dart | 2 +- lib/dualis/model/semester.dart | 2 +- lib/dualis/model/study_grades.dart | 2 +- lib/dualis/service/dualis_authentication.dart | 12 ++- lib/dualis/service/dualis_scraper.dart | 10 +- lib/dualis/service/dualis_service.dart | 4 +- lib/dualis/service/dualis_website_model.dart | 8 +- .../service/fake_data_dualis_scraper.dart | 10 +- .../parsing/access_denied_extract.dart | 2 + .../service/parsing/all_modules_extract.dart | 2 + .../exams_from_module_details_extract.dart | 2 + .../parsing/login_redirect_url_extract.dart | 2 + ...dules_from_course_result_page_extract.dart | 2 + .../parsing/monthly_schedule_extract.dart | 8 +- lib/dualis/service/parsing/parsing_utils.dart | 6 +- ...sters_from_course_result_page_extract.dart | 2 + ...des_from_student_results_page_extract.dart | 34 ++++-- .../service/parsing/timeout_extract.dart | 2 + .../parsing/urls_from_main_page_extract.dart | 2 + lib/dualis/service/session.dart | 8 +- lib/dualis/ui/dualis_navigation_entry.dart | 6 +- lib/dualis/ui/dualis_page.dart | 8 +- .../exam_results_page/exam_results_page.dart | 41 +++---- lib/dualis/ui/login/dualis_login_page.dart | 7 +- .../study_overview/study_overview_page.dart | 10 +- lib/dualis/ui/widgets/dualis_help_dialog.dart | 2 + lib/dualis/ui/widgets/grade_state_icon.dart | 5 +- lib/dualis/ui/widgets/login_form_widget.dart | 6 +- .../useful_information_navigation_entry.dart | 4 +- .../useful_information_page.dart | 2 + lib/native/widget/android_widget_helper.dart | 1 + lib/native/widget/ios_widget_helper.dart | 2 + lib/native/widget/widget_helper.dart | 20 ++-- lib/native/widget/widget_update_callback.dart | 2 +- .../background_schedule_update.dart | 2 +- .../background/calendar_synchronizer.dart | 2 +- .../business/schedule_diff_calculator.dart | 6 +- lib/schedule/business/schedule_filter.dart | 2 +- lib/schedule/business/schedule_provider.dart | 13 +-- .../business/schedule_source_provider.dart | 10 +- .../data/schedule_entry_repository.dart | 2 +- .../data/schedule_filter_repository.dart | 2 +- ...schedule_query_information_repository.dart | 2 +- lib/schedule/model/schedule_query_result.dart | 2 +- ...rror_report_schedule_source_decorator.dart | 2 +- lib/schedule/service/ical/ical_parser.dart | 2 + .../service/ical/ical_schedule_source.dart | 2 +- .../service/invalid_schedule_source.dart | 2 + .../mannheim_course_response_parser.dart | 2 + .../mannheim/mannheim_course_scraper.dart | 11 +- .../service/rapla/rapla_response_parser.dart | 2 + .../service/rapla/rapla_schedule_source.dart | 9 +- lib/schedule/service/schedule_prettifier.dart | 2 + lib/schedule/service/schedule_source.dart | 6 +- .../ui/dailyschedule/daily_schedule_page.dart | 22 ++-- .../current_time_indicator_widget.dart | 2 + .../widgets/daily_schedule_entry_widget.dart | 6 +- .../next_day_information_notification.dart | 2 +- .../schedule_changed_notification.dart | 2 +- .../ui/schedule_navigation_entry.dart | 4 +- lib/schedule/ui/schedule_page.dart | 6 +- .../filter/filter_view_model.dart | 2 +- .../filter/schedule_filter_page.dart | 4 + .../schedule_entry_detail_bottom_sheet.dart | 28 ++--- .../weeklyschedule/weekly_schedule_page.dart | 5 +- .../widgets/schedule_entry_alignment.dart | 2 + .../widgets/schedule_entry_widget.dart | 10 +- .../weeklyschedule/widgets/schedule_grid.dart | 12 +-- .../widgets/schedule_past_overlay.dart | 2 +- .../widgets/schedule_widget.dart | 51 +++++---- .../enter_dualis_credentials_dialog.dart | 2 +- lib/schedule/ui/widgets/enter_url_dialog.dart | 2 +- .../ui/widgets/schedule_empty_state.dart | 4 +- .../ui/widgets/schedule_help_dialog.dart | 2 + .../select_mannheim_course_dialog.dart | 16 ++- .../ui/widgets/select_source_dialog.dart | 2 +- lib/ui/banner_widget.dart | 4 +- lib/ui/login_credentials_widget.dart | 27 ++--- lib/ui/main_page.dart | 15 +-- lib/ui/navigation/navigation_entry.dart | 2 + lib/ui/navigation_drawer.dart | 38 ++++--- lib/ui/onboarding/onboardin_step.dart | 11 ++ lib/ui/onboarding/onboarding_page.dart | 2 +- .../viewmodels/mannheim_view_model.dart | 2 +- .../onboarding_view_model_base.dart | 2 + .../onboarding/widgets/dualis_login_page.dart | 20 ++-- lib/ui/onboarding/widgets/ical_url_page.dart | 18 ++-- lib/ui/onboarding/widgets/mannheim_page.dart | 15 ++- .../widgets/onboarding_button_bar.dart | 4 +- .../widgets/onboarding_page_background.dart | 9 +- lib/ui/onboarding/widgets/rapla_url_page.dart | 18 ++-- .../widgets/select_source_page.dart | 2 +- lib/ui/pager_widget.dart | 7 +- lib/ui/root_page.dart | 19 +--- lib/ui/settings/donate_list_tile.dart | 2 +- .../settings/purchase_widget_list_tile.dart | 2 +- lib/ui/settings/select_theme_dialog.dart | 2 +- lib/ui/settings/settings_page.dart | 102 +++++++++--------- .../parsing/all_dates_extract_test.dart | 2 +- .../parsing/all_modules_extract_test.dart | 4 +- .../parsing/dualis_timeout_extract_test.dart | 7 +- ...xams_from_module_details_extract_test.dart | 4 +- .../monthly_schedule_extract_test.dart | 2 +- ..._from_course_result_page_extract_test.dart | 4 +- ...rom_student_results_page_extract_test.dart | 4 +- .../urls_from_main_page_extract_test.dart | 4 +- .../schedule_diff_calculator_test.dart | 12 +-- .../mannheim_course_response_parser_test.dart | 2 +- 148 files changed, 610 insertions(+), 493 deletions(-) diff --git a/lib/common/appstart/app_initializer.dart b/lib/common/appstart/app_initializer.dart index 7968c307..e614e19b 100644 --- a/lib/common/appstart/app_initializer.dart +++ b/lib/common/appstart/app_initializer.dart @@ -52,9 +52,9 @@ Future initializeApp(bool isBackground) async { WidgetUpdateCallback(KiwiContainer().resolve()) .registerCallback(KiwiContainer().resolve()); - NotificationsInitialize().setupNotifications(); - BackgroundInitialize().setupBackgroundScheduling(); - NotificationScheduleChangedInitialize().setupNotification(); + const NotificationsInitialize().setupNotifications(); + const BackgroundInitialize().setupBackgroundScheduling(); + const NotificationScheduleChangedInitialize().setupNotification(); if (isBackground) { final setup = KiwiContainer().resolve(); diff --git a/lib/common/appstart/background_initialize.dart b/lib/common/appstart/background_initialize.dart index 1fe025e2..6b5f0c26 100644 --- a/lib/common/appstart/background_initialize.dart +++ b/lib/common/appstart/background_initialize.dart @@ -12,6 +12,8 @@ import 'package:kiwi/kiwi.dart'; /// Note: More or less reliable background scheduling only works on android /// class BackgroundInitialize { + const BackgroundInitialize(); + Future setupBackgroundScheduling() async { WorkSchedulerService scheduler; if (Platform.isAndroid) { diff --git a/lib/common/appstart/localization_initialize.dart b/lib/common/appstart/localization_initialize.dart index 133cde4f..97c0efbb 100644 --- a/lib/common/appstart/localization_initialize.dart +++ b/lib/common/appstart/localization_initialize.dart @@ -9,18 +9,20 @@ import 'package:kiwi/kiwi.dart'; /// correct language /// class LocalizationInitialize { - PreferencesProvider? _preferencesProvider; - String? _languageCode; + final PreferencesProvider? _preferencesProvider; + final String? _languageCode; /// /// Initialize the localization using the provided language code /// - LocalizationInitialize.fromLanguageCode(this._languageCode); + const LocalizationInitialize.fromLanguageCode(this._languageCode) + : _preferencesProvider = null; /// /// Initialize the localization using the locale from the preferences provider /// - LocalizationInitialize.fromPreferences(this._preferencesProvider); + const LocalizationInitialize.fromPreferences(this._preferencesProvider) + : _languageCode = null; Future setupLocalizations() async { final localization = L( diff --git a/lib/common/appstart/notification_schedule_changed_initialize.dart b/lib/common/appstart/notification_schedule_changed_initialize.dart index c5c0209d..f29b69d6 100644 --- a/lib/common/appstart/notification_schedule_changed_initialize.dart +++ b/lib/common/appstart/notification_schedule_changed_initialize.dart @@ -8,6 +8,8 @@ import 'package:kiwi/kiwi.dart'; /// Initializes the notification for when the schedule changed /// class NotificationScheduleChangedInitialize { + const NotificationScheduleChangedInitialize(); + void setupNotification() { final provider = KiwiContainer().resolve(); diff --git a/lib/common/appstart/notifications_initialize.dart b/lib/common/appstart/notifications_initialize.dart index ec9a664d..0bf419c7 100644 --- a/lib/common/appstart/notifications_initialize.dart +++ b/lib/common/appstart/notifications_initialize.dart @@ -9,6 +9,8 @@ import 'package:kiwi/kiwi.dart'; /// won't show the notification /// class NotificationsInitialize { + const NotificationsInitialize(); + Future setupNotifications() async { if (Platform.isAndroid) { final notificationApi = NotificationApi(); @@ -17,7 +19,8 @@ class NotificationsInitialize { await notificationApi.initialize(); } else { - KiwiContainer().registerInstance(VoidNotificationApi()); + KiwiContainer() + .registerInstance(const VoidNotificationApi()); } } } diff --git a/lib/common/appstart/service_injector.dart b/lib/common/appstart/service_injector.dart index 77adf9a3..e5c49f77 100644 --- a/lib/common/appstart/service_injector.dart +++ b/lib/common/appstart/service_injector.dart @@ -30,12 +30,12 @@ void injectServices(bool isBackground) { final KiwiContainer c = KiwiContainer(); c.registerInstance( - PreferencesProvider( + const PreferencesProvider( PreferencesAccess(), SecureStorageAccess(), ), ); - c.registerInstance(DatabaseAccess()); + c.registerInstance(const DatabaseAccess()); c.registerInstance( ScheduleEntryRepository( c.resolve(), @@ -80,7 +80,7 @@ void injectServices(bool isBackground) { ); c.registerInstance( DateEntryProvider( - DateManagementService(), + const DateManagementService(), DateEntryRepository(c.resolve()), ), ); diff --git a/lib/common/background/task_callback.dart b/lib/common/background/task_callback.dart index e2a36a1e..dc3e63cf 100644 --- a/lib/common/background/task_callback.dart +++ b/lib/common/background/task_callback.dart @@ -2,6 +2,8 @@ /// Override this class in order to receive a background callback /// abstract class TaskCallback { + const TaskCallback(); + Future run(); Future schedule(); diff --git a/lib/common/background/work_scheduler_service.dart b/lib/common/background/work_scheduler_service.dart index d11baa58..e692db22 100644 --- a/lib/common/background/work_scheduler_service.dart +++ b/lib/common/background/work_scheduler_service.dart @@ -1,6 +1,8 @@ import 'package:dhbwstudentapp/common/background/task_callback.dart'; abstract class WorkSchedulerService { + const WorkSchedulerService(); + Future scheduleOneShotTaskIn(Duration delay, String id, String name); Future scheduleOneShotTaskAt( diff --git a/lib/common/data/database_access.dart b/lib/common/data/database_access.dart index d03bf55f..87dbb25c 100644 --- a/lib/common/data/database_access.dart +++ b/lib/common/data/database_access.dart @@ -3,6 +3,8 @@ import 'package:dhbwstudentapp/common/data/sql_scripts.dart'; import 'package:sqflite/sqflite.dart'; class DatabaseAccess { + const DatabaseAccess(); + static const String _databaseName = "Database.db"; static Database? _databaseInstance; diff --git a/lib/common/data/preferences/preferences_access.dart b/lib/common/data/preferences/preferences_access.dart index ea183eae..08465854 100644 --- a/lib/common/data/preferences/preferences_access.dart +++ b/lib/common/data/preferences/preferences_access.dart @@ -1,6 +1,8 @@ import 'package:shared_preferences/shared_preferences.dart'; class PreferencesAccess { + const PreferencesAccess(); + Future set(String key, T value) async { final SharedPreferences prefs = await SharedPreferences.getInstance(); @@ -43,5 +45,5 @@ class PreferencesAccess { class InvalidValueTypeException implements Exception { final Type type; - InvalidValueTypeException(this.type); + const InvalidValueTypeException(this.type); } diff --git a/lib/common/data/preferences/preferences_provider.dart b/lib/common/data/preferences/preferences_provider.dart index 86a4ff4e..2570bd5c 100644 --- a/lib/common/data/preferences/preferences_provider.dart +++ b/lib/common/data/preferences/preferences_provider.dart @@ -33,7 +33,7 @@ class PreferencesProvider { final PreferencesAccess _preferencesAccess; final SecureStorageAccess _secureStorageAccess; - PreferencesProvider(this._preferencesAccess, this._secureStorageAccess); + const PreferencesProvider(this._preferencesAccess, this._secureStorageAccess); Future appTheme() async { final theme = await _preferencesAccess.get(AppThemeKey); @@ -267,8 +267,7 @@ class PreferencesProvider { } Future setNextRateInStoreLaunchCount(int value) async { - return await _preferencesAccess.set( - "NextRateInStoreLaunchCount", value); + return _preferencesAccess.set("NextRateInStoreLaunchCount", value); } Future getDidShowDonateDialog() async { diff --git a/lib/common/data/preferences/secure_storage_access.dart b/lib/common/data/preferences/secure_storage_access.dart index 2f616d2e..e8fe4da4 100644 --- a/lib/common/data/preferences/secure_storage_access.dart +++ b/lib/common/data/preferences/secure_storage_access.dart @@ -1,7 +1,9 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class SecureStorageAccess { - final _secureStorage = const FlutterSecureStorage(); + static const _secureStorage = FlutterSecureStorage(); + + const SecureStorageAccess(); Future set(String key, String value) async { await _secureStorage.write(key: key, value: value); diff --git a/lib/common/iap/in_app_purchase_helper.dart b/lib/common/iap/in_app_purchase_helper.dart index d469490e..5f0fe27b 100644 --- a/lib/common/iap/in_app_purchase_helper.dart +++ b/lib/common/iap/in_app_purchase_helper.dart @@ -100,8 +100,8 @@ class InAppPurchaseHelper { final productIdPurchases = allPurchases?.where((element) => element.productId == id); - if (productIdPurchases?.isNotEmpty ?? false) { - return productIdPurchases!.any((element) => _isPurchased(element)) + if (productIdPurchases != null && productIdPurchases.isNotEmpty) { + return productIdPurchases.any((element) => _isPurchased(element)) ? PurchaseStateEnum.Purchased : PurchaseStateEnum.NotPurchased; } diff --git a/lib/common/ui/app_launch_dialogs.dart b/lib/common/ui/app_launch_dialogs.dart index 3f3cbe04..3251b313 100644 --- a/lib/common/ui/app_launch_dialogs.dart +++ b/lib/common/ui/app_launch_dialogs.dart @@ -11,7 +11,7 @@ import 'package:flutter/material.dart'; class AppLaunchDialog { final PreferencesProvider _preferencesProvider; - AppLaunchDialog(this._preferencesProvider); + const AppLaunchDialog(this._preferencesProvider); Future showAppLaunchDialogs(BuildContext context) async { final appLaunchCounter = await _preferencesProvider.getAppLaunchCounter(); diff --git a/lib/common/ui/app_theme.dart b/lib/common/ui/app_theme.dart index b9f89f43..33d87c59 100644 --- a/lib/common/ui/app_theme.dart +++ b/lib/common/ui/app_theme.dart @@ -4,7 +4,7 @@ import 'package:dhbwstudentapp/common/ui/text_theme.dart'; import 'package:flutter/material.dart'; class AppTheme { - AppTheme._(); + const AppTheme._(); /// Light theme static final lightThemeData = ThemeData( diff --git a/lib/common/ui/donate_to_developer_dialog.dart b/lib/common/ui/donate_to_developer_dialog.dart index dca41ffc..78b5e5f0 100644 --- a/lib/common/ui/donate_to_developer_dialog.dart +++ b/lib/common/ui/donate_to_developer_dialog.dart @@ -14,7 +14,10 @@ class DonateToDeveloperDialog { final PreferencesProvider _preferencesProvider; final int _appLaunchCounter; - DonateToDeveloperDialog(this._preferencesProvider, this._appLaunchCounter); + const DonateToDeveloperDialog( + this._preferencesProvider, + this._appLaunchCounter, + ); Future showIfNeeded(BuildContext context) async { if (await _preferencesProvider.getDidShowDonateDialog()) return; diff --git a/lib/common/ui/notification_api.dart b/lib/common/ui/notification_api.dart index d2338919..3286df1b 100644 --- a/lib/common/ui/notification_api.dart +++ b/lib/common/ui/notification_api.dart @@ -10,6 +10,8 @@ class NotificationApi { final FlutterLocalNotificationsPlugin _localNotificationsPlugin = FlutterLocalNotificationsPlugin(); + NotificationApi(); + /// /// Initialize the notifications. You can't show any notifications before you /// call this method @@ -84,6 +86,8 @@ class NotificationApi { /// This class implements the methods of the NotificationApi with empty stubs /// class VoidNotificationApi implements NotificationApi { + const VoidNotificationApi(); + @override FlutterLocalNotificationsPlugin get _localNotificationsPlugin => throw UnimplementedError(); diff --git a/lib/common/ui/rate_in_store_dialog.dart b/lib/common/ui/rate_in_store_dialog.dart index 936b7612..e21a3f6b 100644 --- a/lib/common/ui/rate_in_store_dialog.dart +++ b/lib/common/ui/rate_in_store_dialog.dart @@ -13,7 +13,7 @@ class RateInStoreDialog { final PreferencesProvider _preferencesProvider; final int _appLaunchCounter; - RateInStoreDialog(this._preferencesProvider, this._appLaunchCounter); + const RateInStoreDialog(this._preferencesProvider, this._appLaunchCounter); Future showIfNeeded(BuildContext context) async { if (!PlatformUtil.isAndroid()) return; diff --git a/lib/common/ui/widget_help_dialog.dart b/lib/common/ui/widget_help_dialog.dart index 060428e0..c41279d5 100644 --- a/lib/common/ui/widget_help_dialog.dart +++ b/lib/common/ui/widget_help_dialog.dart @@ -11,7 +11,7 @@ class WidgetHelpDialog { final PreferencesProvider _preferencesProvider; final int _appLaunchCounter; - WidgetHelpDialog(this._preferencesProvider, this._appLaunchCounter); + const WidgetHelpDialog(this._preferencesProvider, this._appLaunchCounter); Future showIfNeeded(BuildContext context) async { if (!PlatformUtil.isAndroid()) return; diff --git a/lib/common/ui/widgets/dots_indicator.dart b/lib/common/ui/widgets/dots_indicator.dart index 8a89bd4c..4e50d4e0 100644 --- a/lib/common/ui/widgets/dots_indicator.dart +++ b/lib/common/ui/widgets/dots_indicator.dart @@ -5,10 +5,10 @@ class DotsIndicator extends StatelessWidget { final int currentStep; const DotsIndicator({ - Key? key, + super.key, required this.numberSteps, required this.currentStep, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/common/ui/widgets/error_display.dart b/lib/common/ui/widgets/error_display.dart index c254574a..a6d5c631 100644 --- a/lib/common/ui/widgets/error_display.dart +++ b/lib/common/ui/widgets/error_display.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; class ErrorDisplay extends StatelessWidget { final bool show; - const ErrorDisplay({Key? key, required this.show}) : super(key: key); + const ErrorDisplay({super.key, required this.show}); @override Widget build(BuildContext context) { @@ -25,9 +25,9 @@ class ErrorDisplay extends StatelessWidget { child: Text( L.of(context).noConnectionMessage, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.subtitle2!.copyWith( - color: AppTheme.noConnectionForeground, - ), + style: const TextStyle( + color: AppTheme.noConnectionForeground, + ), ), ), ), diff --git a/lib/common/ui/widgets/help_dialog.dart b/lib/common/ui/widgets/help_dialog.dart index e3098298..08b87df3 100644 --- a/lib/common/ui/widgets/help_dialog.dart +++ b/lib/common/ui/widgets/help_dialog.dart @@ -6,6 +6,8 @@ import 'package:flutter/material.dart'; /// Deriving classes only need to implement the title() and content() methods /// abstract class HelpDialog { + const HelpDialog(); + Future show(BuildContext context) async { await showDialog( context: context, diff --git a/lib/common/ui/widgets/title_list_tile.dart b/lib/common/ui/widgets/title_list_tile.dart index 82de6d27..58b6c7d9 100644 --- a/lib/common/ui/widgets/title_list_tile.dart +++ b/lib/common/ui/widgets/title_list_tile.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; class TitleListTile extends StatelessWidget { final String title; - const TitleListTile({Key? key, required this.title}) : super(key: key); + const TitleListTile({super.key, required this.title}); @override Widget build(BuildContext context) { diff --git a/lib/common/util/cancelable_mutex.dart b/lib/common/util/cancelable_mutex.dart index 4d79d6fb..fdcb1aa2 100644 --- a/lib/common/util/cancelable_mutex.dart +++ b/lib/common/util/cancelable_mutex.dart @@ -6,6 +6,8 @@ class CancelableMutex { CancellationToken? _token; CancellationToken? get token => _token; + CancelableMutex(); + void cancel() { _token?.cancel(); } diff --git a/lib/date_management/business/date_entry_provider.dart b/lib/date_management/business/date_entry_provider.dart index ad8d762f..a493625c 100644 --- a/lib/date_management/business/date_entry_provider.dart +++ b/lib/date_management/business/date_entry_provider.dart @@ -8,21 +8,21 @@ class DateEntryProvider { final DateManagementService _dateEntryService; final DateEntryRepository _dateEntryRepository; - DateEntryProvider(this._dateEntryService, this._dateEntryRepository); + const DateEntryProvider(this._dateEntryService, this._dateEntryRepository); Future> getCachedDateEntries( DateSearchParameters parameters, ) async { List cachedEntries = []; - if (parameters.includeFuture! && parameters.includePast!) { + if (parameters.includeFuture && parameters.includePast) { cachedEntries = await _dateEntryRepository.queryAllDateEntries( parameters.databaseName, parameters.year, ); } else { final now = DateTime.now(); - if (parameters.includeFuture!) { + if (parameters.includeFuture) { final datesAfter = await _dateEntryRepository.queryDateEntriesAfter( parameters.databaseName, parameters.year, @@ -31,7 +31,7 @@ class DateEntryProvider { cachedEntries.addAll(datesAfter); } - if (parameters.includePast!) { + if (parameters.includePast) { final datesBefore = await _dateEntryRepository.queryDateEntriesBefore( parameters.databaseName, parameters.year, @@ -85,11 +85,11 @@ class DateEntryProvider { continue; } - if (dateEntry.start.isBefore(now) && !parameters.includePast!) { + if (dateEntry.start.isBefore(now) && !parameters.includePast) { continue; } - if (dateEntry.end.isAfter(now) && !parameters.includeFuture!) { + if (dateEntry.end.isAfter(now) && !parameters.includeFuture) { continue; } diff --git a/lib/date_management/data/calendar_access.dart b/lib/date_management/data/calendar_access.dart index 5c410cc3..5be9a092 100644 --- a/lib/date_management/data/calendar_access.dart +++ b/lib/date_management/data/calendar_access.dart @@ -17,6 +17,8 @@ enum CalendarPermission { class CalendarAccess { final DeviceCalendarPlugin _deviceCalendarPlugin = DeviceCalendarPlugin(); + CalendarAccess(); + Future requestCalendarPermission() async { try { var permissionsGranted = await _deviceCalendarPlugin.hasPermissions(); @@ -134,12 +136,10 @@ class CalendarAccess { ), ); - var existingEvents = []; - if (existingEventsResult.isSuccess) { - existingEvents = existingEventsResult.data!.toList(); + return existingEventsResult.data!.toList(); } - return existingEvents; + return []; } DateEntry _findFirstEntry(List entries) { diff --git a/lib/date_management/data/date_entry_repository.dart b/lib/date_management/data/date_entry_repository.dart index 986e6366..86aef15e 100644 --- a/lib/date_management/data/date_entry_repository.dart +++ b/lib/date_management/data/date_entry_repository.dart @@ -4,7 +4,7 @@ import 'package:dhbwstudentapp/date_management/model/date_entry.dart'; class DateEntryRepository { final DatabaseAccess _database; - DateEntryRepository(this._database); + const DateEntryRepository(this._database); Future> queryAllDateEntries( String? databaseName, diff --git a/lib/date_management/model/date_database.dart b/lib/date_management/model/date_database.dart index e9da69ed..a10f437a 100644 --- a/lib/date_management/model/date_database.dart +++ b/lib/date_management/model/date_database.dart @@ -2,5 +2,5 @@ class DateDatabase { final String id; final String displayName; - DateDatabase(this.displayName, this.id); + const DateDatabase(this.displayName, this.id); } diff --git a/lib/date_management/model/date_search_parameters.dart b/lib/date_management/model/date_search_parameters.dart index f686fc9f..430f8298 100644 --- a/lib/date_management/model/date_search_parameters.dart +++ b/lib/date_management/model/date_search_parameters.dart @@ -1,10 +1,10 @@ class DateSearchParameters { - bool? includePast; - bool? includeFuture; - String? year; - String? databaseName; + final bool includePast; + final bool includeFuture; + final String? year; + final String? databaseName; - DateSearchParameters( + const DateSearchParameters( this.includePast, this.includeFuture, this.year, diff --git a/lib/date_management/service/date_management_service.dart b/lib/date_management/service/date_management_service.dart index 3a2e26dd..1f153a82 100644 --- a/lib/date_management/service/date_management_service.dart +++ b/lib/date_management/service/date_management_service.dart @@ -5,6 +5,8 @@ import 'package:dhbwstudentapp/date_management/service/parsing/all_dates_extract import 'package:dhbwstudentapp/dualis/service/session.dart'; class DateManagementService { + const DateManagementService(); + Future> queryAllDates( DateSearchParameters parameters, CancellationToken? cancellationToken, @@ -14,7 +16,7 @@ class DateManagementService { cancellationToken, ); - final allDates = AllDatesExtract().extractAllDates( + final allDates = const AllDatesExtract().extractAllDates( queryResult, parameters.databaseName, ); @@ -28,7 +30,7 @@ class DateManagementService { url += "&sel_typ=pub"; url += "&sel_jahrgang= ${parameters.year ?? "*"}"; url += "&sel_bezeichnung=*"; - url += "&selection=${parameters.includePast! ? "**" : "*"}"; + url += "&selection=${parameters.includePast ? "**" : "*"}"; url += "&permission=show"; url += "&sessionid="; url += "&user=nobody"; diff --git a/lib/date_management/service/parsing/all_dates_extract.dart b/lib/date_management/service/parsing/all_dates_extract.dart index bc48b192..a8e94c55 100644 --- a/lib/date_management/service/parsing/all_dates_extract.dart +++ b/lib/date_management/service/parsing/all_dates_extract.dart @@ -5,6 +5,8 @@ import 'package:intl/intl.dart'; // TODO: Parse exception to common module class AllDatesExtract { + const AllDatesExtract(); + List extractAllDates(String? body, String? databaseName) { if (body == null) return []; try { diff --git a/lib/date_management/ui/calendar_export_page.dart b/lib/date_management/ui/calendar_export_page.dart index 749c3fe5..e0231574 100644 --- a/lib/date_management/ui/calendar_export_page.dart +++ b/lib/date_management/ui/calendar_export_page.dart @@ -15,11 +15,11 @@ class CalendarExportPage extends StatefulWidget { final bool isCalendarSyncEnabled; const CalendarExportPage({ - Key? key, + super.key, required this.entriesToExport, this.isCalendarSyncWidget = false, this.isCalendarSyncEnabled = false, - }) : super(key: key); + }); @override _CalendarExportPageState createState() => _CalendarExportPageState(); @@ -28,6 +28,8 @@ class CalendarExportPage extends StatefulWidget { class _CalendarExportPageState extends State { late CalendarExportViewModel viewModel; + _CalendarExportPageState(); + @override void initState() { super.initState(); diff --git a/lib/date_management/ui/date_management_navigation_entry.dart b/lib/date_management/ui/date_management_navigation_entry.dart index 76340b64..dc46e32b 100644 --- a/lib/date_management/ui/date_management_navigation_entry.dart +++ b/lib/date_management/ui/date_management_navigation_entry.dart @@ -11,6 +11,8 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class DateManagementNavigationEntry extends NavigationEntry { + DateManagementNavigationEntry(); + @override Icon icon = const Icon(Icons.date_range); @@ -33,7 +35,7 @@ class DateManagementNavigationEntry IconButton( icon: const Icon(Icons.help_outline), onPressed: () async { - await DateManagementHelpDialog().show(context); + await const DateManagementHelpDialog().show(context); }, tooltip: L.of(context).helpButtonTooltip, ), @@ -43,7 +45,7 @@ class DateManagementNavigationEntry builder: (BuildContext context, DateManagementViewModel? _, __) => PopupMenuButton( onSelected: (i) async { - await NavigatorKey.rootKey.currentState!.push( + await NavigatorKey.rootKey.currentState?.push( MaterialPageRoute( builder: (BuildContext context) => CalendarExportPage( entriesToExport: model.allDates!, @@ -68,7 +70,7 @@ class DateManagementNavigationEntry @override Widget build(BuildContext context) { - return Scaffold(body: DateManagementPage()); + return const Scaffold(body: DateManagementPage()); } @override diff --git a/lib/date_management/ui/date_management_page.dart b/lib/date_management/ui/date_management_page.dart index 8ceb65cc..e321030e 100644 --- a/lib/date_management/ui/date_management_page.dart +++ b/lib/date_management/ui/date_management_page.dart @@ -11,6 +11,8 @@ import 'package:property_change_notifier/property_change_notifier.dart'; import 'package:provider/provider.dart'; class DateManagementPage extends StatelessWidget { + const DateManagementPage({super.key}); + @override Widget build(BuildContext context) { final DateManagementViewModel viewModel = @@ -145,13 +147,11 @@ class DateManagementPage extends StatelessWidget { return dataRows; } - void showDateEntryDetailBottomSheet(BuildContext context, DateEntry? entry) { + void showDateEntryDetailBottomSheet(BuildContext context, DateEntry entry) { showModalBottomSheet( useRootNavigator: true, context: context, - builder: (context) => DateDetailBottomSheet( - dateEntry: entry, - ), + builder: (context) => DateDetailBottomSheet(dateEntry: entry), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(12.0)), ), diff --git a/lib/date_management/ui/viewmodels/date_management_view_model.dart b/lib/date_management/ui/viewmodels/date_management_view_model.dart index 32296b9f..7cc666e9 100644 --- a/lib/date_management/ui/viewmodels/date_management_view_model.dart +++ b/lib/date_management/ui/viewmodels/date_management_view_model.dart @@ -13,23 +13,26 @@ class DateManagementViewModel extends BaseViewModel { final PreferencesProvider _preferencesProvider; final List _allDateDatabases = [ - DateDatabase("BWL-Bank", "Termine_BWL_Bank"), - DateDatabase("Immobilienwirtschaft", "Termine_BWL_Immo"), - DateDatabase( + const DateDatabase("BWL-Bank", "Termine_BWL_Bank"), + const DateDatabase("Immobilienwirtschaft", "Termine_BWL_Immo"), + const DateDatabase( "Dienstleistungsmanagement Consulting & Sales", "Termine_DLM_Consult", ), - DateDatabase("Dienstleistungsmanagement Logistik", "Termine_DLM_Logistik"), - DateDatabase("Campus Horb Informatik", "Termine_Horb_INF"), - DateDatabase("Campus Horb Maschinenbau", "Termine_Horb_MB"), - DateDatabase("International Business", "Termine_IB"), - DateDatabase("Informatik", "Termine_Informatik"), - DateDatabase("MUK (DLM - C&S, LogM, MUK)", "Termine_MUK"), - DateDatabase( + const DateDatabase( + "Dienstleistungsmanagement Logistik", + "Termine_DLM_Logistik", + ), + const DateDatabase("Campus Horb Informatik", "Termine_Horb_INF"), + const DateDatabase("Campus Horb Maschinenbau", "Termine_Horb_MB"), + const DateDatabase("International Business", "Termine_IB"), + const DateDatabase("Informatik", "Termine_Informatik"), + const DateDatabase("MUK (DLM - C&S, LogM, MUK)", "Termine_MUK"), + const DateDatabase( "SO_GuO (Abweichungen und Ergänzungen zum Vorlesungsplan)", "Termine_SO_GuO", ), - DateDatabase("Wirtschaftsingenieurwesen", "Termine_WIW"), + const DateDatabase("Wirtschaftsingenieurwesen", "Termine_WIW"), ]; List get allDateDatabases => _allDateDatabases; diff --git a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart index a715e3ee..656c1bd6 100644 --- a/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart +++ b/lib/date_management/ui/widgets/date_detail_bottom_sheet.dart @@ -6,16 +6,16 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class DateDetailBottomSheet extends StatelessWidget { - final DateEntry? dateEntry; + final DateEntry dateEntry; - const DateDetailBottomSheet({Key? key, this.dateEntry}) : super(key: key); + const DateDetailBottomSheet({super.key, required this.dateEntry}); @override Widget build(BuildContext context) { final date = DateFormat.yMd(L.of(context).locale.languageCode) - .format(dateEntry!.start); + .format(dateEntry.start); final time = DateFormat.Hm(L.of(context).locale.languageCode) - .format(dateEntry!.start); + .format(dateEntry.start); return SizedBox( height: 400, @@ -45,7 +45,7 @@ class DateDetailBottomSheet extends StatelessWidget { children: [ Expanded( child: Text( - dateEntry!.description, + dateEntry.description, style: Theme.of(context).textTheme.headline5, ), ), @@ -59,7 +59,7 @@ class DateDetailBottomSheet extends StatelessWidget { softWrap: true, style: Theme.of(context).textTheme.subtitle2, ), - if (isAtMidnight(dateEntry!.start)) + if (isAtMidnight(dateEntry.start)) Container() else Text( @@ -74,9 +74,7 @@ class DateDetailBottomSheet extends StatelessWidget { ), Padding( padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), - child: Text( - dateEntry!.comment, - ), + child: Text(dateEntry.comment), ), ], ), diff --git a/lib/date_management/ui/widgets/date_filter_options.dart b/lib/date_management/ui/widgets/date_filter_options.dart index 2624293d..25886289 100644 --- a/lib/date_management/ui/widgets/date_filter_options.dart +++ b/lib/date_management/ui/widgets/date_filter_options.dart @@ -6,8 +6,7 @@ import 'package:flutter/material.dart'; class DateFilterOptions extends StatefulWidget { final DateManagementViewModel viewModel; - const DateFilterOptions({Key? key, required this.viewModel}) - : super(key: key); + const DateFilterOptions({super.key, required this.viewModel}); @override _DateFilterOptionsState createState() => _DateFilterOptionsState(); @@ -16,6 +15,8 @@ class DateFilterOptions extends StatefulWidget { class _DateFilterOptionsState extends State { bool _isExpanded = false; + _DateFilterOptionsState(); + @override Widget build(BuildContext context) { return AnimatedCrossFade( @@ -43,11 +44,9 @@ class _DateFilterOptionsState extends State { Widget _buildCollapsed() { return GestureDetector( - onTap: () { - setState(() { - _isExpanded = true; - }); - }, + onTap: () => setState(() { + _isExpanded = true; + }), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ diff --git a/lib/date_management/ui/widgets/date_management_help_dialog.dart b/lib/date_management/ui/widgets/date_management_help_dialog.dart index 55c97285..2b403083 100644 --- a/lib/date_management/ui/widgets/date_management_help_dialog.dart +++ b/lib/date_management/ui/widgets/date_management_help_dialog.dart @@ -3,6 +3,8 @@ import 'package:dhbwstudentapp/common/ui/widgets/help_dialog.dart'; import 'package:flutter/material.dart'; class DateManagementHelpDialog extends HelpDialog { + const DateManagementHelpDialog(); + @override String content(BuildContext context) { return L.of(context).dateManagementHelpDialogContent; diff --git a/lib/dualis/model/exam.dart b/lib/dualis/model/exam.dart index 22cf8f93..33d21730 100644 --- a/lib/dualis/model/exam.dart +++ b/lib/dualis/model/exam.dart @@ -12,7 +12,7 @@ class Exam { final String? semester; final ExamState state; - Exam( + const Exam( this.name, this.grade, this.state, diff --git a/lib/dualis/model/exam_grade.dart b/lib/dualis/model/exam_grade.dart index f3ba7598..90c9518f 100644 --- a/lib/dualis/model/exam_grade.dart +++ b/lib/dualis/model/exam_grade.dart @@ -5,19 +5,20 @@ enum ExamGradeState { Failed, } +// TODO: [leptopoda] implement into the enum class ExamGrade { - ExamGradeState state; - String? gradeValue; + final ExamGradeState state; + final String? gradeValue; - ExamGrade.failed() + const ExamGrade.failed() : state = ExamGradeState.Failed, gradeValue = ""; - ExamGrade.notGraded() + const ExamGrade.notGraded() : state = ExamGradeState.NotGraded, gradeValue = ""; - ExamGrade.passed() + const ExamGrade.passed() : state = ExamGradeState.Passed, gradeValue = ""; @@ -25,11 +26,11 @@ class ExamGrade { factory ExamGrade.fromString(String? grade) { if (grade == "noch nicht gesetzt" || grade == "") { - return ExamGrade.notGraded(); + return const ExamGrade.notGraded(); } if (grade == "b") { - return ExamGrade.passed(); + return const ExamGrade.passed(); } // TODO: Determine the value when a exam is in the "failed" state diff --git a/lib/dualis/model/module.dart b/lib/dualis/model/module.dart index c2d1d879..d26a6a96 100644 --- a/lib/dualis/model/module.dart +++ b/lib/dualis/model/module.dart @@ -8,7 +8,7 @@ class Module { final String? grade; final ExamState? state; - Module( + const Module( this.exams, this.id, this.name, diff --git a/lib/dualis/model/semester.dart b/lib/dualis/model/semester.dart index db30676b..d8e73449 100644 --- a/lib/dualis/model/semester.dart +++ b/lib/dualis/model/semester.dart @@ -4,7 +4,7 @@ class Semester { final String? name; final List modules; - Semester( + const Semester( this.name, this.modules, ); diff --git a/lib/dualis/model/study_grades.dart b/lib/dualis/model/study_grades.dart index e5b25ab4..83caee79 100644 --- a/lib/dualis/model/study_grades.dart +++ b/lib/dualis/model/study_grades.dart @@ -4,7 +4,7 @@ class StudyGrades { final double? creditsTotal; final double? creditsGained; - StudyGrades( + const StudyGrades( this.gpaTotal, this.gpaMainModules, this.creditsTotal, diff --git a/lib/dualis/service/dualis_authentication.dart b/lib/dualis/service/dualis_authentication.dart index c1697443..4291f2d9 100644 --- a/lib/dualis/service/dualis_authentication.dart +++ b/lib/dualis/service/dualis_authentication.dart @@ -15,6 +15,8 @@ import 'package:http/http.dart'; /// with the username and password and then use the [authenticatedGet] method. /// class DualisAuthentication { + DualisAuthentication(); + final RegExp _tokenRegex = RegExp("ARGUMENTS=-N([0-9]{15})"); Credentials? _credentials; @@ -51,7 +53,7 @@ class DualisAuthentication { // TODO: Test for login failed page - final redirectUrl = LoginRedirectUrlExtract().getUrlFromHeader( + final redirectUrl = const LoginRedirectUrlExtract().getUrlFromHeader( loginResponse.headers['refresh'], dualisEndpoint, ); @@ -66,7 +68,7 @@ class DualisAuthentication { cancellationToken, ); - dualisUrls.mainPageUrl = LoginRedirectUrlExtract().readRedirectUrl( + dualisUrls.mainPageUrl = const LoginRedirectUrlExtract().readRedirectUrl( redirectPage, dualisEndpoint, ); @@ -83,7 +85,7 @@ class DualisAuthentication { cancellationToken, ); - UrlsFromMainPageExtract().parseMainPage( + const UrlsFromMainPageExtract().parseMainPage( mainPage, dualisUrls, dualisEndpoint, @@ -145,8 +147,8 @@ class DualisAuthentication { cancellationToken?.throwIfCancelled(); - if (!TimeoutExtract().isTimeoutErrorPage(result) && - !AccessDeniedExtract().isAccessDeniedPage(result)) { + if (!const TimeoutExtract().isTimeoutErrorPage(result) && + !const AccessDeniedExtract().isAccessDeniedPage(result)) { return result; } diff --git a/lib/dualis/service/dualis_scraper.dart b/lib/dualis/service/dualis_scraper.dart index dcd2ff83..44bc4629 100644 --- a/lib/dualis/service/dualis_scraper.dart +++ b/lib/dualis/service/dualis_scraper.dart @@ -29,7 +29,7 @@ class DualisScraper { cancellationToken, ); - return AllModulesExtract().extractAllModules(allModulesPageResponse); + return const AllModulesExtract().extractAllModules(allModulesPageResponse); } Future> loadModuleExams( @@ -41,7 +41,7 @@ class DualisScraper { cancellationToken, ); - return ExamsFromModuleDetailsExtract().extractExamsFromModuleDetails( + return const ExamsFromModuleDetailsExtract().extractExamsFromModuleDetails( detailsResponse, ); } @@ -54,7 +54,7 @@ class DualisScraper { cancellationToken, ); - final semesters = SemestersFromCourseResultPageExtract() + final semesters = const SemestersFromCourseResultPageExtract() .extractSemestersFromCourseResults( courseResultsResponse, dualisEndpoint, @@ -89,7 +89,7 @@ class DualisScraper { cancellationToken, ); - return StudyGradesFromStudentResultsPageExtract() + return const StudyGradesFromStudentResultsPageExtract() .extractStudyGradesFromStudentsResultsPage(studentsResultsPage); } @@ -106,7 +106,7 @@ class DualisScraper { ); final schedule = - MonthlyScheduleExtract().extractScheduleFromMonthly(result); + const MonthlyScheduleExtract().extractScheduleFromMonthly(result); schedule.urls.add(dualisEndpoint); diff --git a/lib/dualis/service/dualis_service.dart b/lib/dualis/service/dualis_service.dart index 22311637..fdc6a11d 100644 --- a/lib/dualis/service/dualis_service.dart +++ b/lib/dualis/service/dualis_service.dart @@ -7,6 +7,8 @@ import 'package:dhbwstudentapp/dualis/model/study_grades.dart'; import 'package:dhbwstudentapp/dualis/service/dualis_scraper.dart'; abstract class DualisService { + const DualisService(); + Future login( Credentials credentials, [ CancellationToken? cancellationToken, @@ -44,7 +46,7 @@ enum LoginResult { class DualisServiceImpl extends DualisService { final DualisScraper _dualisScraper; - DualisServiceImpl(this._dualisScraper); + const DualisServiceImpl(this._dualisScraper); @override Future login( diff --git a/lib/dualis/service/dualis_website_model.dart b/lib/dualis/service/dualis_website_model.dart index dc234e45..a3d076c1 100644 --- a/lib/dualis/service/dualis_website_model.dart +++ b/lib/dualis/service/dualis_website_model.dart @@ -14,6 +14,8 @@ class DualisUrls { String? mainPageUrl; String? monthlyScheduleUrl; + DualisUrls(); + Map semesterCourseResultUrls = {}; } @@ -22,7 +24,7 @@ class DualisSemester { final String? semesterCourseResultsUrl; final List modules; - DualisSemester( + const DualisSemester( this.semesterName, this.semesterCourseResultsUrl, this.modules, @@ -37,7 +39,7 @@ class DualisModule { final String? detailsUrl; final ExamState? state; - DualisModule( + const DualisModule( this.id, this.name, this.finalGrade, @@ -54,7 +56,7 @@ class DualisExam { final ExamGrade grade; final String? semester; - DualisExam( + const DualisExam( this.name, this.moduleName, this.grade, diff --git a/lib/dualis/service/fake_data_dualis_scraper.dart b/lib/dualis/service/fake_data_dualis_scraper.dart index 27466fca..93291d68 100644 --- a/lib/dualis/service/fake_data_dualis_scraper.dart +++ b/lib/dualis/service/fake_data_dualis_scraper.dart @@ -14,6 +14,8 @@ import 'package:dhbwstudentapp/schedule/model/schedule.dart'; class FakeDataDualisScraper implements DualisScraper { bool _isLoggedIn = false; + FakeDataDualisScraper(); + @override bool isLoggedIn() { return _isLoggedIn; @@ -26,7 +28,7 @@ class FakeDataDualisScraper implements DualisScraper { await Future.delayed(const Duration(milliseconds: 200)); return Future.value([ - DualisModule( + const DualisModule( "Module1", "Informatik", "1.0", @@ -70,7 +72,7 @@ class FakeDataDualisScraper implements DualisScraper { ]) async { await Future.delayed(const Duration(milliseconds: 200)); return Future.value([ - DualisModule( + const DualisModule( "Module1", "Informatik", "1.0", @@ -86,7 +88,7 @@ class FakeDataDualisScraper implements DualisScraper { CancellationToken? cancellationToken, ]) async { await Future.delayed(const Duration(milliseconds: 200)); - return Future.value([DualisSemester("SoSe2020", "", [])]); + return Future.value([const DualisSemester("SoSe2020", "", [])]); } @override @@ -95,7 +97,7 @@ class FakeDataDualisScraper implements DualisScraper { ) async { await Future.delayed(const Duration(milliseconds: 200)); return Future.value( - StudyGrades( + const StudyGrades( 1.5, 1.5, 210, diff --git a/lib/dualis/service/parsing/access_denied_extract.dart b/lib/dualis/service/parsing/access_denied_extract.dart index d61f47a8..1c2cd464 100644 --- a/lib/dualis/service/parsing/access_denied_extract.dart +++ b/lib/dualis/service/parsing/access_denied_extract.dart @@ -1,4 +1,6 @@ class AccessDeniedExtract { + const AccessDeniedExtract(); + bool isAccessDeniedPage(String body) { return body.contains("Zugang verweigert"); } diff --git a/lib/dualis/service/parsing/all_modules_extract.dart b/lib/dualis/service/parsing/all_modules_extract.dart index 2196b904..bb5baa4d 100644 --- a/lib/dualis/service/parsing/all_modules_extract.dart +++ b/lib/dualis/service/parsing/all_modules_extract.dart @@ -5,6 +5,8 @@ import 'package:html/dom.dart'; import 'package:html/parser.dart'; class AllModulesExtract { + const AllModulesExtract(); + List extractAllModules(String? body) { try { return _extractAllModules(body); diff --git a/lib/dualis/service/parsing/exams_from_module_details_extract.dart b/lib/dualis/service/parsing/exams_from_module_details_extract.dart index 5e4abb4f..689d73ab 100644 --- a/lib/dualis/service/parsing/exams_from_module_details_extract.dart +++ b/lib/dualis/service/parsing/exams_from_module_details_extract.dart @@ -4,6 +4,8 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:html/parser.dart'; class ExamsFromModuleDetailsExtract { + const ExamsFromModuleDetailsExtract(); + List extractExamsFromModuleDetails(String? body) { try { return _extractExamsFromModuleDetails(body); diff --git a/lib/dualis/service/parsing/login_redirect_url_extract.dart b/lib/dualis/service/parsing/login_redirect_url_extract.dart index 7d1d4811..823f2e8b 100644 --- a/lib/dualis/service/parsing/login_redirect_url_extract.dart +++ b/lib/dualis/service/parsing/login_redirect_url_extract.dart @@ -1,6 +1,8 @@ import 'package:html/parser.dart'; class LoginRedirectUrlExtract { + const LoginRedirectUrlExtract(); + String? readRedirectUrl(String? body, String redirectUrl) { final document = parse(body); diff --git a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart index 3a540183..106e70b3 100644 --- a/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/modules_from_course_result_page_extract.dart @@ -7,6 +7,8 @@ import 'package:html/parser.dart'; class ModulesFromCourseResultPageExtract { final RegExp _extractUrlRegex = RegExp('dl_popUp\\("(.+?)"'); + ModulesFromCourseResultPageExtract(); + List extractModulesFromCourseResultPage( String? body, String endpointUrl, diff --git a/lib/dualis/service/parsing/monthly_schedule_extract.dart b/lib/dualis/service/parsing/monthly_schedule_extract.dart index 4b17151b..1d18577f 100644 --- a/lib/dualis/service/parsing/monthly_schedule_extract.dart +++ b/lib/dualis/service/parsing/monthly_schedule_extract.dart @@ -6,6 +6,8 @@ import 'package:html/parser.dart'; import 'package:intl/intl.dart'; class MonthlyScheduleExtract { + const MonthlyScheduleExtract(); + Schedule extractScheduleFromMonthly(String? body) { try { return _extractScheduleFromMonthly(body); @@ -36,9 +38,9 @@ class MonthlyScheduleExtract { } ScheduleEntry _extractEntry(Element appointment) { - final date = appointment.parent!.parent! - .querySelector(".tbsubhead a")! - .attributes["title"]; + final date = appointment.parent?.parent + ?.querySelector(".tbsubhead a") + ?.attributes["title"]; final information = appointment.attributes["title"]!; final informationParts = information.split(" / "); diff --git a/lib/dualis/service/parsing/parsing_utils.dart b/lib/dualis/service/parsing/parsing_utils.dart index 9e4caa18..434d8e65 100644 --- a/lib/dualis/service/parsing/parsing_utils.dart +++ b/lib/dualis/service/parsing/parsing_utils.dart @@ -45,10 +45,10 @@ Element getElementById( } class ParseException implements Exception { - Object? innerException; - StackTrace? trace; + final Object? innerException; + final StackTrace? trace; - ParseException.withInner(this.innerException, this.trace); + const ParseException.withInner(this.innerException, this.trace); @override String toString() { diff --git a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart index 278d4e24..36be55a6 100644 --- a/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart +++ b/lib/dualis/service/parsing/semesters_from_course_result_page_extract.dart @@ -4,6 +4,8 @@ import 'package:html/dom.dart'; import 'package:html/parser.dart'; class SemestersFromCourseResultPageExtract { + const SemestersFromCourseResultPageExtract(); + List extractSemestersFromCourseResults( String? body, String endpointUrl, diff --git a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart index 0da8da5d..632092cd 100644 --- a/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart +++ b/lib/dualis/service/parsing/study_grades_from_student_results_page_extract.dart @@ -4,6 +4,8 @@ import 'package:html/dom.dart'; import 'package:html/parser.dart'; class StudyGradesFromStudentResultsPageExtract { + const StudyGradesFromStudentResultsPageExtract(); + StudyGrades extractStudyGradesFromStudentsResultsPage(String? body) { try { return _extractStudyGradesFromStudentsResultsPage(body); @@ -51,9 +53,10 @@ class StudyGradesFromStudentResultsPageExtract { neededCredits = neededCredits.replaceAll(",", "."); gainedCredits = gainedCredits.replaceAll(",", "."); - final credits = _Credits(); - credits.gainedCredits = double.tryParse(gainedCredits); - credits.totalCredits = double.tryParse(neededCredits); + final credits = _Credits( + double.tryParse(neededCredits), + double.tryParse(gainedCredits), + ); return credits; } @@ -73,20 +76,31 @@ class StudyGradesFromStudentResultsPageExtract { mainCoursesGpaRowCells[1].innerHtml, )!; - final _Gpa gpa = _Gpa(); - gpa.totalGpa = double.tryParse(totalGpa.replaceAll(",", ".")); - gpa.mainModulesGpa = double.tryParse(mainModulesGpa.replaceAll(",", ".")); + final _Gpa gpa = _Gpa( + double.tryParse(totalGpa.replaceAll(",", ".")), + double.tryParse(mainModulesGpa.replaceAll(",", ".")), + ); return gpa; } } class _Credits { - double? totalCredits; - double? gainedCredits; + final double? totalCredits; + final double? gainedCredits; + + const _Credits( + this.totalCredits, + this.gainedCredits, + ); } class _Gpa { - double? totalGpa; - double? mainModulesGpa; + final double? totalGpa; + final double? mainModulesGpa; + + const _Gpa( + this.totalGpa, + this.mainModulesGpa, + ); } diff --git a/lib/dualis/service/parsing/timeout_extract.dart b/lib/dualis/service/parsing/timeout_extract.dart index d63ad874..a565aebe 100644 --- a/lib/dualis/service/parsing/timeout_extract.dart +++ b/lib/dualis/service/parsing/timeout_extract.dart @@ -1,4 +1,6 @@ class TimeoutExtract { + const TimeoutExtract(); + bool isTimeoutErrorPage(String body) { return body.contains("Timeout!") && body.contains("Bitte melden Sie sich erneut"); diff --git a/lib/dualis/service/parsing/urls_from_main_page_extract.dart b/lib/dualis/service/parsing/urls_from_main_page_extract.dart index 9dad754f..94185cf1 100644 --- a/lib/dualis/service/parsing/urls_from_main_page_extract.dart +++ b/lib/dualis/service/parsing/urls_from_main_page_extract.dart @@ -3,6 +3,8 @@ import 'package:dhbwstudentapp/dualis/service/parsing/parsing_utils.dart'; import 'package:html/parser.dart'; class UrlsFromMainPageExtract { + const UrlsFromMainPageExtract(); + void parseMainPage( String? body, DualisUrls dualsUrls, diff --git a/lib/dualis/service/session.dart b/lib/dualis/service/session.dart index a60f2e89..e533a493 100644 --- a/lib/dualis/service/session.dart +++ b/lib/dualis/service/session.dart @@ -13,7 +13,9 @@ import 'package:http_client_helper/http_client_helper.dart' as http; /// provided get and set methods. /// class Session { - Map _cookies = {}; + final Map _cookies = {}; + + Session(); /// /// Execute a GET request and return the result body as string @@ -54,7 +56,7 @@ class Session { ); if (response == null && !requestCancellationToken.isCanceled) { - throw ServiceRequestFailed("Http request failed!"); + throw const ServiceRequestFailed("Http request failed!"); } _updateCookie(response!); @@ -112,7 +114,7 @@ class Session { ); if (response == null && !requestCancellationToken.isCanceled) { - throw ServiceRequestFailed("Http request failed!"); + throw const ServiceRequestFailed("Http request failed!"); } _updateCookie(response!); diff --git a/lib/dualis/ui/dualis_navigation_entry.dart b/lib/dualis/ui/dualis_navigation_entry.dart index 1435aef5..56482fc5 100644 --- a/lib/dualis/ui/dualis_navigation_entry.dart +++ b/lib/dualis/ui/dualis_navigation_entry.dart @@ -9,6 +9,8 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class DualisNavigationEntry extends NavigationEntry { + DualisNavigationEntry(); + @override Icon icon = const Icon(Icons.data_usage); @@ -27,7 +29,7 @@ class DualisNavigationEntry extends NavigationEntry { @override Widget build(BuildContext context) { - return DualisPage(); + return const DualisPage(); } @override @@ -42,7 +44,7 @@ class DualisNavigationEntry extends NavigationEntry { ? IconButton( icon: const Icon(Icons.help_outline), onPressed: () async { - await DualisHelpDialog().show(context); + await const DualisHelpDialog().show(context); }, tooltip: L.of(context).helpButtonTooltip, ) diff --git a/lib/dualis/ui/dualis_page.dart b/lib/dualis/ui/dualis_page.dart index a5ddbf59..1d37e2e7 100644 --- a/lib/dualis/ui/dualis_page.dart +++ b/lib/dualis/ui/dualis_page.dart @@ -9,6 +9,8 @@ import 'package:property_change_notifier/property_change_notifier.dart'; import 'package:provider/provider.dart'; class DualisPage extends StatelessWidget { + const DualisPage({super.key}); + @override Widget build(BuildContext context) { final StudyGradesViewModel viewModel = @@ -17,7 +19,7 @@ class DualisPage extends StatelessWidget { Widget widget; if (viewModel.loginState != LoginState.LoggedIn) { - widget = DualisLoginPage(); + widget = const DualisLoginPage(); } else { widget = PropertyChangeProvider( value: viewModel, @@ -27,12 +29,12 @@ class DualisPage extends StatelessWidget { PageDefinition( text: L.of(context).pageDualisOverview, icon: const Icon(Icons.dashboard), - builder: (BuildContext context) => StudyOverviewPage(), + builder: (BuildContext context) => const StudyOverviewPage(), ), PageDefinition( text: L.of(context).pageDualisExams, icon: const Icon(Icons.book), - builder: (BuildContext context) => ExamResultsPage(), + builder: (BuildContext context) => const ExamResultsPage(), ), ], ), diff --git a/lib/dualis/ui/exam_results_page/exam_results_page.dart b/lib/dualis/ui/exam_results_page/exam_results_page.dart index 1281b9dd..f5a73130 100644 --- a/lib/dualis/ui/exam_results_page/exam_results_page.dart +++ b/lib/dualis/ui/exam_results_page/exam_results_page.dart @@ -7,6 +7,8 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class ExamResultsPage extends StatelessWidget { + const ExamResultsPage({super.key}); + @override Widget build(BuildContext context) { return SizedBox( @@ -63,8 +65,8 @@ class ExamResultsPage extends StatelessWidget { StudyGradesViewModel? model, Set? properties, ) => - model!.currentSemester != null - ? buildModulesColumn(context, model) + model?.currentSemester != null + ? buildModulesColumn(context, model!) : const Padding( padding: EdgeInsets.fromLTRB(0, 16, 0, 0), child: Center(child: CircularProgressIndicator()), @@ -105,23 +107,26 @@ class ExamResultsPage extends StatelessWidget { ) { final dataTables = []; - var isFirstModule = true; - for (final module in viewModel.currentSemester!.modules) { - dataTables.add( - DataTable( - horizontalMargin: 24, - columnSpacing: 0, - dataRowHeight: 45, - headingRowHeight: 65, - rows: buildModuleDataRows(context, module), - columns: buildModuleColumns( - context, - module, - displayGradeHeader: isFirstModule, + final modules = viewModel.currentSemester?.modules; + if (modules != null) { + var isFirstModule = true; + for (final module in modules) { + dataTables.add( + DataTable( + horizontalMargin: 24, + columnSpacing: 0, + dataRowHeight: 45, + headingRowHeight: 65, + rows: buildModuleDataRows(context, module), + columns: buildModuleColumns( + context, + module, + displayGradeHeader: isFirstModule, + ), ), - ), - ); - isFirstModule = false; + ); + isFirstModule = false; + } } return dataTables; } diff --git a/lib/dualis/ui/login/dualis_login_page.dart b/lib/dualis/ui/login/dualis_login_page.dart index 3d684232..142cade3 100644 --- a/lib/dualis/ui/login/dualis_login_page.dart +++ b/lib/dualis/ui/login/dualis_login_page.dart @@ -5,14 +5,13 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class DualisLoginPage extends StatelessWidget { + const DualisLoginPage({super.key}); + @override Widget build(BuildContext context) { - final StudyGradesViewModel viewModel = + final StudyGradesViewModel model = Provider.of(context); - return buildLoginPage(context, viewModel); - } - Widget buildLoginPage(BuildContext context, StudyGradesViewModel model) { return SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/dualis/ui/study_overview/study_overview_page.dart b/lib/dualis/ui/study_overview/study_overview_page.dart index 679aa187..e68c14c0 100644 --- a/lib/dualis/ui/study_overview/study_overview_page.dart +++ b/lib/dualis/ui/study_overview/study_overview_page.dart @@ -5,6 +5,8 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class StudyOverviewPage extends StatelessWidget { + const StudyOverviewPage({super.key}); + @override Widget build(BuildContext context) { return SizedBox( @@ -40,7 +42,7 @@ class StudyOverviewPage extends StatelessWidget { StudyGradesViewModel? model, Set? properties, ) => - model!.studyGrades != null + model?.studyGrades != null ? Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ @@ -51,7 +53,7 @@ class StudyOverviewPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.baseline, children: [ Text( - model.studyGrades!.gpaTotal.toString(), + model!.studyGrades!.gpaTotal.toString(), style: Theme.of(context).textTheme.headline3, ), Padding( @@ -129,8 +131,8 @@ class StudyOverviewPage extends StatelessWidget { StudyGradesViewModel? model, Set? properties, ) => - model!.allModules != null - ? buildModulesDataTable(context, model) + model?.allModules != null + ? buildModulesDataTable(context, model!) : buildProgressIndicator(), ), ], diff --git a/lib/dualis/ui/widgets/dualis_help_dialog.dart b/lib/dualis/ui/widgets/dualis_help_dialog.dart index 30b39c0e..489d8743 100644 --- a/lib/dualis/ui/widgets/dualis_help_dialog.dart +++ b/lib/dualis/ui/widgets/dualis_help_dialog.dart @@ -3,6 +3,8 @@ import 'package:dhbwstudentapp/common/ui/widgets/help_dialog.dart'; import 'package:flutter/material.dart'; class DualisHelpDialog extends HelpDialog { + const DualisHelpDialog(); + @override String content(BuildContext context) { return L.of(context).dualisHelpDialogContent; diff --git a/lib/dualis/ui/widgets/grade_state_icon.dart b/lib/dualis/ui/widgets/grade_state_icon.dart index 5984b6e4..31729e6d 100644 --- a/lib/dualis/ui/widgets/grade_state_icon.dart +++ b/lib/dualis/ui/widgets/grade_state_icon.dart @@ -4,10 +4,7 @@ import 'package:flutter/material.dart'; class GradeStateIcon extends StatelessWidget { final ExamState? state; - const GradeStateIcon({ - Key? key, - required this.state, - }) : super(key: key); + const GradeStateIcon({super.key, required this.state}); @override Widget build(BuildContext context) { diff --git a/lib/dualis/ui/widgets/login_form_widget.dart b/lib/dualis/ui/widgets/login_form_widget.dart index 0beb44a7..1ebaca9d 100644 --- a/lib/dualis/ui/widgets/login_form_widget.dart +++ b/lib/dualis/ui/widgets/login_form_widget.dart @@ -19,7 +19,7 @@ class LoginForm extends StatefulWidget { final String loginFailedText; const LoginForm({ - Key? key, + super.key, required this.onLogin, required this.title, required this.loginFailedText, @@ -27,7 +27,7 @@ class LoginForm extends StatefulWidget { required this.onSaveCredentials, required this.onClearCredentials, required this.getDoSaveCredentials, - }) : super(key: key); + }); @override _LoginFormState createState() => _LoginFormState(); @@ -41,6 +41,8 @@ class _LoginFormState extends State { final CredentialsEditingController _controller = CredentialsEditingController(); + _LoginFormState(); + @override void initState() { super.initState(); diff --git a/lib/information/ui/useful_information_navigation_entry.dart b/lib/information/ui/useful_information_navigation_entry.dart index 2b05e8b8..d308c6bc 100644 --- a/lib/information/ui/useful_information_navigation_entry.dart +++ b/lib/information/ui/useful_information_navigation_entry.dart @@ -5,9 +5,11 @@ import 'package:dhbwstudentapp/ui/navigation/navigation_entry.dart'; import 'package:flutter/material.dart'; class UsefulInformationNavigationEntry extends NavigationEntry { + UsefulInformationNavigationEntry(); + @override Widget build(BuildContext context) { - return UsefulInformationPage(); + return const UsefulInformationPage(); } @override diff --git a/lib/information/ui/usefulinformation/useful_information_page.dart b/lib/information/ui/usefulinformation/useful_information_page.dart index 61a61a5f..2fb49074 100644 --- a/lib/information/ui/usefulinformation/useful_information_page.dart +++ b/lib/information/ui/usefulinformation/useful_information_page.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; class UsefulInformationPage extends StatelessWidget { + const UsefulInformationPage({super.key}); + @override Widget build(BuildContext context) { return Scaffold( diff --git a/lib/native/widget/android_widget_helper.dart b/lib/native/widget/android_widget_helper.dart index 68ebf490..f58d734d 100644 --- a/lib/native/widget/android_widget_helper.dart +++ b/lib/native/widget/android_widget_helper.dart @@ -6,6 +6,7 @@ import 'package:flutter/services.dart'; /// class AndroidWidgetHelper implements WidgetHelper { static const platform = MethodChannel('de.bennik2000.dhbwstudentapp/widget'); + const AndroidWidgetHelper(); @override Future disableWidget() async { diff --git a/lib/native/widget/ios_widget_helper.dart b/lib/native/widget/ios_widget_helper.dart index d9a55ab7..c495d12c 100644 --- a/lib/native/widget/ios_widget_helper.dart +++ b/lib/native/widget/ios_widget_helper.dart @@ -8,6 +8,8 @@ import 'package:flutter_widgetkit/flutter_widgetkit.dart'; class IOSWidgetHelper implements WidgetHelper { static const platform = MethodChannel('de.bennik2000.dhbwstudentapp/widget'); + const IOSWidgetHelper(); + @override Future disableWidget() async { try { diff --git a/lib/native/widget/widget_helper.dart b/lib/native/widget/widget_helper.dart index e0f03028..ab972564 100644 --- a/lib/native/widget/widget_helper.dart +++ b/lib/native/widget/widget_helper.dart @@ -8,17 +8,15 @@ import 'package:dhbwstudentapp/native/widget/ios_widget_helper.dart'; /// methods to enable/disable or update the widget /// class WidgetHelper { - static WidgetHelper? _instance; + static late WidgetHelper _instance; WidgetHelper() { - if (_instance != null) return; - if (Platform.isAndroid) { - _instance = AndroidWidgetHelper(); + _instance = const AndroidWidgetHelper(); } else if (Platform.isIOS) { - _instance = IOSWidgetHelper(); + _instance = const IOSWidgetHelper(); } else { - _instance = VoidWidgetHelper(); + _instance = const VoidWidgetHelper(); } } @@ -27,14 +25,14 @@ class WidgetHelper { /// scheduled and will happen soon. /// Future requestWidgetRefresh() { - return _instance!.requestWidgetRefresh(); + return _instance.requestWidgetRefresh(); } /// /// Checks if widgets are supported by the device /// Future areWidgetsSupported() { - return _instance!.areWidgetsSupported(); + return _instance.areWidgetsSupported(); } /// @@ -42,7 +40,7 @@ class WidgetHelper { /// its full functionality. /// Future enableWidget() { - return _instance!.enableWidget(); + return _instance.enableWidget(); } /// @@ -50,7 +48,7 @@ class WidgetHelper { /// only provide placeholder content or limited functionality. /// Future disableWidget() { - return _instance!.disableWidget(); + return _instance.disableWidget(); } } @@ -58,6 +56,8 @@ class WidgetHelper { /// Implementation of the WidgetHelper which does nothing /// class VoidWidgetHelper implements WidgetHelper { + const VoidWidgetHelper(); + @override Future disableWidget() { return Future.value(); diff --git a/lib/native/widget/widget_update_callback.dart b/lib/native/widget/widget_update_callback.dart index 17324ae7..7fb14f42 100644 --- a/lib/native/widget/widget_update_callback.dart +++ b/lib/native/widget/widget_update_callback.dart @@ -9,7 +9,7 @@ import 'package:dhbwstudentapp/schedule/model/schedule.dart'; class WidgetUpdateCallback { final WidgetHelper _widgetHelper; - WidgetUpdateCallback(this._widgetHelper); + const WidgetUpdateCallback(this._widgetHelper); void registerCallback(ScheduleProvider provider) { provider.addScheduleUpdatedCallback(_callback); diff --git a/lib/schedule/background/background_schedule_update.dart b/lib/schedule/background/background_schedule_update.dart index bf7a9f6f..e58ce7e9 100644 --- a/lib/schedule/background/background_schedule_update.dart +++ b/lib/schedule/background/background_schedule_update.dart @@ -10,7 +10,7 @@ class BackgroundScheduleUpdate extends TaskCallback { final ScheduleSourceProvider scheduleSource; final WorkSchedulerService scheduler; - BackgroundScheduleUpdate( + const BackgroundScheduleUpdate( this.scheduleProvider, this.scheduleSource, this.scheduler, diff --git a/lib/schedule/background/calendar_synchronizer.dart b/lib/schedule/background/calendar_synchronizer.dart index 6d04fe49..1bc0477a 100644 --- a/lib/schedule/background/calendar_synchronizer.dart +++ b/lib/schedule/background/calendar_synchronizer.dart @@ -12,7 +12,7 @@ class CalendarSynchronizer { final ScheduleSourceProvider scheduleSourceProvider; final PreferencesProvider preferencesProvider; - CalendarSynchronizer( + const CalendarSynchronizer( this.scheduleProvider, this.scheduleSourceProvider, this.preferencesProvider, diff --git a/lib/schedule/business/schedule_diff_calculator.dart b/lib/schedule/business/schedule_diff_calculator.dart index 80e87cf0..c8e1750d 100644 --- a/lib/schedule/business/schedule_diff_calculator.dart +++ b/lib/schedule/business/schedule_diff_calculator.dart @@ -2,6 +2,8 @@ import 'package:dhbwstudentapp/schedule/model/schedule.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class ScheduleDiffCalculator { + const ScheduleDiffCalculator(); + ScheduleDiff calculateDiff( Schedule oldSchedule, Schedule newSchedule, @@ -174,7 +176,7 @@ class ScheduleDiff { final List removedEntries; final List updatedEntries; - ScheduleDiff({ + const ScheduleDiff({ required this.addedEntries, required this.removedEntries, required this.updatedEntries, @@ -191,5 +193,5 @@ class UpdatedEntry { final ScheduleEntry entry; final List properties; - UpdatedEntry(this.entry, this.properties); + const UpdatedEntry(this.entry, this.properties); } diff --git a/lib/schedule/business/schedule_filter.dart b/lib/schedule/business/schedule_filter.dart index 286a03f9..3cd31f32 100644 --- a/lib/schedule/business/schedule_filter.dart +++ b/lib/schedule/business/schedule_filter.dart @@ -5,7 +5,7 @@ import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class ScheduleFilter { final ScheduleFilterRepository _scheduleFilterRepository; - ScheduleFilter(this._scheduleFilterRepository); + const ScheduleFilter(this._scheduleFilterRepository); Future filter(Schedule original) async { final allHiddenNames = diff --git a/lib/schedule/business/schedule_provider.dart b/lib/schedule/business/schedule_provider.dart index d15e1bc5..32345a35 100644 --- a/lib/schedule/business/schedule_provider.dart +++ b/lib/schedule/business/schedule_provider.dart @@ -28,12 +28,11 @@ class ScheduleProvider { final PreferencesProvider _preferencesProvider; final ScheduleSourceProvider _scheduleSource; final ScheduleEntryRepository _scheduleEntryRepository; - final ScheduleFilterRepository _scheduleFilterRepository; final ScheduleQueryInformationRepository _scheduleQueryInformationRepository; final List _scheduleUpdatedCallbacks = []; - late ScheduleFilter _scheduleFilter; + final ScheduleFilter _scheduleFilter; final List _scheduleEntryChangedCallbacks = []; @@ -43,10 +42,8 @@ class ScheduleProvider { this._scheduleEntryRepository, this._scheduleQueryInformationRepository, this._preferencesProvider, - this._scheduleFilterRepository, - ) { - _scheduleFilter = ScheduleFilter(_scheduleFilterRepository); - } + ScheduleFilterRepository scheduleFilterRepository, + ) : _scheduleFilter = ScheduleFilter(scheduleFilterRepository); Future getCachedSchedule(DateTime start, DateTime end) async { var cachedSchedule = @@ -121,8 +118,8 @@ class ScheduleProvider { final oldSchedule = await _scheduleEntryRepository.queryScheduleBetweenDates(start, end); - final diff = - ScheduleDiffCalculator().calculateDiff(oldSchedule, updatedSchedule); + final diff = const ScheduleDiffCalculator() + .calculateDiff(oldSchedule, updatedSchedule); final cleanedDiff = await _cleanDiffFromNewlyQueriedEntries(start, end, diff); diff --git a/lib/schedule/business/schedule_source_provider.dart b/lib/schedule/business/schedule_source_provider.dart index 996b2312..fefc72ed 100644 --- a/lib/schedule/business/schedule_source_provider.dart +++ b/lib/schedule/business/schedule_source_provider.dart @@ -29,7 +29,7 @@ class ScheduleSourceProvider { final ScheduleEntryRepository _scheduleEntryRepository; final ScheduleQueryInformationRepository _scheduleQueryInformationRepository; - ScheduleSource _currentScheduleSource = InvalidScheduleSource(); + ScheduleSource _currentScheduleSource = const InvalidScheduleSource(); ScheduleSource get currentScheduleSource => _currentScheduleSource; @@ -46,7 +46,7 @@ class ScheduleSourceProvider { Future setupScheduleSource() async { final scheduleSourceType = await _getScheduleSourceType(); - ScheduleSource scheduleSource = InvalidScheduleSource(); + ScheduleSource scheduleSource = const InvalidScheduleSource(); final initializer = { ScheduleSourceType.Dualis: () async => _dualisScheduleSource(), @@ -84,7 +84,7 @@ class ScheduleSourceProvider { DualisScheduleSource(KiwiContainer().resolve(), credentials); return ErrorReportScheduleSourceDecorator(dualis); } else { - return InvalidScheduleSource(); + return const InvalidScheduleSource(); } } @@ -104,7 +104,7 @@ class ScheduleSourceProvider { return source; } - return InvalidScheduleSource(); + return const InvalidScheduleSource(); } Future _icalScheduleSource() async { @@ -123,7 +123,7 @@ class ScheduleSourceProvider { } } - return InvalidScheduleSource(); + return const InvalidScheduleSource(); } Future setupForRapla(String? url) async { diff --git a/lib/schedule/data/schedule_entry_repository.dart b/lib/schedule/data/schedule_entry_repository.dart index 039f260d..321b0886 100644 --- a/lib/schedule/data/schedule_entry_repository.dart +++ b/lib/schedule/data/schedule_entry_repository.dart @@ -5,7 +5,7 @@ import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class ScheduleEntryRepository { final DatabaseAccess _database; - ScheduleEntryRepository(this._database); + const ScheduleEntryRepository(this._database); Future queryScheduleForDay(DateTime date) async { return queryScheduleBetweenDates(date, date.add(const Duration(days: 1))); diff --git a/lib/schedule/data/schedule_filter_repository.dart b/lib/schedule/data/schedule_filter_repository.dart index 1ef9e7c3..2aa5c4cb 100644 --- a/lib/schedule/data/schedule_filter_repository.dart +++ b/lib/schedule/data/schedule_filter_repository.dart @@ -3,7 +3,7 @@ import 'package:dhbwstudentapp/common/data/database_access.dart'; class ScheduleFilterRepository { final DatabaseAccess _database; - ScheduleFilterRepository(this._database); + const ScheduleFilterRepository(this._database); Future> queryAllHiddenNames() async { final rows = await _database.queryRows("ScheduleEntryFilters"); diff --git a/lib/schedule/data/schedule_query_information_repository.dart b/lib/schedule/data/schedule_query_information_repository.dart index c76df96d..64d5b716 100644 --- a/lib/schedule/data/schedule_query_information_repository.dart +++ b/lib/schedule/data/schedule_query_information_repository.dart @@ -4,7 +4,7 @@ import 'package:dhbwstudentapp/schedule/model/schedule_query_information.dart'; class ScheduleQueryInformationRepository { final DatabaseAccess _database; - ScheduleQueryInformationRepository(this._database); + const ScheduleQueryInformationRepository(this._database); Future getOldestQueryTimeBetweenDates( DateTime start, diff --git a/lib/schedule/model/schedule_query_result.dart b/lib/schedule/model/schedule_query_result.dart index 421807bc..4b34b5f8 100644 --- a/lib/schedule/model/schedule_query_result.dart +++ b/lib/schedule/model/schedule_query_result.dart @@ -6,7 +6,7 @@ class ScheduleQueryResult { bool get hasError => errors.isNotEmpty; - ScheduleQueryResult(this.schedule, this.errors); + const ScheduleQueryResult(this.schedule, this.errors); } class ParseError { diff --git a/lib/schedule/service/error_report_schedule_source_decorator.dart b/lib/schedule/service/error_report_schedule_source_decorator.dart index 24739d2a..3f5e785f 100644 --- a/lib/schedule/service/error_report_schedule_source_decorator.dart +++ b/lib/schedule/service/error_report_schedule_source_decorator.dart @@ -6,7 +6,7 @@ import 'package:dhbwstudentapp/schedule/service/schedule_source.dart'; class ErrorReportScheduleSourceDecorator extends ScheduleSource { final ScheduleSource _scheduleSource; - ErrorReportScheduleSourceDecorator(this._scheduleSource); + const ErrorReportScheduleSourceDecorator(this._scheduleSource); @override Future querySchedule( diff --git a/lib/schedule/service/ical/ical_parser.dart b/lib/schedule/service/ical/ical_parser.dart index 48fb90e0..f60dd84b 100644 --- a/lib/schedule/service/ical/ical_parser.dart +++ b/lib/schedule/service/ical/ical_parser.dart @@ -6,6 +6,8 @@ import 'package:dhbwstudentapp/schedule/model/schedule_query_result.dart'; /// Parses an ICAL file extracts all schedule entries /// class IcalParser { + IcalParser(); + /// Matches a calendar entry. The first group contains the text between /// the BEGIN:VEVENT and END:VEVENT final String calendarEntryRegex = "BEGIN:VEVENT(.*?)END:VEVENT"; diff --git a/lib/schedule/service/ical/ical_schedule_source.dart b/lib/schedule/service/ical/ical_schedule_source.dart index 6242a8cb..0f7cd4bb 100644 --- a/lib/schedule/service/ical/ical_schedule_source.dart +++ b/lib/schedule/service/ical/ical_schedule_source.dart @@ -60,7 +60,7 @@ class IcalScheduleSource extends ScheduleSource { ); if (response == null && !requestCancellationToken.isCanceled) { - throw ServiceRequestFailed("Http request failed!"); + throw const ServiceRequestFailed("Http request failed!"); } return response; diff --git a/lib/schedule/service/invalid_schedule_source.dart b/lib/schedule/service/invalid_schedule_source.dart index 7f55936b..8a15ce5b 100644 --- a/lib/schedule/service/invalid_schedule_source.dart +++ b/lib/schedule/service/invalid_schedule_source.dart @@ -3,6 +3,8 @@ import 'package:dhbwstudentapp/schedule/model/schedule_query_result.dart'; import 'package:dhbwstudentapp/schedule/service/schedule_source.dart'; class InvalidScheduleSource extends ScheduleSource { + const InvalidScheduleSource(); + @override Future querySchedule( DateTime? from, diff --git a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart index 779fe485..eb57d14c 100644 --- a/lib/schedule/service/mannheim/mannheim_course_response_parser.dart +++ b/lib/schedule/service/mannheim/mannheim_course_response_parser.dart @@ -3,6 +3,8 @@ import 'package:dhbwstudentapp/schedule/service/mannheim/mannheim_course_scraper import 'package:html/parser.dart'; class MannheimCourseResponseParser { + const MannheimCourseResponseParser(); + List parseCoursePage(String body) { final document = parse(body); diff --git a/lib/schedule/service/mannheim/mannheim_course_scraper.dart b/lib/schedule/service/mannheim/mannheim_course_scraper.dart index b463a118..7b24da9d 100644 --- a/lib/schedule/service/mannheim/mannheim_course_scraper.dart +++ b/lib/schedule/service/mannheim/mannheim_course_scraper.dart @@ -10,10 +10,12 @@ class Course { final String icalUrl; final String scheduleId; - Course(this.name, this.icalUrl, this.title, this.scheduleId); + const Course(this.name, this.icalUrl, this.title, this.scheduleId); } class MannheimCourseScraper { + const MannheimCourseScraper(); + Future> loadCourses([ CancellationToken? cancellationToken, ]) async { @@ -24,7 +26,8 @@ class MannheimCourseScraper { cancellationToken, ); - return MannheimCourseResponseParser().parseCoursePage(coursesPage.body); + return const MannheimCourseResponseParser() + .parseCoursePage(coursesPage.body); } Future _makeRequest( @@ -42,7 +45,7 @@ class MannheimCourseScraper { ); if (response == null && !requestCancellationToken.isCanceled) { - throw ServiceRequestFailed("Http request failed!"); + throw const ServiceRequestFailed("Http request failed!"); } return response!; @@ -51,7 +54,7 @@ class MannheimCourseScraper { throw OperationCancelledException(); } catch (ex) { if (!requestCancellationToken.isCanceled) rethrow; - throw ServiceRequestFailed("Http request failed!"); + throw const ServiceRequestFailed("Http request failed!"); } finally { cancellationToken.cancellationCallback = null; } diff --git a/lib/schedule/service/rapla/rapla_response_parser.dart b/lib/schedule/service/rapla/rapla_response_parser.dart index a8c6ac06..bf5cab4b 100644 --- a/lib/schedule/service/rapla/rapla_response_parser.dart +++ b/lib/schedule/service/rapla/rapla_response_parser.dart @@ -8,6 +8,8 @@ import 'package:html/parser.dart' show parse; /// Parsing implementation which parses the response of the rapla schedule source. /// class RaplaResponseParser { + RaplaResponseParser(); + ScheduleQueryResult parseSchedule(String responseBody) { final document = parse(responseBody); diff --git a/lib/schedule/service/rapla/rapla_schedule_source.dart b/lib/schedule/service/rapla/rapla_schedule_source.dart index 9b870fa2..f1abd688 100644 --- a/lib/schedule/service/rapla/rapla_schedule_source.dart +++ b/lib/schedule/service/rapla/rapla_schedule_source.dart @@ -156,7 +156,7 @@ class RaplaScheduleSource extends ScheduleSource { ); if (response == null && !requestCancellationToken.isCanceled) { - throw ServiceRequestFailed("Http request failed!"); + throw const ServiceRequestFailed("Http request failed!"); } return response; @@ -217,6 +217,7 @@ enum FailureReason { ParseError, } +// TODO: [Leptopoda] make enum class ScheduleOrFailure { final FailureReason reason; final Schedule? schedule; @@ -225,16 +226,16 @@ class ScheduleOrFailure { bool get success => reason == FailureReason.Success; - ScheduleOrFailure.success(this.schedule) + const ScheduleOrFailure.success(this.schedule) : reason = FailureReason.Success, exception = null, trace = null; - ScheduleOrFailure.failParseError(this.exception, this.trace) + const ScheduleOrFailure.failParseError(this.exception, this.trace) : reason = FailureReason.ParseError, schedule = null; - ScheduleOrFailure.failRequestError(this.exception, this.trace) + const ScheduleOrFailure.failRequestError(this.exception, this.trace) : reason = FailureReason.RequestError, schedule = null; } diff --git a/lib/schedule/service/schedule_prettifier.dart b/lib/schedule/service/schedule_prettifier.dart index 37cad3ed..75752cb7 100644 --- a/lib/schedule/service/schedule_prettifier.dart +++ b/lib/schedule/service/schedule_prettifier.dart @@ -2,6 +2,8 @@ import 'package:dhbwstudentapp/schedule/model/schedule.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; class SchedulePrettifier { + SchedulePrettifier(); + final RegExp onlinePrefixRegExp = RegExp(r'\(?online\)?([ -]*)', caseSensitive: false); final RegExp onlineSuffixRegExp = diff --git a/lib/schedule/service/schedule_source.dart b/lib/schedule/service/schedule_source.dart index f0109365..d09e33b9 100644 --- a/lib/schedule/service/schedule_source.dart +++ b/lib/schedule/service/schedule_source.dart @@ -2,6 +2,8 @@ import 'package:dhbwstudentapp/common/util/cancellation_token.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_query_result.dart'; abstract class ScheduleSource { + const ScheduleSource(); + /// /// Queries the schedule from the implemented service. The resulting schedule /// contains all entries between the `from` and `to` date. @@ -22,7 +24,7 @@ class ScheduleQueryFailedException implements Exception { final dynamic innerException; final StackTrace? trace; - ScheduleQueryFailedException(this.innerException, [this.trace]); + const ScheduleQueryFailedException(this.innerException, [this.trace]); @override String toString() { @@ -33,7 +35,7 @@ class ScheduleQueryFailedException implements Exception { class ServiceRequestFailed implements Exception { final String message; - ServiceRequestFailed(this.message); + const ServiceRequestFailed(this.message); @override String toString() { diff --git a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart index 0bbcb4c7..7f64a5e3 100644 --- a/lib/schedule/ui/dailyschedule/daily_schedule_page.dart +++ b/lib/schedule/ui/dailyschedule/daily_schedule_page.dart @@ -8,18 +8,12 @@ import 'package:intl/intl.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; import 'package:provider/provider.dart'; -class DailySchedulePage extends StatefulWidget { - const DailySchedulePage({Key? key}) : super(key: key); - @override - _DailySchedulePageState createState() => _DailySchedulePageState(); -} - -class _DailySchedulePageState extends State { - late DailyScheduleViewModel viewModel; +class DailySchedulePage extends StatelessWidget { + const DailySchedulePage({super.key}); @override Widget build(BuildContext context) { - viewModel = Provider.of(context); + final viewModel = Provider.of(context); final textTheme = Theme.of(context).textTheme; final dailyScheduleEntryTitle = @@ -84,7 +78,7 @@ class _DailySchedulePageState extends State { ) else Column( - children: buildEntryWidgets(), + children: buildEntryWidgets(viewModel), ) ], ), @@ -93,14 +87,14 @@ class _DailySchedulePageState extends State { ); } - List buildEntryWidgets() { + List buildEntryWidgets(DailyScheduleViewModel viewModel) { final entryWidgets = []; final now = DateTime.now(); var nowIndicatorInserted = false; for (final entry in viewModel.schedule.entries) { if (!nowIndicatorInserted && (entry.end.isAfter(now))) { - entryWidgets.add(CurrentTimeIndicatorWidget()); + entryWidgets.add(const CurrentTimeIndicatorWidget()); nowIndicatorInserted = true; } @@ -113,7 +107,9 @@ class _DailySchedulePageState extends State { ), ); } - if (!nowIndicatorInserted) entryWidgets.add(CurrentTimeIndicatorWidget()); + if (!nowIndicatorInserted) { + entryWidgets.add(const CurrentTimeIndicatorWidget()); + } return entryWidgets; } } diff --git a/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart b/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart index 25124812..74141dd7 100644 --- a/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/current_time_indicator_widget.dart @@ -2,6 +2,8 @@ import 'package:dhbwstudentapp/common/ui/schedule_theme.dart'; import 'package:flutter/material.dart'; class CurrentTimeIndicatorWidget extends StatelessWidget { + const CurrentTimeIndicatorWidget({super.key}); + @override Widget build(BuildContext context) { final scheduleTheme = Theme.of(context).extension()!; diff --git a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart index 569b7906..15068a23 100644 --- a/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart +++ b/lib/schedule/ui/dailyschedule/widgets/daily_schedule_entry_widget.dart @@ -9,8 +9,7 @@ import 'package:intl/intl.dart'; class DailyScheduleEntryWidget extends StatelessWidget { final ScheduleEntry scheduleEntry; - const DailyScheduleEntryWidget({Key? key, required this.scheduleEntry}) - : super(key: key); + const DailyScheduleEntryWidget({super.key, required this.scheduleEntry}); @override Widget build(BuildContext context) { @@ -87,7 +86,8 @@ class DailyScheduleEntryWidget extends StatelessWidget { scheduleEntry.type, ), style: textTheme.bodyText2?.merge( - customTextThme.dailyScheduleEntryType,), + customTextThme.dailyScheduleEntryType, + ), ), ], ), diff --git a/lib/schedule/ui/notification/next_day_information_notification.dart b/lib/schedule/ui/notification/next_day_information_notification.dart index 4eea6189..54cceeb5 100644 --- a/lib/schedule/ui/notification/next_day_information_notification.dart +++ b/lib/schedule/ui/notification/next_day_information_notification.dart @@ -16,7 +16,7 @@ class NextDayInformationNotification extends TaskCallback { final WorkSchedulerService _scheduler; final L _localization; - NextDayInformationNotification( + const NextDayInformationNotification( this._notificationApi, this._scheduleEntryRepository, this._scheduler, diff --git a/lib/schedule/ui/notification/schedule_changed_notification.dart b/lib/schedule/ui/notification/schedule_changed_notification.dart index 9c57960c..f7f2b0d6 100644 --- a/lib/schedule/ui/notification/schedule_changed_notification.dart +++ b/lib/schedule/ui/notification/schedule_changed_notification.dart @@ -8,7 +8,7 @@ class ScheduleChangedNotification { final NotificationApi notificationApi; final L _localization; - ScheduleChangedNotification(this.notificationApi, this._localization); + const ScheduleChangedNotification(this.notificationApi, this._localization); void showNotification(ScheduleDiff scheduleDiff) { showEntriesAddedNotifications(scheduleDiff); diff --git a/lib/schedule/ui/schedule_navigation_entry.dart b/lib/schedule/ui/schedule_navigation_entry.dart index 19e29b99..0f77d817 100644 --- a/lib/schedule/ui/schedule_navigation_entry.dart +++ b/lib/schedule/ui/schedule_navigation_entry.dart @@ -9,6 +9,8 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class ScheduleNavigationEntry extends NavigationEntry { + ScheduleNavigationEntry(); + @override Icon icon = const Icon(Icons.calendar_today); @@ -42,7 +44,7 @@ class ScheduleNavigationEntry extends NavigationEntry { : IconButton( icon: const Icon(Icons.help_outline), onPressed: () async { - await ScheduleHelpDialog().show(context); + await const ScheduleHelpDialog().show(context); }, tooltip: L.of(context).helpButtonTooltip, ), diff --git a/lib/schedule/ui/schedule_page.dart b/lib/schedule/ui/schedule_page.dart index d8ded79b..f41cf23a 100644 --- a/lib/schedule/ui/schedule_page.dart +++ b/lib/schedule/ui/schedule_page.dart @@ -11,7 +11,7 @@ import 'package:kiwi/kiwi.dart'; import 'package:provider/provider.dart'; class SchedulePage extends StatefulWidget { - const SchedulePage({Key? key}) : super(key: key); + const SchedulePage({super.key}); @override _SchedulePageState createState() => _SchedulePageState(); } @@ -27,12 +27,14 @@ class _SchedulePageState extends State { KiwiContainer().resolve(), ); + _SchedulePageState(); + @override Widget build(BuildContext context) { final ScheduleViewModel viewModel = Provider.of(context); if (!viewModel.didSetupProperly) { - return ScheduleEmptyState(); + return const ScheduleEmptyState(); } else { return PagerWidget( pages: [ diff --git a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart index fb111d83..98b6ba17 100644 --- a/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart +++ b/lib/schedule/ui/weeklyschedule/filter/filter_view_model.dart @@ -48,7 +48,7 @@ class FilterViewModel extends BaseViewModel { class ScheduleEntryFilterState { bool? isDisplayed; - String? entryName; + final String? entryName; ScheduleEntryFilterState(this.isDisplayed, this.entryName); } diff --git a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart index dbe1ad5b..79c30c74 100644 --- a/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart +++ b/lib/schedule/ui/weeklyschedule/filter/schedule_filter_page.dart @@ -5,6 +5,8 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class ScheduleFilterPage extends StatelessWidget { + ScheduleFilterPage({super.key}); + final FilterViewModel _viewModel = FilterViewModel( KiwiContainer().resolve(), KiwiContainer().resolve(), @@ -80,6 +82,8 @@ class FilterStateRow extends StatefulWidget { class _FilterStateRowState extends State { bool? isChecked = false; + _FilterStateRowState(); + @override void initState() { super.initState(); diff --git a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart index a056484c..3691ea78 100644 --- a/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart +++ b/lib/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart @@ -7,19 +7,21 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class ScheduleEntryDetailBottomSheet extends StatelessWidget { - final ScheduleEntry? scheduleEntry; + final ScheduleEntry scheduleEntry; - const ScheduleEntryDetailBottomSheet({Key? key, this.scheduleEntry}) - : super(key: key); + const ScheduleEntryDetailBottomSheet({ + super.key, + required this.scheduleEntry, + }); @override Widget build(BuildContext context) { final formatter = DateFormat.Hm(L.of(context).locale.languageCode); - final timeStart = formatter.format(scheduleEntry!.start); - final timeEnd = formatter.format(scheduleEntry!.end); + final timeStart = formatter.format(scheduleEntry.start); + final timeEnd = formatter.format(scheduleEntry.end); final typeString = - scheduleEntryTypeToReadableString(context, scheduleEntry!.type); + scheduleEntryTypeToReadableString(context, scheduleEntry.type); final textTheme = Theme.of(context).textTheme; final customTextThme = Theme.of(context).extension(); @@ -87,7 +89,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(16, 0, 0, 0), child: Text( - scheduleEntry!.title, + scheduleEntry.title, softWrap: true, style: Theme.of(context).textTheme.subtitle2, ), @@ -103,7 +105,7 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { children: [ Expanded( child: Text( - scheduleEntry!.professor, + scheduleEntry.professor, ), ), Text( @@ -113,14 +115,14 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { ], ), ), - if (scheduleEntry!.room.isEmpty) + if (scheduleEntry.room.isEmpty) Container() else Padding( padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), - child: Text(scheduleEntry!.room.replaceAll(",", "\n")), + child: Text(scheduleEntry.room.replaceAll(",", "\n")), ), - if (scheduleEntry!.details.isEmpty) + if (scheduleEntry.details.isEmpty) Container() else Padding( @@ -130,10 +132,10 @@ class ScheduleEntryDetailBottomSheet extends StatelessWidget { height: 1, ), ), - if (scheduleEntry!.details.isEmpty) + if (scheduleEntry.details.isEmpty) Container() else - Text(scheduleEntry!.details), + Text(scheduleEntry.details), ], ), ), diff --git a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart index f83f499c..91d9307f 100644 --- a/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart +++ b/lib/schedule/ui/weeklyschedule/weekly_schedule_page.dart @@ -1,7 +1,6 @@ import 'package:animations/animations.dart'; import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/common/ui/widgets/error_display.dart'; -import 'package:dhbwstudentapp/schedule/model/schedule.dart'; import 'package:dhbwstudentapp/schedule/model/schedule_entry.dart'; import 'package:dhbwstudentapp/schedule/ui/viewmodels/weekly_schedule_view_model.dart'; import 'package:dhbwstudentapp/schedule/ui/weeklyschedule/schedule_entry_detail_bottom_sheet.dart'; @@ -12,7 +11,7 @@ import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; class WeeklySchedulePage extends StatefulWidget { - const WeeklySchedulePage({Key? key}) : super(key: key); + const WeeklySchedulePage({super.key}); @override _WeeklySchedulePageState createState() => _WeeklySchedulePageState(); @@ -20,7 +19,6 @@ class WeeklySchedulePage extends StatefulWidget { class _WeeklySchedulePageState extends State { late WeeklyScheduleViewModel viewModel; - Schedule? schedule; _WeeklySchedulePageState(); @@ -42,6 +40,7 @@ class _WeeklySchedulePageState extends State { L.of(context).scheduleQueryFailedOpenInBrowser.toUpperCase(), ), onPressed: () { + // TDOD: [Leptopoda] this can throw a null error launchUrl(Uri.parse(viewModel.scheduleUrl!)); }, ) diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart index f51b27d1..efa8bff6 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_alignment.dart @@ -14,6 +14,8 @@ class ScheduleEntryAlignmentInformation { /// https://stackoverflow.com/questions/11311410/visualization-of-calendar-events-algorithm-to-layout-events-with-maximum-width /// class ScheduleEntryAlignmentAlgorithm { + const ScheduleEntryAlignmentAlgorithm(); + List layoutEntries( List entries, ) { diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart index 5ad83b3e..45ec38e5 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_entry_widget.dart @@ -6,13 +6,13 @@ typedef ScheduleEntryTapCallback = Function(ScheduleEntry entry); class ScheduleEntryWidget extends StatelessWidget { final ScheduleEntry scheduleEntry; - final ScheduleEntryTapCallback? onScheduleEntryTap; + final ScheduleEntryTapCallback onScheduleEntryTap; const ScheduleEntryWidget({ - Key? key, + super.key, required this.scheduleEntry, - this.onScheduleEntryTap, - }) : super(key: key); + required this.onScheduleEntryTap, + }); @override Widget build(BuildContext context) { @@ -32,7 +32,7 @@ class ScheduleEntryWidget extends StatelessWidget { margin: const EdgeInsets.fromLTRB(1, 0, 1, 0), child: InkWell( onTap: () { - onScheduleEntryTap?.call(scheduleEntry); + onScheduleEntryTap.call(scheduleEntry); }, child: Padding( padding: const EdgeInsets.fromLTRB(4, 4, 4, 4), diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart index 509b2f5e..9acf73bc 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_grid.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; class ScheduleGrid extends CustomPaint { - final int? fromHour; - final int? toHour; + final int fromHour; + final int toHour; final double timeLabelsWidth; final double dateLabelsHeight; final int columns; @@ -29,14 +29,14 @@ class ScheduleGrid extends CustomPaint { } class ScheduleGridCustomPaint extends CustomPainter { - final int? fromHour; - final int? toHour; + final int fromHour; + final int toHour; final double timeLabelsWidth; final double dateLabelsHeight; final int columns; final Color gridLineColor; - ScheduleGridCustomPaint( + const ScheduleGridCustomPaint( this.fromHour, this.toHour, this.timeLabelsWidth, @@ -51,7 +51,7 @@ class ScheduleGridCustomPaint extends CustomPainter { ..color = gridLineColor ..strokeWidth = 1; - final lines = toHour! - fromHour!; + final lines = toHour - fromHour; drawHorizontalLines(lines, size, canvas, secondaryPaint); drawVerticalLines(size, canvas, secondaryPaint); diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart index 96eec88b..344a1a60 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_past_overlay.dart @@ -43,7 +43,7 @@ class SchedulePastOverlayCustomPaint extends CustomPainter { final int columns; final Color overlayColor; - SchedulePastOverlayCustomPaint( + const SchedulePastOverlayCustomPaint( this.fromDate, this.toDate, this.now, diff --git a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart index 52e0ad10..1c402533 100644 --- a/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart +++ b/lib/schedule/ui/weeklyschedule/widgets/schedule_widget.dart @@ -15,43 +15,40 @@ class ScheduleWidget extends StatelessWidget { final Schedule? schedule; final DateTime? displayStart; final DateTime? displayEnd; - final DateTime? now; - final int? displayStartHour; - final int? displayEndHour; - final ScheduleEntryTapCallback? onScheduleEntryTap; + final DateTime now; + final int displayStartHour; + final int displayEndHour; + final ScheduleEntryTapCallback onScheduleEntryTap; const ScheduleWidget({ - Key? key, - this.schedule, - this.displayStart, - this.displayEnd, - this.onScheduleEntryTap, - this.now, - this.displayStartHour, - this.displayEndHour, - }) : super(key: key); + super.key, + required this.schedule, + required this.displayStart, + required this.displayEnd, + required this.onScheduleEntryTap, + required this.now, + required this.displayStartHour, + required this.displayEndHour, + }); @override Widget build(BuildContext context) { return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return buildWithSize( - context, - constraints.biggest.width, - constraints.biggest.height, - ); - }, + builder: buildWithSize, ); } - Widget buildWithSize(BuildContext context, double width, double height) { + Widget buildWithSize(BuildContext context, BoxConstraints constraints) { final scheduleTheme = Theme.of(context).extension()!; + final height = constraints.biggest.height; + final width = constraints.biggest.width; + const dayLabelsHeight = 40.0; const timeLabelsWidth = 50.0; final hourHeight = - (height - dayLabelsHeight) / (displayEndHour! - displayStartHour!); + (height - dayLabelsHeight) / (displayEndHour - displayStartHour); final minuteHeight = hourHeight / 60; final days = calculateDisplayedDays(); @@ -140,12 +137,12 @@ class ScheduleWidget extends StatelessWidget { ) { final labelWidgets = []; - for (var i = displayStartHour!; i < displayEndHour!; i++) { + for (var i = displayStartHour; i < displayEndHour; i++) { final hourLabelText = "$i:00"; labelWidgets.add( Positioned( - top: rowHeight * (i - displayStartHour!) + dayLabelHeight, + top: rowHeight * (i - displayStartHour) + dayLabelHeight, left: 0, child: Padding( padding: const EdgeInsets.fromLTRB(4, 4, 4, 8), @@ -249,15 +246,15 @@ class ScheduleWidget extends StatelessWidget { final entryWidgets = []; final laidOutEntries = - ScheduleEntryAlignmentAlgorithm().layoutEntries(entries); + const ScheduleEntryAlignmentAlgorithm().layoutEntries(entries); for (final value in laidOutEntries) { final entry = value.entry; - final yStart = hourHeight * (entry.start.hour - displayStartHour!) + + final yStart = hourHeight * (entry.start.hour - displayStartHour) + minuteHeight * entry.start.minute; - final yEnd = hourHeight * (entry.end.hour - displayStartHour!) + + final yEnd = hourHeight * (entry.end.hour - displayStartHour) + minuteHeight * entry.end.minute; final entryLeft = maxWidth * value.leftColumn; diff --git a/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart b/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart index eec5214e..011233c8 100644 --- a/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart +++ b/lib/schedule/ui/widgets/enter_dualis_credentials_dialog.dart @@ -23,7 +23,7 @@ class EnterDualisCredentialsDialog { await showDialog( context: context, - builder: (context) => _buildDialog(context), + builder: _buildDialog, ); } diff --git a/lib/schedule/ui/widgets/enter_url_dialog.dart b/lib/schedule/ui/widgets/enter_url_dialog.dart index f266fb3b..80e20976 100644 --- a/lib/schedule/ui/widgets/enter_url_dialog.dart +++ b/lib/schedule/ui/widgets/enter_url_dialog.dart @@ -18,7 +18,7 @@ abstract class EnterUrlDialog { Future show(BuildContext context) async { await showDialog( context: context, - builder: (context) => _buildDialog(context), + builder: _buildDialog, ); } diff --git a/lib/schedule/ui/widgets/schedule_empty_state.dart b/lib/schedule/ui/widgets/schedule_empty_state.dart index 436d26f1..fab8b29e 100644 --- a/lib/schedule/ui/widgets/schedule_empty_state.dart +++ b/lib/schedule/ui/widgets/schedule_empty_state.dart @@ -6,7 +6,9 @@ import 'package:flutter/material.dart'; import 'package:kiwi/kiwi.dart'; class ScheduleEmptyState extends StatelessWidget { - final Map image = { + const ScheduleEmptyState({super.key}); + + static const Map image = { Brightness.dark: Assets.assets_schedule_empty_state_dark_png, Brightness.light: Assets.assets_schedule_empty_state_png, }; diff --git a/lib/schedule/ui/widgets/schedule_help_dialog.dart b/lib/schedule/ui/widgets/schedule_help_dialog.dart index dd5c4335..ebde3d6e 100644 --- a/lib/schedule/ui/widgets/schedule_help_dialog.dart +++ b/lib/schedule/ui/widgets/schedule_help_dialog.dart @@ -3,6 +3,8 @@ import 'package:dhbwstudentapp/common/ui/widgets/help_dialog.dart'; import 'package:flutter/material.dart'; class ScheduleHelpDialog extends HelpDialog { + const ScheduleHelpDialog(); + @override String content(BuildContext context) { return L.of(context).scheduleHelpDialogContent; diff --git a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart index 94dfdf5f..c01ac6ea 100644 --- a/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart +++ b/lib/schedule/ui/widgets/select_mannheim_course_dialog.dart @@ -7,20 +7,16 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class SelectMannheimCourseDialog { - final ScheduleSourceProvider _scheduleSourceProvider; - - late MannheimViewModel _mannheimViewModel; + final MannheimViewModel _mannheimViewModel; SelectMannheimCourseDialog( - this._scheduleSourceProvider, - ); + ScheduleSourceProvider scheduleSourceProvider, + ) : _mannheimViewModel = MannheimViewModel(scheduleSourceProvider); Future show(BuildContext context) async { - _mannheimViewModel = MannheimViewModel(_scheduleSourceProvider); - await showDialog( context: context, - builder: (context) => _buildDialog(context), + builder: _buildDialog, ); } @@ -43,9 +39,9 @@ class SelectMannheimCourseDialog { style: Theme.of(context).textTheme.bodyText2, ), ), - Expanded( + const Expanded( child: Padding( - padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), + padding: EdgeInsets.fromLTRB(8, 0, 8, 0), child: SelectMannheimCourseWidget(), ), ), diff --git a/lib/schedule/ui/widgets/select_source_dialog.dart b/lib/schedule/ui/widgets/select_source_dialog.dart index bb43eb3c..75713d79 100644 --- a/lib/schedule/ui/widgets/select_source_dialog.dart +++ b/lib/schedule/ui/widgets/select_source_dialog.dart @@ -23,7 +23,7 @@ class SelectSourceDialog { await showDialog( context: context, - builder: (context) => _buildDialog(context), + builder: _buildDialog, ); } diff --git a/lib/ui/banner_widget.dart b/lib/ui/banner_widget.dart index fd1c08c8..ad34acc2 100644 --- a/lib/ui/banner_widget.dart +++ b/lib/ui/banner_widget.dart @@ -6,11 +6,11 @@ class BannerWidget extends StatelessWidget { final VoidCallback onButtonTap; const BannerWidget({ - Key? key, + super.key, required this.message, required this.buttonText, required this.onButtonTap, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/ui/login_credentials_widget.dart b/lib/ui/login_credentials_widget.dart index 70670b9a..9e2601ef 100644 --- a/lib/ui/login_credentials_widget.dart +++ b/lib/ui/login_credentials_widget.dart @@ -2,49 +2,42 @@ import 'package:dhbwstudentapp/common/i18n/localizations.dart'; import 'package:dhbwstudentapp/dualis/model/credentials.dart'; import 'package:flutter/material.dart'; -class LoginCredentialsWidget extends StatefulWidget { +class LoginCredentialsWidget extends StatelessWidget { final CredentialsEditingController controller; final VoidCallback onSubmitted; const LoginCredentialsWidget({ - Key? key, + super.key, required this.controller, required this.onSubmitted, - }) : super(key: key); - - @override - _LoginCredentialsWidgetState createState() => _LoginCredentialsWidgetState(); -} - -class _LoginCredentialsWidgetState extends State { - final _focus = FocusNode(); + }); @override Widget build(BuildContext context) { + final focus = FocusNode(); + return Column( children: [ TextField( - controller: widget.controller.username, + controller: controller.username, decoration: InputDecoration( hintText: L.of(context).loginUsername, icon: const Icon(Icons.alternate_email), ), onSubmitted: (v) { - FocusScope.of(context).requestFocus(_focus); + FocusScope.of(context).requestFocus(focus); }, textInputAction: TextInputAction.next, ), TextField( - controller: widget.controller.password, + controller: controller.password, obscureText: true, decoration: InputDecoration( hintText: L.of(context).loginPassword, icon: const Icon(Icons.lock_outline), ), - focusNode: _focus, - onSubmitted: (_) { - widget.onSubmitted(); - }, + focusNode: focus, + onSubmitted: (_) => onSubmitted(), ), ], ); diff --git a/lib/ui/main_page.dart b/lib/ui/main_page.dart index ed435d30..bd70cf86 100644 --- a/lib/ui/main_page.dart +++ b/lib/ui/main_page.dart @@ -15,7 +15,7 @@ import 'package:provider/provider.dart'; /// To navigate to a new route inside this widget use the [NavigatorKey.mainKey] /// class MainPage extends StatefulWidget { - const MainPage({Key? key}) : super(key: key); + const MainPage({super.key}); @override _MainPageState createState() => _MainPageState(); @@ -29,10 +29,7 @@ class _MainPageState extends State with NavigatorObserver { NavigationEntry get currentEntry => navigationEntries[_currentEntryIndex.value]; - @override - void initState() { - super.initState(); - } + _MainPageState(); @override Widget build(BuildContext context) { @@ -175,7 +172,9 @@ class _MainPageState extends State with NavigatorObserver { @override void didPop(Route route, Route? previousRoute) { - updateNavigationDrawer(previousRoute!.settings.name); + if (previousRoute != null) { + updateNavigationDrawer(previousRoute.settings.name); + } } @override @@ -185,6 +184,8 @@ class _MainPageState extends State with NavigatorObserver { @override void didReplace({Route? newRoute, Route? oldRoute}) { - updateNavigationDrawer(newRoute!.settings.name); + if (newRoute != null) { + updateNavigationDrawer(newRoute.settings.name); + } } } diff --git a/lib/ui/navigation/navigation_entry.dart b/lib/ui/navigation/navigation_entry.dart index 4c123c22..128c7772 100644 --- a/lib/ui/navigation/navigation_entry.dart +++ b/lib/ui/navigation/navigation_entry.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; abstract class NavigationEntry { + NavigationEntry(); + T? _viewModel; String get route; diff --git a/lib/ui/navigation_drawer.dart b/lib/ui/navigation_drawer.dart index 0a0e25dd..023b81a4 100644 --- a/lib/ui/navigation_drawer.dart +++ b/lib/ui/navigation_drawer.dart @@ -16,12 +16,12 @@ class NavigationDrawer extends StatelessWidget { final bool isInDrawer; const NavigationDrawer({ - Key? key, + super.key, required this.selectedIndex, required this.onTap, required this.entries, this.isInDrawer = true, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -134,25 +134,23 @@ class NavigationDrawer extends StatelessWidget { child: Container( height: 56, margin: const EdgeInsets.fromLTRB(0, 0, 0, 20), - child: Padding( - padding: const EdgeInsets.fromLTRB(20, 15, 0, 10), - child: Row( - children: [ - Icon( - Icons.settings, - color: Theme.of(context).disabledColor, - ), - Padding( - padding: const EdgeInsets.fromLTRB(16, 0, 0, 0), - child: Text( - L.of(context).settingsPageTitle, - style: TextStyle( - color: Theme.of(context).disabledColor, - ), + padding: const EdgeInsets.fromLTRB(20, 15, 0, 10), + child: Row( + children: [ + Icon( + Icons.settings, + color: Theme.of(context).disabledColor, + ), + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 0, 0), + child: Text( + L.of(context).settingsPageTitle, + style: TextStyle( + color: Theme.of(context).disabledColor, ), ), - ], - ), + ), + ], ), ), onTap: () { @@ -173,5 +171,5 @@ class DrawerNavigationEntry { final Icon icon; final String title; - DrawerNavigationEntry(this.icon, this.title); + const DrawerNavigationEntry(this.icon, this.title); } diff --git a/lib/ui/onboarding/onboardin_step.dart b/lib/ui/onboarding/onboardin_step.dart index 5d8c03f9..d36f61f4 100644 --- a/lib/ui/onboarding/onboardin_step.dart +++ b/lib/ui/onboarding/onboardin_step.dart @@ -13,6 +13,8 @@ import 'package:flutter/cupertino.dart'; import 'package:kiwi/kiwi.dart'; abstract class OnboardingStep { + const OnboardingStep(); + Widget buildContent(BuildContext context); OnboardingStepViewModel viewModel(); @@ -21,6 +23,8 @@ abstract class OnboardingStep { } class SelectSourceOnboardingStep extends OnboardingStep { + SelectSourceOnboardingStep(); + final SelectSourceViewModel _viewModel = SelectSourceViewModel( KiwiContainer().resolve(), ); @@ -42,6 +46,8 @@ class SelectSourceOnboardingStep extends OnboardingStep { } class DualisCredentialsOnboardingStep extends OnboardingStep { + DualisCredentialsOnboardingStep(); + final DualisLoginViewModel _viewModel = DualisLoginViewModel( KiwiContainer().resolve(), KiwiContainer().resolve(), @@ -64,6 +70,8 @@ class DualisCredentialsOnboardingStep extends OnboardingStep { } class RaplaOnboardingStep extends OnboardingStep { + RaplaOnboardingStep(); + final RaplaUrlViewModel _viewModel = RaplaUrlViewModel( KiwiContainer().resolve(), KiwiContainer().resolve(), @@ -86,6 +94,8 @@ class RaplaOnboardingStep extends OnboardingStep { } class IcalOnboardingStep extends OnboardingStep { + IcalOnboardingStep(); + final IcalUrlViewModel _viewModel = IcalUrlViewModel( KiwiContainer().resolve(), KiwiContainer().resolve(), @@ -109,6 +119,7 @@ class IcalOnboardingStep extends OnboardingStep { class MannheimOnboardingStep extends OnboardingStep { MannheimViewModel? _viewModel; + MannheimOnboardingStep(); @override Widget buildContent(BuildContext context) { diff --git a/lib/ui/onboarding/onboarding_page.dart b/lib/ui/onboarding/onboarding_page.dart index 35aa2aed..5e832802 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/lib/ui/onboarding/onboarding_page.dart @@ -9,7 +9,7 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class OnboardingPage extends StatefulWidget { - const OnboardingPage({Key? key}) : super(key: key); + const OnboardingPage({super.key}); @override _OnboardingPageState createState() => _OnboardingPageState(); diff --git a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart index 30f17349..4037c0ee 100644 --- a/lib/ui/onboarding/viewmodels/mannheim_view_model.dart +++ b/lib/ui/onboarding/viewmodels/mannheim_view_model.dart @@ -31,7 +31,7 @@ class MannheimViewModel extends OnboardingStepViewModel { try { await Future.delayed(const Duration(seconds: 1)); - _courses = await MannheimCourseScraper().loadCourses(); + _courses = await const MannheimCourseScraper().loadCourses(); _loadingState = LoadCoursesState.Loaded; } catch (ex) { _courses = null; diff --git a/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart b/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart index c6be6b65..9504a2b7 100644 --- a/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart +++ b/lib/ui/onboarding/viewmodels/onboarding_view_model_base.dart @@ -1,6 +1,8 @@ import 'package:dhbwstudentapp/common/ui/viewmodels/base_view_model.dart'; abstract class OnboardingStepViewModel extends BaseViewModel { + OnboardingStepViewModel(); + bool _isValid = false; bool get isValid => _isValid; diff --git a/lib/ui/onboarding/widgets/dualis_login_page.dart b/lib/ui/onboarding/widgets/dualis_login_page.dart index 8b0d2477..b0da52db 100644 --- a/lib/ui/onboarding/widgets/dualis_login_page.dart +++ b/lib/ui/onboarding/widgets/dualis_login_page.dart @@ -11,18 +11,26 @@ import 'package:property_change_notifier/property_change_notifier.dart'; /// credentials. /// class DualisLoginCredentialsPage extends StatefulWidget { - const DualisLoginCredentialsPage({Key? key}) : super(key: key); + const DualisLoginCredentialsPage({super.key}); @override - _DualisLoginCredentialsPageState createState() => + State createState() => _DualisLoginCredentialsPageState(); } class _DualisLoginCredentialsPageState extends State { - final CredentialsEditingController _controller = + final CredentialsEditingController controller = CredentialsEditingController(); + _DualisLoginCredentialsPageState(); + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return PropertyChangeConsumer( @@ -36,7 +44,7 @@ class _DualisLoginCredentialsPageState final credentials = viewModel?.credentials; if (credentials != null) { - _controller.credentials = credentials; + controller.credentials = credentials; } final widgets = []; @@ -44,7 +52,7 @@ class _DualisLoginCredentialsPageState widgets.addAll(_buildHeader()); widgets.add( LoginCredentialsWidget( - controller: _controller, + controller: controller, onSubmitted: () async { await _testCredentials(viewModel); }, @@ -114,7 +122,7 @@ class _DualisLoginCredentialsPageState Future _testCredentials(DualisLoginViewModel? viewModel) async { if (viewModel == null) return; - await viewModel.testCredentials(_controller.credentials); + await viewModel.testCredentials(controller.credentials); } List _buildHeader() { diff --git a/lib/ui/onboarding/widgets/ical_url_page.dart b/lib/ui/onboarding/widgets/ical_url_page.dart index 93ebce5f..29d737d9 100644 --- a/lib/ui/onboarding/widgets/ical_url_page.dart +++ b/lib/ui/onboarding/widgets/ical_url_page.dart @@ -4,18 +4,12 @@ import 'package:dhbwstudentapp/ui/onboarding/viewmodels/onboarding_view_model_ba import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; -class IcalUrlPage extends StatefulWidget { - const IcalUrlPage({Key? key}) : super(key: key); - - @override - _IcalUrlPageState createState() => _IcalUrlPageState(); -} - -class _IcalUrlPageState extends State { - final TextEditingController _urlTextController = TextEditingController(); +class IcalUrlPage extends StatelessWidget { + const IcalUrlPage({super.key}); @override Widget build(BuildContext context) { + final TextEditingController urlTextController = TextEditingController(); return Column( children: [ Padding( @@ -49,8 +43,8 @@ class _IcalUrlPageState extends State { final viewModel = model as IcalUrlViewModel?; if (viewModel?.url != null && - _urlTextController.text != viewModel!.url) { - _urlTextController.text = viewModel.url!; + urlTextController.text != viewModel!.url) { + urlTextController.text = viewModel.url!; } return Padding( @@ -60,7 +54,7 @@ class _IcalUrlPageState extends State { children: [ Expanded( child: TextField( - controller: _urlTextController, + controller: urlTextController, decoration: InputDecoration( errorText: (viewModel?.urlHasError == true) ? L.of(context).onboardingRaplaUrlInvalid diff --git a/lib/ui/onboarding/widgets/mannheim_page.dart b/lib/ui/onboarding/widgets/mannheim_page.dart index 75d2bfac..4a6ff63a 100644 --- a/lib/ui/onboarding/widgets/mannheim_page.dart +++ b/lib/ui/onboarding/widgets/mannheim_page.dart @@ -4,14 +4,9 @@ import 'package:dhbwstudentapp/ui/onboarding/viewmodels/onboarding_view_model_ba import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; -class MannheimPage extends StatefulWidget { - const MannheimPage({Key? key}) : super(key: key); +class MannheimPage extends StatelessWidget { + const MannheimPage({super.key}); - @override - _MannheimPageState createState() => _MannheimPageState(); -} - -class _MannheimPageState extends State { @override Widget build(BuildContext context) { return Column( @@ -35,9 +30,9 @@ class _MannheimPageState extends State { style: Theme.of(context).textTheme.bodyText2, textAlign: TextAlign.center, ), - Expanded( + const Expanded( child: Padding( - padding: const EdgeInsets.fromLTRB(0, 32, 0, 0), + padding: EdgeInsets.fromLTRB(0, 32, 0, 0), child: SelectMannheimCourseWidget(), ), ), @@ -47,6 +42,8 @@ class _MannheimPageState extends State { } class SelectMannheimCourseWidget extends StatelessWidget { + const SelectMannheimCourseWidget({super.key}); + @override Widget build(BuildContext context) { return PropertyChangeConsumer( diff --git a/lib/ui/onboarding/widgets/onboarding_button_bar.dart b/lib/ui/onboarding/widgets/onboarding_button_bar.dart index 44fc6a9d..5b141d39 100644 --- a/lib/ui/onboarding/widgets/onboarding_button_bar.dart +++ b/lib/ui/onboarding/widgets/onboarding_button_bar.dart @@ -8,11 +8,11 @@ class OnboardingButtonBar extends StatelessWidget { final VoidCallback onPrevious; const OnboardingButtonBar({ - Key? key, + super.key, required this.viewModel, required this.onNext, required this.onPrevious, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/ui/onboarding/widgets/onboarding_page_background.dart b/lib/ui/onboarding/widgets/onboarding_page_background.dart index e4bf9fad..5d7e6832 100644 --- a/lib/ui/onboarding/widgets/onboarding_page_background.dart +++ b/lib/ui/onboarding/widgets/onboarding_page_background.dart @@ -11,17 +11,17 @@ class OnboardingPageBackground extends StatelessWidget { final Animation bottomForeground; final Animation bottomBackground; - final Map foreground = { + static const Map foreground = { Brightness.light: Assets.assets_onboarding_bottom_foreground_png, Brightness.dark: Assets.assets_onboarding_bottom_foreground_dark_png, }; - final Map background = { + static const Map background = { Brightness.light: Assets.assets_onboarding_bottom_background_png, Brightness.dark: Assets.assets_onboarding_bottom_background_dark_png, }; - OnboardingPageBackground({Key? key, required this.controller}) + OnboardingPageBackground({super.key, required this.controller}) : angleTopBackground = Tween( begin: PlatformUtil.isPhone() ? -32 : -10, end: PlatformUtil.isPhone() ? -10 : -5, @@ -69,8 +69,7 @@ class OnboardingPageBackground extends StatelessWidget { 1, ), ), - ), - super(key: key); + ); Widget _buildAnimation(BuildContext context, Widget? child) { return Stack( diff --git a/lib/ui/onboarding/widgets/rapla_url_page.dart b/lib/ui/onboarding/widgets/rapla_url_page.dart index db2df414..78e48f05 100644 --- a/lib/ui/onboarding/widgets/rapla_url_page.dart +++ b/lib/ui/onboarding/widgets/rapla_url_page.dart @@ -4,18 +4,12 @@ import 'package:dhbwstudentapp/ui/onboarding/viewmodels/rapla_url_view_model.dar import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; -class RaplaUrlPage extends StatefulWidget { - const RaplaUrlPage({Key? key}) : super(key: key); - - @override - _RaplaUrlPageState createState() => _RaplaUrlPageState(); -} - -class _RaplaUrlPageState extends State { - final TextEditingController _urlTextController = TextEditingController(); +class RaplaUrlPage extends StatelessWidget { + const RaplaUrlPage({super.key}); @override Widget build(BuildContext context) { + final TextEditingController urlTextController = TextEditingController(); return Column( children: [ Padding( @@ -49,8 +43,8 @@ class _RaplaUrlPageState extends State { final viewModel = model as RaplaUrlViewModel?; if (viewModel?.raplaUrl != null && - _urlTextController.text != viewModel!.raplaUrl) { - _urlTextController.text = viewModel.raplaUrl!; + urlTextController.text != viewModel!.raplaUrl) { + urlTextController.text = viewModel.raplaUrl!; } return Padding( @@ -60,7 +54,7 @@ class _RaplaUrlPageState extends State { children: [ Expanded( child: TextField( - controller: _urlTextController, + controller: urlTextController, decoration: InputDecoration( errorText: viewModel?.urlHasError == true ? L.of(context).onboardingRaplaUrlInvalid diff --git a/lib/ui/onboarding/widgets/select_source_page.dart b/lib/ui/onboarding/widgets/select_source_page.dart index 4036d051..baa1984b 100644 --- a/lib/ui/onboarding/widgets/select_source_page.dart +++ b/lib/ui/onboarding/widgets/select_source_page.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class SelectSourcePage extends StatelessWidget { - const SelectSourcePage({Key? key}) : super(key: key); + const SelectSourcePage({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/ui/pager_widget.dart b/lib/ui/pager_widget.dart index 3c2286ed..11c75fdc 100644 --- a/lib/ui/pager_widget.dart +++ b/lib/ui/pager_widget.dart @@ -17,8 +17,7 @@ class PagerWidget extends StatefulWidget { final List pages; final String? pagesId; - const PagerWidget({Key? key, required this.pages, this.pagesId}) - : super(key: key); + const PagerWidget({super.key, required this.pages, this.pagesId}); @override _PagerWidgetState createState() => _PagerWidgetState(); @@ -29,6 +28,8 @@ class _PagerWidgetState extends State { int _currentPage = 0; + _PagerWidgetState(); + @override void initState() { super.initState(); @@ -108,7 +109,7 @@ class PageDefinition { final WidgetBuilder builder; final T? viewModel; - PageDefinition({ + const PageDefinition({ required this.icon, required this.text, required this.builder, diff --git a/lib/ui/root_page.dart b/lib/ui/root_page.dart index c3521653..6585369e 100644 --- a/lib/ui/root_page.dart +++ b/lib/ui/root_page.dart @@ -13,25 +13,15 @@ import 'package:property_change_notifier/property_change_notifier.dart'; /// This is the top level widget of the app. It handles navigation of the /// root navigator and rebuilds its child widgets on theme changes /// -class RootPage extends StatefulWidget { +class RootPage extends StatelessWidget { final RootViewModel rootViewModel; - const RootPage({Key? key, required this.rootViewModel}) : super(key: key); - - @override - _RootPageState createState() => _RootPageState(); -} - -class _RootPageState extends State { - @override - void initState() { - super.initState(); - } + const RootPage({super.key, required this.rootViewModel}); @override Widget build(BuildContext context) { return PropertyChangeProvider( - value: widget.rootViewModel, + value: rootViewModel, child: PropertyChangeConsumer( properties: const ["appTheme", "isOnboarding"], builder: @@ -40,8 +30,7 @@ class _RootPageState extends State { theme: AppTheme.lightThemeData, darkTheme: AppTheme.darkThemeData, themeMode: model?.appTheme, - initialRoute: - widget.rootViewModel.isOnboarding ? "onboarding" : "main", + initialRoute: rootViewModel.isOnboarding ? "onboarding" : "main", navigatorKey: NavigatorKey.rootKey, navigatorObservers: [rootNavigationObserver], localizationsDelegates: const [ diff --git a/lib/ui/settings/donate_list_tile.dart b/lib/ui/settings/donate_list_tile.dart index 7b1fea9f..f1c59da9 100644 --- a/lib/ui/settings/donate_list_tile.dart +++ b/lib/ui/settings/donate_list_tile.dart @@ -7,7 +7,7 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class DonateListTile extends StatefulWidget { - const DonateListTile({Key? key}) : super(key: key); + const DonateListTile({super.key}); @override _DonateListTileState createState() => _DonateListTileState(); diff --git a/lib/ui/settings/purchase_widget_list_tile.dart b/lib/ui/settings/purchase_widget_list_tile.dart index 691d9cdb..d519c81b 100644 --- a/lib/ui/settings/purchase_widget_list_tile.dart +++ b/lib/ui/settings/purchase_widget_list_tile.dart @@ -7,7 +7,7 @@ import 'package:kiwi/kiwi.dart'; import 'package:property_change_notifier/property_change_notifier.dart'; class PurchaseWidgetListTile extends StatefulWidget { - const PurchaseWidgetListTile({Key? key}) : super(key: key); + const PurchaseWidgetListTile({super.key}); @override _PurchaseWidgetListTileState createState() => _PurchaseWidgetListTileState(); diff --git a/lib/ui/settings/select_theme_dialog.dart b/lib/ui/settings/select_theme_dialog.dart index f3eb3dd9..3b92fdc5 100644 --- a/lib/ui/settings/select_theme_dialog.dart +++ b/lib/ui/settings/select_theme_dialog.dart @@ -9,7 +9,7 @@ import 'package:property_change_notifier/property_change_notifier.dart'; class SelectThemeDialog { final RootViewModel _rootViewModel; - SelectThemeDialog(this._rootViewModel); + const SelectThemeDialog(this._rootViewModel); Future show(BuildContext context) async { await showDialog( diff --git a/lib/ui/settings/settings_page.dart b/lib/ui/settings/settings_page.dart index 0650f4f1..0bd21eb9 100644 --- a/lib/ui/settings/settings_page.dart +++ b/lib/ui/settings/settings_page.dart @@ -30,7 +30,7 @@ import 'package:url_launcher/url_launcher.dart'; /// of the app /// class SettingsPage extends StatefulWidget { - const SettingsPage({Key? key}) : super(key: key); + const SettingsPage({super.key}); @override _SettingsPageState createState() => _SettingsPageState(); @@ -45,15 +45,17 @@ class _SettingsPageState extends State { KiwiContainer().resolve(), ); + _SettingsPageState(); + @override Widget build(BuildContext context) { - final widgets = []; - - widgets.addAll(buildScheduleSourceSettings(context)); - widgets.addAll(buildDesignSettings(context)); - widgets.addAll(buildNotificationSettings(context)); - widgets.addAll(buildAboutSettings(context)); - widgets.add(buildDisclaimer(context)); + final widgets = [ + ...buildScheduleSourceSettings(), + ...buildDesignSettings(), + ...buildNotificationSettings(), + ...buildAboutSettings(), + buildDisclaimer(), + ]; return Scaffold( appBar: AppBar( @@ -74,7 +76,7 @@ class _SettingsPageState extends State { ); } - Widget buildDisclaimer(BuildContext context) { + Widget buildDisclaimer() { return Padding( padding: const EdgeInsets.all(32), child: Text( @@ -84,7 +86,7 @@ class _SettingsPageState extends State { ); } - List buildAboutSettings(BuildContext context) { + List buildAboutSettings() { return [ TitleListTile(title: L.of(context).settingsAboutTitle), const PurchaseWidgetListTile(), @@ -114,7 +116,7 @@ class _SettingsPageState extends State { ]; } - List buildScheduleSourceSettings(BuildContext context) { + List buildScheduleSourceSettings() { return [ TitleListTile(title: L.of(context).settingsScheduleSourceTitle), ListTile( @@ -141,48 +143,13 @@ class _SettingsPageState extends State { ), ListTile( title: Text(L.of(context).settingsCalendarSync), - onTap: () async { - if (await CalendarAccess().requestCalendarPermission() == - CalendarPermission.PermissionDenied) { - await showDialog( - context: context, - builder: (BuildContext context) => AlertDialog( - title: Text( - L.of(context).dialogTitleCalendarAccessNotGranted, - ), - content: Text(L.of(context).dialogCalendarAccessNotGranted), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(L.of(context).dialogOk), - ) - ], - ), - ); - return; - } - final isCalendarSyncEnabled = await KiwiContainer() - .resolve() - .isCalendarSyncEnabled(); - final List entriesToExport = - KiwiContainer().resolve().listDateEntries; - await NavigatorKey.rootKey.currentState!.push( - MaterialPageRoute( - builder: (BuildContext context) => CalendarExportPage( - entriesToExport: entriesToExport, - isCalendarSyncWidget: true, - isCalendarSyncEnabled: isCalendarSyncEnabled, - ), - settings: const RouteSettings(name: "settings"), - ), - ); - }, + onTap: requestCalendarPermission, ), const Divider(), ]; } - List buildNotificationSettings(BuildContext context) { + List buildNotificationSettings() { final WorkSchedulerService service = KiwiContainer().resolve(); if (service.isSchedulingAvailable()) { return [ @@ -226,7 +193,7 @@ class _SettingsPageState extends State { } } - List buildDesignSettings(BuildContext context) { + List buildDesignSettings() { return [ TitleListTile(title: L.of(context).settingsDesign), PropertyChangeConsumer( @@ -253,6 +220,43 @@ class _SettingsPageState extends State { ]; } + Future requestCalendarPermission() async { + final permission = await CalendarAccess().requestCalendarPermission(); + if (permission == CalendarPermission.PermissionDenied) { + await showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: Text( + L.of(context).dialogTitleCalendarAccessNotGranted, + ), + content: Text(L.of(context).dialogCalendarAccessNotGranted), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(L.of(context).dialogOk), + ) + ], + ), + ); + return; + } + final isCalendarSyncEnabled = await KiwiContainer() + .resolve() + .isCalendarSyncEnabled(); + final List entriesToExport = + KiwiContainer().resolve().listDateEntries; + await NavigatorKey.rootKey.currentState!.push( + MaterialPageRoute( + builder: (BuildContext context) => CalendarExportPage( + entriesToExport: entriesToExport, + isCalendarSyncWidget: true, + isCalendarSyncEnabled: isCalendarSyncEnabled, + ), + settings: const RouteSettings(name: "settings"), + ), + ); + } + @override void dispose() { super.dispose(); diff --git a/test/date_management/service/parsing/all_dates_extract_test.dart b/test/date_management/service/parsing/all_dates_extract_test.dart index 88e72642..14f86bcd 100644 --- a/test/date_management/service/parsing/all_dates_extract_test.dart +++ b/test/date_management/service/parsing/all_dates_extract_test.dart @@ -9,7 +9,7 @@ Future main() async { ).readAsString(); test('AllDatesExtract extract all dates', () async { - final extract = AllDatesExtract(); + const extract = AllDatesExtract(); final dateEntries = extract.extractAllDates(allDatesPage, ""); diff --git a/test/dualis/service/parsing/all_modules_extract_test.dart b/test/dualis/service/parsing/all_modules_extract_test.dart index e637ca0a..eddf4453 100644 --- a/test/dualis/service/parsing/all_modules_extract_test.dart +++ b/test/dualis/service/parsing/all_modules_extract_test.dart @@ -11,7 +11,7 @@ Future main() async { ).readAsString(); test('AllModulesExtract extract all modules', () async { - final extract = AllModulesExtract(); + const extract = AllModulesExtract(); final modules = extract.extractAllModules(studentResultsPage); @@ -27,7 +27,7 @@ Future main() async { }); test('AllModulesExtract invalid html throws exception', () async { - final extract = AllModulesExtract(); + const extract = AllModulesExtract(); try { extract.extractAllModules("Lorem ipsum"); diff --git a/test/dualis/service/parsing/dualis_timeout_extract_test.dart b/test/dualis/service/parsing/dualis_timeout_extract_test.dart index d3cfed2b..8f17eae4 100644 --- a/test/dualis/service/parsing/dualis_timeout_extract_test.dart +++ b/test/dualis/service/parsing/dualis_timeout_extract_test.dart @@ -13,10 +13,13 @@ Future main() async { ).readAsString(); test('DualisTimeoutExtract detect timeout page', () async { - expect(TimeoutExtract().isTimeoutErrorPage(timeoutPage), isTrue); + expect(const TimeoutExtract().isTimeoutErrorPage(timeoutPage), isTrue); }); test('DualisTimeoutExtract detect non timeout page', () async { - expect(TimeoutExtract().isTimeoutErrorPage(monthlySchedulePage), isFalse); + expect( + const TimeoutExtract().isTimeoutErrorPage(monthlySchedulePage), + isFalse, + ); }); } diff --git a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart index 6023bf56..84f3f7de 100644 --- a/test/dualis/service/parsing/exams_from_module_details_extract_test.dart +++ b/test/dualis/service/parsing/exams_from_module_details_extract_test.dart @@ -10,7 +10,7 @@ Future main() async { ).readAsString(); test('ExamsFromModuleDetailsExtract', () async { - final extract = ExamsFromModuleDetailsExtract(); + const extract = ExamsFromModuleDetailsExtract(); final exams = extract.extractExamsFromModuleDetails(moduleDetailsPage); @@ -26,7 +26,7 @@ Future main() async { }); test('ExamsFromModuleDetailsExtract invalid html throws exception', () async { - final extract = ExamsFromModuleDetailsExtract(); + const extract = ExamsFromModuleDetailsExtract(); try { extract.extractExamsFromModuleDetails("Lorem ipsum"); diff --git a/test/dualis/service/parsing/monthly_schedule_extract_test.dart b/test/dualis/service/parsing/monthly_schedule_extract_test.dart index 425a8b25..fa32a675 100644 --- a/test/dualis/service/parsing/monthly_schedule_extract_test.dart +++ b/test/dualis/service/parsing/monthly_schedule_extract_test.dart @@ -9,7 +9,7 @@ Future main() async { ).readAsString(); test('MonthlyScheduleExtract extract all appointments', () async { - final extract = MonthlyScheduleExtract(); + const extract = MonthlyScheduleExtract(); final modules = extract.extractScheduleFromMonthly(monthlySchedulePage); diff --git a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart index abafc0ea..fd336485 100644 --- a/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart +++ b/test/dualis/service/parsing/semesters_from_course_result_page_extract_test.dart @@ -10,7 +10,7 @@ Future main() async { ).readAsString(); test('SemestersFromCourseResultPageExtract', () async { - final extract = SemestersFromCourseResultPageExtract(); + const extract = SemestersFromCourseResultPageExtract(); final semesters = extract.extractSemestersFromCourseResults( courseResultsPage, @@ -34,7 +34,7 @@ Future main() async { test('SemestersFromCourseResultPageExtract invalid html throws exception', () async { - final extract = SemestersFromCourseResultPageExtract(); + const extract = SemestersFromCourseResultPageExtract(); try { extract.extractSemestersFromCourseResults("Lorem ipsum", ""); diff --git a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart index 374142d4..eb01dc61 100644 --- a/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart +++ b/test/dualis/service/parsing/study_grades_from_student_results_page_extract_test.dart @@ -10,7 +10,7 @@ Future main() async { ).readAsString(); test('StudyGradesFromStudentResultsPageExtract', () async { - final extract = StudyGradesFromStudentResultsPageExtract(); + const extract = StudyGradesFromStudentResultsPageExtract(); final studyGrades = extract.extractStudyGradesFromStudentsResultsPage(studentResultsPage); @@ -24,7 +24,7 @@ Future main() async { test('StudyGradesFromStudentResultsPageExtract invalid html throws exception', () async { - final extract = StudyGradesFromStudentResultsPageExtract(); + const extract = StudyGradesFromStudentResultsPageExtract(); try { extract.extractStudyGradesFromStudentsResultsPage("Lorem ipsum"); diff --git a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart index 12365b16..14d37e37 100644 --- a/test/dualis/service/parsing/urls_from_main_page_extract_test.dart +++ b/test/dualis/service/parsing/urls_from_main_page_extract_test.dart @@ -11,7 +11,7 @@ Future main() async { ).readAsString(); test('UrlsFromMainPageExtract', () async { - final extract = UrlsFromMainPageExtract(); + const extract = UrlsFromMainPageExtract(); final mainPageUrls = DualisUrls(); @@ -33,7 +33,7 @@ Future main() async { }); test('UrlsFromMainPageExtract invalid html throws exception', () async { - final extract = UrlsFromMainPageExtract(); + const extract = UrlsFromMainPageExtract(); try { extract.parseMainPage("Lorem ipsum", DualisUrls(), ""); diff --git a/test/schedule/business/schedule_diff_calculator_test.dart b/test/schedule/business/schedule_diff_calculator_test.dart index c832c658..1bc4c182 100644 --- a/test/schedule/business/schedule_diff_calculator_test.dart +++ b/test/schedule/business/schedule_diff_calculator_test.dart @@ -5,7 +5,7 @@ import 'package:test/test.dart'; void main() { test('Diff detect identical schedules', () async { - final calculator = ScheduleDiffCalculator(); + const calculator = ScheduleDiffCalculator(); final oldSchedule = generateSchedule(); final newSchedule = generateSchedule(); @@ -18,7 +18,7 @@ void main() { }); test('Diff detect removed entry', () async { - final calculator = ScheduleDiffCalculator(); + const calculator = ScheduleDiffCalculator(); final oldSchedule = generateSchedule(); final newSchedule = generateSchedule(); @@ -35,7 +35,7 @@ void main() { }); test('Diff detect new entry', () async { - final calculator = ScheduleDiffCalculator(); + const calculator = ScheduleDiffCalculator(); final oldSchedule = generateSchedule(); final newSchedule = generateSchedule(); @@ -61,7 +61,7 @@ void main() { }); test('Diff detect changed entry (time)', () async { - final calculator = ScheduleDiffCalculator(); + const calculator = ScheduleDiffCalculator(); final oldSchedule = generateSchedule(); final newSchedule = generateSchedule(); @@ -88,7 +88,7 @@ void main() { }); test('Diff detect changed entry (start and room)', () async { - final calculator = ScheduleDiffCalculator(); + const calculator = ScheduleDiffCalculator(); final oldSchedule = generateSchedule(); final newSchedule = generateSchedule(); @@ -116,7 +116,7 @@ void main() { }); test('Diff detect two changed entries of same name (start)', () async { - final calculator = ScheduleDiffCalculator(); + const calculator = ScheduleDiffCalculator(); final oldSchedule = generateSchedule(); final newSchedule = generateSchedule(); diff --git a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart index 9a906026..d1db7b28 100644 --- a/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart +++ b/test/schedule/service/mannheim/mannheim_course_response_parser_test.dart @@ -9,7 +9,7 @@ Future main() async { ).readAsString(); test('Mannheim course parser parses correctly', () async { - final parser = MannheimCourseResponseParser(); + const parser = MannheimCourseResponseParser(); final courses = parser.parseCoursePage(coursePage);