import { Duration } from '@fullcalendar/core' import { PositionCache, DateMarker, startOfDay, createDuration, asRoughMs, DateProfile, rangeContainsMarker, } from '@fullcalendar/core/internal' export class TimeColsSlatsCoords { constructor( public positions: PositionCache, private dateProfile: DateProfile, private slotDuration: Duration, ) { } safeComputeTop(date: DateMarker) { // TODO: DRY with computeDateTop let { dateProfile } = this if (rangeContainsMarker(dateProfile.currentRange, date)) { let startOfDayDate = startOfDay(date) let timeMs = date.valueOf() - startOfDayDate.valueOf() if ( timeMs >= asRoughMs(dateProfile.slotMinTime) && timeMs < asRoughMs(dateProfile.slotMaxTime) ) { return this.computeTimeTop(createDuration(timeMs)) } } return null } // Computes the top coordinate, relative to the bounds of the grid, of the given date. // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. computeDateTop(when: DateMarker, startOfDayDate?: DateMarker) { if (!startOfDayDate) { startOfDayDate = startOfDay(when) } return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf())) } // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform. // Eventually allow computation with arbirary slat dates. computeTimeTop(duration: Duration): number { let { positions, dateProfile } = this let len = positions.els.length // floating-point value of # of slots covered let slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration) let slatIndex let slatRemainder // compute a floating-point number for how many slats should be progressed through. // from 0 to number of slats (inclusive) // constrained because slotMinTime/slotMaxTime might be customized. slatCoverage = Math.max(0, slatCoverage) slatCoverage = Math.min(len, slatCoverage) // an integer index of the furthest whole slat // from 0 to number slats (*exclusive*, so len-1) slatIndex = Math.floor(slatCoverage) slatIndex = Math.min(slatIndex, len - 1) // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. // could be 1.0 if slatCoverage is covering *all* the slots slatRemainder = slatCoverage - slatIndex return positions.tops[slatIndex] + positions.getHeight(slatIndex) * slatRemainder } }