Skip to content

Conversation

@Kitenite
Copy link
Contributor

@Kitenite Kitenite commented Oct 6, 2025

Description

Related Issues

Type of Change

  • Bug fix
  • New feature
  • Documentation
  • Refactor
  • Other (please describe):

Testing

Screenshots (if applicable)

Additional Notes


Important

Adds drag-and-drop image upload functionality to the image tab, updating use-image-drag-drop.tsx, image-grid.tsx, and index.tsx.

  • Behavior:
    • Adds drag-and-drop image upload functionality to the image tab.
    • handleDrop function in use-image-drag-drop.tsx processes dropped files and calls onUpload.
  • Components:
    • ImageGrid component updated to accept onUpload prop and handle onDrop event.
    • ImagesTab component passes handleUpload to ImageGrid.

This description was created by Ellipsis for a50209e. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • New Features
    • Drag-and-drop uploads are now supported in the Images tab: drop files directly onto the image grid to start uploading.
    • Smoother drag-over and drop interactions within the image area for a more intuitive experience.
    • Upload behavior is now available both from the search/upload bar and directly in the grid, offering flexible workflows.
    • Improved handling of dropped files ensures uploads begin immediately upon drop, reducing steps and speeding up image management.

@vercel
Copy link

vercel bot commented Oct 6, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
web Building Building Preview Comment Oct 6, 2025 10:34pm
1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
docs Skipped Skipped Oct 6, 2025 10:34pm

@supabase
Copy link

supabase bot commented Oct 6, 2025

This pull request has been ignored for the connected project wowaemfasoptxrdjhilu because there are no changes detected in apps/backend/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai
Copy link

coderabbitai bot commented Oct 6, 2025

Walkthrough

Introduces an optional onUpload callback into the image drag-and-drop flow. The hook now handles drop events and invokes onUpload with dropped files. ImageGrid accepts and forwards onUpload to the hook and binds onDrop. ImagesTab passes its existing handleUpload down to ImageGrid.

Changes

Cohort / File(s) Summary
Hook: drag-and-drop upload handling
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
Added optional onUpload parameter. Implemented handleDrop to process FileList and call onUpload. Exposed handleDrop in returned API. Existing drag handlers unchanged.
Component: ImageGrid integration
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx
Extended props with onUpload: (files: FileList) => Promise. Passed onUpload to hook; bound container onDrop to handleDrop.
Wiring: ImagesTab to ImageGrid
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx
Propagated existing handleUpload to ImageGrid via new onUpload prop. No other behavior changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant IG as ImageGrid
  participant H as useImageDragDrop
  participant CB as onUpload (callback)

  U->>IG: Drag files over container
  IG->>H: handleDragEnter/Over
  H-->>IG: Set dragging state

  U->>IG: Drop files
  IG->>H: handleDrop(event)
  H->>H: Prevent default, clear drag state
  H->>CB: onUpload(FileList)?
  alt onUpload provided
    CB-->>H: Promise resolved/rejected
  else
    H-->>IG: No-op
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I hopped through grids where images drop,
A gentle thunk—then uploads pop.
Hooks now catch the falling files,
Passing them up with tidy smiles.
From tab to grid the currents flow—
Carrots queued, we’re good to go! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description contains the template headings but lacks any actual content under Description, Related Issues, Testing, Screenshots, and Additional Notes sections, leaving only placeholder comments and a Type of Change checkbox filled. As a result, reviewers have no information about the changes made, associated issues, verification steps, or visual context. The appended Ellipsis summary does not replace the required template fields. This makes the description largely incomplete for a proper review. Please complete each section of the template by adding a clear and concise description of your changes, linking related issues, outlining the testing steps you performed, including screenshots if applicable, and providing any additional context in the Additional Notes section. This will give reviewers the information necessary to understand, verify, and merge your PR.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely describes the primary change by stating that it fixes image dropping in the image tab, matching the core functionality introduced in the hook and component updates.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/img-drag-drop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.


const files = e.dataTransfer.files;
if (files.length > 0 && onUpload) {
void onUpload(files);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error handling (e.g., try/catch) around the onUpload(files) call in handleDrop to cover upload failures.

@Kitenite Kitenite merged commit d1d2329 into main Oct 6, 2025
6 of 8 checks passed
@Kitenite Kitenite deleted the feat/img-drag-drop branch October 6, 2025 22:36
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx (1)

95-98: Consider validating dropped files are images.

While handleDragStateChange checks MIME types during drag, the actual dropped files aren't validated. This defensive check would catch edge cases where non‑images slip through.

 const files = e.dataTransfer.files;
-if (files.length > 0 && onUpload) {
+const imageFiles = Array.from(files).filter(file => file.type.startsWith('image/'));
+if (imageFiles.length > 0 && onUpload) {
-    onUpload(files).catch((error) => {
+    const fileList = Object.assign(imageFiles, { item: (i: number) => imageFiles[i] }) as FileList;
+    onUpload(fileList).catch((error) => {
         console.error('Upload failed:', error);
         // TODO: Show user-facing error notification
     });
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f0870e and a50209e.

📒 Files selected for processing (3)
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx (2 hunks)
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx (2 hunks)
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
apps/web/client/src/app/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

apps/web/client/src/app/**/*.tsx: Default to Server Components; add 'use client' when using events, state/effects, browser APIs, or client‑only libraries
Do not use process.env in client code; import env from @/env instead

Avoid hardcoded user-facing text; use next-intl messages/hooks

Files:

  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
apps/web/client/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

apps/web/client/src/**/*.{ts,tsx}: Use path aliases @/* and ~/* for imports that map to apps/web/client/src/*
Avoid hardcoded user-facing text; use next-intl messages/hooks instead

Use path aliases @/* and ~/* for imports mapping to src/*

Files:

  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
apps/web/client/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

apps/web/client/src/**/*.tsx: Create MobX store instances with useState(() => new Store()) for stable references across renders
Keep the active MobX store in a useRef and perform async cleanup with setTimeout(() => storeRef.current?.clear(), 0) to avoid route-change races
Avoid useMemo for creating MobX store instances
Avoid putting the MobX store instance in effect dependency arrays if it causes loops; split concerns by domain

apps/web/client/src/**/*.tsx: Create MobX store instances with useState(() => new Store()) for stable identities across renders
Keep the active MobX store in a useRef and clean up asynchronously with setTimeout(() => storeRef.current?.clear(), 0)
Do not use useMemo to create MobX stores
Avoid placing MobX store instances in effect dependency arrays if it causes loops; split concerns instead
observer components must be client components; place a single client boundary at the feature entry; child observers need not repeat 'use client'

Files:

  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not use the any type unless necessary

Files:

  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
apps/web/client/src/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Default to Server Components; add 'use client' only when using events, state/effects, browser APIs, or client-only libs

Files:

  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
{apps,packages}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Avoid using the any type unless absolutely necessary

Files:

  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx
  • apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
🧬 Code graph analysis (1)
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx (1)
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx (1)
  • useImageDragDrop (6-112)
🔇 Additional comments (5)
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/index.tsx (1)

86-86: LGTM!

The prop wiring correctly enables drag-and-drop uploads by passing handleUpload to ImageGrid.

apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/image-grid.tsx (2)

14-21: LGTM!

The integration correctly wires the upload callback through the hook and binds the drop handler to the container.


31-31: LGTM!

The drop handler binding completes the drag-and-drop upload flow.

apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx (2)

6-6: LGTM!

The optional onUpload parameter correctly enables external upload handling.


106-106: LGTM!

Correctly exposes handleDrop for binding in consumer components.

Comment on lines +90 to +99
const handleDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
setIsDragging(false);
e.currentTarget.removeAttribute('data-dragging-image');

const files = e.dataTransfer.files;
if (files.length > 0 && onUpload) {
void onUpload(files);
}
}, [onUpload]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add error handling for upload failures.

The void onUpload(files) call explicitly ignores the promise, meaning upload errors won't be caught or displayed. Users won't know if their drop upload failed.

Consider handling errors:

 const handleDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {
     e.preventDefault();
     setIsDragging(false);
     e.currentTarget.removeAttribute('data-dragging-image');

     const files = e.dataTransfer.files;
     if (files.length > 0 && onUpload) {
-        void onUpload(files);
+        onUpload(files).catch((error) => {
+            console.error('Upload failed:', error);
+            // TODO: Show user-facing error notification
+        });
     }
 }, [onUpload]);
🤖 Prompt for AI Agents
In
apps/web/client/src/app/project/[id]/_components/left-panel/image-tab/hooks/use-image-drag-drop.tsx
around lines 90–99, the drop handler currently calls void onUpload(files) which
ignores the returned promise and swallows upload errors; change the handler to
await the onUpload call inside a try/catch (or call onUpload(files).catch(...))
so upload failures are caught, set an error state or invoke an existing error
callback (or show a user-facing toast/message) with the error, and ensure the
dependency array reflects any new state or callbacks used; keep preventing
default and clearing dragging attributes as-is.

@coderabbitai coderabbitai bot mentioned this pull request Oct 9, 2025
5 tasks
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.

2 participants