diff --git a/app/api/upload/git/route.ts b/app/api/upload/git/route.ts index c563080..f8705c9 100644 --- a/app/api/upload/git/route.ts +++ b/app/api/upload/git/route.ts @@ -7,7 +7,7 @@ import { parseMultiUpload } from '@/lib/parse-upload' import { compressWithBlender } from '@/lib/blender' import { getRemoteFolder, pushAllToGitHub } from '@/lib/github' import { buildCommitMessage } from '@/lib/commit-message' -import { TMP_DIR } from '@/lib/constants' +import { TMP_DIR, MODEL_EXTENSIONS } from '@/lib/constants' import type { FileChange } from '@/lib/types' export const runtime = 'nodejs' @@ -84,7 +84,9 @@ export async function POST(req: NextRequest) { }) } - // --- Detect existing files and compare size to classify changes (LFS-compatible) --- + // --- Detect existing files and classify changes --- + // Models: always re-push (compression changes size, can't compare with LFS remote) + // Textures: compare by size (not compressed, reliable) const folderPath = `public/models/${destination}/${folderName}` let remoteFileMap: Map @@ -97,23 +99,33 @@ export async function POST(req: NextRequest) { const isReplace = remoteFileMap.size > 0 - // Classify each file: changed, new, or unchanged const fileChanges = new Map() const changedFilesToPush: { path: string; contentBase64: string }[] = [] for (const f of filesToPush) { const filename = f.path.split('/').pop() ?? '' - const localSize = Buffer.from(f.contentBase64, 'base64').length - const remoteSize = remoteFileMap.get(filename.toLowerCase()) + const ext = filename.slice(filename.lastIndexOf('.')).toLowerCase() + const isModel = MODEL_EXTENSIONS.has(ext) - if (remoteSize === undefined) { - fileChanges.set(filename.toLowerCase(), 'new') - changedFilesToPush.push(f) - } else if (remoteSize !== localSize) { - fileChanges.set(filename.toLowerCase(), 'changed') + if (isModel) { + // Model: always re-push since compression makes size comparison unreliable + const remoteSize = remoteFileMap.get(filename.toLowerCase()) + fileChanges.set(filename.toLowerCase(), remoteSize === undefined ? 'new' : 'changed') changedFilesToPush.push(f) } else { - fileChanges.set(filename.toLowerCase(), 'unchanged') + // Texture: compare by size + const localSize = Buffer.from(f.contentBase64, 'base64').length + const remoteSize = remoteFileMap.get(filename.toLowerCase()) + + if (remoteSize === undefined) { + fileChanges.set(filename.toLowerCase(), 'new') + changedFilesToPush.push(f) + } else if (remoteSize !== localSize) { + fileChanges.set(filename.toLowerCase(), 'changed') + changedFilesToPush.push(f) + } else { + fileChanges.set(filename.toLowerCase(), 'unchanged') + } } } diff --git a/components/UploadZone.tsx b/components/UploadZone.tsx index a023967..490a8a3 100644 --- a/components/UploadZone.tsx +++ b/components/UploadZone.tsx @@ -44,33 +44,31 @@ async function checkFolderDiffs( const remoteFiles: { name: string; size: number }[] = data.files || [] const remoteMap = new Map(remoteFiles.map((f) => [f.name.toLowerCase(), f.size])) - // Build local file list with sizes - const localFiles: { name: string; size: number }[] = [] - localFiles.push({ - name: folder.modelFile.name, - size: folder.modelFile.size, - }) - for (const tex of folder.textures) { - localFiles.push({ - name: tex.name, - size: tex.file.size, - }) - } - const diffs: FileDiff[] = [] const localNames = new Set() - for (const local of localFiles) { - const key = local.name.toLowerCase() + // Model: skip size comparison (compression changes the size). + // We only check if it exists on remote or not. + const modelKey = folder.modelFile.name.toLowerCase() + localNames.add(modelKey) + if (!remoteMap.has(modelKey)) { + diffs.push({ name: folder.modelFile.name, status: 'new' }) + } + // If model exists on remote → don't add to diffs (we can't know if it changed) + + // Textures: compare by size (not compressed, so size is reliable) + for (const tex of folder.textures) { + const key = tex.name.toLowerCase() localNames.add(key) const remoteSize = remoteMap.get(key) if (remoteSize === undefined) { - diffs.push({ name: local.name, status: 'new' }) - } else if (remoteSize !== local.size) { - diffs.push({ name: local.name, status: 'changed' }) + diffs.push({ name: tex.name, status: 'new' }) + } else if (remoteSize !== tex.file.size) { + diffs.push({ name: tex.name, status: 'changed' }) } } + // Files on remote but not in local → deleted for (const [name] of remoteMap) { if (!localNames.has(name)) { diffs.push({ name, status: 'deleted' })