feat: P5-21 mention color, P5-22 font selector, P5-27 notification presets; update docs
- P5-21: Custom @mention highlight color picker in Settings → Appearance. CSS vars with luminance-computed text color; resets cleanly to theme default. - P5-22: Font selector (System, Inter, JetBrains Mono, Fira Code) in Settings → Appearance. Fira Code added to Google Fonts preload. - P5-27: Gaming/Work/Sleep preset buttons at top of Settings → Notifications. Each atomically applies a group of notification settings. - AppearanceEffects component in App.tsx applies CSS vars on settings change. - LOTUS_BUGS.md: mark presence + manifest icon bugs as resolved. - LOTUS_TODO.md: mark P3-6, P5-21, P5-22, P5-27 as [x]. - LOTUS_FEATURES.md: document all four completed features. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+38
-1
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { Provider as JotaiProvider, useAtomValue } from 'jotai';
|
||||
import { OverlayContainerProvider, PopOutContainerProvider, TooltipContainerProvider } from 'folds';
|
||||
@@ -16,6 +16,42 @@ import { useCompositionEndTracking } from '../hooks/useComposingCheck';
|
||||
import { settingsAtom } from '../state/settings';
|
||||
import { LotusToastContainer } from '../features/toast/LotusToastContainer';
|
||||
|
||||
const FONT_MAP: Record<string, string> = {
|
||||
system: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
||||
inter: "'InterVariable', sans-serif",
|
||||
'jetbrains-mono': "'JetBrains Mono', monospace",
|
||||
'fira-code': "'Fira Code', monospace",
|
||||
};
|
||||
|
||||
function AppearanceEffects() {
|
||||
const settings = useAtomValue(settingsAtom);
|
||||
|
||||
useEffect(() => {
|
||||
const color = settings.mentionHighlightColor;
|
||||
if (color) {
|
||||
document.body.style.setProperty('--mention-highlight-bg', color);
|
||||
// compute black or white text based on hex luminance
|
||||
const r = parseInt(color.slice(1, 3), 16);
|
||||
const g = parseInt(color.slice(3, 5), 16);
|
||||
const b = parseInt(color.slice(5, 7), 16);
|
||||
const lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
||||
document.body.style.setProperty('--mention-highlight-text', lum > 0.5 ? '#000' : '#fff');
|
||||
document.body.style.setProperty('--mention-highlight-border', color);
|
||||
} else {
|
||||
document.body.style.removeProperty('--mention-highlight-bg');
|
||||
document.body.style.removeProperty('--mention-highlight-text');
|
||||
document.body.style.removeProperty('--mention-highlight-border');
|
||||
}
|
||||
}, [settings.mentionHighlightColor]);
|
||||
|
||||
useEffect(() => {
|
||||
const font = FONT_MAP[settings.fontFamily ?? 'inter'] ?? FONT_MAP.inter;
|
||||
document.body.style.setProperty('--font-secondary', font);
|
||||
}, [settings.fontFamily]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function NightLightOverlay() {
|
||||
const settings = useAtomValue(settingsAtom);
|
||||
if (!settings.nightLightEnabled) return null;
|
||||
@@ -94,6 +130,7 @@ function App() {
|
||||
<ClientConfigProvider value={clientConfig}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<JotaiProvider>
|
||||
<AppearanceEffects />
|
||||
<RouterProvider router={createRouter(clientConfig, screenSize)} />
|
||||
<NightLightOverlay />
|
||||
<LotusToastContainer />
|
||||
|
||||
Reference in New Issue
Block a user