map: improved default center
This commit is contained in:
parent
c5f8981a7e
commit
785e093e84
6 changed files with 52 additions and 20 deletions
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/l10n/l10n.dart';
|
import 'package:aves/l10n/l10n.dart';
|
||||||
|
@ -15,6 +16,7 @@ import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
final Settings settings = Settings._private();
|
final Settings settings = Settings._private();
|
||||||
|
|
||||||
|
@ -121,11 +123,14 @@ class Settings extends ChangeNotifier {
|
||||||
static const subtitleBackgroundColorKey = 'subtitle_background_color';
|
static const subtitleBackgroundColorKey = 'subtitle_background_color';
|
||||||
|
|
||||||
// info
|
// info
|
||||||
static const infoMapStyleKey = 'info_map_style';
|
|
||||||
static const infoMapZoomKey = 'info_map_zoom';
|
static const infoMapZoomKey = 'info_map_zoom';
|
||||||
static const coordinateFormatKey = 'coordinates_format';
|
static const coordinateFormatKey = 'coordinates_format';
|
||||||
static const unitSystemKey = 'unit_system';
|
static const unitSystemKey = 'unit_system';
|
||||||
|
|
||||||
|
// map
|
||||||
|
static const mapStyleKey = 'info_map_style';
|
||||||
|
static const mapDefaultCenterKey = 'map_default_center';
|
||||||
|
|
||||||
// search
|
// search
|
||||||
static const saveSearchHistoryKey = 'save_search_history';
|
static const saveSearchHistoryKey = 'save_search_history';
|
||||||
static const searchHistoryKey = 'search_history';
|
static const searchHistoryKey = 'search_history';
|
||||||
|
@ -198,10 +203,10 @@ class Settings extends ChangeNotifier {
|
||||||
// availability
|
// availability
|
||||||
final defaultMapStyle = mobileServices.defaultMapStyle;
|
final defaultMapStyle = mobileServices.defaultMapStyle;
|
||||||
if (mobileServices.mapStyles.contains(defaultMapStyle)) {
|
if (mobileServices.mapStyles.contains(defaultMapStyle)) {
|
||||||
infoMapStyle = defaultMapStyle;
|
mapStyle = defaultMapStyle;
|
||||||
} else {
|
} else {
|
||||||
final styles = EntryMapStyle.values.whereNot((v) => v.needMobileService).toList();
|
final styles = EntryMapStyle.values.whereNot((v) => v.needMobileService).toList();
|
||||||
infoMapStyle = styles[Random().nextInt(styles.length)];
|
mapStyle = styles[Random().nextInt(styles.length)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,14 +561,6 @@ class Settings extends ChangeNotifier {
|
||||||
|
|
||||||
// info
|
// info
|
||||||
|
|
||||||
EntryMapStyle get infoMapStyle {
|
|
||||||
final preferred = getEnumOrDefault(infoMapStyleKey, SettingsDefaults.infoMapStyle, EntryMapStyle.values);
|
|
||||||
final available = availability.mapStyles;
|
|
||||||
return available.contains(preferred) ? preferred : available.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
set infoMapStyle(EntryMapStyle newValue) => setAndNotify(infoMapStyleKey, newValue.toString());
|
|
||||||
|
|
||||||
double get infoMapZoom => getDouble(infoMapZoomKey) ?? SettingsDefaults.infoMapZoom;
|
double get infoMapZoom => getDouble(infoMapZoomKey) ?? SettingsDefaults.infoMapZoom;
|
||||||
|
|
||||||
set infoMapZoom(double newValue) => setAndNotify(infoMapZoomKey, newValue);
|
set infoMapZoom(double newValue) => setAndNotify(infoMapZoomKey, newValue);
|
||||||
|
@ -576,6 +573,23 @@ class Settings extends ChangeNotifier {
|
||||||
|
|
||||||
set unitSystem(UnitSystem newValue) => setAndNotify(unitSystemKey, newValue.toString());
|
set unitSystem(UnitSystem newValue) => setAndNotify(unitSystemKey, newValue.toString());
|
||||||
|
|
||||||
|
// map
|
||||||
|
|
||||||
|
EntryMapStyle get mapStyle {
|
||||||
|
final preferred = getEnumOrDefault(mapStyleKey, SettingsDefaults.infoMapStyle, EntryMapStyle.values);
|
||||||
|
final available = availability.mapStyles;
|
||||||
|
return available.contains(preferred) ? preferred : available.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
set mapStyle(EntryMapStyle newValue) => setAndNotify(mapStyleKey, newValue.toString());
|
||||||
|
|
||||||
|
LatLng? get mapDefaultCenter {
|
||||||
|
final json = getString(mapDefaultCenterKey);
|
||||||
|
return json != null ? LatLng.fromJson(jsonDecode(json)) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
set mapDefaultCenter(LatLng? newValue) => setAndNotify(mapDefaultCenterKey, newValue != null ? jsonEncode(newValue.toJson()) : null);
|
||||||
|
|
||||||
// search
|
// search
|
||||||
|
|
||||||
bool get saveSearchHistory => getBoolOrDefault(saveSearchHistoryKey, SettingsDefaults.saveSearchHistory);
|
bool get saveSearchHistory => getBoolOrDefault(saveSearchHistoryKey, SettingsDefaults.saveSearchHistory);
|
||||||
|
@ -863,7 +877,8 @@ class Settings extends ChangeNotifier {
|
||||||
case videoLoopModeKey:
|
case videoLoopModeKey:
|
||||||
case videoControlsKey:
|
case videoControlsKey:
|
||||||
case subtitleTextAlignmentKey:
|
case subtitleTextAlignmentKey:
|
||||||
case infoMapStyleKey:
|
case mapStyleKey:
|
||||||
|
case mapDefaultCenterKey:
|
||||||
case coordinateFormatKey:
|
case coordinateFormatKey:
|
||||||
case unitSystemKey:
|
case unitSystemKey:
|
||||||
case accessibilityAnimationsKey:
|
case accessibilityAnimationsKey:
|
||||||
|
|
|
@ -129,11 +129,11 @@ class MapButtonPanel extends StatelessWidget {
|
||||||
onPressed: () => showSelectionDialog<EntryMapStyle>(
|
onPressed: () => showSelectionDialog<EntryMapStyle>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AvesSelectionDialog<EntryMapStyle>(
|
builder: (context) => AvesSelectionDialog<EntryMapStyle>(
|
||||||
initialValue: settings.infoMapStyle,
|
initialValue: settings.mapStyle,
|
||||||
options: Map.fromEntries(availability.mapStyles.map((v) => MapEntry(v, v.getName(context)))),
|
options: Map.fromEntries(availability.mapStyles.map((v) => MapEntry(v, v.getName(context)))),
|
||||||
title: context.l10n.mapStyleDialogTitle,
|
title: context.l10n.mapStyleDialogTitle,
|
||||||
),
|
),
|
||||||
onSelection: (v) => settings.infoMapStyle = v,
|
onSelection: (v) => settings.mapStyle = v,
|
||||||
),
|
),
|
||||||
tooltip: context.l10n.mapStyleTooltip,
|
tooltip: context.l10n.mapStyleTooltip,
|
||||||
),
|
),
|
||||||
|
|
|
@ -149,7 +149,7 @@ class _GeoMapState extends State<GeoMap> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Selector<Settings, EntryMapStyle>(
|
return Selector<Settings, EntryMapStyle>(
|
||||||
selector: (context, s) => s.infoMapStyle,
|
selector: (context, s) => s.mapStyle,
|
||||||
builder: (context, mapStyle, child) {
|
builder: (context, mapStyle, child) {
|
||||||
final isHeavy = mapStyle.isHeavy;
|
final isHeavy = mapStyle.isHeavy;
|
||||||
Widget _buildMarkerWidget(MarkerKey<AvesEntry> key) => ImageMarker(
|
Widget _buildMarkerWidget(MarkerKey<AvesEntry> key) => ImageMarker(
|
||||||
|
@ -281,6 +281,7 @@ class _GeoMapState extends State<GeoMap> {
|
||||||
|
|
||||||
final overlayEntry = widget.overlayEntry;
|
final overlayEntry = widget.overlayEntry;
|
||||||
if (overlayEntry != null) {
|
if (overlayEntry != null) {
|
||||||
|
// fit map to overlaid item
|
||||||
final corner1 = overlayEntry.topLeft;
|
final corner1 = overlayEntry.topLeft;
|
||||||
final corner2 = overlayEntry.bottomRight;
|
final corner2 = overlayEntry.bottomRight;
|
||||||
if (corner1 != null && corner2 != null) {
|
if (corner1 != null && corner2 != null) {
|
||||||
|
@ -290,10 +291,26 @@ class _GeoMapState extends State<GeoMap> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bounds == null) {
|
if (bounds == null) {
|
||||||
|
// fit map to located items
|
||||||
final initialCenter = widget.initialCenter;
|
final initialCenter = widget.initialCenter;
|
||||||
final points = initialCenter != null ? {initialCenter} : entries.map((v) => v.latLng!).toSet();
|
final points = initialCenter != null ? {initialCenter} : entries.map((v) => v.latLng!).toSet();
|
||||||
|
if (points.isNotEmpty) {
|
||||||
|
bounds = ZoomedBounds.fromPoints(
|
||||||
|
points: points,
|
||||||
|
collocationZoom: settings.infoMapZoom,
|
||||||
|
);
|
||||||
|
final center = bounds.projectedCenter;
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (!mounted) return;
|
||||||
|
settings.mapDefaultCenter = center;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bounds == null) {
|
||||||
|
// fallback to default center
|
||||||
|
final center = settings.mapDefaultCenter ??= Constants.wonders[Random().nextInt(Constants.wonders.length)];
|
||||||
bounds = ZoomedBounds.fromPoints(
|
bounds = ZoomedBounds.fromPoints(
|
||||||
points: points.isNotEmpty ? points : {Constants.wonders[Random().nextInt(Constants.wonders.length)]},
|
points: {center},
|
||||||
collocationZoom: settings.infoMapZoom,
|
collocationZoom: settings.infoMapZoom,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
if (settings.infoMapStyle.isHeavy) {
|
if (settings.mapStyle.isHeavy) {
|
||||||
_isPageAnimatingNotifier = ValueNotifier(true);
|
_isPageAnimatingNotifier = ValueNotifier(true);
|
||||||
Future.delayed(Durations.pageTransitionAnimation * timeDilation).then((_) {
|
Future.delayed(Durations.pageTransitionAnimation * timeDilation).then((_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
|
@ -107,7 +107,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
if (settings.infoMapStyle.isHeavy) {
|
if (settings.mapStyle.isHeavy) {
|
||||||
_isPageAnimatingNotifier.value = true;
|
_isPageAnimatingNotifier.value = true;
|
||||||
Future.delayed(Durations.pageTransitionAnimation * timeDilation).then((_) {
|
Future.delayed(Durations.pageTransitionAnimation * timeDilation).then((_) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
@ -170,7 +170,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
child: Selector<Settings, EntryMapStyle>(
|
child: Selector<Settings, EntryMapStyle>(
|
||||||
selector: (context, s) => s.infoMapStyle,
|
selector: (context, s) => s.mapStyle,
|
||||||
builder: (context, mapStyle, child) {
|
builder: (context, mapStyle, child) {
|
||||||
late Widget scroller;
|
late Widget scroller;
|
||||||
if (mapStyle.isHeavy) {
|
if (mapStyle.isHeavy) {
|
||||||
|
|
|
@ -38,6 +38,6 @@ Future<void> configureAndLaunch() async {
|
||||||
..showOverlayThumbnailPreview = true
|
..showOverlayThumbnailPreview = true
|
||||||
..imageBackground = EntryBackground.checkered
|
..imageBackground = EntryBackground.checkered
|
||||||
// info
|
// info
|
||||||
..infoMapStyle = EntryMapStyle.googleNormal;
|
..mapStyle = EntryMapStyle.googleNormal;
|
||||||
app.main();
|
app.main();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue