mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 13:28:11 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2727350837 | |||
| 6c3af0a8d3 | |||
| e784202a36 | |||
| c24f691693 | |||
| 3aeabd63c9 | |||
| 4c79376318 | |||
| bc1c446c37 | |||
| fba335d0c7 | |||
| b4e536da40 | |||
| 8cde8e6323 | |||
| d7a9e93978 | |||
| 69aa62e77f | |||
| 4b842627fb |
Generated
-6962
File diff suppressed because it is too large
Load Diff
+7
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "stacjownik",
|
||||
"version": "1.30.4",
|
||||
"version": "1.30.5",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -17,7 +17,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.42.0",
|
||||
"dotenv": "^16.5.0",
|
||||
"dotenv": "^17.2.2",
|
||||
"pinia": "^3.0.2",
|
||||
"sass": "^1.87.0",
|
||||
"showdown": "^2.1.0",
|
||||
@@ -26,17 +26,17 @@
|
||||
"vue-router": "^4.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.15.15",
|
||||
"@types/node": "^24.3.1",
|
||||
"@types/showdown": "^2.0.6",
|
||||
"@vite-pwa/assets-generator": "^1.0.0",
|
||||
"@vitejs/plugin-vue": "^5.1.0",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"axios": "^1.9.0",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^6.3.5",
|
||||
"vite": "^7.1.4",
|
||||
"vite-plugin-pwa": "^1.0.0",
|
||||
"vue-tsc": "^2.0.28"
|
||||
"vue-tsc": "^3.0.6"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
||||
@@ -43,8 +43,12 @@
|
||||
<span :class="{ 'no-catenary': !route.isElectric, internal: route.isInternal }">
|
||||
{{ route.routeName }}
|
||||
</span>
|
||||
<span v-if="route.routeSpeed" class="speed">{{ route.routeSpeed }}</span>
|
||||
<span v-if="route.routeSpeedExit" class="speed">| {{ route.routeSpeedExit }}</span>
|
||||
<span v-if="route.routeSpeed" class="speed">
|
||||
<span>{{ route.routeSpeed }}</span>
|
||||
<span v-if="route.routeSpeedExit && route.routeSpeedExit != route.routeSpeed">
|
||||
| {{ route.routeSpeedExit }}
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="route.routeLength" class="length">
|
||||
{{ (route.routeLength / 1000).toFixed(1) + 'km' }}
|
||||
</span>
|
||||
@@ -156,7 +160,7 @@ ul.routes-list {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
|
||||
span {
|
||||
& > span {
|
||||
padding: 0.2em;
|
||||
background-color: #007599;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -87,7 +87,8 @@ export default defineComponent({
|
||||
const stop = train.timetableData?.followingStops.find(
|
||||
(stop) =>
|
||||
stop.stopNameRAW.toLowerCase() == name.toLowerCase() ||
|
||||
this.station?.generalInfo?.checkpoints.includes(stop.stopNameRAW)
|
||||
this.station?.generalInfo?.checkpoints.includes(stop.stopNameRAW) ||
|
||||
this.onlineScenery?.missingCheckpoints.includes(stop.stopNameRAW)
|
||||
);
|
||||
|
||||
const sceneryName =
|
||||
|
||||
@@ -54,6 +54,18 @@
|
||||
>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="timetable-checkpoints" v-else-if="onlineScenery">
|
||||
<template v-for="(ch, i) in onlineScenery.missingCheckpoints" :key="i">
|
||||
<template v-if="i > 0">•</template>
|
||||
<router-link
|
||||
class="checkpoint-item"
|
||||
:class="{ current: chosenCheckpoint === ch }"
|
||||
:to="`/scenery?station=${onlineScenery.name}&checkpoint=${ch}`"
|
||||
>{{ ch }}</router-link
|
||||
>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="timetable-list">
|
||||
@@ -287,6 +299,7 @@ export default defineComponent({
|
||||
|
||||
const chosenCheckpoint = ref(
|
||||
props.station?.generalInfo?.checkpoints[0] ??
|
||||
props.onlineScenery?.missingCheckpoints[0] ??
|
||||
props.station?.name ??
|
||||
route.query['station']?.toString() ??
|
||||
''
|
||||
@@ -365,21 +378,30 @@ export default defineComponent({
|
||||
|
||||
methods: {
|
||||
loadSelectedOption() {
|
||||
if (!this.station) return;
|
||||
|
||||
if (!this.station.generalInfo) {
|
||||
this.chosenCheckpoint = this.station.name;
|
||||
return;
|
||||
}
|
||||
|
||||
const queryCheckpoint = this.$route.query['checkpoint']?.toString();
|
||||
|
||||
this.chosenCheckpoint =
|
||||
this.station.generalInfo.checkpoints.find(
|
||||
(ch) => ch.toLocaleLowerCase() === queryCheckpoint?.toLocaleLowerCase()
|
||||
) ??
|
||||
this.station.generalInfo.checkpoints[0] ??
|
||||
this.station.name;
|
||||
let checkpointsListRef: string[] | null = null;
|
||||
let sceneryName = '';
|
||||
|
||||
if (this.station && this.station.generalInfo) {
|
||||
checkpointsListRef = this.station.generalInfo.checkpoints;
|
||||
sceneryName = this.station.name;
|
||||
} else if (this.onlineScenery) {
|
||||
checkpointsListRef = this.onlineScenery.missingCheckpoints;
|
||||
sceneryName = this.onlineScenery.name;
|
||||
} else if (this.station) {
|
||||
this.chosenCheckpoint = this.station.name;
|
||||
sceneryName = this.station.name;
|
||||
}
|
||||
|
||||
if (checkpointsListRef) {
|
||||
this.chosenCheckpoint =
|
||||
checkpointsListRef.find(
|
||||
(ch) => ch.toLocaleLowerCase() === queryCheckpoint?.toLocaleLowerCase()
|
||||
) ??
|
||||
checkpointsListRef[0] ??
|
||||
sceneryName;
|
||||
}
|
||||
},
|
||||
|
||||
setCheckpoint(cp: string) {
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="!train.online && train.lastSeen >= Date.now() - 60000"
|
||||
v-if="!train.online && train.lastSeen <= Date.now() - 60000"
|
||||
class="train-badge offline"
|
||||
>
|
||||
<i class="fa-solid fa-user-slash"></i>
|
||||
@@ -397,6 +397,7 @@ export default defineComponent({
|
||||
.status-badges {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-left: 0.25em;
|
||||
|
||||
gap: 0.25em;
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
id="search-active-driver"
|
||||
:placeholder="$t(`options.search-driver`)"
|
||||
v-model="searchedDriver"
|
||||
@focus="preventKeyDown = true"
|
||||
@blur="preventKeyDown = false"
|
||||
/>
|
||||
|
||||
<button class="btn btn--action search-exit" @click="onInputClear('driver')">
|
||||
|
||||
@@ -12,8 +12,16 @@
|
||||
:data-delayed="stop.departureDelay > 0"
|
||||
:data-stop-type="stop.type"
|
||||
:data-is-active="stop.isActive"
|
||||
:data-track-count-departure="stop.departureLineInfo?.routeTracks ?? 2"
|
||||
:data-track-count-arrival="stop.arrivalLineInfo?.routeTracks ?? 2"
|
||||
:data-track-count-departure="
|
||||
stop.departureLineInfo?.routeTracks ??
|
||||
stop.nextPointRef?.arrivalLineInfo?.routeTracks ??
|
||||
2
|
||||
"
|
||||
:data-track-count-arrival="
|
||||
stop.arrivalLineInfo?.routeTracks ??
|
||||
scheduleStops[i - 1]?.departureLineInfo?.routeTracks ??
|
||||
2
|
||||
"
|
||||
>
|
||||
<span class="stop_info">
|
||||
<span class="distance">
|
||||
@@ -60,7 +68,8 @@
|
||||
<span>
|
||||
|
|
||||
{{
|
||||
stop.departureLineInfo.routeSpeedExit
|
||||
stop.departureLineInfo.routeSpeedExit &&
|
||||
stop.departureLineInfo.routeSpeedExit != stop.departureLineInfo.routeSpeed
|
||||
? `${stop.departureLineInfo.routeSpeedExit} (${stop.departureLineInfo.routeSpeed})`
|
||||
: stop.departureLineInfo.routeSpeed
|
||||
}}</span
|
||||
@@ -113,10 +122,16 @@
|
||||
<span> {{ stop.nextPointRef.arrivalLine }}</span>
|
||||
|
||||
<span v-if="stop.nextPointRef.arrivalLineInfo">
|
||||
<span> | {{ stop.nextPointRef.arrivalLineInfo!.routeSpeed }}</span>
|
||||
<span v-if="stop.nextPointRef.arrivalLineInfo!.routeSpeedExit"
|
||||
>({{ stop.nextPointRef.arrivalLineInfo!.routeSpeedExit }})</span
|
||||
<span> | {{ stop.nextPointRef.arrivalLineInfo.routeSpeed }}</span>
|
||||
<span
|
||||
v-if="
|
||||
stop.nextPointRef.arrivalLineInfo.routeSpeedExit &&
|
||||
stop.nextPointRef.arrivalLineInfo.routeSpeedExit !=
|
||||
stop.nextPointRef.arrivalLineInfo.routeSpeed
|
||||
"
|
||||
>
|
||||
({{ stop.nextPointRef.arrivalLineInfo.routeSpeedExit }})
|
||||
</span>
|
||||
|
||||
<img
|
||||
:src="
|
||||
@@ -186,26 +201,28 @@ export default defineComponent({
|
||||
const sceneryData =
|
||||
this.store.stationList?.find((sc) => sc.name == pathEl.stationName) ?? null;
|
||||
|
||||
if (!sceneryData || !sceneryData.generalInfo) return null;
|
||||
|
||||
const activeScenery = this.apiStore.activeData?.activeSceneries?.find(
|
||||
(sc) => sc.stationName == pathEl.stationName
|
||||
);
|
||||
|
||||
const arrivalLineData = pathEl.arrivalRouteExt
|
||||
? (sceneryData.generalInfo.routes.all.find(
|
||||
(rt) => rt.routeName == pathEl.arrivalRouteExt
|
||||
) ?? null)
|
||||
const arrivalLineData = sceneryData?.generalInfo
|
||||
? pathEl.arrivalRouteExt
|
||||
? (sceneryData.generalInfo.routes.all.find(
|
||||
(rt) => rt.routeName == pathEl.arrivalRouteExt
|
||||
) ?? null)
|
||||
: null
|
||||
: null;
|
||||
|
||||
const departureLineData = pathEl.departureRouteExt
|
||||
? (sceneryData.generalInfo.routes.all.find(
|
||||
(rt) => rt.routeName == pathEl.departureRouteExt
|
||||
) ?? null)
|
||||
const departureLineData = sceneryData?.generalInfo
|
||||
? pathEl.departureRouteExt
|
||||
? (sceneryData.generalInfo.routes.all.find(
|
||||
(rt) => rt.routeName == pathEl.departureRouteExt
|
||||
) ?? null)
|
||||
: null
|
||||
: null;
|
||||
|
||||
return {
|
||||
generalInfo: sceneryData.generalInfo,
|
||||
generalInfo: sceneryData?.generalInfo ?? null,
|
||||
isOnline:
|
||||
activeScenery &&
|
||||
(activeScenery.isOnline == 1 || activeScenery.lastSeen >= Date.now() - 60000),
|
||||
@@ -234,7 +251,7 @@ export default defineComponent({
|
||||
let isActive = false;
|
||||
|
||||
if (pathData?.departureLineData) {
|
||||
// arrivalLineInfo = pathData.departureLineData;
|
||||
arrivalLineInfo = pathData.departureLineData;
|
||||
departureLineInfo = pathData.departureLineData;
|
||||
}
|
||||
|
||||
@@ -245,22 +262,16 @@ export default defineComponent({
|
||||
isExternal = true;
|
||||
|
||||
departureLineInfo = pathData?.arrivalLineData ?? null;
|
||||
|
||||
if (pathData?.arrivalLineData) {
|
||||
arrivalLineInfo = pathData.arrivalLineData;
|
||||
}
|
||||
arrivalLineInfo = pathData.arrivalLineData;
|
||||
}
|
||||
|
||||
let correctedDepartureLineData: StationRoutesInfo | null = null;
|
||||
|
||||
const internalRouteInfo = stop.departureLine
|
||||
? pathData?.generalInfo.routes.all.find(
|
||||
? pathData?.generalInfo?.routes.all.find(
|
||||
(route) => route.isInternal && route.routeName == stop.departureLine
|
||||
)
|
||||
: undefined;
|
||||
|
||||
if (internalRouteInfo) {
|
||||
correctedDepartureLineData = internalRouteInfo;
|
||||
departureLineInfo = internalRouteInfo;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -142,7 +142,7 @@
|
||||
"title": "Control type",
|
||||
"SPK": "SPK",
|
||||
"SCS": "SCS",
|
||||
"SCS-SPK": "SCS/SPK",
|
||||
"SCS-SPK": "SCS + SPK",
|
||||
"SPE": "SPE",
|
||||
"ręczne": "manual",
|
||||
"ręczne+SPK": "manual + SPK",
|
||||
@@ -153,7 +153,7 @@
|
||||
"abbrevs": {
|
||||
"SPK": "SPK",
|
||||
"SCS": "SCS",
|
||||
"SCS-SPK": "S/S",
|
||||
"SCS-SPK": "S+S",
|
||||
"SPE": "SPE",
|
||||
"ręczne": "R",
|
||||
"ręczne+SPK": "R",
|
||||
@@ -343,8 +343,8 @@
|
||||
"ASDEK": "ASDEK program available (defect detection of moving rolling stock)",
|
||||
"TWB-all": "This scenery has two-way route blockade on all routes",
|
||||
"TWB-routes": "This scenery has two-way route blockade on following routes: ",
|
||||
"default": "Scenery available in game package",
|
||||
"nonDefault": "Sceneria available to download from forum site",
|
||||
"default": "Scenery available in the game package",
|
||||
"nonDefault": "Scenery available to download from the forum site",
|
||||
"req-level": "all dispatcher levels | requries {lvl} dispatcher lvl | requires {lvl} dispatcher lvl",
|
||||
"non-public": "Non-public scenery",
|
||||
"unavailable": "Unavailable scenery",
|
||||
|
||||
+3
-3
@@ -139,7 +139,7 @@
|
||||
"title": "Sterowanie",
|
||||
"SPK": "SPK",
|
||||
"SCS": "SCS",
|
||||
"SCS-SPK": "SCS/SPK",
|
||||
"SCS-SPK": "SCS + SPK",
|
||||
"SPE": "SPE",
|
||||
"ręczne": "ręczne",
|
||||
"ręczne+SPK": "ręczne z SPK",
|
||||
@@ -150,7 +150,7 @@
|
||||
"abbrevs": {
|
||||
"SPK": "SPK",
|
||||
"SCS": "SCS",
|
||||
"SCS-SPK": "S/S",
|
||||
"SCS-SPK": "S+S",
|
||||
"SPE": "SPE",
|
||||
"ręczne": "R",
|
||||
"ręczne+SPK": "R",
|
||||
@@ -340,7 +340,7 @@
|
||||
"SUP": "Wymaga programu SUP do kontroli systemu RASP-UZK",
|
||||
"ASDEK": "Dostępny program ASDEK do detekcji stanów awaryjnych taboru w ruchu",
|
||||
"default": "Sceneria dostępna domyślnie w paczce z grą",
|
||||
"nonDefault": "Sceneria dostępna do pobrania ze strony forum",
|
||||
"nonDefault": "Sceneria dostępna do pobrania z forum symulatora",
|
||||
"req-level": "ogólnodostępna | od {lvl} poz. DR | od {lvl} poz. DR",
|
||||
"non-public": "Sceneria niepubliczna",
|
||||
"unavailable": "Sceneria niedostępna",
|
||||
|
||||
+50
-6
@@ -13,6 +13,7 @@ import { useApiStore } from './apiStore';
|
||||
import { MainStoreState } from './typings';
|
||||
|
||||
const checkpointsTrains: Map<string, CheckpointTrain[]> = new Map();
|
||||
const unknownSceneryCheckpoints: Map<string, Set<string>> = new Map();
|
||||
const sceneriesTrains: Map<string, Train[]> = new Map();
|
||||
|
||||
export const useMainStore = defineStore('mainStore', {
|
||||
@@ -42,6 +43,7 @@ export const useMainStore = defineStore('mainStore', {
|
||||
|
||||
checkpointsTrains.clear();
|
||||
sceneriesTrains.clear();
|
||||
unknownSceneryCheckpoints.clear();
|
||||
|
||||
const dateNow = new Date();
|
||||
|
||||
@@ -133,8 +135,13 @@ export const useMainStore = defineStore('mainStore', {
|
||||
|
||||
// Checkpoints trains map
|
||||
if (trainObj.timetableData) {
|
||||
let currentSceneryIndex = 0;
|
||||
const timetablePath = trainObj.timetableData.timetablePath;
|
||||
let currentSceneryIndex = 0;
|
||||
|
||||
let currentSceneryData: Station | null =
|
||||
this.stationList.find(
|
||||
(s) => s.name == timetablePath[currentSceneryIndex].stationName
|
||||
) ?? null;
|
||||
|
||||
trainObj.timetableData.followingStops.forEach((stop, i) => {
|
||||
if (/strong|podg|pe/.test(stop.stopName)) {
|
||||
@@ -153,16 +160,41 @@ export const useMainStore = defineStore('mainStore', {
|
||||
timetablePathElement: timetablePath[currentSceneryIndex]
|
||||
};
|
||||
|
||||
// Adding missing sceneries checkpoints as a fallback when scenery data is missing (and "generalInfo" is unavailable)
|
||||
if (!currentSceneryData) {
|
||||
const sceneryCheckpointsSet = unknownSceneryCheckpoints.get(
|
||||
checkpointTrain.timetablePathElement.stationName
|
||||
);
|
||||
|
||||
if (!sceneryCheckpointsSet) {
|
||||
unknownSceneryCheckpoints.set(
|
||||
checkpointTrain.timetablePathElement.stationName,
|
||||
new Set([stop.stopNameRAW])
|
||||
);
|
||||
} else {
|
||||
sceneryCheckpointsSet.add(stop.stopNameRAW);
|
||||
}
|
||||
}
|
||||
|
||||
// Adding trains to their corresponding checkpoints
|
||||
if (checkpointsTrains.has(stop.stopNameRAW.toLowerCase())) {
|
||||
checkpointsTrains.set(stop.stopNameRAW.toLowerCase(), [
|
||||
...checkpointsTrains.get(stop.stopNameRAW.toLowerCase())!,
|
||||
checkpointTrain
|
||||
]);
|
||||
} else checkpointsTrains.set(stop.stopNameRAW.toLowerCase(), [checkpointTrain]);
|
||||
} else {
|
||||
checkpointsTrains.set(stop.stopNameRAW.toLowerCase(), [checkpointTrain]);
|
||||
}
|
||||
}
|
||||
|
||||
if (timetablePath[currentSceneryIndex].departureRouteExt == stop.departureLine)
|
||||
if (timetablePath[currentSceneryIndex].departureRouteExt == stop.departureLine) {
|
||||
currentSceneryIndex++;
|
||||
|
||||
currentSceneryData =
|
||||
this.stationList.find(
|
||||
(s) => s.name == timetablePath[currentSceneryIndex].stationName
|
||||
) ?? null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -222,7 +254,9 @@ export const useMainStore = defineStore('mainStore', {
|
||||
all: 0,
|
||||
confirmed: 0,
|
||||
unconfirmed: 0
|
||||
}
|
||||
},
|
||||
|
||||
missingCheckpoints: []
|
||||
});
|
||||
});
|
||||
|
||||
@@ -266,7 +300,9 @@ export const useMainStore = defineStore('mainStore', {
|
||||
all: 0,
|
||||
confirmed: 0,
|
||||
unconfirmed: 0
|
||||
}
|
||||
},
|
||||
|
||||
missingCheckpoints: []
|
||||
});
|
||||
|
||||
return list;
|
||||
@@ -277,7 +313,7 @@ export const useMainStore = defineStore('mainStore', {
|
||||
for (let i = 0, n = allActiveSceneries.length; i < n; i++) {
|
||||
const scenery = allActiveSceneries[i];
|
||||
|
||||
const station = this.stationList.find((s) => s.name === scenery.name);
|
||||
let station = this.stationList.find((s) => s.name === scenery.name);
|
||||
|
||||
let checkpointsSet: Set<string> = new Set();
|
||||
|
||||
@@ -293,6 +329,14 @@ export const useMainStore = defineStore('mainStore', {
|
||||
scenery.stationTrains =
|
||||
sceneriesTrains.get(scenery.name)?.filter((sc) => sc.region == this.region.id) ?? [];
|
||||
|
||||
// Missing checkpoints as a fallback for sceneries without generalInfo & checkpoints property
|
||||
const missingCheckpointsToAdd = unknownSceneryCheckpoints.get(scenery.name);
|
||||
|
||||
if (missingCheckpointsToAdd) {
|
||||
checkpoints.push(...missingCheckpointsToAdd);
|
||||
scenery.missingCheckpoints.push(...missingCheckpointsToAdd);
|
||||
}
|
||||
|
||||
const uniqueTrainIds: string[] = [];
|
||||
checkpoints.forEach((cp) => {
|
||||
const scheduledTrains = checkpointsTrains.get(cp.toLowerCase());
|
||||
|
||||
@@ -36,6 +36,6 @@
|
||||
}
|
||||
|
||||
&.SCS-SPK {
|
||||
color: white;
|
||||
color: #aefff8;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ export interface ActiveScenery {
|
||||
confirmed: number;
|
||||
unconfirmed: number;
|
||||
};
|
||||
missingCheckpoints: string[];
|
||||
}
|
||||
|
||||
export interface ScenerySpawn {
|
||||
|
||||
Reference in New Issue
Block a user