From b7eff33f90a0782e791066a75e91f11fafe6be18 Mon Sep 17 00:00:00 2001 From: Sergey Katsubo Date: Fri, 17 Apr 2026 15:56:39 +0300 Subject: [PATCH] chore(web): refactor date section of asset viewer (#24514) Co-authored-by: Daniel Dietzler --- .../web/asset-viewer/detail-panel.e2e-spec.ts | 42 ++++++++- e2e/test-assets | 2 +- .../asset-viewer/detail-panel-date.svelte | 86 +++++++++++++++++++ .../asset-viewer/detail-panel.svelte | 84 +----------------- 4 files changed, 131 insertions(+), 83 deletions(-) create mode 100644 web/src/lib/components/asset-viewer/detail-panel-date.svelte diff --git a/e2e/src/specs/web/asset-viewer/detail-panel.e2e-spec.ts b/e2e/src/specs/web/asset-viewer/detail-panel.e2e-spec.ts index 2f90e4e3d8..bbe0ef328f 100644 --- a/e2e/src/specs/web/asset-viewer/detail-panel.e2e-spec.ts +++ b/e2e/src/specs/web/asset-viewer/detail-panel.e2e-spec.ts @@ -1,7 +1,9 @@ import { AssetMediaResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk'; import { expect, test } from '@playwright/test'; +import { readFile } from 'node:fs/promises'; +import { basename, join } from 'node:path'; import type { Socket } from 'socket.io-client'; -import { utils } from 'src/utils'; +import { testAssetDir, utils } from 'src/utils'; test.describe('Detail Panel', () => { let admin: LoginResponseDto; @@ -83,4 +85,42 @@ test.describe('Detail Panel', () => { await utils.waitForWebsocketEvent({ event: 'assetUpdate', id: asset.id }); await expect(textarea).toHaveValue('new description'); }); + + test.describe('Date editor', () => { + test('displays inferred asset timezone', async ({ context, page }) => { + const test = { + filepath: 'metadata/dates/datetimeoriginal-gps.jpg', + expected: { + dateTime: '2025-12-01T11:30', + // Test with a timezone which is NOT the first among timezones with the same offset + // This is to check that the editor does not simply fall back to the first available timezone with that offset + // America/Denver (-07:00) is not the first among timezones with offset -07:00 + timeZoneWithOffset: 'America/Denver (-07:00)', + }, + }; + + const asset = await utils.createAsset(admin.accessToken, { + assetData: { + bytes: await readFile(join(testAssetDir, test.filepath)), + filename: basename(test.filepath), + }, + }); + + await utils.waitForWebsocketEvent({ event: 'assetUpload', id: asset.id }); + + // asset viewer -> detail panel -> date editor + await utils.setAuthCookies(context, admin.accessToken); + await page.goto(`/photos/${asset.id}`); + await page.waitForSelector('#immich-asset-viewer'); + + await page.getByRole('button', { name: 'Info' }).click(); + await page.getByTestId('detail-panel-edit-date-button').click(); + await page.waitForSelector('[role="dialog"]'); + + const datetime = page.locator('#datetime'); + await expect(datetime).toHaveValue(test.expected.dateTime); + const timezone = page.getByRole('combobox', { name: 'Timezone' }); + await expect(timezone).toHaveValue(test.expected.timeZoneWithOffset); + }); + }); }); diff --git a/e2e/test-assets b/e2e/test-assets index 163c251744..0eac5a3738 160000 --- a/e2e/test-assets +++ b/e2e/test-assets @@ -1 +1 @@ -Subproject commit 163c251744e0a35d7ecfd02682452043f149fc2b +Subproject commit 0eac5a37384c151be88381b41f9e28d8d59a4466 diff --git a/web/src/lib/components/asset-viewer/detail-panel-date.svelte b/web/src/lib/components/asset-viewer/detail-panel-date.svelte new file mode 100644 index 0000000000..f5e85112bc --- /dev/null +++ b/web/src/lib/components/asset-viewer/detail-panel-date.svelte @@ -0,0 +1,86 @@ + + +{#if dateTime} + +{:else if !dateTime && isOwner} +
+
+ +
+
+ +
+
+{/if} diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index 7cb486c5a6..ed31a4b44f 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -1,5 +1,6 @@ (albums = refreshAlbums())} /> @@ -291,65 +271,7 @@ {$t('no_exif_info_available')} {/if} - {#if dateTime} - - {:else if !dateTime && isOwner} -
-
-
- -
-
-
- -
-
- {/if} +