Cleaned up the repo
Singed-off-by: Andreas Fahrecker <AndreasFahrecker@gmail.com>
This commit is contained in:
124
lib/ui/progress/progress_editor_widget.dart
Normal file
124
lib/ui/progress/progress_editor_widget.dart
Normal file
@ -0,0 +1,124 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||
import 'package:time_progress_tracker/ui/buttons/date_picker_btn.dart';
|
||||
|
||||
class ProgressEditorWidget extends StatefulWidget {
|
||||
final TimeProgress timeProgress;
|
||||
final Function(TimeProgress, bool) onTimeProgressChanged;
|
||||
|
||||
ProgressEditorWidget({
|
||||
@required this.timeProgress,
|
||||
@required this.onTimeProgressChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _ProgressEditorWidgetState();
|
||||
}
|
||||
}
|
||||
|
||||
class _ProgressEditorWidgetState extends State<ProgressEditorWidget> {
|
||||
final _nameTextController = TextEditingController();
|
||||
bool _validName = true, _validDate = true;
|
||||
|
||||
void _onNameChanged() {
|
||||
TimeProgress newProgress =
|
||||
widget.timeProgress.copyWith(name: _nameTextController.text);
|
||||
widget.onTimeProgressChanged(
|
||||
newProgress, TimeProgress.isValid(newProgress));
|
||||
setState(() {
|
||||
_validName = TimeProgress.isNameValid(newProgress.name);
|
||||
});
|
||||
}
|
||||
|
||||
void _onStartDateChanged(DateTime newStartDate) {
|
||||
TimeProgress newProgress =
|
||||
widget.timeProgress.copyWith(startTime: newStartDate);
|
||||
widget.onTimeProgressChanged(
|
||||
newProgress, TimeProgress.isValid(newProgress));
|
||||
setState(() {
|
||||
_validDate =
|
||||
TimeProgress.areTimesValid(newStartDate, newProgress.endTime);
|
||||
});
|
||||
}
|
||||
|
||||
void _onEndDateChanged(DateTime newEndDate) {
|
||||
TimeProgress newProgress =
|
||||
widget.timeProgress.copyWith(endTime: newEndDate);
|
||||
widget.onTimeProgressChanged(
|
||||
newProgress, TimeProgress.isValid(newProgress));
|
||||
setState(() {
|
||||
_validDate =
|
||||
TimeProgress.areTimesValid(newProgress.startTime, newEndDate);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_nameTextController.text = widget.timeProgress.name;
|
||||
_nameTextController.addListener(_onNameChanged);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> columnChildren = [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _nameTextController,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "Progress Name",
|
||||
errorText: _validName
|
||||
? null
|
||||
: "The Name need to have at least 3 and at max 20 symbols.",
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 5),
|
||||
child: DatePickerBtn(
|
||||
leadingString: "Start Date:",
|
||||
pickedDate: widget.timeProgress.startTime,
|
||||
onDatePicked: _onStartDateChanged,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
child: DatePickerBtn(
|
||||
leadingString: "End Date:",
|
||||
pickedDate: widget.timeProgress.endTime,
|
||||
onDatePicked: _onEndDateChanged,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
];
|
||||
|
||||
if (!_validDate)
|
||||
columnChildren.add(
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Invalid Dates. The Start Date has to be before the End Date",
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return Container(
|
||||
child: Column(
|
||||
children: columnChildren,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
74
lib/ui/progress/progress_list_item.dart
Normal file
74
lib/ui/progress/progress_list_item.dart
Normal file
@ -0,0 +1,74 @@
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||
import 'package:time_progress_tracker/ui/screens/progress_detail_screen.dart';
|
||||
|
||||
class ProgressListTileStrings {
|
||||
static String percentString(TimeProgress tp) =>
|
||||
"${(tp.percentDone() * 100).floorToDouble()} %";
|
||||
|
||||
static String startsInDaysString(TimeProgress tp) =>
|
||||
"Starts in ${tp.daysTillStart()} Days.";
|
||||
|
||||
static String endedDaysAgoString(TimeProgress tp) =>
|
||||
"Ended ${tp.daysSinceEnd()} Days ago.";
|
||||
}
|
||||
|
||||
class ProgressListItem extends StatelessWidget {
|
||||
final TimeProgress timeProgress;
|
||||
final Color doneColor, leftColor;
|
||||
|
||||
ProgressListItem({
|
||||
@required this.timeProgress,
|
||||
@required this.doneColor,
|
||||
@required this.leftColor,
|
||||
});
|
||||
|
||||
Widget _renderSubtitle(BuildContext context) {
|
||||
if (!timeProgress.hasStarted())
|
||||
return PlatformText(ProgressListTileStrings.startsInDaysString(timeProgress));
|
||||
if (timeProgress.hasEnded())
|
||||
return PlatformText(ProgressListTileStrings.endedDaysAgoString(timeProgress));
|
||||
return LinearPercentIndicator(
|
||||
center: PlatformText(ProgressListTileStrings.percentString(timeProgress)),
|
||||
percent: timeProgress.percentDone(),
|
||||
progressColor: doneColor,
|
||||
backgroundColor: leftColor,
|
||||
lineHeight: 20,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
void _onTileTap() =>
|
||||
Navigator.pushNamed(context, ProgressDetailScreen.routeName,
|
||||
arguments: ProgressDetailScreenArguments(timeProgress.id));
|
||||
Text titleText = Text(timeProgress.name);
|
||||
|
||||
if (Platform.isIOS)
|
||||
return CupertinoButton(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
padding: EdgeInsets.fromLTRB(15, 15, 5, 5),
|
||||
child: Column(
|
||||
children: [
|
||||
titleText,
|
||||
_renderSubtitle(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: _onTileTap);
|
||||
return ListTile(
|
||||
title: titleText,
|
||||
subtitle: _renderSubtitle(context),
|
||||
onTap: _onTileTap,
|
||||
);
|
||||
}
|
||||
}
|
40
lib/ui/progress/progress_list_view.dart
Normal file
40
lib/ui/progress/progress_list_view.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||
import 'package:time_progress_tracker/ui/progress/progress_list_item.dart';
|
||||
|
||||
class ProgressListView extends StatelessWidget {
|
||||
final List<TimeProgress> timeProgressList;
|
||||
final Color doneColor, leftColor;
|
||||
|
||||
ProgressListView({
|
||||
@required this.timeProgressList,
|
||||
@required this.doneColor,
|
||||
@required this.leftColor,
|
||||
});
|
||||
|
||||
Widget _renderListTile(TimeProgress tp) {
|
||||
ProgressListItem listTile = ProgressListItem(
|
||||
timeProgress: tp, doneColor: doneColor, leftColor: leftColor);
|
||||
if (Platform.isIOS) return listTile;
|
||||
return Card(
|
||||
child: listTile,
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _renderListViewChildren() {
|
||||
return timeProgressList
|
||||
.map((e) => _renderListTile(e))
|
||||
.toList(growable: false);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView(
|
||||
padding: EdgeInsets.all(8),
|
||||
children: _renderListViewChildren(),
|
||||
);
|
||||
}
|
||||
}
|
64
lib/ui/progress/progress_view_widget.dart
Normal file
64
lib/ui/progress/progress_view_widget.dart
Normal file
@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||
|
||||
class ProgressViewWidget extends StatelessWidget {
|
||||
final TimeProgress timeProgress;
|
||||
final Color doneColor;
|
||||
final Color leftColor;
|
||||
|
||||
ProgressViewWidget({
|
||||
@required this.timeProgress,
|
||||
@required this.doneColor,
|
||||
@required this.leftColor,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: FittedBox(
|
||||
fit: BoxFit.fitWidth,
|
||||
child: Text(
|
||||
timeProgress.name,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CircularPercentIndicator(
|
||||
radius: 100,
|
||||
lineWidth: 10,
|
||||
percent: timeProgress.percentDone(),
|
||||
progressColor: doneColor,
|
||||
backgroundColor: leftColor,
|
||||
center: Text("${(timeProgress.percentDone() * 100).floor()} %"),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: LinearPercentIndicator(
|
||||
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||
percent: timeProgress.percentDone(),
|
||||
leading: Text("${timeProgress.daysBehind()} Days"),
|
||||
center: Text(
|
||||
"${(timeProgress.percentDone() * 100).floor()} %",
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
trailing: Text("${timeProgress.daysLeft()} Days"),
|
||||
progressColor: doneColor,
|
||||
backgroundColor: leftColor,
|
||||
lineHeight: 25,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user