mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:39:37 -05:00 
			
		
		
		
	chore(web): hide memory lane navigation when it's no longer possible to scroll (#2791)
Fixes: #2790
This commit is contained in:
		
							parent
							
								
									07f7fffae7
								
							
						
					
					
						commit
						4a21cb2d00
					
				@ -1,42 +1,36 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import { onMount } from 'svelte';
 | 
						import { onMount } from 'svelte';
 | 
				
			||||||
	import { DateTime } from 'luxon';
 | 
						import { DateTime } from 'luxon';
 | 
				
			||||||
	import { MemoryLaneResponseDto, api } from '@api';
 | 
						import { api } from '@api';
 | 
				
			||||||
	import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
 | 
						import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
 | 
				
			||||||
	import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
 | 
						import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
 | 
				
			||||||
	import { memoryStore } from '$lib/stores/memory.store';
 | 
						import { memoryStore } from '$lib/stores/memory.store';
 | 
				
			||||||
	import { goto } from '$app/navigation';
 | 
						import { goto } from '$app/navigation';
 | 
				
			||||||
 | 
						import { fade } from 'svelte/transition';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let memoryLane: MemoryLaneResponseDto[] = [];
 | 
						$: shouldRender = $memoryStore?.length > 0;
 | 
				
			||||||
	$: shouldRender = memoryLane.length > 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	onMount(async () => {
 | 
						onMount(async () => {
 | 
				
			||||||
		const { data } = await api.assetApi.getMemoryLane({
 | 
							const { data } = await api.assetApi.getMemoryLane({
 | 
				
			||||||
			timestamp: DateTime.local().startOf('day').toISO()
 | 
								timestamp: DateTime.local().startOf('day').toISO()
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					 | 
				
			||||||
		memoryLane = data;
 | 
					 | 
				
			||||||
		$memoryStore = data;
 | 
							$memoryStore = data;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let memoryLaneElement: HTMLElement;
 | 
						let memoryLaneElement: HTMLElement;
 | 
				
			||||||
	let offsetWidth = 0;
 | 
						let offsetWidth = 0;
 | 
				
			||||||
	let innerWidth = 0;
 | 
						let innerWidth = 0;
 | 
				
			||||||
	$: isOverflow = offsetWidth < innerWidth;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function scrollLeft() {
 | 
						let scrollLeftPosition = 0;
 | 
				
			||||||
		memoryLaneElement.scrollTo({
 | 
					 | 
				
			||||||
			left: memoryLaneElement.scrollLeft - 400,
 | 
					 | 
				
			||||||
			behavior: 'smooth'
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function scrollRight() {
 | 
						const onScroll = () => (scrollLeftPosition = memoryLaneElement?.scrollLeft);
 | 
				
			||||||
		memoryLaneElement.scrollTo({
 | 
					
 | 
				
			||||||
			left: memoryLaneElement.scrollLeft + 400,
 | 
						$: canScrollLeft = scrollLeftPosition > 0;
 | 
				
			||||||
			behavior: 'smooth'
 | 
						$: canScrollRight = scrollLeftPosition < innerWidth - offsetWidth;
 | 
				
			||||||
		});
 | 
					
 | 
				
			||||||
	}
 | 
						const scrollBy = 400;
 | 
				
			||||||
 | 
						const scrollLeft = () => memoryLaneElement.scrollBy({ left: -scrollBy, behavior: 'smooth' });
 | 
				
			||||||
 | 
						const scrollRight = () => memoryLaneElement.scrollBy({ left: scrollBy, behavior: 'smooth' });
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#if shouldRender}
 | 
					{#if shouldRender}
 | 
				
			||||||
@ -45,29 +39,35 @@
 | 
				
			|||||||
		bind:this={memoryLaneElement}
 | 
							bind:this={memoryLaneElement}
 | 
				
			||||||
		class="relative overflow-x-hidden whitespace-nowrap mt-5 transition-all"
 | 
							class="relative overflow-x-hidden whitespace-nowrap mt-5 transition-all"
 | 
				
			||||||
		bind:offsetWidth
 | 
							bind:offsetWidth
 | 
				
			||||||
 | 
							on:scroll={onScroll}
 | 
				
			||||||
	>
 | 
						>
 | 
				
			||||||
		{#if isOverflow}
 | 
							{#if canScrollLeft || canScrollRight}
 | 
				
			||||||
			<div class="sticky left-0 z-20">
 | 
								<div class="sticky left-0 z-20">
 | 
				
			||||||
				<div class="absolute right-0 top-[6rem] z-20">
 | 
									{#if canScrollLeft}
 | 
				
			||||||
					<button
 | 
										<div class="absolute left-4 top-[6rem] z-20" transition:fade={{ duration: 200 }}>
 | 
				
			||||||
						class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
											<button
 | 
				
			||||||
						on:click={scrollRight}
 | 
												class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
				
			||||||
					>
 | 
												on:click={scrollLeft}
 | 
				
			||||||
						<ChevronRight size="36" /></button
 | 
											>
 | 
				
			||||||
					>
 | 
												<ChevronLeft size="36" /></button
 | 
				
			||||||
				</div>
 | 
											>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
				<div class="absolute left-0 top-[6rem] z-20">
 | 
									{/if}
 | 
				
			||||||
					<button
 | 
									{#if canScrollRight}
 | 
				
			||||||
						class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
										<div class="absolute right-4 top-[6rem] z-20" transition:fade={{ duration: 200 }}>
 | 
				
			||||||
						on:click={scrollLeft}><ChevronLeft size="36" /></button
 | 
											<button
 | 
				
			||||||
					>
 | 
												class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
				
			||||||
				</div>
 | 
												on:click={scrollRight}
 | 
				
			||||||
 | 
											>
 | 
				
			||||||
 | 
												<ChevronRight size="36" /></button
 | 
				
			||||||
 | 
											>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
									{/if}
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		{/if}
 | 
							{/if}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<div class="inline-block" bind:offsetWidth={innerWidth}>
 | 
							<div class="inline-block" bind:offsetWidth={innerWidth}>
 | 
				
			||||||
			{#each memoryLane as memory, i (memory.title)}
 | 
								{#each $memoryStore as memory, i (memory.title)}
 | 
				
			||||||
				<button
 | 
									<button
 | 
				
			||||||
					class="memory-card relative inline-block mr-8 rounded-xl aspect-video h-[215px]"
 | 
										class="memory-card relative inline-block mr-8 rounded-xl aspect-video h-[215px]"
 | 
				
			||||||
					on:click={() => goto(`/memory?memory=${i}`)}
 | 
										on:click={() => goto(`/memory?memory=${i}`)}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user