import { VoidComponent, createResource, onMount, ParentComponent, ParentProps, Show, useContext, For } from 'solid-js'; import { createDateNow, getTime } from '@solid-primitives/date'; import { timeline } from '@motionone/dom'; import { AnimationOptions } from '@motionone/types'; import { Motion } from "@motionone/solid"; import { Line, TrafficStatus } from './types'; import { renderLineTransportMode, renderLinePicto } from './utils'; import { BusinessDataContext, BusinessDataStore } from "./businessData"; import styles from './passagesPanel.module.css'; const UnavailablePassage: VoidComponent<{ style: string }> = (props) => { const textStyle = { fill: "#000000" }; return (
Information non disponible
); } const TtwPassage: VoidComponent<{ line: Line, destination: string, index: number, style: string, fontSize: number, fallbackStyle: string }> = (props) => { const businessDataContext: BusinessDataStore | undefined = useContext(BusinessDataContext); if (businessDataContext === undefined) return
; const { getDestinationPassages } = businessDataContext; const [dateNow] = createDateNow(10000); const transition: AnimationOptions = { duration: 3, repeat: Infinity }; return (() => { const passage = getDestinationPassages(props.line.id, props.destination)[props.index]; const refTs = passage !== undefined ? (passage.expectedDepartTs !== null ? passage.expectedDepartTs : passage.expectedArrivalTs) : 0; const ttwSec = refTs - (getTime(dateNow()) / 1000); const isApproaching = ttwSec <= 60; return ( >
{Math.floor(ttwSec / 60)} min
); }); } /* TODO: Manage end of service */ const DestinationPassages: VoidComponent<{ line: Line, destination: string }> = (props) => { /* TODO: Find where to get data to compute traffic status. */ const trafficStatusColor = new Map([ [TrafficStatus.UNKNOWN, "#ffffff"], [TrafficStatus.FLUID, "#00643c"], [TrafficStatus.DISRUPTED, "#ffbe00"], [TrafficStatus.VERY_DISRUPTED, "#ff5a00"], [TrafficStatus.BYPASSED, "#ffffff"] ]); // TODO: Manage traffic status // const trafficStatusStyle = { fill: trafficStatusColor.get(props.line.trafficStatus) }; const trafficStatusStyle = { fill: trafficStatusColor.get(TrafficStatus.UNKNOWN) }; let destinationViewboxRef: SVGSVGElement | undefined = undefined; let destinationTextRef: SVGTextElement | undefined = undefined; onMount(() => { if (destinationViewboxRef !== undefined && destinationTextRef !== undefined) { const overlap = destinationTextRef.getComputedTextLength() - destinationViewboxRef.viewBox.baseVal.width; if (overlap > 0) { timeline( [ [destinationTextRef, { x: [-overlap] }, { duration: 5 }], [destinationTextRef, { x: [0] }, { duration: 2 }], ], { repeat: Infinity }, ); } } }); return (
{renderLineTransportMode(props.line)}
{renderLinePicto(props.line, styles)}
{props.destination}
); } export type PassagesPanelComponentProps = ParentProps & { stopId: number, lineIds: string[], show: boolean }; export type PassagesPanelComponent = ParentComponent; export const PassagesPanel: PassagesPanelComponent = (props) => { const businessDataContext: BusinessDataStore | undefined = useContext(BusinessDataContext); if (businessDataContext === undefined) return
; const { getLine, getLineDestinations } = businessDataContext; const getLines = async (lineIds: string[]): Promise => { const lines = await Promise.all[]>(lineIds.map((lineId) => getLine(lineId))); return lines; } const [lines] = createResource(props.lineIds, getLines); return (
{(line) => {(destination) => } }
); }