новости

This commit is contained in:
2026-03-22 17:36:24 +04:00
parent 4edfb52396
commit 48ff9b63d8
9 changed files with 495 additions and 65 deletions
@@ -10,6 +10,7 @@ import 'package:moonwell_launcher/features/launcher/data/launcher_log_service.da
import 'package:moonwell_launcher/features/launcher/domain/entities/client_manifest.dart';
import 'package:moonwell_launcher/features/launcher/domain/entities/client_manifest_file.dart';
import 'package:moonwell_launcher/features/launcher/domain/entities/launcher_exception.dart';
import 'package:moonwell_launcher/features/launcher/domain/entities/launcher_news_item.dart';
import 'package:moonwell_launcher/features/launcher/domain/entities/launcher_session.dart';
@lazySingleton
@@ -83,6 +84,44 @@ class LauncherApiClient {
}
}
Future<List<LauncherNewsItem>> fetchNews(String accessToken) async {
final newsUri = _resolveUri('api/launcher/news');
try {
final response = await _dio.getUri(
newsUri,
options: _authorizedOptions(accessToken),
);
final payload = _coerceMap(response.data);
final rawItems = payload['data'];
if (rawItems is! List) {
throw const LauncherApiException('Unexpected launcher news payload.');
}
return rawItems
.whereType<Map>()
.map(
(item) => LauncherNewsItem.fromJson(
item.map((key, value) => MapEntry(key.toString(), value)),
),
)
.toList(growable: false);
} on DioException catch (error, stackTrace) {
await _launcherLogService.error(
'Launcher news request failed.',
details: <String, Object?>{
'endpoint': newsUri.toString(),
'statusCode': error.response?.statusCode,
'dioType': error.type.name,
'responseBody': _summarizePayload(error.response?.data),
},
error: error,
stackTrace: stackTrace,
);
throw LauncherApiException(_extractErrorMessage(error));
}
}
Future<void> downloadFile({
required String installationDir,
required String accessToken,
@@ -0,0 +1,41 @@
final class LauncherNewsItem {
final int id;
final String title;
final String body;
final String? imageUrl;
final DateTime? createdAt;
const LauncherNewsItem({
required this.id,
required this.title,
required this.body,
required this.imageUrl,
required this.createdAt,
});
factory LauncherNewsItem.fromJson(Map<String, dynamic> json) {
return LauncherNewsItem(
id: (json['id'] as num? ?? 0).toInt(),
title: (json['title'] as String? ?? '').trim(),
body: (json['body'] as String? ?? '').trim(),
imageUrl: _parseImageUrl(json['image_url'] as String?),
createdAt: _parseDateTime(json['created_at'] as String?),
);
}
static String? _parseImageUrl(String? rawValue) {
if (rawValue == null || rawValue.trim().isEmpty) {
return null;
}
return rawValue.trim();
}
static DateTime? _parseDateTime(String? rawValue) {
if (rawValue == null || rawValue.trim().isEmpty) {
return null;
}
return DateTime.tryParse(rawValue);
}
}