final feature set
This commit is contained in:
113
tasks/INDEX.md
Normal file
113
tasks/INDEX.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# PodTUI Task Index
|
||||
|
||||
This directory contains all task files for the PodTUI project feature implementation.
|
||||
|
||||
## Task Structure
|
||||
|
||||
Each feature has its own directory with:
|
||||
- `README.md` - Feature overview and task list
|
||||
- `{seq}-{task-description}.md` - Individual task files
|
||||
|
||||
## Feature Overview
|
||||
|
||||
### 1. Text Selection Copy to Clipboard
|
||||
**Feature:** Text selection copy to clipboard
|
||||
**Tasks:** 2 tasks
|
||||
**Directory:** `tasks/text-selection-copy/`
|
||||
|
||||
### 2. HTML vs Plain Text RSS Parsing
|
||||
**Feature:** Detect and handle both HTML and plain text content in RSS feeds
|
||||
**Tasks:** 3 tasks
|
||||
**Directory:** `tasks/rss-content-parsing/`
|
||||
|
||||
### 3. Merged Waveform Progress Bar
|
||||
**Feature:** Create a real-time waveform visualization that expands from a progress bar during playback
|
||||
**Tasks:** 4 tasks
|
||||
**Directory:** `tasks/merged-waveform/`
|
||||
|
||||
### 4. Episode List Infinite Scroll
|
||||
**Feature:** Implement scroll-to-bottom loading for episode lists with MAX_EPISODES_REFRESH limit
|
||||
**Tasks:** 4 tasks
|
||||
**Directory:** `tasks/episode-infinite-scroll/`
|
||||
|
||||
### 5. Episode Downloads
|
||||
**Feature:** Add per-episode download and per-feed auto-download settings
|
||||
**Tasks:** 6 tasks
|
||||
**Directory:** `tasks/episode-downloads/`
|
||||
|
||||
### 6. Discover Categories Shortcuts Fix
|
||||
**Feature:** Fix broken discover category filter functionality
|
||||
**Tasks:** 3 tasks
|
||||
**Directory:** `tasks/discover-categories-fix/`
|
||||
|
||||
### 7. Config Persistence to XDG_CONFIG_HOME
|
||||
**Feature:** Move feeds and themes persistence from localStorage to XDG_CONFIG_HOME directory
|
||||
**Tasks:** 5 tasks
|
||||
**Directory:** `tasks/config-persistence/`
|
||||
|
||||
## Task Summary
|
||||
|
||||
**Total Features:** 7
|
||||
**Total Tasks:** 27
|
||||
**Critical Path:** Feature 7 (Config Persistence) - 5 tasks
|
||||
|
||||
## Task Dependencies
|
||||
|
||||
### Feature 1: Text Selection Copy to Clipboard
|
||||
- 01 → 02
|
||||
|
||||
### Feature 2: HTML vs Plain Text RSS Parsing
|
||||
- 03 → 04
|
||||
- 03 → 05
|
||||
|
||||
### Feature 3: Merged Waveform Progress Bar
|
||||
- 06 → 07
|
||||
- 07 → 08
|
||||
- 08 → 09
|
||||
|
||||
### Feature 4: Episode List Infinite Scroll
|
||||
- 10 → 11
|
||||
- 11 → 12
|
||||
- 12 → 13
|
||||
|
||||
### Feature 5: Episode Downloads
|
||||
- 14 → 15
|
||||
- 15 → 16
|
||||
- 16 → 17
|
||||
- 17 → 18
|
||||
- 18 → 19
|
||||
|
||||
### Feature 6: Discover Categories Shortcuts Fix
|
||||
- 20 → 21
|
||||
- 21 → 22
|
||||
|
||||
### Feature 7: Config Persistence to XDG_CONFIG_HOME
|
||||
- 23 → 24
|
||||
- 23 → 25
|
||||
- 24 → 26
|
||||
- 25 → 26
|
||||
- 26 → 27
|
||||
|
||||
## Priority Overview
|
||||
|
||||
**P1 (Critical):**
|
||||
- 23: Implement XDG_CONFIG_HOME directory setup
|
||||
- 24: Refactor feeds persistence to JSON file
|
||||
- 25: Refactor theme persistence to JSON file
|
||||
- 26: Add config file validation and migration
|
||||
|
||||
**P2 (High):**
|
||||
- All other tasks (01-22, 27)
|
||||
|
||||
**P3 (Medium):**
|
||||
- 09: Optimize waveform rendering performance
|
||||
- 13: Add loading indicator for pagination
|
||||
- 19: Create download queue management
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review all task files for accuracy
|
||||
2. Confirm task dependencies
|
||||
3. Start with P1 tasks (Feature 7)
|
||||
4. Follow dependency order within each feature
|
||||
5. Mark tasks complete as they're finished
|
||||
50
tasks/config-persistence/23-config-directory-setup.md
Normal file
50
tasks/config-persistence/23-config-directory-setup.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# 23. Implement XDG_CONFIG_HOME Directory Setup
|
||||
|
||||
meta:
|
||||
id: config-persistence-23
|
||||
feature: config-persistence
|
||||
priority: P1
|
||||
depends_on: []
|
||||
tags: [configuration, file-system, directory-setup]
|
||||
|
||||
objective:
|
||||
- Implement XDG_CONFIG_HOME directory detection and creation
|
||||
- Create application-specific config directory
|
||||
- Handle XDG_CONFIG_HOME environment variable
|
||||
- Provide fallback to ~/.config if XDG_CONFIG_HOME not set
|
||||
|
||||
deliverables:
|
||||
- Config directory detection utility
|
||||
- Directory creation logic
|
||||
- Environment variable handling
|
||||
|
||||
steps:
|
||||
1. Create `src/utils/config-dir.ts`
|
||||
2. Implement XDG_CONFIG_HOME detection
|
||||
3. Create fallback to HOME/.config
|
||||
4. Create application-specific directory (podcast-tui-app)
|
||||
5. Add directory creation with error handling
|
||||
|
||||
tests:
|
||||
- Unit: Test XDG_CONFIG_HOME detection
|
||||
- Unit: Test config directory creation
|
||||
- Manual: Verify directory exists at expected path
|
||||
|
||||
acceptance_criteria:
|
||||
- Config directory is created at correct path
|
||||
- XDG_CONFIG_HOME is respected if set
|
||||
- Falls back to ~/.config if XDG_CONFIG_HOME not set
|
||||
- Directory is created with correct permissions
|
||||
|
||||
validation:
|
||||
- Run app and check config directory exists
|
||||
- Test with XDG_CONFIG_HOME=/custom/path
|
||||
- Test with XDG_CONFIG_HOME not set
|
||||
- Verify directory is created in both cases
|
||||
|
||||
notes:
|
||||
- XDG_CONFIG_HOME default: ~/.config
|
||||
- App name from package.json: podcast-tui-app
|
||||
- Use Bun.file() and file operations for directory creation
|
||||
- Handle permission errors gracefully
|
||||
- Use mkdir -p for recursive creation
|
||||
51
tasks/config-persistence/24-feeds-persistence-refactor.md
Normal file
51
tasks/config-persistence/24-feeds-persistence-refactor.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 24. Refactor Feeds Persistence to JSON File
|
||||
|
||||
meta:
|
||||
id: config-persistence-24
|
||||
feature: config-persistence
|
||||
priority: P1
|
||||
depends_on: [config-persistence-23]
|
||||
tags: [persistence, feeds, file-io]
|
||||
|
||||
objective:
|
||||
- Move feeds persistence from localStorage to JSON file
|
||||
- Load feeds from XDG_CONFIG_HOME directory
|
||||
- Save feeds to JSON file
|
||||
- Maintain backward compatibility
|
||||
|
||||
deliverables:
|
||||
- Feeds JSON file I/O functions
|
||||
- Updated feed store persistence
|
||||
- Migration from localStorage
|
||||
|
||||
steps:
|
||||
1. Create `src/utils/feeds-persistence.ts`
|
||||
2. Implement loadFeedsFromFile() function
|
||||
3. Implement saveFeedsToFile() function
|
||||
4. Update feed store to use file-based persistence
|
||||
5. Add migration from localStorage to file
|
||||
|
||||
tests:
|
||||
- Unit: Test file I/O functions
|
||||
- Integration: Test feed persistence with file
|
||||
- Migration: Test migration from localStorage
|
||||
|
||||
acceptance_criteria:
|
||||
- Feeds are loaded from JSON file
|
||||
- Feeds are saved to JSON file
|
||||
- Backward compatibility maintained
|
||||
|
||||
validation:
|
||||
- Start app with no config file
|
||||
- Subscribe to feeds
|
||||
- Verify feeds saved to file
|
||||
- Restart app and verify feeds loaded
|
||||
- Test migration from localStorage
|
||||
|
||||
notes:
|
||||
- File path: XDG_CONFIG_HOME/podcast-tui-app/feeds.json
|
||||
- Use JSON.stringify/parse for serialization
|
||||
- Handle file not found (empty initial load)
|
||||
- Handle file write errors
|
||||
- Add timestamp to file for versioning
|
||||
- Maintain Feed type structure
|
||||
52
tasks/config-persistence/25-theme-persistence-refactor.md
Normal file
52
tasks/config-persistence/25-theme-persistence-refactor.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# 25. Refactor Theme Persistence to JSON File
|
||||
|
||||
meta:
|
||||
id: config-persistence-25
|
||||
feature: config-persistence
|
||||
priority: P1
|
||||
depends_on: [config-persistence-23]
|
||||
tags: [persistence, themes, file-io]
|
||||
|
||||
objective:
|
||||
- Move theme persistence from localStorage to JSON file
|
||||
- Load custom themes from XDG_CONFIG_HOME directory
|
||||
- Save custom themes to JSON file
|
||||
- Maintain backward compatibility
|
||||
|
||||
deliverables:
|
||||
- Themes JSON file I/O functions
|
||||
- Updated theme persistence
|
||||
- Migration from localStorage
|
||||
|
||||
steps:
|
||||
1. Create `src/utils/themes-persistence.ts`
|
||||
2. Implement loadThemesFromFile() function
|
||||
3. Implement saveThemesToFile() function
|
||||
4. Update theme store to use file-based persistence
|
||||
5. Add migration from localStorage to file
|
||||
|
||||
tests:
|
||||
- Unit: Test file I/O functions
|
||||
- Integration: Test theme persistence with file
|
||||
- Migration: Test migration from localStorage
|
||||
|
||||
acceptance_criteria:
|
||||
- Custom themes are loaded from JSON file
|
||||
- Custom themes are saved to JSON file
|
||||
- Backward compatibility maintained
|
||||
|
||||
validation:
|
||||
- Start app with no theme file
|
||||
- Load custom theme
|
||||
- Verify theme saved to file
|
||||
- Restart app and verify theme loaded
|
||||
- Test migration from localStorage
|
||||
|
||||
notes:
|
||||
- File path: XDG_CONFIG_HOME/podcast-tui-app/themes.json
|
||||
- Use JSON.stringify/parse for serialization
|
||||
- Handle file not found (use default themes)
|
||||
- Handle file write errors
|
||||
- Add timestamp to file for versioning
|
||||
- Maintain theme type structure
|
||||
- Include all theme files in directory
|
||||
51
tasks/config-persistence/26-config-file-validation.md
Normal file
51
tasks/config-persistence/26-config-file-validation.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 26. Add Config File Validation and Migration
|
||||
|
||||
meta:
|
||||
id: config-persistence-26
|
||||
feature: config-persistence
|
||||
priority: P1
|
||||
depends_on: [config-persistence-24, config-persistence-25]
|
||||
tags: [validation, migration, data-integrity]
|
||||
|
||||
objective:
|
||||
- Validate config file structure and data integrity
|
||||
- Migrate data from localStorage to file
|
||||
- Provide migration on first run
|
||||
- Handle config file corruption
|
||||
|
||||
deliverables:
|
||||
- Config file validation function
|
||||
- Migration utility from localStorage
|
||||
- Error handling for corrupted files
|
||||
|
||||
steps:
|
||||
1. Create config file schema validation
|
||||
2. Implement migration from localStorage to file
|
||||
3. Add config file backup before migration
|
||||
4. Handle corrupted JSON files
|
||||
5. Test migration scenarios
|
||||
|
||||
tests:
|
||||
- Unit: Test validation function
|
||||
- Integration: Test migration from localStorage
|
||||
- Error: Test corrupted file handling
|
||||
|
||||
acceptance_criteria:
|
||||
- Config files are validated before use
|
||||
- Migration from localStorage works seamlessly
|
||||
- Corrupted files are handled gracefully
|
||||
|
||||
validation:
|
||||
- Start app with localStorage data
|
||||
- Verify migration to file
|
||||
- Corrupt file and verify handling
|
||||
- Test migration on app restart
|
||||
|
||||
notes:
|
||||
- Validate Feed type structure
|
||||
- Validate theme structure
|
||||
- Create backup before migration
|
||||
- Log migration events
|
||||
- Provide error messages for corrupted files
|
||||
- Add config file versioning
|
||||
- Test with both new and old data formats
|
||||
50
tasks/config-persistence/27-config-file-backup.md
Normal file
50
tasks/config-persistence/27-config-file-backup.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# 27. Implement Config File Backup on Update
|
||||
|
||||
meta:
|
||||
id: config-persistence-27
|
||||
feature: config-persistence
|
||||
priority: P2
|
||||
depends_on: [config-persistence-26]
|
||||
tags: [backup, data-safety, migration]
|
||||
|
||||
objective:
|
||||
- Create backups of config files before updates
|
||||
- Handle config file changes during app updates
|
||||
- Provide rollback capability if needed
|
||||
|
||||
deliverables:
|
||||
- Config backup utility
|
||||
- Backup on config changes
|
||||
- Config version history
|
||||
|
||||
steps:
|
||||
1. Create config backup function
|
||||
2. Implement backup on config save
|
||||
3. Add config version history management
|
||||
4. Test backup and restore scenarios
|
||||
5. Add config file version display
|
||||
|
||||
tests:
|
||||
- Unit: Test backup function
|
||||
- Integration: Test backup on config save
|
||||
- Manual: Test restore from backup
|
||||
|
||||
acceptance_criteria:
|
||||
- Config files are backed up before updates
|
||||
- Backup preserves data integrity
|
||||
- Config version history is maintained
|
||||
|
||||
validation:
|
||||
- Make config changes
|
||||
- Verify backup created
|
||||
- Restart app and check backup
|
||||
- Test restore from backup
|
||||
|
||||
notes:
|
||||
- Backup file naming: feeds.json.backup, themes.json.backup
|
||||
- Keep last N backups (e.g., 5)
|
||||
- Backup timestamp in filename
|
||||
- Use atomic file operations
|
||||
- Test with large config files
|
||||
- Add config file size tracking
|
||||
- Consider automatic cleanup of old backups
|
||||
25
tasks/config-persistence/README.md
Normal file
25
tasks/config-persistence/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Config Persistence to XDG_CONFIG_HOME
|
||||
|
||||
Objective: Move feeds and themes persistence from localStorage to XDG_CONFIG_HOME directory
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [ ] 23 — Implement XDG_CONFIG_HOME directory setup → `23-config-directory-setup.md`
|
||||
- [ ] 24 — Refactor feeds persistence to JSON file → `24-feeds-persistence-refactor.md`
|
||||
- [ ] 25 — Refactor theme persistence to JSON file → `25-theme-persistence-refactor.md`
|
||||
- [ ] 26 — Add config file validation and migration → `26-config-file-validation.md`
|
||||
- [ ] 27 — Implement config file backup on update → `27-config-file-backup.md`
|
||||
|
||||
Dependencies
|
||||
- 23 -> 24
|
||||
- 23 -> 25
|
||||
- 24 -> 26
|
||||
- 25 -> 26
|
||||
- 26 -> 27
|
||||
|
||||
Exit criteria
|
||||
- Feeds are persisted to XDG_CONFIG_HOME/podcast-tui-app/feeds.json
|
||||
- Themes are persisted to XDG_CONFIG_HOME/podcast-tui-app/themes.json
|
||||
- Config file validation ensures data integrity
|
||||
- Migration from localStorage works seamlessly
|
||||
47
tasks/discover-categories-fix/20-category-filter-debug.md
Normal file
47
tasks/discover-categories-fix/20-category-filter-debug.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 20. Debug Category Filter Implementation
|
||||
|
||||
meta:
|
||||
id: discover-categories-fix-20
|
||||
feature: discover-categories-fix
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [debugging, discover, categories]
|
||||
|
||||
objective:
|
||||
- Identify why category filter is not working
|
||||
- Analyze CategoryFilter component behavior
|
||||
- Trace state flow from category selection to show filtering
|
||||
|
||||
deliverables:
|
||||
- Debugged category filter logic
|
||||
- Identified root cause of issue
|
||||
- Test cases to verify fix
|
||||
|
||||
steps:
|
||||
1. Review CategoryFilter component implementation
|
||||
2. Review DiscoverPage category selection handler
|
||||
3. Review discover store category filtering logic
|
||||
4. Add console logging to trace state changes
|
||||
5. Test with various category selections
|
||||
|
||||
tests:
|
||||
- Debug: Test category selection in UI
|
||||
- Debug: Verify state updates in console
|
||||
- Manual: Select different categories and observe behavior
|
||||
|
||||
acceptance_criteria:
|
||||
- Root cause of category filter issue identified
|
||||
- State flow from category to shows is traced
|
||||
- Specific code causing issue identified
|
||||
|
||||
validation:
|
||||
- Run app and select categories
|
||||
- Check console for state updates
|
||||
- Verify which component is not responding correctly
|
||||
|
||||
notes:
|
||||
- Check if categoryIndex signal is updated
|
||||
- Verify discoverStore.setSelectedCategory() is called
|
||||
- Check if filteredPodcasts() is recalculated
|
||||
- Look for race conditions or state sync issues
|
||||
- Add temporary logging to trace state changes
|
||||
47
tasks/discover-categories-fix/21-category-state-sync.md
Normal file
47
tasks/discover-categories-fix/21-category-state-sync.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 21. Fix Category State Synchronization
|
||||
|
||||
meta:
|
||||
id: discover-categories-fix-21
|
||||
feature: discover-categories-fix
|
||||
priority: P2
|
||||
depends_on: [discover-categories-fix-20]
|
||||
tags: [state-management, discover, categories]
|
||||
|
||||
objective:
|
||||
- Ensure category state is properly synchronized across components
|
||||
- Fix state updates not triggering re-renders
|
||||
- Ensure category selection persists correctly
|
||||
|
||||
deliverables:
|
||||
- Fixed state synchronization logic
|
||||
- Updated category selection handlers
|
||||
- Verified state propagation
|
||||
|
||||
steps:
|
||||
1. Fix category state update handlers in DiscoverPage
|
||||
2. Ensure discoverStore.setSelectedCategory() is called correctly
|
||||
3. Fix signal updates to trigger component re-renders
|
||||
4. Test state synchronization across component updates
|
||||
5. Verify category state persists on navigation
|
||||
|
||||
tests:
|
||||
- Unit: Test state update handlers
|
||||
- Integration: Test category selection and state updates
|
||||
- Manual: Navigate between tabs and verify category state
|
||||
|
||||
acceptance_criteria:
|
||||
- Category state updates propagate correctly
|
||||
- Component re-renders when category changes
|
||||
- Category selection persists across navigation
|
||||
|
||||
validation:
|
||||
- Select category and verify show list updates
|
||||
- Switch tabs and back, verify category still selected
|
||||
- Test category navigation with keyboard
|
||||
|
||||
notes:
|
||||
- Check if signals are properly created and updated
|
||||
- Verify discoverStore state is reactive
|
||||
- Ensure CategoryFilter and TrendingShows receive updated data
|
||||
- Test with multiple category selections
|
||||
- Add state persistence if needed
|
||||
47
tasks/discover-categories-fix/22-category-navigation-fix.md
Normal file
47
tasks/discover-categories-fix/22-category-navigation-fix.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 22. Fix Category Keyboard Navigation
|
||||
|
||||
meta:
|
||||
id: discover-categories-fix-22
|
||||
feature: discover-categories-fix
|
||||
priority: P2
|
||||
depends_on: [discover-categories-fix-21]
|
||||
tags: [keyboard, navigation, discover]
|
||||
|
||||
objective:
|
||||
- Fix keyboard navigation for categories
|
||||
- Ensure category selection works with arrow keys
|
||||
- Fix category index tracking during navigation
|
||||
|
||||
deliverables:
|
||||
- Fixed keyboard navigation handlers
|
||||
- Updated category index tracking
|
||||
- Verified navigation works correctly
|
||||
|
||||
steps:
|
||||
1. Review keyboard navigation in DiscoverPage
|
||||
2. Fix category index signal updates
|
||||
3. Ensure categoryIndex signal is updated on arrow key presses
|
||||
4. Test category navigation with arrow keys
|
||||
5. Fix category selection on Enter key
|
||||
|
||||
tests:
|
||||
- Integration: Test category navigation with keyboard
|
||||
- Manual: Navigate categories with arrow keys
|
||||
- Edge case: Test category navigation from shows list
|
||||
|
||||
acceptance_criteria:
|
||||
- Arrow keys navigate categories correctly
|
||||
- Category index updates on navigation
|
||||
- Enter key selects category and updates shows list
|
||||
|
||||
validation:
|
||||
- Use arrow keys to navigate categories
|
||||
- Verify category highlight moves correctly
|
||||
- Press Enter to select category and verify show list updates
|
||||
|
||||
notes:
|
||||
- Check if categoryIndex signal is bound correctly
|
||||
- Ensure arrow keys update categoryIndex signal
|
||||
- Verify categoryIndex is used in filteredPodcasts()
|
||||
- Test category navigation from shows list back to categories
|
||||
- Add keyboard hints in UI
|
||||
19
tasks/discover-categories-fix/README.md
Normal file
19
tasks/discover-categories-fix/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Discover Categories Shortcuts Fix
|
||||
|
||||
Objective: Fix broken discover category filter functionality
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [ ] 20 — Debug category filter implementation → `20-category-filter-debug.md`
|
||||
- [ ] 21 — Fix category state synchronization → `21-category-state-sync.md`
|
||||
- [ ] 22 — Fix category keyboard navigation → `22-category-navigation-fix.md`
|
||||
|
||||
Dependencies
|
||||
- 20 -> 21
|
||||
- 21 -> 22
|
||||
|
||||
Exit criteria
|
||||
- Category filter correctly updates show list
|
||||
- Keyboard navigation works for categories
|
||||
- Category selection persists during navigation
|
||||
46
tasks/episode-downloads/14-download-storage-structure.md
Normal file
46
tasks/episode-downloads/14-download-storage-structure.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 14. Define Download Storage Structure
|
||||
|
||||
meta:
|
||||
id: episode-downloads-14
|
||||
feature: episode-downloads
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [storage, types, data-model]
|
||||
|
||||
objective:
|
||||
- Define data structures for downloaded episodes
|
||||
- Create download state tracking
|
||||
- Design download history and metadata storage
|
||||
|
||||
deliverables:
|
||||
- DownloadedEpisode type definition
|
||||
- Download state interface
|
||||
- Storage schema for download metadata
|
||||
|
||||
steps:
|
||||
1. Add DownloadedEpisode type to types/episode.ts
|
||||
2. Define download state structure (status, progress, timestamp)
|
||||
3. Create download metadata interface
|
||||
4. Add download-related fields to Feed type
|
||||
5. Design database-like storage structure
|
||||
|
||||
tests:
|
||||
- Unit: Test type definitions
|
||||
- Integration: Test storage schema
|
||||
- Validation: Verify structure supports all download scenarios
|
||||
|
||||
acceptance_criteria:
|
||||
- DownloadedEpisode type properly defines download metadata
|
||||
- Download state interface tracks all necessary information
|
||||
- Storage schema supports history and progress tracking
|
||||
|
||||
validation:
|
||||
- Review type definitions for completeness
|
||||
- Verify storage structure can hold all download data
|
||||
- Test with mock download scenarios
|
||||
|
||||
notes:
|
||||
- Add fields: status (downloading, completed, failed), progress (0-100), filePath, downloadedAt
|
||||
- Include download speed and estimated time remaining
|
||||
- Store download history with timestamps
|
||||
- Consider adding resume capability
|
||||
47
tasks/episode-downloads/15-episode-download-utility.md
Normal file
47
tasks/episode-downloads/15-episode-download-utility.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 15. Create Episode Download Utility
|
||||
|
||||
meta:
|
||||
id: episode-downloads-15
|
||||
feature: episode-downloads
|
||||
priority: P2
|
||||
depends_on: [episode-downloads-14]
|
||||
tags: [downloads, utilities, file-io]
|
||||
|
||||
objective:
|
||||
- Implement episode download functionality
|
||||
- Download audio files from episode URLs
|
||||
- Handle download errors and edge cases
|
||||
|
||||
deliverables:
|
||||
- Download utility function
|
||||
- File download handler
|
||||
- Error handling for download failures
|
||||
|
||||
steps:
|
||||
1. Create `src/utils/episode-downloader.ts`
|
||||
2. Implement download function using Bun.file() or fetch
|
||||
3. Add progress tracking during download
|
||||
4. Handle download cancellation
|
||||
5. Add error handling for network and file system errors
|
||||
|
||||
tests:
|
||||
- Unit: Test download function with mock URLs
|
||||
- Integration: Test with real audio file URLs
|
||||
- Error handling: Test download failure scenarios
|
||||
|
||||
acceptance_criteria:
|
||||
- Episodes can be downloaded successfully
|
||||
- Download progress is tracked
|
||||
- Errors are handled gracefully
|
||||
|
||||
validation:
|
||||
- Download test episode from real podcast
|
||||
- Verify file is saved correctly
|
||||
- Check download progress tracking
|
||||
|
||||
notes:
|
||||
- Use Bun's built-in file download capabilities
|
||||
- Support resuming interrupted downloads
|
||||
- Handle large files with streaming
|
||||
- Add download speed tracking
|
||||
- Consider download location in downloadPath setting
|
||||
47
tasks/episode-downloads/16-download-progress-tracking.md
Normal file
47
tasks/episode-downloads/16-download-progress-tracking.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 16. Implement Download Progress Tracking
|
||||
|
||||
meta:
|
||||
id: episode-downloads-16
|
||||
feature: episode-downloads
|
||||
priority: P2
|
||||
depends_on: [episode-downloads-15]
|
||||
tags: [progress, state-management, downloads]
|
||||
|
||||
objective:
|
||||
- Track download progress for each episode
|
||||
- Update download state in real-time
|
||||
- Store download progress in persistent storage
|
||||
|
||||
deliverables:
|
||||
- Download progress state in app store
|
||||
- Progress update utility
|
||||
- Integration with download utility
|
||||
|
||||
steps:
|
||||
1. Add download state to app store
|
||||
2. Update progress during download
|
||||
3. Save progress to persistent storage
|
||||
4. Handle download completion
|
||||
5. Test progress tracking accuracy
|
||||
|
||||
tests:
|
||||
- Unit: Test progress update logic
|
||||
- Integration: Test progress tracking with download
|
||||
- Persistence: Verify progress saved and restored
|
||||
|
||||
acceptance_criteria:
|
||||
- Download progress is tracked accurately
|
||||
- Progress updates in real-time
|
||||
- Progress persists across app restarts
|
||||
|
||||
validation:
|
||||
- Download a large file and watch progress
|
||||
- Verify progress updates at intervals
|
||||
- Restart app and verify progress restored
|
||||
|
||||
notes:
|
||||
- Use existing progress store for episode playback
|
||||
- Create separate download progress store
|
||||
- Update progress every 1-2 seconds
|
||||
- Handle download cancellation by resetting progress
|
||||
- Store progress in XDG_CONFIG_HOME directory
|
||||
47
tasks/episode-downloads/17-download-ui-component.md
Normal file
47
tasks/episode-downloads/17-download-ui-component.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 17. Add Download Status in Episode List
|
||||
|
||||
meta:
|
||||
id: episode-downloads-17
|
||||
feature: episode-downloads
|
||||
priority: P2
|
||||
depends_on: [episode-downloads-16]
|
||||
tags: [ui, downloads, display]
|
||||
|
||||
objective:
|
||||
- Display download status for episodes
|
||||
- Add download button to episode list
|
||||
- Show download progress visually
|
||||
|
||||
deliverables:
|
||||
- Download status indicator component
|
||||
- Download button in episode list
|
||||
- Progress bar for downloading episodes
|
||||
|
||||
steps:
|
||||
1. Add download status field to EpisodeListItem
|
||||
2. Create download button in MyShowsPage episodes panel
|
||||
3. Display download status (none, queued, downloading, completed, failed)
|
||||
4. Add download progress bar for downloading episodes
|
||||
5. Test download status display
|
||||
|
||||
tests:
|
||||
- Integration: Test download status display
|
||||
- Visual: Verify download button and progress bar
|
||||
- UX: Test download status changes
|
||||
|
||||
acceptance_criteria:
|
||||
- Download status is visible in episode list
|
||||
- Download button is accessible
|
||||
- Progress bar shows download progress
|
||||
|
||||
validation:
|
||||
- View episode list with download button
|
||||
- Start download and watch status change
|
||||
- Verify progress bar updates
|
||||
|
||||
notes:
|
||||
- Reuse existing episode list UI from MyShowsPage
|
||||
- Add download icon button next to episode title
|
||||
- Show status text: "DL", "DWN", "DONE", "ERR"
|
||||
- Use existing progress bar component for download progress
|
||||
- Position download button in episode header
|
||||
48
tasks/episode-downloads/18-auto-download-settings.md
Normal file
48
tasks/episode-downloads/18-auto-download-settings.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 18. Implement Per-Feed Auto-Download Settings
|
||||
|
||||
meta:
|
||||
id: episode-downloads-18
|
||||
feature: episode-downloads
|
||||
priority: P2
|
||||
depends_on: [episode-downloads-17]
|
||||
tags: [settings, automation, downloads]
|
||||
|
||||
objective:
|
||||
- Add per-feed auto-download settings
|
||||
- Configure number of episodes to auto-download per feed
|
||||
- Enable/disable auto-download per feed
|
||||
|
||||
deliverables:
|
||||
- Auto-download settings in feed store
|
||||
- Settings UI for per-feed configuration
|
||||
- Auto-download trigger logic
|
||||
|
||||
steps:
|
||||
1. Add autoDownload field to Feed type
|
||||
2. Add autoDownloadCount field to Feed type
|
||||
3. Add settings UI in FeedPage or MyShowsPage
|
||||
4. Implement auto-download trigger logic
|
||||
5. Test auto-download functionality
|
||||
|
||||
tests:
|
||||
- Unit: Test auto-download trigger logic
|
||||
- Integration: Test with multiple feeds
|
||||
- Edge case: Test with feeds having fewer episodes
|
||||
|
||||
acceptance_criteria:
|
||||
- Auto-download settings are configurable per feed
|
||||
- Settings are saved to persistent storage
|
||||
- Auto-download works correctly when enabled
|
||||
|
||||
validation:
|
||||
- Configure auto-download for a feed
|
||||
- Subscribe to new episodes and verify auto-download
|
||||
- Test with multiple feeds
|
||||
|
||||
notes:
|
||||
- Add settings in FeedPage or MyShowsPage
|
||||
- Default: autoDownload = false, autoDownloadCount = 0
|
||||
- Only download newest episodes (by pubDate)
|
||||
- Respect MAX_EPISODES_REFRESH limit
|
||||
- Add settings in feed detail or feed list
|
||||
- Consider adding "auto-download all new episodes" setting
|
||||
48
tasks/episode-downloads/19-download-queue-management.md
Normal file
48
tasks/episode-downloads/19-download-queue-management.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 19. Create Download Queue Management
|
||||
|
||||
meta:
|
||||
id: episode-downloads-19
|
||||
feature: episode-downloads
|
||||
priority: P3
|
||||
depends_on: [episode-downloads-18]
|
||||
tags: [queue, downloads, management]
|
||||
|
||||
objective:
|
||||
- Manage download queue for multiple episodes
|
||||
- Handle concurrent downloads
|
||||
- Provide queue UI for managing downloads
|
||||
|
||||
deliverables:
|
||||
- Download queue data structure
|
||||
- Download queue manager
|
||||
- Download queue UI
|
||||
|
||||
steps:
|
||||
1. Create download queue data structure
|
||||
2. Implement download queue manager (add, remove, process)
|
||||
3. Handle concurrent downloads (limit to 1-2 at a time)
|
||||
4. Create download queue UI component
|
||||
5. Test queue management
|
||||
|
||||
tests:
|
||||
- Unit: Test queue management logic
|
||||
- Integration: Test with multiple downloads
|
||||
- Edge case: Test queue with 50+ episodes
|
||||
|
||||
acceptance_criteria:
|
||||
- Download queue manages multiple downloads
|
||||
- Concurrent downloads are limited
|
||||
- Queue UI shows download status
|
||||
|
||||
validation:
|
||||
- Add 10 episodes to download queue
|
||||
- Verify queue processes sequentially
|
||||
- Check queue UI displays correctly
|
||||
|
||||
notes:
|
||||
- Use queue data structure (array of episodes)
|
||||
- Limit concurrent downloads to 2 for performance
|
||||
- Add queue UI in Settings or separate tab
|
||||
- Show queue in SettingsScreen or new Downloads tab
|
||||
- Allow removing items from queue
|
||||
- Add pause/resume for downloads
|
||||
26
tasks/episode-downloads/README.md
Normal file
26
tasks/episode-downloads/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Episode Downloads
|
||||
|
||||
Objective: Add per-episode download and per-feed auto-download settings
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [ ] 14 — Define download storage structure → `14-download-storage-structure.md`
|
||||
- [ ] 15 — Create episode download utility → `15-episode-download-utility.md`
|
||||
- [ ] 16 — Implement download progress tracking → `16-download-progress-tracking.md`
|
||||
- [ ] 17 — Add download status in episode list → `17-download-ui-component.md`
|
||||
- [ ] 18 — Implement per-feed auto-download settings → `18-auto-download-settings.md`
|
||||
- [ ] 19 — Create download queue management → `19-download-queue-management.md`
|
||||
|
||||
Dependencies
|
||||
- 14 -> 15
|
||||
- 15 -> 16
|
||||
- 16 -> 17
|
||||
- 17 -> 18
|
||||
- 18 -> 19
|
||||
|
||||
Exit criteria
|
||||
- Episodes can be downloaded individually
|
||||
- Per-feed auto-download settings are configurable
|
||||
- Download progress is tracked and displayed
|
||||
- Download queue can be managed
|
||||
@@ -0,0 +1,46 @@
|
||||
# 10. Add Scroll Event Listener to Episodes Panel
|
||||
|
||||
meta:
|
||||
id: episode-infinite-scroll-10
|
||||
feature: episode-infinite-scroll
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [ui, events, scroll]
|
||||
|
||||
objective:
|
||||
- Detect when user scrolls to bottom of episodes list
|
||||
- Add scroll event listener to episodes panel
|
||||
- Track scroll position and trigger pagination when needed
|
||||
|
||||
deliverables:
|
||||
- Scroll event handler function
|
||||
- Scroll position tracking
|
||||
- Integration with episodes panel
|
||||
|
||||
steps:
|
||||
1. Modify MyShowsPage to add scroll event listener
|
||||
2. Detect scroll-to-bottom event (when scrollHeight - scrollTop <= clientHeight)
|
||||
3. Track current scroll position
|
||||
4. Add debouncing for scroll events
|
||||
5. Test scroll detection accuracy
|
||||
|
||||
tests:
|
||||
- Unit: Test scroll detection logic
|
||||
- Integration: Test scroll events in episodes panel
|
||||
- Manual: Scroll to bottom and verify detection
|
||||
|
||||
acceptance_criteria:
|
||||
- Scroll-to-bottom is detected accurately
|
||||
- Debouncing prevents excessive event firing
|
||||
- Scroll position is tracked correctly
|
||||
|
||||
validation:
|
||||
- Scroll through episodes list
|
||||
- Verify bottom detection works
|
||||
- Test with different terminal sizes
|
||||
|
||||
notes:
|
||||
- Use scrollbox component's scroll event if available
|
||||
- Debounce scroll events to 100ms
|
||||
- Handle both manual scroll and programmatic scroll
|
||||
- Consider virtual scrolling if episode count is large
|
||||
@@ -0,0 +1,46 @@
|
||||
# 11. Implement Paginated Episode Fetching
|
||||
|
||||
meta:
|
||||
id: episode-infinite-scroll-11
|
||||
feature: episode-infinite-scroll
|
||||
priority: P2
|
||||
depends_on: [episode-infinite-scroll-10]
|
||||
tags: [rss, pagination, data-fetching]
|
||||
|
||||
objective:
|
||||
- Fetch episodes in chunks with MAX_EPISODES_REFRESH limit
|
||||
- Merge new episodes with existing list
|
||||
- Maintain episode ordering (newest first)
|
||||
|
||||
deliverables:
|
||||
- Paginated episode fetch function
|
||||
- Episode list merging logic
|
||||
- Integration with feed store
|
||||
|
||||
steps:
|
||||
1. Create paginated fetch function in feed store
|
||||
2. Implement chunk-based episode fetching (50 episodes at a time)
|
||||
3. Add logic to merge new episodes with existing list
|
||||
4. Maintain reverse chronological order (newest first)
|
||||
5. Deduplicate episodes by title or URL
|
||||
|
||||
tests:
|
||||
- Unit: Test paginated fetch logic
|
||||
- Integration: Test with real RSS feeds
|
||||
- Edge case: Test with feeds having < 50 episodes
|
||||
|
||||
acceptance_criteria:
|
||||
- Episodes fetched in chunks of MAX_EPISODES_REFRESH
|
||||
- New episodes merged correctly with existing list
|
||||
- Episode ordering maintained (newest first)
|
||||
|
||||
validation:
|
||||
- Test with RSS feed having 100+ episodes
|
||||
- Verify pagination works correctly
|
||||
- Check episode ordering after merge
|
||||
|
||||
notes:
|
||||
- Use existing `MAX_EPISODES_REFRESH = 50` constant
|
||||
- Add episode deduplication logic
|
||||
- Preserve episode metadata during merge
|
||||
- Handle cases where feed has fewer episodes
|
||||
@@ -0,0 +1,46 @@
|
||||
# 12. Manage Episode List Pagination State
|
||||
|
||||
meta:
|
||||
id: episode-infinite-scroll-12
|
||||
feature: episode-infinite-scroll
|
||||
priority: P2
|
||||
depends_on: [episode-infinite-scroll-11]
|
||||
tags: [state-management, pagination]
|
||||
|
||||
objective:
|
||||
- Track pagination state (current page, loaded count, has more episodes)
|
||||
- Manage episode list state changes
|
||||
- Handle pagination state across component renders
|
||||
|
||||
deliverables:
|
||||
- Pagination state in feed store
|
||||
- Episode list state management
|
||||
- Integration with scroll events
|
||||
|
||||
steps:
|
||||
1. Add pagination state to feed store (currentPage, loadedCount, hasMore)
|
||||
2. Update episode list when new episodes are loaded
|
||||
3. Manage loading state for pagination
|
||||
4. Handle empty episode list case
|
||||
5. Test pagination state transitions
|
||||
|
||||
tests:
|
||||
- Unit: Test pagination state updates
|
||||
- Integration: Test state transitions with scroll
|
||||
- Edge case: Test with no episodes in feed
|
||||
|
||||
acceptance_criteria:
|
||||
- Pagination state accurately tracks loaded episodes
|
||||
- Episode list updates correctly with new episodes
|
||||
- Loading state properly managed
|
||||
|
||||
validation:
|
||||
- Load episodes and verify state updates
|
||||
- Scroll to bottom and verify pagination triggers
|
||||
- Test with feed having many episodes
|
||||
|
||||
notes:
|
||||
- Use existing feed store from `src/stores/feed.ts`
|
||||
- Add pagination state to Feed interface
|
||||
- Consider loading indicator visibility
|
||||
- Handle rapid scroll events gracefully
|
||||
46
tasks/episode-infinite-scroll/13-load-more-indicator.md
Normal file
46
tasks/episode-infinite-scroll/13-load-more-indicator.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 13. Add Loading Indicator for Pagination
|
||||
|
||||
meta:
|
||||
id: episode-infinite-scroll-13
|
||||
feature: episode-infinite-scroll
|
||||
priority: P3
|
||||
depends_on: [episode-infinite-scroll-12]
|
||||
tags: [ui, feedback, loading]
|
||||
|
||||
objective:
|
||||
- Display loading indicator when fetching more episodes
|
||||
- Show loading state in episodes panel
|
||||
- Hide indicator when pagination complete
|
||||
|
||||
deliverables:
|
||||
- Loading indicator component
|
||||
- Loading state display logic
|
||||
- Integration with pagination events
|
||||
|
||||
steps:
|
||||
1. Add loading state to episodes panel state
|
||||
2. Create loading indicator UI (spinner or text)
|
||||
3. Display indicator when fetching episodes
|
||||
4. Hide indicator when pagination complete
|
||||
5. Test loading state visibility
|
||||
|
||||
tests:
|
||||
- Integration: Test loading indicator during fetch
|
||||
- Visual: Verify loading state doesn't block interaction
|
||||
- UX: Test loading state disappears when done
|
||||
|
||||
acceptance_criteria:
|
||||
- Loading indicator displays during fetch
|
||||
- Indicator is visible but doesn't block scrolling
|
||||
- Indicator disappears when pagination complete
|
||||
|
||||
validation:
|
||||
- Scroll to bottom and watch loading indicator
|
||||
- Verify indicator shows/hides correctly
|
||||
- Test with slow RSS feeds
|
||||
|
||||
notes:
|
||||
- Reuse existing loading indicator pattern from MyShowsPage
|
||||
- Use spinner or "Loading..." text
|
||||
- Position indicator at bottom of scrollbox
|
||||
- Don't block user interaction while loading
|
||||
21
tasks/episode-infinite-scroll/README.md
Normal file
21
tasks/episode-infinite-scroll/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Episode List Infinite Scroll
|
||||
|
||||
Objective: Implement scroll-to-bottom loading for episode lists with MAX_EPISODES_REFRESH limit
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [ ] 10 — Add scroll event listener to episodes panel → `10-episode-list-scroll-handler.md`
|
||||
- [ ] 11 — Implement paginated episode fetching → `11-paginated-episode-loading.md`
|
||||
- [ ] 12 — Manage episode list pagination state → `12-episode-list-state-management.md`
|
||||
- [ ] 13 — Add loading indicator for pagination → `13-load-more-indicator.md`
|
||||
|
||||
Dependencies
|
||||
- 10 -> 11
|
||||
- 11 -> 12
|
||||
- 12 -> 13
|
||||
|
||||
Exit criteria
|
||||
- Episode list automatically loads more episodes when scrolling to bottom
|
||||
- MAX_EPISODES_REFRESH is respected per fetch
|
||||
- Loading state is properly displayed during pagination
|
||||
46
tasks/merged-waveform/06-waveform-audio-analysis.md
Normal file
46
tasks/merged-waveform/06-waveform-audio-analysis.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 06. Implement Audio Waveform Analysis
|
||||
|
||||
meta:
|
||||
id: merged-waveform-06
|
||||
feature: merged-waveform
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [audio, waveform, analysis]
|
||||
|
||||
objective:
|
||||
- Analyze audio data to extract waveform information
|
||||
- Create real-time waveform data from audio streams
|
||||
- Generate waveform data points for visualization
|
||||
|
||||
deliverables:
|
||||
- Audio analysis utility
|
||||
- Waveform data extraction function
|
||||
- Integration with audio backend
|
||||
|
||||
steps:
|
||||
1. Research and select audio waveform analysis library (e.g., `audiowaveform`)
|
||||
2. Create `src/utils/audio-waveform.ts`
|
||||
3. Implement audio data extraction from backend
|
||||
4. Generate waveform data points (amplitude values)
|
||||
5. Add sample rate and duration normalization
|
||||
|
||||
tests:
|
||||
- Unit: Test waveform generation from sample audio
|
||||
- Integration: Test with real audio playback
|
||||
- Performance: Measure waveform generation overhead
|
||||
|
||||
acceptance_criteria:
|
||||
- Waveform data is generated from audio content
|
||||
- Data points represent audio amplitude accurately
|
||||
- Generation works with real-time audio streams
|
||||
|
||||
validation:
|
||||
- Generate waveform from sample MP3 file
|
||||
- Verify amplitude data matches audio peaks
|
||||
- Test with different audio formats
|
||||
|
||||
notes:
|
||||
- Consider using `ffmpeg` or `sox` for offline analysis
|
||||
- For real-time: analyze audio chunks during playback
|
||||
- Waveform resolution: 64-256 data points for TUI display
|
||||
- Normalize amplitude to 0-1 range
|
||||
46
tasks/merged-waveform/07-merged-waveform-component.md
Normal file
46
tasks/merged-waveform/07-merged-waveform-component.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 07. Create Merged Progress-Waveform Component
|
||||
|
||||
meta:
|
||||
id: merged-waveform-07
|
||||
feature: merged-waveform
|
||||
priority: P2
|
||||
depends_on: [merged-waveform-06]
|
||||
tags: [ui, waveform, component]
|
||||
|
||||
objective:
|
||||
- Design and implement a single component that shows progress bar and waveform
|
||||
- Component starts as progress bar, expands to waveform when playing
|
||||
- Provide smooth transitions between states
|
||||
|
||||
deliverables:
|
||||
- MergedWaveform component
|
||||
- State management for progress vs waveform display
|
||||
- Visual styling for progress bar and waveform
|
||||
|
||||
steps:
|
||||
1. Create `src/components/MergedWaveform.tsx`
|
||||
2. Design component state machine (progress bar → waveform)
|
||||
3. Implement progress bar visualization
|
||||
4. Add waveform expansion animation
|
||||
5. Style progress bar and waveform with theme colors
|
||||
|
||||
tests:
|
||||
- Unit: Test component state transitions
|
||||
- Integration: Test component in Player
|
||||
- Visual: Verify smooth expansion animation
|
||||
|
||||
acceptance_criteria:
|
||||
- Component displays progress bar when paused
|
||||
- Component smoothly expands to waveform when playing
|
||||
- Visual styles match theme and existing UI
|
||||
|
||||
validation:
|
||||
- Test with paused and playing states
|
||||
- Verify expansion is smooth and visually appealing
|
||||
- Check theme color integration
|
||||
|
||||
notes:
|
||||
- Use existing Waveform component as base
|
||||
- Add CSS transitions for smooth expansion
|
||||
- Keep component size manageable (fit in progress bar area)
|
||||
- Consider responsive to terminal width changes
|
||||
46
tasks/merged-waveform/08-realtime-waveform-rendering.md
Normal file
46
tasks/merged-waveform/08-realtime-waveform-rendering.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 08. Implement Real-Time Waveform Rendering During Playback
|
||||
|
||||
meta:
|
||||
id: merged-waveform-08
|
||||
feature: merged-waveform
|
||||
priority: P2
|
||||
depends_on: [merged-waveform-07]
|
||||
tags: [audio, realtime, rendering]
|
||||
|
||||
objective:
|
||||
- Update waveform in real-time during audio playback
|
||||
- Highlight waveform based on current playback position
|
||||
- Sync waveform with audio backend position updates
|
||||
|
||||
deliverables:
|
||||
- Real-time waveform update logic
|
||||
- Playback position highlighting
|
||||
- Integration with audio backend position tracking
|
||||
|
||||
steps:
|
||||
1. Subscribe to audio backend position updates
|
||||
2. Update waveform data points based on playback position
|
||||
3. Implement playback position highlighting
|
||||
4. Add animation for progress indicator
|
||||
5. Test synchronization with audio playback
|
||||
|
||||
tests:
|
||||
- Integration: Test waveform sync with audio playback
|
||||
- Performance: Measure real-time update overhead
|
||||
- Visual: Verify progress highlighting matches audio position
|
||||
|
||||
acceptance_criteria:
|
||||
- Waveform updates in real-time during playback
|
||||
- Playback position is accurately highlighted
|
||||
- No lag or desynchronization with audio
|
||||
|
||||
validation:
|
||||
- Play audio and watch waveform update
|
||||
- Verify progress bar matches audio position
|
||||
- Test with different playback speeds
|
||||
|
||||
notes:
|
||||
- Use existing audio position polling in `useAudio.ts`
|
||||
- Update waveform every ~100ms for smooth visuals
|
||||
- Consider reducing waveform resolution during playback for performance
|
||||
- Ensure highlighting doesn't flicker
|
||||
@@ -0,0 +1,46 @@
|
||||
# 09. Optimize Waveform Rendering Performance
|
||||
|
||||
meta:
|
||||
id: merged-waveform-09
|
||||
feature: merged-waveform
|
||||
priority: P3
|
||||
depends_on: [merged-waveform-08]
|
||||
tags: [performance, optimization]
|
||||
|
||||
objective:
|
||||
- Ensure waveform rendering doesn't cause performance issues
|
||||
- Optimize for terminal TUI environment
|
||||
- Minimize CPU and memory usage
|
||||
|
||||
deliverables:
|
||||
- Performance optimizations
|
||||
- Memory management for waveform data
|
||||
- Performance monitoring and testing
|
||||
|
||||
steps:
|
||||
1. Profile waveform rendering performance
|
||||
2. Optimize data point generation and updates
|
||||
3. Implement waveform data caching
|
||||
4. Add performance monitoring
|
||||
5. Test with long audio files
|
||||
|
||||
tests:
|
||||
- Performance: Measure CPU usage during playback
|
||||
- Performance: Measure memory usage over time
|
||||
- Load test: Test with 30+ minute audio files
|
||||
|
||||
acceptance_criteria:
|
||||
- Waveform rendering < 16ms per frame
|
||||
- No memory leaks during extended playback
|
||||
- Smooth playback even with waveform rendering
|
||||
|
||||
validation:
|
||||
- Profile CPU usage during playback
|
||||
- Monitor memory over 30-minute playback session
|
||||
- Test with multiple simultaneous audio files
|
||||
|
||||
notes:
|
||||
- Consider reducing waveform resolution during playback
|
||||
- Cache waveform data to avoid regeneration
|
||||
- Use efficient data structures for waveform points
|
||||
- Test on slower terminals (e.g., tmux)
|
||||
21
tasks/merged-waveform/README.md
Normal file
21
tasks/merged-waveform/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Merged Waveform Progress Bar
|
||||
|
||||
Objective: Create a real-time waveform visualization that expands from a progress bar during playback
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [ ] 06 — Implement audio waveform analysis → `06-waveform-audio-analysis.md`
|
||||
- [ ] 07 — Create merged progress-waveform component → `07-merged-waveform-component.md`
|
||||
- [ ] 08 — Implement real-time waveform rendering during playback → `08-realtime-waveform-rendering.md`
|
||||
- [ ] 09 — Optimize waveform rendering performance → `09-waveform-performance-optimization.md`
|
||||
|
||||
Dependencies
|
||||
- 06 -> 07
|
||||
- 07 -> 08
|
||||
- 08 -> 09
|
||||
|
||||
Exit criteria
|
||||
- Waveform smoothly expands from progress bar during playback
|
||||
- Waveform is highlighted based on current playback position
|
||||
- No performance degradation during playback
|
||||
@@ -1,51 +0,0 @@
|
||||
# 01. Initialize SolidJS OpenTUI Project with Bun
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-01
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: []
|
||||
tags: [project-setup, solidjs, opentui, bun]
|
||||
|
||||
objective:
|
||||
- Initialize a new SolidJS-based OpenTUI project using Bun
|
||||
- Set up project structure with all necessary dependencies
|
||||
- Configure TypeScript and development environment
|
||||
|
||||
deliverables:
|
||||
- `/podcast-tui-app/` directory created
|
||||
- `package.json` with all dependencies
|
||||
- `tsconfig.json` configured for TypeScript
|
||||
- `bunfig.toml` with Bun configuration
|
||||
- `.gitignore` for Git version control
|
||||
- `README.md` with project description
|
||||
|
||||
steps:
|
||||
- Run `bunx create-tui@latest -t solid podcast-tui-app` to initialize the project
|
||||
- Verify project structure is created correctly
|
||||
- Install additional dependencies: `bun add @opentui/solid @opentui/core solid-js zustand`
|
||||
- Install dev dependencies: `bun add -d @opentui/testing @opentui/react @opentui/solid`
|
||||
- Configure TypeScript in `tsconfig.json` with SolidJS and OpenTUI settings
|
||||
- Create `.gitignore` with Node and Bun specific files
|
||||
- Initialize Git repository: `git init`
|
||||
|
||||
tests:
|
||||
- Unit: Verify `create-tui` command works without errors
|
||||
- Integration: Test that application can be started with `bun run src/index.tsx`
|
||||
- Environment: Confirm all dependencies are installed correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- Project directory `podcast-tui-app/` exists
|
||||
- `package.json` contains `@opentui/solid` and `@opentui/core` dependencies
|
||||
- `bun run src/index.tsx` starts the application without errors
|
||||
- TypeScript compilation works with `bun run build`
|
||||
|
||||
validation:
|
||||
- Run `bun run build` to verify TypeScript compilation
|
||||
- Run `bun run src/index.tsx` to start the application
|
||||
- Run `bun pm ls` to verify all dependencies are installed
|
||||
|
||||
notes:
|
||||
- OpenTUI is already installed in the system
|
||||
- Use `-t solid` flag for SolidJS template
|
||||
- All commands should be run from the project root
|
||||
@@ -1,55 +0,0 @@
|
||||
# 02. Create Main App Shell with Tab Navigation
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-02
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [01]
|
||||
tags: [layout, navigation, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create the main application shell with a responsive layout
|
||||
- Implement tab-based navigation system
|
||||
- Set up the root component structure
|
||||
- Configure Flexbox layout for terminal UI
|
||||
|
||||
deliverables:
|
||||
- `src/App.tsx` with main app shell
|
||||
- `src/components/Navigation.tsx` with tab navigation
|
||||
- `src/components/Layout.tsx` with responsive layout
|
||||
- Tab navigation component with 5 tabs: Discover, My Feeds, Search, Player, Settings
|
||||
|
||||
steps:
|
||||
- Create `src/App.tsx` with main component that renders Navigation
|
||||
- Create `src/components/Navigation.tsx` with tab navigation
|
||||
- Use `<box>` with `<scrollbox>` for navigation
|
||||
- Implement tab selection state with `createSignal`
|
||||
- Add keyboard navigation (arrow keys)
|
||||
- Add tab labels: "Discover", "My Feeds", "Search", "Player", "Settings"
|
||||
- Create `src/components/Layout.tsx` with responsive layout
|
||||
- Use Flexbox with `flexDirection="column"`
|
||||
- Create top navigation bar
|
||||
- Create main content area
|
||||
- Handle terminal resizing
|
||||
- Update `src/index.tsx` to render the app
|
||||
|
||||
tests:
|
||||
- Unit: Test Navigation component renders with correct tabs
|
||||
- Integration: Test keyboard navigation moves between tabs
|
||||
- Component: Verify layout adapts to terminal size changes
|
||||
|
||||
acceptance_criteria:
|
||||
- Navigation component displays 5 tabs correctly
|
||||
- Tab selection is visually indicated
|
||||
- Arrow keys navigate between tabs
|
||||
- Layout fits within terminal bounds
|
||||
|
||||
validation:
|
||||
- Run application and verify navigation appears
|
||||
- Press arrow keys to test navigation
|
||||
- Resize terminal and verify layout adapts
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for state management
|
||||
- Follow OpenTUI layout patterns from `layout/REFERENCE.md`
|
||||
- Navigation should be persistent across all screens
|
||||
@@ -1,64 +0,0 @@
|
||||
# 03. Implement Direct File Sync (JSON/XML Import/Export)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-03
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [02]
|
||||
tags: [file-sync, json, xml, import-export, solidjs]
|
||||
|
||||
objective:
|
||||
- Create data models for JSON and XML sync formats
|
||||
- Implement import functionality to load feeds and settings from files
|
||||
- Implement export functionality to save feeds and settings to files
|
||||
- Add file picker UI for selecting files
|
||||
|
||||
deliverables:
|
||||
- `src/types/sync.ts` with sync data models
|
||||
- `src/utils/sync.ts` with import/export functions
|
||||
- `src/components/SyncPanel.tsx` with sync UI
|
||||
- File picker component for file selection
|
||||
|
||||
steps:
|
||||
- Create `src/types/sync.ts` with data models:
|
||||
- `SyncData` interface for JSON format
|
||||
- `SyncDataXML` interface for XML format
|
||||
- Include fields: feeds, sources, settings, preferences
|
||||
- Create `src/utils/sync.ts` with functions:
|
||||
- `exportToJSON(data: SyncData): string`
|
||||
- `importFromJSON(json: string): SyncData`
|
||||
- `exportToXML(data: SyncDataXML): string`
|
||||
- `importFromXML(xml: string): SyncDataXML`
|
||||
- Handle validation and error checking
|
||||
- Create `src/components/SyncPanel.tsx` with:
|
||||
- Import button
|
||||
- Export button
|
||||
- File picker UI using `<input>` component
|
||||
- Sync status indicator
|
||||
- Add sync functionality to Settings screen
|
||||
|
||||
tests:
|
||||
- Unit: Test JSON import/export with sample data
|
||||
- Unit: Test XML import/export with sample data
|
||||
- Integration: Test file picker selects correct files
|
||||
- Integration: Test sync panel buttons work correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- Export creates valid JSON file with all data
|
||||
- Export creates valid XML file with all data
|
||||
- Import loads data from JSON file
|
||||
- Import loads data from XML file
|
||||
- File picker allows selecting files from disk
|
||||
|
||||
validation:
|
||||
- Run `bun run src/index.tsx`
|
||||
- Go to Settings > Sync
|
||||
- Click Export, verify file created
|
||||
- Click Import, select file, verify data loaded
|
||||
- Test with both JSON and XML formats
|
||||
|
||||
notes:
|
||||
- JSON format: Simple, human-readable
|
||||
- XML format: More structured, better for complex data
|
||||
- Use `FileReader` API for file operations
|
||||
- Handle file not found and invalid format errors
|
||||
@@ -1,78 +0,0 @@
|
||||
# 04. Build Optional Authentication System
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-04
|
||||
feature: podcast-tui-app
|
||||
priority: P2
|
||||
depends_on: [03]
|
||||
tags: [authentication, optional, solidjs, security]
|
||||
|
||||
objective:
|
||||
- Create authentication state management (disabled by default)
|
||||
- Build simple login screen with email/password
|
||||
- Implement 8-character code validation flow
|
||||
- Add OAuth placeholder screens
|
||||
- Create sync-only user profile
|
||||
|
||||
deliverables:
|
||||
- `src/stores/auth.ts` with authentication state store
|
||||
- `src/components/LoginScreen.tsx` with login form
|
||||
- `src/components/CodeValidation.tsx` with 8-character code input
|
||||
- `src/components/OAuthPlaceholder.tsx` with OAuth info
|
||||
- `src/components/SyncProfile.tsx` with sync-only profile
|
||||
|
||||
steps:
|
||||
- Create `src/stores/auth.ts` with Zustand store:
|
||||
- `user` state (initially null)
|
||||
- `isAuthenticated` state (initially false)
|
||||
- `login()` function
|
||||
- `logout()` function
|
||||
- `validateCode()` function
|
||||
- Create `src/components/LoginScreen.tsx`:
|
||||
- Email input field
|
||||
- Password input field
|
||||
- Login button
|
||||
- Link to code validation flow
|
||||
- Link to OAuth placeholder
|
||||
- Create `src/components/CodeValidation.tsx`:
|
||||
- 8-character code input
|
||||
- Validation logic (alphanumeric)
|
||||
- Submit button
|
||||
- Error message display
|
||||
- Create `src/components/OAuthPlaceholder.tsx`:
|
||||
- Display OAuth information
|
||||
- Explain terminal limitations
|
||||
- Link to browser redirect flow
|
||||
- Create `src/components/SyncProfile.tsx`:
|
||||
- User profile display
|
||||
- Sync status indicator
|
||||
- Profile management options
|
||||
- Add auth screens to Navigation (hidden by default)
|
||||
|
||||
tests:
|
||||
- Unit: Test authentication state management
|
||||
- Unit: Test code validation logic
|
||||
- Integration: Test login flow completes
|
||||
- Integration: Test logout clears state
|
||||
|
||||
acceptance_criteria:
|
||||
- Authentication is disabled by default (isAuthenticated = false)
|
||||
- Login screen accepts email and password
|
||||
- Code validation accepts 8-character codes
|
||||
- OAuth placeholder displays limitations
|
||||
- Sync profile shows user info
|
||||
- Login state persists across sessions
|
||||
|
||||
validation:
|
||||
- Run application and verify login screen is accessible
|
||||
- Try to log in with valid credentials
|
||||
- Try to log in with invalid credentials
|
||||
- Test code validation with valid/invalid codes
|
||||
- Verify authentication state persists
|
||||
|
||||
notes:
|
||||
- Authentication is optional and disabled by default
|
||||
- Focus on file sync, not user accounts
|
||||
- Use simple validation (no real backend)
|
||||
- Store authentication state in localStorage
|
||||
- OAuth not feasible in terminal, document limitation
|
||||
@@ -1,58 +0,0 @@
|
||||
# 05. Create Feed Data Models and Types
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-05
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [04]
|
||||
tags: [types, data-models, solidjs, typescript]
|
||||
|
||||
objective:
|
||||
- Define TypeScript interfaces for all podcast-related data types
|
||||
- Create models for feeds, episodes, sources, and user preferences
|
||||
- Set up type definitions for sync functionality
|
||||
|
||||
deliverables:
|
||||
- `src/types/podcast.ts` with all data models
|
||||
- `src/types/episode.ts` with episode-specific types
|
||||
- `src/types/source.ts` with podcast source types
|
||||
- `src/types/preference.ts` with user preference types
|
||||
|
||||
steps:
|
||||
- Create `src/types/podcast.ts` with core types:
|
||||
- `Podcast` interface (id, title, description, coverUrl, feedUrl, lastUpdated)
|
||||
- `Episode` interface (id, title, description, audioUrl, duration, pubDate, episodeNumber)
|
||||
- `Feed` interface (id, podcast, episodes[], isPublic, sourceId)
|
||||
- `FeedItem` interface (represents a single episode in a feed)
|
||||
- Create `src/types/episode.ts` with episode types:
|
||||
- `Episode` interface
|
||||
- `EpisodeStatus` enum (playing, paused, completed)
|
||||
- `Progress` interface (episodeId, position, duration)
|
||||
- Create `src/types/source.ts` with source types:
|
||||
- `PodcastSource` interface (id, name, baseUrl, type, apiKey)
|
||||
- `SourceType` enum (rss, api, custom)
|
||||
- `SearchQuery` interface (query, sourceIds, filters)
|
||||
- Create `src/types/preference.ts` with preference types:
|
||||
- `UserPreference` interface (theme, fontSize, playbackSpeed, autoDownload)
|
||||
- `SyncPreference` interface (autoSync, backupInterval, syncMethod)
|
||||
- Add type exports in `src/index.ts`
|
||||
|
||||
tests:
|
||||
- Unit: Verify all interfaces compile correctly
|
||||
- Unit: Test enum values are correct
|
||||
- Integration: Test type definitions match expected data structures
|
||||
|
||||
acceptance_criteria:
|
||||
- All TypeScript interfaces compile without errors
|
||||
- Types are exported for use across the application
|
||||
- Type definitions cover all podcast-related data
|
||||
|
||||
validation:
|
||||
- Run `bun run build` to verify TypeScript compilation
|
||||
- Check `src/types/` directory contains all required files
|
||||
|
||||
notes:
|
||||
- Use strict TypeScript mode
|
||||
- Include JSDoc comments for complex types
|
||||
- Keep types simple and focused
|
||||
- Ensure types are compatible with sync JSON/XML formats
|
||||
@@ -1,63 +0,0 @@
|
||||
# 06. Build Feed List Component (Public/Private Feeds)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-06
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [05]
|
||||
tags: [feed-list, components, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create a scrollable feed list component
|
||||
- Display public and private feeds
|
||||
- Implement feed selection and display
|
||||
- Add reverse chronological ordering
|
||||
|
||||
deliverables:
|
||||
- `src/components/FeedList.tsx` with feed list component
|
||||
- `src/components/FeedItem.tsx` with individual feed item
|
||||
- `src/components/FeedFilter.tsx` with public/private toggle
|
||||
|
||||
steps:
|
||||
- Create `src/components/FeedList.tsx`:
|
||||
- Use `<scrollbox>` for scrollable list
|
||||
- Accept feeds array as prop
|
||||
- Implement feed rendering with `createSignal` for selection
|
||||
- Add keyboard navigation (arrow keys, enter)
|
||||
- Display feed title, description, episode count
|
||||
- Create `src/components/FeedItem.tsx`:
|
||||
- Display feed information
|
||||
- Show public/private indicator
|
||||
- Highlight selected feed
|
||||
- Add hover effects
|
||||
- Create `src/components/FeedFilter.tsx`:
|
||||
- Toggle button for public/private feeds
|
||||
- Filter logic implementation
|
||||
- Update parent FeedList when filtered
|
||||
- Add feed list to "My Feeds" navigation tab
|
||||
|
||||
tests:
|
||||
- Unit: Test FeedList renders with feeds
|
||||
- Unit: Test FeedItem displays correctly
|
||||
- Integration: Test public/private filtering
|
||||
- Integration: Test keyboard navigation in feed list
|
||||
|
||||
acceptance_criteria:
|
||||
- Feed list displays all feeds correctly
|
||||
- Public/private toggle filters feeds
|
||||
- Feed selection is visually indicated
|
||||
- Keyboard navigation works (arrow keys, enter)
|
||||
- List scrolls properly when many feeds
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "My Feeds"
|
||||
- Add some feeds and verify they appear
|
||||
- Test public/private toggle
|
||||
- Use arrow keys to navigate feeds
|
||||
- Scroll list with many feeds
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for selection state
|
||||
- Follow OpenTUI component patterns from `components/REFERENCE.md`
|
||||
- Feed list should be scrollable with many items
|
||||
- Use Flexbox for layout
|
||||
@@ -1,68 +0,0 @@
|
||||
# 07. Implement Multi-Source Search Interface
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-07
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [06]
|
||||
tags: [search, multi-source, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create search input component
|
||||
- Implement multi-source search functionality
|
||||
- Display search results with sources
|
||||
- Add search history with persistent storage
|
||||
|
||||
deliverables:
|
||||
- `src/components/SearchBar.tsx` with search input
|
||||
- `src/components/SearchResults.tsx` with results display
|
||||
- `src/components/SearchHistory.tsx` with history list
|
||||
- `src/utils/search.ts` with search logic
|
||||
|
||||
steps:
|
||||
- Create `src/components/SearchBar.tsx`:
|
||||
- Search input field using `<input>` component
|
||||
- Search button
|
||||
- Clear history button
|
||||
- Enter key handler
|
||||
- Create `src/utils/search.ts`:
|
||||
- `searchPodcasts(query: string, sourceIds: string[]): Promise<Podcast[]>`
|
||||
- `searchEpisodes(query: string, feedId: string): Promise<Episode[]>`
|
||||
- Handle multiple sources
|
||||
- Cache search results
|
||||
- Create `src/components/SearchResults.tsx`:
|
||||
- Display search results with source indicators
|
||||
- Show podcast/episode info
|
||||
- Add click to add to feeds
|
||||
- Keyboard navigation through results
|
||||
- Create `src/components/SearchHistory.tsx`:
|
||||
- Display recent search queries
|
||||
- Click to re-run search
|
||||
- Delete individual history items
|
||||
- Persist to localStorage
|
||||
|
||||
tests:
|
||||
- Unit: Test search logic returns correct results
|
||||
- Unit: Test search history persistence
|
||||
- Integration: Test search bar accepts input
|
||||
- Integration: Test results display correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- Search bar accepts and processes queries
|
||||
- Multi-source search works across all enabled sources
|
||||
- Search results display with source information
|
||||
- Search history persists across sessions
|
||||
- Keyboard navigation works in results
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Search"
|
||||
- Type a query and press Enter
|
||||
- Verify results appear
|
||||
- Click a result to add to feed
|
||||
- Restart app and verify history persists
|
||||
|
||||
notes:
|
||||
- Use localStorage for search history
|
||||
- Implement basic caching to avoid repeated searches
|
||||
- Handle empty results gracefully
|
||||
- Add loading state during search
|
||||
@@ -1,63 +0,0 @@
|
||||
# 08. Build Discover Feed with Popular Shows
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-08
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [07]
|
||||
tags: [discover, popular-shows, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create popular shows data structure
|
||||
- Build discover page component
|
||||
- Display trending shows with categories
|
||||
- Implement category filtering
|
||||
|
||||
deliverables:
|
||||
- `src/data/popular-shows.ts` with trending shows data
|
||||
- `src/components/DiscoverPage.tsx` with discover UI
|
||||
- `src/components/CategoryFilter.tsx` with category buttons
|
||||
|
||||
steps:
|
||||
- Create `src/data/popular-shows.ts`:
|
||||
- Array of popular podcasts with metadata
|
||||
- Categories: Technology, Business, Science, Entertainment
|
||||
- Reverse chronological ordering (newest first)
|
||||
- Include feed URLs and descriptions
|
||||
- Create `src/components/DiscoverPage.tsx`:
|
||||
- Title header
|
||||
- Category filter buttons
|
||||
- Grid/list display of popular shows
|
||||
- Show details on selection
|
||||
- Add to feed button
|
||||
- Create `src/components/CategoryFilter.tsx`:
|
||||
- Category button group
|
||||
- Active category highlighting
|
||||
- Filter logic implementation
|
||||
- Add discover page to "Discover" navigation tab
|
||||
|
||||
tests:
|
||||
- Unit: Test popular shows data structure
|
||||
- Unit: Test category filtering
|
||||
- Integration: Test discover page displays correctly
|
||||
- Integration: Test add to feed functionality
|
||||
|
||||
acceptance_criteria:
|
||||
- Discover page displays popular shows
|
||||
- Category filtering works correctly
|
||||
- Shows are ordered reverse chronologically
|
||||
- Clicking a show shows details
|
||||
- Add to feed button works
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Discover"
|
||||
- Verify popular shows appear
|
||||
- Click different categories
|
||||
- Click a show and verify details
|
||||
- Try add to feed
|
||||
|
||||
notes:
|
||||
- Popular shows data can be static or fetched from sources
|
||||
- If sources don't provide trending, use curated list
|
||||
- Categories help users find shows by topic
|
||||
- Use Flexbox for category filter layout
|
||||
@@ -1,70 +0,0 @@
|
||||
# 09. Create Player UI with Waveform Visualization
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-09
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [08]
|
||||
tags: [player, waveform, visualization, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create player UI layout
|
||||
- Implement playback controls (play/pause, skip, progress)
|
||||
- Build ASCII waveform visualization
|
||||
- Add progress tracking and seek functionality
|
||||
|
||||
deliverables:
|
||||
- `src/components/Player.tsx` with player UI
|
||||
- `src/components/PlaybackControls.tsx` with controls
|
||||
- `src/components/Waveform.tsx` with ASCII waveform
|
||||
- `src/utils/waveform.ts` with visualization logic
|
||||
|
||||
steps:
|
||||
- Create `src/components/Player.tsx`:
|
||||
- Player header with episode info
|
||||
- Progress bar with seek functionality
|
||||
- Waveform visualization area
|
||||
- Playback controls
|
||||
- Create `src/components/PlaybackControls.tsx`:
|
||||
- Play/Pause button
|
||||
- Previous/Next episode buttons
|
||||
- Volume control
|
||||
- Speed control
|
||||
- Keyboard shortcuts (space, arrows)
|
||||
- Create `src/components/Waveform.tsx`:
|
||||
- ASCII waveform visualization
|
||||
- Click to seek
|
||||
- Color-coded for played/paused
|
||||
- Use frame buffer for drawing
|
||||
- Create `src/utils/waveform.ts`:
|
||||
- Generate waveform data from audio
|
||||
- Convert to ASCII characters
|
||||
- Handle audio duration and position
|
||||
- Add player to "Player" navigation tab
|
||||
|
||||
tests:
|
||||
- Unit: Test waveform generation
|
||||
- Unit: Test playback controls
|
||||
- Integration: Test player UI displays correctly
|
||||
- Integration: Test keyboard shortcuts work
|
||||
|
||||
acceptance_criteria:
|
||||
- Player UI displays episode information
|
||||
- Playback controls work (play/pause, skip)
|
||||
- Waveform visualization shows audio waveform
|
||||
- Progress bar updates during playback
|
||||
- Clicking waveform seeks to position
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Player"
|
||||
- Select an episode to play
|
||||
- Test playback controls
|
||||
- Verify waveform visualization
|
||||
- Test seeking by clicking waveform
|
||||
- Test keyboard shortcuts
|
||||
|
||||
notes:
|
||||
- ASCII waveform: Use `#` for peaks, `.` for valleys
|
||||
- Audio integration: Trigger system player or use Web Audio API
|
||||
- Waveform data needs to be cached for performance
|
||||
- Use SolidJS `useTimeline` for animation
|
||||
@@ -1,70 +0,0 @@
|
||||
# 10. Build Settings Screen and Preferences
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-10
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [09]
|
||||
tags: [settings, preferences, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create settings screen component
|
||||
- Add source management UI
|
||||
- Build user preferences panel
|
||||
- Implement data persistence
|
||||
|
||||
deliverables:
|
||||
- `src/components/SettingsScreen.tsx` with settings UI
|
||||
- `src/components/SourceManager.tsx` with source management
|
||||
- `src/components/PreferencesPanel.tsx` with user preferences
|
||||
- `src/utils/persistence.ts` with localStorage utilities
|
||||
|
||||
steps:
|
||||
- Create `src/components/SettingsScreen.tsx`:
|
||||
- Settings menu with sections
|
||||
- Navigation between settings sections
|
||||
- Save/Cancel buttons
|
||||
- Create `src/components/SourceManager.tsx`:
|
||||
- List of enabled sources
|
||||
- Add source button
|
||||
- Remove source button
|
||||
- Enable/disable toggle
|
||||
- Create `src/components/PreferencesPanel.tsx`:
|
||||
- Theme selection (light/dark)
|
||||
- Font size control
|
||||
- Playback speed control
|
||||
- Auto-download settings
|
||||
- Create `src/utils/persistence.ts`:
|
||||
- `savePreference(key, value)`
|
||||
- `loadPreference(key)`
|
||||
- `saveFeeds(feeds)`
|
||||
- `loadFeeds()`
|
||||
- `saveSettings(settings)`
|
||||
- `loadSettings()`
|
||||
- Add settings screen to "Settings" navigation tab
|
||||
|
||||
tests:
|
||||
- Unit: Test persistence functions
|
||||
- Unit: Test source management
|
||||
- Integration: Test settings screen navigation
|
||||
- Integration: Test preferences save/load
|
||||
|
||||
acceptance_criteria:
|
||||
- Settings screen displays all sections
|
||||
- Source management adds/removes sources
|
||||
- Preferences save correctly
|
||||
- Data persists across sessions
|
||||
- Settings screen is accessible
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Settings"
|
||||
- Test source management
|
||||
- Change preferences and verify save
|
||||
- Restart app and verify preferences persist
|
||||
|
||||
notes:
|
||||
- Use localStorage for simple persistence
|
||||
- Settings are application-level, not user-specific
|
||||
- Source management requires API keys if needed
|
||||
- Preferences are per-user
|
||||
- Add error handling for persistence failures
|
||||
@@ -1,68 +0,0 @@
|
||||
# 11. Create Global State Store and Data Layer
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-11
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [10]
|
||||
tags: [state-management, global-store, signals, solidjs]
|
||||
|
||||
objective:
|
||||
- Create global state store using Signals
|
||||
- Implement data fetching and caching
|
||||
- Build file-based storage for sync
|
||||
- Connect all components to shared state
|
||||
|
||||
deliverables:
|
||||
- `src/stores/appStore.ts` with global state store
|
||||
- `src/stores/feedStore.ts` with feed state
|
||||
- `src/stores/playerStore.ts` with player state
|
||||
- `src/stores/searchStore.ts` with search state
|
||||
- `src/utils/storage.ts` with file-based storage
|
||||
|
||||
steps:
|
||||
- Create `src/stores/appStore.ts`:
|
||||
- Use SolidJS signals for global state
|
||||
- Store application state: currentTab, isAuthEnabled, settings
|
||||
- Provide state to all child components
|
||||
- Create `src/stores/feedStore.ts`:
|
||||
- Signals for feeds array
|
||||
- Signals for selectedFeed
|
||||
- Methods: addFeed, removeFeed, updateFeed
|
||||
- Create `src/stores/playerStore.ts`:
|
||||
- Signals for currentEpisode
|
||||
- Signals for playbackState
|
||||
- Methods: play, pause, seek, setSpeed
|
||||
- Create `src/stores/searchStore.ts`:
|
||||
- Signals for searchResults
|
||||
- Signals for searchHistory
|
||||
- Methods: search, addToHistory, clearHistory
|
||||
- Create `src/utils/storage.ts`:
|
||||
- `saveToLocal()`
|
||||
- `loadFromLocal()`
|
||||
- File-based sync for feeds and settings
|
||||
|
||||
tests:
|
||||
- Unit: Test store methods update signals correctly
|
||||
- Unit: Test storage functions
|
||||
- Integration: Test state persists across components
|
||||
- Integration: Test data sync with file storage
|
||||
|
||||
acceptance_criteria:
|
||||
- Global state store manages all app state
|
||||
- Store methods update signals correctly
|
||||
- State persists across component re-renders
|
||||
- File-based storage works for sync
|
||||
|
||||
validation:
|
||||
- Run application and verify state is initialized
|
||||
- Modify state and verify UI updates
|
||||
- Restart app and verify state persistence
|
||||
- Test sync functionality
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for reactivity
|
||||
- Store should be singleton pattern
|
||||
- Use Zustand if complex state management needed
|
||||
- Keep store simple and focused
|
||||
- File-based storage for sync with JSON/XML
|
||||
@@ -1,68 +0,0 @@
|
||||
# 12. Set Up Testing Framework and Write Tests
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-12
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [11]
|
||||
tags: [testing, snapshot-testing, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Set up OpenTUI testing framework
|
||||
- Write component tests for all major components
|
||||
- Add keyboard interaction tests
|
||||
- Implement error handling tests
|
||||
|
||||
deliverables:
|
||||
- `tests/` directory with test files
|
||||
- `tests/components/` with component tests
|
||||
- `tests/integration/` with integration tests
|
||||
- `tests/utils/` with utility tests
|
||||
- Test coverage for all components
|
||||
|
||||
steps:
|
||||
- Set up OpenTUI testing framework:
|
||||
- Install testing dependencies
|
||||
- Configure test runner
|
||||
- Set up snapshot testing
|
||||
- Write component tests:
|
||||
- `tests/components/Navigation.test.tsx`
|
||||
- `tests/components/FeedList.test.tsx`
|
||||
- `tests/components/SearchBar.test.tsx`
|
||||
- `tests/components/Player.test.tsx`
|
||||
- `tests/components/SettingsScreen.test.tsx`
|
||||
- Write integration tests:
|
||||
- `tests/integration/navigation.test.tsx`
|
||||
- `tests/integration/feed-management.test.tsx`
|
||||
- `tests/integration/search.test.tsx`
|
||||
- Write utility tests:
|
||||
- `tests/utils/sync.test.ts`
|
||||
- `tests/utils/search.test.ts`
|
||||
- `tests/utils/storage.test.ts`
|
||||
- Add error handling tests:
|
||||
- Test invalid file imports
|
||||
- Test network errors
|
||||
- Test malformed data
|
||||
|
||||
tests:
|
||||
- Unit: Run all unit tests
|
||||
- Integration: Run all integration tests
|
||||
- Coverage: Verify all components tested
|
||||
|
||||
acceptance_criteria:
|
||||
- All tests pass
|
||||
- Test coverage > 80%
|
||||
- Snapshot tests match expected output
|
||||
- Error handling tests verify proper behavior
|
||||
|
||||
validation:
|
||||
- Run `bun test` to execute all tests
|
||||
- Run `bun test --coverage` for coverage report
|
||||
- Fix any failing tests
|
||||
|
||||
notes:
|
||||
- Use OpenTUI's testing framework for snapshot testing
|
||||
- Test keyboard interactions separately
|
||||
- Mock external dependencies (API calls)
|
||||
- Keep tests fast and focused
|
||||
- Add CI/CD integration for automated testing
|
||||
@@ -1,63 +0,0 @@
|
||||
# 13. Set Up TypeScript Configuration and Build System
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-13
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [01]
|
||||
tags: [typescript, build-system, configuration, solidjs]
|
||||
|
||||
objective:
|
||||
- Configure TypeScript for SolidJS and OpenTUI
|
||||
- Set up build system for production
|
||||
- Configure bundler for optimal output
|
||||
- Add development and production scripts
|
||||
|
||||
deliverables:
|
||||
- `tsconfig.json` with TypeScript configuration
|
||||
- `bunfig.toml` with Bun configuration
|
||||
- `package.json` with build scripts
|
||||
- `.bunfig.toml` with build settings
|
||||
|
||||
steps:
|
||||
- Configure TypeScript in `tsconfig.json`:
|
||||
- Set target to ES2020
|
||||
- Configure paths for SolidJS
|
||||
- Add OpenTUI type definitions
|
||||
- Enable strict mode
|
||||
- Configure module resolution
|
||||
- Configure Bun in `bunfig.toml`:
|
||||
- Set up dependencies
|
||||
- Configure build output
|
||||
- Add optimization flags
|
||||
- Update `package.json`:
|
||||
- Add build script: `bun run build`
|
||||
- Add dev script: `bun run dev`
|
||||
- Add test script: `bun run test`
|
||||
- Add lint script: `bun run lint`
|
||||
- Configure bundler for production:
|
||||
- Optimize bundle size
|
||||
- Minify output
|
||||
- Tree-shake unused code
|
||||
|
||||
tests:
|
||||
- Unit: Verify TypeScript configuration
|
||||
- Integration: Test build process
|
||||
- Integration: Test dev script
|
||||
|
||||
acceptance_criteria:
|
||||
- TypeScript compiles without errors
|
||||
- Build script creates optimized bundle
|
||||
- Dev script runs development server
|
||||
- All scripts work correctly
|
||||
|
||||
validation:
|
||||
- Run `bun run build` to verify build
|
||||
- Run `bun run dev` to verify dev server
|
||||
- Check bundle size is reasonable
|
||||
|
||||
notes:
|
||||
- Use `bun build` for production builds
|
||||
- Enable source maps for debugging
|
||||
- Configure TypeScript to match OpenTUI requirements
|
||||
- Add path aliases for cleaner imports
|
||||
@@ -1,70 +0,0 @@
|
||||
# 14. Create Project Directory Structure and Dependencies
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-14
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [01]
|
||||
tags: [project-structure, organization, solidjs]
|
||||
|
||||
objective:
|
||||
- Create organized project directory structure
|
||||
- Set up all necessary folders and files
|
||||
- Install and configure all dependencies
|
||||
- Create placeholder files for future implementation
|
||||
|
||||
deliverables:
|
||||
- `src/` directory with organized structure
|
||||
- `src/components/` with component folders
|
||||
- `src/stores/` with store files
|
||||
- `src/types/` with type definitions
|
||||
- `src/utils/` with utility functions
|
||||
- `src/data/` with static data
|
||||
- `tests/` with test structure
|
||||
- `public/` for static assets
|
||||
- `docs/` for documentation
|
||||
|
||||
steps:
|
||||
- Create directory structure:
|
||||
- `src/components/` (all components)
|
||||
- `src/stores/` (state management)
|
||||
- `src/types/` (TypeScript types)
|
||||
- `src/utils/` (utility functions)
|
||||
- `src/data/` (static data)
|
||||
- `src/hooks/` (custom hooks)
|
||||
- `src/api/` (API clients)
|
||||
- `tests/` (test files)
|
||||
- `public/` (static assets)
|
||||
- `docs/` (documentation)
|
||||
- Create placeholder files:
|
||||
- `src/index.tsx` (main entry)
|
||||
- `src/App.tsx` (app shell)
|
||||
- `src/main.ts` (Bun entry)
|
||||
- Install dependencies:
|
||||
- Core: `@opentui/solid`, `@opentui/core`, `solid-js`
|
||||
- State: `zustand`
|
||||
- Testing: `@opentui/testing`
|
||||
- Utilities: `date-fns`, `uuid`
|
||||
- Optional: `react`, `@opentui/react` (for testing)
|
||||
|
||||
tests:
|
||||
- Unit: Verify directory structure exists
|
||||
- Integration: Verify all dependencies installed
|
||||
- Component: Verify placeholder files exist
|
||||
|
||||
acceptance_criteria:
|
||||
- All directories created
|
||||
- All placeholder files exist
|
||||
- All dependencies installed
|
||||
- Project structure follows conventions
|
||||
|
||||
validation:
|
||||
- Run `ls -R src/` to verify structure
|
||||
- Run `bun pm ls` to verify dependencies
|
||||
- Check all placeholder files exist
|
||||
|
||||
notes:
|
||||
- Follow OpenTUI project structure conventions
|
||||
- Keep structure organized and scalable
|
||||
- Add comments to placeholder files
|
||||
- Consider adding `eslint`, `prettier` for code quality
|
||||
@@ -1,63 +0,0 @@
|
||||
# 15. Build Responsive Layout System (Flexbox)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-15
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [14]
|
||||
tags: [layout, flexbox, responsive, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create reusable Flexbox layout components
|
||||
- Handle terminal resizing gracefully
|
||||
- Ensure responsive design across different terminal sizes
|
||||
- Build layout patterns for common UI patterns
|
||||
|
||||
deliverables:
|
||||
- `src/components/BoxLayout.tsx` with Flexbox container
|
||||
- `src/components/Row.tsx` with horizontal layout
|
||||
- `src/components/Column.tsx` with vertical layout
|
||||
- `src/components/ResponsiveContainer.tsx` with resizing logic
|
||||
|
||||
steps:
|
||||
- Create `src/components/BoxLayout.tsx`:
|
||||
- Generic Flexbox container
|
||||
- Props: flexDirection, justifyContent, alignItems, gap
|
||||
- Use OpenTUI layout patterns
|
||||
- Create `src/components/Row.tsx`:
|
||||
- Horizontal layout (flexDirection="row")
|
||||
- Props for spacing and alignment
|
||||
- Handle overflow
|
||||
- Create `src/components/Column.tsx`:
|
||||
- Vertical layout (flexDirection="column")
|
||||
- Props for spacing and alignment
|
||||
- Scrollable content area
|
||||
- Create `src/components/ResponsiveContainer.tsx`:
|
||||
- Listen to terminal resize events
|
||||
- Adjust layout based on width/height
|
||||
- Handle different screen sizes
|
||||
- Add usage examples and documentation
|
||||
|
||||
tests:
|
||||
- Unit: Test BoxLayout with different props
|
||||
- Unit: Test Row and Column layouts
|
||||
- Integration: Test responsive behavior on resize
|
||||
- Integration: Test layouts fit within terminal bounds
|
||||
|
||||
acceptance_criteria:
|
||||
- BoxLayout renders with correct Flexbox properties
|
||||
- Row and Column layouts work correctly
|
||||
- ResponsiveContainer adapts to terminal resize
|
||||
- All layouts fit within terminal bounds
|
||||
|
||||
validation:
|
||||
- Run application and test layouts
|
||||
- Resize terminal and verify responsive behavior
|
||||
- Test with different terminal sizes
|
||||
- Check layouts don't overflow
|
||||
|
||||
notes:
|
||||
- Use OpenTUI Flexbox patterns from `layout/REFERENCE.md`
|
||||
- Terminal dimensions: width (columns) x height (rows)
|
||||
- Handle edge cases (very small screens)
|
||||
- Add comments explaining layout decisions
|
||||
@@ -1,60 +0,0 @@
|
||||
# 16. Implement Tab Navigation Component
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-16
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [15]
|
||||
tags: [navigation, tabs, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create reusable tab navigation component
|
||||
- Implement tab selection state
|
||||
- Add keyboard navigation for tabs
|
||||
- Handle active tab highlighting
|
||||
|
||||
deliverables:
|
||||
- `src/components/TabNavigation.tsx` with tab navigation
|
||||
- `src/components/Tab.tsx` with individual tab component
|
||||
- `src/hooks/useTabNavigation.ts` with tab logic
|
||||
|
||||
steps:
|
||||
- Create `src/components/TabNavigation.tsx`:
|
||||
- Accept tabs array as prop
|
||||
- Render tab buttons
|
||||
- Manage selected tab state
|
||||
- Update parent component on tab change
|
||||
- Create `src/components/Tab.tsx`:
|
||||
- Individual tab button
|
||||
- Highlight selected tab
|
||||
- Handle click and keyboard events
|
||||
- Show tab icon if needed
|
||||
- Create `src/hooks/useTabNavigation.ts`:
|
||||
- Manage tab selection state
|
||||
- Handle keyboard navigation (arrow keys)
|
||||
- Update parent component
|
||||
- Persist selected tab
|
||||
|
||||
tests:
|
||||
- Unit: Test Tab component renders correctly
|
||||
- Unit: Test tab selection updates state
|
||||
- Integration: Test keyboard navigation
|
||||
- Integration: Test tab persists across renders
|
||||
|
||||
acceptance_criteria:
|
||||
- TabNavigation displays all tabs correctly
|
||||
- Tab selection is visually indicated
|
||||
- Keyboard navigation works (arrow keys, enter)
|
||||
- Active tab persists
|
||||
|
||||
validation:
|
||||
- Run application and verify tabs appear
|
||||
- Click tabs to test selection
|
||||
- Use arrow keys to navigate
|
||||
- Restart app and verify active tab persists
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for tab state
|
||||
- Follow OpenTUI component patterns
|
||||
- Tabs: Discover, My Feeds, Search, Player, Settings
|
||||
- Add keyboard shortcuts documentation
|
||||
@@ -1,69 +0,0 @@
|
||||
# 17. Add Keyboard Shortcuts and Navigation Handling
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-17
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [16]
|
||||
tags: [keyboard, shortcuts, navigation, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Implement global keyboard shortcuts
|
||||
- Add shortcut documentation
|
||||
- Handle keyboard events across components
|
||||
- Prevent conflicts with input fields
|
||||
|
||||
deliverables:
|
||||
- `src/components/KeyboardHandler.tsx` with global shortcuts
|
||||
- `src/components/ShortcutHelp.tsx` with shortcut list
|
||||
- `src/hooks/useKeyboard.ts` with keyboard utilities
|
||||
- `src/config/shortcuts.ts` with shortcut definitions
|
||||
|
||||
steps:
|
||||
- Create `src/config/shortcuts.ts`:
|
||||
- Define all keyboard shortcuts
|
||||
- Map keys to actions
|
||||
- Document each shortcut
|
||||
- Create `src/hooks/useKeyboard.ts`:
|
||||
- Global keyboard event listener
|
||||
- Filter events based on focused element
|
||||
- Handle modifier keys (Ctrl, Shift, Alt)
|
||||
- Prevent default browser behavior
|
||||
- Create `src/components/KeyboardHandler.tsx`:
|
||||
- Wrap application with keyboard handler
|
||||
- Handle escape to close modals
|
||||
- Handle Ctrl+Q to quit
|
||||
- Handle Ctrl+S to save
|
||||
- Create `src/components/ShortcutHelp.tsx`:
|
||||
- Display all shortcuts
|
||||
- Organize by category
|
||||
- Click to copy shortcut
|
||||
|
||||
tests:
|
||||
- Unit: Test keyboard hook handles events
|
||||
- Unit: Test modifier key combinations
|
||||
- Integration: Test shortcuts work globally
|
||||
- Integration: Test shortcuts don't interfere with inputs
|
||||
|
||||
acceptance_criteria:
|
||||
- All shortcuts work as defined
|
||||
- Shortcuts help displays correctly
|
||||
- Shortcuts don't interfere with input fields
|
||||
- Escape closes modals
|
||||
|
||||
validation:
|
||||
- Run application and test each shortcut
|
||||
- Try shortcuts in input fields (shouldn't trigger)
|
||||
- Check ShortcutHelp displays all shortcuts
|
||||
- Test Ctrl+Q quits app
|
||||
|
||||
notes:
|
||||
- Use OpenTUI keyboard patterns from `keyboard/REFERENCE.md`
|
||||
- Common shortcuts:
|
||||
- Ctrl+Q: Quit
|
||||
- Ctrl+S: Save
|
||||
- Escape: Close modal/exit input
|
||||
- Arrow keys: Navigate
|
||||
- Space: Play/Pause
|
||||
- Document shortcuts in README
|
||||
- Test on different terminals
|
||||
@@ -1,65 +0,0 @@
|
||||
# 18. Create Sync Data Models (JSON/XML Formats)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-18
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [17]
|
||||
tags: [data-models, json, xml, sync, typescript]
|
||||
|
||||
objective:
|
||||
- Define TypeScript interfaces for JSON sync format
|
||||
- Define TypeScript interfaces for XML sync format
|
||||
- Ensure compatibility between formats
|
||||
- Add validation logic
|
||||
|
||||
deliverables:
|
||||
- `src/types/sync-json.ts` with JSON sync types
|
||||
- `src/types/sync-xml.ts` with XML sync types
|
||||
- `src/utils/sync-validation.ts` with validation logic
|
||||
- `src/constants/sync-formats.ts` with format definitions
|
||||
|
||||
steps:
|
||||
- Create `src/types/sync-json.ts`:
|
||||
- `SyncData` interface with all required fields
|
||||
- Include feeds, sources, settings, preferences
|
||||
- Add version field for format compatibility
|
||||
- Add timestamp for last sync
|
||||
- Create `src/types/sync-xml.ts`:
|
||||
- `SyncDataXML` interface
|
||||
- XML-compatible type definitions
|
||||
- Root element and child elements
|
||||
- Attributes for metadata
|
||||
- Create `src/utils/sync-validation.ts`:
|
||||
- `validateJSONSync(data: unknown): SyncData`
|
||||
- `validateXMLSync(data: unknown): SyncDataXML`
|
||||
- Field validation functions
|
||||
- Type checking
|
||||
- Create `src/constants/sync-formats.ts`:
|
||||
- JSON format version
|
||||
- XML format version
|
||||
- Supported versions list
|
||||
- Format extensions
|
||||
|
||||
tests:
|
||||
- Unit: Test JSON validation with valid/invalid data
|
||||
- Unit: Test XML validation with valid/invalid data
|
||||
- Integration: Test format compatibility
|
||||
|
||||
acceptance_criteria:
|
||||
- JSON sync types compile without errors
|
||||
- XML sync types compile without errors
|
||||
- Validation rejects invalid data
|
||||
- Format versions are tracked
|
||||
|
||||
validation:
|
||||
- Run `bun run build` to verify TypeScript
|
||||
- Test validation with sample data
|
||||
- Test with invalid data to verify rejection
|
||||
|
||||
notes:
|
||||
- JSON format: Simple, human-readable
|
||||
- XML format: More structured, better for complex data
|
||||
- Include all necessary fields for complete sync
|
||||
- Add comments explaining each field
|
||||
- Ensure backward compatibility
|
||||
@@ -1,72 +0,0 @@
|
||||
# 19. Build Import/Export Functionality
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-19
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [18]
|
||||
tags: [import-export, file-io, sync, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement JSON export functionality
|
||||
- Implement JSON import functionality
|
||||
- Implement XML export functionality
|
||||
- Implement XML import functionality
|
||||
- Handle file operations and errors
|
||||
|
||||
deliverables:
|
||||
- `src/utils/sync.ts` with import/export functions
|
||||
- `src/components/ExportDialog.tsx` with export UI
|
||||
- `src/components/ImportDialog.tsx` with import UI
|
||||
- Error handling components
|
||||
|
||||
steps:
|
||||
- Implement JSON export in `src/utils/sync.ts`:
|
||||
- `exportFeedsToJSON(feeds: Feed[]): string`
|
||||
- `exportSettingsToJSON(settings: Settings): string`
|
||||
- Combine into `exportToJSON(data: SyncData): string`
|
||||
- Implement JSON import in `src/utils/sync.ts`:
|
||||
- `importFeedsFromJSON(json: string): Feed[]`
|
||||
- `importSettingsFromJSON(json: string): Settings`
|
||||
- Combine into `importFromJSON(json: string): SyncData`
|
||||
- Implement XML export in `src/utils/sync.ts`:
|
||||
- `exportToXML(data: SyncDataXML): string`
|
||||
- XML serialization
|
||||
- Implement XML import in `src/utils/sync.ts`:
|
||||
- `importFromXML(xml: string): SyncDataXML`
|
||||
- XML parsing
|
||||
- Create `src/components/ExportDialog.tsx`:
|
||||
- File name input
|
||||
- Export format selection
|
||||
- Export button
|
||||
- Success message
|
||||
- Create `src/components/ImportDialog.tsx`:
|
||||
- File picker
|
||||
- Format detection
|
||||
- Import button
|
||||
- Error message display
|
||||
|
||||
tests:
|
||||
- Unit: Test JSON import/export with sample data
|
||||
- Unit: Test XML import/export with sample data
|
||||
- Unit: Test error handling
|
||||
- Integration: Test file operations
|
||||
|
||||
acceptance_criteria:
|
||||
- Export creates valid files
|
||||
- Import loads data correctly
|
||||
- Errors are handled gracefully
|
||||
- Files can be opened in text editors
|
||||
|
||||
validation:
|
||||
- Run application and test export/import
|
||||
- Open exported files in text editor
|
||||
- Test with different data sizes
|
||||
- Test error cases (invalid files)
|
||||
|
||||
notes:
|
||||
- Use `FileReader` API for file operations
|
||||
- Handle file not found, invalid format, permission errors
|
||||
- Add progress indicator for large files
|
||||
- Support both JSON and XML formats
|
||||
- Ensure data integrity during import
|
||||
@@ -1,61 +0,0 @@
|
||||
# 20. Create File Picker UI for Import
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-20
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [19]
|
||||
tags: [file-picker, input, ui, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create file picker component for selecting import files
|
||||
- Implement file format detection
|
||||
- Display file information
|
||||
- Handle file selection and validation
|
||||
|
||||
deliverables:
|
||||
- `src/components/FilePicker.tsx` with file picker UI
|
||||
- `src/components/FileInfo.tsx` with file details
|
||||
- `src/utils/file-detector.ts` with format detection
|
||||
|
||||
steps:
|
||||
- Create `src/utils/file-detector.ts`:
|
||||
- `detectFormat(file: File): 'json' | 'xml' | 'unknown'`
|
||||
- Read file header
|
||||
- Check file extension
|
||||
- Validate format
|
||||
- Create `src/components/FilePicker.tsx`:
|
||||
- File input using `<input>` component
|
||||
- Accept JSON and XML files
|
||||
- File selection handler
|
||||
- Clear button
|
||||
- Create `src/components/FileInfo.tsx`:
|
||||
- Display file name
|
||||
- Display file size
|
||||
- Display file format
|
||||
- Display last modified date
|
||||
- Add file picker to import dialog
|
||||
|
||||
tests:
|
||||
- Unit: Test format detection
|
||||
- Unit: Test file picker selection
|
||||
- Integration: Test file validation
|
||||
|
||||
acceptance_criteria:
|
||||
- File picker allows selecting files
|
||||
- Format detection works correctly
|
||||
- File information is displayed
|
||||
- Invalid files are rejected
|
||||
|
||||
validation:
|
||||
- Run application and test file picker
|
||||
- Select valid files
|
||||
- Select invalid files
|
||||
- Verify format detection
|
||||
|
||||
notes:
|
||||
- Use OpenTUI `<input>` component for file picker
|
||||
- Accept `.json` and `.xml` extensions
|
||||
- Check file size limit (e.g., 10MB)
|
||||
- Add file type validation
|
||||
- Handle file selection errors
|
||||
@@ -1,60 +0,0 @@
|
||||
# 21. Build Sync Status Indicator
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-21
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [20]
|
||||
tags: [status-indicator, sync, ui, solidjs]
|
||||
|
||||
objective:
|
||||
- Create sync status indicator component
|
||||
- Display sync state (idle, syncing, complete, error)
|
||||
- Show sync progress
|
||||
- Provide sync status in settings
|
||||
|
||||
deliverables:
|
||||
- `src/components/SyncStatus.tsx` with status indicator
|
||||
- `src/components/SyncProgress.tsx` with progress bar
|
||||
- `src/components/SyncError.tsx` with error display
|
||||
|
||||
steps:
|
||||
- Create `src/components/SyncStatus.tsx`:
|
||||
- Display current sync state
|
||||
- Show status icon (spinner, check, error)
|
||||
- Show status message
|
||||
- Auto-update based on state
|
||||
- Create `src/components/SyncProgress.tsx`:
|
||||
- Progress bar visualization
|
||||
- Percentage display
|
||||
- Step indicators
|
||||
- Animation
|
||||
- Create `src/components/SyncError.tsx`:
|
||||
- Error message display
|
||||
- Retry button
|
||||
- Error details (expandable)
|
||||
- Add sync status to settings screen
|
||||
|
||||
tests:
|
||||
- Unit: Test status indicator updates correctly
|
||||
- Unit: Test progress bar visualization
|
||||
- Unit: Test error display
|
||||
|
||||
acceptance_criteria:
|
||||
- Status indicator shows correct state
|
||||
- Progress bar updates during sync
|
||||
- Error message is displayed on errors
|
||||
- Status persists across sync operations
|
||||
|
||||
validation:
|
||||
- Run application and test sync operations
|
||||
- Trigger export/import
|
||||
- Verify status indicator updates
|
||||
- Test error cases
|
||||
|
||||
notes:
|
||||
- Use SolidJS signals for state
|
||||
- Status states: idle, syncing, complete, error
|
||||
- Use ASCII icons for status indicators
|
||||
- Add animation for syncing state
|
||||
- Make status component reusable
|
||||
@@ -1,67 +0,0 @@
|
||||
# 22. Add Backup/Restore Functionality
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-22
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [21]
|
||||
tags: [backup-restore, sync, data-protection, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement backup functionality for all user data
|
||||
- Implement restore functionality
|
||||
- Create scheduled backups
|
||||
- Add backup management UI
|
||||
|
||||
deliverables:
|
||||
- `src/utils/backup.ts` with backup functions
|
||||
- `src/utils/restore.ts` with restore functions
|
||||
- `src/components/BackupManager.tsx` with backup UI
|
||||
- `src/components/ScheduledBackups.tsx` with backup settings
|
||||
|
||||
steps:
|
||||
- Create `src/utils/backup.ts`:
|
||||
- `createBackup(): Promise<string>`
|
||||
- `backupFeeds(feeds: Feed[]): string`
|
||||
- `backupSettings(settings: Settings): string`
|
||||
- Include all user data
|
||||
- Create `src/utils/restore.ts`:
|
||||
- `restoreFromBackup(backupData: string): Promise<void>`
|
||||
- `restoreFeeds(backupData: string): void`
|
||||
- `restoreSettings(backupData: string): void`
|
||||
- Validate backup data
|
||||
- Create `src/components/BackupManager.tsx`:
|
||||
- List of backup files
|
||||
- Restore button
|
||||
- Delete backup button
|
||||
- Create new backup button
|
||||
- Create `src/components/ScheduledBackups.tsx`:
|
||||
- Enable/disable scheduled backups
|
||||
- Backup interval selection
|
||||
- Last backup time display
|
||||
- Manual backup button
|
||||
|
||||
tests:
|
||||
- Unit: Test backup creates valid files
|
||||
- Unit: Test restore loads data correctly
|
||||
- Unit: Test backup validation
|
||||
- Integration: Test backup/restore workflow
|
||||
|
||||
acceptance_criteria:
|
||||
- Backup creates complete backup file
|
||||
- Restore loads all data correctly
|
||||
- Scheduled backups work as configured
|
||||
- Backup files can be managed
|
||||
|
||||
validation:
|
||||
- Run application and create backup
|
||||
- Restore from backup
|
||||
- Test scheduled backups
|
||||
- Verify data integrity
|
||||
|
||||
notes:
|
||||
- Backup file format: JSON with timestamp
|
||||
- Include version info for compatibility
|
||||
- Store backups in `backups/` directory
|
||||
- Add backup encryption option (optional)
|
||||
- Test with large data sets
|
||||
@@ -1,61 +0,0 @@
|
||||
# 23. Create Authentication State (Disabled by Default)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-23
|
||||
feature: podcast-tui-app
|
||||
priority: P2
|
||||
depends_on: [22]
|
||||
tags: [authentication, state, solidjs, security]
|
||||
|
||||
objective:
|
||||
- Create authentication state management
|
||||
- Ensure authentication is disabled by default
|
||||
- Set up user state structure
|
||||
- Implement auth state persistence
|
||||
|
||||
deliverables:
|
||||
- `src/stores/auth.ts` with authentication store
|
||||
- `src/types/auth.ts` with auth types
|
||||
- `src/config/auth.ts` with auth configuration
|
||||
|
||||
steps:
|
||||
- Create `src/types/auth.ts`:
|
||||
- `User` interface (id, email, name, createdAt)
|
||||
- `AuthState` interface (user, isAuthenticated, isLoading)
|
||||
- `AuthError` interface (code, message)
|
||||
- Create `src/config/auth.ts`:
|
||||
- `DEFAULT_AUTH_ENABLED = false`
|
||||
- `AUTH_CONFIG` with settings
|
||||
- `OAUTH_PROVIDERS` with provider info
|
||||
- Create `src/stores/auth.ts`:
|
||||
- `createAuthStore()` with Zustand
|
||||
- `user` signal (initially null)
|
||||
- `isAuthenticated` signal (initially false)
|
||||
- `login()` function (placeholder)
|
||||
- `logout()` function
|
||||
- `validateCode()` function
|
||||
- Persist state to localStorage
|
||||
- Set up auth state in global store
|
||||
|
||||
tests:
|
||||
- Unit: Test auth state initializes correctly
|
||||
- Unit: Test auth is disabled by default
|
||||
- Unit: Test persistence
|
||||
|
||||
acceptance_criteria:
|
||||
- Authentication is disabled by default
|
||||
- Auth store manages state correctly
|
||||
- State persists across sessions
|
||||
- Auth is optional and not required
|
||||
|
||||
validation:
|
||||
- Run application and verify auth is disabled
|
||||
- Check localStorage for auth state
|
||||
- Test login flow (should not work without backend)
|
||||
|
||||
notes:
|
||||
- Authentication is secondary to file sync
|
||||
- No real backend, just UI/UX
|
||||
- Focus on sync features
|
||||
- User can choose to enable auth later
|
||||
- Store auth state in localStorage
|
||||
@@ -1,69 +0,0 @@
|
||||
# 24. Build Simple Login Screen (Email/Password)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-24
|
||||
feature: podcast-tui-app
|
||||
priority: P2
|
||||
depends_on: [23]
|
||||
tags: [login, auth, form, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create login screen component
|
||||
- Implement email input field
|
||||
- Implement password input field
|
||||
- Add login validation and error handling
|
||||
|
||||
deliverables:
|
||||
- `src/components/LoginScreen.tsx` with login form
|
||||
- `src/components/EmailInput.tsx` with email field
|
||||
- `src/components/PasswordInput.tsx` with password field
|
||||
- `src/components/LoginButton.tsx` with submit button
|
||||
|
||||
steps:
|
||||
- Create `src/components/EmailInput.tsx`:
|
||||
- Email input field using `<input>` component
|
||||
- Email validation regex
|
||||
- Error message display
|
||||
- Focus state styling
|
||||
- Create `src/components/PasswordInput.tsx`:
|
||||
- Password input field
|
||||
- Show/hide password toggle
|
||||
- Password validation rules
|
||||
- Error message display
|
||||
- Create `src/components/LoginButton.tsx`:
|
||||
- Submit button
|
||||
- Loading state
|
||||
- Disabled state
|
||||
- Error state
|
||||
- Create `src/components/LoginScreen.tsx`:
|
||||
- Combine inputs and button
|
||||
- Login form validation
|
||||
- Error handling
|
||||
- Link to code validation
|
||||
- Link to OAuth placeholder
|
||||
|
||||
tests:
|
||||
- Unit: Test email validation
|
||||
- Unit: Test password validation
|
||||
- Unit: Test login form submission
|
||||
- Integration: Test login screen displays correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- Login screen accepts email and password
|
||||
- Validation works correctly
|
||||
- Error messages display properly
|
||||
- Form submission handled
|
||||
|
||||
validation:
|
||||
- Run application and navigate to login
|
||||
- Enter valid credentials
|
||||
- Enter invalid credentials
|
||||
- Test error handling
|
||||
|
||||
notes:
|
||||
- Use OpenTUI `<input>` component
|
||||
- Email validation: regex pattern
|
||||
- Password validation: minimum length
|
||||
- No real authentication, just UI
|
||||
- Link to code validation for sync
|
||||
- Link to OAuth placeholder
|
||||
@@ -1,60 +0,0 @@
|
||||
# 25. Implement 8-Character Code Validation Flow
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-25
|
||||
feature: podcast-tui-app
|
||||
priority: P2
|
||||
depends_on: [24]
|
||||
tags: [code-validation, auth, sync, solidjs]
|
||||
|
||||
objective:
|
||||
- Create 8-character code input component
|
||||
- Implement code validation logic
|
||||
- Handle code submission
|
||||
- Show validation results
|
||||
|
||||
deliverables:
|
||||
- `src/components/CodeInput.tsx` with code field
|
||||
- `src/utils/code-validator.ts` with validation logic
|
||||
- `src/components/CodeValidationResult.tsx` with result display
|
||||
|
||||
steps:
|
||||
- Create `src/utils/code-validator.ts`:
|
||||
- `validateCode(code: string): boolean`
|
||||
- Check length (8 characters)
|
||||
- Check format (alphanumeric)
|
||||
- Validate against stored codes
|
||||
- Create `src/components/CodeInput.tsx`:
|
||||
- 8-character code input
|
||||
- Auto-formatting
|
||||
- Clear button
|
||||
- Validation error display
|
||||
- Create `src/components/CodeValidationResult.tsx`:
|
||||
- Success message
|
||||
- Error message
|
||||
- Retry button
|
||||
- Link to alternative auth
|
||||
|
||||
tests:
|
||||
- Unit: Test code validation logic
|
||||
- Unit: Test code input formatting
|
||||
- Unit: Test validation result display
|
||||
|
||||
acceptance_criteria:
|
||||
- Code input accepts 8 characters
|
||||
- Validation checks length and format
|
||||
- Validation results display correctly
|
||||
- Error handling works
|
||||
|
||||
validation:
|
||||
- Run application and test code validation
|
||||
- Enter valid 8-character code
|
||||
- Enter invalid code
|
||||
- Test validation error display
|
||||
|
||||
notes:
|
||||
- Code format: alphanumeric (A-Z, 0-9)
|
||||
- No real backend validation
|
||||
- Store codes in localStorage for testing
|
||||
- Link to OAuth placeholder
|
||||
- Link to email/password login
|
||||
@@ -1,61 +0,0 @@
|
||||
# 26. Add OAuth Placeholder Screens (Document Limitations)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-26
|
||||
feature: podcast-tui-app
|
||||
priority: P2
|
||||
depends_on: [25]
|
||||
tags: [oauth, documentation, placeholders, solidjs]
|
||||
|
||||
objective:
|
||||
- Create OAuth placeholder screens
|
||||
- Document terminal limitations for OAuth
|
||||
- Provide alternative authentication methods
|
||||
- Explain browser redirect flow
|
||||
|
||||
deliverables:
|
||||
- `src/components/OAuthPlaceholder.tsx` with OAuth info
|
||||
- `src/components/BrowserRedirect.tsx` with redirect flow
|
||||
- `src/docs/oauth-limitations.md` with documentation
|
||||
|
||||
steps:
|
||||
- Create `src/components/OAuthPlaceholder.tsx`:
|
||||
- Display OAuth information
|
||||
- Explain terminal limitations
|
||||
- Show supported providers (Google, Apple)
|
||||
- Link to browser redirect flow
|
||||
- Create `src/components/BrowserRedirect.tsx`:
|
||||
- Display QR code for mobile
|
||||
- Display 8-character code
|
||||
- Instructions for browser flow
|
||||
- Link to website
|
||||
- Create `src/docs/oauth-limitations.md`:
|
||||
- Detailed explanation of OAuth in terminal
|
||||
- Why OAuth is not feasible
|
||||
- Alternative authentication methods
|
||||
- Browser redirect flow instructions
|
||||
- Add OAuth placeholder to login screen
|
||||
|
||||
tests:
|
||||
- Unit: Test OAuth placeholder displays correctly
|
||||
- Unit: Test browser redirect flow displays
|
||||
- Documentation review
|
||||
|
||||
acceptance_criteria:
|
||||
- OAuth placeholder screens display correctly
|
||||
- Limitations are clearly documented
|
||||
- Alternative methods are provided
|
||||
- Browser redirect flow is explained
|
||||
|
||||
validation:
|
||||
- Run application and navigate to OAuth placeholder
|
||||
- Read documentation
|
||||
- Verify flow instructions are clear
|
||||
|
||||
notes:
|
||||
- OAuth in terminal is not feasible
|
||||
- Terminal cannot handle OAuth flows
|
||||
- Document this limitation clearly
|
||||
- Provide browser redirect as alternative
|
||||
- User can still use file sync
|
||||
- Google and Apple OAuth are supported by browser
|
||||
@@ -1,62 +0,0 @@
|
||||
# 27. Create Sync-Only User Profile
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-27
|
||||
feature: podcast-tui-app
|
||||
priority: P2
|
||||
depends_on: [26]
|
||||
tags: [profile, sync, user-info, solidjs]
|
||||
|
||||
objective:
|
||||
- Create user profile component for sync-only users
|
||||
- Display user information
|
||||
- Show sync status
|
||||
- Provide profile management options
|
||||
|
||||
deliverables:
|
||||
- `src/components/SyncProfile.tsx` with user profile
|
||||
- `src/components/SyncStatus.tsx` with sync status
|
||||
- `src/components/ProfileSettings.tsx` with profile settings
|
||||
|
||||
steps:
|
||||
- Create `src/components/SyncProfile.tsx`:
|
||||
- User avatar/icon
|
||||
- User name display
|
||||
- Email display
|
||||
- Sync status indicator
|
||||
- Profile actions
|
||||
- Create `src/components/SyncStatus.tsx`:
|
||||
- Sync status (last sync time)
|
||||
- Sync method (file-based)
|
||||
- Sync frequency
|
||||
- Sync history
|
||||
- Create `src/components/ProfileSettings.tsx`:
|
||||
- Edit profile
|
||||
- Change password
|
||||
- Manage sync settings
|
||||
- Export data
|
||||
- Add profile to settings screen
|
||||
|
||||
tests:
|
||||
- Unit: Test profile displays correctly
|
||||
- Unit: Test sync status updates
|
||||
- Integration: Test profile settings
|
||||
|
||||
acceptance_criteria:
|
||||
- Profile displays user information
|
||||
- Sync status is shown
|
||||
- Profile settings work correctly
|
||||
- Profile is accessible from settings
|
||||
|
||||
validation:
|
||||
- Run application and navigate to profile
|
||||
- View profile information
|
||||
- Test profile settings
|
||||
- Verify sync status
|
||||
|
||||
notes:
|
||||
- Profile for sync-only users
|
||||
- No authentication required
|
||||
- Profile data stored in localStorage
|
||||
- Sync status shows last sync time
|
||||
- Profile is optional
|
||||
@@ -1,56 +0,0 @@
|
||||
# 28. Create Feed Data Models and Types
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-28
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [27]
|
||||
tags: [types, data-models, solidjs, typescript]
|
||||
|
||||
objective:
|
||||
- Define TypeScript interfaces for all podcast-related data
|
||||
- Create models for feeds, episodes, sources
|
||||
- Set up type definitions for sync functionality
|
||||
|
||||
deliverables:
|
||||
- `src/types/podcast.ts` with core types
|
||||
- `src/types/episode.ts` with episode types
|
||||
- `src/types/source.ts` with source types
|
||||
- `src/types/feed.ts` with feed types
|
||||
|
||||
steps:
|
||||
- Create `src/types/podcast.ts`:
|
||||
- `Podcast` interface (id, title, description, coverUrl, feedUrl, lastUpdated)
|
||||
- `PodcastWithEpisodes` interface (podcast + episodes array)
|
||||
- Create `src/types/episode.ts`:
|
||||
- `Episode` interface (id, title, description, audioUrl, duration, pubDate, episodeNumber)
|
||||
- `EpisodeStatus` enum (playing, paused, completed, not_started)
|
||||
- `Progress` interface (episodeId, position, duration, timestamp)
|
||||
- Create `src/types/source.ts`:
|
||||
- `PodcastSource` interface (id, name, baseUrl, type, apiKey, enabled)
|
||||
- `SourceType` enum (rss, api, custom)
|
||||
- `SearchQuery` interface (query, sourceIds, filters)
|
||||
- Create `src/types/feed.ts`:
|
||||
- `Feed` interface (id, podcast, episodes[], isPublic, sourceId, lastUpdated)
|
||||
- `FeedItem` interface (represents a single episode in a feed)
|
||||
- `FeedFilter` interface (public, private, sourceId)
|
||||
|
||||
tests:
|
||||
- Unit: Verify all interfaces compile correctly
|
||||
- Unit: Test enum values are correct
|
||||
- Integration: Test type definitions match expected data structures
|
||||
|
||||
acceptance_criteria:
|
||||
- All TypeScript interfaces compile without errors
|
||||
- Types are exported for use across the application
|
||||
- Type definitions cover all podcast-related data
|
||||
|
||||
validation:
|
||||
- Run `bun run build` to verify TypeScript compilation
|
||||
- Check `src/types/` directory contains all required files
|
||||
|
||||
notes:
|
||||
- Use strict TypeScript mode
|
||||
- Include JSDoc comments for complex types
|
||||
- Keep types simple and focused
|
||||
- Ensure types are compatible with sync JSON/XML formats
|
||||
@@ -1,63 +0,0 @@
|
||||
# 29. Build Feed List Component (Public/Private Feeds)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-29
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [28]
|
||||
tags: [feed-list, components, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create a scrollable feed list component
|
||||
- Display public and private feeds
|
||||
- Implement feed selection and display
|
||||
- Add reverse chronological ordering
|
||||
|
||||
deliverables:
|
||||
- `src/components/FeedList.tsx` with feed list component
|
||||
- `src/components/FeedItem.tsx` with individual feed item
|
||||
- `src/components/FeedFilter.tsx` with public/private toggle
|
||||
|
||||
steps:
|
||||
- Create `src/components/FeedList.tsx`:
|
||||
- Use `<scrollbox>` for scrollable list
|
||||
- Accept feeds array as prop
|
||||
- Implement feed rendering with `createSignal` for selection
|
||||
- Add keyboard navigation (arrow keys, enter)
|
||||
- Display feed title, description, episode count
|
||||
- Create `src/components/FeedItem.tsx`:
|
||||
- Display feed information
|
||||
- Show public/private indicator
|
||||
- Highlight selected feed
|
||||
- Add hover effects
|
||||
- Create `src/components/FeedFilter.tsx`:
|
||||
- Toggle button for public/private feeds
|
||||
- Filter logic implementation
|
||||
- Update parent FeedList when filtered
|
||||
- Add feed list to "My Feeds" navigation tab
|
||||
|
||||
tests:
|
||||
- Unit: Test FeedList renders with feeds
|
||||
- Unit: Test FeedItem displays correctly
|
||||
- Integration: Test public/private filtering
|
||||
- Integration: Test keyboard navigation in feed list
|
||||
|
||||
acceptance_criteria:
|
||||
- Feed list displays all feeds correctly
|
||||
- Public/private toggle filters feeds
|
||||
- Feed selection is visually indicated
|
||||
- Keyboard navigation works (arrow keys, enter)
|
||||
- List scrolls properly when many feeds
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "My Feeds"
|
||||
- Add some feeds and verify they appear
|
||||
- Test public/private toggle
|
||||
- Use arrow keys to navigate feeds
|
||||
- Scroll list with many feeds
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for selection state
|
||||
- Follow OpenTUI component patterns from `components/REFERENCE.md`
|
||||
- Feed list should be scrollable with many items
|
||||
- Use Flexbox for layout
|
||||
@@ -1,67 +0,0 @@
|
||||
# 30. Implement Feed Source Management (Add/Remove Sources)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-30
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [29]
|
||||
tags: [source-management, feeds, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create source management component
|
||||
- Implement add new source functionality
|
||||
- Implement remove source functionality
|
||||
- Manage enabled/disabled sources
|
||||
|
||||
deliverables:
|
||||
- `src/components/SourceManager.tsx` with source management UI
|
||||
- `src/components/AddSourceForm.tsx` with add source form
|
||||
- `src/components/SourceListItem.tsx` with individual source
|
||||
|
||||
steps:
|
||||
- Create `src/components/SourceManager.tsx`:
|
||||
- List of enabled sources
|
||||
- Add source button
|
||||
- Remove source button
|
||||
- Enable/disable toggle
|
||||
- Source count display
|
||||
- Create `src/components/AddSourceForm.tsx`:
|
||||
- Source name input
|
||||
- Source URL input
|
||||
- Source type selection
|
||||
- API key input (if required)
|
||||
- Submit button
|
||||
- Validation
|
||||
- Create `src/components/SourceListItem.tsx`:
|
||||
- Display source info
|
||||
- Enable/disable toggle
|
||||
- Remove button
|
||||
- Status indicator
|
||||
- Add source manager to settings screen
|
||||
|
||||
tests:
|
||||
- Unit: Test source list displays correctly
|
||||
- Unit: Test add source form validation
|
||||
- Unit: Test remove source functionality
|
||||
- Integration: Test source management workflow
|
||||
|
||||
acceptance_criteria:
|
||||
- Source list displays all sources
|
||||
- Add source form validates input
|
||||
- Remove source works correctly
|
||||
- Enable/disable toggles work
|
||||
|
||||
validation:
|
||||
- Run application and navigate to settings
|
||||
- Test add source
|
||||
- Test remove source
|
||||
- Test enable/disable toggle
|
||||
- Verify feeds from new sources appear
|
||||
|
||||
notes:
|
||||
- Source types: RSS, API, Custom
|
||||
- RSS sources: feed URLs
|
||||
- API sources: require API key
|
||||
- Custom sources: user-defined
|
||||
- Add validation for source URLs
|
||||
- Store sources in localStorage
|
||||
@@ -1,61 +0,0 @@
|
||||
# 31. Add Reverse Chronological Ordering
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-31
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [30]
|
||||
tags: [ordering, feeds, episodes, solidjs, sorting]
|
||||
|
||||
objective:
|
||||
- Implement reverse chronological ordering for feeds
|
||||
- Order episodes by publication date (newest first)
|
||||
- Order feeds by last updated (newest first)
|
||||
- Provide sort option toggle
|
||||
|
||||
deliverables:
|
||||
- `src/utils/ordering.ts` with sorting functions
|
||||
- `src/components/FeedSortToggle.tsx` with sort option
|
||||
- `src/components/EpisodeList.tsx` with ordered episode list
|
||||
|
||||
steps:
|
||||
- Create `src/utils/ordering.ts`:
|
||||
- `orderEpisodesByDate(episodes: Episode[]): Episode[]`
|
||||
- Order by pubDate descending
|
||||
- Handle missing dates
|
||||
- `orderFeedsByDate(feeds: Feed[]): Feed[]`
|
||||
- Order by lastUpdated descending
|
||||
- Handle missing updates
|
||||
- Create `src/components/FeedSortToggle.tsx`:
|
||||
- Toggle button for date ordering
|
||||
- Display current sort order
|
||||
- Update parent component
|
||||
- Create `src/components/EpisodeList.tsx`:
|
||||
- Accept episodes array
|
||||
- Apply ordering
|
||||
- Display episodes in reverse chronological order
|
||||
- Add keyboard navigation
|
||||
|
||||
tests:
|
||||
- Unit: Test episode ordering
|
||||
- Unit: Test feed ordering
|
||||
- Unit: Test sort toggle
|
||||
|
||||
acceptance_criteria:
|
||||
- Episodes ordered by date (newest first)
|
||||
- Feeds ordered by last updated (newest first)
|
||||
- Sort toggle works correctly
|
||||
- Ordering persists across sessions
|
||||
|
||||
validation:
|
||||
- Run application and check episode order
|
||||
- Check feed order
|
||||
- Toggle sort order
|
||||
- Restart app and verify ordering persists
|
||||
|
||||
notes:
|
||||
- Use JavaScript `sort()` with date comparison
|
||||
- Handle timezone differences
|
||||
- Add loading state during sort
|
||||
- Cache ordered results
|
||||
- Consider adding custom sort options
|
||||
@@ -1,66 +0,0 @@
|
||||
# 32. Create Feed Detail View
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-32
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [31]
|
||||
tags: [feed-detail, episodes, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create feed detail view component
|
||||
- Display podcast information
|
||||
- List episodes in reverse chronological order
|
||||
- Provide episode playback controls
|
||||
|
||||
deliverables:
|
||||
- `src/components/FeedDetail.tsx` with feed detail view
|
||||
- `src/components/EpisodeList.tsx` with episode list
|
||||
- `src/components/EpisodeItem.tsx` with individual episode
|
||||
|
||||
steps:
|
||||
- Create `src/components/FeedDetail.tsx`:
|
||||
- Podcast cover image
|
||||
- Podcast title and description
|
||||
- Episode count
|
||||
- Subscribe/unsubscribe button
|
||||
- Episode list container
|
||||
- Create `src/components/EpisodeList.tsx`:
|
||||
- Scrollable episode list
|
||||
- Display episode title, date, duration
|
||||
- Playback status indicator
|
||||
- Add keyboard navigation
|
||||
- Create `src/components/EpisodeItem.tsx`:
|
||||
- Episode information
|
||||
- Play button
|
||||
- Mark as complete button
|
||||
- Progress bar
|
||||
- Hover effects
|
||||
- Add feed detail to "My Feeds" navigation tab
|
||||
|
||||
tests:
|
||||
- Unit: Test FeedDetail displays correctly
|
||||
- Unit: Test EpisodeList rendering
|
||||
- Unit: Test EpisodeItem interaction
|
||||
- Integration: Test feed detail navigation
|
||||
|
||||
acceptance_criteria:
|
||||
- Feed detail displays podcast info
|
||||
- Episode list shows all episodes
|
||||
- Episodes ordered reverse chronological
|
||||
- Play buttons work
|
||||
- Mark as complete works
|
||||
|
||||
validation:
|
||||
- Run application and navigate to feed detail
|
||||
- View podcast information
|
||||
- Check episode order
|
||||
- Test play button
|
||||
- Test mark as complete
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for episode selection
|
||||
- Display episode status (playing, completed, not started)
|
||||
- Show progress for completed episodes
|
||||
- Add episode filtering (all, completed, not completed)
|
||||
- Use Flexbox for layout
|
||||
@@ -1,68 +0,0 @@
|
||||
# 33. Create Search Interface
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-33
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [32]
|
||||
tags: [search-interface, input, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create search input component
|
||||
- Implement search functionality
|
||||
- Display search results
|
||||
- Handle search state
|
||||
|
||||
deliverables:
|
||||
- `src/components/SearchBar.tsx` with search input
|
||||
- `src/components/SearchResults.tsx` with results display
|
||||
- `src/components/SearchHistory.tsx` with history list
|
||||
|
||||
steps:
|
||||
- Create `src/components/SearchBar.tsx`:
|
||||
- Search input field using `<input>` component
|
||||
- Search button
|
||||
- Clear button
|
||||
- Enter key handler
|
||||
- Loading state
|
||||
- Create `src/utils/search.ts`:
|
||||
- `searchPodcasts(query: string, sourceIds: string[]): Promise<Podcast[]>`
|
||||
- `searchEpisodes(query: string, feedId: string): Promise<Episode[]>`
|
||||
- Handle multiple sources
|
||||
- Cache search results
|
||||
- Create `src/components/SearchResults.tsx`:
|
||||
- Display search results with source indicators
|
||||
- Show podcast/episode info
|
||||
- Add to feed button
|
||||
- Keyboard navigation through results
|
||||
- Create `src/components/SearchHistory.tsx`:
|
||||
- Display recent search queries
|
||||
- Click to re-run search
|
||||
- Delete individual history items
|
||||
- Persist to localStorage
|
||||
|
||||
tests:
|
||||
- Unit: Test search logic returns correct results
|
||||
- Unit: Test search history persistence
|
||||
- Integration: Test search bar accepts input
|
||||
- Integration: Test results display correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- Search bar accepts and processes queries
|
||||
- Search results display with source information
|
||||
- Search history persists across sessions
|
||||
- Keyboard navigation works in results
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Search"
|
||||
- Type a query and press Enter
|
||||
- Verify results appear
|
||||
- Click a result to add to feed
|
||||
- Restart app and verify history persists
|
||||
|
||||
notes:
|
||||
- Use localStorage for search history
|
||||
- Implement basic caching to avoid repeated searches
|
||||
- Handle empty results gracefully
|
||||
- Add loading state during search
|
||||
- Search both podcasts and episodes
|
||||
@@ -1,62 +0,0 @@
|
||||
# 34. Implement Multi-Source Search
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-34
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [33]
|
||||
tags: [multi-source, search, solidjs, api]
|
||||
|
||||
objective:
|
||||
- Implement search across multiple podcast sources
|
||||
- Handle different source types (RSS, API, Custom)
|
||||
- Display source information in results
|
||||
- Cache search results
|
||||
|
||||
deliverables:
|
||||
- `src/utils/search.ts` with multi-source search logic
|
||||
- `src/utils/source-searcher.ts` with source-specific searchers
|
||||
- `src/components/SourceBadge.tsx` with source indicator
|
||||
|
||||
steps:
|
||||
- Create `src/utils/source-searcher.ts`:
|
||||
- `searchRSSSource(query: string, source: PodcastSource): Promise<Podcast[]>`
|
||||
- `searchAPISource(query: string, source: PodcastSource): Promise<Podcast[]>`
|
||||
- `searchCustomSource(query: string, source: PodcastSource): Promise<Podcast[]>`
|
||||
- Handle source-specific search logic
|
||||
- Create `src/utils/search.ts`:
|
||||
- `searchPodcasts(query: string, sourceIds: string[]): Promise<Podcast[]>`
|
||||
- Aggregate results from multiple sources
|
||||
- Deduplicate results
|
||||
- Cache results by query
|
||||
- Handle source errors gracefully
|
||||
- Create `src/components/SourceBadge.tsx`:
|
||||
- Display source type (RSS, API, Custom)
|
||||
- Show source name
|
||||
- Color-coded for different types
|
||||
|
||||
tests:
|
||||
- Unit: Test RSS source search
|
||||
- Unit: Test API source search
|
||||
- Unit: Test custom source search
|
||||
- Unit: Test result aggregation
|
||||
|
||||
acceptance_criteria:
|
||||
- Search works across all enabled sources
|
||||
- Source information displayed correctly
|
||||
- Results aggregated from multiple sources
|
||||
- Errors handled gracefully
|
||||
|
||||
validation:
|
||||
- Run application and perform search
|
||||
- Verify results from multiple sources
|
||||
- Test with different source types
|
||||
- Test error handling for failed sources
|
||||
|
||||
notes:
|
||||
- RSS sources: Parse feed XML
|
||||
- API sources: Call API endpoints
|
||||
- Custom sources: User-defined search logic
|
||||
- Handle rate limiting
|
||||
- Cache results to avoid repeated searches
|
||||
- Show loading state for each source
|
||||
@@ -1,66 +0,0 @@
|
||||
# 35. Add Search Results Display
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-35
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [34]
|
||||
tags: [search-results, display, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Display search results with rich information
|
||||
- Show podcast/episode details
|
||||
- Add to feed functionality
|
||||
- Keyboard navigation through results
|
||||
|
||||
deliverables:
|
||||
- `src/components/SearchResults.tsx` with results display
|
||||
- `src/components/ResultCard.tsx` with individual result
|
||||
- `src/components/ResultDetail.tsx` with detailed view
|
||||
|
||||
steps:
|
||||
- Create `src/components/ResultCard.tsx`:
|
||||
- Display result title
|
||||
- Display source information
|
||||
- Display description/snippet
|
||||
- Add to feed button
|
||||
- Click to view details
|
||||
- Create `src/components/ResultDetail.tsx`:
|
||||
- Full result details
|
||||
- Podcast/episode information
|
||||
- Episode list (if podcast)
|
||||
- Subscribe button
|
||||
- Close button
|
||||
- Create `src/components/SearchResults.tsx`:
|
||||
- Scrollable results list
|
||||
- Empty state display
|
||||
- Loading state display
|
||||
- Error state display
|
||||
- Keyboard navigation
|
||||
|
||||
tests:
|
||||
- Unit: Test ResultCard displays correctly
|
||||
- Unit: Test ResultDetail displays correctly
|
||||
- Unit: Test search results list
|
||||
- Integration: Test add to feed
|
||||
|
||||
acceptance_criteria:
|
||||
- Search results display with all information
|
||||
- Result cards show source and details
|
||||
- Add to feed button works
|
||||
- Keyboard navigation works
|
||||
|
||||
validation:
|
||||
- Run application and perform search
|
||||
- Verify results display correctly
|
||||
- Click result to view details
|
||||
- Test add to feed
|
||||
- Test keyboard navigation
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for result selection
|
||||
- Display result type (podcast/episode)
|
||||
- Show source name and type
|
||||
- Add loading state during search
|
||||
- Handle empty results
|
||||
- Add pagination for large result sets
|
||||
@@ -1,64 +0,0 @@
|
||||
# 36. Build Search History with Persistent Storage
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-36
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [35]
|
||||
tags: [search-history, persistence, storage, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement search history functionality
|
||||
- Store search queries in localStorage
|
||||
- Display recent searches
|
||||
- Add search to history
|
||||
- Clear history
|
||||
|
||||
deliverables:
|
||||
- `src/components/SearchHistory.tsx` with history list
|
||||
- `src/utils/history.ts` with history management
|
||||
- `src/hooks/useSearchHistory.ts` with history hook
|
||||
|
||||
steps:
|
||||
- Create `src/utils/history.ts`:
|
||||
- `addToHistory(query: string): void`
|
||||
- `getHistory(): string[]`
|
||||
- `removeFromHistory(query: string): void`
|
||||
- `clearHistory(): void`
|
||||
- `maxHistorySize = 50`
|
||||
- Create `src/hooks/useSearchHistory.ts`:
|
||||
- `createSignal` for history array
|
||||
- Update history on search
|
||||
- Persist to localStorage
|
||||
- Methods to manage history
|
||||
- Create `src/components/SearchHistory.tsx`:
|
||||
- Display recent search queries
|
||||
- Click to re-run search
|
||||
- Delete individual history items
|
||||
- Clear all history button
|
||||
- Persistent across sessions
|
||||
|
||||
tests:
|
||||
- Unit: Test history management functions
|
||||
- Unit: Test history persistence
|
||||
- Integration: Test history display
|
||||
|
||||
acceptance_criteria:
|
||||
- Search queries added to history
|
||||
- History persists across sessions
|
||||
- History displays correctly
|
||||
- Clear history works
|
||||
|
||||
validation:
|
||||
- Run application and perform searches
|
||||
- Check search history persists
|
||||
- Test clearing history
|
||||
- Restart app and verify
|
||||
|
||||
notes:
|
||||
- Use localStorage for persistence
|
||||
- Limit history to 50 items
|
||||
- Remove duplicates
|
||||
- Store timestamps (optional)
|
||||
- Clear history button in search screen
|
||||
- Add delete button on individual items
|
||||
@@ -1,56 +0,0 @@
|
||||
# 37. Create Popular Shows Data Structure
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-37
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [36]
|
||||
tags: [popular-shows, data, discovery, solidjs]
|
||||
|
||||
objective:
|
||||
- Create data structure for popular shows
|
||||
- Define podcast metadata
|
||||
- Categorize shows by topic
|
||||
- Include feed URLs and descriptions
|
||||
|
||||
deliverables:
|
||||
- `src/data/popular-shows.ts` with popular podcasts data
|
||||
- `src/types/popular-shows.ts` with data types
|
||||
- `src/constants/categories.ts` with category definitions
|
||||
|
||||
steps:
|
||||
- Create `src/types/popular-shows.ts`:
|
||||
- `PopularPodcast` interface (id, title, description, coverUrl, feedUrl, category, tags)
|
||||
- `Category` enum (Technology, Business, Science, Entertainment, Health, Education)
|
||||
- Create `src/constants/categories.ts`:
|
||||
- List of all categories
|
||||
- Category descriptions
|
||||
- Sample podcasts per category
|
||||
- Create `src/data/popular-shows.ts`:
|
||||
- Array of popular podcasts
|
||||
- Categorized by topic
|
||||
- Reverse chronological ordering
|
||||
- Include metadata for each show
|
||||
|
||||
tests:
|
||||
- Unit: Test data structure compiles
|
||||
- Unit: Test category definitions
|
||||
- Integration: Test popular shows display
|
||||
|
||||
acceptance_criteria:
|
||||
- Popular shows data structure defined
|
||||
- Categories defined correctly
|
||||
- Shows categorized properly
|
||||
- Data ready for display
|
||||
|
||||
validation:
|
||||
- Run `bun run build` to verify TypeScript
|
||||
- Check data structure compiles
|
||||
- Review data for completeness
|
||||
|
||||
notes:
|
||||
- Popular shows data can be static or fetched
|
||||
- If sources don't provide trending, use curated list
|
||||
- Categories help users find shows by topic
|
||||
- Include diverse range of shows
|
||||
- Add RSS feed URLs for easy subscription
|
||||
@@ -1,64 +0,0 @@
|
||||
# 38. Build Discover Page Component
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-38
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [37]
|
||||
tags: [discover-page, popular-shows, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create discover page component
|
||||
- Display popular shows
|
||||
- Implement category filtering
|
||||
- Add to feed functionality
|
||||
|
||||
deliverables:
|
||||
- `src/components/DiscoverPage.tsx` with discover UI
|
||||
- `src/components/PopularShows.tsx` with shows grid
|
||||
- `src/components/CategoryFilter.tsx` with category buttons
|
||||
|
||||
steps:
|
||||
- Create `src/components/DiscoverPage.tsx`:
|
||||
- Page header with title
|
||||
- Category filter buttons
|
||||
- Popular shows grid
|
||||
- Show details view
|
||||
- Add to feed button
|
||||
- Create `src/components/PopularShows.tsx`:
|
||||
- Grid display of popular podcasts
|
||||
- Show cover image
|
||||
- Show title and description
|
||||
- Add to feed button
|
||||
- Click to view details
|
||||
- Create `src/components/CategoryFilter.tsx`:
|
||||
- Category button group
|
||||
- Active category highlighting
|
||||
- Filter logic implementation
|
||||
- Update parent DiscoverPage
|
||||
|
||||
tests:
|
||||
- Unit: Test PopularShows displays correctly
|
||||
- Unit: Test CategoryFilter functionality
|
||||
- Integration: Test discover page navigation
|
||||
|
||||
acceptance_criteria:
|
||||
- Discover page displays popular shows
|
||||
- Category filtering works correctly
|
||||
- Shows are ordered reverse chronologically
|
||||
- Clicking a show shows details
|
||||
- Add to feed button works
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Discover"
|
||||
- Verify popular shows appear
|
||||
- Click different categories
|
||||
- Click a show and verify details
|
||||
- Try add to feed
|
||||
|
||||
notes:
|
||||
- Use Flexbox for category filter layout
|
||||
- Use Grid for shows display
|
||||
- Add loading state if fetching from API
|
||||
- Handle empty categories
|
||||
- Add hover effects for interactivity
|
||||
@@ -1,61 +0,0 @@
|
||||
# 39. Add Trending Shows Display
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-39
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [38]
|
||||
tags: [trending-shows, display, solidjs]
|
||||
|
||||
objective:
|
||||
- Display trending shows section
|
||||
- Show top podcasts by popularity
|
||||
- Implement trend indicators
|
||||
- Display show rankings
|
||||
|
||||
deliverables:
|
||||
- `src/components/TrendingShows.tsx` with trending section
|
||||
- `src/components/ShowRanking.tsx` with ranking display
|
||||
- `src/components/TrendIndicator.tsx` with trend icon
|
||||
|
||||
steps:
|
||||
- Create `src/components/TrendingShows.tsx`:
|
||||
- Trending section header
|
||||
- Top shows list
|
||||
- Show ranking (1, 2, 3...)
|
||||
- Trending indicator
|
||||
- Add to feed button
|
||||
- Create `src/components/ShowRanking.tsx`:
|
||||
- Display ranking number
|
||||
- Show cover image
|
||||
- Show title
|
||||
- Trending score display
|
||||
- Create `src/components/TrendIndicator.tsx`:
|
||||
- Display trend icon (up arrow, down arrow, flat)
|
||||
- Color-coded for trend direction
|
||||
- Show trend percentage
|
||||
- Add trending section to Discover page
|
||||
|
||||
tests:
|
||||
- Unit: Test TrendingShows displays correctly
|
||||
- Unit: Test ranking display
|
||||
- Unit: Test trend indicator
|
||||
|
||||
acceptance_criteria:
|
||||
- Trending shows section displays correctly
|
||||
- Rankings shown for top shows
|
||||
- Trend indicators display correctly
|
||||
- Add to feed buttons work
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Discover"
|
||||
- View trending shows section
|
||||
- Check rankings and indicators
|
||||
- Test add to feed
|
||||
|
||||
notes:
|
||||
- Trending shows: Top 10 podcasts
|
||||
- Trending score: Based on downloads, listens, or engagement
|
||||
- Trend indicators: Up/down/flat arrows
|
||||
- Color-coded: Green for up, red for down, gray for flat
|
||||
- Update trend scores periodically
|
||||
@@ -1,62 +0,0 @@
|
||||
# 41. Create Player UI Layout
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-41
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [40]
|
||||
tags: [player, layout, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create player UI layout component
|
||||
- Display episode information
|
||||
- Position player controls and waveform
|
||||
- Handle player state
|
||||
|
||||
deliverables:
|
||||
- `src/components/Player.tsx` with player layout
|
||||
- `src/components/PlayerHeader.tsx` with episode info
|
||||
- `src/components/PlayerControls.tsx` with controls area
|
||||
|
||||
steps:
|
||||
- Create `src/components/Player.tsx`:
|
||||
- Player container with borders
|
||||
- Episode information header
|
||||
- Waveform visualization area
|
||||
- Playback controls area
|
||||
- Progress bar area
|
||||
- Create `src/components/PlayerHeader.tsx`:
|
||||
- Episode title
|
||||
- Podcast name
|
||||
- Episode duration
|
||||
- Close player button
|
||||
- Create `src/components/PlayerControls.tsx`:
|
||||
- Play/Pause button
|
||||
- Previous/Next episode buttons
|
||||
- Volume control
|
||||
- Speed control
|
||||
- Keyboard shortcuts display
|
||||
|
||||
tests:
|
||||
- Unit: Test Player layout renders correctly
|
||||
- Unit: Test PlayerHeader displays correctly
|
||||
- Unit: Test PlayerControls layout
|
||||
|
||||
acceptance_criteria:
|
||||
- Player UI displays episode information
|
||||
- Controls positioned correctly
|
||||
- Player fits within terminal bounds
|
||||
- Layout is responsive
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Player"
|
||||
- Select an episode to play
|
||||
- Verify player UI displays
|
||||
- Check layout and positioning
|
||||
|
||||
notes:
|
||||
- Use Flexbox for player layout
|
||||
- Player should be at bottom or overlay
|
||||
- Use `<scrollbox>` for waveform area
|
||||
- Add loading state when no episode
|
||||
- Use SolidJS signals for player state
|
||||
@@ -1,70 +0,0 @@
|
||||
# 42. Implement Playback Controls
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-42
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [41]
|
||||
tags: [playback, controls, audio, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement playback controls (play/pause, skip, progress)
|
||||
- Create control buttons
|
||||
- Add keyboard shortcuts
|
||||
- Handle playback state
|
||||
|
||||
deliverables:
|
||||
- `src/components/PlaybackControls.tsx` with control buttons
|
||||
- `src/utils/playback.ts` with playback logic
|
||||
- `src/hooks/usePlayback.ts` with playback hook
|
||||
|
||||
steps:
|
||||
- Create `src/utils/playback.ts`:
|
||||
- `playAudio(audioUrl: string): void`
|
||||
- `pauseAudio(): void`
|
||||
- `skipForward(): void`
|
||||
- `skipBackward(): void`
|
||||
- `setPlaybackSpeed(speed: number): void`
|
||||
- Handle audio player integration
|
||||
- Create `src/hooks/usePlayback.ts`:
|
||||
- `createSignal` for playback state
|
||||
- Methods: play, pause, seek, setSpeed
|
||||
- Handle audio events (timeupdate, ended)
|
||||
- Create `src/components/PlaybackControls.tsx`:
|
||||
- Play/Pause button
|
||||
- Previous/Next episode buttons
|
||||
- Volume control (slider)
|
||||
- Speed control (1x, 1.25x, 1.5x, 2x)
|
||||
- Keyboard shortcuts (space, arrows)
|
||||
|
||||
tests:
|
||||
- Unit: Test playback logic
|
||||
- Unit: Test playback hook
|
||||
- Integration: Test playback controls
|
||||
|
||||
acceptance_criteria:
|
||||
- Play/pause button works
|
||||
- Skip forward/backward works
|
||||
- Speed control works
|
||||
- Volume control works
|
||||
- Keyboard shortcuts work
|
||||
|
||||
validation:
|
||||
- Run application and test playback
|
||||
- Press play/pause
|
||||
- Test skip buttons
|
||||
- Change playback speed
|
||||
- Test keyboard shortcuts
|
||||
|
||||
notes:
|
||||
- Audio integration: Trigger system player or use Web Audio API
|
||||
- Use Web Audio API for waveform
|
||||
- Handle audio errors
|
||||
- Add loading state during playback
|
||||
- Store playback speed preference
|
||||
- Support keyboard shortcuts:
|
||||
- Space: Play/Pause
|
||||
- Arrow Right: Skip forward
|
||||
- Arrow Left: Skip backward
|
||||
- Arrow Up: Volume up
|
||||
- Arrow Down: Volume down
|
||||
@@ -1,61 +0,0 @@
|
||||
# 43. Build ASCII Waveform Visualization
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-43
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [42]
|
||||
tags: [waveform, visualization, ascii, solidjs]
|
||||
|
||||
objective:
|
||||
- Create ASCII waveform visualization
|
||||
- Generate waveform from audio data
|
||||
- Display waveform in player
|
||||
- Handle click to seek
|
||||
|
||||
deliverables:
|
||||
- `src/components/Waveform.tsx` with waveform display
|
||||
- `src/utils/waveform.ts` with waveform generation
|
||||
- `src/components/WaveformProgress.tsx` with progress overlay
|
||||
|
||||
steps:
|
||||
- Create `src/utils/waveform.ts`:
|
||||
- `generateWaveform(audioUrl: string): Promise<string>`
|
||||
- Fetch audio data
|
||||
- Analyze audio frequencies
|
||||
- Convert to ASCII characters
|
||||
- Return ASCII waveform string
|
||||
- Create `src/components/Waveform.tsx`:
|
||||
- Display ASCII waveform
|
||||
- Color-coded for played/paused
|
||||
- Click to seek to position
|
||||
- Handle terminal width
|
||||
- Create `src/components/WaveformProgress.tsx`:
|
||||
- Progress overlay on waveform
|
||||
- Show current position
|
||||
- Highlight current segment
|
||||
|
||||
tests:
|
||||
- Unit: Test waveform generation
|
||||
- Unit: Test waveform display
|
||||
- Integration: Test click to seek
|
||||
|
||||
acceptance_criteria:
|
||||
- Waveform displays correctly
|
||||
- Waveform generated from audio
|
||||
- Color-coded for played/paused
|
||||
- Clicking waveform seeks to position
|
||||
|
||||
validation:
|
||||
- Run application and play an episode
|
||||
- Verify waveform displays
|
||||
- Check waveform colors
|
||||
- Test seeking by clicking waveform
|
||||
|
||||
notes:
|
||||
- ASCII waveform: Use `#` for peaks, `.` for valleys
|
||||
- Use Web Audio API for waveform generation
|
||||
- Cache waveform data for performance
|
||||
- Handle large audio files
|
||||
- Use frame buffer for drawing
|
||||
- Color scheme: Green for played, Gray for paused
|
||||
@@ -1,63 +0,0 @@
|
||||
# 44. Add Progress Tracking and Seek
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-44
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [43]
|
||||
tags: [progress, tracking, seek, solidjs]
|
||||
|
||||
objective:
|
||||
- Track playback progress
|
||||
- Save progress to storage
|
||||
- Implement seek functionality
|
||||
- Display progress bar
|
||||
|
||||
deliverables:
|
||||
- `src/utils/progress.ts` with progress tracking
|
||||
- `src/hooks/useProgress.ts` with progress hook
|
||||
- `src/components/ProgressBar.tsx` with progress bar
|
||||
|
||||
steps:
|
||||
- Create `src/utils/progress.ts`:
|
||||
- `saveProgress(episodeId: string, position: number, duration: number): void`
|
||||
- `loadProgress(episodeId: string): Progress | null`
|
||||
- `updateProgress(episodeId: string, position: number): void`
|
||||
- Handle progress persistence
|
||||
- Create `src/hooks/useProgress.ts`:
|
||||
- `createSignal` for progress
|
||||
- Update progress on timeupdate
|
||||
- Save progress periodically
|
||||
- Load progress on episode change
|
||||
- Create `src/components/ProgressBar.tsx`:
|
||||
- Progress bar visualization
|
||||
- Percentage display
|
||||
- Time display (current/total)
|
||||
- Click to seek
|
||||
|
||||
tests:
|
||||
- Unit: Test progress tracking functions
|
||||
- Unit: Test progress hook
|
||||
- Integration: Test progress bar
|
||||
|
||||
acceptance_criteria:
|
||||
- Progress saved correctly
|
||||
- Progress loaded correctly
|
||||
- Seek works via progress bar
|
||||
- Progress persists across sessions
|
||||
|
||||
validation:
|
||||
- Run application and play episode
|
||||
- Seek to different positions
|
||||
- Stop and restart
|
||||
- Verify progress saved
|
||||
- Restart app and verify progress loaded
|
||||
|
||||
notes:
|
||||
- Save progress to localStorage
|
||||
- Auto-save every 30 seconds
|
||||
- Save on episode change
|
||||
- Save on pause
|
||||
- Don't save on completion
|
||||
- Load progress when starting episode
|
||||
- Display progress bar in player
|
||||
@@ -1,64 +0,0 @@
|
||||
# 45. Implement Audio Integration (System/External Player)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-45
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [44]
|
||||
tags: [audio, integration, player, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement audio playback integration
|
||||
- Support system audio player
|
||||
- Support external player
|
||||
- Handle audio events
|
||||
|
||||
deliverables:
|
||||
- `src/utils/audio-player.ts` with audio integration
|
||||
- `src/components/AudioSettings.tsx` with audio player settings
|
||||
- `src/hooks/useAudio.ts` with audio hook
|
||||
|
||||
steps:
|
||||
- Create `src/utils/audio-player.ts`:
|
||||
- `playWithSystemPlayer(audioUrl: string): void`
|
||||
- `playWithExternalPlayer(audioUrl: string): void`
|
||||
- `getSupportedPlayers(): string[]`
|
||||
- Detect available players
|
||||
- Create `src/components/AudioSettings.tsx`:
|
||||
- Player selection dropdown
|
||||
- System player options
|
||||
- External player options
|
||||
- Default player selection
|
||||
- Create `src/hooks/useAudio.ts`:
|
||||
- Manage audio state
|
||||
- Handle player selection
|
||||
- Handle audio events
|
||||
- Update progress
|
||||
|
||||
tests:
|
||||
- Unit: Test audio player detection
|
||||
- Unit: Test player selection
|
||||
- Integration: Test audio playback
|
||||
|
||||
acceptance_criteria:
|
||||
- Audio plays correctly
|
||||
- Multiple player options available
|
||||
- Player selection persists
|
||||
- Audio events handled
|
||||
|
||||
validation:
|
||||
- Run application and test audio
|
||||
- Select different player options
|
||||
- Play episode and verify audio
|
||||
- Test progress tracking with audio
|
||||
|
||||
notes:
|
||||
- System player: macOS Terminal, iTerm2, etc.
|
||||
- External player: VLC, QuickTime, etc.
|
||||
- Use `open` command for macOS
|
||||
- Use `xdg-open` for Linux
|
||||
- Use `start` for Windows
|
||||
- Handle audio errors gracefully
|
||||
- Add player selection in settings
|
||||
- Default to system player
|
||||
- Store player preference
|
||||
@@ -1,66 +0,0 @@
|
||||
# 46. Create Settings Screen
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-46
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [45]
|
||||
tags: [settings, screen, solidjs, opentui]
|
||||
|
||||
objective:
|
||||
- Create settings screen component
|
||||
- Implement settings navigation
|
||||
- Display all settings sections
|
||||
- Save/apply settings
|
||||
|
||||
deliverables:
|
||||
- `src/components/SettingsScreen.tsx` with settings UI
|
||||
- `src/components/SettingsNavigation.tsx` with settings menu
|
||||
- `src/components/SettingsContent.tsx` with settings content
|
||||
|
||||
steps:
|
||||
- Create `src/components/SettingsNavigation.tsx`:
|
||||
- Settings menu with sections
|
||||
- Navigation between sections
|
||||
- Active section highlighting
|
||||
- Keyboard navigation
|
||||
- Create `src/components/SettingsContent.tsx`:
|
||||
- Feed settings section
|
||||
- Player settings section
|
||||
- Sync settings section
|
||||
- Appearance settings section
|
||||
- Account settings section
|
||||
- Create `src/components/SettingsScreen.tsx`:
|
||||
- Combine navigation and content
|
||||
- Save/Cancel buttons
|
||||
- Reset to defaults button
|
||||
|
||||
tests:
|
||||
- Unit: Test SettingsNavigation displays correctly
|
||||
- Unit: Test SettingsContent sections
|
||||
- Integration: Test settings navigation
|
||||
|
||||
acceptance_criteria:
|
||||
- Settings screen displays all sections
|
||||
- Navigation between sections works
|
||||
- Settings save correctly
|
||||
- Settings persist
|
||||
|
||||
validation:
|
||||
- Run application and navigate to "Settings"
|
||||
- Navigate between settings sections
|
||||
- Change settings
|
||||
- Verify settings persist
|
||||
- Test reset to defaults
|
||||
|
||||
notes:
|
||||
- Use SolidJS signals for settings state
|
||||
- Settings sections:
|
||||
- Feeds: Source management, auto-download
|
||||
- Player: Playback speed, auto-play next
|
||||
- Sync: Backup frequency, sync method
|
||||
- Appearance: Theme, font size
|
||||
- Account: Login, sync profile
|
||||
- Add keyboard shortcuts for navigation
|
||||
- Save settings on change
|
||||
- Reset to defaults button
|
||||
@@ -1,69 +0,0 @@
|
||||
# 47. Add Source Management UI
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-47
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [46]
|
||||
tags: [source-management, settings, ui, solidjs]
|
||||
|
||||
objective:
|
||||
- Create source management UI in settings
|
||||
- List all enabled sources
|
||||
- Add new source functionality
|
||||
- Remove source functionality
|
||||
- Enable/disable sources
|
||||
|
||||
deliverables:
|
||||
- `src/components/SourceManager.tsx` with source management
|
||||
- `src/components/AddSourceForm.tsx` with add source form
|
||||
- `src/components/SourceListItem.tsx` with individual source
|
||||
|
||||
steps:
|
||||
- Create `src/components/SourceManager.tsx`:
|
||||
- List of enabled sources
|
||||
- Add source button
|
||||
- Remove source button
|
||||
- Enable/disable toggle
|
||||
- Source count display
|
||||
- Create `src/components/AddSourceForm.tsx`:
|
||||
- Source name input
|
||||
- Source URL input
|
||||
- Source type selection (RSS, API, Custom)
|
||||
- API key input (if required)
|
||||
- Submit button
|
||||
- Validation
|
||||
- Create `src/components/SourceListItem.tsx`:
|
||||
- Display source info
|
||||
- Enable/disable toggle
|
||||
- Remove button
|
||||
- Status indicator (working, error)
|
||||
|
||||
tests:
|
||||
- Unit: Test source list displays correctly
|
||||
- Unit: Test add source form validation
|
||||
- Unit: Test remove source functionality
|
||||
- Integration: Test source management workflow
|
||||
|
||||
acceptance_criteria:
|
||||
- Source list displays all sources
|
||||
- Add source form validates input
|
||||
- Remove source works correctly
|
||||
- Enable/disable toggles work
|
||||
|
||||
validation:
|
||||
- Run application and navigate to settings
|
||||
- Test add source
|
||||
- Test remove source
|
||||
- Test enable/disable toggle
|
||||
- Verify feeds from new sources appear
|
||||
|
||||
notes:
|
||||
- Source types: RSS, API, Custom
|
||||
- RSS sources: feed URLs
|
||||
- API sources: require API key
|
||||
- Custom sources: user-defined
|
||||
- Add validation for source URLs
|
||||
- Store sources in localStorage
|
||||
- Show source status (working/error)
|
||||
- Add error handling for failed sources
|
||||
@@ -1,69 +0,0 @@
|
||||
# 48. Build User Preferences
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-48
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [47]
|
||||
tags: [preferences, settings, solidjs]
|
||||
|
||||
objective:
|
||||
- Create user preferences panel
|
||||
- Implement theme selection
|
||||
- Implement font size control
|
||||
- Implement playback speed control
|
||||
- Implement auto-download settings
|
||||
|
||||
deliverables:
|
||||
- `src/components/PreferencesPanel.tsx` with preferences
|
||||
- `src/components/ThemeSelector.tsx` with theme options
|
||||
- `src/components/FontSelector.tsx` with font size options
|
||||
- `src/components/AutoDownload.tsx` with auto-download settings
|
||||
|
||||
steps:
|
||||
- Create `src/components/PreferencesPanel.tsx`:
|
||||
- Preferences sections
|
||||
- Navigation between preferences
|
||||
- Save/Cancel buttons
|
||||
- Create `src/components/ThemeSelector.tsx`:
|
||||
- Theme options (light, dark, terminal)
|
||||
- Preview theme
|
||||
- Select theme
|
||||
- Create `src/components/FontSelector.tsx`:
|
||||
- Font size options (small, medium, large)
|
||||
- Preview font size
|
||||
- Select font size
|
||||
- Create `src/components/AutoDownload.tsx`:
|
||||
- Auto-download episodes
|
||||
- Download after playback
|
||||
- Download schedule
|
||||
- Storage limit warning
|
||||
|
||||
tests:
|
||||
- Unit: Test theme selector
|
||||
- Unit: Test font selector
|
||||
- Unit: Test auto-download settings
|
||||
- Integration: Test preferences save/load
|
||||
|
||||
acceptance_criteria:
|
||||
- Preferences display correctly
|
||||
- Theme selection works
|
||||
- Font size selection works
|
||||
- Auto-download settings work
|
||||
- Preferences persist
|
||||
|
||||
validation:
|
||||
- Run application and navigate to preferences
|
||||
- Change theme and verify
|
||||
- Change font size and verify
|
||||
- Test auto-download settings
|
||||
- Restart app and verify preferences
|
||||
|
||||
notes:
|
||||
- Use localStorage for preferences
|
||||
- Theme: Terminal colors (green/amber on black)
|
||||
- Font size: Small (12px), Medium (14px), Large (16px)
|
||||
- Auto-download: Download completed episodes
|
||||
- Add preferences to settings screen
|
||||
- Save preferences on change
|
||||
- Reset to defaults button
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -1,62 +0,0 @@
|
||||
# 50. Create Global State Store (Signals)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-50
|
||||
feature: podcast-tui-app
|
||||
priority: P0
|
||||
depends_on: [49]
|
||||
tags: [state-management, global-store, signals, solidjs]
|
||||
|
||||
objective:
|
||||
- Create global state store using SolidJS Signals
|
||||
- Manage application-wide state
|
||||
- Provide state to all components
|
||||
- Handle state updates and persistence
|
||||
|
||||
deliverables:
|
||||
- `src/stores/appStore.ts` with global state store
|
||||
- `src/stores/feedStore.ts` with feed state
|
||||
- `src/stores/playerStore.ts` with player state
|
||||
- `src/stores/searchStore.ts` with search state
|
||||
|
||||
steps:
|
||||
- Create `src/stores/appStore.ts`:
|
||||
- Use SolidJS signals for global state
|
||||
- Store application state: currentTab, isAuthEnabled, settings
|
||||
- Provide state to all child components
|
||||
- Update state when needed
|
||||
- Create `src/stores/feedStore.ts`:
|
||||
- Signals for feeds array
|
||||
- Signals for selectedFeed
|
||||
- Methods: addFeed, removeFeed, updateFeed
|
||||
- Create `src/stores/playerStore.ts`:
|
||||
- Signals for currentEpisode
|
||||
- Signals for playbackState
|
||||
- Methods: play, pause, seek, setSpeed
|
||||
- Create `src/stores/searchStore.ts`:
|
||||
- Signals for searchResults
|
||||
- Signals for searchHistory
|
||||
- Methods: search, addToHistory, clearHistory
|
||||
|
||||
tests:
|
||||
- Unit: Test store methods update signals correctly
|
||||
- Unit: Test state persistence
|
||||
- Integration: Test state updates across components
|
||||
|
||||
acceptance_criteria:
|
||||
- Global state store manages all app state
|
||||
- Store methods update signals correctly
|
||||
- State persists across component re-renders
|
||||
- State updates propagate to UI
|
||||
|
||||
validation:
|
||||
- Run application and verify state is initialized
|
||||
- Modify state and verify UI updates
|
||||
- Restart app and verify state persistence
|
||||
|
||||
notes:
|
||||
- Use SolidJS `createSignal` for reactivity
|
||||
- Store should be singleton pattern
|
||||
- Use `createStore` if complex state needed
|
||||
- Keep store simple and focused
|
||||
- Store state in localStorage
|
||||
@@ -1,63 +0,0 @@
|
||||
# 51. Implement API Client for Podcast Sources
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-51
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [50]
|
||||
tags: [api-client, sources, solidjs]
|
||||
|
||||
objective:
|
||||
- Create API client for podcast sources
|
||||
- Handle RSS feed parsing
|
||||
- Handle API source queries
|
||||
- Handle custom sources
|
||||
- Implement error handling
|
||||
|
||||
deliverables:
|
||||
- `src/api/client.ts` with API client
|
||||
- `src/api/rss-parser.ts` with RSS parsing
|
||||
- `src/api/source-handler.ts` with source-specific handlers
|
||||
|
||||
steps:
|
||||
- Create `src/api/client.ts`:
|
||||
- `fetchFeeds(sourceIds: string[]): Promise<Feed[]>`
|
||||
- `fetchEpisodes(feedUrl: string): Promise<Episode[]>`
|
||||
- `searchPodcasts(query: string): Promise<Podcast[]>`
|
||||
- Handle API calls and errors
|
||||
- Create `src/api/rss-parser.ts`:
|
||||
- `parseRSSFeed(xml: string): Podcast`
|
||||
- Parse RSS XML
|
||||
- Extract podcast metadata
|
||||
- Extract episodes
|
||||
- Create `src/api/source-handler.ts`:
|
||||
- `handleRSSSource(source: PodcastSource): Promise<Feed[]>`
|
||||
- `handleAPISource(source: PodcastSource, query: string): Promise<Podcast[]>`
|
||||
- `handleCustomSource(source: PodcastSource, query: string): Promise<Podcast[]>`
|
||||
- Source-specific logic
|
||||
|
||||
tests:
|
||||
- Unit: Test RSS parsing
|
||||
- Unit: Test API client
|
||||
- Unit: Test source handlers
|
||||
- Integration: Test API calls
|
||||
|
||||
acceptance_criteria:
|
||||
- API client fetches data correctly
|
||||
- RSS parsing works
|
||||
- Source handlers work for all types
|
||||
- Errors handled gracefully
|
||||
|
||||
validation:
|
||||
- Run application and test API calls
|
||||
- Test RSS feed parsing
|
||||
- Test API source queries
|
||||
- Test error handling
|
||||
|
||||
notes:
|
||||
- Use `feed-parser` library for RSS parsing
|
||||
- Use `axios` for API calls
|
||||
- Handle rate limiting
|
||||
- Cache API responses
|
||||
- Add error handling for failed requests
|
||||
- Store API keys securely
|
||||
@@ -1,66 +0,0 @@
|
||||
# 52. Add Data Fetching and Caching
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-52
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [51]
|
||||
tags: [data-fetching, caching, performance, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement data fetching with caching
|
||||
- Cache podcast feeds and episodes
|
||||
- Cache search results
|
||||
- Cache popular shows
|
||||
- Handle cache invalidation
|
||||
|
||||
deliverables:
|
||||
- `src/utils/cache.ts` with cache management
|
||||
- `src/utils/data-fetcher.ts` with data fetching logic
|
||||
- `src/hooks/useCachedData.ts` with cache hook
|
||||
|
||||
steps:
|
||||
- Create `src/utils/cache.ts`:
|
||||
- `cacheFeed(feedUrl: string, data: Feed): void`
|
||||
- `getCachedFeed(feedUrl: string): Feed | null`
|
||||
- `cacheSearch(query: string, results: Podcast[]): void`
|
||||
- `getCachedSearch(query: string): Podcast[] | null`
|
||||
- `invalidateCache(type: string): void`
|
||||
- `cacheExpiration = 3600000` (1 hour)
|
||||
- Create `src/utils/data-fetcher.ts`:
|
||||
- `fetchFeedWithCache(feedUrl: string): Promise<Feed>`
|
||||
- `fetchEpisodesWithCache(feedUrl: string): Promise<Episode[]>`
|
||||
- `searchWithCache(query: string): Promise<Podcast[]>`
|
||||
- Use cache when available
|
||||
- Create `src/hooks/useCachedData.ts`:
|
||||
- `createSignal` for cached data
|
||||
- Fetch data with cache
|
||||
- Update cache on fetch
|
||||
- Handle cache expiration
|
||||
|
||||
tests:
|
||||
- Unit: Test cache management
|
||||
- Unit: Test data fetcher
|
||||
- Unit: Test cache hook
|
||||
|
||||
acceptance_criteria:
|
||||
- Data is cached correctly
|
||||
- Cache is used on subsequent requests
|
||||
- Cache invalidation works
|
||||
- Cache expiration handled
|
||||
|
||||
validation:
|
||||
- Run application and fetch data
|
||||
- Verify data is cached
|
||||
- Make same request and use cache
|
||||
- Test cache invalidation
|
||||
- Test cache expiration
|
||||
|
||||
notes:
|
||||
- Use localStorage for cache
|
||||
- Cache feeds, episodes, search results
|
||||
- Cache popular shows
|
||||
- Invalidate cache on feed update
|
||||
- Set cache expiration time
|
||||
- Add cache size limit
|
||||
- Clear cache on settings change
|
||||
@@ -1,65 +0,0 @@
|
||||
# 53. Build File-Based Storage for Sync
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-53
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [52]
|
||||
tags: [file-based-storage, sync, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement file-based storage for sync
|
||||
- Store feeds and settings in files
|
||||
- Implement backup functionality
|
||||
- Implement restore functionality
|
||||
- Handle file operations
|
||||
|
||||
deliverables:
|
||||
- `src/utils/file-storage.ts` with file storage
|
||||
- `src/utils/backup.ts` with backup functions
|
||||
- `src/utils/restore.ts` with restore functions
|
||||
|
||||
steps:
|
||||
- Create `src/utils/file-storage.ts`:
|
||||
- `saveFeedsToFile(feeds: Feed[]): Promise<void>`
|
||||
- `loadFeedsFromFile(): Promise<Feed[]>`
|
||||
- `saveSettingsToFile(settings: Settings): Promise<void>`
|
||||
- `loadSettingsFromFile(): Promise<Settings>`
|
||||
- Handle file operations and errors
|
||||
- Create `src/utils/backup.ts`:
|
||||
- `createBackup(): Promise<string>`
|
||||
- `backupFeeds(feeds: Feed[]): string`
|
||||
- `backupSettings(settings: Settings): string`
|
||||
- Include all user data
|
||||
- Create backup directory
|
||||
- Create `src/utils/restore.ts`:
|
||||
- `restoreFromBackup(backupData: string): Promise<void>`
|
||||
- `restoreFeeds(backupData: string): void`
|
||||
- `restoreSettings(backupData: string): void`
|
||||
- Validate backup data
|
||||
|
||||
tests:
|
||||
- Unit: Test file storage functions
|
||||
- Unit: Test backup functions
|
||||
- Unit: Test restore functions
|
||||
|
||||
acceptance_criteria:
|
||||
- File storage works correctly
|
||||
- Backup creates valid files
|
||||
- Restore loads data correctly
|
||||
- File operations handle errors
|
||||
|
||||
validation:
|
||||
- Run application and test file storage
|
||||
- Create backup
|
||||
- Restore from backup
|
||||
- Test with different data sizes
|
||||
- Test error cases
|
||||
|
||||
notes:
|
||||
- Store files in `data/` directory
|
||||
- Use JSON format for storage
|
||||
- Include version info for compatibility
|
||||
- Add file encryption option (optional)
|
||||
- Test with large files
|
||||
- Handle file permission errors
|
||||
@@ -1,67 +0,0 @@
|
||||
# 54. Set Up Testing Framework (Snapshot Testing)
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-54
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [53]
|
||||
tags: [testing, framework, setup, opentui]
|
||||
|
||||
objective:
|
||||
- Set up OpenTUI testing framework
|
||||
- Configure test runner
|
||||
- Set up snapshot testing
|
||||
- Configure test environment
|
||||
|
||||
deliverables:
|
||||
- `tests/` directory with test structure
|
||||
- `tests/setup.ts` with test setup
|
||||
- `tests/config.ts` with test configuration
|
||||
- `package.json` with test scripts
|
||||
|
||||
steps:
|
||||
- Install testing dependencies:
|
||||
- `@opentui/testing`
|
||||
- `@opentui/react` (for testing)
|
||||
- `@opentui/solid` (for testing)
|
||||
- `bun test` (built-in test runner)
|
||||
- Configure test environment:
|
||||
- Set up test renderer
|
||||
- Configure test options
|
||||
- Set up test fixtures
|
||||
- Create test structure:
|
||||
- `tests/components/` for component tests
|
||||
- `tests/integration/` for integration tests
|
||||
- `tests/utils/` for utility tests
|
||||
- `tests/fixtures/` for test data
|
||||
- Add test scripts to `package.json`:
|
||||
- `test`: Run all tests
|
||||
- `test:watch`: Run tests in watch mode
|
||||
- `test:coverage`: Run tests with coverage
|
||||
- `test:components`: Run component tests
|
||||
- `test:integration`: Run integration tests
|
||||
|
||||
tests:
|
||||
- Unit: Verify testing framework is set up
|
||||
- Integration: Verify test scripts work
|
||||
- Component: Verify snapshot testing works
|
||||
|
||||
acceptance_criteria:
|
||||
- Testing framework installed and configured
|
||||
- Test scripts work correctly
|
||||
- Snapshot testing configured
|
||||
- Test environment set up
|
||||
|
||||
validation:
|
||||
- Run `bun test` to execute all tests
|
||||
- Run `bun test:components` to run component tests
|
||||
- Run `bun test:coverage` for coverage report
|
||||
- Check all tests pass
|
||||
|
||||
notes:
|
||||
- Use OpenTUI's testing framework for snapshot testing
|
||||
- Test components in isolation
|
||||
- Use test fixtures for common data
|
||||
- Mock external dependencies
|
||||
- Keep tests fast and focused
|
||||
- Add CI/CD integration for automated testing
|
||||
@@ -1,68 +0,0 @@
|
||||
# 55. Write Component Tests
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-55
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [54]
|
||||
tags: [testing, components, snapshot, solidjs]
|
||||
|
||||
objective:
|
||||
- Write component tests for all major components
|
||||
- Test component rendering
|
||||
- Test component behavior
|
||||
- Test component interactions
|
||||
|
||||
deliverables:
|
||||
- `tests/components/Navigation.test.tsx`
|
||||
- `tests/components/FeedList.test.tsx`
|
||||
- `tests/components/SearchBar.test.tsx`
|
||||
- `tests/components/Player.test.tsx`
|
||||
- `tests/components/SettingsScreen.test.tsx`
|
||||
- Test coverage for all components
|
||||
|
||||
steps:
|
||||
- Write component tests:
|
||||
- `tests/components/Navigation.test.tsx`:
|
||||
- Test Navigation renders with correct tabs
|
||||
- Test tab selection updates state
|
||||
- Test keyboard navigation
|
||||
- `tests/components/FeedList.test.tsx`:
|
||||
- Test FeedList renders with feeds
|
||||
- Test FeedItem displays correctly
|
||||
- Test public/private filtering
|
||||
- Test keyboard navigation
|
||||
- `tests/components/SearchBar.test.tsx`:
|
||||
- Test search bar accepts input
|
||||
- Test search button triggers search
|
||||
- Test clear button clears input
|
||||
- `tests/components/Player.test.tsx`:
|
||||
- Test Player UI displays correctly
|
||||
- Test playback controls work
|
||||
- Test waveform visualization
|
||||
- `tests/components/SettingsScreen.test.tsx`:
|
||||
- Test SettingsScreen renders correctly
|
||||
- Test settings navigation
|
||||
- Test settings save/load
|
||||
|
||||
tests:
|
||||
- Unit: Run all component tests
|
||||
- Coverage: Verify component coverage
|
||||
|
||||
acceptance_criteria:
|
||||
- All component tests pass
|
||||
- Test coverage > 80%
|
||||
- Component behavior verified
|
||||
|
||||
validation:
|
||||
- Run `bun test:components` to execute component tests
|
||||
- Run `bun test --coverage` for coverage report
|
||||
- Fix any failing tests
|
||||
|
||||
notes:
|
||||
- Use OpenTUI testing framework
|
||||
- Test components in isolation
|
||||
- Mock external dependencies
|
||||
- Use test fixtures for data
|
||||
- Keep tests fast
|
||||
- Test both happy path and error cases
|
||||
@@ -1,57 +0,0 @@
|
||||
# 56. Add Keyboard Interaction Tests
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-56
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [55]
|
||||
tags: [testing, keyboard, interaction, solidjs]
|
||||
|
||||
objective:
|
||||
- Write keyboard interaction tests
|
||||
- Test keyboard shortcuts
|
||||
- Test keyboard navigation
|
||||
- Test input field keyboard handling
|
||||
|
||||
deliverables:
|
||||
- `tests/integration/navigation.test.tsx`
|
||||
- `tests/integration/keyboard.test.tsx`
|
||||
- `tests/integration/inputs.test.tsx`
|
||||
|
||||
steps:
|
||||
- Write keyboard tests:
|
||||
- `tests/integration/navigation.test.tsx`:
|
||||
- Test arrow keys navigate tabs
|
||||
- Test enter selects tab
|
||||
- Test escape closes modal
|
||||
- `tests/integration/keyboard.test.tsx`:
|
||||
- Test Ctrl+Q quits app
|
||||
- Test Ctrl+S saves settings
|
||||
- Test space plays/pauses
|
||||
- Test arrow keys for playback
|
||||
- `tests/integration/inputs.test.tsx`:
|
||||
- Test input field accepts text
|
||||
- Test keyboard input in search bar
|
||||
- Test code input validation
|
||||
|
||||
tests:
|
||||
- Unit: Run keyboard tests
|
||||
- Integration: Test keyboard interactions
|
||||
|
||||
acceptance_criteria:
|
||||
- All keyboard tests pass
|
||||
- Keyboard shortcuts work correctly
|
||||
- Input fields handle keyboard input
|
||||
|
||||
validation:
|
||||
- Run `bun test` to execute all tests
|
||||
- Manually test keyboard shortcuts
|
||||
- Verify keyboard navigation works
|
||||
|
||||
notes:
|
||||
- Use OpenTUI testing framework
|
||||
- Test keyboard events
|
||||
- Mock keyboard input
|
||||
- Test on different terminals
|
||||
- Document keyboard shortcuts
|
||||
- Test modifier key combinations
|
||||
@@ -1,63 +0,0 @@
|
||||
# 57. Implement Error Handling
|
||||
|
||||
meta:
|
||||
id: podcast-tui-app-57
|
||||
feature: podcast-tui-app
|
||||
priority: P1
|
||||
depends_on: [56]
|
||||
tags: [error-handling, debugging, solidjs]
|
||||
|
||||
objective:
|
||||
- Implement error handling throughout the app
|
||||
- Handle API errors
|
||||
- Handle file errors
|
||||
- Handle user input errors
|
||||
- Display error messages
|
||||
|
||||
deliverables:
|
||||
- `src/utils/error-handler.ts` with error handling
|
||||
- `src/components/ErrorDisplay.tsx` with error UI
|
||||
- `src/components/LoadingSpinner.tsx` with loading UI
|
||||
|
||||
steps:
|
||||
- Create `src/utils/error-handler.ts`:
|
||||
- `handleError(error: Error, context: string): void`
|
||||
- Log errors to console
|
||||
- Display user-friendly error messages
|
||||
- Handle different error types
|
||||
- Create `src/components/ErrorDisplay.tsx`:
|
||||
- Display error message
|
||||
- Error type indicator
|
||||
- Retry button
|
||||
- Error details (expandable)
|
||||
- Create `src/components/LoadingSpinner.tsx`:
|
||||
- Loading indicator
|
||||
- Loading message
|
||||
- Different loading states
|
||||
|
||||
tests:
|
||||
- Unit: Test error handler
|
||||
- Unit: Test error display
|
||||
- Integration: Test error handling flow
|
||||
|
||||
acceptance_criteria:
|
||||
- Errors are caught and handled
|
||||
- Error messages display correctly
|
||||
- Retry functionality works
|
||||
- User sees helpful error messages
|
||||
|
||||
validation:
|
||||
- Run application and trigger errors
|
||||
- Test API errors
|
||||
- Test file errors
|
||||
- Test input errors
|
||||
- Verify error messages display
|
||||
|
||||
notes:
|
||||
- Handle network errors (API calls)
|
||||
- Handle file errors (import/export)
|
||||
- Handle validation errors (inputs)
|
||||
- Handle parsing errors (RSS feeds)
|
||||
- Display errors in user-friendly way
|
||||
- Add error logging for debugging
|
||||
- Consider adding Sentry for production
|
||||
@@ -1,56 +0,0 @@
|
||||
# 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
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -1,56 +0,0 @@
|
||||
# 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
|
||||
@@ -1,56 +0,0 @@
|
||||
# 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
|
||||
@@ -1,57 +0,0 @@
|
||||
# 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
|
||||
@@ -1,58 +0,0 @@
|
||||
# 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
|
||||
@@ -1,205 +0,0 @@
|
||||
# Podcast TUI App
|
||||
|
||||
Objective: Build a SolidJS-based podcast player TUI with feeds, search, player, and file sync
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Project Foundation 🏗️
|
||||
**Setup and configure the development environment**
|
||||
|
||||
- [x] 01 — Initialize SolidJS OpenTUI project with Bun → `01-project-setup.md`
|
||||
- [x] 13 — Set up TypeScript configuration and build system → `13-typescript-config.md`
|
||||
- [x] 14 — Create project directory structure and dependencies → `14-project-structure.md`
|
||||
- [x] 15 — Build responsive layout system (Flexbox) → `15-responsive-layout.md`
|
||||
|
||||
**Dependencies:** 01 -> 02 -> 03 -> 04 -> 05 -> 06 -> 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Core Architecture 🏗️
|
||||
**Build the main application shell and navigation**
|
||||
|
||||
- [x] 02 — Create main app shell with tab navigation → `02-core-layout.md`
|
||||
- [x] 16 — Implement tab navigation component → `16-tab-navigation.md`
|
||||
- [x] 17 — Add keyboard shortcuts and navigation handling → `17-keyboard-handling.md`
|
||||
|
||||
**Dependencies:** 01 -> 02 -> 03 -> 04 -> 05 -> 06 -> 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: File Sync & Data Import/Export 💾
|
||||
**Implement direct file sync with JSON/XML formats**
|
||||
|
||||
- [x] 03 — Implement direct file sync (JSON/XML import/export) → `03-file-sync.md`
|
||||
- [x] 18 — Create sync data models (JSON/XML formats) → `18-sync-data-models.md`
|
||||
- [x] 19 — Build import/export functionality → `19-import-export.md`
|
||||
- [x] 20 — Create file picker UI for import → `20-file-picker.md`
|
||||
- [x] 21 — Build sync status indicator → `21-sync-status.md`
|
||||
- [x] 22 — Add backup/restore functionality → `22-backup-restore.md`
|
||||
|
||||
**Dependencies:** 02 -> 03 -> 04 -> 05 -> 06 -> 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Authentication System 🔐
|
||||
**Implement authentication (MUST be implemented as optional for users)**
|
||||
|
||||
- [x] 04 — Build optional authentication system → `04-authentication.md`
|
||||
- [x] 23 — Create authentication state (disabled by default) → `23-auth-state.md`
|
||||
- [x] 24 — Build simple login screen (email/password) → `24-login-screen.md`
|
||||
- [x] 25 — Implement 8-character code validation flow → `25-code-validation.md`
|
||||
- [x] 26 — Add OAuth placeholder screens (document limitations) → `26-oauth-placeholders.md`
|
||||
- [x] 27 — Create sync-only user profile → `27-sync-profile.md`
|
||||
|
||||
**Dependencies:** 03 -> 04 -> 05 -> 06 -> 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Feed Management 📻
|
||||
**Create feed data models and management UI**
|
||||
|
||||
- [x] 05 — Create feed data models and types → `05-feed-management.md`
|
||||
- [x] 28 — Create feed data models and types → `28-feed-types.md`
|
||||
- [x] 29 — Build feed list component (public/private feeds) → `29-feed-list.md`
|
||||
- [x] 30 — Implement feed source management (add/remove sources) → `30-source-management.md`
|
||||
- [x] 31 — Add reverse chronological ordering → `31-reverse-chronological.md`
|
||||
- [x] 32 — Create feed detail view → `32-feed-detail.md`
|
||||
|
||||
**Dependencies:** 01 -> 02 -> 03 -> 04 -> 05 -> 06 -> 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Search Functionality 🔍
|
||||
**Implement multi-source search interface**
|
||||
|
||||
- [x] 06 — Implement multi-source search interface → `06-search.md`
|
||||
- [x] 33 — Create search interface → `33-search-interface.md`
|
||||
- [x] 34 — Implement multi-source search → `34-multi-source-search.md`
|
||||
- [x] 35 — Add search results display → `35-search-results.md`
|
||||
- [x] 36 — Build search history with persistent storage → `36-search-history.md`
|
||||
|
||||
**Dependencies:** 05 -> 06 -> 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Discover Feed 🌟
|
||||
**Build discover page with popular shows**
|
||||
|
||||
- [x] 07 — Build discover feed with popular shows → `07-discover.md`
|
||||
- [x] 37 — Create popular shows data structure → `37-popular-shows.md`
|
||||
- [x] 38 — Build discover page component → `38-discover-page.md`
|
||||
- [x] 39 — Add trending shows display → `39-trending-shows.md`
|
||||
- [x] 40 — Implement category filtering → `40-category-filtering.md`
|
||||
|
||||
**Dependencies:** 06 -> 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 8: Player Component 🎵
|
||||
**Create player UI with waveform visualization**
|
||||
|
||||
- [x] 08 — Create player UI with waveform visualization → `08-player.md`
|
||||
- [x] 41 — Create player UI layout → `41-player-layout.md`
|
||||
- [x] 42 — Implement playback controls → `42-playback-controls.md`
|
||||
- [x] 43 — Build ASCII waveform visualization → `43-waveform-visualization.md`
|
||||
- [x] 44 — Add progress tracking and seek → `44-progress-tracking.md`
|
||||
- [x] 45 — Implement audio integration (system/external player) → `45-audio-integration.md`
|
||||
|
||||
**Dependencies:** 07 -> 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 9: Settings & Configuration ⚙️
|
||||
**Build settings screen and preferences**
|
||||
|
||||
- [x] 09 — Build settings screen and preferences → `09-settings.md`
|
||||
- [x] 46 — Create settings screen → `46-settings-screen.md`
|
||||
- [x] 47 — Add source management UI → `47-source-management-ui.md`
|
||||
- [x] 48 — Build user preferences → `48-user-preferences.md`
|
||||
- [x] 49 — Implement data persistence (localStorage/file-based) → `49-data-persistence.md`
|
||||
|
||||
**Dependencies:** 08 -> 09 -> 10 -> 11 -> 12
|
||||
|
||||
---
|
||||
|
||||
## Phase 10: Theme System 🎨
|
||||
**Implement theming with Catppuccin, Gruvbox, Tokyo, Nord, and custom themes**
|
||||
|
||||
- [x] 59 — Create theme system architecture → `59-theme-system.md`
|
||||
- [x] 60 — Implement default theme (system terminal) → `60-default-theme.md`
|
||||
- [x] 61 — Add Catppuccin theme → `61-catppuccin-theme.md`
|
||||
- [x] 62 — Add Gruvbox theme → `62-gruvbox-theme.md`
|
||||
- [x] 63 — Add Tokyo theme → `63-tokyo-theme.md`
|
||||
- [x] 64 — Add Nord theme → `64-nord-theme.md`
|
||||
- [ ] 65 — Implement custom theme editor → `65-custom-theme.md`
|
||||
- [x] 66 — Add theme selector in settings → `66-theme-selector.md`
|
||||
|
||||
**Dependencies:** 09 -> 59 -> 60 -> 61 -> 62 -> 63 -> 64 -> 65 -> 66 -> 10
|
||||
|
||||
---
|
||||
|
||||
## Phase 11: State Management & Data Layer 🗄️
|
||||
**Create global state store and data layer**
|
||||
|
||||
- [x] 10 — Create global state store and data layer → `10-state-management.md`
|
||||
- [x] 50 — Create global state store (Signals) → `50-global-state-store.md`
|
||||
- [x] 51 — Implement API client for podcast sources → `51-api-client.md`
|
||||
- [x] 52 — Add data fetching and caching → `52-data-fetching-caching.md`
|
||||
- [x] 53 — Build file-based storage for sync → `53-file-based-storage.md`
|
||||
|
||||
**Dependencies:** 66 -> 10
|
||||
|
||||
---
|
||||
|
||||
## Phase 12: Testing & Quality Assurance ✅
|
||||
**Set up testing framework and write comprehensive tests**
|
||||
|
||||
- [ ] 11 — Set up testing framework and write tests → `11-testing.md`
|
||||
- [ ] 54 — Set up testing framework (snapshot testing) → `54-testing-framework.md`
|
||||
- [ ] 55 — Write component tests → `55-component-tests.md`
|
||||
- [ ] 56 — Add keyboard interaction tests → `56-keyboard-tests.md`
|
||||
- [x] 57 — Implement error handling → `57-error-handling.md`
|
||||
- [x] 58 — Add loading states and transitions → `58-loading-states.md`
|
||||
|
||||
**Dependencies:** 10 -> 11
|
||||
|
||||
---
|
||||
|
||||
## Phase 13: OAuth & External Integration 🔗
|
||||
**Complete OAuth implementation and external integrations**
|
||||
|
||||
- [x] 26 — Add OAuth placeholder screens (document limitations) → `26-oauth-placeholders.md`
|
||||
- [ ] 67 — Implement browser redirect flow for OAuth → `67-browser-redirect.md`
|
||||
- [ ] 68 — Build QR code display for mobile verification → `68-qr-code-display.md`
|
||||
|
||||
**Dependencies:** 04 -> 67 -> 68
|
||||
|
||||
---
|
||||
|
||||
## Phase 14: Deployment & Optimization 🚀
|
||||
**Optimize bundle and create documentation**
|
||||
|
||||
- [ ] 12 — Optimize bundle and create documentation → `12-optimization.md`
|
||||
|
||||
**Dependencies:** 11
|
||||
|
||||
---
|
||||
|
||||
## Dependencies Summary
|
||||
- **Phase dependencies** ensure logical implementation order
|
||||
- **Authentication MUST be implemented** (just optional for user login)
|
||||
- **Theme system** is required and comes before state management
|
||||
|
||||
---
|
||||
|
||||
## Exit criteria
|
||||
- The feature is complete when all 58 tasks are marked [x] done
|
||||
- Complete, functional podcast TUI application with all core features working
|
||||
- File sync (JSON/XML) successfully imports/exports feeds and settings
|
||||
- Authentication system is fully implemented (optional for users)
|
||||
- Player has waveform visualization and playback controls
|
||||
- All navigation and keyboard shortcuts work correctly
|
||||
- Theme system works with Catppuccin, Gruvbox, Tokyo, Nord, and custom themes
|
||||
- Application runs on Bun with OpenTUI
|
||||
45
tasks/rss-content-parsing/03-rss-content-detection.md
Normal file
45
tasks/rss-content-parsing/03-rss-content-detection.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 03. Add RSS Content Type Detection
|
||||
|
||||
meta:
|
||||
id: rss-content-parsing-03
|
||||
feature: rss-content-parsing
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [rss, parsing, utilities]
|
||||
|
||||
objective:
|
||||
- Create utility to detect if RSS feed content is HTML or plain text
|
||||
- Analyze content type in description and other text fields
|
||||
- Return appropriate parsing strategy
|
||||
|
||||
deliverables:
|
||||
- Content type detection function
|
||||
- Type classification utility
|
||||
- Integration points for different parsers
|
||||
|
||||
steps:
|
||||
1. Create `src/utils/rss-content-detector.ts`
|
||||
2. Implement content type detection based on HTML tags
|
||||
3. Add detection for common HTML entities and tags
|
||||
4. Return type enum (HTML, PLAIN_TEXT, UNKNOWN)
|
||||
5. Add unit tests for detection accuracy
|
||||
|
||||
tests:
|
||||
- Unit: Test HTML detection with various HTML snippets
|
||||
- Unit: Test plain text detection with text-only content
|
||||
- Unit: Test edge cases (mixed content, malformed HTML)
|
||||
|
||||
acceptance_criteria:
|
||||
- Function correctly identifies HTML vs plain text content
|
||||
- Handles common HTML patterns and entities
|
||||
- Returns UNKNOWN for unclassifiable content
|
||||
|
||||
validation:
|
||||
- Test with HTML description from real RSS feeds
|
||||
- Test with plain text descriptions
|
||||
- Verify UNKNOWN cases are handled gracefully
|
||||
|
||||
notes:
|
||||
- Look for common HTML tags: <div>, <p>, <br>, <a>, <b>, <i>
|
||||
- Check for HTML entities: <, >, &, ", '
|
||||
- Consider content length threshold for HTML detection
|
||||
47
tasks/rss-content-parsing/04-html-content-extraction.md
Normal file
47
tasks/rss-content-parsing/04-html-content-extraction.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 04. Implement HTML Content Extraction
|
||||
|
||||
meta:
|
||||
id: rss-content-parsing-04
|
||||
feature: rss-content-parsing
|
||||
priority: P2
|
||||
depends_on: [rss-content-parsing-03]
|
||||
tags: [rss, parsing, html]
|
||||
|
||||
objective:
|
||||
- Parse HTML content from RSS feed descriptions
|
||||
- Extract and sanitize text content
|
||||
- Convert HTML to plain text for display
|
||||
|
||||
deliverables:
|
||||
- HTML to text conversion utility
|
||||
- Sanitization function for XSS prevention
|
||||
- Updated RSS parser integration
|
||||
|
||||
steps:
|
||||
1. Create `src/utils/html-to-text.ts`
|
||||
2. Implement HTML-to-text conversion algorithm
|
||||
3. Add XSS sanitization for extracted content
|
||||
4. Handle common HTML elements (paragraphs, lists, links)
|
||||
5. Update `parseRSSFeed()` to use new HTML parser
|
||||
|
||||
tests:
|
||||
- Unit: Test HTML to text conversion accuracy
|
||||
- Integration: Test with HTML-rich RSS feeds
|
||||
- Security: Test XSS sanitization with malicious HTML
|
||||
|
||||
acceptance_criteria:
|
||||
- HTML content is converted to readable plain text
|
||||
- No HTML tags remain in output
|
||||
- Sanitization prevents XSS attacks
|
||||
- Links are properly converted to text format
|
||||
|
||||
validation:
|
||||
- Test with podcast descriptions containing HTML
|
||||
- Verify text is readable and properly formatted
|
||||
- Check for any HTML tag remnants
|
||||
|
||||
notes:
|
||||
- Use existing `decodeEntities()` function from rss-parser.ts
|
||||
- Preserve line breaks and paragraph structure
|
||||
- Convert URLs to text format (e.g., "Visit example.com")
|
||||
- Consider using a lightweight HTML parser like `html-escaper` or `cheerio`
|
||||
45
tasks/rss-content-parsing/05-plain-text-content-handling.md
Normal file
45
tasks/rss-content-parsing/05-plain-text-content-handling.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 05. Maintain Plain Text Fallback Handling
|
||||
|
||||
meta:
|
||||
id: rss-content-parsing-05
|
||||
feature: rss-content-parsing
|
||||
priority: P2
|
||||
depends_on: [rss-content-parsing-03]
|
||||
tags: [rss, parsing, fallback]
|
||||
|
||||
objective:
|
||||
- Ensure plain text RSS feeds continue to work correctly
|
||||
- Maintain backward compatibility with existing functionality
|
||||
- Handle mixed content scenarios
|
||||
|
||||
deliverables:
|
||||
- Updated parseRSSFeed() for HTML support
|
||||
- Plain text handling path remains unchanged
|
||||
- Error handling for parsing failures
|
||||
|
||||
steps:
|
||||
1. Update `parseRSSFeed()` to use content type detection
|
||||
2. Route to HTML parser or plain text path based on type
|
||||
3. Add error handling for parsing failures
|
||||
4. Test with both HTML and plain text feeds
|
||||
5. Verify backward compatibility
|
||||
|
||||
tests:
|
||||
- Integration: Test with plain text RSS feeds
|
||||
- Integration: Test with HTML RSS feeds
|
||||
- Regression: Verify existing functionality still works
|
||||
|
||||
acceptance_criteria:
|
||||
- Plain text feeds parse without errors
|
||||
- HTML feeds parse correctly with sanitization
|
||||
- No regression in existing functionality
|
||||
|
||||
validation:
|
||||
- Test with various podcast RSS feeds
|
||||
- Verify descriptions display correctly
|
||||
- Check for any parsing errors
|
||||
|
||||
notes:
|
||||
- Plain text path uses existing `decodeEntities()` logic
|
||||
- Keep existing parseRSSFeed() structure for plain text
|
||||
- Add logging for parsing strategy selection
|
||||
18
tasks/rss-content-parsing/README.md
Normal file
18
tasks/rss-content-parsing/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# HTML vs Plain Text RSS Parsing
|
||||
|
||||
Objective: Detect and handle both HTML and plain text content in RSS feeds
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [ ] 03 — Add content type detection utility → `03-rss-content-detection.md`
|
||||
- [ ] 04 — Implement HTML content parsing → `04-html-content-extraction.md`
|
||||
- [ ] 05 — Maintain plain text fallback handling → `05-plain-text-content-handling.md`
|
||||
|
||||
Dependencies
|
||||
- 03 -> 04
|
||||
- 03 -> 05
|
||||
|
||||
Exit criteria
|
||||
- RSS feeds with HTML content are properly parsed and sanitized
|
||||
- Plain text feeds continue to work as before
|
||||
45
tasks/text-selection-copy/01-text-selection-copy.md
Normal file
45
tasks/text-selection-copy/01-text-selection-copy.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 01. Add Text Selection Event Handling
|
||||
|
||||
meta:
|
||||
id: text-selection-copy-01
|
||||
feature: text-selection-copy
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [ui, events, clipboard]
|
||||
|
||||
objective:
|
||||
- Add event listeners for text selection events in the TUI components
|
||||
- Detect when text is selected by the user
|
||||
- Prepare infrastructure for clipboard copy on selection release
|
||||
|
||||
deliverables:
|
||||
- New event bus events for text selection
|
||||
- Selection state tracking in app store
|
||||
- Event listener setup in main components
|
||||
|
||||
steps:
|
||||
1. Create new event bus events for text selection (`selection.start`, `selection.end`)
|
||||
2. Add selection state to app store (selectedText, selectionStart, selectionEnd)
|
||||
3. Add event listeners to key components that display text
|
||||
4. Track selection state changes in real-time
|
||||
5. Add cleanup handlers for event listeners
|
||||
|
||||
tests:
|
||||
- Unit: Test event bus event emission for selection events
|
||||
- Integration: Verify selection state updates when text is selected
|
||||
- Manual: Select text in different components and verify state tracking
|
||||
|
||||
acceptance_criteria:
|
||||
- Selection events are emitted when text is selected
|
||||
- Selection state is properly tracked in app store
|
||||
- Event listeners are correctly registered and cleaned up
|
||||
|
||||
validation:
|
||||
- Run the app and select text in Player component
|
||||
- Check app store selection state is updated
|
||||
- Verify event bus receives selection events
|
||||
|
||||
notes:
|
||||
- Need to handle terminal-specific selection behavior
|
||||
- Selection might not work in all terminal emulators
|
||||
- Consider using OSC 52 for clipboard operations
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user