fix: mobile edit handling (#25315)

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
This commit is contained in:
Brandon Wees
2026-01-19 12:22:53 -06:00
committed by GitHub
parent b3f5b8ede8
commit 1b56bb84f9
64 changed files with 9350 additions and 168 deletions
@@ -112,14 +112,17 @@ ImageProvider getFullImageProvider(BaseAsset asset, {Size size = const Size(1080
provider = LocalFullImageProvider(id: id, size: size, assetType: asset.type);
} else {
final String assetId;
final String thumbhash;
if (asset is LocalAsset && asset.hasRemote) {
assetId = asset.remoteId!;
thumbhash = "";
} else if (asset is RemoteAsset) {
assetId = asset.id;
thumbhash = asset.thumbHash ?? "";
} else {
throw ArgumentError("Unsupported asset type: ${asset.runtimeType}");
}
provider = RemoteFullImageProvider(assetId: assetId);
provider = RemoteFullImageProvider(assetId: assetId, thumbhash: thumbhash);
}
return provider;
@@ -132,8 +135,9 @@ ImageProvider? getThumbnailImageProvider(BaseAsset asset, {Size size = kThumbnai
}
final assetId = asset is RemoteAsset ? asset.id : (asset as LocalAsset).remoteId;
return assetId != null ? RemoteThumbProvider(assetId: assetId) : null;
final thumbhash = asset is RemoteAsset ? asset.thumbHash ?? "" : "";
return assetId != null ? RemoteThumbProvider(assetId: assetId, thumbhash: thumbhash) : null;
}
bool _shouldUseLocalAsset(BaseAsset asset) =>
asset.hasLocal && (!asset.hasRemote || !AppSetting.get(Setting.preferRemoteImage));
asset.hasLocal && (!asset.hasRemote || !AppSetting.get(Setting.preferRemoteImage)) && !asset.isEdited;
@@ -16,8 +16,9 @@ class RemoteThumbProvider extends CancellableImageProvider<RemoteThumbProvider>
with CancellableImageProviderMixin<RemoteThumbProvider> {
static final cacheManager = RemoteThumbnailCacheManager();
final String assetId;
final String thumbhash;
RemoteThumbProvider({required this.assetId});
RemoteThumbProvider({required this.assetId, required this.thumbhash});
@override
Future<RemoteThumbProvider> obtainKey(ImageConfiguration configuration) {
@@ -38,7 +39,7 @@ class RemoteThumbProvider extends CancellableImageProvider<RemoteThumbProvider>
Stream<ImageInfo> _codec(RemoteThumbProvider key, ImageDecoderCallback decode) {
final request = this.request = RemoteImageRequest(
uri: getThumbnailUrlForRemoteId(key.assetId),
uri: getThumbnailUrlForRemoteId(key.assetId, thumbhash: key.thumbhash),
headers: ApiService.getRequestHeaders(),
cacheManager: cacheManager,
);
@@ -49,22 +50,23 @@ class RemoteThumbProvider extends CancellableImageProvider<RemoteThumbProvider>
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other is RemoteThumbProvider) {
return assetId == other.assetId;
return assetId == other.assetId && thumbhash == other.thumbhash;
}
return false;
}
@override
int get hashCode => assetId.hashCode;
int get hashCode => assetId.hashCode ^ thumbhash.hashCode;
}
class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImageProvider>
with CancellableImageProviderMixin<RemoteFullImageProvider> {
static final cacheManager = RemoteThumbnailCacheManager();
final String assetId;
final String thumbhash;
RemoteFullImageProvider({required this.assetId});
RemoteFullImageProvider({required this.assetId, required this.thumbhash});
@override
Future<RemoteFullImageProvider> obtainKey(ImageConfiguration configuration) {
@@ -75,7 +77,7 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
ImageStreamCompleter loadImage(RemoteFullImageProvider key, ImageDecoderCallback decode) {
return OneFramePlaceholderImageStreamCompleter(
_codec(key, decode),
initialImage: getInitialImage(RemoteThumbProvider(assetId: key.assetId)),
initialImage: getInitialImage(RemoteThumbProvider(assetId: key.assetId, thumbhash: key.thumbhash)),
informationCollector: () => <DiagnosticsNode>[
DiagnosticsProperty<ImageProvider>('Image provider', this),
DiagnosticsProperty<String>('Asset Id', key.assetId),
@@ -94,7 +96,7 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
final headers = ApiService.getRequestHeaders();
final request = this.request = RemoteImageRequest(
uri: getThumbnailUrlForRemoteId(key.assetId, type: AssetMediaSize.preview),
uri: getThumbnailUrlForRemoteId(key.assetId, type: AssetMediaSize.preview, thumbhash: key.thumbhash),
headers: headers,
cacheManager: cacheManager,
);
@@ -115,12 +117,12 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other is RemoteFullImageProvider) {
return assetId == other.assetId;
return assetId == other.assetId && thumbhash == other.thumbhash;
}
return false;
}
@override
int get hashCode => assetId.hashCode;
int get hashCode => assetId.hashCode ^ thumbhash.hashCode;
}
@@ -21,9 +21,14 @@ class Thumbnail extends StatefulWidget {
const Thumbnail({this.imageProvider, this.fit = BoxFit.cover, this.thumbhashProvider, super.key});
Thumbnail.remote({required String remoteId, this.fit = BoxFit.cover, Size size = kThumbnailResolution, super.key})
: imageProvider = RemoteThumbProvider(assetId: remoteId),
thumbhashProvider = null;
Thumbnail.remote({
required String remoteId,
required String thumbhash,
this.fit = BoxFit.cover,
Size size = kThumbnailResolution,
super.key,
}) : imageProvider = RemoteThumbProvider(assetId: remoteId, thumbhash: thumbhash),
thumbhashProvider = null;
Thumbnail.fromAsset({
required BaseAsset? asset,