83 lines
2.7 KiB
Dart
83 lines
2.7 KiB
Dart
import '../../../../../api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart';
|
|
import '../../../infrastructure/loadableState/loading_error.dart';
|
|
import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart';
|
|
import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart';
|
|
import '../repository/files_repository.dart';
|
|
import 'files_event.dart';
|
|
import 'files_state.dart';
|
|
|
|
class FilesBloc extends LoadableHydratedBloc<FilesEvent, FilesState, FilesRepository> {
|
|
final List<String> initialPath;
|
|
|
|
FilesBloc({this.initialPath = const []});
|
|
|
|
@override
|
|
FilesRepository repository() => FilesRepository();
|
|
|
|
@override
|
|
FilesState fromNothing() => FilesState(currentPath: initialPath);
|
|
|
|
@override
|
|
FilesState fromStorage(Map<String, dynamic> json) => FilesState.fromJson(json);
|
|
|
|
@override
|
|
Map<String, dynamic>? toStorage(FilesState state) => null;
|
|
|
|
@override
|
|
Future<void> gatherData() async {
|
|
final path = innerState?.currentPath ?? initialPath;
|
|
await _query(path);
|
|
}
|
|
|
|
Future<void> refresh() async {
|
|
add(RefetchStarted<FilesState>());
|
|
final path = innerState?.currentPath ?? initialPath;
|
|
await _query(path);
|
|
}
|
|
|
|
Future<void> setPath(List<String> path) async {
|
|
add(Emit((s) => s.copyWith(currentPath: path, listing: null)));
|
|
add(RefetchStarted<FilesState>());
|
|
await _query(path);
|
|
}
|
|
|
|
Future<void> createFolder(String name) async {
|
|
final path = innerState?.currentPath ?? initialPath;
|
|
await repo.data.createFolder('${path.join('/')}/$name');
|
|
await refresh();
|
|
}
|
|
|
|
Future<void> _query(List<String> path) async {
|
|
final pathString = path.isEmpty ? '/' : path.join('/');
|
|
|
|
Object? capturedError;
|
|
ListFilesResponse? listing;
|
|
try {
|
|
listing = await repo.data.listFiles(
|
|
pathString,
|
|
onCacheData: (cached) {
|
|
// Cached payload arrives before the network call settles. Surface it
|
|
// immediately via Emit so the listing is visible while isLoading
|
|
// stays true and the top loading bar keeps spinning.
|
|
cached.files.removeWhere((file) => file.name.isEmpty || file.name == path.lastOrNull);
|
|
add(Emit((s) => s.copyWith(listing: cached)));
|
|
},
|
|
onError: (e) => capturedError = e,
|
|
);
|
|
} catch (e) {
|
|
capturedError = e;
|
|
}
|
|
|
|
if (listing != null) {
|
|
listing.files.removeWhere((file) => file.name.isEmpty || file.name == path.lastOrNull);
|
|
add(DataGathered((s) => s.copyWith(listing: listing)));
|
|
}
|
|
if (capturedError != null) {
|
|
add(Error(LoadingError(
|
|
message: capturedError.toString(),
|
|
allowRetry: true,
|
|
)));
|
|
}
|
|
}
|
|
}
|