feat(app): clean architecture with typed repositories, DTO models and calendar event logos

This commit is contained in:
2026-08-15 01:03:22 +02:00
parent f08fecde23
commit 15f8f7896e
34 changed files with 1435 additions and 1420 deletions
@@ -2,6 +2,7 @@ import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../core/network/api_client.dart';
import '../models/discovery_asset_model.dart';
import '../repositories/discovery_repository.dart';
class DiscoveryState extends Equatable {
final List<DiscoveryAssetModel> assets;
@@ -27,27 +28,24 @@ class DiscoveryState extends Equatable {
}
class DiscoveryCubit extends Cubit<DiscoveryState> {
final ApiClient apiClient;
final DiscoveryRepository repository;
DiscoveryCubit({required this.apiClient}) : super(const DiscoveryState());
DiscoveryCubit({
DiscoveryRepository? repository,
ApiClient? apiClient,
}) : repository = repository ?? DiscoveryRepository(apiClient: apiClient!),
super(const DiscoveryState());
Future<void> loadDiscovery({int limit = 15}) async {
if (state.isLoading) return;
emit(state.copyWith(isLoading: true));
try {
final res = await apiClient.get('/api/v1/assets/discovery?limit=$limit');
if (res.statusCode == 200 && res.data is List) {
final list = (res.data as List)
.map((e) => DiscoveryAssetModel.fromJson(Map<String, dynamic>.from(e)))
.toList();
emit(DiscoveryState(assets: list, isLoading: false));
} else {
emit(state.copyWith(isLoading: false));
}
final list = await repository.getDiscoveryAssets(limit: limit);
emit(DiscoveryState(assets: list, isLoading: false));
} catch (_) {
emit(state.copyWith(isLoading: false));
}
}
}
@@ -0,0 +1,21 @@
import '../../../core/network/api_client.dart';
import '../models/discovery_asset_model.dart';
/// Clean Architecture Repository for fetching asset discovery data.
class DiscoveryRepository {
final ApiClient apiClient;
const DiscoveryRepository({required this.apiClient});
/// Fetches top discovery assets.
Future<List<DiscoveryAssetModel>> getDiscoveryAssets({int limit = 15}) async {
final res = await apiClient.get('/api/v1/assets/discovery?limit=$limit');
if (res.statusCode == 200 && res.data is List) {
return (res.data as List)
.whereType<Map<String, dynamic>>()
.map((e) => DiscoveryAssetModel.fromJson(e))
.toList();
}
return [];
}
}