Merge pull request #6 from Spythere/development

v1.1.1
This commit is contained in:
Spythere
2025-06-22 14:13:27 +02:00
committed by GitHub
10 changed files with 150 additions and 12 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "srjp-td2", "name": "srjp-td2",
"private": true, "private": true,
"version": "1.1.0", "version": "1.1.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --mode staging", "dev": "vite --mode staging",
+33 -2
View File
@@ -285,7 +285,7 @@
<table class="h-full w-full border-collapse"> <table class="h-full w-full border-collapse">
<tbody> <tbody>
<tr class="border-b-[1px] border-b-black dark:border-b-white"> <tr class="border-b-[1px] border-b-black dark:border-b-white">
<td>{{ row.stockMass }}</td> <td>{{ Math.floor(row.stockMass / 1000) }}</td>
</tr> </tr>
<tr> <tr>
<td>{{ row.stockLength }}</td> <td>{{ row.stockLength }}</td>
@@ -305,6 +305,28 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div class="mt-2">
<b><u>Kursuje:</u></b>
<div>
- {{ parseTimetableRunDate(computedTimetableRows[0].scheduledDepartureDate!) }}
<span
v-if="computedTimetableRows[computedTimetableRows.length - 1].scheduledArrivalDate!.getDate() != computedTimetableRows[0].scheduledDepartureDate!.getDate()"
>
-
{{
parseTimetableRunDate(
computedTimetableRows[computedTimetableRows.length - 1].scheduledArrivalDate!
)
}}
</span>
</div>
<div v-if="timetableWarnings.length != 0">
<b><u>Uwagi do rozkładu:</u></b>
<div>- {{ timetableWarnings }}</div>
</div>
</div>
</div> </div>
</template> </template>
@@ -313,6 +335,7 @@ import { computed } from 'vue';
import { useApiStore } from '../../stores/api.store'; import { useApiStore } from '../../stores/api.store';
import { useGlobalStore } from '../../stores/global.store'; import { useGlobalStore } from '../../stores/global.store';
import type { SceneryRoute, StopRow, TimetablePathData } from '../../types/common.types'; import type { SceneryRoute, StopRow, TimetablePathData } from '../../types/common.types';
import { parseTimetableRunDate } from '../../utils/dateUtils';
const globalStore = useGlobalStore(); const globalStore = useGlobalStore();
const apiStore = useApiStore(); const apiStore = useApiStore();
@@ -320,6 +343,14 @@ const apiStore = useApiStore();
// Tymczasowa tabelka z posterunkami APO // Tymczasowa tabelka z posterunkami APO
const apoNames = ['Stary Kisielin, pe', 'Czerwony Dwór, pe', 'Szczejkowice, pe']; 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 computedTimetableRows = computed(() => {
const timetableData = globalStore.currentTimetableData; const timetableData = globalStore.currentTimetableData;
@@ -328,7 +359,7 @@ const computedTimetableRows = computed(() => {
let timeFrom = Date.now(); let timeFrom = Date.now();
const stockVmax = timetableData.trainMaxSpeed, const stockVmax = timetableData.trainMaxSpeed,
stockMass = Math.floor(timetableData.mass / 1000), stockMass = timetableData.mass,
stockLength = timetableData.length; stockLength = timetableData.length;
const timetablePath = parseTimetablePath(timetableData.path); const timetablePath = parseTimetablePath(timetableData.path);
+25
View File
@@ -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 };
}
+21 -2
View File
@@ -4,9 +4,15 @@ import { defineStore } from 'pinia';
import { import {
DataStatus, DataStatus,
type ActiveDataResponse, type ActiveDataResponse,
type SceneriesDataResponse type SceneriesDataResponse,
type VehiclesDataResponse
} from '../types/api.types'; } 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; let activeDataInterval = -1;
@@ -17,6 +23,7 @@ export const useApiStore = defineStore('api', {
activeData: null as ActiveData | null, activeData: null as ActiveData | null,
sceneryData: null as SceneryData[] | null, sceneryData: null as SceneryData[] | null,
vehiclesData: null as VehicleData[] | null,
journalTimetablesData: null as JournalTimetableShort[] | null, journalTimetablesData: null as JournalTimetableShort[] | null,
outdatedTimerId: -1, outdatedTimerId: -1,
@@ -57,6 +64,8 @@ export const useApiStore = defineStore('api', {
}, 25000); }, 25000);
this.fetchSceneriesData(); this.fetchSceneriesData();
this.fetchVehiclesData();
await this.fetchActiveData(); await this.fetchActiveData();
}, },
@@ -86,6 +95,16 @@ export const useApiStore = defineStore('api', {
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }
},
async fetchVehiclesData() {
try {
const response = (await this.client!.get<VehiclesDataResponse>('/api/getVehicles')).data;
this.vehiclesData = response;
} catch (error) {
console.error(error);
}
} }
} }
}); });
+8 -2
View File
@@ -7,6 +7,7 @@ import type {
ViewMode ViewMode
} from '../types/common.types'; } from '../types/common.types';
import { getHeadUnits } from '../utils/trainUtils'; import { getHeadUnits } from '../utils/trainUtils';
import { useVehicleMixin } from '../mixins/useVehicleMixin';
export const useGlobalStore = defineStore('global', { export const useGlobalStore = defineStore('global', {
state: () => ({ state: () => ({
@@ -48,6 +49,8 @@ export const useGlobalStore = defineStore('global', {
}, },
currentTimetableData(): TimetableData | null { currentTimetableData(): TimetableData | null {
const vehicleUtils = useVehicleMixin();
if (this.viewMode == 'active') { if (this.viewMode == 'active') {
const selectedTrain = this.selectedActiveTrain; const selectedTrain = this.selectedActiveTrain;
@@ -55,7 +58,7 @@ export const useGlobalStore = defineStore('global', {
return { return {
trainNo: selectedTrain.trainNo, trainNo: selectedTrain.trainNo,
mass: selectedTrain.mass, mass: vehicleUtils.getLocoLoad(selectedTrain.mass, selectedTrain.stockString),
length: selectedTrain.length, length: selectedTrain.length,
driverId: selectedTrain.driverId, driverId: selectedTrain.driverId,
driverName: selectedTrain.driverName, driverName: selectedTrain.driverName,
@@ -88,7 +91,10 @@ export const useGlobalStore = defineStore('global', {
return { return {
journalCreatedAt: new Date(selectedTimetable.createdAt).getTime(), journalCreatedAt: new Date(selectedTimetable.createdAt).getTime(),
trainNo: selectedTimetable.trainNo, trainNo: selectedTimetable.trainNo,
mass: selectedTimetable.stockMass, mass: vehicleUtils.getLocoLoad(
selectedTimetable.stockMass,
selectedTimetable.stockString
),
length: selectedTimetable.stockLength, length: selectedTimetable.stockLength,
driverId: selectedTimetable.driverId, driverId: selectedTimetable.driverId,
driverName: selectedTimetable.driverName, driverName: selectedTimetable.driverName,
+4 -2
View File
@@ -1,4 +1,4 @@
import type { ActiveData, JournalTimetableShort, SceneryData } from './common.types'; import type { ActiveData, JournalTimetableShort, SceneryData, VehicleData } from './common.types';
export type ActiveDataResponse = ActiveData; export type ActiveDataResponse = ActiveData;
@@ -6,9 +6,11 @@ export type SceneriesDataResponse = SceneryData[];
export type JournalTimetablesShortResponse = JournalTimetableShort[]; export type JournalTimetablesShortResponse = JournalTimetableShort[];
export type VehiclesDataResponse = VehicleData[];
export enum DataStatus { export enum DataStatus {
'INIT' = -1, 'INIT' = -1,
'LOADING' = 0, 'LOADING' = 0,
'SUCCESS' = 1, 'SUCCESS' = 1,
'ERROR' = 2, 'ERROR' = 2
} }
+44
View File
@@ -286,3 +286,47 @@ export interface TimetableData {
savedTimestamp?: number; savedTimestamp?: number;
journalCreatedAt?: 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<string, number>;
passenger?: Record<string, number>;
}
+8
View File
@@ -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)}`;
}
+4 -1
View File
@@ -14,9 +14,12 @@ export default defineConfig({
cleanupOutdatedCaches: true, cleanupOutdatedCaches: true,
runtimeCaching: [ runtimeCaching: [
{ {
urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/getSceneries/i, urlPattern: /^https:\/\/stacjownik.spythere.eu\/api\/(getSceneries|getVehicles)/i,
handler: 'NetworkFirst', handler: 'NetworkFirst',
options: { options: {
expiration: {
maxAgeSeconds: 3600
},
cacheName: 'stacjownik-api-cache', cacheName: 'stacjownik-api-cache',
cacheableResponse: { statuses: [0, 200] } cacheableResponse: { statuses: [0, 200] }
} }