mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
fix: gallery viewer sliding window offload assets (#17016)
* fix: gallery viewer sliding window offload assets * fix: update bottom sliding window * do not use negative * Calculate offset before gallery --------- Co-authored-by: Min Idzelis <min123@gmail.com>
This commit is contained in:
parent
21954939cf
commit
dbc279f843
@ -67,9 +67,12 @@
|
||||
let paused = $state(false);
|
||||
let current = $state<MemoryAsset | undefined>(undefined);
|
||||
let isSaved = $derived(current?.memory.isSaved);
|
||||
let viewerHeight = $state(0);
|
||||
|
||||
const { isViewing } = assetViewingStore;
|
||||
const viewport: Viewport = $state({ width: 0, height: 0 });
|
||||
// need to include padding in the viewport for gallery
|
||||
const galleryViewport: Viewport = $derived({ height: viewport.height, width: viewport.width - 32 });
|
||||
const assetInteraction = new AssetInteraction();
|
||||
let progressBarController: Tween<number> | undefined = $state(undefined);
|
||||
let videoPlayer: HTMLVideoElement | undefined = $state();
|
||||
@ -331,7 +334,12 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<section id="memory-viewer" class="w-full bg-immich-dark-gray" bind:this={memoryWrapper}>
|
||||
<section
|
||||
id="memory-viewer"
|
||||
class="w-full bg-immich-dark-gray"
|
||||
bind:this={memoryWrapper}
|
||||
use:resizeObserver={({ height, width }) => ((viewport.height = height), (viewport.width = width))}
|
||||
>
|
||||
{#if current}
|
||||
<ControlAppBar onClose={() => goto(AppRoute.PHOTOS)} forceDark multiRow>
|
||||
{#snippet leading()}
|
||||
@ -386,7 +394,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
<!-- Viewer -->
|
||||
<section class="overflow-hidden pt-32 md:pt-20">
|
||||
<section class="overflow-hidden pt-32 md:pt-20" bind:clientHeight={viewerHeight}>
|
||||
<div
|
||||
class="ml-[-100%] box-border flex h-[calc(100vh_-_224px)] md:h-[calc(100vh_-_180px)] w-[300%] items-center justify-center gap-10 overflow-hidden"
|
||||
>
|
||||
@ -580,43 +588,44 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- GALLERY VIEWER -->
|
||||
<section class="bg-immich-dark-gray p-4">
|
||||
<div
|
||||
class="sticky mb-10 flex place-content-center place-items-center transition-all"
|
||||
class:opacity-0={galleryInView}
|
||||
class:opacity-100={!galleryInView}
|
||||
>
|
||||
<CircleIconButton
|
||||
title={$t('show_gallery')}
|
||||
icon={mdiChevronDown}
|
||||
color="light"
|
||||
onclick={() => memoryGallery?.scrollIntoView({ behavior: 'smooth' })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="gallery-memory"
|
||||
use:intersectionObserver={{
|
||||
onIntersect: handleGalleryScrollsIntoView,
|
||||
onSeparate: handleGalleryScrollsOutOfView,
|
||||
bottom: '-200px',
|
||||
}}
|
||||
use:resizeObserver={({ height, width }) => ((viewport.height = height), (viewport.width = width))}
|
||||
bind:this={memoryGallery}
|
||||
>
|
||||
<GalleryViewer
|
||||
onNext={handleNextAsset}
|
||||
onPrevious={handlePreviousAsset}
|
||||
assets={current.memory.assets}
|
||||
{viewport}
|
||||
{assetInteraction}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
</section>
|
||||
{#if current}
|
||||
<!-- GALLERY VIEWER -->
|
||||
<section class="bg-immich-dark-gray p-4">
|
||||
<div
|
||||
class="sticky mb-10 flex place-content-center place-items-center transition-all"
|
||||
class:opacity-0={galleryInView}
|
||||
class:opacity-100={!galleryInView}
|
||||
>
|
||||
<CircleIconButton
|
||||
title={$t('show_gallery')}
|
||||
icon={mdiChevronDown}
|
||||
color="light"
|
||||
onclick={() => memoryGallery?.scrollIntoView({ behavior: 'smooth' })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
id="gallery-memory"
|
||||
use:intersectionObserver={{
|
||||
onIntersect: handleGalleryScrollsIntoView,
|
||||
onSeparate: handleGalleryScrollsOutOfView,
|
||||
bottom: '-200px',
|
||||
}}
|
||||
bind:this={memoryGallery}
|
||||
>
|
||||
<GalleryViewer
|
||||
onNext={handleNextAsset}
|
||||
onPrevious={handlePreviousAsset}
|
||||
assets={current.memory.assets}
|
||||
viewport={galleryViewport}
|
||||
{assetInteraction}
|
||||
slidingWindowOffset={viewerHeight}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.main-view {
|
||||
|
@ -35,6 +35,8 @@
|
||||
onPrevious?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
||||
onNext?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
||||
onRandom?: (() => Promise<AssetResponseDto | undefined>) | undefined;
|
||||
pageHeaderOffset?: number;
|
||||
slidingWindowOffset?: number;
|
||||
}
|
||||
|
||||
let {
|
||||
@ -49,6 +51,8 @@
|
||||
onPrevious = undefined,
|
||||
onNext = undefined,
|
||||
onRandom = undefined,
|
||||
slidingWindowOffset = 0,
|
||||
pageHeaderOffset = 0,
|
||||
}: Props = $props();
|
||||
|
||||
let { isViewing: isViewerOpen, asset: viewingAsset, setAsset } = assetViewingStore;
|
||||
@ -86,7 +90,7 @@
|
||||
height: geometry.getHeight(i),
|
||||
};
|
||||
// 54 is the content height of the asset-selection-app-bar
|
||||
const layoutTopWithOffset = layout.top + 54;
|
||||
const layoutTopWithOffset = layout.top + pageHeaderOffset;
|
||||
const layoutBottom = layoutTopWithOffset + layout.height;
|
||||
|
||||
const display = layoutTopWithOffset < slidingWindow.bottom && layoutBottom > slidingWindow.top;
|
||||
@ -109,7 +113,7 @@
|
||||
|
||||
const updateSlidingWindow = () => {
|
||||
const v = $state.snapshot(viewport);
|
||||
const top = document.scrollingElement?.scrollTop || 0;
|
||||
const top = (document.scrollingElement?.scrollTop || 0) - slidingWindowOffset;
|
||||
const bottom = top + v.height;
|
||||
const w = {
|
||||
top,
|
||||
|
@ -154,7 +154,13 @@
|
||||
<!-- Assets -->
|
||||
{#if data.pathAssets && data.pathAssets.length > 0}
|
||||
<div bind:clientHeight={viewport.height} bind:clientWidth={viewport.width} class="mt-2">
|
||||
<GalleryViewer assets={data.pathAssets} {assetInteraction} {viewport} showAssetName={true} />
|
||||
<GalleryViewer
|
||||
assets={data.pathAssets}
|
||||
{assetInteraction}
|
||||
{viewport}
|
||||
showAssetName={true}
|
||||
pageHeaderOffset={54}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
|
@ -368,6 +368,7 @@
|
||||
onIntersected={loadNextPage}
|
||||
showArchiveIcon={true}
|
||||
{viewport}
|
||||
pageHeaderOffset={54}
|
||||
/>
|
||||
{:else if !isLoading}
|
||||
<div class="flex min-h-[calc(66vh_-_11rem)] w-full place-content-center items-center dark:text-white">
|
||||
|
Loading…
x
Reference in New Issue
Block a user