mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-04 22:08:12 +00:00
refactor: optimization of train schedules
This commit is contained in:
@@ -60,10 +60,7 @@ export default defineComponent({
|
|||||||
htmlChangelog() {
|
htmlChangelog() {
|
||||||
if (this.mainStore.appUpdate == null) return '';
|
if (this.mainStore.appUpdate == null) return '';
|
||||||
|
|
||||||
const x = converter.makeHtml(this.mainStore.appUpdate.changelog);
|
return converter.makeHtml(this.mainStore.appUpdate.changelog);
|
||||||
console.log(x);
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
<div class="info-lists">
|
<div class="info-lists">
|
||||||
<!-- user list -->
|
<!-- user list -->
|
||||||
<SceneryInfoUserList :onlineScenery="onlineScenery" />
|
<SceneryInfoUserList :onlineScenery="onlineScenery" :station="station" />
|
||||||
|
|
||||||
<!-- spawn list -->
|
<!-- spawn list -->
|
||||||
<SceneryInfoSpawnList :onlineScenery="onlineScenery" />
|
<SceneryInfoSpawnList :onlineScenery="onlineScenery" />
|
||||||
|
|||||||
@@ -13,13 +13,13 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
v-for="train in onlineScenery?.stationTrains"
|
v-for="{ train, status } in stationTrains"
|
||||||
class="badge user"
|
class="badge user"
|
||||||
:class="train.stopStatus"
|
|
||||||
:key="train.trainId"
|
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click.prevent="selectModalTrain(train.trainId, $event.currentTarget)"
|
:key="train.id"
|
||||||
@keydown.enter="selectModalTrain(train.trainId, $event.currentTarget)"
|
:data-status="status"
|
||||||
|
@click.prevent="selectModalTrain(train.id, $event.currentTarget)"
|
||||||
|
@keydown.enter="selectModalTrain(train.id, $event.currentTarget)"
|
||||||
>
|
>
|
||||||
<span class="user_train">{{ train.trainNo }}</span>
|
<span class="user_train">{{ train.trainNo }}</span>
|
||||||
<span class="user_name">{{ train.driverName }}</span>
|
<span class="user_name">{{ train.driverName }}</span>
|
||||||
@@ -32,7 +32,9 @@
|
|||||||
import { PropType, defineComponent } from 'vue';
|
import { PropType, defineComponent } from 'vue';
|
||||||
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../../mixins/modalTrainMixin';
|
||||||
import routerMixin from '../../../mixins/routerMixin';
|
import routerMixin from '../../../mixins/routerMixin';
|
||||||
import { ActiveScenery } from '../../../typings/common';
|
import { ActiveScenery, Station, StopStatus } from '../../../typings/common';
|
||||||
|
import { getTrainStopStatus } from '../utils';
|
||||||
|
import { useMainStore } from '../../../store/mainStore';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [routerMixin, modalTrainMixin],
|
mixins: [routerMixin, modalTrainMixin],
|
||||||
@@ -41,6 +43,38 @@ export default defineComponent({
|
|||||||
onlineScenery: {
|
onlineScenery: {
|
||||||
type: Object as PropType<ActiveScenery>,
|
type: Object as PropType<ActiveScenery>,
|
||||||
required: false
|
required: false
|
||||||
|
},
|
||||||
|
station: {
|
||||||
|
type: Object as PropType<Station>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mainStore: useMainStore()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
stationTrains() {
|
||||||
|
if (!this.onlineScenery) return;
|
||||||
|
|
||||||
|
const name = this.station?.generalInfo?.checkpoints[0] ?? this.onlineScenery.name;
|
||||||
|
|
||||||
|
return this.onlineScenery.stationTrains.map((train) => {
|
||||||
|
const stop = train.timetableData?.followingStops.find(
|
||||||
|
(stop) => stop.stopNameRAW.toLowerCase() == name.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
const status = stop
|
||||||
|
? getTrainStopStatus(stop, train.currentStationName, this.onlineScenery!.name)
|
||||||
|
: 'no-timetable';
|
||||||
|
|
||||||
|
return {
|
||||||
|
train,
|
||||||
|
status
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -74,31 +108,31 @@ ul {
|
|||||||
-webkit-transition: background-color 200ms;
|
-webkit-transition: background-color 200ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.no-timetable .user_train {
|
&[data-status='no-timetable'] .user_train {
|
||||||
background-color: $no-timetable;
|
background-color: $no-timetable;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.departed > &_train {
|
&[data-status='departed'] > &_train {
|
||||||
background-color: $departed;
|
background-color: $departed;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.stopped > &_train {
|
&[data-status='stopped'] > &_train {
|
||||||
background-color: $stopped;
|
background-color: $stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.online > &_train {
|
&[data-status='online'] > &_train {
|
||||||
background-color: $online;
|
background-color: $online;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.terminated > &_train {
|
&[data-status='terminated'] > &_train {
|
||||||
background-color: $terminated;
|
background-color: $terminated;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disconnected > &_train {
|
&[data-status='disconnected'] > &_train {
|
||||||
background-color: $disconnected;
|
background-color: $disconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.offline {
|
&[data-status='offline'] {
|
||||||
background: firebrick;
|
background: firebrick;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<transition-group name="list-anim">
|
<transition-group name="list-anim">
|
||||||
<div
|
<div
|
||||||
style="padding-bottom: 5em"
|
style="padding-bottom: 5em"
|
||||||
v-if="apiStore.dataStatuses.connection == 0 && computedScheduledTrains.length == 0"
|
v-if="apiStore.dataStatuses.connection == 0 && sceneryTimetables.length == 0"
|
||||||
key="list-loading"
|
key="list-loading"
|
||||||
>
|
>
|
||||||
<Loading />
|
<Loading />
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
<span
|
<span
|
||||||
class="timetable-item empty"
|
class="timetable-item empty"
|
||||||
v-else-if="computedScheduledTrains.length == 0 && !onlineScenery"
|
v-else-if="sceneryTimetables.length == 0 && !onlineScenery"
|
||||||
key="list-offline"
|
key="list-offline"
|
||||||
>
|
>
|
||||||
{{ $t('scenery.offline') }}
|
{{ $t('scenery.offline') }}
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class="timetable-item empty"
|
class="timetable-item empty"
|
||||||
v-else-if="computedScheduledTrains.length == 0"
|
v-else-if="sceneryTimetables.length == 0"
|
||||||
key="list-no-timetables"
|
key="list-no-timetables"
|
||||||
>
|
>
|
||||||
{{ $t('scenery.no-timetables') }}
|
{{ $t('scenery.no-timetables') }}
|
||||||
@@ -65,59 +65,56 @@
|
|||||||
<div
|
<div
|
||||||
class="timetable-item"
|
class="timetable-item"
|
||||||
v-else
|
v-else
|
||||||
v-for="scheduledTrain in computedScheduledTrains"
|
v-for="row in sceneryTimetables"
|
||||||
:key="scheduledTrain.trainId + scheduledTrain.stopInfo.arrivalTimestamp"
|
:key="row.train.id + row.checkpointStop.arrivalTimestamp"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click.prevent.stop="selectModalTrain(scheduledTrain.trainId, $event.currentTarget)"
|
@click.prevent.stop="selectModalTrain(row.train.id, $event.currentTarget)"
|
||||||
@keydown.enter.prevent="selectModalTrain(scheduledTrain.trainId, $event.currentTarget)"
|
@keydown.enter.prevent="selectModalTrain(row.train.id, $event.currentTarget)"
|
||||||
>
|
>
|
||||||
<span class="timetable-general">
|
<span class="timetable-general">
|
||||||
<span class="general-info">
|
<span class="general-info">
|
||||||
<span class="info-number">
|
<span class="info-number">
|
||||||
<strong>{{ scheduledTrain.category }}</strong>
|
<strong>{{ row.train.timetableData!.category }}</strong>
|
||||||
{{ scheduledTrain.trainNo }}
|
{{ row.train.trainNo }}
|
||||||
|
|
||||||
<span
|
<span v-if="row.checkpointStop.comments" :title="row.checkpointStop.comments">
|
||||||
v-if="scheduledTrain.stopInfo.comments"
|
|
||||||
:title="scheduledTrain.stopInfo.comments"
|
|
||||||
>
|
|
||||||
<img src="/images/icon-warning.svg" />
|
<img src="/images/icon-warning.svg" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
|
||||||
<span>
|
<span>
|
||||||
{{ scheduledTrain.driverName }}
|
{{ row.train.driverName }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="info-route">
|
<div class="info-route">
|
||||||
<strong>{{ scheduledTrain.beginsAt }} - {{ scheduledTrain.terminatesAt }}</strong>
|
<strong>{{ row.train.timetableData!.route.replace('|', ' - ') }}</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ScheduledTrainStatus :scheduledTrain="scheduledTrain" />
|
<ScheduledTrainStatus :sceneryTimetableRow="row" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="timetable-schedule">
|
<span class="timetable-schedule">
|
||||||
<span class="schedule-arrival">
|
<span class="schedule-arrival">
|
||||||
<span class="arrival-time begins" v-if="scheduledTrain.stopInfo.beginsHere">
|
<span class="arrival-time begins" v-if="row.checkpointStop.beginsHere">
|
||||||
{{ $t('timetables.begins') }}
|
{{ $t('timetables.begins') }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="arrival-time" v-else>
|
<span class="arrival-time" v-else>
|
||||||
<div v-if="scheduledTrain.stopInfo.arrivalDelay == 0">
|
<div v-if="row.checkpointStop.arrivalDelay == 0">
|
||||||
<span>{{ timestampToString(scheduledTrain.stopInfo.arrivalTimestamp) }}</span>
|
<span>{{ timestampToString(row.checkpointStop.arrivalTimestamp) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div>
|
<div>
|
||||||
<s style="margin-right: 0.2em" class="text--grayed">{{
|
<s style="margin-right: 0.2em" class="text--grayed">{{
|
||||||
timestampToString(scheduledTrain.stopInfo.arrivalTimestamp)
|
timestampToString(row.checkpointStop.arrivalTimestamp)
|
||||||
}}</s>
|
}}</s>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{{ timestampToString(scheduledTrain.stopInfo.arrivalRealTimestamp) }}
|
{{ timestampToString(row.checkpointStop.arrivalRealTimestamp) }}
|
||||||
({{ scheduledTrain.stopInfo.arrivalDelay > 0 ? '+' : ''
|
({{ row.checkpointStop.arrivalDelay > 0 ? '+' : ''
|
||||||
}}{{ scheduledTrain.stopInfo.arrivalDelay }})
|
}}{{ row.checkpointStop.arrivalDelay }})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
@@ -125,41 +122,39 @@
|
|||||||
|
|
||||||
<span class="schedule-stop">
|
<span class="schedule-stop">
|
||||||
<span class="stop-connection">
|
<span class="stop-connection">
|
||||||
{{ scheduledTrain.arrivingLine }}
|
{{ row.arrivingLine }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="stop-time">
|
<span class="stop-time">
|
||||||
{{ scheduledTrain.stopInfo.stopTime || '' }}
|
{{ row.checkpointStop.stopTime || '' }}
|
||||||
{{
|
{{ row.checkpointStop.stopTime ? row.checkpointStop.stopType || 'pt' : '' }}
|
||||||
scheduledTrain.stopInfo.stopTime ? scheduledTrain.stopInfo.stopType || 'pt' : ''
|
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="stop-connection">
|
<span class="stop-connection">
|
||||||
{{ scheduledTrain.departureLine }}
|
{{ row.departureLine }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="schedule-departure">
|
<span class="schedule-departure">
|
||||||
<span class="departure-time terminates" v-if="scheduledTrain.stopInfo.terminatesHere">
|
<span class="departure-time terminates" v-if="row.checkpointStop.terminatesHere">
|
||||||
{{ $t('timetables.terminates') }}
|
{{ $t('timetables.terminates') }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="departure-time" v-else>
|
<span class="departure-time" v-else>
|
||||||
<div v-if="scheduledTrain.stopInfo.departureDelay == 0">
|
<div v-if="row.checkpointStop.departureDelay == 0">
|
||||||
<span>{{ timestampToString(scheduledTrain.stopInfo.departureTimestamp) }}</span>
|
<span>{{ timestampToString(row.checkpointStop.departureTimestamp) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div>
|
<div>
|
||||||
<s style="margin-right: 0.2em" class="text--grayed">{{
|
<s style="margin-right: 0.2em" class="text--grayed">{{
|
||||||
timestampToString(scheduledTrain.stopInfo.departureTimestamp)
|
timestampToString(row.checkpointStop.departureTimestamp)
|
||||||
}}</s>
|
}}</s>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{{ timestampToString(scheduledTrain.stopInfo.departureRealTimestamp) }}
|
{{ timestampToString(row.checkpointStop.departureRealTimestamp) }}
|
||||||
({{ scheduledTrain.stopInfo.departureDelay > 0 ? '+' : ''
|
({{ row.checkpointStop.departureDelay > 0 ? '+' : ''
|
||||||
}}{{ scheduledTrain.stopInfo.departureDelay }})
|
}}{{ row.checkpointStop.departureDelay }})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
@@ -183,6 +178,8 @@ import modalTrainMixin from '../../mixins/modalTrainMixin';
|
|||||||
import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
|
import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
|
||||||
import { useApiStore } from '../../store/apiStore';
|
import { useApiStore } from '../../store/apiStore';
|
||||||
import { ActiveScenery, Station } from '../../typings/common';
|
import { ActiveScenery, Station } from '../../typings/common';
|
||||||
|
import { SceneryTimetableRow } from './typings';
|
||||||
|
import { getTrainStopStatus, stopStatusPriority } from './utils';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SceneryTimetable',
|
name: 'SceneryTimetable',
|
||||||
@@ -204,10 +201,6 @@ export default defineComponent({
|
|||||||
listOpen: false
|
listOpen: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.loadSelectedOption();
|
|
||||||
},
|
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
this.loadSelectedOption();
|
this.loadSelectedOption();
|
||||||
},
|
},
|
||||||
@@ -241,27 +234,105 @@ export default defineComponent({
|
|||||||
return url;
|
return url;
|
||||||
},
|
},
|
||||||
|
|
||||||
computedScheduledTrains() {
|
sceneryTimetables(): SceneryTimetableRow[] {
|
||||||
if (!this.station) return [];
|
if (!this.station) return [];
|
||||||
|
if (!this.onlineScenery) return [];
|
||||||
|
|
||||||
return (
|
return this.onlineScenery.scheduledTrains
|
||||||
this.onlineScenery?.scheduledTrains
|
.filter(
|
||||||
?.filter(
|
(ct) =>
|
||||||
(train) =>
|
ct.train.region == this.mainStore.region.id &&
|
||||||
train.checkpointName.toLocaleLowerCase() ==
|
this.chosenCheckpoint &&
|
||||||
(this.chosenCheckpoint || this.station!.name).toLocaleLowerCase() &&
|
ct.checkpointStop.stopNameRAW.toLowerCase() == this.chosenCheckpoint.toLowerCase()
|
||||||
train.region == this.mainStore.region.id
|
)
|
||||||
)
|
.map((ct) => {
|
||||||
.sort((a, b) => {
|
const trainStopStatus = getTrainStopStatus(
|
||||||
if (a.stopStatusID > b.stopStatusID) return 1;
|
ct.checkpointStop,
|
||||||
if (a.stopStatusID < b.stopStatusID) return -1;
|
ct.train.currentStationName,
|
||||||
|
this.station!.name
|
||||||
|
);
|
||||||
|
|
||||||
if (a.stopInfo.arrivalTimestamp > b.stopInfo.arrivalTimestamp) return 1;
|
const trainStopIndex =
|
||||||
if (a.stopInfo.arrivalTimestamp < b.stopInfo.arrivalTimestamp) return -1;
|
ct.train.timetableData?.followingStops.findIndex(
|
||||||
|
(stop) => stop.stopName == ct.checkpointStop.stopName
|
||||||
|
) ?? -1;
|
||||||
|
|
||||||
return a.stopInfo.departureTimestamp > b.stopInfo.departureTimestamp ? 1 : -1;
|
let prevStationName = '',
|
||||||
}) || []
|
nextStationName = '';
|
||||||
);
|
|
||||||
|
let departureLine: string | null = null;
|
||||||
|
let arrivingLine: string | null = null;
|
||||||
|
|
||||||
|
let prevDepartureLine: string | null = null,
|
||||||
|
nextArrivalLine: string | null = null;
|
||||||
|
|
||||||
|
if (trainStopIndex > -1 && ct.train.timetableData?.followingStops !== undefined) {
|
||||||
|
for (let i = trainStopIndex; i >= 0; i--) {
|
||||||
|
const stop = ct.train.timetableData.followingStops[i];
|
||||||
|
|
||||||
|
if (
|
||||||
|
/strong|podg\.|pe\./g.test(stop.stopName) &&
|
||||||
|
!prevStationName &&
|
||||||
|
i <= trainStopIndex - 1
|
||||||
|
)
|
||||||
|
prevStationName = stop.stopNameRAW.replace(/,.*/g, '');
|
||||||
|
|
||||||
|
if (
|
||||||
|
stop.arrivalLine != null &&
|
||||||
|
!arrivingLine &&
|
||||||
|
!/-|_|it|sbl/gi.test(stop.arrivalLine)
|
||||||
|
) {
|
||||||
|
arrivingLine = stop.arrivalLine;
|
||||||
|
prevDepartureLine =
|
||||||
|
ct.train.timetableData.followingStops[i - 1]?.departureLine || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = trainStopIndex; i < ct.train.timetableData.followingStops.length; i++) {
|
||||||
|
const stop = ct.train.timetableData.followingStops[i];
|
||||||
|
|
||||||
|
if (
|
||||||
|
/strong|podg\.|pe\./g.test(stop.stopName) &&
|
||||||
|
!nextStationName &&
|
||||||
|
i > trainStopIndex
|
||||||
|
)
|
||||||
|
nextStationName = stop.stopNameRAW.replace(/,.*/g, '');
|
||||||
|
|
||||||
|
if (
|
||||||
|
stop.departureLine &&
|
||||||
|
!departureLine &&
|
||||||
|
!/-|_|it|sbl/gi.test(stop.departureLine)
|
||||||
|
) {
|
||||||
|
departureLine = stop.departureLine;
|
||||||
|
nextArrivalLine = ct.train.timetableData.followingStops[i + 1]?.arrivalLine || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
checkpointStop: ct.checkpointStop,
|
||||||
|
train: ct.train,
|
||||||
|
prevDepartureLine,
|
||||||
|
nextArrivalLine,
|
||||||
|
departureLine,
|
||||||
|
arrivingLine,
|
||||||
|
prevStationName,
|
||||||
|
nextStationName,
|
||||||
|
status: trainStopStatus
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (stopStatusPriority.indexOf(a.status) - stopStatusPriority.indexOf(b.status) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (stopStatusPriority.indexOf(a.status) - stopStatusPriority.indexOf(b.status) > 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (a.checkpointStop.arrivalTimestamp > b.checkpointStop.arrivalTimestamp) return 1;
|
||||||
|
if (a.checkpointStop.arrivalTimestamp < b.checkpointStop.arrivalTimestamp) return -1;
|
||||||
|
|
||||||
|
return a.checkpointStop.departureTimestamp > b.checkpointStop.departureTimestamp ? 1 : -1;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="general-status">
|
<div class="general-status">
|
||||||
<span
|
<span
|
||||||
:class="computedScheduledTrain.stopStatus"
|
:class="computedScheduledTrain.status"
|
||||||
:title="computedScheduledTrain.stopStatusDescription"
|
:title="computedScheduledTrain.stopStatusDescription"
|
||||||
>
|
>
|
||||||
{{ computedScheduledTrain.stopStatusIndicator }}
|
{{ computedScheduledTrain.stopStatusIndicator }}
|
||||||
@@ -11,25 +11,21 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import { ScheduledTrain, StopStatus } from '../../typings/common';
|
import { StopStatus } from '../../typings/common';
|
||||||
|
import { SceneryTimetableRow } from './typings';
|
||||||
interface ScheduledTrainComp extends ScheduledTrain {
|
|
||||||
stopStatusIndicator: string;
|
|
||||||
stopStatusDescription: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
scheduledTrain: {
|
sceneryTimetableRow: {
|
||||||
type: Object as PropType<ScheduledTrain>,
|
type: Object as PropType<SceneryTimetableRow>,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
computedScheduledTrain(): ScheduledTrainComp {
|
computedScheduledTrain() {
|
||||||
const { prevDepartureLine, prevStationName, stopStatus, nextArrivalLine, nextStationName } =
|
const { prevDepartureLine, prevStationName, nextArrivalLine, nextStationName, status } =
|
||||||
this.scheduledTrain;
|
this.sceneryTimetableRow;
|
||||||
|
|
||||||
const prevDepartureIndicator = prevDepartureLine
|
const prevDepartureIndicator = prevDepartureLine
|
||||||
? `(${prevDepartureLine}) ${prevStationName}`
|
? `(${prevDepartureLine}) ${prevStationName}`
|
||||||
@@ -41,7 +37,7 @@ export default defineComponent({
|
|||||||
let stopStatusDescription = '',
|
let stopStatusDescription = '',
|
||||||
stopStatusIndicator = '';
|
stopStatusIndicator = '';
|
||||||
|
|
||||||
switch (stopStatus) {
|
switch (status) {
|
||||||
case StopStatus.ARRIVING:
|
case StopStatus.ARRIVING:
|
||||||
stopStatusIndicator = `${this.$t('timetables.from')}: ${prevDepartureIndicator}`;
|
stopStatusIndicator = `${this.$t('timetables.from')}: ${prevDepartureIndicator}`;
|
||||||
stopStatusDescription = this.$t('timetables.desc-arriving', {
|
stopStatusDescription = this.$t('timetables.desc-arriving', {
|
||||||
@@ -56,7 +52,7 @@ export default defineComponent({
|
|||||||
? `${this.$t('timetables.to')}: ${nextArrivalIndicator}`
|
? `${this.$t('timetables.to')}: ${nextArrivalIndicator}`
|
||||||
: `${this.$t('timetables.desc-end')}`;
|
: `${this.$t('timetables.desc-end')}`;
|
||||||
stopStatusDescription = nextArrivalLine
|
stopStatusDescription = nextArrivalLine
|
||||||
? this.$t(`timetables.desc-${stopStatus}`, { nextStationName, nextArrivalLine })
|
? this.$t(`timetables.desc-${status}`, { nextStationName, nextArrivalLine })
|
||||||
: '';
|
: '';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -85,7 +81,7 @@ export default defineComponent({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...this.scheduledTrain,
|
...this.sceneryTimetableRow,
|
||||||
stopStatusDescription,
|
stopStatusDescription,
|
||||||
stopStatusIndicator
|
stopStatusIndicator
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { StopStatus, Train, TrainStop } from '../../typings/common';
|
||||||
|
|
||||||
|
export interface SceneryTimetableRow {
|
||||||
|
checkpointStop: TrainStop;
|
||||||
|
train: Train;
|
||||||
|
prevDepartureLine: string | null;
|
||||||
|
nextArrivalLine: string | null;
|
||||||
|
departureLine: string | null;
|
||||||
|
arrivingLine: string | null;
|
||||||
|
prevStationName: string | null;
|
||||||
|
nextStationName: string | null;
|
||||||
|
status: StopStatus;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { StopStatus, TrainStop } from '../../typings/common';
|
||||||
|
|
||||||
|
export const stopStatusPriority = [
|
||||||
|
StopStatus.ONLINE,
|
||||||
|
StopStatus.STOPPED,
|
||||||
|
StopStatus.DEPARTED,
|
||||||
|
StopStatus.ARRIVING,
|
||||||
|
StopStatus.DEPARTED_AWAY,
|
||||||
|
StopStatus.TERMINATED
|
||||||
|
];
|
||||||
|
|
||||||
|
export function getTrainStopStatus(
|
||||||
|
stopInfo: TrainStop,
|
||||||
|
currentStationName: string,
|
||||||
|
sceneryName: string
|
||||||
|
) {
|
||||||
|
if (stopInfo.terminatesHere && stopInfo.confirmed) {
|
||||||
|
return StopStatus.TERMINATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName == sceneryName) {
|
||||||
|
return StopStatus.DEPARTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName != sceneryName) {
|
||||||
|
return StopStatus.DEPARTED_AWAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentStationName == sceneryName && !stopInfo.stopped) {
|
||||||
|
return StopStatus.ONLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentStationName == sceneryName && stopInfo.stopped) {
|
||||||
|
return StopStatus.STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentStationName != sceneryName) {
|
||||||
|
return StopStatus.ARRIVING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StopStatus.ONLINE;
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useTooltipStore } from '../../store/tooltipStore';
|
import { useTooltipStore } from '../../store/tooltipStore';
|
||||||
import { StationTrain } from '../../typings/common';
|
import { Train } from '../../typings/common';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
@@ -23,7 +23,7 @@ export default defineComponent({
|
|||||||
trains() {
|
trains() {
|
||||||
if (this.tooltipStore.content == '') return [];
|
if (this.tooltipStore.content == '') return [];
|
||||||
|
|
||||||
const parsedTrains = JSON.parse(this.tooltipStore.content) as StationTrain[];
|
const parsedTrains = JSON.parse(this.tooltipStore.content) as Train[];
|
||||||
return (parsedTrains ?? []).sort((a, b) => a.trainNo - b.trainNo);
|
return (parsedTrains ?? []).sort((a, b) => a.trainNo - b.trainNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
chosenTrain() {
|
chosenTrain() {
|
||||||
return this.store.trainList.find((train) => train.trainId == this.store.chosenModalTrainId);
|
return this.store.trainList.find((train) => train.id == this.store.chosenModalTrainId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
<li
|
<li
|
||||||
class="train-row"
|
class="train-row"
|
||||||
v-for="train in trains"
|
v-for="train in trains"
|
||||||
:key="train.trainId"
|
:key="train.id"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click.stop="selectModalTrain(train.trainId, $event.currentTarget)"
|
@click.stop="selectModalTrain(train.id, $event.currentTarget)"
|
||||||
@keydown.enter="selectModalTrain(train.trainId, $event.currentTarget)"
|
@keydown.enter="selectModalTrain(train.id, $event.currentTarget)"
|
||||||
>
|
>
|
||||||
<TrainInfo :train="train" :extended="false" />
|
<TrainInfo :train="train" :extended="false" />
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
+72
-35
@@ -1,9 +1,9 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { parseSpawns, getScheduledTrains, getStationTrains } from './utils';
|
import { parseSpawns } from './utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActiveScenery,
|
ActiveScenery,
|
||||||
ScheduledTrain,
|
CheckpointTrain,
|
||||||
Station,
|
Station,
|
||||||
StationRoutes,
|
StationRoutes,
|
||||||
Status,
|
Status,
|
||||||
@@ -12,6 +12,9 @@ import {
|
|||||||
import { useApiStore } from './apiStore';
|
import { useApiStore } from './apiStore';
|
||||||
import { MainStoreState } from './typings';
|
import { MainStoreState } from './typings';
|
||||||
|
|
||||||
|
const checkpointsTrains: Map<string, CheckpointTrain[]> = new Map();
|
||||||
|
const sceneriesTrains: Map<string, Train[]> = new Map();
|
||||||
|
|
||||||
export const useMainStore = defineStore('mainStore', {
|
export const useMainStore = defineStore('mainStore', {
|
||||||
state: () =>
|
state: () =>
|
||||||
({
|
({
|
||||||
@@ -33,10 +36,17 @@ export const useMainStore = defineStore('mainStore', {
|
|||||||
}) as MainStoreState,
|
}) as MainStoreState,
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
|
checkpointsTrains() {
|
||||||
|
return checkpointsTrains;
|
||||||
|
},
|
||||||
|
|
||||||
trainList(): Train[] {
|
trainList(): Train[] {
|
||||||
const apiStore = useApiStore();
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
return (apiStore.activeData?.trains ?? [])
|
checkpointsTrains.clear();
|
||||||
|
sceneriesTrains.clear();
|
||||||
|
|
||||||
|
const x = (apiStore.activeData?.trains ?? [])
|
||||||
.filter((train) => train.timetable || train.online)
|
.filter((train) => train.timetable || train.online)
|
||||||
.map((train) => {
|
.map((train) => {
|
||||||
const stock = train.stockString.split(';');
|
const stock = train.stockString.split(';');
|
||||||
@@ -53,8 +63,8 @@ export const useMainStore = defineStore('mainStore', {
|
|||||||
sceneryHash
|
sceneryHash
|
||||||
) ?? [];
|
) ?? [];
|
||||||
|
|
||||||
return {
|
const trainObj = {
|
||||||
trainId: train.driverName + train.trainNo.toString(),
|
id: train.id,
|
||||||
|
|
||||||
trainNo: train.trainNo,
|
trainNo: train.trainNo,
|
||||||
mass: train.mass,
|
mass: train.mass,
|
||||||
@@ -93,7 +103,36 @@ export const useMainStore = defineStore('mainStore', {
|
|||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
} as Train;
|
} as Train;
|
||||||
|
|
||||||
|
// Sceneries trains map
|
||||||
|
if (sceneriesTrains.has(train.currentStationName)) {
|
||||||
|
sceneriesTrains.set(train.currentStationName, [
|
||||||
|
...sceneriesTrains.get(train.currentStationName)!,
|
||||||
|
trainObj
|
||||||
|
]);
|
||||||
|
} else sceneriesTrains.set(train.currentStationName, [trainObj]);
|
||||||
|
|
||||||
|
// Checkpoints trains map
|
||||||
|
timetable?.stopList.forEach((stop, i) => {
|
||||||
|
if (/strong|podg\.|pe\./.test(stop.stopName)) {
|
||||||
|
const checkpointTrain: CheckpointTrain = {
|
||||||
|
train: trainObj,
|
||||||
|
checkpointStop: stop
|
||||||
|
};
|
||||||
|
|
||||||
|
if (checkpointsTrains.has(stop.stopNameRAW.toLowerCase())) {
|
||||||
|
checkpointsTrains.set(stop.stopNameRAW.toLowerCase(), [
|
||||||
|
...checkpointsTrains.get(stop.stopNameRAW.toLowerCase())!,
|
||||||
|
checkpointTrain
|
||||||
|
]);
|
||||||
|
} else checkpointsTrains.set(stop.stopNameRAW.toLowerCase(), [checkpointTrain]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return trainObj;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return x;
|
||||||
},
|
},
|
||||||
|
|
||||||
// computed active sceneries
|
// computed active sceneries
|
||||||
@@ -104,6 +143,7 @@ export const useMainStore = defineStore('mainStore', {
|
|||||||
|
|
||||||
if (!apiStore.activeData?.activeSceneries) return [];
|
if (!apiStore.activeData?.activeSceneries) return [];
|
||||||
|
|
||||||
|
console.time('activeSceneryList');
|
||||||
const offlineActiveSceneries = this.trainList.reduce((acc, train) => {
|
const offlineActiveSceneries = this.trainList.reduce((acc, train) => {
|
||||||
if (!train.timetableData) return acc;
|
if (!train.timetableData) return acc;
|
||||||
|
|
||||||
@@ -131,13 +171,14 @@ export const useMainStore = defineStore('mainStore', {
|
|||||||
dispatcherId: -1,
|
dispatcherId: -1,
|
||||||
dispatcherExp: -1,
|
dispatcherExp: -1,
|
||||||
dispatcherIsSupporter: false,
|
dispatcherIsSupporter: false,
|
||||||
scheduledTrains: [],
|
|
||||||
stationTrains: [],
|
|
||||||
dispatcherStatus: Status.ActiveDispatcher.FREE,
|
dispatcherStatus: Status.ActiveDispatcher.FREE,
|
||||||
dispatcherTimestamp: -1,
|
dispatcherTimestamp: -1,
|
||||||
|
|
||||||
isOnline: false,
|
isOnline: false,
|
||||||
|
|
||||||
|
stationTrains: [],
|
||||||
|
scheduledTrains: [],
|
||||||
|
|
||||||
scheduledTrainCount: {
|
scheduledTrainCount: {
|
||||||
all: 0,
|
all: 0,
|
||||||
confirmed: 0,
|
confirmed: 0,
|
||||||
@@ -177,8 +218,9 @@ export const useMainStore = defineStore('mainStore', {
|
|||||||
|
|
||||||
isOnline: scenery.isOnline == 1,
|
isOnline: scenery.isOnline == 1,
|
||||||
|
|
||||||
scheduledTrains: [],
|
|
||||||
stationTrains: [],
|
stationTrains: [],
|
||||||
|
scheduledTrains: [],
|
||||||
|
|
||||||
scheduledTrainCount: {
|
scheduledTrainCount: {
|
||||||
all: 0,
|
all: 0,
|
||||||
confirmed: 0,
|
confirmed: 0,
|
||||||
@@ -196,39 +238,34 @@ export const useMainStore = defineStore('mainStore', {
|
|||||||
|
|
||||||
const station = this.stationList.find((s) => s.name === scenery.name);
|
const station = this.stationList.find((s) => s.name === scenery.name);
|
||||||
|
|
||||||
const scheduledTrains = getScheduledTrains(
|
const checkpoints = [scenery.name];
|
||||||
this.trainList,
|
if (station?.generalInfo?.checkpoints) checkpoints.push(...station.generalInfo.checkpoints);
|
||||||
station?.generalInfo,
|
|
||||||
scenery.name,
|
|
||||||
scenery.region
|
|
||||||
);
|
|
||||||
|
|
||||||
const stationTrains = getStationTrains(
|
scenery.stationTrains =
|
||||||
this.trainList,
|
sceneriesTrains.get(scenery.name)?.filter((sc) => sc.region == this.region.id) ?? [];
|
||||||
scheduledTrains,
|
|
||||||
this.region.id,
|
|
||||||
scenery.name
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove checkpoint duplicates
|
const uniqueTrainIds: string[] = [];
|
||||||
const uniqueScheduledTrains = scheduledTrains.reduce(
|
checkpoints.forEach((cp) => {
|
||||||
(uniqueList, sTrain) =>
|
const scheduledTrains = checkpointsTrains.get(cp.toLowerCase());
|
||||||
uniqueList.find((v) => v.trainId === sTrain.trainId)
|
|
||||||
? uniqueList
|
|
||||||
: [...uniqueList, sTrain],
|
|
||||||
[] as ScheduledTrain[]
|
|
||||||
);
|
|
||||||
|
|
||||||
scenery.scheduledTrains = scheduledTrains;
|
if (!scheduledTrains) return;
|
||||||
scenery.stationTrains = stationTrains;
|
|
||||||
|
|
||||||
scenery.scheduledTrainCount = {
|
scheduledTrains.forEach(({ train, checkpointStop }) => {
|
||||||
all: uniqueScheduledTrains.length,
|
if (uniqueTrainIds.includes(train.id) || train.region != this.region.id) return;
|
||||||
confirmed: uniqueScheduledTrains.filter((train) => train.stopInfo.confirmed).length,
|
|
||||||
unconfirmed: uniqueScheduledTrains.filter((train) => !train.stopInfo.confirmed).length
|
scenery.scheduledTrainCount.all += 1;
|
||||||
};
|
scenery.scheduledTrains.push({ train, checkpointStop });
|
||||||
|
|
||||||
|
if (checkpointStop.confirmed) scenery.scheduledTrainCount.confirmed++;
|
||||||
|
else scenery.scheduledTrainCount.unconfirmed++;
|
||||||
|
|
||||||
|
uniqueTrainIds.push(train.id);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.timeEnd('activeSceneryList');
|
||||||
|
|
||||||
return allActiveSceneries;
|
return allActiveSceneries;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { API } from '../typings/api';
|
import { API } from '../typings/api';
|
||||||
import { Availability, StationRoutesInfo, Status } from '../typings/common';
|
import { Availability, CheckpointTrain, StationRoutesInfo, Status } from '../typings/common';
|
||||||
|
|
||||||
export interface MainStoreState {
|
export interface MainStoreState {
|
||||||
region: { id: string; value: string; name: string };
|
region: { id: string; value: string; name: string };
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import {
|
|||||||
TrainStop,
|
TrainStop,
|
||||||
StopStatus,
|
StopStatus,
|
||||||
Train,
|
Train,
|
||||||
ScheduledTrain,
|
|
||||||
Station,
|
Station,
|
||||||
StationTrain,
|
StationTrain,
|
||||||
ScenerySpawn,
|
ScenerySpawn,
|
||||||
@@ -57,176 +56,3 @@ export function parseSpawns(spawnString: string | null): ScenerySpawn[] {
|
|||||||
export function getTimestamp(date: string | null): number {
|
export function getTimestamp(date: string | null): number {
|
||||||
return date ? new Date(date).getTime() : 0;
|
return date ? new Date(date).getTime() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTrainStopStatus(
|
|
||||||
stopInfo: TrainStop,
|
|
||||||
currentStationName: string,
|
|
||||||
sceneryName: string
|
|
||||||
) {
|
|
||||||
let stopStatus = StopStatus.ARRIVING,
|
|
||||||
stopLabel = '',
|
|
||||||
stopStatusID = -1;
|
|
||||||
|
|
||||||
if (stopInfo.terminatesHere && stopInfo.confirmed) {
|
|
||||||
stopStatus = StopStatus.TERMINATED;
|
|
||||||
stopLabel = 'Skończył bieg';
|
|
||||||
stopStatusID = 5;
|
|
||||||
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName == sceneryName) {
|
|
||||||
stopStatus = StopStatus.DEPARTED;
|
|
||||||
stopLabel = 'Odprawiony';
|
|
||||||
stopStatusID = 2;
|
|
||||||
} else if (!stopInfo.terminatesHere && stopInfo.confirmed && currentStationName != sceneryName) {
|
|
||||||
stopStatus = StopStatus.DEPARTED_AWAY;
|
|
||||||
stopLabel = 'Odjechał';
|
|
||||||
stopStatusID = 4;
|
|
||||||
} else if (currentStationName == sceneryName && !stopInfo.stopped) {
|
|
||||||
stopStatus = StopStatus.ONLINE;
|
|
||||||
stopLabel = 'Na stacji';
|
|
||||||
stopStatusID = 0;
|
|
||||||
} else if (currentStationName == sceneryName && stopInfo.stopped) {
|
|
||||||
stopStatus = StopStatus.STOPPED;
|
|
||||||
stopLabel = 'Postój';
|
|
||||||
stopStatusID = 1;
|
|
||||||
} else if (currentStationName != sceneryName) {
|
|
||||||
stopStatus = StopStatus.ARRIVING;
|
|
||||||
stopLabel = 'W drodze';
|
|
||||||
stopStatusID = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { stopStatus, stopLabel, stopStatusID };
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCheckpointTrain(
|
|
||||||
train: Train,
|
|
||||||
trainStopIndex: number,
|
|
||||||
sceneryName: string
|
|
||||||
): ScheduledTrain {
|
|
||||||
const timetable = train.timetableData!;
|
|
||||||
const followingStops = timetable.followingStops;
|
|
||||||
const trainStop = followingStops[trainStopIndex];
|
|
||||||
|
|
||||||
const trainStopStatus = getTrainStopStatus(trainStop, train.currentStationName, sceneryName);
|
|
||||||
|
|
||||||
let prevStationName = '',
|
|
||||||
nextStationName = '';
|
|
||||||
|
|
||||||
let departureLine: string | null = null;
|
|
||||||
let arrivingLine: string | null = null;
|
|
||||||
|
|
||||||
let prevDepartureLine: string | null = null,
|
|
||||||
nextArrivalLine: string | null = null;
|
|
||||||
|
|
||||||
for (let i = trainStopIndex; i >= 0; i--) {
|
|
||||||
const stop = followingStops[i];
|
|
||||||
|
|
||||||
if (/strong|podg\.|pe\./g.test(stop.stopName) && !prevStationName && i <= trainStopIndex - 1)
|
|
||||||
prevStationName = stop.stopNameRAW.replace(/,.*/g, '');
|
|
||||||
|
|
||||||
if (stop.arrivalLine != null && !arrivingLine && !/-|_|it|sbl/gi.test(stop.arrivalLine)) {
|
|
||||||
arrivingLine = stop.arrivalLine;
|
|
||||||
prevDepartureLine = followingStops[i - 1]?.departureLine || null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = trainStopIndex; i < followingStops.length; i++) {
|
|
||||||
const stop = followingStops[i];
|
|
||||||
|
|
||||||
if (/strong|podg\.|pe\./g.test(stop.stopName) && !nextStationName && i > trainStopIndex)
|
|
||||||
nextStationName = stop.stopNameRAW.replace(/,.*/g, '');
|
|
||||||
|
|
||||||
if (stop.departureLine && !departureLine && !/-|_|it|sbl/gi.test(stop.departureLine)) {
|
|
||||||
departureLine = stop.departureLine;
|
|
||||||
nextArrivalLine = followingStops[i + 1]?.arrivalLine || null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
checkpointName: trainStop.stopNameRAW,
|
|
||||||
|
|
||||||
trainNo: train.trainNo,
|
|
||||||
trainId: train.trainId,
|
|
||||||
|
|
||||||
signal: train.signal,
|
|
||||||
connectedTrack: train.connectedTrack,
|
|
||||||
|
|
||||||
driverName: train.driverName,
|
|
||||||
driverId: train.driverId,
|
|
||||||
currentStationName: train.currentStationName,
|
|
||||||
currentStationHash: train.currentStationHash,
|
|
||||||
category: timetable.category,
|
|
||||||
beginsAt: timetable.followingStops[0].stopNameRAW,
|
|
||||||
terminatesAt: timetable.followingStops[timetable.followingStops.length - 1].stopNameRAW,
|
|
||||||
|
|
||||||
nextStationName,
|
|
||||||
prevStationName,
|
|
||||||
|
|
||||||
stopInfo: trainStop,
|
|
||||||
stopLabel: trainStopStatus.stopLabel,
|
|
||||||
stopStatus: trainStopStatus.stopStatus,
|
|
||||||
stopStatusID: trainStopStatus.stopStatusID,
|
|
||||||
|
|
||||||
region: train.region,
|
|
||||||
|
|
||||||
arrivingLine: arrivingLine,
|
|
||||||
departureLine: departureLine,
|
|
||||||
|
|
||||||
nextArrivalLine,
|
|
||||||
prevDepartureLine
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getScheduledTrains(
|
|
||||||
trainList: Train[],
|
|
||||||
stationGeneralInfo: Station['generalInfo'],
|
|
||||||
stationName: string,
|
|
||||||
region: string
|
|
||||||
// sceneryData: API.ActiveSceneries.Data,
|
|
||||||
): ScheduledTrain[] {
|
|
||||||
// stationGeneralInfo?.checkpoints.forEach((cp) => (cp.scheduledTrains.length = 0));
|
|
||||||
|
|
||||||
return trainList.reduce((acc: ScheduledTrain[], train) => {
|
|
||||||
if (!train.timetableData) return acc;
|
|
||||||
if (train.region != region) return acc;
|
|
||||||
|
|
||||||
const timetable = train.timetableData;
|
|
||||||
if (!timetable.sceneryNames.includes(stationName)) return acc;
|
|
||||||
|
|
||||||
const checkpoints = [stationName];
|
|
||||||
if (stationGeneralInfo?.checkpoints) checkpoints.push(...stationGeneralInfo.checkpoints);
|
|
||||||
|
|
||||||
const checkpointScheduledTrains: ScheduledTrain[] = [];
|
|
||||||
for (let i = 0; i < timetable.followingStops.length; i++) {
|
|
||||||
if (
|
|
||||||
new RegExp(`^(${checkpoints.join('|')})$`, 'i').test(
|
|
||||||
timetable.followingStops[i].stopNameRAW
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
checkpointScheduledTrains.push(getCheckpointTrain(train, i, stationName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
acc.push(...checkpointScheduledTrains);
|
|
||||||
return acc;
|
|
||||||
}, []) as ScheduledTrain[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getStationTrains(
|
|
||||||
trainList: Train[],
|
|
||||||
scheduledTrainList: ScheduledTrain[],
|
|
||||||
region: string,
|
|
||||||
stationName: string
|
|
||||||
): StationTrain[] {
|
|
||||||
return trainList
|
|
||||||
.filter(
|
|
||||||
(train) =>
|
|
||||||
train?.region === region && train.online && train.currentStationName === stationName
|
|
||||||
)
|
|
||||||
.map((train) => ({
|
|
||||||
driverName: train.driverName,
|
|
||||||
driverId: train.driverId,
|
|
||||||
trainNo: train.trainNo,
|
|
||||||
trainId: train.trainId,
|
|
||||||
stopStatus:
|
|
||||||
scheduledTrainList.find((st) => st.trainNo === train.trainNo)?.stopStatus || 'no-timetable'
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ export namespace API {
|
|||||||
stopNameRAW: string;
|
stopNameRAW: string;
|
||||||
stopType: string;
|
stopType: string;
|
||||||
stopDistance: number;
|
stopDistance: number;
|
||||||
pointId: string;
|
|
||||||
|
|
||||||
mainStop: boolean;
|
mainStop: boolean;
|
||||||
|
|
||||||
|
|||||||
+9
-49
@@ -41,7 +41,6 @@ export interface RegionCounters {
|
|||||||
|
|
||||||
export interface Train {
|
export interface Train {
|
||||||
id: string;
|
id: string;
|
||||||
trainId: string;
|
|
||||||
mass: number;
|
mass: number;
|
||||||
length: number;
|
length: number;
|
||||||
speed: number;
|
speed: number;
|
||||||
@@ -148,8 +147,8 @@ export interface ActiveScenery {
|
|||||||
dispatcherStatus: Status.ActiveDispatcher | number;
|
dispatcherStatus: Status.ActiveDispatcher | number;
|
||||||
dispatcherTimestamp: number | null;
|
dispatcherTimestamp: number | null;
|
||||||
isOnline: boolean;
|
isOnline: boolean;
|
||||||
stationTrains?: StationTrain[];
|
stationTrains: Train[];
|
||||||
scheduledTrains?: ScheduledTrain[];
|
scheduledTrains: CheckpointTrain[];
|
||||||
scheduledTrainCount: {
|
scheduledTrainCount: {
|
||||||
all: number;
|
all: number;
|
||||||
confirmed: number;
|
confirmed: number;
|
||||||
@@ -164,49 +163,6 @@ export interface ScenerySpawn {
|
|||||||
spawnType: ScenerySpawnType;
|
spawnType: ScenerySpawnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StationTrain {
|
|
||||||
driverName: string;
|
|
||||||
driverId: number;
|
|
||||||
trainNo: number;
|
|
||||||
trainId: string;
|
|
||||||
stopStatus: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ScheduledTrain {
|
|
||||||
checkpointName: string;
|
|
||||||
|
|
||||||
trainId: string;
|
|
||||||
trainNo: number;
|
|
||||||
|
|
||||||
driverName: string;
|
|
||||||
driverId: number;
|
|
||||||
currentStationName: string;
|
|
||||||
currentStationHash: string;
|
|
||||||
category: string;
|
|
||||||
stopInfo: TrainStop;
|
|
||||||
|
|
||||||
terminatesAt: string;
|
|
||||||
beginsAt: string;
|
|
||||||
|
|
||||||
prevStationName: string;
|
|
||||||
nextStationName: string;
|
|
||||||
|
|
||||||
arrivingLine: string | null;
|
|
||||||
departureLine: string | null;
|
|
||||||
|
|
||||||
prevDepartureLine: string | null;
|
|
||||||
nextArrivalLine: string | null;
|
|
||||||
|
|
||||||
signal: string;
|
|
||||||
connectedTrack: string;
|
|
||||||
|
|
||||||
stopLabel: string;
|
|
||||||
stopStatus: StopStatus;
|
|
||||||
stopStatusID: number;
|
|
||||||
|
|
||||||
region: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TrainStop {
|
export interface TrainStop {
|
||||||
stopName: string;
|
stopName: string;
|
||||||
stopNameRAW: string;
|
stopNameRAW: string;
|
||||||
@@ -223,13 +179,17 @@ export interface TrainStop {
|
|||||||
departureTimestamp: number;
|
departureTimestamp: number;
|
||||||
departureRealTimestamp: number;
|
departureRealTimestamp: number;
|
||||||
departureDelay: number;
|
departureDelay: number;
|
||||||
pointId: number;
|
|
||||||
|
|
||||||
comments?: string;
|
comments?: string;
|
||||||
|
|
||||||
beginsHere: boolean;
|
beginsHere: boolean;
|
||||||
terminatesHere: boolean;
|
terminatesHere: boolean;
|
||||||
confirmed: boolean;
|
confirmed: number;
|
||||||
stopped: boolean;
|
stopped: number;
|
||||||
stopTime: number | null;
|
stopTime: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CheckpointTrain {
|
||||||
|
checkpointStop: TrainStop;
|
||||||
|
train: Train;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user