it is time
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { createSignal } from "solid-js"
|
||||
import { useKeyboard } from "@opentui/solid"
|
||||
import { useAppStore } from "../stores/app"
|
||||
import { createColorResolver } from "../utils/color"
|
||||
import type { ThemeName } from "../types/settings"
|
||||
|
||||
type FocusField = "theme" | "font" | "speed" | "explicit" | "auto"
|
||||
@@ -22,8 +21,6 @@ export function PreferencesPanel() {
|
||||
const settings = () => appStore.state().settings
|
||||
const preferences = () => appStore.state().preferences
|
||||
|
||||
const resolveColor = createColorResolver(appStore.resolveTheme())
|
||||
|
||||
const handleKey = (key: { name: string; shift?: boolean }) => {
|
||||
if (key.name === "tab") {
|
||||
const fields: FocusField[] = ["theme", "font", "speed", "explicit", "auto"]
|
||||
@@ -79,55 +76,55 @@ export function PreferencesPanel() {
|
||||
|
||||
return (
|
||||
<box flexDirection="column" gap={1}>
|
||||
<text fg={resolveColor("--color-muted")}>Preferences</text>
|
||||
<text fg="var(--color-muted)">Preferences</text>
|
||||
|
||||
<box flexDirection="column" gap={1}>
|
||||
<box flexDirection="row" gap={1} alignItems="center">
|
||||
<text fg={focusField() === "theme" ? resolveColor("--color-primary") : resolveColor("--color-muted")}>Theme:</text>
|
||||
<text fg={focusField() === "theme" ? "var(--color-primary)" : "var(--color-muted)"}>Theme:</text>
|
||||
<box border padding={0}>
|
||||
<text fg={resolveColor("--color-text")}>{THEME_LABELS.find((t) => t.value === settings().theme)?.label}</text>
|
||||
<text fg="var(--color-text)">{THEME_LABELS.find((t) => t.value === settings().theme)?.label}</text>
|
||||
</box>
|
||||
<text fg={resolveColor("--color-muted")}>[Left/Right]</text>
|
||||
<text fg="var(--color-muted)">[Left/Right]</text>
|
||||
</box>
|
||||
|
||||
<box flexDirection="row" gap={1} alignItems="center">
|
||||
<text fg={focusField() === "font" ? resolveColor("--color-primary") : resolveColor("--color-muted")}>Font Size:</text>
|
||||
<text fg={focusField() === "font" ? "var(--color-primary)" : "var(--color-muted)"}>Font Size:</text>
|
||||
<box border padding={0}>
|
||||
<text fg={resolveColor("--color-text")}>{settings().fontSize}px</text>
|
||||
<text fg="var(--color-text)">{settings().fontSize}px</text>
|
||||
</box>
|
||||
<text fg={resolveColor("--color-muted")}>[Left/Right]</text>
|
||||
<text fg="var(--color-muted)">[Left/Right]</text>
|
||||
</box>
|
||||
|
||||
<box flexDirection="row" gap={1} alignItems="center">
|
||||
<text fg={focusField() === "speed" ? resolveColor("--color-primary") : resolveColor("--color-muted")}>Playback:</text>
|
||||
<text fg={focusField() === "speed" ? "var(--color-primary)" : "var(--color-muted)"}>Playback:</text>
|
||||
<box border padding={0}>
|
||||
<text fg={resolveColor("--color-text")}>{settings().playbackSpeed}x</text>
|
||||
<text fg="var(--color-text)">{settings().playbackSpeed}x</text>
|
||||
</box>
|
||||
<text fg={resolveColor("--color-muted")}>[Left/Right]</text>
|
||||
<text fg="var(--color-muted)">[Left/Right]</text>
|
||||
</box>
|
||||
|
||||
<box flexDirection="row" gap={1} alignItems="center">
|
||||
<text fg={focusField() === "explicit" ? resolveColor("--color-primary") : resolveColor("--color-muted")}>Show Explicit:</text>
|
||||
<text fg={focusField() === "explicit" ? "var(--color-primary)" : "var(--color-muted)"}>Show Explicit:</text>
|
||||
<box border padding={0}>
|
||||
<text fg={preferences().showExplicit ? resolveColor("--color-success") : resolveColor("--color-muted")}>
|
||||
<text fg={preferences().showExplicit ? "var(--color-success)" : "var(--color-muted)"}>
|
||||
{preferences().showExplicit ? "On" : "Off"}
|
||||
</text>
|
||||
</box>
|
||||
<text fg={resolveColor("--color-muted")}>[Space]</text>
|
||||
<text fg="var(--color-muted)">[Space]</text>
|
||||
</box>
|
||||
|
||||
<box flexDirection="row" gap={1} alignItems="center">
|
||||
<text fg={focusField() === "auto" ? resolveColor("--color-primary") : resolveColor("--color-muted")}>Auto Download:</text>
|
||||
<text fg={focusField() === "auto" ? "var(--color-primary)" : "var(--color-muted)"}>Auto Download:</text>
|
||||
<box border padding={0}>
|
||||
<text fg={preferences().autoDownload ? resolveColor("--color-success") : resolveColor("--color-muted")}>
|
||||
<text fg={preferences().autoDownload ? "var(--color-success)" : "var(--color-muted)"}>
|
||||
{preferences().autoDownload ? "On" : "Off"}
|
||||
</text>
|
||||
</box>
|
||||
<text fg={resolveColor("--color-muted")}>[Space]</text>
|
||||
<text fg="var(--color-muted)">[Space]</text>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
<text fg={resolveColor("--color-muted")}>Tab to move focus, Left/Right to adjust</text>
|
||||
<text fg="var(--color-muted)">Tab to move focus, Left/Right to adjust</text>
|
||||
</box>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import { createSignal, For } from "solid-js"
|
||||
import { useFeedStore } from "../stores/feed"
|
||||
import { SourceType } from "../types/source"
|
||||
import { createColorResolver } from "../utils/color"
|
||||
import type { PodcastSource } from "../types/source"
|
||||
|
||||
interface SourceManagerProps {
|
||||
@@ -149,8 +148,6 @@ export function SourceManager(props: SourceManagerProps) {
|
||||
const sourceExplicit = () => selectedSource()?.allowExplicit !== false
|
||||
const sourceLanguage = () => selectedSource()?.language || "en_us"
|
||||
|
||||
const resolveColor = createColorResolver({})
|
||||
|
||||
return (
|
||||
<box flexDirection="column" border padding={1} gap={1}>
|
||||
<box flexDirection="row" justifyContent="space-between">
|
||||
@@ -158,15 +155,15 @@ export function SourceManager(props: SourceManagerProps) {
|
||||
<strong>Podcast Sources</strong>
|
||||
</text>
|
||||
<box border padding={0} onMouseDown={props.onClose}>
|
||||
<text fg={resolveColor("--color-primary")}>[Esc] Close</text>
|
||||
<text fg="var(--color-primary)">[Esc] Close</text>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
<text fg={resolveColor("--color-muted")}>Manage where to search for podcasts</text>
|
||||
<text fg="var(--color-muted)">Manage where to search for podcasts</text>
|
||||
|
||||
{/* Source list */}
|
||||
<box border padding={1} flexDirection="column" gap={1}>
|
||||
<text fg={focusArea() === "list" ? resolveColor("--color-primary") : resolveColor("--color-muted")}>Sources:</text>
|
||||
<text fg={focusArea() === "list" ? "var(--color-primary)" : "var(--color-muted)"}>Sources:</text>
|
||||
<scrollbox height={6}>
|
||||
<For each={sources()}>
|
||||
{(source, index) => (
|
||||
@@ -176,7 +173,7 @@ export function SourceManager(props: SourceManagerProps) {
|
||||
padding={0}
|
||||
backgroundColor={
|
||||
focusArea() === "list" && index() === selectedIndex()
|
||||
? resolveColor("--color-primary")
|
||||
? "var(--color-primary)"
|
||||
: undefined
|
||||
}
|
||||
onMouseDown={() => {
|
||||
@@ -187,21 +184,21 @@ export function SourceManager(props: SourceManagerProps) {
|
||||
>
|
||||
<text fg={
|
||||
focusArea() === "list" && index() === selectedIndex()
|
||||
? resolveColor("--color-primary")
|
||||
: resolveColor("--color-muted")
|
||||
? "var(--color-primary)"
|
||||
: "var(--color-muted)"
|
||||
}>
|
||||
{focusArea() === "list" && index() === selectedIndex()
|
||||
? ">"
|
||||
: " "}
|
||||
</text>
|
||||
<text fg={source.enabled ? resolveColor("--color-success") : resolveColor("--color-error")}>
|
||||
<text fg={source.enabled ? "var(--color-success)" : "var(--color-error)"}>
|
||||
{source.enabled ? "[x]" : "[ ]"}
|
||||
</text>
|
||||
<text fg={resolveColor("--color-accent")}>{getSourceIcon(source)}</text>
|
||||
<text fg="var(--color-accent)">{getSourceIcon(source)}</text>
|
||||
<text
|
||||
fg={
|
||||
focusArea() === "list" && index() === selectedIndex()
|
||||
? resolveColor("--color-text")
|
||||
? "var(--color-text)"
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
@@ -211,7 +208,7 @@ export function SourceManager(props: SourceManagerProps) {
|
||||
)}
|
||||
</For>
|
||||
</scrollbox>
|
||||
<text fg={resolveColor("--color-muted")}>Space/Enter to toggle, d to delete, a to add</text>
|
||||
<text fg="var(--color-muted)">Space/Enter to toggle, d to delete, a to add</text>
|
||||
|
||||
{/* API settings */}
|
||||
<box flexDirection="column" gap={1}>
|
||||
|
||||
@@ -42,21 +42,18 @@ export function ThemeProvider({ children }: { children: any }) {
|
||||
// Handle system theme changes
|
||||
createEffect(() => {
|
||||
if (isSystemTheme()) {
|
||||
// Check if window and matchMedia are available
|
||||
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
const handler = () => {
|
||||
const newMode = getSystemThemeMode()
|
||||
setCurrentMode(newMode)
|
||||
setResolvedTheme(appStore.resolveTheme())
|
||||
}
|
||||
|
||||
mediaQuery.addEventListener("change", handler)
|
||||
|
||||
onCleanup(() => {
|
||||
mediaQuery.removeEventListener("change", handler)
|
||||
})
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
const handler = () => {
|
||||
const newMode = getSystemThemeMode()
|
||||
setCurrentMode(newMode)
|
||||
setResolvedTheme(appStore.resolveTheme())
|
||||
}
|
||||
|
||||
mediaQuery.addEventListener("change", handler)
|
||||
|
||||
onCleanup(() => {
|
||||
mediaQuery.removeEventListener("change", handler)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Color Resolution Utility
|
||||
* Converts CSS variable references to actual color values
|
||||
*/
|
||||
|
||||
/**
|
||||
* Map of CSS variable names to their default color values
|
||||
* Used as fallback when CSS variables aren't resolved
|
||||
*/
|
||||
const CSS_VARIABLE_MAP: Record<string, string> = {
|
||||
"--color-background": "transparent",
|
||||
"--color-surface": "#1b1f27",
|
||||
"--color-primary": "#6fa8ff",
|
||||
"--color-secondary": "#a9b1d6",
|
||||
"--color-accent": "#f6c177",
|
||||
"--color-text": "#e6edf3",
|
||||
"--color-muted": "#7d8590",
|
||||
"--color-warning": "#f0b429",
|
||||
"--color-error": "#f47067",
|
||||
"--color-success": "#3fb950",
|
||||
"--color-layer0": "transparent",
|
||||
"--color-layer1": "#1e222e",
|
||||
"--color-layer2": "#161b22",
|
||||
"--color-layer3": "#0d1117",
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a CSS variable reference to an actual color value
|
||||
* @param variable The CSS variable string (e.g., "var(--color-primary)")
|
||||
* @returns The resolved color value or a default fallback
|
||||
*/
|
||||
export function resolveCSSVariable(variable: string): string {
|
||||
if (!variable || typeof variable !== "string") {
|
||||
return "#ff00ff" // Default magenta fallback
|
||||
}
|
||||
|
||||
// Extract the variable name from var(--name)
|
||||
const match = variable.match(/var\(([^)]+)\)/)
|
||||
if (match && match[1]) {
|
||||
const varName = match[1].trim()
|
||||
// Get the computed style value from the document
|
||||
if (typeof document !== "undefined") {
|
||||
const root = document.documentElement
|
||||
const computedValue = getComputedStyle(root).getPropertyValue(varName)
|
||||
if (computedValue) {
|
||||
return computedValue.trim()
|
||||
}
|
||||
}
|
||||
// Fall back to the map
|
||||
return CSS_VARIABLE_MAP[varName] || "#ff00ff"
|
||||
}
|
||||
|
||||
// Return the original value if it's not a CSS variable
|
||||
return variable
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that resolves CSS variables from a theme object
|
||||
* @param theme The theme object with color properties
|
||||
* @returns A function that resolves CSS variable strings to actual colors
|
||||
*/
|
||||
export function createColorResolver(theme: {
|
||||
background?: string
|
||||
surface?: string
|
||||
primary?: string
|
||||
secondary?: string
|
||||
accent?: string
|
||||
text?: string
|
||||
muted?: string
|
||||
warning?: string
|
||||
error?: string
|
||||
success?: string
|
||||
layerBackgrounds?: {
|
||||
layer0?: string
|
||||
layer1?: string
|
||||
layer2?: string
|
||||
layer3?: string
|
||||
}
|
||||
}) {
|
||||
return (color: string | undefined): string => {
|
||||
if (!color) {
|
||||
return "#ff00ff" // Default magenta fallback
|
||||
}
|
||||
|
||||
// If it's already a valid hex or named color, return it
|
||||
if (/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(color) || /^[a-z]+$/i.test(color)) {
|
||||
return color
|
||||
}
|
||||
|
||||
// Otherwise, try to resolve it as a CSS variable
|
||||
return resolveCSSVariable(color)
|
||||
}
|
||||
}
|
||||
63
tasks/subtasks/theme-refactoring-01-create-schema.md
Normal file
63
tasks/subtasks/theme-refactoring-01-create-schema.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# 01. Create JSON Theme Schema and File Structure
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-01
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P0
|
||||
depends_on: []
|
||||
tags: [implementation, infrastructure]
|
||||
|
||||
objective:
|
||||
- Create the JSON theme schema and establish the file structure for theme definitions
|
||||
- Define the theme.json schema that opencode uses
|
||||
- Create the directory structure for JSON theme files
|
||||
|
||||
deliverables:
|
||||
- `src/types/theme-schema.ts` - JSON theme schema definition
|
||||
- `src/themes/*.json` - Directory for theme JSON files
|
||||
- `src/themes/schema.json` - Theme schema reference
|
||||
|
||||
steps:
|
||||
- Step 1.1: Create `src/types/theme-schema.ts` with TypeScript interfaces matching the opencode theme JSON structure
|
||||
- Define `ThemeJson` interface with `$schema`, `defs`, and `theme` properties
|
||||
- Define `ColorValue` type supporting hex colors, color references, variants, and RGBA
|
||||
- Define `Variant` type for light/dark mode color definitions
|
||||
- Export interfaces for type checking
|
||||
|
||||
- Step 1.2: Create `src/themes/schema.json` with the opencode theme schema reference
|
||||
- Add `$schema: "https://opencode.ai/theme.json"`
|
||||
- Document the theme structure in comments
|
||||
|
||||
- Step 1.3: Create `src/themes/` directory
|
||||
- Ensure directory exists for JSON theme files
|
||||
|
||||
- Step 1.4: Create a sample theme file in `src/themes/opencode.json`
|
||||
- Use the opencode theme as reference
|
||||
- Include proper `$schema` reference
|
||||
- Define `defs` with all color references
|
||||
- Define `theme` with semantic color mappings
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test `ThemeJson` type definition matches opencode structure
|
||||
- Test `ColorValue` type accepts hex colors, references, variants, and RGBA
|
||||
- Test `Variant` type structure is correct
|
||||
|
||||
- Integration/e2e:
|
||||
- Verify JSON file can be parsed without errors
|
||||
- Validate schema reference is correct
|
||||
|
||||
acceptance_criteria:
|
||||
- `src/types/theme-schema.ts` file exists with all required interfaces
|
||||
- `src/themes/schema.json` contains valid schema reference
|
||||
- `src/themes/` directory is created
|
||||
- `src/themes/opencode.json` can be imported and parsed successfully
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass with no type errors
|
||||
- Run: `cat src/themes/opencode.json | jq .` - Should be valid JSON
|
||||
|
||||
notes:
|
||||
- Follow opencode's theme.json structure exactly
|
||||
- Use TypeScript interfaces to ensure type safety
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme/`
|
||||
77
tasks/subtasks/theme-refactoring-02-convert-themes.md
Normal file
77
tasks/subtasks/theme-refactoring-02-convert-themes.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 02. Convert Existing Themes to JSON Format
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-02
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P0
|
||||
depends_on: [theme-refactoring-01]
|
||||
tags: [implementation, migration]
|
||||
|
||||
objective:
|
||||
- Convert all existing PodTui themes (catppuccin, gruvbox, tokyo, nord) from TypeScript constants to JSON format
|
||||
- Ensure each theme matches the opencode JSON structure
|
||||
- Maintain color fidelity with original theme definitions
|
||||
|
||||
deliverables:
|
||||
- `src/themes/catppuccin.json` - Catppuccin theme in JSON format
|
||||
- `src/themes/gruvbox.json` - Gruvbox theme in JSON format
|
||||
- `src/themes/tokyo.json` - Tokyo Night theme in JSON format
|
||||
- `src/themes/nord.json` - Nord theme in JSON format
|
||||
|
||||
steps:
|
||||
- Step 2.1: Convert `catppuccin` theme from `src/types/desktop-theme.ts` to JSON
|
||||
- Extract all color definitions from `THEMES_DESKTOP.variants.find((v) => v.name === "catppuccin")!.colors`
|
||||
- Create `defs` object with all color references (dark and light variants)
|
||||
- Create `theme` object with semantic mappings
|
||||
- Add `$schema` reference
|
||||
- Verify color values match original definitions
|
||||
|
||||
- Step 2.2: Convert `gruvbox` theme from `src/types/desktop-theme.ts` to JSON
|
||||
- Extract all color definitions from `THEMES_DESKTOP.variants.find((v) => v.name === "gruvbox")!.colors`
|
||||
- Create `defs` object with all color references
|
||||
- Create `theme` object with semantic mappings
|
||||
- Add `$schema` reference
|
||||
|
||||
- Step 2.3: Convert `tokyo` theme from `src/types/desktop-theme.ts` to JSON
|
||||
- Extract all color definitions from `THEMES_DESKTOP.variants.find((v) => v.name === "tokyo")!.colors`
|
||||
- Create `defs` object with all color references
|
||||
- Create `theme` object with semantic mappings
|
||||
- Add `$schema` reference
|
||||
|
||||
- Step 2.4: Convert `nord` theme from `src/types/desktop-theme.ts` to JSON
|
||||
- Extract all color definitions from `THEMES_DESKTOP.variants.find((v) => v.name === "nord")!.colors`
|
||||
- Create `defs` object with all color references
|
||||
- Create `theme` object with semantic mappings
|
||||
- Add `$schema` reference
|
||||
|
||||
- Step 2.5: Verify all JSON files are valid
|
||||
- Check syntax with `bun run typecheck`
|
||||
- Ensure all imports work correctly
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test each JSON file can be imported without errors
|
||||
- Verify color values match original TypeScript definitions
|
||||
|
||||
- Integration/e2e:
|
||||
- Load each theme and verify all colors are present
|
||||
- Check that theme structure matches expected schema
|
||||
|
||||
acceptance_criteria:
|
||||
- All four theme JSON files exist in `src/themes/`
|
||||
- Each JSON file follows the theme schema
|
||||
- Color values match original theme definitions exactly
|
||||
- All JSON files are valid and can be parsed
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass
|
||||
- Run: `cat src/themes/catppuccin.json | jq .` - Should be valid JSON
|
||||
- Run: `cat src/themes/gruvbox.json | jq .` - Should be valid JSON
|
||||
- Run: `cat src/themes/tokyo.json | jq .` - Should be valid JSON
|
||||
- Run: `cat src/themes/nord.json | jq .` - Should be valid JSON
|
||||
|
||||
notes:
|
||||
- Use opencode's theme structure as reference
|
||||
- Maintain backward compatibility with existing color definitions
|
||||
- Ensure both dark and light variants are included if available
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme/`
|
||||
70
tasks/subtasks/theme-refactoring-03-update-types.md
Normal file
70
tasks/subtasks/theme-refactoring-03-update-types.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 03. Update Type Definitions for Color References and Variants
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-03
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P0
|
||||
depends_on: [theme-refactoring-01]
|
||||
tags: [implementation, types]
|
||||
|
||||
objective:
|
||||
- Update type definitions to support the new JSON theme structure
|
||||
- Add support for color references, variants, and light/dark mode
|
||||
- Maintain backward compatibility with existing code
|
||||
|
||||
deliverables:
|
||||
- `src/types/theme-schema.ts` - Updated with new types
|
||||
- `src/types/settings.ts` - Updated with color reference types
|
||||
- `src/types/desktop-theme.ts` - Updated to support JSON themes
|
||||
|
||||
steps:
|
||||
- Step 3.1: Update `src/types/theme-schema.ts`
|
||||
- Export `ThemeJson` interface
|
||||
- Export `ColorValue` type
|
||||
- Export `Variant` type
|
||||
- Add `ThemeColors` type for resolved theme colors
|
||||
|
||||
- Step 3.2: Update `src/types/settings.ts`
|
||||
- Add `ThemeJson` import
|
||||
- Add `ColorValue` type definition
|
||||
- Add `Variant` type definition
|
||||
- Update `ThemeColors` to support color references
|
||||
- Add `ThemeJson` type for JSON theme files
|
||||
|
||||
- Step 3.3: Update `src/types/desktop-theme.ts`
|
||||
- Add imports for `ThemeJson`, `ColorValue`, `Variant`
|
||||
- Add `ThemeJson` type for JSON theme files
|
||||
- Update existing types to support color references
|
||||
- Add helper functions for JSON theme loading
|
||||
|
||||
- Step 3.4: Ensure backward compatibility
|
||||
- Keep existing `ThemeColors` structure for resolved themes
|
||||
- Ensure existing code can still use theme colors as strings
|
||||
- Add type guards for color references
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test `ThemeJson` type accepts valid JSON theme structure
|
||||
- Test `ColorValue` type accepts hex colors, references, variants, and RGBA
|
||||
- Test `Variant` type structure is correct
|
||||
- Test existing `ThemeColors` type remains compatible
|
||||
|
||||
- Integration/e2e:
|
||||
- Verify type imports work correctly
|
||||
- Test type inference with JSON theme files
|
||||
|
||||
acceptance_criteria:
|
||||
- All type definitions are updated and exported
|
||||
- Backward compatibility maintained with existing code
|
||||
- New types support color references and variants
|
||||
- Type checking passes without errors
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass with no errors
|
||||
- Verify existing components can still use theme colors
|
||||
- Test type inference with new theme JSON files
|
||||
|
||||
notes:
|
||||
- Use TypeScript's `with { type: "json" }` for JSON imports
|
||||
- Ensure all types are properly exported for use across the codebase
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx`
|
||||
83
tasks/subtasks/theme-refactoring-04-theme-resolution.md
Normal file
83
tasks/subtasks/theme-refactoring-04-theme-resolution.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# 04. Create Theme Resolution Logic with Color Reference Lookup
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-04
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P0
|
||||
depends_on: [theme-refactoring-02, theme-refactoring-03]
|
||||
tags: [implementation, logic]
|
||||
|
||||
objective:
|
||||
- Implement theme resolution logic that handles color references and variants
|
||||
- Create function to resolve colors from theme JSON files
|
||||
- Support hex colors, color references, ANSI codes, and RGBA values
|
||||
- Handle light/dark mode selection based on current mode
|
||||
|
||||
deliverables:
|
||||
- `src/utils/theme-resolver.ts` - Theme resolution utility
|
||||
- `src/utils/ansi-to-rgba.ts` - ANSI color conversion utility
|
||||
|
||||
steps:
|
||||
- Step 4.1: Create `src/utils/ansi-to-rgba.ts`
|
||||
- Implement `ansiToRgba(code: number): RGBA` function
|
||||
- Handle standard ANSI colors (0-15)
|
||||
- Handle 6x6x6 color cube (16-231)
|
||||
- Handle grayscale ramp (232-255)
|
||||
- Add type definitions for RGBA
|
||||
|
||||
- Step 4.2: Create `src/utils/theme-resolver.ts`
|
||||
- Implement `resolveTheme(theme: ThemeJson, mode: "dark" | "light"): ThemeColors`
|
||||
- Create `resolveColor(c: ColorValue): RGBA` helper function
|
||||
- Handle RGBA objects directly
|
||||
- Handle hex color strings
|
||||
- Handle color references from `defs`
|
||||
- Handle variants (dark/light mode)
|
||||
- Handle ANSI codes
|
||||
- Add error handling for invalid color references
|
||||
|
||||
- Step 4.3: Implement color reference resolution
|
||||
- Create lookup logic for `defs` object
|
||||
- Add fallback to theme colors if reference not in defs
|
||||
- Throw descriptive errors for invalid references
|
||||
|
||||
- Step 4.4: Handle optional theme properties
|
||||
- Support `selectedListItemText` property
|
||||
- Support `backgroundMenu` property
|
||||
- Support `thinkingOpacity` property
|
||||
- Add default values for missing properties
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test `ansiToRgba` with ANSI codes 0-15
|
||||
- Test `ansiToRgba` with color cube codes 16-231
|
||||
- Test `ansiToRgba` with grayscale codes 232-255
|
||||
- Test `resolveColor` with hex colors
|
||||
- Test `resolveColor` with color references
|
||||
- Test `resolveColor` with light/dark variants
|
||||
- Test `resolveColor` with RGBA objects
|
||||
- Test `resolveTheme` with complete theme JSON
|
||||
- Test `resolveTheme` with missing optional properties
|
||||
- Test error handling for invalid color references
|
||||
|
||||
- Integration/e2e:
|
||||
- Test resolving colors from actual theme JSON files
|
||||
- Verify light/dark mode selection works correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- `src/utils/ansi-to-rgba.ts` file exists with conversion functions
|
||||
- `src/utils/theme-resolver.ts` file exists with resolution logic
|
||||
- All color value types are handled correctly
|
||||
- Error messages are descriptive and helpful
|
||||
- Theme resolution works with both light and dark modes
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass
|
||||
- Run unit tests with `bun test src/utils/theme-resolver.test.ts`
|
||||
- Test with sample theme JSON files
|
||||
- Verify error messages are clear
|
||||
|
||||
notes:
|
||||
- Use opencode's implementation as reference for color resolution
|
||||
- Ensure RGBA values are normalized to 0-1 range
|
||||
- Add comprehensive error handling for invalid inputs
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx` (lines 176-277)
|
||||
80
tasks/subtasks/theme-refactoring-05-theme-context.md
Normal file
80
tasks/subtasks/theme-refactoring-05-theme-context.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# 05. Migrate ThemeContext to SolidJS Pattern
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-05
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P0
|
||||
depends_on: [theme-refactoring-04]
|
||||
tags: [implementation, context]
|
||||
|
||||
objective:
|
||||
- Migrate ThemeContext from basic React context to SolidJS context pattern
|
||||
- Implement reactive state management for theme switching
|
||||
- Add persistence for theme selection and mode
|
||||
- Support system theme detection
|
||||
|
||||
deliverables:
|
||||
- `src/context/ThemeContext.tsx` - Updated with SolidJS pattern
|
||||
- `src/utils/theme-context.ts` - Theme context utilities
|
||||
|
||||
steps:
|
||||
- Step 5.1: Update `src/context/ThemeContext.tsx`
|
||||
- Import SolidJS hooks: `createSignal`, `createEffect`, `createMemo`, `createStore`
|
||||
- Replace React context with SolidJS `createSimpleContext` pattern (from opencode)
|
||||
- Add theme loading logic
|
||||
- Implement reactive theme state
|
||||
- Add system theme detection
|
||||
- Support theme persistence via localStorage
|
||||
|
||||
- Step 5.2: Implement theme state management
|
||||
- Create store with `themes`, `mode`, `active`, `ready`
|
||||
- Initialize with default theme (opencode)
|
||||
- Load custom themes from JSON files
|
||||
- Handle system theme detection
|
||||
|
||||
- Step 5.3: Add reactive theme resolution
|
||||
- Create `createMemo` for resolved theme colors
|
||||
- Create `createMemo` for syntax highlighting
|
||||
- Create `createMemo` for subtle syntax
|
||||
|
||||
- Step 5.4: Implement theme switching
|
||||
- Add `setTheme(theme: string)` method
|
||||
- Add `setMode(mode: "dark" | "light")` method
|
||||
- Persist theme and mode to localStorage
|
||||
|
||||
- Step 5.5: Add system theme detection
|
||||
- Detect terminal background and foreground colors
|
||||
- Generate system theme based on terminal palette
|
||||
- Handle system theme preference changes
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test theme state initialization
|
||||
- Test theme switching logic
|
||||
- Test mode switching logic
|
||||
- Test system theme detection
|
||||
- Test localStorage persistence
|
||||
|
||||
- Integration/e2e:
|
||||
- Test theme context in component tree
|
||||
- Test reactive theme updates
|
||||
- Test system theme changes
|
||||
|
||||
acceptance_criteria:
|
||||
- `src/context/ThemeContext.tsx` uses SolidJS pattern
|
||||
- Theme context provides reactive theme state
|
||||
- Theme switching works correctly
|
||||
- System theme detection is functional
|
||||
- Theme and mode are persisted to localStorage
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass
|
||||
- Run: `bun test src/context/ThemeContext.test.ts`
|
||||
- Test theme switching in application
|
||||
- Test system theme detection
|
||||
|
||||
notes:
|
||||
- Use opencode's ThemeProvider pattern as reference
|
||||
- Follow SolidJS best practices for reactive state
|
||||
- Ensure proper cleanup of effects and listeners
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx` (lines 279-392)
|
||||
79
tasks/subtasks/theme-refactoring-06-theme-loader.md
Normal file
79
tasks/subtasks/theme-refactoring-06-theme-loader.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# 06. Add Theme Loader for JSON Files and Custom Themes
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-06
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P1
|
||||
depends_on: [theme-refactoring-02, theme-refactoring-04]
|
||||
tags: [implementation, loading]
|
||||
|
||||
objective:
|
||||
- Create theme loader to load JSON theme files
|
||||
- Support loading custom themes from multiple directories
|
||||
- Provide API for theme discovery and loading
|
||||
- Handle theme file validation
|
||||
|
||||
deliverables:
|
||||
- `src/utils/theme-loader.ts` - Theme loader utilities
|
||||
- `src/utils/custom-themes.ts` - Custom theme loading logic
|
||||
|
||||
steps:
|
||||
- Step 6.1: Create `src/utils/theme-loader.ts`
|
||||
- Implement `loadTheme(name: string): Promise<ThemeJson>`
|
||||
- Implement `loadThemeFromPath(path: string): Promise<ThemeJson>`
|
||||
- Implement `getAllThemes(): Promise<Record<string, ThemeJson>>`
|
||||
- Add error handling for missing or invalid theme files
|
||||
|
||||
- Step 6.2: Create `src/utils/custom-themes.ts`
|
||||
- Implement `getCustomThemes()` function
|
||||
- Scan for theme files in multiple directories:
|
||||
- `~/.config/podtui/themes/`
|
||||
- `./.podtui/themes/`
|
||||
- Project root `./themes/`
|
||||
- Support custom theme files with `.json` extension
|
||||
- Return merged theme registry
|
||||
|
||||
- Step 6.3: Add theme file validation
|
||||
- Validate theme JSON structure
|
||||
- Check required properties (`defs`, `theme`)
|
||||
- Validate color references in `defs`
|
||||
- Add warning for optional properties
|
||||
|
||||
- Step 6.4: Implement theme discovery
|
||||
- List all available theme files
|
||||
- Provide theme metadata (name, description)
|
||||
- Support theme aliases (e.g., "catppuccin" -> "catppuccin.json")
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test `loadTheme` with existing theme files
|
||||
- Test `loadTheme` with missing theme files
|
||||
- Test `loadThemeFromPath` with custom paths
|
||||
- Test `getAllThemes` returns all available themes
|
||||
- Test `getCustomThemes` scans multiple directories
|
||||
- Test theme file validation
|
||||
|
||||
- Integration/e2e:
|
||||
- Test loading all available themes
|
||||
- Test custom theme loading from directories
|
||||
- Verify theme discovery works correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- `src/utils/theme-loader.ts` file exists with loading functions
|
||||
- `src/utils/custom-themes.ts` file exists with custom theme logic
|
||||
- Custom themes can be loaded from multiple directories
|
||||
- Theme validation prevents invalid files
|
||||
- Theme discovery API is functional
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass
|
||||
- Run: `bun test src/utils/theme-loader.test.ts`
|
||||
- Run: `bun test src/utils/custom-themes.test.ts`
|
||||
- Test loading all available themes manually
|
||||
- Test custom theme loading from directories
|
||||
|
||||
notes:
|
||||
- Use opencode's `getCustomThemes` pattern as reference
|
||||
- Support both local and global theme directories
|
||||
- Add comprehensive error messages for invalid theme files
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx` (lines 394-419)
|
||||
83
tasks/subtasks/theme-refactoring-07-system-theme.md
Normal file
83
tasks/subtasks/theme-refactoring-07-system-theme.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# 07. Implement System Theme Detection with Terminal Palette
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-07
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P1
|
||||
depends_on: [theme-refactoring-04, theme-refactoring-06]
|
||||
tags: [implementation, detection]
|
||||
|
||||
objective:
|
||||
- Implement system theme detection based on terminal palette
|
||||
- Generate system theme from terminal colors
|
||||
- Detect light/dark mode based on terminal background
|
||||
- Handle terminal color palette limitations
|
||||
|
||||
deliverables:
|
||||
- `src/utils/system-theme.ts` - System theme detection utilities
|
||||
- `src/utils/color-generation.ts` - Color generation helpers
|
||||
|
||||
steps:
|
||||
- Step 7.1: Create `src/utils/system-theme.ts`
|
||||
- Implement `detectSystemTheme()` function
|
||||
- Detect terminal background and foreground colors
|
||||
- Determine light/dark mode based on luminance
|
||||
- Return detected theme information
|
||||
|
||||
- Step 7.2: Implement terminal palette detection
|
||||
- Detect terminal colors using `@opentui/core` renderer
|
||||
- Get default background and foreground colors
|
||||
- Extract color palette (16 standard colors)
|
||||
- Handle missing or invalid palette data
|
||||
|
||||
- Step 7.3: Create `src/utils/color-generation.ts`
|
||||
- Implement `generateGrayScale(bg: RGBA, isDark: boolean): Record<number, RGBA>`
|
||||
- Implement `generateMutedTextColor(bg: RGBA, isDark: boolean): RGBA`
|
||||
- Implement `tint(base: RGBA, overlay: RGBA, alpha: number): RGBA`
|
||||
- Generate gray scale based on background luminance
|
||||
- Generate muted text colors for readability
|
||||
|
||||
- Step 7.4: Create system theme JSON generator
|
||||
- Implement `generateSystemTheme(colors: TerminalColors, mode: "dark" | "light"): ThemeJson`
|
||||
- Use ANSI color references for primary colors
|
||||
- Generate appropriate background colors
|
||||
- Generate diff colors with alpha blending
|
||||
- Generate markdown and syntax colors
|
||||
|
||||
- Step 7.5: Add system theme caching
|
||||
- Cache terminal palette detection results
|
||||
- Handle palette cache invalidation
|
||||
- Support manual cache clear on SIGUSR2
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test `detectSystemTheme` returns correct mode
|
||||
- Test `generateGrayScale` produces correct grays
|
||||
- Test `generateMutedTextColor` produces readable colors
|
||||
- Test `tint` produces correct blended colors
|
||||
- Test `generateSystemTheme` produces valid theme JSON
|
||||
|
||||
- Integration/e2e:
|
||||
- Test system theme detection in terminal
|
||||
- Test theme generation with actual terminal palette
|
||||
- Verify light/dark mode detection is accurate
|
||||
|
||||
acceptance_criteria:
|
||||
- `src/utils/system-theme.ts` file exists with detection functions
|
||||
- `src/utils/color-generation.ts` file exists with generation helpers
|
||||
- System theme detection works correctly
|
||||
- Light/dark mode detection is accurate
|
||||
- Theme generation produces valid JSON
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass
|
||||
- Run: `bun test src/utils/system-theme.test.ts`
|
||||
- Run: `bun test src/utils/color-generation.test.ts`
|
||||
- Test system theme detection manually in terminal
|
||||
- Verify theme colors are readable
|
||||
|
||||
notes:
|
||||
- Use opencode's system theme detection as reference
|
||||
- Handle terminal transparency gracefully
|
||||
- Add fallback for terminals without palette support
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx` (lines 428-535)
|
||||
83
tasks/subtasks/theme-refactoring-08-syntax-highlighting.md
Normal file
83
tasks/subtasks/theme-refactoring-08-syntax-highlighting.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# 08. Add Syntax Highlighting Integration
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-08
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P1
|
||||
depends_on: [theme-refactoring-04, theme-refactoring-05]
|
||||
tags: [implementation, syntax]
|
||||
|
||||
objective:
|
||||
- Add syntax highlighting support using theme colors
|
||||
- Generate syntax rules from theme definitions
|
||||
- Support markdown syntax highlighting
|
||||
- Integrate with OpenTUI syntax highlighting
|
||||
|
||||
deliverables:
|
||||
- `src/utils/syntax-highlighter.ts` - Syntax highlighting utilities
|
||||
- `src/utils/syntax-rules.ts` - Syntax rule generation
|
||||
|
||||
steps:
|
||||
- Step 8.1: Create `src/utils/syntax-rules.ts`
|
||||
- Implement `getSyntaxRules(theme: ThemeColors)` function
|
||||
- Define syntax scopes and their mappings
|
||||
- Map theme colors to syntax scopes:
|
||||
- Default text
|
||||
- Keywords (return, conditional, repeat, coroutine)
|
||||
- Types (function, class, module)
|
||||
- Variables (parameter, member, builtin)
|
||||
- Strings, numbers, booleans
|
||||
- Comments
|
||||
- Operators and punctuation
|
||||
- Markdown-specific scopes (headings, bold, italic, links)
|
||||
- Diff scopes (added, removed, context)
|
||||
- Add style properties (foreground, bold, italic, underline)
|
||||
|
||||
- Step 8.2: Create `src/utils/syntax-highlighter.ts`
|
||||
- Implement `generateSyntax(theme: ThemeColors)` function
|
||||
- Implement `generateSubtleSyntax(theme: ThemeColors)` function
|
||||
- Apply opacity to syntax colors for subtle highlighting
|
||||
- Use theme's `thinkingOpacity` property
|
||||
|
||||
- Step 8.3: Integrate with OpenTUI syntax highlighting
|
||||
- Import `SyntaxStyle` from `@opentui/core`
|
||||
- Use `SyntaxStyle.fromTheme()` to create syntax styles
|
||||
- Apply syntax styles to code components
|
||||
|
||||
- Step 8.4: Add syntax scope mappings
|
||||
- Map common programming language scopes
|
||||
- Map markdown and markup scopes
|
||||
- Map diff and git scopes
|
||||
- Add scope aliases for common patterns
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test `getSyntaxRules` generates correct rules
|
||||
- Test `generateSyntax` creates valid syntax styles
|
||||
- Test `generateSubtleSyntax` applies opacity correctly
|
||||
- Test syntax rules cover all expected scopes
|
||||
|
||||
- Integration/e2e:
|
||||
- Test syntax highlighting with different themes
|
||||
- Verify syntax colors match theme definitions
|
||||
- Test markdown highlighting
|
||||
|
||||
acceptance_criteria:
|
||||
- `src/utils/syntax-rules.ts` file exists with rule generation
|
||||
- `src/utils/syntax-highlighter.ts` file exists with style generation
|
||||
- Syntax highlighting works with theme colors
|
||||
- Markdown highlighting is supported
|
||||
- Syntax rules cover common programming patterns
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass
|
||||
- Run: `bun test src/utils/syntax-rules.test.ts`
|
||||
- Run: `bun test src/utils/syntax-highlighter.test.ts`
|
||||
- Test syntax highlighting in application
|
||||
- Verify syntax colors are readable
|
||||
|
||||
notes:
|
||||
- Use opencode's syntax rule generation as reference
|
||||
- Include comprehensive scope mappings
|
||||
- Support common programming languages
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx` (lines 622-1152)
|
||||
77
tasks/subtasks/theme-refactoring-09-theme-utils.md
Normal file
77
tasks/subtasks/theme-refactoring-09-theme-utils.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 09. Update Theme Utilities and CSS Variable Application
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-09
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P1
|
||||
depends_on: [theme-refactoring-04]
|
||||
tags: [implementation, utilities]
|
||||
|
||||
objective:
|
||||
- Update existing theme utilities to work with JSON theme structure
|
||||
- Refactor CSS variable application logic
|
||||
- Add support for theme color references
|
||||
- Ensure backward compatibility with existing components
|
||||
|
||||
deliverables:
|
||||
- `src/utils/theme.ts` - Updated theme utilities
|
||||
- `src/utils/theme-css.ts` - CSS variable application utilities
|
||||
|
||||
steps:
|
||||
- Step 9.1: Update `src/utils/theme.ts`
|
||||
- Refactor `applyTheme()` to accept `ThemeColors` type
|
||||
- Keep existing function signature for backward compatibility
|
||||
- Update to work with resolved theme colors
|
||||
|
||||
- Step 9.2: Create `src/utils/theme-css.ts`
|
||||
- Implement `applyThemeToCSS(theme: ThemeColors)` function
|
||||
- Apply theme colors as CSS custom properties
|
||||
- Support all theme color properties
|
||||
- Handle layer backgrounds if present
|
||||
|
||||
- Step 9.3: Update theme attribute handling
|
||||
- Implement `setThemeAttribute(themeName: string)` function
|
||||
- Update to use data-theme attribute
|
||||
- Support system theme attribute
|
||||
|
||||
- Step 9.4: Add color reference support
|
||||
- Implement `resolveColorReference(color: string): string` function
|
||||
- Convert color references to CSS values
|
||||
- Handle hex colors, color references, and RGBA
|
||||
|
||||
- Step 9.5: Add theme utility functions
|
||||
- Implement `getThemeByName(name: string): ThemeJson | undefined`
|
||||
- Implement `getDefaultTheme(): ThemeJson`
|
||||
- Implement `getAllThemes(): ThemeJson[]`
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test `applyThemeToCSS` applies all colors correctly
|
||||
- Test `setThemeAttribute` sets attribute correctly
|
||||
- Test `resolveColorReference` converts references correctly
|
||||
- Test theme utility functions return correct results
|
||||
|
||||
- Integration/e2e:
|
||||
- Test theme application in browser
|
||||
- Verify CSS variables are updated correctly
|
||||
- Test theme attribute changes
|
||||
|
||||
acceptance_criteria:
|
||||
- `src/utils/theme.ts` is updated and backward compatible
|
||||
- `src/utils/theme-css.ts` file exists with CSS utilities
|
||||
- CSS variables are applied correctly
|
||||
- Color references are resolved properly
|
||||
- Theme utilities are functional
|
||||
|
||||
validation:
|
||||
- Run: `bun run typecheck` - Should pass
|
||||
- Run: `bun test src/utils/theme.test.ts`
|
||||
- Run: `bun test src/utils/theme-css.test.ts`
|
||||
- Test theme application in browser
|
||||
- Verify CSS variables are applied correctly
|
||||
|
||||
notes:
|
||||
- Maintain backward compatibility with existing code
|
||||
- Use CSS custom properties for theming
|
||||
- Ensure all theme colors are applied
|
||||
- Reference: `/home/mike/code/PodTui/src/utils/theme.ts` (original file)
|
||||
80
tasks/subtasks/theme-refactoring-10-theme-switching.md
Normal file
80
tasks/subtasks/theme-refactoring-10-theme-switching.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# 10. Test Theme Switching and Light/Dark Mode
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-10
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P0
|
||||
depends_on: [theme-refactoring-05, theme-refactoring-09]
|
||||
tags: [testing, verification]
|
||||
|
||||
objective:
|
||||
- Comprehensive testing of theme switching functionality
|
||||
- Verify light/dark mode switching works correctly
|
||||
- Test all theme JSON files load and apply correctly
|
||||
- Ensure theme persistence works across sessions
|
||||
|
||||
deliverables:
|
||||
- `src/utils/theme.test.ts` - Theme utility tests
|
||||
- `src/context/ThemeContext.test.ts` - Context tests
|
||||
- Test results showing all themes work correctly
|
||||
|
||||
steps:
|
||||
- Step 10.1: Create `src/utils/theme.test.ts`
|
||||
- Test theme loading functions
|
||||
- Test theme resolution logic
|
||||
- Test color reference resolution
|
||||
- Test ANSI color conversion
|
||||
|
||||
- Step 10.2: Create `src/context/ThemeContext.test.ts`
|
||||
- Test theme context initialization
|
||||
- Test theme switching
|
||||
- Test mode switching
|
||||
- Test system theme detection
|
||||
- Test localStorage persistence
|
||||
- Test reactive theme updates
|
||||
|
||||
- Step 10.3: Manual testing
|
||||
- Test switching between all themes (catppuccin, gruvbox, tokyo, nord)
|
||||
- Test light/dark mode switching
|
||||
- Test system theme detection
|
||||
- Test theme persistence (close and reopen app)
|
||||
- Test custom theme loading
|
||||
|
||||
- Step 10.4: Visual verification
|
||||
- Verify all theme colors are correct
|
||||
- Check readability of text colors
|
||||
- Verify background colors are appropriate
|
||||
- Check that all UI elements use theme colors
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Run all theme utility tests
|
||||
- Run all theme context tests
|
||||
- Verify all tests pass
|
||||
|
||||
- Integration/e2e:
|
||||
- Test theme switching in application
|
||||
- Test light/dark mode switching
|
||||
- Test theme persistence
|
||||
- Test system theme detection
|
||||
|
||||
acceptance_criteria:
|
||||
- All unit tests pass
|
||||
- All integration tests pass
|
||||
- Theme switching works correctly
|
||||
- Light/dark mode switching works correctly
|
||||
- All themes load and apply correctly
|
||||
- Theme persistence works across sessions
|
||||
|
||||
validation:
|
||||
- Run: `bun test src/utils/theme.test.ts`
|
||||
- Run: `bun test src/context/ThemeContext.test.ts`
|
||||
- Run: `bun test` - Run all tests
|
||||
- Manual testing of all themes
|
||||
- Visual verification of theme appearance
|
||||
|
||||
notes:
|
||||
- Test with actual terminal to verify system theme detection
|
||||
- Verify all theme colors are visually appealing
|
||||
- Check for any color contrast issues
|
||||
- Test edge cases (missing themes, invalid colors)
|
||||
77
tasks/subtasks/theme-refactoring-11-custom-themes.md
Normal file
77
tasks/subtasks/theme-refactoring-11-custom-themes.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 11. Verify Custom Theme Loading and Persistence
|
||||
|
||||
meta:
|
||||
id: theme-refactoring-11
|
||||
feature: theme-refactoring-json-format
|
||||
priority: P1
|
||||
depends_on: [theme-refactoring-06, theme-refactoring-10]
|
||||
tags: [testing, verification]
|
||||
|
||||
objective:
|
||||
- Test custom theme loading from directories
|
||||
- Verify theme persistence works correctly
|
||||
- Test custom theme switching
|
||||
- Ensure custom themes are loaded on app start
|
||||
|
||||
deliverables:
|
||||
- Test results for custom theme loading
|
||||
- Documentation for custom theme format
|
||||
- Verification that custom themes work correctly
|
||||
|
||||
steps:
|
||||
- Step 11.1: Create test theme files
|
||||
- Create test theme in `~/.config/podtui/themes/`
|
||||
- Create test theme in `./.podtui/themes/`
|
||||
- Create test theme in `./themes/`
|
||||
|
||||
- Step 11.2: Test custom theme loading
|
||||
- Start application and verify custom themes are loaded
|
||||
- Switch to custom theme
|
||||
- Verify custom theme applies correctly
|
||||
|
||||
- Step 11.3: Test theme persistence
|
||||
- Set custom theme
|
||||
- Close application
|
||||
- Reopen application
|
||||
- Verify custom theme is still selected
|
||||
|
||||
- Step 11.4: Test theme discovery
|
||||
- List all available themes
|
||||
- Verify custom themes appear in list
|
||||
- Test switching to custom themes
|
||||
|
||||
- Step 11.5: Test invalid theme handling
|
||||
- Create invalid theme JSON
|
||||
- Verify error is handled gracefully
|
||||
- Verify app doesn't crash
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test custom theme loading functions
|
||||
- Test theme discovery
|
||||
- Test invalid theme handling
|
||||
|
||||
- Integration/e2e:
|
||||
- Test custom theme loading from directories
|
||||
- Test theme persistence
|
||||
- Test theme discovery
|
||||
- Test invalid theme handling
|
||||
|
||||
acceptance_criteria:
|
||||
- Custom themes can be loaded from directories
|
||||
- Custom themes persist across sessions
|
||||
- Custom themes appear in theme list
|
||||
- Invalid themes are handled gracefully
|
||||
- Theme discovery works correctly
|
||||
|
||||
validation:
|
||||
- Run: `bun test src/utils/custom-themes.test.ts`
|
||||
- Run: `bun test` - Run all tests
|
||||
- Manual testing of custom themes
|
||||
- Verify themes persist after restart
|
||||
|
||||
notes:
|
||||
- Create documentation for custom theme format
|
||||
- Reference: `/home/mike/code/PodTui/opencode/packages/opencode/src/cli/cmd/tui/context/theme.tsx` (lines 394-419)
|
||||
- Test with multiple custom themes
|
||||
- Verify all custom themes work correctly
|
||||
Reference in New Issue
Block a user