mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
fix(mobile): improve image load cancellation handling (#27624)
fix(image): improve image load cancellation handling
This commit is contained in:
@@ -19,6 +19,7 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
static final _log = Logger('CancellableImageProviderMixin');
|
||||
|
||||
bool isCancelled = false;
|
||||
bool isFinished = false;
|
||||
ImageRequest? request;
|
||||
CancelableOperation<ImageInfo?>? cachedOperation;
|
||||
|
||||
@@ -53,13 +54,15 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
Stream<ImageInfo> loadRequest(ImageRequest request, ImageDecoderCallback decode, {bool evictOnError = true}) async* {
|
||||
if (isCancelled) {
|
||||
this.request = null;
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final image = await request.load(decode);
|
||||
if ((image == null && evictOnError) || isCancelled) {
|
||||
if (isCancelled) {
|
||||
return;
|
||||
}
|
||||
if (image == null && evictOnError) {
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
return;
|
||||
} else if (image == null) {
|
||||
@@ -67,6 +70,9 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
}
|
||||
yield image;
|
||||
} catch (e, stack) {
|
||||
if (isCancelled) {
|
||||
return;
|
||||
}
|
||||
if (evictOnError) {
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
rethrow;
|
||||
@@ -80,20 +86,24 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
Future<ui.Codec?> loadCodecRequest(ImageRequest request) async {
|
||||
if (isCancelled) {
|
||||
this.request = null;
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final codec = await request.loadCodec();
|
||||
if (codec == null || isCancelled) {
|
||||
if (isCancelled) {
|
||||
codec?.dispose();
|
||||
return null;
|
||||
}
|
||||
if (codec == null) {
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
return null;
|
||||
}
|
||||
return codec;
|
||||
} catch (e) {
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
if (!isCancelled) {
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
}
|
||||
rethrow;
|
||||
} finally {
|
||||
this.request = null;
|
||||
@@ -121,6 +131,8 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
@override
|
||||
void cancel() {
|
||||
isCancelled = true;
|
||||
final hasActiveWork = !isFinished;
|
||||
|
||||
final request = this.request;
|
||||
if (request != null) {
|
||||
this.request = null;
|
||||
@@ -132,6 +144,10 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
|
||||
cachedOperation = null;
|
||||
operation.cancel();
|
||||
}
|
||||
|
||||
if (hasActiveWork) {
|
||||
PaintingBinding.instance.imageCache.evict(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user