From 08db53db20cbed8819f0da868042be3d0b34b890 Mon Sep 17 00:00:00 2001 From: Andreas Fahrecker Date: Thu, 18 Mar 2021 18:34:29 +0100 Subject: [PATCH] Updated Flutter SDK for Null-Safety Ported Progress Detail Screen to PlatformScaffold Signed-off-by: Andreas Fahrecker --- lib/app.dart | 4 +- lib/models/app_settings.dart | 20 ++-- lib/models/time_progress.dart | 15 +-- lib/persistence/app_settings.dart | 11 +- lib/persistence/time_progress.dart | 2 +- lib/redux/app_state.dart | 9 +- lib/redux/reducers/model_reducers.dart | 3 +- lib/redux/redux_selectors.dart | 10 +- .../create_time_progress_store_connector.dart | 2 +- .../settings_store_connector.dart | 2 +- .../time_progress_list_store_connector.dart | 2 +- .../time_progress_store_connector.dart | 8 +- lib/ui/app_yes_no_dialog_widget.dart | 8 +- lib/ui/buttons/color_picker_btn.dart | 12 +-- lib/ui/buttons/create_progress_button.dart | 2 +- lib/ui/buttons/date_picker_btn.dart | 12 +-- .../buttons/detail_screen_leading_button.dart | 34 ++++++ .../detail_screen_trailing_button.dart | 31 ++++++ lib/ui/buttons/platform_action_button.dart | 13 ++- lib/ui/buttons/select_duration_btn.dart | 6 +- ...detail_screen_floating_action_buttons.dart | 16 +-- lib/ui/progress/progress_editor_widget.dart | 4 +- lib/ui/progress/progress_list_item.dart | 6 +- lib/ui/progress/progress_list_view.dart | 6 +- lib/ui/progress/progress_view_widget.dart | 6 +- lib/ui/screens/dashboard_screen.dart | 2 +- lib/ui/screens/progress_creation_screen.dart | 8 +- lib/ui/screens/progress_detail_screen.dart | 101 +++++++++++------- lib/ui/settings/color_settings_widget.dart | 8 +- lib/ui/settings/duration_settings_widget.dart | 4 +- lib/utils/constants.dart | 10 +- lib/utils/helper_functions.dart | 2 +- pubspec.lock | 2 +- pubspec.yaml | 2 +- 34 files changed, 245 insertions(+), 138 deletions(-) create mode 100644 lib/ui/buttons/detail_screen_leading_button.dart create mode 100644 lib/ui/buttons/detail_screen_trailing_button.dart diff --git a/lib/app.dart b/lib/app.dart index 773bf0a..bbdf081 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -13,8 +13,8 @@ class TimeProgressTrackerApp extends StatelessWidget { final Store store; TimeProgressTrackerApp({ - Key key, - this.store, + Key? key, + required this.store, }) : super(key: key); @override diff --git a/lib/models/app_settings.dart b/lib/models/app_settings.dart index 120da4e..c124a60 100644 --- a/lib/models/app_settings.dart +++ b/lib/models/app_settings.dart @@ -7,22 +7,16 @@ class AppSettings { final Color leftColor; final Duration duration; - AppSettings({ - this.doneColor, - this.leftColor, - this.duration, + const AppSettings({ + required this.doneColor, + required this.leftColor, + required this.duration, }); - factory AppSettings.defaults() => AppSettings( - doneColor: Colors.green, - leftColor: Colors.red, - duration: Duration(days: 365), - ); - AppSettings copyWith({ - Color doneColor, - Color leftColor, - Duration duration, + Color? doneColor, + Color? leftColor, + Duration? duration, }) => AppSettings( doneColor: doneColor ?? this.doneColor, diff --git a/lib/models/time_progress.dart b/lib/models/time_progress.dart index dfc387e..ee02ba4 100644 --- a/lib/models/time_progress.dart +++ b/lib/models/time_progress.dart @@ -10,7 +10,7 @@ class TimeProgress { final DateTime startTime; final DateTime endTime; - TimeProgress(this.name, this.startTime, this.endTime, {String id}) + TimeProgress(this.name, this.startTime, this.endTime, {String? id}) : id = id ?? Uuid().generateV4(); factory TimeProgress.initialDefault() { @@ -23,7 +23,7 @@ class TimeProgress { TimeProgress("", DateTime.now(), DateTime.now().add(duration)); TimeProgress copyWith( - {String id, String name, DateTime startTime, DateTime endTime}) => + {String? id, String? name, DateTime? startTime, DateTime? endTime}) => TimeProgress( name ?? this.name, startTime ?? this.startTime, @@ -87,16 +87,19 @@ class TimeProgress { return TimeProgressEntity(id, name, startTime, endTime); } - static TimeProgress fromEntity(TimeProgressEntity entity) => - TimeProgress(entity.name, entity.startTime, entity.endTime, - id: entity.id ?? Uuid().generateV4()); + static TimeProgress fromEntity(TimeProgressEntity entity) => TimeProgress( + entity.name, + entity.startTime, + entity.endTime, + id: entity.id, + ); static bool isValid(TimeProgress tp) => TimeProgress.isNameValid(tp.name) && TimeProgress.areTimesValid(tp.startTime, tp.endTime); static bool isNameValid(String name) => - name != null && name != "" && name.length > 2 && name.length < 21; + name != "" && name.length > 2 && name.length < 21; static bool areTimesValid(DateTime startTime, DateTime endTime) => startTime.isBefore(endTime); diff --git a/lib/persistence/app_settings.dart b/lib/persistence/app_settings.dart index fce1891..936d119 100644 --- a/lib/persistence/app_settings.dart +++ b/lib/persistence/app_settings.dart @@ -1,6 +1,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:time_progress_tracker/models/app_settings.dart'; import 'package:time_progress_tracker/persistence/repository.dart'; +import 'package:time_progress_tracker/utils/constants.dart'; class AppSettingsRepository extends Repository { static const String _key = "app_settings"; @@ -9,7 +10,7 @@ class AppSettingsRepository extends Repository { @override Future load() { - final String jsonString = this.prefs.getString(_key); + final String? jsonString = this.prefs.getString(_key); if (jsonString == null) return Future.value(AppSettingsEntity.defaults()); return Future.value( @@ -30,7 +31,7 @@ class AppSettingsEntity { AppSettingsEntity( this.doneColorValue, this.leftColorValue, this.durationDays); - factory AppSettingsEntity.defaults() => AppSettings.defaults().toEntity(); + factory AppSettingsEntity.defaults() => defaultAppSettings.toEntity(); @override int get hashCode => doneColorValue.hashCode ^ leftColorValue.hashCode; @@ -51,8 +52,8 @@ class AppSettingsEntity { static AppSettingsEntity fromJson(Map json) => AppSettingsEntity( - json[_doneKey], - json[_leftKey], - json[_durationDaysKey], + json[_doneKey] as int, + json[_leftKey] as int, + json[_durationDaysKey] as int, ); } diff --git a/lib/persistence/time_progress.dart b/lib/persistence/time_progress.dart index 0948219..af58842 100644 --- a/lib/persistence/time_progress.dart +++ b/lib/persistence/time_progress.dart @@ -8,7 +8,7 @@ class TimeProgressRepository extends Repository> { @override Future> load() { - final String jsonString = this.prefs.getString(_key); + final String? jsonString = this.prefs.getString(_key); if (jsonString == null) { return Future>.value([]); } diff --git a/lib/redux/app_state.dart b/lib/redux/app_state.dart index 350aa42..aeae525 100644 --- a/lib/redux/app_state.dart +++ b/lib/redux/app_state.dart @@ -1,6 +1,7 @@ import 'package:meta/meta.dart'; import 'package:time_progress_tracker/models/app_settings.dart'; import 'package:time_progress_tracker/models/time_progress.dart'; +import 'package:time_progress_tracker/utils/constants.dart'; @immutable class AppState { @@ -12,14 +13,14 @@ class AppState { {this.hasProgressesLoaded = false, this.hasSettingsLoaded = false, this.timeProgressList = const [], - this.appSettings}); + this.appSettings = defaultAppSettings}); factory AppState.initial() => - AppState(hasProgressesLoaded: false, appSettings: AppSettings.defaults()); + AppState(hasProgressesLoaded: false, appSettings: defaultAppSettings); AppState copyWith({ - bool hasLoaded, - List timeProgressList, + bool? hasLoaded, + List? timeProgressList, }) { return AppState( hasProgressesLoaded: hasLoaded ?? this.hasProgressesLoaded, diff --git a/lib/redux/reducers/model_reducers.dart b/lib/redux/reducers/model_reducers.dart index 9613ac0..78cf23f 100644 --- a/lib/redux/reducers/model_reducers.dart +++ b/lib/redux/reducers/model_reducers.dart @@ -4,6 +4,7 @@ import 'package:time_progress_tracker/models/time_progress.dart'; import 'package:time_progress_tracker/redux/actions/app_settings_actions.dart'; import 'package:time_progress_tracker/redux/actions/redux_actions.dart'; import 'package:time_progress_tracker/redux/actions/time_progress_actions.dart'; +import 'package:time_progress_tracker/utils/constants.dart'; final timeProgressListReducer = combineReducers>([ TypedReducer, TimeProgressListLoadedAction>( @@ -55,7 +56,7 @@ final appSettingsReducers = combineReducers([ AppSettings _setDefaultSettings( AppSettings appSettings, AppSettingsNotLoadedAction action) => - AppSettings.defaults(); + defaultAppSettings; AppSettings _updateAppSettings( AppSettings appSettings, AppSettingsAction action) => diff --git a/lib/redux/redux_selectors.dart b/lib/redux/redux_selectors.dart index 5c06ec7..3b77864 100644 --- a/lib/redux/redux_selectors.dart +++ b/lib/redux/redux_selectors.dart @@ -1,8 +1,8 @@ import 'dart:ui'; import 'package:time_progress_tracker/models/app_settings.dart'; -import 'package:time_progress_tracker/redux/app_state.dart'; import 'package:time_progress_tracker/models/time_progress.dart'; +import 'package:time_progress_tracker/redux/app_state.dart'; List timeProgressListSelector(AppState state) => state.timeProgressList; @@ -45,10 +45,12 @@ List pastTimeProgressesSelector(AppState state) => DateTime.now().millisecondsSinceEpoch) .toList(); -TimeProgress timeProgressByIdSelector(AppState state, String id) { +TimeProgress? timeProgressByIdSelector(AppState state, String id) { if (state.timeProgressList.length < 1) return null; - return state.timeProgressList - .firstWhere((timeProgress) => timeProgress.id == id, orElse: () => null); + TimeProgress tp = state.timeProgressList.firstWhere( + (timeProgress) => timeProgress.id == id, + orElse: () => TimeProgress.initialDefault()); + return tp != TimeProgress.initialDefault() ? tp : null; } AppSettings appSettingsSelector(AppState state) { diff --git a/lib/redux/store_connectors/create_time_progress_store_connector.dart b/lib/redux/store_connectors/create_time_progress_store_connector.dart index cc297f3..153c8d2 100644 --- a/lib/redux/store_connectors/create_time_progress_store_connector.dart +++ b/lib/redux/store_connectors/create_time_progress_store_connector.dart @@ -14,7 +14,7 @@ class CreateTimeProgressStoreConnector extends StatelessWidget { loadedBuilder; CreateTimeProgressStoreConnector({ - @required this.loadedBuilder, + required this.loadedBuilder, }); @override diff --git a/lib/redux/store_connectors/settings_store_connector.dart b/lib/redux/store_connectors/settings_store_connector.dart index 3633962..6dc538b 100644 --- a/lib/redux/store_connectors/settings_store_connector.dart +++ b/lib/redux/store_connectors/settings_store_connector.dart @@ -10,7 +10,7 @@ class SettingsStoreConnector extends StatelessWidget { final Widget Function(BuildContext, SettingsViewModel) loadedBuilder; SettingsStoreConnector({ - @required this.loadedBuilder, + required this.loadedBuilder, }); @override diff --git a/lib/redux/store_connectors/time_progress_list_store_connector.dart b/lib/redux/store_connectors/time_progress_list_store_connector.dart index 18d7d8e..8138492 100644 --- a/lib/redux/store_connectors/time_progress_list_store_connector.dart +++ b/lib/redux/store_connectors/time_progress_list_store_connector.dart @@ -9,7 +9,7 @@ class TimeProgressListStoreConnector extends StatelessWidget { final Widget Function(BuildContext, TimeProgressListViewModel) loadedBuilder; TimeProgressListStoreConnector({ - @required this.loadedBuilder, + required this.loadedBuilder, }); @override diff --git a/lib/redux/store_connectors/time_progress_store_connector.dart b/lib/redux/store_connectors/time_progress_store_connector.dart index fa1f409..ff331de 100644 --- a/lib/redux/store_connectors/time_progress_store_connector.dart +++ b/lib/redux/store_connectors/time_progress_store_connector.dart @@ -4,16 +4,16 @@ import 'package:redux/redux.dart'; import 'package:time_progress_tracker/redux/actions/time_progress_actions.dart'; import 'package:time_progress_tracker/redux/app_state.dart'; import 'package:time_progress_tracker/models/time_progress.dart'; +import 'package:time_progress_tracker/utils/helper_functions.dart'; -import '../../utils/helper_functions.dart'; class TimeProgressStoreConnector extends StatelessWidget { final String timeProgressId; final Widget Function(BuildContext, TimeProgressViewModel) loadedBuilder; TimeProgressStoreConnector({ - @required this.timeProgressId, - @required this.loadedBuilder, + required this.timeProgressId, + required this.loadedBuilder, }); @override @@ -38,7 +38,7 @@ class TimeProgressStoreConnector extends StatelessWidget { } class TimeProgressViewModel { - final TimeProgress tp; + final TimeProgress? tp; final bool hasTpListLoaded; final void Function(TimeProgress) updateTimeProgress; diff --git a/lib/ui/app_yes_no_dialog_widget.dart b/lib/ui/app_yes_no_dialog_widget.dart index 270752b..2b8f63a 100644 --- a/lib/ui/app_yes_no_dialog_widget.dart +++ b/lib/ui/app_yes_no_dialog_widget.dart @@ -6,10 +6,10 @@ class AppYesNoDialog extends StatelessWidget { final void Function() onYesPressed; AppYesNoDialog({ - Key key, - @required this.titleText, - @required this.contentText, - @required this.onYesPressed, + Key? key, + required this.titleText, + required this.contentText, + required this.onYesPressed, }) : super(key: key); @override diff --git a/lib/ui/buttons/color_picker_btn.dart b/lib/ui/buttons/color_picker_btn.dart index 00bb55c..f5bbc79 100644 --- a/lib/ui/buttons/color_picker_btn.dart +++ b/lib/ui/buttons/color_picker_btn.dart @@ -8,10 +8,10 @@ class ColorPickerButton extends StatelessWidget { final void Function(Color) onColorPicked; ColorPickerButton({ - @required this.title, - @required this.dialogTitle, - @required this.selectedColor, - @required this.onColorPicked, + required this.title, + required this.dialogTitle, + required this.selectedColor, + required this.onColorPicked, }); @override @@ -37,8 +37,8 @@ class ColorPickerButton extends StatelessWidget { child: Text(title), style: TextButton.styleFrom( primary: useBrightBackground(selectedColor) - ? appTheme.primaryTextTheme.button.color - : appTheme.textTheme.button.color, + ? appTheme.primaryTextTheme.button!.color + : appTheme.textTheme.button!.color, backgroundColor: selectedColor, ), ); diff --git a/lib/ui/buttons/create_progress_button.dart b/lib/ui/buttons/create_progress_button.dart index 3de2b25..8d15641 100644 --- a/lib/ui/buttons/create_progress_button.dart +++ b/lib/ui/buttons/create_progress_button.dart @@ -8,7 +8,7 @@ class CreateProgressButton extends StatelessWidget { final void Function() createProgress; - const CreateProgressButton({Key key, @required this.createProgress}) + const CreateProgressButton({Key? key, required this.createProgress}) : super(key: key); @override diff --git a/lib/ui/buttons/date_picker_btn.dart b/lib/ui/buttons/date_picker_btn.dart index 908dbfd..d5c51f1 100644 --- a/lib/ui/buttons/date_picker_btn.dart +++ b/lib/ui/buttons/date_picker_btn.dart @@ -6,18 +6,18 @@ class DatePickerBtn extends StatelessWidget { final void Function(DateTime) onDatePicked; DatePickerBtn({ - @required this.leadingString, - @required this.pickedDate, - @required this.onDatePicked, + required this.leadingString, + required this.pickedDate, + required this.onDatePicked, }) : super(); void _onButtonPressed(BuildContext context) async { - onDatePicked(await showDatePicker( + onDatePicked((await showDatePicker( context: context, initialDate: pickedDate, firstDate: DateTime(1900), lastDate: DateTime(2100), - )); + ))!); } @override @@ -28,7 +28,7 @@ class DatePickerBtn extends StatelessWidget { child: Text( "$leadingString ${pickedDate.toLocal().toString().split(" ")[0]}"), style: TextButton.styleFrom( - primary: appTheme.primaryTextTheme.button.color, + primary: appTheme.primaryTextTheme.button!.color, backgroundColor: appTheme.accentColor, ), ); diff --git a/lib/ui/buttons/detail_screen_leading_button.dart b/lib/ui/buttons/detail_screen_leading_button.dart new file mode 100644 index 0000000..aba2667 --- /dev/null +++ b/lib/ui/buttons/detail_screen_leading_button.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:time_progress_tracker/ui/buttons/platform_action_button.dart'; + +class DetailScreenLeadingButton extends StatelessWidget { + final bool isEditMode, isEditedTpValid; + final void Function() saveTp, editTp; + + const DetailScreenLeadingButton({ + Key? key, + required this.isEditMode, + required this.isEditedTpValid, + required this.saveTp, + required this.editTp, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final ThemeData materialTheme = Theme.of(context); + + if (isEditMode) + return PlatformActionButton( + heroTag: "saveEditedTimeProgressBTN", + icon: Icons.save, + materialBackground: Colors.green, + onBtnPressed: isEditedTpValid ? saveTp : null); + return PlatformActionButton( + heroTag: "editTimeProgressBTN", + icon: Icons.edit, + materialBackground: materialTheme.accentColor, + onBtnPressed: editTp, + ); + } +} diff --git a/lib/ui/buttons/detail_screen_trailing_button.dart b/lib/ui/buttons/detail_screen_trailing_button.dart new file mode 100644 index 0000000..a477497 --- /dev/null +++ b/lib/ui/buttons/detail_screen_trailing_button.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:time_progress_tracker/ui/buttons/platform_action_button.dart'; + +class DetailScreenTrailingButton extends StatelessWidget { + final bool isEditMode; + final void Function() cancelEditTp, deleteTp; + + const DetailScreenTrailingButton({ + Key? key, + required this.isEditMode, + required this.cancelEditTp, + required this.deleteTp, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + if (isEditMode) + return PlatformActionButton( + heroTag: "cancelEditTimeProgressBTN", + icon: Icons.cancel, + materialBackground: Colors.red, + onBtnPressed: cancelEditTp); + return PlatformActionButton( + heroTag: "deleteTimeProgressBTN", + icon: Icons.delete, + materialBackground: Colors.red, + onBtnPressed: deleteTp, + ); + } +} diff --git a/lib/ui/buttons/platform_action_button.dart b/lib/ui/buttons/platform_action_button.dart index 593231d..36b53a3 100644 --- a/lib/ui/buttons/platform_action_button.dart +++ b/lib/ui/buttons/platform_action_button.dart @@ -6,13 +6,15 @@ import 'package:time_progress_tracker/utils/helper_functions.dart'; class PlatformActionButton extends StatelessWidget { final String heroTag; final IconData icon; - final void Function() onBtnPressed; + final Color? materialBackground; + final void Function()? onBtnPressed; const PlatformActionButton({ - Key key, - @required this.heroTag, - @required this.icon, - @required this.onBtnPressed, + Key? key, + required this.heroTag, + required this.icon, + this.materialBackground, + required this.onBtnPressed, }) : super(key: key); @override @@ -32,6 +34,7 @@ class PlatformActionButton extends StatelessWidget { return FloatingActionButton( heroTag: heroTag, child: Icon(icon), + backgroundColor: materialBackground, onPressed: onBtnPressed, ); } diff --git a/lib/ui/buttons/select_duration_btn.dart b/lib/ui/buttons/select_duration_btn.dart index 5490000..7573540 100644 --- a/lib/ui/buttons/select_duration_btn.dart +++ b/lib/ui/buttons/select_duration_btn.dart @@ -6,8 +6,8 @@ class SelectDurationBtn extends StatelessWidget { final void Function(Duration) updateDuration; SelectDurationBtn({ - @required this.duration, - @required this.updateDuration, + required this.duration, + required this.updateDuration, }); void _onPickerConfirm(Picker picker, List values) { @@ -40,7 +40,7 @@ class SelectDurationBtn extends StatelessWidget { onPressed: () => _onButtonPressed(context, appTheme), child: Text("$years Years $months Months $days Days"), style: TextButton.styleFrom( - primary: appTheme.primaryTextTheme.button.color, + primary: appTheme.primaryTextTheme.button!.color, backgroundColor: appTheme.accentColor, )); } diff --git a/lib/ui/detail_screen_floating_action_buttons.dart b/lib/ui/detail_screen_floating_action_buttons.dart index 8180687..af17541 100644 --- a/lib/ui/detail_screen_floating_action_buttons.dart +++ b/lib/ui/detail_screen_floating_action_buttons.dart @@ -11,14 +11,14 @@ class DetailScreenFloatingActionButtons extends StatelessWidget { onDeleteProgress; DetailScreenFloatingActionButtons({ - @required this.editMode, - @required this.originalProgress, - @required this.editedProgress, - @required this.isEditedProgressValid, - @required this.onEditProgress, - @required this.onSaveEditedProgress, - @required this.onCancelEditProgress, - @required this.onDeleteProgress, + required this.editMode, + required this.originalProgress, + required this.editedProgress, + required this.isEditedProgressValid, + required this.onEditProgress, + required this.onSaveEditedProgress, + required this.onCancelEditProgress, + required this.onDeleteProgress, }); @override diff --git a/lib/ui/progress/progress_editor_widget.dart b/lib/ui/progress/progress_editor_widget.dart index ffead6c..a94a78f 100644 --- a/lib/ui/progress/progress_editor_widget.dart +++ b/lib/ui/progress/progress_editor_widget.dart @@ -8,8 +8,8 @@ class ProgressEditorWidget extends StatefulWidget { final Function(TimeProgress, bool) onTimeProgressChanged; ProgressEditorWidget({ - @required this.timeProgress, - @required this.onTimeProgressChanged, + required this.timeProgress, + required this.onTimeProgressChanged, }); @override diff --git a/lib/ui/progress/progress_list_item.dart b/lib/ui/progress/progress_list_item.dart index a8c7814..36f8e36 100644 --- a/lib/ui/progress/progress_list_item.dart +++ b/lib/ui/progress/progress_list_item.dart @@ -24,9 +24,9 @@ class ProgressListItem extends StatelessWidget { final Color doneColor, leftColor; ProgressListItem({ - @required this.timeProgress, - @required this.doneColor, - @required this.leftColor, + required this.timeProgress, + required this.doneColor, + required this.leftColor, }); @override diff --git a/lib/ui/progress/progress_list_view.dart b/lib/ui/progress/progress_list_view.dart index 837d2a5..b0adcb7 100644 --- a/lib/ui/progress/progress_list_view.dart +++ b/lib/ui/progress/progress_list_view.dart @@ -10,9 +10,9 @@ class ProgressListView extends StatelessWidget { final Color doneColor, leftColor; ProgressListView({ - @required this.timeProgressList, - @required this.doneColor, - @required this.leftColor, + required this.timeProgressList, + required this.doneColor, + required this.leftColor, }); Widget _renderListTile(TimeProgress tp) { diff --git a/lib/ui/progress/progress_view_widget.dart b/lib/ui/progress/progress_view_widget.dart index ca5b205..b38fe4d 100644 --- a/lib/ui/progress/progress_view_widget.dart +++ b/lib/ui/progress/progress_view_widget.dart @@ -9,9 +9,9 @@ class ProgressViewWidget extends StatelessWidget { final Color leftColor; ProgressViewWidget({ - @required this.timeProgress, - @required this.doneColor, - @required this.leftColor, + required this.timeProgress, + required this.doneColor, + required this.leftColor, }); @override diff --git a/lib/ui/screens/dashboard_screen.dart b/lib/ui/screens/dashboard_screen.dart index 817fac9..09ce99b 100644 --- a/lib/ui/screens/dashboard_screen.dart +++ b/lib/ui/screens/dashboard_screen.dart @@ -44,7 +44,7 @@ class _DashboardScreenState extends State { @override Widget build(BuildContext context) { - Widget _renderCreateProgressBtn() => _tabSelectedIndex == 2 + PlatformActionButton? _renderCreateProgressBtn() => _tabSelectedIndex == 2 ? null : PlatformActionButton( heroTag: "goToCreateTimeProgressBTN", diff --git a/lib/ui/screens/progress_creation_screen.dart b/lib/ui/screens/progress_creation_screen.dart index f817f98..72d403c 100644 --- a/lib/ui/screens/progress_creation_screen.dart +++ b/lib/ui/screens/progress_creation_screen.dart @@ -26,11 +26,11 @@ class ProgressCreationScreen extends StatefulWidget { } class _ProgressCreationScreenState extends State { - TimeProgress timeProgressToCreate; + TimeProgress timeProgressToCreate = TimeProgress.initialDefault(); bool _isProgressValid = false; void initTimeProgress(TimeProgress timeProgress) { - if (timeProgressToCreate == null) + if (timeProgressToCreate == TimeProgress.initialDefault()) setState(() { timeProgressToCreate = timeProgress; }); @@ -180,8 +180,8 @@ class _ViewModel { final void Function(TimeProgress) onAddTimeProgress; _ViewModel({ - @required this.defaultDurationProgress, - @required this.onAddTimeProgress, + required this.defaultDurationProgress, + required this.onAddTimeProgress, }); factory _ViewModel.create(Store store) { diff --git a/lib/ui/screens/progress_detail_screen.dart b/lib/ui/screens/progress_detail_screen.dart index 2dc9ce3..fbb35c0 100644 --- a/lib/ui/screens/progress_detail_screen.dart +++ b/lib/ui/screens/progress_detail_screen.dart @@ -1,18 +1,20 @@ import 'package:flutter/material.dart'; +import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:time_progress_tracker/models/time_progress.dart'; import 'package:time_progress_tracker/redux/store_connectors/settings_store_connector.dart'; import 'package:time_progress_tracker/redux/store_connectors/time_progress_store_connector.dart'; -import 'package:time_progress_tracker/ui/screens/dashboard_screen.dart'; -import 'package:time_progress_tracker/ui/detail_screen_floating_action_buttons.dart'; +import 'package:time_progress_tracker/ui/buttons/detail_screen_leading_button.dart'; +import 'package:time_progress_tracker/ui/buttons/detail_screen_trailing_button.dart'; import 'package:time_progress_tracker/ui/progress/progress_editor_widget.dart'; import 'package:time_progress_tracker/ui/progress/progress_view_widget.dart'; +import 'package:time_progress_tracker/utils/theme_utils.dart'; class ProgressDetailScreen extends StatefulWidget { static const title = "Progress View"; final String tpId; - const ProgressDetailScreen({Key key, @required this.tpId}) : super(key: key); + const ProgressDetailScreen({Key? key, required this.tpId}) : super(key: key); @override State createState() { @@ -22,10 +24,11 @@ class ProgressDetailScreen extends StatefulWidget { class _ProgressDetailScreenState extends State { bool _editMode = false, _isEditedProgressValid = false; - TimeProgress _editedProgress, _originalProgress; + TimeProgress _editedProgress = TimeProgress.initialDefault(), + _originalProgress = TimeProgress.initialDefault(); void _initEditedProgress(TimeProgress tp) { - if (_editedProgress == null) { + if (_editedProgress == TimeProgress.initialDefault()) { _editedProgress = tp; _originalProgress = tp; } @@ -54,10 +57,11 @@ class _ProgressDetailScreenState extends State { List _renderColumnChildren( SettingsViewModel settingsVm, TimeProgressViewModel tpVm) { + TimeProgress tp = tpVm.tp ?? TimeProgress.initialDefault(); List columnChildren = [ Expanded( child: ProgressViewWidget( - timeProgress: _editMode ? _editedProgress : tpVm.tp, + timeProgress: _editMode ? _editedProgress : tp, doneColor: settingsVm.appSettings.doneColor, leftColor: settingsVm.appSettings.leftColor, )) @@ -73,16 +77,67 @@ class _ProgressDetailScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(ProgressDetailScreen.title), + TimeProgressStoreConnector leadingActionButton = TimeProgressStoreConnector( + timeProgressId: widget.tpId, + loadedBuilder: (context, tpVm) { + void _saveEditedTp() { + tpVm.updateTimeProgress(_editedProgress); + _switchEditMode(false); + } + + return DetailScreenLeadingButton( + isEditMode: _editMode, + isEditedTpValid: _isEditedProgressValid, + saveTp: _saveEditedTp, + editTp: () => _switchEditMode(true), + ); + }, + ); + + TimeProgressStoreConnector trailingActionButton = + TimeProgressStoreConnector( + timeProgressId: widget.tpId, + loadedBuilder: (context, tpVm) { + void _deleteTp() { + tpVm.deleteTimeProgress(); + Navigator.popUntil(context, (route) => route.isFirst); + } + + return DetailScreenTrailingButton( + isEditMode: _editMode, + cancelEditTp: _cancelEditMode, + deleteTp: _deleteTp, + ); + }, + ); + + return PlatformScaffold( + appBar: PlatformAppBar( + title: Text( + ProgressDetailScreen.title, + style: toolbarTextStyle, + ), + cupertino: (_, __) => CupertinoNavigationBarData( + transitionBetweenRoutes: false, + leading: leadingActionButton, + trailing: trailingActionButton, + ), + ), + material: (_, __) => MaterialScaffoldData( + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: Row( + children: [ + Expanded(child: leadingActionButton), + Expanded(child: trailingActionButton), + ], + ), ), body: SettingsStoreConnector( loadedBuilder: (context, settingsVm) { return TimeProgressStoreConnector( timeProgressId: widget.tpId, loadedBuilder: (context, tpVm) { - _initEditedProgress(tpVm.tp); + _initEditedProgress(tpVm.tp!); return Container( margin: EdgeInsets.all(8), child: Column( @@ -92,32 +147,6 @@ class _ProgressDetailScreenState extends State { ); }, ), - floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, - floatingActionButton: TimeProgressStoreConnector( - timeProgressId: widget.tpId, - loadedBuilder: (context, tpVm) { - void _saveEditedProgress() { - tpVm.updateTimeProgress(_editedProgress); - _switchEditMode(false); - } - - void _deleteTimeProgress() { - tpVm.deleteTimeProgress(); - Navigator.popUntil( - context, ModalRoute.withName(DashboardScreen.routeName)); - } - - return DetailScreenFloatingActionButtons( - editMode: _editMode, - originalProgress: tpVm.tp, - editedProgress: _editedProgress, - isEditedProgressValid: _isEditedProgressValid, - onEditProgress: () => _switchEditMode(true), - onSaveEditedProgress: _saveEditedProgress, - onCancelEditProgress: _cancelEditMode, - onDeleteProgress: _deleteTimeProgress); - }, - ), ); } } diff --git a/lib/ui/settings/color_settings_widget.dart b/lib/ui/settings/color_settings_widget.dart index e758bdf..67f900a 100644 --- a/lib/ui/settings/color_settings_widget.dart +++ b/lib/ui/settings/color_settings_widget.dart @@ -6,10 +6,10 @@ class ColorSettingsWidget extends StatelessWidget { final void Function(Color) updateDoneColor, updateLeftColor; ColorSettingsWidget({ - @required this.doneColor, - @required this.leftColor, - @required this.updateDoneColor, - @required this.updateLeftColor, + required this.doneColor, + required this.leftColor, + required this.updateDoneColor, + required this.updateLeftColor, }); @override diff --git a/lib/ui/settings/duration_settings_widget.dart b/lib/ui/settings/duration_settings_widget.dart index 379036c..7f25a3d 100644 --- a/lib/ui/settings/duration_settings_widget.dart +++ b/lib/ui/settings/duration_settings_widget.dart @@ -6,8 +6,8 @@ class DurationSettingsWidget extends StatelessWidget { final void Function(Duration) updateDuration; DurationSettingsWidget({ - @required this.duration, - @required this.updateDuration, + required this.duration, + required this.updateDuration, }); @override diff --git a/lib/utils/constants.dart b/lib/utils/constants.dart index 0109997..d108639 100644 --- a/lib/utils/constants.dart +++ b/lib/utils/constants.dart @@ -1,3 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:time_progress_tracker/models/app_settings.dart'; + const txtActiveProgressesScreen = "Active Progresses"; const txtInactiveProgressesScreen = "Inactive Progresses"; -const txtSettingsScreen = "Settings"; \ No newline at end of file +const txtSettingsScreen = "Settings"; +const defaultAppSettings = AppSettings( + doneColor: Colors.green, + leftColor: Colors.red, + duration: Duration(days: 365), +); \ No newline at end of file diff --git a/lib/utils/helper_functions.dart b/lib/utils/helper_functions.dart index 6966508..c9c17e6 100644 --- a/lib/utils/helper_functions.dart +++ b/lib/utils/helper_functions.dart @@ -17,7 +17,7 @@ void loadSettingsIfUnloaded(Store store) { if (!store.state.hasSettingsLoaded) store.dispatch(LoadAppSettingsAction()); } -TimeProgress selectProgressById(List tpList, String id) => +TimeProgress? selectProgressById(List tpList, String id) => tpList.firstWhere((tp) => tp.id == id, orElse: null); List selectActiveProgresses(List tpList) => diff --git a/pubspec.lock b/pubspec.lock index 5188740..9cba98b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -381,5 +381,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.12.0-259.9.beta <3.0.0" + dart: ">=2.12.0 <3.0.0" flutter: ">=1.20.4" diff --git a/pubspec.yaml b/pubspec.yaml index 81cfbae..c130e38 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 0.0.19+19 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: