Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
Walkthrough두 파일에 동일한 패턴으로 드래그 앤 드롭 이미지 업로드 기능이 추가되었습니다. 각 파일에서는 DragEvent 처리와 깊이 추적 참조(dragDepthRef)를 통해 드래그 상태를 관리하고, 드래그 오버레이 UI를 표시합니다. 새로운 selectImageFile 헬퍼 함수로 이미지 MIME 타입을 검증하며, 유효하지 않은 파일 선택 시 토스트로 사용자에게 피드백합니다. Estimated code review effortPostModifyForm.tsx PostForm.tsx 두 파일 모두 동일한 구조의 변경이 반복되므로, 첫 파일을 검토한 후 두 번째 파일은 일관성 확인만 필요합니다. Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 380f5d82a4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const handleImageDragEnter = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); |
There was a problem hiding this comment.
Restrict drag handlers to file drags only
The new drag handlers unconditionally call preventDefault/stopPropagation, so any drag operation inside this form (including dragging selected text or dropping text/links into the post textarea) is now intercepted as an image-drop flow and native drop behavior is blocked. This is a user-facing regression introduced with the image DnD support; gate the handlers to dataTransfer.types containing files before suppressing default behavior (the same pattern is also present in the modify form).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/app/community/`[boardCode]/[postId]/modify/PostModifyForm.tsx:
- Around line 101-137: Add a small helper (e.g., isFileDrag(event:
DragEvent<HTMLDivElement>): boolean) that returns true only when
event.dataTransfer?.types includes "Files" (and for drop, that
event.dataTransfer?.files?.length > 0); then update handleImageDragEnter,
handleImageDragOver, handleImageDragLeave, and handleImageDrop to call this
helper first and early-return if false so preventDefault()/stopPropagation() and
the overlay logic only run for actual file drags (for handleImageDrop also read
the files after the helper confirms a file drag).
In `@apps/web/src/app/community/`[boardCode]/create/PostForm.tsx:
- Around line 84-120: Add a helper isFileDrag that checks
event.dataTransfer?.types includes "Files" and update the drag handlers
(handleImageDragEnter, handleImageDragOver, handleImageDragLeave,
handleImageDrop) to early-return when !isFileDrag(event) so you only call
event.preventDefault() and event.stopPropagation() for actual file drags; keep
existing dragDepthRef and setIsDraggingImage logic inside the file-drag branch
and only read files from event.dataTransfer in handleImageDrop when isFileDrag
is true, then call selectImageFile as before.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: d06af50d-c80f-4ce4-8240-13cebd14c3e8
📒 Files selected for processing (2)
apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsxapps/web/src/app/community/[boardCode]/create/PostForm.tsx
| const handleImageDragEnter = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
|
|
||
| dragDepthRef.current += 1; | ||
| setIsDraggingImage(true); | ||
| }; | ||
|
|
||
| const handleImageDragOver = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| event.dataTransfer.dropEffect = "copy"; | ||
| }; | ||
|
|
||
| const handleImageDragLeave = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
|
|
||
| dragDepthRef.current -= 1; | ||
| if (dragDepthRef.current <= 0) { | ||
| dragDepthRef.current = 0; | ||
| setIsDraggingImage(false); | ||
| } | ||
| }; | ||
|
|
||
| const handleImageDrop = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
|
|
||
| dragDepthRef.current = 0; | ||
| setIsDraggingImage(false); | ||
|
|
||
| const file = event.dataTransfer.files?.[0] ?? null; | ||
| if (!file) return; | ||
|
|
||
| selectImageFile(file); | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -type f -name "PostModifyForm.tsx" | head -20Repository: solid-connection/solid-connect-web
Length of output: 153
🏁 Script executed:
fd "PostModifyForm.tsx" -x cat -n {} | head -200Repository: solid-connection/solid-connect-web
Length of output: 6738
🏁 Script executed:
rg "handleImageDrag" -A 3 -B 1Repository: solid-connection/solid-connect-web
Length of output: 4340
🏁 Script executed:
sed -n '190,210p' ./apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsxRepository: solid-connection/solid-connect-web
Length of output: 1049
🏁 Script executed:
rg "textarea" ./apps/web/src/app/community/[boardCode]/[postId]/modify/PostModifyForm.tsx -B 2 -A 2Repository: solid-connection/solid-connect-web
Length of output: 1683
🏁 Script executed:
rg "dataTransfer\.types" . -t tsx -t tsRepository: solid-connection/solid-connect-web
Length of output: 105
파일 드래그만 감지하도록 조건을 추가해주세요.
현재 구현에서는 모든 드래그 이벤트에 preventDefault()를 호출하고 있어서, 제목과 내용 textarea의 텍스트 드롭 동작도 막히고 있습니다. 결과적으로 이미지 업로드와 무관한 드래그 액션에도 오버레이가 표시되고 사용자 편의성이 떨어집니다.
다음과 같이 파일 드래그 여부를 먼저 확인한 후에만 기본 동작을 중단하도록 수정해주세요:
-
파일 드래그 감지 헬퍼 함수 추가
event.dataTransfer.types에 "Files"가 포함되어 있는지 확인- 파일 드래그가 아니면 조기 반환
-
각 드래그 핸들러에 조건문 적용
handleImageDragEnter,handleImageDragOver,handleImageDragLeave,handleImageDrop모두에 파일 확인 로직 추가preventDefault()호출 전에 파일 드래그 여부 검사
🔧 수정 예시
+const isFileDrag = (event: DragEvent<HTMLDivElement>) =>
+ Array.from(event.dataTransfer.types).includes("Files");
+
const handleImageDragEnter = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
dragDepthRef.current += 1;
setIsDraggingImage(true);
};
const handleImageDragOver = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
event.dataTransfer.dropEffect = "copy";
};
const handleImageDragLeave = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
dragDepthRef.current -= 1;
if (dragDepthRef.current <= 0) {
@@
};
const handleImageDrop = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
dragDepthRef.current = 0;
setIsDraggingImage(false);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleImageDragEnter = (event: DragEvent<HTMLDivElement>) => { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| dragDepthRef.current += 1; | |
| setIsDraggingImage(true); | |
| }; | |
| const handleImageDragOver = (event: DragEvent<HTMLDivElement>) => { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| event.dataTransfer.dropEffect = "copy"; | |
| }; | |
| const handleImageDragLeave = (event: DragEvent<HTMLDivElement>) => { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| dragDepthRef.current -= 1; | |
| if (dragDepthRef.current <= 0) { | |
| dragDepthRef.current = 0; | |
| setIsDraggingImage(false); | |
| } | |
| }; | |
| const handleImageDrop = (event: DragEvent<HTMLDivElement>) => { | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| dragDepthRef.current = 0; | |
| setIsDraggingImage(false); | |
| const file = event.dataTransfer.files?.[0] ?? null; | |
| if (!file) return; | |
| selectImageFile(file); | |
| }; | |
| const isFileDrag = (event: DragEvent<HTMLDivElement>) => | |
| Array.from(event.dataTransfer.types).includes("Files"); | |
| const handleImageDragEnter = (event: DragEvent<HTMLDivElement>) => { | |
| if (!isFileDrag(event)) return; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| dragDepthRef.current += 1; | |
| setIsDraggingImage(true); | |
| }; | |
| const handleImageDragOver = (event: DragEvent<HTMLDivElement>) => { | |
| if (!isFileDrag(event)) return; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| event.dataTransfer.dropEffect = "copy"; | |
| }; | |
| const handleImageDragLeave = (event: DragEvent<HTMLDivElement>) => { | |
| if (!isFileDrag(event)) return; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| dragDepthRef.current -= 1; | |
| if (dragDepthRef.current <= 0) { | |
| dragDepthRef.current = 0; | |
| setIsDraggingImage(false); | |
| } | |
| }; | |
| const handleImageDrop = (event: DragEvent<HTMLDivElement>) => { | |
| if (!isFileDrag(event)) return; | |
| event.preventDefault(); | |
| event.stopPropagation(); | |
| dragDepthRef.current = 0; | |
| setIsDraggingImage(false); | |
| const file = event.dataTransfer.files?.[0] ?? null; | |
| if (!file) return; | |
| selectImageFile(file); | |
| }; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/app/community/`[boardCode]/[postId]/modify/PostModifyForm.tsx
around lines 101 - 137, Add a small helper (e.g., isFileDrag(event:
DragEvent<HTMLDivElement>): boolean) that returns true only when
event.dataTransfer?.types includes "Files" (and for drop, that
event.dataTransfer?.files?.length > 0); then update handleImageDragEnter,
handleImageDragOver, handleImageDragLeave, and handleImageDrop to call this
helper first and early-return if false so preventDefault()/stopPropagation() and
the overlay logic only run for actual file drags (for handleImageDrop also read
the files after the helper confirms a file drag).
| const handleImageDragEnter = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
|
|
||
| dragDepthRef.current += 1; | ||
| setIsDraggingImage(true); | ||
| }; | ||
|
|
||
| const handleImageDragOver = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
| event.dataTransfer.dropEffect = "copy"; | ||
| }; | ||
|
|
||
| const handleImageDragLeave = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
|
|
||
| dragDepthRef.current -= 1; | ||
| if (dragDepthRef.current <= 0) { | ||
| dragDepthRef.current = 0; | ||
| setIsDraggingImage(false); | ||
| } | ||
| }; | ||
|
|
||
| const handleImageDrop = (event: DragEvent<HTMLDivElement>) => { | ||
| event.preventDefault(); | ||
| event.stopPropagation(); | ||
|
|
||
| dragDepthRef.current = 0; | ||
| setIsDraggingImage(false); | ||
|
|
||
| const file = event.dataTransfer.files?.[0] ?? null; | ||
| if (!file) return; | ||
|
|
||
| selectImageFile(file); | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check if the file exists and get its complete context
fd "PostForm.tsx" --type fRepository: solid-connection/solid-connect-web
Length of output: 136
🏁 Script executed:
# Once we find the file, let's read the relevant section
cat -n apps/web/src/app/community/[boardCode]/create/PostForm.tsx | sed -n '80,125p'Repository: solid-connection/solid-connect-web
Length of output: 1569
🏁 Script executed:
# Let's also check the full file structure to understand the context better
wc -l apps/web/src/app/community/[boardCode]/create/PostForm.tsxRepository: solid-connection/solid-connect-web
Length of output: 140
🏁 Script executed:
# Search for drag event handlers in the file
rg "handle.*Drag|dragDepthRef" apps/web/src/app/community/[boardCode]/create/PostForm.tsx -A 3 -B 1Repository: solid-connection/solid-connect-web
Length of output: 1361
파일 드래그가 아닐 때는 기본 드롭 동작을 살려 주세요.
현재 모든 drag 이벤트에서 preventDefault()를 호출하고 있어서, 폼 안의 textarea로 텍스트를 끌어다 놓는 기본 동작까지 차단됩니다. 그 결과 이미지와 무관한 텍스트/링크 드래그에도 오버레이가 표시되고, 텍스트 편집 UX가 회귀합니다.
다음과 같이 수정해주세요:
-
드래그 타입 검사 함수 추가
event.dataTransfer.types에서 "Files"가 포함되어 있는지 확인하는isFileDrag()헬퍼 함수를 추가합니다.
-
각 드래그 핸들러에 파일 검증 로직 추가
handleImageDragEnter,handleImageDragOver,handleImageDragLeave,handleImageDrop각 함수에서 파일 드래그가 아니면 조기에 반환합니다.preventDefault()와stopPropagation()은 파일 드래그일 때만 호출되도록 변경합니다.
이렇게 하면 이미지 드롭은 정상적으로 처리되면서도, 텍스트나 링크 드래그는 브라우저의 기본 동작을 유지할 수 있습니다.
🔧 최소 수정 예시
+const isFileDrag = (event: DragEvent<HTMLDivElement>) =>
+ Array.from(event.dataTransfer.types).includes("Files");
+
const handleImageDragEnter = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
dragDepthRef.current += 1;
setIsDraggingImage(true);
};
const handleImageDragOver = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
event.dataTransfer.dropEffect = "copy";
};
const handleImageDragLeave = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
dragDepthRef.current -= 1;
if (dragDepthRef.current <= 0) {
@@
};
const handleImageDrop = (event: DragEvent<HTMLDivElement>) => {
+ if (!isFileDrag(event)) return;
event.preventDefault();
event.stopPropagation();
dragDepthRef.current = 0;
setIsDraggingImage(false);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/src/app/community/`[boardCode]/create/PostForm.tsx around lines 84 -
120, Add a helper isFileDrag that checks event.dataTransfer?.types includes
"Files" and update the drag handlers (handleImageDragEnter, handleImageDragOver,
handleImageDragLeave, handleImageDrop) to early-return when !isFileDrag(event)
so you only call event.preventDefault() and event.stopPropagation() for actual
file drags; keep existing dragDepthRef and setIsDraggingImage logic inside the
file-drag branch and only read files from event.dataTransfer in handleImageDrop
when isFileDrag is true, then call selectImageFile as before.
변경 사항
구현 상세
PostForm.tsxselectImageFile유틸로 파일 검증 로직 통합PostModifyForm.tsx검증
pnpm --filter @solid-connect/web run ci:check통과ci:check+build통과