87 lines
2.5 KiB
Dart
87 lines
2.5 KiB
Dart
import 'package:dio/dio.dart';
|
|
|
|
import '../models/knowledge_item.dart';
|
|
import 'api_client.dart';
|
|
|
|
class KnowledgeApi {
|
|
final Dio _dio;
|
|
const KnowledgeApi(this._dio);
|
|
|
|
/// Fetch a page of IDs. Returns (ids, total).
|
|
Future<(List<int>, int)> fetchIds({
|
|
String? noteType,
|
|
List<String> tags = const [],
|
|
String sort = 'modified',
|
|
String? q,
|
|
int limit = 50,
|
|
int offset = 0,
|
|
}) async {
|
|
try {
|
|
final params = <String, dynamic>{
|
|
'limit': limit,
|
|
'offset': offset,
|
|
'sort': sort,
|
|
if (noteType != null) 'type': noteType,
|
|
if (tags.isNotEmpty) 'tags': tags.join(','),
|
|
if (q != null && q.isNotEmpty) 'q': q,
|
|
};
|
|
final response =
|
|
await _dio.get('/api/knowledge/ids', queryParameters: params);
|
|
final data = response.data as Map<String, dynamic>;
|
|
final ids =
|
|
(data['ids'] as List<dynamic>).map((e) => e as int).toList();
|
|
final total = data['total'] as int;
|
|
return (ids, total);
|
|
} on DioException catch (e) {
|
|
throw dioToApp(e);
|
|
}
|
|
}
|
|
|
|
/// Batch-hydrate up to 100 IDs into full items.
|
|
Future<List<KnowledgeItem>> fetchBatch(List<int> ids) async {
|
|
if (ids.isEmpty) return [];
|
|
try {
|
|
final response = await _dio.get(
|
|
'/api/knowledge/batch',
|
|
queryParameters: {'ids': ids.join(',')},
|
|
);
|
|
final data = response.data as Map<String, dynamic>;
|
|
return (data['items'] as List<dynamic>)
|
|
.map((e) => KnowledgeItem.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
} on DioException catch (e) {
|
|
throw dioToApp(e);
|
|
}
|
|
}
|
|
|
|
/// Per-type counts for tab labels.
|
|
Future<Map<String, int>> fetchCounts({List<String> tags = const []}) async {
|
|
try {
|
|
final params = <String, dynamic>{
|
|
if (tags.isNotEmpty) 'tags': tags.join(','),
|
|
};
|
|
final response = await _dio.get('/api/knowledge/counts',
|
|
queryParameters: params);
|
|
return (response.data as Map<String, dynamic>)
|
|
.map((k, v) => MapEntry(k, (v as num).toInt()));
|
|
} on DioException catch (e) {
|
|
throw dioToApp(e);
|
|
}
|
|
}
|
|
|
|
/// All tags for the current type filter.
|
|
Future<List<String>> fetchTags({String? noteType}) async {
|
|
try {
|
|
final response = await _dio.get(
|
|
'/api/knowledge/tags',
|
|
queryParameters: {if (noteType != null) 'type': noteType},
|
|
);
|
|
return (response.data['tags'] as List<dynamic>)
|
|
.map((e) => e as String)
|
|
.toList();
|
|
} on DioException catch (e) {
|
|
throw dioToApp(e);
|
|
}
|
|
}
|
|
}
|