um
This commit is contained in:
parent
9240263490
commit
5e5fc372cc
3 changed files with 94 additions and 73 deletions
|
@ -8,7 +8,13 @@ export const client = ky.create({
|
|||
|
||||
export const api = {
|
||||
file: async (uid: string) => await client.get<Blob>(uid),
|
||||
list: async () => await client.get('list').json<StereoFile[]>(),
|
||||
list: async (page?: number, size?: number) => {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (page !== undefined) searchParams.append('page', String(page));
|
||||
if (size !== undefined) searchParams.append('size', String(size));
|
||||
|
||||
return await client.get('list', { searchParams }).json<StereoFile[]>();
|
||||
},
|
||||
upload: async (file: File) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { RequestEvent, RequestHandler } from '@builder.io/qwik-city';
|
||||
|
||||
const proxy = async ({ send, url, pathname, request }: RequestEvent) => {
|
||||
const targetUrl = new URL(`http://localhost:8081${pathname}`, url);
|
||||
const targetUrl = new URL(`http://localhost:8081${pathname}${url.search}`, url);
|
||||
const headers = new Headers(request.headers);
|
||||
|
||||
const fetchOptions: RequestInit = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { component$, Signal, useSignal, useTask$, useVisibleTask$ } from "@builder.io/qwik";
|
||||
import { $, component$, Signal, useSignal, useTask$, useVisibleTask$ } from "@builder.io/qwik";
|
||||
import { routeLoader$, type DocumentHead } from "@builder.io/qwik-city";
|
||||
import Actionbar from "~/components/dashboard/Actionbar";
|
||||
import Settings from "~/components/dashboard/Settings";
|
||||
|
@ -35,7 +35,7 @@ export default component$(() => {
|
|||
<Actionbar />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
const formatSize = (bytes: number) => {
|
||||
|
@ -50,81 +50,96 @@ const Files = component$<{
|
|||
files: Signal<StereoFile[]>;
|
||||
loaded: Signal<boolean>;
|
||||
}>(({ files }) => {
|
||||
const File = component$(({ file }: { file: StereoFile }) => {
|
||||
const Preview = component$(() => {
|
||||
type FileType = "image" | "video" | "audio" | "other";
|
||||
const fileType: Signal<FileType> = useSignal<FileType>("other");
|
||||
const type = file.Mime.split("/")[1];
|
||||
useTask$(() => {
|
||||
if (["jpeg", "jpg", "png", "gif", "webp"].includes(type)) fileType.value = "image";
|
||||
else if (["mp4", "webm", "ogg", "avi", "mov"].includes(type)) fileType.value = "video";
|
||||
else if (["mp3", "wav", "flac", "aac"].includes(type)) fileType.value = "audio";
|
||||
else fileType.value = "other";
|
||||
});
|
||||
return (
|
||||
<div class="w-full h-max object-cover flex-grow relative overflow-clip">
|
||||
{fileType.value === "image" && (
|
||||
// eslint-disable-next-line qwik/jsx-img
|
||||
<img
|
||||
width={400}
|
||||
src={`/api/${file.ID}`}
|
||||
alt={file.Name}
|
||||
class="w-full min-h-30 object-cover flex-grow hover:scale-[102.5%] transition-all duration-500"
|
||||
/>
|
||||
)}
|
||||
{fileType.value === "video" && (
|
||||
<video
|
||||
width={400}
|
||||
src={`/api/${file.ID}`}
|
||||
controls
|
||||
class="w-full min-h-30 object-cover flex-grow hover:scale-[102.5%] transition-all duration-500"
|
||||
/>
|
||||
)}
|
||||
{fileType.value === "audio" && (
|
||||
<audio
|
||||
src={`/api/${file.ID}`}
|
||||
controls
|
||||
class="w-full min-h-30 object-cover flex-grow hover:scale-[102.5%] transition-all duration-500"
|
||||
/>
|
||||
)}
|
||||
{fileType.value === "other" && (
|
||||
<div class="w-full min-h-30 flex items-center justify-center bg-gray-200 text-gray-500">
|
||||
<p>Unsupported file type</p>
|
||||
const File = component$(({ file }: { file: StereoFile }) => {
|
||||
const Preview = component$(() => {
|
||||
type FileType = "image" | "video" | "audio" | "other";
|
||||
const fileType: Signal<FileType> = useSignal<FileType>("other");
|
||||
const type = file.Mime.split("/")[1];
|
||||
|
||||
useTask$(() => {
|
||||
if (["jpeg", "jpg", "png", "gif", "webp"].includes(type)) fileType.value = "image";
|
||||
else if (["mp4", "webm", "ogg", "avi", "mov"].includes(type)) fileType.value = "video";
|
||||
else if (["mp3", "wav", "flac", "aac"].includes(type)) fileType.value = "audio";
|
||||
else fileType.value = "other";
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="w-full h-max object-cover flex-grow relative overflow-clip">
|
||||
{fileType.value === "image" && (
|
||||
// eslint-disable-next-line qwik/jsx-img
|
||||
<img
|
||||
width={400}
|
||||
src={`/api/${file.ID}`}
|
||||
alt={file.Name}
|
||||
class="w-full min-h-30 object-cover flex-grow hover:scale-[102.5%] transition-all duration-500"
|
||||
/>
|
||||
)}
|
||||
{fileType.value === "video" && (
|
||||
<video
|
||||
width={400}
|
||||
src={`/api/${file.ID}`}
|
||||
controls
|
||||
class="w-full min-h-30 object-cover flex-grow hover:scale-[102.5%] transition-all duration-500"
|
||||
/>
|
||||
)}
|
||||
{fileType.value === "audio" && (
|
||||
<audio
|
||||
src={`/api/${file.ID}`}
|
||||
controls
|
||||
class="w-full min-h-30 object-cover flex-grow hover:scale-[102.5%] transition-all duration-500"
|
||||
/>
|
||||
)}
|
||||
{fileType.value === "other" && (
|
||||
<div class="w-full min-h-30 flex items-center justify-center bg-gray-200 text-gray-500">
|
||||
<p>Unsupported file type</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(180deg, rgba(255, 38, 78, 0.00) 57.21%, rgba(255, 38, 78, 0.17) 100%); ",
|
||||
boxShadow: "0px 4px 21.2px 2px rgba(255, 38, 78, 0.05)",
|
||||
}}
|
||||
class="transition-all rounded-3xl flex flex-col overflow-clip items-center justify-center mb-4 break-inside-avoid"
|
||||
>
|
||||
<Preview />
|
||||
<div class="flex flex-col items-center justify-center text-center w-full h-full p-5">
|
||||
<p class="text-xl truncate w-full">{file.Name}</p>
|
||||
<p class="text-stereo/50 text-lg">
|
||||
{formatSize(file.Size)}
|
||||
<span class="text-stereo/40"> • </span>
|
||||
Uploaded on {new Date(file.CreatedAt).toLocaleDateString()}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
const loadingMore = useSignal(false);
|
||||
|
||||
const onScroll = $(async (e: Event) => {
|
||||
const element = e.target as HTMLElement;
|
||||
if (!element) return;
|
||||
|
||||
const isAtBottom = element.scrollHeight - element.scrollTop - element.clientHeight < threshold;
|
||||
if (isAtBottom) {
|
||||
console.log("Loading more files...");
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(180deg, rgba(255, 38, 78, 0.00) 57.21%, rgba(255, 38, 78, 0.17) 100%); ",
|
||||
boxShadow: "0px 4px 21.2px 2px rgba(255, 38, 78, 0.05)",
|
||||
}}
|
||||
class="transition-all rounded-3xl flex flex-col overflow-clip items-center justify-center mb-4 break-inside-avoid"
|
||||
>
|
||||
<Preview />
|
||||
<div class="flex flex-col items-center justify-center text-center w-full h-full p-5">
|
||||
<p class="text-xl truncate w-full">{file.Name}</p>
|
||||
<p class="text-stereo/50 text-lg">
|
||||
{formatSize(file.Size)}
|
||||
<span class="text-stereo/40"> • </span>
|
||||
Uploaded on {new Date(file.CreatedAt).toLocaleDateString()}
|
||||
</p>
|
||||
<div class="px-2 mb-6 flex-grow overflow-y-auto mask-clip-content rounded-3xl" onScroll$={onScroll}>
|
||||
<div class="w-full columns-1 md:columns-2 lg:columns-4 gap-2 space-y-2">
|
||||
{files.value.map((file) => (
|
||||
<File key={file.ID} file={file} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div class="px-2 mb-6 flex-grow overflow-y-auto mask-clip-content rounded-3xl">
|
||||
<div class="w-full columns-1 md:columns-2 lg:columns-4 gap-2 space-y-2">
|
||||
{files.value.map((file) => (
|
||||
<File key={file.ID} file={file} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const head: DocumentHead = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue