From be0b66c10401ea0b7871fb0ddd458c36629710f8 Mon Sep 17 00:00:00 2001
From: Jin <22962980+JYC333@users.noreply.github.com>
Date: Mon, 31 Mar 2025 23:56:12 +0200
Subject: [PATCH] =?UTF-8?q?chore:=20=F0=9F=A4=96=20use=20dayjs=20fully?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
 src/public/app/widgets/buttons/calendar.ts | 118 ++++++++++-----------
 1 file changed, 54 insertions(+), 64 deletions(-)
diff --git a/src/public/app/widgets/buttons/calendar.ts b/src/public/app/widgets/buttons/calendar.ts
index 41b73415b..87803f6cb 100644
--- a/src/public/app/widgets/buttons/calendar.ts
+++ b/src/public/app/widgets/buttons/calendar.ts
@@ -8,7 +8,7 @@ import toastService from "../../services/toast.js";
 import options from "../../services/options.js";
 import { Dropdown } from "bootstrap";
 import type { EventData } from "../../components/app_context.js";
-import dayjs from "dayjs";
+import dayjs, { Dayjs } from "dayjs";
 import utc from "dayjs/plugin/utc.js";
 import "../../../stylesheets/calendar.css";
 
@@ -90,9 +90,9 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
     private monthDropdown!: Dropdown;
     private firstDayOfWeek!: number;
     private weekCalculationOptions!: WeekCalculationOptions;
-    private activeDate: Date | null = null;
-    private todaysDate!: Date;
-    private date!: Date;
+    private activeDate: Dayjs | null = null;
+    private todaysDate!: Dayjs;
+    private date!: Dayjs;
 
     constructor(title: string = "", icon: string = "") {
         super(title, icon, DROPDOWN_TPL);
@@ -118,18 +118,18 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
             const target = e.target as HTMLElement;
             const value = target.dataset.value;
             if (value) {
-                this.date = dayjs(this.date).month(parseInt(value)).toDate();
+                this.date = this.date.month(parseInt(value));
                 this.createMonth();
             }
         });
         this.$next = this.$dropdownContent.find('[data-calendar-toggle="next"]');
         this.$next.on("click", () => {
-            this.date = dayjs(this.date).add(1, 'month').toDate();
+            this.date = this.date.add(1, 'month');
             this.createMonth();
         });
         this.$previous = this.$dropdownContent.find('[data-calendar-toggle="previous"]');
         this.$previous.on("click", () => {
-            this.date = dayjs(this.date).subtract(1, 'month').toDate();
+            this.date = this.date.subtract(1, 'month');
             this.createMonth();
         });
 
@@ -137,17 +137,17 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
         this.$yearSelect = this.$dropdownContent.find('[data-calendar-input="year"]');
         this.$yearSelect.on("input", (e) => {
             const target = e.target as HTMLInputElement;
-            this.date = dayjs(this.date).year(parseInt(target.value)).toDate();
+            this.date = this.date.year(parseInt(target.value));
             this.createMonth();
         });
         this.$nextYear = this.$dropdownContent.find('[data-calendar-toggle="nextYear"]');
         this.$nextYear.on("click", () => {
-            this.date = dayjs(this.date).add(1, 'year').toDate();
+            this.date = this.date.add(1, 'year');
             this.createMonth();
         });
         this.$previousYear = this.$dropdownContent.find('[data-calendar-toggle="previousYear"]');
         this.$previousYear.on("click", () => {
-            this.date = dayjs(this.date).subtract(1, 'year').toDate();
+            this.date = this.date.subtract(1, 'year');
             this.createMonth();
         });
 
@@ -203,9 +203,9 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
         };
     }
 
-    getWeekNumber(date: Date): number {
-        const year = dayjs(date).year();
-        const jan1 = dayjs().year(year).month(0).date(1);
+    getWeekNumber(date: Dayjs): number {
+        const year = date.year();
+        const jan1 = date.clone().startOf('year');
         const jan1Day = jan1.day();
 
         let firstWeekStart = jan1.clone();
@@ -239,22 +239,23 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
             }
         }
 
-        const diffDays = dayjs(date).diff(firstWeekStart, 'day') + 1;
+        const diffDays = date.diff(firstWeekStart, 'day') + 1;
         const weekNumber = Math.floor(diffDays / 7) + 1;
 
         // Check if the week number is less than 0, which means the date is in the previous year
         if (weekNumber <= 0) {
-            const prevYearLastWeek = this.getWeekNumber(dayjs(date).subtract(1, 'year').endOf('year').toDate());
+            const prevYearLastWeek = this.getWeekNumber(date.subtract(1, 'year').endOf('year'));
             return prevYearLastWeek;
         }
 
         // Check if it's the last week of December
-        if (dayjs(date).month() === 11) { // December
-            const lastDayOfYear = dayjs().year(year).month(11).date(31);
+        if (date.month() === 11) { // December
+            const lastDayOfYear = date.clone().month(11).date(31);
             const lastWeekStart = lastDayOfYear.subtract((lastDayOfYear.day() - this.firstDayOfWeek + 7) % 7, 'day');
 
-            if (this.isEqual(date, lastWeekStart.toDate())) {
-                const nextYearFirstWeek = this.getWeekNumber(lastDayOfYear.add(1, 'day').toDate());
+            // Use local timezone to avoid date mismatch
+            if (date.isSame(lastWeekStart, 'day')) {
+                const nextYearFirstWeek = this.getWeekNumber(lastDayOfYear.add(1, 'day'));
                 return nextYearFirstWeek;
             }
         }
@@ -268,29 +269,29 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
 
     init(activeDate: string | null) {
         // attaching time fixes local timezone handling
-        this.activeDate = activeDate ? dayjs(`${activeDate}T12:00:00`).toDate() : null;
-        this.todaysDate = dayjs().toDate();
-        this.date = dayjs(this.activeDate || this.todaysDate).startOf('month').toDate();
+        this.activeDate = activeDate ? dayjs(`${activeDate}T12:00:00`) : null;
+        this.todaysDate = dayjs();
+        this.date = dayjs(this.activeDate || this.todaysDate).startOf('month');
 
         this.createMonth();
     }
 
     createDay(dateNotesForMonth: DateNotesForMonth, num: number) {
-        const $newDay = $("").addClass("calendar-date").attr("data-calendar-date", utils.formatDateISO(this.date));
+        const $newDay = $("").addClass("calendar-date").attr("data-calendar-date", this.date.local().format('YYYY-MM-DD'));
         const $date = $("").html(String(num));
 
-        const dateNoteId = dateNotesForMonth[utils.formatDateISO(this.date)];
+        const dateNoteId = dateNotesForMonth[this.date.local().format('YYYY-MM-DD')];
 
         if (dateNoteId) {
             $newDay.addClass("calendar-date-exists");
             $newDay.attr("data-href", `#root/${dateNoteId}`);
         }
 
-        if (this.isEqual(this.date, this.activeDate)) {
+        if (this.date.isSame(this.activeDate, 'day')) {
             $newDay.addClass("calendar-date-active");
         }
 
-        if (this.isEqual(this.date, this.todaysDate)) {
+        if (this.date.isSame(this.todaysDate, 'day')) {
             $newDay.addClass("calendar-date-today");
         }
 
@@ -307,61 +308,51 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
         return $newWeekNumber;
     }
 
-    isEqual(a: Date, b: Date | null) {
-        if ((!a && b) || (a && !b)) {
-            return false;
-        }
-
-        if (!b) return false;
-
-        return dayjs(a).isSame(dayjs(b), 'day');
-    }
-
-    private getPrevMonthDays(firstDayOfWeek: number): { weekNumber: number, dates: Date[] } {
-        const prevMonthLastDay = dayjs(this.date).subtract(1, 'month').endOf('month');
+    private getPrevMonthDays(firstDayOfWeek: number): { weekNumber: number, dates: Dayjs[] } {
+        const prevMonthLastDay = this.date.subtract(1, 'month').endOf('month');
         const daysToAdd = (firstDayOfWeek - this.firstDayOfWeek + 7) % 7;
-        const dates = [];
+        const dates: Dayjs[] = [];
 
-        const firstDay = dayjs(this.date).startOf('month');
-        const weekNumber = this.getWeekNumber(firstDay.toDate());
+        const firstDay = this.date.startOf('month');
+        const weekNumber = this.getWeekNumber(firstDay);
 
         // Get dates from previous month
         for (let i = daysToAdd - 1; i >= 0; i--) {
-            dates.push(prevMonthLastDay.subtract(i, 'day').toDate());
+            dates.push(prevMonthLastDay.subtract(i, 'day'));
         }
 
         return { weekNumber, dates };
     }
 
-    private getNextMonthDays(lastDayOfWeek: number): Date[] {
-        const nextMonthFirstDay = dayjs(this.date).add(1, 'month').startOf('month');
-        const dates = [];
+    private getNextMonthDays(lastDayOfWeek: number): Dayjs[] {
+        const nextMonthFirstDay = this.date.add(1, 'month').startOf('month');
+        const dates: Dayjs[] = [];
 
         const lastDayOfUserWeek = (this.firstDayOfWeek + 6) % 7;
         const daysToAdd = (lastDayOfUserWeek - lastDayOfWeek + 7) % 7;
 
         // Get dates from next month
         for (let i = 0; i < daysToAdd; i++) {
-            dates.push(nextMonthFirstDay.add(i, 'day').toDate());
+            dates.push(nextMonthFirstDay.add(i, 'day'));
         }
 
         return dates;
     }
 
     async createMonth() {
-        const month = dayjs(this.date).format('YYYY-MM');
+        const month = this.date.format('YYYY-MM');
         const dateNotesForMonth: DateNotesForMonth = await server.get(`special-notes/notes-for-month/${month}`);
 
         this.$month.empty();
 
-        const firstDay = dayjs(this.date).startOf('month');
+        const firstDay = this.date.startOf('month');
         const firstDayOfWeek = firstDay.day();
 
         // Add dates from previous month
         if (firstDayOfWeek !== this.firstDayOfWeek) {
             const { weekNumber, dates } = this.getPrevMonthDays(firstDayOfWeek);
 
-            const prevMonth = dayjs(this.date).subtract(1, 'month').format('YYYY-MM');
+            const prevMonth = this.date.subtract(1, 'month').format('YYYY-MM');
             const dateNotesForPrevMonth: DateNotesForMonth = await server.get(`special-notes/notes-for-month/${prevMonth}`);
 
             const $weekNumber = this.createWeekNumber(weekNumber);
@@ -370,55 +361,54 @@ export default class CalendarWidget extends RightDropdownButtonWidget {
             dates.forEach(date => {
                 const tempDate = this.date;
                 this.date = date;
-                const $day = this.createDay(dateNotesForPrevMonth, dayjs(date).date());
+                const $day = this.createDay(dateNotesForPrevMonth, date.date());
                 $day.addClass('calendar-date-prev-month');
                 this.$month.append($day);
                 this.date = tempDate;
             });
         }
 
-        const currentMonth = this.date.getMonth();
+        const currentMonth = this.date.month();
 
-        while (this.date.getMonth() === currentMonth) {
-            // Using UTC to avoid issues with summer/winter time
-            const weekNumber = this.getWeekNumber(dayjs(this.date).utc().toDate());
+        while (this.date.month() === currentMonth) {
+            const weekNumber = this.getWeekNumber(this.date);
 
             // Add week number if it's first day of week
-            if (this.date.getDay() === this.firstDayOfWeek) {
+            if (this.date.day() === this.firstDayOfWeek) {
                 const $weekNumber = this.createWeekNumber(weekNumber);
                 this.$month.append($weekNumber);
             }
 
-            const $day = this.createDay(dateNotesForMonth, this.date.getDate());
+            const $day = this.createDay(dateNotesForMonth, this.date.date());
             this.$month.append($day);
 
-            this.date = dayjs(this.date).add(1, 'day').toDate();
+            this.date = this.date.add(1, 'day');
         }
         // while loop trips over and day is at 30/31, bring it back
-        this.date = dayjs(this.date).startOf('month').subtract(1, 'month').toDate();
+        this.date = this.date.startOf('month').subtract(1, 'month');
 
         // Add dates from next month
-        const lastDayOfMonth = dayjs(this.date).endOf('month').toDate();
-        const lastDayOfWeek = lastDayOfMonth.getDay();
+        const lastDayOfMonth = this.date.endOf('month');
+        const lastDayOfWeek = lastDayOfMonth.day();
         const lastDayOfUserWeek = (this.firstDayOfWeek + 6) % 7;
         if (lastDayOfWeek !== lastDayOfUserWeek) {
             const dates = this.getNextMonthDays(lastDayOfWeek);
 
-            const nextMonth = dayjs(this.date).add(1, 'month').format('YYYY-MM');
+            const nextMonth = this.date.add(1, 'month').format('YYYY-MM');
             const dateNotesForNextMonth: DateNotesForMonth = await server.get(`special-notes/notes-for-month/${nextMonth}`);
 
             dates.forEach(date => {
                 const tempDate = this.date;
                 this.date = date;
-                const $day = this.createDay(dateNotesForNextMonth, dayjs(date).date());
+                const $day = this.createDay(dateNotesForNextMonth, date.date());
                 $day.addClass('calendar-date-next-month');
                 this.$month.append($day);
                 this.date = tempDate;
             });
         }
 
-        this.$monthSelect.text(MONTHS[this.date.getMonth()]);
-        this.$yearSelect.val(this.date.getFullYear());
+        this.$monthSelect.text(MONTHS[this.date.month()]);
+        this.$yearSelect.val(this.date.year());
     }
 
     async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {