fix: Change shortcut listeners from window to document (#18416)

* fix: Change shortcut listeners to document

* fix: split into window and document

* chore: upgrade ui package
This commit is contained in:
Arno 2025-05-21 18:12:00 +02:00 committed by GitHub
parent b2ef8ea7dd
commit 188188a844
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 40 additions and 39 deletions

22
web/package-lock.json generated
View File

@ -11,7 +11,7 @@
"dependencies": {
"@formatjs/icu-messageformat-parser": "^2.9.8",
"@immich/sdk": "file:../open-api/typescript-sdk",
"@immich/ui": "^0.22.1",
"@immich/ui": "^0.22.2",
"@mapbox/mapbox-gl-rtl-text": "0.2.3",
"@mdi/js": "^7.4.47",
"@photo-sphere-viewer/core": "^5.11.5",
@ -1342,13 +1342,13 @@
"link": true
},
"node_modules/@immich/ui": {
"version": "0.22.1",
"resolved": "https://registry.npmjs.org/@immich/ui/-/ui-0.22.1.tgz",
"integrity": "sha512-/QdqctBit+eX8QZgTL4PlgS7l6/NCGXeDjR6kQNLOVBPhbjkmtwqsvZ+RymYClcHAEhutXOKRhnlQU9mNLC/SA==",
"version": "0.22.2",
"resolved": "https://registry.npmjs.org/@immich/ui/-/ui-0.22.2.tgz",
"integrity": "sha512-aP9B54i4SqL+y7EzkI1gVhx/qtiSYDOFz6vjn1PyXfCnA0RrE+dxYu/Y7f9PXLX0MPrTro5MxmNC06JjuS/Gow==",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@mdi/js": "^7.4.47",
"bits-ui": "^1.0.0-next.46",
"bits-ui": "^1.5.3",
"tailwind-merge": "^2.5.4",
"tailwind-variants": "^1.0.0"
},
@ -1357,9 +1357,9 @@
}
},
"node_modules/@internationalized/date": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.8.0.tgz",
"integrity": "sha512-J51AJ0fEL68hE4CwGPa6E0PO6JDaVLd8aln48xFCSy7CZkZc96dGEGmLs2OEEbBxcsVZtfrqkXJwI2/MSG8yKw==",
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.8.1.tgz",
"integrity": "sha512-PgVE6B6eIZtzf9Gu5HvJxRK3ufUFz9DhspELuhW/N0GuMGMTLvPQNRkHP2hTuP9lblOk+f+1xi96sPiPXANXAA==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
@ -3599,9 +3599,9 @@
"license": "MIT"
},
"node_modules/bits-ui": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-1.4.8.tgz",
"integrity": "sha512-j34GsdSsJ+ZBl9h/70VkufvrlEgTKQSZvm80eM5VvuhLJWvpfEpn9+k0FVmtDQl9NSPgEVtI9imYhm8nW9Nj/w==",
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-1.5.3.tgz",
"integrity": "sha512-BTZ9/GU11DaEGyQp+AY+sXCMLZO0gbDC5J8l7+Ngj4Vf6hNOwrpMmoh5iuKktA6cphXYolVkUDgBWmkh415I+w==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.4",

View File

@ -28,7 +28,7 @@
"dependencies": {
"@formatjs/icu-messageformat-parser": "^2.9.8",
"@immich/sdk": "file:../open-api/typescript-sdk",
"@immich/ui": "^0.22.1",
"@immich/ui": "^0.22.2",
"@mapbox/mapbox-gl-rtl-text": "0.2.3",
"@mdi/js": "^7.4.47",
"@photo-sphere-viewer/core": "^5.11.5",

View File

@ -48,7 +48,7 @@
});
</script>
<svelte:window
<svelte:document
use:shortcut={{
shortcut: { key: 'Escape' },
onShortcut: () => {

View File

@ -36,7 +36,7 @@
};
</script>
<svelte:window
<svelte:document
use:shortcut={{ shortcut: { key: 'l', shift: shared }, onShortcut: () => (showSelectionModal = true) }}
/>

View File

@ -28,7 +28,7 @@
};
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'a', shift: true }, onShortcut: onArchive }} />
<svelte:document use:shortcut={{ shortcut: { key: 'a', shift: true }, onShortcut: onArchive }} />
<MenuOption
icon={asset.isArchived ? mdiArchiveArrowUpOutline : mdiArchiveArrowDownOutline}

View File

@ -11,6 +11,6 @@
let { onClose }: Props = $props();
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
<svelte:document use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
<CircleIconButton color="opaque" icon={mdiArrowLeft} title={$t('go_back')} onclick={onClose} />

View File

@ -73,7 +73,7 @@
};
</script>
<svelte:window
<svelte:document
use:shortcuts={[
{ shortcut: { key: 'Delete' }, onShortcut: () => trashOrDelete(asset.isTrashed) },
{ shortcut: { key: 'Delete', shift: true }, onShortcut: () => trashOrDelete(true) },

View File

@ -19,7 +19,7 @@
const onDownloadFile = async () => downloadFile(await getAssetInfo({ id: asset.id, key: authManager.key }));
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'd', shift: true }, onShortcut: onDownloadFile }} />
<svelte:document use:shortcut={{ shortcut: { key: 'd', shift: true }, onShortcut: onDownloadFile }} />
{#if !menuItem}
<CircleIconButton color="opaque" icon={mdiFolderDownloadOutline} title={$t('download')} onclick={onDownloadFile} />

View File

@ -46,7 +46,7 @@
};
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'f' }, onShortcut: toggleFavorite }} />
<svelte:document use:shortcut={{ shortcut: { key: 'f' }, onShortcut: toggleFavorite }} />
<CircleIconButton
color="opaque"

View File

@ -12,7 +12,7 @@
let { onNextAsset }: Props = $props();
</script>
<svelte:window
<svelte:document
use:shortcuts={[
{ shortcut: { key: 'ArrowRight' }, onShortcut: onNextAsset },
{ shortcut: { key: 'd' }, onShortcut: onNextAsset },

View File

@ -12,7 +12,7 @@
let { onPreviousAsset }: Props = $props();
</script>
<svelte:window
<svelte:document
use:shortcuts={[
{ shortcut: { key: 'ArrowLeft' }, onShortcut: onPreviousAsset },
{ shortcut: { key: 'a' }, onShortcut: onPreviousAsset },

View File

@ -11,6 +11,6 @@
let { onShowDetail }: Props = $props();
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'i' }, onShortcut: onShowDetail }} />
<svelte:document use:shortcut={{ shortcut: { key: 'i' }, onShortcut: onShowDetail }} />
<CircleIconButton color="opaque" icon={mdiInformationOutline} onclick={onShowDetail} title={$t('info')} />

View File

@ -40,7 +40,7 @@
const onConfirm = () => (typeof $showCancelConfirmDialog === 'boolean' ? null : $showCancelConfirmDialog());
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
<svelte:document use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
<section class="relative p-2 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
<div class="flex place-items-center gap-2">

View File

@ -202,7 +202,7 @@
let containerHeight = $state(0);
</script>
<svelte:window
<svelte:document
use:shortcuts={[
{ shortcut: { key: 'c', ctrl: true }, onShortcut: onCopyShortcut, preventDefault: false },
{ shortcut: { key: 'c', meta: true }, onShortcut: onCopyShortcut, preventDefault: false },

View File

@ -107,7 +107,7 @@
};
</script>
<svelte:window
<svelte:document
onmousemove={showControlBar}
use:shortcuts={[
{ shortcut: { key: 'Escape' }, onShortcut: onClose },

View File

@ -108,7 +108,7 @@
let toggleButton = $derived(toggleButtonOptions[getNextVisibility(toggleVisibility)]);
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
<svelte:document use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
<div
class="fixed top-0 flex h-16 w-full items-center justify-between border-b bg-white p-1 dark:border-immich-dark-gray dark:bg-black dark:text-immich-dark-fg md:p-8"

View File

@ -301,7 +301,7 @@
});
</script>
<svelte:window
<svelte:document
use:shortcuts={$isViewing
? []
: [

View File

@ -35,7 +35,7 @@
let menuItemIcon = $derived(getAssets().length === 1 ? mdiFileDownloadOutline : mdiFolderDownloadOutline);
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'd', shift: true }, onShortcut: handleDownloadFiles }} />
<svelte:document use:shortcut={{ shortcut: { key: 'd', shift: true }, onShortcut: handleDownloadFiles }} />
{#if menuItem}
<MenuOption text={$t('download')} icon={menuItemIcon} onClick={handleDownloadFiles} />

View File

@ -712,7 +712,7 @@
});
</script>
<svelte:window onkeydown={onKeyDown} onkeyup={onKeyUp} onselectstart={onSelectStart} use:shortcuts={shortcutList} />
<svelte:document onkeydown={onKeyDown} onkeyup={onKeyUp} onselectstart={onSelectStart} use:shortcuts={shortcutList} />
{#if isShowDeleteConfirmation}
<DeleteAssetDialog

View File

@ -1,9 +1,9 @@
<script lang="ts">
import Icon from '$lib/components/elements/icon.svelte';
import { generateId } from '$lib/utils/generate-id';
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
import type { Shortcut } from '$lib/actions/shortcut';
import { shortcutLabel as computeShortcutLabel, shortcut as bindShortcut } from '$lib/actions/shortcut';
import { shortcut as bindShortcut, shortcutLabel as computeShortcutLabel } from '$lib/actions/shortcut';
import Icon from '$lib/components/elements/icon.svelte';
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
import { generateId } from '$lib/utils/generate-id';
interface Props {
text: string;
@ -44,7 +44,7 @@
: () => {};
</script>
<svelte:window use:bindShortcutIfSet />
<svelte:document use:bindShortcutIfSet />
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_mouse_events_have_key_events -->

View File

@ -446,7 +446,7 @@
});
</script>
<svelte:window
<svelte:document
onkeydown={onKeyDown}
onkeyup={onKeyUp}
onselectstart={onSelectStart}

View File

@ -206,7 +206,7 @@
}
</script>
<svelte:window
<svelte:document
use:shortcuts={[
{ shortcut: { key: 'Escape' }, onShortcut: onEscape },
{ shortcut: { ctrl: true, key: 'k' }, onShortcut: () => input?.select() },

View File

@ -98,7 +98,7 @@
};
</script>
<svelte:window
<svelte:document
use:shortcuts={[
{ shortcut: { key: 'a' }, onShortcut: onSelectAll },
{

View File

@ -248,7 +248,8 @@
}
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onEscape }} bind:scrollY />
<svelte:window bind:scrollY />
<svelte:document use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onEscape }} />
<section>
{#if assetInteraction.selectionActive}

View File

@ -101,7 +101,7 @@
{/if}
</svelte:head>
<svelte:window
<svelte:document
use:shortcut={{
shortcut: { ctrl: true, shift: true, key: 'm' },
onShortcut: () => copyToClipboard(getMyImmichLink().toString()),