# v2.5 — Settings 頁更新 > 本章對應 R5-4(Settings 新增自動開瀏覽器 toggle)+ R5-5a(砍 Mock 模式相關設定)+ R5-D2(Linux 預設 OFF)+ R5-D3(每次啟動都自動開)+ R5-E(階段化啟動進度)。 > 上層索引:`../design-spec-v2.md` > 版本:**v2.1** · 更新日期:2026-04-14 --- ## 1. 變更摘要 Settings 維持 v1 的 **4 個分頁** 結構(R4 第四輪決策確認): | Tab | v1 內容 | v2 變更 | |-----|---------|---------| | 一般 | 語言、深色模式狀態(唯讀) | **新增**「首次啟動時自動開啟瀏覽器」toggle | | 硬體 | 真實 / Mock 切換、裝置掃描策略 | **刪除** Mock 相關,只保留裝置掃描策略 | | 模型 | 預置模型清單、上傳、自訂 | 不變 | | 進階 | 資料目錄、Python 雙策略、清 log 等 | 不變 | --- ## 2. 「一般」分頁新增項目 ### 2.1 結構 ``` ┌─ Settings > 一般 ───────────────────────────────────────────┐ │ │ │ 語言 │ │ ┌───────────────────────────┐ │ │ │ 繁體中文 ▾ │ │ │ └───────────────────────────┘ │ │ │ │ 深色模式 │ │ 跟隨系統(目前:深色) │ │ │ │ ── 啟動行為 ──────────────────────────────────────── │ │ │ │ 首次啟動時自動開啟瀏覽器 [■□] ON │ │ 啟動 visionA-local 時自動在預設瀏覽器開啟 Web UI。 │ │ 關閉此選項後,你需要手動點控制台的「在瀏覽器開啟」按鈕。 │ │ │ └──────────────────────────────────────────────────────────────┘ ``` ### 2.2 Toggle 規格 | 屬性 | 值 | |------|----| | 元件類型 | ``(shadcn) | | **預設值(依平台)** | **macOS / Windows = `ON`**;**Linux = `OFF`**(R5-D2) | | i18n key | `settings.general.autoOpenBrowser.label` / `settings.general.autoOpenBrowser.description` | | 落地檔案 | **`preferences.json` 位於 `/`**(對齊 TDD v2)
路徑:
• macOS `~/Library/Application Support/visiona-local/preferences.json`
• Windows `%APPDATA%\visiona-local\preferences.json`
• Linux `~/.local/share/visiona-local/preferences.json` | | 儲存機制 | **Go server 端負責讀寫**(`visiona-local/preferences.go`,非 Wails 內建機制 — Wails v2 沒有 settings store)
JSON 格式:`{"openBrowserOnStart": true}`
原子寫入:**write-rename pattern**(`os.WriteFile(path+".tmp", ...)` → `os.Rename(path+".tmp", path)`),POSIX / Windows 均原子 | | 讀取失敗 fallback | 呼叫 `DefaultPreferences()`,依 `runtime.GOOS` 回傳平台預設:
`Preferences{OpenBrowserOnStart: runtime.GOOS != "linux"}` | | 生效時機 | 立即生效,不需 restart app | | 影響對象 | 控制台的「每次啟動自動開瀏覽器」邏輯(見 `v2/control-panel.md §7`) | **Linux 首次使用說明(R5-D2 落地)**: Linux 使用者第一次開 Wails 控制台時,Settings > 一般 的「啟動時自動開啟瀏覽器」toggle **預設是關的**。原因是 Linux 桌面環境差異大,`xdg-open` 在無頭環境 / i3 / xmonad / 極簡 WM 下行為可能異常(例如無預設瀏覽器、或開到錯的 DE session)。Linux 使用者若確認自己的環境可以正常 `xdg-open`,可手動打開此 toggle,下次啟動就會自動開瀏覽器。 關閉此 toggle 時,**啟動進度面板仍然會顯示**(見 `v2/startup-progress.md`),只是第 5 階段「開啟瀏覽器」會被標記為 `跳過(依偏好設定)/ Skipped (per preference)`,第 6 階段「等待 Web UI 連線」改為「等待使用者手動點擊『在瀏覽器開啟』」— 視覺上仍會收尾至 Running state,只是由使用者主動觸發第 5 階段(對齊 R5-E 階段化體驗)。 ### 2.3 重要細節(R5-D3 已定案) **這個 toggle 同時影響「首次」和「每次」啟動嗎?** **R5-D3 決策**:**每次**啟動(含每次 `StartServer` 成功後)都會自動開瀏覽器,不是只有首次。R5-4 原字面「首次啟動」已於 R5-D3 修正。精確行為: - **Toggle ON(macOS / Windows 預設)**:每次雙擊 app 或每次 Start Server 成功後,控制台自動呼叫 OS open browser - **Toggle OFF(Linux 預設)**:啟動時只開控制台,不開瀏覽器;使用者自行點控制台的「在瀏覽器開啟」按鈕 - **Restart Server 情境**:因為 Restart 是同一個 Wails App process 內重啟(R5 雙 UI 架構下 Wails 不關),且啟動進度面板只在 Wails 剛啟動時顯示一次;Restart 時瀏覽器 tab 應由 Offline Overlay 自動重連,不會再開新 tab(避免開一堆重複 tab) **Label 定版**:「啟動時自動開啟瀏覽器」/ "Auto-open browser on startup"(去掉「首次」二字) | 版本 | label | description | |------|-------|-------------| | 原 R5-4 字面 | 首次啟動時自動開啟瀏覽器 | — | | **最終採用(R5-D3 定案)** | 啟動時自動開啟瀏覽器 | 啟動 visionA-local 時自動在預設瀏覽器開啟 Web UI。關閉此選項後,你需要手動點控制台的「在瀏覽器開啟」按鈕。 | --- ## 3. 「硬體」分頁變更 ### 3.1 刪除項目(R5-5a) **所有 Mock 模式相關設定全砍**: | v1 項目 | 說明 | v2 處理 | |---------|------|---------| | `模式:真實硬體 / Mock` radio | 切換整個 app 推論來源 | **刪除** | | `Mock 模式描述` 說明文字 | 介紹 Mock 用途 | **刪除** | | `Mock 模式假資料速率` slider | 調 Mock 輸出速率 | **刪除** | | `Mock 模式裝置名稱` input | 自訂假裝置名 | **刪除** | | `切換模式會重啟推論 session` 警告 | 切換時的提醒 | **刪除** | ### 3.2 保留項目 | 項目 | 說明 | |------|------| | 裝置自動掃描頻率 | 每次啟動時 / 手動 / 關閉 | | USB 熱插拔偵測 toggle | 自動偵測新裝置插入 | | Kneron KL520 / KL720 韌體版本顯示 | 唯讀 | ### 3.3 新增項目 無。R5-5a 砍 Mock 後這個 tab 變得更簡潔。 ### 3.4 Tab 是否保留? 因為「硬體」tab 被清空後仍有內容(掃描頻率、熱插拔、韌體版本),**tab 結構保留**,不合併也不刪除。 --- ## 4. 「模型」與「進階」分頁 **完全不動**。R5 沒有觸及這兩個 tab 的內容。 --- ## 5. i18n key 異動 ### 5.1 新增 key | Key | zh-TW | en | |-----|-------|----| | `settings.general.sectionStartup` | 啟動行為 | Startup behavior | | `settings.general.autoOpenBrowser.label` | 啟動時自動開啟瀏覽器 | Auto-open browser on startup | | `settings.general.autoOpenBrowser.description` | 啟動 visionA-local 時自動在預設瀏覽器開啟 Web UI。關閉此選項後,你需要手動點控制台的「在瀏覽器開啟」按鈕。 | Automatically open the Web UI in your default browser when visionA-local starts. When off, you need to manually click "Open in Browser" in the Control Panel. | ### 5.2 刪除 key 執行 grep 找出所有 mock 相關 key: ``` grep -rE "mock|Mock" frontend/src/lib/i18n/ ``` 預期刪除(實際清單以 grep 為準): | Key | 原值(zh-TW) | |-----|-------------| | `settings.hardware.mode.label` | 模式 | | `settings.hardware.mode.real` | 真實硬體 | | `settings.hardware.mode.mock` | Mock | | `settings.hardware.mode.description` | 選擇 visionA-local 的執行模式 | | `settings.hardware.mock.rate.label` | Mock 速率 | | `settings.hardware.mock.deviceName.label` | Mock 裝置名稱 | | `settings.hardware.modeSwitchWarning` | 切換模式會重啟推論 session | | `firstRun.mode.*` | 全部(見 `v2/first-run-update.md §5.2`) | | `devices.mockBadge` | Mock | (若存在於 Devices 頁面的 Mock 標籤) | `dashboard.tryMockHint` | 或切換到 Mock 模式試用 | (若 Dashboard 空狀態有這句) ### 5.3 type 檔同步 `frontend/src/lib/i18n/types.ts` 對應 interface 欄位全砍,確保 TypeScript 編譯不留 dangling reference。 --- ## 6. 清理殘留的 Mock 程式碼 Settings 改完後,前後端其他地方可能仍有 Mock 殘留: ### 6.1 前端 - `frontend/src/stores/` 任何 `mock` state / action - `frontend/src/components/` 任何 `Mock` badge / pill - `frontend/src/app/devices/` 頁面右上的「真實 / Mock」切換(v1 `design-spec.md §第三輪修訂後仍待確認 4.` 提到) ### 6.2 後端 - Go server 任何 mock handler、假資料 generator - Python sidecar 的 mock inference path **這部分非 Design 的 scope**,但 Design 提醒 Orchestrator:**R5-5a 的「完全砍除」不只是 UI 層面,後端也要同步砍**。交 Architect Agent 評估實作影響。 --- ## 7. 遷移策略(Migration) **使用者情境**:v1 版本沒有 `preferences.json`;Mock 模式相關設定(若存在)是記在前端 localStorage 或 v1 舊式 config,不在 Go 端的 preferences 檔裡。v2 改用 Go 端 `preferences.json` 管理「是否啟動時自動開瀏覽器」,是**全新的檔案**。 **v2 首次讀取 preferences.json 流程**: 1. 檢查 `/preferences.json` 是否存在 2. **不存在** → 呼叫 `DefaultPreferences()`(依 `runtime.GOOS` 回傳平台預設:macOS/Windows `OpenBrowserOnStart=true`,Linux `OpenBrowserOnStart=false`) 3. **存在但解析失敗**(JSON 毀損等)→ 同樣 fallback 到 `DefaultPreferences()`,並發 log WARN(不擋啟動) 4. **存在且解析成功** → 使用使用者設定 5. 使用者在 Settings 點擊 toggle → write-rename atomic pattern 寫回 `preferences.json` **v1 → v2 無 migration 成本**:因為 v1 沒有對應檔案,v2 啟動時若 `preferences.json` 不存在就建立新檔(或延遲到使用者第一次改 toggle 才寫),行為是**靜默**的,使用者不需要知道。 **Mock 模式殘留**:v1 localStorage 可能有 mock 相關 key,Frontend 清理見 §6.1;與 `preferences.json` 無關。 --- ## 8. 無障礙考量 | 項目 | 設計 | |------|------| | Toggle 元件 | 沿用 shadcn ``,已內建 `role="switch"` / `aria-checked` | | Tab 切換 | 沿用現有 Tabs 元件,`role="tablist"` / `role="tab"` / `role="tabpanel"` | | Keyboard | `←` / `→` 切換 tab、`Tab` 進入 tab panel 內部 | | 分區標題 | 「啟動行為」區用 `

` 讓 screen reader 感知結構 | --- ## 9. 與 v1 差異對照 | 面向 | v1 | v2 | |------|----|----| | 一般 tab 項目數 | 2(語言、深色模式) | **3**(新增 auto-open browser) | | 硬體 tab 項目數 | 5+(含 Mock 相關) | 3(只剩真實硬體相關) | | Mock 模式 UI | Settings + Devices pill + First-Run Step | **全砍** | | 模型 / 進階 tab | — | 不變 | --- ## 10. v2 → v2.1 Diff(2026-04-14) | # | 位置 | v2 | v2.1 | 來源 | |---|------|----|----|------| | 1 | §2.2 落地檔案 | `settings.json` + 「走 Wails 既有 settings store」 | **`preferences.json` @ `/`** + Go server 讀寫 + write-rename atomic | Architect Review Major 1 | | 2 | §2.2 預設值 | 三平台一致 `ON` | **macOS/Windows = `ON`,Linux = `OFF`**(依 `DefaultPreferences()` 依 `runtime.GOOS`) | R5-D2 / Architect Review Major 2 | | 3 | §2.2 新增 | — | Linux 首次使用說明(toggle 預設關、關閉時啟動進度面板仍顯示、第 5/6 階段跳過)| R5-D2 + R5-E | | 4 | §2.3 標題 | 「重要細節」待 confirm | **「R5-D3 已定案」每次啟動都開瀏覽器**,label 定版 | R5-D3 | | 5 | §7 遷移策略 | 假設 v1 有 `settings.json` + mock key 遷移 | 澄清 `preferences.json` 是**全新檔**,無 v1 migration 成本 | Architect Review Major 1 衍生 | --- ## 11. 給 Orchestrator 的提醒 1. ~~**R5-4 的 label 字面歧義**~~ → **已於 R5-D3 定案**(每次啟動都開,label 去掉「首次」) 2. **後端 Mock 清理**不在 Design scope,需轉給 Architect / Backend Agent 3. **Devices 頁面的 Mock pill**(v1 `design-spec.md` 第三輪修訂 §4)要一併砍,此變更未在本文件細寫,但屬 R5-5a 範圍 4. **Linux 預設 OFF 對 E2E 測試的影響**:testing Agent 在 Linux CI 上跑自動化時要注意,啟動後不會 auto-open,需手動模擬點擊「在瀏覽器開啟」或在測試前將 `preferences.json` 改為 `{"openBrowserOnStart": true}` --- **下一步**:交 Frontend Agent 更新 Settings 頁面。