resolved conflict and update doc

This commit is contained in:
PacoX
2026-07-09 09:08:50 +02:00
93 changed files with 5593 additions and 511 deletions
+24 -5
View File
@@ -4,6 +4,7 @@ class FeatureToggleRow extends StatefulWidget {
final String title;
final String subtitle;
final bool value;
final bool enabled;
final bool hasRefreshing;
final bool isRefreshing;
final ValueChanged<bool>? onChanged;
@@ -15,6 +16,7 @@ class FeatureToggleRow extends StatefulWidget {
required this.title,
required this.subtitle,
required this.value,
this.enabled = true,
this.hasRefreshing = false,
this.isRefreshing = false,
this.onChanged,
@@ -31,6 +33,13 @@ class _FeatureToggleRow extends State<FeatureToggleRow> {
Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
final textTheme = Theme.of(context).textTheme;
final isEnabled = widget.enabled;
final titleColor = isEnabled
? scheme.onSurface
: scheme.onSurfaceVariant.withValues(alpha: 0.7);
final subtitleColor = isEnabled
? scheme.onSurfaceVariant
: scheme.onSurfaceVariant.withValues(alpha: 0.55);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
@@ -44,14 +53,13 @@ class _FeatureToggleRow extends State<FeatureToggleRow> {
widget.title,
style: textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w600,
color: titleColor,
),
),
const SizedBox(height: 2),
Text(
widget.subtitle,
style: textTheme.bodySmall?.copyWith(
color: scheme.onSurfaceVariant,
),
style: textTheme.bodySmall?.copyWith(color: subtitleColor),
),
],
),
@@ -60,7 +68,18 @@ class _FeatureToggleRow extends State<FeatureToggleRow> {
Row(
mainAxisSize: MainAxisSize.min,
children: [
Switch(value: widget.value, onChanged: widget.onChanged),
Switch(
value: widget.value,
onChanged: isEnabled ? widget.onChanged : null,
thumbColor: !isEnabled
? WidgetStatePropertyAll<Color?>(scheme.onSurfaceVariant)
: null,
trackColor: !isEnabled
? WidgetStatePropertyAll<Color?>(
scheme.onSurfaceVariant.withValues(alpha: 0.35),
)
: null,
),
if (widget.hasRefreshing) ...[
const SizedBox(width: 4),
widget.isRefreshing
@@ -74,7 +93,7 @@ class _FeatureToggleRow extends State<FeatureToggleRow> {
)
: IconButton(
icon: const Icon(Icons.refresh, size: 18),
onPressed: widget.onRefresh,
onPressed: isEnabled ? widget.onRefresh : null,
tooltip: widget.refreshTooltip,
visualDensity: VisualDensity.compact,
padding: EdgeInsets.zero,
+10 -3
View File
@@ -26,9 +26,16 @@ class QuickSwitchBar extends StatelessWidget {
final colorScheme = theme.colorScheme;
final labelStyle = theme.textTheme.labelMedium ?? const TextStyle();
final background = highContrast ? MapPalette.panelDark : Colors.transparent;
final selectedColor = highContrast
// The selected icon sits on the primary indicator pill, so it uses
// onPrimary. The label sits below on the bar background, so it must use a
// foreground color that contrasts with the surface (not onPrimary, which
// is white-on-white in the light theme).
final selectedIconColor = highContrast
? MapPalette.textPrimary
: colorScheme.onPrimary;
final selectedLabelColor = highContrast
? MapPalette.textPrimary
: colorScheme.onSurface;
final unselectedColor = highContrast
? MapPalette.textSecondary
: colorScheme.onSurfaceVariant;
@@ -59,13 +66,13 @@ class QuickSwitchBar extends StatelessWidget {
final isSelected = states.contains(WidgetState.selected);
return labelStyle.copyWith(
fontWeight: isSelected ? FontWeight.w700 : FontWeight.w500,
color: isSelected ? selectedColor : unselectedColor,
color: isSelected ? selectedLabelColor : unselectedColor,
);
}),
iconTheme: WidgetStateProperty.resolveWith((states) {
final isSelected = states.contains(WidgetState.selected);
return IconThemeData(
color: isSelected ? selectedColor : unselectedColor,
color: isSelected ? selectedIconColor : unselectedColor,
);
}),
),
+1 -2
View File
@@ -11,7 +11,6 @@ import '../models/app_settings.dart';
import '../models/contact.dart';
import '../services/app_settings_service.dart';
import '../services/map_tile_cache_service.dart';
import 'themed_map_tile_layer.dart';
class TelemetryLocationMap extends StatefulWidget {
final double latitude;
@@ -115,7 +114,7 @@ class _TelemetryLocationMapState extends State<TelemetryLocationMap> {
),
),
children: [
ThemedMapTileLayer(tileCache: tileCache),
tileCache.buildTileLayer(context),
MarkerLayer(
markers: [
...contacts.map(_buildContactMarker),
-60
View File
@@ -1,60 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import '../services/map_tile_cache_service.dart';
/// Shared cached map tiles with an automatic dark-mode treatment.
///
/// The dark style transforms the existing OpenStreetMap raster tiles, so light
/// and dark maps share the same offline cache and network requests.
class ThemedMapTileLayer extends StatelessWidget {
final MapTileCacheService tileCache;
final double opacity;
const ThemedMapTileLayer({
super.key,
required this.tileCache,
this.opacity = 1,
});
static const ColorFilter _darkMapFilter = ColorFilter.matrix([
-0.0850,
-0.2861,
-0.0289,
0,
120,
-0.0957,
-0.3218,
-0.0325,
0,
140,
-0.1169,
-0.3934,
-0.0397,
0,
170,
0,
0,
0,
1,
0,
]);
@override
Widget build(BuildContext context) {
Widget layer = TileLayer(
urlTemplate: kMapTileUrlTemplate,
tileProvider: tileCache.tileProvider,
userAgentPackageName: MapTileCacheService.userAgentPackageName,
maxZoom: 19,
);
if (Theme.of(context).brightness == Brightness.dark) {
layer = ColorFiltered(colorFilter: _darkMapFilter, child: layer);
}
if (opacity < 1) {
layer = Opacity(opacity: opacity, child: layer);
}
return layer;
}
}
+5 -4
View File
@@ -11,18 +11,19 @@ class UnreadBadge extends StatelessWidget {
Widget build(BuildContext context) {
final display = count > 9999 ? '9999+' : count.toString();
return Container(
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2),
constraints: const BoxConstraints(minWidth: 20),
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
alignment: Alignment.center,
decoration: BoxDecoration(
color: MeshPalette.blue.withValues(alpha: 0.18),
color: MeshPalette.alert,
borderRadius: BorderRadius.circular(MeshRadii.pill),
border: Border.all(color: MeshPalette.blue.withValues(alpha: 0.45)),
),
child: Text(
display,
style: MeshTheme.mono(
fontSize: 11,
fontWeight: FontWeight.w700,
color: MeshPalette.blue,
color: Colors.white,
),
),
);