mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat(files): wire serverFileId for version tracking
Add serverFileId to FileEntry, pass fileId in tool processor formData when a file originates from the Files page, and set serverFileId on the loaded entry so subsequent tool runs create new file versions instead of duplicates.
This commit is contained in:
@@ -56,6 +56,13 @@ export function FileDetails({ mobile = false }: FileDetailsProps) {
|
||||
const file = new File([blob], details.originalName, { type: details.mimeType });
|
||||
setFiles([file]);
|
||||
navigate("/");
|
||||
// Set serverFileId so tool processing creates a new version
|
||||
setTimeout(() => {
|
||||
const entries = useFileStore.getState().entries;
|
||||
if (entries.length > 0) {
|
||||
useFileStore.getState().updateEntry(0, { serverFileId: details.id });
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
if (!selectedFileId) {
|
||||
@@ -63,7 +70,9 @@ export function FileDetails({ mobile = false }: FileDetailsProps) {
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col items-center justify-center text-muted-foreground",
|
||||
mobile ? "flex-1" : "w-72 shrink-0 border-l border-border",
|
||||
mobile
|
||||
? "flex flex-col gap-4"
|
||||
: "w-60 border-l border-border p-4 shrink-0 hidden lg:flex flex-col",
|
||||
)}
|
||||
>
|
||||
<FileImage className="h-12 w-12 mb-3 opacity-30" />
|
||||
@@ -77,7 +86,9 @@ export function FileDetails({ mobile = false }: FileDetailsProps) {
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center",
|
||||
mobile ? "flex-1" : "w-72 shrink-0 border-l border-border",
|
||||
mobile
|
||||
? "flex flex-col gap-4"
|
||||
: "w-60 border-l border-border p-4 shrink-0 hidden lg:flex flex-col",
|
||||
)}
|
||||
>
|
||||
<div className="h-6 w-6 border-2 border-primary border-t-transparent rounded-full animate-spin" />
|
||||
@@ -90,12 +101,14 @@ export function FileDetails({ mobile = false }: FileDetailsProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col overflow-y-auto",
|
||||
mobile ? "flex-1" : "w-72 shrink-0 border-l border-border",
|
||||
"overflow-y-auto",
|
||||
mobile
|
||||
? "flex flex-col gap-4"
|
||||
: "w-60 border-l border-border p-4 shrink-0 hidden lg:flex flex-col",
|
||||
)}
|
||||
>
|
||||
{/* Thumbnail */}
|
||||
<div className="p-4 border-b border-border">
|
||||
<div className={cn("border-b border-border", mobile ? "" : "pb-4")}>
|
||||
<img
|
||||
src={getFileThumbnailUrl(details.id)}
|
||||
alt={details.originalName}
|
||||
@@ -104,7 +117,7 @@ export function FileDetails({ mobile = false }: FileDetailsProps) {
|
||||
</div>
|
||||
|
||||
{/* Details card */}
|
||||
<div className="flex-1 p-4">
|
||||
<div className="flex-1">
|
||||
<div className="rounded-lg border border-border overflow-hidden">
|
||||
<div className="bg-blue-500/10 border-b border-border px-3 py-2">
|
||||
<h4 className="text-sm font-semibold text-blue-600 dark:text-blue-400">File Details</h4>
|
||||
@@ -135,7 +148,7 @@ export function FileDetails({ mobile = false }: FileDetailsProps) {
|
||||
</div>
|
||||
|
||||
{/* Open File button */}
|
||||
<div className="p-4 border-t border-border">
|
||||
<div className={cn("border-t border-border", mobile ? "pt-3" : "pt-4")}>
|
||||
<button
|
||||
onClick={handleOpenFile}
|
||||
className="w-full px-4 py-2 bg-primary text-primary-foreground text-sm font-medium rounded-lg hover:bg-primary/90 transition-colors"
|
||||
|
||||
@@ -10,6 +10,7 @@ interface ProcessResult {
|
||||
downloadUrl: string;
|
||||
originalSize: number;
|
||||
processedSize: number;
|
||||
savedFileId?: string;
|
||||
}
|
||||
|
||||
export interface ToolProgress {
|
||||
@@ -128,6 +129,12 @@ export function useToolProcessor(toolId: string) {
|
||||
formData.append("clientJobId", clientJobId);
|
||||
}
|
||||
|
||||
// If this file came from the Files page, include its ID for version tracking
|
||||
const currentEntry = useFileStore.getState().currentEntry;
|
||||
if (currentEntry?.serverFileId) {
|
||||
formData.append("fileId", currentEntry.serverFileId);
|
||||
}
|
||||
|
||||
// Use XHR for upload progress tracking
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhrRef.current = xhr;
|
||||
@@ -168,6 +175,13 @@ export function useToolProcessor(toolId: string) {
|
||||
setJobId(result.jobId);
|
||||
setProcessedUrl(result.downloadUrl);
|
||||
setSizes(result.originalSize, result.processedSize);
|
||||
// Update serverFileId if a new version was saved
|
||||
if (result.savedFileId) {
|
||||
const state = useFileStore.getState();
|
||||
if (state.entries[state.selectedIndex]) {
|
||||
state.updateEntry(state.selectedIndex, { serverFileId: result.savedFileId });
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
setError("Invalid response from server");
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ export interface FileEntry {
|
||||
originalSize: number;
|
||||
status: "pending" | "processing" | "completed" | "failed";
|
||||
error: string | null;
|
||||
serverFileId?: string;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -23,6 +24,7 @@ function createEntry(file: File): FileEntry {
|
||||
originalSize: file.size,
|
||||
status: "pending",
|
||||
error: null,
|
||||
serverFileId: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user