Refactor theme management: delegate preferences to PreferencesService#8
Merged
Refactor theme management: delegate preferences to PreferencesService#8
Conversation
One-way markdown → Google Docs sync with three-way diffing infrastructure for surgical updates that preserve reviewer comments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
16-task plan covering auth, converter, three-way diffing, API wrapper, IPC handlers, UI components, mermaid support, and E2E tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lection Theme mode was stored in two places (ThemeService's theme-preferences.json and PreferencesService's preferences.json), causing them to drift out of sync — toolbar toggles were lost on restart because only ThemeService was updated while PreferencesService (the one read at startup) kept stale data. This commit makes PreferencesService the single source of truth: - ThemeService stripped to OS-level system theme detection only - ThemeHandler's GET_CURRENT/SET now delegate to PreferencesService - Removed dual-write in renderer's handlePreferencesChange - Removed ThemeService.initialize() from main process startup Also adds user-configurable font families (body + monospace) to the preferences system, as requested in issue #6's last comment. Font values are stored in preferences.json and override the theme defaults via CSS variables. Closes #6 https://claude.ai/code/session_01JPKgqUDYb7zrib8Qi6KF6n
The font family preferences were being generated as --font-body and --font-mono CSS variables but the CSS used hardcoded font stacks. Replace hardcoded values with var() references so user-configured fonts actually take effect. Fallbacks preserve the original stacks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4f10e8b to
046dcc0
Compare
Replace raw CSS font-stack text inputs with a searchable dropdown that enumerates installed system fonts via queryLocalFonts(). Each option previews in its own typeface. "System Default" uses the built-in fallback stack. Empty string = system default, so generateTypographyCSS skips the variable and the CSS var() fallback takes over. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Font family CSS variables should only affect .markdown-body (the rendered markdown), not the app chrome (toolbar, preferences panel, find bar). Reverted body and color picker input back to hardcoded font stacks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Separates document font variables from app chrome fonts. The app UI keeps its hardcoded font stacks; only the markdown content area uses the --font-doc-* variables from user preferences. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Click the color swatch to open the macOS native color picker (NSColorPanel). Hex result is converted to OKLCH via existing utils. Text inputs for hex and OKLCH direct entry remain functional. A reset button (↺) appears when the color differs from its default value. All core color pickers (background, link, headings) and plugin color pickers now receive their default values for reset support. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the native color input with a purpose-built OKLCH picker that shows a 2D Lightness×Chroma plane with the sRGB gamut boundary as a natural curve, plus a hue strip. Clicking the swatch opens the picker as a popup. Uses inline OKLCH→sRGB math (no extra dependencies) with ImageData rendering for the canvas. Cached image data avoids full re-renders when only the crosshair position changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructure ColorPicker layout from one shared swatch to per-row
swatches. Each input (hex and oklch) now has its own mini swatch
that opens the OKLCH picker popup. DOM references stored directly
during construction — no querySelector for event binding.
Layout: [swatch] #hex [reset]
[swatch] oklch(...)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add try-catch and console.error to swatch click handler for debugging. Set pointer-events: none on swatch child elements so clicks reliably reach the parent preview element. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The popup (z-index: 2000) was rendering behind the preferences container (z-index: 9000). Raised to 10000 so it appears on top. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3936cf5 to
03bda06
Compare
Reverted to one swatch per ColorPicker (not two per-row swatches
that confused background/foreground). Layout is now:
[swatch] [hex input ] [reset]
[oklch input]
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
03bda06 to
9ea4c73
Compare
field.defaultValue is already narrowed by the switch on field.type, so the `as string` and `as ColorPair` casts are redundant and flagged by @typescript-eslint/no-unnecessary-type-assertion. https://claude.ai/code/session_01JPKgqUDYb7zrib8Qi6KF6n
Fix duplicate System sections caused by async race condition in renderSystemSection, eliminate flicker by updating controls in-place instead of rebuilding DOM, and debounce expensive diagram re-renders during color picker drag. Rename all document CSS variables to --doc-* prefix to distinguish from app chrome variables, fixing the background color picker which was writing to a dead variable. Flatten heading controls inline in Typography section with separator lines, and drive collapsible section visibility from CSS classes instead of inline styles. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR refactors theme management to establish a clear separation of concerns: ThemeService now handles only OS-level system theme detection, while PreferencesService becomes the single source of truth for theme mode preferences (light/dark/system).
Key Changes
ThemeService simplification: Removed all preference persistence logic (
getCurrentTheme(),setTheme(), preferences file I/O,getPreferencesPath()). ThemeService now focuses exclusively on detecting system theme vianativeThemeand notifying listeners of OS-level changes.PreferencesService integration: Theme mode preference is now stored and managed through PreferencesService's
core.theme.modefield, ensuring consistency with other user preferences.ThemeHandler delegation:
GET_CURRENTandSETIPC handlers now delegate to PreferencesService instead of ThemeServiceGET_SYSTEMandON_SYSTEM_CHANGEcontinue to use ThemeService for OS detectionRenderer synchronization: Removed redundant theme sync logic in
renderer.ts. Theme mode is now exclusively managed through PreferencesService, eliminating the need to separately calltheme.set().Typography preferences: Added
fontFamilyandmonoFontFamilyfields to CorePreferences with sensible defaults, allowing users to customize font families alongside other typography settings.CSS generation: Updated theme CSS generation to respect user-configured font families from preferences.
Test updates: Refactored unit tests to reflect the new architecture, removing preference persistence tests from ThemeService and updating ThemeHandler tests to verify PreferencesService integration.
Implementation Details
registerThemeHandlers()alongside ThemeServicehttps://claude.ai/code/session_01JPKgqUDYb7zrib8Qi6KF6n