- Add WebSocket heartbeat ping every 30s to detect stale connections - Add completer guards to prevent double-completion errors in: - music_assistant_api.dart (connection completers) - music_assistant_provider.dart (registration completers) - player_provider.dart (registration completers) - Add heartbeatInterval constant to Timings class - Update AUDIT_PROGRESS.md with Phase 8 status 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.1 KiB
Ensemble App - Audit Progress Tracker
Audit Date: 2025-12-08
Branch: refactor/audit-cleanup
Overall Health Score: 6.5/10 (before fixes)
Phase 1: Quick Wins (1-2 days)
Low effort, immediate impact
- Remove unused
cupertino_iconsdependency frompubspec.yaml - Remove 12 debug
print()statements frommain.dart(replaced with_logger.log()) - Fix empty
setState(() {})in progress timer (expandable_player.dart) - converted toValueNotifier - Fix empty
setState(() {})on text input (search_screen.dart) - removed unnecessary setState - Complete or remove TODO comments:
queue_screen.dart- enhanced comment with API requirementslibrary_screen.dart- IMPLEMENTED play track functionalityexpandable_player.dart- enhanced comment with API limitations
Phase 2: Performance Fixes (2-3 days)
Medium effort, significant performance gains
- Fix slider setState spam - use ValueNotifier pattern (
expandable_player.dart) - Replace volume polling with events (
volume_control.dart) - removed polling loop - Cache
Theme.of(context)lookups - removed unused lookup insearch_screen.dart - Move
SystemChromeout of build() (main.dart) - created SystemUIWrapper widget - Replace
Image.networkwithCachedNetworkImage(expandable_player.dart) - Use
ListView.builderinstead of spread operators (search_screen.dart)
Phase 3: Dead Code Cleanup (1 day)
Consolidate and remove unused files
- Delete unused
library_screen.dart(old version,new_library_screen.dartis active) - Remove unused
PlayerStateService(player_state_service.dart) - Remove unused
Playerimport fromdebug_log_screen.dart
Note: new_home_screen.dart and new_library_screen.dart are NOT dead code - they are
the active screens used in home_screen.dart. The naming suggests they replaced older
versions during a refactor.
Phase 4: State Management Refactor (3-4 days)
Split monolithic provider (2,106 lines)
- Extract cache logic →
CacheService(lib/services/cache_service.dart) - Update
MusicAssistantProviderto delegate caching toCacheService - Delete unused
library_service.dart - Extract connection logic →
ConnectionProvider(skeleton created) - Extract library data →
LibraryProvider(skeleton created) - Extract player state →
PlayerProvider(skeleton created) - Remove global singleton (
navigation_provider.dart:40) - Add stream filtering (
.distinct(),.where())
Note: Phase 4 partial completion - extracted CacheService and reduced
music_assistant_provider.dart from 2,106 to ~1,650 lines. Full provider
split deferred as lower priority.
Phase 5: Widget Decomposition (3-4 days)
Split mega-widgets into focused components
expandable_player.dart (1,365 → 1,150 lines) - DONE
- Extract
DeviceSelectorBar→lib/widgets/player/device_selector_bar.dart - Extract
QueuePanel→lib/widgets/player/queue_panel.dart - Create
PlayerControls→lib/widgets/player/player_controls.dart(available for future use)
login_screen.dart (968 → 843 lines) - DONE
- Extract
DebugConsole→lib/widgets/debug/debug_console.dart - Extract
DebugToggleButton→ included in debug_console.dart
album_details_screen.dart (818 lines)
- Extract
TrackListSection - Extract
PlayOnBottomSheet(shared)
search_screen.dart (516 lines)
- Extract
MediaItemTile - Extract
SearchFilters
Phase 6: Code Deduplication (2-3 days)
Extract reusable widgets
- Create
MediaItemTile(consolidate 3 list tile builders) - Create
PlayOnBottomSheet(consolidate 4 implementations) - Create
EmptyState(consolidate 6+ implementations) →lib/widgets/common/empty_state.dart - Create
FilterChipRow(consolidate 3 implementations) - Create
DisconnectedState(consolidate 3 implementations) →lib/widgets/common/disconnected_state.dart
Note: Phase 6 partial completion - extracted EmptyState (8 usages, ~227 lines removed) and DisconnectedState (3 usages, ~140 lines removed). Total ~367 lines of duplicate code removed.
Phase 7: Design System (2 days)
Centralize hardcoded values
- Create
lib/theme/design_tokens.dart:- Spacing constants (Spacing class with xxs-xxxl scale)
- Border radius constants (Radii class)
- Icon size constants (IconSizes class)
- Dimension constants (Dimensions class)
- Animation duration constants (Durations class)
- Apply tokens to extracted widgets:
empty_state.dart- Spacing tokensdisconnected_state.dart- Spacing, IconSizes, Radii tokensqueue_panel.dart- Spacing, Radii, IconSizes tokensplayer_controls.dart- Spacing tokensdevice_selector_bar.dart- Spacing, IconSizes tokensdebug_console.dart- Spacing, Radii, IconSizes tokens
- Continue replacing remaining hardcoded values (~223 remaining)
- Create
lib/constants/strings.dart(40+ strings)
Phase 8: Polish (Backlog)
Nice-to-have improvements
- Add Semantics labels for accessibility
- Implement localization (i18n)
- Add test coverage
- Implement WebSocket heartbeat (
music_assistant_api.dart- ping every 30s) - Add responsive grid layouts for tablets
- Add completer guards to prevent double-completion (
music_assistant_api.dart,music_assistant_provider.dart,player_provider.dart)
Completed Summary
| Phase | Status | Completed Date |
|---|---|---|
| Phase 1 | COMPLETED | 2025-12-08 |
| Phase 2 | COMPLETED | 2025-12-08 |
| Phase 3 | COMPLETED | 2025-12-08 |
| Phase 4 | PARTIAL | 2025-12-08 |
| Phase 5 | PARTIAL | 2025-12-08 |
| Phase 6 | PARTIAL | 2025-12-08 |
| Phase 7 | PARTIAL | 2025-12-08 |
| Phase 8 | PARTIAL | 2025-12-08 |
Notes
- Original audit performed by 7 parallel sub-agents analyzing different aspects
- Total LOC: 17,454 across 57 Dart files
- Largest files:
music_assistant_provider.dart(2,106),music_assistant_api.dart(1,948),expandable_player.dart(1,335)