Music Recognition app using Audd's Music recognition API
🏗️ Construction is underway, there may be a lot of elements missing in this README
Couple steps are required to run this app on your local machine.
First, get an API Token from Audd by following this link.
An API Token is required to run the app. This API Token is retrieved from environment variables read throught dart define. You'll need to provide is as well as the api base url:
$ flutter run --dart-define apiBaseUrl=https://api.audd.io --dart-define AUDD_API_TOKEN=<YOUR_API_TOKEN>
Install dependencies:
$ flutter pub get
Run code generation:
$ flutter pub run build_runner build --delete-conflicting-outputs
This project uses the BLoC Architecture. Learn more on https://bloclibrary.dev
This layer is responsible of manipulating data from one or more sources
Are responsible for API calls. They all extend the BaseApiController
class. Are not responsible for data processing.
class UserApiController extends BaseApiController {
UserApiController({required super.dio});
Future<Response<Json>> recognize({
required Request request,
CancelToken? cancelToken,
}) async {
try {
final Response<Json> response = await dio.post('/endpoint', data: await request.toJson());
return response;
} on DioError catch (_) {
rethrow;
}
}
}
They can aggregate multiple data sources (eg. Multiple API Controllers). They all extend be BaseRepository
class which contains the runApiCall
method that has necessary logi cfor errors handling.
class TestRepository extends BaseRepository {
final MyApiController _myApiController;
final MySecondApiController _mySecondApiController;
TestRepository({
MyApiController? myApiController,
MySecondApiController? mySecondApiController,
}) : _myApiController = myApiController ?? locator<MyApiController>(),
_mySecondApiController = mySecondApiController ?? locator<MySecondApiController>();
Future<NetworkResponse<TestResponse, CustomHttpException>> test(MyRequest request) async {
return runApiCall<TestResponse>(
call: () async {
final response = await _myApiController.test(request: request);
return NetworkResponse.success(TestResponse.fromJson(response.data!));
},
);
}
}
The business logic layer's responsibility is to respond to input from the presentation layer with new states. This layer can depend on one or more repositories to retrieve data needed to build up the application state.
This layer hosts our blocks, cubits and services.
They are used to store any logic that's not related to a UI State
They are used to store any logic that can result to a UI State change
This layer is the one the user interacts with. It renders itself base on one or more BLoC/Cubit's state
Here's how our folder structure look like:
lib/
├── generated/
└── src/
├── core/
│ ├── i18n/
│ ├── routing/
│ ├── theme/
│ ├── app_initialiser.dart
│ ├── application.dart
│ └── environment.dart
├── datasource/
│ ├── http/
│ ├── models/
│ └── repositories/
│ └── base_repository.dart
├── features/
│ ├── music_recognition/
│ │ ├── enums/
│ │ ├── exceptions/
│ │ ├── logic/
│ │ ├── repositories/
│ │ ├── services/
│ │ └── ui/
│ └── music_details/
└── main.dart
This repo uses couple of testing libs :
- bloc_test: A Dart package that makes testing blocs and cubits easy
- mocktail: A Dart mock library which simplifies mocking with null safety support and no manual mocks or code generation.
- http_mock_adapter: A simple to use mocking package for Dio intended to be used in tests. It provides various types and methods to declaratively mock request-response communication.
Usage examples are available in the test
dir.
- fvm: used for flutter version management
- flutter_gen: Used to generated assets