missing md
This commit is contained in:
39
src/App.tsx
39
src/App.tsx
@@ -2,7 +2,6 @@ import { createSignal } from "solid-js";
|
|||||||
import { Layout } from "./components/Layout";
|
import { Layout } from "./components/Layout";
|
||||||
import { Navigation } from "./components/Navigation";
|
import { Navigation } from "./components/Navigation";
|
||||||
import { TabNavigation } from "./components/TabNavigation";
|
import { TabNavigation } from "./components/TabNavigation";
|
||||||
import { SyncPanel } from "./components/SyncPanel";
|
|
||||||
import { FeedList } from "./components/FeedList";
|
import { FeedList } from "./components/FeedList";
|
||||||
import { LoginScreen } from "./components/LoginScreen";
|
import { LoginScreen } from "./components/LoginScreen";
|
||||||
import { CodeValidation } from "./components/CodeValidation";
|
import { CodeValidation } from "./components/CodeValidation";
|
||||||
@@ -10,6 +9,8 @@ import { OAuthPlaceholder } from "./components/OAuthPlaceholder";
|
|||||||
import { SyncProfile } from "./components/SyncProfile";
|
import { SyncProfile } from "./components/SyncProfile";
|
||||||
import { SearchPage } from "./components/SearchPage";
|
import { SearchPage } from "./components/SearchPage";
|
||||||
import { DiscoverPage } from "./components/DiscoverPage";
|
import { DiscoverPage } from "./components/DiscoverPage";
|
||||||
|
import { Player } from "./components/Player";
|
||||||
|
import { SettingsScreen } from "./components/SettingsScreen";
|
||||||
import { useAuthStore } from "./stores/auth";
|
import { useAuthStore } from "./stores/auth";
|
||||||
import { useFeedStore } from "./stores/feed";
|
import { useFeedStore } from "./stores/feed";
|
||||||
import { FeedVisibility } from "./types/feed";
|
import { FeedVisibility } from "./types/feed";
|
||||||
@@ -101,29 +102,15 @@ export function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<box flexDirection="column" gap={1}>
|
<SettingsScreen
|
||||||
<SyncPanel />
|
onOpenAccount={() => setShowAuthPanel(true)}
|
||||||
<box height={1} />
|
accountLabel={
|
||||||
<box border padding={1}>
|
auth.isAuthenticated
|
||||||
<box flexDirection="row" gap={2}>
|
? `Signed in as ${auth.user?.email}`
|
||||||
<text fg="gray">Account:</text>
|
: "Not signed in"
|
||||||
{auth.isAuthenticated ? (
|
}
|
||||||
<text fg="green">Signed in as {auth.user?.email}</text>
|
accountStatus={auth.isAuthenticated ? "signed-in" : "signed-out"}
|
||||||
) : (
|
/>
|
||||||
<text fg="yellow">Not signed in</text>
|
|
||||||
)}
|
|
||||||
<box
|
|
||||||
border
|
|
||||||
padding={0}
|
|
||||||
onMouseDown={() => setShowAuthPanel(true)}
|
|
||||||
>
|
|
||||||
<text fg="cyan">
|
|
||||||
{auth.isAuthenticated ? "[A] Account" : "[A] Sign In"}
|
|
||||||
</text>
|
|
||||||
</box>
|
|
||||||
</box>
|
|
||||||
</box>
|
|
||||||
</box>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
case "discover":
|
case "discover":
|
||||||
@@ -154,13 +141,15 @@ export function App() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
case "player":
|
case "player":
|
||||||
|
return <Player focused={!inputFocused()} />;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<box border style={{ padding: 2 }}>
|
<box border style={{ padding: 2 }}>
|
||||||
<text>
|
<text>
|
||||||
<strong>{tab}</strong>
|
<strong>{tab}</strong>
|
||||||
<br />
|
<br />
|
||||||
Player - coming in later phases
|
Coming soon
|
||||||
</text>
|
</text>
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -39,15 +39,17 @@ export function DiscoverPage(props: DiscoverPageProps) {
|
|||||||
// Category navigation
|
// Category navigation
|
||||||
if (area === "categories") {
|
if (area === "categories") {
|
||||||
if (key.name === "left" || key.name === "h") {
|
if (key.name === "left" || key.name === "h") {
|
||||||
setCategoryIndex((i) => Math.max(0, i - 1))
|
const nextIndex = Math.max(0, categoryIndex() - 1)
|
||||||
const cat = DISCOVER_CATEGORIES[categoryIndex()]
|
setCategoryIndex(nextIndex)
|
||||||
|
const cat = DISCOVER_CATEGORIES[nextIndex]
|
||||||
if (cat) discoverStore.setSelectedCategory(cat.id)
|
if (cat) discoverStore.setSelectedCategory(cat.id)
|
||||||
setShowIndex(0) // Reset show selection when changing category
|
setShowIndex(0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (key.name === "right" || key.name === "l") {
|
if (key.name === "right" || key.name === "l") {
|
||||||
setCategoryIndex((i) => Math.min(DISCOVER_CATEGORIES.length - 1, i + 1))
|
const nextIndex = Math.min(DISCOVER_CATEGORIES.length - 1, categoryIndex() + 1)
|
||||||
const cat = DISCOVER_CATEGORIES[categoryIndex()]
|
setCategoryIndex(nextIndex)
|
||||||
|
const cat = DISCOVER_CATEGORIES[nextIndex]
|
||||||
if (cat) discoverStore.setSelectedCategory(cat.id)
|
if (cat) discoverStore.setSelectedCategory(cat.id)
|
||||||
setShowIndex(0)
|
setShowIndex(0)
|
||||||
return
|
return
|
||||||
@@ -67,10 +69,15 @@ export function DiscoverPage(props: DiscoverPageProps) {
|
|||||||
if (area === "shows") {
|
if (area === "shows") {
|
||||||
const shows = discoverStore.filteredPodcasts()
|
const shows = discoverStore.filteredPodcasts()
|
||||||
if (key.name === "down" || key.name === "j") {
|
if (key.name === "down" || key.name === "j") {
|
||||||
|
if (shows.length === 0) return
|
||||||
setShowIndex((i) => Math.min(i + 1, shows.length - 1))
|
setShowIndex((i) => Math.min(i + 1, shows.length - 1))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (key.name === "up" || key.name === "k") {
|
if (key.name === "up" || key.name === "k") {
|
||||||
|
if (shows.length === 0) {
|
||||||
|
setFocusArea("categories")
|
||||||
|
return
|
||||||
|
}
|
||||||
const newIndex = showIndex() - 1
|
const newIndex = showIndex() - 1
|
||||||
if (newIndex < 0) {
|
if (newIndex < 0) {
|
||||||
setFocusArea("categories")
|
setFocusArea("categories")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { createSignal, For, Show } from "solid-js"
|
import { createSignal, For, Show } from "solid-js"
|
||||||
|
import { useKeyboard } from "@opentui/solid"
|
||||||
import type { Feed } from "../types/feed"
|
import type { Feed } from "../types/feed"
|
||||||
import type { Episode } from "../types/episode"
|
import type { Episode } from "../types/episode"
|
||||||
import { format } from "date-fns"
|
import { format } from "date-fns"
|
||||||
@@ -72,6 +73,11 @@ export function FeedDetail(props: FeedDetailProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useKeyboard((key) => {
|
||||||
|
if (!props.focused) return
|
||||||
|
handleKeyPress(key)
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<box flexDirection="column" gap={1}>
|
<box flexDirection="column" gap={1}>
|
||||||
{/* Header with back button */}
|
{/* Header with back button */}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { createSignal, For, Show } from "solid-js"
|
import { createSignal, For, Show } from "solid-js"
|
||||||
|
import { useKeyboard } from "@opentui/solid"
|
||||||
import { FeedItem } from "./FeedItem"
|
import { FeedItem } from "./FeedItem"
|
||||||
import { useFeedStore } from "../stores/feed"
|
import { useFeedStore } from "../stores/feed"
|
||||||
import { FeedVisibility, FeedSortField } from "../types/feed"
|
import { FeedVisibility, FeedSortField } from "../types/feed"
|
||||||
@@ -65,6 +66,11 @@ export function FeedList(props: FeedListProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useKeyboard((key) => {
|
||||||
|
if (!props.focused) return
|
||||||
|
handleKeyPress(key)
|
||||||
|
})
|
||||||
|
|
||||||
const cycleVisibilityFilter = () => {
|
const cycleVisibilityFilter = () => {
|
||||||
const current = feedStore.filter().visibility
|
const current = feedStore.filter().visibility
|
||||||
let next: FeedVisibility | "all"
|
let next: FeedVisibility | "all"
|
||||||
|
|||||||
52
tasks/podcast-tui-app/50-global-state-store.md
Normal file
52
tasks/podcast-tui-app/50-global-state-store.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# 50. Create Global State Store (Signals)
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-50
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [66]
|
||||||
|
tags: [state-management, signals, solidjs, global-store]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Create a global state store using SolidJS Signals for reactive state management
|
||||||
|
- Implement a store that manages application-wide state (feeds, settings, user, etc.)
|
||||||
|
- Provide reactive subscriptions for state changes
|
||||||
|
- Ensure thread-safe state updates
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/store/index.ts` - Global state store with Signals
|
||||||
|
- `/src/store/types.ts` - State type definitions
|
||||||
|
- `/src/store/hooks.ts` - Custom hooks for state access
|
||||||
|
- Updated `src/index.tsx` to initialize the store
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Define state interface with all application state properties (feeds, settings, user, etc.)
|
||||||
|
- Create Signal-based store using `createSignal` from SolidJS
|
||||||
|
- Implement computed signals for derived state (filtered feeds, search results, etc.)
|
||||||
|
- Create state update functions that trigger reactivity
|
||||||
|
- Add subscription mechanism for reactive UI updates
|
||||||
|
- Export store and hooks for use across components
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Test that signals update correctly when state changes
|
||||||
|
- Unit: Test computed signals produce correct derived values
|
||||||
|
- Integration: Verify store updates trigger UI re-renders
|
||||||
|
- Integration: Test multiple components can subscribe to same state
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Store can be initialized with default state
|
||||||
|
- State changes trigger reactive updates in components
|
||||||
|
- Computed signals work correctly for derived state
|
||||||
|
- Multiple components can access and subscribe to store
|
||||||
|
- State updates are thread-safe
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Run application and verify state changes are reactive
|
||||||
|
- Check console for any errors during state updates
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Use `createSignal`, `createComputed`, `createEffect` from SolidJS
|
||||||
|
- Store should follow single source of truth pattern
|
||||||
|
- Consider using `batch` for multiple state updates
|
||||||
|
- State should be serializable for persistence
|
||||||
56
tasks/podcast-tui-app/59-theme-system.md
Normal file
56
tasks/podcast-tui-app/59-theme-system.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# 59. Create Theme System Architecture
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-59
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [09]
|
||||||
|
tags: [theming, architecture, solidjs, design-system]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Design and implement a flexible theme system architecture
|
||||||
|
- Support multiple color themes (Catppuccin, Gruvbox, Tokyo, Nord, custom)
|
||||||
|
- Provide theme switching capabilities
|
||||||
|
- Ensure theme persistence across sessions
|
||||||
|
- Define theme properties (colors, fonts, spacing, borders)
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/themes/types.ts` - Theme type definitions
|
||||||
|
- `/src/themes/theme.ts` - Theme system core implementation
|
||||||
|
- `/src/themes/themes/` - Directory with theme files
|
||||||
|
- `/src/themes/default.ts` - Default system theme
|
||||||
|
- `/src/themes/hooks.ts` - Theme hooks (useTheme, useThemeColor)
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Define `Theme` interface with properties: name, colors, fonts, spacing, borders
|
||||||
|
- Create theme color palettes (background, foreground, primary, secondary, accent, etc.)
|
||||||
|
- Implement `ThemeManager` class to handle theme loading, switching, and persistence
|
||||||
|
- Create `useTheme` hook for React/Solid components to access current theme
|
||||||
|
- Implement `useThemeColor` hook for accessing specific theme colors
|
||||||
|
- Add theme persistence using localStorage or file-based storage
|
||||||
|
- Export theme utilities for programmatic theme access
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Test theme loading from JSON file
|
||||||
|
- Unit: Test theme switching updates current theme
|
||||||
|
- Unit: Test theme persistence saves/loads correctly
|
||||||
|
- Integration: Verify components update when theme changes
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Theme system can load multiple theme definitions
|
||||||
|
- Theme switching works instantly across all components
|
||||||
|
- Theme preferences persist across application restarts
|
||||||
|
- Theme colors are accessible via hooks
|
||||||
|
- Theme manager handles errors gracefully
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test theme switching manually in application
|
||||||
|
- Verify localStorage/file storage works
|
||||||
|
- Check all theme colors render correctly
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Theme files should be JSON or TypeScript modules
|
||||||
|
- Use CSS variables or terminal color codes
|
||||||
|
- Consider dark/light mode compatibility
|
||||||
|
- Themes should be easily extensible
|
||||||
52
tasks/podcast-tui-app/60-default-theme.md
Normal file
52
tasks/podcast-tui-app/60-default-theme.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# 60. Implement Default Theme (System Terminal)
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-60
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [59]
|
||||||
|
tags: [theming, default, solidjs, terminal]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Implement the default system terminal theme
|
||||||
|
- Define colors matching common terminal environments
|
||||||
|
- Ensure good readability and contrast
|
||||||
|
- Support both light and dark terminal modes
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/themes/themes/default.ts` - Default theme definition
|
||||||
|
- `/src/themes/themes/default-light.ts` - Light mode theme
|
||||||
|
- `/src/themes/themes/default-dark.ts` - Dark mode theme
|
||||||
|
- Updated `/src/themes/theme.ts` to load default theme
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Define default color palette for system terminals
|
||||||
|
- Create light mode theme with standard terminal colors
|
||||||
|
- Create dark mode theme with standard terminal colors
|
||||||
|
- Ensure proper contrast ratios for readability
|
||||||
|
- Test theme in both light and dark terminal environments
|
||||||
|
- Export default theme as fallback
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Verify default theme colors are defined
|
||||||
|
- Unit: Test theme renders correctly in light mode
|
||||||
|
- Unit: Test theme renders correctly in dark mode
|
||||||
|
- Visual: Verify text contrast meets accessibility standards
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Default theme works in light terminal mode
|
||||||
|
- Default theme works in dark terminal mode
|
||||||
|
- Colors have good readability and contrast
|
||||||
|
- Theme is used as fallback when no theme selected
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test in light terminal (e.g., iTerm2, Terminal.app)
|
||||||
|
- Test in dark terminal (e.g., Kitty, Alacritty)
|
||||||
|
- Check color contrast visually
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Use standard terminal color codes (ANSI escape codes)
|
||||||
|
- Consider common terminal themes (Solarized, Dracula, etc.)
|
||||||
|
- Test on multiple terminal emulators
|
||||||
|
- Document terminal requirements
|
||||||
52
tasks/podcast-tui-app/61-catppuccin-theme.md
Normal file
52
tasks/podcast-tui-app/61-catppuccin-theme.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# 61. Add Catppuccin Theme
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-61
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [59]
|
||||||
|
tags: [theming, catppuccin, solidjs, popular]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Implement Catppuccin Mocha theme for the podcast TUI
|
||||||
|
- Provide beautiful, modern color scheme
|
||||||
|
- Ensure high contrast and readability
|
||||||
|
- Support both dark and light variants
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/themes/themes/catppuccin.ts` - Catppuccin theme definition
|
||||||
|
- `/src/themes/themes/catppuccin-mocha.ts` - Dark mode Catppuccin
|
||||||
|
- `/src/themes/themes/catppuccin-latte.ts` - Light mode Catppuccin
|
||||||
|
- Updated `/src/themes/themes/index.ts` to export Catppuccin themes
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Research and implement Catppuccin Mocha color palette
|
||||||
|
- Define all color tokens (background, foreground, surface, primary, secondary, etc.)
|
||||||
|
- Create Catppuccin Mocha (dark) theme
|
||||||
|
- Create Catppuccin Latte (light) theme
|
||||||
|
- Ensure proper color contrast for accessibility
|
||||||
|
- Add Catppuccin to theme registry
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Verify Catppuccin theme colors are defined
|
||||||
|
- Unit: Test Catppuccin Mocha renders correctly
|
||||||
|
- Unit: Test Catppuccin Latte renders correctly
|
||||||
|
- Visual: Verify Catppuccin colors are visually appealing
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Catppuccin Mocha theme works in dark terminals
|
||||||
|
- Catppuccin Latte theme works in light terminals
|
||||||
|
- Colors match official Catppuccin design
|
||||||
|
- Theme is selectable from theme list
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test Catppuccin theme manually in application
|
||||||
|
- Compare with official Catppuccin color palette
|
||||||
|
- Check color harmony and contrast
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Catppuccin Mocha is the recommended dark theme
|
||||||
|
- Include all standard Catppuccin colors (latte, frappe, macchiato, mocha)
|
||||||
|
- Use official color values from Catppuccin repository
|
||||||
|
- Consider adding custom color variations
|
||||||
52
tasks/podcast-tui-app/62-gruvbox-theme.md
Normal file
52
tasks/podcast-tui-app/62-gruvbox-theme.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# 62. Add Gruvbox Theme
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-62
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [59]
|
||||||
|
tags: [theming, gruvbox, solidjs, retro]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Implement Gruvbox Dark theme for the podcast TUI
|
||||||
|
- Provide warm, nostalgic color scheme
|
||||||
|
- Ensure good contrast and readability
|
||||||
|
- Support both dark and light variants
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/themes/themes/gruvbox.ts` - Gruvbox theme definition
|
||||||
|
- `/src/themes/themes/gruvbox-dark.ts` - Dark mode Gruvbox
|
||||||
|
- `/src/themes/themes/gruvbox-light.ts` - Light mode Gruvbox
|
||||||
|
- Updated `/src/themes/themes/index.ts` to export Gruvbox themes
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Research and implement Gruvbox Dark theme color palette
|
||||||
|
- Define all color tokens (background, foreground, primary, secondary, etc.)
|
||||||
|
- Create Gruvbox Dark theme
|
||||||
|
- Create Gruvbox Light theme
|
||||||
|
- Ensure proper color contrast for accessibility
|
||||||
|
- Add Gruvbox to theme registry
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Verify Gruvbox theme colors are defined
|
||||||
|
- Unit: Test Gruvbox Dark renders correctly
|
||||||
|
- Unit: Test Gruvbox Light renders correctly
|
||||||
|
- Visual: Verify Gruvbox colors are visually appealing
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Gruvbox Dark theme works in dark terminals
|
||||||
|
- Gruvbox Light theme works in light terminals
|
||||||
|
- Colors match official Gruvbox design
|
||||||
|
- Theme is selectable from theme list
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test Gruvbox theme manually in application
|
||||||
|
- Compare with official Gruvbox color palette
|
||||||
|
- Check color harmony and contrast
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Gruvbox Dark is the recommended variant
|
||||||
|
- Include all standard Gruvbox colors (hard, soft, light)
|
||||||
|
- Use official color values from Gruvbox repository
|
||||||
|
- Gruvbox is popular among developers for its warmth
|
||||||
52
tasks/podcast-tui-app/63-tokyo-theme.md
Normal file
52
tasks/podcast-tui-app/63-tokyo-theme.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# 63. Add Tokyo Night Theme
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-63
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [59]
|
||||||
|
tags: [theming, tokyo-night, solidjs, modern]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Implement Tokyo Night theme for the podcast TUI
|
||||||
|
- Provide modern, vibrant color scheme
|
||||||
|
- Ensure good contrast and readability
|
||||||
|
- Support both dark and light variants
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/themes/themes/tokyo-night.ts` - Tokyo Night theme definition
|
||||||
|
- `/src/themes/themes/tokyo-night-day.ts` - Light mode Tokyo Night
|
||||||
|
- `/src/themes/themes/tokyo-night-night.ts` - Dark mode Tokyo Night
|
||||||
|
- Updated `/src/themes/themes/index.ts` to export Tokyo Night themes
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Research and implement Tokyo Night theme color palette
|
||||||
|
- Define all color tokens (background, foreground, primary, secondary, etc.)
|
||||||
|
- Create Tokyo Night Night (dark) theme
|
||||||
|
- Create Tokyo Night Day (light) theme
|
||||||
|
- Ensure proper color contrast for accessibility
|
||||||
|
- Add Tokyo Night to theme registry
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Verify Tokyo Night theme colors are defined
|
||||||
|
- Unit: Test Tokyo Night Night renders correctly
|
||||||
|
- Unit: Test Tokyo Night Day renders correctly
|
||||||
|
- Visual: Verify Tokyo Night colors are visually appealing
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Tokyo Night Night theme works in dark terminals
|
||||||
|
- Tokyo Night Day theme works in light terminals
|
||||||
|
- Colors match official Tokyo Night design
|
||||||
|
- Theme is selectable from theme list
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test Tokyo Night theme manually in application
|
||||||
|
- Compare with official Tokyo Night color palette
|
||||||
|
- Check color harmony and contrast
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Tokyo Night Night is the recommended variant
|
||||||
|
- Include all standard Tokyo Night colors
|
||||||
|
- Use official color values from Tokyo Night repository
|
||||||
|
- Tokyo Night is popular for its modern, clean look
|
||||||
52
tasks/podcast-tui-app/64-nord-theme.md
Normal file
52
tasks/podcast-tui-app/64-nord-theme.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# 64. Add Nord Theme
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-64
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [59]
|
||||||
|
tags: [theming, nord, solidjs, minimal]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Implement Nord theme for the podcast TUI
|
||||||
|
- Provide clean, minimal color scheme
|
||||||
|
- Ensure good contrast and readability
|
||||||
|
- Support both dark and light variants
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/themes/themes/nord.ts` - Nord theme definition
|
||||||
|
- `/src/themes/themes/nord-dark.ts` - Dark mode Nord
|
||||||
|
- `/src/themes/themes/nord-light.ts` - Light mode Nord
|
||||||
|
- Updated `/src/themes/themes/index.ts` to export Nord themes
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Research and implement Nord theme color palette
|
||||||
|
- Define all color tokens (background, foreground, primary, secondary, etc.)
|
||||||
|
- Create Nord Dark theme
|
||||||
|
- Create Nord Light theme
|
||||||
|
- Ensure proper color contrast for accessibility
|
||||||
|
- Add Nord to theme registry
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Verify Nord theme colors are defined
|
||||||
|
- Unit: Test Nord Dark renders correctly
|
||||||
|
- Unit: Test Nord Light renders correctly
|
||||||
|
- Visual: Verify Nord colors are visually appealing
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Nord Dark theme works in dark terminals
|
||||||
|
- Nord Light theme works in light terminals
|
||||||
|
- Colors match official Nord design
|
||||||
|
- Theme is selectable from theme list
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test Nord theme manually in application
|
||||||
|
- Compare with official Nord color palette
|
||||||
|
- Check color harmony and contrast
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Nord Dark is the recommended variant
|
||||||
|
- Include all standard Nord colors
|
||||||
|
- Use official color values from Nord repository
|
||||||
|
- Nord is popular for its minimalist, clean aesthetic
|
||||||
56
tasks/podcast-tui-app/65-custom-theme.md
Normal file
56
tasks/podcast-tui-app/65-custom-theme.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# 65. Implement Custom Theme Editor
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-65
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P2
|
||||||
|
depends_on: [59]
|
||||||
|
tags: [theming, editor, custom, solidjs]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Build a UI for creating and editing custom themes
|
||||||
|
- Allow users to modify color palettes
|
||||||
|
- Provide live preview of theme changes
|
||||||
|
- Save custom themes to storage
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/components/ThemeEditor.tsx` - Theme editor component
|
||||||
|
- `/src/components/ThemePreview.tsx` - Live theme preview component
|
||||||
|
- `/src/components/ColorPicker.tsx` - Custom color picker component
|
||||||
|
- `/src/store/theme-editor.ts` - Theme editor state management
|
||||||
|
- Updated settings screen to include theme editor
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Create ThemeEditor component with color palette editor
|
||||||
|
- Implement ColorPicker component for selecting theme colors
|
||||||
|
- Create ThemePreview component showing live theme changes
|
||||||
|
- Build form controls for editing all theme properties
|
||||||
|
- Add save functionality for custom themes
|
||||||
|
- Implement delete functionality for custom themes
|
||||||
|
- Add validation for theme color values
|
||||||
|
- Update settings screen to show theme editor
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Test theme editor saves custom themes correctly
|
||||||
|
- Unit: Test color picker updates theme colors
|
||||||
|
- Unit: Test theme preview updates in real-time
|
||||||
|
- Integration: Test custom theme can be loaded
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Theme editor allows editing all theme colors
|
||||||
|
- Custom theme can be saved and loaded
|
||||||
|
- Live preview shows theme changes in real-time
|
||||||
|
- Custom themes persist across sessions
|
||||||
|
- Invalid color values are rejected
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test theme editor manually in application
|
||||||
|
- Verify custom themes save/load correctly
|
||||||
|
- Check live preview works smoothly
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Use existing theme type definitions
|
||||||
|
- Provide preset color palettes for quick selection
|
||||||
|
- Consider adding theme templates
|
||||||
|
- Ensure editor works on small terminal sizes
|
||||||
56
tasks/podcast-tui-app/66-theme-selector.md
Normal file
56
tasks/podcast-tui-app/66-theme-selector.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# 66. Add Theme Selector in Settings
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-66
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P1
|
||||||
|
depends_on: [59, 60, 61, 62, 63, 64, 65]
|
||||||
|
tags: [theming, settings, selector, solidjs]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Add theme selection UI in settings screen
|
||||||
|
- Display all available themes (default, Catppuccin, Gruvbox, Tokyo, Nord, custom)
|
||||||
|
- Allow users to select and switch themes
|
||||||
|
- Show currently selected theme
|
||||||
|
- Persist theme preference
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/components/ThemeSelector.tsx` - Theme selector component
|
||||||
|
- Updated `/src/components/SettingsScreen.tsx` to include theme selector
|
||||||
|
- Updated `/src/store/theme.ts` to handle theme preference persistence
|
||||||
|
- Theme selector in settings navigation
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Create ThemeSelector component with theme list
|
||||||
|
- Implement theme selection logic
|
||||||
|
- Display current theme with visual indicator
|
||||||
|
- Add theme descriptions or icons
|
||||||
|
- Integrate theme selector into Settings screen
|
||||||
|
- Save theme preference to storage
|
||||||
|
- Handle theme switching with instant updates
|
||||||
|
- Add keyboard navigation for theme list
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Test theme selector displays all themes
|
||||||
|
- Unit: Test theme selection updates current theme
|
||||||
|
- Unit: Test theme preference saves to storage
|
||||||
|
- Integration: Test theme switching works across all components
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- Theme selector shows all available themes
|
||||||
|
- Users can select and switch themes
|
||||||
|
- Current theme is clearly indicated
|
||||||
|
- Theme preference persists across sessions
|
||||||
|
- Theme changes apply immediately to all components
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test theme selector manually in settings
|
||||||
|
- Verify theme preference saves/loads correctly
|
||||||
|
- Check theme applies to all UI components
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Use existing theme manager for theme switching
|
||||||
|
- Consider adding theme search/filter
|
||||||
|
- Show theme preview in selector if possible
|
||||||
|
- Ensure accessibility for keyboard navigation
|
||||||
57
tasks/podcast-tui-app/67-browser-redirect.md
Normal file
57
tasks/podcast-tui-app/67-browser-redirect.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# 67. Implement Browser Redirect Flow for OAuth
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-67
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P2
|
||||||
|
depends_on: [04]
|
||||||
|
tags: [oauth, authentication, browser, solidjs]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Implement browser redirect flow for OAuth authentication
|
||||||
|
- Handle OAuth callback in terminal application
|
||||||
|
- Exchange authorization code for access token
|
||||||
|
- Store authentication tokens securely
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/auth/oauth-redirect.ts` - OAuth redirect handler
|
||||||
|
- `/src/auth/oauth-callback.ts` - OAuth callback handler
|
||||||
|
- `/src/auth/token-handler.ts` - Token exchange and storage
|
||||||
|
- Updated `/src/auth/login-screen.tsx` with OAuth option
|
||||||
|
- Updated `/src/auth/authentication-state.ts` for OAuth state
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Implement OAuth authorization URL generation with client ID/secret
|
||||||
|
- Create OAuth redirect handler to capture callback
|
||||||
|
- Handle authorization code exchange with token endpoint
|
||||||
|
- Store access token and refresh token securely
|
||||||
|
- Implement error handling for OAuth failures
|
||||||
|
- Add OAuth state parameter for security
|
||||||
|
- Update authentication state to track OAuth login status
|
||||||
|
- Add OAuth logout functionality
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Test OAuth authorization URL generation
|
||||||
|
- Unit: Test token exchange with valid/invalid code
|
||||||
|
- Unit: Test token storage and retrieval
|
||||||
|
- Integration: Test OAuth flow from start to finish
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- OAuth authorization URL is generated correctly
|
||||||
|
- OAuth callback is handled without errors
|
||||||
|
- Access token is stored securely
|
||||||
|
- OAuth flow works with valid credentials
|
||||||
|
- OAuth errors are handled gracefully
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test OAuth flow manually with test credentials
|
||||||
|
- Verify token storage in localStorage
|
||||||
|
- Check error handling for invalid tokens
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Use standard OAuth 2.0 flow (authorization code grant)
|
||||||
|
- Document OAuth requirements (client ID, redirect URI)
|
||||||
|
- Consider using PKCE for enhanced security
|
||||||
|
- Test with real OAuth provider if possible
|
||||||
|
- Document limitations and requirements
|
||||||
58
tasks/podcast-tui-app/68-qr-code-display.md
Normal file
58
tasks/podcast-tui-app/68-qr-code-display.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# 68. Build QR Code Display for Mobile Verification
|
||||||
|
|
||||||
|
meta:
|
||||||
|
id: podcast-tui-app-68
|
||||||
|
feature: podcast-tui-app
|
||||||
|
priority: P2
|
||||||
|
depends_on: [04]
|
||||||
|
tags: [authentication, qr-code, mobile, verification, solidjs]
|
||||||
|
|
||||||
|
objective:
|
||||||
|
- Display QR code for mobile device verification
|
||||||
|
- Generate QR code from verification URL
|
||||||
|
- Handle manual code entry as fallback
|
||||||
|
- Show verification status and expiration
|
||||||
|
|
||||||
|
deliverables:
|
||||||
|
- `/src/components/QrCodeDisplay.tsx` - QR code display component
|
||||||
|
- `/src/utils/qr-code-generator.ts` - QR code generation utility
|
||||||
|
- `/src/auth/verification-handler.ts` - Verification flow handler
|
||||||
|
- Updated `/src/auth/login-screen.tsx` with QR code option
|
||||||
|
- Updated `/src/auth/code-validation.tsx` for manual entry
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- Integrate QR code generation library (e.g., `qrcode` package)
|
||||||
|
- Create QRCodeDisplay component with generated QR image
|
||||||
|
- Implement verification URL generation
|
||||||
|
- Add manual code entry fallback UI
|
||||||
|
- Show verification expiration timer
|
||||||
|
- Display verification success/failure status
|
||||||
|
- Handle QR code scan timeout
|
||||||
|
- Update authentication state on successful verification
|
||||||
|
|
||||||
|
tests:
|
||||||
|
- Unit: Test QR code generation
|
||||||
|
- Unit: Test verification URL generation
|
||||||
|
- Unit: Test verification code validation
|
||||||
|
- Integration: Test complete verification flow
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- QR code is generated correctly from verification URL
|
||||||
|
- QR code is displayed in terminal
|
||||||
|
- Manual code entry works as fallback
|
||||||
|
- Verification status is shown clearly
|
||||||
|
- Verification expires after timeout
|
||||||
|
- Successful verification updates auth state
|
||||||
|
|
||||||
|
validation:
|
||||||
|
- Run `bun run build` to verify TypeScript compilation
|
||||||
|
- Test QR code display manually
|
||||||
|
- Test manual code entry fallback
|
||||||
|
- Verify verification flow works end-to-end
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- Use `qrcode` or similar library for QR generation
|
||||||
|
- Display QR code in ASCII or image format
|
||||||
|
- Consider using external scanner app
|
||||||
|
- Add verification expiration (e.g., 5 minutes)
|
||||||
|
- Document mobile app requirements for scanning
|
||||||
Reference in New Issue
Block a user