From 0174ddb8ab08d22041af482eec7e46b6b6286845 Mon Sep 17 00:00:00 2001 From: Spythere Date: Mon, 27 Jan 2025 19:13:31 +0100 Subject: [PATCH] chore: added outdated data indicator --- src/components/Timetable/TimetableBody.vue | 166 +------------------ src/components/Timetable/TimetableSelect.vue | 10 +- src/components/Timetable/TrainTimetable.vue | 166 ++++++++++++++++++- src/stores/api.store.ts | 22 ++- src/utils/trainUtils.ts | 21 +++ 5 files changed, 212 insertions(+), 173 deletions(-) create mode 100644 src/utils/trainUtils.ts diff --git a/src/components/Timetable/TimetableBody.vue b/src/components/Timetable/TimetableBody.vue index 8c967b1..2c67cff 100644 --- a/src/components/Timetable/TimetableBody.vue +++ b/src/components/Timetable/TimetableBody.vue @@ -1,5 +1,5 @@ diff --git a/src/components/Timetable/TimetableSelect.vue b/src/components/Timetable/TimetableSelect.vue index 4369c81..1125373 100644 --- a/src/components/Timetable/TimetableSelect.vue +++ b/src/components/Timetable/TimetableSelect.vue @@ -8,9 +8,9 @@ v-model="selectedTrainId" @change="selectTrain" > - + @@ -18,8 +18,9 @@ - @@ -30,6 +31,7 @@ import { useApiStore } from '../../stores/api.store'; import { DataStatus } from '../../types/api.types'; import { useGlobalStore } from '../../stores/global.store'; import { PrinterIcon, ArrowPathIcon } from '@heroicons/vue/16/solid'; +import { getRegionNameById } from '../../utils/trainUtils'; // Stores const apiStore = useApiStore(); @@ -38,8 +40,6 @@ const globalStore = useGlobalStore(); // Variables & refs let selectedTrainId = ref(null) as Ref; -// Computed - // Methods function selectTrain() { if (!apiStore.activeData) return; diff --git a/src/components/Timetable/TrainTimetable.vue b/src/components/Timetable/TrainTimetable.vue index f23aeb8..f402a7b 100644 --- a/src/components/Timetable/TrainTimetable.vue +++ b/src/components/Timetable/TrainTimetable.vue @@ -5,17 +5,177 @@ {{ globalStore.selectedTrain.timetable?.route.replace('|', ' - ') }} - +
- +
+ +
Wybierz aktywny pociąg, aby wygenerować SRJP
\ No newline at end of file +const apiStore = useApiStore(); + +const computedTimetable = computed(() => { + if (!globalStore.selectedTrain) return []; + + const timetable = globalStore.selectedTrain.timetable; + + if (!timetable) return []; + + let timeFrom = Date.now(); + + const headLocos = globalStore.selectedTrain.stockString + .split(';') + .slice(0, 3) + .filter((s, i) => i == 0 || /-\d+$/.test(s)) + .map((s) => s.slice(0, s.indexOf('-'))); + + const stockVmax = 70, + stockMass = Math.floor(globalStore.selectedTrain.mass / 1000), + stockLength = globalStore.selectedTrain.length; + + const timetablePath = timetable.path.split(';').map((pathEl) => { + const [arrivalLine, scenery, departureLine] = pathEl.split(','); + const sceneryName = scenery.split(' ').slice(0, -1).join(' '); + + const sceneryData = apiStore.sceneryData?.find((sc) => sc.name == sceneryName) ?? null; + const arrivalLineData = arrivalLine ? sceneryData?.routesInfo.find((rt) => rt.routeName == arrivalLine) ?? null : null; + const departureLineData = departureLine ? sceneryData?.routesInfo.find((rt) => rt.routeName == departureLine) ?? null : null; + + return { + sceneryName, + sceneryData: sceneryData ?? null, + arrivalLine: arrivalLine ?? '', + arrivalLineData, + departureLine: departureLine ?? '', + departureLineData, + }; + }); + + const stopRows: StopRow[] = []; + + let currentPathIndex = 0; + let currentPath = timetablePath[0]; + + let lastDepartureTimestamp = 0; + + let arrivalKm = 0, + arrivalSpeed = currentPath.departureLineData?.routeSpeed ?? 0, + arrivalTracks = currentPath.departureLineData?.routeTracks ?? 0; + + let departureSpeed = currentPath.departureLineData?.routeSpeed ?? 0, + departureTracks = currentPath.departureLineData?.routeTracks ?? 2; + + let realLineNo = 0; + + // console.debug('=========== ' + this.selectedTrain.trainNo + ' ==========='); + + for (const stop of timetable.stopList) { + if (stop.arrivalLine && stop.arrivalLine == currentPath.arrivalLine) { + arrivalKm = stop.stopDistance; + + if (currentPath.arrivalLineData) { + arrivalSpeed = currentPath.arrivalLineData.routeSpeed; + arrivalTracks = currentPath.arrivalLineData.routeTracks; + } + + departureSpeed = arrivalSpeed; + departureTracks = arrivalTracks; + } + + if (/^|, (podg|po)$|^(!_, pe)$/.test(stop.stopName)) { + let correctedDepartureSpeed = 0, + correctedDepartureTracks = 0; + + const internalRouteInfo = stop.departureLine + ? currentPath.sceneryData?.routesInfo.find((route) => route.isInternal && route.routeName == stop.departureLine) + : undefined; + + if (internalRouteInfo) { + correctedDepartureSpeed = internalRouteInfo.routeSpeed; + departureSpeed = internalRouteInfo.routeSpeed; + + correctedDepartureTracks = internalRouteInfo.routeTracks; + departureTracks = internalRouteInfo.routeTracks; + } + + let rowData: StopRow = { + isMain: /^/.test(stop.stopName), + pointKm: stop.stopDistance.toFixed(3), + pointName: stop.stopNameRAW, + scheduledArrivalDate: stop.arrivalTimestamp ? new Date(stop.arrivalTimestamp) : null, + scheduledDepartureDate: stop.departureTimestamp ? new Date(stop.departureTimestamp) : null, + stopTime: stop.stopTime ? (stop.departureTimestamp - stop.arrivalTimestamp) / 60000 : 0, + stopType: stop.stopType, + sceneryName: currentPath.sceneryName, + realLine: realLineNo == 0 ? ' - ' : realLineNo.toString(), + driveTime: lastDepartureTimestamp ? stop.arrivalTimestamp - lastDepartureTimestamp : 0, + additionalAbbrevs: [], + controlAbbrevs: [], + + arrivalKm: arrivalKm.toFixed(3), + departureKm: stop.stopDistance.toFixed(3), + + arrivalSpeed: arrivalSpeed, + arrivalTracks: arrivalTracks, + + departureSpeed: departureSpeed, + departureTracks: departureTracks, + + headLocos, + stockVmax, + stockLength, + stockMass, + }; + + // console.debug(stop.stopNameRAW, stop.departureLine); + + arrivalKm = stop.stopDistance; + arrivalSpeed = correctedDepartureSpeed || arrivalSpeed; + arrivalTracks = correctedDepartureTracks || arrivalTracks; + + if (stop.departureTimestamp) lastDepartureTimestamp = stop.departureTimestamp; + + stopRows.push(rowData); + } + + if (stop.departureLine && stop.departureLine == currentPath.departureLine) { + // Reverse search for last scenery checkpoint + for (let i = stopRows.length - 1; i > 0; i--) { + if (currentPath.departureLineData) { + stopRows[i].departureTracks = currentPath.departureLineData.routeTracks; + stopRows[i].departureSpeed = currentPath.departureLineData.routeSpeed; + stopRows[i].realLine = currentPath.departureLineData.realLineNo?.toString() ?? ' - '; + + if (stopRows[i].isMain || stopRows[i].pointName.endsWith(', podg')) { + stopRows[i].departureSpeed = currentPath.departureLineData.routeSpeed; + stopRows[i].departureTracks = currentPath.departureLineData.routeTracks; + break; + } + + stopRows[i].arrivalSpeed = currentPath.departureLineData.routeSpeed; + stopRows[i].arrivalTracks = currentPath.departureLineData.routeTracks; + } + } + + currentPath = timetablePath[++currentPathIndex]; + } + } + + let timeTo = Date.now(); + + globalStore.generatedMs = timeTo - timeFrom; + + return stopRows; +}); + diff --git a/src/stores/api.store.ts b/src/stores/api.store.ts index dc0b3b4..5fcb907 100644 --- a/src/stores/api.store.ts +++ b/src/stores/api.store.ts @@ -8,11 +8,14 @@ export const useApiStore = defineStore('api', { state() { return { client: null as AxiosInstance | null, - + activeData: null as ActiveData | null, sceneryData: null as SceneryData[] | null, - activeDataStatus: DataStatus.LOADING + outdatedTimerId: -1, + isActiveDataOutdated: false, + + activeDataStatus: DataStatus.LOADING, }; }, @@ -36,13 +39,13 @@ export const useApiStore = defineStore('api', { this.client = axios.create({ baseURL, }); - + this.fetchSceneriesData(); this.fetchActiveData(); - setInterval(() => { - this.fetchActiveData(); - }, 20000); + // setInterval(() => { + // this.fetchActiveData(); + // }, 20000); }, async fetchActiveData() { @@ -51,6 +54,13 @@ export const useApiStore = defineStore('api', { this.activeData = response; this.activeDataStatus = DataStatus.SUCCESS; + this.isActiveDataOutdated = false; + + if (this.outdatedTimerId != -1) clearTimeout(this.outdatedTimerId); + + this.outdatedTimerId = setTimeout(() => { + this.isActiveDataOutdated = true; + }, 30000); } catch (error) { console.error(error); } diff --git a/src/utils/trainUtils.ts b/src/utils/trainUtils.ts new file mode 100644 index 0000000..15ce848 --- /dev/null +++ b/src/utils/trainUtils.ts @@ -0,0 +1,21 @@ +export const getRegionNameById = (id: string) => { + switch (id) { + case 'eu': + return 'PL1'; + + case 'cae': + return 'PL2'; + + case 'us': + return 'CZE'; + + case 'usw': + return 'DE'; + + case 'ru': + return 'ENG'; + + default: + return 'PL1'; + } +};