diff --git a/lib/screens/channel_message_path_screen.dart b/lib/screens/channel_message_path_screen.dart index d2f8d812..0092f225 100644 --- a/lib/screens/channel_message_path_screen.dart +++ b/lib/screens/channel_message_path_screen.dart @@ -302,10 +302,12 @@ class _ChannelMessagePathMapScreenState extends State { static const double _labelZoomThreshold = 8.5; + final MapController _mapController = MapController(); Uint8List? _selectedPath; double _pathDistance = 0.0; bool _showNodeLabels = true; bool _didReceivePositionUpdate = false; + int? _focusedHopIndex; @override void initState() { @@ -336,6 +338,22 @@ class _ChannelMessagePathMapScreenState return totalDistance; } + void _focusHop(_PathHop hop) { + if (!hop.hasLocation) return; + final targetZoom = _didReceivePositionUpdate + ? max(_mapController.camera.zoom, 14.0) + : 14.0; + _mapController.move(hop.position!, targetZoom); + } + + void _onHopTapped(_PathHop hop) { + _focusHop(hop); + if (!mounted) return; + setState(() { + _focusedHopIndex = hop.index; + }); + } + @override Widget build(BuildContext context) { return Consumer( @@ -419,6 +437,7 @@ class _ChannelMessagePathMapScreenState children: [ FlutterMap( key: mapKey, + mapController: _mapController, options: MapOptions( initialCenter: initialCenter, initialZoom: initialZoom, @@ -470,6 +489,7 @@ class _ChannelMessagePathMapScreenState ) { setState(() { _selectedPath = observedPaths[index].pathBytes; + _focusedHopIndex = null; }); }), if (points.isEmpty) @@ -725,8 +745,17 @@ class _ChannelMessagePathMapScreenState separatorBuilder: (_, _) => const Divider(height: 1), itemBuilder: (context, index) { final hop = hops[index]; + final isFocused = _focusedHopIndex == hop.index; return ListTile( dense: true, + enabled: hop.hasLocation, + selected: isFocused, + selectedTileColor: Theme.of( + context, + ).colorScheme.primary.withValues(alpha: 0.12), + onTap: hop.hasLocation + ? () => _onHopTapped(hop) + : null, leading: CircleAvatar( radius: 14, child: Text( diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index d2ea57e9..4084d9b8 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import flutter_blue_plus_darwin import flutter_local_notifications import mobile_scanner import package_info_plus +import path_provider_foundation import share_plus import shared_preferences_foundation import sqflite_darwin @@ -20,6 +21,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))