Spaces:
Sleeping
Sleeping
File size: 2,864 Bytes
43a06dc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
<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>
|