Skip to content

refactor(upload): unify file-drop pipeline across all list pages#492

Open
Papyszoo wants to merge 2 commits into
mainfrom
claude/upload-pipeline-unification
Open

refactor(upload): unify file-drop pipeline across all list pages#492
Papyszoo wants to merge 2 commits into
mainfrom
claude/upload-pipeline-unification

Conversation

@Papyszoo
Copy link
Copy Markdown
Owner

Summary

  • Replaces hand-rolled UploadableGrid + per-feature drag handlers with a single canonical <UploadDropZone> wrapper backed by a shared useDragAndDrop hook (one source of truth for the file-drop affordance across the app)
  • Adds bounded-concurrency uploads (4 workers) and a skip-clone Zustand update path so dropping many files no longer hangs the UI
  • Wires panel-wide tab-drop: tabs can now be dropped anywhere on a side panel, not just the dock bar — file/tab drags coexist via MIME-type isolation

What changed

New canonical drop wrapper

  • UploadDropZone.tsx/.css — single visual treatment (dashed primary-color border on .drag-over), routes drops to onFilesDropped, ignores tab drags at hook level

Migrated 5 list pages → UploadDropZone

  • EnvironmentMapList, ModelGrid, SoundList, SpriteList, TextureSetList

Migrated 4 container tabs → UploadDropZone

  • ContainerSpritesTab, ContainerSoundsTab, ContainerEnvironmentMapsTab, ContainerTextureSetsTab
  • Drops the redundant local "Uploading..." spinner overlay (the global UploadProgressWindow already shows per-file progress)

Deletes

  • UploadableGrid.tsx + UploadableGrid.css (replaced by UploadDropZone)
  • Stale :hover:not(.drag-over) rules in EnvironmentMapList.css, ModelGrid.css, TextureSetGrid.css that were leaking drop styling into the idle hover state

Performance

  • uploadProgressStore: per-item updates skip cloning unaffected batches (O(N²) → O(N))
  • useFileUpload.uploadMultipleFiles: bounded concurrency pool of 4 workers replaces serial for loop
  • Drag listeners: module-level shared window listeners with refcount, instead of one pair per useDragAndDrop instance

Panel-wide tab drop

  • DockPanelContent attaches the existing tab-drop handlers to the .dock-content div
  • File drags pass through (handlers gate on draggedTab); inner UploadDropZone calls stopPropagation so file drops never reach the tab-drop listener

Test plan

  • npx jest — 247/247 tests passing across 21 suites
  • npx vite build — clean build
  • Manual: drop a single file on each list page (Models / EnvMaps / Sounds / Sprites / TextureSets) — uploads + global progress window appear
  • Manual: drop many (10+) files at once — UI stays responsive, 4 parallel uploads visible
  • Manual: drop image files inside container detail tabs (Sprites / Sounds / EnvMaps / TextureSets) — creates assets in the container
  • Manual: drag a tab from one side panel to the other side panel's content area (not just the dock bar) — tab moves
  • Manual: while dragging a file, hover over the dock content area on a tab without an upload zone — no spurious drop highlight
  • Manual: confirm idle hover on grid items no longer shows the dashed drop border

🤖 Generated with Claude Code

Papyszoo and others added 2 commits April 25, 2026 09:15
Replace the flat tonemapped HDR/EXR preview with the same metallic-
sphere orbit animation the real asset processor produces, and cache
results per-variant so the variant preview endpoint stays consistent
with the map-level preview.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces the hand-rolled UploadableGrid + per-feature drag handlers with
a single canonical UploadDropZone wrapper backed by a shared
useDragAndDrop hook. Eliminates duplicate code, fixes a hover-state bug
where the dashed-border drop affordance leaked into idle :hover, and
adds bounded-concurrency uploads (4 workers) so dropping many files no
longer hangs the UI.

Also wires panel-wide tab-drop on the dock content area: tabs can now
be dropped anywhere on the side panel, not just on the dock bar. File
and tab drags coexist via MIME-type isolation — UploadDropZone filters
on `Files`, and inner stopPropagation prevents file drops from bubbling
to the panel-wide tab-drop listener.

Performance:
- O(N²) Zustand store updates → skip-clone for unaffected batches
- Serial upload loop → bounded concurrency pool of 4
- Module-level shared drag listeners with refcount instead of per-instance

Migrations:
- 5 list pages (EnvironmentMap, Model, Sound, Sprite, TextureSet)
- 4 container tabs (Sprites, Sounds, EnvironmentMaps, TextureSets)
- Deletes UploadableGrid.tsx + UploadableGrid.css

All 247 tests pass; vite build clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant