From 9144664c98824924e3d7668557a4455693bcf7f6 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Tue, 16 Aug 2022 15:14:43 +0200 Subject: saving and reading --- lib/main.dart | 7 +- lib/pages/add_shift_page.dart | 33 ++++++-- lib/pages/agenda_page.dart | 16 ++-- lib/pages/home_page.dart | 14 +-- lib/services/program_provider_service.dart | 104 +++++++++++++++++++++++ lib/shift.dart | 29 +++++-- lib/widgets/agenda_week_item.dart | 132 +++++++++++++++++++++-------- 7 files changed, 272 insertions(+), 63 deletions(-) create mode 100644 lib/services/program_provider_service.dart (limited to 'lib') diff --git a/lib/main.dart b/lib/main.dart index 88db8b5..5690a5f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,7 @@ import 'package:event_bus/event_bus.dart'; import 'package:flutter/material.dart'; import 'package:training_planner/services/ishift_provider_service.dart'; import 'package:training_planner/services/mock_program_provider_service.dart'; +import 'package:training_planner/services/program_provider_service.dart'; import 'pages/home_page.dart'; import 'package:local_auth/local_auth.dart'; @@ -9,7 +10,7 @@ void main() { runApp(const MyApp()); } -IProgramProviderService shiftProvider = MockShiftProviderService(); +IProgramProviderService shiftProvider = ShiftProviderService(); final LocalAuthentication auth = LocalAuthentication(); EventBus eventBus = EventBus(); @@ -25,7 +26,9 @@ class MyApp extends StatelessWidget { theme: ThemeData( backgroundColor: Color.fromARGB(255, 255, 204, 0), ), - home: HomePage(), + home: HomePage( + agendaWeekNr: 0, + ), ); } } diff --git a/lib/pages/add_shift_page.dart b/lib/pages/add_shift_page.dart index 64b6142..d81ae3e 100644 --- a/lib/pages/add_shift_page.dart +++ b/lib/pages/add_shift_page.dart @@ -32,6 +32,9 @@ class _AddShiftPageState extends State { void addShift() { DateTime startDate = widget.mondayOfWeek; switch (dropdownValue) { + case 'Maandag': + startDate = startDate.add(Duration(days: 0)); + break; case 'Dinsdag': startDate = startDate.add(Duration(days: 1)); break; @@ -52,20 +55,34 @@ class _AddShiftPageState extends State { break; } - shiftProvider.addShift(Shift( - start: startDate, - type: isSelected[0] - ? ShiftType.Dagrit - : isSelected[1] - ? ShiftType.Avondrit - : ShiftType.Terugscannen)); + ShiftType type = ShiftType.Dagrit; + if (isSelected[1]) type = ShiftType.Avondrit; + if (isSelected[2]) type = ShiftType.Terugscannen; + + switch (type) { + case ShiftType.Dagrit: + startDate = startDate.add(Duration(hours: 10)); + break; + case ShiftType.Avondrit: + startDate = startDate.add(Duration( + hours: startDate.weekday == 6 ? 15 : 17, + minutes: startDate.weekday == 6 ? 30 : 0)); + break; + case ShiftType.Terugscannen: + startDate = startDate.add( + Duration(hours: startDate.weekday == 6 ? 13 : 14, minutes: 30)); + break; + } + + shiftProvider.addShift(Shift(start: startDate, type: type)); Navigator.pop(context, true); // Previous page will not refresh without this. Navigator.pushAndRemoveUntil( context, - MaterialPageRoute(builder: (context) => HomePage()), + MaterialPageRoute( + builder: (context) => HomePage(agendaWeekNr: widget.pageIndex)), (Route route) => false, ); } diff --git a/lib/pages/agenda_page.dart b/lib/pages/agenda_page.dart index 55c7360..a273cd0 100644 --- a/lib/pages/agenda_page.dart +++ b/lib/pages/agenda_page.dart @@ -9,10 +9,12 @@ import 'package:training_planner/widgets/agenda_week.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; class AgendaPage extends StatefulWidget { + final int agendaWeekNr; + @override _AgendaPageState createState() => _AgendaPageState(); - const AgendaPage({Key? key}) : super(key: key); + const AgendaPage({Key? key, required this.agendaWeekNr}) : super(key: key); } class _AgendaPageState extends State { @@ -28,10 +30,12 @@ class _AgendaPageState extends State { initState() { super.initState(); + weekToStartAt = widget.agendaWeekNr; weeks = getWeeks(); currentSelectedPageIndex = weekToStartAt; currentSelectedPageNr = weekNrs[weekToStartAt]; + currentSelectedWeek = dateTimes[weekToStartAt]; } List getWeeks() { @@ -52,7 +56,7 @@ class _AgendaPageState extends State { bool isCurrentWeek = false; if (mondayOfWeek == firstDayOfCurrentWeek) { - weekToStartAt = i; + if (weekToStartAt == 0) weekToStartAt = i; isCurrentWeek = true; } @@ -102,13 +106,7 @@ class _AgendaPageState extends State { pageIndex: currentSelectedPageIndex, mondayOfWeek: currentSelectedWeek, )), - ).then((val) => { - setState(() { - weeks = getWeeks(); - currentSelectedPageIndex = weekToStartAt; - currentSelectedPageNr = weekNrs[weekToStartAt]; - }) - }); + ); }, backgroundColor: Style.titleColor, child: const Icon(Icons.add), diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 821caed..6b81451 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -6,27 +6,31 @@ import 'package:training_planner/main.dart'; import 'package:training_planner/style/style.dart'; class HomePage extends StatefulWidget { + int agendaWeekNr; @override _HomePageState createState() => _HomePageState(); - const HomePage({Key? key}) : super(key: key); + HomePage({Key? key, required this.agendaWeekNr}) : super(key: key); } class _HomePageState extends State { int _selectedIndex = 0; - static final List _widgetOptions = [ - new AgendaPage(), - new LogbookPage(), - ]; + List _widgetOptions = []; @override initState() { + _widgetOptions = [ + new AgendaPage(agendaWeekNr: widget.agendaWeekNr), + new LogbookPage(), + ]; + super.initState(); } void _onItemTapped(int index) { setState(() { + widget.agendaWeekNr = 0; _selectedIndex = index; }); } diff --git a/lib/services/program_provider_service.dart b/lib/services/program_provider_service.dart new file mode 100644 index 0000000..375ed8b --- /dev/null +++ b/lib/services/program_provider_service.dart @@ -0,0 +1,104 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:training_planner/services/ishift_provider_service.dart'; +import 'package:training_planner/shift.dart'; +import 'package:uuid/uuid.dart'; +import 'package:in_date_utils/in_date_utils.dart' as DateUtilities; +import 'package:path_provider/path_provider.dart'; + +class ShiftProviderService extends IProgramProviderService { + ShiftProviderService() { + writeShiftsFromFile([]); + } + + Future get _localPath async { + final directory = await getApplicationDocumentsDirectory(); + return directory.path; + } + + Future get _localFile async { + final path = await _localPath; + return File('$path/shifts.json'); + } + + Future writeShiftsFromFile(List shifts) async { + try { + final file = await _localFile; + String content = jsonEncode(shifts); + await file.writeAsString(content); + print('Writing to file: ' + content); + } catch (e, stacktrace) { + print(stacktrace); + print(e); + } + } + + Future> readShiftsFromFile() async { + try { + final file = await _localFile; + final contents = await file.readAsString(); + final Iterable iterable = await jsonDecode(contents); + List data = + List.from(iterable.map((model) => Shift.fromJson(model))); + print('Read from file: ' + contents); + + return data; + } catch (e, stacktrace) { + print(stacktrace); + print(e); + return []; + } + } + + @override + Future updateShift(Shift shift) async { + List savedShifts = await readShiftsFromFile(); + for (var item in savedShifts) { + if (DateUtilities.DateUtils.isSameDay(shift.start, item.start)) { + item.isActive = shift.isActive; + item.start = shift.start; + item.end = shift.end; + item.type = shift.type; + break; + } + } + await writeShiftsFromFile(savedShifts); + } + + @override + Future addShift(Shift shift) async { + List savedShifts = await readShiftsFromFile(); + for (var item in savedShifts) { + if (DateUtilities.DateUtils.isSameDay(shift.start, item.start)) { + return; + } + } + + savedShifts.add(shift); + await writeShiftsFromFile(savedShifts); + } + + @override + Future> getPastShifts() async { + List shifts = await readShiftsFromFile(); + shifts.sort((a, b) => a.start.compareTo(b.start)); + + return shifts; + } + + @override + Future> getShiftsForWeek(DateTime firstDayOfWeek) async { + var items = await getPastShifts(); + List result = []; + + for (var item in items) { + if (DateUtilities.DateUtils.firstDayOfWeek(item.start) == + firstDayOfWeek) { + result.add(item); + } + } + + return result; + } +} diff --git a/lib/shift.dart b/lib/shift.dart index 382b39f..143fe58 100644 --- a/lib/shift.dart +++ b/lib/shift.dart @@ -16,10 +16,23 @@ class Shift { Shift({this.end = null, required this.start, required this.type}); + Shift.fromJson(Map json) + : start = DateTime.parse(json['start']), + end = json['end'] == null ? null : DateTime.tryParse(json['end']), + type = ShiftType.values.firstWhere((e) => e.toString() == json['type']), + isActive = json['isActive'] == 'true'; + + Map toJson() { + return { + 'start': start.toIso8601String(), + 'end': end?.toIso8601String(), + 'type': type.toString(), + 'isActive': isActive.toString(), + }; + } + Widget getStatusIcon() { - if (end == null && - start.isBefore(DateTime.now()) && - !DateUtilities.DateUtils.isSameDay(start, DateTime.now())) { + if (shiftIsOpenButBeforeToday()) { return Icon(Icons.pending); } if (getIsActive() && end == null) { @@ -88,6 +101,12 @@ class Shift { return 0.22916666; } + bool shiftIsOpenButBeforeToday() { + return end == null && + start.isBefore(DateTime.now()) && + !DateUtilities.DateUtils.isSameDay(start, DateTime.now()); + } + double getMoneyForActiveSession() { if (getIsActive()) { Duration elapsed = DateTime.now().difference(start); @@ -120,9 +139,7 @@ class Shift { } Color getStatusColor() { - if (end == null && - start.isBefore(DateTime.now()) && - !DateUtilities.DateUtils.isSameDay(start, DateTime.now())) { + if (shiftIsOpenButBeforeToday()) { return Colors.orange; } if (getIsActive() && end == null) { diff --git a/lib/widgets/agenda_week_item.dart b/lib/widgets/agenda_week_item.dart index ba70083..f3145dd 100644 --- a/lib/widgets/agenda_week_item.dart +++ b/lib/widgets/agenda_week_item.dart @@ -112,48 +112,114 @@ class _ExerciseEntryState extends State { flutterLocalNotificationsPlugin.cancelAll(); } - @override - Widget build(BuildContext context) { - Widget startShiftWidget = Padding(padding: const EdgeInsets.all(0)); - TextStyle endDateTextStyle = TextStyle(color: Colors.black); + Widget createStartShiftButton() { + return TextButton( + onPressed: () => { + setState(() { + widget.shift.setIsActive(true); + shiftProvider.updateShift(widget.shift); + setStartAndEndTime(); + showNotificationForActiveSession(); + }) + }, + child: Text('Begin')); + } + + Widget createStopShiftButton() { + return TextButton( + onPressed: () { + auth + .authenticate( + localizedReason: 'Weet je zeker dat je wilt eindigen?') + .then((value) => { + if (value) + { + setState(() { + widget.shift.setIsActive(false); + shiftProvider.updateShift(widget.shift); + stopNotificationForActiveSession(); + }) + } + }) + .catchError((f) => {}); + }, + child: Text('Einde')); + } + + Future requestStartAndEndTimeForShift() async { + final TimeOfDay? startTime = await showTimePicker( + context: context, + helpText: 'Begin tijd', + initialTime: TimeOfDay( + hour: widget.shift.start.hour, minute: widget.shift.start.minute), + initialEntryMode: TimePickerEntryMode.input, + ); + + if (startTime == null) { + return; + } + + final TimeOfDay? endTime = await showTimePicker( + context: context, + helpText: 'Eind tijd', + initialTime: TimeOfDay( + hour: widget.shift.expectedEndTime().hour, + minute: widget.shift.expectedEndTime().minute), + initialEntryMode: TimePickerEntryMode.input, + ); + + if (endTime == null) { + return; + } + + widget.shift.start = DateTime( + widget.shift.start.year, + widget.shift.start.month, + widget.shift.start.day, + startTime.hour, + startTime.minute); + + widget.shift.end = DateTime( + widget.shift.start.year, + widget.shift.start.month, + widget.shift.start.day, + endTime.hour, + endTime.minute); + + shiftProvider.updateShift(widget.shift); + } + + Widget createCompleteOldShiftButton() { + return TextButton( + onPressed: () => { + requestStartAndEndTimeForShift().then((e) => {setState(() {})}) + }, + child: Text('Invullen')); + } + Widget createShiftModifyButton() { if (!widget.shift.getIsActive() && widget.shift.canStart()) { - startShiftWidget = TextButton( - onPressed: () => { - setState(() { - showNotificationForActiveSession(); - widget.shift.setIsActive(true); - shiftProvider.updateShift(widget.shift); - setStartAndEndTime(); - }) - }, - child: Text('Begin')); + return createStartShiftButton(); } else if (widget.shift.getIsActive()) { - startShiftWidget = TextButton( - onPressed: () { - auth - .authenticate( - localizedReason: 'Weet je zeker dat je wilt eindigen?') - .then((value) => { - if (value) - { - setState(() { - widget.shift.setIsActive(false); - shiftProvider.updateShift(widget.shift); - setStartAndEndTime(); - stopNotificationForActiveSession(); - }) - } - }) - .catchError((f) => {}); - }, - child: Text('Einde')); + return createStopShiftButton(); + } else if (widget.shift.shiftIsOpenButBeforeToday()) { + return createCompleteOldShiftButton(); } + return Padding(padding: const EdgeInsets.all(0)); + } + + @override + Widget build(BuildContext context) { + Widget startShiftWidget = createShiftModifyButton(); + TextStyle endDateTextStyle = TextStyle(color: Colors.black); + if (!widget.shift.isDone()) { endDateTextStyle = TextStyle(color: Color.fromARGB(80, 0, 0, 0)); } + setStartAndEndTime(); + return Padding( padding: const EdgeInsets.only(bottom: 8, left: 10, right: 10), child: Container( -- cgit v1.2.3-70-g09d2