From c524fe3c2e7fc0e6d079b231df7ee2b7bcd95752 Mon Sep 17 00:00:00 2001 From: Fred Boniface Date: Sun, 3 May 2026 20:58:22 +0100 Subject: [PATCH] Reorganise colouring of schedule times, add 'delay' column (E, RT, D). Including reusable function to assist. --- src/lib/components/ui/TrainService.svelte | 49 ++++++++++++++++++----- src/lib/utils/time.ts | 32 +++++++++++++++ 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/src/lib/components/ui/TrainService.svelte b/src/lib/components/ui/TrainService.svelte index 12bb4fb..e82fa97 100644 --- a/src/lib/components/ui/TrainService.svelte +++ b/src/lib/components/ui/TrainService.svelte @@ -3,9 +3,10 @@ import { OwlClient, ApiError, ValidationError } from '$lib/owlClient'; import { slide } from 'svelte/transition'; import { quintOut } from 'svelte/easing'; - import { formatUkTime } from '$lib/utils/time'; + import { formatUkTime, calculateDelay } from '$lib/utils/time'; import TocStyle from '$lib/components/ui/TocStyle.svelte'; import TiplocConverter from '$lib/components/ui/TiplocConverter.svelte'; + import { IconCircleArrowDownFilled } from '@tabler/icons-svelte'; let { service }: { service: ApiTrainsTrainByHeadcode.TrainByHeadcodeResponse } = $props(); let isExpanded = $state(false); let loadingDetails = $state(false); @@ -66,8 +67,9 @@
{service.dt}
- - +
+ +
{#if isExpanded && details} @@ -115,9 +117,10 @@ Location Plat Sch - Act + Est/Act Sch - Act + Est/Act + @@ -141,6 +144,10 @@ >{formatUkTime(loc.atd || loc.etd || '--')} {/if} + {#if loc} + {@const delay = calculateDelay(loc)} + {delay.val} + {/if} {/each} @@ -162,8 +169,10 @@ filter: brightness(1.1); } - .summary:hover { - filter: invert(); + @media (hover: hover) { + .train-service:hover { + filter: brightness(1.2); + } } .summary { @@ -248,6 +257,18 @@ color: red; } + .arrow { + padding: 0; + margin: 0; + margin-left: auto; + height: 25px; + transition: all 0.3s; + } + + .expanded { + transform: rotateX(180deg); + } + .box-ext { display: flex; flex-direction: column; @@ -319,11 +340,13 @@ .tpl-cell { color: yellow; + text-align: left; } .pass-loc { color: var(--color-title); opacity: 0.75; + font-style: oblique; } .can-loc { @@ -331,11 +354,19 @@ } .est { - font-style: oblique; + color: yellow; opacity: 0.5; } .act { - color: yellow; + color: white; + } + + .delay-late { + color: red; + } + + .delay-early { + color: blue; } diff --git a/src/lib/utils/time.ts b/src/lib/utils/time.ts index e6ac239..5830fd6 100644 --- a/src/lib/utils/time.ts +++ b/src/lib/utils/time.ts @@ -1,3 +1,4 @@ +import type { ApiTrainsTrainDetails } from '@owlboard/owlboard-ts'; /** * Converts ISO/JSON time to UK-formatted HH:MM string. * Ensures Europe/London timezone irrespective of browser timezone. @@ -15,3 +16,34 @@ export function formatUkTime(dateStr: string | Date | undefined): string { timeZone: 'Europe/London' }); } + +/** + * Calculates a 'delay' value, in the formats: + * RT, 1E, 7L, etc. + * @param 'Schedule Location' object + * @returns Delay string for departure boards + */ +export function calculateDelay(loc: ApiTrainsTrainDetails.ServiceLocation): {val: string, type: string} { +const pairs = [ + { actual: loc.atd, sched: loc.ptd ?? loc.wtd }, + { actual: loc.ata, sched: loc.pta ?? loc.wta }, + { actual: loc.atp, sched: loc.wtp } + ]; + + const match = pairs.find(p => p.actual && p.sched); + + if (!match || !match.actual || !match.sched) return {val: '', type: 'none'}; + + const diffMinutes = Math.round( + (Date.parse(match.actual) - Date.parse(match.sched)) / 60000 + ); + + if (diffMinutes === 0) return {val: 'RT', type: 'ontime'}; + + const absDiff = Math.abs(diffMinutes); + if (diffMinutes > 0) { + return { val: `${absDiff}L`, type: 'late' }; + } else { + return { val: `${absDiff}E`, type: 'early' }; + } +}