mirror of
https://github.com/immich-app/immich.git
synced 2024-12-25 10:43:13 +02:00
fix(mobile): images rendered twice due to rebuild (#4060)
* fix(mobile): images rendered twice due to rebuild * fix bottom sheet triggered multiple times
This commit is contained in:
parent
d023d5b6b4
commit
bd226e9e2c
@ -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/asset_viewer/ui/description_input.dart';
|
||||||
import 'package:immich_mobile/modules/map/ui/map_thumbnail.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/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:immich_mobile/shared/ui/drag_sheet.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:immich_mobile/utils/bytes_units.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);
|
const ExifBottomSheet({Key? key, required this.asset}) : super(key: key);
|
||||||
|
|
||||||
bool get hasCoordinates =>
|
bool hasCoordinates(ExifInfo? exifInfo) =>
|
||||||
asset.exifInfo?.latitude != null &&
|
exifInfo != null &&
|
||||||
asset.exifInfo?.longitude != null &&
|
exifInfo.latitude != null &&
|
||||||
asset.exifInfo!.latitude! != 0 &&
|
exifInfo.longitude != null &&
|
||||||
asset.exifInfo!.longitude! != 0;
|
exifInfo.latitude != 0 &&
|
||||||
|
exifInfo.longitude != 0;
|
||||||
|
|
||||||
String get formattedDateTime {
|
String get formattedDateTime {
|
||||||
final fileCreatedAt = asset.fileCreatedAt.toLocal();
|
final fileCreatedAt = asset.fileCreatedAt.toLocal();
|
||||||
@ -31,13 +34,13 @@ class ExifBottomSheet extends HookConsumerWidget {
|
|||||||
return '$date • $time';
|
return '$date • $time';
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uri?> _createCoordinatesUri() async {
|
Future<Uri?> _createCoordinatesUri(ExifInfo? exifInfo) async {
|
||||||
if (!hasCoordinates) {
|
if (!hasCoordinates(exifInfo)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
double latitude = asset.exifInfo!.latitude!;
|
final double latitude = exifInfo!.latitude!;
|
||||||
double longitude = asset.exifInfo!.longitude!;
|
final double longitude = exifInfo.longitude!;
|
||||||
|
|
||||||
const zoomLevel = 16;
|
const zoomLevel = 16;
|
||||||
|
|
||||||
@ -75,7 +78,8 @@ class ExifBottomSheet extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
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 isDarkTheme = Theme.of(context).brightness == Brightness.dark;
|
||||||
var textColor = isDarkTheme ? Colors.white : Colors.black;
|
var textColor = isDarkTheme ? Colors.white : Colors.black;
|
||||||
|
|
||||||
@ -104,7 +108,7 @@ class ExifBottomSheet extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
onTap: (tapPosition, latLong) async {
|
onTap: (tapPosition, latLong) async {
|
||||||
Uri? uri = await _createCoordinatesUri();
|
Uri? uri = await _createCoordinatesUri(exifInfo);
|
||||||
|
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
return;
|
return;
|
||||||
@ -146,7 +150,7 @@ class ExifBottomSheet extends HookConsumerWidget {
|
|||||||
|
|
||||||
buildLocation() {
|
buildLocation() {
|
||||||
// Guard no lat/lng
|
// Guard no lat/lng
|
||||||
if (!hasCoordinates) {
|
if (!hasCoordinates(exifInfo)) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +214,6 @@ class ExifBottomSheet extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
buildImageProperties() {
|
buildImageProperties() {
|
||||||
// Helper to create the ListTile and avoid repeating code
|
// Helper to create the ListTile and avoid repeating code
|
||||||
@ -334,7 +337,7 @@ class ExifBottomSheet extends HookConsumerWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: hasCoordinates ? 5 : 0,
|
flex: hasCoordinates(exifInfo) ? 5 : 0,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 8.0),
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
child: buildLocation(),
|
child: buildLocation(),
|
||||||
@ -364,7 +367,7 @@ class ExifBottomSheet extends HookConsumerWidget {
|
|||||||
if (asset.isRemote) DescriptionInput(asset: asset),
|
if (asset.isRemote) DescriptionInput(asset: asset),
|
||||||
const SizedBox(height: 8.0),
|
const SizedBox(height: 8.0),
|
||||||
buildLocation(),
|
buildLocation(),
|
||||||
SizedBox(height: hasCoordinates ? 16.0 : 0.0),
|
SizedBox(height: hasCoordinates(exifInfo) ? 16.0 : 0.0),
|
||||||
buildDetail(),
|
buildDetail(),
|
||||||
const SizedBox(height: 50),
|
const SizedBox(height: 50),
|
||||||
],
|
],
|
||||||
|
@ -64,9 +64,8 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||||||
final authToken = 'Bearer ${Store.get(StoreKey.accessToken)}';
|
final authToken = 'Bearer ${Store.get(StoreKey.accessToken)}';
|
||||||
final currentIndex = useState(initialIndex);
|
final currentIndex = useState(initialIndex);
|
||||||
final currentAsset = loadAsset(currentIndex.value);
|
final currentAsset = loadAsset(currentIndex.value);
|
||||||
final watchedAsset = ref.watch(assetDetailProvider(currentAsset));
|
|
||||||
|
|
||||||
Asset asset() => watchedAsset.value ?? currentAsset;
|
Asset asset() => currentAsset;
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() {
|
() {
|
||||||
@ -194,7 +193,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
bottom: MediaQuery.of(context).viewInsets.bottom,
|
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||||
),
|
),
|
||||||
child: ExifBottomSheet(asset: asset()),
|
child: ExifBottomSheet(asset: currentAsset),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/shared/models/asset.dart';
|
import 'package:immich_mobile/shared/models/asset.dart';
|
||||||
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
||||||
import 'package:immich_mobile/utils/storage_indicator.dart';
|
import 'package:immich_mobile/utils/storage_indicator.dart';
|
||||||
|
|
||||||
class ThumbnailImage extends HookConsumerWidget {
|
class ThumbnailImage extends StatelessWidget {
|
||||||
final Asset asset;
|
final Asset asset;
|
||||||
final int index;
|
final int index;
|
||||||
final Asset Function(int index) loadAsset;
|
final Asset Function(int index) loadAsset;
|
||||||
@ -36,7 +35,7 @@ class ThumbnailImage extends HookConsumerWidget {
|
|||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
|
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
|
||||||
final assetContainerColor =
|
final assetContainerColor =
|
||||||
isDarkTheme ? Colors.blueGrey : Theme.of(context).primaryColorLight;
|
isDarkTheme ? Colors.blueGrey : Theme.of(context).primaryColorLight;
|
||||||
@ -61,8 +60,8 @@ class ThumbnailImage extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildImage(Asset asset) {
|
Widget buildImage() {
|
||||||
var image = SizedBox(
|
final image = SizedBox(
|
||||||
width: 300,
|
width: 300,
|
||||||
height: 300,
|
height: 300,
|
||||||
child: Hero(
|
child: Hero(
|
||||||
@ -133,7 +132,7 @@ class ThumbnailImage extends HookConsumerWidget {
|
|||||||
)
|
)
|
||||||
: const Border(),
|
: const Border(),
|
||||||
),
|
),
|
||||||
child: buildImage(asset),
|
child: buildImage(),
|
||||||
),
|
),
|
||||||
if (multiselectEnabled)
|
if (multiselectEnabled)
|
||||||
Padding(
|
Padding(
|
||||||
|
Loading…
Reference in New Issue
Block a user