From 7445dad0dd5fcffdc3fbeb7f8788f9b1c8942417 Mon Sep 17 00:00:00 2001 From: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Date: Mon, 29 Jul 2024 16:42:55 +0200 Subject: [PATCH] fix(web): timeline group date formatting (#11392) * fix(web): timeline group date formatting * add isValid check * remove duplicate type --- web/src/lib/utils/timeline-util.spec.ts | 49 +++++++++++++++++++++++++ web/src/lib/utils/timeline-util.ts | 16 +++++--- 2 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 web/src/lib/utils/timeline-util.spec.ts diff --git a/web/src/lib/utils/timeline-util.spec.ts b/web/src/lib/utils/timeline-util.spec.ts new file mode 100644 index 0000000000..863b6e613a --- /dev/null +++ b/web/src/lib/utils/timeline-util.spec.ts @@ -0,0 +1,49 @@ +import { formatGroupTitle } from '$lib/utils/timeline-util'; +import { DateTime } from 'luxon'; + +describe('formatGroupTitle', () => { + beforeAll(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date('2024-07-27T12:00:00Z')); + }); + + afterAll(() => { + vi.useRealTimers(); + }); + + it('formats today', () => { + const date = DateTime.fromISO('2024-07-27T01:00:00Z'); + expect(formatGroupTitle(date.setLocale('en'))).toBe('today'); + expect(formatGroupTitle(date.setLocale('es'))).toBe('hoy'); + }); + + it('formats yesterday', () => { + const date = DateTime.fromISO('2024-07-26T23:59:59Z'); + expect(formatGroupTitle(date.setLocale('en'))).toBe('yesterday'); + expect(formatGroupTitle(date.setLocale('fr'))).toBe('hier'); + }); + + it('formats last week', () => { + const date = DateTime.fromISO('2024-07-21T00:00:00Z'); + expect(formatGroupTitle(date.setLocale('en'))).toBe('Sunday'); + expect(formatGroupTitle(date.setLocale('ar-SA'))).toBe('الأحد'); + }); + + it('formats date 7 days ago', () => { + const date = DateTime.fromISO('2024-07-20T00:00:00Z'); + expect(formatGroupTitle(date.setLocale('en'))).toBe('Sat, Jul 20'); + expect(formatGroupTitle(date.setLocale('de'))).toBe('Sa., 20. Juli'); + }); + + it('formats date this year', () => { + const date = DateTime.fromISO('2020-01-01T00:00:00Z'); + expect(formatGroupTitle(date.setLocale('en'))).toBe('Wed, Jan 1, 2020'); + expect(formatGroupTitle(date.setLocale('ja'))).toBe('2020年1月1日(水)'); + }); + + it('returns "Invalid DateTime" when date is invalid', () => { + const date = DateTime.invalid('test'); + expect(formatGroupTitle(date.setLocale('en'))).toBe('Invalid DateTime'); + expect(formatGroupTitle(date.setLocale('es'))).toBe('Invalid DateTime'); + }); +}); diff --git a/web/src/lib/utils/timeline-util.ts b/web/src/lib/utils/timeline-util.ts index 83756a4064..fe5f799bc3 100644 --- a/web/src/lib/utils/timeline-util.ts +++ b/web/src/lib/utils/timeline-util.ts @@ -1,7 +1,7 @@ import { locale } from '$lib/stores/preferences.store'; import type { AssetResponseDto } from '@immich/sdk'; import { groupBy, sortBy } from 'lodash-es'; -import { DateTime, Interval } from 'luxon'; +import { DateTime } from 'luxon'; import { get } from 'svelte/store'; export const fromLocalDateTime = (localDateTime: string) => @@ -14,21 +14,25 @@ export const groupDateFormat: Intl.DateTimeFormatOptions = { year: 'numeric', }; -export function formatGroupTitle(date: DateTime): string { +export function formatGroupTitle(_date: DateTime): string { + if (!_date.isValid) { + return _date.toString(); + } + const date = _date as DateTime; const today = DateTime.now().startOf('day'); // Today if (today.hasSame(date, 'day')) { - return 'Today'; + return date.toRelativeCalendar(); } // Yesterday - if (Interval.fromDateTimes(date, today).length('days') == 1) { - return 'Yesterday'; + if (today.minus({ days: 1 }).hasSame(date, 'day')) { + return date.toRelativeCalendar(); } // Last week - if (Interval.fromDateTimes(date, today).length('weeks') < 1) { + if (date >= today.minus({ days: 6 })) { return date.toLocaleString({ weekday: 'long' }); }