fix(time): use Intl numeric day-month-year everywhere so chat day dividers follow the system locale instead of hardcoded English full-month
This commit is contained in:
parent
2dac76f9af
commit
f5e992daad
4 changed files with 21 additions and 12 deletions
|
|
@ -7,7 +7,7 @@ import { getMemberDisplayName, getStateEvent } from '../../utils/room';
|
||||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||||
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||||
import { timeDayMonthYear, timeHourMinute } from '../../utils/time';
|
import { timeDayMonYear, timeHourMinute } from '../../utils/time';
|
||||||
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
||||||
import { RoomAvatar } from '../room-avatar';
|
import { RoomAvatar } from '../room-avatar';
|
||||||
import { nameInitials } from '../../utils/common';
|
import { nameInitials } from '../../utils/common';
|
||||||
|
|
@ -75,7 +75,7 @@ export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) =>
|
||||||
i18nKey="Room.created_by"
|
i18nKey="Room.created_by"
|
||||||
values={{
|
values={{
|
||||||
creator: creatorName,
|
creator: creatorName,
|
||||||
date: timeDayMonthYear(ts),
|
date: timeDayMonYear(ts),
|
||||||
time: timeHourMinute(ts),
|
time: timeHourMinute(ts),
|
||||||
}}
|
}}
|
||||||
components={{ bold: <b /> }}
|
components={{ bold: <b /> }}
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ import { markAsRead } from '../../utils/notifications';
|
||||||
import { useDebounce } from '../../hooks/useDebounce';
|
import { useDebounce } from '../../hooks/useDebounce';
|
||||||
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
|
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
|
||||||
import * as css from './RoomTimeline.css';
|
import * as css from './RoomTimeline.css';
|
||||||
import { inSameDay, minuteDifference, timeDayMonthYear, today, yesterday } from '../../utils/time';
|
import { inSameDay, minuteDifference, timeDayMonYear, today, yesterday } from '../../utils/time';
|
||||||
import { isEmptyEditor } from '../../components/editor';
|
import { isEmptyEditor } from '../../components/editor';
|
||||||
import { draftKey, roomIdToReplyDraftAtomFamily } from '../../state/room/roomInputDrafts';
|
import { draftKey, roomIdToReplyDraftAtomFamily } from '../../state/room/roomInputDrafts';
|
||||||
import { usePowerLevelsContext } from '../../hooks/usePowerLevels';
|
import { usePowerLevelsContext } from '../../hooks/usePowerLevels';
|
||||||
|
|
@ -2211,7 +2211,7 @@ export function RoomTimeline({
|
||||||
const dayLabel = (() => {
|
const dayLabel = (() => {
|
||||||
if (today(mEvent.getTs())) return t('Room.today');
|
if (today(mEvent.getTs())) return t('Room.today');
|
||||||
if (yesterday(mEvent.getTs())) return t('Room.yesterday');
|
if (yesterday(mEvent.getTs())) return t('Room.yesterday');
|
||||||
return timeDayMonthYear(mEvent.getTs());
|
return timeDayMonYear(mEvent.getTs());
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const renderDayDivider = () => (
|
const renderDayDivider = () => (
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import { useAlive } from '../../../hooks/useAlive';
|
||||||
import { useStateEvent } from '../../../hooks/useStateEvent';
|
import { useStateEvent } from '../../../hooks/useStateEvent';
|
||||||
import { useRoom } from '../../../hooks/useRoom';
|
import { useRoom } from '../../../hooks/useRoom';
|
||||||
import { StateEvent } from '../../../../types/matrix/room';
|
import { StateEvent } from '../../../../types/matrix/room';
|
||||||
import { getToday, getYesterday, timeDayMonthYear, timeHourMinute } from '../../../utils/time';
|
import { getToday, getYesterday, timeDayMonYear, timeHourMinute } from '../../../utils/time';
|
||||||
import { DatePicker, TimePicker } from '../../../components/time-date';
|
import { DatePicker, TimePicker } from '../../../components/time-date';
|
||||||
|
|
||||||
type JumpToTimeProps = {
|
type JumpToTimeProps = {
|
||||||
|
|
@ -168,7 +168,7 @@ export function JumpToTime({ onCancel, onSubmit }: JumpToTimeProps) {
|
||||||
after={<Icon size="50" src={Icons.ChevronBottom} />}
|
after={<Icon size="50" src={Icons.ChevronBottom} />}
|
||||||
onClick={handleDatePicker}
|
onClick={handleDatePicker}
|
||||||
>
|
>
|
||||||
<Text size="B300">{timeDayMonthYear(ts)}</Text>
|
<Text size="B300">{timeDayMonYear(ts)}</Text>
|
||||||
</Chip>
|
</Chip>
|
||||||
<PopOut
|
<PopOut
|
||||||
anchor={datePickerCords}
|
anchor={datePickerCords}
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,20 @@ const detectSystemHour24 = (): boolean => {
|
||||||
|
|
||||||
export const SYSTEM_HOUR_24: boolean = detectSystemHour24();
|
export const SYSTEM_HOUR_24: boolean = detectSystemHour24();
|
||||||
|
|
||||||
// 24-hour systems get the European day-month-year layout; 12-hour systems get
|
// Locale picks its own day-month-year order and separator: de-DE/ru-RU yield
|
||||||
// the American month-day-year layout.
|
// "13.05.2026", en-GB "13/05/2026", en-US "05/13/2026". Built once at module
|
||||||
const SYSTEM_DAY_MON_YEAR_FORMAT = SYSTEM_HOUR_24 ? 'DD/MM/YYYY' : 'MM/DD/YYYY';
|
// load — locale doesn't change without a page reload.
|
||||||
|
const dayMonYearFormatter: Pick<Intl.DateTimeFormat, 'format'> = (() => {
|
||||||
|
try {
|
||||||
|
return new Intl.DateTimeFormat(undefined, {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return { format: (date: Date) => dayjs(date).format('DD.MM.YYYY') };
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
export const today = (ts: number): boolean => dayjs(ts).isToday();
|
export const today = (ts: number): boolean => dayjs(ts).isToday();
|
||||||
|
|
||||||
|
|
@ -45,9 +56,7 @@ export const timeYear = (ts: number): string => dayjs(ts).format('YYYY');
|
||||||
export const timeHourMinute = (ts: number): string =>
|
export const timeHourMinute = (ts: number): string =>
|
||||||
dayjs(ts).format(SYSTEM_HOUR_24 ? 'HH:mm' : 'hh:mm A');
|
dayjs(ts).format(SYSTEM_HOUR_24 ? 'HH:mm' : 'hh:mm A');
|
||||||
|
|
||||||
export const timeDayMonYear = (ts: number): string => dayjs(ts).format(SYSTEM_DAY_MON_YEAR_FORMAT);
|
export const timeDayMonYear = (ts: number): string => dayMonYearFormatter.format(new Date(ts));
|
||||||
|
|
||||||
export const timeDayMonthYear = (ts: number): string => dayjs(ts).format('D MMMM YYYY');
|
|
||||||
|
|
||||||
export const daysInMonth = (month: number, year: number): number =>
|
export const daysInMonth = (month: number, year: number): number =>
|
||||||
dayjs(`${year}-${month}-1`).daysInMonth();
|
dayjs(`${year}-${month}-1`).daysInMonth();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue