Skip to content

fix: persist appearance theme only after save - #13

Open
Devanshukoli wants to merge 2 commits into
mainfrom
development
Open

fix: persist appearance theme only after save#13
Devanshukoli wants to merge 2 commits into
mainfrom
development

Conversation

@Devanshukoli

Copy link
Copy Markdown
Owner

Summary

  • Closes Appearance change theme #6: selecting a new Appearance theme no longer sticks when you switch to other Settings tabs (or leave Settings) without saving.
  • Theme selection now previews only. The previous saved theme is restored until you click Save Changes, which persists it to localStorage and the profile.
  • Adds regression tests for preview vs persist vs revert in src/lib/theme.test.ts.

Why

Previously, clicking Light / Dark / System called applyTheme() immediately, which wrote localStorage and applied the class globally. Navigating to General, Security, etc. kept that unsaved theme.

How to test

  • Open Settings → Appearance with a saved theme (e.g. Light).
  • Select Dark (or another option) and confirm the UI previews it.
  • Switch to another Settings tab without saving — the original saved theme should return, and the Appearance selection should reset to the saved value.
  • Select a new theme again, click Save Changes, then switch tabs / leave Settings — the new theme should stay.
  • Reload the app — the saved theme should still apply.

Made with Cursor

Theme picks now preview in place and revert when leaving Appearance or Settings, so unsaved choices no longer stick across tabs. Save Changes is what commits the theme.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f05434b6-2fb8-4c20-ae72-2cc076e5cac4


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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Persist appearance theme only after saving settings

🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Separates temporary theme previews from persisted appearance preferences.
• Reverts unsaved previews when leaving Appearance or Settings.
• Covers preview, save, revert, and system-theme behavior with regression tests.
Diagram

sequenceDiagram
  actor User
  participant Settings as Settings View
  participant Theme as Theme Library
  participant DOM as Document Root
  participant Store as Local Storage
  participant Profile as Profile API
  User->>Settings: Select theme
  Settings->>Theme: Preview theme
  Theme->>DOM: Toggle dark class
  alt Save changes
    Settings->>Profile: Persist profile
    Profile-->>Settings: Save succeeds
    Settings->>Theme: Apply theme
    Theme->>Store: Store mode
    Theme->>DOM: Apply mode
  else Leave appearance
    Settings->>Theme: Revert preview
    Theme->>Store: Read saved mode
    Theme->>DOM: Restore mode
  end
Loading
High-Level Assessment

The preview-versus-commit split in the shared theme utility is the appropriate approach: it preserves immediate visual feedback while centralizing persistence semantics. Keeping temporary selection state in SettingsView and reverting it at navigation and unmount boundaries is proportionate to this scoped workflow.

Files changed (3) +145 / -13

Bug fix (2) +44 / -13
SettingsView.tsxTreat appearance selection as a reversible preview +25/-8

Treat appearance selection as a reversible preview

• Theme option clicks now preview without persistence. Leaving Appearance or unmounting Settings restores the committed theme, while a successful Save Changes operation persists and applies the selected mode.

src/components/SettingsView.tsx

theme.tsSeparate theme previewing from persistence +19/-5

Separate theme previewing from persistence

• Extracts dark-mode resolution and introduces a non-persistent preview function. Persistent application now delegates visual updates to preview logic, while a revert helper restores the stored preference.

src/lib/theme.ts

Tests (1) +101 / -0
theme.test.tsCover preview, persistence, and theme reversion +101/-0

Cover preview, persistence, and theme reversion

• Adds mocked DOM and localStorage regression tests proving previews do not persist, saves do persist, reverts restore the saved theme, and system-mode previews honor the OS preference.

src/lib/theme.test.ts

@qodo-code-review

qodo-code-review Bot commented Aug 26, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. System changes break previews ✓ Resolved 🐞 Bug ≡ Correctness
Description
previewTheme applies a transient mode without recording it, while the OS color-scheme listener
still gates updates on the persisted getStoredTheme() value. An OS theme change therefore
overwrites an explicit preview when the saved mode is system, or fails to update a system
preview when the saved mode is explicit.
Code

src/lib/theme.ts[R19-20]

+export function previewTheme(mode: ThemeMode) {
+  if (isDarkMode(mode)) {
Evidence
The new preview function only changes the DOM class, whereas the existing listener reads
localStorage. The Settings view now deliberately allows the preview mode and stored mode to differ,
exposing both mismatch cases.

src/lib/theme.ts[3-15]
src/lib/theme.ts[18-35]
src/lib/theme.ts[38-51]
src/components/SettingsView.tsx[365-377]
src/lib/theme.test.ts[90-100]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The system color-scheme listener uses the persisted theme instead of the currently active preview mode, so OS changes handle unsaved previews incorrectly.

## Issue Context
Maintain an in-memory active theme mode. Update it from `previewTheme`, and have the `matchMedia` listener react only when that active mode is `system`; ensure apply and revert paths keep it synchronized.

## Fix Focus Areas
- src/lib/theme.ts[11-35]
- src/lib/theme.ts[38-51]
- src/lib/theme.test.ts[90-101]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced

Grey Divider

Tip of the day
💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/lib/theme.ts
The matchMedia listener now uses in-memory preview mode instead of localStorage, so unsaved system previews track OS changes and other previews do not.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Appearance change theme

1 participant