Use local uploadedAt date

This commit is contained in:
Arnaud 2025-02-07 15:35:23 +01:00
parent 0e720ce59a
commit 6a0f2f8f99
No known key found for this signature in database
GPG Key ID: 69D6CE281FCAE663
9 changed files with 116 additions and 69 deletions

View File

@ -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,

View File

@ -117,7 +117,7 @@ export function FileDetails({ onClose, details }: Props) {
<p>Date:</p>
<p>
{FilesUtils.formatDate(
details.manifest.uploadedAt
FilesUtils.getUploadedAt(details.cid)
).toString()}
</p>
</li>

View File

@ -166,7 +166,7 @@ export function Files({ limit }: Props) {
<FileCell content={c}></FileCell>,
<Cell>{Bytes.pretty(c.manifest.datasetSize)}</Cell>,
<Cell>
{FilesUtils.formatDate(c.manifest.uploadedAt).toString()}
{FilesUtils.formatDate(FilesUtils.getUploadedAt(c.cid)).toString()}
</Cell>,
<FileActions
content={c}

View File

@ -20,75 +20,95 @@ export const FilesUtils = {
return !!type && type.startsWith("video");
},
isArchive(mimetype: string | null) {
return !!mimetype && archiveMimetypes.includes(mimetype)
return !!mimetype && archiveMimetypes.includes(mimetype);
},
type(mimetype: string | null) {
if (FilesUtils.isArchive(mimetype)) {
return "archive"
return "archive";
}
if (FilesUtils.isVideo(mimetype)) {
return "video"
return "video";
}
if (FilesUtils.isImage(mimetype)) {
return "image"
return "image";
}
return "document"
return "document";
},
sortByName: (state: TabSortState) =>
(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 = {

View File

@ -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) => {

View File

@ -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 });

View File

@ -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"] });
};

View File

@ -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),
}));
}

View File

@ -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<string, string[]>(this.store) || []
const items = (await entries<string, string[]>(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<string[]>(folder, this.store) || []
const files = (await get<string[]>(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<string[]>(folder, this.store) || []
return set(folder, files.filter(item => item !== cid), this.store)
const files = (await get<string[]>(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<string>(key, this.store);
},
@ -120,6 +120,6 @@ export const WebStorage = {
async set(key: string, date: string) {
return set(key, date, this.store);
},
}
}
},
},
};