From ee69c62adc5943a1dbd154df5142c0e726bdd317 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Fri, 13 Mar 2026 16:49:10 +0100 Subject: feat(routes): add realtime estimates panel with pattern-aware styling - New GET /api/stops/estimates endpoint (nano mode: tripId, patternId, estimate, delay only) - useStopEstimates hook wiring estimates to routes-$id stop panel - Pattern-aware styling: dim schedules and estimates from other patterns - Past scheduled departures shown with strikethrough instead of hidden - Persist selected pattern in URL hash (replace navigation, no history push) - Fix planner arrivals using new estimates endpoint --- src/Enmarcha.Backend/Services/Processors/CorunaRealTimeProcessor.cs | 3 --- .../Services/Processors/CtagShuttleRealTimeProcessor.cs | 1 - src/Enmarcha.Backend/Services/Processors/FilterAndSortProcessor.cs | 4 ++-- src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs | 2 ++ src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs | 2 ++ src/Enmarcha.Backend/Services/Processors/ShapeProcessor.cs | 2 +- src/Enmarcha.Backend/Services/Processors/VigoUsageProcessor.cs | 2 +- src/Enmarcha.Backend/Services/Processors/VitrasaRealTimeProcessor.cs | 3 --- 8 files changed, 8 insertions(+), 11 deletions(-) (limited to 'src/Enmarcha.Backend/Services/Processors') diff --git a/src/Enmarcha.Backend/Services/Processors/CorunaRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/CorunaRealTimeProcessor.cs index b933bf4..797221f 100644 --- a/src/Enmarcha.Backend/Services/Processors/CorunaRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/CorunaRealTimeProcessor.cs @@ -95,7 +95,6 @@ public class CorunaRealTimeProcessor : AbstractRealTimeProcessor if (stopLocation != null) { Position? currentPosition = null; - int? stopShapeIndex = null; if (arrival.RawOtpTrip is ArrivalsAtStopResponse.Arrival otpArrival && otpArrival.Trip.Geometry?.Points != null) @@ -111,7 +110,6 @@ public class CorunaRealTimeProcessor : AbstractRealTimeProcessor var result = _shapeService.GetBusPosition(shape, stopLocation, meters); currentPosition = result.BusPosition; - stopShapeIndex = result.StopIndex; if (currentPosition != null) { @@ -168,7 +166,6 @@ public class CorunaRealTimeProcessor : AbstractRealTimeProcessor if (currentPosition != null) { arrival.CurrentPosition = currentPosition; - arrival.StopShapeIndex = stopShapeIndex; } } diff --git a/src/Enmarcha.Backend/Services/Processors/CtagShuttleRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/CtagShuttleRealTimeProcessor.cs index 316591d..8f3e6db 100644 --- a/src/Enmarcha.Backend/Services/Processors/CtagShuttleRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/CtagShuttleRealTimeProcessor.cs @@ -213,7 +213,6 @@ public class CtagShuttleRealTimeProcessor : AbstractRealTimeProcessor } activeArrival.CurrentPosition = shuttleWgs84; - activeArrival.StopShapeIndex = stopPointIndex; _logger.LogInformation( "Updated active trip {TripId}: {Minutes} min (was {Scheduled} min, delay: {Delay} min, distance: {Distance:F1}m)", diff --git a/src/Enmarcha.Backend/Services/Processors/FilterAndSortProcessor.cs b/src/Enmarcha.Backend/Services/Processors/FilterAndSortProcessor.cs index 18ba2ac..cbcda93 100644 --- a/src/Enmarcha.Backend/Services/Processors/FilterAndSortProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/FilterAndSortProcessor.cs @@ -29,8 +29,8 @@ public class FilterAndSortProcessor : IArrivalsProcessor return a.Estimate.Minutes >= -10; }).ToList(); - // 3. Limit results - var limit = context.IsReduced ? 4 : 10; + // 3. Limit results — nano requests a full set so route/via filtering in the controller doesn't starve + var limit = context.IsNano ? 100 : context.IsReduced ? 4 : 10; var limited = filtered.Take(limit).ToList(); // Update the context list in-place diff --git a/src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs index 9e620c2..d5ff58e 100644 --- a/src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs @@ -11,6 +11,8 @@ public class MarqueeProcessor : IArrivalsProcessor public Task ProcessAsync(ArrivalsContext context) { + if (context.IsNano) return Task.CompletedTask; + var feedId = context.StopId.Split(':')[0]; foreach (var arrival in context.Arrivals) diff --git a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs index 5d02066..5bdb5bb 100644 --- a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs @@ -13,6 +13,8 @@ public class NextStopsProcessor : IArrivalsProcessor public Task ProcessAsync(ArrivalsContext context) { + if (context.IsNano) return Task.CompletedTask; + var feedId = context.StopId.Split(':')[0]; foreach (var arrival in context.Arrivals) diff --git a/src/Enmarcha.Backend/Services/Processors/ShapeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/ShapeProcessor.cs index f3af3a5..76f896f 100644 --- a/src/Enmarcha.Backend/Services/Processors/ShapeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/ShapeProcessor.cs @@ -13,7 +13,7 @@ public class ShapeProcessor : IArrivalsProcessor public Task ProcessAsync(ArrivalsContext context) { - if (context.IsReduced) + if (context.IsReduced || context.IsNano) { return Task.CompletedTask; } diff --git a/src/Enmarcha.Backend/Services/Processors/VigoUsageProcessor.cs b/src/Enmarcha.Backend/Services/Processors/VigoUsageProcessor.cs index 487d55a..52218d9 100644 --- a/src/Enmarcha.Backend/Services/Processors/VigoUsageProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/VigoUsageProcessor.cs @@ -25,7 +25,7 @@ public class VigoUsageProcessor : IArrivalsProcessor public async Task ProcessAsync(ArrivalsContext context) { - if (!context.StopId.StartsWith("vitrasa:") || context.IsReduced) return; + if (!context.StopId.StartsWith("vitrasa:") || context.IsReduced || context.IsNano) return; var normalizedCode = _feedService.NormalizeStopCode("vitrasa", context.StopCode); diff --git a/src/Enmarcha.Backend/Services/Processors/VitrasaRealTimeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/VitrasaRealTimeProcessor.cs index e374f24..43152fd 100644 --- a/src/Enmarcha.Backend/Services/Processors/VitrasaRealTimeProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/VitrasaRealTimeProcessor.cs @@ -160,7 +160,6 @@ public class VitrasaRealTimeProcessor : AbstractRealTimeProcessor if (stopLocation != null) { Position? currentPosition = null; - int? stopShapeIndex = null; if (arrival.RawOtpTrip is ArrivalsAtStopResponse.Arrival otpArrival && otpArrival.Trip.Geometry?.Points != null) @@ -176,7 +175,6 @@ public class VitrasaRealTimeProcessor : AbstractRealTimeProcessor var result = _shapeService.GetBusPosition(shape, stopLocation, meters); currentPosition = result.BusPosition; - stopShapeIndex = result.StopIndex; // Populate Shape GeoJSON if (!context.IsReduced && currentPosition != null) @@ -228,7 +226,6 @@ public class VitrasaRealTimeProcessor : AbstractRealTimeProcessor if (currentPosition != null) { arrival.CurrentPosition = currentPosition; - arrival.StopShapeIndex = stopShapeIndex; } } -- cgit v1.3