map: theme tweaks, info -> map

This commit is contained in:
Thibault Deckers 2021-09-15 11:53:01 +09:00
parent d10fa5dc5e
commit a7f4d89dc7
10 changed files with 174 additions and 107 deletions

View file

@ -869,6 +869,8 @@
"@mapAttributionOsmHot": {}, "@mapAttributionOsmHot": {},
"mapAttributionStamen": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)", "mapAttributionStamen": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)",
"@mapAttributionStamen": {}, "@mapAttributionStamen": {},
"openMapTooltip": "View on Map page",
"@openMapTooltip": {},
"viewerInfoOpenEmbeddedFailureFeedback": "Failed to extract embedded data", "viewerInfoOpenEmbeddedFailureFeedback": "Failed to extract embedded data",
"@viewerInfoOpenEmbeddedFailureFeedback": {}, "@viewerInfoOpenEmbeddedFailureFeedback": {},

View file

@ -424,6 +424,7 @@
"mapPointNorthUpTooltip": "북쪽을 위로 가리키기", "mapPointNorthUpTooltip": "북쪽을 위로 가리키기",
"mapAttributionOsmHot": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [HOT](https://www.hotosm.org/) • 호스팅 [OSM France](https://openstreetmap.fr/)", "mapAttributionOsmHot": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [HOT](https://www.hotosm.org/) • 호스팅 [OSM France](https://openstreetmap.fr/)",
"mapAttributionStamen": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)", "mapAttributionStamen": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)",
"openMapTooltip": "지도 페이지에서 보기",
"viewerInfoOpenEmbeddedFailureFeedback": "첨부 데이터 추출 오류", "viewerInfoOpenEmbeddedFailureFeedback": "첨부 데이터 추출 오류",
"viewerInfoOpenLinkText": "열기", "viewerInfoOpenLinkText": "열기",

View file

@ -1,7 +1,7 @@
import 'package:aves/model/settings/enums.dart'; import 'package:aves/model/settings/enums.dart';
import 'package:aves/model/settings/map_style.dart'; import 'package:aves/model/settings/map_style.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/services/android_app_service.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
@ -9,16 +9,17 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/fx/blurred.dart'; import 'package:aves/widgets/common/fx/blurred.dart';
import 'package:aves/widgets/common/fx/borders.dart'; import 'package:aves/widgets/common/fx/borders.dart';
import 'package:aves/widgets/common/map/compass.dart'; import 'package:aves/widgets/common/map/compass.dart';
import 'package:aves/widgets/common/map/theme.dart';
import 'package:aves/widgets/common/map/zoomed_bounds.dart'; import 'package:aves/widgets/common/map/zoomed_bounds.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:aves/widgets/dialogs/aves_selection_dialog.dart'; import 'package:aves/widgets/dialogs/aves_selection_dialog.dart';
import 'package:aves/widgets/map/map_page.dart';
import 'package:aves/widgets/viewer/overlay/common.dart'; import 'package:aves/widgets/viewer/overlay/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
import 'package:provider/provider.dart';
class MapButtonPanel extends StatelessWidget { class MapButtonPanel extends StatelessWidget {
final bool showBackButton;
final ValueNotifier<ZoomedBounds> boundsNotifier; final ValueNotifier<ZoomedBounds> boundsNotifier;
final Future<void> Function(double amount)? zoomBy; final Future<void> Function(double amount)? zoomBy;
final VoidCallback? resetRotation; final VoidCallback? resetRotation;
@ -27,7 +28,6 @@ class MapButtonPanel extends StatelessWidget {
const MapButtonPanel({ const MapButtonPanel({
Key? key, Key? key,
required this.showBackButton,
required this.boundsNotifier, required this.boundsNotifier,
this.zoomBy, this.zoomBy,
this.resetRotation, this.resetRotation,
@ -37,6 +37,28 @@ class MapButtonPanel extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final iconTheme = IconTheme.of(context); final iconTheme = IconTheme.of(context);
final iconSize = Size.square(iconTheme.size!); final iconSize = Size.square(iconTheme.size!);
Widget? navigationButton;
switch (context.select<MapThemeData, MapNavigationButton>((v) => v.navigationButton)) {
case MapNavigationButton.back:
navigationButton = MapOverlayButton(
icon: const BackButtonIcon(),
onPressed: () => Navigator.pop(context),
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
);
break;
case MapNavigationButton.map:
final collection = context.read<CollectionLens?>();
if (collection != null) {
navigationButton = MapOverlayButton(
icon: const Icon(AIcons.map),
onPressed: () => _goToMap(context, collection),
tooltip: context.l10n.openMapTooltip,
);
}
break;
}
return Positioned.fill( return Positioned.fill(
child: Align( child: Align(
alignment: AlignmentDirectional.centerEnd, alignment: AlignmentDirectional.centerEnd,
@ -53,43 +75,38 @@ class MapButtonPanel extends StatelessWidget {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
if (showBackButton) if (navigationButton != null) ...[
MapOverlayButton( navigationButton,
icon: const BackButtonIcon(),
onPressed: () => Navigator.pop(context),
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
),
if (resetRotation != null) ...[
const SizedBox(height: padding), const SizedBox(height: padding),
ValueListenableBuilder<ZoomedBounds>(
valueListenable: boundsNotifier,
builder: (context, bounds, child) {
final degrees = bounds.rotation;
final opacity = degrees == 0 ? .0 : 1.0;
return IgnorePointer(
ignoring: opacity == 0,
child: AnimatedOpacity(
opacity: opacity,
duration: Durations.viewerOverlayAnimation,
child: MapOverlayButton(
icon: Transform(
origin: iconSize.center(Offset.zero),
transform: Matrix4.rotationZ(degToRadian(degrees)),
child: CustomPaint(
painter: CompassPainter(
color: iconTheme.color!,
),
size: iconSize,
),
),
onPressed: () => resetRotation?.call(),
tooltip: context.l10n.mapPointNorthUpTooltip,
),
),
);
},
),
], ],
ValueListenableBuilder<ZoomedBounds>(
valueListenable: boundsNotifier,
builder: (context, bounds, child) {
final degrees = bounds.rotation;
final opacity = degrees == 0 ? .0 : 1.0;
return IgnorePointer(
ignoring: opacity == 0,
child: AnimatedOpacity(
opacity: opacity,
duration: Durations.viewerOverlayAnimation,
child: MapOverlayButton(
icon: Transform(
origin: iconSize.center(Offset.zero),
transform: Matrix4.rotationZ(degToRadian(degrees)),
child: CustomPaint(
painter: CompassPainter(
color: iconTheme.color!,
),
size: iconSize,
),
),
onPressed: () => resetRotation?.call(),
tooltip: context.l10n.mapPointNorthUpTooltip,
),
),
);
},
),
], ],
), ),
), ),
@ -98,14 +115,6 @@ class MapButtonPanel extends StatelessWidget {
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
MapOverlayButton(
icon: const Icon(AIcons.openOutside),
onPressed: () => AndroidAppService.openMap(boundsNotifier.value.center).then((success) {
if (!success) showNoMatchingAppDialog(context);
}),
tooltip: context.l10n.entryActionOpenMap,
),
const SizedBox(height: padding),
MapOverlayButton( MapOverlayButton(
icon: const Icon(AIcons.layers), icon: const Icon(AIcons.layers),
onPressed: () async { onPressed: () async {
@ -161,6 +170,20 @@ class MapButtonPanel extends StatelessWidget {
), ),
); );
} }
void _goToMap(BuildContext context, CollectionLens collection) {
final entries = collection.sortedEntries.where((entry) => entry.hasGps).toList();
Navigator.push(
context,
MaterialPageRoute(
settings: const RouteSettings(name: MapPage.routeName),
builder: (context) => MapPage(
entries: entries,
),
),
);
}
} }
class MapOverlayButton extends StatelessWidget { class MapOverlayButton extends StatelessWidget {
@ -177,6 +200,7 @@ class MapOverlayButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final visualDensity = context.select<MapThemeData, VisualDensity?>((v) => v.visualDensity);
final blurred = settings.enableOverlayBlurEffect; final blurred = settings.enableOverlayBlurEffect;
return BlurredOval( return BlurredOval(
enabled: blurred, enabled: blurred,
@ -190,7 +214,7 @@ class MapOverlayButton extends StatelessWidget {
), ),
child: IconButton( child: IconButton(
iconSize: 20, iconSize: 20,
visualDensity: VisualDensity.compact, visualDensity: visualDensity,
icon: icon, icon: icon,
onPressed: onPressed, onPressed: onPressed,
tooltip: tooltip, tooltip: tooltip,

View file

@ -1,7 +1,8 @@
import 'package:aves/widgets/common/map/theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MapDecorator extends StatelessWidget { class MapDecorator extends StatelessWidget {
final bool interactive;
final Widget? child; final Widget? child;
static const mapBorderRadius = BorderRadius.all(Radius.circular(24)); // to match button circles static const mapBorderRadius = BorderRadius.all(Radius.circular(24)); // to match button circles
@ -10,12 +11,12 @@ class MapDecorator extends StatelessWidget {
const MapDecorator({ const MapDecorator({
Key? key, Key? key,
required this.interactive,
this.child, this.child,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final interactive = context.select<MapThemeData, bool>((v) => v.interactive);
return GestureDetector( return GestureDetector(
onScaleStart: interactive onScaleStart: interactive
? null ? null

View file

@ -16,6 +16,7 @@ import 'package:aves/widgets/common/map/geo_entry.dart';
import 'package:aves/widgets/common/map/google/map.dart'; import 'package:aves/widgets/common/map/google/map.dart';
import 'package:aves/widgets/common/map/leaflet/map.dart'; import 'package:aves/widgets/common/map/leaflet/map.dart';
import 'package:aves/widgets/common/map/marker.dart'; import 'package:aves/widgets/common/map/marker.dart';
import 'package:aves/widgets/common/map/theme.dart';
import 'package:aves/widgets/common/map/zoomed_bounds.dart'; import 'package:aves/widgets/common/map/zoomed_bounds.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
@ -27,8 +28,6 @@ import 'package:provider/provider.dart';
class GeoMap extends StatefulWidget { class GeoMap extends StatefulWidget {
final AvesMapController? controller; final AvesMapController? controller;
final List<AvesEntry> entries; final List<AvesEntry> entries;
final bool interactive, showBackButton;
final double? mapHeight;
final ValueNotifier<bool> isAnimatingNotifier; final ValueNotifier<bool> isAnimatingNotifier;
final UserZoomChangeCallback? onUserZoomChange; final UserZoomChangeCallback? onUserZoomChange;
final MarkerTapCallback? onMarkerTap; final MarkerTapCallback? onMarkerTap;
@ -40,9 +39,6 @@ class GeoMap extends StatefulWidget {
Key? key, Key? key,
this.controller, this.controller,
required this.entries, required this.entries,
required this.interactive,
required this.showBackButton,
this.mapHeight,
required this.isAnimatingNotifier, required this.isAnimatingNotifier,
this.onUserZoomChange, this.onUserZoomChange,
this.onMarkerTap, this.onMarkerTap,
@ -64,12 +60,6 @@ class _GeoMapState extends State<GeoMap> {
List<AvesEntry> get entries => widget.entries; List<AvesEntry> get entries => widget.entries;
bool get interactive => widget.interactive;
bool get showBackButton => widget.showBackButton;
double? get mapHeight => widget.mapHeight;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -139,8 +129,6 @@ class _GeoMapState extends State<GeoMap> {
? EntryGoogleMap( ? EntryGoogleMap(
controller: widget.controller, controller: widget.controller,
boundsNotifier: _boundsNotifier, boundsNotifier: _boundsNotifier,
interactive: interactive,
showBackButton: showBackButton,
minZoom: 0, minZoom: 0,
maxZoom: 20, maxZoom: 20,
style: mapStyle, style: mapStyle,
@ -152,8 +140,6 @@ class _GeoMapState extends State<GeoMap> {
: EntryLeafletMap( : EntryLeafletMap(
controller: widget.controller, controller: widget.controller,
boundsNotifier: _boundsNotifier, boundsNotifier: _boundsNotifier,
interactive: interactive,
showBackButton: showBackButton,
minZoom: 2, minZoom: 2,
maxZoom: 16, maxZoom: 16,
style: mapStyle, style: mapStyle,
@ -167,6 +153,7 @@ class _GeoMapState extends State<GeoMap> {
onMarkerTap: _onMarkerTap, onMarkerTap: _onMarkerTap,
); );
final mapHeight = context.select<MapThemeData, double?>((v) => v.mapHeight);
child = Column( child = Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -192,11 +179,8 @@ class _GeoMapState extends State<GeoMap> {
} }
Widget replacement = Stack( Widget replacement = Stack(
children: [ children: [
MapDecorator( const MapDecorator(),
interactive: interactive,
),
MapButtonPanel( MapButtonPanel(
showBackButton: showBackButton,
boundsNotifier: _boundsNotifier, boundsNotifier: _boundsNotifier,
), ),
], ],

View file

@ -10,15 +10,16 @@ import 'package:aves/widgets/common/map/decorator.dart';
import 'package:aves/widgets/common/map/geo_entry.dart'; import 'package:aves/widgets/common/map/geo_entry.dart';
import 'package:aves/widgets/common/map/geo_map.dart'; import 'package:aves/widgets/common/map/geo_map.dart';
import 'package:aves/widgets/common/map/google/marker_generator.dart'; import 'package:aves/widgets/common/map/google/marker_generator.dart';
import 'package:aves/widgets/common/map/theme.dart';
import 'package:aves/widgets/common/map/zoomed_bounds.dart'; import 'package:aves/widgets/common/map/zoomed_bounds.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:latlong2/latlong.dart' as ll; import 'package:latlong2/latlong.dart' as ll;
import 'package:provider/provider.dart';
class EntryGoogleMap extends StatefulWidget { class EntryGoogleMap extends StatefulWidget {
final AvesMapController? controller; final AvesMapController? controller;
final ValueNotifier<ZoomedBounds> boundsNotifier; final ValueNotifier<ZoomedBounds> boundsNotifier;
final bool interactive, showBackButton;
final double? minZoom, maxZoom; final double? minZoom, maxZoom;
final EntryMapStyle style; final EntryMapStyle style;
final MarkerClusterBuilder markerClusterBuilder; final MarkerClusterBuilder markerClusterBuilder;
@ -30,8 +31,6 @@ class EntryGoogleMap extends StatefulWidget {
Key? key, Key? key,
this.controller, this.controller,
required this.boundsNotifier, required this.boundsNotifier,
required this.interactive,
required this.showBackButton,
this.minZoom, this.minZoom,
this.maxZoom, this.maxZoom,
required this.style, required this.style,
@ -56,8 +55,6 @@ class _EntryGoogleMapState extends State<EntryGoogleMap> with WidgetsBindingObse
ZoomedBounds get bounds => boundsNotifier.value; ZoomedBounds get bounds => boundsNotifier.value;
bool get interactive => widget.interactive;
static const uninitializedLatLng = LatLng(0, 0); static const uninitializedLatLng = LatLng(0, 0);
@override @override
@ -123,14 +120,12 @@ class _EntryGoogleMapState extends State<EntryGoogleMap> with WidgetsBindingObse
}, },
), ),
MapDecorator( MapDecorator(
interactive: interactive,
child: _buildMap(), child: _buildMap(),
), ),
MapButtonPanel( MapButtonPanel(
showBackButton: widget.showBackButton,
boundsNotifier: boundsNotifier, boundsNotifier: boundsNotifier,
zoomBy: _zoomBy, zoomBy: _zoomBy,
resetRotation: interactive ? _resetRotation : null, resetRotation: _resetRotation,
), ),
], ],
); );
@ -155,7 +150,7 @@ class _EntryGoogleMapState extends State<EntryGoogleMap> with WidgetsBindingObse
} }
}); });
final interactive = widget.interactive; final interactive = context.select<MapThemeData, bool>((v) => v.interactive);
return GoogleMap( return GoogleMap(
initialCameraPosition: CameraPosition( initialCameraPosition: CameraPosition(
target: _toGoogleLatLng(bounds.center), target: _toGoogleLatLng(bounds.center),

View file

@ -11,15 +11,16 @@ import 'package:aves/widgets/common/map/geo_map.dart';
import 'package:aves/widgets/common/map/latlng_tween.dart'; import 'package:aves/widgets/common/map/latlng_tween.dart';
import 'package:aves/widgets/common/map/leaflet/scale_layer.dart'; import 'package:aves/widgets/common/map/leaflet/scale_layer.dart';
import 'package:aves/widgets/common/map/leaflet/tile_layers.dart'; import 'package:aves/widgets/common/map/leaflet/tile_layers.dart';
import 'package:aves/widgets/common/map/theme.dart';
import 'package:aves/widgets/common/map/zoomed_bounds.dart'; import 'package:aves/widgets/common/map/zoomed_bounds.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
import 'package:provider/provider.dart';
class EntryLeafletMap extends StatefulWidget { class EntryLeafletMap extends StatefulWidget {
final AvesMapController? controller; final AvesMapController? controller;
final ValueNotifier<ZoomedBounds> boundsNotifier; final ValueNotifier<ZoomedBounds> boundsNotifier;
final bool interactive, showBackButton;
final double minZoom, maxZoom; final double minZoom, maxZoom;
final EntryMapStyle style; final EntryMapStyle style;
final MarkerClusterBuilder markerClusterBuilder; final MarkerClusterBuilder markerClusterBuilder;
@ -32,8 +33,6 @@ class EntryLeafletMap extends StatefulWidget {
Key? key, Key? key,
this.controller, this.controller,
required this.boundsNotifier, required this.boundsNotifier,
required this.interactive,
required this.showBackButton,
this.minZoom = 0, this.minZoom = 0,
this.maxZoom = 22, this.maxZoom = 22,
required this.style, required this.style,
@ -58,8 +57,6 @@ class _EntryLeafletMapState extends State<EntryLeafletMap> with TickerProviderSt
ZoomedBounds get bounds => boundsNotifier.value; ZoomedBounds get bounds => boundsNotifier.value;
bool get interactive => widget.interactive;
// duration should match the uncustomizable Google Maps duration // duration should match the uncustomizable Google Maps duration
static const _cameraAnimationDuration = Duration(milliseconds: 600); static const _cameraAnimationDuration = Duration(milliseconds: 600);
@ -104,14 +101,12 @@ class _EntryLeafletMapState extends State<EntryLeafletMap> with TickerProviderSt
return Stack( return Stack(
children: [ children: [
MapDecorator( MapDecorator(
interactive: interactive,
child: _buildMap(), child: _buildMap(),
), ),
MapButtonPanel( MapButtonPanel(
showBackButton: widget.showBackButton,
boundsNotifier: boundsNotifier, boundsNotifier: boundsNotifier,
zoomBy: _zoomBy, zoomBy: _zoomBy,
resetRotation: interactive ? _resetRotation : null, resetRotation: _resetRotation,
), ),
], ],
); );
@ -135,13 +130,14 @@ class _EntryLeafletMapState extends State<EntryLeafletMap> with TickerProviderSt
); );
}).toList(); }).toList();
final interactive = context.select<MapThemeData, bool>((v) => v.interactive);
return FlutterMap( return FlutterMap(
options: MapOptions( options: MapOptions(
center: bounds.center, center: bounds.center,
zoom: bounds.zoom, zoom: bounds.zoom,
minZoom: widget.minZoom, minZoom: widget.minZoom,
maxZoom: widget.maxZoom, maxZoom: widget.maxZoom,
interactiveFlags: widget.interactive ? InteractiveFlag.all : InteractiveFlag.none, interactiveFlags: interactive ? InteractiveFlag.all : InteractiveFlag.none,
controller: _leafletMapController, controller: _leafletMapController,
), ),
mapController: _leafletMapController, mapController: _leafletMapController,

View file

@ -0,0 +1,53 @@
import 'package:aves/model/settings/settings.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
enum MapNavigationButton { back, map }
class MapTheme extends StatelessWidget {
final bool interactive;
final MapNavigationButton navigationButton;
final VisualDensity? visualDensity;
final double? mapHeight;
final Widget child;
const MapTheme({
Key? key,
required this.interactive,
required this.navigationButton,
this.visualDensity,
this.mapHeight,
required this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ProxyProvider<Settings, MapThemeData>(
update: (_, settings, __) {
return MapThemeData(
interactive: interactive,
navigationButton: navigationButton,
visualDensity: visualDensity,
mapHeight: mapHeight,
// TODO TLAD use settings?
// showLocation: showBackButton ?? settings.showThumbnailLocation,
);
},
child: child,
);
}
}
class MapThemeData {
final bool interactive;
final MapNavigationButton navigationButton;
final VisualDensity? visualDensity;
final double? mapHeight;
const MapThemeData({
required this.interactive,
required this.navigationButton,
this.visualDensity,
this.mapHeight,
});
}

View file

@ -5,6 +5,7 @@ import 'package:aves/theme/durations.dart';
import 'package:aves/utils/debouncer.dart'; import 'package:aves/utils/debouncer.dart';
import 'package:aves/widgets/common/map/controller.dart'; import 'package:aves/widgets/common/map/controller.dart';
import 'package:aves/widgets/common/map/geo_map.dart'; import 'package:aves/widgets/common/map/geo_map.dart';
import 'package:aves/widgets/common/map/theme.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:aves/widgets/common/thumbnail/scroller.dart'; import 'package:aves/widgets/common/thumbnail/scroller.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -65,20 +66,22 @@ class _MapPageState extends State<MapPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: GeoMap( child: MapTheme(
controller: _mapController,
entries: entries,
interactive: true, interactive: true,
showBackButton: true, navigationButton: MapNavigationButton.back,
isAnimatingNotifier: _isAnimatingNotifier, child: GeoMap(
onMarkerTap: (markerEntry, getClusterEntries) { controller: _mapController,
final index = entries.indexOf(markerEntry); entries: entries,
if (_selectedIndexNotifier.value != index) { isAnimatingNotifier: _isAnimatingNotifier,
_selectedIndexNotifier.value = index; onMarkerTap: (markerEntry, getClusterEntries) {
} else { final index = entries.indexOf(markerEntry);
_moveToEntry(markerEntry); if (_selectedIndexNotifier.value != index) {
} _selectedIndexNotifier.value = index;
}, } else {
_moveToEntry(markerEntry);
}
},
),
), ),
), ),
const Divider(), const Divider(),

View file

@ -8,8 +8,10 @@ import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:aves/widgets/common/map/geo_map.dart'; import 'package:aves/widgets/common/map/geo_map.dart';
import 'package:aves/widgets/common/map/theme.dart';
import 'package:aves/widgets/viewer/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class LocationSection extends StatefulWidget { class LocationSection extends StatefulWidget {
final CollectionLens? collection; final CollectionLens? collection;
@ -82,13 +84,19 @@ class _LocationSectionState extends State<LocationSection> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (widget.showTitle) const SectionRow(icon: AIcons.location), if (widget.showTitle) const SectionRow(icon: AIcons.location),
GeoMap( ChangeNotifierProvider<CollectionLens?>.value(
entries: [entry], value: collection,
interactive: false, child: MapTheme(
showBackButton: false, interactive: false,
mapHeight: 200, navigationButton: MapNavigationButton.map,
isAnimatingNotifier: widget.isScrollingNotifier, visualDensity: VisualDensity.compact,
onUserZoomChange: (zoom) => settings.infoMapZoom = zoom, mapHeight: 200,
child: GeoMap(
entries: [entry],
isAnimatingNotifier: widget.isScrollingNotifier,
onUserZoomChange: (zoom) => settings.infoMapZoom = zoom,
),
),
), ),
_AddressInfoGroup(entry: entry), _AddressInfoGroup(entry: entry),
if (filters.isNotEmpty) if (filters.isNotEmpty)