From 45989ef97db1d155ca4c795caa937f65f46124f3 Mon Sep 17 00:00:00 2001 From: Elijah Date: Sat, 23 May 2026 13:57:43 -0700 Subject: [PATCH] fix: Go compiler error with MoveRequest inline struct and remove refactor.js --- backend/handlers/files.go | 11 +- refactor.js | 302 -------------------------------------- 2 files changed, 7 insertions(+), 306 deletions(-) delete mode 100644 refactor.js diff --git a/backend/handlers/files.go b/backend/handlers/files.go index 3c7142a..67b4f1c 100644 --- a/backend/handlers/files.go +++ b/backend/handlers/files.go @@ -403,13 +403,16 @@ func (h *FSHandler) Rename(c *fiber.Ctx) error { return c.JSON(fiber.Map{"message": "renamed successfully", "new_path": filepath.ToSlash(newPath)}) } +type MoveRequest struct { + SourcePath string `json:"source_path"` + DestPath string `json:"dest_path"` + Resolution string `json:"resolution"` // "overwrite", "rename", "skip" +} + // Move moves a file or folder to a new location. // POST /api/files/move func (h *FSHandler) Move(c *fiber.Ctx) error { - var body struct { - SourcePath string `json:"source_path"` - DestPath string `json:"dest_path"` - } + var body MoveRequest if err := c.BodyParser(&body); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid request body"}) } diff --git a/refactor.js b/refactor.js deleted file mode 100644 index 36fc3ef..0000000 --- a/refactor.js +++ /dev/null @@ -1,302 +0,0 @@ -const fs = require('fs'); - -let content = fs.readFileSync('frontend/src/components/FileExplorer.tsx', 'utf-8'); - -// 1. Add ConflictState to the component state -const stateInsertPos = content.indexOf(' const [deleteConfirm'); -const conflictStateCode = ` const [conflictState, setConflictState] = useState<{ - type: 'upload' | 'move' | 'copy'; - files?: {file: File, path: string}[]; - sourcePaths?: string[]; - destPath: string; - conflicts: string[]; - } | null>(null);\n`; -content = content.slice(0, stateInsertPos) + conflictStateCode + content.slice(stateInsertPos); - -// 2. Replace handleDrop and uploadFile with processUploadBatch and updated handleDrop -const uploadFileStart = content.indexOf(' async function uploadFile'); -const handleCreateFolderStart = content.indexOf(' async function handleCreateFolder'); - -const newUploadCode = ` async function processUploadBatch(entries: {file: File, path: string}[], destPath: string, overwrite: boolean = false) { - if (!entries.length) return; - const batchId = 'batch-' + Date.now(); - const totalFiles = entries.length; - const totalBytes = entries.reduce((acc, curr) => acc + curr.file.size, 0); - const batchName = totalFiles === 1 ? entries[0].file.name : \`Uploading \${totalFiles} items\`; - - setUploads(prev => [...prev, { - id: batchId, - name: batchName, - totalBytes, - uploadedBytes: 0, - totalFiles, - filesUploaded: 0, - status: 'uploading' - }]); - - const MAX_CONCURRENT = 4; - let currentIndex = 0; - let completedFiles = 0; - let currentUploadedBytes = 0; - const fileProgressMap = new Map(); - - const updateProgress = () => { - let totalUploaded = 0; - fileProgressMap.forEach(bytes => { totalUploaded += bytes; }); - setUploads(prev => prev.map(b => b.id === batchId ? { - ...b, - uploadedBytes: totalUploaded, - filesUploaded: completedFiles, - status: completedFiles === totalFiles ? 'complete' : 'uploading' - } : b)); - }; - - const worker = async () => { - while (currentIndex < entries.length) { - const index = currentIndex++; - const { file, path } = entries[index]; - const uploadPath = path ? (destPath === '.' ? path : \`\${destPath}/\${path}\`) : destPath; - - try { - await api.upload(file, uploadPath, { - overwrite, - onProgress: (percent) => { - fileProgressMap.set(file.name + path, (percent / 100) * file.size); - updateProgress(); - } - }); - completedFiles++; - fileProgressMap.set(file.name + path, file.size); - updateProgress(); - } catch (err: any) { - setUploads(prev => prev.map(b => b.id === batchId ? { ...b, status: 'error', error: err.message || 'Upload failed' } : b)); - } - } - }; - - const workers = []; - for (let i = 0; i < Math.min(MAX_CONCURRENT, entries.length); i++) { - workers.push(worker()); - } - await Promise.all(workers); - - setTimeout(() => { - setUploads(prev => prev.filter(u => u.id !== batchId)); - loadFiles(undefined, true); - }, 3000); - } - - async function handleDrop(e: React.DragEvent) { - e.preventDefault(); - setDragOver(false); - if (draggedFile) return; - - if (e.dataTransfer.items) { - const filesToUpload: { file: File; path: string }[] = []; - const promises: Promise[] = []; - - const processEntry = async (entry: any, path: string = '') => { - if (entry.isFile) { - const file = await new Promise((resolve) => entry.file(resolve)); - filesToUpload.push({ file, path: path.replace(/\\/$/, '') }); - } else if (entry.isDirectory) { - const dirReader = entry.createReader(); - let entries: any[] = []; - - const readAllEntries = async () => { - const batch = await new Promise((resolve) => dirReader.readEntries(resolve)); - if (batch.length > 0) { - entries = entries.concat(batch); - await readAllEntries(); - } - }; - await readAllEntries(); - - for (const child of entries) { - await processEntry(child, \`\${path}\${entry.name}/\`); - } - } - }; - - for (let i = 0; i < e.dataTransfer.items.length; i++) { - const item = e.dataTransfer.items[i]; - if (item.kind === 'file') { - const entry = item.webkitGetAsEntry(); - if (entry) { - promises.push(processEntry(entry)); - } - } - } - - await Promise.all(promises); - - if (filesToUpload.length > 0) { - // Collect destination paths to create folders - const uniqueDirs = new Set(); - filesToUpload.forEach(({path}) => { - if (path) uniqueDirs.add(currentPath === '.' ? path : \`\${currentPath}/\${path}\`); - }); - - for (const dir of Array.from(uniqueDirs)) { - try { await api.createFolder(dir); } catch {} - } - - const fileNames = filesToUpload.map(f => f.path ? \`\${f.path}/\${f.file.name}\` : f.file.name); - try { - const res = await api.checkConflicts(currentPath, fileNames); - if (res.conflicts && res.conflicts.length > 0) { - setConflictState({ type: 'upload', files: filesToUpload, destPath: currentPath, conflicts: res.conflicts }); - return; - } - } catch {} - - processUploadBatch(filesToUpload, currentPath); - } - } - } - - async function handleFileUpload(e: React.ChangeEvent) { - const uploadFiles = e.target.files; - if (!uploadFiles) return; - const filesArray = Array.from(uploadFiles).map(f => ({ file: f, path: '' })); - - const fileNames = filesArray.map(f => f.file.name); - try { - const res = await api.checkConflicts(currentPath, fileNames); - if (res.conflicts && res.conflicts.length > 0) { - setConflictState({ type: 'upload', files: filesArray, destPath: currentPath, conflicts: res.conflicts }); - return; - } - } catch {} - - processUploadBatch(filesArray, currentPath); - } - -`; - -content = content.slice(0, uploadFileStart) + newUploadCode + content.slice(handleCreateFolderStart); - -// Add Conflict Modal rendering -const renderModalsPos = content.lastIndexOf('{showMoveModal && ('); -const conflictModalCode = ` - {conflictState && ( -
setConflictState(null)}> - e.stopPropagation()} - > -
-

Name Conflict Detected

-

- The following files already exist in the destination. How would you like to proceed? -

-
-
-
    - {conflictState.conflicts.map(c =>
  • {c}
  • )} -
-
-
- - - - -
-
-
- )} -`; -content = content.slice(0, renderModalsPos) + conflictModalCode + content.slice(renderModalsPos); - -// Add executeConflictResolution function -const execFunctionCode = ` - async function executeConflictResolution(resolution: string) { - if (!conflictState) return; - const { type, destPath, conflicts } = conflictState; - - if (type === 'upload' && conflictState.files) { - let filesToUpload = conflictState.files; - if (resolution === 'skip') { - filesToUpload = filesToUpload.filter(f => { - const name = f.path ? \`\${f.path}/\${f.file.name}\` : f.file.name; - return !conflicts.includes(name); - }); - } - setConflictState(null); - if (filesToUpload.length > 0) { - processUploadBatch(filesToUpload, destPath, resolution === 'overwrite'); - } - } else if (type === 'move' && conflictState.sourcePaths) { - let pathsToMove = conflictState.sourcePaths; - if (resolution === 'skip') { - pathsToMove = pathsToMove.filter(p => !conflicts.includes(p.split('/').pop()!)); - } - setConflictState(null); - if (pathsToMove.length > 0) { - try { - await Promise.all(pathsToMove.map(src => api.move(src, destPath, resolution))); - setShowMoveModal(false); - setMovingFiles([]); - loadFiles(undefined, true); - setSelectedFiles(new Set()); - showToast(\`Moved \${pathsToMove.length} item\${pathsToMove.length > 1 ? 's' : ''}\`); - } catch (e) { - console.error(e); - } - } - } - } - -`; - -const handleDropOnFolderStart = content.indexOf(' async function handleDropOnFolder'); -content = content.slice(0, handleDropOnFolderStart) + execFunctionCode + content.slice(handleDropOnFolderStart); - -// Update handleMoveExecute -content = content.replace( - \` async function handleMoveExecute() { - if (movingFiles.length === 0) return; - try { - await Promise.all(movingFiles.map(src => api.move(src, moveModalPath === '.' ? '.' : moveModalPath)));\`, - \` async function handleMoveExecute() { - if (movingFiles.length === 0) return; - try { - const destPath = moveModalPath === '.' ? '.' : moveModalPath; - const fileNames = movingFiles.map(src => src.split('/').pop() || src); - const res = await api.checkConflicts(destPath, fileNames); - if (res.conflicts && res.conflicts.length > 0) { - setConflictState({ type: 'move', sourcePaths: movingFiles, destPath, conflicts: res.conflicts }); - return; - } - await Promise.all(movingFiles.map(src => api.move(src, destPath)));\` -); - -// Update handleDropOnFolder -content = content.replace( - \` async function handleDropOnFolder(file: FileItem, targetFolder: FileItem) { - if (file.path === targetFolder.path) return; - try { - await api.move(file.path, targetFolder.path);\`, - \` async function handleDropOnFolder(file: FileItem, targetFolder: FileItem) { - if (file.path === targetFolder.path) return; - try { - const res = await api.checkConflicts(targetFolder.path, [file.name]); - if (res.conflicts && res.conflicts.length > 0) { - setConflictState({ type: 'move', sourcePaths: [file.path], destPath: targetFolder.path, conflicts: res.conflicts }); - return; - } - await api.move(file.path, targetFolder.path);\` -); - -fs.writeFileSync('frontend/src/components/FileExplorer.tsx', content);