nc-photos/lib/use_case/remove_from_album.dart
Ming Ming 6e9a34342a Revamp how share is managed for album
Shares are now stored in the album json, such that users other than the album owner are aware of the shares
2021-11-25 21:02:41 +08:00

113 lines
3.9 KiB
Dart

import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/cover_provider.dart';
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/entity/share.dart';
import 'package:nc_photos/iterable_extension.dart';
import 'package:nc_photos/pref.dart';
import 'package:nc_photos/string_extension.dart';
import 'package:nc_photos/use_case/preprocess_album.dart';
import 'package:nc_photos/use_case/unshare_file_from_album.dart';
import 'package:nc_photos/use_case/update_album.dart';
import 'package:nc_photos/use_case/update_album_with_actual_items.dart';
class RemoveFromAlbum {
const RemoveFromAlbum(
this.albumRepo, this.shareRepo, this.fileRepo, this.appDb, this.pref);
/// Remove a list of AlbumItems from [album]
///
/// The items are compared with [identical], so it must come from [album] for
/// it to work
Future<Album> call(
Account account, Album album, List<AlbumItem> items) async {
_log.info("[call] Remove ${items.length} items from album '${album.name}'");
assert(album.provider is AlbumStaticProvider);
final provider = album.provider as AlbumStaticProvider;
final newItems = provider.items
.where((element) => !items.containsIdentical(element))
.toList();
var newAlbum = album.copyWith(
provider: AlbumStaticProvider.of(album).copyWith(
items: newItems,
),
);
newAlbum = await _fixAlbumPostRemove(account, newAlbum, items);
await UpdateAlbum(albumRepo)(account, newAlbum);
if (pref.isLabEnableSharedAlbumOr(false)) {
final removeFiles =
items.whereType<AlbumFileItem>().map((e) => e.file).toList();
if (removeFiles.isNotEmpty) {
await _unshareFiles(account, newAlbum, removeFiles);
}
}
return newAlbum;
}
/// Update the album accordingly if any of the removed items is interesting
/// (e.g., cover, latest item, etc)
Future<Album> _fixAlbumPostRemove(
Account account, Album newAlbum, List<AlbumItem> items) async {
bool isNeedUpdate = false;
for (final fileItem in items.whereType<AlbumFileItem>()) {
if (newAlbum.coverProvider
.getCover(newAlbum)
?.compareServerIdentity(fileItem.file) ==
true) {
// revert to auto cover so [UpdateAutoAlbumCover] can do its work
newAlbum = newAlbum.copyWith(
coverProvider: AlbumAutoCoverProvider(),
);
isNeedUpdate = true;
break;
}
if (fileItem.file.bestDateTime == newAlbum.provider.latestItemTime) {
isNeedUpdate = true;
break;
}
}
if (!isNeedUpdate) {
return newAlbum;
}
_log.info(
"[_fixAlbumPostRemove] Resync as interesting item is being removed");
// need to update the album properties
final newItemsSynced = await PreProcessAlbum(appDb)(account, newAlbum);
newAlbum = await UpdateAlbumWithActualItems(null)(
account,
newAlbum,
newItemsSynced,
);
return newAlbum;
}
Future<void> _unshareFiles(
Account account, Album album, List<File> files) async {
if (album.shares?.isNotEmpty != true) {
return;
}
final albumShares = (album.shares!.map((e) => e.userId).toList()
..add(album.albumFile!.ownerId ?? account.username))
.where((element) => !element.equalsIgnoreCase(account.username))
.toList();
if (albumShares.isNotEmpty) {
await UnshareFileFromAlbum(shareRepo, fileRepo, albumRepo)(
account, album, files, albumShares);
}
}
final AlbumRepo albumRepo;
final ShareRepo shareRepo;
final FileRepo fileRepo;
final AppDb appDb;
final Pref pref;
static final _log = Logger("use_case.remove_from_album.RemoveFromAlbum");
}