mirror of
https://github.com/immich-app/immich.git
synced 2025-04-16 12:18:51 +02:00
fix(web): detail panel out of sync when reopening (#11713)
* fix(web): detail panel out of sync when reopening * extract event handler
This commit is contained in:
parent
b749a68349
commit
c2965c4408
@ -1,16 +1,23 @@
|
|||||||
import { AssetMediaResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk';
|
import { AssetMediaResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk';
|
||||||
import { expect, test } from '@playwright/test';
|
import { expect, test } from '@playwright/test';
|
||||||
|
import type { Socket } from 'socket.io-client';
|
||||||
import { utils } from 'src/utils';
|
import { utils } from 'src/utils';
|
||||||
|
|
||||||
test.describe('Detail Panel', () => {
|
test.describe('Detail Panel', () => {
|
||||||
let admin: LoginResponseDto;
|
let admin: LoginResponseDto;
|
||||||
let asset: AssetMediaResponseDto;
|
let asset: AssetMediaResponseDto;
|
||||||
|
let websocket: Socket;
|
||||||
|
|
||||||
test.beforeAll(async () => {
|
test.beforeAll(async () => {
|
||||||
utils.initSdk();
|
utils.initSdk();
|
||||||
await utils.resetDatabase();
|
await utils.resetDatabase();
|
||||||
admin = await utils.adminSetup();
|
admin = await utils.adminSetup();
|
||||||
asset = await utils.createAsset(admin.accessToken);
|
asset = await utils.createAsset(admin.accessToken);
|
||||||
|
websocket = await utils.connectWebsocket(admin.accessToken);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll(() => {
|
||||||
|
utils.disconnectWebsocket(websocket);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can be opened for shared links', async ({ page }) => {
|
test('can be opened for shared links', async ({ page }) => {
|
||||||
@ -57,4 +64,23 @@ test.describe('Detail Panel', () => {
|
|||||||
await expect(textarea).toBeVisible();
|
await expect(textarea).toBeVisible();
|
||||||
await expect(textarea).not.toBeDisabled();
|
await expect(textarea).not.toBeDisabled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('description changes are visible after reopening', async ({ context, page }) => {
|
||||||
|
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();
|
||||||
|
const textarea = page.getByRole('textbox', { name: 'Add a description' });
|
||||||
|
await textarea.fill('new description');
|
||||||
|
await expect(textarea).toHaveValue('new description');
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Info' }).click();
|
||||||
|
await expect(textarea).not.toBeVisible();
|
||||||
|
await page.getByRole('button', { name: 'Info' }).click();
|
||||||
|
await expect(textarea).toBeVisible();
|
||||||
|
|
||||||
|
await utils.waitForWebsocketEvent({ event: 'assetUpdate', id: asset.id });
|
||||||
|
await expect(textarea).toHaveValue('new description');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
let isLiked: ActivityResponseDto | null = null;
|
let isLiked: ActivityResponseDto | null = null;
|
||||||
let numberOfComments: number;
|
let numberOfComments: number;
|
||||||
let fullscreenElement: Element;
|
let fullscreenElement: Element;
|
||||||
let unsubscribe: () => void;
|
let unsubscribes: (() => void)[] = [];
|
||||||
let zoomToggle = () => void 0;
|
let zoomToggle = () => void 0;
|
||||||
let copyImage: () => Promise<void>;
|
let copyImage: () => Promise<void>;
|
||||||
|
|
||||||
@ -172,6 +172,12 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onAssetUpdate = (assetUpdate: AssetResponseDto) => {
|
||||||
|
if (assetUpdate.id === asset.id) {
|
||||||
|
asset = assetUpdate;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (isShared && asset.id) {
|
if (isShared && asset.id) {
|
||||||
handlePromiseError(getFavorite());
|
handlePromiseError(getFavorite());
|
||||||
@ -180,11 +186,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
unsubscribe = websocketEvents.on('on_upload_success', (assetUpdate) => {
|
unsubscribes.push(
|
||||||
if (assetUpdate.id === asset.id) {
|
websocketEvents.on('on_upload_success', onAssetUpdate),
|
||||||
asset = assetUpdate;
|
websocketEvents.on('on_asset_update', onAssetUpdate),
|
||||||
}
|
);
|
||||||
});
|
|
||||||
await navigate({ targetRoute: 'current', assetId: asset.id });
|
await navigate({ targetRoute: 'current', assetId: asset.id });
|
||||||
slideshowStateUnsubscribe = slideshowState.subscribe((value) => {
|
slideshowStateUnsubscribe = slideshowState.subscribe((value) => {
|
||||||
if (value === SlideshowState.PlaySlideshow) {
|
if (value === SlideshowState.PlaySlideshow) {
|
||||||
@ -225,7 +231,10 @@
|
|||||||
if (shuffleSlideshowUnsubscribe) {
|
if (shuffleSlideshowUnsubscribe) {
|
||||||
shuffleSlideshowUnsubscribe();
|
shuffleSlideshowUnsubscribe();
|
||||||
}
|
}
|
||||||
unsubscribe?.();
|
|
||||||
|
for (const unsubscribe of unsubscribes) {
|
||||||
|
unsubscribe();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
import { locale } from '$lib/stores/preferences.store';
|
import { locale } from '$lib/stores/preferences.store';
|
||||||
import { featureFlags } from '$lib/stores/server-config.store';
|
import { featureFlags } from '$lib/stores/server-config.store';
|
||||||
import { user } from '$lib/stores/user.store';
|
import { user } from '$lib/stores/user.store';
|
||||||
import { websocketEvents } from '$lib/stores/websocket';
|
|
||||||
import { getAssetThumbnailUrl, getPeopleThumbnailUrl, handlePromiseError, isSharedLink } from '$lib/utils';
|
import { getAssetThumbnailUrl, getPeopleThumbnailUrl, handlePromiseError, isSharedLink } from '$lib/utils';
|
||||||
import { delay, isFlipped } from '$lib/utils/asset-utils';
|
import { delay, isFlipped } from '$lib/utils/asset-utils';
|
||||||
import {
|
import {
|
||||||
@ -30,7 +29,7 @@
|
|||||||
mdiAccountOff,
|
mdiAccountOff,
|
||||||
} from '@mdi/js';
|
} from '@mdi/js';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { createEventDispatcher, onMount } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import { getByteUnitString } from '$lib/utils/byte-units';
|
import { getByteUnitString } from '$lib/utils/byte-units';
|
||||||
import { handleError } from '$lib/utils/handle-error';
|
import { handleError } from '$lib/utils/handle-error';
|
||||||
@ -99,14 +98,6 @@
|
|||||||
|
|
||||||
$: unassignedFaces = asset.unassignedFaces || [];
|
$: unassignedFaces = asset.unassignedFaces || [];
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
return websocketEvents.on('on_asset_update', (assetUpdate) => {
|
|
||||||
if (assetUpdate.id === asset.id) {
|
|
||||||
asset = assetUpdate;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{
|
const dispatch = createEventDispatcher<{
|
||||||
close: void;
|
close: void;
|
||||||
}>();
|
}>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user