diff --git a/components/settings/calendar-settings.tsx b/components/settings/calendar-settings.tsx index b8e655f8..4154f17b 100644 --- a/components/settings/calendar-settings.tsx +++ b/components/settings/calendar-settings.tsx @@ -4,17 +4,14 @@ import { useTranslations } from 'next-intl'; import { useCalendarStore, CalendarViewMode } from '@/stores/calendar-store'; import { useSettingsStore } from '@/stores/settings-store'; import { usePolicyStore } from '@/stores/policy-store'; -import { SettingsSection, SettingItem, Select, RadioGroup, ToggleSwitch } from './settings-section'; +import { SettingsSection, SettingItem, Select, ToggleSwitch } from './settings-section'; export function CalendarSettings() { const t = useTranslations('calendar.settings'); const tViews = useTranslations('calendar.views'); - const tDays = useTranslations('calendar.days'); const { viewMode, setViewMode } = useCalendarStore(); const { - timeFormat, - firstDayOfWeek, showTimeInMonthView, showWeekNumbers, enableCalendarTasks, @@ -40,28 +37,6 @@ export function CalendarSettings() { /> - - updateSetting('firstDayOfWeek', parseInt(value) as 0 | 1)} - options={[ - { value: '1', label: tDays('monday') }, - { value: '0', label: tDays('sunday') }, - ]} - /> - - - - updateSetting('timeFormat', value as '12h' | '24h')} - options={[ - { value: '12h', label: t('time_format_12h') }, - { value: '24h', label: t('time_format_24h') }, - ]} - /> - - s.locale); + + const preview = useMemo(() => { + // Build sample timestamps for each bucket so users see what their pick + // will look like in practice. Use offsets relative to "now" so the + // bucketing is stable even though the wall-clock keeps moving. + void locale; void dateFormat; void timeFormat; + const now = new Date(); + const today = new Date(now); + today.setHours(15, 31, 0, 0); + const thisWeek = new Date(now); + thisWeek.setDate(now.getDate() - 2); + thisWeek.setHours(15, 31, 0, 0); + const older = new Date(now); + older.setMonth(now.getMonth() - 2); + older.setHours(15, 31, 0, 0); + return { + today: formatDate(today), + thisWeek: formatDate(thisWeek), + older: formatDate(older), + }; + }, [locale, dateFormat, timeFormat]); return ( - + + + + + updateSetting('dateFormat', value as DateFormat)} + options={[ + { value: 'smart', label: t('date_format.smart') }, + { value: 'relative', label: t('date_format.relative') }, + { value: 'full', label: t('date_format.full') }, + ]} + /> + + + {t('date_format.preview_today')} + {preview.today} + + + {t('date_format.preview_this_week')} + {preview.thisWeek} + + + {t('date_format.preview_older')} + {preview.older} + + + + + + + updateSetting('timeFormat', value as TimeFormat)} + options={[ + { value: '12h', label: t('time_format.12h') }, + { value: '24h', label: t('time_format.24h') }, + ]} + /> + + + + updateSetting('firstDayOfWeek', parseInt(value) as FirstDayOfWeek)} + options={[ + { value: '1', label: tDays('monday') }, + { value: '0', label: tDays('sunday') }, + ]} + /> + ); } diff --git a/lib/utils.ts b/lib/utils.ts index d6bd9371..9c623d27 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -3,6 +3,8 @@ import { twMerge } from "tailwind-merge"; import { Mailbox, UNIFIED_MAILBOX_IDS } from "./jmap/types"; import type { UnifiedMailboxRole } from "./jmap/types"; import { debug } from "./debug"; +import { useLocaleStore } from "@/stores/locale-store"; +import { useSettingsStore } from "@/stores/settings-store"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -40,24 +42,86 @@ export function generateUUID(): string { return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`; } +/** + * Formats a received-at date for the email list. The output style is + * controlled by the `dateFormat` user setting: + * + * - `smart` (default) — locale-aware, age-bucketed: + * today → time only ("15:31" or "3:31 PM") + * last 7 days → short weekday+time ("Fr 15:31", "Fri 3:31 PM") + * older → full locale date ("28.04.2026", "04/28/2026") + * - `relative` — legacy en-US relative format ("1h ago", "2d ago"). + * - `full` — always the full locale date+time. + * + * Both the locale (from the language picker) and 12h/24h preference are + * read via `getState()` so this stays SSR-safe. + */ export function formatDate(date: Date | string): string { const d = typeof date === "string" ? new Date(date) : date; const now = new Date(); - const diff = now.getTime() - d.getTime(); - const minutes = Math.floor(diff / 60000); - const hours = Math.floor(diff / 3600000); - const days = Math.floor(diff / 86400000); + const localeRaw = useLocaleStore.getState().locale; + const locale = localeRaw && localeRaw.length > 0 ? localeRaw : "en"; + // `en` alone resolves to en-US in Intl; everything else uses the language + // subtag as-is and lets the runtime pick a sensible default region. + const intlLocale = locale === "en" ? "en-US" : locale; + const { dateFormat, timeFormat } = useSettingsStore.getState(); + const hour12 = timeFormat === "12h"; - if (minutes < 1) return "Just now"; - if (minutes < 60) return `${minutes}m ago`; - if (hours < 24) return `${hours}h ago`; - if (days < 7) return `${days}d ago`; + if (dateFormat === "relative") { + const diff = now.getTime() - d.getTime(); + const minutes = Math.floor(diff / 60000); + const hours = Math.floor(diff / 3600000); + const days = Math.floor(diff / 86400000); + if (minutes < 1) return "Just now"; + if (minutes < 60) return `${minutes}m ago`; + if (hours < 24) return `${hours}h ago`; + if (days < 7) return `${days}d ago`; + return d.toLocaleDateString(intlLocale, { + month: "short", + day: "numeric", + year: d.getFullYear() !== now.getFullYear() ? "numeric" : undefined, + }); + } - return d.toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: d.getFullYear() !== now.getFullYear() ? "numeric" : undefined, + if (dateFormat === "full") { + return d.toLocaleString(intlLocale, { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + hour12, + }); + } + + // 'smart' (default) + const timeStr = d.toLocaleTimeString(intlLocale, { + hour: "2-digit", + minute: "2-digit", + hour12, + }); + + const isSameDay = + d.getFullYear() === now.getFullYear() && + d.getMonth() === now.getMonth() && + d.getDate() === now.getDate(); + if (isSameDay) return timeStr; + + const daysAgo = Math.floor((now.getTime() - d.getTime()) / 86400000); + if (daysAgo < 7) { + // German Intl outputs "Fr." with a trailing dot for `weekday: 'short'`; + // strip it so the result reads cleanly next to the time. + const weekday = d + .toLocaleDateString(intlLocale, { weekday: "short" }) + .replace(/\.$/, ""); + return `${weekday} ${timeStr}`; + } + + return d.toLocaleDateString(intlLocale, { + year: "numeric", + month: "2-digit", + day: "2-digit", }); } diff --git a/locales/cs/common.json b/locales/cs/common.json index ba4801a0..833f774a 100644 --- a/locales/cs/common.json +++ b/locales/cs/common.json @@ -752,7 +752,7 @@ "keep_editing": "Pokračovat v úpravách", "tabs": { "appearance": "Vzhled", - "language": "Jazyk a region", + "language": "Jazyk, region a čas", "email": "Chování e-mailu", "composer": "Psaní zpráv", "privacy": "Soukromí a bezpečnost", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Jazyk a region", - "description": "Nakonfigurujte jazykové a místní předvolby", + "title": "Jazyk, region a čas", + "description": "Jazyk, formát data, formát času a další regionální předvolby", "language": { "label": "Jazyk", "description": "Vyberte preferovaný jazyk", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Formát data", - "description": "Jak se mají zobrazovat data", - "regional": "Místní", - "iso": "ISO 8601", - "custom": "Vlastní" + "description": "Jak se zobrazují data v seznamu e-mailů", + "smart": "Chytrý (regionální)", + "relative": "Relativní (před 1 h, před 2 d)", + "full": "Vždy úplné datum", + "preview_today": "Dnes:", + "preview_this_week": "Tento týden:", + "preview_older": "Starší:" }, "time_format": { "label": "Formát času", diff --git a/locales/da/common.json b/locales/da/common.json index 12e51df1..ba1aba8a 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -755,7 +755,7 @@ "search_no_results": "Ingen match i indstillinger", "tabs": { "appearance": "Udseende", - "language": "Sprog & region", + "language": "Sprog, region & tid", "email": "E-mail-adfærd", "composer": "Komponist", "privacy": "Privatliv & sikkerhed", @@ -935,8 +935,8 @@ } }, "language_region": { - "title": "Sprog & region", - "description": "Konfigurér sprog og regionale præferencer", + "title": "Sprog, region & tid", + "description": "Sprog, datoformat, tidsformat og andre regionale indstillinger", "language": { "label": "Sprog", "description": "Vælg dit foretrukne sprog", @@ -945,10 +945,13 @@ }, "date_format": { "label": "Datoformat", - "description": "Hvordan datoer skal vises", - "regional": "Regionalt", - "iso": "ISO 8601", - "custom": "Brugerdefineret" + "description": "Sådan vises datoer på e-mail-listen", + "smart": "Smart (regionalt)", + "relative": "Relativ (for 1 t siden, for 2 d siden)", + "full": "Altid fuld dato", + "preview_today": "I dag:", + "preview_this_week": "Denne uge:", + "preview_older": "Ældre:" }, "time_format": { "label": "Tidsformat", diff --git a/locales/de/common.json b/locales/de/common.json index e834e9a7..eb9a913f 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -752,7 +752,7 @@ "keep_editing": "Weiter bearbeiten", "tabs": { "appearance": "Darstellung", - "language": "Sprache & Region", + "language": "Sprache, Region & Zeit", "email": "E-Mail-Verhalten", "composer": "Editor", "privacy": "Datenschutz & Sicherheit", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Sprache & Region", - "description": "Konfigurieren Sie Sprach- und Regionaleinstellungen", + "title": "Sprache, Region & Zeit", + "description": "Sprache, Datums- und Zeitformat sowie weitere regionale Einstellungen", "language": { "label": "Sprache", "description": "Wählen Sie Ihre bevorzugte Sprache", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Datumsformat", - "description": "Wie Daten angezeigt werden sollen", - "regional": "Regional", - "iso": "ISO 8601", - "custom": "Benutzerdefiniert" + "description": "Wie Daten in der E-Mail-Liste angezeigt werden", + "smart": "Intelligent (gebietsschemaabhängig)", + "relative": "Relativ (vor 1 Std., vor 2 Tagen)", + "full": "Immer vollständiges Datum", + "preview_today": "Heute:", + "preview_this_week": "Diese Woche:", + "preview_older": "Älter:" }, "time_format": { "label": "Zeitformat", diff --git a/locales/en/common.json b/locales/en/common.json index d916c100..072169df 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -755,7 +755,7 @@ "search_no_results": "No matching settings", "tabs": { "appearance": "Appearance", - "language": "Language & Region", + "language": "Language, Region & Time", "email": "Email Behavior", "composer": "Composer", "privacy": "Privacy & Security", @@ -935,8 +935,8 @@ } }, "language_region": { - "title": "Language & Region", - "description": "Configure language and regional preferences", + "title": "Language, Region & Time", + "description": "Language, date format, time format, and other regional preferences", "language": { "label": "Language", "description": "Choose your preferred language", @@ -945,10 +945,13 @@ }, "date_format": { "label": "Date Format", - "description": "How dates should be displayed", - "regional": "Regional", - "iso": "ISO 8601", - "custom": "Custom" + "description": "How dates are shown in the email list", + "smart": "Smart (locale-aware)", + "relative": "Relative (1h ago, 2d ago)", + "full": "Always full date", + "preview_today": "Today:", + "preview_this_week": "This week:", + "preview_older": "Older:" }, "time_format": { "label": "Time Format", diff --git a/locales/es/common.json b/locales/es/common.json index 950a5e37..60687c16 100644 --- a/locales/es/common.json +++ b/locales/es/common.json @@ -752,7 +752,7 @@ "keep_editing": "Seguir editando", "tabs": { "appearance": "Apariencia", - "language": "Idioma y Región", + "language": "Idioma, Región y Hora", "email": "Comportamiento del Correo", "composer": "Editor", "privacy": "Privacidad y Seguridad", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Idioma y Región", - "description": "Configure las preferencias de idioma y región", + "title": "Idioma, Región y Hora", + "description": "Idioma, formato de fecha, formato de hora y otras preferencias regionales", "language": { "label": "Idioma", "description": "Elija su idioma preferido", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Formato de Fecha", - "description": "Cómo se deben mostrar las fechas", - "regional": "Regional", - "iso": "ISO 8601", - "custom": "Personalizado" + "description": "Cómo se muestran las fechas en la lista de correos", + "smart": "Inteligente (según región)", + "relative": "Relativo (hace 1 h, hace 2 d)", + "full": "Fecha completa siempre", + "preview_today": "Hoy:", + "preview_this_week": "Esta semana:", + "preview_older": "Más antiguo:" }, "time_format": { "label": "Formato de Hora", diff --git a/locales/fr/common.json b/locales/fr/common.json index f3c7067d..41ca1cf0 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -752,7 +752,7 @@ "keep_editing": "Continuer l'édition", "tabs": { "appearance": "Apparence", - "language": "Langue et région", + "language": "Langue, région et heure", "email": "Comportement email", "composer": "Compositeur", "privacy": "Confidentialité et sécurité", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Langue et région", - "description": "Configurez vos préférences linguistiques et régionales", + "title": "Langue, région et heure", + "description": "Langue, format de date, format d'heure et autres préférences régionales", "language": { "label": "Langue", "description": "Choisissez votre langue préférée", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Format de date", - "description": "Comment les dates doivent être affichées", - "regional": "Régional", - "iso": "ISO 8601", - "custom": "Personnalisé" + "description": "Comment les dates apparaissent dans la liste des e-mails", + "smart": "Intelligent (adapté à la région)", + "relative": "Relatif (il y a 1 h, il y a 2 j)", + "full": "Toujours la date complète", + "preview_today": "Aujourd'hui :", + "preview_this_week": "Cette semaine :", + "preview_older": "Plus ancien :" }, "time_format": { "label": "Format d'heure", diff --git a/locales/it/common.json b/locales/it/common.json index 7723fe38..e7a0d7e5 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -752,7 +752,7 @@ "keep_editing": "Continua a modificare", "tabs": { "appearance": "Aspetto", - "language": "Lingua e regione", + "language": "Lingua, regione e ora", "email": "Comportamento email", "composer": "Editor", "privacy": "Privacy e sicurezza", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Lingua e regione", - "description": "Configura le preferenze di lingua e regionali", + "title": "Lingua, regione e ora", + "description": "Lingua, formato data, formato ora e altre preferenze regionali", "language": { "label": "Lingua", "description": "Scegli la tua lingua preferita", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Formato data", - "description": "Come devono essere visualizzate le date", - "regional": "Regionale", - "iso": "ISO 8601", - "custom": "Personalizzato" + "description": "Come vengono visualizzate le date nell'elenco delle e-mail", + "smart": "Intelligente (in base alla regione)", + "relative": "Relativo (1 h fa, 2 g fa)", + "full": "Sempre data completa", + "preview_today": "Oggi:", + "preview_this_week": "Questa settimana:", + "preview_older": "Più vecchio:" }, "time_format": { "label": "Formato ora", diff --git a/locales/ja/common.json b/locales/ja/common.json index 8f37e703..85ecd13b 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -752,7 +752,7 @@ "keep_editing": "編集を続ける", "tabs": { "appearance": "外観", - "language": "言語と地域", + "language": "言語、地域、時刻", "email": "メール動作", "composer": "作成", "privacy": "プライバシーとセキュリティ", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "言語と地域", - "description": "言語と地域の設定を構成", + "title": "言語、地域、時刻", + "description": "言語、日付形式、時刻形式、その他の地域設定", "language": { "label": "言語", "description": "お好みの言語を選択", @@ -942,10 +942,13 @@ }, "date_format": { "label": "日付形式", - "description": "日付の表示形式", - "regional": "地域設定", - "iso": "ISO 8601", - "custom": "カスタム" + "description": "メール一覧での日付の表示方法", + "smart": "スマート(地域に合わせる)", + "relative": "相対表示(1時間前、2日前)", + "full": "常に完全な日付", + "preview_today": "今日:", + "preview_this_week": "今週:", + "preview_older": "それ以前:" }, "time_format": { "label": "時刻形式", diff --git a/locales/ko/common.json b/locales/ko/common.json index 722fbf06..5b34dd9a 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -752,7 +752,7 @@ "keep_editing": "계속 수정하기", "tabs": { "appearance": "화면 설정", - "language": "언어 및 지역", + "language": "언어, 지역 및 시간", "email": "메일 동작", "composer": "메일 쓰기", "privacy": "개인정보 및 보안", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "언어 및 지역", - "description": "언어와 지역 형식을 설정해 주세요", + "title": "언어, 지역 및 시간", + "description": "언어, 날짜 형식, 시간 형식 및 기타 지역 환경설정", "language": { "label": "언어", "description": "사용할 언어를 선택해 주세요", @@ -942,10 +942,13 @@ }, "date_format": { "label": "날짜 형식", - "description": "날짜가 표시되는 방식을 설정해요", - "regional": "지역 설정", - "iso": "ISO 8601", - "custom": "사용자 지정" + "description": "이메일 목록에 날짜가 표시되는 방식", + "smart": "스마트 (지역에 맞춤)", + "relative": "상대 시간 (1시간 전, 2일 전)", + "full": "항상 전체 날짜", + "preview_today": "오늘:", + "preview_this_week": "이번 주:", + "preview_older": "이전:" }, "time_format": { "label": "시간 형식", diff --git a/locales/lv/common.json b/locales/lv/common.json index 7c4311a2..eb405b2f 100644 --- a/locales/lv/common.json +++ b/locales/lv/common.json @@ -752,7 +752,7 @@ "keep_editing": "Turpināt rediģēšanu", "tabs": { "appearance": "Izskats", - "language": "Valoda un reģions", + "language": "Valoda, reģions un laiks", "email": "Pasta darbība", "composer": "Redaktors", "privacy": "Privātums un drošība", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Valoda un reģions", - "description": "Iestatiet valodas un reģionālās preferences", + "title": "Valoda, reģions un laiks", + "description": "Valoda, datuma formāts, laika formāts un citas reģionālās preferences", "language": { "label": "Valoda", "description": "Izvēlieties vēlamo valodu", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Datuma formāts", - "description": "Kā attēlot datumus", - "regional": "Reģionālais", - "iso": "ISO 8601", - "custom": "Pielāgots" + "description": "Kā datumi tiek attēloti e-pasta sarakstā", + "smart": "Gudrs (atbilstoši reģionam)", + "relative": "Relatīvs (pirms 1 st., pirms 2 d.)", + "full": "Vienmēr pilns datums", + "preview_today": "Šodien:", + "preview_this_week": "Šajā nedēļā:", + "preview_older": "Vecāks:" }, "time_format": { "label": "Laika formāts", diff --git a/locales/nl/common.json b/locales/nl/common.json index ea6ad7db..65397108 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -752,7 +752,7 @@ "keep_editing": "Doorgaan met bewerken", "tabs": { "appearance": "Uiterlijk", - "language": "Taal & Regio", + "language": "Taal, Regio & Tijd", "email": "E-mailgedrag", "composer": "Opstellen", "privacy": "Privacy & Beveiliging", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Taal & Regio", - "description": "Configureer taal- en regiovoorkeuren", + "title": "Taal, Regio & Tijd", + "description": "Taal, datumnotatie, tijdnotatie en andere regionale voorkeuren", "language": { "label": "Taal", "description": "Kies je voorkeurstaal", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Datumnotatie", - "description": "Hoe datums moeten worden weergegeven", - "regional": "Regionaal", - "iso": "ISO 8601", - "custom": "Aangepast" + "description": "Hoe datums worden weergegeven in de e-maillijst", + "smart": "Slim (regionaal)", + "relative": "Relatief (1 u geleden, 2 d geleden)", + "full": "Altijd volledige datum", + "preview_today": "Vandaag:", + "preview_this_week": "Deze week:", + "preview_older": "Ouder:" }, "time_format": { "label": "Tijdnotatie", diff --git a/locales/pl/common.json b/locales/pl/common.json index 2ff0dc34..151c4a06 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -752,7 +752,7 @@ "keep_editing": "Kontynuuj edycję", "tabs": { "appearance": "Wygląd", - "language": "Język i region", + "language": "Język, region i czas", "email": "Zachowanie poczty e-mail", "composer": "Redagowanie", "privacy": "Prywatność i bezpieczeństwo", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Język i region", - "description": "Skonfiguruj preferencje językowe i regionalne", + "title": "Język, region i czas", + "description": "Język, format daty, format godziny i inne preferencje regionalne", "language": { "label": "Język", "description": "Wybierz preferowany język", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Format daty", - "description": "Jak mają być wyświetlane daty", - "regional": "Regionalny", - "iso": "ISO 8601", - "custom": "Niestandardowy" + "description": "Jak daty są wyświetlane na liście e-maili", + "smart": "Inteligentny (regionalny)", + "relative": "Względny (1 g temu, 2 d temu)", + "full": "Zawsze pełna data", + "preview_today": "Dzisiaj:", + "preview_this_week": "W tym tygodniu:", + "preview_older": "Starsze:" }, "time_format": { "label": "Format czasu", diff --git a/locales/pt/common.json b/locales/pt/common.json index 489605fe..a6ce3596 100644 --- a/locales/pt/common.json +++ b/locales/pt/common.json @@ -752,7 +752,7 @@ "keep_editing": "Continuar editando", "tabs": { "appearance": "Aparência", - "language": "Idioma e Região", + "language": "Idioma, Região e Hora", "email": "Comportamento de E-mail", "composer": "Editor", "privacy": "Privacidade e Segurança", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Idioma e Região", - "description": "Configure preferências de idioma e região", + "title": "Idioma, Região e Hora", + "description": "Idioma, formato de data, formato de hora e outras preferências regionais", "language": { "label": "Idioma", "description": "Escolha seu idioma preferido", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Formato de Data", - "description": "Como as datas devem ser exibidas", - "regional": "Regional", - "iso": "ISO 8601", - "custom": "Personalizado" + "description": "Como as datas são mostradas na lista de e-mails", + "smart": "Inteligente (regional)", + "relative": "Relativo (há 1 h, há 2 d)", + "full": "Sempre data completa", + "preview_today": "Hoje:", + "preview_this_week": "Esta semana:", + "preview_older": "Mais antigo:" }, "time_format": { "label": "Formato de Hora", diff --git a/locales/ru/common.json b/locales/ru/common.json index da8e624b..45e2de45 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -752,7 +752,7 @@ "keep_editing": "Продолжить редактирование", "tabs": { "appearance": "Внешний вид", - "language": "Язык и регион", + "language": "Язык, регион и время", "email": "Поведение почты", "composer": "Редактор", "privacy": "Конфиденциальность и безопасность", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Язык и регион", - "description": "Настройте языковые и региональные предпочтения", + "title": "Язык, регион и время", + "description": "Язык, формат даты, формат времени и другие региональные настройки", "language": { "label": "Язык", "description": "Выберите предпочтительный язык", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Формат даты", - "description": "Как отображать даты", - "regional": "Региональный", - "iso": "ISO 8601", - "custom": "Пользовательский" + "description": "Как отображаются даты в списке писем", + "smart": "Умный (по региону)", + "relative": "Относительный (1 ч назад, 2 д назад)", + "full": "Всегда полная дата", + "preview_today": "Сегодня:", + "preview_this_week": "На этой неделе:", + "preview_older": "Старее:" }, "time_format": { "label": "Формат времени", diff --git a/locales/tr/common.json b/locales/tr/common.json index c9e6648a..7d2f5037 100644 --- a/locales/tr/common.json +++ b/locales/tr/common.json @@ -752,7 +752,7 @@ "keep_editing": "Düzenlemeye devam et", "tabs": { "appearance": "Görünüm", - "language": "Dil ve Bölge", + "language": "Dil, Bölge ve Saat", "email": "E-posta Davranışı", "composer": "Yazıcı", "privacy": "Gizlilik ve Güvenlik", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Dil ve Bölge", - "description": "Dil ve bölgesel tercihleri yapılandırın", + "title": "Dil, Bölge ve Saat", + "description": "Dil, tarih biçimi, saat biçimi ve diğer bölgesel tercihler", "language": { "label": "Dil", "description": "Tercih ettiğiniz dili seçin", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Tarih Biçimi", - "description": "Tarihlerin nasıl görüntüleneceği", - "regional": "Bölgesel", - "iso": "ISO 8601", - "custom": "Özel" + "description": "Tarihlerin e-posta listesinde nasıl gösterileceği", + "smart": "Akıllı (bölgeye duyarlı)", + "relative": "Göreceli (1 sa önce, 2 g önce)", + "full": "Her zaman tam tarih", + "preview_today": "Bugün:", + "preview_this_week": "Bu hafta:", + "preview_older": "Daha eski:" }, "time_format": { "label": "Saat Biçimi", diff --git a/locales/uk/common.json b/locales/uk/common.json index 54bc2ec1..fd1a458d 100644 --- a/locales/uk/common.json +++ b/locales/uk/common.json @@ -752,7 +752,7 @@ "keep_editing": "Продовжуйте редагувати", "tabs": { "appearance": "Зовнішній вигляд", - "language": "Мова та регіон", + "language": "Мова, регіон і час", "email": "Поведінка електронної пошти", "composer": "Композитор", "privacy": "Конфіденційність і безпека", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "Мова та регіон", - "description": "Налаштуйте мовні та регіональні параметри", + "title": "Мова, регіон і час", + "description": "Мова, формат дати, формат часу та інші регіональні налаштування", "language": { "label": "Мова", "description": "Виберіть бажану мову", @@ -942,10 +942,13 @@ }, "date_format": { "label": "Формат дати", - "description": "Як мають відображатися дати", - "regional": "Регіональний", - "iso": "ISO 8601", - "custom": "Довільний" + "description": "Як відображаються дати у списку листів", + "smart": "Розумний (за регіоном)", + "relative": "Відносний (1 год тому, 2 дн тому)", + "full": "Завжди повна дата", + "preview_today": "Сьогодні:", + "preview_this_week": "Цього тижня:", + "preview_older": "Старіше:" }, "time_format": { "label": "Формат часу", diff --git a/locales/zh/common.json b/locales/zh/common.json index 2be4f21e..3de1074e 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -752,7 +752,7 @@ "keep_editing": "继续编辑", "tabs": { "appearance": "外观", - "language": "语言及地区", + "language": "语言、地区与时间", "email": "邮件行为", "composer": "邮件撰写", "privacy": "隐私与安全", @@ -932,8 +932,8 @@ } }, "language_region": { - "title": "语言及地区", - "description": "配置语言和区域首选项", + "title": "语言、地区与时间", + "description": "语言、日期格式、时间格式以及其他区域设置", "language": { "label": "语言", "description": "选择您的首选语言", @@ -942,10 +942,13 @@ }, "date_format": { "label": "日期格式", - "description": "日期应如何显示", - "regional": "区域格式", - "iso": "ISO 8601", - "custom": "自定义" + "description": "电子邮件列表中日期的显示方式", + "smart": "智能(按地区)", + "relative": "相对时间(1 小时前、2 天前)", + "full": "始终完整日期", + "preview_today": "今天:", + "preview_this_week": "本周:", + "preview_older": "更早:" }, "time_format": { "label": "时间格式", diff --git a/stores/settings-store.ts b/stores/settings-store.ts index a93ab891..08bc4a05 100644 --- a/stores/settings-store.ts +++ b/stores/settings-store.ts @@ -31,7 +31,7 @@ export type ListDensity = Density; export type DeleteAction = 'trash' | 'trash-and-read' | 'permanent'; export type ReplyMode = 'reply' | 'replyAll'; export type SignaturePosition = 'above_quote' | 'below_quote'; -export type DateFormat = 'regional' | 'iso' | 'custom'; +export type DateFormat = 'smart' | 'relative' | 'full'; export type TimeFormat = '12h' | '24h'; export type FirstDayOfWeek = 0 | 1; // 0 = Sunday, 1 = Monday export type ExternalContentPolicy = 'ask' | 'block' | 'allow'; @@ -300,7 +300,7 @@ const DEFAULT_SETTINGS = { animationsEnabled: true, // Language & Region - dateFormat: 'regional' as DateFormat, + dateFormat: 'smart' as DateFormat, timeFormat: '24h' as TimeFormat, firstDayOfWeek: 1 as FirstDayOfWeek, // Monday @@ -760,7 +760,7 @@ export const useSettingsStore = create()( }), { name: 'settings-storage', - version: 3, + version: 4, migrate: (persisted, version) => { const state = persisted as Record; if (version < 2 && state.listDensity) { @@ -771,6 +771,12 @@ export const useSettingsStore = create()( state.protocolOpenMode = state.protocolMailtoOpenMode; } delete state.protocolMailtoOpenMode; + // v4: `dateFormat` was repurposed from 'regional'|'iso'|'custom' to + // 'smart'|'relative'|'full'. The old setting was never read anywhere, + // so every persisted value maps to the new default. + if (version < 4) { + state.dateFormat = 'smart'; + } return state as unknown as SettingsState; }, onRehydrateStorage: () => {