116 lines
3.5 KiB
Dart
116 lines
3.5 KiB
Dart
import 'package:dio/dio.dart';
|
|
import '../core/app_config.dart';
|
|
import '../models/drive_models.dart';
|
|
import '../models/user_profile.dart';
|
|
import 'token_store.dart';
|
|
|
|
class ApiClient {
|
|
ApiClient(this._tokens) {
|
|
dio = Dio(
|
|
BaseOptions(
|
|
baseUrl: AppConfig.apiBaseUrl,
|
|
connectTimeout: const Duration(seconds: 20),
|
|
receiveTimeout: const Duration(minutes: 5),
|
|
),
|
|
);
|
|
dio.interceptors.add(
|
|
InterceptorsWrapper(
|
|
onRequest: (options, handler) async {
|
|
final token = await _tokens.read();
|
|
if (token != null) {
|
|
options.headers['Authorization'] = 'Bearer $token';
|
|
}
|
|
final organizationId = await _tokens.readOrganization();
|
|
if (organizationId != null) {
|
|
options.headers['X-Organization-Id'] = organizationId;
|
|
}
|
|
handler.next(options);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
final TokenStore _tokens;
|
|
late final Dio dio;
|
|
|
|
String messageFrom(Object error) {
|
|
if (error is DioException) {
|
|
final data = error.response?.data;
|
|
if (data is Map && data['error'] is String) {
|
|
return data['error'] as String;
|
|
}
|
|
if (error.type == DioExceptionType.connectionError) {
|
|
return 'Cannot reach the server. Check the API address and network.';
|
|
}
|
|
}
|
|
return 'Something went wrong. Please try again.';
|
|
}
|
|
|
|
Future<({String token, UserProfile user})> login(
|
|
String username,
|
|
String password,
|
|
) async {
|
|
final response = await dio.post(
|
|
'/auth/login',
|
|
data: {'username': username, 'password': password},
|
|
);
|
|
return (
|
|
token: response.data['token'] as String,
|
|
user: UserProfile.fromJson(response.data['user']),
|
|
);
|
|
}
|
|
|
|
Future<String> register(Map<String, dynamic> input) async {
|
|
final response = await dio.post('/auth/register', data: input);
|
|
return response.data['message'] as String;
|
|
}
|
|
|
|
Future<UserProfile> me() async {
|
|
final response = await dio.get('/auth/me');
|
|
return UserProfile.fromJson(response.data['user']);
|
|
}
|
|
|
|
Future<void> deleteAccount(String password) =>
|
|
dio.delete('/retention/account', data: {'password': password});
|
|
|
|
Future<OrganizationSummary> lookupOrganization(String code) async {
|
|
final response = await dio.get(
|
|
'/organizations/lookup/${Uri.encodeComponent(code)}',
|
|
);
|
|
return OrganizationSummary.fromJson(response.data['organization']);
|
|
}
|
|
|
|
Future<String> joinOrganization(String code) async {
|
|
final response = await dio.post(
|
|
'/auth/join',
|
|
data: {'organizationCode': code},
|
|
);
|
|
return response.data['message'] as String;
|
|
}
|
|
|
|
Future<List<DriveFolder>> folders(String? parentId) async {
|
|
final response = await dio.get(
|
|
'/folders',
|
|
queryParameters: parentId == null ? null : {'parentId': parentId},
|
|
);
|
|
return (response.data['folders'] as List)
|
|
.map((item) => DriveFolder.fromJson(item))
|
|
.toList();
|
|
}
|
|
|
|
Future<List<DriveFile>> files(String? folderId) async {
|
|
final response = await dio.get(
|
|
'/files',
|
|
queryParameters: folderId == null ? null : {'folderId': folderId},
|
|
);
|
|
return (response.data['files'] as List)
|
|
.map((item) => DriveFile.fromJson(item))
|
|
.toList();
|
|
}
|
|
|
|
Future<void> createFolder(String name, String? parentId) =>
|
|
dio.post('/folders', data: {'name': name, 'parentId': parentId});
|
|
Future<void> deleteFolder(String id) => dio.delete('/folders/$id');
|
|
Future<void> deleteFile(String id) => dio.delete('/files/$id');
|
|
String contentUrl(String id) => '${AppConfig.apiBaseUrl}/files/$id/content';
|
|
}
|