Fix dark mode for system setting (#630)

* Perfect!  I've successfully fixed the diff theme detection issue by:

## What I Did:

### 1. **Created a shared theme utility** (`frontend/src/utils/theme.ts`):
- Properly handles all theme modes including SYSTEM
- When theme is SYSTEM, it checks `window.matchMedia('(prefers-color-scheme: dark)')`
- Treats all colored themes (PURPLE, GREEN, BLUE, ORANGE, RED) as dark themes

### 2. **Updated all diff-related components** to use the utility:
- **DiffCard.tsx** 
- **EditDiffRenderer.tsx** 
- **FileChangeRenderer.tsx** 

### 3. **Replaced the broken pattern**:
```tsx
// OLD - only worked for explicit DARK theme
let theme = 'light';
if (config?.theme === ThemeMode.DARK) theme = 'dark';

// NEW - works for all themes including SYSTEM
const theme = getActualTheme(config?.theme);
```

## Result:
Now when you have **VK theme set to SYSTEM** and your **OS is in dark mode**, the diff viewers will correctly show dark theme colors instead of the incorrect light theme colors.

The fix ensures consistency with how other components (Logo, JSONEditor) handle theme detection and follows the same pattern that the ThemeProvider uses internally.

* fmt

* Lint
This commit is contained in:
Alex Netsch
2025-09-05 11:02:30 +02:00
committed by GitHub
parent 2598306347
commit 621649b0b5
4 changed files with 31 additions and 10 deletions

View File

@@ -1,9 +1,10 @@
import { Diff as Diff, ThemeMode } from 'shared/types';
import { Diff } from 'shared/types';
import { DiffModeEnum, DiffView } from '@git-diff-view/react';
import { generateDiffFile } from '@git-diff-view/file';
import { useMemo } from 'react';
import { useConfig } from '@/components/config-provider';
import { getHighLightLanguageFromPath } from '@/utils/extToLanguage';
import { getActualTheme } from '@/utils/theme';
import { Button } from '@/components/ui/button';
import {
ChevronRight,
@@ -46,7 +47,7 @@ export default function DiffCard({
selectedAttempt,
}: Props) {
const { config } = useConfig();
const theme = config?.theme === ThemeMode.DARK ? 'dark' : 'light';
const theme = getActualTheme(config?.theme);
const oldName = diff.oldPath || undefined;
const newName = diff.newPath || oldName || 'unknown';

View File

@@ -5,11 +5,11 @@ import {
DiffLineType,
parseInstance,
} from '@git-diff-view/react';
import { ThemeMode } from 'shared/types';
import { ChevronRight, ChevronUp } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useConfig } from '@/components/config-provider';
import { getHighLightLanguageFromPath } from '@/utils/extToLanguage';
import { getActualTheme } from '@/utils/theme';
import '@/styles/diff-style-overrides.css';
import '@/styles/edit-diff-overrides.css';
@@ -67,10 +67,7 @@ function EditDiffRenderer({
const { config } = useConfig();
const [expanded, setExpanded] = useExpandable(expansionKey, false);
let theme: 'light' | 'dark' | undefined = 'light';
if (config?.theme === ThemeMode.DARK) {
theme = 'dark';
}
const theme = getActualTheme(config?.theme);
const { hunks, hideLineNumbers, additions, deletions, isValidDiff } = useMemo(
() => processUnifiedDiff(unifiedDiff, hasLineNumbers),

View File

@@ -1,4 +1,4 @@
import { ThemeMode, type FileChange } from 'shared/types';
import { type FileChange } from 'shared/types';
import { useConfig } from '@/components/config-provider';
import { Button } from '@/components/ui/button';
import {
@@ -9,6 +9,7 @@ import {
ArrowRight,
} from 'lucide-react';
import { getHighLightLanguageFromPath } from '@/utils/extToLanguage';
import { getActualTheme } from '@/utils/theme';
import EditDiffRenderer from './EditDiffRenderer';
import FileContentView from './FileContentView';
import '@/styles/diff-style-overrides.css';
@@ -45,8 +46,7 @@ const FileChangeRenderer = ({ path, change, expansionKey }: Props) => {
const { config } = useConfig();
const [expanded, setExpanded] = useExpandable(expansionKey, false);
let theme: 'light' | 'dark' | undefined = 'light';
if (config?.theme === ThemeMode.DARK) theme = 'dark';
const theme = getActualTheme(config?.theme);
// Edit: delegate to EditDiffRenderer for identical styling and behavior
if (isEdit(change)) {

View File

@@ -0,0 +1,23 @@
import { ThemeMode } from 'shared/types';
/**
* Resolves the actual theme (light/dark) based on the theme mode setting.
* Handles system theme detection properly.
*/
export function getActualTheme(
themeMode: ThemeMode | undefined
): 'light' | 'dark' {
if (!themeMode || themeMode === ThemeMode.LIGHT) {
return 'light';
}
if (themeMode === ThemeMode.SYSTEM) {
// Check system preference
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
}
// All other themes (DARK, PURPLE, GREEN, BLUE, ORANGE, RED) have dark backgrounds
return 'dark';
}