refactored data providers with centralized cache resolution, unified UI using custom dialogs and bottom sheets, and enhanced network error handling for Dio and TLS errors
This commit is contained in:
@@ -4,6 +4,7 @@ import 'dart:convert';
|
||||
import 'package:localstore/localstore.dart';
|
||||
|
||||
import 'api_response.dart';
|
||||
import 'errors/parse_exception.dart';
|
||||
|
||||
abstract class RequestCache<T extends ApiResponse?> {
|
||||
static const int cacheNothing = 0;
|
||||
@@ -81,10 +82,8 @@ abstract class RequestCache<T extends ApiResponse?> {
|
||||
|
||||
}
|
||||
|
||||
/// Concrete [RequestCache] that delegates the two overrides to functions
|
||||
/// passed in the constructor. Used to collapse the dozens of one-class-per-
|
||||
/// endpoint cache files that all just forward to `<Endpoint>().run()` and
|
||||
/// `<Response>.fromJson(jsonDecode(...))`.
|
||||
/// Concrete [RequestCache] that takes the two overrides as constructor
|
||||
/// callbacks instead of requiring a subclass per endpoint.
|
||||
class SimpleCache<T extends ApiResponse?> extends RequestCache<T> {
|
||||
final Future<T> Function() _loader;
|
||||
final T Function(Map<String, dynamic> json) _fromJson;
|
||||
@@ -115,3 +114,30 @@ class SimpleCache<T extends ApiResponse?> extends RequestCache<T> {
|
||||
@override
|
||||
T onLocalData(String json) => _fromJson(jsonDecode(json) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
/// Captures the latest cache payload (cached or network) and rethrows the
|
||||
/// captured network error if no payload arrived. Collapses the
|
||||
/// `latest`/`capturedError`/`await ready` boilerplate that DataProviders
|
||||
/// otherwise repeat per endpoint.
|
||||
Future<T> resolveFromCache<T extends ApiResponse?>(
|
||||
RequestCache<T> Function(void Function(T) onUpdate, void Function(Exception) onError) build, {
|
||||
void Function(Object)? onError,
|
||||
String? operationName,
|
||||
}) async {
|
||||
T? latest;
|
||||
Object? capturedError;
|
||||
final cache = build(
|
||||
(data) => latest = data,
|
||||
(e) {
|
||||
capturedError = e;
|
||||
onError?.call(e);
|
||||
},
|
||||
);
|
||||
await cache.ready;
|
||||
if (latest != null) return latest as T;
|
||||
final err = capturedError;
|
||||
if (err != null) throw err;
|
||||
throw ParseException(
|
||||
technicalDetails: operationName != null ? 'No data and no error from $operationName' : null,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user