mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05: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,7 +588,9 @@
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
  {/if}
 | 
			
		||||
</section>
 | 
			
		||||
{#if current}
 | 
			
		||||
  <!-- GALLERY VIEWER -->
 | 
			
		||||
  <section class="bg-immich-dark-gray p-4">
 | 
			
		||||
    <div
 | 
			
		||||
@ -603,20 +613,19 @@
 | 
			
		||||
        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}
 | 
			
		||||
        viewport={galleryViewport}
 | 
			
		||||
        {assetInteraction}
 | 
			
		||||
        slidingWindowOffset={viewerHeight}
 | 
			
		||||
      />
 | 
			
		||||
    </div>
 | 
			
		||||
  </section>
 | 
			
		||||
  {/if}
 | 
			
		||||
</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