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">
 | 
			
		||||
	import { onMount } from 'svelte';
 | 
			
		||||
	import { DateTime } from 'luxon';
 | 
			
		||||
	import { MemoryLaneResponseDto, api } from '@api';
 | 
			
		||||
	import { api } from '@api';
 | 
			
		||||
	import ChevronLeft from 'svelte-material-icons/ChevronLeft.svelte';
 | 
			
		||||
	import ChevronRight from 'svelte-material-icons/ChevronRight.svelte';
 | 
			
		||||
	import { memoryStore } from '$lib/stores/memory.store';
 | 
			
		||||
	import { goto } from '$app/navigation';
 | 
			
		||||
	import { fade } from 'svelte/transition';
 | 
			
		||||
 | 
			
		||||
	let memoryLane: MemoryLaneResponseDto[] = [];
 | 
			
		||||
	$: shouldRender = memoryLane.length > 0;
 | 
			
		||||
	$: shouldRender = $memoryStore?.length > 0;
 | 
			
		||||
 | 
			
		||||
	onMount(async () => {
 | 
			
		||||
		const { data } = await api.assetApi.getMemoryLane({
 | 
			
		||||
			timestamp: DateTime.local().startOf('day').toISO()
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		memoryLane = data;
 | 
			
		||||
		$memoryStore = data;
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	let memoryLaneElement: HTMLElement;
 | 
			
		||||
	let offsetWidth = 0;
 | 
			
		||||
	let innerWidth = 0;
 | 
			
		||||
	$: isOverflow = offsetWidth < innerWidth;
 | 
			
		||||
 | 
			
		||||
	function scrollLeft() {
 | 
			
		||||
		memoryLaneElement.scrollTo({
 | 
			
		||||
			left: memoryLaneElement.scrollLeft - 400,
 | 
			
		||||
			behavior: 'smooth'
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	let scrollLeftPosition = 0;
 | 
			
		||||
 | 
			
		||||
	function scrollRight() {
 | 
			
		||||
		memoryLaneElement.scrollTo({
 | 
			
		||||
			left: memoryLaneElement.scrollLeft + 400,
 | 
			
		||||
			behavior: 'smooth'
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	const onScroll = () => (scrollLeftPosition = memoryLaneElement?.scrollLeft);
 | 
			
		||||
 | 
			
		||||
	$: canScrollLeft = scrollLeftPosition > 0;
 | 
			
		||||
	$: canScrollRight = scrollLeftPosition < innerWidth - offsetWidth;
 | 
			
		||||
 | 
			
		||||
	const scrollBy = 400;
 | 
			
		||||
	const scrollLeft = () => memoryLaneElement.scrollBy({ left: -scrollBy, behavior: 'smooth' });
 | 
			
		||||
	const scrollRight = () => memoryLaneElement.scrollBy({ left: scrollBy, behavior: 'smooth' });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{#if shouldRender}
 | 
			
		||||
@ -45,29 +39,35 @@
 | 
			
		||||
		bind:this={memoryLaneElement}
 | 
			
		||||
		class="relative overflow-x-hidden whitespace-nowrap mt-5 transition-all"
 | 
			
		||||
		bind:offsetWidth
 | 
			
		||||
		on:scroll={onScroll}
 | 
			
		||||
	>
 | 
			
		||||
		{#if isOverflow}
 | 
			
		||||
		{#if canScrollLeft || canScrollRight}
 | 
			
		||||
			<div class="sticky left-0 z-20">
 | 
			
		||||
				<div class="absolute right-0 top-[6rem] z-20">
 | 
			
		||||
					<button
 | 
			
		||||
						class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
			
		||||
						on:click={scrollRight}
 | 
			
		||||
					>
 | 
			
		||||
						<ChevronRight size="36" /></button
 | 
			
		||||
					>
 | 
			
		||||
				</div>
 | 
			
		||||
 | 
			
		||||
				<div class="absolute left-0 top-[6rem] z-20">
 | 
			
		||||
					<button
 | 
			
		||||
						class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
			
		||||
						on:click={scrollLeft}><ChevronLeft size="36" /></button
 | 
			
		||||
					>
 | 
			
		||||
				</div>
 | 
			
		||||
				{#if canScrollLeft}
 | 
			
		||||
					<div class="absolute left-4 top-[6rem] z-20" transition:fade={{ duration: 200 }}>
 | 
			
		||||
						<button
 | 
			
		||||
							class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
			
		||||
							on:click={scrollLeft}
 | 
			
		||||
						>
 | 
			
		||||
							<ChevronLeft size="36" /></button
 | 
			
		||||
						>
 | 
			
		||||
					</div>
 | 
			
		||||
				{/if}
 | 
			
		||||
				{#if canScrollRight}
 | 
			
		||||
					<div class="absolute right-4 top-[6rem] z-20" transition:fade={{ duration: 200 }}>
 | 
			
		||||
						<button
 | 
			
		||||
							class="rounded-full opacity-50 hover:opacity-100 p-2 border border-gray-500 bg-gray-100 text-gray-500"
 | 
			
		||||
							on:click={scrollRight}
 | 
			
		||||
						>
 | 
			
		||||
							<ChevronRight size="36" /></button
 | 
			
		||||
						>
 | 
			
		||||
					</div>
 | 
			
		||||
				{/if}
 | 
			
		||||
			</div>
 | 
			
		||||
		{/if}
 | 
			
		||||
 | 
			
		||||
		<div class="inline-block" bind:offsetWidth={innerWidth}>
 | 
			
		||||
			{#each memoryLane as memory, i (memory.title)}
 | 
			
		||||
			{#each $memoryStore as memory, i (memory.title)}
 | 
			
		||||
				<button
 | 
			
		||||
					class="memory-card relative inline-block mr-8 rounded-xl aspect-video h-[215px]"
 | 
			
		||||
					on:click={() => goto(`/memory?memory=${i}`)}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user