From 2dc4d82887816ec4ae7f8d5192151a08f49ab13a Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 09:52:48 -0400 Subject: [PATCH 01/10] Fixed css layout. --- assets/css/v2/elevator/normal.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/css/v2/elevator/normal.scss b/assets/css/v2/elevator/normal.scss index 7544a2c22..e0409e51d 100644 --- a/assets/css/v2/elevator/normal.scss +++ b/assets/css/v2/elevator/normal.scss @@ -7,8 +7,8 @@ .screen-normal__body { position: absolute; - top: 288px; + top: 0; left: 0; - width: 1200px; - height: 2912px; + width: 1080px; + height: 1920px; } From ef9369bd7a3e09a371e9c1e48c98b806187b67fe Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 09:53:49 -0400 Subject: [PATCH 02/10] Added new widget to layout. --- assets/src/apps/v2/elevator.tsx | 4 +-- .../v2/elevator/elevator_closures.tsx | 17 ++++++++++ .../v2/candidate_generator/elevator.ex | 12 +++---- .../v2/widget_instance/elevator_closures.ex | 31 +++++++++++++++++++ .../views/v2/audio/elevator_closures_view.ex | 7 +++++ 5 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 assets/src/components/v2/elevator/elevator_closures.tsx create mode 100644 lib/screens/v2/widget_instance/elevator_closures.ex create mode 100644 lib/screens_web/views/v2/audio/elevator_closures_view.ex diff --git a/assets/src/apps/v2/elevator.tsx b/assets/src/apps/v2/elevator.tsx index 87df1852a..79314a54a 100644 --- a/assets/src/apps/v2/elevator.tsx +++ b/assets/src/apps/v2/elevator.tsx @@ -10,15 +10,15 @@ import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import NormalScreen from "Components/v2/elevator/normal_screen"; -import Placeholder from "Components/v2/placeholder"; import EvergreenContent from "Components/v2/evergreen_content"; import ScreenPage from "Components/v2/screen_page"; import { MappingContext } from "Components/v2/widget"; import MultiScreenPage from "Components/v2/multi_screen_page"; +import ElevatorClosures from "Components/v2/elevator/elevator_closures"; const TYPE_TO_COMPONENT = { normal: NormalScreen, - placeholder: Placeholder, + elevator_closures: ElevatorClosures, evergreen_content: EvergreenContent, }; diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx new file mode 100644 index 000000000..2a68c8454 --- /dev/null +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -0,0 +1,17 @@ +import React from "react"; + +interface Props { + id: string; +} + +const ElevatorClosures: React.ComponentType = ({ id }: Props) => { + return ( +
+
+ {id} +
+
+ ); +}; + +export default ElevatorClosures; diff --git a/lib/screens/v2/candidate_generator/elevator.ex b/lib/screens/v2/candidate_generator/elevator.ex index 3e6bddfbc..0578223fc 100644 --- a/lib/screens/v2/candidate_generator/elevator.ex +++ b/lib/screens/v2/candidate_generator/elevator.ex @@ -3,7 +3,7 @@ defmodule Screens.V2.CandidateGenerator.Elevator do alias Screens.V2.CandidateGenerator alias Screens.V2.Template.Builder - alias Screens.V2.WidgetInstance.Placeholder + alias Screens.V2.WidgetInstance.ElevatorClosures @behaviour CandidateGenerator @@ -17,15 +17,13 @@ defmodule Screens.V2.CandidateGenerator.Elevator do |> Builder.build_template() end - def candidate_instances(_config) do - placeholder_instances() + def candidate_instances(config) do + elevator_closures_instances(config) end def audio_only_instances(_widgets, _config), do: [] - defp placeholder_instances do - [ - %Placeholder{color: :blue, slot_names: [:main_content]} - ] + defp elevator_closures_instances(config) do + [%ElevatorClosures{screen: config, alerts: []}] end end diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex new file mode 100644 index 000000000..353cf3db5 --- /dev/null +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -0,0 +1,31 @@ +defmodule Screens.V2.WidgetInstance.ElevatorClosures do + alias ScreensConfig.Screen + alias ScreensConfig.V2.Elevator + alias Screens.Alerts.Alert + + defstruct screen: nil, + alerts: nil + + @type t :: %__MODULE__{ + screen: Screen.t(), + alerts: list(Alert.t()) + } + + def serialize(%__MODULE__{screen: %Screen{app_params: %Elevator{elevator_id: id}}}) do + %{id: id, alerts: []} + end + + defimpl Screens.V2.WidgetInstance do + alias Screens.V2.WidgetInstance.ElevatorClosures + + def priority(_instance), do: [1] + def serialize(instance), do: ElevatorClosures.serialize(instance) + def slot_names(_instance), do: [:main_content] + def widget_type(_instance), do: :elevator_closures + def valid_candidate?(_instance), do: true + def audio_serialize(_instance), do: %{} + def audio_sort_key(_instance), do: [0] + def audio_valid_candidate?(_instance), do: false + def audio_view(_instance), do: ScreensWeb.V2.Audio.ElevatorClosuresView + end +end diff --git a/lib/screens_web/views/v2/audio/elevator_closures_view.ex b/lib/screens_web/views/v2/audio/elevator_closures_view.ex new file mode 100644 index 000000000..7bd732227 --- /dev/null +++ b/lib/screens_web/views/v2/audio/elevator_closures_view.ex @@ -0,0 +1,7 @@ +defmodule ScreensWeb.V2.Audio.ElevatorClosuresView do + use ScreensWeb, :view + + def render("_widget.ssml", _) do + ~E"" + end +end From 23252c05b9912b44a1901b6f3b0ab5544ce508f7 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 10:15:32 -0400 Subject: [PATCH 03/10] Added header. --- assets/css/elevator_v2.scss | 4 +++- assets/css/v2/elevator/elevator_closures.scss | 15 +++++++++++++++ .../v2/elevator/elevator_closures.tsx | 19 ++++++++++++++----- .../v2/candidate_generator/elevator.ex | 8 ++++---- .../v2/widget_instance/elevator_closures.ex | 10 ++++++---- 5 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 assets/css/v2/elevator/elevator_closures.scss diff --git a/assets/css/elevator_v2.scss b/assets/css/elevator_v2.scss index 23dc583b0..937785947 100644 --- a/assets/css/elevator_v2.scss +++ b/assets/css/elevator_v2.scss @@ -1,4 +1,6 @@ -@import "v2/placeholder"; +@import "https://rsms.me/inter/inter.css"; +@import "colors"; +@import "v2/elevator/elevator_closures"; @import "v2/elevator/normal"; body { diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss new file mode 100644 index 000000000..4846c2f2e --- /dev/null +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -0,0 +1,15 @@ +.elevator-closures { + font-family: Inter, sans-serif; + .header { + display: flex; + width: 100%; + height: 104px; + background-color: $cool-black-15; + color: $warm-neutral-90; + align-items: center; + justify-content: space-between; + font-size: 48px; + line-height: 62px; + padding: 0 48px; + } +} diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 2a68c8454..9f2f3ab91 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -1,15 +1,24 @@ import React from "react"; +import { formatTimeString } from "Util/util"; -interface Props { +interface HeaderProps { id: string; + time: string; } -const ElevatorClosures: React.ComponentType = ({ id }: Props) => { +const Header = ({ id, time }: HeaderProps) => { + return ( +
+ Elevator {id} + {formatTimeString(time)} +
+ ); +}; + +const ElevatorClosures: React.ComponentType = ({ id, time }: Props) => { return (
-
- {id} -
+
); }; diff --git a/lib/screens/v2/candidate_generator/elevator.ex b/lib/screens/v2/candidate_generator/elevator.ex index 0578223fc..b07262c35 100644 --- a/lib/screens/v2/candidate_generator/elevator.ex +++ b/lib/screens/v2/candidate_generator/elevator.ex @@ -17,13 +17,13 @@ defmodule Screens.V2.CandidateGenerator.Elevator do |> Builder.build_template() end - def candidate_instances(config) do - elevator_closures_instances(config) + def candidate_instances(config, now \\ DateTime.utc_now()) do + elevator_closures_instances(config, now) end def audio_only_instances(_widgets, _config), do: [] - defp elevator_closures_instances(config) do - [%ElevatorClosures{screen: config, alerts: []}] + defp elevator_closures_instances(config, now) do + [%ElevatorClosures{screen: config, alerts: [], time: now}] end end diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index 353cf3db5..a4737060e 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -4,15 +4,17 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do alias Screens.Alerts.Alert defstruct screen: nil, - alerts: nil + alerts: nil, + time: nil @type t :: %__MODULE__{ screen: Screen.t(), - alerts: list(Alert.t()) + alerts: list(Alert.t()), + time: DateTime.t() } - def serialize(%__MODULE__{screen: %Screen{app_params: %Elevator{elevator_id: id}}}) do - %{id: id, alerts: []} + def serialize(%__MODULE__{screen: %Screen{app_params: %Elevator{elevator_id: id}}, time: time}) do + %{id: id, alerts: [], time: DateTime.to_iso8601(time)} end defimpl Screens.V2.WidgetInstance do From 4bbf748dea4dfbb3f42229ac73922b714bb42c2a Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 10:42:53 -0400 Subject: [PATCH 04/10] Added an in-station summary section. --- assets/css/colors.scss | 3 ++ assets/css/v2/elevator/elevator_closures.scss | 19 +++++++++- assets/css/v2/elevator/normal.scss | 3 -- .../v2/elevator/elevator_closures.tsx | 36 ++++++++++++++++++- .../images/svgr_bundled/normal-service.svg | 11 ++++++ .../v2/widget_instance/elevator_closures.ex | 2 +- 6 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 assets/static/images/svgr_bundled/normal-service.svg diff --git a/assets/css/colors.scss b/assets/css/colors.scss index 193eab607..71753a1d3 100644 --- a/assets/css/colors.scss +++ b/assets/css/colors.scss @@ -15,3 +15,6 @@ $warm-neutral-80: #cccbc8; $warm-neutral-90: #e5e4e1; $cool-black-15: #171f26; +$cool-black-30: #2e3e4d; + +$normal-service-green: #145a06; diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 4846c2f2e..d77f699a0 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -1,8 +1,10 @@ .elevator-closures { + position: relative; font-family: Inter, sans-serif; + background-color: $warm-neutral-90; + .header { display: flex; - width: 100%; height: 104px; background-color: $cool-black-15; color: $warm-neutral-90; @@ -12,4 +14,19 @@ line-height: 62px; padding: 0 48px; } + + .in-station-summary { + display: flex; + padding: 24px 58px; + justify-content: space-between; + font-weight: 400; + font-size: 48px; + line-height: 64px; + color: $cool-black-30; + } + + hr { + height: 24px; + background-color: $cool-black-15; + } } diff --git a/assets/css/v2/elevator/normal.scss b/assets/css/v2/elevator/normal.scss index e0409e51d..646f65546 100644 --- a/assets/css/v2/elevator/normal.scss +++ b/assets/css/v2/elevator/normal.scss @@ -6,9 +6,6 @@ } .screen-normal__body { - position: absolute; - top: 0; - left: 0; width: 1080px; height: 1920px; } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 9f2f3ab91..9ad606436 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -1,5 +1,6 @@ import React from "react"; import { formatTimeString } from "Util/util"; +import NormalService from "Images/svgr_bundled/normal-service.svg"; interface HeaderProps { id: string; @@ -14,11 +15,44 @@ const Header = ({ id, time }: HeaderProps) => { ); }; +interface InStationSummaryProps { + alerts: string[]; +} + +const InStationSummary = ({ alerts }: InStationSummaryProps) => { + const summaryText = alerts.length + ? "" + : "All elevators at this station are currently working"; + + return ( + <> +
+ {summaryText} + + + +
+
+ + ); +}; + +interface Props { + id: string; + time: string; + in_station_alerts: string[]; + outside_alerts: string[]; +} -const ElevatorClosures: React.ComponentType = ({ id, time }: Props) => { +const ElevatorClosures: React.ComponentType = ({ + id, + time, + in_station_alerts: inStationAlerts, +}: Props) => { return (
+
); }; diff --git a/assets/static/images/svgr_bundled/normal-service.svg b/assets/static/images/svgr_bundled/normal-service.svg new file mode 100644 index 000000000..fe2f97ea5 --- /dev/null +++ b/assets/static/images/svgr_bundled/normal-service.svg @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index a4737060e..0b05c4f87 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -14,7 +14,7 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do } def serialize(%__MODULE__{screen: %Screen{app_params: %Elevator{elevator_id: id}}, time: time}) do - %{id: id, alerts: [], time: DateTime.to_iso8601(time)} + %{id: id, in_station_alerts: [], outside_alerts: [], time: DateTime.to_iso8601(time)} end defimpl Screens.V2.WidgetInstance do From e88f18b552682972ce437f96ff11ea1727af2aa9 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 10:56:26 -0400 Subject: [PATCH 05/10] Started on outside alert list. --- assets/css/v2/elevator/elevator_closures.scss | 14 +++++++++++- .../v2/elevator/elevator_closures.tsx | 22 ++++++++++++++++++- .../svgr_bundled/accessibility-alert.svg | 11 ++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 assets/static/images/svgr_bundled/accessibility-alert.svg diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index d77f699a0..61a5a86e2 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -3,7 +3,7 @@ font-family: Inter, sans-serif; background-color: $warm-neutral-90; - .header { + .screen-header { display: flex; height: 104px; background-color: $cool-black-15; @@ -29,4 +29,16 @@ height: 24px; background-color: $cool-black-15; } + + .outside-alert-list { + background-color: $warm-neutral-90; + + .header { + display: flex; + font-size: 150px; + font-weight: 700; + line-height: 150px; + padding: 48px; + } + } } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 9ad606436..607ebea32 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -1,6 +1,7 @@ import React from "react"; import { formatTimeString } from "Util/util"; import NormalService from "Images/svgr_bundled/normal-service.svg"; +import AccessibilityAlert from "Images/svgr_bundled/accessibility-alert.svg"; interface HeaderProps { id: string; @@ -9,7 +10,7 @@ interface HeaderProps { const Header = ({ id, time }: HeaderProps) => { return ( -
+
Elevator {id} {formatTimeString(time)}
@@ -37,6 +38,23 @@ const InStationSummary = ({ alerts }: InStationSummaryProps) => { ); }; +interface OutsideAlertListProps { + alerts: string[]; +} + +const OutsideAlertList = (_props: OutsideAlertListProps) => { + return ( +
+
+ MBTA Elevator Closures + + + +
+
+ ); +}; + interface Props { id: string; time: string; @@ -48,11 +66,13 @@ const ElevatorClosures: React.ComponentType = ({ id, time, in_station_alerts: inStationAlerts, + outside_alerts: outsideAlerts, }: Props) => { return (
+
); }; diff --git a/assets/static/images/svgr_bundled/accessibility-alert.svg b/assets/static/images/svgr_bundled/accessibility-alert.svg new file mode 100644 index 000000000..69c41faab --- /dev/null +++ b/assets/static/images/svgr_bundled/accessibility-alert.svg @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file From 1c2d9f7f64cd72d5fc2f342e594cafccca446245 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 11:11:30 -0400 Subject: [PATCH 06/10] Added footer. --- assets/css/v2/elevator/elevator_closures.scss | 16 ++++++++++++++++ .../components/v2/elevator/elevator_closures.tsx | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 61a5a86e2..37cac6e1c 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -1,4 +1,7 @@ .elevator-closures { + display: flex; + flex-direction: column; + height: 100%; position: relative; font-family: Inter, sans-serif; background-color: $warm-neutral-90; @@ -27,10 +30,12 @@ hr { height: 24px; + width: 100%; background-color: $cool-black-15; } .outside-alert-list { + height: 100%; background-color: $warm-neutral-90; .header { @@ -41,4 +46,15 @@ padding: 48px; } } + + .footer { + display: flex; + height: 184px; + background-color: $cool-black-30; + color: white; + font-size: 48px; + line-height: 62px; + align-items: center; + padding: 26px 48px; + } } diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index 607ebea32..e2ee3d9cd 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -55,6 +55,17 @@ const OutsideAlertList = (_props: OutsideAlertListProps) => { ); }; +const Footer = () => { + return ( +
+ + For more info and alternate paths: mbta.com/alerts/access or (617) + 222-2828 + +
+ ); +}; + interface Props { id: string; time: string; @@ -73,6 +84,7 @@ const ElevatorClosures: React.ComponentType = ({
+
); }; From 79cf319b7d553dc2d2896da8128abce238496765 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 11:24:04 -0400 Subject: [PATCH 07/10] Credo and tests. --- .../v2/widget_instance/elevator_closures.ex | 4 +- .../elevator_closures_test.exs | 71 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 test/screens/v2/widget_instance/elevator_closures_test.exs diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index 0b05c4f87..e08abf23f 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -1,7 +1,9 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do + @moduledoc false + + alias Screens.Alerts.Alert alias ScreensConfig.Screen alias ScreensConfig.V2.Elevator - alias Screens.Alerts.Alert defstruct screen: nil, alerts: nil, diff --git a/test/screens/v2/widget_instance/elevator_closures_test.exs b/test/screens/v2/widget_instance/elevator_closures_test.exs new file mode 100644 index 000000000..bd12183a6 --- /dev/null +++ b/test/screens/v2/widget_instance/elevator_closures_test.exs @@ -0,0 +1,71 @@ +defmodule Screens.V2.WidgetInstance.ElevatorClosuresTest do + use ExUnit.Case, async: true + + alias Screens.V2.WidgetInstance + alias Screens.V2.WidgetInstance.ElevatorClosures + alias ScreensConfig.Screen + alias ScreensConfig.V2.Elevator + + setup do + %{ + instance: %ElevatorClosures{ + screen: struct(Screen, %{app_params: %Elevator{elevator_id: "111"}}), + time: ~U[2024-10-16T09:00:00Z], + alerts: [] + } + } + end + + describe "priority/1" do + test "returns 1", %{instance: instance} do + assert [1] == WidgetInstance.priority(instance) + end + end + + describe "serialize/1" do + test "returns map with id, alerts, and time", %{instance: instance} do + assert %{ + id: "111", + time: DateTime.to_iso8601(~U[2024-10-16T09:00:00Z]), + in_station_alerts: [], + outside_alerts: [] + } == WidgetInstance.serialize(instance) + end + end + + describe "slot_names/1" do + test "returns main_content", %{instance: instance} do + assert [:main_content] == WidgetInstance.slot_names(instance) + end + end + + describe "widget_type/1" do + test "returns elevator_closures", %{instance: instance} do + assert :elevator_closures == WidgetInstance.widget_type(instance) + end + end + + describe "audio_serialize/1" do + test "returns empty map", %{instance: instance} do + assert %{} == WidgetInstance.audio_serialize(instance) + end + end + + describe "audio_sort_key/1" do + test "returns [0]", %{instance: instance} do + assert [0] == WidgetInstance.audio_sort_key(instance) + end + end + + describe "audio_valid_candidate?/1" do + test "returns false", %{instance: instance} do + refute WidgetInstance.audio_valid_candidate?(instance) + end + end + + describe "audio_view/1" do + test "returns ElevatorClosuresView", %{instance: instance} do + assert ScreensWeb.V2.Audio.ElevatorClosuresView == WidgetInstance.audio_view(instance) + end + end +end From 8c89a6db25a2994f6c99b9f3bd641b695a01df13 Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Wed, 16 Oct 2024 15:05:55 -0400 Subject: [PATCH 08/10] Lint. --- assets/css/v2/elevator/elevator_closures.scss | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 37cac6e1c..492f73729 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -1,36 +1,36 @@ .elevator-closures { + position: relative; display: flex; flex-direction: column; height: 100%; - position: relative; font-family: Inter, sans-serif; background-color: $warm-neutral-90; .screen-header { display: flex; - height: 104px; - background-color: $cool-black-15; - color: $warm-neutral-90; align-items: center; justify-content: space-between; + height: 104px; + padding: 0 48px; font-size: 48px; line-height: 62px; - padding: 0 48px; + color: $warm-neutral-90; + background-color: $cool-black-15; } .in-station-summary { display: flex; - padding: 24px 58px; justify-content: space-between; - font-weight: 400; + padding: 24px 58px; font-size: 48px; + font-weight: 400; line-height: 64px; color: $cool-black-30; } hr { - height: 24px; width: 100%; + height: 24px; background-color: $cool-black-15; } @@ -40,21 +40,21 @@ .header { display: flex; + padding: 48px; font-size: 150px; font-weight: 700; line-height: 150px; - padding: 48px; } } .footer { display: flex; + align-items: center; height: 184px; - background-color: $cool-black-30; - color: white; + padding: 26px 48px; font-size: 48px; line-height: 62px; - align-items: center; - padding: 26px 48px; + color: white; + background-color: $cool-black-30; } } From ad774a0d2a3cf16d3741c02e29d0553129fc199f Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Thu, 17 Oct 2024 09:22:28 -0400 Subject: [PATCH 09/10] Added simulation code for elevators. --- assets/css/elevator_v2.scss | 2 ++ assets/src/apps/v2/elevator.tsx | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/assets/css/elevator_v2.scss b/assets/css/elevator_v2.scss index 937785947..6c470d510 100644 --- a/assets/css/elevator_v2.scss +++ b/assets/css/elevator_v2.scss @@ -2,6 +2,8 @@ @import "colors"; @import "v2/elevator/elevator_closures"; @import "v2/elevator/normal"; +@import "v2/simulation_common"; +@import "v2/lcd_common/simulation"; body { margin: 0; diff --git a/assets/src/apps/v2/elevator.tsx b/assets/src/apps/v2/elevator.tsx index 79314a54a..4a28ce6fe 100644 --- a/assets/src/apps/v2/elevator.tsx +++ b/assets/src/apps/v2/elevator.tsx @@ -15,6 +15,7 @@ import ScreenPage from "Components/v2/screen_page"; import { MappingContext } from "Components/v2/widget"; import MultiScreenPage from "Components/v2/multi_screen_page"; import ElevatorClosures from "Components/v2/elevator/elevator_closures"; +import SimulationScreenPage from "Components/v2/simulation_screen_page"; const TYPE_TO_COMPONENT = { normal: NormalScreen, @@ -29,11 +30,22 @@ const App = (): JSX.Element => { - + + + + + + ); From ff876a27449376cb46a0c406a1fad577fbaed9ff Mon Sep 17 00:00:00 2001 From: cmaddox5 Date: Fri, 18 Oct 2024 13:43:21 -0400 Subject: [PATCH 10/10] Split header and footer into separate slots. --- assets/css/elevator_v2.scss | 2 ++ assets/css/v2/elevator/elevator_closures.scss | 25 ++------------- assets/css/v2/elevator/footer.scss | 11 +++++++ assets/css/v2/elevator/header.scss | 12 +++++++ assets/css/v2/elevator/normal.scss | 13 +++++++- assets/src/apps/v2/elevator.tsx | 4 +++ .../v2/elevator/elevator_closures.tsx | 30 ------------------ assets/src/components/v2/elevator/footer.tsx | 12 +++++++ .../components/v2/elevator/normal_screen.tsx | 12 +++++-- .../v2/candidate_generator/elevator.ex | 24 +++++++++++--- .../v2/widget_instance/elevator_closures.ex | 10 +++--- lib/screens/v2/widget_instance/footer.ex | 31 +++++++++++++++++++ .../v2/candidate_generator/elevator_test.exs | 2 +- .../elevator_closures_test.exs | 4 +-- 14 files changed, 120 insertions(+), 72 deletions(-) create mode 100644 assets/css/v2/elevator/footer.scss create mode 100644 assets/css/v2/elevator/header.scss create mode 100644 assets/src/components/v2/elevator/footer.tsx create mode 100644 lib/screens/v2/widget_instance/footer.ex diff --git a/assets/css/elevator_v2.scss b/assets/css/elevator_v2.scss index 6c470d510..c874acaab 100644 --- a/assets/css/elevator_v2.scss +++ b/assets/css/elevator_v2.scss @@ -4,6 +4,8 @@ @import "v2/elevator/normal"; @import "v2/simulation_common"; @import "v2/lcd_common/simulation"; +@import "v2/elevator/header"; +@import "v2/elevator/footer"; body { margin: 0; diff --git a/assets/css/v2/elevator/elevator_closures.scss b/assets/css/v2/elevator/elevator_closures.scss index 492f73729..b8f33e3b7 100644 --- a/assets/css/v2/elevator/elevator_closures.scss +++ b/assets/css/v2/elevator/elevator_closures.scss @@ -6,18 +6,6 @@ font-family: Inter, sans-serif; background-color: $warm-neutral-90; - .screen-header { - display: flex; - align-items: center; - justify-content: space-between; - height: 104px; - padding: 0 48px; - font-size: 48px; - line-height: 62px; - color: $warm-neutral-90; - background-color: $cool-black-15; - } - .in-station-summary { display: flex; justify-content: space-between; @@ -31,6 +19,8 @@ hr { width: 100%; height: 24px; + margin-top: 0; + margin-bottom: 0; background-color: $cool-black-15; } @@ -46,15 +36,4 @@ line-height: 150px; } } - - .footer { - display: flex; - align-items: center; - height: 184px; - padding: 26px 48px; - font-size: 48px; - line-height: 62px; - color: white; - background-color: $cool-black-30; - } } diff --git a/assets/css/v2/elevator/footer.scss b/assets/css/v2/elevator/footer.scss new file mode 100644 index 000000000..94e75283c --- /dev/null +++ b/assets/css/v2/elevator/footer.scss @@ -0,0 +1,11 @@ +.footer { + display: flex; + align-items: center; + height: 100%; + padding: 0 48px; + font-family: Inter, sans-serif; + font-size: 48px; + line-height: 62px; + color: white; + background-color: $cool-black-30; +} diff --git a/assets/css/v2/elevator/header.scss b/assets/css/v2/elevator/header.scss new file mode 100644 index 000000000..c3102b3cd --- /dev/null +++ b/assets/css/v2/elevator/header.scss @@ -0,0 +1,12 @@ +.normal-header { + display: flex; + align-items: center; + justify-content: space-between; + height: 100%; + padding: 0 48px; + font-family: Inter, sans-serif; + font-size: 48px; + line-height: 62px; + color: $warm-neutral-90; + background-color: $cool-black-15; +} diff --git a/assets/css/v2/elevator/normal.scss b/assets/css/v2/elevator/normal.scss index 646f65546..cdf209a7c 100644 --- a/assets/css/v2/elevator/normal.scss +++ b/assets/css/v2/elevator/normal.scss @@ -5,7 +5,18 @@ margin-left: auto; } +.screen-normal__header { + width: 1080px; + height: 104px; +} + .screen-normal__body { width: 1080px; - height: 1920px; + height: 1632px; +} + +.screen-normal__footer { + position: relative; + width: 1080px; + height: 184px; } diff --git a/assets/src/apps/v2/elevator.tsx b/assets/src/apps/v2/elevator.tsx index 4a28ce6fe..cea5a1e47 100644 --- a/assets/src/apps/v2/elevator.tsx +++ b/assets/src/apps/v2/elevator.tsx @@ -16,11 +16,15 @@ import { MappingContext } from "Components/v2/widget"; import MultiScreenPage from "Components/v2/multi_screen_page"; import ElevatorClosures from "Components/v2/elevator/elevator_closures"; import SimulationScreenPage from "Components/v2/simulation_screen_page"; +import Footer from "Components/v2/elevator/footer"; +import NormalHeader from "Components/v2/normal_header"; const TYPE_TO_COMPONENT = { normal: NormalScreen, elevator_closures: ElevatorClosures, evergreen_content: EvergreenContent, + footer: Footer, + normal_header: NormalHeader, }; const App = (): JSX.Element => { diff --git a/assets/src/components/v2/elevator/elevator_closures.tsx b/assets/src/components/v2/elevator/elevator_closures.tsx index e2ee3d9cd..0e7b668c6 100644 --- a/assets/src/components/v2/elevator/elevator_closures.tsx +++ b/assets/src/components/v2/elevator/elevator_closures.tsx @@ -1,21 +1,7 @@ import React from "react"; -import { formatTimeString } from "Util/util"; import NormalService from "Images/svgr_bundled/normal-service.svg"; import AccessibilityAlert from "Images/svgr_bundled/accessibility-alert.svg"; -interface HeaderProps { - id: string; - time: string; -} - -const Header = ({ id, time }: HeaderProps) => { - return ( -
- Elevator {id} - {formatTimeString(time)} -
- ); -}; interface InStationSummaryProps { alerts: string[]; } @@ -55,36 +41,20 @@ const OutsideAlertList = (_props: OutsideAlertListProps) => { ); }; -const Footer = () => { - return ( -
- - For more info and alternate paths: mbta.com/alerts/access or (617) - 222-2828 - -
- ); -}; - interface Props { id: string; - time: string; in_station_alerts: string[]; outside_alerts: string[]; } const ElevatorClosures: React.ComponentType = ({ - id, - time, in_station_alerts: inStationAlerts, outside_alerts: outsideAlerts, }: Props) => { return (
-
-
); }; diff --git a/assets/src/components/v2/elevator/footer.tsx b/assets/src/components/v2/elevator/footer.tsx new file mode 100644 index 000000000..70e2fb2d9 --- /dev/null +++ b/assets/src/components/v2/elevator/footer.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +const Footer = () => { + return ( +
+ For more info and alternate paths: mbta.com/alerts/access or (617) + 222-2828 +
+ ); +}; + +export default Footer; diff --git a/assets/src/components/v2/elevator/normal_screen.tsx b/assets/src/components/v2/elevator/normal_screen.tsx index eb2d79c61..5d572cce2 100644 --- a/assets/src/components/v2/elevator/normal_screen.tsx +++ b/assets/src/components/v2/elevator/normal_screen.tsx @@ -3,17 +3,23 @@ import React from "react"; import Widget, { WidgetData } from "Components/v2/widget"; interface Props { + header: WidgetData; main_content: WidgetData; + footer: WidgetData; } -const NormalScreen: React.ComponentType = ({ - main_content: mainContent, -}) => { +const NormalScreen = ({ header, main_content: mainContent, footer }: Props) => { return (
+
+ +
+
+ +
); }; diff --git a/lib/screens/v2/candidate_generator/elevator.ex b/lib/screens/v2/candidate_generator/elevator.ex index b07262c35..eeefbdb50 100644 --- a/lib/screens/v2/candidate_generator/elevator.ex +++ b/lib/screens/v2/candidate_generator/elevator.ex @@ -3,7 +3,9 @@ defmodule Screens.V2.CandidateGenerator.Elevator do alias Screens.V2.CandidateGenerator alias Screens.V2.Template.Builder - alias Screens.V2.WidgetInstance.ElevatorClosures + alias Screens.V2.WidgetInstance.{ElevatorClosures, Footer, NormalHeader} + alias ScreensConfig.Screen + alias ScreensConfig.V2.Elevator @behaviour CandidateGenerator @@ -11,19 +13,31 @@ defmodule Screens.V2.CandidateGenerator.Elevator do { :screen, %{ - normal: [:main_content] + normal: [ + :header, + :main_content, + :footer + ] } } |> Builder.build_template() end def candidate_instances(config, now \\ DateTime.utc_now()) do - elevator_closures_instances(config, now) + [header_instance(config, now), elevator_closures_instance(config), footer_instance(config)] end def audio_only_instances(_widgets, _config), do: [] - defp elevator_closures_instances(config, now) do - [%ElevatorClosures{screen: config, alerts: [], time: now}] + defp elevator_closures_instance(config) do + %ElevatorClosures{screen: config, alerts: []} + end + + defp header_instance(%Screen{app_params: %Elevator{elevator_id: elevator_id}} = config, now) do + %NormalHeader{text: "Elevator #{elevator_id}", screen: config, time: now} + end + + defp footer_instance(config) do + %Footer{screen: config} end end diff --git a/lib/screens/v2/widget_instance/elevator_closures.ex b/lib/screens/v2/widget_instance/elevator_closures.ex index e08abf23f..59f612653 100644 --- a/lib/screens/v2/widget_instance/elevator_closures.ex +++ b/lib/screens/v2/widget_instance/elevator_closures.ex @@ -6,17 +6,15 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosures do alias ScreensConfig.V2.Elevator defstruct screen: nil, - alerts: nil, - time: nil + alerts: nil @type t :: %__MODULE__{ screen: Screen.t(), - alerts: list(Alert.t()), - time: DateTime.t() + alerts: list(Alert.t()) } - def serialize(%__MODULE__{screen: %Screen{app_params: %Elevator{elevator_id: id}}, time: time}) do - %{id: id, in_station_alerts: [], outside_alerts: [], time: DateTime.to_iso8601(time)} + def serialize(%__MODULE__{screen: %Screen{app_params: %Elevator{elevator_id: id}}}) do + %{id: id, in_station_alerts: [], outside_alerts: []} end defimpl Screens.V2.WidgetInstance do diff --git a/lib/screens/v2/widget_instance/footer.ex b/lib/screens/v2/widget_instance/footer.ex new file mode 100644 index 000000000..9a5f54904 --- /dev/null +++ b/lib/screens/v2/widget_instance/footer.ex @@ -0,0 +1,31 @@ +defmodule Screens.V2.WidgetInstance.Footer do + @moduledoc false + + alias ScreensConfig.Screen + + defstruct screen: nil + + @type t :: %__MODULE__{ + screen: Screen.t() + } + + defimpl Screens.V2.WidgetInstance do + def priority(_instance), do: [1] + + def serialize(_instance), do: %{} + + def slot_names(_instance), do: [:footer] + + def widget_type(_instance), do: :footer + + def valid_candidate?(_instance), do: true + + def audio_serialize(_instance), do: %{} + + def audio_sort_key(_instance), do: [0] + + def audio_valid_candidate?(_instance), do: false + + def audio_view(_instance), do: ScreensWeb.V2.Audio.FooterView + end +end diff --git a/test/screens/v2/candidate_generator/elevator_test.exs b/test/screens/v2/candidate_generator/elevator_test.exs index deb681162..4053999b1 100644 --- a/test/screens/v2/candidate_generator/elevator_test.exs +++ b/test/screens/v2/candidate_generator/elevator_test.exs @@ -22,7 +22,7 @@ defmodule Screens.V2.CandidateGenerator.ElevatorTest do test "returns template" do assert {:screen, %{ - normal: [:main_content] + normal: [:header, :main_content, :footer] }} == Elevator.screen_template() end end diff --git a/test/screens/v2/widget_instance/elevator_closures_test.exs b/test/screens/v2/widget_instance/elevator_closures_test.exs index bd12183a6..96ef7e858 100644 --- a/test/screens/v2/widget_instance/elevator_closures_test.exs +++ b/test/screens/v2/widget_instance/elevator_closures_test.exs @@ -10,7 +10,6 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosuresTest do %{ instance: %ElevatorClosures{ screen: struct(Screen, %{app_params: %Elevator{elevator_id: "111"}}), - time: ~U[2024-10-16T09:00:00Z], alerts: [] } } @@ -23,10 +22,9 @@ defmodule Screens.V2.WidgetInstance.ElevatorClosuresTest do end describe "serialize/1" do - test "returns map with id, alerts, and time", %{instance: instance} do + test "returns map with id and alerts", %{instance: instance} do assert %{ id: "111", - time: DateTime.to_iso8601(~U[2024-10-16T09:00:00Z]), in_station_alerts: [], outside_alerts: [] } == WidgetInstance.serialize(instance)