Upload pipeline: staging, MD5 auto-match, IQDB, three-column board
Backend: - TempUpload model: staged files (pending / visual_match / completed / error) with resolution, e621 payload, custom metadata and IQDB data - Files land in a temp folder and only move into the watched library folder once resolved; duplicates resolve immediately without a copy - Endpoints: stage (multipart), list, retrieve, temp file, IQDB save, resolve (link to post or custom metadata), discard/dismiss - cleanup_temp_uploads command for old staged files - Replaces the old direct-to-library upload endpoint Frontend: - Upload page is now a three-column board (Pending & Unmatched / Visual Similarity Detected / Auto-uploaded & Indexed) - After upload: MD5s are batch-checked against e621 and matches auto-complete with full post metadata; remaining files run through IQDB and move to the similarity column when candidates exist - Metadata modal with IQDB candidates, post-ID linking and custom tags/rating/notes; discard and dismiss actions - e621 client gains fetchPostsByMd5 and iqdbSearch helpers Roadmap updated with the completed upload items.
This commit is contained in:
+10
-3
@@ -1,4 +1,4 @@
|
||||
import type { MediaItem } from "@/lib/types";
|
||||
import type { TempUpload } from "@/lib/types";
|
||||
|
||||
const TOKEN_KEY = "j621.token";
|
||||
|
||||
@@ -6,6 +6,13 @@ export function getToken(): string | null {
|
||||
return window.localStorage.getItem(TOKEN_KEY);
|
||||
}
|
||||
|
||||
export function authHeaders(extra?: HeadersInit): Headers {
|
||||
const headers = new Headers(extra);
|
||||
const token = getToken();
|
||||
if (token) headers.set("Authorization", `Token ${token}`);
|
||||
return headers;
|
||||
}
|
||||
|
||||
export function setToken(token: string | null): void {
|
||||
if (token) {
|
||||
window.localStorage.setItem(TOKEN_KEY, token);
|
||||
@@ -82,7 +89,7 @@ export function uploadFile(
|
||||
file: File,
|
||||
fields: Record<string, string> = {},
|
||||
onProgress?: (percent: number) => void,
|
||||
): Promise<MediaItem> {
|
||||
): Promise<TempUpload> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const form = new FormData();
|
||||
form.append("file", file);
|
||||
@@ -107,7 +114,7 @@ export function uploadFile(
|
||||
data = null;
|
||||
}
|
||||
if (request.status >= 200 && request.status < 300) {
|
||||
resolve(data as MediaItem);
|
||||
resolve(data as TempUpload);
|
||||
} else {
|
||||
reject(new ApiError(request.status, data));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user