refactored chat data fetching to support separate cache and network callbacks
This commit is contained in:
@@ -5,7 +5,8 @@ import 'get_chat_response.dart';
|
||||
|
||||
class GetChatCache extends SimpleCache<GetChatResponse> {
|
||||
GetChatCache({
|
||||
required void Function(GetChatResponse) onUpdate,
|
||||
super.onCacheData,
|
||||
super.onNetworkData,
|
||||
super.onError,
|
||||
required String chatToken,
|
||||
}) : super(
|
||||
@@ -19,7 +20,6 @@ class GetChatCache extends SimpleCache<GetChatResponse> {
|
||||
),
|
||||
).run(),
|
||||
fromJson: GetChatResponse.fromJson,
|
||||
onUpdate: onUpdate,
|
||||
) {
|
||||
start('nc-chat-$chatToken');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import '../../../../../api/errors/error_mapper.dart';
|
||||
import '../../../../../api/marianumcloud/talk/chat/get_chat_response.dart';
|
||||
import '../../../infrastructure/loadable_state/loading_error.dart';
|
||||
import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc.dart';
|
||||
import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc_event.dart';
|
||||
@@ -57,23 +56,35 @@ class ChatBloc extends LoadableHydratedBloc<ChatEvent, ChatState, ChatRepository
|
||||
final requestStart = DateTime.now();
|
||||
_lastTokenSet = requestStart;
|
||||
|
||||
bool stillCurrent() {
|
||||
if (_lastTokenSet.isAfter(requestStart)) return false;
|
||||
if ((innerState?.currentToken ?? '') != token) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Object? capturedError;
|
||||
GetChatResponse? response;
|
||||
try {
|
||||
response = await repo.data.getChat(
|
||||
await repo.data.getChat(
|
||||
token: token,
|
||||
onCacheData: (data) {
|
||||
if (!stillCurrent()) return;
|
||||
// Cache hit: show data immediately but preserve lastFetch — the
|
||||
// cached payload may be stale and we don't want the UI to claim a
|
||||
// fresh fetch just happened.
|
||||
add(Emit((s) => s.copyWith(chatResponse: data)));
|
||||
},
|
||||
onNetworkData: (data) {
|
||||
if (!stillCurrent()) return;
|
||||
add(DataGathered((s) => s.copyWith(chatResponse: data)));
|
||||
},
|
||||
onError: (e) => capturedError = e,
|
||||
);
|
||||
} catch (e) {
|
||||
capturedError = e;
|
||||
}
|
||||
|
||||
if (_lastTokenSet.isAfter(requestStart)) return;
|
||||
if ((innerState?.currentToken ?? '') != token) return;
|
||||
if (!stillCurrent()) return;
|
||||
|
||||
if (response != null) {
|
||||
add(DataGathered((s) => s.copyWith(chatResponse: response)));
|
||||
}
|
||||
if (capturedError != null) {
|
||||
add(Error(LoadingError(
|
||||
message: errorToUserMessage(capturedError),
|
||||
|
||||
@@ -2,26 +2,18 @@ import '../../../../../api/marianumcloud/talk/chat/get_chat_cache.dart';
|
||||
import '../../../../../api/marianumcloud/talk/chat/get_chat_response.dart';
|
||||
|
||||
class ChatDataProvider {
|
||||
Future<GetChatResponse> getChat({
|
||||
Future<void> getChat({
|
||||
required String token,
|
||||
void Function(GetChatResponse data)? onUpdate,
|
||||
void Function(GetChatResponse data)? onCacheData,
|
||||
void Function(GetChatResponse data)? onNetworkData,
|
||||
void Function(Object)? onError,
|
||||
}) async {
|
||||
GetChatResponse? latest;
|
||||
Object? capturedError;
|
||||
final cache = GetChatCache(
|
||||
chatToken: token,
|
||||
onUpdate: (data) {
|
||||
latest = data;
|
||||
onUpdate?.call(data);
|
||||
},
|
||||
onError: (e) {
|
||||
capturedError = e;
|
||||
onError?.call(e);
|
||||
},
|
||||
onCacheData: onCacheData,
|
||||
onNetworkData: onNetworkData,
|
||||
onError: (e) => onError?.call(e),
|
||||
);
|
||||
await cache.ready;
|
||||
if (latest != null) return latest!;
|
||||
throw capturedError ?? Exception('No data and no error from getChat');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user