<script lang="ts"> import type { PageFragment } from '$gql/graphql'; import { getSelectionContext } from '$lib/Selection'; import SelectionOverlay from '$lib/selection/SelectionOverlay.svelte'; import { src } from '$lib/Utils'; import { createEventDispatcher } from 'svelte'; export let page: PageFragment; export let index: number; const selection = getSelectionContext<PageFragment>(); let span: 'single' | 'double' | 'triple'; $: page.image.aspectRatio, updateSpan(); function updateSpan() { const aspectRatio = page.image.aspectRatio; if (aspectRatio <= 1) { span = 'single'; } else if (aspectRatio > 1 && aspectRatio <= 2) { span = 'double'; } else if (aspectRatio > 2) { span = 'triple'; } } const dispatch = createEventDispatcher<{ open: number; cover: number }>(); function press(event: MouseEvent | KeyboardEvent) { if (event instanceof KeyboardEvent && event.key !== 'Enter') { return; } if ($selection.active) { if (event.ctrlKey) { dispatch('open', index); } else if (selectable) { $selection = $selection.update(index, event.shiftKey); } } else if (event.ctrlKey) { dispatch('cover', page.id); } else { dispatch('open', index); } event.preventDefault(); } $: selectable = $selection.selectable(page); $: dim = $selection.active && !selectable; $: selected = $selection.contains(page.id); </script> <div class:dim role="button" tabindex="0" class="{span} focus-thick focus-blue relative overflow-hidden rounded" on:click={press} on:keydown={press} > <SelectionOverlay position="top" {selected} /> <img class="h-full w-full object-cover object-[center_top] transition-opacity" loading="lazy" alt="" width={page.image.width} height={page.image.height} src={src(page.image)} title={`${page.path} (${page.image.width} x ${page.image.height})`} /> </div> <style> .dim { cursor: not-allowed; } .dim > img { opacity: 0.2; filter: grayscale(1); } .double { grid-column: span 2; } .triple { grid-column: span 3; } </style>