88 lines
2.5 KiB
Dart
88 lines
2.5 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import '../../config/api_config.dart';
|
|
import '../../models/question_source_preference.dart';
|
|
import '../../services/auth_service.dart';
|
|
import 'question_source_api_exception.dart';
|
|
|
|
/// HTTP client for per-user question source preferences.
|
|
class QuestionSourceRemoteStore {
|
|
QuestionSourceRemoteStore({http.Client? client})
|
|
: _client = client ?? http.Client();
|
|
|
|
final http.Client _client;
|
|
|
|
Future<List<QuestionSourcePreference>?> fetchPreferences() async {
|
|
final String? token = await AuthService.instance.getIdToken();
|
|
if (token == null) {
|
|
return null;
|
|
}
|
|
|
|
final http.Response response = await _client.get(
|
|
Uri.parse('$apiBaseUrl/v1/me/question-sources'),
|
|
headers: _authHeaders(token),
|
|
);
|
|
|
|
if (response.statusCode != 200) {
|
|
throw QuestionSourceApiException(response.statusCode, response.body);
|
|
}
|
|
|
|
final Map<String, dynamic> body =
|
|
jsonDecode(response.body) as Map<String, dynamic>;
|
|
final List<dynamic> sources =
|
|
body['sources'] as List<dynamic>? ?? <dynamic>[];
|
|
return sources
|
|
.map(
|
|
(dynamic entry) => QuestionSourcePreference.fromJson(
|
|
entry as Map<String, dynamic>,
|
|
),
|
|
)
|
|
.toList();
|
|
}
|
|
|
|
Future<List<QuestionSourcePreference>> savePreferences(
|
|
List<QuestionSourcePreference> sources,
|
|
) async {
|
|
final String? token = await AuthService.instance.getIdToken();
|
|
if (token == null) {
|
|
throw StateError('Not signed in');
|
|
}
|
|
|
|
final http.Response response = await _client.put(
|
|
Uri.parse('$apiBaseUrl/v1/me/question-sources'),
|
|
headers: _authHeaders(token),
|
|
body: jsonEncode(<String, dynamic>{
|
|
'sources': sources
|
|
.map((QuestionSourcePreference source) => source.toStorageJson())
|
|
.toList(),
|
|
}),
|
|
);
|
|
|
|
if (response.statusCode != 200) {
|
|
throw QuestionSourceApiException(response.statusCode, response.body);
|
|
}
|
|
|
|
final Map<String, dynamic> body =
|
|
jsonDecode(response.body) as Map<String, dynamic>;
|
|
final List<dynamic> saved =
|
|
body['sources'] as List<dynamic>? ?? <dynamic>[];
|
|
return saved
|
|
.map(
|
|
(dynamic entry) => QuestionSourcePreference.fromJson(
|
|
entry as Map<String, dynamic>,
|
|
),
|
|
)
|
|
.toList();
|
|
}
|
|
|
|
Map<String, String> _authHeaders(String token) {
|
|
return <String, String>{
|
|
'Authorization': 'Bearer $token',
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
};
|
|
}
|
|
}
|