mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-23 01:06:21 +01:00
Throttle album clean ups when removing file
This commit is contained in:
parent
36e5a1c17b
commit
c3376b10da
2 changed files with 73 additions and 11 deletions
|
@ -33,4 +33,12 @@ extension IterableExtension<T> on Iterable<T> {
|
|||
/// Same as [contains] but uses [identical] to compare the objects
|
||||
bool containsIdentical(T element) =>
|
||||
containsIf(element, (a, b) => identical(a, b));
|
||||
|
||||
Iterable<Tuple2<U, List<T>>> groupBy<U>({required U Function(T e) key}) {
|
||||
final map = fold<Map<U, List<T>>>(
|
||||
{},
|
||||
(previousValue, element) =>
|
||||
previousValue..putIfAbsent(key(element), () => []).add(element));
|
||||
return map.entries.map((e) => Tuple2(e.key, e.value));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import 'package:nc_photos/entity/album/item.dart';
|
|||
import 'package:nc_photos/entity/album/provider.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/iterable_extension.dart';
|
||||
import 'package:nc_photos/throttler.dart';
|
||||
import 'package:nc_photos/use_case/list_album.dart';
|
||||
import 'package:nc_photos/use_case/update_album.dart';
|
||||
|
||||
|
@ -18,26 +20,77 @@ class Remove {
|
|||
await fileRepo.remove(account, file);
|
||||
if (albumRepo != null) {
|
||||
_log.info("[call] Skip albums cleanup as albumRepo == null");
|
||||
await _cleanUpAlbums(account, file);
|
||||
_CleanUpAlbums()(_CleanUpAlbumsData(fileRepo, albumRepo!, account, file));
|
||||
}
|
||||
KiwiContainer().resolve<EventBus>().fire(FileRemovedEvent(account, file));
|
||||
}
|
||||
|
||||
Future<void> _cleanUpAlbums(Account account, File file) async {
|
||||
final albumRepo = this.albumRepo!;
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo? albumRepo;
|
||||
|
||||
static final _log = Logger("use_case.remove.Remove");
|
||||
}
|
||||
|
||||
class _CleanUpAlbumsData {
|
||||
_CleanUpAlbumsData(this.fileRepo, this.albumRepo, this.account, this.file);
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo albumRepo;
|
||||
final Account account;
|
||||
final File file;
|
||||
}
|
||||
|
||||
class _CleanUpAlbums {
|
||||
factory _CleanUpAlbums() {
|
||||
if (_inst == null) {
|
||||
_inst = _CleanUpAlbums._();
|
||||
}
|
||||
return _inst!;
|
||||
}
|
||||
|
||||
_CleanUpAlbums._() {
|
||||
_throttler = Throttler<_CleanUpAlbumsData>(
|
||||
onTriggered: (data) {
|
||||
_onTriggered(data);
|
||||
},
|
||||
logTag: "remove._CleanUpAlbums",
|
||||
);
|
||||
}
|
||||
|
||||
void call(_CleanUpAlbumsData data) {
|
||||
_throttler.trigger(
|
||||
maxResponceTime: const Duration(seconds: 3),
|
||||
maxPendingCount: 10,
|
||||
data: data,
|
||||
);
|
||||
}
|
||||
|
||||
void _onTriggered(List<_CleanUpAlbumsData> data) async {
|
||||
for (final pair in data.groupBy(key: (e) => e.account)) {
|
||||
final list = pair.item2;
|
||||
await _cleanUp(list.first.fileRepo, list.first.albumRepo,
|
||||
list.first.account, list.map((e) => e.file).toList());
|
||||
}
|
||||
}
|
||||
|
||||
/// Clean up for a single account
|
||||
Future<void> _cleanUp(FileRepo fileRepo, AlbumRepo albumRepo, Account account,
|
||||
List<File> removes) async {
|
||||
final albums = (await ListAlbum(fileRepo, albumRepo)(account)
|
||||
.where((event) => event is Album)
|
||||
.toList()).cast<Album>();
|
||||
.where((event) => event is Album)
|
||||
.toList())
|
||||
.cast<Album>();
|
||||
// clean up only make sense for static albums
|
||||
for (final a
|
||||
in albums.where((element) => element.provider is AlbumStaticProvider)) {
|
||||
try {
|
||||
final provider = AlbumStaticProvider.of(a);
|
||||
if (provider.items.any((element) =>
|
||||
element is AlbumFileItem && element.file.path == file.path)) {
|
||||
if (provider.items.whereType<AlbumFileItem>().any((element) =>
|
||||
removes.containsIf(element.file, (a, b) => a.path == b.path))) {
|
||||
final newItems = provider.items.where((element) {
|
||||
if (element is AlbumFileItem) {
|
||||
return element.file.path != file.path;
|
||||
return !removes.containsIf(
|
||||
element.file, (a, b) => a.path == b.path);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -58,8 +111,9 @@ class Remove {
|
|||
}
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo? albumRepo;
|
||||
late final Throttler<_CleanUpAlbumsData> _throttler;
|
||||
|
||||
static final _log = Logger("use_case.remove.Remove");
|
||||
static final _log = Logger("use_case.remove");
|
||||
|
||||
static _CleanUpAlbums? _inst;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue