half broken dropzone component to be used later fr
This commit is contained in:
parent
39005e75e0
commit
7be62fcbb2
4 changed files with 99 additions and 3 deletions
62
src/components/Dropzone.tsx
Normal file
62
src/components/Dropzone.tsx
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import { component$, useVisibleTask$ } from "@builder.io/qwik";
|
||||||
|
import { useDropzone } from "~/hooks/dropzone";
|
||||||
|
import { useNanostore$ } from "~/hooks/nanostores";
|
||||||
|
import { api } from "~/lib/api";
|
||||||
|
import { dashboardFiles } from "~/lib/stores";
|
||||||
|
import { StereoFile } from "~/lib/types";
|
||||||
|
|
||||||
|
export default component$(() => {
|
||||||
|
const dashfiles = useNanostore$<StereoFile[]>(dashboardFiles);
|
||||||
|
|
||||||
|
const {
|
||||||
|
highlight,
|
||||||
|
onDragOver,
|
||||||
|
onDragLeave,
|
||||||
|
onInputChange,
|
||||||
|
triggerFileInput,
|
||||||
|
fileInputRef,
|
||||||
|
} = useDropzone();
|
||||||
|
|
||||||
|
useVisibleTask$(() => {
|
||||||
|
const dropzone = document.getElementById("dropzone");
|
||||||
|
if (!dropzone) return;
|
||||||
|
const handler = async (e: DragEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
highlight.value = false;
|
||||||
|
const files = Array.from(e.dataTransfer?.files || []);
|
||||||
|
for (const file of files) {
|
||||||
|
const name = file.name.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
||||||
|
const f = new File([file], name, { type: file.type });
|
||||||
|
await api.upload(f);
|
||||||
|
dashfiles.value = await api.list();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dropzone.addEventListener("drop", handler);
|
||||||
|
return () => dropzone.removeEventListener("drop", handler);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id="dropzone"
|
||||||
|
preventdefault:drop
|
||||||
|
class={{
|
||||||
|
"relative z-10 border-2 border-dashed rounded-lg p-10 transition-colors": true,
|
||||||
|
"border-white bg-black/20": highlight.value,
|
||||||
|
"border-neutral-800": !highlight.value,
|
||||||
|
}}
|
||||||
|
onDragOver$={onDragOver}
|
||||||
|
onDragLeave$={onDragLeave}
|
||||||
|
onClick$={triggerFileInput}
|
||||||
|
>
|
||||||
|
<p class="text-center text-neutral-500 pointer-events-none">drop file ehre</p>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
ref={fileInputRef}
|
||||||
|
multiple
|
||||||
|
accept="image/*"
|
||||||
|
class="hidden"
|
||||||
|
onChange$={onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
|
@ -65,14 +65,18 @@ export default component$(({ file }: FileProps) => {
|
||||||
return (
|
return (
|
||||||
<div class="rounded-xl bg-neutral-900 flex flex-col group overflow-hidden hover:bg-neutral-800 transition-all duration-200">
|
<div class="rounded-xl bg-neutral-900 flex flex-col group overflow-hidden hover:bg-neutral-800 transition-all duration-200">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<a href={`/api/${file.Owner}/${file.Name}`} target="_blank">
|
<a
|
||||||
|
href={`/api/${file.Owner}/${file.Name}`}
|
||||||
|
target="_blank"
|
||||||
|
class="block w-full h-60 overflow-clip"
|
||||||
|
>
|
||||||
{ (file.Name.endsWith(".png") || file.Name.endsWith(".jpg") || file.Name.endsWith(".jpeg")) && (
|
{ (file.Name.endsWith(".png") || file.Name.endsWith(".jpg") || file.Name.endsWith(".jpeg")) && (
|
||||||
<img
|
<img
|
||||||
width={400}
|
width={400}
|
||||||
height={300}
|
height={300}
|
||||||
src={`/api/${file.Owner}/${file.Name}`}
|
src={`/api/${file.Owner}/${file.Name}`}
|
||||||
alt={file.Name}
|
alt={file.Name}
|
||||||
class="w-full h-60 object-cover bg-neutral-800 flex-grow"
|
class="w-full h-60 object-cover bg-neutral-800 flex-grow group-hover:scale-110 group-hover:saturate-150 transition-all duration-500"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
|
|
28
src/hooks/dropzone.tsx
Normal file
28
src/hooks/dropzone.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import { $, useSignal } from '@builder.io/qwik';
|
||||||
|
|
||||||
|
export const useDropzone = () => {
|
||||||
|
const highlight = useSignal(false);
|
||||||
|
|
||||||
|
const onInputChange = $(async (e: Event) => {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
const fileInputRef = useSignal<HTMLInputElement | undefined>(undefined);
|
||||||
|
|
||||||
|
return {
|
||||||
|
highlight,
|
||||||
|
onDragOver: $((e: DragEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
highlight.value = true;
|
||||||
|
}),
|
||||||
|
onDragLeave: $((e: DragEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
highlight.value = false;
|
||||||
|
}),
|
||||||
|
onInputChange,
|
||||||
|
triggerFileInput: $(() => {
|
||||||
|
fileInputRef.value?.click();
|
||||||
|
}),
|
||||||
|
fileInputRef,
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { component$, useVisibleTask$ } from "@builder.io/qwik";
|
import { component$, useVisibleTask$ } from "@builder.io/qwik";
|
||||||
import { routeLoader$, type DocumentHead } from "@builder.io/qwik-city";
|
import { routeLoader$, type DocumentHead } from "@builder.io/qwik-city";
|
||||||
import Controlbar from "~/components/Controlbar";
|
import Controlbar from "~/components/Controlbar";
|
||||||
|
// import Dropzone from "~/components/Dropzone";
|
||||||
import File from "~/components/File";
|
import File from "~/components/File";
|
||||||
import { SolarUploadLinear, SvgSpinnersBarsRotateFade } from "~/components/Icons";
|
import { SolarUploadLinear, SvgSpinnersBarsRotateFade } from "~/components/Icons";
|
||||||
import { useNanostore$ } from "~/hooks/nanostores";
|
import { useNanostore$ } from "~/hooks/nanostores";
|
||||||
|
@ -28,6 +29,7 @@ export default component$(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{/* <Dropzone /> */}
|
||||||
<Controlbar />
|
<Controlbar />
|
||||||
{!loaded.value ? (
|
{!loaded.value ? (
|
||||||
<div class="absolute w-full h-screen flex justify-center items-center flex-col">
|
<div class="absolute w-full h-screen flex justify-center items-center flex-col">
|
||||||
|
@ -44,7 +46,7 @@ export default component$(() => {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
: (
|
: (
|
||||||
<div class="grid grid-cols-4 gap-4 p-4 mb-18">
|
<div class="grid grid-cols-4 gap-4 p-4 mb-16">
|
||||||
{files.value.map((file) => (
|
{files.value.map((file) => (
|
||||||
<File key={file.Name} file={file} />
|
<File key={file.Name} file={file} />
|
||||||
))}
|
))}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue