From 828d0acc0b468bdc509e2808f8db1bbf132c4ff4 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 29 Oct 2026 14:34:00 +0100 Subject: [PATCH] feat: offer this morning and this afternoon as schedule times while they are ahead #1390 --- lib/__tests__/schedule-presets.test.ts | 15 +++++++++++++++ lib/schedule-presets.ts | 15 ++++++++++++--- locales/ar/common.json | 2 ++ locales/ca/common.json | 2 ++ locales/cs/common.json | 2 ++ locales/da/common.json | 2 ++ locales/de/common.json | 2 ++ locales/en/common.json | 2 ++ locales/es/common.json | 2 ++ locales/et/common.json | 2 ++ locales/fa/common.json | 2 ++ locales/fr/common.json | 2 ++ locales/he/common.json | 2 ++ locales/hu/common.json | 2 ++ locales/it/common.json | 2 ++ locales/ja/common.json | 2 ++ locales/ko/common.json | 2 ++ locales/lv/common.json | 2 ++ locales/mn/common.json | 2 ++ locales/nb/common.json | 2 ++ locales/nl/common.json | 2 ++ locales/pl/common.json | 2 ++ locales/pt/common.json | 2 ++ locales/ro/common.json | 2 ++ locales/ru/common.json | 2 ++ locales/sk/common.json | 2 ++ locales/th/common.json | 2 ++ locales/tr/common.json | 2 ++ locales/uk/common.json | 2 ++ locales/zh-TW/common.json | 2 ++ locales/zh/common.json | 2 ++ 31 files changed, 85 insertions(+), 3 deletions(-) diff --git a/lib/__tests__/schedule-presets.test.ts b/lib/__tests__/schedule-presets.test.ts index fe5d1c028..48d81f9e2 100644 --- a/lib/__tests__/schedule-presets.test.ts +++ b/lib/__tests__/schedule-presets.test.ts @@ -24,4 +24,19 @@ describe('schedulePresets', () => { const presets = schedulePresets(local(2026, 10, 12, 9)); expect(presets.find((p) => p.key === 'monday_morning')?.date.getTime()).toBe(local(2026, 10, 19, 8).getTime()); }); + + it('offers this morning and afternoon after midnight, while they are ahead (#1390)', () => { + // Thursday 2026-10-15, 01:30 + const presets = schedulePresets(local(2026, 10, 15, 1, 30)); + expect(presets.slice(0, 3).map((p) => [p.key, p.date.getTime()])).toEqual([ + ['this_morning', local(2026, 10, 15, 8).getTime()], + ['this_afternoon', local(2026, 10, 15, 13).getTime()], + ['tomorrow_morning', local(2026, 10, 16, 8).getTime()], + ]); + }); + + it('drops a time of today that is past or about to be', () => { + expect(schedulePresets(local(2026, 10, 15, 9)).map((p) => p.key)[0]).toBe('this_afternoon'); + expect(schedulePresets(local(2026, 10, 15, 12, 58)).map((p) => p.key)[0]).toBe('tomorrow_morning'); + }); }); diff --git a/lib/schedule-presets.ts b/lib/schedule-presets.ts index fe89e1145..8f99f0402 100644 --- a/lib/schedule-presets.ts +++ b/lib/schedule-presets.ts @@ -1,4 +1,4 @@ -export type SchedulePresetKey = 'tomorrow_morning' | 'tomorrow_afternoon' | 'monday_morning'; +export type SchedulePresetKey = 'this_morning' | 'this_afternoon' | 'tomorrow_morning' | 'tomorrow_afternoon' | 'monday_morning'; export interface SchedulePreset { key: SchedulePresetKey; @@ -12,16 +12,25 @@ function at(base: Date, daysAhead: number, hour: number): Date { return date; } +/** How far ahead a time for today must be to be offered, so it is not past by the click. */ +const TODAY_LEAD_MS = 5 * 60_000; + /** * One-click times for "Schedule send", like other mail clients offer: * tomorrow at 8:00 and 13:00, and next Monday at 8:00. Monday is left out - * when it is tomorrow anyway (on a Sunday). + * when it is tomorrow anyway (on a Sunday). Today's 8:00 and 13:00 come + * first while they are still ahead, so a message written after midnight can + * go out the same morning (#1390). */ export function schedulePresets(now: Date = new Date()): SchedulePreset[] { const presets: SchedulePreset[] = [ + { key: 'this_morning' as const, date: at(now, 0, 8) }, + { key: 'this_afternoon' as const, date: at(now, 0, 13) }, + ].filter((preset) => preset.date.getTime() - now.getTime() >= TODAY_LEAD_MS); + presets.push( { key: 'tomorrow_morning', date: at(now, 1, 8) }, { key: 'tomorrow_afternoon', date: at(now, 1, 13) }, - ]; + ); const daysToMonday = ((8 - now.getDay()) % 7) || 7; if (daysToMonday > 1) presets.push({ key: 'monday_morning', date: at(now, daysToMonday, 8) }); return presets; diff --git a/locales/ar/common.json b/locales/ar/common.json index 1f6721436..60207738f 100644 --- a/locales/ar/common.json +++ b/locales/ar/common.json @@ -927,6 +927,8 @@ "schedule_send": "جدولة الإرسال", "schedule_send_description": "اختر متى يجب على الخادم إرسال هذه الرسالة.", "schedule_preset": { + "this_morning": "هذا الصباح", + "this_afternoon": "بعد ظهر اليوم", "tomorrow_morning": "صباح الغد", "tomorrow_afternoon": "ظهر الغد", "monday_morning": "صباح الاثنين" diff --git a/locales/ca/common.json b/locales/ca/common.json index 11329b541..66f09be0c 100644 --- a/locales/ca/common.json +++ b/locales/ca/common.json @@ -927,6 +927,8 @@ "schedule_send": "Programa l'enviament", "schedule_send_description": "Trieu quan ha d'alliberar el servidor aquest missatge.", "schedule_preset": { + "this_morning": "Aquest matí", + "this_afternoon": "Aquesta tarda", "tomorrow_morning": "Demà al matí", "tomorrow_afternoon": "Demà a la tarda", "monday_morning": "Dilluns al matí" diff --git a/locales/cs/common.json b/locales/cs/common.json index 0fedecc94..145c56f8a 100644 --- a/locales/cs/common.json +++ b/locales/cs/common.json @@ -927,6 +927,8 @@ "schedule_send": "Naplánovat odeslání", "schedule_send_description": "Vyberte, kdy má server tuto zprávu odeslat.", "schedule_preset": { + "this_morning": "Dnes ráno", + "this_afternoon": "Dnes odpoledne", "tomorrow_morning": "Zítra ráno", "tomorrow_afternoon": "Zítra odpoledne", "monday_morning": "V pondělí ráno" diff --git a/locales/da/common.json b/locales/da/common.json index 23c54e29e..ebb1d5b9c 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -927,6 +927,8 @@ "schedule_send": "Planlæg afsendelse", "schedule_send_description": "Vælg hvornår serveren skal frigive denne besked.", "schedule_preset": { + "this_morning": "I dag formiddag", + "this_afternoon": "I eftermiddag", "tomorrow_morning": "I morgen formiddag", "tomorrow_afternoon": "I morgen eftermiddag", "monday_morning": "Mandag formiddag" diff --git a/locales/de/common.json b/locales/de/common.json index e5adba6d7..eb4618cff 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -927,6 +927,8 @@ "schedule_send": "Senden planen", "schedule_send_description": "Wählen Sie, wann der Server diese Nachricht freigeben soll.", "schedule_preset": { + "this_morning": "Heute früh", + "this_afternoon": "Heute Nachmittag", "tomorrow_morning": "Morgen früh", "tomorrow_afternoon": "Morgen Nachmittag", "monday_morning": "Montag früh" diff --git a/locales/en/common.json b/locales/en/common.json index 3e38c69d4..70f09206e 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -929,6 +929,8 @@ "schedule_send": "Schedule send", "schedule_send_description": "Choose when the server should release this message.", "schedule_preset": { + "this_morning": "This morning", + "this_afternoon": "This afternoon", "tomorrow_morning": "Tomorrow morning", "tomorrow_afternoon": "Tomorrow afternoon", "monday_morning": "Monday morning" diff --git a/locales/es/common.json b/locales/es/common.json index f5ed90990..a77fcc8bf 100644 --- a/locales/es/common.json +++ b/locales/es/common.json @@ -927,6 +927,8 @@ "schedule_send": "Programar envío", "schedule_send_description": "Elige cuándo debe liberar el servidor este mensaje.", "schedule_preset": { + "this_morning": "Esta mañana", + "this_afternoon": "Esta tarde", "tomorrow_morning": "Mañana por la mañana", "tomorrow_afternoon": "Mañana por la tarde", "monday_morning": "El lunes por la mañana" diff --git a/locales/et/common.json b/locales/et/common.json index 3c17d2424..7a128fbe0 100644 --- a/locales/et/common.json +++ b/locales/et/common.json @@ -927,6 +927,8 @@ "schedule_send": "Ajasta saatmine", "schedule_send_description": "Vali, millal server peaks selle sõnumi välja saatma.", "schedule_preset": { + "this_morning": "Täna hommikul", + "this_afternoon": "Täna pärastlõunal", "tomorrow_morning": "Homme hommikul", "tomorrow_afternoon": "Homme pärastlõunal", "monday_morning": "Esmaspäeva hommikul" diff --git a/locales/fa/common.json b/locales/fa/common.json index 0aae36bdd..26aa011e9 100644 --- a/locales/fa/common.json +++ b/locales/fa/common.json @@ -927,6 +927,8 @@ "schedule_send": "زمان‌بندی ارسال", "schedule_send_description": "زمان انتشار پیام توسط سرور را انتخاب کنید.", "schedule_preset": { + "this_morning": "امروز صبح", + "this_afternoon": "امروز بعدازظهر", "tomorrow_morning": "فردا صبح", "tomorrow_afternoon": "فردا بعدازظهر", "monday_morning": "دوشنبه صبح" diff --git a/locales/fr/common.json b/locales/fr/common.json index 2487816ae..e0a4e99c8 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -927,6 +927,8 @@ "schedule_send": "Planifier l’envoi", "schedule_send_description": "Choisissez quand le serveur doit libérer ce message.", "schedule_preset": { + "this_morning": "Ce matin", + "this_afternoon": "Cet après-midi", "tomorrow_morning": "Demain matin", "tomorrow_afternoon": "Demain après-midi", "monday_morning": "Lundi matin" diff --git a/locales/he/common.json b/locales/he/common.json index 3b95e54c8..67b0e8b8f 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -892,6 +892,8 @@ "schedule_send": "תזמן שליחה", "schedule_send_description": "בחר מתי השרת צריך לשחרר הודעה זו.", "schedule_preset": { + "this_morning": "הבוקר", + "this_afternoon": "היום אחר הצהריים", "tomorrow_morning": "מחר בבוקר", "tomorrow_afternoon": "מחר אחר הצהריים", "monday_morning": "יום שני בבוקר" diff --git a/locales/hu/common.json b/locales/hu/common.json index 682e3a873..94f4410a5 100644 --- a/locales/hu/common.json +++ b/locales/hu/common.json @@ -927,6 +927,8 @@ "schedule_send": "Késleltetett küldés", "schedule_send_description": "Válaszd ki, mikor küldje el a szerver az üzenetet.", "schedule_preset": { + "this_morning": "Ma reggel", + "this_afternoon": "Ma délután", "tomorrow_morning": "Holnap reggel", "tomorrow_afternoon": "Holnap délután", "monday_morning": "Hétfő reggel" diff --git a/locales/it/common.json b/locales/it/common.json index d9d0c7cae..ba7d6ae1e 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -927,6 +927,8 @@ "schedule_send": "Programma invio", "schedule_send_description": "Scegli quando il server deve rilasciare questo messaggio.", "schedule_preset": { + "this_morning": "Stamattina", + "this_afternoon": "Oggi pomeriggio", "tomorrow_morning": "Domattina", "tomorrow_afternoon": "Domani pomeriggio", "monday_morning": "Lunedì mattina" diff --git a/locales/ja/common.json b/locales/ja/common.json index 1b5a9b1b0..719e8c865 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -927,6 +927,8 @@ "schedule_send": "送信を予約", "schedule_send_description": "サーバーがこのメッセージを送信する日時を選択します。", "schedule_preset": { + "this_morning": "今朝", + "this_afternoon": "今日の午後", "tomorrow_morning": "明日の朝", "tomorrow_afternoon": "明日の午後", "monday_morning": "月曜日の朝" diff --git a/locales/ko/common.json b/locales/ko/common.json index 107cbf04a..acf7ff05f 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -927,6 +927,8 @@ "schedule_send": "보내기 예약", "schedule_send_description": "서버가 이 메시지를 보낼 시간을 선택하세요.", "schedule_preset": { + "this_morning": "오늘 아침", + "this_afternoon": "오늘 오후", "tomorrow_morning": "내일 오전", "tomorrow_afternoon": "내일 오후", "monday_morning": "월요일 오전" diff --git a/locales/lv/common.json b/locales/lv/common.json index 868f4e240..6becb299b 100644 --- a/locales/lv/common.json +++ b/locales/lv/common.json @@ -927,6 +927,8 @@ "schedule_send": "Ieplānot sūtīšanu", "schedule_send_description": "Izvēlieties, kad serverim jānosūta šis ziņojums.", "schedule_preset": { + "this_morning": "Šorīt", + "this_afternoon": "Šodien pēcpusdienā", "tomorrow_morning": "Rīt no rīta", "tomorrow_afternoon": "Rīt pēcpusdienā", "monday_morning": "Pirmdien no rīta" diff --git a/locales/mn/common.json b/locales/mn/common.json index a074d4b5e..aafd83659 100644 --- a/locales/mn/common.json +++ b/locales/mn/common.json @@ -927,6 +927,8 @@ "schedule_send": "Хуваарь илгээх", "schedule_send_description": "Сервер энэ мессежийг хэзээ гаргахыг сонгоно уу.", "schedule_preset": { + "this_morning": "Өнөө өглөө", + "this_afternoon": "Өнөөдөр үдээс хойш", "tomorrow_morning": "Маргааш өглөө", "tomorrow_afternoon": "Маргааш үдээс хойш", "monday_morning": "Даваа гарагийн өглөө" diff --git a/locales/nb/common.json b/locales/nb/common.json index 427ebbb4e..381c22609 100644 --- a/locales/nb/common.json +++ b/locales/nb/common.json @@ -927,6 +927,8 @@ "schedule_send": "Planlegg sending", "schedule_send_description": "Velg når serveren skal sende denne meldingen.", "schedule_preset": { + "this_morning": "I dag tidlig", + "this_afternoon": "I ettermiddag", "tomorrow_morning": "I morgen tidlig", "tomorrow_afternoon": "I morgen ettermiddag", "monday_morning": "Mandag morgen" diff --git a/locales/nl/common.json b/locales/nl/common.json index 952e26546..5a3072284 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -927,6 +927,8 @@ "schedule_send": "Verzenden plannen", "schedule_send_description": "Kies wanneer de server dit bericht moet vrijgeven.", "schedule_preset": { + "this_morning": "Vanochtend", + "this_afternoon": "Vanmiddag", "tomorrow_morning": "Morgenochtend", "tomorrow_afternoon": "Morgenmiddag", "monday_morning": "Maandagochtend" diff --git a/locales/pl/common.json b/locales/pl/common.json index 50152f289..c38d5a435 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -927,6 +927,8 @@ "schedule_send": "Zaplanuj wysyłkę", "schedule_send_description": "Wybierz, kiedy serwer ma wysłać tę wiadomość.", "schedule_preset": { + "this_morning": "Dziś rano", + "this_afternoon": "Dziś po południu", "tomorrow_morning": "Jutro rano", "tomorrow_afternoon": "Jutro po południu", "monday_morning": "W poniedziałek rano" diff --git a/locales/pt/common.json b/locales/pt/common.json index 2762a57c3..70af36552 100644 --- a/locales/pt/common.json +++ b/locales/pt/common.json @@ -927,6 +927,8 @@ "schedule_send": "Agendar envio", "schedule_send_description": "Escolha quando o servidor deve liberar esta mensagem.", "schedule_preset": { + "this_morning": "Esta manhã", + "this_afternoon": "Esta tarde", "tomorrow_morning": "Amanhã de manhã", "tomorrow_afternoon": "Amanhã à tarde", "monday_morning": "Segunda de manhã" diff --git a/locales/ro/common.json b/locales/ro/common.json index 156dddb5f..8728037a6 100644 --- a/locales/ro/common.json +++ b/locales/ro/common.json @@ -927,6 +927,8 @@ "schedule_send": "Programează trimiterea", "schedule_send_description": "Alegeți momentul în care serverul ar trebui să transmită acest mesaj.", "schedule_preset": { + "this_morning": "Azi dimineață", + "this_afternoon": "Azi după-amiază", "tomorrow_morning": "Mâine dimineață", "tomorrow_afternoon": "Mâine după-amiază", "monday_morning": "Luni dimineață" diff --git a/locales/ru/common.json b/locales/ru/common.json index 7dac0b900..d40414a9a 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -927,6 +927,8 @@ "schedule_send": "Запланировать отправку", "schedule_send_description": "Выберите, когда сервер должен отправить это сообщение.", "schedule_preset": { + "this_morning": "Сегодня утром", + "this_afternoon": "Сегодня днём", "tomorrow_morning": "Завтра утром", "tomorrow_afternoon": "Завтра днём", "monday_morning": "В понедельник утром" diff --git a/locales/sk/common.json b/locales/sk/common.json index ffaefe654..5157b4346 100644 --- a/locales/sk/common.json +++ b/locales/sk/common.json @@ -927,6 +927,8 @@ "schedule_send": "Naplánovať odoslanie", "schedule_send_description": "Vyberte, kedy má server túto správu odoslať.", "schedule_preset": { + "this_morning": "Dnes ráno", + "this_afternoon": "Dnes popoludní", "tomorrow_morning": "Zajtra ráno", "tomorrow_afternoon": "Zajtra popoludní", "monday_morning": "V pondelok ráno" diff --git a/locales/th/common.json b/locales/th/common.json index f8c564eff..fc7fdc75d 100644 --- a/locales/th/common.json +++ b/locales/th/common.json @@ -1154,6 +1154,8 @@ "schedule_send": "กำหนดเวลาส่ง", "schedule_send_description": "เลือกเวลาที่ต้องการให้เซิร์ฟเวอร์ส่งข้อความนี้", "schedule_preset": { + "this_morning": "เช้านี้", + "this_afternoon": "บ่ายนี้", "tomorrow_morning": "เช้าวันพรุ่งนี้", "tomorrow_afternoon": "บ่ายวันพรุ่งนี้", "monday_morning": "เช้าวันจันทร์" diff --git a/locales/tr/common.json b/locales/tr/common.json index 387423f77..c8cc1b5b9 100644 --- a/locales/tr/common.json +++ b/locales/tr/common.json @@ -927,6 +927,8 @@ "schedule_send": "Göndermeyi zamanla", "schedule_send_description": "Sunucunun bu iletiyi ne zaman göndereceğini seçin.", "schedule_preset": { + "this_morning": "Bu sabah", + "this_afternoon": "Bu öğleden sonra", "tomorrow_morning": "Yarın sabah", "tomorrow_afternoon": "Yarın öğleden sonra", "monday_morning": "Pazartesi sabah" diff --git a/locales/uk/common.json b/locales/uk/common.json index 6c814cfa3..3602926df 100644 --- a/locales/uk/common.json +++ b/locales/uk/common.json @@ -927,6 +927,8 @@ "schedule_send": "Запланувати надсилання", "schedule_send_description": "Виберіть, коли сервер має надіслати це повідомлення.", "schedule_preset": { + "this_morning": "Сьогодні вранці", + "this_afternoon": "Сьогодні вдень", "tomorrow_morning": "Завтра вранці", "tomorrow_afternoon": "Завтра вдень", "monday_morning": "У понеділок вранці" diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json index 4cb7ca215..b55432a0a 100644 --- a/locales/zh-TW/common.json +++ b/locales/zh-TW/common.json @@ -927,6 +927,8 @@ "schedule_send": "排程寄送", "schedule_send_description": "選擇伺服器要在何時送出這封郵件。", "schedule_preset": { + "this_morning": "今天早上", + "this_afternoon": "今天下午", "tomorrow_morning": "明天上午", "tomorrow_afternoon": "明天下午", "monday_morning": "星期一上午" diff --git a/locales/zh/common.json b/locales/zh/common.json index bc0a2d846..ba6d60b48 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -927,6 +927,8 @@ "schedule_send": "计划发送", "schedule_send_description": "选择服务器应何时发送此邮件。", "schedule_preset": { + "this_morning": "今天早上", + "this_afternoon": "今天下午", "tomorrow_morning": "明天上午", "tomorrow_afternoon": "明天下午", "monday_morning": "周一上午"