diff --git a/package.json b/package.json index b2f70b9..f09a4cd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "srjp-td2", "private": true, - "version": "1.1.0", + "version": "1.1.1", "type": "module", "scripts": { "dev": "vite --mode staging", diff --git a/src/components/Timetable/TimetableContent.vue b/src/components/Timetable/TimetableContent.vue index a355a8b..d93e713 100644 --- a/src/components/Timetable/TimetableContent.vue +++ b/src/components/Timetable/TimetableContent.vue @@ -285,7 +285,7 @@ - + @@ -305,6 +305,28 @@
{{ row.stockMass }}{{ Math.floor(row.stockMass / 1000) }}
{{ row.stockLength }}
+ +
+ Kursuje: +
+ - {{ parseTimetableRunDate(computedTimetableRows[0].scheduledDepartureDate!) }} + + - + {{ + parseTimetableRunDate( + computedTimetableRows[computedTimetableRows.length - 1].scheduledArrivalDate! + ) + }} + +
+ +
+ Uwagi do rozkładu: +
- {{ timetableWarnings }}
+
+
@@ -313,6 +335,7 @@ import { computed } from 'vue'; import { useApiStore } from '../../stores/api.store'; import { useGlobalStore } from '../../stores/global.store'; import type { SceneryRoute, StopRow, TimetablePathData } from '../../types/common.types'; +import { parseTimetableRunDate } from '../../utils/dateUtils'; const globalStore = useGlobalStore(); const apiStore = useApiStore(); @@ -320,6 +343,14 @@ const apiStore = useApiStore(); // Tymczasowa tabelka z posterunkami APO const apoNames = ['Stary Kisielin, pe', 'Czerwony Dwór, pe', 'Szczejkowice, pe']; +const timetableWarnings = computed(() => { + const timetableData = globalStore.currentTimetableData; + + if (!timetableData) return ''; + + return timetableData.warningNotes; +}); + const computedTimetableRows = computed(() => { const timetableData = globalStore.currentTimetableData; @@ -328,7 +359,7 @@ const computedTimetableRows = computed(() => { let timeFrom = Date.now(); const stockVmax = timetableData.trainMaxSpeed, - stockMass = Math.floor(timetableData.mass / 1000), + stockMass = timetableData.mass, stockLength = timetableData.length; const timetablePath = parseTimetablePath(timetableData.path); diff --git a/src/mixins/useVehicleMixin.ts b/src/mixins/useVehicleMixin.ts new file mode 100644 index 0000000..4e65c99 --- /dev/null +++ b/src/mixins/useVehicleMixin.ts @@ -0,0 +1,25 @@ +import { useApiStore } from '../stores/api.store'; + +export function useVehicleMixin() { + const apiStore = useApiStore(); + + /** + * Gets loco load (obc. lok.) in tons - effectively train mass without locomotive or lone locomotive / unit mass + */ + function getLocoLoad(trainMass: number, stockString: string) { + if (!apiStore.vehiclesData) return trainMass; + + const stockArray = stockString.split(';'); + const headUnitsNames = stockArray.slice(0, 3).filter((v) => /-\d{3,}$/.test(v)); + + if (headUnitsNames.length == 1 && stockArray.length == 1) return trainMass; + + const headVehicleData = apiStore.vehiclesData.find((v) => v.name == headUnitsNames[0]); + + if (!headVehicleData) return trainMass; + + return Math.min(trainMass, trainMass - headVehicleData.group.weight); + } + + return { getLocoLoad }; +} diff --git a/src/stores/api.store.ts b/src/stores/api.store.ts index e749e29..9c2c31e 100644 --- a/src/stores/api.store.ts +++ b/src/stores/api.store.ts @@ -4,9 +4,15 @@ import { defineStore } from 'pinia'; import { DataStatus, type ActiveDataResponse, - type SceneriesDataResponse + type SceneriesDataResponse, + type VehiclesDataResponse } from '../types/api.types'; -import type { ActiveData, JournalTimetableShort, SceneryData } from '../types/common.types'; +import type { + ActiveData, + JournalTimetableShort, + SceneryData, + VehicleData +} from '../types/common.types'; let activeDataInterval = -1; @@ -17,6 +23,7 @@ export const useApiStore = defineStore('api', { activeData: null as ActiveData | null, sceneryData: null as SceneryData[] | null, + vehiclesData: null as VehicleData[] | null, journalTimetablesData: null as JournalTimetableShort[] | null, outdatedTimerId: -1, @@ -57,6 +64,8 @@ export const useApiStore = defineStore('api', { }, 25000); this.fetchSceneriesData(); + this.fetchVehiclesData(); + await this.fetchActiveData(); }, @@ -86,6 +95,16 @@ export const useApiStore = defineStore('api', { } catch (error) { console.error(error); } + }, + + async fetchVehiclesData() { + try { + const response = (await this.client!.get('/api/getVehicles')).data; + + this.vehiclesData = response; + } catch (error) { + console.error(error); + } } } }); diff --git a/src/stores/global.store.ts b/src/stores/global.store.ts index bbd8d10..67a4134 100644 --- a/src/stores/global.store.ts +++ b/src/stores/global.store.ts @@ -7,6 +7,7 @@ import type { ViewMode } from '../types/common.types'; import { getHeadUnits } from '../utils/trainUtils'; +import { useVehicleMixin } from '../mixins/useVehicleMixin'; export const useGlobalStore = defineStore('global', { state: () => ({ @@ -48,6 +49,8 @@ export const useGlobalStore = defineStore('global', { }, currentTimetableData(): TimetableData | null { + const vehicleUtils = useVehicleMixin(); + if (this.viewMode == 'active') { const selectedTrain = this.selectedActiveTrain; @@ -55,7 +58,7 @@ export const useGlobalStore = defineStore('global', { return { trainNo: selectedTrain.trainNo, - mass: selectedTrain.mass, + mass: vehicleUtils.getLocoLoad(selectedTrain.mass, selectedTrain.stockString), length: selectedTrain.length, driverId: selectedTrain.driverId, driverName: selectedTrain.driverName, @@ -88,7 +91,10 @@ export const useGlobalStore = defineStore('global', { return { journalCreatedAt: new Date(selectedTimetable.createdAt).getTime(), trainNo: selectedTimetable.trainNo, - mass: selectedTimetable.stockMass, + mass: vehicleUtils.getLocoLoad( + selectedTimetable.stockMass, + selectedTimetable.stockString + ), length: selectedTimetable.stockLength, driverId: selectedTimetable.driverId, driverName: selectedTimetable.driverName, diff --git a/src/types/api.types.ts b/src/types/api.types.ts index 4023799..868c4fc 100644 --- a/src/types/api.types.ts +++ b/src/types/api.types.ts @@ -1,14 +1,16 @@ -import type { ActiveData, JournalTimetableShort, SceneryData } from './common.types'; +import type { ActiveData, JournalTimetableShort, SceneryData, VehicleData } from './common.types'; export type ActiveDataResponse = ActiveData; export type SceneriesDataResponse = SceneryData[]; -export type JournalTimetablesShortResponse = JournalTimetableShort[]; +export type JournalTimetablesShortResponse = JournalTimetableShort[]; + +export type VehiclesDataResponse = VehicleData[]; export enum DataStatus { 'INIT' = -1, 'LOADING' = 0, 'SUCCESS' = 1, - 'ERROR' = 2, + 'ERROR' = 2 } diff --git a/src/types/common.types.ts b/src/types/common.types.ts index 6e44557..cbb57f0 100644 --- a/src/types/common.types.ts +++ b/src/types/common.types.ts @@ -286,3 +286,47 @@ export interface TimetableData { savedTimestamp?: number; journalCreatedAt?: number; } + +export interface VehicleData { + id: number; + name: string; + type: string; + group: VehicleGroup; + cabinName?: string; + restrictions?: VehicleRestrictions; + simulatorVersion: string; +} + +export interface VehicleRestrictions { + sponsorOnly?: number; + teamOnly?: boolean; +} + +export interface VehicleGroup { + id: number; + name: string; + speed: number; + speedLoaded?: number; + speedLoco?: number; + length: number; + weight: number; + cargoTypes?: VehicleCargoType[]; + locoProps?: VehicleLocoProps; + massSpeeds?: VehicleMassSpeeds; +} + +export interface VehicleCargoType { + id: string; + weight: number; +} + +export interface VehicleLocoProps { + coldStart: boolean; + doubleManned: boolean; +} + +export interface VehicleMassSpeeds { + none: number; + cargo?: Record; + passenger?: Record; +} diff --git a/src/utils/dateUtils.ts b/src/utils/dateUtils.ts new file mode 100644 index 0000000..ca76854 --- /dev/null +++ b/src/utils/dateUtils.ts @@ -0,0 +1,8 @@ +const romanMonthDigits = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII']; + +export function parseTimetableRunDate(date: Date) { + return `${date.getDate()}.${romanMonthDigits[date.getMonth()]}.${date + .getFullYear() + .toString() + .slice(2)}`; +} diff --git a/src/utils/trainUtils.ts b/src/utils/trainUtils.ts index 602a71b..80b7a33 100644 --- a/src/utils/trainUtils.ts +++ b/src/utils/trainUtils.ts @@ -42,4 +42,4 @@ export function getHeadUnits(stockString: string) { return acc; }, [] as string[]); -} +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index e10c9db..a64eaa6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -14,9 +14,12 @@ export default defineConfig({ cleanupOutdatedCaches: true, runtimeCaching: [ { - urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/getSceneries/i, + urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/(getSceneries|getVehicles)/i, handler: 'NetworkFirst', options: { + expiration: { + maxAgeSeconds: 3600 + }, cacheName: 'stacjownik-api-cache', cacheableResponse: { statuses: [0, 200] } }