authorgravatar for vitalyiegorov@gmail.comVitaly Iegorov <vitalyiegorov@gmail.com> 2026-08-30 22:02:21+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-30 16:02:21-04:00
log7980dfddb193864e07a5bcc013b0ccb93fb4300c
treea84c5c169162b1d3cda8fab9a78def6d3073565e
parentac4aae101d060b5355a5de58e23c7387886d9021
signature Signed by PGP key B5690EEEBB952194

fix(web,mobile): snooze menu no longer offers the same wake time twice (#8741)


2 files changed, 24 insertions(+), 7 deletions(-)

packages/client-runtime/src/state/threadSettled.ts+11-7
......@@ -394,7 +394,9 @@ function addSnoozeDays(base: Date, days: number): Date {
394394/**
395395 * Shared "snooze until" choices for every client. "This evening" only
396396 * appears while it is meaningfully before evening; after that the calendar
397 * choices start at "Tomorrow".
397 * choices start at "Tomorrow". Calendar presets that land on the same
398 * instant collapse: on Sundays "Tomorrow" and "Next week" are both Monday
399 * morning, so only "Tomorrow" is offered.
398400 */
399401export function resolveSnoozePresets(now: Date): ReadonlyArray<SnoozePreset> {
400402 const inAnHour = new Date(now.getTime() + HOUR_MS);
......@@ -434,12 +436,14 @@ export function resolveSnoozePresets(now: Date): ReadonlyArray<SnoozePreset> {
434436
435437 const daysUntilMonday = (1 - now.getDay() + 7) % 7 || 7;
436438 const nextWeek = snoozeAtHour(addSnoozeDays(now, daysUntilMonday), MORNING_HOUR);
437 presets.push({
438 id: "next-week",
439 label: "Next week",
440 whenLabel: `${nextWeek.toLocaleDateString(undefined, { weekday: "short" })} ${snoozeTimeOfDayLabel(nextWeek)}`,
441 snoozedUntil: nextWeek.toISOString(),
442 });
439 if (nextWeek.getTime() !== tomorrow.getTime()) {
440 presets.push({
441 id: "next-week",
442 label: "Next week",
443 whenLabel: `${nextWeek.toLocaleDateString(undefined, { weekday: "short" })} ${snoozeTimeOfDayLabel(nextWeek)}`,
444 snoozedUntil: nextWeek.toISOString(),
445 });
446 }
443447
444448 return presets;
445449}
packages/client-runtime/src/state/threadSnoozed.test.ts+13
......@@ -297,4 +297,17 @@ describe("resolveSnoozePresets", () => {
297297 expect(nextWeek.getDay()).toBe(1);
298298 expect(nextWeek.getDate()).toBe(13);
299299 });
300
301 it("drops next week on Sundays, when it lands on the same Monday as tomorrow", () => {
302 // Sunday 2026-08-30 07:01: "Tomorrow" and "Next week" are both Monday 9:00.
303 const presets = resolveSnoozePresets(localDate(2026, 8, 30, 7, 1));
304 expect(presets.map((preset) => preset.id)).toEqual([
305 "hour",
306 "three-hours",
307 "evening",
308 "tomorrow",
309 ]);
310 const tomorrow = new Date(presets.find((preset) => preset.id === "tomorrow")!.snoozedUntil);
311 expect(tomorrow.getDay()).toBe(1);
312 });
300313});