mirror of
https://github.com/immich-app/immich.git
synced 2025-08-11 09:16:31 -04:00
98 lines
3.0 KiB
Dart
98 lines
3.0 KiB
Dart
import 'package:flutter/widgets.dart';
|
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|
import 'package:immich_mobile/domain/models/setting.model.dart';
|
|
import 'package:immich_mobile/domain/services/setting.service.dart';
|
|
import 'package:immich_mobile/presentation/widgets/images/local_image_provider.dart';
|
|
import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart';
|
|
import 'package:immich_mobile/presentation/widgets/timeline/constants.dart';
|
|
import 'package:immich_mobile/infrastructure/repositories/asset_media.repository.dart';
|
|
|
|
abstract class CancellableImageProvider {
|
|
void cancel();
|
|
}
|
|
|
|
mixin class CancellableImageProviderMixin implements CancellableImageProvider {
|
|
ImageRequest? request;
|
|
|
|
@override
|
|
void cancel() {
|
|
final request = this.request;
|
|
if (request == null) {
|
|
return;
|
|
}
|
|
this.request = null;
|
|
return request.cancel();
|
|
}
|
|
}
|
|
|
|
ImageProvider getFullImageProvider(BaseAsset asset, {Size size = const Size(1080, 1920)}) {
|
|
// Create new provider and cache it
|
|
final ImageProvider provider;
|
|
if (_shouldUseLocalAsset(asset)) {
|
|
final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).localId!;
|
|
provider = LocalFullImageProvider(id: id, size: size);
|
|
} else {
|
|
final String assetId;
|
|
if (asset is LocalAsset && asset.hasRemote) {
|
|
assetId = asset.remoteId!;
|
|
} else if (asset is RemoteAsset) {
|
|
assetId = asset.id;
|
|
} else {
|
|
throw ArgumentError("Unsupported asset type: ${asset.runtimeType}");
|
|
}
|
|
provider = RemoteFullImageProvider(assetId: assetId);
|
|
}
|
|
|
|
return provider;
|
|
}
|
|
|
|
ImageProvider getThumbnailImageProvider({BaseAsset? asset, String? remoteId, Size size = kThumbnailResolution}) {
|
|
assert(asset != null || remoteId != null, 'Either asset or remoteId must be provided');
|
|
|
|
if (remoteId != null) {
|
|
return RemoteThumbProvider(assetId: remoteId);
|
|
}
|
|
|
|
if (_shouldUseLocalAsset(asset!)) {
|
|
final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).localId!;
|
|
return LocalThumbProvider(id: id, size: size);
|
|
}
|
|
|
|
final String assetId;
|
|
if (asset is LocalAsset && asset.hasRemote) {
|
|
assetId = asset.remoteId!;
|
|
} else if (asset is RemoteAsset) {
|
|
assetId = asset.id;
|
|
} else {
|
|
throw ArgumentError("Unsupported asset type: ${asset.runtimeType}");
|
|
}
|
|
|
|
return RemoteThumbProvider(assetId: assetId);
|
|
}
|
|
|
|
bool _shouldUseLocalAsset(BaseAsset asset) =>
|
|
asset.hasLocal && (!asset.hasRemote || !AppSetting.get(Setting.preferRemoteImage));
|
|
|
|
ImageInfo? getCachedImage(ImageProvider key) {
|
|
ImageInfo? thumbnail;
|
|
final ImageStreamCompleter? stream = PaintingBinding.instance.imageCache.putIfAbsent(
|
|
key,
|
|
() => throw Exception(), // don't bother loading if it isn't cached
|
|
onError: (_, __) {},
|
|
);
|
|
|
|
if (stream != null) {
|
|
void listener(ImageInfo info, bool synchronousCall) {
|
|
thumbnail = info;
|
|
}
|
|
|
|
try {
|
|
stream.addListener(ImageStreamListener(listener));
|
|
} finally {
|
|
stream.removeListener(ImageStreamListener(listener));
|
|
}
|
|
}
|
|
|
|
return thumbnail;
|
|
}
|