file copying & open in new tab + tailwind-scrollbar
This commit is contained in:
parent
6089c569a1
commit
33c3bd1a2c
7 changed files with 87 additions and 15 deletions
|
@ -1,9 +1,10 @@
|
|||
import { $, component$ } from "@builder.io/qwik";
|
||||
import ky from "ky";
|
||||
import { useNanostore$ } from "~/hooks/nanostores";
|
||||
import { api } from "~/lib/api";
|
||||
import { DashboardFiles } from "~/lib/stores";
|
||||
import { StereoFile } from "~/lib/types";
|
||||
import { SolarTrashBin2Bold } from "./Icons";
|
||||
import { SolarClipboardAddBold, SolarDownloadMinimalisticBold, SolarTrashBin2Bold } from "./Icons";
|
||||
|
||||
type FileProps = {
|
||||
file: StereoFile;
|
||||
|
@ -30,6 +31,19 @@ export default component$(({ file }: FileProps) => {
|
|||
console.log(await api.delete(id))
|
||||
files.value = await api.list();
|
||||
});
|
||||
|
||||
const addFileToClipboard = $(async (base64: string) => {
|
||||
if (!base64) return;
|
||||
try {
|
||||
const blob = await ky.get(`data:image/png;base64,${base64}`).then(res => res.blob());
|
||||
const item = new ClipboardItem({ "image/png": blob });
|
||||
await navigator.clipboard.write([item]);
|
||||
alert("File copied to clipboard!");
|
||||
} catch (error) {
|
||||
console.error("Failed to copy file to clipboard:", error);
|
||||
alert("Failed to copy file to clipboard.");
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="rounded-xl bg-neutral-900 flex flex-col group overflow-hidden hover:bg-neutral-800 transition-all duration-200">
|
||||
|
@ -41,14 +55,29 @@ export default component$(({ file }: FileProps) => {
|
|||
height={300}
|
||||
src={`data:image/png;base64,${file.Base64}`}
|
||||
alt={file.ID}
|
||||
class="w-full h-60 object-cover bg-gray-800 flex-grow"
|
||||
class="w-full h-60 object-cover bg-neutral-800 flex-grow"
|
||||
/>
|
||||
)}
|
||||
</a>
|
||||
|
||||
<div class="absolute bottom-2 right-2 gap-2 z-10 group-hover:flex hidden duration-200 transition-all">
|
||||
<a
|
||||
class="bg-neutral-600/40 backdrop-blur-lg hover:bg-neutral-600/70 transition-all duration-200 text-white p-2 rounded-lg"
|
||||
href={`/api/${file.ID}`}
|
||||
target="_blank"
|
||||
>
|
||||
<SolarDownloadMinimalisticBold class="w-6 h-6"/>
|
||||
</a>
|
||||
|
||||
<button
|
||||
class="duration-100 bg-red-600 hover:bg-white text-white hover:text-black p-2 rounded-lg"
|
||||
class="bg-green-600/50 backdrop-blur-lg hover:bg-green-600/75 transition-all duration-200 text-white p-2 rounded-lg"
|
||||
onClick$={async () => await addFileToClipboard(file.Base64)}
|
||||
>
|
||||
<SolarClipboardAddBold class="w-6 h-6"/>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="bg-red-600/50 backdrop-blur-lg hover:bg-red-600/75 transition-all duration-200 text-white p-2 rounded-lg"
|
||||
onClick$={async () => await deleteFile(file.ID)}
|
||||
>
|
||||
<SolarTrashBin2Bold class="w-6 h-6"/>
|
||||
|
@ -59,9 +88,9 @@ export default component$(({ file }: FileProps) => {
|
|||
<p class="text-lg font-semibold text-white w-full truncate">
|
||||
{ file.ID.split("_").slice(1).join("_") || "Untitled" }
|
||||
</p>
|
||||
<div class="flex gap-1 text-sm text-gray-400 items-center justify-center">
|
||||
<div class="flex gap-1 text-sm text-neutral-400 items-center justify-center">
|
||||
<span>{ formatSize(getBase64Size(file.Base64)) }</span>
|
||||
<span class="text-gray-600">•</span>
|
||||
<span class="text-neutral-600">•</span>
|
||||
<p>Uploaded on { new Date(file.CreatedAt).toLocaleDateString() }</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,4 +11,24 @@ export function SolarTrashBin2Bold(props: QwikIntrinsicElements['svg'], key: str
|
|||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props} key={key}><path fill="currentColor" d="M2.75 6.167c0-.46.345-.834.771-.834h2.665c.529-.015.996-.378 1.176-.916l.03-.095l.115-.372c.07-.228.131-.427.217-.605c.338-.702.964-1.189 1.687-1.314c.184-.031.377-.031.6-.031h3.478c.223 0 .417 0 .6.031c.723.125 1.35.612 1.687 1.314c.086.178.147.377.217.605l.115.372l.03.095c.18.538.74.902 1.27.916h2.57c.427 0 .772.373.772.834S20.405 7 19.979 7H3.52c-.426 0-.771-.373-.771-.833M11.607 22h.787c2.707 0 4.06 0 4.941-.863c.88-.864.97-2.28 1.15-5.111l.26-4.081c.098-1.537.147-2.305-.295-2.792s-1.187-.487-2.679-.487H8.23c-1.491 0-2.237 0-2.679.487s-.392 1.255-.295 2.792l.26 4.08c.18 2.833.27 4.248 1.15 5.112S8.9 22 11.607 22" /></svg>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export function SolarClipboardAddBold(props: QwikIntrinsicElements['svg'], key: string) {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props} key={key}><path fill="currentColor" d="M9.5 2A1.5 1.5 0 0 0 8 3.5v1A1.5 1.5 0 0 0 9.5 6h5A1.5 1.5 0 0 0 16 4.5v-1A1.5 1.5 0 0 0 14.5 2z" /><path fill="currentColor" fill-rule="evenodd" d="M3.879 4.877c.569-.57 1.363-.77 2.621-.84V4.5a3 3 0 0 0 3 3h5a3 3 0 0 0 3-3v-.463c1.258.07 2.052.27 2.621.84C21 5.756 21 7.17 21 9.998v6c0 2.829 0 4.243-.879 5.122c-.878.878-2.293.878-5.121.878H9c-2.828 0-4.243 0-5.121-.878C3 20.24 3 18.827 3 15.998v-6c0-2.828 0-4.242.879-5.121M12.75 11a.75.75 0 0 0-1.5 0v2.25H9a.75.75 0 0 0 0 1.5h2.25V17a.75.75 0 0 0 1.5 0v-2.25H15a.75.75 0 0 0 0-1.5h-2.25z" clip-rule="evenodd" /></svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function SolarLinkRoundBold(props: QwikIntrinsicElements['svg'], key: string) {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props} key={key}><path fill="currentColor" fill-rule="evenodd" d="M1.25 9A6.75 6.75 0 0 1 8 2.25h4a6.75 6.75 0 0 1 0 13.5h-2a.75.75 0 0 1 0-1.5h2a5.25 5.25 0 1 0 0-10.5H8a5.25 5.25 0 0 0-3.913 8.75a.75.75 0 0 1-1.118 1A6.73 6.73 0 0 1 1.25 9M12 9.75a5.25 5.25 0 1 0 0 10.5h4a5.25 5.25 0 0 0 3.913-8.75a.75.75 0 1 1 1.118-1A6.75 6.75 0 0 1 16 21.75h-4a6.75 6.75 0 0 1 0-13.5h2a.75.75 0 0 1 0 1.5z" clip-rule="evenodd" /></svg>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export function SolarDownloadMinimalisticBold(props: QwikIntrinsicElements['svg'], key: string) {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...props} key={key}><path fill="currentColor" d="M12.554 16.506a.75.75 0 0 1-1.107 0l-4-4.375a.75.75 0 0 1 1.107-1.012l2.696 2.95V3a.75.75 0 0 1 1.5 0v11.068l2.697-2.95a.75.75 0 1 1 1.107 1.013z" /><path fill="currentColor" d="M3.75 15a.75.75 0 0 0-1.5 0v.055c0 1.367 0 2.47.117 3.337c.12.9.38 1.658.981 2.26c.602.602 1.36.86 2.26.982c.867.116 1.97.116 3.337.116h6.11c1.367 0 2.47 0 3.337-.116c.9-.122 1.658-.38 2.26-.982s.86-1.36.982-2.26c.116-.867.116-1.97.116-3.337V15a.75.75 0 0 0-1.5 0c0 1.435-.002 2.436-.103 3.192c-.099.734-.28 1.122-.556 1.399c-.277.277-.665.457-1.4.556c-.755.101-1.756.103-3.191.103H9c-1.435 0-2.437-.002-3.192-.103c-.734-.099-1.122-.28-1.399-.556c-.277-.277-.457-.665-.556-1.4c-.101-.755-.103-1.756-.103-3.191" /></svg>
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue