Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions mobile/lib/presentation/widgets/images/image_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,26 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
return null;
}

Stream<ImageInfo> loadRequest(ImageRequest request, ImageDecoderCallback decode, {bool evictOnError = true}) async* {
Stream<ImageInfo> loadRequest(ImageRequest request, ImageDecoderCallback decode, {required bool isFinal}) async* {
if (isCancelled) {
this.request = null;
return;
}

try {
final image = await request.load(decode);
if (isCancelled) {
return;
}
if (image == null && evictOnError) {
PaintingBinding.instance.imageCache.evict(this);
return;
} else if (image == null) {
if (isCancelled || image == null) {
image?.dispose();
return;
}
isFinished = isFinal;
yield image;
} catch (e, stack) {
if (isCancelled) {
return;
}
if (evictOnError) {
if (isFinal) {
isFinished = true;
PaintingBinding.instance.imageCache.evict(this);
rethrow;
}
Expand All @@ -83,28 +80,27 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
}
Comment thread
LeLunZ marked this conversation as resolved.
}

Future<ui.Codec?> loadCodecRequest(ImageRequest request) async {
Future<ui.Codec?> loadCodecRequest(ImageRequest request, {required bool isFinal}) async {
if (isCancelled) {
this.request = null;
return null;
}

try {
final codec = await request.loadCodec();
if (isCancelled) {
if (isCancelled || codec == null) {
codec?.dispose();
return null;
}
if (codec == null) {
PaintingBinding.instance.imageCache.evict(this);
return null;
}
isFinished = isFinal;
return codec;
} catch (e) {
if (!isCancelled) {
if (isFinal) {
isFinished = true;
PaintingBinding.instance.imageCache.evict(this);
rethrow;
}
rethrow;
return null;
} finally {
this.request = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class LocalThumbProvider extends CancellableImageProvider<LocalThumbProvider>

Stream<ImageInfo> _codec(LocalThumbProvider key, ImageDecoderCallback decode) {
final request = this.request = LocalImageRequest(localId: key.id, size: key.size, assetType: key.assetType);
return loadRequest(request, decode);
return loadRequest(request, decode, isFinal: true);
}

@override
Expand Down Expand Up @@ -103,16 +103,16 @@ class LocalFullImageProvider extends CancellableImageProvider<LocalFullImageProv
return;
}

final loadOriginal = Store.get(StoreKey.loadOriginal, false);
final devicePixelRatio = PlatformDispatcher.instance.views.first.devicePixelRatio;
var request = this.request = LocalImageRequest(
localId: key.id,
size: Size(size.width * devicePixelRatio, size.height * devicePixelRatio),
assetType: key.assetType,
);
yield* loadRequest(request, decode);
yield* loadRequest(request, decode, isFinal: !loadOriginal);

if (!Store.get(StoreKey.loadOriginal, false)) {
isFinished = true;
if (!loadOriginal) {
return;
}

Expand All @@ -122,8 +122,7 @@ class LocalFullImageProvider extends CancellableImageProvider<LocalFullImageProv

request = this.request = LocalImageRequest(localId: key.id, assetType: key.assetType, size: Size.zero);

yield* loadRequest(request, decode);
isFinished = true;
yield* loadRequest(request, decode, isFinal: true);
}

Stream<Object> _animatedCodec(LocalFullImageProvider key, ImageDecoderCallback decode) async* {
Expand All @@ -139,21 +138,20 @@ class LocalFullImageProvider extends CancellableImageProvider<LocalFullImageProv
size: Size(size.width * devicePixelRatio, size.height * devicePixelRatio),
assetType: key.assetType,
);
yield* loadRequest(previewRequest, decode);
yield* loadRequest(previewRequest, decode, isFinal: false);

if (isCancelled) {
return;
}

// always try original for animated, since previews don't support animation
final originalRequest = request = LocalImageRequest(localId: key.id, size: Size.zero, assetType: key.assetType);
final codec = await loadCodecRequest(originalRequest);
final codec = await loadCodecRequest(originalRequest, isFinal: true);
if (codec == null) {
if (isCancelled) return;
throw StateError('Failed to load animated codec for local asset ${key.id}');
}
yield codec;
isFinished = true;
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class RemoteImageProvider extends CancellableImageProvider<RemoteImageProvider>

Stream<ImageInfo> _codec(RemoteImageProvider key, ImageDecoderCallback decode) {
final request = this.request = RemoteImageRequest(uri: key.url);
return loadRequest(request, decode);
return loadRequest(request, decode, isFinal: true);
}

@override
Expand Down Expand Up @@ -112,10 +112,9 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
uri: getThumbnailUrlForRemoteId(key.assetId, type: AssetMediaSize.preview, thumbhash: key.thumbhash),
);
final loadOriginal = assetType == AssetType.image && AppSetting.get(Setting.loadOriginal);
yield* loadRequest(previewRequest, decode, evictOnError: !loadOriginal);
yield* loadRequest(previewRequest, decode, isFinal: !loadOriginal);

if (!loadOriginal) {
isFinished = true;
return;
}

Expand All @@ -124,8 +123,7 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
}

final originalRequest = request = RemoteImageRequest(uri: getOriginalUrlForRemoteId(key.assetId));
yield* loadRequest(originalRequest, decode);
isFinished = true;
yield* loadRequest(originalRequest, decode, isFinal: true);
}

Stream<Object> _animatedCodec(RemoteFullImageProvider key, ImageDecoderCallback decode) async* {
Expand All @@ -138,23 +136,22 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
final previewRequest = request = RemoteImageRequest(
uri: getThumbnailUrlForRemoteId(key.assetId, type: AssetMediaSize.preview, thumbhash: key.thumbhash),
);
yield* loadRequest(previewRequest, decode, evictOnError: false);
yield* loadRequest(previewRequest, decode, isFinal: false);

if (isCancelled) {
return;
}

// always try original for animated, since previews don't support animation
final originalRequest = request = RemoteImageRequest(uri: getOriginalUrlForRemoteId(key.assetId));
final codec = await loadCodecRequest(originalRequest);
final codec = await loadCodecRequest(originalRequest, isFinal: true);
if (codec == null) {
if (isCancelled) {
return;
}
throw StateError('Failed to load animated codec for asset ${key.assetId}');
}
yield codec;
isFinished = true;
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ThumbHashProvider extends CancellableImageProvider<ThumbHashProvider>

Stream<ImageInfo> _loadCodec(ThumbHashProvider key, ImageDecoderCallback decode) {
final request = this.request = ThumbhashImageRequest(thumbhash: key.thumbHash);
return loadRequest(request, decode);
return loadRequest(request, decode, isFinal: true);
}

@override
Expand Down
Loading