diff --git a/app/data/pinning.ts b/app/data/pinning.ts index d622dd9..fd292b6 100644 --- a/app/data/pinning.ts +++ b/app/data/pinning.ts @@ -1,83 +1,103 @@ -import {PROTOCOL_S5, Sdk} from "@lumeweb/portal-sdk"; -import {useSdk} from "~/components/lib/sdk-context.js"; -import {S5Client} from "@lumeweb/s5-js"; -import {S5Error} from "@lumeweb/s5-js/lib/client.js"; +import { PROTOCOL_S5, Sdk } from "@lumeweb/portal-sdk"; +import { useSdk } from "~/components/lib/sdk-context.js"; +import { S5Client } from "@lumeweb/s5-js"; +import { S5Error } from "@lumeweb/s5-js/lib/client.js"; export interface PinningStatus { - id: string; - progress: number; - status: 'processing' | 'completed'; + id: string; + progress: number; + status: "processing" | "completed"; } // biome-ignore lint/complexity/noStaticOnlyClass: export class PinningProcess { - private static instances: Map = new Map(); + private static instances: Map = new Map(); - private static sdk?: Sdk; + private static sdk?: Sdk; - static async pin(id: string): Promise<{ success: boolean; message: string }> { - const s5 = PinningProcess.sdk?.protocols().get(PROTOCOL_S5)!.getSdk()!; - if (PinningProcess.instances.has(id)) { - return {success: false, message: "ID is already being processed"}; - } + static async pin(id: string): Promise<{ success: boolean; message: string }> { + try { + const s5 = PinningProcess.sdk?.protocols().get("s5")!.getSdk()!; + console.log({ s5 }); + if (PinningProcess.instances.has(id)) { + return { success: false, message: "ID is already being processed" }; + } - const pinningStatus: PinningStatus = {id, progress: 0, status: 'processing'}; - PinningProcess.instances.set(id, pinningStatus); + const pinningStatus: PinningStatus = { + id, + progress: 0, + status: "processing", + }; - await s5.pin(id); + const response = await s5.pin(id); + console.log({ response }); + PinningProcess.instances.set(id, pinningStatus); - return {success: true, message: "Pinning process started"}; + return { success: true, message: "Pinning process started" }; + } catch (e) { + console.error(e); + return { success: false, message: "Pinning process failed" }; + } + } + + static async unpin( + id: string, + ): Promise<{ success: boolean; message: string }> { + if (!PinningProcess.instances.has(id)) { + return { success: false, message: "ID not found or not being processed" }; } - static async unpin(id: string): Promise<{ success: boolean; message: string }> { - if (!PinningProcess.instances.has(id)) { - return {success: false, message: "ID not found or not being processed"}; - } + await PinningProcess.sdk + ?.protocols() + .get(PROTOCOL_S5)! + .getSdk() + .unpin(id); - await PinningProcess.sdk?.protocols().get(PROTOCOL_S5)!.getSdk().unpin(id); + return { success: true, message: "Pinning process removed" }; + } - return {success: true, message: "Pinning process removed"} + static *pollAllProgress(): Generator { + let allStatuses = Array.from(PinningProcess.instances.values()); + let inProgress = allStatuses.some((status) => { + PinningProcess.checkStatus(status.id); + return status.status !== "completed"; + }); + + while (inProgress) { + yield allStatuses; + allStatuses = Array.from(PinningProcess.instances.values()); + inProgress = allStatuses.some((status) => { + PinningProcess.checkStatus(status.id); + return status.status !== "completed"; + }); } - static* pollAllProgress(): Generator { - let allStatuses = Array.from(PinningProcess.instances.values()); - let inProgress = allStatuses.some(status => { - PinningProcess.checkStatus(status.id); - return status.status !== 'completed'; - }); + yield allStatuses ?? []; // Yield the final statuses + } - while (inProgress) { - yield allStatuses; - allStatuses = Array.from(PinningProcess.instances.values()); - inProgress = allStatuses.some(status => { - PinningProcess.checkStatus(status.id); - return status.status !== 'completed'; - }); - } + private static async checkStatus(id: string) { + const s5 = PinningProcess.sdk + ?.protocols() + .get(PROTOCOL_S5)! + .getSdk()!; + try { + const ret = await s5.pinStatus(id); + const status = PinningProcess.instances.get(id); + if (!status) { + return; + } - yield allStatuses ?? []; // Yield the final statuses + status.progress = ret.progress; + status.status = ret.status as any; + } catch (e) { + if ((e as S5Error).statusCode == 404) { + PinningProcess.instances.delete(id); + } + return; } + } - private static async checkStatus(id: string) { - const s5 = PinningProcess.sdk?.protocols().get(PROTOCOL_S5)!.getSdk()!; - try { - const ret = await s5.pinStatus(id); - const status = PinningProcess.instances.get(id); - if (!status) { - return; - } - - status.progress = ret.progress; - status.status = ret.status as any; - } catch (e) { - if ((e as S5Error).statusCode == 404) { - PinningProcess.instances.delete(id); - } - return - } - } - - public static setupSdk(sdk: Sdk) { - PinningProcess.sdk = sdk; - } + public static setupSdk(sdk: Sdk) { + PinningProcess.sdk = sdk; + } } diff --git a/app/hooks/usePinning.ts b/app/hooks/usePinning.ts index 9b4c638..fe704ea 100644 --- a/app/hooks/usePinning.ts +++ b/app/hooks/usePinning.ts @@ -21,9 +21,11 @@ export const usePinning = () => { message: `Error pinning ${cid}`, description: response.message, }); + return Promise.reject(response); } - + queryClient.invalidateQueries({ queryKey: ["pin-progress", "file"] }); + return Promise.resolve(response); }, }); @@ -39,8 +41,10 @@ export const usePinning = () => { message: `Error removing ${cid}`, description: response.message, }); + return Promise.reject(response); } queryClient.invalidateQueries({ queryKey: ["pin-progress"] }); + return Promise.resolve(response); }, }); diff --git a/app/routes/file-manager/columns.tsx b/app/routes/file-manager/columns.tsx index a8e7df3..20b5920 100644 --- a/app/routes/file-manager/columns.tsx +++ b/app/routes/file-manager/columns.tsx @@ -75,29 +75,32 @@ export const columns: ColumnDef[] = [ header: () => null, size: 20, cell: ({ row }) => { - const {unpin} = usePinning(); + const { unpin } = usePinning(); return ( -
- - - - - - - { - unpin(row.getValue("cid")) - }}> - - Delete - - - - -
- )}, +
+ + + + + + + { + unpin(row.getValue("cid")); + }}> + + Delete + + + + +
+ ); + }, }, ]; diff --git a/app/routes/file-manager/index.tsx b/app/routes/file-manager/index.tsx index 83e1ebf..dca42a1 100644 --- a/app/routes/file-manager/index.tsx +++ b/app/routes/file-manager/index.tsx @@ -112,7 +112,7 @@ const PinFilesSchema = z.object({ }); const PinFilesForm = ({ close }: { close: () => void }) => { - const { bulkPin, pinStatus } = usePinning(); + const { bulkPin, pinStatus, pinData } = usePinning(); const [form, fields] = useForm({ id: "pin-files", constraint: getZodConstraint(PinFilesSchema), @@ -130,6 +130,8 @@ const PinFilesForm = ({ close }: { close: () => void }) => { }, }); + console.log({pinStatus, pinData}) + useEffect(() => { if (pinStatus === "success") { close(); @@ -148,7 +150,7 @@ const PinFilesForm = ({ close }: { close: () => void }) => { placeholder: "Comma separated CIDs", }} labelProps={{ htmlFor: "cids", children: "Content to Pin" }} - errors={fields.cids.errors} + errors={fields.cids.errors || pinStatus === "error" ? ["An error occurred, please try again"] : []} />