refactored chat data fetching to support separate cache and network callbacks

This commit is contained in:
2026-05-07 09:46:30 +02:00
parent 517e515ac1
commit 710e88d744
3 changed files with 27 additions and 24 deletions
@@ -5,7 +5,8 @@ import 'get_chat_response.dart';
class GetChatCache extends SimpleCache<GetChatResponse> { class GetChatCache extends SimpleCache<GetChatResponse> {
GetChatCache({ GetChatCache({
required void Function(GetChatResponse) onUpdate, super.onCacheData,
super.onNetworkData,
super.onError, super.onError,
required String chatToken, required String chatToken,
}) : super( }) : super(
@@ -19,7 +20,6 @@ class GetChatCache extends SimpleCache<GetChatResponse> {
), ),
).run(), ).run(),
fromJson: GetChatResponse.fromJson, fromJson: GetChatResponse.fromJson,
onUpdate: onUpdate,
) { ) {
start('nc-chat-$chatToken'); start('nc-chat-$chatToken');
} }
+19 -8
View File
@@ -1,5 +1,4 @@
import '../../../../../api/errors/error_mapper.dart'; import '../../../../../api/errors/error_mapper.dart';
import '../../../../../api/marianumcloud/talk/chat/get_chat_response.dart';
import '../../../infrastructure/loadable_state/loading_error.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.dart';
import '../../../infrastructure/utility_widgets/loadable_hydrated_bloc/loadable_hydrated_bloc_event.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(); final requestStart = DateTime.now();
_lastTokenSet = requestStart; _lastTokenSet = requestStart;
bool stillCurrent() {
if (_lastTokenSet.isAfter(requestStart)) return false;
if ((innerState?.currentToken ?? '') != token) return false;
return true;
}
Object? capturedError; Object? capturedError;
GetChatResponse? response;
try { try {
response = await repo.data.getChat( await repo.data.getChat(
token: token, 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, onError: (e) => capturedError = e,
); );
} catch (e) { } catch (e) {
capturedError = e; capturedError = e;
} }
if (_lastTokenSet.isAfter(requestStart)) return; if (!stillCurrent()) return;
if ((innerState?.currentToken ?? '') != token) return;
if (response != null) {
add(DataGathered((s) => s.copyWith(chatResponse: response)));
}
if (capturedError != null) { if (capturedError != null) {
add(Error(LoadingError( add(Error(LoadingError(
message: errorToUserMessage(capturedError), 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'; import '../../../../../api/marianumcloud/talk/chat/get_chat_response.dart';
class ChatDataProvider { class ChatDataProvider {
Future<GetChatResponse> getChat({ Future<void> getChat({
required String token, required String token,
void Function(GetChatResponse data)? onUpdate, void Function(GetChatResponse data)? onCacheData,
void Function(GetChatResponse data)? onNetworkData,
void Function(Object)? onError, void Function(Object)? onError,
}) async { }) async {
GetChatResponse? latest;
Object? capturedError;
final cache = GetChatCache( final cache = GetChatCache(
chatToken: token, chatToken: token,
onUpdate: (data) { onCacheData: onCacheData,
latest = data; onNetworkData: onNetworkData,
onUpdate?.call(data); onError: (e) => onError?.call(e),
},
onError: (e) {
capturedError = e;
onError?.call(e);
},
); );
await cache.ready; await cache.ready;
if (latest != null) return latest!;
throw capturedError ?? Exception('No data and no error from getChat');
} }
} }