feat: extract settings into a separate native window#53
Conversation
- Added `OpenSettingsWindow` in the Go backend to handle spawning and focusing a dedicated settings window via Wails v3 WebviewWindow. - Modified the application menu (`main.go`) to trigger the new native window instead of emitting an IPC event. - Extracted the settings modal from `App.tsx` into a new standalone `SettingsWindow.tsx` component. - Implemented client-side routing in `main.tsx` to serve the settings view on the `/settings` path. - Updated `App.tsx` to synchronize `watchFolder` and `exportFolder` states via the `settings_saved` Wails event. - Added a draggable top bar to the settings window for better native UX. - Improved type safety and Promise error handling based on code review.
📝 WalkthroughSummary by CodeRabbitリリースノート
WalkthroughSettings ウィンドウを App 内ローカルモーダルから独立 Wails ウィンドウに変更。バックエンド側で OpenSettingsWindow() メソッド追加、フロントエンドに新規 SettingsWindow コンポーネント実装、既存 App から設定モーダルと関連イベント処理削除、イベント駆動で設定変更後の再読み込み追加。 ChangesSettings Window の独立化
🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/src/SettingsWindow.tsx`:
- Around line 37-66: The settings_saved event emitted by handleSave triggers
this component's own settings_saved listener and causes an unnecessary
GetSettings() reload; modify Events.Emit("settings_saved") to include an
identifier (e.g., { source: myWindowId } or { skipSelf: true }) and update the
local listener (the settings_saved handler in this component that calls
GetSettings()) to ignore events coming from the same source (compare
payload.source to a currentWindowId) or payload.skipSelf === true, while leaving
other windows to continue reacting normally; reference handleSave, Events.Emit,
the settings_saved listener, GetSettings, and
setFullSettings/setWatchFolder/setExportFolder when making the change.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 80010365-e7e0-4f1e-9c1e-80b11481002f
📒 Files selected for processing (5)
app.gofrontend/src/App.tsxfrontend/src/SettingsWindow.tsxfrontend/src/main.tsxmain.go
| const handleSave = async (newWatch: string, newExport: string) => { | ||
| if (!fullSettings) return; | ||
|
|
||
| const s = new Settings(); | ||
| // Copy existing settings | ||
| Object.assign(s, fullSettings); | ||
|
|
||
| // Update folders | ||
| s.watchFolder = newWatch; | ||
| s.exportFolder = newExport; | ||
|
|
||
| try { | ||
| const errStr = await AppAPI.SaveSettings(s); | ||
| if (errStr && errStr !== "") { | ||
| console.error(errStr); | ||
| alert(errStr); | ||
| return; | ||
| } | ||
|
|
||
| // Update local state | ||
| setWatchFolder(newWatch); | ||
| setExportFolder(newExport); | ||
| setFullSettings(s); | ||
|
|
||
| // Notify other windows | ||
| Events.Emit("settings_saved"); | ||
| } catch (e: any) { | ||
| console.error("Error saving settings", e); | ||
| } | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
保存後に自身のイベントを受信して設定を再読み込みしています。
handleSave が Events.Emit("settings_saved") を呼び出すと、同じコンポーネント内の settings_saved リスナー(24-30行目)がトリガーされ、保存したばかりの設定を再度 GetSettings() で取得します。
クロスウィンドウ同期のためにリスナーは必要ですが、自身の保存操作による再読み込みは冗長です。パフォーマンスへの影響は軽微ですが、最適化する場合は保存元ウィンドウを識別するフラグをイベントペイロードに含めることを検討してください。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/src/SettingsWindow.tsx` around lines 37 - 66, The settings_saved
event emitted by handleSave triggers this component's own settings_saved
listener and causes an unnecessary GetSettings() reload; modify
Events.Emit("settings_saved") to include an identifier (e.g., { source:
myWindowId } or { skipSelf: true }) and update the local listener (the
settings_saved handler in this component that calls GetSettings()) to ignore
events coming from the same source (compare payload.source to a currentWindowId)
or payload.skipSelf === true, while leaving other windows to continue reacting
normally; reference handleSave, Events.Emit, the settings_saved listener,
GetSettings, and setFullSettings/setWatchFolder/setExportFolder when making the
change.
OpenSettingsWindowin the Go backend to handle spawning and focusing a dedicated settings window via Wails v3 WebviewWindow.main.go) to trigger the new native window instead of emitting an IPC event.App.tsxinto a new standaloneSettingsWindow.tsxcomponent.main.tsxto serve the settings view on the/settingspath.App.tsxto synchronizewatchFolderandexportFolderstates via thesettings_savedWails event.resolved #30