mirror of
https://github.com/immich-app/immich.git
synced 2024-11-28 09:33:27 +02:00
feat(web): scrubber label and animation (#13815)
* feat(web): scrubber label and animation * tune x fly in distance * refactor * lint and minor fix * fly height
This commit is contained in:
parent
0d62ff11f1
commit
244c8cb4d4
@ -36,6 +36,7 @@
|
||||
import { page } from '$app/stores';
|
||||
import type { UpdatePayload } from 'vite';
|
||||
import { generateId } from '$lib/utils/generate-id';
|
||||
import { isTimelineScrolling } from '$lib/stores/timeline.store';
|
||||
|
||||
export let isSelectionMode = false;
|
||||
export let singleSelect = false;
|
||||
@ -331,7 +332,17 @@
|
||||
}
|
||||
};
|
||||
|
||||
let scrollObserverTimer: NodeJS.Timeout;
|
||||
|
||||
const _handleTimelineScroll = () => {
|
||||
$isTimelineScrolling = true;
|
||||
if (scrollObserverTimer) {
|
||||
clearTimeout(scrollObserverTimer);
|
||||
}
|
||||
scrollObserverTimer = setTimeout(() => {
|
||||
$isTimelineScrolling = false;
|
||||
}, 1000);
|
||||
|
||||
leadout = false;
|
||||
if ($assetStore.timelineHeight < safeViewport.height * 2) {
|
||||
// edge case - scroll limited due to size of content, must adjust - use the overall percent instead
|
||||
|
@ -1,9 +1,12 @@
|
||||
<script lang="ts">
|
||||
import type { AssetStore, AssetBucket, BucketListener } from '$lib/stores/assets.store';
|
||||
import type { DateTime } from 'luxon';
|
||||
import { DateTime } from 'luxon';
|
||||
import { fromLocalDateTime, type ScrubberListener } from '$lib/utils/timeline-util';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { onMount } from 'svelte';
|
||||
import { isTimelineScrolling } from '$lib/stores/timeline.store';
|
||||
import { parseUtcDate } from '$lib/utils/date-time';
|
||||
import { fly } from 'svelte/transition';
|
||||
|
||||
export let timelineTopOffset = 0;
|
||||
export let timelineBottomOffset = 0;
|
||||
@ -72,6 +75,7 @@
|
||||
$: timelineFullHeight = $assetStore.timelineHeight + timelineTopOffset + timelineBottomOffset;
|
||||
$: relativeTopOffset = toScrollY(timelineTopOffset / timelineFullHeight);
|
||||
$: relativeBottomOffset = toScrollY(timelineBottomOffset / timelineFullHeight);
|
||||
$: formatedDate = scrubBucket?.bucketDate ? parseUtcDate(scrubBucket?.bucketDate).toFormat('MMM yyyy') : '';
|
||||
|
||||
const listener: BucketListener = (event) => {
|
||||
const { type } = event;
|
||||
@ -210,8 +214,9 @@
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
|
||||
<div
|
||||
transition:fly={{ x: 50, duration: 250 }}
|
||||
id="immich-scrubbable-scrollbar"
|
||||
class={`absolute right-0 z-[1] select-none bg-immich-bg hover:cursor-row-resize`}
|
||||
class="absolute right-0 z-[1] select-none bg-immich-bg hover:cursor-row-resize"
|
||||
style:padding-top={HOVER_DATE_HEIGHT + 'px'}
|
||||
style:padding-bottom={HOVER_DATE_HEIGHT + 'px'}
|
||||
class:invisible
|
||||
@ -235,9 +240,20 @@
|
||||
<!-- Scroll Position Indicator Line -->
|
||||
{#if !isDragging}
|
||||
<div
|
||||
class="absolute right-0 h-[2px] w-10 bg-immich-primary dark:bg-immich-dark-primary"
|
||||
class="absolute right-0 {$isTimelineScrolling && formatedDate
|
||||
? 'h-[0px]'
|
||||
: 'h-[2px]'} w-10 bg-immich-primary dark:bg-immich-dark-primary"
|
||||
style:top="{scrollY + HOVER_DATE_HEIGHT}px"
|
||||
/>
|
||||
>
|
||||
{#if $isTimelineScrolling && formatedDate}
|
||||
<p
|
||||
transition:fly={{ y: -15, duration: 350 }}
|
||||
class="truncate opacity-85 pointer-events-none absolute right-0 bottom-0 z-[100] min-w-20 max-w-64 w-fit rounded-tl-md border-b-2 border-immich-primary bg-immich-bg py-1 px-1 text-sm font-medium shadow-[0_0_8px_rgba(0,0,0,0.25)] dark:border-immich-dark-primary dark:bg-immich-dark-gray dark:text-immich-dark-fg"
|
||||
>
|
||||
{formatedDate}
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<div id="lead-in" class="relative" style:height={relativeTopOffset + 'px'} data-label={segments.at(0)?.dateFormatted}>
|
||||
{#if relativeTopOffset > 6}
|
||||
|
3
web/src/lib/stores/timeline.store.ts
Normal file
3
web/src/lib/stores/timeline.store.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export const isTimelineScrolling = writable(false);
|
Loading…
Reference in New Issue
Block a user