BLoC State Management Layer
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The BLoC (Business Logic Component) State Management Layer serves as the core architectural pattern for handling state across the BT Speaker monorepo. It decouple's the project's business logic from the UI, specifically facilitating real-time communication between the Raspberry Pi display application (pi_app) and the mobile companion application (phone_app). The layer is built using the flutter_bloc library and follows a "BLoC-per-feature" pattern to ensure modularity and testability.
Sources: README.md:31-33, CLAUDE.md:52-54, pubspec.yaml:7-11
Architectural Overview
The state management architecture is designed around a reactive flow where WebSocket events are transformed into feature-specific states. The Raspberry Pi application acts as a WebSocket server, receiving typed JSON messages from the phone client. These messages are parsed into a sealed class hierarchy of events, which are then consumed by individual BLoCs to update the user interface and hardware peripherals (like the LED ring).
Data Flow Pattern
The following diagram illustrates the unidirectional data flow from the phone app (client) to the Pi app's BLoC layer:
Sources: README.md:25-30, CLAUDE.md:27-31
Feature-Specific BLoCs
The system implements five primary BLoCs within the pi_app, each responsible for a distinct functional domain. These BLoCs subscribe to a shared WebSocket event stream provided by the core communication layer.
BLoC Definitions
| BLoC Name | Responsibility | Key Data Types |
|---|---|---|
| ConnectionBloc | Manages WebSocket connection status | waiting, connected |
| VisualizerBloc | Handles high-frequency audio visualization data | BeatData (FFT, BPM, Intensity) |
| NowPlayingBloc | Processes track metadata and playback progress | NowPlaying (Title, Artist, Art) |
| EqBloc | Manages real-time equalizer adjustments | EqSettings (Bass, Mid, Treble) |
| LedBloc | Controls the WS2812B LED ring pulse and color | LedCommand |
Sources: README.md:35-42, CLAUDE.md:65-71
Implementation Standards
The project enforces strict coding conventions for the BLoC layer to maintain consistency across the monorepo:
- File Layout: All BLoC files must be located in
lib/features/<feature>/bloc/, with corresponding widgets inlib/features/<feature>/widgets/. - Part Files: Events and states are separated from the main BLoC logic using the
partandpart ofdirectives. - State Comparisons: The
equatablepackage is used (included inpi_appandphone_appdependencies) to ensure efficient UI rebuilds by comparing state values rather than references. - Naming Hazards: A critical hazard exists with
ConnectionState. Developers must useimport 'package:flutter/material.dart' hide ConnectionState;when importing Material alongside custom BLoC connection states to avoid conflicts withdart:async.
Sources: CLAUDE.md:41-48, CLAUDE.md:52-58, apps/pi_app/pubspec.yaml:26-27
Testing the BLoC Layer
BLoC logic is verified using a combination of flutter_test and bloc_test. The testing strategy utilizes a MockBloc pattern and handles the asynchronous nature of the WebSocket server.
Conclusion
The BLoC State Management Layer provides a robust foundation for the BT Speaker project, enabling the Raspberry Pi to handle high-frequency visualizer data (~30–60 Hz) and hardware commands in a predictable manner. By centralizing business logic within typed BLoCs and sharing data models through bt_speaker_core, the architecture ensures that both the Pi and phone applications remain synchronized and maintainable.
Sources: README.md:44-46, CLAUDE.md:6-10