Files
xtremflow/lib/core/api/api_client.dart
T
GitHub CopilotandClaude Haiku 4.5 288bf9e6ee fix(api): auto-restore authentication token on app startup
Fixed playlist loading failure by ensuring the auth token is automatically
restored from localStorage when ApiClient initializes. Previously, the token
was stored but never restored, causing 401 Unauthorized errors on API calls.

Added _restoreTokenFromStorage() method to ApiClient constructor to load
and apply stored token immediately on app startup. This ensures all API
calls (including playlist fetching) have proper authentication.

Fixes: "I still don't have a playlist" issue where playlists were not loading

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-26 15:44:38 +01:00

96 lines
2.3 KiB
Dart

import 'package:dio/dio.dart';
import 'dart:html' as html;
/// API Client for communicating with the backend
class ApiClient {
static final ApiClient _instance = ApiClient._internal();
factory ApiClient() => _instance;
late final Dio _dio;
String? _token;
ApiClient._internal() {
_dio = Dio(BaseOptions(
baseUrl: _getBaseUrl(),
headers: {'Content-Type': 'application/json'},
connectTimeout: const Duration(seconds: 60),
receiveTimeout: const Duration(seconds: 60),
),);
// Add interceptor for logging
_dio.interceptors.add(LogInterceptor(
requestBody: true,
responseBody: true,
),);
// Restore token from localStorage on initialization
_restoreTokenFromStorage();
}
/// Restore token from localStorage on app startup
void _restoreTokenFromStorage() {
final storedToken = getStoredToken();
if (storedToken != null) {
_token = storedToken;
_dio.options.headers['Authorization'] = 'Bearer $storedToken';
}
}
/// Get base URL (same origin for production)
String _getBaseUrl() {
// Use current origin for API calls
return '';
}
/// Set authentication token
void setToken(String? token) {
_token = token;
if (token != null) {
_dio.options.headers['Authorization'] = 'Bearer $token';
// Store in localStorage for persistence
html.window.localStorage['auth_token'] = token;
} else {
_dio.options.headers.remove('Authorization');
html.window.localStorage.remove('auth_token');
}
}
/// Get stored token from localStorage
String? getStoredToken() {
return html.window.localStorage['auth_token'];
}
/// Restore token from localStorage
void restoreToken() {
final storedToken = getStoredToken();
if (storedToken != null) {
setToken(storedToken);
}
}
/// Clear token
void clearToken() {
setToken(null);
}
/// GET request
Future<Response> get(String path) async {
return _dio.get(path);
}
/// POST request
Future<Response> post(String path, {dynamic data}) async {
return _dio.post(path, data: data);
}
/// PUT request
Future<Response> put(String path, {dynamic data}) async {
return _dio.put(path, data: data);
}
/// DELETE request
Future<Response> delete(String path) async {
return _dio.delete(path);
}
}