Spaces:
Paused
Paused
| <script lang="ts"> | |
| import { t } from "$lib/i18n/translations"; | |
| import { downloadFile } from "$lib/download"; | |
| import type { DialogPickerItem } from "$lib/types/dialog"; | |
| import Skeleton from "$components/misc/Skeleton.svelte"; | |
| import IconMovie from "@tabler/icons-svelte/IconMovie.svelte"; | |
| import IconPhoto from "@tabler/icons-svelte/IconPhoto.svelte"; | |
| import IconGif from "@tabler/icons-svelte/IconGif.svelte"; | |
| export let item: DialogPickerItem; | |
| export let number: number; | |
| let imageLoaded = false; | |
| let validUrl = false; | |
| try { | |
| new URL(item.url); | |
| validUrl = true; | |
| } catch {} | |
| const isTunnel = validUrl && new URL(item.url).pathname === "/tunnel"; | |
| $: itemType = item.type ?? "photo"; | |
| </script> | |
| <button | |
| class="picker-item" | |
| on:click={() => { | |
| if (validUrl) { | |
| downloadFile({ | |
| url: item.url, | |
| urlType: isTunnel ? "tunnel" : "redirect", | |
| }); | |
| } | |
| }} | |
| > | |
| <div class="picker-type"> | |
| {#if itemType === "video"} | |
| <IconMovie /> | |
| {:else if itemType === "gif"} | |
| <IconGif /> | |
| {:else} | |
| <IconPhoto /> | |
| {/if} | |
| </div> | |
| <img | |
| class="picker-image" | |
| src={item.thumb ?? item.url} | |
| class:loading={!imageLoaded} | |
| class:video-thumbnail={["video", "gif"].includes(itemType)} | |
| on:load={() => (imageLoaded = true)} | |
| alt="{$t(`a11y.dialog.picker.item.${itemType}`)} {number}" | |
| /> | |
| <Skeleton class="picker-image elevated" hidden={imageLoaded} /> | |
| </button> | |
| <style> | |
| .picker-item { | |
| position: relative; | |
| background: none; | |
| padding: 2px; | |
| box-shadow: none; | |
| border-radius: calc(var(--border-radius) / 2 + 2px); | |
| } | |
| :global(.picker-image) { | |
| display: block; | |
| width: 100%; | |
| height: 100%; | |
| aspect-ratio: 1/1; | |
| pointer-events: all; | |
| object-fit: cover; | |
| border-radius: calc(var(--border-radius) / 2); | |
| } | |
| .picker-image.loading { | |
| display: none; | |
| } | |
| .picker-image.video-thumbnail { | |
| pointer-events: none; | |
| } | |
| :global(.picker-item:active .picker-image) { | |
| opacity: 0.7; | |
| } | |
| @media (hover: hover) { | |
| :global(.picker-item:hover .picker-image) { | |
| opacity: 0.7; | |
| } | |
| } | |
| .picker-type { | |
| position: absolute; | |
| color: var(--white); | |
| background: rgba(0, 0, 0, 0.5); | |
| width: 24px; | |
| height: 24px; | |
| z-index: 9; | |
| display: flex; | |
| flex-direction: row; | |
| align-items: center; | |
| justify-content: center; | |
| top: 6px; | |
| left: 6px; | |
| border-radius: 6px; | |
| pointer-events: none; | |
| } | |
| .picker-type :global(svg) { | |
| width: 22px; | |
| height: 22px; | |
| } | |
| </style> | |