✨ Add platform id to passages panels
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { createContext, createEffect, createResource, createSignal, For, JSX, ParentComponent, Show, useContext, VoidComponent, VoidProps } from "solid-js";
|
import { createContext, createEffect, createResource, createSignal, For, JSX, ParentComponent, Show, useContext, VoidComponent } from "solid-js";
|
||||||
import { createStore } from "solid-js/store";
|
import { createStore } from "solid-js/store";
|
||||||
import { createDateNow } from "@solid-primitives/date";
|
import { createDateNow } from "@solid-primitives/date";
|
||||||
import { IconButton, Menu, MenuTrigger, MenuContent, MenuItem } from "@hope-ui/solid";
|
import { IconButton, Menu, MenuTrigger, MenuContent, MenuItem } from "@hope-ui/solid";
|
||||||
@@ -7,7 +7,6 @@ import { format } from "date-fns";
|
|||||||
import { BusinessDataContext, BusinessDataStore } from "./businessData";
|
import { BusinessDataContext, BusinessDataStore } from "./businessData";
|
||||||
import { SearchContext, SearchStore } from "./search";
|
import { SearchContext, SearchStore } from "./search";
|
||||||
|
|
||||||
import { Passage, Passages } from "./types";
|
|
||||||
import { getTransportModeSrc } from "./utils";
|
import { getTransportModeSrc } from "./utils";
|
||||||
import { PassagesPanel } from "./passagesPanel";
|
import { PassagesPanel } from "./passagesPanel";
|
||||||
import { IconHamburgerMenu } from './extra/iconHamburgerMenu';
|
import { IconHamburgerMenu } from './extra/iconHamburgerMenu';
|
||||||
@@ -202,7 +201,7 @@ const Body: ParentComponent<{ maxPassagesPerPanel: number, syncPeriodMsec: numbe
|
|||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { getLinePassages, getLineDestinations, passages, getPassagesLineIds, clearPassages, refreshPassages } = businessDataStore;
|
const { getLineDestinations, passages, getPassagesLineIds, clearPassages, refreshPassages } = businessDataStore;
|
||||||
const { isPassagesRefreshEnabled, getDisplayedPanelId, setDisplayedPanelId, getPanels, setPanels } = passagesDisplayStore;
|
const { isPassagesRefreshEnabled, getDisplayedPanelId, setDisplayedPanelId, getPanels, setPanels } = passagesDisplayStore;
|
||||||
const { getDisplayedStops } = searchStore;
|
const { getDisplayedStops } = searchStore;
|
||||||
|
|
||||||
|
@@ -126,3 +126,72 @@
|
|||||||
.unavailableSecondPassage svg {
|
.unavailableSecondPassage svg {
|
||||||
font-family: IDFVoyageur-regular;
|
font-family: IDFVoyageur-regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.withPlatformFirstPassage {
|
||||||
|
height: calc(120/176*100%);
|
||||||
|
aspect-ratio: 250/120;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
padding-right: calc(30/1920*100%);
|
||||||
|
|
||||||
|
/* TODO: compute the border weight according to the parent width */
|
||||||
|
border-right: solid calc(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.withPlatformFirstPassage .passage {
|
||||||
|
aspect-ratio: 215/50;
|
||||||
|
height: calc(1/2*100%);
|
||||||
|
|
||||||
|
font-family: IDFVoyageur-bold;
|
||||||
|
margin-top: calc(5/176*100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform {
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: calc(5/176*100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.withPlatformFirstPassage .platform rect {
|
||||||
|
background-color: var(--idfm-black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.withPlatformFirstPassage .platform text {
|
||||||
|
vertical-align: middle;
|
||||||
|
font-family: IDFVoyageur-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withPlatformSecondPassage {
|
||||||
|
height: calc(120/176*100%);
|
||||||
|
aspect-ratio: 215/120;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
margin-right: calc(30/1920*100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.withPlatformSecondPassage .passage {
|
||||||
|
aspect-ratio: 215/45;
|
||||||
|
height: calc(45/120*100%);
|
||||||
|
/* 5px + (first passage font size - second passage font size/2) to align passages... */
|
||||||
|
/* There must exist a better way to align them. */
|
||||||
|
margin-top: calc(7.5/176*100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.withPlatformSecondPassage svg {
|
||||||
|
font-family: IDFVoyageur-regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withPlatformSecondPassage .platform rect {
|
||||||
|
background-color: var(--idfm-black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.withPlatformSecondPassage .platform text {
|
||||||
|
vertical-align: middle;
|
||||||
|
font-family: IDFVoyageur-bold;
|
||||||
|
}
|
||||||
|
@@ -26,7 +26,38 @@ const UnavailablePassage: VoidComponent<{ style: string }> = (props) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TtwPassage: VoidComponent<{ line: Line, destination: string, index: number, style: string, fontSize: number, fallbackStyle: string }> = (props) => {
|
const Platform: VoidComponent<{ name: string }> = (props) => {
|
||||||
|
|
||||||
|
const platformTextPaddingPx: number = 20;
|
||||||
|
const viewBoxWidthPx: number = 215;
|
||||||
|
|
||||||
|
let rectRef: SVGSVGElement | undefined = undefined;
|
||||||
|
let textRef: SVGTextElement | undefined = undefined;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (rectRef !== undefined && textRef !== undefined) {
|
||||||
|
const textWidth = textRef.getComputedTextLength();
|
||||||
|
const rectWidth = textWidth + platformTextPaddingPx * 2;
|
||||||
|
rectRef.setAttribute("width", `${rectWidth}px`);
|
||||||
|
rectRef.setAttribute("x", `${viewBoxWidthPx - rectWidth}px`);
|
||||||
|
textRef.setAttribute("x", `${viewBoxWidthPx - platformTextPaddingPx}px`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<svg class={styles.platform} viewBox={`0 0 ${viewBoxWidthPx} 40`}>
|
||||||
|
<rect ref={rectRef} x="0" y="0" height="100%" rx="9" ry="9" />
|
||||||
|
<text ref={textRef} x="100%" y="55%" dominant-baseline="middle" text-anchor="end" font-size="25" style={{ fill: "#ffffff" }}>
|
||||||
|
QUAI {props.name}
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TtwPassage: VoidComponent<{
|
||||||
|
line: Line, destination: string, index: number, style: string,
|
||||||
|
withPlatformStyle: string, fontSize: number, fallbackStyle: string
|
||||||
|
}> = (props) => {
|
||||||
|
|
||||||
const businessDataContext: BusinessDataStore | undefined = useContext(BusinessDataContext);
|
const businessDataContext: BusinessDataStore | undefined = useContext(BusinessDataContext);
|
||||||
if (businessDataContext === undefined)
|
if (businessDataContext === undefined)
|
||||||
@@ -46,10 +77,7 @@ const TtwPassage: VoidComponent<{ line: Line, destination: string, index: number
|
|||||||
const ttwRepr = ttwSec < 3600 ? `${Math.floor(ttwSec / 60)} min` : format(refTs * 1000, "HH:mm");
|
const ttwRepr = ttwSec < 3600 ? `${Math.floor(ttwSec / 60)} min` : format(refTs * 1000, "HH:mm");
|
||||||
const isApproaching = ttwSec <= 60;
|
const isApproaching = ttwSec <= 60;
|
||||||
|
|
||||||
return (
|
const text = <svg class={styles.passage} viewBox={`0 0 215 ${props.fontSize}`}>
|
||||||
<Show when={passage !== undefined} fallback=<UnavailablePassage style={props.fallbackStyle} />>
|
|
||||||
<div class={props.style}>
|
|
||||||
<svg viewBox={`0 0 215 ${props.fontSize}`}>
|
|
||||||
<Motion.text
|
<Motion.text
|
||||||
x="100%" y="55%"
|
x="100%" y="55%"
|
||||||
dominant-baseline="middle" text-anchor="end"
|
dominant-baseline="middle" text-anchor="end"
|
||||||
@@ -59,9 +87,22 @@ const TtwPassage: VoidComponent<{ line: Line, destination: string, index: number
|
|||||||
transition={transition}>
|
transition={transition}>
|
||||||
{ttwRepr}
|
{ttwRepr}
|
||||||
</Motion.text>
|
</Motion.text>
|
||||||
</svg>
|
</svg>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Show when={passage !== undefined} fallback=<UnavailablePassage style={props.fallbackStyle} />>
|
||||||
|
<Show
|
||||||
|
when={passage.arrivalPlatformName !== null}
|
||||||
|
fallback={
|
||||||
|
<div class={props.style}>
|
||||||
|
{text}
|
||||||
|
</div>}>
|
||||||
|
<div class={props.withPlatformStyle}>
|
||||||
|
{text}
|
||||||
|
<Platform name={passage.arrivalPlatformName} />
|
||||||
</div>
|
</div>
|
||||||
</Show >
|
</Show >
|
||||||
|
</Show >
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -121,9 +162,11 @@ const DestinationPassages: VoidComponent<{ line: Line, destination: string }> =
|
|||||||
<circle cx="50%" cy="50%" r="24" stroke="#231f20" stroke-width="3" style={trafficStatusStyle} />
|
<circle cx="50%" cy="50%" r="24" stroke="#231f20" stroke-width="3" style={trafficStatusStyle} />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<TtwPassage line={props.line} destination={props.destination} index={0} style={styles.firstPassage}
|
<TtwPassage line={props.line} destination={props.destination} index={0}
|
||||||
|
style={styles.firstPassage} withPlatformStyle={styles.withPlatformFirstPassage}
|
||||||
fontSize={50} fallbackStyle={styles.unavailableFirstPassage} />
|
fontSize={50} fallbackStyle={styles.unavailableFirstPassage} />
|
||||||
<TtwPassage line={props.line} destination={props.destination} index={1} style={styles.secondPassage}
|
<TtwPassage line={props.line} destination={props.destination} index={1}
|
||||||
|
style={styles.secondPassage} withPlatformStyle={styles.withPlatformSecondPassage}
|
||||||
fontSize={45} fallbackStyle={styles.unavailableSecondPassage} />
|
fontSize={45} fallbackStyle={styles.unavailableSecondPassage} />
|
||||||
</div >
|
</div >
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user