mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-23 01:06:21 +01:00
182 lines
5.5 KiB
Dart
182 lines
5.5 KiB
Dart
import 'package:bloc/bloc.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:kiwi/kiwi.dart';
|
|
import 'package:logging/logging.dart';
|
|
import 'package:nc_photos/account.dart';
|
|
import 'package:nc_photos/bloc/bloc_util.dart' as bloc_util;
|
|
import 'package:nc_photos/di_container.dart';
|
|
import 'package:nc_photos/entity/file.dart';
|
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
|
import 'package:nc_photos/event/event.dart';
|
|
import 'package:nc_photos/throttler.dart';
|
|
import 'package:nc_photos/use_case/ls_trashbin.dart';
|
|
import 'package:to_string/to_string.dart';
|
|
|
|
part 'ls_trashbin.g.dart';
|
|
|
|
abstract class LsTrashbinBlocEvent {
|
|
const LsTrashbinBlocEvent();
|
|
}
|
|
|
|
@toString
|
|
class LsTrashbinBlocQuery extends LsTrashbinBlocEvent {
|
|
const LsTrashbinBlocQuery(this.account);
|
|
|
|
@override
|
|
String toString() => _$toString();
|
|
|
|
final Account account;
|
|
}
|
|
|
|
/// An external event has happened and may affect the state of this bloc
|
|
@toString
|
|
class _LsTrashbinBlocExternalEvent extends LsTrashbinBlocEvent {
|
|
const _LsTrashbinBlocExternalEvent();
|
|
|
|
@override
|
|
String toString() => _$toString();
|
|
}
|
|
|
|
@toString
|
|
abstract class LsTrashbinBlocState {
|
|
const LsTrashbinBlocState(this.account, this.items);
|
|
|
|
@override
|
|
String toString() => _$toString();
|
|
|
|
final Account? account;
|
|
final List<File> items;
|
|
}
|
|
|
|
class LsTrashbinBlocInit extends LsTrashbinBlocState {
|
|
LsTrashbinBlocInit() : super(null, const []);
|
|
}
|
|
|
|
class LsTrashbinBlocLoading extends LsTrashbinBlocState {
|
|
const LsTrashbinBlocLoading(Account? account, List<File> items)
|
|
: super(account, items);
|
|
}
|
|
|
|
class LsTrashbinBlocSuccess extends LsTrashbinBlocState {
|
|
const LsTrashbinBlocSuccess(Account? account, List<File> items)
|
|
: super(account, items);
|
|
}
|
|
|
|
@toString
|
|
class LsTrashbinBlocFailure extends LsTrashbinBlocState {
|
|
const LsTrashbinBlocFailure(
|
|
Account? account, List<File> items, this.exception)
|
|
: super(account, items);
|
|
|
|
@override
|
|
String toString() => _$toString();
|
|
|
|
final dynamic exception;
|
|
}
|
|
|
|
/// The state of this bloc is inconsistent. This typically means that the data
|
|
/// may have been changed externally
|
|
class LsTrashbinBlocInconsistent extends LsTrashbinBlocState {
|
|
const LsTrashbinBlocInconsistent(Account? account, List<File> items)
|
|
: super(account, items);
|
|
}
|
|
|
|
class LsTrashbinBloc extends Bloc<LsTrashbinBlocEvent, LsTrashbinBlocState> {
|
|
LsTrashbinBloc() : super(LsTrashbinBlocInit()) {
|
|
_fileRemovedEventListener =
|
|
AppEventListener<FileRemovedEvent>(_onFileRemovedEvent);
|
|
_fileTrashbinRestoredEventListener =
|
|
AppEventListener<FileTrashbinRestoredEvent>(
|
|
_onFileTrashbinRestoredEvent);
|
|
_fileRemovedEventListener.begin();
|
|
_fileTrashbinRestoredEventListener.begin();
|
|
|
|
_refreshThrottler = Throttler(
|
|
onTriggered: (_) {
|
|
add(const _LsTrashbinBlocExternalEvent());
|
|
},
|
|
logTag: "LsTrashbinBloc.refresh",
|
|
);
|
|
|
|
on<LsTrashbinBlocEvent>(_onEvent);
|
|
}
|
|
|
|
static LsTrashbinBloc of(Account account) {
|
|
final name = bloc_util.getInstNameForAccount("LsTrashbinBloc", account);
|
|
try {
|
|
_log.fine("[of] Resolving bloc for '$name'");
|
|
return KiwiContainer().resolve<LsTrashbinBloc>(name);
|
|
} catch (_) {
|
|
// no created instance for this account, make a new one
|
|
_log.info("[of] New bloc instance for account: $account");
|
|
final bloc = LsTrashbinBloc();
|
|
KiwiContainer().registerInstance<LsTrashbinBloc>(bloc, name: name);
|
|
return bloc;
|
|
}
|
|
}
|
|
|
|
Future<void> _onEvent(
|
|
LsTrashbinBlocEvent event, Emitter<LsTrashbinBlocState> emit) async {
|
|
_log.info("[_onEvent] $event");
|
|
if (event is LsTrashbinBlocQuery) {
|
|
await _onEventQuery(event, emit);
|
|
} else if (event is _LsTrashbinBlocExternalEvent) {
|
|
await _onExternalEvent(event, emit);
|
|
}
|
|
}
|
|
|
|
Future<void> _onEventQuery(
|
|
LsTrashbinBlocQuery ev, Emitter<LsTrashbinBlocState> emit) async {
|
|
try {
|
|
emit(LsTrashbinBlocLoading(ev.account, state.items));
|
|
emit(LsTrashbinBlocSuccess(ev.account, await _query(ev)));
|
|
} catch (e) {
|
|
_log.severe("[_onEventQuery] Exception while request", e);
|
|
emit(LsTrashbinBlocFailure(ev.account, state.items, e));
|
|
}
|
|
}
|
|
|
|
Future<void> _onExternalEvent(_LsTrashbinBlocExternalEvent ev,
|
|
Emitter<LsTrashbinBlocState> emit) async {
|
|
emit(LsTrashbinBlocInconsistent(state.account, state.items));
|
|
}
|
|
|
|
void _onFileRemovedEvent(FileRemovedEvent ev) {
|
|
if (state is LsTrashbinBlocInit) {
|
|
// no data in this bloc, ignore
|
|
return;
|
|
}
|
|
if (file_util.isTrash(ev.account, ev.file)) {
|
|
_refreshThrottler.trigger(
|
|
maxResponceTime: const Duration(seconds: 3),
|
|
maxPendingCount: 10,
|
|
);
|
|
}
|
|
}
|
|
|
|
void _onFileTrashbinRestoredEvent(FileTrashbinRestoredEvent ev) {
|
|
if (state is LsTrashbinBlocInit) {
|
|
// no data in this bloc, ignore
|
|
return;
|
|
}
|
|
_refreshThrottler.trigger(
|
|
maxResponceTime: const Duration(seconds: 3),
|
|
maxPendingCount: 10,
|
|
);
|
|
}
|
|
|
|
Future<List<File>> _query(LsTrashbinBlocQuery ev) async {
|
|
final c = KiwiContainer().resolve<DiContainer>();
|
|
// caching contents in trashbin doesn't sounds useful
|
|
final files = await LsTrashbin(c.fileRepoRemote)(ev.account);
|
|
return files.where((f) => file_util.isSupportedFormat(f)).toList();
|
|
}
|
|
|
|
late final AppEventListener<FileRemovedEvent> _fileRemovedEventListener;
|
|
late final AppEventListener<FileTrashbinRestoredEvent>
|
|
_fileTrashbinRestoredEventListener;
|
|
|
|
late Throttler _refreshThrottler;
|
|
|
|
static final _log = Logger("bloc.ls_trashbin.LsTrashbinBloc");
|
|
}
|