52 lines
1.5 KiB
Dart
52 lines
1.5 KiB
Dart
import 'package:dio/dio.dart';
|
|
|
|
import 'emergency_notice.dart';
|
|
|
|
/// Loads the emergency notice from a foreign URL over a standalone [Dio] — no
|
|
/// MarianumConnect interceptors/base URL/auth, so it survives a backend outage.
|
|
/// Never throws: any failure yields `null` (nothing shown).
|
|
///
|
|
/// A [cacheTtl] in-memory throttle keeps rapid resumes from hammering the host;
|
|
/// it lives only for the process, so a cold start always fetches fresh.
|
|
class EmergencyNoticeClient {
|
|
EmergencyNoticeClient();
|
|
|
|
static const Duration cacheTtl = Duration(minutes: 1);
|
|
|
|
EmergencyNotice? _cached;
|
|
String? _cachedUrl;
|
|
DateTime? _cachedAt;
|
|
|
|
Future<EmergencyNotice?> fetch(String url) async {
|
|
final cachedAt = _cachedAt;
|
|
if (cachedAt != null &&
|
|
_cachedUrl == url &&
|
|
DateTime.now().difference(cachedAt) < cacheTtl) {
|
|
return _cached;
|
|
}
|
|
|
|
EmergencyNotice? result;
|
|
try {
|
|
final dio = Dio(
|
|
BaseOptions(
|
|
connectTimeout: const Duration(seconds: 5),
|
|
receiveTimeout: const Duration(seconds: 5),
|
|
sendTimeout: const Duration(seconds: 5),
|
|
responseType: ResponseType.plain,
|
|
),
|
|
);
|
|
final response = await dio.get<String>(url);
|
|
final raw = response.data;
|
|
result = (raw == null || raw.isEmpty) ? null : EmergencyNotice.parse(raw);
|
|
} catch (_) {
|
|
result = null;
|
|
}
|
|
|
|
// Cache failures too, so a down server isn't retried on every resume.
|
|
_cached = result;
|
|
_cachedUrl = url;
|
|
_cachedAt = DateTime.now();
|
|
return result;
|
|
}
|
|
}
|