mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-02-12 16:52:51 +00:00
Moving the right direction I think
This commit is contained in:
@@ -356,6 +356,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
||||
sheetHeight: activeSheetHeight,
|
||||
selectedNodeId: _selectedNodeId,
|
||||
onNodeTap: openNodeTagSheet,
|
||||
onSearchPressed: _onNavigationButtonPressed,
|
||||
onUserGesture: () {
|
||||
if (appState.followMeMode != FollowMeMode.off) {
|
||||
appState.setFollowMeMode(FollowMeMode.off);
|
||||
@@ -438,16 +439,6 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Search button as floating map control
|
||||
Positioned(
|
||||
bottom: 200, // Position above other controls
|
||||
right: 16,
|
||||
child: FloatingActionButton(
|
||||
onPressed: _onNavigationButtonPressed,
|
||||
tooltip: appState.hasActiveRoute ? 'Route Overview' : 'Search Location',
|
||||
child: Icon(appState.hasActiveRoute ? Icons.route : Icons.search),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -109,7 +109,17 @@ class NavigationState extends ChangeNotifier {
|
||||
_provisionalPinLocation = null;
|
||||
_provisionalPinAddress = null;
|
||||
_clearSearchResults();
|
||||
debugPrint('[NavigationState] Cancelled search mode');
|
||||
|
||||
// Also clear any partial route data
|
||||
if (_routeStart != null && _routeEnd == null) {
|
||||
_routeStart = null;
|
||||
_routeStartAddress = null;
|
||||
} else if (_routeEnd != null && _routeStart == null) {
|
||||
_routeEnd = null;
|
||||
_routeEndAddress = null;
|
||||
}
|
||||
|
||||
debugPrint('[NavigationState] Cancelled search mode - cleaned up provisional pin');
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -137,15 +147,32 @@ class NavigationState extends ChangeNotifier {
|
||||
|
||||
/// Start route setup (user clicked "route to" or "route from")
|
||||
void startRouteSetup({required bool settingStart}) {
|
||||
if (_mode != AppNavigationMode.search || _provisionalPinLocation == null) return;
|
||||
debugPrint('[NavigationState] startRouteSetup called - settingStart: $settingStart, mode: $_mode, location: $_provisionalPinLocation');
|
||||
|
||||
if (_mode != AppNavigationMode.search || _provisionalPinLocation == null) {
|
||||
debugPrint('[NavigationState] startRouteSetup - early return');
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear any previous route data
|
||||
_routeStart = null;
|
||||
_routeEnd = null;
|
||||
_routeStartAddress = null;
|
||||
_routeEndAddress = null;
|
||||
_routePath = null;
|
||||
_routeDistance = null;
|
||||
|
||||
_settingRouteStart = settingStart;
|
||||
if (settingStart) {
|
||||
// "Route From" - this location is the START, we need to pick END
|
||||
_routeStart = _provisionalPinLocation;
|
||||
_routeStartAddress = _provisionalPinAddress;
|
||||
debugPrint('[NavigationState] Set route start: $_routeStart');
|
||||
} else {
|
||||
// "Route To" - this location is the END, we need to pick START
|
||||
_routeEnd = _provisionalPinLocation;
|
||||
_routeEndAddress = _provisionalPinAddress;
|
||||
debugPrint('[NavigationState] Set route end: $_routeEnd');
|
||||
}
|
||||
|
||||
_mode = AppNavigationMode.routeSetup;
|
||||
@@ -156,16 +183,25 @@ class NavigationState extends ChangeNotifier {
|
||||
|
||||
/// Lock in second route location
|
||||
void selectRouteLocation() {
|
||||
if (_mode != AppNavigationMode.routeSetup || _provisionalPinLocation == null) return;
|
||||
debugPrint('[NavigationState] selectRouteLocation called - mode: $_mode, provisional: $_provisionalPinLocation');
|
||||
|
||||
if (_mode != AppNavigationMode.routeSetup || _provisionalPinLocation == null) {
|
||||
debugPrint('[NavigationState] selectRouteLocation - early return (mode: $_mode, location: $_provisionalPinLocation)');
|
||||
return;
|
||||
}
|
||||
|
||||
if (_settingRouteStart) {
|
||||
_routeStart = _provisionalPinLocation;
|
||||
_routeStartAddress = _provisionalPinAddress;
|
||||
debugPrint('[NavigationState] Set route start: $_routeStart');
|
||||
} else {
|
||||
_routeEnd = _provisionalPinLocation;
|
||||
_routeEndAddress = _provisionalPinAddress;
|
||||
debugPrint('[NavigationState] Set route end: $_routeEnd');
|
||||
}
|
||||
|
||||
debugPrint('[NavigationState] Route points - start: $_routeStart, end: $_routeEnd');
|
||||
|
||||
// Start route calculation
|
||||
_calculateRoute();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../app_state.dart';
|
||||
import '../../dev_config.dart';
|
||||
@@ -13,6 +14,7 @@ class MapOverlays extends StatelessWidget {
|
||||
final AddNodeSession? session;
|
||||
final EditNodeSession? editSession;
|
||||
final String? attribution; // Attribution for current tile provider
|
||||
final VoidCallback? onSearchPressed; // Callback for search button
|
||||
|
||||
const MapOverlays({
|
||||
super.key,
|
||||
@@ -21,6 +23,7 @@ class MapOverlays extends StatelessWidget {
|
||||
this.session,
|
||||
this.editSession,
|
||||
this.attribution,
|
||||
this.onSearchPressed,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -113,45 +116,58 @@ class MapOverlays extends StatelessWidget {
|
||||
Positioned(
|
||||
bottom: bottomPositionFromButtonBar(kZoomControlsSpacingAboveButtonBar, MediaQuery.of(context).padding.bottom),
|
||||
right: 16,
|
||||
child: Column(
|
||||
children: [
|
||||
// Layer selector button
|
||||
const LayerSelectorButton(),
|
||||
const SizedBox(height: 8),
|
||||
// Zoom in button
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: "zoom_in",
|
||||
onPressed: () {
|
||||
try {
|
||||
final zoom = mapController.camera.zoom;
|
||||
mapController.move(mapController.camera.center, zoom + 1);
|
||||
} catch (_) {
|
||||
// Map controller not ready yet
|
||||
}
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
// Zoom out button
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: "zoom_out",
|
||||
onPressed: () {
|
||||
try {
|
||||
final zoom = mapController.camera.zoom;
|
||||
mapController.move(mapController.camera.center, zoom - 1);
|
||||
} catch (_) {
|
||||
// Map controller not ready yet
|
||||
}
|
||||
},
|
||||
child: const Icon(Icons.remove),
|
||||
),
|
||||
],
|
||||
child: Consumer<AppState>(
|
||||
builder: (context, appState, child) {
|
||||
return Column(
|
||||
children: [
|
||||
// Search/Route button (top of controls)
|
||||
if (onSearchPressed != null)
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: "search_nav",
|
||||
onPressed: onSearchPressed,
|
||||
tooltip: appState.hasActiveRoute ? 'Route Overview' : 'Search Location',
|
||||
child: Icon(appState.hasActiveRoute ? Icons.route : Icons.search),
|
||||
),
|
||||
if (onSearchPressed != null) const SizedBox(height: 8),
|
||||
|
||||
// Layer selector button
|
||||
const LayerSelectorButton(),
|
||||
const SizedBox(height: 8),
|
||||
// Zoom in button
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: "zoom_in",
|
||||
onPressed: () {
|
||||
try {
|
||||
final zoom = mapController.camera.zoom;
|
||||
mapController.move(mapController.camera.center, zoom + 1);
|
||||
} catch (_) {
|
||||
// Map controller not ready yet
|
||||
}
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
// Zoom out button
|
||||
FloatingActionButton(
|
||||
mini: true,
|
||||
heroTag: "zoom_out",
|
||||
onPressed: () {
|
||||
try {
|
||||
final zoom = mapController.camera.zoom;
|
||||
mapController.move(mapController.camera.center, zoom - 1);
|
||||
} catch (_) {
|
||||
// Map controller not ready yet
|
||||
}
|
||||
},
|
||||
child: const Icon(Icons.remove),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ class MapView extends StatefulWidget {
|
||||
this.sheetHeight = 0.0,
|
||||
this.selectedNodeId,
|
||||
this.onNodeTap,
|
||||
this.onSearchPressed,
|
||||
});
|
||||
|
||||
final FollowMeMode followMeMode;
|
||||
@@ -45,6 +46,7 @@ class MapView extends StatefulWidget {
|
||||
final double sheetHeight;
|
||||
final int? selectedNodeId;
|
||||
final void Function(OsmNode)? onNodeTap;
|
||||
final VoidCallback? onSearchPressed;
|
||||
|
||||
@override
|
||||
State<MapView> createState() => MapViewState();
|
||||
@@ -497,6 +499,7 @@ class MapViewState extends State<MapView> {
|
||||
session: session,
|
||||
editSession: editSession,
|
||||
attribution: appState.selectedTileType?.attribution,
|
||||
onSearchPressed: widget.onSearchPressed,
|
||||
),
|
||||
|
||||
// Network status indicator (top-left) - conditionally shown
|
||||
|
||||
@@ -180,22 +180,25 @@ class _LocationSearchBarState extends State<LocationSearchBar> {
|
||||
focusNode: _focusNode,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search places or coordinates...',
|
||||
prefixIcon: const Icon(Icons.search),
|
||||
suffixIcon: Row(
|
||||
prefixIcon: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (_controller.text.isNotEmpty)
|
||||
IconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
onPressed: _onClear,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: _onCancel,
|
||||
tooltip: 'Cancel search',
|
||||
),
|
||||
const Icon(Icons.search),
|
||||
],
|
||||
),
|
||||
prefixIconConstraints: const BoxConstraints(minWidth: 80),
|
||||
suffixIcon: _controller.text.isNotEmpty
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
onPressed: _onClear,
|
||||
tooltip: 'Clear text',
|
||||
)
|
||||
: null,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide.none,
|
||||
|
||||
Reference in New Issue
Block a user