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:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:aves/l10n/l10n.dart';
|
||||
|
@ -15,6 +16,7 @@ import 'package:aves_map/aves_map.dart';
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
final Settings settings = Settings._private();
|
||||
|
||||
|
@ -121,11 +123,14 @@ class Settings extends ChangeNotifier {
|
|||
static const subtitleBackgroundColorKey = 'subtitle_background_color';
|
||||
|
||||
// info
|
||||
static const infoMapStyleKey = 'info_map_style';
|
||||
static const infoMapZoomKey = 'info_map_zoom';
|
||||
static const coordinateFormatKey = 'coordinates_format';
|
||||
static const unitSystemKey = 'unit_system';
|
||||
|
||||
// map
|
||||
static const mapStyleKey = 'info_map_style';
|
||||
static const mapDefaultCenterKey = 'map_default_center';
|
||||
|
||||
// search
|
||||
static const saveSearchHistoryKey = 'save_search_history';
|
||||
static const searchHistoryKey = 'search_history';
|
||||
|
@ -198,10 +203,10 @@ class Settings extends ChangeNotifier {
|
|||
// availability
|
||||
final defaultMapStyle = mobileServices.defaultMapStyle;
|
||||
if (mobileServices.mapStyles.contains(defaultMapStyle)) {
|
||||
infoMapStyle = defaultMapStyle;
|
||||
mapStyle = defaultMapStyle;
|
||||
} else {
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
set infoMapZoom(double newValue) => setAndNotify(infoMapZoomKey, newValue);
|
||||
|
@ -576,6 +573,23 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
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
|
||||
|
||||
bool get saveSearchHistory => getBoolOrDefault(saveSearchHistoryKey, SettingsDefaults.saveSearchHistory);
|
||||
|
@ -863,7 +877,8 @@ class Settings extends ChangeNotifier {
|
|||
case videoLoopModeKey:
|
||||
case videoControlsKey:
|
||||
case subtitleTextAlignmentKey:
|
||||
case infoMapStyleKey:
|
||||
case mapStyleKey:
|
||||
case mapDefaultCenterKey:
|
||||
case coordinateFormatKey:
|
||||
case unitSystemKey:
|
||||
case accessibilityAnimationsKey:
|
||||
|
|
|
@ -129,11 +129,11 @@ class MapButtonPanel extends StatelessWidget {
|
|||
onPressed: () => showSelectionDialog<EntryMapStyle>(
|
||||
context: context,
|
||||
builder: (context) => AvesSelectionDialog<EntryMapStyle>(
|
||||
initialValue: settings.infoMapStyle,
|
||||
initialValue: settings.mapStyle,
|
||||
options: Map.fromEntries(availability.mapStyles.map((v) => MapEntry(v, v.getName(context)))),
|
||||
title: context.l10n.mapStyleDialogTitle,
|
||||
),
|
||||
onSelection: (v) => settings.infoMapStyle = v,
|
||||
onSelection: (v) => settings.mapStyle = v,
|
||||
),
|
||||
tooltip: context.l10n.mapStyleTooltip,
|
||||
),
|
||||
|
|
|
@ -149,7 +149,7 @@ class _GeoMapState extends State<GeoMap> {
|
|||
}
|
||||
|
||||
return Selector<Settings, EntryMapStyle>(
|
||||
selector: (context, s) => s.infoMapStyle,
|
||||
selector: (context, s) => s.mapStyle,
|
||||
builder: (context, mapStyle, child) {
|
||||
final isHeavy = mapStyle.isHeavy;
|
||||
Widget _buildMarkerWidget(MarkerKey<AvesEntry> key) => ImageMarker(
|
||||
|
@ -281,6 +281,7 @@ class _GeoMapState extends State<GeoMap> {
|
|||
|
||||
final overlayEntry = widget.overlayEntry;
|
||||
if (overlayEntry != null) {
|
||||
// fit map to overlaid item
|
||||
final corner1 = overlayEntry.topLeft;
|
||||
final corner2 = overlayEntry.bottomRight;
|
||||
if (corner1 != null && corner2 != null) {
|
||||
|
@ -290,10 +291,26 @@ class _GeoMapState extends State<GeoMap> {
|
|||
}
|
||||
}
|
||||
if (bounds == null) {
|
||||
// fit map to located items
|
||||
final initialCenter = widget.initialCenter;
|
||||
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(
|
||||
points: points.isNotEmpty ? points : {Constants.wonders[Random().nextInt(Constants.wonders.length)]},
|
||||
points: {center},
|
||||
collocationZoom: settings.infoMapZoom,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (settings.infoMapStyle.isHeavy) {
|
||||
if (settings.mapStyle.isHeavy) {
|
||||
_isPageAnimatingNotifier = ValueNotifier(true);
|
||||
Future.delayed(Durations.pageTransitionAnimation * timeDilation).then((_) {
|
||||
if (!mounted) return;
|
||||
|
|
|
@ -107,7 +107,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (settings.infoMapStyle.isHeavy) {
|
||||
if (settings.mapStyle.isHeavy) {
|
||||
_isPageAnimatingNotifier.value = true;
|
||||
Future.delayed(Durations.pageTransitionAnimation * timeDilation).then((_) {
|
||||
if (!mounted) return;
|
||||
|
@ -170,7 +170,7 @@ class _ContentState extends State<_Content> with SingleTickerProviderStateMixin
|
|||
return true;
|
||||
},
|
||||
child: Selector<Settings, EntryMapStyle>(
|
||||
selector: (context, s) => s.infoMapStyle,
|
||||
selector: (context, s) => s.mapStyle,
|
||||
builder: (context, mapStyle, child) {
|
||||
late Widget scroller;
|
||||
if (mapStyle.isHeavy) {
|
||||
|
|
|
@ -38,6 +38,6 @@ Future<void> configureAndLaunch() async {
|
|||
..showOverlayThumbnailPreview = true
|
||||
..imageBackground = EntryBackground.checkered
|
||||
// info
|
||||
..infoMapStyle = EntryMapStyle.googleNormal;
|
||||
..mapStyle = EntryMapStyle.googleNormal;
|
||||
app.main();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue