2021-04-10 06:28:12 +02:00
|
|
|
import 'package:bloc/bloc.dart';
|
2021-08-16 21:05:00 +02:00
|
|
|
import 'package:equatable/equatable.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'package:nc_photos/account.dart';
|
|
|
|
import 'package:nc_photos/entity/file.dart';
|
|
|
|
import 'package:nc_photos/use_case/ls.dart';
|
|
|
|
|
2021-08-16 21:05:00 +02:00
|
|
|
class LsDirBlocItem with EquatableMixin {
|
2021-04-10 06:28:12 +02:00
|
|
|
LsDirBlocItem(this.file, this.children);
|
|
|
|
|
2021-06-05 19:50:00 +02:00
|
|
|
@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}}";
|
2021-06-05 19:50:00 +02:00
|
|
|
return "$runtimeType {"
|
|
|
|
"file: '${file.path}', "
|
2021-07-23 22:05:57 +02:00
|
|
|
"children: $childrenStr, "
|
2021-06-05 19:50:00 +02:00
|
|
|
"}";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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!) {
|
2021-06-05 19:50:00 +02:00
|
|
|
product += c._toDeepString(level + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return product;
|
|
|
|
}
|
|
|
|
|
2021-08-16 21:05:00 +02:00
|
|
|
@override
|
|
|
|
get props => [
|
|
|
|
file,
|
|
|
|
children,
|
|
|
|
];
|
|
|
|
|
2021-07-23 22:05:57 +02:00
|
|
|
final File file;
|
2021-04-10 06:28:12 +02:00
|
|
|
|
2021-06-05 19:50:00 +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 {
|
2021-06-05 19:50:00 +02:00
|
|
|
const LsDirBlocQuery(
|
|
|
|
this.account,
|
|
|
|
this.root, {
|
|
|
|
this.depth = 1,
|
|
|
|
});
|
2021-04-10 06:28:12 +02:00
|
|
|
|
|
|
|
@override
|
|
|
|
toString() {
|
|
|
|
return "$runtimeType {"
|
|
|
|
"account: $account, "
|
2021-06-05 19:50:00 +02:00
|
|
|
"root: '${root.path}', "
|
|
|
|
"depth: $depth, "
|
2021-04-10 06:28:12 +02:00
|
|
|
"}";
|
|
|
|
}
|
|
|
|
|
2021-06-05 19:50:00 +02:00
|
|
|
LsDirBlocQuery copyWith({
|
2021-07-23 22:05:57 +02:00
|
|
|
Account? account,
|
|
|
|
File? root,
|
|
|
|
int? depth,
|
2021-06-05 19:50:00 +02:00
|
|
|
}) {
|
|
|
|
return LsDirBlocQuery(
|
|
|
|
account ?? this.account,
|
|
|
|
root ?? this.root,
|
|
|
|
depth: depth ?? this.depth,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-04-10 06:28:12 +02:00
|
|
|
final Account account;
|
2021-06-05 19:50:00 +02:00
|
|
|
final File root;
|
|
|
|
final int depth;
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|
|
|
|
|
2021-08-16 21:05:00 +02:00
|
|
|
abstract class LsDirBlocState with EquatableMixin {
|
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, "
|
2021-08-16 21:05:00 +02:00
|
|
|
"root: ${root.path}, "
|
2021-04-10 06:28:12 +02:00
|
|
|
"items: List {length: ${items.length}}, "
|
|
|
|
"}";
|
|
|
|
}
|
|
|
|
|
2021-08-16 21:05:00 +02:00
|
|
|
@override
|
|
|
|
get props => [
|
|
|
|
account,
|
|
|
|
root,
|
|
|
|
items,
|
|
|
|
];
|
|
|
|
|
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 {
|
2021-06-05 19:50:00 +02:00
|
|
|
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)
|
2021-06-05 19:50:00 +02:00
|
|
|
: 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)
|
2021-06-05 19:50:00 +02:00
|
|
|
: 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)
|
2021-06-05 19:50:00 +02:00
|
|
|
: super(account, root, items);
|
2021-04-10 06:28:12 +02:00
|
|
|
|
|
|
|
@override
|
|
|
|
toString() {
|
|
|
|
return "$runtimeType {"
|
|
|
|
"super: ${super.toString()}, "
|
|
|
|
"exception: $exception, "
|
|
|
|
"}";
|
|
|
|
}
|
|
|
|
|
2021-08-16 21:05:00 +02:00
|
|
|
@override
|
|
|
|
get props => [
|
|
|
|
...super.props,
|
|
|
|
exception,
|
|
|
|
];
|
|
|
|
|
2021-04-10 06:28:12 +02:00
|
|
|
final dynamic exception;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A bloc that return all directories under a dir recursively
|
|
|
|
class LsDirBloc extends Bloc<LsDirBlocEvent, LsDirBlocState> {
|
2021-11-11 15:18:33 +01:00
|
|
|
LsDirBloc(this.fileRepo) : super(LsDirBlocInit());
|
2021-04-10 06:28:12 +02:00
|
|
|
|
|
|
|
@override
|
|
|
|
mapEventToState(LsDirBlocEvent event) async* {
|
|
|
|
_log.info("[mapEventToState] $event");
|
|
|
|
if (event is LsDirBlocQuery) {
|
|
|
|
yield* _onEventQuery(event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stream<LsDirBlocState> _onEventQuery(LsDirBlocQuery ev) async* {
|
|
|
|
try {
|
2021-06-05 19:50:00 +02:00
|
|
|
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);
|
2021-06-05 19:50:00 +02:00
|
|
|
yield LsDirBlocFailure(ev.account, ev.root, state.items, e);
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-05 19:50:00 +02:00
|
|
|
Future<List<LsDirBlocItem>> _query(LsDirBlocQuery ev) async {
|
|
|
|
final product = <LsDirBlocItem>[];
|
|
|
|
var files = _cache[ev.root.path];
|
|
|
|
if (files == null) {
|
2021-08-16 21:05:00 +02:00
|
|
|
files = (await Ls(fileRepo)(ev.account, ev.root))
|
2021-07-23 22:05:57 +02:00
|
|
|
.where((f) => f.isCollection ?? false)
|
2021-06-05 19:50:00 +02:00
|
|
|
.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;
|
2021-06-05 19:50:00 +02:00
|
|
|
if (ev.depth > 1) {
|
|
|
|
children = await _query(ev.copyWith(root: f, depth: ev.depth - 1));
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|
2021-06-05 19:50:00 +02:00
|
|
|
product.add(LsDirBlocItem(f, children));
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|
2021-06-05 19:50:00 +02:00
|
|
|
return product;
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|
|
|
|
|
2021-08-16 21:05:00 +02:00
|
|
|
final FileRepo fileRepo;
|
|
|
|
|
2021-06-05 19:50:00 +02:00
|
|
|
final _cache = <String, List<File>>{};
|
|
|
|
|
2021-04-10 06:28:12 +02:00
|
|
|
static final _log = Logger("bloc.ls_dir.LsDirBloc");
|
|
|
|
}
|