From 7b9b63b4bc28bf751efbd559cac8bd96b0d3d2d0 Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 18:05:45 +0000 Subject: [PATCH 1/8] feat: platform 0, plus some fixes for inflections --- .../systems/stations/AmeyCelia.tsx | 6 ++ .../systems/stations/AmeyPhil.tsx | 61 ++++++++++++++----- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/announcement-data/systems/stations/AmeyCelia.tsx b/src/announcement-data/systems/stations/AmeyCelia.tsx index 73361ba85..6a5897003 100644 --- a/src/announcement-data/systems/stations/AmeyCelia.tsx +++ b/src/announcement-data/systems/stations/AmeyCelia.tsx @@ -15,6 +15,12 @@ export default class AmeyCelia extends AmeyPhil { readonly DelayCodeMapping = DelayCodeMapping + protected readonly genericOptions = { + platform: 's.platform-2', + platformZeroM: 'm.0', + platformZeroE: 'e.0', + } + protected readonly callingPointsOptions = { beforeCallingAtDelay: this.BEFORE_SECTION_DELAY, afterCallingAtDelay: 0, diff --git a/src/announcement-data/systems/stations/AmeyPhil.tsx b/src/announcement-data/systems/stations/AmeyPhil.tsx index a2ef9cb71..711889cbd 100644 --- a/src/announcement-data/systems/stations/AmeyPhil.tsx +++ b/src/announcement-data/systems/stations/AmeyPhil.tsx @@ -97,6 +97,13 @@ export default class AmeyPhil extends StationAnnouncementSystem { readonly DelayCodeMapping: Record = DelayCodeMapping + protected readonly genericOptions = { + platform: 's.platform-2', + platformZeroM: 'm.0', + // No end inflection + platformZeroE: 'm.0', + } + protected readonly callingPointsOptions = { beforeCallingAtDelay: this.BEFORE_SECTION_DELAY, afterCallingAtDelay: 0, @@ -844,9 +851,11 @@ export default class AmeyPhil extends StationAnnouncementSystem { } get PLATFORMS() { - return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - .flatMap(x => [`${x}`, `${x}a`, `${x}b`, `${x}c`, `${x}d`]) - .concat(['13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', 'a', 'b', 'c', 'd']) + return ['0'].concat( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + .flatMap(x => [`${x}`, `${x}a`, `${x}b`, `${x}c`, `${x}d`]) + .concat(['13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', 'a', 'b', 'c', 'd']), + ) } get STATIONS() { @@ -4303,21 +4312,27 @@ export default class AmeyPhil extends StationAnnouncementSystem { const plat = parseInt(options.platform) - function getPlatFiles(startDelay: number = 0) { + const getPlatFiles = (startDelay: number = 0) => { const platFiles: AudioItem[] = [] - if (plat <= 12 || ['a', 'b'].includes(options.platform.toLowerCase())) { + if (options.platform === '0') { + platFiles.push( + { id: this.genericOptions.platform, opts: { delayStart: 250 } }, + `m.0`, + options.isDelayed ? `m.for the delayed` : `m.for the`, + ) + } else if (plat <= 12 || ['a', 'b'].includes(options.platform.toLowerCase())) { platFiles.push({ id: `s.platform ${options.platform} for the`, opts: { delayStart: 250 } }) if (options.isDelayed) platFiles.push('m.delayed') } else if (plat >= 21) { - files.push( - { id: `s.platform`, opts: { delayStart: 250 } }, + platFiles.push( + { id: this.genericOptions.platform, opts: { delayStart: 250 } }, `mins.m.${options.platform}`, options.isDelayed ? `m.for the delayed` : `m.for the`, ) } else { platFiles.push( - { id: `s.platform`, opts: { delayStart: 250 } }, + { id: this.genericOptions.platform, opts: { delayStart: 250 } }, `platform.s.${options.platform}`, options.isDelayed ? `m.for the delayed` : `m.for the`, ) @@ -4414,8 +4429,10 @@ export default class AmeyPhil extends StationAnnouncementSystem { function getPlatFiles() { const platFiles: AudioItem[] = [] - if (plat >= 21) { - files.push(`mins.m.${options.platform}`, options.isDelayed ? `m.is the delayed` : `m.is the`) + if (options.platform === '0') { + platFiles.push(`m.0`, options.isDelayed ? `m.is the delayed` : `m.is the`) + } else if (plat >= 21) { + platFiles.push(`mins.m.${options.platform}`, options.isDelayed ? `m.is the delayed` : `m.is the`) } else { platFiles.push(`platform.s.${options.platform}`, options.isDelayed ? `m.is the delayed` : `m.is the`) } @@ -4579,7 +4596,17 @@ export default class AmeyPhil extends StationAnnouncementSystem { let plat = parseInt(options.platform) - files.push('s.stand well away from the edge of platform', plat >= 21 ? `mins.e.${options.platform}` : `platform.e.${options.platform}`, { + const platformAudio = (() => { + if (options.platform === '0') { + return `e.0` + } else if (isNaN(plat) || plat <= 20) { + return `platform.e.${options.platform}` + } else { + return `mins.e.${options.platform}` + } + })() + + files.push('s.stand well away from the edge of platform', platformAudio, { id: 'w.the approaching train is not scheduled to stop at this station', opts: { delayStart: this.BEFORE_SECTION_DELAY }, }) @@ -4602,7 +4629,9 @@ export default class AmeyPhil extends StationAnnouncementSystem { const plat = parseInt(options.platform) - if (plat <= 20 && options.platform.match(/^\d+$/)) { + if (options.platform === '0') { + files.push(`s.the train now approaching platform`, 'm.0') + } else if (plat <= 20 && options.platform.match(/^\d+$/)) { files.push(`s.the train now approaching platform ${plat}`) } else if (plat >= 21) { files.push(`s.the train now approaching platform`, `mins.m.${options.platform}`) @@ -4895,7 +4924,7 @@ export default class AmeyPhil extends StationAnnouncementSystem { }, platform: { name: 'Platform', - default: this.PLATFORMS[0], + default: this.PLATFORMS[1], options: this.PLATFORMS.map(p => ({ title: `Platform ${p.toUpperCase()}`, value: p })), type: 'select', }, @@ -5022,7 +5051,7 @@ export default class AmeyPhil extends StationAnnouncementSystem { }, platform: { name: 'Platform', - default: this.PLATFORMS[0], + default: this.PLATFORMS[1], options: this.PLATFORMS.map(p => ({ title: `Platform ${p.toUpperCase()}`, value: p })), type: 'select', }, @@ -5124,7 +5153,7 @@ export default class AmeyPhil extends StationAnnouncementSystem { }, platform: { name: 'Platform', - default: this.PLATFORMS[0], + default: this.PLATFORMS[1], options: this.PLATFORMS.map(p => ({ title: `Platform ${p.toUpperCase()}`, value: p })), type: 'select', }, @@ -5359,7 +5388,7 @@ export default class AmeyPhil extends StationAnnouncementSystem { }, platform: { name: 'Platform', - default: this.PLATFORMS[0], + default: this.PLATFORMS[1], options: this.PLATFORMS.map(p => ({ title: `Platform ${p.toUpperCase()}`, value: p })), type: 'select', }, From 658b3d686d0165437f21af78509ed78427889628 Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 18:06:42 +0000 Subject: [PATCH 2/8] fix: actually add plat 0 for celia --- src/announcement-data/systems/stations/AmeyCelia.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/announcement-data/systems/stations/AmeyCelia.tsx b/src/announcement-data/systems/stations/AmeyCelia.tsx index 6a5897003..a21ae380a 100644 --- a/src/announcement-data/systems/stations/AmeyCelia.tsx +++ b/src/announcement-data/systems/stations/AmeyCelia.tsx @@ -38,9 +38,11 @@ export default class AmeyCelia extends AmeyPhil { } get PLATFORMS() { - return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - .flatMap(x => [`${x}`, `${x}a`, `${x}b`, `${x}c`, `${x}d`]) - .concat(['13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']) + return ['0'].concat( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + .flatMap(x => [`${x}`, `${x}a`, `${x}b`, `${x}c`, `${x}d`]) + .concat(['13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']), + ) } protected get AVAILABLE_TOCS() { From dc788965b532cc40e6805a327962c48deeb36382 Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 18:22:50 +0000 Subject: [PATCH 3/8] chore: update changelog --- src/data/changelog.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/data/changelog.ts b/src/data/changelog.ts index db3919704..c51558951 100644 --- a/src/data/changelog.ts +++ b/src/data/changelog.ts @@ -378,6 +378,23 @@ const changelog: IChangelogVersion[] = [ additions: ['[Amey Live Trains] Announce Eurostar services'], fixes: ['[Amey Live Trains] Fix error when no stations are in calling points list'], }, + { + date: '2024-01-27', + fixes: ['[Amey Phil & Celia] Improved split handling'], + }, + { + date: '2024-01-28', + additions: ['[Amey Phil] More bodged station audio files (APY, ASF, AVP, BOW, BYL)'], + }, + { + date: '2024-02-08', + additions: [ + '[Amey Phil & Celia] Add Platform 0', + '[LNER Azuma] Add Reston station', + '[Amey Live Trains] Add option to announce legacy TOCs', + ], + fixes: ['[Amey Phil & Celia] Corrected audio files used for fast train announcements'], + }, ] export default changelog From c922d01785976b9ded78d45fecc874168cab4a6b Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 18:23:30 +0000 Subject: [PATCH 4/8] chore: update changelog again --- src/data/changelog.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/data/changelog.ts b/src/data/changelog.ts index c51558951..24f126691 100644 --- a/src/data/changelog.ts +++ b/src/data/changelog.ts @@ -388,11 +388,11 @@ const changelog: IChangelogVersion[] = [ }, { date: '2024-02-08', - additions: [ - '[Amey Phil & Celia] Add Platform 0', - '[LNER Azuma] Add Reston station', - '[Amey Live Trains] Add option to announce legacy TOCs', - ], + additions: ['[LNER Azuma] Add Reston station', '[Amey Live Trains] Add option to announce legacy TOCs'], + }, + { + date: '2024-02-09', + additions: ['[Amey Phil & Celia] Add Platform 0'], fixes: ['[Amey Phil & Celia] Corrected audio files used for fast train announcements'], }, ] From d1ed62a4ab31919268603f4f90361a213c06684d Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 19:24:54 +0000 Subject: [PATCH 5/8] feat: add activities per-stop in API --- cf-workers/src/get-services.ts | 73 ++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/cf-workers/src/get-services.ts b/cf-workers/src/get-services.ts index 4e539a584..bfa5f6071 100644 --- a/cf-workers/src/get-services.ts +++ b/cf-workers/src/get-services.ts @@ -1,5 +1,28 @@ import type { Env } from '.' +export interface AssociatedServiceDetail { + cancelReason: CancelLatenessReason | null + delayReason: CancelLatenessReason | null + isCharter: boolean + isPassengerService: boolean + category: string + sta: string + staSpecified: boolean + ata: string + ataSpecified: boolean + eta: string + etaSpecified: boolean + std: string + stdSpecified: boolean + atd: string + atdSpecified: boolean + etd: string + etdSpecified: boolean + rid: string + uid: string + locations: AssociatedServiceLocation[] +} + export interface StaffServicesResponse { trainServices: TrainService[] | null busServices: null @@ -18,14 +41,14 @@ export interface StaffServicesResponse { servicesAreUnavailable: boolean } -interface TrainService { +export interface TrainService { previousLocations: any - subsequentLocations: SubsequentLocation[] + subsequentLocations: TimingLocation[] cancelReason: CancelLatenessReason | null delayReason: CancelLatenessReason | null category: string activities: string - length: number + length: number | null isReverseFormation: boolean detachFront: boolean origin: EndPointLocation[] @@ -73,7 +96,7 @@ interface TrainService { adhocAlerts: any } -interface SubsequentLocation { +export interface TimingLocation { locationName: string tiploc: string crs?: string @@ -106,16 +129,29 @@ interface SubsequentLocation { lateness: any associations: Association[] | null adhocAlerts: any + activities?: string } -interface Association { +export enum AssociationCategory { + Join = 0, + Divide = 1, + LinkedFrom = 2, + LinkedTo = 3, +} + +interface AssociatedServiceLocation extends TimingLocation { + length: number | null + falseDest: null | EndPointLocation[] +} + +export interface Association { /** * 0: Join * 1: Divide * 2: Linked-From (last service) * 3: Linked-To (next service) */ - category: number + category: AssociationCategory rid: string uid: string trainid: string @@ -132,7 +168,7 @@ interface Association { /** * Added by this proxy */ - service: TrainService + service: Category extends AssociationCategory.Divide ? AssociatedServiceDetail : undefined } interface CancelLatenessReason { @@ -142,7 +178,7 @@ interface CancelLatenessReason { stationName?: string | null } -interface EndPointLocation { +export interface EndPointLocation { isOperationalEndPoint: boolean locationName: string crs: string @@ -160,9 +196,9 @@ interface NrccMessage { import TiplocToStation from './tiploc_to_station.json' -async function getServiceByRid(rid: string): Promise { +async function getServiceByRid(rid: string): Promise { const response = await fetch(`https://national-rail-api.davwheat.dev/service/${rid}`) - const json: TrainService = await response.json() + const json: AssociatedServiceDetail = await response.json() return json } @@ -196,33 +232,38 @@ export async function getServicesHandler(request: Request, env: Env, ctx: Execut const json: StaffServicesResponse = await response.json() for (const s in json.trainServices) { - const service: TrainService = json.trainServices[s] + const service: TrainService = json.trainServices[s as any] + const serviceData = await getServiceByRid(service.rid) if (service.cancelReason?.near) { - service.cancelReason.stationName = TiplocToStation[service.cancelReason.tiploc] || null + service.cancelReason.stationName = TiplocToStation[service.cancelReason.tiploc as keyof typeof TiplocToStation].crs || null } if (service.delayReason?.near) { - service.delayReason.stationName = TiplocToStation[service.delayReason.tiploc] || null + service.delayReason.stationName = TiplocToStation[service.delayReason.tiploc as keyof typeof TiplocToStation].crs || null } for (const l in service.subsequentLocations) { - const location: SubsequentLocation = service.subsequentLocations[l] + const location: TimingLocation = service.subsequentLocations[l] for (const a in location.associations) { - const association: Association = location.associations[a] + const association: Association = location.associations[a as any] // Joins/Divides only if ([0, 1].includes(association.category)) { ;(association as any).service = await getServiceByRid(association.rid) } } + + location.activities = serviceData.locations.find(l => { + return l.tiploc === location.tiploc && (l.sta === location.sta || l.std === location.std) + })?.activities } } return Response.json(json) } catch (ex) { - if (ex && ex.message) { + if (ex && ex instanceof Error) { return Response.json({ error: true, message: ex.message }) } else { return Response.json({ error: true, message: 'Unknown error' }) From aee8e025d8750a7f14d4f14ae0b71519ebaac4fe Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 19:25:42 +0000 Subject: [PATCH 6/8] chore: use interfaces directly from the api code --- src/components/AmeyLiveTrainAnnouncements.tsx | 210 +----------------- 1 file changed, 12 insertions(+), 198 deletions(-) diff --git a/src/components/AmeyLiveTrainAnnouncements.tsx b/src/components/AmeyLiveTrainAnnouncements.tsx index 338deb680..564f66f1d 100644 --- a/src/components/AmeyLiveTrainAnnouncements.tsx +++ b/src/components/AmeyLiveTrainAnnouncements.tsx @@ -7,6 +7,14 @@ import NREPowered from '@assets/NRE_Powered_logo.png' import FullScreen from 'react-fullscreen-crossbrowser' import Select from 'react-select' +import { + AssociationCategory, + type TrainService, + type StaffServicesResponse, + type TimingLocation, + type EndPointLocation, +} from '../../cf-workers/src/get-services' + import './AmeyLiveTrainAnnouncements.css' import type { CallingAtPoint } from '@components/CallingAtSelector' @@ -19,7 +27,7 @@ import type { IStandingTrainAnnouncementOptions, } from '../announcement-data/systems/stations/AmeyPhil' -import dayjs, { Dayjs } from 'dayjs' +import dayjs from 'dayjs' import dayjsUtc from 'dayjs/plugin/utc' import dayjsTz from 'dayjs/plugin/timezone' import Breakpoints from '@data/breakpoints' @@ -55,200 +63,6 @@ export interface LiveTrainAnnouncementsProps { standingTrainHandler: Record Promise> } -interface ServicesResponse { - trainServices: TrainService[] | null - busServices: null - ferryServices: null - isTruncated: boolean - generatedAt: string - locationName: string - crs: string - filterLocationName: null - filtercrs: null - filterType: number - stationManager: string - stationManagerCode: string - nrccMessages: NrccMessage[] - platformsAreHidden: boolean - servicesAreUnavailable: boolean -} - -interface TrainService { - previousLocations: any - subsequentLocations: TimingLocation[] - cancelReason: CancelReason | null - delayReason: DelayReason | null - category: string - activities: string - length: number - isReverseFormation: boolean - detachFront: boolean - origin: Origin[] - destination: Destination[] - currentOrigins: null | Origin[] - currentDestinations: null | Destination[] - formation: any - rid: string - uid: string - trainid: string - rsid: string | null - sdd: string - operator: string - operatorCode: string - isPassengerService: boolean - isCharter: boolean - isCancelled: boolean - isCircularRoute: boolean - filterLocationCancelled: boolean - filterLocationOperational: boolean - isOperationalCall: boolean - sta: string - staSpecified: boolean - ata: string - ataSpecified: boolean - eta: string - etaSpecified: boolean - arrivalType: number - arrivalTypeSpecified: boolean - arrivalSource: string | null - arrivalSourceInstance: any - std: string - stdSpecified: boolean - atd: string - atdSpecified: boolean - etd: string - etdSpecified: boolean - departureType: number - departureTypeSpecified: boolean - departureSource: string | null - departureSourceInstance: any - platform: string - platformIsHidden: boolean - serviceIsSupressed: boolean - adhocAlerts: any -} - -interface TimingLocation { - locationName: string - tiploc: string - crs?: string - isOperational: boolean - isPass: boolean - isCancelled: boolean - platform?: string - platformIsHidden: boolean - serviceIsSuppressed: boolean - sta: string - staSpecified: boolean - ata: string - ataSpecified: boolean - eta: string - etaSpecified: boolean - arrivalType: number - arrivalTypeSpecified: boolean - arrivalSource: string | null - arrivalSourceInstance: any - std: string - stdSpecified: boolean - atd: string - atdSpecified: boolean - etd: string - etdSpecified: boolean - departureType: number - departureTypeSpecified: boolean - departureSource: string | null - departureSourceInstance: any - lateness: any - associations?: Association[] - adhocAlerts: any -} - -interface AssociatedServiceLocation extends TimingLocation { - length: number | null - falseDest: null | Destination[] -} - -interface AssociatedServiceDetail { - cancelReason: CancelReason | null - delayReason: DelayReason | null - category: string - sta: string - staSpecified: boolean - ata: string - ataSpecified: boolean - eta: string - etaSpecified: boolean - std: string - stdSpecified: boolean - atd: string - atdSpecified: boolean - etd: string - etdSpecified: boolean - rid: string - uid: string - locations: AssociatedServiceLocation[] -} - -enum AssociationCategory { - Join = 0, - Divide = 1, -} - -interface Association { - category: Category - rid: string - uid: string - trainid: string - rsid?: string - sdd: string - origin: string - originCRS: string - originTiploc: string - destination: string - destCRS: string - destTiploc: string - isCancelled: boolean - service: Category extends AssociationCategory.Divide ? AssociatedServiceDetail : undefined -} - -interface CancelReason { - tiploc: string - near: boolean - value: number -} - -interface DelayReason { - tiploc: string - near: boolean - value: number -} - -interface Origin { - isOperationalEndPoint: boolean - locationName: string - crs: string - tiploc: string - via: any - futureChangeTo: number - futureChangeToSpecified: boolean -} - -interface Destination { - isOperationalEndPoint: boolean - locationName: string - crs: string - tiploc: string - via: any - futureChangeTo: number - futureChangeToSpecified: boolean -} - -interface NrccMessage { - category: number - severity: number - xhtmlMessage: string -} - type DisplayType = 'gtr-new' | 'tfwm-lcd' const MindTheGapStations: Record = { @@ -482,13 +296,13 @@ export function LiveTrainAnnouncements({ }, [removeOldIds]) const getStation = useCallback( - function getStation(location: TimingLocation | Destination | Origin, systemKey: SystemKeys): string { + function getStation(location: TimingLocation | EndPointLocation, systemKey: SystemKeys): string { return systems[systemKey].liveTrainsTiplocStationOverrides(location?.tiploc) ?? location.crs!! }, [systems], ) - const guessViaPoint = useCallback(function guessViaPoint(via: string, stops: (TimingLocation | Destination)[]): string | null { + const guessViaPoint = useCallback(function guessViaPoint(via: string, stops: (TimingLocation | EndPointLocation)[]): string | null { if (stationNameToCrsMap[via]) return stationNameToCrsMap[via] // Manual entries @@ -1009,7 +823,7 @@ export function LiveTrainAnnouncements({ } try { - const data: ServicesResponse = await resp.json() + const data: StaffServicesResponse = await resp.json() services = data.trainServices } catch { addLog("Couldn't parse JSON from API") From 4b5f6cd691dfaeef9fc0aa4044694cdd01b0788d Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 19:25:50 +0000 Subject: [PATCH 7/8] feat: announce request stops as such --- src/components/AmeyLiveTrainAnnouncements.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/AmeyLiveTrainAnnouncements.tsx b/src/components/AmeyLiveTrainAnnouncements.tsx index 564f66f1d..62aa1c9ee 100644 --- a/src/components/AmeyLiveTrainAnnouncements.tsx +++ b/src/components/AmeyLiveTrainAnnouncements.tsx @@ -371,6 +371,7 @@ export function LiveTrainAnnouncements({ crsCode: getStation(p, systemKey), name: '', randomId: '', + requestStop: p.activities === 'R', } p.associations @@ -387,7 +388,7 @@ export function LiveTrainAnnouncements({ if (!systems[systemKey].STATIONS.includes(s.crs)) return false return true }) - .map(l => ({ crsCode: l.crs!!, name: l.locationName, randomId: '' })) + .map(l => ({ crsCode: l.crs!!, name: l.locationName, randomId: '', requestStop: p.activities === 'R' })) }) return stop @@ -596,6 +597,7 @@ export function LiveTrainAnnouncements({ crsCode: getStation(p, systemKey), name: '', randomId: '', + requestStop: p.activities === 'R', } p.associations @@ -612,7 +614,7 @@ export function LiveTrainAnnouncements({ if (!systems[systemKey].STATIONS.includes(s.crs)) return false return true }) - .map(l => ({ crsCode: l.crs!!, name: l.locationName, randomId: '' })) + .map(l => ({ crsCode: l.crs!!, name: l.locationName, randomId: '', requestStop: p.activities === 'R' })) }) return stop @@ -1404,8 +1406,8 @@ export function LiveTrainAnnouncements({
  • are terminating at the selected station
  • - We also can't handle request stops, short platforms and several more features as this information isn't contained within the open data - provided by National Rail. + We also can't handle short platforms and some other features as this information isn't contained within the open data provided by + National Rail.

    {!hasEnabledFeature ? ( From 5876a4a9a57b7821e25b630a87004639c2975d0c Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Fri, 9 Feb 2024 19:36:48 +0000 Subject: [PATCH 8/8] chore: update changelog again --- src/data/changelog.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/changelog.ts b/src/data/changelog.ts index 24f126691..3069976ec 100644 --- a/src/data/changelog.ts +++ b/src/data/changelog.ts @@ -392,7 +392,7 @@ const changelog: IChangelogVersion[] = [ }, { date: '2024-02-09', - additions: ['[Amey Phil & Celia] Add Platform 0'], + additions: ['[Amey Phil & Celia] Add Platform 0', '[Amey Live Trains] Recognise and announce request stops'], fixes: ['[Amey Phil & Celia] Corrected audio files used for fast train announcements'], }, ]