Files
AudiOhm/frontend/lib/infrastructure/datasources/remote/api_service.dart
T
root a89c7894cf Initial commit: AudiOhm - Alternative Spotify avec streaming YouTube
Backend:
- FastAPI avec PostgreSQL et Redis
- Authentification JWT complète
- API REST pour musique, playlists, recherche
- Streaming audio via yt-dlp
- SQLAlchemy 2.0 async

Frontend:
- Flutter avec thème néon cyberpunk
- State management Riverpod
- Layout adaptatif desktop/mobile
- Lecteur audio avec mini-player

Infrastructure:
- Docker Compose (PostgreSQL + Redis)
- Scripts d'installation automatisés
- Scripts de build pour exécutables

Fichiers ajoutés:
- BUILD_CLIENT_*.bat/sh: Scripts de compilation
- BUILD_CLIENT_README.md: Documentation compilation
- CHECK_FLUTTER.sh: Vérificateur d'environnement
- requirements.txt mis à jour pour Python 3.13
- Modèles SQLAlchemy corrigés (metadata -> extra_metadata)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-18 20:08:36 +00:00

77 lines
2.2 KiB
Dart

/// API Service - Main HTTP client using Dio
library;
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import '../../../core/constants/api_constants.dart';
import '../../providers/auth_provider.dart';
/// API Service provider
final apiServiceProvider = Provider<Dio>((ref) {
final authState = ref.watch(authProvider);
final token = authState?.accessToken;
final options = BaseOptions(
baseUrl: ApiConstants.baseUrl,
connectTimeout: const Duration(milliseconds: ApiConstants.connectionTimeoutMs),
receiveTimeout: const Duration(milliseconds: ApiConstants.receiveTimeoutMs),
sendTimeout: const Duration(milliseconds: ApiConstants.sendTimeoutMs),
headers: {
'Content-Type': 'application/json',
if (token != null) 'Authorization': 'Bearer $token',
},
);
final dio = Dio(options);
// Add logger in debug mode
dio.interceptors.add(
PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseBody: true,
responseHeader: false,
error: true,
compact: true,
),
);
// Add token refresh interceptor
dio.interceptors.add(
InterceptorsWrapper(
onError: (error, handler) async {
if (error.response?.statusCode == 401) {
// Try to refresh token
try {
final newToken = await ref.read(authProvider.notifier).refreshToken();
if (newToken != null) {
// Retry original request with new token
final opts = options.copyWith(
headers: {
...options.headers,
'Authorization': 'Bearer $newToken',
},
);
final clonedReq = await dio.fetch(opts..path = error.requestOptions.path);
return handler.resolve(clonedReq);
}
} catch (e) {
// Refresh failed, logout user
ref.read(authProvider.notifier).logout();
}
}
return handler.next(error);
},
),
);
return dio;
});
/// Get API client
Dio getDio(Ref ref) {
return ref.read(apiServiceProvider);
}