Ver Fonte

fix(mobile): images rendered twice due to rebuild (#4060)

* fix(mobile): images rendered twice due to rebuild

* fix bottom sheet triggered multiple times
Fynn Petersen-Frey há 1 ano atrás
pai
commit
bd226e9e2c

+ 18 - 15
mobile/lib/modules/asset_viewer/ui/exif_bottom_sheet.dart

@@ -7,6 +7,8 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/modules/asset_viewer/ui/description_input.dart';
 import 'package:immich_mobile/modules/map/ui/map_thumbnail.dart';
 import 'package:immich_mobile/shared/models/asset.dart';
+import 'package:immich_mobile/shared/models/exif_info.dart';
+import 'package:immich_mobile/shared/providers/asset.provider.dart';
 import 'package:immich_mobile/shared/ui/drag_sheet.dart';
 import 'package:latlong2/latlong.dart';
 import 'package:immich_mobile/utils/bytes_units.dart';
@@ -17,11 +19,12 @@ class ExifBottomSheet extends HookConsumerWidget {
 
   const ExifBottomSheet({Key? key, required this.asset}) : super(key: key);
 
-  bool get hasCoordinates =>
-      asset.exifInfo?.latitude != null &&
-      asset.exifInfo?.longitude != null &&
-      asset.exifInfo!.latitude! != 0 &&
-      asset.exifInfo!.longitude! != 0;
+  bool hasCoordinates(ExifInfo? exifInfo) =>
+      exifInfo != null &&
+      exifInfo.latitude != null &&
+      exifInfo.longitude != null &&
+      exifInfo.latitude != 0 &&
+      exifInfo.longitude != 0;
 
   String get formattedDateTime {
     final fileCreatedAt = asset.fileCreatedAt.toLocal();
@@ -31,13 +34,13 @@ class ExifBottomSheet extends HookConsumerWidget {
     return '$date • $time';
   }
 
-  Future<Uri?> _createCoordinatesUri() async {
-    if (!hasCoordinates) {
+  Future<Uri?> _createCoordinatesUri(ExifInfo? exifInfo) async {
+    if (!hasCoordinates(exifInfo)) {
       return null;
     }
 
-    double latitude = asset.exifInfo!.latitude!;
-    double longitude = asset.exifInfo!.longitude!;
+    final double latitude = exifInfo!.latitude!;
+    final double longitude = exifInfo.longitude!;
 
     const zoomLevel = 16;
 
@@ -75,7 +78,8 @@ class ExifBottomSheet extends HookConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final exifInfo = asset.exifInfo;
+    final assetWithExif = ref.watch(assetDetailProvider(asset));
+    final exifInfo = (assetWithExif.value ?? asset).exifInfo;
     var isDarkTheme = Theme.of(context).brightness == Brightness.dark;
     var textColor = isDarkTheme ? Colors.white : Colors.black;
 
@@ -104,7 +108,7 @@ class ExifBottomSheet extends HookConsumerWidget {
                 ),
               ],
               onTap: (tapPosition, latLong) async {
-                Uri? uri = await _createCoordinatesUri();
+                Uri? uri = await _createCoordinatesUri(exifInfo);
 
                 if (uri == null) {
                   return;
@@ -146,7 +150,7 @@ class ExifBottomSheet extends HookConsumerWidget {
 
     buildLocation() {
       // Guard no lat/lng
-      if (!hasCoordinates) {
+      if (!hasCoordinates(exifInfo)) {
         return Container();
       }
 
@@ -210,7 +214,6 @@ class ExifBottomSheet extends HookConsumerWidget {
         ),
       );
     }
-    
 
     buildImageProperties() {
       // Helper to create the ListTile and avoid repeating code
@@ -334,7 +337,7 @@ class ExifBottomSheet extends HookConsumerWidget {
                           crossAxisAlignment: CrossAxisAlignment.start,
                           children: [
                             Flexible(
-                              flex: hasCoordinates ? 5 : 0,
+                              flex: hasCoordinates(exifInfo) ? 5 : 0,
                               child: Padding(
                                 padding: const EdgeInsets.only(right: 8.0),
                                 child: buildLocation(),
@@ -364,7 +367,7 @@ class ExifBottomSheet extends HookConsumerWidget {
                     if (asset.isRemote) DescriptionInput(asset: asset),
                     const SizedBox(height: 8.0),
                     buildLocation(),
-                    SizedBox(height: hasCoordinates ? 16.0 : 0.0),
+                    SizedBox(height: hasCoordinates(exifInfo) ? 16.0 : 0.0),
                     buildDetail(),
                     const SizedBox(height: 50),
                   ],

+ 2 - 3
mobile/lib/modules/asset_viewer/views/gallery_viewer.dart

@@ -64,9 +64,8 @@ class GalleryViewerPage extends HookConsumerWidget {
     final authToken = 'Bearer ${Store.get(StoreKey.accessToken)}';
     final currentIndex = useState(initialIndex);
     final currentAsset = loadAsset(currentIndex.value);
-    final watchedAsset = ref.watch(assetDetailProvider(currentAsset));
 
-    Asset asset() => watchedAsset.value ?? currentAsset;
+    Asset asset() => currentAsset;
 
     useEffect(
       () {
@@ -194,7 +193,7 @@ class GalleryViewerPage extends HookConsumerWidget {
             padding: EdgeInsets.only(
               bottom: MediaQuery.of(context).viewInsets.bottom,
             ),
-            child: ExifBottomSheet(asset: asset()),
+            child: ExifBottomSheet(asset: currentAsset),
           );
         },
       );

+ 5 - 6
mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart

@@ -1,13 +1,12 @@
 import 'package:auto_route/auto_route.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:immich_mobile/routing/router.dart';
 import 'package:immich_mobile/shared/models/asset.dart';
 import 'package:immich_mobile/shared/ui/immich_image.dart';
 import 'package:immich_mobile/utils/storage_indicator.dart';
 
-class ThumbnailImage extends HookConsumerWidget {
+class ThumbnailImage extends StatelessWidget {
   final Asset asset;
   final int index;
   final Asset Function(int index) loadAsset;
@@ -36,7 +35,7 @@ class ThumbnailImage extends HookConsumerWidget {
   }) : super(key: key);
 
   @override
-  Widget build(BuildContext context, WidgetRef ref) {
+  Widget build(BuildContext context) {
     final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
     final assetContainerColor =
         isDarkTheme ? Colors.blueGrey : Theme.of(context).primaryColorLight;
@@ -61,8 +60,8 @@ class ThumbnailImage extends HookConsumerWidget {
       }
     }
 
-    Widget buildImage(Asset asset) {
-      var image = SizedBox(
+    Widget buildImage() {
+      final image = SizedBox(
         width: 300,
         height: 300,
         child: Hero(
@@ -133,7 +132,7 @@ class ThumbnailImage extends HookConsumerWidget {
                     )
                   : const Border(),
             ),
-            child: buildImage(asset),
+            child: buildImage(),
           ),
           if (multiselectEnabled)
             Padding(