docs: add chat summaries and plan documents
Made-with: Cursor
This commit is contained in:
126
docs/plans/2026-03-10-settings-panel-design.md
Normal file
126
docs/plans/2026-03-10-settings-panel-design.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Settings Panel Design
|
||||
|
||||
## Overview
|
||||
|
||||
Add four new feature sections to the existing `SettingsScreen`: SomaFM quality preference, now-playing history file logging, reset customizations, and restart app.
|
||||
|
||||
## 1. SomaFM Quality Preference
|
||||
|
||||
### Data Model
|
||||
|
||||
New `station_streams` table:
|
||||
|
||||
| Column | Type | Notes |
|
||||
|-----------|---------|----------------------------------|
|
||||
| id | Long PK | Auto-generated |
|
||||
| stationId | Long FK | References `stations.id` |
|
||||
| bitrate | Int | 128 or 256 |
|
||||
| ssl | Boolean | true = HTTPS, false = HTTP |
|
||||
| url | String | Full stream URL |
|
||||
|
||||
URL patterns:
|
||||
- SSL: `https://ice1.somafm.com/{streamId}-{bitrate}-mp3`
|
||||
- Non-SSL: `http://ice1.somafm.com/{streamId}-{bitrate}-mp3`
|
||||
|
||||
Stations with only 128kbps support get 2 rows; stations with 256kbps get 4 rows.
|
||||
|
||||
### Preference Storage
|
||||
|
||||
- **Global preference** in `RadioPreferences`: ordered list stored as JSON string, e.g. `["256-ssl","256-nossl","128-ssl","128-nossl"]`. Users can reorder in settings.
|
||||
- **Per-station override**: nullable `qualityOverride` column on `Station`. When non-null, overrides the global preference with the same JSON format. When null, uses the global default.
|
||||
|
||||
### Playback Resolution
|
||||
|
||||
New `StreamResolver` utility:
|
||||
1. Queries `station_streams` for the station's available streams.
|
||||
2. Orders them by the applicable preference (per-station override or global default).
|
||||
3. Returns the first URL. On connection failure, `AudioEngine`/`RadioPlaybackService` tries the next URL in the chain.
|
||||
|
||||
Non-SomaFM stations use `station.url` directly — no streams table involvement.
|
||||
|
||||
### Settings UI
|
||||
|
||||
- Draggable list showing the 4 quality tiers in current preference order
|
||||
- Per-station: accessible from station long-press menu or edit dialog
|
||||
|
||||
## 2. Now Playing History (File Logging)
|
||||
|
||||
### Preference Keys in `RadioPreferences`
|
||||
|
||||
- `historyEnabled: Boolean` — default `false`
|
||||
- `historyFormat: String` — `"csv"`, `"json"`, or `"plain"` (default `"csv"`)
|
||||
- `historyFilePath: String` — default: app's external files directory
|
||||
|
||||
### File Formats
|
||||
|
||||
- **CSV**: `"2026-03-10 09:30:15","Groove Salad","Tycho","A Walk"`
|
||||
- **JSON lines**: `{"timestamp":"2026-03-10T09:30:15","station":"Groove Salad","artist":"Tycho","title":"A Walk"}`
|
||||
- **Plain text**: `2026-03-10 09:30 | Groove Salad | Tycho - A Walk`
|
||||
|
||||
File names: `now-playing-history.csv`, `.jsonl`, or `.txt` based on format.
|
||||
|
||||
### Writer
|
||||
|
||||
`NowPlayingHistoryWriter` class:
|
||||
- Called from `RadioPlaybackService` after `metadataSnapshotDao.insert()` when ICY metadata changes
|
||||
- Checks `historyEnabled` preference; if true, appends a line to the file in the chosen format
|
||||
- Thread-safe file writes on `Dispatchers.IO`
|
||||
|
||||
### Settings UI
|
||||
|
||||
- Toggle: "Enable Now Playing History"
|
||||
- Dropdown/chips: format selector (CSV, JSON, Plain Text)
|
||||
- Current path display + "Choose Directory" button (launches `ACTION_OPEN_DOCUMENT_TREE`)
|
||||
|
||||
## 3. Reset Customizations
|
||||
|
||||
### Behavior
|
||||
|
||||
A "Reset All Customizations" button with a companion toggle: **"Also delete saved stations/playlists"**.
|
||||
|
||||
Confirmation dialog adapts its message based on the toggle state.
|
||||
|
||||
### Always resets (in a single DB transaction):
|
||||
- `starred = false` on all stations
|
||||
- `sortOrder` restored to original seed index
|
||||
- `isHidden = false` on all stations
|
||||
- `qualityOverride = null` on all stations
|
||||
|
||||
### If toggle is on, also:
|
||||
- Deletes all non-built-in playlists and their stations
|
||||
|
||||
### Error handling:
|
||||
- Wrapped in try/catch
|
||||
- Shows a Toast on failure
|
||||
- Fails gracefully — partial reset should not corrupt state (transaction rollback)
|
||||
|
||||
## 4. Restart App
|
||||
|
||||
### Behavior
|
||||
|
||||
A "Restart App" button that:
|
||||
|
||||
1. Calls `RadioController.stop()` for graceful shutdown
|
||||
2. Waits up to 3 seconds for `PlaybackState.Idle`
|
||||
3. If still not idle, force-stops the service via `stopService()`
|
||||
4. Restarts: launches `MainActivity` with `FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK`, then `Runtime.getRuntime().exit(0)`
|
||||
|
||||
No external libraries needed.
|
||||
|
||||
## Files Affected
|
||||
|
||||
### New files:
|
||||
- `data/model/StationStream.kt` — Room entity
|
||||
- `data/db/StationStreamDao.kt` — DAO
|
||||
- `service/StreamResolver.kt` — URL resolution logic
|
||||
- `data/logging/NowPlayingHistoryWriter.kt` — file logger
|
||||
|
||||
### Modified files:
|
||||
- `data/model/Station.kt` — add `qualityOverride` column
|
||||
- `data/db/RadioDatabase.kt` — add entity, bump version, add migration
|
||||
- `data/db/SomaFmSeedData.kt` — seed `station_streams` rows
|
||||
- `data/prefs/RadioPreferences.kt` — add quality, history prefs
|
||||
- `service/RadioPlaybackService.kt` — use `StreamResolver`, call history writer
|
||||
- `ui/screens/settings/SettingsScreen.kt` — add all 4 new sections
|
||||
- `ui/screens/settings/SettingsViewModel.kt` — add reset/restart/quality/history logic
|
||||
- `RadioApplication.kt` — expose history writer
|
||||
Reference in New Issue
Block a user