Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Working triptych app skeleton with viewport shifter, request logging, packaging instructions #1833

Merged
merged 32 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5bc8975
Rename `isDup` -> `isOFM` since we now run on two different OFM scree…
jzimbel-mbta Aug 10, 2023
5154c37
Triptych app setup + packaging instructions
jzimbel-mbta Aug 10, 2023
c2938b7
Working triptych app with viewport shifter
jzimbel-mbta Aug 11, 2023
89b2d5b
Remove TODO--made an asana task for it
jzimbel-mbta Aug 11, 2023
83dbcfb
Use matching param for triptych pane in data requests
jzimbel-mbta Aug 11, 2023
7182494
Cleanup and fix accidentally committed test code
jzimbel-mbta Aug 11, 2023
5ece363
Working triptych frontend with new route + cleaned up OFM utilities
jzimbel-mbta Aug 23, 2023
5f3f985
Address credo complaints
jzimbel-mbta Aug 23, 2023
fa3f629
Use default simulation component for triptychs
jzimbel-mbta Aug 23, 2023
90f0320
Add triptych player name mapping for tests
jzimbel-mbta Aug 24, 2023
7f7744f
fix: Tweak config so vscode can consistently resolve aliased import p…
jzimbel-mbta Aug 24, 2023
10653e6
Remove a few console.logs that I missed
jzimbel-mbta Aug 25, 2023
6de37c2
Unclutter useBaseApiResponse and memoize logic that computes API url
jzimbel-mbta Aug 25, 2023
a28d258
Add some missing config for the test env :doh:
jzimbel-mbta Aug 25, 2023
88e5511
A no-op change in lib/, because the last commit didn't trigger CI for…
jzimbel-mbta Aug 25, 2023
7db3eae
Revert "A no-op change in lib/, because the last commit didn't trigge…
jzimbel-mbta Aug 25, 2023
b1064f1
Revert "Revert "A no-op change in lib/, because the last commit didn'…
jzimbel-mbta Aug 28, 2023
99c181a
Merge branch 'master' into jz/triptych-packaging
jzimbel-mbta Aug 28, 2023
1605140
Uncomment accidentally commented line of code
jzimbel-mbta Aug 28, 2023
284a5ca
Revert `isDUP` name to `isDup`
jzimbel-mbta Aug 28, 2023
4189456
Rename a few more isDUPs that the vscode refactor tool missed
jzimbel-mbta Aug 28, 2023
a0171c0
Run prettier
jzimbel-mbta Aug 29, 2023
4ea45fa
Merge branch 'master' into jz/triptych-packaging
jzimbel-mbta Aug 29, 2023
f775909
Rename split-screen slots to left_, middle_, right_pane for consistency
jzimbel-mbta Aug 29, 2023
e669c59
"Closed" -> "Car closed" per designs (plus some tweaks to avoid prett…
jzimbel-mbta Aug 29, 2023
e157570
Add packaging README section on communicating with Outfront
jzimbel-mbta Aug 30, 2023
f995910
Document `platform_position` value
jzimbel-mbta Aug 30, 2023
e9c6a03
Adjust no-data/disabled templates to match new slot names
jzimbel-mbta Aug 30, 2023
72059da
Finish documenting OFM util functions and hooks
jzimbel-mbta Aug 30, 2023
1005d8b
Reorder lines for consistency with surrounding functions
jzimbel-mbta Aug 30, 2023
9e76838
Use getMRAID in useCurrentPage + update fake MRAID with new fields fo…
jzimbel-mbta Aug 30, 2023
f266e7c
Prettier
jzimbel-mbta Aug 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Some examples of the various client apps, as of January 2023:
| [Multimodal LCD][solari sample] | used at high-traffic transfer stations served by many routes/modes |
| [Pre-fare duo LCD][pre_fare sample] | posted outside of fare gates at rapid transit stations; content is split across two portrait-oriented 1080p physical displays |
| ["Digital Urban Panel" LCD][dup sample] | content appears in rotation with ads on screens posted outside rapid transit station entrances |
| Triptych trio LCD | (:construction: WIP!) posted across the tracks from platforms at major stations; content is split across three portrait-oriented 1080p physical displays and appears in rotation with ads |

and more to come!

Expand All @@ -34,11 +35,11 @@ On <sup>almost</sup> all of our screen types, we use a common "framework" to fet

Check out [ARCHITECTURE.md](/ARCHITECTURE.md) for an overview of the application architecture, as well as links to further more detailed documentation.

## Packaging the DUP app
## Packaging the DUP and Triptych apps

The DUP screens require the client app to be packaged into a single HTML file rather than dynamically served from our Phoenix server.
The DUP and Triptych screens require the client app to be packaged into a single HTML file rather than dynamically served from our Phoenix server.

You can find instructions on the packaging process [here](assets/src/components/v2/dup/README.md).
You can find instructions on the DUP packaging process [here](assets/src/components/v2/dup/README.md), the triptych packaging process [here](assets/src/components/v2/triptych/README.md).

## Version upgrade guide

Expand Down
5 changes: 3 additions & 2 deletions assets/css/triptych_v2.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
@import "fonts/helvetica_font_face";
@import "v2/common/widget";

@import "v2/triptych/viewport";
@import "v2/triptych/screen_container";

@import "v2/triptych/screen/normal";

@import "v2/triptych/body/normal";
@import "v2/triptych/screen/takeover";

@import "v2/lcd_common_styles/page_load_no_data";
@import "v2/lcd_common_styles/no_data";
@import "v2/triptych/no_data";

@import "v2/placeholder";

Expand Down
9 changes: 0 additions & 9 deletions assets/css/v2/triptych/body/normal.scss
jzimbel-mbta marked this conversation as resolved.
Show resolved Hide resolved

This file was deleted.

11 changes: 11 additions & 0 deletions assets/css/v2/triptych/no_data.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.no-data-middle {
position: absolute;
top: 0px;
left: 1080px;
}

.no-data-right {
position: absolute;
top: 0px;
left: 2160px;
}
9 changes: 5 additions & 4 deletions assets/css/v2/triptych/screen/normal.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.screen-normal {
width: 1080px;
width: 3240px;
height: 1920px;
margin-left: auto;
margin-right: auto;
position: relative;
Expand All @@ -9,16 +10,16 @@
position: absolute;
top: 0px;
left: 0px;
width: 1080px;
width: 3240px;
height: 272px;
overflow: hidden;
}

.screen-normal__body {
.screen-normal__main-content {
position: absolute;
top: 272px;
left: 0px;
width: 1080px;
width: 3240px;
height: 1648px;
overflow: hidden;
}
16 changes: 16 additions & 0 deletions assets/css/v2/triptych/screen/takeover.scss
jzimbel-mbta marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.screen-takeover {
width: 3240px;
height: 1920px;
margin-left: auto;
margin-right: auto;
position: relative;
}

.screen-takeover__full-screen {
position: absolute;
top: 0px;
left: 0px;
width: 3240px;
height: 1920px;
overflow: hidden;
}
11 changes: 10 additions & 1 deletion assets/css/v2/triptych/screen_container.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
.screen-container {
position: relative;
width: 1080px;
width: 3240px;
height: 1920px;
margin: 0px auto;
overflow: hidden;
}

.screen-container-blink {
jzimbel-mbta marked this conversation as resolved.
Show resolved Hide resolved
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
}
31 changes: 31 additions & 0 deletions assets/css/v2/triptych/viewport.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.triptych-screen-viewport {
width: 1080px;
height: 1920px;
overflow: hidden;
position: relative;
margin-left: auto;
margin-right: auto;

.triptych-shifter {
width: 3240px;
height: 1920px;
overflow: hidden;
position: absolute;
}

.triptych-shifter--left {
left: 0;
}

.triptych-shifter--middle {
left: -1080px;
}

.triptych-shifter--right {
right: 0px;
}
}

.triptych-screen-viewport--all {
width: 3240px;
}
4 changes: 2 additions & 2 deletions assets/src/apps/dup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import {
MultiRotationPage,
SimulationPage,
} from "Components/dup/dup_screen_page";
import { isDup } from "Util/util";
import { isOFM } from "Util/util";

const App = (): JSX.Element => {
if (isDup()) {
if (isOFM()) {
return <ScreenPage screenContainer={ScreenContainer} />;
} else {
return (
Expand Down
47 changes: 38 additions & 9 deletions assets/src/apps/v2/triptych.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,32 @@ require("../../../css/triptych_v2.scss");
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

import ScreenPage from "Components/v2/screen_page";
import { MappingContext } from "Components/v2/widget";
import {
ResponseMapper,
ResponseMapperContext,
LOADING_LAYOUT,
} from "Components/v2/screen_container";
import { MappingContext } from "Components/v2/widget";

import NormalScreen from "Components/v2/bus_shelter/normal_screen";
import NormalBody from "Components/v2/bus_shelter/normal_body";
import MultiScreenPage from "Components/v2/multi_screen_page";
import SimulationScreenPage from "Components/v2/simulation_screen_page";

// Remove on go-live.
import Placeholder from "Components/v2/placeholder";

import SimulationScreenPage from "Components/v2/simulation_screen_page";
import PageLoadNoData from "Components/v2/lcd/page_load_no_data";
import NoData from "Components/v2/lcd/no_data";
import Viewport from "Components/v2/triptych/viewport";
import NormalScreen from "Components/v2/triptych/normal_screen";
import TakeoverScreen from "Components/v2/triptych/takeover_screen";
import PageLoadNoData from "Components/v2/triptych/page_load_no_data";
import NoData from "Components/v2/triptych/no_data";

import useOutfrontPlayerName from "Hooks/use_outfront_player_name";

const TYPE_TO_COMPONENT = {
screen_normal: NormalScreen,
body_normal: NormalBody,
screen_takeover: TakeoverScreen,
placeholder: Placeholder,
page_load_no_data: PageLoadNoData,
no_data: NoData,
Expand Down Expand Up @@ -55,20 +61,43 @@ const responseMapper: ResponseMapper = (apiResponse) => {
};

const App = (): JSX.Element => {
const playerName = useOutfrontPlayerName();

if (playerName !== null) {
const id = `TRI-${playerName.trim()}`;
return (
<MappingContext.Provider value={TYPE_TO_COMPONENT}>
<ResponseMapperContext.Provider value={responseMapper}>
<Viewport>
<ScreenPage id={id} />
</Viewport>
</ResponseMapperContext.Provider>
</MappingContext.Provider>
);
}

return (
<Router>
<Switch>
<Route exact path="/v2/screen/triptych_v2">
<MultiScreenPage
components={TYPE_TO_COMPONENT}
responseMapper={responseMapper}
/>
</Route>
<Route exact path="/v2/screen/:id/simulation">
<MappingContext.Provider value={TYPE_TO_COMPONENT}>
<ResponseMapperContext.Provider value={responseMapper}>
<SimulationScreenPage />
<SimulationScreenPage opts={{ alternateView: true }} />
jzimbel-mbta marked this conversation as resolved.
Show resolved Hide resolved
</ResponseMapperContext.Provider>
</MappingContext.Provider>
</Route>
<Route path="/v2/screen/:id">
<MappingContext.Provider value={TYPE_TO_COMPONENT}>
<ResponseMapperContext.Provider value={responseMapper}>
<ScreenPage />
<Viewport>
<ScreenPage />
</Viewport>
</ResponseMapperContext.Provider>
</MappingContext.Provider>
</Route>
Expand Down
9 changes: 5 additions & 4 deletions assets/src/components/dup/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# DUP app packaging

- Ensure [Corsica](https://hexdocs.pm/corsica/Corsica.html) is used on the server to allow CORS requests (ideally limited to just the DUP-relevant routes). It should already be configured at [this line](/lib/screens_web/controllers/screen_api_controller.ex#L7) in the API controller--if it is, you don't need to do anything for this step.
- Double check that any behavior specific to the DUP screen environment happens inside of an `isDup()` check. This includes:
- Double check that any behavior specific to the DUP screen environment happens inside of an `isOFM()` check. This includes:
- `buildApiPath` in use_api_response.tsx should return a full URL for the API path: prefix `apiPath` string with "https://screens.mbta.com".
- `App` component in dup.tsx should just return `<ScreenPage screenContainer={ScreenContainer} />`.
- `imagePath` in util.tsx should return relative paths (no leading `/`).
Expand All @@ -16,7 +16,6 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Screens</title>
<link rel="stylesheet" href="inter_font_face.css" />
<link rel="stylesheet" href="dup.css" />
</head>

Expand All @@ -40,8 +39,10 @@
for ROTATION_INDEX in {0..2}; do
echo "export const ROTATION_INDEX = ${ROTATION_INDEX};" > ../../assets/src/components/dup/rotation_index.tsx
npm --prefix ../../assets run deploy
cp -r css/dup.css js/polyfills.js js/dup.js ../inter_font_face.css ../fonts ../template.json ../preview.png .
zip -r dup-app-${ROTATION_INDEX}.zip dup.css polyfills.js dup.js inter_font_face.css fonts images dup-app.html template.json preview.png
cp -r css/dup.css js/polyfills.js js/dup.js ../dup_preview.png .
cp ../dup_template.json ./template.json
sed -i "" "s/DUP APP ./DUP APP ${ROTATION_INDEX}/" template.json
zip -r dup-app-${ROTATION_INDEX}.zip dup.css polyfills.js dup.js fonts images dup-app.html template.json dup_preview.png
done
```
- Commit the version bump on a branch, push it, and create a PR to mark the deploy.
Expand Down
4 changes: 2 additions & 2 deletions assets/src/components/dup/dup_screen_page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useParams } from "react-router-dom";
import useOutfrontStation from "Hooks/use_outfront_station";
import { ROTATION_INDEX } from "./rotation_index";
import { NoDataLayout } from "Components/dup/screen_container";
import { isDup } from "Util/util";
import { isOFM } from "Util/util";
import { fetchDatasetValue } from "Util/dataset";
import { DUP_SIMULATION_REFRESH_MS } from "Constants";

Expand Down Expand Up @@ -37,7 +37,7 @@ const ScreenPage = ({
}: {
screenContainer: React.ComponentType;
}): JSX.Element =>
isDup() ? (
isOFM() ? (
<DupScreenPage screenContainer={screenContainer} />
) : (
<DevelopmentScreenPage screenContainer={screenContainer} />
Expand Down
10 changes: 6 additions & 4 deletions assets/src/components/v2/dup/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# DUP app packaging v2

- Ensure [Corsica](https://hexdocs.pm/corsica/Corsica.html) is used on the server to allow CORS requests (ideally limited to just the DUP-relevant routes). It should already be configured at [this line](/lib/screens_web/controllers/v2/screen_api_controller.ex#L9) in the API controller--if it is, you don't need to do anything for this step.
- Double check that any behavior specific to the DUP screen environment happens inside of an `isDup()` check. This includes:
- Double check that any behavior specific to the DUP screen environment happens inside of an `isOFM()` check. This includes:
- `buildApiPath` in use_api_response.tsx should return a full URL for the API path: prefix `apiPath` string with "https://screens.mbta.com".
- `imagePath` in util.tsx should return relative paths (no leading `/`).
- Create priv/static/dup-app.html if it doesn’t already exist. Copy paste the following contents in:
Expand Down Expand Up @@ -33,14 +33,16 @@
- In assets/webpack.config.js, change `publicPath` in the font config to have value `'fonts/'`.
- **Only if you are packaging for local testing**
- replace `const playerName = useOutfrontPlayerName();` in assets/src/apps/v2/dup.tsx with `const playerName = "BRW-DUP-005";` (or any other player name from one of the DUP screen IDs (`DUP-${playerName}`)). This data is provided by Outfront's "wrapper" app that runs on the real DUP screens, but we need to set it ourselves during testing. Think of it as a sort of frontend environment variable.
- replace `apiPath = "https://screens.mbta.com" + apiPath;` in assets/src/hooks/v2/use_api_response.tsx with `apiPath = "http://localhost:4000" + apiPath;`.
- replace `apiPath = "https://screens.mbta.com...";` in assets/src/hooks/v2/use_api_response.tsx with `apiPath = "http://localhost:4000...";`.
- `cd` to priv/static and run the following:
```sh
for ROTATION_INDEX in {0..2}; do
echo "export const ROTATION_INDEX = ${ROTATION_INDEX};" > ../../assets/src/components/v2/dup/rotation_index.tsx
npm --prefix ../../assets run deploy
cp -r css/dup_v2.css js/polyfills.js js/dup_v2.js ../inter_font_face.css ../fonts ../template.json ../preview.png .
zip -r dup-app-${ROTATION_INDEX}.zip dup_v2.css polyfills.js dup_v2.js inter_font_face.css fonts images dup-app.html template.json preview.png
cp -r css/dup_v2.css js/polyfills.js js/dup_v2.js ../dup_preview.png .
cp ../dup_template.json ./template.json
sed -i "" "s/DUP APP ./DUP APP ${ROTATION_INDEX}/" template.json
zip -r dup-app-${ROTATION_INDEX}.zip dup_v2.css polyfills.js dup_v2.js fonts images dup-app.html template.json dup_preview.png
done
```
- Commit the version bump on a branch, push it, and create a PR to mark the deploy.
Expand Down
8 changes: 4 additions & 4 deletions assets/src/components/v2/screen_container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import React, {
import useApiResponse, {
ApiResponse,
SimulationApiResponse,
useDupApiResponse,
useOFMApiResponse,
} from "Hooks/v2/use_api_response";
import WidgetTreeErrorBoundary from "Components/v2/widget_tree_error_boundary";
import Widget, { WidgetData } from "Components/v2/widget";
import useAudioReadout from "Hooks/v2/use_audio_readout";
import { isDup } from "Util/util";
import { isOFM } from "Util/util";

type ResponseMapper = (
apiResponse: ApiResponse
Expand Down Expand Up @@ -93,7 +93,7 @@ const ScreenLayout: ComponentType<ScreenLayoutProps> = ({
showBlink,
}) => {
const responseMapper = useContext(ResponseMapperContext);
const ErrorBoundaryOrFragment = isDup() ? Fragment : WidgetTreeErrorBoundary;
const ErrorBoundaryOrFragment = isOFM() ? Fragment : WidgetTreeErrorBoundary;

return (
<div className="screen-container">
Expand All @@ -109,7 +109,7 @@ const ScreenContainer = ({ id }) => {
const blinkConfig = useContext(BlinkConfigContext);
const audioConfig = useContext(AudioConfigContext);
const [showBlink, setShowBlink] = useState(false);
const hook = isDup() ? useDupApiResponse : useApiResponse;
const hook = isOFM() ? useOFMApiResponse : useApiResponse;

const { apiResponse, requestCount, lastSuccess } = hook({ id });

Expand Down
Loading