fix(mobile): revert cache fixes (#17786)

* Revert "fix(mobile): use immutable cache keys for local images (#17736)"

This reverts commit 010b144754680f39979a65668311b5a5ffee2416.

* Revert "perf(mobile): remove small thumbnail and cache generated thumbnails (#17682)"

This reverts commit b71039e83c2497f9829f1592573dbc2e85bb2f2c.
This commit is contained in:
Alex 2025-04-22 12:15:54 -05:00 committed by GitHub
parent af36eaa61b
commit 0986a71ce3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 36 deletions

View File

@ -106,12 +106,12 @@ class ImmichLocalImageProvider extends ImageProvider<ImmichLocalImageProvider> {
bool operator ==(Object other) { bool operator ==(Object other) {
if (identical(this, other)) return true; if (identical(this, other)) return true;
if (other is ImmichLocalImageProvider) { if (other is ImmichLocalImageProvider) {
return asset.id == other.asset.id; return asset == other.asset;
} }
return false; return false;
} }
@override @override
int get hashCode => asset.id.hashCode; int get hashCode => asset.hashCode;
} }

View File

@ -2,14 +2,11 @@ import 'dart:async';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:immich_mobile/providers/image/cache/thumbnail_image_cache_manager.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:photo_manager/photo_manager.dart' show ThumbnailSize; import 'package:photo_manager/photo_manager.dart' show ThumbnailSize;
import 'package:logging/logging.dart';
/// The local image provider for an asset /// The local image provider for an asset
/// Only viable /// Only viable
@ -18,14 +15,11 @@ class ImmichLocalThumbnailProvider
final Asset asset; final Asset asset;
final int height; final int height;
final int width; final int width;
final CacheManager? cacheManager;
final Logger log = Logger("ImmichLocalThumbnailProvider");
ImmichLocalThumbnailProvider({ ImmichLocalThumbnailProvider({
required this.asset, required this.asset,
this.height = 256, this.height = 256,
this.width = 256, this.width = 256,
this.cacheManager,
}) : assert(asset.local != null, 'Only usable when asset.local is set'); }) : assert(asset.local != null, 'Only usable when asset.local is set');
/// Converts an [ImageProvider]'s settings plus an [ImageConfiguration] to a key /// Converts an [ImageProvider]'s settings plus an [ImageConfiguration] to a key
@ -42,10 +36,11 @@ class ImmichLocalThumbnailProvider
ImmichLocalThumbnailProvider key, ImmichLocalThumbnailProvider key,
ImageDecoderCallback decode, ImageDecoderCallback decode,
) { ) {
final cache = cacheManager ?? ThumbnailImageCacheManager(); final chunkEvents = StreamController<ImageChunkEvent>();
return MultiImageStreamCompleter( return MultiImageStreamCompleter(
codec: _codec(key.asset, cache, decode), codec: _codec(key.asset, decode, chunkEvents),
scale: 1.0, scale: 1.0,
chunkEvents: chunkEvents.stream,
informationCollector: () sync* { informationCollector: () sync* {
yield ErrorDescription(asset.fileName); yield ErrorDescription(asset.fileName);
}, },
@ -55,48 +50,43 @@ class ImmichLocalThumbnailProvider
// Streams in each stage of the image as we ask for it // Streams in each stage of the image as we ask for it
Stream<ui.Codec> _codec( Stream<ui.Codec> _codec(
Asset key, Asset key,
CacheManager cache,
ImageDecoderCallback decode, ImageDecoderCallback decode,
StreamController<ImageChunkEvent> chunkEvents,
) async* { ) async* {
final cacheKey = '${key.id}_${width}x$height'; // Load a small thumbnail
final fileFromCache = await cache.getFileFromCache(cacheKey); final thumbBytes = await asset.local?.thumbnailDataWithSize(
if (fileFromCache != null) { const ThumbnailSize.square(32),
try { quality: 75,
final buffer = );
await ui.ImmutableBuffer.fromFilePath(fileFromCache.file.path); if (thumbBytes != null) {
final codec = await decode(buffer); final buffer = await ui.ImmutableBuffer.fromUint8List(thumbBytes);
yield codec; final codec = await decode(buffer);
return; yield codec;
} catch (error) { } else {
log.severe('Found thumbnail in cache, but loading it failed', error); debugPrint("Loading thumb for ${asset.fileName} failed");
}
} }
final thumbnailBytes = await asset.local?.thumbnailDataWithSize( final normalThumbBytes =
ThumbnailSize(width, height), await asset.local?.thumbnailDataWithSize(ThumbnailSize(width, height));
quality: 80, if (normalThumbBytes == null) {
);
if (thumbnailBytes == null) {
throw StateError( throw StateError(
"Loading thumb for local photo ${asset.fileName} failed", "Loading thumb for local photo ${asset.fileName} failed",
); );
} }
final buffer = await ui.ImmutableBuffer.fromUint8List(thumbnailBytes); final buffer = await ui.ImmutableBuffer.fromUint8List(normalThumbBytes);
final codec = await decode(buffer); final codec = await decode(buffer);
yield codec; yield codec;
await cache.putFile(cacheKey, thumbnailBytes);
chunkEvents.close();
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
if (other is! ImmichLocalThumbnailProvider) return false;
if (identical(this, other)) return true; if (identical(this, other)) return true;
if (other is ImmichLocalThumbnailProvider) { return asset == other.asset;
return asset.id == other.asset.id;
}
return false;
} }
@override @override
int get hashCode => asset.id.hashCode; int get hashCode => asset.hashCode;
} }