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:
parent
2010c92b61
commit
e0864768c2
@ -180,4 +180,4 @@ SPEC CHECKSUMS:
|
|||||||
|
|
||||||
PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d
|
PODFILE CHECKSUM: 64c9b5291666c0ca3caabdfe9865c141ac40321d
|
||||||
|
|
||||||
COCOAPODS: 1.12.1
|
COCOAPODS: 1.11.3
|
||||||
|
@ -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;
|
||||||
|
@ -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) => {
|
||||||
|
@ -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 {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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: [
|
||||||
|
Loading…
Reference in New Issue
Block a user