Fix node edge blinking, prevent nav+edit conflicts, smarter follow-me w/rt nav

This commit is contained in:
stopflock
2025-12-05 15:27:01 -06:00
parent 6cda350f22
commit 24214e94f9
10 changed files with 281 additions and 21 deletions
+22 -4
View File
@@ -24,6 +24,21 @@ class MapDataManager {
}
}
/// Expand bounds by the given multiplier, maintaining center point.
/// Used to expand rendering bounds to prevent nodes blinking at screen edges.
LatLngBounds _expandBounds(LatLngBounds bounds, double multiplier) {
final centerLat = (bounds.north + bounds.south) / 2;
final centerLng = (bounds.east + bounds.west) / 2;
final latSpan = (bounds.north - bounds.south) * multiplier / 2;
final lngSpan = (bounds.east - bounds.west) * multiplier / 2;
return LatLngBounds(
LatLng(centerLat - latSpan, centerLng - lngSpan),
LatLng(centerLat + latSpan, centerLng + lngSpan),
);
}
/// Get nodes to render based on current map state
/// Returns a MapDataResult containing all relevant node data and limit state
MapDataResult getNodesForRendering({
@@ -39,10 +54,13 @@ class MapDataManager {
bool isLimitActive = false;
if (currentZoom >= minZoom) {
// Above minimum zoom - get cached nodes directly (no Provider needed)
allNodes = (mapBounds != null)
? NodeProviderWithCache.instance.getCachedNodesForBounds(mapBounds)
: <OsmNode>[];
// Above minimum zoom - get cached nodes with expanded bounds to prevent edge blinking
if (mapBounds != null) {
final expandedBounds = _expandBounds(mapBounds, kNodeRenderingBoundsExpansion);
allNodes = NodeProviderWithCache.instance.getCachedNodesForBounds(expandedBounds);
} else {
allNodes = <OsmNode>[];
}
// Filter out invalid coordinates before applying limit
final validNodes = allNodes.where((node) {
+12 -4
View File
@@ -62,16 +62,22 @@ class MarkerLayerBuilder {
return LayoutBuilder(
builder: (context, constraints) {
// Determine if we should dim node markers (when suspected location is selected)
final shouldDimNodes = appState.selectedSuspectedLocation != null;
// Determine if nodes should be dimmed and/or disabled
final shouldDimNodes = appState.selectedSuspectedLocation != null ||
appState.isInSearchMode ||
appState.showingOverview;
// Disable node interactions when navigation is in conflicting state
final shouldDisableNodeTaps = appState.isInSearchMode || appState.showingOverview;
final markers = NodeMarkersBuilder.buildNodeMarkers(
nodes: nodesToRender,
mapController: mapController.mapController,
userLocation: userLocation,
selectedNodeId: selectedNodeId,
onNodeTap: onNodeTap,
onNodeTap: onNodeTap, // Keep the original callback
shouldDim: shouldDimNodes,
enabled: !shouldDisableNodeTaps, // Use enabled parameter instead
);
// Build suspected location markers (respect same zoom and count limits as nodes)
@@ -101,7 +107,9 @@ class MarkerLayerBuilder {
locations: filteredSuspectedLocations,
mapController: mapController.mapController,
selectedLocationId: appState.selectedSuspectedLocation?.ticketNo,
onLocationTap: onSuspectedLocationTap,
onLocationTap: onSuspectedLocationTap, // Keep the original callback
shouldDimAll: shouldDisableNodeTaps,
enabled: !shouldDisableNodeTaps, // Use enabled parameter instead
),
);
}
+8
View File
@@ -13,11 +13,13 @@ class NodeMapMarker extends StatefulWidget {
final OsmNode node;
final MapController mapController;
final void Function(OsmNode)? onNodeTap;
final bool enabled;
const NodeMapMarker({
required this.node,
required this.mapController,
this.onNodeTap,
this.enabled = true,
Key? key,
}) : super(key: key);
@@ -31,6 +33,8 @@ class _NodeMapMarkerState extends State<NodeMapMarker> {
static const Duration tapTimeout = kMarkerTapTimeout;
void _onTap() {
if (!widget.enabled) return; // Don't respond to taps when disabled
_tapTimer = Timer(tapTimeout, () {
// Don't center immediately - let the sheet opening handle the coordinated animation
@@ -48,6 +52,8 @@ class _NodeMapMarkerState extends State<NodeMapMarker> {
}
void _onDoubleTap() {
if (!widget.enabled) return; // Don't respond to double taps when disabled
_tapTimer?.cancel();
widget.mapController.move(widget.node.coord, widget.mapController.camera.zoom + kNodeDoubleTapZoomDelta);
}
@@ -96,6 +102,7 @@ class NodeMarkersBuilder {
int? selectedNodeId,
void Function(OsmNode)? onNodeTap,
bool shouldDim = false,
bool enabled = true,
}) {
final markers = <Marker>[
// Node markers
@@ -116,6 +123,7 @@ class NodeMarkersBuilder {
node: n,
mapController: mapController,
onNodeTap: onNodeTap,
enabled: enabled,
),
),
);
@@ -13,11 +13,13 @@ class SuspectedLocationMapMarker extends StatefulWidget {
final SuspectedLocation location;
final MapController mapController;
final void Function(SuspectedLocation)? onLocationTap;
final bool enabled;
const SuspectedLocationMapMarker({
required this.location,
required this.mapController,
this.onLocationTap,
this.enabled = true,
Key? key,
}) : super(key: key);
@@ -31,6 +33,8 @@ class _SuspectedLocationMapMarkerState extends State<SuspectedLocationMapMarker>
static const Duration tapTimeout = kMarkerTapTimeout;
void _onTap() {
if (!widget.enabled) return; // Don't respond to taps when disabled
_tapTimer = Timer(tapTimeout, () {
// Use callback if provided, otherwise fallback to direct modal
if (widget.onLocationTap != null) {
@@ -46,6 +50,8 @@ class _SuspectedLocationMapMarkerState extends State<SuspectedLocationMapMarker>
}
void _onDoubleTap() {
if (!widget.enabled) return; // Don't respond to double taps when disabled
_tapTimer?.cancel();
widget.mapController.move(widget.location.centroid, widget.mapController.camera.zoom + kNodeDoubleTapZoomDelta);
}
@@ -73,6 +79,8 @@ class SuspectedLocationMarkersBuilder {
required MapController mapController,
String? selectedLocationId,
void Function(SuspectedLocation)? onLocationTap,
bool shouldDimAll = false,
bool enabled = true,
}) {
final markers = <Marker>[];
@@ -81,7 +89,7 @@ class SuspectedLocationMarkersBuilder {
// Check if this location should be highlighted (selected) or dimmed
final isSelected = selectedLocationId == location.ticketNo;
final shouldDim = selectedLocationId != null && !isSelected;
final shouldDim = shouldDimAll || (selectedLocationId != null && !isSelected);
markers.add(
Marker(
@@ -94,6 +102,7 @@ class SuspectedLocationMarkersBuilder {
location: location,
mapController: mapController,
onLocationTap: onLocationTap,
enabled: enabled,
),
),
),