Files
wehub-resource-sync 2114b14ee0
Sync main into demo / sync (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:26 +08:00

100 lines
3.5 KiB
TypeScript

import * as TimeService from '@/os/TimeService';
export const REMINDER_STEP_MINUTES = 5;
const REMINDER_STEP_MS = REMINDER_STEP_MINUTES * 60 * 1000;
const REMINDER_MAX_DAY_OFFSET = 366;
const REMINDER_MAX_HOUR = 11;
const REMINDER_MAX_MINUTE = 55;
const WEEKDAY_LABELS = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] as const;
export type ReminderBounds = {
minTs: number;
maxTs: number;
};
export type ReminderDateOption = {
value: number;
label: string;
};
export function roundUpToReminderStep(timestamp: number): number {
return Math.ceil(timestamp / REMINDER_STEP_MS) * REMINDER_STEP_MS;
}
export function startOfLocalDay(timestamp: number): number {
const date = TimeService.fromTimestamp(timestamp);
return TimeService.fromLocalParts(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
}
export function getReminderBounds(nowTs: number): ReminderBounds {
const minTs = roundUpToReminderStep(nowTs);
const maxDate = TimeService.fromTimestamp(startOfLocalDay(nowTs));
maxDate.setDate(maxDate.getDate() + REMINDER_MAX_DAY_OFFSET);
maxDate.setHours(REMINDER_MAX_HOUR, REMINDER_MAX_MINUTE, 0, 0);
return {
minTs,
maxTs: maxDate.getTime(),
};
}
export function clampReminderSelection(timestamp: number, nowTs: number): number {
const { minTs, maxTs } = getReminderBounds(nowTs);
const rounded = roundUpToReminderStep(timestamp);
return Math.min(maxTs, Math.max(minTs, rounded));
}
export function buildReminderTimestamp(dayStartTs: number, hour: number, minute: number): number {
const date = TimeService.fromTimestamp(dayStartTs);
date.setHours(hour, minute, 0, 0);
return date.getTime();
}
export function formatReminderDateLabel(dayStartTs: number): string {
const date = TimeService.fromTimestamp(dayStartTs);
return `${date.getMonth() + 1}${date.getDate()}${WEEKDAY_LABELS[date.getDay()]}`;
}
export function getReminderDateOptions(nowTs: number): ReminderDateOption[] {
const { minTs, maxTs } = getReminderBounds(nowTs);
const options: ReminderDateOption[] = [];
const startDay = startOfLocalDay(minTs);
const endDay = startOfLocalDay(maxTs);
for (let dayStart = startDay; dayStart <= endDay; dayStart += 24 * 60 * 60 * 1000) {
options.push({
value: dayStart,
label: formatReminderDateLabel(dayStart),
});
}
return options;
}
function isSameLocalDay(leftTs: number, rightTs: number): boolean {
return startOfLocalDay(leftTs) === startOfLocalDay(rightTs);
}
export function getReminderHourOptions(dayStartTs: number, nowTs: number): number[] {
const { minTs, maxTs } = getReminderBounds(nowTs);
const minHour = isSameLocalDay(dayStartTs, minTs) ? TimeService.fromTimestamp(minTs).getHours() : 0;
const maxHour = isSameLocalDay(dayStartTs, maxTs) ? TimeService.fromTimestamp(maxTs).getHours() : 23;
return Array.from({ length: maxHour - minHour + 1 }, (_, index) => minHour + index);
}
export function getReminderMinuteOptions(dayStartTs: number, hour: number, nowTs: number): number[] {
const { minTs, maxTs } = getReminderBounds(nowTs);
const minDate = TimeService.fromTimestamp(minTs);
const maxDate = TimeService.fromTimestamp(maxTs);
const minMinute =
isSameLocalDay(dayStartTs, minTs) && hour === minDate.getHours() ? minDate.getMinutes() : 0;
const maxMinute =
isSameLocalDay(dayStartTs, maxTs) && hour === maxDate.getHours() ? maxDate.getMinutes() : 55;
return Array.from(
{ length: Math.floor((maxMinute - minMinute) / REMINDER_STEP_MINUTES) + 1 },
(_, index) => minMinute + index * REMINDER_STEP_MINUTES,
);
}