diff --git a/src/components/FileCellRender/FileCell.tsx b/src/components/FileCellRender/FileCell.tsx index 07c699a..8cf0484 100644 --- a/src/components/FileCellRender/FileCell.tsx +++ b/src/components/FileCellRender/FileCell.tsx @@ -7,6 +7,7 @@ import { import "./FileCell.css"; import { WebStorage } from "../../utils/web-storage"; import { CodexDataContent } from "@codex-storage/sdk-js"; +import { FilesUtils } from "../Files/files.utils"; type FileMetadata = { mimetype: string | null; @@ -37,11 +38,10 @@ export function FileCell({ requestId, purchaseCid, data, onMetadata }: Props) { const content = data.find((m) => m.cid === cid); if (content) { - const { - filename = "-", - mimetype = "application/octet-stream", - uploadedAt = 0, - } = content.manifest; + const { filename = "-", mimetype = "application/octet-stream" } = + content.manifest; + const uploadedAt = FilesUtils.getUploadedAt(content.cid); + setMetadata({ filename, mimetype, diff --git a/src/components/Files/FileDetails.tsx b/src/components/Files/FileDetails.tsx index 8d0b1d0..1c254e3 100644 --- a/src/components/Files/FileDetails.tsx +++ b/src/components/Files/FileDetails.tsx @@ -117,7 +117,7 @@ export function FileDetails({ onClose, details }: Props) {

Date:

{FilesUtils.formatDate( - details.manifest.uploadedAt + FilesUtils.getUploadedAt(details.cid) ).toString()}

diff --git a/src/components/Files/Files.tsx b/src/components/Files/Files.tsx index 172e727..23a9f2e 100644 --- a/src/components/Files/Files.tsx +++ b/src/components/Files/Files.tsx @@ -166,7 +166,7 @@ export function Files({ limit }: Props) { , {Bytes.pretty(c.manifest.datasetSize)}, - {FilesUtils.formatDate(c.manifest.uploadedAt).toString()} + {FilesUtils.formatDate(FilesUtils.getUploadedAt(c.cid)).toString()} , - (a: CodexDataContent, b: CodexDataContent) => { - const { manifest: { filename: afilename } } = a - const { manifest: { filename: bfilename } } = b + sortByName: + (state: TabSortState) => (a: CodexDataContent, b: CodexDataContent) => { + const { + manifest: { filename: afilename }, + } = a; + const { + manifest: { filename: bfilename }, + } = b; return state === "desc" ? (bfilename || "") - .toLocaleLowerCase() - .localeCompare((afilename || "").toLocaleLowerCase()) + .toLocaleLowerCase() + .localeCompare((afilename || "").toLocaleLowerCase()) : (afilename || "") - .toLocaleLowerCase() - .localeCompare((bfilename || "").toLocaleLowerCase()) + .toLocaleLowerCase() + .localeCompare((bfilename || "").toLocaleLowerCase()); }, - sortBySize: (state: TabSortState) => - (a: CodexDataContent, b: CodexDataContent) => state === "desc" - ? b.manifest.datasetSize - a.manifest.datasetSize - : a.manifest.datasetSize - b.manifest.datasetSize - , - sortByDate: (state: TabSortState) => - (a: CodexDataContent, b: CodexDataContent) => state === "desc" - ? new Date(b.manifest.uploadedAt).getTime() - - new Date(a.manifest.uploadedAt).getTime() - : new Date(a.manifest.uploadedAt).getTime() - - new Date(b.manifest.uploadedAt).getTime() - , - removeCidFromFolder(folders: [string, string[]][], folder: string, cid: string): [string, string[]][] { + sortBySize: + (state: TabSortState) => (a: CodexDataContent, b: CodexDataContent) => + state === "desc" + ? b.manifest.datasetSize - a.manifest.datasetSize + : a.manifest.datasetSize - b.manifest.datasetSize, + sortByDate: + (state: TabSortState) => (a: CodexDataContent, b: CodexDataContent) => { + const aUploadedAt = FilesUtils.getUploadedAt(a.cid); + const bUploadedAt = FilesUtils.getUploadedAt(b.cid); + + return state === "desc" + ? new Date(bUploadedAt).getTime() - new Date(aUploadedAt).getTime() + : new Date(bUploadedAt).getTime() - new Date(aUploadedAt).getTime(); + }, + + removeCidFromFolder( + folders: [string, string[]][], + folder: string, + cid: string + ): [string, string[]][] { return folders.map(([name, files]) => - name === folder - ? [name, files.filter((id) => id !== cid)] - : [name, files] - ) + name === folder ? [name, files.filter((id) => id !== cid)] : [name, files] + ); }, - addCidToFolder(folders: [string, string[]][], folder: string, cid: string): [string, string[]][] { + addCidToFolder( + folders: [string, string[]][], + folder: string, + cid: string + ): [string, string[]][] { return folders.map(([name, files]) => name === folder ? [name, [...files, cid]] : [name, files] - ) + ); }, exists(folders: [string, string[]][], name: string) { - return !!folders.find(([folder]) => folder === name) + return !!folders.find(([folder]) => folder === name); }, - toggleFilters: (filters: string[], filter: string) => filters.includes(filter) - ? filters.filter((f) => f !== filter) - : [...filters, filter], - listInFolder(files: CodexDataContent[], folders: [string, string[]][], index: number) { + toggleFilters: (filters: string[], filter: string) => + filters.includes(filter) + ? filters.filter((f) => f !== filter) + : [...filters, filter], + listInFolder( + files: CodexDataContent[], + folders: [string, string[]][], + index: number + ) { return index === 0 ? files : files.filter((file) => folders[index - 1][1].includes(file.cid)); }, applyFilters(files: CodexDataContent[], filters: string[]) { return files.filter( - (file) => filters.length === 0 || filters.includes(this.type(file.manifest.mimetype)) - ) + (file) => + filters.length === 0 || + filters.includes(this.type(file.manifest.mimetype)) + ); }, formatDate(date: number) { if (!date) { @@ -99,7 +119,14 @@ export const FilesUtils = { dateStyle: "medium", timeStyle: "short", }).format(new Date(date * 1000)); - } + }, + getUploadedAt(key: string) { + return parseInt(localStorage.getItem(key + "-uploadedAt") || "0", 10); + }, + + setUploadedAt(key: string, value: number) { + localStorage.setItem(key + "-uploadedAt", value.toString()); + }, }; export type CodexFileMetadata = { diff --git a/src/components/ManifestFetch/ManifestFetch.tsx b/src/components/ManifestFetch/ManifestFetch.tsx index 082f1a2..c611cad 100644 --- a/src/components/ManifestFetch/ManifestFetch.tsx +++ b/src/components/ManifestFetch/ManifestFetch.tsx @@ -11,6 +11,17 @@ export function ManifestFetch() { const { refetch } = useQuery({ queryFn: () => { + CodexSdk.data() + .networkDownload(cid) + .then((s) => { + if (s.error === false) { + setCid(""); + queryClient.invalidateQueries({ queryKey: ["cids"] }); + console.info("Done"); + } + return Promises.rejectOnError(s); + }); + return CodexSdk.data() .fetchManifest(cid) .then((s) => { diff --git a/src/components/StorageRequestSetup/StorageRequestFileChooser.tsx b/src/components/StorageRequestSetup/StorageRequestFileChooser.tsx index 9f934ae..28bc2b1 100644 --- a/src/components/StorageRequestSetup/StorageRequestFileChooser.tsx +++ b/src/components/StorageRequestSetup/StorageRequestFileChooser.tsx @@ -12,6 +12,7 @@ import { StorageRequestComponentProps } from "./types"; import { useQueryClient } from "@tanstack/react-query"; import ChooseCidIcon from "../../assets/icons/choose-cid.svg?react"; import UploadIcon from "../../assets/icons/upload.svg?react"; +import { FilesUtils } from "../Files/files.utils"; export function StorageRequestFileChooser({ storageRequest, @@ -39,6 +40,8 @@ export function StorageRequestFileChooser({ }; const onSuccess = (data: string) => { + FilesUtils.setUploadedAt(data, Date.now()); + queryClient.invalidateQueries({ queryKey: ["cids"] }); onStorageRequestChange({ cid: data }); diff --git a/src/components/UploadCard/UploadCard.tsx b/src/components/UploadCard/UploadCard.tsx index a437007..b923e58 100644 --- a/src/components/UploadCard/UploadCard.tsx +++ b/src/components/UploadCard/UploadCard.tsx @@ -2,11 +2,13 @@ import { Upload } from "@codex-storage/marketplace-ui-components"; import { CodexSdk } from "../../sdk/codex"; import { useQueryClient } from "@tanstack/react-query"; import UploadIcon from "../../assets/icons/upload.svg?react"; +import { FilesUtils } from "../Files/files.utils"; export function UploadCard() { const queryClient = useQueryClient(); - const onSuccess = () => { + const onSuccess = (cid: string) => { + FilesUtils.setUploadedAt(cid, Date.now()); queryClient.invalidateQueries({ queryKey: ["cids"] }); }; diff --git a/src/hooks/useData.tsx b/src/hooks/useData.tsx index 19e7b52..a2865f1 100644 --- a/src/hooks/useData.tsx +++ b/src/hooks/useData.tsx @@ -2,6 +2,7 @@ import { useQuery } from "@tanstack/react-query"; import { CodexSdk } from "../sdk/codex"; import { CodexDataResponse } from "@codex-storage/sdk-js"; import { Promises } from "../utils/promises"; +import { FilesUtils } from "../components/Files/files.utils"; export function useData() { const { data = { content: [] } satisfies CodexDataResponse } = @@ -29,5 +30,8 @@ export function useData() { throwOnError: true, }); - return data.content; + return data.content.map((c) => ({ + ...c, + uploadedAt: FilesUtils.getUploadedAt(c.cid), + })); } diff --git a/src/utils/web-storage.ts b/src/utils/web-storage.ts index 4136c5b..cc37db0 100644 --- a/src/utils/web-storage.ts +++ b/src/utils/web-storage.ts @@ -1,6 +1,5 @@ import { createStore, del, entries, get, set } from "idb-keyval"; - export const WebStorage = { set(key: string, value: unknown) { return set(key, value); @@ -16,27 +15,27 @@ export const WebStorage = { onBoarding: { getStep() { - return parseInt(localStorage.getItem("onboarding-step") || "0", 10) + return parseInt(localStorage.getItem("onboarding-step") || "0", 10); }, setStep(step: number) { - localStorage.setItem("onboarding-step", step.toString()) + localStorage.setItem("onboarding-step", step.toString()); }, setDisplayName(displayName: string) { - localStorage.setItem("display-name", displayName) + localStorage.setItem("display-name", displayName); }, getDisplayName() { - return localStorage.getItem("display-name") || "" + return localStorage.getItem("display-name") || ""; }, setEmoji(emoji: string) { - localStorage.setItem("emoji", emoji) + localStorage.setItem("emoji", emoji); }, getEmoji() { - return localStorage.getItem("emoji") || "🤖" + return localStorage.getItem("emoji") || "🤖"; }, }, @@ -48,33 +47,35 @@ export const WebStorage = { }, async list(): Promise<[string, string[]][]> { - const items = await entries(this.store) || [] + const items = (await entries(this.store)) || []; if (items.length == 0) { - return [["Favorites", []]] + return [["Favorites", []]]; } if (items[0][0] !== "Favorites") { - return [["Favorites", []], ...items] + return [["Favorites", []], ...items]; } - - return items + return items; }, delete(key: string) { return del(key, this.store); }, async addFile(folder: string, cid: string) { - const files = await get(folder, this.store) || [] + const files = (await get(folder, this.store)) || []; - return set(folder, [...files, cid], this.store) + return set(folder, [...files, cid], this.store); }, async deleteFile(folder: string, cid: string) { - const files = await get(folder, this.store) || [] - - return set(folder, files.filter(item => item !== cid), this.store) + const files = (await get(folder, this.store)) || []; + return set( + folder, + files.filter((item) => item !== cid), + this.store + ); }, }, @@ -97,7 +98,6 @@ export const WebStorage = { purchases: { store: createStore("purchases", "purchases"), - async get(key: string) { return get(key, this.store); }, @@ -120,6 +120,6 @@ export const WebStorage = { async set(key: string, date: string) { return set(key, date, this.store); }, - } - } + }, + }, };