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> {
|
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');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user