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",
"private": true,
"version": "1.1.0",
"version": "1.1.1",
"type": "module",
"scripts": {
"dev": "vite --mode staging",
+33 -2
View File
@@ -285,7 +285,7 @@
<table class="h-full w-full border-collapse">
<tbody>
<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>
<td>{{ row.stockLength }}</td>
@@ -305,6 +305,28 @@
</tr>
</tbody>
</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>
</template>
@@ -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);
+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 {
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<VehiclesDataResponse>('/api/getVehicles')).data;
this.vehiclesData = response;
} catch (error) {
console.error(error);
}
}
}
});
+8 -2
View File
@@ -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,
+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;
@@ -6,9 +6,11 @@ export type SceneriesDataResponse = SceneryData[];
export type JournalTimetablesShortResponse = JournalTimetableShort[];
export type VehiclesDataResponse = VehicleData[];
export enum DataStatus {
'INIT' = -1,
'LOADING' = 0,
'SUCCESS' = 1,
'ERROR' = 2,
'ERROR' = 2
}
+44
View File
@@ -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<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,
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] }
}