LCOV - code coverage report
Current view: top level - utils - calendar_table_helper.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 57 57 100.0 %
Date: 2022-10-19 14:19:28 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:alh_calendar/enums/day_of_week.dart';
       2             : import 'package:alh_calendar/models/calendar_day.dart';
       3             : import 'package:alh_calendar/models/calendar_month.dart';
       4             : import 'package:alh_calendar/models/calendar_week.dart';
       5             : import 'package:alh_calendar/utils/date_helper.dart';
       6             : import 'package:alh_calendar/widgets/alh_calendar.dart';
       7             : import 'package:alh_calendar/widgets/calendar_cell.dart';
       8             : import 'package:flutter/material.dart';
       9             : 
      10             : /// Creates a list of all days needed to show a CalendarMonth.
      11             : ///
      12             : /// The CalendarTableHelper need the DateTime of the month which should be shown.
      13             : /// Because a month does not always start at monday and end at a sunday we would get
      14             : /// empty days in front and at the end of the month. To avoid this empty days we add
      15             : /// days from the previous month in front and days from the next month at the end of
      16             : /// the current month:
      17             : /// [daysOfPreviousMonth + daysOfCurrentMonth + daysOfNextMonth]
      18             : class CalendarTableHelper {
      19           4 :   static int weekSize = DateTime.daysPerWeek;
      20             :   static int calendarWeekLength = 5;
      21             : 
      22           2 :   static CalendarMonth buildCurrentCalendarMonth({
      23             :     required DateTime date,
      24             :     required bool forceSixWeekMonth,
      25             :   }) {
      26           2 :     return CalendarMonth(
      27             :       weeks:
      28           2 :           _getCalendarWeeks(date: date, forceSixWeekMonth: forceSixWeekMonth),
      29           6 :       month: DateTime(date.year, date.month),
      30             :     );
      31             :   }
      32             : 
      33             :   // returns chunks of all given days as calendarWeeks
      34           2 :   static List<CalendarWeek> _getCalendarWeeks(
      35             :       {required DateTime date, required bool forceSixWeekMonth}) {
      36           2 :     final calendarWeeks = <CalendarWeek>[];
      37             :     // get all days in current month
      38           2 :     final daysInCurrentMonth = _getDaysInMonth(date, true);
      39             : 
      40             :     // get all days in previous month
      41             :     final daysInPreviousMonth =
      42          10 :         _getDaysInMonth(DateTime(date.year, date.month - 1), false);
      43             : 
      44             :     // get all days in next month
      45             :     final daysInNextMonth =
      46          10 :         _getDaysInMonth(DateTime(date.year, date.month + 1), false);
      47             : 
      48             :     // weekday on which the month starts
      49           2 :     final firstWeekDayOfMonth = _getFirstWeekDayOfMonth(date);
      50             : 
      51             :     // fills up the days in front of currtenmonth days with days from previous month
      52           2 :     final daysOfPreviousMonth = _fillDaysInMonthBeginning(
      53             :       weekday: firstWeekDayOfMonth,
      54             :       lastMonthDays: daysInPreviousMonth,
      55             :     );
      56           2 :     final daysOfNextMonth = _fillDaysInMonthEnd(
      57           6 :       weekday: daysInCurrentMonth.last.date.weekday,
      58             :       nextMonthDays: daysInNextMonth,
      59             :     );
      60           4 :     final days = daysOfPreviousMonth + daysInCurrentMonth + daysOfNextMonth;
      61             : 
      62           8 :     for (var i = 0; i < days.length; i += weekSize) {
      63           2 :       final newCalendarWeek = CalendarWeek(
      64           6 :         days: days.sublist(i, i + weekSize),
      65             :       );
      66           2 :       calendarWeeks.add(newCalendarWeek);
      67             :     }
      68             : 
      69           4 :     if (forceSixWeekMonth && calendarWeeks.length == calendarWeekLength) {
      70           8 :       final start = daysOfNextMonth.isEmpty ? 0 : daysOfNextMonth.last.date.day;
      71           2 :       final newCalendarWeek = CalendarWeek(
      72           6 :         days: daysInNextMonth.sublist(start, start + weekSize),
      73             :       );
      74           2 :       calendarWeeks.add(newCalendarWeek);
      75             :     }
      76             : 
      77             :     return calendarWeeks;
      78             :   }
      79             : 
      80             :   /// Returns on which day of the week the month starts
      81             :   ///
      82             :   /// for example: monday or saturday
      83           2 :   static int _getFirstWeekDayOfMonth(DateTime month) {
      84          10 :     return DateTime(month.year, month.month, month.day).weekday;
      85             :   }
      86             : 
      87             :   /// Depending on which weekday the month starts, we need to fill the List of days in front.
      88             :   ///
      89             :   /// For example if the month starts at wednesday, then monday and tuesday would be empty.
      90             :   /// In this case these days get filled with the last two days of the previous month.
      91           2 :   static List<CalendarDay> _fillDaysInMonthBeginning({
      92             :     required int weekday,
      93             :     required List<CalendarDay> lastMonthDays,
      94             :   }) {
      95           2 :     final lastMonthDaysLength = lastMonthDays.length;
      96           2 :     return lastMonthDays.sublist(
      97           4 :       lastMonthDaysLength - weekday + 1,
      98             :       lastMonthDaysLength,
      99             :     );
     100             :   }
     101             : 
     102             :   /// Depending on which weekday the month ends, days should be added at the end of the month.
     103             :   ///
     104             :   /// For example if the month ends at friday, then saturday and sunday would be empty.
     105             :   /// In this case these days get filled with the first two days of the next month.
     106           2 :   static List<CalendarDay> _fillDaysInMonthEnd({
     107             :     required int weekday,
     108             :     required List<CalendarDay> nextMonthDays,
     109             :   }) {
     110           4 :     return nextMonthDays.sublist(0, DateTime.daysPerWeek - weekday);
     111             :   }
     112             : 
     113             :   /// Returns a list of calendarDays
     114             :   ///
     115             :   /// For every day in the given month a clendarDay is added to the list.
     116           2 :   static List<CalendarDay> _getDaysInMonth(
     117             :     DateTime date,
     118             :     bool isCurrentMonth,
     119             :   ) {
     120           6 :     final totalDays = DateUtils.getDaysInMonth(date.year, date.month);
     121           2 :     final List<CalendarDay> dateTimeDayList = [];
     122           4 :     for (int i = 0; i < totalDays; i++) {
     123           8 :       final day = DateTime(date.year, date.month, i + 1);
     124             : 
     125           4 :       dateTimeDayList.add(CalendarDay(
     126             :         date: day,
     127             :         isInCurrentMonth: isCurrentMonth,
     128           6 :         dayOfWeek: DayOfWeek.values[day.weekday - 1],
     129             :       ));
     130             :     }
     131             : 
     132             :     return dateTimeDayList;
     133             :   }
     134             : 
     135             :   /// Returns a list with all TableRows needed.
     136             :   ///
     137             :   /// For every calendarWeek in given [CalendarMonth], one TableRow is build and
     138             :   /// each row gets filled with the calendarDays of the calendarWeeks.
     139           3 :   static List<TableRow> buildCalendarTableRow({
     140             :     required CalendarMonth calendarMonth,
     141             :     required bool disableSixthRow,
     142             :     required DateTime selectedDateTime,
     143             :     required DayBuilder dayBuilder,
     144             :     required ValueChanged<DateTime> onSelectDay,
     145             :     required bool disableClickOnOutOfRange,
     146             :     DateTime? minimumDayDate,
     147             :     DateTime? maximumDayDate,
     148             :   }) {
     149           3 :     return calendarMonth.weeks
     150           9 :         .map((week) => TableRow(
     151           3 :             children: week.days
     152           9 :                 .map((day) => _buildCalendarCell(
     153             :                     calendarMonth: calendarMonth,
     154             :                     calendarDay: day,
     155             :                     calendarWeek: week,
     156             :                     disableSixthRow: disableSixthRow,
     157             :                     selectedDateTime: selectedDateTime,
     158             :                     dayBuilder: dayBuilder,
     159             :                     onSelectDay: onSelectDay,
     160             :                     disableClickOnOutOfRange: disableSixthRow,
     161             :                     minimumDayDate: minimumDayDate,
     162             :                     maximumDayDate: maximumDayDate))
     163           3 :                 .toList()))
     164           3 :         .toList();
     165             :   }
     166             : 
     167           3 :   static CalendarCell _buildCalendarCell({
     168             :     required CalendarMonth calendarMonth,
     169             :     required CalendarDay calendarDay,
     170             :     required CalendarWeek calendarWeek,
     171             :     required bool disableSixthRow,
     172             :     required DateTime selectedDateTime,
     173             :     required DayBuilder dayBuilder,
     174             :     required ValueChanged<DateTime> onSelectDay,
     175             :     required bool disableClickOnOutOfRange,
     176             :     DateTime? minimumDayDate,
     177             :     DateTime? maximumDayDate,
     178             :   }) {
     179             :     late bool disableLastRow = false;
     180             :     // if disableSixthRow == true the last row has to be disabled
     181           9 :     if (calendarWeek == calendarMonth.weeks.last && disableSixthRow) {
     182             :       disableLastRow =
     183           1 :           !DateHelper.isDayOfCurrentMonthInLastRow(calendarWeek: calendarWeek);
     184             :     }
     185             :     // calculate if day is out of range
     186           3 :     final isOutOfRange = DateHelper.isDayOutOfRange(
     187           3 :         dayDateTime: calendarDay.date,
     188             :         minimumDayDate: minimumDayDate,
     189             :         maximumDayDate: maximumDayDate);
     190           3 :     return CalendarCell(
     191             :       isSixthRowAndDisabled: disableLastRow,
     192           3 :       date: calendarDay.date,
     193           3 :       isInCurrentMonth: calendarDay.isInCurrentMonth,
     194           6 :       isSelected: selectedDateTime == calendarDay.date,
     195           6 :       isWeekend: calendarDay.dayOfWeek.isWeekend,
     196             :       isOutOfRange: isOutOfRange,
     197             :       dayBuilder: dayBuilder,
     198             :       onTap: !disableClickOnOutOfRange || !isOutOfRange
     199           6 :           ? () => onSelectDay(calendarDay.date)
     200             :           : null,
     201             :     );
     202             :   }
     203             : }

Generated by: LCOV version 1.16