mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-16 05:40:46 +10:00
Merge pull request #461 from ericszimmermann/ez_alternative_maps
Alternative Maps
This commit is contained in:
+124
-90
@@ -25,7 +25,6 @@ import '../utils/battery_utils.dart';
|
||||
import '../utils/route_transitions.dart';
|
||||
import '../widgets/quick_switch_bar.dart';
|
||||
import '../widgets/sync_progress_overlay.dart';
|
||||
import '../widgets/themed_map_tile_layer.dart';
|
||||
import '../icons/los_icon.dart';
|
||||
import 'channels_screen.dart';
|
||||
import 'chat_screen.dart';
|
||||
@@ -107,6 +106,31 @@ class _MapScreenState extends State<MapScreen> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
ColorScheme get _overlayScheme => Theme.of(context).colorScheme;
|
||||
|
||||
bool get _useDarkOverlay => Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
Color get _overlayPanelColor => _useDarkOverlay
|
||||
? MapPalette.panelDark
|
||||
: _overlayScheme.surfaceContainerLow.withValues(alpha: 0.96);
|
||||
|
||||
Color get _overlayPrimaryTextColor =>
|
||||
_useDarkOverlay ? MapPalette.textPrimary : _overlayScheme.onSurface;
|
||||
|
||||
Color get _overlaySecondaryTextColor => _useDarkOverlay
|
||||
? MapPalette.textSecondary
|
||||
: _overlayScheme.onSurfaceVariant;
|
||||
|
||||
Color get _overlayMutedTextColor =>
|
||||
_useDarkOverlay ? MapPalette.textMuted : _overlayScheme.onSurfaceVariant;
|
||||
|
||||
Color get _overlayBorderColor =>
|
||||
_useDarkOverlay ? MapPalette.border : _overlayScheme.outlineVariant;
|
||||
|
||||
Color get _overlayShadowColor => _useDarkOverlay
|
||||
? MapPalette.markerShadow
|
||||
: Colors.black.withValues(alpha: 0.18);
|
||||
|
||||
_NodeAge _ageOf(Contact contact) {
|
||||
final d = DateTime.now().difference(contact.lastSeen);
|
||||
if (d.inMinutes <= 60) return _NodeAge.online;
|
||||
@@ -233,12 +257,12 @@ class _MapScreenState extends State<MapScreen> {
|
||||
bottom: 96,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
borderRadius: BorderRadius.circular(MeshRadii.md),
|
||||
border: Border.all(color: MapPalette.border),
|
||||
boxShadow: const [
|
||||
border: Border.all(color: _overlayBorderColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: MapPalette.markerShadow,
|
||||
color: _overlayShadowColor,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
@@ -250,20 +274,20 @@ class _MapScreenState extends State<MapScreen> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
icon: const Icon(Icons.add),
|
||||
visualDensity: VisualDensity.standard,
|
||||
tooltip: context.l10n.map_zoomIn,
|
||||
onPressed: () => _zoomMapBy(1),
|
||||
),
|
||||
IconButton(
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
icon: const Icon(Icons.remove),
|
||||
tooltip: context.l10n.map_zoomOut,
|
||||
onPressed: () => _zoomMapBy(-1),
|
||||
),
|
||||
IconButton(
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
icon: const Icon(Icons.crop_free),
|
||||
tooltip: context.l10n.map_centerMap,
|
||||
onPressed: () => _mapController.move(center, zoom),
|
||||
@@ -328,6 +352,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
final settingsService = context.read<AppSettingsService>();
|
||||
final pathHistory = context.read<PathHistoryService>();
|
||||
final tileCache = context.read<MapTileCacheService>();
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
final isDesktop = _isDesktopPlatform(defaultTargetPlatform);
|
||||
final allContacts = connector.allContacts;
|
||||
|
||||
@@ -579,8 +604,8 @@ class _MapScreenState extends State<MapScreen> {
|
||||
canPop: allowBack,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: MapPalette.panelDark,
|
||||
foregroundColor: MapPalette.textPrimary,
|
||||
backgroundColor: scheme.surface,
|
||||
foregroundColor: scheme.onSurface,
|
||||
title: AppBarTitle(context.l10n.map_title),
|
||||
centerTitle: true,
|
||||
automaticallyImplyLeading: false,
|
||||
@@ -753,7 +778,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
},
|
||||
),
|
||||
children: [
|
||||
ThemedMapTileLayer(tileCache: tileCache),
|
||||
tileCache.buildTileLayer(context),
|
||||
if (_polylines.isNotEmpty && _isBuildingPathTrace)
|
||||
PolylineLayer(polylines: _polylines),
|
||||
if (sharedMarkerPolylines.isNotEmpty)
|
||||
@@ -906,7 +931,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
_handleQuickSwitch(index, context),
|
||||
contactsUnreadCount: connector.getTotalContactsUnreadCount(),
|
||||
channelsUnreadCount: connector.getTotalChannelsUnreadCount(),
|
||||
highContrast: true,
|
||||
highContrast: _useDarkOverlay,
|
||||
),
|
||||
),
|
||||
floatingActionButton:
|
||||
@@ -1207,14 +1232,14 @@ class _MapScreenState extends State<MapScreen> {
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
border: Border.all(
|
||||
color: guess.highConfidence ? color : MapPalette.textMuted,
|
||||
color: guess.highConfidence ? color : _overlayMutedTextColor,
|
||||
width: guess.highConfidence ? 2.5 : 2,
|
||||
),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: MapPalette.markerShadow,
|
||||
color: _overlayShadowColor,
|
||||
blurRadius: 7,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -1223,7 +1248,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
Icons.not_listed_location,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
size: 19,
|
||||
),
|
||||
),
|
||||
@@ -1541,12 +1566,12 @@ class _MapScreenState extends State<MapScreen> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
borderRadius: BorderRadius.circular(MeshRadii.xs),
|
||||
border: Border.all(color: MapPalette.border),
|
||||
boxShadow: const [
|
||||
border: Border.all(color: _overlayBorderColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: MapPalette.markerShadow,
|
||||
color: _overlayShadowColor,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
@@ -1560,7 +1585,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1681,7 +1706,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: statusColor,
|
||||
border: Border.all(color: MapPalette.panelDark, width: 2),
|
||||
border: Border.all(color: _overlayPanelColor, width: 2),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: batteryLow
|
||||
@@ -1704,10 +1729,10 @@ class _MapScreenState extends State<MapScreen> {
|
||||
Expanded(
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: MapPalette.textSecondary,
|
||||
color: _overlaySecondaryTextColor,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -1765,9 +1790,9 @@ class _MapScreenState extends State<MapScreen> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Material(
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
shape: StadiumBorder(
|
||||
side: const BorderSide(color: MapPalette.border),
|
||||
side: BorderSide(color: _overlayBorderColor),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: TextField(
|
||||
@@ -1775,17 +1800,15 @@ class _MapScreenState extends State<MapScreen> {
|
||||
focusNode: _searchFocus,
|
||||
decoration: InputDecoration(
|
||||
hintText: context.l10n.map_searchHint,
|
||||
hintStyle: const TextStyle(
|
||||
color: MapPalette.textSecondary,
|
||||
),
|
||||
prefixIcon: const Icon(
|
||||
hintStyle: TextStyle(color: _overlaySecondaryTextColor),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
size: 20,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
suffixIcon: hasQuery
|
||||
? IconButton(
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
icon: const Icon(Icons.close, size: 18),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
@@ -1805,9 +1828,9 @@ class _MapScreenState extends State<MapScreen> {
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
cursorColor: MapPalette.selected,
|
||||
@@ -1819,9 +1842,9 @@ class _MapScreenState extends State<MapScreen> {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Material(
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
shape: StadiumBorder(
|
||||
side: const BorderSide(color: MapPalette.border),
|
||||
side: BorderSide(color: _overlayBorderColor),
|
||||
),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: InkWell(
|
||||
@@ -1845,17 +1868,17 @@ class _MapScreenState extends State<MapScreen> {
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
AnimatedRotation(
|
||||
turns: _statsExpanded ? 0.5 : 0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.expand_more,
|
||||
size: 16,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1954,12 +1977,12 @@ class _MapScreenState extends State<MapScreen> {
|
||||
color: selected
|
||||
? Color.alphaBlend(
|
||||
accent.withValues(alpha: 0.34),
|
||||
MapPalette.panelDark,
|
||||
_overlayPanelColor,
|
||||
)
|
||||
: MapPalette.panelDark,
|
||||
: _overlayPanelColor,
|
||||
shape: StadiumBorder(
|
||||
side: BorderSide(
|
||||
color: selected ? accent : MapPalette.border,
|
||||
color: selected ? accent : _overlayBorderColor,
|
||||
width: selected ? 1.5 : 1,
|
||||
),
|
||||
),
|
||||
@@ -1975,11 +1998,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (selected) ...[
|
||||
const Icon(
|
||||
Icons.check,
|
||||
size: 13,
|
||||
color: MapPalette.textPrimary,
|
||||
),
|
||||
Icon(Icons.check, size: 13, color: _overlayPrimaryTextColor),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
Text(
|
||||
@@ -1988,8 +2007,8 @@ class _MapScreenState extends State<MapScreen> {
|
||||
fontSize: 12.5,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: selected
|
||||
? MapPalette.textPrimary
|
||||
: MapPalette.textSecondary,
|
||||
? _overlayPrimaryTextColor
|
||||
: _overlaySecondaryTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -2019,14 +2038,14 @@ class _MapScreenState extends State<MapScreen> {
|
||||
margin: const EdgeInsets.only(top: 6),
|
||||
constraints: const BoxConstraints(maxHeight: 300),
|
||||
decoration: BoxDecoration(
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
borderRadius: BorderRadius.circular(MeshRadii.md),
|
||||
border: Border.all(color: MapPalette.border),
|
||||
boxShadow: const [
|
||||
border: Border.all(color: _overlayBorderColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: MapPalette.markerShadow,
|
||||
color: _overlayShadowColor,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -2035,8 +2054,8 @@ class _MapScreenState extends State<MapScreen> {
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
context.l10n.map_noResults,
|
||||
style: const TextStyle(
|
||||
color: MapPalette.textSecondary,
|
||||
style: TextStyle(
|
||||
color: _overlaySecondaryTextColor,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
@@ -2046,7 +2065,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
itemCount: results.length,
|
||||
separatorBuilder: (_, _) =>
|
||||
const Divider(height: 1, color: MapPalette.border),
|
||||
Divider(height: 1, color: _overlayBorderColor),
|
||||
itemBuilder: (context, index) {
|
||||
final c = results[index];
|
||||
final color = _getNodeColor(c.type);
|
||||
@@ -2067,10 +2086,10 @@ class _MapScreenState extends State<MapScreen> {
|
||||
children: [
|
||||
Text(
|
||||
c.name,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13.5,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -2078,7 +2097,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
c.publicKeyHex.substring(0, 12),
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 10.5,
|
||||
color: MapPalette.textSecondary,
|
||||
color: _overlaySecondaryTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -2088,13 +2107,13 @@ class _MapScreenState extends State<MapScreen> {
|
||||
Icon(
|
||||
Icons.chevron_right,
|
||||
size: 18,
|
||||
color: MapPalette.textSecondary,
|
||||
color: _overlaySecondaryTextColor,
|
||||
)
|
||||
else
|
||||
Text(
|
||||
context.l10n.map_noGps.toUpperCase(),
|
||||
style: MeshTheme.accentLabel(
|
||||
color: MapPalette.textMuted,
|
||||
color: _overlayMutedTextColor,
|
||||
fontSize: 8.5,
|
||||
),
|
||||
),
|
||||
@@ -2154,14 +2173,14 @@ class _MapScreenState extends State<MapScreen> {
|
||||
width: 230,
|
||||
padding: const EdgeInsets.fromLTRB(14, 12, 14, 12),
|
||||
decoration: BoxDecoration(
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
borderRadius: BorderRadius.circular(MeshRadii.md),
|
||||
border: Border.all(color: MapPalette.border),
|
||||
boxShadow: const [
|
||||
border: Border.all(color: _overlayBorderColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: MapPalette.markerShadow,
|
||||
color: _overlayShadowColor,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -2178,7 +2197,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
),
|
||||
_statRow(context.l10n.map_hidden, hiddenCount, MapPalette.offline),
|
||||
_statRow(context.l10n.map_markers, pinCount, MapPalette.shared),
|
||||
const Divider(height: 16, color: MapPalette.border),
|
||||
Divider(height: 16, color: _overlayBorderColor),
|
||||
_buildLegendItem(
|
||||
Icons.person,
|
||||
context.l10n.map_chat,
|
||||
@@ -2208,7 +2227,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
_buildLegendItem(
|
||||
Icons.not_listed_location,
|
||||
context.l10n.map_guessedLocation,
|
||||
MapPalette.textMuted,
|
||||
_overlayMutedTextColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -2229,7 +2248,10 @@ class _MapScreenState extends State<MapScreen> {
|
||||
Expanded(
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(fontSize: 12.5, color: MapPalette.textSecondary),
|
||||
style: TextStyle(
|
||||
fontSize: 12.5,
|
||||
color: _overlaySecondaryTextColor,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
@@ -2238,7 +2260,7 @@ class _MapScreenState extends State<MapScreen> {
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -2271,8 +2293,8 @@ class _MapScreenState extends State<MapScreen> {
|
||||
child: MeshCard(
|
||||
margin: EdgeInsets.zero,
|
||||
padding: const EdgeInsets.fromLTRB(14, 12, 8, 12),
|
||||
color: MapPalette.panelDark,
|
||||
borderColor: MapPalette.border,
|
||||
color: _overlayPanelColor,
|
||||
borderColor: _overlayBorderColor,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -2295,10 +2317,10 @@ class _MapScreenState extends State<MapScreen> {
|
||||
Flexible(
|
||||
child: Text(
|
||||
contact.name,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -2326,9 +2348,9 @@ class _MapScreenState extends State<MapScreen> {
|
||||
Flexible(
|
||||
child: Text(
|
||||
contact.typeLabel(context.l10n),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11.5,
|
||||
color: MapPalette.textSecondary,
|
||||
color: _overlaySecondaryTextColor,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -2340,13 +2362,13 @@ class _MapScreenState extends State<MapScreen> {
|
||||
),
|
||||
if (pos != null)
|
||||
IconButton(
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
icon: const Icon(Icons.center_focus_strong, size: 20),
|
||||
tooltip: context.l10n.map_centerOnNode,
|
||||
onPressed: () => _mapController.move(pos, max(_zoom, 15)),
|
||||
),
|
||||
IconButton(
|
||||
color: MapPalette.textPrimary,
|
||||
color: _overlayPrimaryTextColor,
|
||||
icon: const Icon(Icons.close, size: 20),
|
||||
onPressed: _clearSelection,
|
||||
),
|
||||
@@ -2407,14 +2429,17 @@ class _MapScreenState extends State<MapScreen> {
|
||||
Text(
|
||||
label.toUpperCase(),
|
||||
style: MeshTheme.accentLabel(
|
||||
color: MapPalette.textMuted,
|
||||
color: _overlayMutedTextColor,
|
||||
fontSize: 8,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 1),
|
||||
Text(
|
||||
value,
|
||||
style: MeshTheme.mono(fontSize: 11.5, color: MapPalette.textPrimary),
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 11.5,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -3555,14 +3580,14 @@ class _MapScreenState extends State<MapScreen> {
|
||||
right: 16,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: MapPalette.panelDark,
|
||||
color: _overlayPanelColor,
|
||||
borderRadius: BorderRadius.circular(MeshRadii.md),
|
||||
border: Border.all(color: MapPalette.border),
|
||||
boxShadow: const [
|
||||
border: Border.all(color: _overlayBorderColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: MapPalette.markerShadow,
|
||||
color: _overlayShadowColor,
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -3575,18 +3600,27 @@ class _MapScreenState extends State<MapScreen> {
|
||||
children: [
|
||||
Text(
|
||||
l10n.contacts_pathTrace,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: _overlayPrimaryTextColor,
|
||||
),
|
||||
),
|
||||
if (_pathTrace.isEmpty) const SizedBox(height: 8),
|
||||
if (_pathTrace.isEmpty)
|
||||
Text(l10n.map_tapToAdd, style: TextStyle(fontSize: 12)),
|
||||
Text(
|
||||
l10n.map_tapToAdd,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: _overlaySecondaryTextColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
if (_pathTrace.isNotEmpty)
|
||||
Text(
|
||||
"${l10n.path_currentPathLabel} ${formatDistance(getPathDistanceMeters(_points), isImperial: isImperial)}",
|
||||
style: MeshTheme.mono(
|
||||
fontSize: 12,
|
||||
color: MapPalette.textSecondary,
|
||||
color: _overlaySecondaryTextColor,
|
||||
),
|
||||
),
|
||||
SelectableText(
|
||||
|
||||
Reference in New Issue
Block a user