nc-photos/lib/bloc/ls_dir.dart

172 lines
4.3 KiB
Dart
Raw Normal View History

2021-04-10 06:28:12 +02:00
import 'package:bloc/bloc.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/entity/file.dart';
2021-05-24 09:09:25 +02:00
import 'package:nc_photos/entity/file/data_source.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/use_case/ls.dart';
class LsDirBlocItem {
LsDirBlocItem(this.file, this.children);
@override
toString({bool isDeep = false}) {
if (isDeep) {
return "$runtimeType:${_toDeepString(0)}";
} else {
2021-07-23 22:05:57 +02:00
final childrenStr =
children == null ? "null" : "List {length: ${children!.length}}";
return "$runtimeType {"
"file: '${file.path}', "
2021-07-23 22:05:57 +02:00
"children: $childrenStr, "
"}";
}
}
String _toDeepString(int level) {
String product = "\n" + " " * (level * 2) + "-${file.path}";
if (children != null) {
2021-07-23 22:05:57 +02:00
for (final c in children!) {
product += c._toDeepString(level + 1);
}
}
return product;
}
2021-07-23 22:05:57 +02:00
final File file;
2021-04-10 06:28:12 +02:00
/// Child directories under this directory
///
/// Null if this dir is not listed, due to things like depth limitation
2021-07-23 22:05:57 +02:00
List<LsDirBlocItem>? children;
2021-04-10 06:28:12 +02:00
}
abstract class LsDirBlocEvent {
const LsDirBlocEvent();
}
class LsDirBlocQuery extends LsDirBlocEvent {
const LsDirBlocQuery(
this.account,
this.root, {
this.depth = 1,
});
2021-04-10 06:28:12 +02:00
@override
toString() {
return "$runtimeType {"
"account: $account, "
"root: '${root.path}', "
"depth: $depth, "
2021-04-10 06:28:12 +02:00
"}";
}
LsDirBlocQuery copyWith({
2021-07-23 22:05:57 +02:00
Account? account,
File? root,
int? depth,
}) {
return LsDirBlocQuery(
account ?? this.account,
root ?? this.root,
depth: depth ?? this.depth,
);
}
2021-04-10 06:28:12 +02:00
final Account account;
final File root;
final int depth;
2021-04-10 06:28:12 +02:00
}
abstract class LsDirBlocState {
2021-07-23 22:05:57 +02:00
const LsDirBlocState(this.account, this.root, this.items);
2021-04-10 06:28:12 +02:00
@override
toString() {
return "$runtimeType {"
"account: $account, "
"root: ${root.path}"
2021-04-10 06:28:12 +02:00
"items: List {length: ${items.length}}, "
"}";
}
2021-07-23 22:05:57 +02:00
final Account? account;
final File root;
final List<LsDirBlocItem> items;
2021-04-10 06:28:12 +02:00
}
class LsDirBlocInit extends LsDirBlocState {
LsDirBlocInit() : super(null, File(path: ""), const []);
2021-04-10 06:28:12 +02:00
}
class LsDirBlocLoading extends LsDirBlocState {
2021-07-23 22:05:57 +02:00
const LsDirBlocLoading(Account? account, File root, List<LsDirBlocItem> items)
: super(account, root, items);
2021-04-10 06:28:12 +02:00
}
class LsDirBlocSuccess extends LsDirBlocState {
2021-07-23 22:05:57 +02:00
const LsDirBlocSuccess(Account? account, File root, List<LsDirBlocItem> items)
: super(account, root, items);
2021-04-10 06:28:12 +02:00
}
class LsDirBlocFailure extends LsDirBlocState {
const LsDirBlocFailure(
2021-07-23 22:05:57 +02:00
Account? account, File root, List<LsDirBlocItem> items, this.exception)
: super(account, root, items);
2021-04-10 06:28:12 +02:00
@override
toString() {
return "$runtimeType {"
"super: ${super.toString()}, "
"exception: $exception, "
"}";
}
final dynamic exception;
}
/// A bloc that return all directories under a dir recursively
class LsDirBloc extends Bloc<LsDirBlocEvent, LsDirBlocState> {
LsDirBloc() : super(LsDirBlocInit());
@override
mapEventToState(LsDirBlocEvent event) async* {
_log.info("[mapEventToState] $event");
if (event is LsDirBlocQuery) {
yield* _onEventQuery(event);
}
}
Stream<LsDirBlocState> _onEventQuery(LsDirBlocQuery ev) async* {
try {
yield LsDirBlocLoading(ev.account, ev.root, state.items);
yield LsDirBlocSuccess(ev.account, ev.root, await _query(ev));
2021-04-10 06:28:12 +02:00
} catch (e) {
_log.severe("[_onEventQuery] Exception while request", e);
yield LsDirBlocFailure(ev.account, ev.root, state.items, e);
2021-04-10 06:28:12 +02:00
}
}
Future<List<LsDirBlocItem>> _query(LsDirBlocQuery ev) async {
final product = <LsDirBlocItem>[];
var files = _cache[ev.root.path];
if (files == null) {
files = (await Ls(FileRepo(FileWebdavDataSource()))(ev.account, ev.root))
2021-07-23 22:05:57 +02:00
.where((f) => f.isCollection ?? false)
.toList();
_cache[ev.root.path] = files;
}
2021-04-10 06:28:12 +02:00
for (final f in files) {
2021-07-23 22:05:57 +02:00
List<LsDirBlocItem>? children;
if (ev.depth > 1) {
children = await _query(ev.copyWith(root: f, depth: ev.depth - 1));
2021-04-10 06:28:12 +02:00
}
product.add(LsDirBlocItem(f, children));
2021-04-10 06:28:12 +02:00
}
return product;
2021-04-10 06:28:12 +02:00
}
final _cache = <String, List<File>>{};
2021-04-10 06:28:12 +02:00
static final _log = Logger("bloc.ls_dir.LsDirBloc");
}