feat: [Game] 遊戲設定記住上次腔調/級別,並雲端同步 - #229
Conversation
開遊戲 modal 時優先套用上一次實際玩過的腔調/級別(存於 localStorage hakkaGameLastDataVarName,隨遊戲進度一起雲端同步);若從未玩過遊戲,才 退回網頁本身(或其他功能)目前設定的腔調/級別,行為與既有 fallback 邏輯 一致。
There was a problem hiding this comment.
Code Review
This pull request introduces a feature to remember and sync the last played game dialect and level (hakkaGameLastDataVarName) across devices. It updates the game UI to restore this preference upon opening the game modal and integrates it into the cloud synchronization logic. However, the current sync implementation has two critical issues: first, a data loss bug where local preference changes can be overwritten by older cloud data during sync; second, a redundant upload bug where pulling new settings from the cloud triggers an unnecessary push back to the cloud. Introducing a synced preferences snapshot (hakkaPrefsSynced) to track local changes and compare merged values is recommended to resolve these issues.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Review 摘要這個 PR 讓遊戲 modal 開啟時優先套用「上一次實際玩過」的腔調/級別(存於 主要想請作者確認一個可能會讓功能實質失效的同步 race,其餘是程式碼品質層級的建議。 🐛 潛在的正確性問題(建議修正):cloud-wins 覆寫發生在 push 讀值之前,導致本地最新選擇被吃掉
// 空字串代表雲端「從未玩過遊戲」,此時保留本地值(可能本地剛玩過、還沒推上去)
if (cloudPrefs.gameLastDataVarName) {
localStorage.setItem('hakkaGameLastDataVarName', cloudPrefs.gameLastDataVarName);
}這段會在雲端已有「非空」值時,無條件用雲端值覆寫本地 localStorage——即使本地剛剛才寫入了一個更新的值。緊接著 Smart Push 判斷 實際重現路徑(單一裝置、不需要多裝置併發):
也就是說,只要使用者切換到「跟目前雲端已同步值不同」的新關卡,這個新選擇幾乎都會在下一次同步後被悄悄吃掉——這剛好是這個 PR 想解決的核心情境(記住最近一次玩的關卡),影響會比較明顯。 這個「雲端非空就整包覆寫本地」的寫法其實是沿用既有 建議方向(擇一即可):
若這個 race 是已知且可接受的技術債,麻煩在 PR 說明或程式碼註解點一下,避免之後被誤認為新 bug。 🧹 程式碼品質:新增的「套用上次關卡」邏輯與既有兩段高度重複
這次新增等於是把重複次數從 2 次變成 3 次。建議抽出一個小 helper,例如: function applyGameLevelSelection(dataVarName, displayName) {
gameActiveDataVarName = dataVarName;
const 腔 = dataVarName.substring(0, 1);
const 級 = dataVarName.substring(1);
gameActiveDialect = getDialectInfo(腔, 級).腔名 || '四縣';
document.getElementById('game-target-level').textContent = displayName;
if (readyBlock) readyBlock.style.display = 'block';
if (selectBlock) selectBlock.style.display = 'none';
const startSessionBtn = document.getElementById('gameStartSessionBtn');
if (startSessionBtn) startSessionBtn.style.display = 'block';
showGameView('setup');
gameModal.style.display = 'flex';
}三個分支都改呼叫這個函式即可,往後如果 ready-block 的 DOM 結構要調整,只需要改一處,不會有漏改其中一支分支的風險。 其他觀察(非阻擋項)
整體來說方向正確、有照著既有慣例(版本號、AGENTS.md 表格、try/catch)做,主要建議是確認一下上面那個同步覆寫的 race,以及考慮把三段重複邏輯合併成一個 helper。 |
開遊戲 modal 仍照舊優先用網頁本身(或其他功能)目前設定的腔調/級別; 換腔換級按鈕旁新增橘色醒目「搞上擺个腔級」按鈕,只有跟上次實際玩過的 腔調/級別不同時才會出現,按下去才代入 localStorage 記住的上次遊戲設定。
Deploying hakspring with
|
| Latest commit: |
67281ea
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://31943c2c.hakspring.pages.dev |
| Branch Preview URL: | https://claude-game-settings-localst.hakspring.pages.dev |
|
Review: feat: 遊戲設定記住上次腔調/級別,並雲端同步 (PR 229) Overview Strengths
Issues
style.css adds: but there is no dark-mode override. The existing @media (prefers-color-scheme: dark) block (around line 4158) already overrides
The PR description states the modal will prioritize/auto-apply the last-played tone/level when opening the game modal. Looking at handleStartGameClick in game-ui.js, the priority order when opening the modal is unchanged: (1) current site-wide dialect/level, (2) inferred from SRS due dates - hakkaGameLastDataVarName is never consulted there. It is only applied when the user explicitly clicks the new "搞上擺个腔級" button. That is a reasonable (arguably safer/more explicit) design, but it does not match what the PR description promises. Worth updating the PR description (or the code, whichever reflects the real intent) so reviewers/testers are not testing for the wrong behavior. Minor notes
Security / Performance Overall a small, well-scoped feature that follows the repos cloud-sync governance conventions closely. The main things worth addressing before merge are the dark-mode CSS gap and clarifying the actual vs. described auto-apply behavior. Generated with Claude Code |
- 回應 PR review:偏好設定同步比照 hakkaDailyStatsSynced 引入 hakkaPrefsSynced 已同步快照,本地相對快照未變才套用雲端值, 否則保留本地並用合併後的最終值判斷是否需要 push,避免剛玩的 新關卡被雲端舊值覆寫、或把剛拉下來的舊值又原封不動推回去。 - .game-btn-highlight 補上暗色模式覆寫,避免橘色醒目按鈕在暗色 模式下被 .game-btn 的藍色覆蓋掉。 - 結果頁「調整設定/換其他腔調/級別」按鈕改回選項畫面(沿用剛 打完那局的腔調/級別),不再每次都先逼使用者重選腔調/級別; 真要換的話畫面上仍有「換其他腔/其他級」可點。
|
Review: 遊戲設定記住上次腔調/級別,並雲端同步 (#229) Overview Code quality & conventions
Potential issues
Security Performance Test coverage Overall a well-scoped, carefully-commented change that follows the project's established sync-governance patterns. The migration nuance in point 1 is the only thing worth a second look before merging. |
開遊戲 modal 時優先套用上一次實際玩過的腔調/級別(存於 localStorage
hakkaGameLastDataVarName,隨遊戲進度一起雲端同步);若從未玩過遊戲,才
退回網頁本身(或其他功能)目前設定的腔調/級別,行為與既有 fallback 邏輯
一致。