diff options
Diffstat (limited to 'lib/widgets')
| -rw-r--r-- | lib/widgets/agenda_week.dart | 100 | ||||
| -rw-r--r-- | lib/widgets/agenda_week_item.dart | 225 | ||||
| -rw-r--r-- | lib/widgets/agenda_week_title.dart | 49 |
3 files changed, 374 insertions, 0 deletions
diff --git a/lib/widgets/agenda_week.dart b/lib/widgets/agenda_week.dart new file mode 100644 index 0000000..4a654ce --- /dev/null +++ b/lib/widgets/agenda_week.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; +import 'package:training_planner/main.dart'; +import 'package:training_planner/shift.dart'; +import 'package:training_planner/style/style.dart'; +import 'package:training_planner/utils/date.dart'; +import 'package:training_planner/widgets/agenda_week_item.dart'; +import 'package:training_planner/widgets/agenda_week_title.dart'; + +class AgendaWeek extends StatefulWidget { + final int weekNr; + final DateTime mondayOfWeek; + final bool isCurrentWeek; + + @override + _AgendaWeekState createState() => _AgendaWeekState(); + + const AgendaWeek({ + Key? key, + required this.weekNr, + required this.mondayOfWeek, + required this.isCurrentWeek, + }) : super(key: key); +} + +class _AgendaWeekState extends State<AgendaWeek> { + List<Widget> weekItems = []; + + @override + void initState() { + super.initState(); + + shiftProvider + .getShiftsForWeek(this.widget.mondayOfWeek) + .then((value) => setState(() { + weekItems = [ + AgendaWeekTitle( + weekNr: this.widget.weekNr, + mondayOfWeek: this.widget.mondayOfWeek, + isCurrentWeek: this.widget.isCurrentWeek), + Padding( + padding: const EdgeInsets.all(10), + ) + ]; + + for (var item in value) { + weekItems.add(new AgendaWeekItem(shift: item)); + } + + weekItems.add(Padding( + padding: const EdgeInsets.all(50), + )); + })); + } + + @override + Widget build(BuildContext context) { + return ShaderMask( + shaderCallback: (Rect rect) { + return LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Style.background, + Colors.transparent, + Colors.transparent, + Style.background + ], + stops: [ + 0.0, + 0.05, + 0.95, + 1.0 + ], // 10% purple, 80% transparent, 10% purple + ).createShader(rect); + }, + blendMode: BlendMode.dstOut, + child: SafeArea( + child: CustomScrollView( + physics: null, + slivers: [ + SliverPadding(padding: EdgeInsets.only(top: 20)), + SliverList( + delegate: SliverChildBuilderDelegate( + (BuildContext context, int index) { + return weekItems[index]; + }, + childCount: weekItems.length, + )), + + // Rest day + //if (day == null) + // createRestDayPage(list) + + SliverPadding(padding: EdgeInsets.only(top: 20)), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/agenda_week_item.dart b/lib/widgets/agenda_week_item.dart new file mode 100644 index 0000000..ba70083 --- /dev/null +++ b/lib/widgets/agenda_week_item.dart @@ -0,0 +1,225 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:training_planner/main.dart'; +import 'package:training_planner/shift.dart'; +import 'package:training_planner/utils/date.dart'; +import '../style/style.dart'; + +class AgendaWeekItem extends StatefulWidget { + final Shift shift; + const AgendaWeekItem({ + Key? key, + required this.shift, + }) : super(key: key); + + @override + _ExerciseEntryState createState() => _ExerciseEntryState(); +} + +class _ExerciseEntryState extends State<AgendaWeekItem> { + String shiftTypeName = ''; + String shiftTime = ''; + String shiftTimeEnd = ''; + bool canUseLocalAuth = false; + + final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = + FlutterLocalNotificationsPlugin(); + + Future<void> _showOngoingNotification() async { + if (widget.shift.isDone()) return; + + AndroidNotificationDetails androidPlatformChannelSpecifics = + AndroidNotificationDetails('channel_1', 'Actieve Sessie', + channelDescription: '3:45 => \$50', + importance: Importance.max, + priority: Priority.high, + ongoing: true, + icon: 'dhl', + showProgress: true, + onlyAlertOnce: true, + maxProgress: 100, + channelAction: AndroidNotificationChannelAction.update, + progress: widget.shift.getPercentage(), + color: Style.background, + autoCancel: false); + NotificationDetails platformChannelSpecifics = + NotificationDetails(android: androidPlatformChannelSpecifics); + + String elapsedTime = + "${widget.shift.getElapsedSessionTime().inHours.toString().padLeft(2, '0')}:${(widget.shift.getElapsedSessionTime().inMinutes % 60).toString().padLeft(2, '0')}"; + + await flutterLocalNotificationsPlugin.show( + 0, + 'Sessie actief', + '⏱ ' + + elapsedTime + + ' => €' + + widget.shift.getMoneyForActiveSession().toStringAsFixed(2), + platformChannelSpecifics); + } + + void initState() { + super.initState(); + + auth.canCheckBiometrics.then((bio) => { + auth + .isDeviceSupported() + .then((supported) => {canUseLocalAuth = bio && supported}) + }); + + setState(() { + switch (widget.shift.type) { + case ShiftType.Avondrit: + shiftTypeName = 'Avondrit'; + break; + case ShiftType.Dagrit: + shiftTypeName = 'Dagrit'; + break; + case ShiftType.Terugscannen: + shiftTypeName = 'Terugscannen'; + break; + } + + setStartAndEndTime(); + }); + } + + void setStartAndEndTime() { + shiftTime = + "${widget.shift.start.hour.toString().padLeft(2, '0')}:${widget.shift.start.minute.toString().padLeft(2, '0')}"; + + DateTime? expectedEndTime = widget.shift.expectedEndTime(); + if (widget.shift.isDone()) { + expectedEndTime = widget.shift.end; + } + + shiftTimeEnd = ' - ' + + "${expectedEndTime?.hour.toString().padLeft(2, '0')}:${expectedEndTime?.minute.toString().padLeft(2, '0')}"; + } + + Timer? updateNotificationTimer; + void showNotificationForActiveSession() { + _showOngoingNotification(); + updateNotificationTimer = Timer.periodic( + Duration(seconds: 10), (Timer t) => _showOngoingNotification()); + } + + void stopNotificationForActiveSession() { + updateNotificationTimer?.cancel(); + flutterLocalNotificationsPlugin.cancelAll(); + } + + @override + Widget build(BuildContext context) { + Widget startShiftWidget = Padding(padding: const EdgeInsets.all(0)); + TextStyle endDateTextStyle = TextStyle(color: Colors.black); + + if (!widget.shift.getIsActive() && widget.shift.canStart()) { + startShiftWidget = TextButton( + onPressed: () => { + setState(() { + showNotificationForActiveSession(); + widget.shift.setIsActive(true); + shiftProvider.updateShift(widget.shift); + setStartAndEndTime(); + }) + }, + child: Text('Begin')); + } 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')); + } + + if (!widget.shift.isDone()) { + endDateTextStyle = TextStyle(color: Color.fromARGB(80, 0, 0, 0)); + } + + return Padding( + padding: const EdgeInsets.only(bottom: 8, left: 10, right: 10), + child: Container( + decoration: const BoxDecoration( + color: Style.listEntryBackground, + borderRadius: BorderRadius.all(Radius.circular(8))), + child: Padding( + padding: const EdgeInsets.all(0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(4))), + padding: EdgeInsets.all(0), + child: Padding( + padding: EdgeInsets.only(right: 5), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: widget.shift.getStatusColor(), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(8))), + height: 48.0, + width: 32.0, + child: widget.shift.getStatusIcon(), + ), + Container( + padding: const EdgeInsets.only(left: 10), + child: Text( + DateHelper.getWeekdayName(widget.shift.start.weekday), + style: Style.listItemTitletextBold, + ), + width: 35, + ), + Container( + child: RichText( + text: TextSpan( + style: TextStyle(color: Colors.black), + children: [ + TextSpan(text: ' | ' + shiftTime), + TextSpan( + text: shiftTimeEnd, style: endDateTextStyle) + ], + ), + ), + width: 95, + ), + Container( + child: Text( + '| ' + shiftTypeName, + ), + width: 100, + ), + startShiftWidget, + ], + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/widgets/agenda_week_title.dart b/lib/widgets/agenda_week_title.dart new file mode 100644 index 0000000..582b6b8 --- /dev/null +++ b/lib/widgets/agenda_week_title.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:training_planner/utils/date.dart'; +import '../style/style.dart'; + +class AgendaWeekTitle extends StatefulWidget { + final int weekNr; + final DateTime mondayOfWeek; + final bool isCurrentWeek; + + const AgendaWeekTitle({ + Key? key, + required this.weekNr, + required this.mondayOfWeek, + required this.isCurrentWeek, + }) : super(key: key); + + @override + _AgendaWeekTitleState createState() => _AgendaWeekTitleState(); +} + +class _AgendaWeekTitleState extends State<AgendaWeekTitle> { + @override + Widget build(BuildContext context) { + return Column(children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + this.widget.isCurrentWeek + ? Icon(Icons.today) + : Padding(padding: const EdgeInsets.all(0)), + Center( + child: Text( + " Week #" + + this.widget.weekNr.toString() + + " | " + + this.widget.mondayOfWeek.day.toString() + + " " + + DateHelper.getMonthName(this.widget.mondayOfWeek.month) + + " " + + this.widget.mondayOfWeek.year.toString(), + style: TextStyle( + fontWeight: FontWeight.bold, + )), + ), + ]), + ]); + } +} |
