fix(web): timezone handling in search filter (#7384)

This commit is contained in:
Michel Heusschen 2024-02-24 21:23:30 +01:00 committed by GitHub
parent 57758293e5
commit 6ec4c5874b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 29 additions and 27 deletions

View File

@ -3,7 +3,7 @@
import Icon from '$lib/components/elements/icon.svelte'; import Icon from '$lib/components/elements/icon.svelte';
import { ProjectionType } from '$lib/constants'; import { ProjectionType } from '$lib/constants';
import { getAssetFileUrl, getAssetThumbnailUrl, isSharedLink } from '$lib/utils'; import { getAssetFileUrl, getAssetThumbnailUrl, isSharedLink } from '$lib/utils';
import { timeToSeconds } from '$lib/utils/time-to-seconds'; import { timeToSeconds } from '$lib/utils/date-time';
import { AssetTypeEnum, ThumbnailFormat, type AssetResponseDto } from '@immich/sdk'; import { AssetTypeEnum, ThumbnailFormat, type AssetResponseDto } from '@immich/sdk';
import { import {
mdiArchiveArrowDownOutline, mdiArchiveArrowDownOutline,

View File

@ -16,7 +16,7 @@
import { createEventDispatcher, onMount } from 'svelte'; import { createEventDispatcher, onMount } from 'svelte';
import { fly } from 'svelte/transition'; import { fly } from 'svelte/transition';
import Combobox, { type ComboBoxOption } from '../combobox.svelte'; import Combobox, { type ComboBoxOption } from '../combobox.svelte';
import { DateTime } from 'luxon'; import { parseUtcDate } from '$lib/utils/date-time';
enum MediaType { enum MediaType {
All = 'all', All = 'all',
@ -231,6 +231,9 @@
}; };
}; };
const parseOptionalDate = (dateString?: string) => (dateString ? parseUtcDate(dateString) : undefined);
const toStartOfDayDate = (dateString: string) => parseUtcDate(dateString)?.startOf('day').toISODate() || undefined;
const search = async () => { const search = async () => {
let type: AssetTypeEnum | undefined = undefined; let type: AssetTypeEnum | undefined = undefined;
@ -246,16 +249,11 @@
city: filter.location.city?.value, city: filter.location.city?.value,
make: filter.camera.make?.value, make: filter.camera.make?.value,
model: filter.camera.model?.value, model: filter.camera.model?.value,
takenAfter: filter.date.takenAfter takenAfter: parseOptionalDate(filter.date.takenAfter)?.startOf('day').toISO() || undefined,
? DateTime.fromFormat(filter.date.takenAfter, 'yyyy-MM-dd').toUTC().startOf('day').toString() takenBefore: parseOptionalDate(filter.date.takenBefore)?.endOf('day').toISO() || undefined,
: undefined, isArchived: filter.isArchive || undefined,
takenBefore: filter.date.takenBefore isFavorite: filter.isFavorite || undefined,
? DateTime.fromFormat(filter.date.takenBefore, 'yyyy-MM-dd').toUTC().endOf('day').toString() isNotInAlbum: filter.isNotInAlbum || undefined,
: undefined,
/* eslint-disable unicorn/prefer-logical-operator-over-ternary */
isArchived: filter.isArchive ? filter.isArchive : undefined,
isFavorite: filter.isFavorite ? filter.isFavorite : undefined,
isNotInAlbum: filter.isNotInAlbum ? filter.isNotInAlbum : undefined,
personIds: filter.people && filter.people.length > 0 ? filter.people.map((p) => p.id) : undefined, personIds: filter.people && filter.people.length > 0 ? filter.people.map((p) => p.id) : undefined,
type, type,
}; };
@ -295,12 +293,8 @@
model: searchQuery.model ? { label: searchQuery.model, value: searchQuery.model } : undefined, model: searchQuery.model ? { label: searchQuery.model, value: searchQuery.model } : undefined,
}, },
date: { date: {
takenAfter: searchQuery.takenAfter takenAfter: searchQuery.takenAfter ? toStartOfDayDate(searchQuery.takenAfter) : undefined,
? DateTime.fromISO(searchQuery.takenAfter).toUTC().toFormat('yyyy-MM-dd') takenBefore: searchQuery.takenBefore ? toStartOfDayDate(searchQuery.takenBefore) : undefined,
: undefined,
takenBefore: searchQuery.takenBefore
? DateTime.fromISO(searchQuery.takenBefore).toUTC().toFormat('yyyy-MM-dd')
: undefined,
}, },
isArchive: searchQuery.isArchived, isArchive: searchQuery.isArchived,
isFavorite: searchQuery.isFavorite, isFavorite: searchQuery.isFavorite,

View File

@ -1,4 +1,4 @@
import { timeToSeconds } from './time-to-seconds'; import { timeToSeconds } from './date-time';
describe('converting time to seconds', () => { describe('converting time to seconds', () => {
it('parses hh:mm:ss correctly', () => { it('parses hh:mm:ss correctly', () => {

View File

@ -1,4 +1,4 @@
import { Duration } from 'luxon'; import { DateTime, Duration } from 'luxon';
/** /**
* Convert time like `01:02:03.456` to seconds. * Convert time like `01:02:03.456` to seconds.
@ -11,3 +11,7 @@ export function timeToSeconds(time: string) {
return Duration.fromObject({ hours, minutes, seconds }).as('seconds'); return Duration.fromObject({ hours, minutes, seconds }).as('seconds');
} }
export function parseUtcDate(date: string) {
return DateTime.fromISO(date, { zone: 'UTC' }).toUTC();
}

View File

@ -35,6 +35,7 @@
import type { Viewport } from '$lib/stores/assets.store'; import type { Viewport } from '$lib/stores/assets.store';
import { locale } from '$lib/stores/preferences.store'; import { locale } from '$lib/stores/preferences.store';
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
import { parseUtcDate } from '$lib/utils/date-time';
const MAX_ASSET_COUNT = 5000; const MAX_ASSET_COUNT = 5000;
let { isViewing: showAssetViewer } = assetViewingStore; let { isViewing: showAssetViewer } = assetViewingStore;
@ -143,13 +144,16 @@
isLoading = false; isLoading = false;
}; };
function getHumanReadableDate(date: string) { function getHumanReadableDate(dateString: string) {
const d = new Date(date); const date = parseUtcDate(dateString).startOf('day');
return d.toLocaleDateString($locale, { return date.toLocaleString(
year: 'numeric', {
month: 'long', year: 'numeric',
day: 'numeric', month: 'long',
}); day: 'numeric',
},
{ locale: $locale },
);
} }
function getHumanReadableSearchKey(key: keyof SearchTerms): string { function getHumanReadableSearchKey(key: keyof SearchTerms): string {