Skip to content

Commit 7d5b675

Browse files
committed
feat(SF2.0/UpcomingDepartures): Fancy labels for Commuter Rail predictions
1 parent 6eb2852 commit 7d5b675

File tree

4 files changed

+583
-15
lines changed

4 files changed

+583
-15
lines changed

lib/dotcom/schedule_finder/upcoming_departures.ex

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ defmodule Dotcom.ScheduleFinder.UpcomingDepartures do
1515

1616
@predictions_repo Application.compile_env!(:dotcom, :repo_modules)[:predictions]
1717
@schedules_repo Application.compile_env!(:dotcom, :repo_modules)[:schedules]
18+
@stops_repo Application.compile_env!(:dotcom, :repo_modules)[:stops]
1819

1920
defmodule UpcomingDeparture do
2021
@moduledoc """
@@ -23,9 +24,13 @@ defmodule Dotcom.ScheduleFinder.UpcomingDepartures do
2324

2425
defstruct [
2526
:arrival_status,
27+
:arrival_substatus,
2628
:headsign,
29+
:platform_name,
30+
:status,
2731
:trip_details,
28-
:trip_id
32+
:trip_id,
33+
:trip_name
2934
]
3035

3136
defmodule TripDetails do
@@ -136,15 +141,35 @@ defmodule Dotcom.ScheduleFinder.UpcomingDepartures do
136141
route_type: route_type,
137142
now: now
138143
}),
144+
arrival_substatus:
145+
arrival_substatus(%{
146+
predicted_schedule: predicted_schedule,
147+
route_type: route_type
148+
}),
139149
headsign: trip.headsign,
150+
platform_name: platform_name(predicted_schedule),
151+
status: predicted_schedule |> PredictedSchedule.status(),
140152
trip_details: trip_details,
141-
trip_id: trip.id
153+
trip_id: trip.id,
154+
trip_name: if(route_type == :commuter_rail, do: trip.name, else: nil)
142155
}
143156
end
144157

145158
defp seconds_between(nil, _now), do: nil
146159
defp seconds_between(prediction_time, now), do: DateTime.diff(prediction_time, now, :second)
147160

161+
defp platform_name(predicted_schedule) do
162+
predicted_schedule
163+
|> PredictedSchedule.platform_stop_id()
164+
|> @stops_repo.get()
165+
|> Kernel.then(& &1.platform_name)
166+
|> case do
167+
nil -> nil
168+
"Commuter Rail" -> nil
169+
name -> name |> String.trim("Commuter Rail - ")
170+
end
171+
end
172+
148173
defp trip_details(predictions_by_trip_id, trip_id, stop_id) do
149174
other_stops = other_stops(predictions_by_trip_id |> Map.get(trip_id))
150175

@@ -191,6 +216,14 @@ defmodule Dotcom.ScheduleFinder.UpcomingDepartures do
191216
}),
192217
do: :hidden
193218

219+
defp arrival_status(%{
220+
predicted_schedule: %PredictedSchedule{prediction: prediction},
221+
route_type: :commuter_rail
222+
})
223+
when prediction != nil do
224+
{:time, prediction.departure_time}
225+
end
226+
194227
defp arrival_status(%{
195228
predicted_schedule: %PredictedSchedule{prediction: prediction},
196229
route_type: route_type,
@@ -209,7 +242,15 @@ defmodule Dotcom.ScheduleFinder.UpcomingDepartures do
209242

210243
defp arrival_status(%{
211244
predicted_schedule: %PredictedSchedule{schedule: schedule},
212-
route_type: _route_type
245+
route_type: :commuter_rail
246+
})
247+
when schedule != nil do
248+
{:scheduled, schedule.departure_time}
249+
end
250+
251+
defp arrival_status(%{
252+
predicted_schedule: %PredictedSchedule{schedule: schedule},
253+
213254
})
214255
when schedule != nil do
215256
{:scheduled, prediction_time(schedule)}
@@ -249,4 +290,34 @@ defmodule Dotcom.ScheduleFinder.UpcomingDepartures do
249290
do: :approaching
250291

251292
defp realtime_arrival_status(%{arrival_seconds: seconds}), do: {:arrival_seconds, seconds}
293+
294+
defp arrival_substatus(%{route_type: route_type}) when route_type != :commuter_rail, do: nil
295+
296+
defp arrival_substatus(%{
297+
predicted_schedule: %PredictedSchedule{prediction: nil}
298+
}),
299+
do: :scheduled
300+
301+
defp arrival_substatus(%{
302+
predicted_schedule: %PredictedSchedule{prediction: %Prediction{status: status}}
303+
}) when status != nil,
304+
do: {:status, status |> String.split(" ") |> Enum.map(&String.capitalize/1) |> Enum.join(" ")}
305+
306+
defp arrival_substatus(%{
307+
predicted_schedule: %PredictedSchedule{schedule: nil}
308+
}),
309+
do: :on_time
310+
311+
defp arrival_substatus(%{
312+
predicted_schedule: %PredictedSchedule{schedule: schedule, prediction: prediction}
313+
}) do
314+
scheduled_time = schedule.departure_time
315+
predicted_time = prediction.departure_time
316+
317+
if DateTime.diff(scheduled_time, predicted_time, :second) |> abs() < 60 do
318+
:on_time
319+
else
320+
{:scheduled_at, scheduled_time}
321+
end
322+
end
252323
end

lib/dotcom_web/live/schedule_finder_live.ex

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -477,11 +477,22 @@ defmodule DotcomWeb.ScheduleFinderLive do
477477
summary_class="flex items-center border-gray-lightest py-3 px-2 gap-2 group-open:bg-gray-lightest hover:bg-brand-primary-lightest group-open:hover:bg-brand-primary-lightest"
478478
>
479479
<:heading>
480-
<div class="w-full flex gap-2">
481-
<RouteComponents.route_icon size="small" route={@route} />
482-
<div>{upcoming_departure.headsign}</div>
483-
<div class="ml-auto">
480+
<div class="w-full flex items-center">
481+
<div class="grid grid-cols-[max-content_max-content] gap-x-1.5 gap-y-1 items-center">
482+
<RouteComponents.route_icon size="small" route={@route} />
483+
<div>{upcoming_departure.headsign}</div>
484+
485+
<div />
486+
<div :if={upcoming_departure.trip_name} class="leading-none text-[0.75rem]">
487+
Train {upcoming_departure.trip_name}
488+
<span>
489+
&bull; {upcoming_departure.platform_name || "Track TBA"}
490+
</span>
491+
</div>
492+
</div>
493+
<div class="ml-auto flex flex-col items-end">
484494
<.prediction_time_display arrival_status={upcoming_departure.arrival_status} />
495+
<.prediction_substatus_display arrival_substatus={upcoming_departure.arrival_substatus} />
485496
</div>
486497
</div>
487498
</:heading>
@@ -583,11 +594,42 @@ defmodule DotcomWeb.ScheduleFinderLive do
583594
defp realtime_text({:departure_seconds, seconds}),
584595
do: seconds_to_localized_minutes(seconds)
585596

597+
defp realtime_text({:time, time}),
598+
do: format!(time, :hour_12_minutes)
599+
586600
defp realtime_text(:approaching), do: ~t"Approaching"
587601
defp realtime_text(:arriving), do: ~t"Arriving"
588602
defp realtime_text(:boarding), do: ~t"Boarding"
589603
defp realtime_text(:now), do: ~t"Now"
590604

605+
defp prediction_substatus_display(%{arrival_substatus: nil} = assigns), do: ~H""
606+
607+
defp prediction_substatus_display(%{arrival_substatus: {:scheduled_at, time}} = assigns) do
608+
assigns = assigns |> assign(:time, time)
609+
610+
~H"""
611+
<span class="text-[0.75rem] line-through">{format!(@time, :hour_12_minutes)}</span>
612+
"""
613+
end
614+
615+
defp prediction_substatus_display(%{arrival_substatus: {:status, status}} = assigns) do
616+
assigns = assigns |> assign(:status, status)
617+
618+
~H"""
619+
<span class="text-[0.75rem]">{@status}</span>
620+
"""
621+
end
622+
623+
defp prediction_substatus_display(assigns) do
624+
~H"""
625+
<span class="text-[0.75rem]">{substatus_text(@arrival_substatus)}</span>
626+
"""
627+
end
628+
629+
defp substatus_text(:on_time), do: ~t"On Time"
630+
defp substatus_text(:scheduled), do: ~t"Scheduled"
631+
defp substatus_text(text), do: text
632+
591633
defp remaining_service(%{route_type: route_type} = assigns) when route_type in [0, 1] do
592634
~H"""
593635
<div class="flex justify-center bg-gray-lightest w-full py-3">

lib/predicted_schedule.ex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,20 @@ defmodule PredictedSchedule do
158158
def stop(%PredictedSchedule{schedule: %Schedule{stop: stop}}), do: stop
159159
def stop(%PredictedSchedule{prediction: %Prediction{stop: stop}}), do: stop
160160

161+
@doc """
162+
Returns the stop for a given PredictedSchedule
163+
"""
164+
def platform_stop_id(%PredictedSchedule{
165+
prediction: %Prediction{platform_stop_id: platform_stop_id}
166+
}),
167+
do: platform_stop_id
168+
169+
@spec platform_stop_id(PredictedSchedule.t()) :: Stops.Stop.id_t()
170+
def platform_stop_id(%PredictedSchedule{
171+
schedule: %Schedule{platform_stop_id: platform_stop_id}
172+
}),
173+
do: platform_stop_id
174+
161175
@doc """
162176
Returns the route for a given PredictedSchedule.
163177
"""

0 commit comments

Comments
 (0)