mirror of
https://github.com/immich-app/immich.git
synced 2026-03-01 01:59:06 +03:00
feat(mobile): inline asset details (#25952)
The existing implementation for showing asset details uses a bottom sheet, and is not in sync with the preview or scroll intent. Other apps use inline details, which is much cleaner and feels better to use.
This commit is contained in:
@@ -7,7 +7,7 @@ import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart';
|
||||
import 'package:immich_mobile/widgets/map/map_theme_override.dart';
|
||||
import 'package:immich_mobile/widgets/map/positioned_asset_marker_icon.dart';
|
||||
import 'package:immich_mobile/widgets/map/asset_market_icon.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
|
||||
/// A non-interactive thumbnail of a map in the given coordinates with optional markers
|
||||
@@ -45,21 +45,12 @@ class MapThumbnail extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final offsettedCentre = LatLng(centre.latitude + 0.002, centre.longitude);
|
||||
final controller = useRef<MapLibreMapController?>(null);
|
||||
final styleLoaded = useState(false);
|
||||
final position = useValueNotifier<Point<num>?>(null);
|
||||
|
||||
Future<void> onMapCreated(MapLibreMapController mapController) async {
|
||||
controller.value = mapController;
|
||||
styleLoaded.value = false;
|
||||
if (assetMarkerRemoteId != null) {
|
||||
// The iOS impl returns wrong toScreenLocation without the delay
|
||||
Future.delayed(
|
||||
const Duration(milliseconds: 100),
|
||||
() async => position.value = await mapController.toScreenLocation(centre),
|
||||
);
|
||||
}
|
||||
onCreated?.call(mapController);
|
||||
}
|
||||
|
||||
@@ -90,11 +81,11 @@ class MapThumbnail extends HookConsumerWidget {
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(15)),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
alignment: AlignmentGeometry.topCenter,
|
||||
children: [
|
||||
style.widgetWhen(
|
||||
onData: (style) => MapLibreMap(
|
||||
initialCameraPosition: CameraPosition(target: offsettedCentre, zoom: zoom),
|
||||
initialCameraPosition: CameraPosition(target: centre, zoom: zoom),
|
||||
styleString: style,
|
||||
onMapCreated: onMapCreated,
|
||||
onStyleLoadedCallback: onStyleLoaded,
|
||||
@@ -109,17 +100,16 @@ class MapThumbnail extends HookConsumerWidget {
|
||||
attributionButtonMargins: showAttribution == false ? const Point(-100, 0) : null,
|
||||
),
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: position,
|
||||
builder: (_, value, __) => value != null && assetMarkerRemoteId != null && assetThumbhash != null
|
||||
? PositionedAssetMarkerIcon(
|
||||
size: height / 2,
|
||||
point: value,
|
||||
assetRemoteId: assetMarkerRemoteId!,
|
||||
assetThumbhash: assetThumbhash!,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
if (assetMarkerRemoteId != null && assetThumbhash != null)
|
||||
Container(
|
||||
width: width,
|
||||
height: height / 2,
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: SizedBox.square(
|
||||
dimension: height / 2.5,
|
||||
child: AssetMarkerIcon(id: assetMarkerRemoteId!, thumbhash: assetThumbhash!),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user