Feature/basic app (#1)
Feature/Basic App (#1) Basic App Structure Consists of Time Progress Dashboard, Time Progress Detail View and Time Progress Creator. All of these have an AppDrawer with a Link To the Dashboard and all your Track Time Progresses, also an About Button. Commits: * Undetailed Commit more work * Changed isEditing ? in Detail Screen and Extracted FAB row to widget * Extracted Progress Detail Fab Row and Progress Detail select Date Btn to widgets * Create Progress Detail Widgets Folder * Extracted Edit Dates Row Widget * Extracted Functions from ui * Made some fields private * LoadTimerProgressList if unloaded function * Created App Yes No Dialog Widget * Using Yes No Dialog in Detail Screen * Created TimeProgress Initial Default factory * Renamed to Time Progress Tracker * Added About Button in App Drawer * Code cleanup * Code clean up and fixed Bug with null as string in Repository Signed-off-by Andreas Fahrecker <AndreasFahrecker@gmail.com>
This commit is contained in:
committed by
GitHub
parent
976fbec455
commit
f013c0de65
110
lib/widgets/app_drawer_widget.dart
Normal file
110
lib/widgets/app_drawer_widget.dart
Normal file
@ -0,0 +1,110 @@
|
||||
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/progress_dashboard_screen.dart';
|
||||
import 'package:time_progress_tracker/screens/progress_detail_screen.dart';
|
||||
|
||||
class AppDrawer extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Drawer(
|
||||
child: StoreConnector(
|
||||
converter: _ViewModel.fromStore,
|
||||
onInit: loadTimeProgressListIfUnloaded,
|
||||
builder: (context, _ViewModel vm) {
|
||||
List<Widget> drawerTileList = List<Widget>();
|
||||
drawerTileList.add(DrawerHeader(
|
||||
child: Text(TimeProgressTrackerApp.name),
|
||||
decoration: BoxDecoration(color: Colors.blue),
|
||||
margin: EdgeInsets.zero,
|
||||
));
|
||||
drawerTileList.add(Container(
|
||||
color: Colors.lightBlue,
|
||||
margin: EdgeInsets.only(bottom: 8),
|
||||
child: ListTile(
|
||||
title: Text(ProgressDashboardScreen.title),
|
||||
trailing: Icon(Icons.dashboard),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.pushNamed(context, ProgressDashboardScreen.routeName);
|
||||
},
|
||||
),
|
||||
));
|
||||
if (vm.timeProgressList.length > 0) {
|
||||
for (TimeProgress tp in vm.timeProgressList) {
|
||||
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.timeProgressList.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 0.0.1',
|
||||
applicationLegalese: '\u00a9Andreas Fahrecker 2020'
|
||||
);
|
||||
},
|
||||
),
|
||||
));
|
||||
return ListView(
|
||||
children: drawerTileList,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ViewModel {
|
||||
final List<TimeProgress> timeProgressList;
|
||||
|
||||
_ViewModel({@required this.timeProgressList});
|
||||
|
||||
static _ViewModel fromStore(Store<AppState> store) {
|
||||
return _ViewModel(
|
||||
timeProgressList: store.state.timeProgressList,
|
||||
);
|
||||
}
|
||||
}
|
34
lib/widgets/app_yes_no_dialog_widget.dart
Normal file
34
lib/widgets/app_yes_no_dialog_widget.dart
Normal file
@ -0,0 +1,34 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppYesNoDialog extends StatelessWidget {
|
||||
final String titleText;
|
||||
final String contentText;
|
||||
final void Function() onYesPressed;
|
||||
final void Function() onNoPressed;
|
||||
|
||||
AppYesNoDialog({
|
||||
Key key,
|
||||
@required this.titleText,
|
||||
@required this.contentText,
|
||||
@required this.onYesPressed,
|
||||
@required this.onNoPressed,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(titleText),
|
||||
content: Text(contentText),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text("Yes"),
|
||||
onPressed: onYesPressed,
|
||||
),
|
||||
FlatButton(
|
||||
child: Text("No"),
|
||||
onPressed: onNoPressed,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
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()} %"),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
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,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
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,
|
||||
))
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
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,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
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) {
|
||||
return FlatButton(
|
||||
color: Colors.blue,
|
||||
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);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user