1
0
mirror of https://github.com/immich-app/immich.git synced 2024-11-28 09:33:27 +02:00

refactor(mobile): map heatmap color and location picker (#6553)

* refactor(mobile): make location picker scaffold primary

* chore(mobile): update map heatmap colors

* style(mobile): map bottomsheet - only use borders on top

* fix(mobile): location picker show buttons above navigation bar

* fix: crash on iOS due to heatmap invalid color format

* disable rotate

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
shenlong 2024-02-08 03:07:43 +00:00 committed by GitHub
parent 2010c92b61
commit e0864768c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 102 additions and 100 deletions

View File

@ -180,4 +180,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d
COCOAPODS: 1.12.1 COCOAPODS: 1.11.3

View File

@ -1,14 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
extension ContextHelper on BuildContext { extension ContextHelper on BuildContext {
// Returns the current size from MediaQuery // Returns the current padding from MediaQuery
Size get size => MediaQuery.sizeOf(this); EdgeInsets get padding => MediaQuery.paddingOf(this);
// Returns the current width from MediaQuery // Returns the current width from MediaQuery
double get width => size.width; double get width => MediaQuery.sizeOf(this).width;
// Returns the current height from MediaQuery // Returns the current height from MediaQuery
double get height => size.height; double get height => MediaQuery.sizeOf(this).height;
// Returns true if the app is running on a mobile device (!tablets) // Returns true if the app is running on a mobile device (!tablets)
bool get isMobile => width < 550; bool get isMobile => width < 550;

View File

@ -19,17 +19,17 @@ class MapUtils {
["linear"], ["linear"],
["heatmap-density"], ["heatmap-density"],
0.0, 0.0,
"rgba(246,239,247,0.0)", "rgba(103,58,183,0.0)",
0.2, 0.3,
"rgb(208,209,230)", "rgb(103,58,183)",
0.4, 0.5,
"rgb(166,189,219)", "rgb(33,149,243)",
0.6, 0.7,
"rgb(103,169,207)", "rgb(76,175,79)",
0.8, 0.95,
"rgb(28,144,153)", "rgb(255,235,59)",
1.0, 1.0,
"rgb(1,108,89)", "rgb(255,86,34)",
], ],
heatmapIntensity: [ heatmapIntensity: [
Expressions.interpolate, ["linear"], // Expressions.interpolate, ["linear"], //
@ -44,6 +44,7 @@ class MapUtils {
4, 8, 4, 8,
9, 16, 9, 16,
], ],
heatmapOpacity: 0.7,
); );
static Map<String, dynamic> _addFeature(MapMarker marker) => { static Map<String, dynamic> _addFeature(MapMarker marker) => {

View File

@ -11,7 +11,6 @@ import 'package:immich_mobile/extensions/maplibrecontroller_extensions.dart';
import 'package:immich_mobile/modules/map/widgets/map_theme_override.dart'; import 'package:immich_mobile/modules/map/widgets/map_theme_override.dart';
import 'package:maplibre_gl/maplibre_gl.dart'; import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:immich_mobile/modules/map/utils/map_utils.dart'; import 'package:immich_mobile/modules/map/utils/map_utils.dart';
import 'package:geolocator/geolocator.dart';
@RoutePage<LatLng?>() @RoutePage<LatLng?>()
class MapLocationPickerPage extends HookConsumerWidget { class MapLocationPickerPage extends HookConsumerWidget {
@ -46,15 +45,13 @@ class MapLocationPickerPage extends HookConsumerWidget {
} }
Future<void> getCurrentLocation() async { Future<void> getCurrentLocation() async {
var (currentLocation, locationPermission) = var (currentLocation, _) =
await MapUtils.checkPermAndGetLocation(context); await MapUtils.checkPermAndGetLocation(context);
if (locationPermission == LocationPermission.denied ||
locationPermission == LocationPermission.deniedForever) {
return;
}
if (currentLocation == null) { if (currentLocation == null) {
return; return;
} }
var currentLatLng = var currentLatLng =
LatLng(currentLocation.latitude, currentLocation.longitude); LatLng(currentLocation.latitude, currentLocation.longitude);
selectedLatLng.value = currentLatLng; selectedLatLng.value = currentLatLng;
@ -67,11 +64,9 @@ class MapLocationPickerPage extends HookConsumerWidget {
backgroundColor: ctx.themeData.cardColor, backgroundColor: ctx.themeData.cardColor,
appBar: _AppBar(onClose: onClose), appBar: _AppBar(onClose: onClose),
extendBodyBehindAppBar: true, extendBodyBehindAppBar: true,
body: Column( primary: true,
children: [ body: style.widgetWhen(
style.widgetWhen( onData: (style) => Container(
onData: (style) => Expanded(
child: Container(
clipBehavior: Clip.antiAliasWithSaveLayer, clipBehavior: Clip.antiAliasWithSaveLayer,
decoration: const BoxDecoration( decoration: const BoxDecoration(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
@ -94,14 +89,11 @@ class MapLocationPickerPage extends HookConsumerWidget {
), ),
), ),
), ),
), bottomNavigationBar: _BottomBar(
_BottomBar(
selectedLatLng: selectedLatLng, selectedLatLng: selectedLatLng,
onUseLocation: () => onClose(selectedLatLng.value), onUseLocation: () => onClose(selectedLatLng.value),
onGetCurrentLocation: getCurrentLocation, onGetCurrentLocation: getCurrentLocation,
), ),
],
),
), ),
), ),
); );
@ -116,8 +108,7 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: EdgeInsets.only(top: MediaQuery.paddingOf(context).top + 25), padding: const EdgeInsets.only(top: 25),
child: Expanded(
child: Align( child: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: ElevatedButton( child: ElevatedButton(
@ -128,7 +119,6 @@ class _AppBar extends StatelessWidget implements PreferredSizeWidget {
child: const Icon(Icons.arrow_back_ios_new_rounded), child: const Icon(Icons.arrow_back_ios_new_rounded),
), ),
), ),
),
); );
} }
@ -150,7 +140,9 @@ class _BottomBar extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(
height: 150, height: 150 + context.padding.bottom,
child: Padding(
padding: EdgeInsets.only(bottom: context.padding.bottom),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -173,7 +165,8 @@ class _BottomBar extends StatelessWidget {
children: [ children: [
ElevatedButton( ElevatedButton(
onPressed: onUseLocation, onPressed: onUseLocation,
child: const Text("map_location_picker_page_use_location").tr(), child:
const Text("map_location_picker_page_use_location").tr(),
), ),
ElevatedButton( ElevatedButton(
onPressed: onGetCurrentLocation, onPressed: onGetCurrentLocation,
@ -183,6 +176,7 @@ class _BottomBar extends StatelessWidget {
), ),
], ],
), ),
),
); );
} }
} }

View File

@ -220,10 +220,9 @@ class MapPage extends HookConsumerWidget {
} }
void onZoomToLocation() async { void onZoomToLocation() async {
final location = await MapUtils.checkPermAndGetLocation(context); final (location, error) = await MapUtils.checkPermAndGetLocation(context);
if (location.$2 != null) { if (error != null) {
if (location.$2 == LocationPermission.unableToDetermine && if (error == LocationPermission.unableToDetermine && context.mounted) {
context.mounted) {
ImmichToast.show( ImmichToast.show(
context: context, context: context,
gravity: ToastGravity.BOTTOM, gravity: ToastGravity.BOTTOM,
@ -234,10 +233,10 @@ class MapPage extends HookConsumerWidget {
return; return;
} }
if (mapController.value != null && location.$1 != null) { if (mapController.value != null && location != null) {
mapController.value!.animateCamera( mapController.value!.animateCamera(
CameraUpdate.newLatLngZoom( CameraUpdate.newLatLngZoom(
LatLng(location.$1!.latitude, location.$1!.longitude), LatLng(location.latitude, location.longitude),
mapZoomToAssetLevel, mapZoomToAssetLevel,
), ),
duration: const Duration(milliseconds: 800), duration: const Duration(milliseconds: 800),
@ -389,6 +388,7 @@ class _MapWithMarker extends StatelessWidget {
dragEnabled: false, dragEnabled: false,
myLocationEnabled: false, myLocationEnabled: false,
attributionButtonPosition: AttributionButtonPosition.TopRight, attributionButtonPosition: AttributionButtonPosition.TopRight,
rotateGesturesEnabled: false,
), ),
), ),
ValueListenableBuilder( ValueListenableBuilder(

View File

@ -231,7 +231,14 @@ class _MapSheetDragRegion extends StatelessWidget {
physics: const ClampingScrollPhysics(), physics: const ClampingScrollPhysics(),
child: Card( child: Card(
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
shape: context.isMobile ? null : const BeveledRectangleBorder(), shape: context.isMobile
? const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
),
)
: const BeveledRectangleBorder(),
elevation: 0.0, elevation: 0.0,
child: Stack( child: Stack(
children: [ children: [