import 'dart:core'; import 'package:flutter/material.dart'; import 'package:hiddingsel_app/constants/constant.dart'; import 'package:hiddingsel_app/packages/list_view_extension/colum_extension.dart'; import 'package:table_calendar/table_calendar.dart'; import '../constants/enums.dart'; import '../appflow/controller/events.dart'; import '../appflow/model/event.dart'; import '../appflow/view/navigation_drawer.dart'; import 'calendar_list.dart'; class CalendarListPage extends StatefulWidget with NavigationDrawerItem { final String title = 'Termine'; @override State createState() => CalendarListPageState(); } class CalendarListPageState extends State { List _selectedDayList = []; Map> _events = {}; @override void dispose() { super.dispose(); } @override void initState() { super.initState(); init(); } void init() async { EventController.getEventListStream().forEach((events) { setState(() { _events = _mapListToCalendarEvents(events); }); }); } @override Widget build(BuildContext context) => SafeArea( bottom: false, child: Padding( padding: const EdgeInsets.fromLTRB(UIShapes.paddingSimple, UIShapes.paddingSimple, UIShapes.paddingSimple, 0), child: ListView( primary: true, children: [ FormattedCalendar(_events, _onDaySelected), ColumnExtension.builder( itemCount: _selectedDayList.length, itemBuilder: (context, index) => CalendarListTile(_selectedDayList[index]), ), ], ), ), ); void _onDaySelected(DateTime dateTime) { setState(() { _selectedDayList = _events[DateTime(dateTime.year, dateTime.month, dateTime.day)] ?? []; }); } Map> _mapListToCalendarEvents(List list) { final map = >{}; DateTime dateKey; int i; int j; for (final e in list) { j = 0; dateKey = e.schedule.startTime; do { if (e.schedule.frequency != Frequency.once && e.schedule.interval != null) { if (e.schedule.frequency == Frequency.days) { dateKey = dateKey.add(Duration(days: e.schedule.interval!)); } else if (e.schedule.frequency == Frequency.weeks) { dateKey = dateKey.add(Duration(days: 7 * e.schedule.interval!)); } else if (e.schedule.frequency == Frequency.months) { dateKey = dateKey = DateTime(dateKey.year, dateKey.month + e.schedule.interval!, dateKey.day); } if (e.schedule.until != null && e.schedule.until!.isBefore(dateKey)) { break; } } i = 0; do { var dateKey2 = dateKey.add(Duration(days: i)); dateKey2 = DateTime(dateKey2.year, dateKey2.month, dateKey2.day); if (map.containsKey(dateKey2)) { map[dateKey2]!.add(e); } else { map[dateKey2] = [e]; } i++; } while (i < e.schedule.endTime.difference(e.schedule.startTime).inDays); j++; } while (e.schedule.frequency != Frequency.once && e.schedule.interval != null && j < 52); } return map; } } class FormattedCalendar extends StatefulWidget { final Map> _events; final void Function(DateTime) _onDaySelected; FormattedCalendar(this._events, this._onDaySelected); @override _FormattedCalendarState createState() => _FormattedCalendarState(); } class _FormattedCalendarState extends State { DateTime _focusedDay = DateTime.now(); DateTime? _selectedDay; _FormattedCalendarState(); @override Widget build(BuildContext context) { var firstDay = DateTime.utc(2010, 10, 16); var lastDay = DateTime.utc(2030, 3, 14); final calendar = TableCalendar( locale: 'de_DE', availableCalendarFormats: const { CalendarFormat.month: 'Month', }, headerStyle: HeaderStyle( titleCentered: true, titleTextStyle: UITheme.theme.textTheme.headlineSmall!, ), firstDay: firstDay, lastDay: lastDay, focusedDay: _focusedDay, startingDayOfWeek: StartingDayOfWeek.monday, calendarStyle: CalendarStyle( weekendTextStyle: UITheme.theme.textTheme.bodyLarge!, defaultTextStyle: UITheme.theme.textTheme.bodyLarge!, todayTextStyle: UITheme.theme.textTheme.bodyMedium!, selectedTextStyle: UITheme.theme.textTheme.bodyMedium!, selectedDecoration: BoxDecoration( color: UIColors.grey5, shape: BoxShape.circle, ), todayDecoration: BoxDecoration( color: UIColors.grey4, shape: BoxShape.circle, ), markerDecoration: BoxDecoration( color: UIColors.yellow, shape: BoxShape.circle, ) ), eventLoader: (day) { return _getEventsForDay(day); }, selectedDayPredicate: (day) { return isSameDay(_selectedDay, day); }, onDaySelected: (selectedDay, focusedDay) { setState(() { _selectedDay = selectedDay; _focusedDay = focusedDay; widget._onDaySelected(selectedDay); }); }, ); return calendar; } List _getEventsForDay(DateTime day) { return widget._events[DateTime(day.year, day.month, day.day)] ?? []; } }