```
**Button to open settings (in control panel):**
```html
```
**Success Criteria:**
- Settings modal with GPU toggle
- Concurrent downloads slider (2-8, 0=auto)
- GPU info displayed from detection
- Save button updates config
---
### **Task 4: Add Queue Status Panel** (45 min)
#### File: `index.html`
Add after control panel, before footer:
```html
Download Queue
Active:0/4Queued:0
CPU Usage
--
Memory
--
GPU Accel
--
```
**Success Criteria:**
- Queue stats displayed (active/max/queued)
- System metrics updated every 2 seconds
- GPU status shows type or "Software"
- Clean, compact design
---
### **Task 5: Implement UI Logic in app.js** (1.5 hours)
#### File: `scripts/app.js`
Add settings management:
```javascript
// Settings modal handlers
initSettingsModal() {
const modal = document.getElementById('settingsModal')
const settingsBtn = document.getElementById('settingsBtn')
const closeBtn = document.getElementById('closeSettingsBtn')
const saveBtn = document.getElementById('saveSettingsBtn')
settingsBtn?.addEventListener('click', () => this.openSettings())
closeBtn?.addEventListener('click', () => this.closeSettings())
saveBtn?.addEventListener('click', () => this.saveSettings())
}
async openSettings() {
const modal = document.getElementById('settingsModal')
modal.classList.remove('hidden')
// Load current settings
const useGPU = document.getElementById('useGPUCheckbox')
const slider = document.getElementById('maxConcurrentSlider')
useGPU.checked = this.state.config.useGPU
slider.value = this.state.config.maxConcurrent || 0
// Get GPU info
const gpuInfo = await window.IPCManager.getGPUInfo()
this.displayGPUInfo(gpuInfo)
}
saveSettings() {
const useGPU = document.getElementById('useGPUCheckbox').checked
const maxConcurrent = parseInt(document.getElementById('maxConcurrentSlider').value)
this.state.updateConfig({
useGPU,
maxConcurrent: maxConcurrent === 0 ? null : maxConcurrent
})
this.closeSettings()
}
// Queue panel updates
async updateQueuePanel() {
const stats = await window.IPCManager.getDownloadStats()
document.getElementById('activeCount').textContent = stats.active
document.getElementById('maxConcurrentDisplay').textContent = stats.maxConcurrent
document.getElementById('queuedCount').textContent = stats.queued
}
// Performance metrics
async updatePerformanceMetrics() {
const stats = await window.IPCManager.getPerformanceStats()
document.getElementById('cpuUsage').textContent = `${stats.system.currentCPU}%`
const mem = stats.system.currentMemory
document.getElementById('memoryUsage').textContent = `${mem.used}/${mem.total} MB`
const gpuStatus = this.state.config.useGPU && stats.gpu?.type
? stats.gpu.type
: 'Software'
document.getElementById('gpuStatus').textContent = gpuStatus
}
// Start monitoring
startMonitoring() {
// Update every 2 seconds
this.monitoringInterval = setInterval(() => {
this.updateQueuePanel()
this.updatePerformanceMetrics()
}, 2000)
}
```
**Success Criteria:**
- Settings modal opens/closes correctly
- GPU info displayed from detection
- Settings saved to AppState
- Queue panel updates every 2 seconds
- Performance metrics displayed
---
### **Task 6: Add IPC Handlers** (30 min)
#### File: `src/preload.js`
```javascript
// Performance monitoring
getPerformanceStats: () => ipcRenderer.invoke('get-performance-stats'),
// GPU info
getGPUInfo: () => ipcRenderer.invoke('get-gpu-info'),
// Download stats (already exists, verify)
getDownloadStats: () => ipcRenderer.invoke('get-download-stats')
```
#### File: `src/main.js`
```javascript
// GPU info handler
ipcMain.handle('get-gpu-info', async () => {
const gpuDetector = require('../scripts/utils/gpu-detector')
const capabilities = await gpuDetector.detect()
return {
hasGPU: capabilities.hasGPU,
type: capabilities.type,
description: capabilities.description,
encoders: capabilities.encoders
}
})
```
**Success Criteria:**
- IPC handlers registered
- GPU info accessible from renderer
- Performance stats accessible
- No TypeErrors or missing methods
---
### **Task 7: Add CSS Styling** (15 min)
#### File: `styles/main.css`
```css
/* Queue Panel */
#queuePanel {
font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code", monospace;
}
/* Settings Modal */
#settingsModal {
backdrop-filter: blur(4px);
}
/* Range Slider */
input[type="range"] {
accent-color: var(--primary-blue);
}
input[type="range"]::-webkit-slider-thumb {
background: var(--primary-blue);
cursor: pointer;
}
/* Checkbox */
input[type="checkbox"]:checked {
background-color: var(--primary-blue);
border-color: var(--primary-blue);
}
```
**Success Criteria:**
- Queue panel uses monospace font
- Settings modal has backdrop blur
- Range slider styled with primary blue
- Checkbox matches design system
---
### **Task 8: Testing** (45 min)
#### File: `tests/performance-monitor.test.js` (NEW)
```javascript
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import PerformanceMonitor from '../scripts/utils/performance-monitor.js'
describe('Performance Monitor', () => {
let monitor
beforeEach(() => {
monitor = new PerformanceMonitor()
})
afterEach(() => {
monitor.stop()
})
it('should initialize correctly', () => {
expect(monitor.metrics).toBeDefined()
expect(monitor.startTime).toBeGreaterThan(0)
})
it('should sample system metrics', () => {
monitor.sampleSystemMetrics()
expect(monitor.metrics.cpuSamples.length).toBeGreaterThan(0)
expect(monitor.metrics.memorySamples.length).toBeGreaterThan(0)
})
it('should record downloads', () => {
monitor.recordDownload({
videoId: 'test1',
duration: 5000,
status: 'completed'
})
expect(monitor.metrics.downloads.length).toBe(1)
})
it('should get stats', () => {
const stats = monitor.getStats()
expect(stats).toHaveProperty('downloads')
expect(stats).toHaveProperty('conversions')
expect(stats).toHaveProperty('system')
})
it('should limit sample history to 100', () => {
for (let i = 0; i < 150; i++) {
monitor.sampleSystemMetrics()
}
expect(monitor.metrics.cpuSamples.length).toBeLessThanOrEqual(100)
})
})
```
**Success Criteria:**
- All performance monitor tests pass
- Integration tests for IPC handlers
- UI component visibility tests
---
## Implementation Order
1. **AppState GPU Config** (15 min) - Foundation for settings
2. **Performance Monitor Module** (45 min) - Core monitoring system
3. **IPC Handlers** (30 min) - Bridge for data access
4. **Settings Panel UI** (30 min) - User configuration interface
5. **Queue Status Panel** (45 min) - Real-time status display
6. **UI Logic in app.js** (1.5 hours) - Wire everything together
7. **CSS Styling** (15 min) - Polish the UI
8. **Testing** (45 min) - Quality assurance
**Total Time:** ~4.5 hours
---
## Success Metrics
### Functional Requirements
- ✅ Settings modal opens and saves GPU/concurrency settings
- ✅ Queue panel shows active/queued download counts
- ✅ Performance metrics update every 2 seconds
- ✅ GPU info displayed correctly (type or "Software")
- ✅ CPU and memory usage displayed
### Performance Requirements
- ✅ UI updates don't block main thread
- ✅ Metrics sampling minimal CPU overhead (< 1%)
- ✅ Settings save instantly to state
### User Experience
- ✅ Clean, intuitive settings interface
- ✅ Real-time feedback on system performance
- ✅ GPU status clearly communicated
- ✅ Concurrency slider with visual feedback
---
## Next Actions
Once approved, I'll execute in this order:
1. Add GPU config to AppState
2. Create PerformanceMonitor module
3. Add IPC handlers for GPU info and performance stats
4. Build Settings modal HTML
5. Build Queue status panel HTML
6. Implement UI logic in app.js
7. Add CSS styling
8. Create tests
Ready to begin! 🚀