chore: prepare yanting monorepo handoff
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../models/models.dart';
|
||||
|
||||
abstract class ReportDataSource {
|
||||
Future<List<ReportCardModel>> recommended();
|
||||
Future<List<ReportCardModel>> reports();
|
||||
Future<List<Institution>> institutions();
|
||||
Future<Institution> institutionDetail(String institutionId);
|
||||
Future<List<AudioItem>> listen();
|
||||
Future<ReportDetail> reportDetail(String reportId);
|
||||
Future<ModuleDetail> moduleDetail(String reportId, String moduleId);
|
||||
}
|
||||
|
||||
class RnbApiDataSource implements ReportDataSource {
|
||||
RnbApiDataSource({
|
||||
http.Client? client,
|
||||
this.baseUrl = const String.fromEnvironment('RNB_API_BASE'),
|
||||
}) : client = client ?? http.Client();
|
||||
|
||||
final http.Client client;
|
||||
final String baseUrl;
|
||||
|
||||
Future<JsonMap> _get(String path) async {
|
||||
if (baseUrl.isEmpty) {
|
||||
throw StateError('RNB_API_BASE is required for live API requests.');
|
||||
}
|
||||
final response = await client.get(Uri.parse('$baseUrl$path'));
|
||||
if (response.statusCode != 200) {
|
||||
throw StateError('Request failed: ${response.statusCode}');
|
||||
}
|
||||
return jsonDecode(utf8.decode(response.bodyBytes)) as JsonMap;
|
||||
}
|
||||
|
||||
List<JsonMap> _items(JsonMap body) => asMapList(body['items']);
|
||||
|
||||
@override
|
||||
Future<List<ReportCardModel>> recommended() async {
|
||||
final body = await _get('/feed/recommended');
|
||||
return _items(body).map(ReportCardModel.fromJson).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ReportCardModel>> reports() async {
|
||||
final body = await _get('/reports');
|
||||
return _items(body).map(ReportCardModel.fromJson).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Institution>> institutions() async {
|
||||
final body = await _get('/institutions');
|
||||
return _items(body).map(Institution.fromJson).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Institution> institutionDetail(String institutionId) async {
|
||||
return Institution.fromJson(await _get('/institutions/$institutionId'));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<AudioItem>> listen() async {
|
||||
final body = await _get('/listen');
|
||||
return _items(body).map(AudioItem.fromJson).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ReportDetail> reportDetail(String reportId) async {
|
||||
return ReportDetail.fromJson(await _get('/reports/$reportId'));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ModuleDetail> moduleDetail(String reportId, String moduleId) async {
|
||||
return ModuleDetail.fromJson(await _get('/reports/$reportId/modules/$moduleId'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user