Skip to content

Open sidebar file drags in the file viewer#334

Merged
MocA-Love merged 2 commits into
mainfrom
feat/desktop-sidebar-file-drag-viewer
Apr 19, 2026
Merged

Open sidebar file drags in the file viewer#334
MocA-Love merged 2 commits into
mainfrom
feat/desktop-sidebar-file-drag-viewer

Conversation

@MocA-Love
Copy link
Copy Markdown
Owner

@MocA-Love MocA-Love commented Apr 18, 2026

Summary

  • add a desktop setting to choose how internal sidebar file drags behave, defaulting to opening the file viewer
  • route internal file drops in v1/v2 terminal panes to the file viewer while keeping external file drops as pasted paths
  • persist the new preference in local-db and include small lint-driven fixes needed for root lint to pass

Validation

  • bun run lint
  • bun run typecheck

Summary by CodeRabbit

リリースノート

  • 新機能
    • ファイルドラッグ動作設定を追加しました。ファイルをドラッグ時にファイルビューアで開くか、パスを貼り付けるかを選択できるようになりました。設定は「動作」セクションで変更できます。

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 18, 2026

Warning

Rate limit exceeded

@MocA-Love has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 37 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 46 minutes and 37 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6f739c28-b5e9-4f7d-bc3e-d223e98cff3a

📥 Commits

Reviewing files that changed from the base of the PR and between 3fdb55c and ab025af.

📒 Files selected for processing (3)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/AudioEditor/AudioEditor.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/EditCustomRingtoneDialog/EditCustomRingtoneDialog.tsx
📝 Walkthrough

Walkthrough

ファイルドラッグ動作設定を新規追加し、ユーザーがファイルをドラッグ時に「ファイルビューアで開く」または「パスを貼り付け」のいずれかを選択できる機能を実装しました。データベーススキーマ拡張、TRPC設定エンドポイント、UIコンポーネント、ドラッグアンドドロップハンドラーを追加しました。

Changes

Cohort / File(s) Summary
Database Schema & Types
packages/local-db/drizzle/0065_add_file_drag_behavior_setting.sql, packages/local-db/drizzle/meta/..., packages/local-db/src/schema/zod.ts, packages/local-db/src/schema/schema.ts
settingsテーブルにfile_drag_behaviorカラムを追加し、FileDragBehavior型とFILE_DRAG_BEHAVIORS定数を定義しました。
TRPC Settings Router
apps/desktop/src/lib/trpc/routers/settings/index.ts, apps/desktop/src/shared/constants.ts
getFileDragBehaviorクエリとsetFileDragBehaviorミューテーションを追加し、ファイルドラッグ動作の取得・保存を実装しました。
Settings UI
apps/desktop/src/renderer/routes/_authenticated/settings/behavior/components/BehaviorSettings/BehaviorSettings.tsx, apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts
ファイルドラッグ動作設定用のセレクトコンポーネントと設定検索インデックスを追加しました。
File Drag Utilities
apps/desktop/src/renderer/lib/file-drag.ts, apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/hooks/useFileDrag.ts
内部ファイルパス用のINTERNAL_FILE_PATH_MIME定数とgetInternalDraggedFilePath()ヘルパー関数を追加しました。
Terminal Component Drag Handling
apps/desktop/src/main/todo-agent/schedule-sync.ts, apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx, apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
ドラッグされたファイルパスを検出し、設定に基づいてファイルビューアを開くか動作を制御するロジックを追加しました。
File Opening Handler
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
handleTerminalOpenFileコールバックにopenInNewTabパラメータを追加し、サイドバーでのファイル開き動作に対応しました。
Audio Editor & Dialog
apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/AudioEditor/AudioEditor.tsx, apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/EditCustomRingtoneDialog/EditCustomRingtoneDialog.tsx
useEffect依存配列を更新して、hasInitialRangeおよびopenSourcecloseSourceの変更時に効果が再実行されるようにしました。
Test Setup
apps/desktop/test-setup.ts
ローカルDBモックにFILE_DRAG_BEHAVIORS設定を追加しました。

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Settings UI
    participant TRPC Settings
    participant Database
    participant Drag Handler
    participant File Viewer

    User->>Settings UI: ファイルドラッグ動作を選択<br/>(open-file-viewer / paste-path)
    Settings UI->>TRPC Settings: setFileDragBehavior(newBehavior)
    TRPC Settings->>Database: upsert settings.fileDragBehavior
    Database-->>TRPC Settings: success
    TRPC Settings-->>Settings UI: { success: true }
    Settings UI->>User: 設定を保存

    User->>Drag Handler: ファイルをドラッグ&ドロップ
    Drag Handler->>TRPC Settings: getFileDragBehavior()
    TRPC Settings->>Database: select fileDragBehavior
    Database-->>TRPC Settings: behavior value
    TRPC Settings-->>Drag Handler: behavior
    alt behavior === "open-file-viewer"
        Drag Handler->>File Viewer: addFileViewerPane(filePath)
        File Viewer->>User: ファイルを表示
    else behavior === "paste-path"
        Drag Handler->>User: パスをペースト
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #170: addFileViewerPane呼び出しにuseRightSidebarOpenViewWidthオプションを渡す変更が重複しており、ファイルビューアペイン開始地点での関連変更があります。
  • PR #287: 同じTRPC設定ルーター(apps/desktop/src/lib/trpc/routers/settings/index.ts)にクエリ・ミューテーションを追加する点で、コードレベルの関連性があります。
  • PR #24: Terminal.tsxコンポーネントを両方が修正しており、内部ファイルドラッグハンドリングとシェル履歴提案機能の実装でファイルレベルの重複があります。

Poem

🐰 ファイルをね、ドラッグするとね
設定どおりに、ひょいと動く
ビューアで見たり、パスを貼ったり
ウサギもうれしい、自由な選択
つんっ!🐇

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning 説明は提供されているテンプレートの構造に従わず、必須セクション「Related Issues」「Type of Change」「Testing」が不足しており、基本情報のみが記載されています。 プルリクエストの説明をテンプレートに従うように更新してください。関連するイシュー、変更の種類(New featureなど)、実施したテストの詳細を追加してください。
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed タイトルはプルリクエストの主な変更を正確に要約しており、内部サイドバーファイルドラッグをファイルビューアで開くという主要な機能改善を明確に説明しています。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/desktop-sidebar-file-drag-viewer

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.

Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/EditCustomRingtoneDialog/EditCustomRingtoneDialog.tsx (1)

33-91: ⚠️ Potential issue | 🟠 Major

useMutation の戻り値オブジェクトを effect の依存配列から削除してください。

Line 78 と Line 91 で openSource / closeSource 全体を依存配列に含めると、mutation の状態更新でオブジェクト identity が変わる場合に effect が再実行されます。特に Line 56-78 の acquisition effect は mutation オブジェクトの identity 変化をきっかけに openCustomSource.mutateAsync() を複数回呼び出す可能性があり、最後の tempId だけが openedTempIdRef に残るため、先に確保した temp audio リソースを解放できないリスクがあります。

mutateAsync / mutate を分割代入して、それらだけを依存配列に入れてください。

修正案
-	const openSource = electronTrpc.ringtone.openCustomSource.useMutation();
-	const closeSource = electronTrpc.ringtone.closeCustomSource.useMutation();
+	const { mutateAsync: openCustomSource } =
+		electronTrpc.ringtone.openCustomSource.useMutation();
+	const { mutate: closeCustomSource } =
+		electronTrpc.ringtone.closeCustomSource.useMutation();
 	const reEdit = electronTrpc.ringtone.reEditCustom.useMutation();
 
 	// ...
 
 	useEffect(() => {
 		if (!open) return;
 		let cancelled = false;
-		openSource
-			.mutateAsync()
+		openCustomSource()
 			.then((result) => {
 				if (cancelled) return;
 				if (result.tempId) {
 					setTempId(result.tempId);
 					openedTempIdRef.current = result.tempId;
 				} else {
 					setErrorMessage(
 						"No saved source audio for this ringtone. Re-import from YouTube to enable editing.",
 					);
 				}
 			})
 			.catch((err: Error) => {
 				if (!cancelled) setErrorMessage(err.message);
 			});
 		return () => {
 			cancelled = true;
 		};
-	}, [open, openSource]);
+	}, [open, openCustomSource]);
 
 	// Release the tempId when the dialog closes.
 	useEffect(() => {
 		if (open) return;
 		const id = openedTempIdRef.current;
 		if (id) {
-			closeSource.mutate({ tempId: id });
+			closeCustomSource({ tempId: id });
 			openedTempIdRef.current = null;
 		}
 		setTempId(null);
 		setErrorMessage(null);
 		setDisplayName(currentDisplayName);
-	}, [open, closeSource, currentDisplayName]);
+	}, [open, closeCustomSource, currentDisplayName]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/EditCustomRingtoneDialog/EditCustomRingtoneDialog.tsx`
around lines 33 - 91, The effects should depend only on the mutation functions,
not the whole mutation objects; destructure openSource.mutateAsync and
closeSource.mutate into local constants (e.g. const { mutateAsync:
openMutateAsync } = openSource and const { mutate: closeMutate } = closeSource)
and use those in the respective useEffect dependency arrays instead of
openSource/closeSource, so the acquisition effect that calls
openSource.mutateAsync() and the cleanup effect that calls closeSource.mutate()
won't re-run due to identity changes of the mutation objects and risk leaking
temp audio (openedTempIdRef/tempId).
🧹 Nitpick comments (2)
apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/AudioEditor/AudioEditor.tsx (1)

208-237: hasInitialRange 依存追加により波形の再デコードが発生する点に注意。

hasInitialRange を依存配列に追加したことで、initialStartSeconds / initialEndSecondsundefined から値ありへ(またはその逆へ)切り替わった際に、decodeWaveformPeaks による fetch + AudioContext.decodeAudioData が丸ごと再実行されます。audioUrl (= tempId) が変わっていないのに波形を再計算するのは無駄で、再編集フローでプロップが遅延して入ってくるケースではローディングスピナーが一瞬再表示される可能性もあります。

本来このエフェクトが気にしたいのは「初回デコード完了後に hasInitialRange が false なら [0, min(10, duration)] を適用する」という初期レンジの適用ロジックだけのはずなので、デコード用エフェクトと初期レンジ適用用エフェクトを分ける方が意図が明確で再デコードも避けられます。

♻️ 提案する分割
-	useEffect(() => {
-		let cancelled = false;
-		setIsLoadingWaveform(true);
-		setWaveformError(null);
-
-		decodeWaveformPeaks(audioUrl, 2400)
-			.then((data) => {
-				if (!cancelled) {
-					setWaveform(data);
-					if (!hasInitialRange) {
-						setStartSeconds(0);
-						setEndSeconds(Math.min(10, data.duration));
-					}
-				}
-			})
-			.catch((err) => {
-				if (!cancelled) {
-					setWaveformError(
-						err instanceof Error ? err.message : "Failed to load audio",
-					);
-				}
-			})
-			.finally(() => {
-				if (!cancelled) setIsLoadingWaveform(false);
-			});
-
-		return () => {
-			cancelled = true;
-		};
-	}, [audioUrl, hasInitialRange]);
+	const hasInitialRangeRef = useRef(hasInitialRange);
+	hasInitialRangeRef.current = hasInitialRange;
+	useEffect(() => {
+		let cancelled = false;
+		setIsLoadingWaveform(true);
+		setWaveformError(null);
+
+		decodeWaveformPeaks(audioUrl, 2400)
+			.then((data) => {
+				if (!cancelled) {
+					setWaveform(data);
+					if (!hasInitialRangeRef.current) {
+						setStartSeconds(0);
+						setEndSeconds(Math.min(10, data.duration));
+					}
+				}
+			})
+			.catch((err) => {
+				if (!cancelled) {
+					setWaveformError(
+						err instanceof Error ? err.message : "Failed to load audio",
+					);
+				}
+			})
+			.finally(() => {
+				if (!cancelled) setIsLoadingWaveform(false);
+			});
+
+		return () => {
+			cancelled = true;
+		};
+	}, [audioUrl]);

なお、本 PR のタイトル/説明(サイドバーのファイルドラッグ挙動)とこのファイルの変更は無関係に見えます。意図的な同梱なのか、別ブランチから混入したものなのかご確認ください。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/AudioEditor/AudioEditor.tsx`
around lines 208 - 237, The current useEffect mixes waveform decoding and
initial-range application causing unnecessary re-decodes when hasInitialRange
changes; split it into two effects: 1) keep the decoding effect using
useEffect(..., [audioUrl]) that sets setIsLoadingWaveform, setWaveformError,
decodes via decodeWaveformPeaks(audioUrl, 2400) with the existing cancelled flag
and finally sets setIsLoadingWaveform(false) and setWaveform(data) (but do NOT
touch start/end seconds here), and 2) add a separate effect using useEffect(...,
[waveform, hasInitialRange]) that runs only after waveform is available and when
hasInitialRange is false to call setStartSeconds(0) and
setEndSeconds(Math.min(10, waveform.duration)); this prevents re-running
decodeWaveformPeaks when hasInitialRange toggles while preserving the
initial-range logic tied to setStartSeconds/setEndSeconds.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx (1)

292-312: ネイティブファイルドロップとの分岐順序に関する軽微な不整合

Terminal.tsx(v1)の handleDrop では files.length === 0 && internalFilePath && ... と外部ファイルドロップを優先する条件になっていますが、こちらの v2 TerminalPane では files.length のチェックが無く、INTERNAL_FILE_PATH_MIME が立っていれば dataTransfer.files の有無に関わらずファイルビューアを開きます。現状は useFileDrag だけがこの MIME を設定するため実害は無いものの、将来的にネイティブドロップ元が同 MIME を付与した場合に v1/v2 で挙動が分岐し得ます。防御的に両者を揃えておくと安心です。

♻️ 揃えるための差分案
-		const internalFilePath = getInternalDraggedFilePath(event.dataTransfer);
-		if (
-			internalFilePath &&
-			(fileDragBehavior ?? DEFAULT_FILE_DRAG_BEHAVIOR) === "open-file-viewer"
-		) {
+		const hasNativeFiles = event.dataTransfer.files.length > 0;
+		const internalFilePath = getInternalDraggedFilePath(event.dataTransfer);
+		if (
+			!hasNativeFiles &&
+			internalFilePath &&
+			(fileDragBehavior ?? DEFAULT_FILE_DRAG_BEHAVIOR) === "open-file-viewer"
+		) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/`$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx
around lines 292 - 312, The drop handler handleDrop currently treats an
INTERNAL_FILE_PATH_MIME drop as a file-viewer open regardless of native file
presence; change the branching to mirror v1 by first checking
event.dataTransfer.files.length === 0 AND internalFilePath (from
getInternalDraggedFilePath(event.dataTransfer)) before deciding to call
onOpenFile (respecting fileDragBehavior/DEFAULT_FILE_DRAG_BEHAVIOR and
fileOpenMode/DEFAULT_FILE_OPEN_MODE). Keep the early returns for connectionState
=== "closed" and empty resolved text (resolveDroppedText), and still focus/paste
via terminalRuntimeRegistry.getTerminal(terminalId) /
terminalRuntimeRegistry.paste when not opening the file viewer.
🤖 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/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/`$workspaceId/page.tsx:
- Around line 358-373: Update the FORK NOTE above handleTerminalOpenFile to
explicitly state the behavioral difference when openInNewTab is false versus
undefined: explain that handleTerminalOpenFile(filePath, openInNewTab?) checks
openInNewTab !== undefined, so callers passing openInNewTab = false (e.g., drag
& drop or fileOpenMode="split-pane") go through openSidebarFilePane(filePath,
false) which triggers sidebar split-width recalculation, whereas callers that
omit the second arg (undefined) call openFilePane(filePath) and do not adjust
the sidebar width; mention the functions handleTerminalOpenFile,
openSidebarFilePane and openFilePane so future readers understand why false must
be treated as a defined value.

---

Outside diff comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/EditCustomRingtoneDialog/EditCustomRingtoneDialog.tsx`:
- Around line 33-91: The effects should depend only on the mutation functions,
not the whole mutation objects; destructure openSource.mutateAsync and
closeSource.mutate into local constants (e.g. const { mutateAsync:
openMutateAsync } = openSource and const { mutate: closeMutate } = closeSource)
and use those in the respective useEffect dependency arrays instead of
openSource/closeSource, so the acquisition effect that calls
openSource.mutateAsync() and the cleanup effect that calls closeSource.mutate()
won't re-run due to identity changes of the mutation objects and risk leaking
temp audio (openedTempIdRef/tempId).

---

Nitpick comments:
In
`@apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/`$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx:
- Around line 292-312: The drop handler handleDrop currently treats an
INTERNAL_FILE_PATH_MIME drop as a file-viewer open regardless of native file
presence; change the branching to mirror v1 by first checking
event.dataTransfer.files.length === 0 AND internalFilePath (from
getInternalDraggedFilePath(event.dataTransfer)) before deciding to call
onOpenFile (respecting fileDragBehavior/DEFAULT_FILE_DRAG_BEHAVIOR and
fileOpenMode/DEFAULT_FILE_OPEN_MODE). Keep the early returns for connectionState
=== "closed" and empty resolved text (resolveDroppedText), and still focus/paste
via terminalRuntimeRegistry.getTerminal(terminalId) /
terminalRuntimeRegistry.paste when not opening the file viewer.

In
`@apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/AudioEditor/AudioEditor.tsx`:
- Around line 208-237: The current useEffect mixes waveform decoding and
initial-range application causing unnecessary re-decodes when hasInitialRange
changes; split it into two effects: 1) keep the decoding effect using
useEffect(..., [audioUrl]) that sets setIsLoadingWaveform, setWaveformError,
decodes via decodeWaveformPeaks(audioUrl, 2400) with the existing cancelled flag
and finally sets setIsLoadingWaveform(false) and setWaveform(data) (but do NOT
touch start/end seconds here), and 2) add a separate effect using useEffect(...,
[waveform, hasInitialRange]) that runs only after waveform is available and when
hasInitialRange is false to call setStartSeconds(0) and
setEndSeconds(Math.min(10, waveform.duration)); this prevents re-running
decodeWaveformPeaks when hasInitialRange toggles while preserving the
initial-range logic tied to setStartSeconds/setEndSeconds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1cc41b2d-6a82-4832-8ba7-17e669f86b5e

📥 Commits

Reviewing files that changed from the base of the PR and between 261df24 and 3fdb55c.

📒 Files selected for processing (18)
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/main/todo-agent/schedule-sync.ts
  • apps/desktop/src/renderer/lib/file-drag.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/TerminalPane/TerminalPane.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/behavior/components/BehaviorSettings/BehaviorSettings.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/AudioEditor/AudioEditor.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/components/RingtonesSettings/components/EditCustomRingtoneDialog/EditCustomRingtoneDialog.tsx
  • apps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/RightSidebar/ChangesView/hooks/useFileDrag.ts
  • apps/desktop/src/shared/constants.ts
  • apps/desktop/test-setup.ts
  • packages/local-db/drizzle/0065_add_file_drag_behavior_setting.sql
  • packages/local-db/drizzle/meta/0065_snapshot.json
  • packages/local-db/drizzle/meta/_journal.json
  • packages/local-db/src/schema/schema.ts
  • packages/local-db/src/schema/zod.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3fdb55cb68

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@MocA-Love MocA-Love self-assigned this Apr 18, 2026
@MocA-Love
Copy link
Copy Markdown
Owner Author

自動レビューの指摘は分類して確認しました。今回の対応は以下です。

  • EditCustomRingtoneDialog: useMutation() の戻り値オブジェクト依存は再実行リスクがあるため修正しました。
  • TerminalPane: v1 terminal と同じく、ネイティブファイル drop がある場合は internal MIME で file viewer を開かないよう分岐を揃えました。
  • AudioEditor: hasInitialRange 変化で波形を再デコードしないよう、decode と初期レンジ適用の effect を分離しました。

対応しなかったのは page.tsx の FORK NOTE 拡張提案だけです。これは機能修正ではなくコメント粒度の提案で、現状の実装意図とコメントで十分に追えるため、この PR では据え置いています。

補足として、PR テンプレート / docstring coverage の自動警告は今回の変更の blocking issue ではないため未対応です。

@MocA-Love
Copy link
Copy Markdown
Owner Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab025afaa1

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +300 to +303
!hasNativeFiles &&
internalFilePath &&
(fileDragBehavior ?? DEFAULT_FILE_DRAG_BEHAVIOR) === "open-file-viewer"
) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip file-viewer open for directory drags

This condition treats any internal sidebar drag as a file and immediately routes it to onOpenFile, but folder rows are also draggable in the Files sidebar (FileTreeItem wires useFileDrag for every entry.path). Dragging a directory into a terminal now opens a file pane that resolves to an "is directory" error and never pastes the path, which regresses the prior drag-to-terminal workflow for directories; this branch should verify the dropped path is a file (or fall back to paste behavior for directories).

Useful? React with 👍 / 👎.

@MocA-Love MocA-Love merged commit 9ed4307 into main Apr 19, 2026
14 checks passed
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