168 lines
6.4 KiB
Svelte
168 lines
6.4 KiB
Svelte
<script lang="ts">
|
|
import type { FileRecord } from '$lib/types';
|
|
import { formatName, formatSize } from '$lib/format';
|
|
|
|
let {
|
|
file,
|
|
selected,
|
|
onselect,
|
|
onpreview,
|
|
ondownload,
|
|
ondelete
|
|
}: {
|
|
file: FileRecord;
|
|
selected: boolean;
|
|
onselect: () => void;
|
|
onpreview: () => void;
|
|
ondownload: () => void;
|
|
ondelete: () => void;
|
|
} = $props();
|
|
|
|
let confirming = $state(false);
|
|
</script>
|
|
|
|
<div
|
|
role="button"
|
|
tabindex="0"
|
|
onkeydown={(e) => {
|
|
if (e.key === 'Enter') {
|
|
onpreview();
|
|
} else if (e.key === ' ') {
|
|
e.preventDefault();
|
|
onselect();
|
|
}
|
|
}}
|
|
onclick={onselect}
|
|
ondblclick={onpreview}
|
|
class="flex items-stretch border-l transition-all hover:bg-white/2 {selected
|
|
? 'border-sky-400/50 bg-white/2 ring-1 ring-sky-400/50 ring-inset'
|
|
: 'border-sky-200/20 border-l-transparent hover:border-l-sky-400/50'}"
|
|
>
|
|
<span class="flex-1 truncate py-2 pl-6 text-sm font-medium text-white"
|
|
>{formatName(file.name)}</span
|
|
>
|
|
<span class="w-40 py-2 text-sm text-white/40">{formatSize(file.size)}</span>
|
|
<span class="w-48 py-2 text-sm text-white/40">{new Date(file.uploadedAt).toLocaleString()}</span
|
|
>
|
|
<div class="w-px self-stretch bg-sky-200/20"></div>
|
|
<div class="relative flex w-32 items-center justify-center gap-4">
|
|
<!-- Download -->
|
|
<button
|
|
class="cursor-pointer text-white/40 transition-all hover:scale-110 hover:text-emerald-400"
|
|
title="Download"
|
|
onclick={ondownload}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
<polyline points="7 10 12 15 17 10" />
|
|
<line x1="12" y1="15" x2="12" y2="3" />
|
|
</svg>
|
|
</button>
|
|
<!-- TODO: Copy -->
|
|
<button
|
|
class="cursor-pointer text-white/40 transition-all hover:scale-110 hover:text-blue-400"
|
|
title="Copy link"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
|
|
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
|
|
</svg>
|
|
</button>
|
|
<!-- Delete -->
|
|
<div class="relative">
|
|
<button
|
|
class="cursor-pointer text-white/40 transition-all hover:scale-110 hover:text-red-400"
|
|
title="Delete"
|
|
onclick={() => (confirming = true)}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<polyline points="3 6 5 6 21 6" />
|
|
<path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
|
|
<path d="M10 11v6" />
|
|
<path d="M14 11v6" />
|
|
<path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" />
|
|
</svg>
|
|
</button>
|
|
{#if confirming}
|
|
<div class="absolute top-1/2 left-6 z-10 flex -translate-y-1/2 items-center">
|
|
<div
|
|
class="h-0 w-0 border-t-4 border-r-4 border-b-4 border-t-transparent border-r-sky-200/20 border-b-transparent"
|
|
></div>
|
|
<div
|
|
class="flex items-center gap-2 rounded border border-sky-200/20 bg-[#0f1117] px-3 py-2 whitespace-nowrap"
|
|
>
|
|
<span class="text-xs text-white/40">Confirm action</span>
|
|
<button
|
|
class="cursor-pointer text-white/60 transition-colors hover:text-white"
|
|
title="Confirm"
|
|
onclick={() => {
|
|
ondelete();
|
|
confirming = false;
|
|
}}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<polyline points="20 6 9 17 4 12" />
|
|
</svg>
|
|
</button>
|
|
<button
|
|
class="cursor-pointer text-white/60 transition-colors hover:text-white"
|
|
title="Cancel"
|
|
onclick={() => (confirming = false)}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-4 w-4"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2.5"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
>
|
|
<line x1="18" y1="6" x2="6" y2="18" />
|
|
<line x1="6" y1="6" x2="18" y2="18" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
</div>
|