file ordering
This commit is contained in:
128
tasks/INDEX.md
128
tasks/INDEX.md
@@ -1,128 +0,0 @@
|
||||
# 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/`
|
||||
|
||||
### 8. Audio Playback Fix
|
||||
**Feature:** Fix non-functional volume/speed controls and add multimedia key support
|
||||
**Tasks:** 5 tasks
|
||||
**Directory:** `tasks/audio-playback-fix/`
|
||||
|
||||
## Task Summary
|
||||
|
||||
**Total Features:** 8
|
||||
**Total Tasks:** 32
|
||||
**Critical Path:** Feature 7 (Config Persistence) - 5 tasks, Feature 8 (Audio Playback Fix) - 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
|
||||
|
||||
### Feature 8: Audio Playback Fix
|
||||
- 28 -> 29
|
||||
- 29 -> 30
|
||||
- 30 -> 31
|
||||
- 31 -> 32
|
||||
|
||||
## 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
|
||||
- 28: Fix volume and speed controls in audio backends
|
||||
- 32: Test multimedia controls across platforms
|
||||
|
||||
**P2 (High):**
|
||||
- All other tasks (01-22, 27, 29-31)
|
||||
|
||||
**P3 (Medium):**
|
||||
- 09: Optimize waveform rendering performance
|
||||
- 13: Add loading indicator for pagination
|
||||
- 19: Create download queue management
|
||||
- 30: Add multimedia key detection and handling
|
||||
- 31: Implement platform-specific media stream integration
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review all task files for accuracy
|
||||
2. Confirm task dependencies
|
||||
3. Start with P1 tasks (Feature 7 or Feature 8)
|
||||
4. Follow dependency order within each feature
|
||||
5. Mark tasks complete as they're finished
|
||||
@@ -1,65 +0,0 @@
|
||||
# 01. Fix volume and speed controls in audio backends [x]
|
||||
|
||||
meta:
|
||||
id: audio-playback-fix-01
|
||||
feature: audio-playback-fix
|
||||
priority: P1
|
||||
depends_on: []
|
||||
tags: [implementation, backend-fix, testing-required]
|
||||
|
||||
objective:
|
||||
- Fix non-functional volume and speed controls in audio player backends (mpv, ffplay, afplay)
|
||||
- Implement proper error handling and validation for volume/speed commands
|
||||
- Ensure commands are successfully received and applied by the audio player
|
||||
|
||||
deliverables:
|
||||
- Fixed `MpvBackend.setVolume()` and `MpvBackend.setSpeed()` methods with proper IPC command validation
|
||||
- Enhanced `AfplayBackend.setVolume()` and `AfplayBackend.setSpeed()` for runtime changes
|
||||
- Added command response validation in all backends
|
||||
- Unit tests for volume and speed control methods
|
||||
|
||||
steps:
|
||||
- Step 1: Analyze current IPC implementation in MpvBackend (lines 206-223)
|
||||
- Step 2: Implement proper response validation for setVolume and setSpeed IPC commands
|
||||
- Step 3: Fix afplay backend to apply volume/speed changes at runtime (currently only on next play)
|
||||
- Step 4: Add error handling and logging for failed volume/speed commands
|
||||
- Step 5: Add unit tests in `src/utils/audio-player.test.ts` for volume/speed methods
|
||||
- Step 6: Verify volume changes apply immediately and persist across playback
|
||||
- Step 7: Verify speed changes apply immediately and persist across playback
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test MpvBackend.setVolume() sends correct IPC command and receives valid response
|
||||
- Test MpvBackend.setSpeed() sends correct IPC command and receives valid response
|
||||
- Test AfplayBackend.setVolume() applies volume immediately
|
||||
- Test AfplayBackend.setSpeed() applies speed immediately
|
||||
- Test volume clamp values (0-1 range)
|
||||
- Test speed clamp values (0.25-3 range)
|
||||
- Integration:
|
||||
- Test volume control through Player component UI
|
||||
- Test speed control through Player component UI
|
||||
- Test volume/speed changes persist across pause/resume cycles
|
||||
- Test volume/speed changes persist across track changes
|
||||
|
||||
acceptance_criteria:
|
||||
- Volume slider in Player component changes volume in real-time
|
||||
- Speed controls in Player component change playback speed in real-time
|
||||
- Volume changes are visible in system audio output
|
||||
- Speed changes are immediately reflected in playback rate
|
||||
- No errors logged when changing volume or speed
|
||||
- Volume/speed settings persist when restarting the app
|
||||
|
||||
validation:
|
||||
- Run `bun test src/utils/audio-player.test.ts` to verify unit tests pass
|
||||
- Test volume control using Up/Down arrow keys in Player
|
||||
- Test speed control using 'S' key in Player
|
||||
- Verify volume level is visible in PlaybackControls component
|
||||
- Verify speed level is visible in PlaybackControls component
|
||||
- Check console logs for any IPC errors
|
||||
|
||||
notes:
|
||||
- mpv backend uses JSON IPC over Unix socket - need to validate response format
|
||||
- afplay backend needs to restart process for volume/speed changes (current behavior)
|
||||
- ffplay backend doesn't support runtime volume/speed changes (document limitation)
|
||||
- Volume and speed state is stored in backend class properties and should be updated on successful commands
|
||||
- Reference: src/utils/audio-player.ts lines 206-223 (mpv send method), lines 789-791 (afplay setVolume), lines 793-795 (afplay setSpeed)
|
||||
@@ -1,61 +0,0 @@
|
||||
# 02. Add multimedia key detection and handling [x]
|
||||
|
||||
meta:
|
||||
id: audio-playback-fix-02
|
||||
feature: audio-playback-fix
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [implementation, keyboard, multimedia]
|
||||
|
||||
objective:
|
||||
- Implement detection and handling of multimedia keys (Play/Pause, Next/Previous, Volume Up/Down)
|
||||
- Create reusable multimedia key handler hook
|
||||
- Map multimedia keys to audio playback actions
|
||||
|
||||
deliverables:
|
||||
- New `useMultimediaKeys()` hook in `src/hooks/useMultimediaKeys.ts`
|
||||
- Integration with existing audio hook to handle multimedia key events
|
||||
- Documentation of supported multimedia keys and their mappings
|
||||
|
||||
steps:
|
||||
- Step 1: Research @opentui/solid keyboard event types for multimedia key detection
|
||||
- Step 2: Create `useMultimediaKeys()` hook with event listener for multimedia keys
|
||||
- Step 3: Define multimedia key mappings (Play/Pause, Next, Previous, Volume Up, Volume Down)
|
||||
- Step 4: Integrate hook with audio hook to trigger playback actions
|
||||
- Step 5: Add keyboard event filtering to prevent conflicts with other shortcuts
|
||||
- Step 6: Test multimedia key detection across different platforms
|
||||
- Step 7: Add help text to Player component showing multimedia key bindings
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test multimedia key events are detected correctly
|
||||
- Test key mapping functions return correct audio actions
|
||||
- Test hook cleanup removes event listeners
|
||||
- Integration:
|
||||
- Test Play/Pause key toggles playback
|
||||
- Test Next/Previous keys skip tracks (placeholder for future)
|
||||
- Test Volume Up/Down keys adjust volume
|
||||
- Test keys don't trigger when input is focused
|
||||
- Test keys don't trigger when player is not focused
|
||||
|
||||
acceptance_criteria:
|
||||
- Multimedia keys are detected and logged when pressed
|
||||
- Play/Pause key toggles audio playback
|
||||
- Volume Up/Down keys adjust volume level
|
||||
- Keys work when Player component is focused
|
||||
- Keys don't interfere with other keyboard shortcuts
|
||||
- Help text displays multimedia key bindings
|
||||
|
||||
validation:
|
||||
- Press multimedia keys while Player is focused and verify playback responds
|
||||
- Check console logs for detected multimedia key events
|
||||
- Verify Up/Down keys adjust volume display in Player component
|
||||
- Verify Space key still works for play/pause
|
||||
- Test in different terminal emulators (iTerm2, Terminal.app, etc.)
|
||||
|
||||
notes:
|
||||
- Multimedia key detection may vary by platform and terminal emulator
|
||||
- Common multimedia keys: Space (Play/Pause), ArrowUp (Volume Up), ArrowDown (Volume Down)
|
||||
- Some terminals don't pass multimedia keys to application
|
||||
- May need to use platform-specific APIs or terminal emulator-specific key codes
|
||||
- Reference: @opentui/solid keyboard event types and existing useKeyboard hook patterns
|
||||
@@ -1,66 +0,0 @@
|
||||
# 03. Implement platform-specific media stream integration [x]
|
||||
|
||||
meta:
|
||||
id: audio-playback-fix-03
|
||||
feature: audio-playback-fix
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [implementation, platform-integration, media-apis]
|
||||
|
||||
objective:
|
||||
- Register audio player with platform-specific media frameworks
|
||||
- Enable OS media controls (notification center, lock screen, multimedia keys)
|
||||
- Support macOS AVFoundation, Windows Media Foundation, and Linux PulseAudio/GStreamer
|
||||
|
||||
deliverables:
|
||||
- Platform-specific media registration module in `src/utils/media-registry.ts`
|
||||
- Integration with audio hook to register/unregister media streams
|
||||
- Platform detection and conditional registration logic
|
||||
- Documentation of supported platforms and media APIs
|
||||
|
||||
steps:
|
||||
- Step 1: Research platform-specific media API integration options
|
||||
- Step 2: Create `MediaRegistry` class with platform detection
|
||||
- Step 3: Implement macOS AVFoundation integration (AVPlayer + AVAudioSession)
|
||||
- Step 4: Implement Windows Media Foundation integration (MediaSession + PlaybackInfo)
|
||||
- Step 5: Implement Linux PulseAudio/GStreamer integration (Mpris or libpulse)
|
||||
- Step 6: Integrate with audio hook to register media stream on play
|
||||
- Step 7: Unregister media stream on stop or dispose
|
||||
- Step 8: Handle platform-specific limitations and fallbacks
|
||||
- Step 9: Test media registration across platforms
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test platform detection returns correct platform name
|
||||
- Test MediaRegistry.register() calls platform-specific APIs
|
||||
- Test MediaRegistry.unregister() cleans up platform resources
|
||||
- Integration:
|
||||
- Test audio player appears in macOS notification center
|
||||
- Test audio player appears in Windows media controls
|
||||
- Test audio player appears in Linux media player notifications
|
||||
- Test media controls update with playback position
|
||||
- Test multimedia keys control playback through media APIs
|
||||
|
||||
acceptance_criteria:
|
||||
- Audio player appears in platform media controls (notification center, lock screen)
|
||||
- Media controls update with current track info and playback position
|
||||
- Multimedia keys work through media APIs (not just terminal)
|
||||
- Media registration works on macOS, Windows, and Linux
|
||||
- Media unregistration properly cleans up resources
|
||||
- No memory leaks from media stream registration
|
||||
|
||||
validation:
|
||||
- On macOS: Check notification center for audio player notification
|
||||
- On Windows: Check media controls in taskbar/notification area
|
||||
- On Linux: Check media player notifications in desktop environment
|
||||
- Test multimedia keys work with system media player (not just terminal)
|
||||
- Monitor memory usage for leaks
|
||||
|
||||
notes:
|
||||
- Platform-specific media APIs are complex and may have limitations
|
||||
- macOS AVFoundation: Use AVPlayer with AVAudioSession for media registration
|
||||
- Windows Media Foundation: Use MediaSession API and PlaybackInfo for media controls
|
||||
- Linux: Use Mpris (Media Player Remote Interface Specification) or libpulse
|
||||
- May need additional platform-specific dependencies or native code
|
||||
- Fallback to terminal multimedia key handling if platform APIs unavailable
|
||||
- Reference: Platform-specific media API documentation and examples
|
||||
@@ -1,63 +0,0 @@
|
||||
# 04. Add media key listeners to audio hook [x]
|
||||
|
||||
meta:
|
||||
id: audio-playback-fix-04
|
||||
feature: audio-playback-fix
|
||||
priority: P2
|
||||
depends_on: []
|
||||
tags: [implementation, integration, event-handling]
|
||||
|
||||
objective:
|
||||
- Integrate multimedia key handling with existing audio hook
|
||||
- Route multimedia key events to appropriate audio control actions
|
||||
- Ensure proper cleanup of event listeners
|
||||
|
||||
deliverables:
|
||||
- Updated `useAudio()` hook with multimedia key event handling
|
||||
- Media key event listener registration in audio hook
|
||||
- Integration with multimedia key detection hook
|
||||
- Proper cleanup of event listeners on component unmount
|
||||
|
||||
steps:
|
||||
- Step 1: Import multimedia key detection hook into audio hook
|
||||
- Step 2: Register multimedia key event listener in audio hook
|
||||
- Step 3: Map multimedia key events to audio control actions (play/pause, seek, volume)
|
||||
- Step 4: Add event listener cleanup on hook dispose
|
||||
- Step 5: Test event listener cleanup with multiple component instances
|
||||
- Step 6: Add error handling for failed multimedia key events
|
||||
- Step 7: Test multimedia key events trigger correct audio actions
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test multimedia key events are captured in audio hook
|
||||
- Test events are mapped to correct audio control actions
|
||||
- Test event listeners are properly cleaned up
|
||||
- Test multiple audio hook instances don't conflict
|
||||
- Integration:
|
||||
- Test multimedia keys control playback from any component
|
||||
- Test multimedia keys work when player is not focused
|
||||
- Test multimedia keys don't interfere with other keyboard shortcuts
|
||||
- Test event listeners are removed when audio hook is disposed
|
||||
|
||||
acceptance_criteria:
|
||||
- Multimedia key events are captured by audio hook
|
||||
- Multimedia keys trigger correct audio control actions
|
||||
- Event listeners are properly cleaned up on unmount
|
||||
- No duplicate event listeners when components re-render
|
||||
- No memory leaks from event listeners
|
||||
- Error handling prevents crashes from invalid events
|
||||
|
||||
validation:
|
||||
- Use multimedia keys and verify audio responds correctly
|
||||
- Unmount and remount audio hook to test cleanup
|
||||
- Check for memory leaks with browser dev tools or system monitoring
|
||||
- Verify event listener count is correct after cleanup
|
||||
- Test with multiple Player components to ensure no conflicts
|
||||
|
||||
notes:
|
||||
- Audio hook is a singleton, so event listeners should be registered once
|
||||
- Multimedia key detection hook should be reused to avoid duplicate listeners
|
||||
- Event listener cleanup should use onCleanup from solid-js
|
||||
- Reference: src/hooks/useAudio.ts for event listener patterns
|
||||
- Multimedia keys may only work when terminal is focused (platform limitation)
|
||||
- Consider adding platform-specific key codes for better compatibility
|
||||
@@ -1,138 +0,0 @@
|
||||
# 05. Test multimedia controls across platforms [x]
|
||||
|
||||
meta:
|
||||
id: audio-playback-fix-05
|
||||
feature: audio-playback-fix
|
||||
priority: P1
|
||||
depends_on: []
|
||||
tags: [testing, integration, cross-platform]
|
||||
|
||||
objective:
|
||||
- Comprehensive testing of volume/speed controls and multimedia key support
|
||||
- Verify platform-specific media integration works correctly
|
||||
- Validate all controls across different audio backends
|
||||
|
||||
deliverables:
|
||||
- Test suite for volume/speed controls in `src/utils/audio-player.test.ts`
|
||||
- Integration tests for multimedia key handling in `src/hooks/useMultimediaKeys.test.ts`
|
||||
- Platform-specific integration tests in `src/utils/media-registry.test.ts`
|
||||
- Test coverage report showing all features tested
|
||||
|
||||
steps:
|
||||
- Step 1: Run existing unit tests for audio player backends
|
||||
- Step 2: Add volume control tests (setVolume, volume clamp, persistence)
|
||||
- Step 3: Add speed control tests (setSpeed, speed clamp, persistence)
|
||||
- Step 4: Create integration test for multimedia key handling
|
||||
- Step 5: Test volume/speed controls with Player component UI
|
||||
- Step 6: Test multimedia keys with Player component UI
|
||||
- Step 7: Test platform-specific media integration on each platform
|
||||
- Step 8: Test all controls across mpv, ffplay, and afplay backends
|
||||
- Step 9: Document any platform-specific limitations or workarounds
|
||||
|
||||
tests:
|
||||
- Unit:
|
||||
- Test volume control methods in all backends
|
||||
- Test speed control methods in all backends
|
||||
- Test volume clamp logic (0-1 range)
|
||||
- Test speed clamp logic (0.25-3 range)
|
||||
- Test multimedia key detection
|
||||
- Test event listener cleanup
|
||||
- Integration:
|
||||
- Test volume control via Player component UI
|
||||
- Test speed control via Player component UI
|
||||
- Test multimedia keys via keyboard
|
||||
- Test volume/speed persistence across pause/resume
|
||||
- Test volume/speed persistence across track changes
|
||||
- Cross-platform:
|
||||
- Test volume/speed controls on macOS
|
||||
- Test volume/speed controls on Linux
|
||||
- Test volume/speed controls on Windows
|
||||
- Test multimedia keys on each platform
|
||||
- Test media registration on each platform
|
||||
|
||||
acceptance_criteria:
|
||||
- All unit tests pass with >90% code coverage
|
||||
- All integration tests pass
|
||||
- Volume controls work correctly on all platforms
|
||||
- Speed controls work correctly on all platforms
|
||||
- Multimedia keys work on all platforms
|
||||
- Media controls appear on all supported platforms
|
||||
- All audio backends (mpv, ffplay, afplay) work correctly
|
||||
- No regressions in existing audio functionality
|
||||
|
||||
validation:
|
||||
- Run full test suite: `bun test`
|
||||
- Check test coverage: `bun test --coverage`
|
||||
- Manually test volume controls on each platform
|
||||
- Manually test speed controls on each platform
|
||||
- Manually test multimedia keys on each platform
|
||||
- Verify media controls appear on each platform
|
||||
- Check for any console errors or warnings
|
||||
|
||||
notes:
|
||||
- Test suite should cover all audio backend implementations
|
||||
- Integration tests should verify UI controls work correctly
|
||||
- Platform-specific tests should run on actual platform if possible
|
||||
- Consider using test doubles for platform-specific APIs
|
||||
- Document any platform-specific issues or limitations found
|
||||
- Reference: Test patterns from existing test files in src/utils/
|
||||
|
||||
## Implementation Notes (Completed)
|
||||
|
||||
### Manual Validation Steps
|
||||
|
||||
1. **Volume controls (all backends)**
|
||||
- Launch app, load an episode, press Up/Down arrows on Player tab
|
||||
- Volume indicator in PlaybackControls should update (0.00 - 1.00)
|
||||
- Audio output volume should change audibly
|
||||
- Test on non-Player tabs: Up/Down should still adjust volume via global media keys
|
||||
|
||||
2. **Speed controls (mpv, afplay)**
|
||||
- Press `S` to cycle speed: 1.0 -> 1.25 -> 1.5 -> 1.75 -> 2.0 -> 0.5
|
||||
- Speed indicator should update in PlaybackControls
|
||||
- Audible pitch/speed change on mpv and afplay
|
||||
- ffplay: speed changes require track restart (documented limitation)
|
||||
|
||||
3. **Seek controls**
|
||||
- Press Left/Right arrows to seek -10s / +10s
|
||||
- Position indicator should update
|
||||
- Works on Player tab (local) and other tabs (global media keys)
|
||||
|
||||
4. **Global media keys (non-Player tabs)**
|
||||
- Navigate to Feed, Shows, or Discover tab
|
||||
- Start playing an episode from Player tab first
|
||||
- Switch to another tab
|
||||
- Press Space to toggle play/pause
|
||||
- Press Up/Down to adjust volume
|
||||
- Press Left/Right to seek
|
||||
- Press S to cycle speed
|
||||
|
||||
5. **Platform media integration (macOS)**
|
||||
- Install `nowplaying-cli`: `brew install nowplaying-cli`
|
||||
- Track info should appear in macOS Now Playing widget
|
||||
- If `nowplaying-cli` is not installed, graceful no-op (no errors)
|
||||
|
||||
### Platform Limitations
|
||||
|
||||
| Backend | Volume | Speed | Seek | Notes |
|
||||
|---------|--------|-------|------|-------|
|
||||
| **mpv** | Runtime (IPC) | Runtime (IPC) | Runtime (IPC) | Best support, uses Unix socket |
|
||||
| **afplay** | Restart required | Restart required | Not supported | Process restarts with new args |
|
||||
| **ffplay** | Restart required | Not supported | Not supported | No runtime speed flag |
|
||||
| **system** | Depends on OS | Depends on OS | Depends on OS | Uses `open`/`xdg-open` |
|
||||
| **noop** | No-op | No-op | No-op | Silent fallback |
|
||||
|
||||
### Media Registry Platform Support
|
||||
|
||||
| Platform | Integration | Status |
|
||||
|----------|------------|--------|
|
||||
| **macOS** | `nowplaying-cli` | Works if binary installed |
|
||||
| **Linux** | MPRIS D-Bus | Stub (no-op), upgradable |
|
||||
| **Windows** | None | No-op stub |
|
||||
|
||||
### Key Architecture Decisions
|
||||
- Global media keys use event bus (`media.*` events) for decoupling
|
||||
- `useMultimediaKeys` hook is called once in App.tsx
|
||||
- Guards prevent double-handling when Player tab is focused (Player.tsx handles locally)
|
||||
- Guards prevent interference when text input is focused
|
||||
- MediaRegistry is a singleton, fire-and-forget, never throws
|
||||
@@ -1,26 +0,0 @@
|
||||
# Audio Playback Fix
|
||||
|
||||
Objective: Fix volume and speed controls and add multimedia key support with platform media stream integration
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [x] 01 — Fix volume and speed controls in audio backends → `01-fix-volume-speed-controls.md`
|
||||
- [x] 02 — Add multimedia key detection and handling → `02-add-multimedia-key-detection.md`
|
||||
- [x] 03 — Implement platform-specific media stream integration → `03-implement-platform-media-integration.md`
|
||||
- [x] 04 — Add media key listeners to audio hook → `04-add-media-key-listeners.md`
|
||||
- [x] 05 — Test multimedia controls across platforms → `05-test-multimedia-controls.md`
|
||||
|
||||
Dependencies
|
||||
- 01 depends on 02
|
||||
- 02 depends on 03
|
||||
- 03 depends on 04
|
||||
- 04 depends on 05
|
||||
|
||||
Exit criteria
|
||||
- Volume controls change playback volume in real-time
|
||||
- Speed controls change playback speed in real-time
|
||||
- Multimedia keys (Space, Arrow keys, Volume keys, Media keys) control playback
|
||||
- Audio player appears in system media controls
|
||||
- System multimedia keys trigger appropriate playback actions
|
||||
- All controls work across mpv, ffplay, and afplay backends
|
||||
@@ -1,50 +0,0 @@
|
||||
# 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
|
||||
@@ -1,51 +0,0 @@
|
||||
# 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
|
||||
@@ -1,52 +0,0 @@
|
||||
# 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
|
||||
@@ -1,51 +0,0 @@
|
||||
# 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
|
||||
@@ -1,50 +0,0 @@
|
||||
# 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
|
||||
@@ -1,25 +0,0 @@
|
||||
# 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
|
||||
@@ -1,47 +0,0 @@
|
||||
# 20. Debug Category Filter Implementation [x]
|
||||
|
||||
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
|
||||
@@ -1,47 +0,0 @@
|
||||
# 21. Fix Category State Synchronization [x]
|
||||
|
||||
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
|
||||
@@ -1,47 +0,0 @@
|
||||
# 22. Fix Category Keyboard Navigation [x]
|
||||
|
||||
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
|
||||
@@ -1,19 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 14. Define Download Storage Structure [x]
|
||||
|
||||
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
|
||||
@@ -1,47 +0,0 @@
|
||||
# 15. Create Episode Download Utility [x]
|
||||
|
||||
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
|
||||
@@ -1,47 +0,0 @@
|
||||
# 16. Implement Download Progress Tracking [x]
|
||||
|
||||
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
|
||||
@@ -1,47 +0,0 @@
|
||||
# 17. Add Download Status in Episode List [x]
|
||||
|
||||
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
|
||||
@@ -1,48 +0,0 @@
|
||||
# 18. Implement Per-Feed Auto-Download Settings [x]
|
||||
|
||||
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
|
||||
@@ -1,48 +0,0 @@
|
||||
# 19. Create Download Queue Management [x]
|
||||
|
||||
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
|
||||
@@ -1,26 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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
|
||||
@@ -1,21 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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
|
||||
@@ -1,46 +0,0 @@
|
||||
# 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)
|
||||
@@ -1,21 +0,0 @@
|
||||
# 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,57 +0,0 @@
|
||||
# 01. Copy cavacore library files to project
|
||||
|
||||
meta:
|
||||
id: real-time-audio-visualization-01
|
||||
feature: real-time-audio-visualization
|
||||
priority: P0
|
||||
depends_on: []
|
||||
tags: [setup, build]
|
||||
|
||||
objective:
|
||||
- Copy necessary cava library files from cava/ directory to src/utils/ for integration
|
||||
|
||||
deliverables:
|
||||
- src/utils/cavacore.h - Header file with cavacore API
|
||||
- src/utils/cavacore.c - Implementation of cavacore library
|
||||
- src/utils/audio-stream.h - Audio stream reader header
|
||||
- src/utils/audio-stream.c - Audio stream reader implementation
|
||||
- src/utils/audio-input.h - Common audio input types
|
||||
- src/utils/audio-input.c - Audio input buffer management
|
||||
|
||||
steps:
|
||||
- Identify necessary files from cava/ directory:
|
||||
- cavacore.h (API definition)
|
||||
- cavacore.c (FFT processing implementation)
|
||||
- input/common.h (common audio data structures)
|
||||
- input/common.c (input buffer handling)
|
||||
- input/fifo.h (FIFO input support - optional, for testing)
|
||||
- input/fifo.c (FIFO input implementation - optional)
|
||||
- Copy cavacore.h to src/utils/
|
||||
- Copy cavacore.c to src/utils/
|
||||
- Copy input/common.h to src/utils/
|
||||
- Copy input/common.c to src/utils/
|
||||
- Copy input/fifo.h to src/utils/ (optional)
|
||||
- Copy input/fifo.c to src/utils/ (optional)
|
||||
- Update file headers to indicate origin and licensing
|
||||
- Note: Files from cava/ directory will be removed after integration
|
||||
|
||||
tests:
|
||||
- Unit: Verify all files compile successfully
|
||||
- Integration: Ensure no import errors in TypeScript/JavaScript files
|
||||
- Manual: Check that files are accessible from src/utils/
|
||||
|
||||
acceptance_criteria:
|
||||
- All required cava files are copied to src/utils/
|
||||
- File headers include proper copyright and license information
|
||||
- No compilation errors from missing dependencies
|
||||
- Files are properly formatted for TypeScript/JavaScript integration
|
||||
|
||||
validation:
|
||||
- Run: `bun run build` to verify compilation
|
||||
- Check: `ls src/utils/*.c src/utils/*.h` to confirm file presence
|
||||
|
||||
notes:
|
||||
- Only need cavacore.c, cavacore.h, and common.c/common.h for basic functionality
|
||||
- input/fifo.c is optional - can be added later if needed
|
||||
- FFTW library will need to be installed and linked separately
|
||||
- The files will be integrated into the audio-waveform utility
|
||||
@@ -1,61 +0,0 @@
|
||||
# 02. Integrate cavacore library for audio analysis
|
||||
|
||||
meta:
|
||||
id: real-time-audio-visualization-02
|
||||
feature: real-time-audio-visualization
|
||||
priority: P0
|
||||
depends_on: [real-time-audio-visualization-01]
|
||||
tags: [integration, audio-processing]
|
||||
|
||||
objective:
|
||||
- Create a TypeScript binding for the cavacore C library
|
||||
- Provide async API for real-time audio frequency analysis
|
||||
|
||||
deliverables:
|
||||
- src/utils/cavacore.ts - TypeScript bindings for cavacore API
|
||||
- src/utils/audio-visualizer.ts - High-level audio visualizer class
|
||||
- Updated package.json with FFTW dependency
|
||||
|
||||
steps:
|
||||
- Review cavacore.h API and understand the interface:
|
||||
- cava_init() - Initialize with parameters
|
||||
- cava_execute() - Process samples and return frequencies
|
||||
- cava_destroy() - Clean up
|
||||
- Create cavacore.ts wrapper with TypeScript types:
|
||||
- Define C-style structs as TypeScript interfaces
|
||||
- Create bind() function to load shared library
|
||||
- Implement async wrappers for init, execute, destroy
|
||||
- Create audio-visualizer.ts class:
|
||||
- Handle initialization with configurable parameters (bars, sensitivity, noise reduction)
|
||||
- Provide execute() method that accepts audio samples and returns frequency data
|
||||
- Manage cleanup and error handling
|
||||
- Update package.json:
|
||||
- Add @types/fftw3 dependency (if available) or document manual installation
|
||||
- Add build instructions for linking FFTW library
|
||||
- Test basic initialization and execution with dummy data
|
||||
|
||||
tests:
|
||||
- Unit: Test cavacore initialization with valid parameters
|
||||
- Unit: Test cavacore execution with sample audio data
|
||||
- Unit: Test cleanup and memory management
|
||||
- Integration: Verify no memory leaks after multiple init/destroy cycles
|
||||
- Integration: Test with actual audio data from ffmpeg
|
||||
|
||||
acceptance_criteria:
|
||||
- cavacore.ts compiles without TypeScript errors
|
||||
- audio-visualizer.ts can be imported and initialized
|
||||
- execute() method returns frequency data array
|
||||
- Proper error handling for missing FFTW library
|
||||
- No memory leaks in long-running tests
|
||||
|
||||
validation:
|
||||
- Run: `bun run build` to verify TypeScript compilation
|
||||
- Run: `bun test` for unit tests
|
||||
- Manual: Test with sample audio file and verify output
|
||||
|
||||
notes:
|
||||
- FFTW library needs to be installed separately on the system
|
||||
- On macOS: brew install fftw
|
||||
- On Linux: apt install libfftw3-dev
|
||||
- The C code will need to be compiled into a shared library (.so/.dylib/.dll)
|
||||
- For Bun, we can use `Bun.native()` or `Bun.ffi` to call C functions
|
||||
@@ -1,72 +0,0 @@
|
||||
# 03. Create audio stream reader for real-time data
|
||||
|
||||
meta:
|
||||
id: real-time-audio-visualization-03
|
||||
feature: real-time-audio-visualization
|
||||
priority: P1
|
||||
depends_on: [real-time-audio-visualization-02]
|
||||
tags: [audio-stream, real-time]
|
||||
|
||||
objective:
|
||||
- Create a mechanism to read audio stream from mpv backend
|
||||
- Convert audio data to format suitable for cavacore processing
|
||||
- Implement efficient buffer management
|
||||
|
||||
deliverables:
|
||||
- src/utils/audio-stream-reader.ts - Audio stream reader class
|
||||
- src/utils/audio-stream-reader.test.ts - Unit tests
|
||||
|
||||
steps:
|
||||
- Design audio stream reader interface:
|
||||
- Constructor accepts audio URL and backend (mpv)
|
||||
- Start() method initiates audio playback and stream capture
|
||||
- readSamples() method returns next batch of audio samples
|
||||
- stop() method terminates stream capture
|
||||
- Implement stream reading for mpv backend:
|
||||
- Use mpv IPC to query audio device parameters (sample rate, channels)
|
||||
- Use ffmpeg or similar to pipe audio output to stdin
|
||||
- Read PCM samples from the stream
|
||||
- Convert audio samples to appropriate format:
|
||||
- Handle different bit depths (16-bit, 32-bit)
|
||||
- Handle different sample rates (44100, 48000, etc.)
|
||||
- Interleave stereo channels if needed
|
||||
- Implement buffer management:
|
||||
- Circular buffer for efficient sample storage
|
||||
- Non-blocking read with timeout
|
||||
- Sample rate conversion if needed
|
||||
- Handle errors:
|
||||
- Invalid audio URL
|
||||
- Backend connection failure
|
||||
- Sample format mismatch
|
||||
- Create unit tests:
|
||||
- Mock mpv backend
|
||||
- Test sample reading
|
||||
- Test buffer management
|
||||
- Test error conditions
|
||||
|
||||
tests:
|
||||
- Unit: Test sample rate detection
|
||||
- Unit: Test channel detection
|
||||
- Unit: Test sample reading with valid data
|
||||
- Unit: Test buffer overflow handling
|
||||
- Unit: Test error handling for invalid audio
|
||||
- Integration: Test with actual audio file and mpv
|
||||
- Integration: Test with ffplay backend
|
||||
|
||||
acceptance_criteria:
|
||||
- Audio stream reader successfully reads audio data from mpv
|
||||
- Samples are converted to 16-bit PCM format
|
||||
- Buffer management prevents overflow
|
||||
- Error handling works for invalid audio
|
||||
- No memory leaks in long-running tests
|
||||
|
||||
validation:
|
||||
- Run: `bun test` for unit tests
|
||||
- Manual: Play audio and verify stream reader captures data
|
||||
- Manual: Test with different audio formats (mp3, wav, m4a)
|
||||
|
||||
notes:
|
||||
- mpv can output audio via pipe to stdin using --audio-file-pipe
|
||||
- Alternative: Use ffmpeg to re-encode audio to standard format
|
||||
- Sample rate conversion may be needed for cavacore compatibility
|
||||
- For simplicity, start with 16-bit PCM, single channel (mono)
|
||||
@@ -1,75 +0,0 @@
|
||||
# 04. Create realtime waveform component
|
||||
|
||||
meta:
|
||||
id: real-time-audio-visualization-04
|
||||
feature: real-time-audio-visualization
|
||||
priority: P1
|
||||
depends_on: [real-time-audio-visualization-03]
|
||||
tags: [component, ui]
|
||||
|
||||
objective:
|
||||
- Create a SolidJS component that displays real-time audio visualization
|
||||
- Integrate audio-visualizer and audio-stream-reader
|
||||
- Display frequency data as visual waveform bars
|
||||
|
||||
deliverables:
|
||||
- src/components/RealtimeWaveform.tsx - Real-time waveform component
|
||||
- src/components/RealtimeWaveform.test.tsx - Component tests
|
||||
|
||||
steps:
|
||||
- Create RealtimeWaveform component:
|
||||
- Accept props: audioUrl, position, duration, isPlaying, onSeek, resolution
|
||||
- Initialize audio-visualizer with cavacore
|
||||
- Initialize audio-stream-reader for mpv backend
|
||||
- Create render loop that:
|
||||
- Reads audio samples from stream reader
|
||||
- Passes samples to cavacore execute()
|
||||
- Gets frequency data back
|
||||
- Maps frequency data to visual bars
|
||||
- Renders bars with appropriate colors
|
||||
- Implement rendering logic:
|
||||
- Map frequency values to bar heights
|
||||
- Color-code bars based on intensity
|
||||
- Handle played vs unplayed portions
|
||||
- Support click-to-seek
|
||||
- Create visual style:
|
||||
- Use terminal block characters for bars
|
||||
- Apply colors based on frequency bands (bass, mid, treble)
|
||||
- Add visual flair (gradients, glow effects if possible)
|
||||
- Implement state management:
|
||||
- Track current frequency data
|
||||
- Track playback position
|
||||
- Handle component lifecycle (cleanup)
|
||||
- Create unit tests:
|
||||
- Test component initialization
|
||||
- Test render loop
|
||||
- Test click-to-seek
|
||||
- Test cleanup
|
||||
|
||||
tests:
|
||||
- Unit: Test component props
|
||||
- Unit: Test frequency data mapping
|
||||
- Unit: Test visual bar rendering
|
||||
- Integration: Test with mock audio data
|
||||
- Integration: Test with actual audio playback
|
||||
|
||||
acceptance_criteria:
|
||||
- Component renders without errors
|
||||
- Visual bars update in real-time during playback
|
||||
- Frequency data is correctly calculated from audio samples
|
||||
- Click-to-seek works
|
||||
- Component cleans up resources properly
|
||||
- Visual style matches design requirements
|
||||
|
||||
validation:
|
||||
- Run: `bun test` for unit tests
|
||||
- Manual: Play audio and verify visualization updates
|
||||
- Manual: Test seeking and verify visualization follows
|
||||
- Performance: Monitor frame rate and CPU usage
|
||||
|
||||
notes:
|
||||
- Use SolidJS createEffect for reactive updates
|
||||
- Keep render loop efficient to maintain 60fps
|
||||
- Consider debouncing if processing is too heavy
|
||||
- May need to adjust sample rate for performance
|
||||
- Visual style should complement existing MergedWaveform design
|
||||
@@ -1,64 +0,0 @@
|
||||
# 05. Update Player component to use realtime visualization
|
||||
|
||||
meta:
|
||||
id: real-time-audio-visualization-05
|
||||
feature: real-time-audio-visualization
|
||||
priority: P1
|
||||
depends_on: [real-time-audio-visualization-04]
|
||||
tags: [integration, player]
|
||||
|
||||
objective:
|
||||
- Replace static waveform display with real-time visualization
|
||||
- Update Player.tsx to use RealtimeWaveform component
|
||||
- Ensure seamless transition and proper state management
|
||||
|
||||
deliverables:
|
||||
- Updated src/components/Player.tsx
|
||||
- Updated src/components/MergedWaveform.tsx (optional, for fallback)
|
||||
- Documentation of changes
|
||||
|
||||
steps:
|
||||
- Update Player.tsx:
|
||||
- Import RealtimeWaveform component
|
||||
- Replace MergedWaveform with RealtimeWaveform
|
||||
- Pass same props (audioUrl, position, duration, isPlaying, onSeek)
|
||||
- Remove audioUrl from props if no longer needed
|
||||
- Test with different audio formats
|
||||
- Add fallback handling:
|
||||
- If realtime visualization fails, show static waveform
|
||||
- Graceful degradation for systems without FFTW
|
||||
- Update component documentation
|
||||
- Test all player controls work with new visualization
|
||||
- Verify keyboard shortcuts still work
|
||||
- Test seek, pause, resume, volume, speed controls
|
||||
|
||||
tests:
|
||||
- Unit: Test Player with RealtimeWaveform
|
||||
- Integration: Test complete playback flow
|
||||
- Integration: Test seek functionality
|
||||
- Integration: Test pause/resume
|
||||
- Integration: Test volume and speed changes
|
||||
- Integration: Test with different audio formats
|
||||
- Manual: Verify all player features work correctly
|
||||
|
||||
acceptance_criteria:
|
||||
- Player displays real-time visualization during playback
|
||||
- All player controls work correctly
|
||||
- Seek functionality works with visualization
|
||||
- Graceful fallback for systems without FFTW
|
||||
- No regression in existing functionality
|
||||
- Visual style matches design requirements
|
||||
|
||||
validation:
|
||||
- Run: `bun run build` to verify compilation
|
||||
- Run: `bun test` for integration tests
|
||||
- Manual: Play various audio files
|
||||
- Manual: Test all keyboard shortcuts
|
||||
- Performance: Monitor frame rate and CPU usage
|
||||
|
||||
notes:
|
||||
- Keep MergedWaveform as fallback option
|
||||
- Consider showing a loading state while visualizer initializes
|
||||
- May need to handle the case where mpv doesn't support audio pipe
|
||||
- The visualizer should integrate smoothly with existing Player layout
|
||||
- Consider adding a toggle to switch between static and realtime visualization
|
||||
@@ -1,78 +0,0 @@
|
||||
# 06. Add visualizer controls and settings
|
||||
|
||||
meta:
|
||||
id: real-time-audio-visualization-06
|
||||
feature: real-time-audio-visualization
|
||||
priority: P2
|
||||
depends_on: [real-time-audio-visualization-05]
|
||||
tags: [ui, controls, settings]
|
||||
|
||||
objective:
|
||||
- Add user controls for visualizer settings
|
||||
- Create settings panel for customization
|
||||
- Allow users to adjust visualizer parameters
|
||||
|
||||
deliverables:
|
||||
- src/components/VisualizerSettings.tsx - Settings component
|
||||
- Updated src/components/Player.tsx - Settings panel integration
|
||||
- src/types/settings.ts - Visualizer settings type definition
|
||||
- src/stores/settings.ts - Settings state management
|
||||
|
||||
steps:
|
||||
- Define visualizer settings types:
|
||||
- Number of bars (resolution)
|
||||
- Sensitivity (autosens toggle + manual value)
|
||||
- Noise reduction level
|
||||
- Frequency cutoffs (low/high)
|
||||
- Bar width and spacing
|
||||
- Color scheme options
|
||||
- Create VisualizerSettings component:
|
||||
- Display current settings
|
||||
- Allow adjusting each parameter
|
||||
- Show real-time feedback
|
||||
- Save settings to app store
|
||||
- Integrate with Player component:
|
||||
- Add settings button
|
||||
- Show settings panel when toggled
|
||||
- Apply settings to RealtimeWaveform component
|
||||
- Update settings state management:
|
||||
- Load saved settings from app store
|
||||
- Save settings on change
|
||||
- Provide default values
|
||||
- Create UI for settings:
|
||||
- Keyboard shortcuts for quick adjustment
|
||||
- Visual feedback for changes
|
||||
- Help text for each setting
|
||||
- Add settings persistence
|
||||
- Create tests for settings component
|
||||
|
||||
tests:
|
||||
- Unit: Test settings type definitions
|
||||
- Unit: Test settings state management
|
||||
- Unit: Test VisualizerSettings component
|
||||
- Integration: Test settings apply to visualization
|
||||
- Integration: Test settings persistence
|
||||
- Manual: Test all settings controls
|
||||
|
||||
acceptance_criteria:
|
||||
- VisualizerSettings component renders correctly
|
||||
- All settings can be adjusted
|
||||
- Changes apply in real-time
|
||||
- Settings persist between sessions
|
||||
- Keyboard shortcuts work
|
||||
- Component handles invalid settings gracefully
|
||||
|
||||
validation:
|
||||
- Run: `bun test` for unit tests
|
||||
- Run: `bun test` for integration tests
|
||||
- Manual: Test all settings
|
||||
- Manual: Test keyboard shortcuts
|
||||
- Manual: Test settings persistence
|
||||
|
||||
notes:
|
||||
- Settings should have sensible defaults
|
||||
- Some settings may require visualizer re-initialization
|
||||
- Consider limiting certain settings to avoid performance issues
|
||||
- Add tooltips or help text for complex settings
|
||||
- Settings should be optional - users can start without them
|
||||
- Keep UI simple and intuitive
|
||||
@@ -1,30 +0,0 @@
|
||||
# Real-time Audio Visualization
|
||||
|
||||
Objective: Integrate cava library for real-time audio visualization in Player component
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [x] 01 — Copy cavacore library files to project → `01-copy-cavacore-files.md`
|
||||
- [x] 02 — Integrate cavacore library for audio analysis → `02-integrate-cavacore-library.md`
|
||||
- [x] 03 — Create audio stream reader for real-time data → `03-create-audio-stream-reader.md`
|
||||
- [x] 04 — Create realtime waveform component → `04-create-realtime-waveform-component.md`
|
||||
- [x] 05 — Update Player component to use realtime visualization → `05-update-player-visualization.md`
|
||||
- [x] 06 — Add visualizer controls and settings → `06-add-visualizer-controls.md`
|
||||
|
||||
Dependencies
|
||||
- 01 depends on (none)
|
||||
- 02 depends on 01
|
||||
- 03 depends on 02
|
||||
- 04 depends on 03
|
||||
- 05 depends on 04
|
||||
- 06 depends on 05
|
||||
|
||||
Exit criteria
|
||||
- Audio visualization updates in real-time during playback
|
||||
- Waveform bars respond to actual audio frequencies
|
||||
- Visualizer controls (sensitivity, bar count) work
|
||||
- Performance is smooth with 60fps updates
|
||||
- All necessary cava files are integrated into project
|
||||
|
||||
Note: Files from cava/ directory will be removed after integration
|
||||
@@ -1,45 +0,0 @@
|
||||
# 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
|
||||
@@ -1,47 +0,0 @@
|
||||
# 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`
|
||||
@@ -1,45 +0,0 @@
|
||||
# 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
|
||||
@@ -1,18 +0,0 @@
|
||||
# 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
|
||||
@@ -1,45 +0,0 @@
|
||||
# 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
|
||||
@@ -1,45 +0,0 @@
|
||||
# 02. Implement Clipboard Copy on Selection Release
|
||||
|
||||
meta:
|
||||
id: text-selection-copy-02
|
||||
feature: text-selection-copy
|
||||
priority: P2
|
||||
depends_on: [text-selection-copy-01]
|
||||
tags: [clipboard, events, user-experience]
|
||||
|
||||
objective:
|
||||
- Copy selected text to clipboard when selection is released
|
||||
- Handle terminal clipboard limitations
|
||||
- Provide user feedback when copy succeeds
|
||||
|
||||
deliverables:
|
||||
- Clipboard copy logic triggered on selection release
|
||||
- User notifications for copy actions
|
||||
- Integration with existing clipboard utilities
|
||||
|
||||
steps:
|
||||
1. Add event listener for selection release events
|
||||
2. Extract selected text from current focus component
|
||||
3. Use existing Clipboard.copy() utility
|
||||
4. Emit "clipboard.copied" event for notifications
|
||||
5. Add visual feedback (toast notification)
|
||||
|
||||
tests:
|
||||
- Unit: Test clipboard copy function with various text inputs
|
||||
- Integration: Verify copy happens on selection release
|
||||
- Manual: Select text and verify it appears in clipboard
|
||||
|
||||
acceptance_criteria:
|
||||
- Selected text is copied to clipboard when selection ends
|
||||
- User receives feedback when copy succeeds
|
||||
- Works across different terminal environments
|
||||
|
||||
validation:
|
||||
- Select text in Player description
|
||||
- Verify text is in clipboard after selection ends
|
||||
- Check for toast notification
|
||||
|
||||
notes:
|
||||
- Use existing Clipboard namespace from `src/utils/clipboard.ts`
|
||||
- Consider timing of selection release vs terminal refresh
|
||||
- May need to debounce copy operations
|
||||
@@ -1,15 +0,0 @@
|
||||
# Text Selection Copy to Clipboard
|
||||
|
||||
Objective: When text is selected in the TUI, copy it to the clipboard on release
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [ ] 01 — Add text selection event handling → `01-text-selection-copy.md`
|
||||
- [ ] 02 — Implement clipboard copy on selection release → `02-clipboard-copy-on-release.md`
|
||||
|
||||
Dependencies
|
||||
- 01 -> 02
|
||||
|
||||
Exit criteria
|
||||
- Users can select text and it gets copied to clipboard when selection is released
|
||||
Reference in New Issue
Block a user