New App Layout
Signed-off-by: Andreas Fahrecker <AndreasFahrecker@gmail.com>
This commit is contained in:
parent
c5e240e813
commit
409ccbcdda
14
lib/app.dart
14
lib/app.dart
@ -10,12 +10,10 @@ class TimeProgressTrackerApp extends StatelessWidget {
|
|||||||
static const String name = "Time Progress Tracker";
|
static const String name = "Time Progress Tracker";
|
||||||
|
|
||||||
final Store<AppState> store;
|
final Store<AppState> store;
|
||||||
final String appVersion;
|
|
||||||
|
|
||||||
TimeProgressTrackerApp({
|
TimeProgressTrackerApp({
|
||||||
Key key,
|
Key key,
|
||||||
this.store,
|
this.store,
|
||||||
this.appVersion,
|
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -33,17 +31,11 @@ class TimeProgressTrackerApp extends StatelessWidget {
|
|||||||
initialRoute: ProgressDashboardScreen.routeName,
|
initialRoute: ProgressDashboardScreen.routeName,
|
||||||
routes: {
|
routes: {
|
||||||
ProgressDashboardScreen.routeName: (BuildContext context) =>
|
ProgressDashboardScreen.routeName: (BuildContext context) =>
|
||||||
ProgressDashboardScreen(
|
ProgressDashboardScreen(),
|
||||||
appVersion: appVersion,
|
|
||||||
),
|
|
||||||
ProgressDetailScreen.routeName: (BuildContext context) =>
|
ProgressDetailScreen.routeName: (BuildContext context) =>
|
||||||
ProgressDetailScreen(
|
ProgressDetailScreen(),
|
||||||
appVersion: appVersion,
|
|
||||||
),
|
|
||||||
ProgressCreationScreen.routeName: (BuildContext context) =>
|
ProgressCreationScreen.routeName: (BuildContext context) =>
|
||||||
ProgressCreationScreen(
|
ProgressCreationScreen(),
|
||||||
appVersion: appVersion,
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -19,6 +19,5 @@ Future<void> main() async {
|
|||||||
TimeProgressRepository(await SharedPreferences.getInstance()),
|
TimeProgressRepository(await SharedPreferences.getInstance()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
appVersion: (await PackageInfo.fromPlatform()).version,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ class TimeProgress {
|
|||||||
|
|
||||||
factory TimeProgress.initialDefault() {
|
factory TimeProgress.initialDefault() {
|
||||||
int thisYear = DateTime.now().year;
|
int thisYear = DateTime.now().year;
|
||||||
return TimeProgress("Initial Name", DateTime(thisYear - 1), DateTime(thisYear + 1));
|
return TimeProgress(
|
||||||
|
"Initial Name", DateTime(thisYear - 1), DateTime(thisYear + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeProgress copyWith(
|
TimeProgress copyWith(
|
||||||
@ -48,6 +49,16 @@ class TimeProgress {
|
|||||||
return this.daysBehind() / (this.allDays() / 100) / 100;
|
return this.daysBehind() / (this.allDays() / 100) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasStarted() {
|
||||||
|
return DateTime.now().millisecondsSinceEpoch >
|
||||||
|
startTime.millisecondsSinceEpoch;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasEnded() {
|
||||||
|
return DateTime.now().millisecondsSinceEpoch >
|
||||||
|
endTime.millisecondsSinceEpoch;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
id.hashCode ^ name.hashCode ^ startTime.hashCode ^ endTime.hashCode;
|
id.hashCode ^ name.hashCode ^ startTime.hashCode ^ endTime.hashCode;
|
||||||
|
@ -11,11 +11,6 @@ import 'package:time_progress_tracker/widgets/app_drawer_widget.dart';
|
|||||||
class ProgressCreationScreen extends StatefulWidget {
|
class ProgressCreationScreen extends StatefulWidget {
|
||||||
static const routeName = "/progress-creation";
|
static const routeName = "/progress-creation";
|
||||||
|
|
||||||
final String appVersion;
|
|
||||||
|
|
||||||
ProgressCreationScreen({Key key, @required this.appVersion})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
return _ProgressCreationScreenState();
|
return _ProgressCreationScreenState();
|
||||||
@ -67,9 +62,9 @@ class _ProgressCreationScreenState extends State<ProgressCreationScreen> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text("Create Time Progress"),
|
title: Text("Create Time Progress"),
|
||||||
),
|
),
|
||||||
drawer: AppDrawer(
|
/*drawer: AppDrawer(
|
||||||
appVersion: widget.appVersion,
|
appVersion: widget.appVersion,
|
||||||
),
|
),*/
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.all(8),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -1,38 +1,49 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
|
||||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
|
||||||
import 'package:redux/redux.dart';
|
import 'package:redux/redux.dart';
|
||||||
import 'package:time_progress_tracker/actions/actions.dart';
|
|
||||||
import 'package:time_progress_tracker/models/app_state.dart';
|
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/progress_creation_screen.dart';
|
import 'package:time_progress_tracker/screens/progress_creation_screen.dart';
|
||||||
import 'package:time_progress_tracker/screens/progress_detail_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_drawer_widget.dart';
|
import 'package:time_progress_tracker/widgets/home_widgets/home_bottom_navbar.dart';
|
||||||
|
import 'package:time_progress_tracker/widgets/home_widgets/home_active_progresses_tab.dart';
|
||||||
|
import 'package:time_progress_tracker/widgets/home_widgets/home_inactive_progresses_tab.dart';
|
||||||
|
import 'package:time_progress_tracker/widgets/home_widgets/home_settings_tab.dart';
|
||||||
|
|
||||||
class ProgressDashboardScreen extends StatelessWidget {
|
class ProgressDashboardScreen extends StatefulWidget {
|
||||||
static const routeName = "/progress-dashboard";
|
static const routeName = "/progress-dashboard";
|
||||||
static const title = "Time Progress Dashboard";
|
static const title = "Time Progress Tracker";
|
||||||
|
|
||||||
final String appVersion;
|
@override
|
||||||
|
State<StatefulWidget> createState() {
|
||||||
|
return _ProgressDashboardScreenState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ProgressDashboardScreen({
|
class _ProgressDashboardScreenState extends State<ProgressDashboardScreen> {
|
||||||
Key key,
|
int _currentIndex = 0;
|
||||||
@required this.appVersion,
|
final List<Widget> _children = [
|
||||||
}) : super(key: key);
|
HomeActiveProgressesTab(),
|
||||||
|
HomeInactiveProgressesTab(),
|
||||||
|
HomeSettingsTab(),
|
||||||
|
];
|
||||||
|
|
||||||
|
void onBottomTabTapped(int index) {
|
||||||
|
setState(() {
|
||||||
|
_currentIndex = index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
AppBar appBar = AppBar(
|
ThemeData appTheme = Theme.of(context);
|
||||||
title: Text(title),
|
|
||||||
);
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: appBar,
|
appBar: AppBar(
|
||||||
drawer: AppDrawer(
|
title: Text(ProgressDashboardScreen.title),
|
||||||
appVersion: appVersion,
|
|
||||||
),
|
),
|
||||||
body: StoreConnector(
|
body: _children[_currentIndex],
|
||||||
|
/*
|
||||||
|
StoreConnector(
|
||||||
converter: _ViewModel.fromStore,
|
converter: _ViewModel.fromStore,
|
||||||
onInit: loadTimeProgressListIfUnloaded,
|
onInit: loadTimeProgressListIfUnloaded,
|
||||||
builder: (BuildContext context, _ViewModel vm) {
|
builder: (BuildContext context, _ViewModel vm) {
|
||||||
@ -43,29 +54,6 @@ class ProgressDashboardScreen extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> startedProgressesTileList = List<Widget>();
|
List<Widget> startedProgressesTileList = List<Widget>();
|
||||||
if (vm.hasCurrentProgresses) {
|
|
||||||
for (TimeProgress tp in vm.currentTimeProgresses) {
|
|
||||||
startedProgressesTileList.add(
|
|
||||||
Card(
|
|
||||||
child: ListTile(
|
|
||||||
title: Text(tp.name),
|
|
||||||
subtitle: LinearPercentIndicator(
|
|
||||||
center: Text("${(tp.percentDone() * 100).floor()} %"),
|
|
||||||
percent: tp.percentDone(),
|
|
||||||
progressColor: Colors.green,
|
|
||||||
backgroundColor: Colors.red,
|
|
||||||
lineHeight: 20,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pushNamed(
|
|
||||||
context, ProgressDetailScreen.routeName,
|
|
||||||
arguments: ProgressDetailScreenArguments(tp.id));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> futureProgressesTileList = List<Widget>();
|
List<Widget> futureProgressesTileList = List<Widget>();
|
||||||
if (vm.hasFutureProgresses) {
|
if (vm.hasFutureProgresses) {
|
||||||
@ -107,8 +95,7 @@ class ProgressDashboardScreen extends StatelessWidget {
|
|||||||
|
|
||||||
double dividerHeight = 1;
|
double dividerHeight = 1;
|
||||||
double screenHeight = MediaQuery.of(context).size.height -
|
double screenHeight = MediaQuery.of(context).size.height -
|
||||||
appBar.preferredSize.height -
|
50 -
|
||||||
24 -
|
|
||||||
dividerHeight -
|
dividerHeight -
|
||||||
1; //Divider
|
1; //Divider
|
||||||
|
|
||||||
@ -118,43 +105,13 @@ class ProgressDashboardScreen extends StatelessWidget {
|
|||||||
vm.pastTimeProgresses.length;
|
vm.pastTimeProgresses.length;
|
||||||
if (vm.hasCurrentProgresses) {
|
if (vm.hasCurrentProgresses) {
|
||||||
columnChildren.add(Container(
|
columnChildren.add(Container(
|
||||||
height:
|
height: screenHeight - 100,
|
||||||
(screenHeight / tpCount) * vm.currentTimeProgresses.length,
|
|
||||||
child: ListView(
|
child: ListView(
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.all(8),
|
||||||
children: startedProgressesTileList,
|
children: startedProgressesTileList,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (vm.hasCurrentProgresses && vm.hasFutureProgresses) {
|
|
||||||
columnChildren.add(Divider(
|
|
||||||
height: dividerHeight,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if (vm.hasFutureProgresses) {
|
|
||||||
columnChildren.add(Container(
|
|
||||||
height: (screenHeight / tpCount) * vm.futureTimeProgresses.length,
|
|
||||||
child: ListView(
|
|
||||||
padding: EdgeInsets.all(8),
|
|
||||||
children: futureProgressesTileList,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if ((vm.hasCurrentProgresses || vm.hasFutureProgresses) &&
|
|
||||||
vm.pastTimeProgresses.length > 0) {
|
|
||||||
columnChildren.add(Divider(
|
|
||||||
height: dividerHeight,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if (vm.pastTimeProgresses.length > 0) {
|
|
||||||
columnChildren.add(Container(
|
|
||||||
height: (screenHeight / tpCount) * vm.pastTimeProgresses.length,
|
|
||||||
child: ListView(
|
|
||||||
padding: EdgeInsets.all(8),
|
|
||||||
children: pastProgressesTileList,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vm.hasCurrentProgresses &&
|
if (!vm.hasCurrentProgresses &&
|
||||||
!vm.hasFutureProgresses &&
|
!vm.hasFutureProgresses &&
|
||||||
@ -171,14 +128,21 @@ class ProgressDashboardScreen extends StatelessWidget {
|
|||||||
children: columnChildren,
|
children: columnChildren,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
)
|
||||||
|
*/
|
||||||
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: _currentIndex != 2
|
||||||
heroTag: "createProgressBTN",
|
? FloatingActionButton(
|
||||||
child: Icon(Icons.add),
|
heroTag: "createProgressBTN",
|
||||||
onPressed: () {
|
child: Icon(Icons.add),
|
||||||
Navigator.pushNamed(context, ProgressCreationScreen.routeName);
|
onPressed: () {
|
||||||
},
|
Navigator.pushNamed(context, ProgressCreationScreen.routeName);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
bottomNavigationBar: HomeBottomNavBar(
|
||||||
|
currentIndex: _currentIndex,
|
||||||
|
onTap: onBottomTabTapped,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,6 @@ class ProgressDetailScreenArguments {
|
|||||||
class ProgressDetailScreen extends StatefulWidget {
|
class ProgressDetailScreen extends StatefulWidget {
|
||||||
static const routeName = "/progress-detail";
|
static const routeName = "/progress-detail";
|
||||||
|
|
||||||
final String appVersion;
|
|
||||||
|
|
||||||
ProgressDetailScreen({
|
|
||||||
Key key,
|
|
||||||
@required this.appVersion,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() {
|
State<StatefulWidget> createState() {
|
||||||
return _ProgressDetailScreenState();
|
return _ProgressDetailScreenState();
|
||||||
@ -154,9 +147,9 @@ class _ProgressDetailScreenState extends State<ProgressDetailScreen> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text("Progress"),
|
title: Text("Progress"),
|
||||||
),
|
),
|
||||||
drawer: AppDrawer(
|
/*drawer: AppDrawer(
|
||||||
appVersion: widget.appVersion,
|
appVersion: widget.appVersion,
|
||||||
),
|
),*/
|
||||||
body: Container(
|
body: Container(
|
||||||
margin: EdgeInsets.all(8),
|
margin: EdgeInsets.all(8),
|
||||||
child: StoreConnector(
|
child: StoreConnector(
|
||||||
|
@ -4,6 +4,21 @@ import 'package:time_progress_tracker/models/time_progress.dart';
|
|||||||
List<TimeProgress> timeProgressListSelector(AppState state) =>
|
List<TimeProgress> timeProgressListSelector(AppState state) =>
|
||||||
state.timeProgressList;
|
state.timeProgressList;
|
||||||
|
|
||||||
|
List<TimeProgress> activeTimeProgressesSelector(AppState state) {
|
||||||
|
return state.timeProgressList
|
||||||
|
.where((timeProgress) =>
|
||||||
|
timeProgress.hasStarted() && !timeProgress.hasEnded())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TimeProgress> inactiveTimeProgressesSelector(AppState state) {
|
||||||
|
return state.timeProgressList
|
||||||
|
.where((timeProgress) =>
|
||||||
|
!timeProgress.hasStarted() || timeProgress.hasEnded())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("use active TimeProgresses Selector instead.")
|
||||||
List<TimeProgress> currentTimeProgressSelector(AppState state) {
|
List<TimeProgress> currentTimeProgressSelector(AppState state) {
|
||||||
int currentTime = DateTime.now().millisecondsSinceEpoch;
|
int currentTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
return state.timeProgressList
|
return state.timeProgressList
|
||||||
|
57
lib/widgets/home_widgets/home_active_progresses_tab.dart
Normal file
57
lib/widgets/home_widgets/home_active_progresses_tab.dart
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:time_progress_tracker/actions/actions.dart';
|
||||||
|
import 'package:time_progress_tracker/models/app_state.dart';
|
||||||
|
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||||
|
import 'package:time_progress_tracker/selectors/time_progress_selectors.dart';
|
||||||
|
import 'package:time_progress_tracker/widgets/home_widgets/home_progress_list_tile.dart';
|
||||||
|
|
||||||
|
class HomeActiveProgressesTab extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
ThemeData appTheme = Theme.of(context);
|
||||||
|
return StoreConnector(
|
||||||
|
converter: _ViewModel.fromStore,
|
||||||
|
onInit: loadTimeProgressListIfUnloaded,
|
||||||
|
builder: (BuildContext scContext, _ViewModel vm) {
|
||||||
|
if (!vm.hasLoaded)
|
||||||
|
return Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
if (vm.activeTimeProgresses.length < 1)
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
"You don't have any currently active time progresses, that are tracked."),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return ListView(
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
children: vm.activeTimeProgresses
|
||||||
|
.map((timeProgress) => HomeProgressListTile(
|
||||||
|
timeProgress: timeProgress,
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ViewModel {
|
||||||
|
final List<TimeProgress> activeTimeProgresses;
|
||||||
|
final bool hasLoaded;
|
||||||
|
|
||||||
|
_ViewModel({
|
||||||
|
@required this.activeTimeProgresses,
|
||||||
|
@required this.hasLoaded,
|
||||||
|
});
|
||||||
|
|
||||||
|
static _ViewModel fromStore(Store<AppState> store) {
|
||||||
|
return _ViewModel(
|
||||||
|
activeTimeProgresses: activeTimeProgressesSelector(store.state),
|
||||||
|
hasLoaded: store.state.hasLoaded,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
45
lib/widgets/home_widgets/home_bottom_navbar.dart
Normal file
45
lib/widgets/home_widgets/home_bottom_navbar.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class HomeBottomNavBar extends StatelessWidget {
|
||||||
|
final int currentIndex;
|
||||||
|
final Function onTap;
|
||||||
|
|
||||||
|
HomeBottomNavBar({
|
||||||
|
Key key,
|
||||||
|
@required this.currentIndex,
|
||||||
|
@required this.onTap,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
ThemeData appTheme = Theme.of(context);
|
||||||
|
|
||||||
|
return BottomNavigationBar(
|
||||||
|
onTap: onTap,
|
||||||
|
currentIndex: currentIndex,
|
||||||
|
items: [
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: new Icon(
|
||||||
|
Icons.alarm,
|
||||||
|
color: appTheme.primaryColor,
|
||||||
|
),
|
||||||
|
label: "Active Progresses",
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: new Icon(
|
||||||
|
Icons.alarm_off,
|
||||||
|
color: appTheme.primaryColor,
|
||||||
|
),
|
||||||
|
label: "Inactive Progresses",
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: new Icon(
|
||||||
|
Icons.settings,
|
||||||
|
color: appTheme.primaryColor,
|
||||||
|
),
|
||||||
|
label: "Settings",
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
60
lib/widgets/home_widgets/home_inactive_progresses_tab.dart
Normal file
60
lib/widgets/home_widgets/home_inactive_progresses_tab.dart
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
import 'package:redux/redux.dart';
|
||||||
|
import 'package:time_progress_tracker/actions/actions.dart';
|
||||||
|
import 'package:time_progress_tracker/models/app_state.dart';
|
||||||
|
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||||
|
import 'package:time_progress_tracker/selectors/time_progress_selectors.dart';
|
||||||
|
import 'package:time_progress_tracker/widgets/home_widgets/home_progress_list_tile.dart';
|
||||||
|
|
||||||
|
class HomeInactiveProgressesTab extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
ThemeData appTheme = Theme.of(context);
|
||||||
|
// TODO: implement build
|
||||||
|
return StoreConnector(
|
||||||
|
converter: _ViewModel.fromStore,
|
||||||
|
onInit: loadTimeProgressListIfUnloaded,
|
||||||
|
builder: (BuildContext scContext, _ViewModel vm) {
|
||||||
|
if (!vm.hasLoaded)
|
||||||
|
return Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
if (vm.inactiveTimeProgresses.length < 1)
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
"You don't have any currently inactive time progresses, that are tracked."),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return ListView(
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
children: vm.inactiveTimeProgresses
|
||||||
|
.map((timeProgress) =>
|
||||||
|
HomeProgressListTile(timeProgress: timeProgress))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return Container(
|
||||||
|
child: Text("Inactive Progresses"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ViewModel {
|
||||||
|
final List<TimeProgress> inactiveTimeProgresses;
|
||||||
|
final bool hasLoaded;
|
||||||
|
|
||||||
|
_ViewModel({
|
||||||
|
@required this.inactiveTimeProgresses,
|
||||||
|
@required this.hasLoaded,
|
||||||
|
});
|
||||||
|
|
||||||
|
static _ViewModel fromStore(Store<AppState> store) {
|
||||||
|
return _ViewModel(
|
||||||
|
inactiveTimeProgresses: inactiveTimeProgressesSelector(store.state),
|
||||||
|
hasLoaded: store.state.hasLoaded,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
44
lib/widgets/home_widgets/home_progress_list_tile.dart
Normal file
44
lib/widgets/home_widgets/home_progress_list_tile.dart
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
|
import 'package:time_progress_tracker/models/time_progress.dart';
|
||||||
|
import 'package:time_progress_tracker/screens/progress_detail_screen.dart';
|
||||||
|
|
||||||
|
class HomeProgressListTile extends StatelessWidget {
|
||||||
|
final TimeProgress timeProgress;
|
||||||
|
|
||||||
|
HomeProgressListTile({
|
||||||
|
Key key,
|
||||||
|
@required this.timeProgress,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Widget listTileSubTitle;
|
||||||
|
if (timeProgress.hasStarted() && !timeProgress.hasEnded())
|
||||||
|
listTileSubTitle = LinearPercentIndicator(
|
||||||
|
center: Text("${(timeProgress.percentDone() * 100).floor()} %"),
|
||||||
|
percent: timeProgress.percentDone(),
|
||||||
|
progressColor: Colors.green,
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
lineHeight: 20,
|
||||||
|
);
|
||||||
|
if (!timeProgress.hasStarted())
|
||||||
|
listTileSubTitle = Text(
|
||||||
|
"Starts in ${timeProgress.startTime.difference(DateTime.now()).inDays} Days");
|
||||||
|
if (timeProgress.hasEnded())
|
||||||
|
listTileSubTitle = Text(
|
||||||
|
"Ended ${DateTime.now().difference(timeProgress.endTime).inDays} Days ago.");
|
||||||
|
|
||||||
|
return Card(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(timeProgress.name),
|
||||||
|
subtitle: listTileSubTitle,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pushNamed(context, ProgressDetailScreen.routeName,
|
||||||
|
arguments: ProgressDetailScreenArguments(timeProgress.id));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
30
lib/widgets/home_widgets/home_settings_tab.dart
Normal file
30
lib/widgets/home_widgets/home_settings_tab.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:package_info/package_info.dart';
|
||||||
|
import 'package:time_progress_tracker/app.dart';
|
||||||
|
|
||||||
|
class HomeSettingsTab extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
ThemeData appTheme = Theme.of(context);
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text("The Settings of this App are not yet implemented."),
|
||||||
|
FlatButton(
|
||||||
|
onPressed: () {
|
||||||
|
showAboutDialog(
|
||||||
|
context: context,
|
||||||
|
applicationName: TimeProgressTrackerApp.name,
|
||||||
|
applicationVersion: "Beta",
|
||||||
|
applicationLegalese: '\u00a9Andreas Fahrecker 2020-2021');
|
||||||
|
},
|
||||||
|
child: Text("About"))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
10
pubspec.lock
10
pubspec.lock
@ -134,7 +134,7 @@ packages:
|
|||||||
name: image
|
name: image
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.18"
|
version: "2.1.19"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -162,7 +162,7 @@ packages:
|
|||||||
name: package_info
|
name: package_info
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.3+2"
|
version: "0.4.3+4"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -197,7 +197,7 @@ packages:
|
|||||||
name: percent_indicator
|
name: percent_indicator
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.9+1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -274,7 +274,7 @@ packages:
|
|||||||
name: shared_preferences_windows
|
name: shared_preferences_windows
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.1+3"
|
version: "0.0.2+3"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -342,7 +342,7 @@ packages:
|
|||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.3"
|
version: "1.7.4+1"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 0.0.7+7
|
version: 0.0.8+8
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user