Compare commits
No commits in common. "98a582c8d430b3785c40ef31417678f45bd44600" and "c1726f5a3975734b934f078ef49175e2bbaebb1c" have entirely different histories.
98a582c8d4
...
c1726f5a39
10 changed files with 31 additions and 66 deletions
|
@ -1,3 +0,0 @@
|
|||
<svg width="281" height="248" viewBox="0 0 281 248" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.744835 19.1645C0.340705 16.0258 0.876443 12.8377 2.2843 10.0034L6.37392 1.7703C7.01957 0.470487 8.7912 0.269553 9.71155 1.39175L85.375 93.6495H195.875L271.538 1.39175C272.459 0.269551 274.23 0.470487 274.876 1.77029L278.966 10.0034C280.374 12.8377 280.909 16.0258 280.505 19.1645L264.378 144.419C256.8 203.277 206.688 247.35 147.344 247.35H133.906C74.5619 247.35 24.4504 203.277 16.872 144.419L0.744835 19.1645Z" fill="#D9D9D9"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 548 B |
|
@ -1,14 +1,12 @@
|
|||
import { $, component$, noSerialize, NoSerialize, useSignal, useVisibleTask$ } from "@builder.io/qwik";
|
||||
import { useNanostore$ } from "~/hooks/nanostores";
|
||||
import { api } from "~/lib/api";
|
||||
import { areFilesLoaded, dashboardFiles } from "~/lib/stores";
|
||||
import { DashboardFiles } from "~/lib/stores";
|
||||
import { StereoFile } from "~/lib/types";
|
||||
import { SolarUploadLinear, SvgSpinnersBarsRotateFade } from "./Icons";
|
||||
import StereoLogo from "./StereoLogo";
|
||||
import { SolarUploadLinear } from "./Icons";
|
||||
|
||||
export default component$(() => {
|
||||
const loaded = useNanostore$<boolean>(areFilesLoaded);
|
||||
const files = useNanostore$<StereoFile[]>(dashboardFiles);
|
||||
const files = useNanostore$<StereoFile[]>(DashboardFiles);
|
||||
const fileInputRef = useSignal<HTMLInputElement>();
|
||||
const uploadingFile = useSignal<NoSerialize<File> | undefined>();
|
||||
const now = useSignal(new Date());
|
||||
|
@ -27,18 +25,14 @@ export default component$(() => {
|
|||
}
|
||||
|
||||
try {
|
||||
const unsafe = uploadingFile.value as File;
|
||||
const name = unsafe.name.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
||||
const f = new File([unsafe], name, { type: unsafe.type });
|
||||
|
||||
await api.upload(f);
|
||||
await api.upload(uploadingFile.value as File)
|
||||
files.value = await api.list();
|
||||
} catch (error) {
|
||||
console.error("Error uploading file:", error);
|
||||
}
|
||||
})
|
||||
return (
|
||||
<div class="z-[999999999] fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-neutral-700/10 backdrop-blur-3xl w-1/3 p-2 pr-4 rounded-lg flex items-center justify-between">
|
||||
<div class="z-[999999999] fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-neutral-950/50 backdrop-blur-3xl w-1/3 p-2 rounded-lg flex items-center justify-between">
|
||||
<input
|
||||
type="file"
|
||||
ref={fileInputRef}
|
||||
|
@ -49,26 +43,7 @@ export default component$(() => {
|
|||
}}
|
||||
/>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
class="duration-100 hover:bg-white text-white hover:text-black p-2 rounded-lg"
|
||||
onClick$={async () => {
|
||||
loaded.value = false;
|
||||
files.value = await api.list()
|
||||
loaded.value = true;
|
||||
}}
|
||||
>
|
||||
{
|
||||
loaded.value ? (
|
||||
<StereoLogo class="w-6 h-6" />
|
||||
) : (
|
||||
<SvgSpinnersBarsRotateFade class="w-6 h-6" />
|
||||
)
|
||||
}
|
||||
</button>
|
||||
|
||||
<p class="text-white/25 font-light text-xl"> | </p>
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
<button
|
||||
class="duration-100 hover:bg-white text-white hover:text-black p-2 rounded-lg"
|
||||
onClick$={() => { fileInputRef.value?.click() }}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { $, component$ } from "@builder.io/qwik";
|
||||
import { useNanostore$ } from "~/hooks/nanostores";
|
||||
import { api } from "~/lib/api";
|
||||
import { dashboardFiles } from "~/lib/stores";
|
||||
import { DashboardFiles } from "~/lib/stores";
|
||||
import { StereoFile } from "~/lib/types";
|
||||
import { SolarClipboardAddBold, SolarDownloadMinimalisticBold, SolarTrashBin2Bold } from "./Icons";
|
||||
|
||||
|
@ -17,16 +17,16 @@ const formatSize = (bytes: number) => {
|
|||
}
|
||||
|
||||
export default component$(({ file }: FileProps) => {
|
||||
const files = useNanostore$<StereoFile[]>(dashboardFiles);
|
||||
const files = useNanostore$<StereoFile[]>(DashboardFiles);
|
||||
|
||||
const deleteFile = $(async (uid: string, name: string) => {
|
||||
const deleteFile = $(async (id: string) => {
|
||||
if (!confirm("Are you sure you want to delete this file?")) return;
|
||||
console.log(await api.delete(uid, name));
|
||||
console.log(await api.delete(id))
|
||||
files.value = await api.list();
|
||||
});
|
||||
|
||||
const addFileToClipboard = $(async () => {
|
||||
const response = await api.file(file.Name);
|
||||
const response = await api.file(file.ID);
|
||||
const data = await response.blob();
|
||||
let mime = data.type || "application/octet-stream";
|
||||
let clip;
|
||||
|
@ -65,13 +65,13 @@ export default component$(({ file }: FileProps) => {
|
|||
return (
|
||||
<div class="rounded-xl bg-neutral-900 flex flex-col group overflow-hidden hover:bg-neutral-800 transition-all duration-200">
|
||||
<div class="relative">
|
||||
<a href={`/api/${file.Owner}/${file.Name}`} target="_blank">
|
||||
{ (file.Name.endsWith(".png") || file.Name.endsWith(".jpg") || file.Name.endsWith(".jpeg")) && (
|
||||
<a href={`/api/${file.ID}`} target="_blank">
|
||||
{ (file.ID.endsWith(".png") || file.ID.endsWith(".jpg") || file.ID.endsWith(".jpeg")) && (
|
||||
<img
|
||||
width={400}
|
||||
height={300}
|
||||
src={`/api/${file.Owner}/${file.Name}`}
|
||||
alt={file.Name}
|
||||
src={`/api/${file.ID}`}
|
||||
alt={file.ID}
|
||||
class="w-full h-60 object-cover bg-neutral-800 flex-grow"
|
||||
/>
|
||||
)}
|
||||
|
@ -80,7 +80,7 @@ export default component$(({ file }: FileProps) => {
|
|||
<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/75 transition-all duration-200 text-white p-2 rounded-lg active:scale-95"
|
||||
href={`/api/${file.Owner}/${file.Name}`}
|
||||
href={`/api/${file.ID}`}
|
||||
target="_blank"
|
||||
>
|
||||
<SolarDownloadMinimalisticBold class="w-6 h-6"/>
|
||||
|
@ -95,7 +95,7 @@ export default component$(({ file }: FileProps) => {
|
|||
|
||||
<button
|
||||
class="bg-red-600/50 backdrop-blur-lg hover:bg-red-600/75 transition-all duration-200 text-white p-2 rounded-lg active:scale-95"
|
||||
onClick$={async () => await deleteFile(file.Owner, file.Name)}
|
||||
onClick$={async () => await deleteFile(file.ID)}
|
||||
>
|
||||
<SolarTrashBin2Bold class="w-6 h-6"/>
|
||||
</button>
|
||||
|
@ -105,7 +105,7 @@ export default component$(({ file }: FileProps) => {
|
|||
<div class="flex justify-center items-center h-full">
|
||||
<div class="p-4 flex flex-col w-full text-center">
|
||||
<p class="text-lg font-semibold text-white w-full truncate">
|
||||
{ file.Name || "Untitled" }
|
||||
{ file.ID.split("_").slice(1).join("_") || "Untitled" }
|
||||
</p>
|
||||
<div class="flex gap-1 text-sm text-neutral-500 items-center justify-center">
|
||||
<span>{ formatSize(file.Size) }</span>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import { component$, QwikIntrinsicElements } from "@builder.io/qwik";
|
||||
|
||||
export default component$((props: QwikIntrinsicElements['svg']) => {
|
||||
return (
|
||||
<svg width="281" height="248" viewBox="0 0 281 248" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
||||
<path d="M0.744835 19.1645C0.340705 16.0258 0.876443 12.8377 2.2843 10.0034L6.37392 1.7703C7.01957 0.470487 8.7912 0.269553 9.71155 1.39175L85.375 93.6495H195.875L271.538 1.39175C272.459 0.269551 274.23 0.470487 274.876 1.77029L278.966 10.0034C280.374 12.8377 280.909 16.0258 280.505 19.1645L264.378 144.419C256.8 203.277 206.688 247.35 147.344 247.35H133.906C74.5619 247.35 24.4504 203.277 16.872 144.419L0.744835 19.1645Z" fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
})
|
|
@ -10,7 +10,7 @@ import {
|
|||
} from "@builder.io/qwik";
|
||||
import { Atom, WritableAtom } from "nanostores";
|
||||
|
||||
function writeable<T>(store: Atom<T> | WritableAtom<T>): store is WritableAtom<T> {
|
||||
function writeable<T = any>(store: Atom<T> | WritableAtom<T>): store is WritableAtom<T> {
|
||||
return typeof (store as WritableAtom<T>).set === 'function';
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,10 @@ export const api = {
|
|||
formData.append('file', file);
|
||||
return await client.post('upload', { body: formData });
|
||||
},
|
||||
delete: async (uid: string, file: string) => {
|
||||
return await client.delete(`${uid}/${file}`).json();
|
||||
delete: async (file_id: string) => {
|
||||
console.log("Deleting file with ID:", file_id);
|
||||
return await client.delete(`delete`, {
|
||||
json: { file_id }
|
||||
}).json();
|
||||
},
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { atom } from "nanostores";
|
||||
import { StereoFile } from "./types";
|
||||
|
||||
export const areFilesLoaded = atom<boolean>(false);
|
||||
export const dashboardFiles = atom<StereoFile[]>([]);
|
||||
export const DashboardFiles = atom<StereoFile[]>([]);
|
|
@ -1,5 +1,5 @@
|
|||
export type StereoFile = {
|
||||
Name: string;
|
||||
ID: string;
|
||||
Owner: string;
|
||||
CreatedAt: string;
|
||||
Size: number;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { component$, useVisibleTask$ } from "@builder.io/qwik";
|
||||
import { component$, useSignal, useVisibleTask$ } from "@builder.io/qwik";
|
||||
import type { DocumentHead } from "@builder.io/qwik-city";
|
||||
import Controlbar from "~/components/Controlbar";
|
||||
import File from "~/components/File";
|
||||
|
@ -6,14 +6,14 @@ import { SolarUploadLinear, SvgSpinnersBarsRotateFade } from "~/components/Icons
|
|||
import { useNanostore$ } from "~/hooks/nanostores";
|
||||
import { api } from "~/lib/api";
|
||||
import { OAUTH_LINK } from "~/lib/constants";
|
||||
import { areFilesLoaded, dashboardFiles } from "~/lib/stores";
|
||||
import { DashboardFiles } from "~/lib/stores";
|
||||
import { StereoFile } from "~/lib/types";
|
||||
|
||||
// TODO: move this to dashboard/index.tsx
|
||||
|
||||
export default component$(() => {
|
||||
const files = useNanostore$<StereoFile[]>(dashboardFiles);
|
||||
const loaded = useNanostore$<boolean>(areFilesLoaded);
|
||||
const files = useNanostore$<StereoFile[]>(DashboardFiles);
|
||||
const loaded = useSignal(false);
|
||||
|
||||
useVisibleTask$(async () => {
|
||||
loaded.value = false;
|
||||
|
@ -43,7 +43,7 @@ export default component$(() => {
|
|||
: (
|
||||
<div class="grid grid-cols-4 gap-4 p-4 mb-18">
|
||||
{files.value.map((file) => (
|
||||
<File key={file.Name} file={file} />
|
||||
<File key={file.ID} file={file} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue