🚚 Rename NextPassagesDisplay/NextPassagesPanel (remove Next prefix)

This commit is contained in:
2023-01-23 22:34:33 +01:00
parent b8984e455c
commit e96e7aeae0
5 changed files with 33 additions and 38 deletions

View File

@@ -0,0 +1,120 @@
import { Component } from 'solid-js';
import { createDateNow, getTime } from '@solid-primitives/date';
import { Motion } from "@motionone/solid";
import { TrafficStatus } from './types';
import { renderLineTransportMode, renderLinePicto } from './utils';
import styles from "./passagesPanel.module.css";
export const PassagesPanel: Component = (props) => {
/* TODO: Find where to get data to compute traffic status. */
const trafficStatusColor = new Map<TrafficStatus, string>([
[TrafficStatus.UNKNOWN, "#ffffff"],
[TrafficStatus.FLUID, "#00643c"],
[TrafficStatus.DISRUPTED, "#ffbe00"],
[TrafficStatus.VERY_DISRUPTED, "#ff5a00"],
[TrafficStatus.BYPASSED, "#ffffff"]
]);
const [dateNow] = createDateNow(5000);
function _computeTtwPassage(class_, passage, fontSize) {
const refTs = passage.expectedDepartTs !== null ? passage.expectedDepartTs : passage.expectedArrivalTs;
const ttwSec = refTs - (getTime(dateNow()) / 1000);
const isApproaching = ttwSec <= 60;
return (
<div class={class_}>
<svg viewBox={`0 0 215 ${fontSize}`}>
<Motion.text
x="100%" y="55%"
dominant-baseline="middle" text-anchor="end"
font-size={fontSize} style={{ fill: "#000000" }}
initial={isApproaching}
animate={{ opacity: [1, 0, 1] }}
transition={{ duration: 3, repeat: Infinity }}>
{Math.floor(ttwSec / 60)} min
</Motion.text>
</svg>
</div>
);
}
function _computeUnavailablePassage(class_) {
const textStyle = { fill: "#000000" };
return (
<div class={class_}>
<svg viewbox="0 0 230 110">
<text x="100%" y="26" font-size="25" text-anchor="end" style={textStyle}>Information</text>
<text x="100%" y="63" font-size="25" text-anchor="end" style={textStyle}>non</text>
<text x="100%" y="100" font-size="25" text-anchor="end" style={textStyle}>disponible</text>
</svg>
</div>
);
}
function _computeSecondPassage(passage): JSX.Element {
return (
<Show when={passage !== undefined} fallback={_computeUnavailablePassage(styles.unavailableSecondPassage)}>
{_computeTtwPassage(styles.secondPassage, passage, 45)}
</Show>
);
}
function _computeFirstPassage(passage): JSX.Element {
return (
<Show when={passage !== undefined} fallback={_computeUnavailablePassage(styles.unavailableFirstPassage)}>
{_computeTtwPassage(styles.firstPassage, passage, 50)}
</Show>
);
}
/* TODO: Manage end of service */
function _genPassages(passages, line, destination) {
const passagesLength = passages.length;
const firstPassage = passagesLength > 0 ? passages[0] : undefined;
const secondPassage = passagesLength > 1 ? passages[1] : undefined;
const trafficStatusStyle = { fill: trafficStatusColor.get(line.trafficStatus) };
return (
<div class={styles.line}>
<div class={styles.transportMode}>
{renderLineTransportMode(line)}
</div>
{renderLinePicto(line, styles)}
<div class={styles.destination}>
<svg viewbox="0 0 600 40">
<text x="0" y="50%" dominant-baseline="middle" font-size="40" style={{ fill: "#000000" }}>
{destination}
</text>
</svg>
</div>
<div class={styles.trafficStatus}>
<svg viewBox="0 0 51 51">
<circle cx="50%" cy="50%" r="24" stroke="#231f20" stroke-width="3" style={trafficStatusStyle} />
</svg>
</div>
{firstPassage ? _computeFirstPassage(firstPassage) : null}
{secondPassage ? _computeSecondPassage(secondPassage) : null}
</div>
);
}
return (
<div classList={{ [styles.passagesContainer]: true, [styles.displayed]: props.show }} style={{ "top": `${100 * props.position}%` }}>
{() => {
const ret = [];
for (const lineId of Object.keys(props.passages)) {
const line = props.lines.get(lineId);
const byLinePassages = props.passages[lineId];
for (const destination of Object.keys(byLinePassages)) {
const passages = byLinePassages[destination];
ret.push(_genPassages(passages, line, destination));
}
}
return ret;
}}
</div>
);
}