feat: improve/refactor focus handling (#17796)

* feat: improve focus

* test

* lint

* use modulus in loop
This commit is contained in:
Min Idzelis
2025-04-30 00:19:38 -04:00
committed by GitHub
parent 2e8a286540
commit 4b1ced439b
11 changed files with 92 additions and 129 deletions
@@ -100,9 +100,6 @@
}
};
const assetOnFocusHandler = (asset: AssetResponseDto) => {
assetInteraction.focussedAssetId = asset.id;
};
function filterIntersecting<R extends { intersecting: boolean }>(intersectable: R[]) {
return intersectable.filter((int) => int.intersecting);
}
@@ -182,13 +179,11 @@
{showArchiveIcon}
{asset}
{groupIndex}
focussed={assetInteraction.isFocussedAsset(asset.id)}
onClick={(asset) => onClick(assetStore, dateGroup.getAssets(), dateGroup.groupTitle, asset)}
onSelect={(asset) => assetSelectHandler(assetStore, asset, dateGroup.getAssets(), dateGroup.groupTitle)}
onMouseEvent={() => assetMouseEventHandler(dateGroup.groupTitle, assetSnapshot(asset))}
selected={assetInteraction.hasSelectedAsset(asset.id) || dateGroup.bucket.store.albumAssets.has(asset.id)}
selectionCandidate={assetInteraction.hasSelectionCandidate(asset.id)}
handleFocus={() => assetOnFocusHandler(asset)}
disabled={dateGroup.bucket.store.albumAssets.has(asset.id)}
thumbnailWidth={position.width}
thumbnailHeight={position.height}
@@ -26,6 +26,7 @@
import type { UpdatePayload } from 'vite';
import type { AssetInteraction } from '$lib/stores/asset-interaction.svelte';
import { mobileDevice } from '$lib/stores/mobile-device.svelte';
import { focusNext } from '$lib/utils/focus-util';
interface Props {
isSelectionMode?: boolean;
@@ -616,34 +617,8 @@
}
};
const focusNextAsset = async () => {
if (assetInteraction.focussedAssetId === null) {
const firstAsset = assetStore.getFirstAsset();
if (firstAsset) {
assetInteraction.focussedAssetId = firstAsset.id;
}
} else {
const focussedAsset = assetStore.getAssets().find((asset) => asset.id === assetInteraction.focussedAssetId);
if (focussedAsset) {
const nextAsset = await assetStore.getNextAsset(focussedAsset);
if (nextAsset) {
assetInteraction.focussedAssetId = nextAsset.id;
}
}
}
};
const focusPreviousAsset = async () => {
if (assetInteraction.focussedAssetId !== null) {
const focussedAsset = assetStore.getAssets().find((asset) => asset.id === assetInteraction.focussedAssetId);
if (focussedAsset) {
const previousAsset = await assetStore.getPreviousAsset(focussedAsset);
if (previousAsset) {
assetInteraction.focussedAssetId = previousAsset.id;
}
}
}
};
const focusNextAsset = () => focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, true);
const focusPreviousAsset = () => focusNext((element) => element.dataset.thumbnailFocusContainer !== undefined, false);
let isTrashEnabled = $derived($featureFlags.loaded && $featureFlags.trash);
let isEmpty = $derived(assetStore.isInitialized && assetStore.buckets.length === 0);