Skip to content

Commit 8cafeb4

Browse files
authored
Merge pull request #15 from fadyphil/feat/analytics-overhaul
Feat/analytics overhaul (UI only no data integration)
2 parents c3c9680 + baa22b6 commit 8cafeb4

37 files changed

Lines changed: 34258 additions & 287 deletions

README.md

Lines changed: 24 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
> **Clean Architecture** and **BLoC**. Some features may be incomplete.
44
55
---
6-
7-
title: Music Player Architecture Reference
6+
title: Music Player
87
description: A production-grade Flutter application demonstrating Feature-First Clean Architecture, BLoC, and Offline-First principles.
98
tags: [flutter, clean-architecture, bloc, audio, sqlite]
10-
119
---
1210

1311
# Music Player 🎵
@@ -18,34 +16,37 @@ tags: [flutter, clean-architecture, bloc, audio, sqlite]
1816
1917
## Overview
2018

21-
This project serves as a strictly typed, production-grade reference implementation for **Clean Architecture** in Flutter. It is designed to demonstrate how to build a scalable, testable, and offline-first mobile application that survives background process termination and strictly enforces separation of concerns.
19+
This project serves as a strictly typed, production-grade reference implementation for **Clean Architecture** in Flutter. It is designed to demonstrate how to build a scalable, testable, and offline-first mobile application that survives background process termination.
20+
21+
**Key Features:**
22+
- **Background Audio:** Robust playback with notification controls (`audio_service` + `just_audio`).
23+
- **Offline-First:** Local SQLite database for analytics (`sqflite`).
24+
- **Granular Permissions:** Handling Android 13+ media permissions.
25+
- **Complex UI:** Physics-based animations and custom shaders.
2226

23-
Unlike simple "todo apps," this project tackles real-world complexity:
27+
## Documentation
2428

25-
- **Background Audio:** Managing Android/iOS media sessions (`MediaSessionService`) when the app is killed.
26-
- **Persistence:** A local SQLite database for analytics and `SharedPreferences` for flags.
27-
- **Hardware Permissions:** Graceful handling of Android 13+ granular media permissions.
28-
- **User Identity:** Local-first user profiles with avatar customization and physics-based interactions.
29+
* **[System Architecture](docs/architecture.md):** Deep dive into the Three-Layer Clean Architecture, DDD, and Folder Structure.
30+
* **[Background Audio Feature](docs/features/background_notifications.md):** How the background service and notifications work.
31+
* **[Analytics Feature](docs/features/analytics.md):** Implementation of local-first data tracking.
2932

3033
## Getting Started
3134

3235
### Prerequisites
3336

3437
- **Flutter SDK:** Stable channel (v3.10+)
35-
- **Platform:** Android (min SDK 21) or iOS (min 13.0). _Desktop support is experimental._
38+
- **Platform:** Android (min SDK 21) or iOS (min 13.0).
3639

3740
### Installation & Run
3841

3942
1. **Clone and Install:**
40-
4143
```bash
4244
git clone [repository_url]
4345
flutter pub get
4446
```
4547

4648
2. **Code Generation (Mandatory):**
4749
This project uses `freezed` and `json_serializable`. You must run the build runner before launching:
48-
4950
```bash
5051
dart run build_runner build --delete-conflicting-outputs
5152
```
@@ -55,84 +56,21 @@ Unlike simple "todo apps," this project tackles real-world complexity:
5556
flutter run
5657
```
5758

58-
## Architecture & Design (Reference)
59-
60-
The codebase follows the **Feature-First** packaging strategy. Each feature is a self-contained module with its own "Three-Layer" architecture.
61-
62-
### Directory Structure
63-
64-
```text
65-
lib/
66-
├── core/ # Shared Kernel (DI, Themes, Failures)
67-
├── features/
68-
│ ├── analytics/ # [Feature] Listening History & Graphs
69-
│ ├── home/ # [Feature] Navigation Shell & Orchestration
70-
│ ├── local music/ # [Feature] Device Storage Scanning
71-
│ ├── music_player/ # [Feature] Audio Engine & UI
72-
│ ├── onboarding/ # [Feature] First-Time User Experience & Registration
73-
│ └── profile/ # [Feature] User Identity & System Settings
74-
└── main.dart # Entry Point & Service Locator
75-
```
76-
77-
### The Three Layers (Per Feature)
78-
79-
1. **Domain (Inner Layer):**
80-
81-
- **Role:** Business Logic & Rules.
82-
- **Contents:** `Entities` (Pure Dart classes), `UseCases` (Single-action classes), `Repository Interfaces`.
83-
- **Dependencies:** ZERO Flutter dependencies. Pure Dart.
84-
85-
2. **Data (Middle Layer):**
59+
## Tech Stack
8660

87-
- **Role:** Data Retrieval & Transformation.
88-
- **Contents:** `DataSources` (API/DB/File), `DTOs` (Models), `Repository Implementations`.
89-
- **Dependencies:** External packages (`sqflite`, `dio`, `on_audio_query`).
90-
91-
3. **Presentation (Outer Layer):**
92-
- **Role:** UI & State Management.
93-
- **Contents:** `Pages`, `Widgets`, `BLoCs` / `Cubits`.
94-
- **Dependencies:** Flutter, `flutter_bloc`.
95-
96-
## Feature Catalog
97-
98-
| Feature | Description | Key Tech |
99-
| :--------------- | :------------------------------------------------------------------------ | :------------------------------------- |
100-
| **Local Music** | Scans device storage for audio files using `ContentResolver`. | `on_audio_query`, `permission_handler` |
101-
| **Music Player** | Robust playback engine with gapless queue, shuffle, and repeat. | `just_audio`, `audio_service` |
102-
| **Analytics** | Tracks playback history and visualizes data (Top Genres, Daily Activity). | `sqflite`, `fl_chart` |
103-
| **Onboarding** | First-run experience with "Auditory Profile" registration (Avatar/Name). | `flutter_animate`, `bloc` |
104-
| **Profile** | User identity management, UI customization, and Deep Cache Purge. | `image_picker`, `path_provider` |
105-
| **Background** | Keeps audio alive when the app is minimized or screen is off. | `Android Foreground Service` |
106-
107-
## Tech Stack & Decisions
108-
109-
| Category | Package | Reasoning |
110-
| :--------------- | :---------------------- | :--------------------------------------------------------------- |
111-
| **State** | `flutter_bloc` | Ensures unidirectional data flow and easy testing of states. |
112-
| **DI** | `get_it` | Decouples instantiation from usage (Service Locator pattern). |
113-
| **Functional** | `fpdart` | Enforces error handling via `Either<Failure, Success>` types. |
114-
| **Immutability** | `freezed` | Prevents side-effects in State objects and Entities. |
115-
| **Database** | `sqflite` | High-performance SQL engine for aggregation queries (Analytics). |
116-
| **Media** | `image_picker` | Native image selection for user avatars. |
117-
| **Assets** | `flutter_native_splash` | Provides a seamless launch experience on Android 12+. |
61+
| Category | Package |
62+
| :--------------- | :---------------------- |
63+
| **State** | `flutter_bloc` |
64+
| **DI** | `get_it` |
65+
| **Functional** | `fpdart` |
66+
| **Immutability** | `freezed` |
67+
| **Database** | `sqflite` |
68+
| **Audio** | `just_audio` |
11869

11970
## Troubleshooting
12071

121-
### Common Errors
122-
12372
**Error:** `Missing concrete implementation of ...` or `The method ... isn't defined.`
124-
125-
- **Cause:** The generated files (`*.g.dart`, `*.freezed.dart`) are out of sync.
126-
- **Fix:** Run `dart run build_runner build --delete-conflicting-outputs`.
73+
* **Fix:** Run `dart run build_runner build --delete-conflicting-outputs`.
12774
12875
**Error:** `Permission denied (READ_MEDIA_AUDIO)`
129-
130-
- **Cause:** Testing on Android 13+ emulator without granting runtime permissions.
131-
- **Fix:** Accept the system dialog, or manually enable permissions in App Settings.
132-
133-
**Error:** `No Material widget found`
134-
135-
- **Cause:** Using Material widgets (like `TextField`) without a `Scaffold` or `Material` ancestor.
136-
- **Fix:** Ensure top-level pages are wrapped in `Scaffold`.
137-
138-
---
76+
* **Fix:** Accept the system dialog, or manually enable permissions in App Settings.

android/app/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ android {
3535
// TODO: Add your own signing config for the release build.
3636
// Signing with the debug keys for now, so `flutter run --release` works.
3737
signingConfig = signingConfigs.getByName("debug")
38+
isMinifyEnabled = true
39+
isShrinkResources = true
40+
proguardFiles(
41+
getDefaultProguardFile("proguard-android-optimize.txt"),
42+
"proguard-rules.pro"
43+
)
3844
}
3945
}
4046
}

0 commit comments

Comments
 (0)