refactor(react/launch_bar): use different mechanism for gathering calendar info

This commit is contained in:
Elian Doran 2025-12-04 19:22:28 +02:00
parent 5c8445f3fe
commit bab5326d7c
No known key found for this signature in database
2 changed files with 84 additions and 63 deletions

View File

@ -8,6 +8,7 @@ import { VNode } from "preact";
import clsx from "clsx"; import clsx from "clsx";
import "./CalendarWidget.css"; import "./CalendarWidget.css";
import server from "../../services/server"; import server from "../../services/server";
import { getMonthInformation } from "./CalendarWidgetUtils";
interface DateNotesForMonth { interface DateNotesForMonth {
[date: string]: string; [date: string]: string;
@ -45,19 +46,19 @@ function Calendar({ date, firstDayOfWeekISO }: { date: Dayjs, firstDayOfWeekISO:
const month = date.format('YYYY-MM'); const month = date.format('YYYY-MM');
const firstDay = date.startOf('month'); const firstDay = date.startOf('month');
const firstDayISO = firstDay.isoWeekday(); const firstDayISO = firstDay.isoWeekday();
const monthInfo = getMonthInformation(date, firstDayISO, firstDayOfWeekISO);
return ( return (
<div className="calendar-body" data-calendar-area="month"> <div className="calendar-body" data-calendar-area="month">
{firstDayISO !== firstDayOfWeekISO && <PreviousMonthDays date={date} firstDayISO={firstDayISO} firstDayOfWeekISO={firstDayOfWeekISO} />} {firstDayISO !== firstDayOfWeekISO && <PreviousMonthDays date={date} dates={monthInfo.prevMonth.dates} />}
<CurrentMonthDays date={date} firstDayOfWeekISO={firstDayOfWeekISO} /> <CurrentMonthDays date={date} dates={monthInfo.currentMonth.dates} />
<NextMonthDays date={date} firstDayOfWeekISO={firstDayOfWeekISO} /> <NextMonthDays date={date} dates={monthInfo.nextMonth.dates} />
</div> </div>
) )
} }
function PreviousMonthDays({ date, firstDayISO, firstDayOfWeekISO }: { date: Dayjs, firstDayISO: number, firstDayOfWeekISO: number }) { function PreviousMonthDays({ date, dates }: { date: Dayjs, dates: Dayjs[] }) {
const prevMonth = date.subtract(1, 'month').format('YYYY-MM'); const prevMonth = date.subtract(1, 'month').format('YYYY-MM');
const { weekNumber, dates } = getPrevMonthDays(date, firstDayISO, firstDayOfWeekISO);
const [ dateNotesForPrevMonth, setDateNotesForPrevMonth ] = useState<DateNotesForMonth>(); const [ dateNotesForPrevMonth, setDateNotesForPrevMonth ] = useState<DateNotesForMonth>();
useEffect(() => { useEffect(() => {
@ -69,18 +70,13 @@ function PreviousMonthDays({ date, firstDayISO, firstDayOfWeekISO }: { date: Day
)); ));
} }
function CurrentMonthDays({ date, firstDayOfWeekISO }: { date: Dayjs, firstDayOfWeekISO: number }) { function CurrentMonthDays({ date, dates }: { date: Dayjs, dates: Dayjs[] }) {
const dates = getCurMonthDays(date, firstDayOfWeekISO);
return dates.map(date => ( return dates.map(date => (
<CalendarDay date={date} dateNotesForMonth={{}} /> <CalendarDay date={date} dateNotesForMonth={{}} />
)); ));
} }
function NextMonthDays({ date, firstDayOfWeekISO }: { date: Dayjs, firstDayOfWeekISO: number }) { function NextMonthDays({ date, dates }: { date: Dayjs, dates: Dayjs[] }) {
const lastDayOfMonth = date.endOf('month');
const lastDayISO = lastDayOfMonth.isoWeekday();
const lastDayOfUserWeek = ((firstDayOfWeekISO + 6 - 1) % 7) + 1;
const nextMonth = date.add(1, 'month').format('YYYY-MM'); const nextMonth = date.add(1, 'month').format('YYYY-MM');
const [ dateNotesForNextMonth, setDateNotesForNextMonth ] = useState<DateNotesForMonth>(); const [ dateNotesForNextMonth, setDateNotesForNextMonth ] = useState<DateNotesForMonth>();
@ -88,7 +84,6 @@ function NextMonthDays({ date, firstDayOfWeekISO }: { date: Dayjs, firstDayOfWee
server.get<DateNotesForMonth>(`special-notes/notes-for-month/${nextMonth}`).then(setDateNotesForNextMonth); server.get<DateNotesForMonth>(`special-notes/notes-for-month/${nextMonth}`).then(setDateNotesForNextMonth);
}, [ date ]); }, [ date ]);
const dates = lastDayISO !== lastDayOfUserWeek ? getNextMonthDays(date, lastDayISO, firstDayOfWeekISO) : [];
return dates.map(date => ( return dates.map(date => (
<CalendarDay date={date} dateNotesForMonth={dateNotesForNextMonth} className="calendar-date-next-month" /> <CalendarDay date={date} dateNotesForMonth={dateNotesForNextMonth} className="calendar-date-next-month" />
)); ));
@ -107,53 +102,3 @@ function CalendarDay({ date, dateNotesForMonth, className }: { date: Dayjs, date
); );
} }
function getPrevMonthDays(date: Dayjs, firstDayISO: number, firstDayOfWeekISO: number): { weekNumber: number, dates: Dayjs[] } {
const prevMonthLastDay = date.subtract(1, 'month').endOf('month');
const daysToAdd = (firstDayISO - firstDayOfWeekISO + 7) % 7;
const dates: Dayjs[] = [];
const firstDay = date.startOf('month');
const weekNumber = getWeekNumber(firstDay, firstDayOfWeekISO);
// Get dates from previous month
for (let i = daysToAdd - 1; i >= 0; i--) {
dates.push(prevMonthLastDay.subtract(i, 'day'));
}
return { weekNumber, dates };
}
function getCurMonthDays(date: Dayjs, firstDayOfWeekISO: number) {
let dateCursor = date;
const currentMonth = date.month();
const dates: Dayjs[] = [];
while (dateCursor.month() === currentMonth) {
dates.push(dateCursor);
dateCursor = dateCursor.add(1, "day");
}
return dates;
}
function getNextMonthDays(date: Dayjs, lastDayISO: number, firstDayOfWeekISO): Dayjs[] {
const nextMonthFirstDay = date.add(1, 'month').startOf('month');
const dates: Dayjs[] = [];
const lastDayOfUserWeek = ((firstDayOfWeekISO + 6 - 1) % 7) + 1; // ISO wrap
const daysToAdd = (lastDayOfUserWeek - lastDayISO + 7) % 7;
for (let i = 0; i < daysToAdd; i++) {
dates.push(nextMonthFirstDay.add(i, 'day'));
}
return dates;
}
function getWeekNumber(date: Dayjs, firstDayOfWeekISO: number): number {
const weekStart = getWeekStartDate(date, firstDayOfWeekISO);
return weekStart.isoWeek();
}
function getWeekStartDate(date: Dayjs, firstDayOfWeekISO: number): Dayjs {
const currentISO = date.isoWeekday();
const diff = (currentISO - firstDayOfWeekISO + 7) % 7;
return date.clone().subtract(diff, "day").startOf("day");
}

View File

@ -0,0 +1,76 @@
import { Dayjs } from "@triliumnext/commons";
interface DateRangeInfo {
weekNumbers: number[];
dates: Dayjs[];
}
export function getMonthInformation(date: Dayjs, firstDayISO: number, firstDayOfWeekISO: number) {
return {
prevMonth: getPrevMonthDays(date, firstDayISO, firstDayOfWeekISO),
currentMonth: getCurMonthDays(date, firstDayOfWeekISO),
nextMonth: getNextMonthDays(date, firstDayOfWeekISO)
}
}
function getPrevMonthDays(date: Dayjs, firstDayISO: number, firstDayOfWeekISO: number): DateRangeInfo {
const prevMonthLastDay = date.subtract(1, 'month').endOf('month');
const daysToAdd = (firstDayISO - firstDayOfWeekISO + 7) % 7;
const dates: Dayjs[] = [];
const firstDay = date.startOf('month');
const weekNumber = getWeekNumber(firstDay, firstDayOfWeekISO);
// Get dates from previous month
for (let i = daysToAdd - 1; i >= 0; i--) {
dates.push(prevMonthLastDay.subtract(i, 'day'));
}
return { weekNumbers: [ weekNumber ], dates };
}
function getCurMonthDays(date: Dayjs, firstDayOfWeekISO: number): DateRangeInfo {
let dateCursor = date;
const currentMonth = date.month();
const dates: Dayjs[] = [];
const weekNumbers: number[] = [];
while (dateCursor.month() === currentMonth) {
const weekNumber = getWeekNumber(date, firstDayOfWeekISO);
if (date.isoWeekday() === firstDayOfWeekISO) {
weekNumbers.push(weekNumber);
}
dates.push(dateCursor);
dateCursor = dateCursor.add(1, "day");
}
return { weekNumbers, dates };
}
function getNextMonthDays(date: Dayjs, firstDayOfWeekISO: number): DateRangeInfo {
const lastDayOfMonth = date.endOf('month');
const lastDayISO = lastDayOfMonth.isoWeekday();
const lastDayOfUserWeek = ((firstDayOfWeekISO + 6 - 1) % 7) + 1;
const nextMonthFirstDay = date.add(1, 'month').startOf('month');
const dates: Dayjs[] = [];
if (lastDayISO !== lastDayOfUserWeek) {
const daysToAdd = (lastDayOfUserWeek - lastDayISO + 7) % 7;
for (let i = 0; i < daysToAdd; i++) {
dates.push(nextMonthFirstDay.add(i, 'day'));
}
}
return { weekNumbers: [], dates };
}
function getWeekNumber(date: Dayjs, firstDayOfWeekISO: number): number {
const weekStart = getWeekStartDate(date, firstDayOfWeekISO);
return weekStart.isoWeek();
}
function getWeekStartDate(date: Dayjs, firstDayOfWeekISO: number): Dayjs {
const currentISO = date.isoWeekday();
const diff = (currentISO - firstDayOfWeekISO + 7) % 7;
return date.clone().subtract(diff, "day").startOf("day");
}