Cleanup of Progress Detail Screen
Signed-off-by: Andreas Fahrecker <AndreasFahrecker@gmail.com>
This commit is contained in:
parent
c09b164a61
commit
5c2592f601
@ -6,9 +6,7 @@ import 'package:time_progress_tracker/models/app_state.dart';
|
|||||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||||
import 'package:time_progress_tracker/screens/home_screen.dart';
|
import 'package:time_progress_tracker/screens/home_screen.dart';
|
||||||
import 'package:time_progress_tracker/selectors/time_progress_selectors.dart';
|
import 'package:time_progress_tracker/selectors/time_progress_selectors.dart';
|
||||||
import 'package:time_progress_tracker/widgets/app_yes_no_dialog_widget.dart';
|
import 'package:time_progress_tracker/widgets/detail_screen_floating_action_buttons.dart';
|
||||||
import 'package:time_progress_tracker/widgets/progress_detail_widgets/progress_detail_fab_editing_row_widget.dart';
|
|
||||||
import 'package:time_progress_tracker/widgets/progress_detail_widgets/progress_detail_fab_row_widget.dart';
|
|
||||||
import 'package:time_progress_tracker/widgets/progress_editor_widget.dart';
|
import 'package:time_progress_tracker/widgets/progress_editor_widget.dart';
|
||||||
import 'package:time_progress_tracker/widgets/progress_view_widget.dart';
|
import 'package:time_progress_tracker/widgets/progress_view_widget.dart';
|
||||||
|
|
||||||
@ -20,6 +18,7 @@ class ProgressDetailScreenArguments {
|
|||||||
|
|
||||||
class ProgressDetailScreen extends StatefulWidget {
|
class ProgressDetailScreen extends StatefulWidget {
|
||||||
static const routeName = "/progress-detail";
|
static const routeName = "/progress-detail";
|
||||||
|
static const title = "Progress View";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
@ -29,7 +28,7 @@ class ProgressDetailScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
||||||
bool _editMode = false;
|
bool _editMode = false;
|
||||||
TimeProgress _editedProgress = TimeProgress.initialDefault();
|
TimeProgress _editedProgress;
|
||||||
|
|
||||||
void _onEditedProgressChanged(TimeProgress newProgress) {
|
void _onEditedProgressChanged(TimeProgress newProgress) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -37,162 +36,70 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onSaveTimeProgress(Store<AppState> store, id) {
|
void _switchEditMode(bool newMode) {
|
||||||
if (!TimeProgress.isValid(_editedProgress)) return;
|
|
||||||
store.dispatch(UpdateTimeProgressAction(id, _editedProgress));
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_editMode = false;
|
_editMode = newMode;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showCancelEditTimeProgressDialog(AppState state, id) {
|
|
||||||
TimeProgress originalTp = timeProgressByIdSelector(state, id);
|
|
||||||
if (originalTp != _editedProgress) {
|
|
||||||
String originalName = originalTp.name;
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (_) => AppYesNoDialog(
|
|
||||||
titleText: "Cancel Editing of $originalName",
|
|
||||||
contentText:
|
|
||||||
"Are you sure that you want to discard the changes done to $originalName",
|
|
||||||
onYesPressed: () {
|
|
||||||
_cancelEditMode();
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
onNoPressed: _onCloseDialog,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_cancelEditMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _cancelEditMode() {
|
|
||||||
setState(() {
|
|
||||||
_editMode = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onEditTimeProgress(AppState state, id) {
|
|
||||||
setState(() {
|
|
||||||
_editMode = true;
|
|
||||||
_editedProgress = timeProgressByIdSelector(state, id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showDeleteTimeProgressDialog(Store<AppState> store, id) {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (_) => AppYesNoDialog(
|
|
||||||
titleText: "Delete ${timeProgressByIdSelector(store.state, id).name}",
|
|
||||||
contentText: "Are you sure you want to delete this time progress?",
|
|
||||||
onYesPressed: () => _onDeleteTimeProgress(store, id),
|
|
||||||
onNoPressed: _onCloseDialog,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onDeleteTimeProgress(Store<AppState> store, String id) {
|
|
||||||
store.dispatch(DeleteTimeProgressAction(id));
|
|
||||||
Navigator.popUntil(context, ModalRoute.withName(HomeScreen.routeName));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onCloseDialog() {
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ProgressDetailScreenArguments args =
|
final ProgressDetailScreenArguments args =
|
||||||
ModalRoute.of(context).settings.arguments;
|
ModalRoute.of(context).settings.arguments;
|
||||||
final Store<AppState> store = StoreProvider.of<AppState>(context);
|
final Store<AppState> store = StoreProvider.of<AppState>(context);
|
||||||
final ThemeData appTheme = Theme.of(context);
|
final TimeProgress _timeProgress =
|
||||||
|
timeProgressByIdSelector(store.state, args.id);
|
||||||
|
|
||||||
|
if (_timeProgress == null) //+++++Time Progress Not Found Error+++++
|
||||||
|
return Center(
|
||||||
|
child: Text("Error Invalid Time Progress"),
|
||||||
|
);
|
||||||
|
if (_editedProgress == null)
|
||||||
|
_editedProgress = _timeProgress; // initialize _editedProgress
|
||||||
|
|
||||||
|
void _saveEditedProgress() {
|
||||||
|
store.dispatch(UpdateTimeProgressAction(args.id, _editedProgress));
|
||||||
|
_switchEditMode(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _deleteTimeProgress() {
|
||||||
|
store.dispatch(DeleteTimeProgressAction(args.id));
|
||||||
|
Navigator.popUntil(context, ModalRoute.withName(HomeScreen.routeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> columnChildren = [
|
||||||
|
Expanded(
|
||||||
|
child: ProgressViewWidget(
|
||||||
|
timeProgress: _editMode ? _editedProgress : _timeProgress),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
if (_editMode)
|
||||||
|
columnChildren.add(Expanded(
|
||||||
|
child: ProgressEditorWidget(
|
||||||
|
timeProgress: _editedProgress,
|
||||||
|
onTimeProgressChanged: _onEditedProgressChanged,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text("Progress"),
|
title: Text(ProgressDetailScreen.title),
|
||||||
),
|
),
|
||||||
body: Container(
|
body: Container(
|
||||||
margin: EdgeInsets.all(8),
|
margin: EdgeInsets.all(8),
|
||||||
child: StoreConnector(
|
child: Column(
|
||||||
converter: (Store<AppState> store) =>
|
children: columnChildren,
|
||||||
_ViewModel.fromStoreAndArg(store, args),
|
|
||||||
onInit: loadTimeProgressListIfUnloaded,
|
|
||||||
builder: (BuildContext context, _ViewModel vm) {
|
|
||||||
if (vm.timeProgress == null)
|
|
||||||
return Center(
|
|
||||||
child: Text("Error Invalid Time Progress"),
|
|
||||||
);
|
|
||||||
List<Widget> columnChildren = [
|
|
||||||
Expanded(
|
|
||||||
child: ProgressViewWidget(
|
|
||||||
timeProgress:
|
|
||||||
_editMode ? _editedProgress : vm.timeProgress),
|
|
||||||
)
|
|
||||||
];
|
|
||||||
if (_editMode)
|
|
||||||
columnChildren.add(Expanded(
|
|
||||||
child: ProgressEditorWidget(
|
|
||||||
timeProgress: _editedProgress,
|
|
||||||
onTimeProgressChanged: _onEditedProgressChanged,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
return Column(
|
|
||||||
children: columnChildren,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||||
floatingActionButton: Row(
|
floatingActionButton: DetailScreenFloatingActionButtons(
|
||||||
children: [
|
editMode: _editMode,
|
||||||
Expanded(
|
originalProgress: timeProgressByIdSelector(store.state, args.id),
|
||||||
child: FloatingActionButton(
|
editedProgress: _editedProgress,
|
||||||
heroTag: _editMode
|
onEditProgress: () => _switchEditMode(true),
|
||||||
? "saveEditedTimeProgressBTN"
|
onSaveEditedProgress: _saveEditedProgress,
|
||||||
: "editTimeProgressBTN",
|
onCancelEditProgress: () => _switchEditMode(false),
|
||||||
child: _editMode ? Icon(Icons.save) : Icon(Icons.edit),
|
onDeleteProgress: _deleteTimeProgress),
|
||||||
backgroundColor: _editMode ? Colors.green : appTheme.accentColor,
|
|
||||||
onPressed: _editMode
|
|
||||||
? () {
|
|
||||||
_onSaveTimeProgress(store, args.id);
|
|
||||||
}
|
|
||||||
: () {
|
|
||||||
_onEditTimeProgress(store.state, args.id);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: FloatingActionButton(
|
|
||||||
heroTag: _editMode
|
|
||||||
? "cancelEditTimeProgressBTN"
|
|
||||||
: "deleteTimeProgressBTN",
|
|
||||||
child: _editMode ? Icon(Icons.cancel) : Icon(Icons.delete),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
onPressed: _editMode
|
|
||||||
? () {
|
|
||||||
_showCancelEditTimeProgressDialog(store.state, args.id);
|
|
||||||
}
|
|
||||||
: () {
|
|
||||||
_showDeleteTimeProgressDialog(store, args.id);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ViewModel {
|
|
||||||
final TimeProgress timeProgress;
|
|
||||||
|
|
||||||
_ViewModel({@required this.timeProgress});
|
|
||||||
|
|
||||||
static _ViewModel fromStoreAndArg(
|
|
||||||
Store<AppState> store, ProgressDetailScreenArguments args) {
|
|
||||||
return _ViewModel(
|
|
||||||
timeProgress: timeProgressByIdSelector(store.state, args.id),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
|
||||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
|
||||||
import 'package:redux/redux.dart';
|
|
||||||
import 'package:time_progress_tracker/actions/actions.dart';
|
|
||||||
import 'package:time_progress_tracker/app.dart';
|
|
||||||
import 'package:time_progress_tracker/models/app_state.dart';
|
|
||||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
|
||||||
import 'package:time_progress_tracker/screens/home_screen.dart';
|
|
||||||
import 'package:time_progress_tracker/screens/progress_detail_screen.dart';
|
|
||||||
import 'package:time_progress_tracker/selectors/time_progress_selectors.dart';
|
|
||||||
|
|
||||||
class AppDrawer extends StatelessWidget {
|
|
||||||
final String appVersion;
|
|
||||||
|
|
||||||
AppDrawer({
|
|
||||||
Key key,
|
|
||||||
@required this.appVersion,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
ThemeData appTheme = Theme.of(context);
|
|
||||||
|
|
||||||
return Drawer(
|
|
||||||
child: StoreConnector(
|
|
||||||
converter: _ViewModel.fromStore,
|
|
||||||
onInit: loadTimeProgressListIfUnloaded,
|
|
||||||
builder: (context, _ViewModel vm) {
|
|
||||||
if (!vm.hasLoaded) {
|
|
||||||
return Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
List<Widget> drawerTileList = List<Widget>();
|
|
||||||
drawerTileList.add(DrawerHeader(
|
|
||||||
child: Text(TimeProgressTrackerApp.name),
|
|
||||||
decoration: BoxDecoration(color: appTheme.primaryColor),
|
|
||||||
margin: EdgeInsets.zero,
|
|
||||||
));
|
|
||||||
drawerTileList.add(Container(
|
|
||||||
color: appTheme.accentColor,
|
|
||||||
margin: EdgeInsets.only(bottom: 8),
|
|
||||||
child: ListTile(
|
|
||||||
title: Text(HomeScreen.title),
|
|
||||||
trailing: Icon(Icons.dashboard),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
Navigator.pushNamed(context, HomeScreen.routeName);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
));
|
|
||||||
if (vm.currentTimeProgresses.length > 0) {
|
|
||||||
for (TimeProgress tp in vm.currentTimeProgresses) {
|
|
||||||
drawerTileList.add(ListTile(
|
|
||||||
title: Text(tp.name),
|
|
||||||
trailing: CircularPercentIndicator(
|
|
||||||
percent: tp.percentDone(),
|
|
||||||
radius: 40,
|
|
||||||
progressColor: Colors.green,
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
center: FittedBox(
|
|
||||||
fit: BoxFit.scaleDown,
|
|
||||||
child:
|
|
||||||
Text((tp.percentDone() * 100).floor().toString() + "%"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
Navigator.pushNamed(
|
|
||||||
context,
|
|
||||||
ProgressDetailScreen.routeName,
|
|
||||||
arguments: ProgressDetailScreenArguments(tp.id),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
));
|
|
||||||
if (vm.currentTimeProgresses.last != tp) {
|
|
||||||
drawerTileList.add(Divider(
|
|
||||||
color: Colors.black12,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
drawerTileList.add(ListTile(
|
|
||||||
title: Text("You don't have any tracked time progress."),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
drawerTileList.add(Divider(
|
|
||||||
color: Colors.black38,
|
|
||||||
));
|
|
||||||
drawerTileList.add(Container(
|
|
||||||
margin: EdgeInsets.only(bottom: 8),
|
|
||||||
child: ListTile(
|
|
||||||
title: Text("About"),
|
|
||||||
onTap: () {
|
|
||||||
showAboutDialog(
|
|
||||||
context: context,
|
|
||||||
applicationName: TimeProgressTrackerApp.name,
|
|
||||||
applicationVersion: " Version $appVersion",
|
|
||||||
applicationLegalese: '\u00a9Andreas Fahrecker 2020-2021');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
));
|
|
||||||
return ListView(
|
|
||||||
children: drawerTileList,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ViewModel {
|
|
||||||
final List<TimeProgress> currentTimeProgresses;
|
|
||||||
final bool hasLoaded;
|
|
||||||
|
|
||||||
_ViewModel({
|
|
||||||
@required this.currentTimeProgresses,
|
|
||||||
@required this.hasLoaded,
|
|
||||||
});
|
|
||||||
|
|
||||||
static _ViewModel fromStore(Store<AppState> store) {
|
|
||||||
return _ViewModel(
|
|
||||||
currentTimeProgresses: currentTimeProgressSelector(store.state),
|
|
||||||
hasLoaded: store.state.hasLoaded,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,14 +4,12 @@ class AppYesNoDialog extends StatelessWidget {
|
|||||||
final String titleText;
|
final String titleText;
|
||||||
final String contentText;
|
final String contentText;
|
||||||
final void Function() onYesPressed;
|
final void Function() onYesPressed;
|
||||||
final void Function() onNoPressed;
|
|
||||||
|
|
||||||
AppYesNoDialog({
|
AppYesNoDialog({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.titleText,
|
@required this.titleText,
|
||||||
@required this.contentText,
|
@required this.contentText,
|
||||||
@required this.onYesPressed,
|
@required this.onYesPressed,
|
||||||
@required this.onNoPressed,
|
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -26,7 +24,9 @@ class AppYesNoDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text("No"),
|
child: Text("No"),
|
||||||
onPressed: onNoPressed,
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
87
lib/widgets/detail_screen_floating_action_buttons.dart
Normal file
87
lib/widgets/detail_screen_floating_action_buttons.dart
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||||
|
import 'package:time_progress_tracker/widgets/app_yes_no_dialog_widget.dart';
|
||||||
|
|
||||||
|
class DetailScreenFloatingActionButtons extends StatelessWidget {
|
||||||
|
final bool editMode;
|
||||||
|
final TimeProgress originalProgress, editedProgress;
|
||||||
|
final void Function() onEditProgress,
|
||||||
|
onSaveEditedProgress,
|
||||||
|
onCancelEditProgress,
|
||||||
|
onDeleteProgress;
|
||||||
|
|
||||||
|
DetailScreenFloatingActionButtons({
|
||||||
|
@required this.editMode,
|
||||||
|
@required this.originalProgress,
|
||||||
|
@required this.editedProgress,
|
||||||
|
@required this.onEditProgress,
|
||||||
|
@required this.onSaveEditedProgress,
|
||||||
|
@required this.onCancelEditProgress,
|
||||||
|
@required this.onDeleteProgress,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final ThemeData appTheme = Theme.of(context);
|
||||||
|
|
||||||
|
void _onCancelEditTimeProgressBTN() {
|
||||||
|
if (originalProgress == editedProgress)
|
||||||
|
onCancelEditProgress();
|
||||||
|
else {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => AppYesNoDialog(
|
||||||
|
titleText: "Cancel Editing of ${originalProgress.name}",
|
||||||
|
contentText:
|
||||||
|
"Are you sure that you want to discard the changes done to ${originalProgress.name}",
|
||||||
|
onYesPressed: () {
|
||||||
|
onCancelEditProgress();
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onDeleteTimeProgressBTN() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => AppYesNoDialog(
|
||||||
|
titleText: "Delete ${originalProgress.name}",
|
||||||
|
contentText: "Are you sure you want to delete this time progress?",
|
||||||
|
onYesPressed: onDeleteProgress,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: FloatingActionButton(
|
||||||
|
heroTag:
|
||||||
|
editMode ? "saveEditedTimeProgressBTN" : "editTimeProgressBTN",
|
||||||
|
child: editMode ? Icon(Icons.save) : Icon(Icons.edit),
|
||||||
|
backgroundColor: editMode ? Colors.green : appTheme.accentColor,
|
||||||
|
onPressed: editMode
|
||||||
|
? TimeProgress.isValid(editedProgress)
|
||||||
|
? onSaveEditedProgress
|
||||||
|
: null
|
||||||
|
: onEditProgress,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: FloatingActionButton(
|
||||||
|
heroTag: editMode
|
||||||
|
? "cancelEditTimeProgressBTN"
|
||||||
|
: "deleteTimeProgressBTN",
|
||||||
|
child: editMode ? Icon(Icons.cancel) : Icon(Icons.delete),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
onPressed: editMode
|
||||||
|
? _onCancelEditTimeProgressBTN
|
||||||
|
: _onDeleteTimeProgressBTN,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
|
||||||
|
|
||||||
class ProgressDetailCircularPercent extends StatelessWidget {
|
|
||||||
final double percentDone;
|
|
||||||
|
|
||||||
ProgressDetailCircularPercent({Key key, @required this.percentDone})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return CircularPercentIndicator(
|
|
||||||
radius: 100,
|
|
||||||
lineWidth: 10,
|
|
||||||
percent: percentDone,
|
|
||||||
progressColor: Colors.green,
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
center: Text("${(percentDone * 100).floor()} %"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:time_progress_tracker/widgets/progress_detail_widgets/progress_detail_select_date_btn_widget.dart';
|
|
||||||
|
|
||||||
class ProgressDetailEditDatesRow extends StatelessWidget {
|
|
||||||
final DateTime startTime;
|
|
||||||
final DateTime endTime;
|
|
||||||
final void Function(DateTime) onStartTimeChanged;
|
|
||||||
final void Function(DateTime) onEndTimeChanged;
|
|
||||||
|
|
||||||
ProgressDetailEditDatesRow({
|
|
||||||
Key key,
|
|
||||||
@required this.startTime,
|
|
||||||
@required this.endTime,
|
|
||||||
@required this.onStartTimeChanged,
|
|
||||||
@required this.onEndTimeChanged,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
flex: 5,
|
|
||||||
child: ProgressDetailSelectDateButton(
|
|
||||||
leadingString: "Start Date:",
|
|
||||||
selectedDate: startTime,
|
|
||||||
onDateSelected: onStartTimeChanged,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Spacer(
|
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
flex: 5,
|
|
||||||
child: ProgressDetailSelectDateButton(
|
|
||||||
leadingString: "End Date:",
|
|
||||||
selectedDate: endTime,
|
|
||||||
onDateSelected: onEndTimeChanged,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class ProgressDetailFabEditingRow extends StatelessWidget {
|
|
||||||
final void Function() onSave;
|
|
||||||
final void Function() onCancelEdit;
|
|
||||||
|
|
||||||
ProgressDetailFabEditingRow({
|
|
||||||
Key key,
|
|
||||||
@required this.onSave,
|
|
||||||
@required this.onCancelEdit,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: FloatingActionButton(
|
|
||||||
heroTag: "saveEditedTimeProgressBTN",
|
|
||||||
child: Icon(Icons.save),
|
|
||||||
backgroundColor: Colors.green,
|
|
||||||
onPressed: this.onSave,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: FloatingActionButton(
|
|
||||||
heroTag: "cancelEditTimeProgressBTN",
|
|
||||||
child: Icon(Icons.cancel),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
onPressed: this.onCancelEdit,
|
|
||||||
))
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class ProgressDetailFabRow extends StatelessWidget {
|
|
||||||
final void Function() onEdit;
|
|
||||||
final void Function() onDelete;
|
|
||||||
|
|
||||||
ProgressDetailFabRow(
|
|
||||||
{Key key, @required this.onEdit, @required this.onDelete})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: FloatingActionButton(
|
|
||||||
heroTag: "editTimeProgressBTN",
|
|
||||||
child: Icon(Icons.edit),
|
|
||||||
onPressed: onEdit,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: FloatingActionButton(
|
|
||||||
heroTag: "deleteTimeProgressBTN",
|
|
||||||
child: Icon(Icons.delete),
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
onPressed: onDelete,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
|
||||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
|
||||||
|
|
||||||
class ProgressDetailLinearPercent extends StatelessWidget {
|
|
||||||
final TimeProgress timeProgress;
|
|
||||||
|
|
||||||
ProgressDetailLinearPercent({Key key, @required this.timeProgress})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return LinearPercentIndicator(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 15),
|
|
||||||
percent: this.timeProgress.percentDone(),
|
|
||||||
leading: Text("${this.timeProgress.daysBehind()} Days"),
|
|
||||||
center: Text("${(this.timeProgress.percentDone() * 100).floor()} %"),
|
|
||||||
trailing: Text("${this.timeProgress.daysLeft()} Days"),
|
|
||||||
progressColor: Colors.green,
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
lineHeight: 25,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class ProgressDetailSelectDateButton extends StatelessWidget {
|
|
||||||
final String leadingString;
|
|
||||||
final DateTime selectedDate;
|
|
||||||
final void Function(DateTime) onDateSelected;
|
|
||||||
|
|
||||||
ProgressDetailSelectDateButton({
|
|
||||||
Key key,
|
|
||||||
@required this.leadingString,
|
|
||||||
@required this.selectedDate,
|
|
||||||
@required this.onDateSelected,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
ThemeData appTheme = Theme.of(context);
|
|
||||||
|
|
||||||
return FlatButton(
|
|
||||||
color: appTheme.accentColor,
|
|
||||||
child: Text(
|
|
||||||
"$leadingString ${selectedDate.toLocal().toString().split(" ")[0]}"),
|
|
||||||
onPressed: () async {
|
|
||||||
DateTime picked = await showDatePicker(
|
|
||||||
context: context,
|
|
||||||
initialDate: selectedDate,
|
|
||||||
firstDate: DateTime(selectedDate.year - 5),
|
|
||||||
lastDate: DateTime(selectedDate.year + 5),
|
|
||||||
);
|
|
||||||
onDateSelected(picked);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user