mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-24 18:38:48 +01:00
Fix no albums shown if any one of them erred
This commit is contained in:
parent
60339968de
commit
a124c99f33
4 changed files with 72 additions and 65 deletions
|
@ -6,6 +6,7 @@ import 'package:nc_photos/entity/file.dart';
|
|||
import 'package:nc_photos/entity/file/data_source.dart';
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/use_case/list_album.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
abstract class ListAlbumBlocEvent {
|
||||
const ListAlbumBlocEvent();
|
||||
|
@ -124,30 +125,19 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
|
|||
|
||||
if (!hasContent) {
|
||||
// show something instantly on first load
|
||||
ListAlbumBlocState cacheState = ListAlbumBlocInit();
|
||||
await for (final s in _queryOffline(ev, () => cacheState)) {
|
||||
cacheState = s;
|
||||
}
|
||||
final cacheState = await _queryOffline(ev);
|
||||
yield ListAlbumBlocLoading(ev.account, cacheState.albums);
|
||||
hasContent = cacheState.albums.isNotEmpty;
|
||||
}
|
||||
|
||||
ListAlbumBlocState newState = ListAlbumBlocInit();
|
||||
if (!hasContent) {
|
||||
await for (final s in _queryOnline(ev, () => newState)) {
|
||||
newState = s;
|
||||
yield s;
|
||||
}
|
||||
final newState = await _queryOnline(ev);
|
||||
if (newState is ListAlbumBlocFailure) {
|
||||
yield ListAlbumBlocFailure(
|
||||
ev.account,
|
||||
newState.albums?.isNotEmpty == true ? newState.albums : state.albums,
|
||||
newState.exception);
|
||||
} else {
|
||||
await for (final s in _queryOnline(ev, () => newState)) {
|
||||
newState = s;
|
||||
}
|
||||
if (newState is ListAlbumBlocSuccess) {
|
||||
yield newState;
|
||||
} else if (newState is ListAlbumBlocFailure) {
|
||||
yield ListAlbumBlocFailure(
|
||||
ev.account, state.albums, newState.exception);
|
||||
}
|
||||
yield newState;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,29 +172,37 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
|
|||
add(_ListAlbumBlocExternalEvent());
|
||||
}
|
||||
|
||||
Stream<ListAlbumBlocState> _queryOffline(
|
||||
ListAlbumBlocQuery ev, ListAlbumBlocState Function() getState) =>
|
||||
Future<ListAlbumBlocState> _queryOffline(ListAlbumBlocQuery ev) =>
|
||||
_queryWithAlbumDataSource(
|
||||
ev, getState, FileAppDbDataSource(), AlbumAppDbDataSource());
|
||||
ev, FileAppDbDataSource(), AlbumAppDbDataSource());
|
||||
|
||||
Stream<ListAlbumBlocState> _queryOnline(
|
||||
ListAlbumBlocQuery ev, ListAlbumBlocState Function() getState) =>
|
||||
Future<ListAlbumBlocState> _queryOnline(ListAlbumBlocQuery ev) =>
|
||||
_queryWithAlbumDataSource(
|
||||
ev, getState, FileCachedDataSource(), AlbumCachedDataSource());
|
||||
ev, FileCachedDataSource(), AlbumCachedDataSource());
|
||||
|
||||
Stream<ListAlbumBlocState> _queryWithAlbumDataSource(
|
||||
ListAlbumBlocQuery ev,
|
||||
ListAlbumBlocState Function() getState,
|
||||
FileDataSource fileDataSource,
|
||||
AlbumDataSource albumDataSrc) async* {
|
||||
Future<ListAlbumBlocState> _queryWithAlbumDataSource(ListAlbumBlocQuery ev,
|
||||
FileDataSource fileDataSource, AlbumDataSource albumDataSrc) async {
|
||||
try {
|
||||
final results = await ListAlbum(
|
||||
FileRepo(fileDataSource), AlbumRepo(albumDataSrc))(ev.account);
|
||||
yield ListAlbumBlocSuccess(ev.account, results);
|
||||
final albums = <Album>[];
|
||||
final errors = <dynamic>[];
|
||||
await for (final result in ListAlbum(
|
||||
FileRepo(fileDataSource), AlbumRepo(albumDataSrc))(ev.account)) {
|
||||
if (result is Tuple2) {
|
||||
_log.severe("[_queryWithAlbumDataSource] Exception while ListAlbum",
|
||||
result.item1, result.item2);
|
||||
errors.add(result.item1);
|
||||
} else if (result is Album) {
|
||||
albums.add(result);
|
||||
}
|
||||
}
|
||||
if (errors.isEmpty) {
|
||||
return ListAlbumBlocSuccess(ev.account, albums);
|
||||
} else {
|
||||
return ListAlbumBlocFailure(ev.account, albums, errors.first);
|
||||
}
|
||||
} catch (e, stacktrace) {
|
||||
_log.severe(
|
||||
"[_queryWithAlbumDataSource] Exception while request", e, stacktrace);
|
||||
yield ListAlbumBlocFailure(ev.account, getState().albums, e);
|
||||
_log.severe("[_queryWithAlbumDataSource] Exception", e, stacktrace);
|
||||
return ListAlbumBlocFailure(ev.account, [], e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,9 @@ class ListImportableAlbumBloc
|
|||
try {
|
||||
final fileRepo = FileRepo(FileCachedDataSource());
|
||||
final albumRepo = AlbumRepo(AlbumCachedDataSource());
|
||||
final albums = await ListAlbum(fileRepo, albumRepo)(ev.account);
|
||||
final albums = (await ListAlbum(fileRepo, albumRepo)(ev.account)
|
||||
.where((event) => event is Album)
|
||||
.toList()).cast<Album>();
|
||||
final importedDirs = albums.map((a) {
|
||||
if (a.provider is! AlbumDirProvider) {
|
||||
return <File>[];
|
||||
|
|
|
@ -6,54 +6,59 @@ import 'package:nc_photos/exception.dart';
|
|||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||
import 'package:nc_photos/use_case/compat/v15.dart';
|
||||
import 'package:nc_photos/use_case/ls.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class ListAlbum {
|
||||
ListAlbum(this.fileRepo, this.albumRepo);
|
||||
|
||||
/// List all albums associated with [account]
|
||||
Future<List<Album>> call(Account account) async {
|
||||
final results = await _call(account);
|
||||
if (results.isEmpty) {
|
||||
///
|
||||
/// The returned stream would emit either Album data or a tuple of exception
|
||||
/// and stacktrace
|
||||
Stream<dynamic> call(Account account) async* {
|
||||
bool hasAlbum = false;
|
||||
await for (final result in _call(account)) {
|
||||
hasAlbum = true;
|
||||
yield result;
|
||||
}
|
||||
if (!hasAlbum) {
|
||||
if (await CompatV15.migrateAlbumFiles(account, fileRepo)) {
|
||||
// migrated
|
||||
return await _call(account);
|
||||
} else {
|
||||
// no need to migrate
|
||||
return [];
|
||||
// migrated, try again
|
||||
yield* _call(account);
|
||||
}
|
||||
} else {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Album>> _call(Account account) async {
|
||||
Stream<dynamic> _call(Account account) async* {
|
||||
List<File> ls;
|
||||
try {
|
||||
final ls = await Ls(fileRepo)(
|
||||
ls = await Ls(fileRepo)(
|
||||
account,
|
||||
File(
|
||||
path: remote_storage_util.getRemoteAlbumsDir(account),
|
||||
));
|
||||
final albumFiles =
|
||||
ls.where((element) => element.isCollection != true).toList();
|
||||
final albums = <Album>[];
|
||||
for (final f in albumFiles) {
|
||||
final album = await albumRepo.get(account, f);
|
||||
albums.add(album);
|
||||
}
|
||||
try {
|
||||
albumRepo.cleanUp(account, albumFiles);
|
||||
} catch (e, stacktrace) {
|
||||
// not important, log and ignore
|
||||
_log.shout("[_call] Failed while cleanUp", e, stacktrace);
|
||||
}
|
||||
return albums;
|
||||
} catch (e) {
|
||||
if (e is ApiException && e.response.statusCode == 404) {
|
||||
// no albums
|
||||
return [];
|
||||
return;
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
final albumFiles =
|
||||
ls.where((element) => element.isCollection != true).toList();
|
||||
for (final f in albumFiles) {
|
||||
try {
|
||||
yield await albumRepo.get(account, f);
|
||||
} catch (e, stacktrace) {
|
||||
yield Tuple2(e, stacktrace);
|
||||
}
|
||||
}
|
||||
try {
|
||||
albumRepo.cleanUp(account, albumFiles);
|
||||
} catch (e, stacktrace) {
|
||||
// not important, log and ignore
|
||||
_log.shout("[_call] Failed while cleanUp", e, stacktrace);
|
||||
}
|
||||
}
|
||||
|
||||
final FileRepo fileRepo;
|
||||
|
|
|
@ -24,7 +24,9 @@ class Remove {
|
|||
}
|
||||
|
||||
Future<void> _cleanUpAlbums(Account account, File file) async {
|
||||
final albums = await ListAlbum(fileRepo, albumRepo)(account);
|
||||
final albums = (await ListAlbum(fileRepo, albumRepo)(account)
|
||||
.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)) {
|
||||
|
|
Loading…
Reference in a new issue