diff --git a/src/helper/calc.helper.ts b/src/helper/calc.helper.ts deleted file mode 100644 index ade5fab..0000000 --- a/src/helper/calc.helper.ts +++ /dev/null @@ -1 +0,0 @@ -export class CalcHelper {} diff --git a/src/helper/day.helper.ts b/src/helper/day.helper.ts deleted file mode 100644 index 06c6de8..0000000 --- a/src/helper/day.helper.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { FcEvent, LeapDay } from "src/@types"; -import type { Moon, Phase } from "src/@types/moons"; -import { wrap } from "src/utils/functions"; -import { MonthHelper } from "./month.helper"; - -export class DayHelper { - private _events: FcEvent[]; - shouldUpdate: boolean = false; - get calendar() { - return this.month.calendar; - } - get date() { - return { - day: this.number, - month: this.month.number, - year: this.year, - }; - } - get events(): FcEvent[] { - if (!this._events || !this._events.length || this.shouldUpdate) { - this._events = this.month.getEventsOnDay(this.date); - } - return this._events; - } - get longDate() { - return { - day: this.number, - month: this.month.name, - year: this.year, - }; - } - /** Days before this day in the year. */ - get daysBefore() { - return ( - this.month.daysBefore + - this.number - - 1 - - this.month.leapDays.filter((l) => l.numbered && l.after < this.number - 1) - .length - ); - } - get year() { - return this.month.year; - } - get weekday() { - const firstOfYear = this.calendar.firstDayOfYear(this.year); - return wrap( - (this.daysBefore % this.calendar.weekdays.length) + firstOfYear, - this.calendar.weekdays.length - ); - } - get isCurrentDay() { - return ( - this.number == this.calendar.current.day && - this.month.number == this.calendar.current.month && - this.month.year == this.calendar.current.year - ); - } - get isDisplaying() { - return ( - this.number == this.calendar.viewing.day && - this.month.year == this.calendar.viewing.year && - this.month.number == this.calendar.viewing.month - ); - } - private _moons: Array<[Moon, Phase]>; - get moons() { - if (!this._moons || !this._moons.length) { - this._moons = this.month.getMoonsForDay(this.date); - } - return this._moons; - } - - constructor( - public month: MonthHelper, - public number: number, - public leapday?: LeapDay - ) {} -} diff --git a/src/helper/helper.worker.ts b/src/helper/helper.worker.ts deleted file mode 100644 index f81f40d..0000000 --- a/src/helper/helper.worker.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** Worker for eventual offloading of calendar calculation. */ -import type { FcEvent } from "src/@types/index"; - -const ctx: Worker = self as any; - -interface EventMessage { - type: "hash"; - events: FcEvent[]; -} - -// Respond to message from parent thread -ctx.addEventListener("message", (event: MessageEvent) => { - if (event.data.type == "hash") { - //build hash; - - } -}); - -export default {} as typeof Worker & (new () => Worker); diff --git a/src/helper/index.ts b/src/helper/index.ts deleted file mode 100644 index fb80643..0000000 --- a/src/helper/index.ts +++ /dev/null @@ -1,862 +0,0 @@ -import { Events, Notice } from "obsidian"; -import type Calendarium from "src/main"; -import { MOON_PHASES, Phase } from "src/utils/constants"; -import { - dateString, - isValidDay, - isValidMonth, - isValidYear, - wrap -} from "src/utils/functions"; -import type { - Calendar, - FcDate, - Month, - FcEvent, - LeapDay, - Moon -} from "src/@types"; -import { DayHelper } from "./day.helper"; -import { MonthHelper } from "./month.helper"; - - - -interface YearEventCache { - events: FcEvent[]; - shouldUpdate: boolean; - months: Map; -} - -export default class CalendarHelper extends Events { - addEvent(event: FcEvent) { - const year = event.date.year; - const month = event.date.month; - - this.refreshMonth(month, year); - } - refreshMonth(month: number, year: number) { - if (!this._cache.has(year)) return; - if (!this._cache.get(year).months.has(month)) return; - this._cache.get(year).shouldUpdate = true; - this._cache - .get(year) - .months.forEach((month) => (month.shouldUpdate = true)); - if ( - (year == this.displayed.year && month == this.displayed.month) || - (year == this.viewing.year && month == this.viewing.month) - ) { - this.trigger("month-update"); - } - } - refreshYear(year: number) { - if (!this._cache.has(year)) return; - this._cache.get(year).shouldUpdate = true; - this._cache - .get(year) - .months.forEach((month) => (month.shouldUpdate = true)); - if (year == this.displayed.year || year == this.viewing.year) { - this.trigger("month-update"); - } - } - standardMonths: Month[]; - /** - * Get a day helper from cache for a given date calendar. - */ - getDayForDate(date: FcDate): DayHelper { - const month = this.getMonth(date.month, date.year); - const day = month.days[date.day - 1]; - return day; - } - /** - * Get all the events that occur in a given month. - */ - getEventsForMonth(helper: MonthHelper): FcEvent[] { - //get from cache first - - //else - const { year, number: month } = helper; - - if (!this._cache.has(year)) { - this._cache.set(year, { - events: [], - shouldUpdate: true, - months: new Map() - }); - } - if (this._cache.get(year).shouldUpdate) { - const events = this.calendar.events.filter((event) => { - const date = { ...event.date }; - const end = { ...event.end }; - - //Year and Month match - if (date.year == year || date.year == undefined) return true; - - //Event is after the month - if (date.year > year) return false; - - //No end date and event is before the month - if (!end && !event.formulas?.length && date.year < year) - return false; - - if ( - date.year <= year && - (end?.year >= year || event.formulas?.length) - ) - return true; - - return false; - }); - this._cache.set(year, { - months: this._cache.get(year).months, - events, - shouldUpdate: false - }); - } - - const events = this._cache.get(year).events.filter((event) => { - const date = { ...event.date }; - const end = { ...event.end }; - - //No-month events are on every month. - if (date.month == undefined) return true; - - //Year and Month match - if ( - (date.year == year || date.year == undefined) && - date.month == month - ) - return true; - - //Event is after the month - if (date.year > year || (date.year == year && date.month > month)) - return false; - - //No end date and event is before the month - if ( - !end && - !event.formulas?.length && - (date.month != month || date.year < year) - ) - return false; - - if (date.year == undefined) end.year = date.year = year; - if ( - (date.year <= year || date.month <= month) && - (event.formulas?.length || - (end.year >= year && end.month >= month)) - ) - return true; - - return false; - }); - - return events; - } - /** - * Get the display name for a year. Used mainly for custom years. - */ - getNameForYear(year: number): string { - if (!this.data.useCustomYears) return `${year}`; - if ( - this.data.useCustomYears && - year - 1 >= 0 && - year <= this.data.years?.length - ) { - return this.data.years[year - 1].name; - } - } - /** - * Maximum number of days possible in a year. - */ - maxDays: number; - /** - * Options alias. - */ - get displayWeeks() { - return this.calendar.displayWeeks; - } - /** - * Creates an instance of CalendarHelper. - * @param {Calendar} calendar - * @param {Calendarium} plugin - * @memberof CalendarHelper - */ - constructor(public calendar: Calendar, public plugin: Calendarium) { - super(); - this.displayed = { ...this.current }; - this.update(this.calendar); - - this.plugin.registerEvent( - this.plugin.app.workspace.on( - "calendarium-event-update", - (tree) => { - if (!tree.has(this.calendar.id)) return; - - const years = tree.get(this.calendar.id); - - for (const year of years) { - if (!this._cache.has(year)) continue; - this.refreshYear(year); - } - } - ) - ); - } - - /** - * Cache used to store built month helpers, events, and whether a year should update. - */ - private _cache: Map = new Map(); - - /** - * Get an array of month helpers for an entire year. - */ - getMonthsForYear(year: number) { - if (!this._cache.has(year)) { - this._cache.set(year, { - events: [], - shouldUpdate: true, - months: new Map( - this.data.months.map((m, i) => [ - i, - new MonthHelper(m, i, year, this) - ]) - ) - }); - } - if (this._cache.get(year).months.size != this.data.months.length) { - this._cache.set(year, { - ...this._cache.get(year), - months: new Map( - this.data.months.map((m, i) => [ - i, - new MonthHelper(m, i, year, this) - ]) - ) - }); - } - return Array.from(this._cache.get(year).months.values()); - } - /** - * Get a hash of a given date. - * - * Hash takes the form of `YYYYMMDD`, with months and days padded to the maximum value. - */ - hash(date: Partial) { - if (date.year == null || date.month == null || date.day == null) - return null; - const months = `${this.data.months.length}`.length; - const month = `${date.month}`.padStart(months, "0"); - const days = `${this.maxDays}`.length; - const day = `${date.day}`.padStart(days, "0"); - return `${date.year}${month}${day}`; - } - - /** - * Update the calendar object to a new calendar. - */ - update(calendar?: Calendar) { - this.calendar = calendar ?? this.calendar; - this.maxDays = Math.max(...this.data.months.map((m) => m.length)); - - this.standardMonths = this.data.months.filter( - (m) => m.type != "intercalary" - ); - - if (!this.calendar?.current) { - this.calendar.current = { - day: null, - month: null, - year: null - }; - } - if (!isValidYear(this.calendar?.current.year, this.calendar)) { - this.calendar.current.year = 1; - } - if (!isValidMonth(this.calendar?.current.month, this.calendar)) { - this.calendar.current.month = 0; - } - if (!isValidDay(this.calendar?.current.day, this.calendar)) { - this.calendar.current.day = 1; - } - - this.trigger("month-update"); - this.trigger("day-update"); - } - /** - * Alias for calendar categories. - */ - get categories() { - return this.calendar.categories; - } - /** - * Alias for calendar static data. - */ - get data() { - return this.calendar.static; - } - /** - * Alias for calendar current date. - */ - get current() { - return this.calendar.current; - } - /** - * Alias for calendar leap days data. - */ - get leapdays() { - return this.data.leapDays ?? []; - } - - /** - * Used to track currently displayed date on the calendar. - * Probably just need to track month and year... or a MonthHelper. - */ - displayed: FcDate = { - year: null, - month: null, - day: null - }; - /** - * Used to track current viewed date (day view) on the calendar. - * Probably just need to track a DayHelper. - */ - viewing: FcDate = { - year: null, - month: null, - day: null - }; - /** - * Display string for current date. - */ - get currentDate() { - return dateString(this.current, this.calendar); - } - - /** - * Display string for displayed date. - */ - get displayedDate() { - return dateString(this.displayed, this.calendar); - } - /** - * Display string for viewed date. - */ - get viewedDate() { - return dateString(this.viewing, this.calendar); - } - - /** - * Reset a calendar to display current date. - */ - reset() { - this.displayed = { ...this.current }; - this.viewing = { ...this.current }; - - this.trigger("month-update"); - this.trigger("day-update"); - } - - /** - * Set the current displayed month. - */ - setCurrentMonth(n: number) { - this.displayed.month = n; - - this.trigger("month-update"); - } - /** - * Increment viewed day and overflow months and years as necessary. - */ - goToNextDay() { - const day = this.getDayForDate(this.viewing); - this.viewing.day += 1; - if (this.viewing.day > day.month.days.length) { - this.goToNext(); - this.viewing.month = this.displayed.month; - this.viewing.year = this.displayed.year; - this.viewing.day = 1; - } - this.trigger("day-update"); - } - /** - * Increment current day and overflow months and years as necessary. - */ - goToNextCurrentDay() { - this.current.day += 1; - const currentMonth = this.getMonth( - this.current.month, - this.current.year - ); - if (this.current.day >= currentMonth.days.length) { - this.current.day = 1; - this.current.month += 1; - if (this.current.month >= this.data.months.length) { - this.current.month = 0; - this.current.year += 1; - } - } - this.trigger("day-update"); - } - /** - * Get the index of the next month to be displayed, wrapping as necessary. - */ - get nextMonthIndex() { - return wrap(this.displayed.month + 1, this.data.months.length); - } - /** - * Get the MonthHelper of the next month to be displayed. - */ - get nextMonth() { - return this.getMonth(this.displayed.month + 1, this.displayed.year); - } - /** - * Check if the calendar can increment year. Always returns true unless the calendar has custom years defined. - */ - canGoToNextYear(year = this.displayed.year) { - return !this.data.useCustomYears || year < this.data.years.length; - } - getNextMonth() { - if (this.plugin.data.showIntercalary) { - return this.getMonth(this.displayed.month + 1, this.displayed.year); - } else { - return this.getDirectionalStandardMonthHelper(1); - } - } - getNextMonthIndex() { - const month = this.getNextMonth(); - return this.data.months.indexOf(month.data); - } - getPreviousMonth() { - if (this.plugin.data.showIntercalary) { - return this.getMonth(this.displayed.month - 1, this.displayed.year); - } else { - return this.getDirectionalStandardMonthHelper(-1); - } - } - getPreviousMonthIndex() { - const month = this.getPreviousMonth(); - if (!month) return Infinity; - return this.data.months.indexOf(month.data); - } - getDirectionalStandardMonthHelper( - direction: 1 | -1, - year = this.displayed.year - ) { - const index = this.getDirectionalStandardMonth(direction); - return this.getMonth(index, year); - } - getDirectionalStandardMonth(direction: 1 | -1) { - const current = this.data.months[this.displayed.month]; - const standardIndex = this.standardMonths.indexOf(current); - const directionIndex = wrap( - standardIndex + direction, - this.standardMonths.length - ); - const index = this.data.months.indexOf( - this.standardMonths[directionIndex] - ); - return index; - } - /** - * Go to the next month index. Used to change months on the calendar. - */ - goToNext() { - const index = this.getNextMonthIndex(); - - if (index < this.displayed.month) { - if (!this.canGoToNextYear()) { - new Notice( - "This is the last year. Additional years can be created in settings." - ); - return; - } - this.goToNextYear(); - } - this.setCurrentMonth(index); - } - /** - * Go to the next year index. Used to change years on the calendar. - */ - goToNextYear() { - this.displayed.year += 1; - this.trigger("year-update"); - } - - /** - * Get the index of the previous month to be displayed, wrapping as necessary. - */ - get prevMonthIndex() { - return wrap(this.displayed.month - 1, this.data.months.length); - } - /** - * Get the MonthHelper of the previous month to be displayed. - */ - get previousMonth() { - return this.getMonth(this.displayed.month - 1, this.displayed.year); - } - /** - * Go to the previous month index. Used to change months on the calendar. - */ - goToPrevious() { - const index = this.getPreviousMonthIndex(); - - if (index > this.displayed.month) { - if (this.displayed.year == 1) { - new Notice("This is the earliest year."); - return; - } - this.goToPreviousYear(); - } - this.setCurrentMonth(index); - } - /** - * Go to the viewed previous day. Used to change days on the day view. - */ - goToPreviousDay() { - this.viewing.day -= 1; - if (this.viewing.day < 1) { - this.goToPrevious(); - this.viewing.month = this.displayed.month; - this.viewing.year = this.displayed.year; - this.viewing.day = this.currentMonth.days.length; - } - this.trigger("day-update"); - } - /** - * Go to the previous year index. Used to change years on the calendar. - */ - goToPreviousYear() { - this.displayed.year -= 1; - this.trigger("year-update"); - } - /** - * Alias for calendar data weekdays. - */ - get weekdays() { - return this.data.weekdays; - } - /** - * Get the MonthHelper for the currently displayed month. - */ - get currentMonth() { - return this.getMonth(this.displayed.month, this.displayed.year); - } - - /** - * Test if a leap day occurs in a given year. - */ - testLeapDay(leapday: LeapDay, year: number) { - return leapday.interval - .sort((a, b) => a.interval - b.interval) - .some(({ interval, exclusive }, index, array) => { - if (exclusive && index == 0) { - return (year - leapday.offset ?? 0) % interval != 0; - } - - if (exclusive) return; - - if (array[index + 1] && array[index + 1].exclusive) { - return ( - (year - leapday.offset ?? 0) % interval == 0 && - (year - leapday.offset ?? 0) % - array[index + 1].interval != - 0 - ); - } - return (year - leapday.offset ?? 0) % interval == 0; - }); - } - /** - * Get all leapdays that occur in a given year. - */ - leapDaysForYear(year: number) { - return this.leapdays.filter((l) => { - return this.testLeapDay(l, year); - }); - } - /** - * Get all leapdays that occur in a given month in a specific year. - */ - leapDaysForMonth(month: number, year = this.displayed.year) { - return this.leapdays.filter((l) => { - if (l.timespan != month) return false; - return this.testLeapDay(l, year); - }); - } - - /** - * Get a MonthHelper for a month number in a specific year, wrapping the month number as necessary. - * - * Will prioritize pulling a MonthHelper from the cache. - * - * Direction is used to skip intercalary months. - */ - getMonth(number: number, year: number, direction: number = 0): MonthHelper { - const months = this.data.months; - let index = wrap(number, months.length); - - if (number < 0) year -= 1; - if (year == 0) return null; - - if (number >= months.length) year += 1; - - if (this._cache.has(year)) { - if (this._cache.get(year)!.months.has(index)) { - return this._cache.get(year)!.months.get(index); - } - } else { - this._cache.set(year, { - events: [], - shouldUpdate: true, - months: new Map() - }); - } - - if (months[index].type == "intercalary" && direction != 0) { - return this.getMonth(number + direction, year, direction); - } - - const helper = new MonthHelper(months[index], index, year, this); - this._cache.get(year).months.set(index, helper); - this._cache.set(year, this._cache.get(year)); - return helper; - } - /** - * Get the padded days for a given month. - * - * This is used to display the "overflowed" days from the previous and next month on the calendar. - * - * This has the side benefit of pre-caching the previous and next months, so they are built when switched to. - */ - getPaddedDaysForMonth(month: MonthHelper) { - let current = month.days; - - /** Get Days of Previous Month */ - let previous: DayHelper[] = []; - - const previousMonth = this.getMonth( - month.index - 1, - this.displayed.year, - -1 - ); - if (month.firstWeekday > 0 && month.type == "month") { - previous = - previousMonth != null - ? previousMonth.days.slice(-month.firstWeekday) - : Array(month.firstWeekday).fill(null); - } - - /** Get Days of Next Month */ - let next: DayHelper[] = []; - const nextMonth = this.getMonth( - month.index + 1, - this.displayed.year, - 1 - ); - if ( - month.lastWeekday < this.weekdays.length - 1 && - month.type == "month" - ) { - next = nextMonth.days.slice( - 0, - this.weekdays.length - month.lastWeekday - 1 - ); - } - - return { - previous, - current, - next - }; - } - - /** - * Returns the rounded up number of weeks of the current month. Use to build calendar rows. - */ - get weeksPerCurrentMonth() { - return Math.ceil( - this.getMonth(this.displayed.month, this.displayed.year).length / - this.data.weekdays.length - ); - } - /** - * Get the number of weeks in a given month. - */ - weeksOfMonth(month: MonthHelper) { - return Math.ceil( - (month.length + month.firstWeekday) / this.data.weekdays.length - ); - } - /** - * Get the first week number of a given month. - * - * TODO: Figure out how to add in ISO spec compliance here. - */ - weekNumbersOfMonth(month: MonthHelper) { - const daysBefore = month.daysBefore + this.firstDayOfYear(month.year); - return Math.floor(daysBefore / this.data.weekdays.length); - } - /** - * Total number of days in a year. Does not include leap days. - */ - get daysPerYear() { - return this.data.months - .filter((m) => m.type === "month") - .reduce((a, b) => a + b.length, 0); - } - /** - * Get the total number of days in a year before a given month. - */ - daysBeforeMonth(month: number, year: number, all: boolean = false) { - if (!month || month == 0) return 0; - - return this.data.months - .slice(0, month) - .filter((m) => (all ? true : m.type == "month")) - .map((m, i) => { - const leapdays = this.leapDaysForMonth(i, year); - return m.length + leapdays.filter((l) => !l.intercalary).length; - }) - .reduce((a, b) => a + b, 0); - } - - dayNumberForDate(date: FcDate) { - return this.daysBeforeMonth(date.month, date.year, true) + date.day; - } - - get firstWeekday() { - return this.data.firstWeekDay; - } - - /** - * Alias to get the total number of leap days that have occured before the currently displayed year. - */ - get leapDaysBefore() { - if (this.displayed.year == 1) return 0; - return this.leapDaysBeforeYear(this.displayed.year - 1); - } - /** Get Total Number of Leap Days before a given year - * @param tester Year to find leap days before NOT INCLUDING THIS YEAR - */ - leapDaysBeforeYear(tester: number) { - /** If we're checking year 1, there are no leap days. */ - if (tester == 1) return 0; - /** Subtract 1 from tester. We're looking for leap days BEFORE the year. */ - const year = tester - 1; - let total = 0; - /** Iterate over each leap day. */ - for (const { interval, offset } of this.leapdays.filter( - (l) => !l.intercalary - )) { - let leapdays = 0; - - /** Iterate over each condition on each leapday. */ - for (let i = 0; i < interval.length; i++) { - const condition = interval[i]; - /** Determine how many leap days match non-exclusive rules AFTER this rule. - * This has to be done to avoid "double-counting" days for days that match multiple rules. - */ - const rest = interval - .slice(i + 1) - .filter((c) => !c.exclusive) - .map((c) => - Math.floor( - (year + (c.ignore ? 0 : offset)) / c.interval - ) - ) - .reduce((a, b) => a + b, 0); - /** Calculate how many days match this rule. */ - const calc = Math.floor( - (year + (condition.ignore ? 0 : offset)) / - condition.interval - ); - if (condition.exclusive) { - /** If the rule is exlusive, subtract the result from the total, then add in the rest. */ - leapdays -= calc; - leapdays += rest; - } else { - /** If the rule is exlusive, add the result to the total, then subtract out the rest. */ - leapdays += calc; - leapdays -= rest; - } - } - total += leapdays; - } - return total; - } - /** - * Alias to get the total number of days before the currently displayed year. - */ - get totalDaysBefore() { - return this.totalDaysBeforeYear(this.displayed.year); - } - /** - * Get the total number of days before a given year. - */ - totalDaysBeforeYear(year: number, all = false) { - if (year < 1) return 0; - return ( - Math.abs(year - 1) * - this.data.months - .filter((m) => all || m.type == "month") - .reduce((a, b) => a + b.length, 0) + - this.leapDaysBeforeYear(year) - ); - } - /** - * Get the weekday of a given year. - */ - firstDayOfYear(year = this.displayed.year) { - if (!this.data.overflow) return 0; - if (year == 1) return this.firstWeekday; - - return wrap( - (this.totalDaysBeforeYear(year) % this.data.weekdays.length) + - this.firstWeekday + - (this.data.offset ?? 0), - this.data.weekdays.length - ); - } - - /** - * Alias to get the moon data. - */ - get moons() { - return this.data.moons; - } - /** - * Get the moons and their phases for a given month. - */ - getMoonsForMonth(month: MonthHelper): Array<[Moon, Phase]>[] { - const phases: Array<[Moon, Phase]>[] = []; - - for (const day of month.days) { - const daysBefore = - this.totalDaysBeforeYear(month.year, true) + - this.daysBeforeMonth(month.number, month.year, true) + - day.number - - 1; - const moons: Array<[Moon, Phase]> = []; - for (let moon of this.moons) { - const { offset, cycle } = moon; - const granularity = 24; - - let data = (daysBefore - offset) / cycle; - let position = data - Math.floor(data); - - const phase = (position * granularity) % granularity; - - const options = MOON_PHASES[granularity]; - - moons.push([ - moon, - options[wrap(Math.round(phase), options.length)] - ]); - } - phases.push(moons); - } - - return phases; - } -} diff --git a/src/helper/month.helper.ts b/src/helper/month.helper.ts deleted file mode 100644 index 1076fca..0000000 --- a/src/helper/month.helper.ts +++ /dev/null @@ -1,114 +0,0 @@ -import type { LeapDay, FcEvent, FcDate, Moon, Phase, Month } from "src/@types"; -import CalendarHelper from "."; -import { DayHelper } from "./day.helper"; - -export class MonthHelper { - days: DayHelper[] = []; - daysBefore: number; - leapDays: LeapDay[] = []; - shouldUpdate = false; - - get id() { - return this.data.id; - } - get index() { - return this.calendar.data.months.indexOf(this.data); - } - get name() { - return this.data.name; - } - get length() { - return this.days.length; - } - - get firstWeekday() { - if (!this.calendar.data.overflow) return 0; - return this.days[0].weekday; - } - get lastWeekday() { - return this.days[this.days.length - 1].weekday; - } - - get type() { - return this.data.type; - } - events: FcEvent[]; - getEventsOnDay(day: FcDate) { - if (!this.events || !this.events.length || this.shouldUpdate) { - this.days.forEach((day) => (day.shouldUpdate = true)); - this.events = this.calendar.getEventsForMonth(this); - this.shouldUpdate = false; - } - return this.events.filter((event) => { - if ( - (!event.date.year || event.date.year == day.year) && - (!event.date.month || event.date.month == day.month) && - event.date.day == day.day - ) - return true; - if (!event.end && !event.formulas?.length) return false; - const start = { ...event.date }; - const end = { - ...(event.end ?? {}), - }; - - if (!start.year) start.year = end.year = this.year; - if (!start.month) start.month = end.month = this.number; - - const hash = Number(this.calendar.hash(day)); - if ( - Number(this.calendar.hash(start)) <= hash && - hash <= Number(this.calendar.hash(end) ?? Infinity) - ) { - if (!event.formulas?.length) { - return true; - } else { - const startDays = - this.calendar.totalDaysBeforeYear(start.year) + - this.calendar.daysBeforeMonth(start.month, start.year, true) + - start.day; - const currentDays = - this.calendar.totalDaysBeforeYear(day.year) + - this.calendar.daysBeforeMonth(day.month, day.year, true) + - day.day; - const daysBetween = currentDays - startDays; - - return daysBetween % event.formulas[0].number == 0; - } - } - return false; - }); - } - shouldUpdateMoons = false; - moons: Array<[Moon, Phase]>[]; - getMoonsForDay(day: FcDate) { - if (!this.moons || !this.moons.length || this.shouldUpdateMoons) { - this.moons = this.calendar.getMoonsForMonth(this); - } - return this.moons[day.day - 1]; - } - constructor( - public data: Month, - public number: number, - public year: number, - public calendar: CalendarHelper - ) { - this.leapDays = this.calendar.leapDaysForMonth(this.number, year); - this.daysBefore = this.calendar.daysBeforeMonth(this.number, this.year); - - this.days = [ - ...new Array( - data.length + - this.leapDays.filter( - (l) => !l.intercalary || (l.intercalary && l.numbered) - ).length - ).keys(), - ].map((k) => { - return new DayHelper( - this, - k + 1, - this.leapDays.find((leapday) => leapday.after == k) - ); - }); - } -} diff --git a/src/utils/functions.ts b/src/utils/functions.ts index 5b9b855..6ea1678 100644 --- a/src/utils/functions.ts +++ b/src/utils/functions.ts @@ -196,9 +196,9 @@ export function areDatesEqual( export function sortEventList(list: FcEvent[]): FcEvent[] { return list.sort((a, b) => { - if (a.sort.timestamp === b.sort.timestamp) { + if (a.sort?.timestamp === b.sort?.timestamp) { return a.sort.order.localeCompare(b.sort.order); } - return a.sort.timestamp - b.sort.timestamp; + return a.sort?.timestamp - b.sort?.timestamp; }); } \ No newline at end of file