relatica/lib/services/gallery_service.dart
2023-02-24 17:53:48 -05:00

105 lines
3 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:result_monad/result_monad.dart';
import '../friendica_client/friendica_client.dart';
import '../friendica_client/paging_data.dart';
import '../globals.dart';
import '../models/exec_error.dart';
import '../models/gallery_data.dart';
import '../models/image_entry.dart';
import 'auth_service.dart';
class GalleryService extends ChangeNotifier {
static const IMAGES_PER_PAGE = 50;
final _galleries = <String, GalleryData>{};
final _galleryPages = <String, List<PagingData>>{};
final _images = <String, Set<ImageEntry>>{};
var _loaded = false;
bool get loaded => _loaded;
List<GalleryData> getGalleries() {
if (_galleries.isEmpty) {
updateGalleries();
}
return _galleries.values.toList(growable: false);
}
Result<GalleryData, ExecError> getGallery(String galleryName) {
final gallery = _galleries[galleryName];
if (gallery == null) {
return buildErrorResult(
type: ErrorType.notFound,
message: 'Gallery $galleryName not found',
);
}
return Result.ok(gallery);
}
FutureResult<List<GalleryData>, ExecError> updateGalleries() async {
final result = await GalleryClient(getIt<AuthService>().currentCredentials)
.getGalleryData();
if (result.isFailure) {
return result.errorCast();
}
for (final gallery in result.value) {
_galleries[gallery.name] = gallery;
}
_loaded = true;
notifyListeners();
return Result.ok(_galleries.values.toList(growable: false));
}
Result<List<ImageEntry>, ExecError> getGalleryImageList(String galleryName) {
if (!_galleries.containsKey(galleryName)) {
return Result.error(
ExecError(
type: ErrorType.localError,
message: 'Unknown Gallery: $galleryName',
),
);
}
if (!_images.containsKey(galleryName)) {
updateGalleryImageList(galleryName: galleryName, withNextPage: true);
return Result.ok([]);
} else {
return Result.ok(_images[galleryName]!.toList(growable: false));
}
}
//TODO Paging
FutureResult<List<ImageEntry>, ExecError> updateGalleryImageList(
{required String galleryName,
required bool withNextPage,
bool nextPageOnly = true}) async {
final pages = _galleryPages.putIfAbsent(galleryName, () => []);
if (pages.isEmpty) {
pages.add(PagingData(offset: 0, limit: IMAGES_PER_PAGE));
} else if (withNextPage) {
final offset = pages.last.offset! + 1;
pages.add(PagingData(offset: offset, limit: IMAGES_PER_PAGE));
}
final imageSet = _images.putIfAbsent(galleryName, () => {});
final pagesToUse = nextPageOnly ? [pages.last] : pages;
for (final page in pagesToUse) {
final result =
await GalleryClient(getIt<AuthService>().currentCredentials)
.getGalleryImages(galleryName, page);
if (result.isFailure) {
return result.errorCast();
}
imageSet.addAll(result.value);
}
notifyListeners();
return Result.ok(imageSet.toList(growable: false));
}
}