loading state and error handling refactor

This commit is contained in:
2026-05-06 10:11:45 +02:00
parent 2c376afd91
commit 4b1d4379a0
48 changed files with 1377 additions and 354 deletions
@@ -1,3 +1,4 @@
import '../../../../../api/errors/error_mapper.dart';
import '../../../../../api/marianumcloud/talk/chat/getChatResponse.dart';
import '../../../infrastructure/loadableState/loading_error.dart';
import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart';
@@ -75,8 +76,9 @@ class ChatBloc extends LoadableHydratedBloc<ChatEvent, ChatState, ChatRepository
}
if (capturedError != null) {
add(Error(LoadingError(
message: capturedError.toString(),
allowRetry: true,
message: errorToUserMessage(capturedError),
technicalDetails: errorToTechnicalDetails(capturedError),
allowRetry: errorAllowsRetry(capturedError),
)));
}
}
@@ -1,5 +1,6 @@
import 'package:flutter_app_badge/flutter_app_badge.dart';
import '../../../../../api/errors/error_mapper.dart';
import '../../../infrastructure/loadableState/loading_error.dart';
import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart';
import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart';
@@ -59,8 +60,9 @@ class ChatListBloc extends LoadableHydratedBloc<ChatListEvent, ChatListState, Ch
}
if (capturedError != null) {
add(Error(LoadingError(
message: capturedError.toString(),
allowRetry: true,
message: errorToUserMessage(capturedError),
technicalDetails: errorToTechnicalDetails(capturedError),
allowRetry: errorAllowsRetry(capturedError),
)));
}
}
@@ -1,3 +1,4 @@
import '../../../../../api/errors/error_mapper.dart';
import '../../../../../api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart';
import '../../../infrastructure/loadableState/loading_error.dart';
import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart';
@@ -74,8 +75,9 @@ class FilesBloc extends LoadableHydratedBloc<FilesEvent, FilesState, FilesReposi
}
if (capturedError != null) {
add(Error(LoadingError(
message: capturedError.toString(),
allowRetry: true,
message: errorToUserMessage(capturedError),
technicalDetails: errorToTechnicalDetails(capturedError),
allowRetry: errorAllowsRetry(capturedError),
)));
}
}
@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:developer';
import 'package:easy_debounce/easy_debounce.dart';
@@ -9,14 +10,23 @@ import '../../app_modules.dart';
class SettingsCubit extends HydratedCubit<Settings> {
static const _debounceTag = 'settings_persist';
bool _emitScheduled = false;
SettingsCubit() : super(DefaultSettings.get());
Settings val({bool write = false}) {
if (write) {
// Notify listeners immediately so the UI reflects the mutation right away;
// debounce the actual persistence to disk to avoid hammering on rapid edits.
_emitFreshInstance();
// Defer the emit until the synchronous mutation on the returned object
// has finished. Without this scheduleMicrotask the cubit emits a copy
// captured *before* the assignment runs, so listeners (and HydratedBloc
// persistence) see the old value on the first emit.
if (!_emitScheduled) {
_emitScheduled = true;
scheduleMicrotask(() {
_emitScheduled = false;
_emitFreshInstance();
});
}
EasyDebounce.debounce(_debounceTag, const Duration(milliseconds: 500), _emitFreshInstance);
}
return state;