1
0
mirror of https://github.com/immich-app/immich.git synced 2025-07-07 06:16:05 +02:00

feat(web): Scroll to asset in gridview; increase gridview perf; reduce memory; scrollbar ticks in fixed position (#10646)

* Squashed

* Change strategy - now pre-measure buckets offscreen, so don't need to worry about sub-bucket scroll preservation

* Reduce jank on scroll, delay DOM updates until after scroll

* css opt, log measure time

* Trickle out queue while scrolling, flush when stopped

* yay

* Cleanup cleanup...

* everybody...

* everywhere...

* Clean up cleanup!

* Everybody do their share

* CLEANUP!

* package-lock ?

* dynamic measure, todo

* Fix web test

* type lint

* fix e2e

* e2e test

* Better scrollbar

* Tuning, and more tunables

* Tunable tweaks, more tunables

* Scrollbar dots and viewport events

* lint

* Tweaked tunnables, use requestIdleCallback for garbage tasks, bug fixes

* New tunables, and don't update url by default

* Bug fixes

* Bug fix, with debug

* Fix flickr, fix graybox bug, reduced debug

* Refactor/cleanup

* Fix

* naming

* Final cleanup

* review comment

* Forgot to update this after naming change

* scrubber works, with debug

* cleanup

* Rename scrollbar to scrubber

* rename  to

* left over rename and change to previous album bar

* bugfix addassets, comments

* missing destroy(), cleanup

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
Min Idzelis
2024-08-21 22:15:21 -04:00
committed by GitHub
parent 07538299cf
commit 837b1e4929
50 changed files with 2947 additions and 843 deletions

View File

@ -4,25 +4,25 @@
import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
import { AppRoute, AssetAction } from '$lib/constants';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import type { BucketPosition, Viewport } from '$lib/stores/assets.store';
import type { Viewport } from '$lib/stores/assets.store';
import { getAssetRatio } from '$lib/utils/asset-utils';
import { handleError } from '$lib/utils/handle-error';
import { navigate } from '$lib/utils/navigation';
import { calculateWidth } from '$lib/utils/timeline-util';
import { type AssetResponseDto } from '@immich/sdk';
import justifiedLayout from 'justified-layout';
import { createEventDispatcher, onDestroy } from 'svelte';
import { onDestroy } from 'svelte';
import { t } from 'svelte-i18n';
import AssetViewer from '../../asset-viewer/asset-viewer.svelte';
import Portal from '../portal/portal.svelte';
const dispatch = createEventDispatcher<{ intersected: { container: HTMLDivElement; position: BucketPosition } }>();
import { handlePromiseError } from '$lib/utils';
export let assets: AssetResponseDto[];
export let selectedAssets: Set<AssetResponseDto> = new Set();
export let disableAssetSelect = false;
export let showArchiveIcon = false;
export let viewport: Viewport;
export let onIntersected: (() => void) | undefined = undefined;
export let showAssetName = false;
let { isViewing: isViewerOpen, asset: viewingAsset, setAsset } = assetViewingStore;
@ -127,18 +127,15 @@
<Thumbnail
{asset}
readonly={disableAssetSelect}
onClick={async (asset, e) => {
e.preventDefault();
onClick={(asset) => {
if (isMultiSelectionMode) {
selectAssetHandler(asset);
return;
}
await viewAssetHandler(asset);
void viewAssetHandler(asset);
}}
on:select={(e) => selectAssetHandler(e.detail.asset)}
on:intersected={(event) =>
i === Math.max(1, assets.length - 7) ? dispatch('intersected', event.detail) : undefined}
onSelect={(asset) => selectAssetHandler(asset)}
onIntersected={() => (i === Math.max(1, assets.length - 7) ? onIntersected?.() : void 0)}
selected={selectedAssets.has(asset)}
{showArchiveIcon}
thumbnailWidth={geometry.boxes[i].width}
@ -159,6 +156,15 @@
<!-- Overlay Asset Viewer -->
{#if $isViewerOpen}
<Portal target="body">
<AssetViewer asset={$viewingAsset} onAction={handleAction} on:previous={handlePrevious} on:next={handleNext} />
<AssetViewer
asset={$viewingAsset}
onAction={handleAction}
on:previous={handlePrevious}
on:next={handleNext}
on:close={() => {
assetViewingStore.showAssetViewer(false);
handlePromiseError(navigate({ targetRoute: 'current', assetId: null }));
}}
/>
</Portal>
{/if}