diff --git a/lib/alarm/logic/alarm_controls.dart b/lib/alarm/logic/alarm_controls.dart index 72c7883c..0a4ed248 100644 --- a/lib/alarm/logic/alarm_controls.dart +++ b/lib/alarm/logic/alarm_controls.dart @@ -29,6 +29,19 @@ void triggerScheduledNotification(int scheduleId, Json params) async { print("Alarm triggered: $scheduleId"); } // print("Alarm Trigger Isolate: ${Service.getIsolateID(Isolate.current)}"); + if (params == null) { + if (kDebugMode) { + print("Params was null when triggering alarm"); + } + return; + } + + if (params['type'] == null) { + if (kDebugMode) { + print("Params Type was null when triggering alarm"); + } + return; + } ScheduledNotificationType notificationType = ScheduledNotificationType.values.byName(params['type']); @@ -72,6 +85,13 @@ void stopScheduledNotification(List message) { } void triggerAlarm(int scheduleId, Json params) async { + if (params == null) { + if (kDebugMode) { + print("Params was null when triggering alarm"); + } + return; + } + await updateAlarms(); GetStorage().write("fullScreenNotificationRecentlyShown", true); diff --git a/lib/alarm/screens/alarm_screen.dart b/lib/alarm/screens/alarm_screen.dart index 42787a59..2f3ebfdf 100644 --- a/lib/alarm/screens/alarm_screen.dart +++ b/lib/alarm/screens/alarm_screen.dart @@ -7,6 +7,7 @@ import 'package:clock_app/alarm/widgets/alarm_time_picker.dart'; import 'package:clock_app/common/logic/customize_screen.dart'; import 'package:clock_app/common/types/picker_result.dart'; import 'package:clock_app/common/types/time.dart'; +import 'package:clock_app/common/utils/json_serialize.dart'; import 'package:clock_app/common/widgets/fab.dart'; import 'package:clock_app/common/widgets/list/customize_list_item_screen.dart'; import 'package:clock_app/common/widgets/list/persistent_list_view.dart'; @@ -113,9 +114,14 @@ class _AlarmScreenState extends State { _handleCustomizeAlarm(Alarm alarm) async { int index = _listController.getItemIndex(alarm); + // if (index < 0) return; await _openCustomizeAlarmScreen(alarm, onSave: (newAlarm) { newAlarm.update(); - _listController.changeItems((alarms) => alarms[index] = newAlarm); + _listController.changeItems((alarms) { + print( + "alasasasrm ${alarms.map((alarms) => alarm.id).toList()}, ${alarm.id}"); + alarms[index] = newAlarm; + }); _showNextScheduleSnackBar(newAlarm); }); } diff --git a/lib/alarm/types/alarm.dart b/lib/alarm/types/alarm.dart index 50dbafb2..e3fc5767 100644 --- a/lib/alarm/types/alarm.dart +++ b/lib/alarm/types/alarm.dart @@ -34,7 +34,7 @@ List createSchedules(SettingGroup settings) { } class Alarm extends CustomizableListItem { - Time _time; + late Time _time; bool _isEnabled = true; bool _isFinished = false; DateTime? _snoozeTime; @@ -271,22 +271,27 @@ class Alarm extends CustomizableListItem { return (getSetting("Interval") as SelectSetting).value; } - Alarm.fromJson(Json json) - : _time = Time.fromJson(json['timeOfDay']), - _isEnabled = json['enabled'], - _isFinished = json['finished'], - _snoozeTime = json['snoozeTime'] != 0 - ? DateTime.fromMillisecondsSinceEpoch(json['snoozeTime']) - : null, - _snoozeCount = json['snoozeCount'], - _settings = SettingGroup( - "Alarm Settings", - appSettings - .getGroup("Alarm") - .getGroup("Default Settings") - .copy() - .settingItems, - ) { + Alarm.fromJson(Json json) { + if (json == null) { + _time = Time.now(); + _schedules = createSchedules(_settings); + return; + } + _time = Time.fromJson(json['timeOfDay']); + _isEnabled = json['enabled']; + _isFinished = json['finished']; + _snoozeTime = json['snoozeTime'] != 0 + ? DateTime.fromMillisecondsSinceEpoch(json['snoozeTime']) + : null; + _snoozeCount = json['snoozeCount']; + _settings = SettingGroup( + "Alarm Settings", + appSettings + .getGroup("Alarm") + .getGroup("Default Settings") + .copy() + .settingItems, + ); _settings.loadValueFromJson(json['settings']); _schedules = [ OnceAlarmSchedule.fromJson(json['schedules'][0]), diff --git a/lib/alarm/types/alarm_runner.dart b/lib/alarm/types/alarm_runner.dart index e3d5b616..b26cccf7 100644 --- a/lib/alarm/types/alarm_runner.dart +++ b/lib/alarm/types/alarm_runner.dart @@ -23,12 +23,17 @@ class AlarmRunner extends JsonSerializable { cancelAlarm(_id); } - AlarmRunner.fromJson(Json json) : _id = json['id'] { - int millisecondsSinceEpoch = json['currentScheduleDateTime']; - + AlarmRunner.fromJson(Json? json) { + if (json == null) { + _id = UniqueKey().hashCode; + return; + } + _id = json['id'] ?? UniqueKey().hashCode; + int millisecondsSinceEpoch = json['currentScheduleDateTime'] ?? 0; _currentScheduleDateTime = millisecondsSinceEpoch == 0 ? null - : DateTime.fromMillisecondsSinceEpoch(json['currentScheduleDateTime']); + : DateTime.fromMillisecondsSinceEpoch( + json['currentScheduleDateTime'] ?? 0); } @override diff --git a/lib/alarm/types/alarm_task.dart b/lib/alarm/types/alarm_task.dart index 4aedf8c2..e73b767d 100644 --- a/lib/alarm/types/alarm_task.dart +++ b/lib/alarm/types/alarm_task.dart @@ -31,7 +31,8 @@ class AlarmTaskSchema extends JsonSerializable { return _builder(onSolve, settings); } - void loadFromJson(Json json) { + void loadFromJson(Json? json) { + if (json == null) return; settings.loadValueFromJson(json['settings']); } @@ -48,7 +49,7 @@ class AlarmTaskSchema extends JsonSerializable { } class AlarmTask extends CustomizableListItem { - final AlarmTaskType type; + late final AlarmTaskType type; late final AlarmTaskSchema _schema; AlarmTask(this.type) : _schema = alarmTaskSchemasMap[type]!.copy(); @@ -57,8 +58,13 @@ class AlarmTask extends CustomizableListItem { : type = task.type, _schema = task._schema.copy(); - AlarmTask.fromJson(Json json) - : type = AlarmTaskType.values.byName(json['type']) { + AlarmTask.fromJson(Json json) { + if (json == null) { + type = AlarmTaskType.math; + _schema = alarmTaskSchemasMap[type]!.copy(); + return; + } + type = AlarmTaskType.values.byName(json['type']); _schema = alarmTaskSchemasMap[type]!.copy(); _schema.loadFromJson(json['schema']); } diff --git a/lib/alarm/types/schedules/daily_alarm_schedule.dart b/lib/alarm/types/schedules/daily_alarm_schedule.dart index d36e4a3f..3bd66c74 100644 --- a/lib/alarm/types/schedules/daily_alarm_schedule.dart +++ b/lib/alarm/types/schedules/daily_alarm_schedule.dart @@ -5,7 +5,7 @@ import 'package:clock_app/common/types/json.dart'; import 'package:clock_app/common/types/time.dart'; class DailyAlarmSchedule extends AlarmSchedule { - final AlarmRunner _alarmRunner; + late final AlarmRunner _alarmRunner; @override DateTime? get currentScheduleDateTime => _alarmRunner.currentScheduleDateTime; @@ -39,9 +39,13 @@ class DailyAlarmSchedule extends AlarmSchedule { 'alarmRunner': _alarmRunner.toJson(), }; - DailyAlarmSchedule.fromJson(Json json) - : _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']), - super(); + DailyAlarmSchedule.fromJson(Json json) { + if (json == null) { + _alarmRunner = AlarmRunner(); + return; + } + _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + } @override bool hasId(int id) { diff --git a/lib/alarm/types/schedules/dates_alarm_schedule.dart b/lib/alarm/types/schedules/dates_alarm_schedule.dart index fe62c4e5..c7fbe7db 100644 --- a/lib/alarm/types/schedules/dates_alarm_schedule.dart +++ b/lib/alarm/types/schedules/dates_alarm_schedule.dart @@ -5,14 +5,19 @@ import 'package:clock_app/common/types/time.dart'; import 'package:clock_app/settings/types/setting.dart'; class DateSchedule extends JsonSerializable { - DateTime date; - AlarmRunner alarmRunner; + late DateTime date; + late AlarmRunner alarmRunner; DateSchedule(this.date) : alarmRunner = AlarmRunner(); - DateSchedule.fromJson(Json json) - : date = DateTime.parse(json['date']), - alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + DateSchedule.fromJson(Json json) { + if (json == null) { + date = DateTime.now(); + return; + } + date = json['date'] != null ? DateTime.parse(json['date']) : DateTime.now(); + alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + } @override Json toJson() => { @@ -23,9 +28,9 @@ class DateSchedule extends JsonSerializable { class DatesAlarmSchedule extends AlarmSchedule { // List _weekdaySchedules = []; - final DateTimeSetting _datesSetting; - final AlarmRunner _alarmRunner; - bool _isFinished; + late final DateTimeSetting _datesSetting; + late final AlarmRunner _alarmRunner; + late bool _isFinished; @override bool get isDisabled => false; @@ -86,11 +91,16 @@ class DatesAlarmSchedule extends AlarmSchedule { 'isFinished': _isFinished, }; - DatesAlarmSchedule.fromJson(Json json, Setting datesSetting) - : _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']), - _datesSetting = datesSetting as DateTimeSetting, - _isFinished = json['isFinished'], - super(); + DatesAlarmSchedule.fromJson(Json json, Setting datesSetting) : super() { + _datesSetting = datesSetting as DateTimeSetting; + if (json == null) { + _alarmRunner = AlarmRunner(); + _isFinished = false; + return; + } + _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + _isFinished = json['isFinished'] ?? false; + } @override bool hasId(int id) { diff --git a/lib/alarm/types/schedules/once_alarm_schedule.dart b/lib/alarm/types/schedules/once_alarm_schedule.dart index ee623b72..9467fdfe 100644 --- a/lib/alarm/types/schedules/once_alarm_schedule.dart +++ b/lib/alarm/types/schedules/once_alarm_schedule.dart @@ -46,10 +46,14 @@ class OnceAlarmSchedule extends AlarmSchedule { 'isDisabled': _isDisabled, }; - OnceAlarmSchedule.fromJson(Json json) - : _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']), - _isDisabled = json['isDisabled'], - super(); + OnceAlarmSchedule.fromJson(Json json) { + if (json == null) { + _alarmRunner = AlarmRunner(); + return; + } + _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + _isDisabled = json['isDisabled'] ?? false; + } @override bool hasId(int id) { diff --git a/lib/alarm/types/schedules/range_alarm_schedule.dart b/lib/alarm/types/schedules/range_alarm_schedule.dart index bde53767..c5f76906 100644 --- a/lib/alarm/types/schedules/range_alarm_schedule.dart +++ b/lib/alarm/types/schedules/range_alarm_schedule.dart @@ -8,8 +8,8 @@ import 'package:clock_app/settings/types/setting.dart'; class RangeAlarmSchedule extends AlarmSchedule { late final AlarmRunner _alarmRunner; - final DateTimeSetting _datesRangeSetting; - final SelectSetting _intervalSetting; + late final DateTimeSetting _datesRangeSetting; + late final SelectSetting _intervalSetting; bool _isFinished = false; RangeInterval get interval => _intervalSetting.value; @@ -66,11 +66,15 @@ class RangeAlarmSchedule extends AlarmSchedule { }; RangeAlarmSchedule.fromJson( - Json json, Setting datesRangeSetting, Setting intervalSetting) - : _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']), - _datesRangeSetting = datesRangeSetting as DateTimeSetting, - _intervalSetting = intervalSetting as SelectSetting, - super(); + Json json, Setting datesRangeSetting, Setting intervalSetting) { + _datesRangeSetting = datesRangeSetting as DateTimeSetting; + _intervalSetting = intervalSetting as SelectSetting; + if (json == null) { + _alarmRunner = AlarmRunner(); + return; + } + _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + } @override bool hasId(int id) { diff --git a/lib/alarm/types/schedules/weekly_alarm_schedule.dart b/lib/alarm/types/schedules/weekly_alarm_schedule.dart index 8f99677b..de1e17f1 100644 --- a/lib/alarm/types/schedules/weekly_alarm_schedule.dart +++ b/lib/alarm/types/schedules/weekly_alarm_schedule.dart @@ -9,14 +9,19 @@ import 'package:clock_app/settings/types/setting.dart'; import 'package:flutter/foundation.dart'; class WeekdaySchedule extends JsonSerializable { - int weekday; - AlarmRunner alarmRunner; + int weekday = 0; + late AlarmRunner alarmRunner; WeekdaySchedule(this.weekday) : alarmRunner = AlarmRunner(); - WeekdaySchedule.fromJson(Json json) - : weekday = json['weekday'], - alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + WeekdaySchedule.fromJson(Json json) { + if (json == null) { + alarmRunner = AlarmRunner(); + return; + } + weekday = json['weekday']; + alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + } @override Json toJson() => { @@ -26,8 +31,11 @@ class WeekdaySchedule extends JsonSerializable { } class WeeklyAlarmSchedule extends AlarmSchedule { - List _weekdaySchedules = []; - final ToggleSetting _weekdaySetting; + // This is just a dummy alarmRunner so we get a consistent currentAlarmRunnerId; + late final AlarmRunner _alarmRunner; + + late List _weekdaySchedules = []; + late final ToggleSetting _weekdaySetting; @override bool get isDisabled => false; @@ -44,15 +52,21 @@ class WeeklyAlarmSchedule extends AlarmSchedule { WeekdaySchedule get nextWeekdaySchedule { if (_weekdaySchedules.isEmpty) return WeekdaySchedule(0); - if (_weekdaySchedules.any((weeklySchedule) => - weeklySchedule.alarmRunner.currentScheduleDateTime == null)) { - return _weekdaySchedules[0]; + if (_weekdaySchedules.every( + (element) => element.alarmRunner.currentScheduleDateTime == null)) { + return WeekdaySchedule(0); } - return _weekdaySchedules.reduce((a, b) => a - .alarmRunner.currentScheduleDateTime! - .isBefore(b.alarmRunner.currentScheduleDateTime!) - ? a - : b); + return _weekdaySchedules.reduce((a, b) { + if (a.alarmRunner.currentScheduleDateTime == null) return b; + if (b.alarmRunner.currentScheduleDateTime == null) return a; + + if (a.alarmRunner.currentScheduleDateTime! + .isBefore(b.alarmRunner.currentScheduleDateTime!)) { + return a; + } else { + return b; + } + }); } @override @@ -60,10 +74,13 @@ class WeeklyAlarmSchedule extends AlarmSchedule { nextWeekdaySchedule.alarmRunner.currentScheduleDateTime; @override - int get currentAlarmRunnerId => nextWeekdaySchedule.alarmRunner.id; + int get currentAlarmRunnerId => _alarmRunner.id; + + int get currentWeekdayAlarmRunnerId => nextWeekdaySchedule.alarmRunner.id; WeeklyAlarmSchedule(Setting weekdaySetting) : _weekdaySetting = weekdaySetting as ToggleSetting, + _alarmRunner = AlarmRunner(), super(); @override @@ -99,16 +116,22 @@ class WeeklyAlarmSchedule extends AlarmSchedule { @override toJson() { return { + 'alarmRunner': _alarmRunner.toJson(), 'weekdaySchedules': _weekdaySchedules.map((e) => e.toJson()).toList(), }; } - WeeklyAlarmSchedule.fromJson(Json json, Setting weekdaySetting) - : _weekdaySchedules = (json['weekdaySchedules'] as List) - .map((e) => WeekdaySchedule.fromJson(e)) - .toList(), - _weekdaySetting = weekdaySetting as ToggleSetting, - super(); + WeeklyAlarmSchedule.fromJson(Json json, Setting weekdaySetting) { + _weekdaySetting = weekdaySetting as ToggleSetting; + if (json == null) { + _alarmRunner = AlarmRunner(); + return; + } + _weekdaySchedules = ((json['weekdaySchedules'] ?? []) as List) + .map((e) => WeekdaySchedule.fromJson(e)) + .toList(); + _alarmRunner = AlarmRunner.fromJson(json['alarmRunner']); + } @override bool hasId(int id) { diff --git a/lib/audio/types/audio.dart b/lib/audio/types/audio.dart index 7d0a07be..4d58ca00 100644 --- a/lib/audio/types/audio.dart +++ b/lib/audio/types/audio.dart @@ -13,10 +13,10 @@ class Audio { required this.uri, }); - factory Audio.fromJson(Json map) => Audio( - id: map['id'] as String, - title: map['title'] as String, - uri: map['uri'] as String, + factory Audio.fromJson(Json json) => Audio( + id: json != null ? json['id'] ?? '' : '', + title: json != null ? json['title'] ?? 'Unknown' : 'Unknown', + uri: json != null ? json['uri'] ?? '' : '', ); Json toJson() => { diff --git a/lib/clock/types/city.dart b/lib/clock/types/city.dart index 9b313b8d..1cc860e4 100644 --- a/lib/clock/types/city.dart +++ b/lib/clock/types/city.dart @@ -3,10 +3,10 @@ import 'package:clock_app/common/types/list_item.dart'; import 'package:flutter/material.dart'; class City extends ListItem { - final String _name; - final String _country; - final String _timezone; - late final int _id; + late String _name = "Unknown"; + late String _country = "Unknown"; + late String _timezone = 'America/Detroit'; + late int _id; String get name => _name; String get country => _country; @@ -24,11 +24,16 @@ class City extends ListItem { return City(name, country, timezone); } - City.fromJson(Json jsonData) - : _name = jsonData['name'], - _country = jsonData['country'], - _timezone = jsonData['timezone'], - _id = jsonData['id']; + City.fromJson(Json json) { + if (json == null) { + _id = UniqueKey().hashCode; + return; + } + _name = json['name'] ?? 'Unknown'; + _country = json['country'] ?? 'Unknown'; + _timezone = json['timezone'] ?? 'America/Detroit'; + _id = json['id'] ?? UniqueKey().hashCode; + } @override Json toJson() => { diff --git a/lib/common/types/json.dart b/lib/common/types/json.dart index b74122a3..9ecd7a59 100644 --- a/lib/common/types/json.dart +++ b/lib/common/types/json.dart @@ -1,4 +1,4 @@ -typedef Json = Map; +typedef Json = Map?; abstract class JsonSerializable { const JsonSerializable(); diff --git a/lib/common/types/time.dart b/lib/common/types/time.dart index a7334295..f594bc1f 100644 --- a/lib/common/types/time.dart +++ b/lib/common/types/time.dart @@ -32,9 +32,9 @@ class Time extends JsonSerializable { } Time.fromJson(Json json) - : hour = json['hours'], - minute = json['minutes'], - second = json['seconds']; + : hour = json != null ? json['hours'] ?? 0 : 0, + minute = json != null ? json['minutes'] ?? 0 : 0, + second = json != null ? json['seconds'] ?? 0 : 0; @override Json toJson() { diff --git a/lib/common/utils/time_of_day.dart b/lib/common/utils/time_of_day.dart index 1e479dbc..cbb9eaf8 100644 --- a/lib/common/utils/time_of_day.dart +++ b/lib/common/utils/time_of_day.dart @@ -27,8 +27,8 @@ extension TimeOfDayUtils on TimeOfDay { } static TimeOfDay fromJson(Json json) => TimeOfDay( - hour: json['hour'], - minute: json['minute'], + hour: json != null ? json['hour'] ?? 0 : 0, + minute: json != null ? json['minute'] ?? 0 : 0, ); DateTime toDateTime() { diff --git a/lib/settings/types/vendor.dart b/lib/settings/types/vendor.dart index 896e0104..ae3b8143 100644 --- a/lib/settings/types/vendor.dart +++ b/lib/settings/types/vendor.dart @@ -10,6 +10,6 @@ class Vendor { }); Vendor.fromJson(Json json) - : name = json['name'], - url = json['url'] {} + : name = json != null ? json['name'] ?? 'Unknown' : 'Unknown', + url = json != null ? json['url'] ?? '' : ''; } diff --git a/lib/settings/widgets/list_setting_add_bottom_sheet.dart b/lib/settings/widgets/list_setting_add_bottom_sheet.dart index 951f5583..347252d8 100644 --- a/lib/settings/widgets/list_setting_add_bottom_sheet.dart +++ b/lib/settings/widgets/list_setting_add_bottom_sheet.dart @@ -22,7 +22,7 @@ class ListSettingAddBottomSheet height: MediaQuery.of(context).size.height * 0.7, child: Container( decoration: BoxDecoration( - color: theme.colorScheme.background, + color: theme.colorScheme.surface, borderRadius: borderRadius, ), child: Column( @@ -34,7 +34,7 @@ class ListSettingAddBottomSheet child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(64), - color: theme.colorScheme.onBackground.withOpacity(0.6)), + color: theme.colorScheme.onSurface.withOpacity(0.6)), ), ), const SizedBox(height: 12.0), @@ -46,7 +46,7 @@ class ListSettingAddBottomSheet Text( "Choose Task to Add", style: theme.textTheme.titleMedium?.copyWith( - color: theme.colorScheme.onBackground.withOpacity(0.6)), + color: theme.colorScheme.onSurface.withOpacity(0.6)), ), ], ), diff --git a/lib/stopwatch/types/lap.dart b/lib/stopwatch/types/lap.dart index be4956d6..3330cb47 100644 --- a/lib/stopwatch/types/lap.dart +++ b/lib/stopwatch/types/lap.dart @@ -3,9 +3,9 @@ import 'package:clock_app/common/types/list_item.dart'; import 'package:clock_app/timer/types/time_duration.dart'; class Lap extends ListItem { - final int number; - final TimeDuration lapTime; - final TimeDuration elapsedTime; + late final int number; + late final TimeDuration lapTime; + late final TimeDuration elapsedTime; @override int get id => number; @@ -14,10 +14,17 @@ class Lap extends ListItem { Lap({required this.elapsedTime, required this.number, required this.lapTime}); - Lap.fromJson(Json json) - : number = json['number'], - lapTime = TimeDuration.fromJson(json['lapTime']), - elapsedTime = TimeDuration.fromJson(json['elapsedTime']); + Lap.fromJson(Json? json) { + if (json == null) { + number = 0; + lapTime = TimeDuration.zero; + elapsedTime = TimeDuration.zero; + return; + } + number = json['number'] ?? 0; + lapTime = TimeDuration.fromJson(json['lapTime']); + elapsedTime = TimeDuration.fromJson(json['elapsedTime']); + } @override Json toJson() => { diff --git a/lib/stopwatch/types/stopwatch.dart b/lib/stopwatch/types/stopwatch.dart index 9ae6b1c5..a2921a3a 100644 --- a/lib/stopwatch/types/stopwatch.dart +++ b/lib/stopwatch/types/stopwatch.dart @@ -6,10 +6,10 @@ import 'package:clock_app/timer/types/time_duration.dart'; import 'package:flutter/material.dart'; class ClockStopwatch extends JsonSerializable { - int _elapsedMillisecondsOnPause; - DateTime _startTime; - TimerState _state; - final int _id; + int _elapsedMillisecondsOnPause = 0; + DateTime _startTime = DateTime(0); + TimerState _state = TimerState.stopped; + late final int _id; List _laps = []; Lap? _fastestLap; Lap? _slowestLap; @@ -114,18 +114,26 @@ class ClockStopwatch extends JsonSerializable { Json toJson() { return { 'id': _id, - '_elapsedMillisecondsOnPause': _elapsedMillisecondsOnPause, + 'elapsedMillisecondsOnPause': _elapsedMillisecondsOnPause, 'startTime': _startTime.toIso8601String(), 'state': _state.toString(), 'laps': _laps.map((e) => e.toJson()).toList(), }; } - ClockStopwatch.fromJson(Json json) - : _elapsedMillisecondsOnPause = json['_elapsedMillisecondsOnPause'], - _startTime = DateTime.parse(json['startTime']), - _state = - TimerState.values.firstWhere((e) => e.toString() == json['state']), - _id = json['id'], - _laps = (json['laps'] as List).map((e) => Lap.fromJson(e)).toList(); + ClockStopwatch.fromJson(Json json) { + if (json == null) { + _id = UniqueKey().hashCode; + return; + } + _elapsedMillisecondsOnPause = json['elapsedMillisecondsOnPause'] ?? 0; + _startTime = json['startTime'] != null + ? DateTime.parse(json['startTime']) + : DateTime.now(); + _state = TimerState.values.firstWhere( + (e) => e.toString() == (json['state'] ?? ''), + orElse: () => TimerState.stopped); + _id = json['id'] ?? UniqueKey().hashCode; + _laps = ((json['laps'] ?? []) as List).map((e) => Lap.fromJson(e)).toList(); + } } diff --git a/lib/theme/types/theme_item.dart b/lib/theme/types/theme_item.dart index 601a7e9c..30d805d4 100644 --- a/lib/theme/types/theme_item.dart +++ b/lib/theme/types/theme_item.dart @@ -4,9 +4,9 @@ import 'package:clock_app/settings/types/setting_group.dart'; import 'package:flutter/material.dart'; abstract class ThemeItem extends CustomizableListItem { - final int _id; + late final int _id; final SettingGroup _settings; - final bool _isDefault; + bool _isDefault = false; ThemeItem(SettingGroup defaultSettings, bool isDefault, [int? id]) : _id = id ?? UniqueKey().hashCode, @@ -36,10 +36,13 @@ abstract class ThemeItem extends CustomizableListItem { }; } - ThemeItem.fromJson(Json json, SettingGroup settings) - : _id = json['id'], - _isDefault = json['isDefault'], - _settings = settings { + ThemeItem.fromJson(Json json, SettingGroup settings) : _settings = settings { + if (json == null) { + _id = UniqueKey().hashCode; + return; + } + _id = json['id'] ?? UniqueKey().hashCode; + _isDefault = json['isDefault'] ?? false; settings.loadValueFromJson(json['settings']); } } diff --git a/lib/timer/types/time_duration.dart b/lib/timer/types/time_duration.dart index 1ded66b9..10a49528 100644 --- a/lib/timer/types/time_duration.dart +++ b/lib/timer/types/time_duration.dart @@ -92,8 +92,8 @@ class TimeDuration extends JsonSerializable { }; TimeDuration.fromJson(Json json) - : hours = json['hours'], - minutes = json['minutes'], - seconds = json['seconds'], - milliseconds = json['milliseconds']; + : hours = json != null ? json['hours'] ?? 0 : 0, + minutes = json != null ? json['minutes'] ?? 0 : 0, + seconds = json != null ? json['seconds'] ?? 0 : 0, + milliseconds = json != null ? json['milliseconds'] ?? 0 : 0; } diff --git a/lib/timer/types/timer.dart b/lib/timer/types/timer.dart index 947e2aae..b0d208c0 100644 --- a/lib/timer/types/timer.dart +++ b/lib/timer/types/timer.dart @@ -14,12 +14,12 @@ import 'package:clock_app/common/utils/duration.dart'; import 'package:clock_app/timer/types/time_duration.dart'; class ClockTimer extends CustomizableListItem { - TimeDuration _duration; - TimeDuration _currentDuration; - int _secondsRemainingOnPause; - DateTime _startTime; - TimerState _state; - final int _id; + TimeDuration _duration = TimeDuration.fromSeconds(5); + TimeDuration _currentDuration = TimeDuration.fromSeconds(5); + int _secondsRemainingOnPause = 5; + DateTime _startTime = DateTime(0); + TimerState _state = TimerState.stopped; + late final int _id; SettingGroup _settings = SettingGroup( "Timer Settings", appSettings @@ -164,22 +164,28 @@ class ClockTimer extends CustomizableListItem { }; } - ClockTimer.fromJson(Json json) - : _duration = TimeDuration.fromSeconds(json['duration']), - _currentDuration = TimeDuration.fromSeconds(json['currentDuration']), - _secondsRemainingOnPause = json['durationRemainingOnPause'], - _startTime = DateTime.parse(json['startTime']), - _state = - TimerState.values.firstWhere((e) => e.toString() == json['state']), - _id = json['id'], - _settings = SettingGroup( - "Timer Settings", - appSettings - .getGroup("Timer") - .getGroup("Default Settings") - .copy() - .settingItems, - ) { + ClockTimer.fromJson(Json json) { + if (json == null) { + _id = UniqueKey().hashCode; + return; + } + _duration = TimeDuration.fromSeconds(json['duration'] ?? 0); + _currentDuration = TimeDuration.fromSeconds(json['currentDuration'] ?? 0); + _secondsRemainingOnPause = json['durationRemainingOnPause'] ?? 0; + _startTime = json['startTime'] != null + ? DateTime.parse(json['startTime']) + : DateTime.now(); + _state = TimerState.values.firstWhere((e) => e.toString() == json['state'], + orElse: () => TimerState.stopped); + _id = json['id'] ?? UniqueKey().hashCode; + _settings = SettingGroup( + "Timer Settings", + appSettings + .getGroup("Timer") + .getGroup("Default Settings") + .copy() + .settingItems, + ); _settings.loadValueFromJson(json['settings']); } diff --git a/lib/timer/types/timer_preset.dart b/lib/timer/types/timer_preset.dart index ec8ce4a7..1d587110 100644 --- a/lib/timer/types/timer_preset.dart +++ b/lib/timer/types/timer_preset.dart @@ -4,9 +4,9 @@ import 'package:clock_app/timer/types/time_duration.dart'; import 'package:flutter/foundation.dart'; class TimerPreset extends ListItem { - final int _id; - String name; - TimeDuration duration; + late final int _id; + String name = "Preset"; + TimeDuration duration = const TimeDuration(minutes: 5); TimerPreset(this.name, this.duration) : _id = UniqueKey().hashCode; @override @@ -26,10 +26,15 @@ class TimerPreset extends ListItem { 'duration': duration.toJson(), }; - TimerPreset.fromJson(Json json) - : _id = json['id'], - name = json['name'], - duration = TimeDuration.fromJson(json['duration']); + TimerPreset.fromJson(Json json) { + if (json == null) { + _id = UniqueKey().hashCode; + return; + } + _id = json['id'] ?? UniqueKey().hashCode; + name = json['name'] ?? "Preset"; + duration = TimeDuration.fromJson(json['duration']); + } @override copy() { diff --git a/test/alarm/types/schedules/weekly_alarm_schedule_test.dart b/test/alarm/types/schedules/weekly_alarm_schedule_test.dart index eac17c81..d7fd4b1a 100644 --- a/test/alarm/types/schedules/weekly_alarm_schedule_test.dart +++ b/test/alarm/types/schedules/weekly_alarm_schedule_test.dart @@ -97,7 +97,7 @@ void main() { }); test('returns true when id is in alarmRunners', () { schedule.schedule(const Time(hour: 10, minute: 30)); - expect(schedule.hasId(schedule.currentAlarmRunnerId), true); + expect(schedule.hasId(schedule.currentWeekdayAlarmRunnerId), true); }); }); @@ -134,12 +134,16 @@ void main() { final weekdayScheduleJson = { 'weekday': 1, 'alarmRunner': { - 'id': schedule.currentAlarmRunnerId, + 'id': schedule.currentWeekdayAlarmRunnerId, 'currentScheduleDateTime': schedule.currentScheduleDateTime?.millisecondsSinceEpoch, }, }; final weeklyScheduleJson = { + 'alarmRunner': { + 'id': schedule.currentAlarmRunnerId, + 'currentScheduleDateTime': 0, + }, 'weekdaySchedules': [weekdayScheduleJson], }; @@ -157,6 +161,10 @@ void main() { }, }; final weeklyScheduleJson = { + 'alarmRunner': { + 'id': 60, + 'currentScheduleDateTime': 0, + }, 'weekdaySchedules': [weekdayScheduleJson], }; @@ -165,7 +173,8 @@ void main() { expect(weeklySchedule.scheduledWeekdays.length, 1); expect(weeklySchedule.scheduledWeekdays[0].id, 1); - expect(weeklySchedule.currentAlarmRunnerId, 50); + expect(weeklySchedule.currentAlarmRunnerId, 60); + expect(weeklySchedule.currentWeekdayAlarmRunnerId, 50); expect(weeklySchedule.currentScheduleDateTime?.millisecondsSinceEpoch, dateTime.millisecondsSinceEpoch); });