Compare commits

..

11 Commits

14 changed files with 272 additions and 101 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "stacjownik", "name": "stacjownik",
"version": "1.30.3", "version": "1.30.4",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
@@ -18,7 +18,11 @@
:key="train.id" :key="train.id"
:data-status="status" :data-status="status"
> >
<router-link :to="train.driverRouteLocation"> <router-link
:to="train.driverRouteLocation"
data-tooltip-type="TrainInfoTooltip"
:data-tooltip-content="train.id"
>
<span class="user_train"> {{ train.trainNo }}</span> <span class="user_train"> {{ train.trainNo }}</span>
<span class="user_name"> <span class="user_name">
{{ train.driverName }} {{ train.driverName }}
+19 -16
View File
@@ -122,28 +122,30 @@
</span> </span>
<!-- Train info --> <!-- Train info -->
<span> <span
<b data-tooltip-type="TrainInfoTooltip"
data-tooltip-type="BaseTooltip" :data-tooltip-content="row.train.id"
:data-tooltip-content=" class="tooltip-help"
getCategoryExplanation(row.train.timetableData!.category) >
" <b class="text--primary">
class="text--primary tooltip-help"
>
{{ row.train.timetableData!.category }} {{ row.train.timetableData!.category }}
</b> </b>
<b>&nbsp;{{ row.train.trainNo }}</b> <b>&nbsp;{{ row.train.trainNo }}</b>
&bull;
{{ row.train.driverName }}
<i
class="fa-solid fa-user-slash"
style="color: salmon"
v-if="!row.train.online && row.train.lastSeen <= Date.now() - 60000"
></i>
</span> </span>
<span>&bull;</span>
<span>{{ row.train.driverName }}</span>
<span>&bull;</span>
<b style="color: #ddd">{{ row.train.stockList[0] }}</b>
<!-- Train stop comments --> <!-- Train stop comments -->
<span <span
class="stop-comments-icon"
v-if="row.checkpointStop.comments" v-if="row.checkpointStop.comments"
class="stop-comments-icon"
data-tooltip-type="BaseTooltip" data-tooltip-type="BaseTooltip"
:data-tooltip-content="row.checkpointStop.comments" :data-tooltip-content="row.checkpointStop.comments"
> >
@@ -243,7 +245,7 @@ import { useMainStore } from '../../store/mainStore';
import { useApiStore } from '../../store/apiStore'; import { useApiStore } from '../../store/apiStore';
import ScheduledTrainStatus from './ScheduledTrainStatus.vue'; import ScheduledTrainStatus from './ScheduledTrainStatus.vue';
import { SceneryTimetableRow } from './typings'; import { SceneryTimetableRow } from './typings';
import { ActiveScenery, Station } from '../../typings/common'; import { ActiveScenery, Station, TooltipTrainInfo, Train } from '../../typings/common';
import { getTrainStopStatus, stopStatusPriority } from './utils'; import { getTrainStopStatus, stopStatusPriority } from './utils';
export default defineComponent({ export default defineComponent({
@@ -527,11 +529,12 @@ export default defineComponent({
.info-route { .info-route {
width: 100%; width: 100%;
margin-top: 0.25em;
} }
.stop-comments-icon > img { .stop-comments-icon > img {
width: 1.2em; width: 1.3em;
vertical-align: middle; vertical-align: top;
} }
.schedule { .schedule {
@@ -1,11 +1,18 @@
<template> <template>
<div class="general-status"> <div class="general-status">
<span <router-link
v-if="computedScheduledTrain.stationNameHref"
:to="`/scenery?station=${computedScheduledTrain.stationNameHref}`"
:class="computedScheduledTrain.status" :class="computedScheduledTrain.status"
@click.prevent="() => {}"
v-html="computedScheduledTrain.stopStatusIndicator" v-html="computedScheduledTrain.stopStatusIndicator"
> >
</span> </router-link>
<span
v-else
:class="computedScheduledTrain.status"
v-html="computedScheduledTrain.stopStatusIndicator"
></span>
</div> </div>
</template> </template>
@@ -27,6 +34,7 @@ export default defineComponent({
const { status, prevElement, currentElement, nextElement } = this.sceneryTimetableRow; const { status, prevElement, currentElement, nextElement } = this.sceneryTimetableRow;
let stopStatusIndicator = ''; let stopStatusIndicator = '';
let stationNameHref = '';
switch (status) { switch (status) {
case StopStatus.ARRIVING: case StopStatus.ARRIVING:
@@ -35,6 +43,8 @@ export default defineComponent({
prevStationName: prevElement?.stationName ?? '', prevStationName: prevElement?.stationName ?? '',
prevDepartureLine: prevElement?.departureRouteExt ?? '' prevDepartureLine: prevElement?.departureRouteExt ?? ''
}); });
stationNameHref = prevElement?.stationName ?? '';
} else { } else {
stopStatusIndicator = this.$t('timetables.desc-beginning'); stopStatusIndicator = this.$t('timetables.desc-beginning');
} }
@@ -48,6 +58,9 @@ export default defineComponent({
nextArrivalLine: nextElement?.arrivalRouteExt nextArrivalLine: nextElement?.arrivalRouteExt
}) })
: this.$t(`timetables.desc-end`); : this.$t(`timetables.desc-end`);
stationNameHref = nextElement?.stationName ?? '';
break; break;
case StopStatus.DEPARTED: case StopStatus.DEPARTED:
@@ -55,11 +68,15 @@ export default defineComponent({
stopStatusIndicator = this.$t('timetables.desc-departed-ends', { stopStatusIndicator = this.$t('timetables.desc-departed-ends', {
nextStationName: currentElement.stationName nextStationName: currentElement.stationName
}); });
stationNameHref = nextElement?.stationName ?? '';
} else { } else {
stopStatusIndicator = this.$t('timetables.desc-departed', { stopStatusIndicator = this.$t('timetables.desc-departed', {
nextStationName: nextElement?.stationName ?? currentElement.stationName, nextStationName: nextElement?.stationName ?? currentElement.stationName,
nextArrivalLine: nextElement?.arrivalRouteExt nextArrivalLine: nextElement?.arrivalRouteExt
}); });
stationNameHref = nextElement?.stationName ?? '';
} }
break; break;
@@ -69,6 +86,8 @@ export default defineComponent({
nextStationName: nextElement?.stationName, nextStationName: nextElement?.stationName,
nextArrivalLine: nextElement?.arrivalRouteExt nextArrivalLine: nextElement?.arrivalRouteExt
}); });
stationNameHref = nextElement?.stationName ?? '';
break; break;
case StopStatus.TERMINATED: case StopStatus.TERMINATED:
@@ -80,9 +99,18 @@ export default defineComponent({
} }
return { return {
...this.sceneryTimetableRow, ...this.sceneryTimetableRow,
stationNameHref,
stopStatusIndicator stopStatusIndicator
}; };
} }
},
methods: {
navigateToScenery(sceneryName?: string) {
if (!sceneryName) return;
this.$router.push(`/scenery?station=${sceneryName}`);
}
} }
}); });
</script> </script>
@@ -91,11 +119,11 @@ export default defineComponent({
.general-status { .general-status {
margin-top: 0.5em; margin-top: 0.5em;
span.arriving { & > .arriving {
color: #ccc; color: #ccc;
} }
span.departed { & > .departed {
color: lime; color: lime;
&-away { &-away {
@@ -103,15 +131,15 @@ export default defineComponent({
} }
} }
span.stopped { & > .stopped {
color: #ffa600; color: #ffa600;
} }
span.online { & > .online {
color: gold; color: gold;
} }
span.terminated { & > .terminated {
color: salmon; color: salmon;
} }
} }
+66 -36
View File
@@ -33,12 +33,12 @@
class="header-image" class="header-image"
:class="headerName" :class="headerName"
> >
<span class="header_wrapper"> <span
<img class="header_wrapper"
:src="`/images/icon-${headerName}.svg`" data-tooltip-type="BaseTooltip"
:alt="headerName" :data-tooltip-content="$t(`sceneries.headers.${headerName}`)"
:title="$t(`sceneries.headers.${headerName}`)" >
/> <img :src="`/images/icon-${headerName}.svg`" :alt="headerName" />
<img <img
class="sort-icon" class="sort-icon"
@@ -76,37 +76,49 @@
station.generalInfo.availability != 'nonPublic' && station.generalInfo.availability != 'nonPublic' &&
station.generalInfo.availability != 'unavailable' station.generalInfo.availability != 'unavailable'
" "
data-tooltip-type="BaseTooltip"
:data-tooltip-content="`${$t(`sceneries.info.${station.generalInfo.availability}`)} (${$t(
'sceneries.info.req-level',
{ lvl: station.generalInfo.reqLevel },
station.generalInfo.reqLevel
)})`"
:style="calculateExpStyle(station.generalInfo.reqLevel)" :style="calculateExpStyle(station.generalInfo.reqLevel)"
> >
{{ station.generalInfo.reqLevel >= 2 ? station.generalInfo.reqLevel : 'L' }} {{ station.generalInfo.reqLevel >= 2 ? station.generalInfo.reqLevel : 'L' }}
</span> </span>
<span v-else-if="station.generalInfo.availability == 'abandoned'"> <span
<img v-else-if="station.generalInfo.availability == 'abandoned'"
src="/images/icon-abandoned.svg" data-tooltip-type="BaseTooltip"
alt="non-public" :data-tooltip-content="$t('sceneries.info.abandoned')"
:title="$t('sceneries.info.abandoned')" >
/> <img src="/images/icon-abandoned.svg" alt="non-public" />
</span> </span>
<span v-else-if="station.generalInfo.availability == 'nonPublic'"> <span
<img v-else-if="station.generalInfo.availability == 'nonPublic'"
src="/images/icon-lock.svg" data-tooltip-type="BaseTooltip"
alt="non-public" :data-tooltip-content="$t('sceneries.info.non-public')"
:title="$t('sceneries.info.non-public')" >
/> <img src="/images/icon-lock.svg" alt="non-public" />
</span> </span>
<span v-else> <span
<img v-else
src="/images/icon-unavailable.svg" data-tooltip-type="BaseTooltip"
alt="unavailable" :data-tooltip-content="$t('sceneries.info.unavailable')"
:title="$t('sceneries.info.unavailable')" >
/> <img src="/images/icon-unavailable.svg" alt="unavailable" />
</span> </span>
</span> </span>
<span v-else> ? </span> <span
v-else
data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('sceneries.info.unknown')"
>
?
</span>
</td> </td>
<td class="station-status"> <td class="station-status">
@@ -153,7 +165,8 @@
<span <span
v-if="station.generalInfo.routes.singleElectrifiedNames.length != 0" v-if="station.generalInfo.routes.singleElectrifiedNames.length != 0"
class="track catenary" class="track catenary"
:title="`${$t('sceneries.info.single-track-routes-catenary')}${ data-tooltip-type="BaseTooltip"
:data-tooltip-content="`${$t('sceneries.info.single-track-routes-catenary')}${
station.generalInfo.routes.singleElectrifiedNames.length station.generalInfo.routes.singleElectrifiedNames.length
}`" }`"
> >
@@ -163,7 +176,8 @@
<span <span
v-if="station.generalInfo.routes.singleOtherNames.length != 0" v-if="station.generalInfo.routes.singleOtherNames.length != 0"
class="track no-catenary" class="track no-catenary"
:title="`${$t('sceneries.info.single-track-routes-other')}${ data-tooltip-type="BaseTooltip"
:data-tooltip-content="`${$t('sceneries.info.single-track-routes-other')}${
station.generalInfo.routes.singleOtherNames.length station.generalInfo.routes.singleOtherNames.length
}`" }`"
> >
@@ -177,7 +191,8 @@
<span <span
v-if="station.generalInfo.routes.doubleElectrifiedNames.length != 0" v-if="station.generalInfo.routes.doubleElectrifiedNames.length != 0"
class="track catenary" class="track catenary"
:title="`${$t('sceneries.info.double-track-routes-catenary')}${ data-tooltip-type="BaseTooltip"
:data-tooltip-content="`${$t('sceneries.info.double-track-routes-catenary')}${
station.generalInfo.routes.doubleElectrifiedNames.length station.generalInfo.routes.doubleElectrifiedNames.length
}`" }`"
> >
@@ -187,7 +202,8 @@
<span <span
v-if="station.generalInfo.routes.doubleOtherNames.length != 0" v-if="station.generalInfo.routes.doubleOtherNames.length != 0"
class="track no-catenary" class="track no-catenary"
:title="`${$t('sceneries.info.double-track-routes-other')}${ data-tooltip-type="BaseTooltip"
:data-tooltip-content="`${$t('sceneries.info.double-track-routes-other')}${
station.generalInfo.routes.doubleOtherNames.length station.generalInfo.routes.doubleOtherNames.length
}`" }`"
> >
@@ -201,7 +217,8 @@
v-if="station.generalInfo?.signalType" v-if="station.generalInfo?.signalType"
class="scenery-icon icon-info" class="scenery-icon icon-info"
:class="station.generalInfo?.controlType.replace('+', '-')" :class="station.generalInfo?.controlType.replace('+', '-')"
:title=" data-tooltip-type="BaseTooltip"
:data-tooltip-content="
$t('sceneries.info.control-type') + $t('sceneries.info.control-type') +
$t(`controls.${station.generalInfo?.controlType}`) $t(`controls.${station.generalInfo?.controlType}`)
" "
@@ -214,7 +231,8 @@
class="icon-info" class="icon-info"
:src="`/images/icon-${station.generalInfo.signalType}.svg`" :src="`/images/icon-${station.generalInfo.signalType}.svg`"
:alt="station.generalInfo.signalType" :alt="station.generalInfo.signalType"
:title=" data-tooltip-type="BaseTooltip"
:data-tooltip-content="
$t('sceneries.info.signals-type') + $t(`signals.${station.generalInfo.signalType}`) $t('sceneries.info.signals-type') + $t(`signals.${station.generalInfo.signalType}`)
" "
/> />
@@ -224,7 +242,8 @@
class="icon-info" class="icon-info"
src="/images/icon-SUP.svg" src="/images/icon-SUP.svg"
alt="SUP (RASP-UZK)" alt="SUP (RASP-UZK)"
:title="$t('sceneries.info.SUP')" data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('sceneries.info.SUP')"
/> />
<img <img
@@ -232,7 +251,8 @@
class="icon-info" class="icon-info"
src="/images/icon-ASDEK.svg" src="/images/icon-ASDEK.svg"
alt="dSAT ASDEK" alt="dSAT ASDEK"
:title="$t('sceneries.info.ASDEK')" data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('sceneries.info.ASDEK')"
/> />
<img <img
@@ -240,7 +260,8 @@
class="icon-info" class="icon-info"
src="/images/icon-unknown.svg" src="/images/icon-unknown.svg"
alt="icon-unknown" alt="icon-unknown"
:title="$t('sceneries.info.unknown')" data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('sceneries.info.unknown')"
/> />
</td> </td>
@@ -248,7 +269,7 @@
class="station-users" class="station-users"
:class="{ inactive: !station.onlineInfo }" :class="{ inactive: !station.onlineInfo }"
data-tooltip-type="UsersTooltip" data-tooltip-type="UsersTooltip"
:data-tooltip-content="JSON.stringify(station.onlineInfo?.stationTrains ?? [])" :data-tooltip-content="getUsersTooltipContent(station.onlineInfo?.stationTrains ?? [])"
> >
<span class="text--primary">{{ <span class="text--primary">{{
station.onlineInfo?.stationTrains?.length ?? '-' station.onlineInfo?.stationTrains?.length ?? '-'
@@ -318,7 +339,7 @@ import dateMixin from '../../mixins/dateMixin';
import styleMixin from '../../mixins/styleMixin'; import styleMixin from '../../mixins/styleMixin';
import { useApiStore } from '../../store/apiStore'; import { useApiStore } from '../../store/apiStore';
import { useMainStore } from '../../store/mainStore'; import { useMainStore } from '../../store/mainStore';
import { Station, Status } from '../../typings/common'; import { Station, Status, TooltipUserTrain, Train } from '../../typings/common';
import { useTooltipStore } from '../../store/tooltipStore'; import { useTooltipStore } from '../../store/tooltipStore';
import { getChangedFilters } from '../../managers/stationFilterManager'; import { getChangedFilters } from '../../managers/stationFilterManager';
import { ActiveSorter, HeadIdsType, headIconsIds, headIds } from './typings'; import { ActiveSorter, HeadIdsType, headIconsIds, headIds } from './typings';
@@ -394,6 +415,15 @@ export default defineComponent({
else this.activeSorter.dir = 1; else this.activeSorter.dir = 1;
this.activeSorter.headerName = headerName; this.activeSorter.headerName = headerName;
},
getUsersTooltipContent(stationTrains: Train[]): string {
const usersTrains: TooltipUserTrain[] = stationTrains.map((train) => ({
driverName: train.driverName,
trainNo: train.trainNo
}));
return JSON.stringify(usersTrains);
} }
} }
}); });
+3 -1
View File
@@ -13,6 +13,7 @@ import BaseTooltip from './BaseTooltip.vue';
import SpawnsTooltip from './SpawnsTooltip.vue'; import SpawnsTooltip from './SpawnsTooltip.vue';
import UsersTooltip from './UsersTooltip.vue'; import UsersTooltip from './UsersTooltip.vue';
import HtmlTooltip from './HtmlTooltip.vue'; import HtmlTooltip from './HtmlTooltip.vue';
import TrainInfoTooltip from "./TrainInfoTooltip.vue";
const BOX_PADDING_PX = 20; const BOX_PADDING_PX = 20;
@@ -23,7 +24,8 @@ export default defineComponent({
BaseTooltip, BaseTooltip,
SpawnsTooltip, SpawnsTooltip,
UsersTooltip, UsersTooltip,
HtmlTooltip HtmlTooltip,
TrainInfoTooltip
}, },
data() { data() {
@@ -0,0 +1,69 @@
<template>
<div class="tooltip-content">
<span v-if="trainInfo">
<b v-if="trainInfo.timetableData" style="text-transform: uppercase">
<span class="text--primary">{{ trainInfo.timetableData.category }}</span>
{{ getCategoryExplanation(trainInfo.timetableData.category) }}
</b>
<div class="text--primary">
<b>{{ trainInfo.stockList[0] }}</b> &bull; {{ trainInfo.length }}m &bull;
{{ (trainInfo.mass / 1000).toFixed(2) }}t
</div>
<div class="text--grayed">
{{ displayTrainPosition(trainInfo) }} - {{ trainInfo.speed }}km/h
<span v-if="!trainInfo.online" style="color: salmon">
- offline {{ lastSeenMessage(trainInfo.lastSeen) }}</span
>
</div>
<div></div>
</span>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useTooltipStore } from '../../store/tooltipStore';
import trainCategoryMixin from '../../mixins/trainCategoryMixin';
import trainInfoMixin from '../../mixins/trainInfoMixin';
import { useMainStore } from '../../store/mainStore';
export default defineComponent({
mixins: [trainCategoryMixin, trainInfoMixin],
data: () => ({
tooltipStore: useTooltipStore(),
mainStore: useMainStore()
}),
computed: {
trainInfo() {
if (this.tooltipStore.content == '') return null;
// Passed "content" string should be the desired train's ID
return this.mainStore.trainList.find((t) => t.id === this.tooltipStore.content);
},
lastSceneryStatus() {
}
}
});
</script>
<style lang="scss" scoped>
.tooltip-content {
padding: 0.25em 0.5em;
border-radius: 0.25em;
width: 100%;
background-color: #1f1f1f;
box-shadow: 0 0 5px 2px #aaa;
}
img {
height: 1em;
}
</style>
+2 -2
View File
@@ -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 { Train } from '../../typings/common'; import { TooltipUserTrain } 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 Train[]; const parsedTrains = JSON.parse(this.tooltipStore.content) as TooltipUserTrain[];
return (parsedTrains ?? []).sort((a, b) => a.trainNo - b.trainNo); return (parsedTrains ?? []).sort((a, b) => a.trainNo - b.trainNo);
} }
} }
+4 -1
View File
@@ -110,7 +110,10 @@
{{ $t('trains.scenery-offline') }} {{ $t('trains.scenery-offline') }}
</div> </div>
<div v-if="!train.online" class="train-badge offline"> <div
v-if="!train.online && train.lastSeen >= Date.now() - 60000"
class="train-badge offline"
>
<i class="fa-solid fa-user-slash"></i> <i class="fa-solid fa-user-slash"></i>
Offline {{ lastSeenMessage(train.lastSeen) }} Offline {{ lastSeenMessage(train.lastSeen) }}
</div> </div>
+11 -8
View File
@@ -30,17 +30,20 @@
</div> </div>
<div class="search-box"> <div class="search-box">
<select <datalist id="search-active-driver">
class="search-input"
name="active-trains"
id="active-trains"
v-model="searchedDriver"
>
<option value="">{{ $t('options.select-driver') }}</option>
<option v-for="driverName in activeDriverNames" :value="driverName"> <option v-for="driverName in activeDriverNames" :value="driverName">
{{ driverName }} {{ driverName }}
</option> </option>
</select> </datalist>
<input
class="search-input"
list="search-active-driver"
name="search-active-driver"
id="search-active-driver"
:placeholder="$t(`options.search-driver`)"
v-model="searchedDriver"
/>
<button class="btn btn--action search-exit" @click="onInputClear('driver')"> <button class="btn btn--action search-exit" @click="onInputClear('driver')">
<img src="/images/icon-exit.svg" alt="Trains search clear icon" /> <img src="/images/icon-exit.svg" alt="Trains search clear icon" />
+19 -17
View File
@@ -337,18 +337,20 @@
}, },
"info": { "info": {
"control-type": "Control type: ", "control-type": "Control type: ",
"signals-type": "Signals type: ", "signals-type": "Signalling type: ",
"SBL": "This scenery has automatic block signalling (ABS/SBL) system on following routes: ", "SBL": "A scenery with automatic block signalling (ABS/SBL) on routes: ",
"SUP": "Requires the SUP program (level crossing remote control)", "SUP": "Requires the SUP program (level crossing remote control)",
"ASDEK": "Requires the ASDEK program (defect detection of moving rolling stock)", "ASDEK": "ASDEK program available (defect detection of moving rolling stock)",
"TWB-all": "This scenery has two-way route blockade on all routes", "TWB-all": "This scenery has two-way route blockade on all routes",
"TWB-routes": "This scenery has two-way route blockade on following routes: ", "TWB-routes": "This scenery has two-way route blockade on following routes: ",
"default": "This scenery is available by default", "default": "Scenery available in game package",
"non-public": "This scenery is not public", "nonDefault": "Sceneria available to download from forum site",
"unavailable": "This scenery is unavailable", "req-level": "all dispatcher levels | requries {lvl} dispatcher lvl | requires {lvl} dispatcher lvl",
"abandoned": "This scenery is no longer supported by its creators", "non-public": "Non-public scenery",
"unknown": "This scenery isn't recognizable right now", "unavailable": "Unavailable scenery",
"real": "Scenery with real lines: ", "abandoned": "Abandoned scenery",
"unknown": "Unknown scenery",
"real": "Scenery with real Polish routes: ",
"double-track-routes-catenary": "Electrified double-track routes count: ", "double-track-routes-catenary": "Electrified double-track routes count: ",
"single-track-routes-catenary": "Electrified single-track routes count: ", "single-track-routes-catenary": "Electrified single-track routes count: ",
"double-track-routes-other": "Not electrified double-track routes count: ", "double-track-routes-other": "Not electrified double-track routes count: ",
@@ -591,14 +593,14 @@
"terminates": "TERMINATES\nHERE", "terminates": "TERMINATES\nHERE",
"from": "Arrives from", "from": "Arrives from",
"to": "Departs to", "to": "Departs to",
"desc-beginning": "The train begins here", "desc-beginning": "Outside scenery / begins here",
"desc-arriving": "<i>Arrives from: <b>{prevStationName} ({prevDepartureLine})</b></i>", "desc-arriving": "Arrives from: <b><u>{prevStationName} ({prevDepartureLine})</u></b>",
"desc-online": "On scenery / <i>direction: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-online": "On scenery / direction: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-stopped": "On scenery - stopped / <i>direction: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-stopped": "On scenery - stopped / direction: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-next-arrival": "On scenery / <i>direction: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-next-arrival": "On scenery / direction: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-departed": "On scenery / <i>departed to: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-departed": "On scenery / departed to: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-departed-ends": "On scenery / <i>departed to: <b>{nextStationName}</b></i>", "desc-departed-ends": "On scenery / departed to: <b><u>{nextStationName}</u></b>",
"desc-departed-away": "<i>Departed to: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-departed-away": "Departed to: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-end": "The train terminates here", "desc-end": "The train terminates here",
"desc-terminated": "The train has been terminated" "desc-terminated": "The train has been terminated"
}, },
+11 -9
View File
@@ -338,8 +338,10 @@
"signals-type": "Sygnalizacja: ", "signals-type": "Sygnalizacja: ",
"SBL": "Sceneria posiada SBL na szlakach: ", "SBL": "Sceneria posiada SBL na szlakach: ",
"SUP": "Wymaga programu SUP do kontroli systemu RASP-UZK", "SUP": "Wymaga programu SUP do kontroli systemu RASP-UZK",
"ASDEK": "Wymaga programu ASDEK do detekcji stanów awaryjnych taboru w ruchu", "ASDEK": "Dostępny program ASDEK do detekcji stanów awaryjnych taboru w ruchu",
"default": "Sceneria dostępna domyślnie w paczce z grą", "default": "Sceneria dostępna domyślnie w paczce z grą",
"nonDefault": "Sceneria dostępna do pobrania ze strony forum",
"req-level": "ogólnodostępna | od {lvl} poz. DR | od {lvl} poz. DR",
"non-public": "Sceneria niepubliczna", "non-public": "Sceneria niepubliczna",
"unavailable": "Sceneria niedostępna", "unavailable": "Sceneria niedostępna",
"abandoned": "Sceneria wycofana z rozgrywki", "abandoned": "Sceneria wycofana z rozgrywki",
@@ -577,14 +579,14 @@
"terminates": "KOŃCZY BIEG", "terminates": "KOŃCZY BIEG",
"from": "Przyjedzie z", "from": "Przyjedzie z",
"to": "Odjeżdża do", "to": "Odjeżdża do",
"desc-beginning": "Pociąg rozpoczyna bieg", "desc-beginning": "Poza scenerią / rozpoczyna bieg",
"desc-arriving": "<i>Przyjedzie z: <b>{prevStationName} ({prevDepartureLine})</b></i>", "desc-arriving": "Przyjedzie z: <b><u>{prevStationName} ({prevDepartureLine})</u></b>",
"desc-online": "Na scenerii / <i>kierunek: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-online": "Na scenerii / kierunek: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-stopped": "Na scenerii - postój / <i>kierunek: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-stopped": "Na scenerii - postój / kierunek: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-next-arrival": "Na scenerii / <i>kierunek: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-next-arrival": "Na scenerii / kierunek: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-departed": "Na scenerii / <i>odprawiony do: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-departed": "Na scenerii / odprawiony do: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-departed-ends": "Na scenerii / <i>odprawiony do: <b>{nextStationName}</b></i>", "desc-departed-ends": "Na scenerii / odprawiony do: <b><u>{nextStationName}</u></b>",
"desc-departed-away": "<i>Odprawiony do: <b>{nextStationName} ({nextArrivalLine})</b></i>", "desc-departed-away": "Odprawiony do: <b><u>{nextStationName} ({nextArrivalLine})</u></b>",
"desc-end": "Pociąg kończy bieg", "desc-end": "Pociąg kończy bieg",
"desc-terminated": "Pociąg zakończył bieg" "desc-terminated": "Pociąg zakończył bieg"
}, },
+4 -1
View File
@@ -8,7 +8,8 @@ export const tooltipKeys = [
'VehiclePreviewTooltip', 'VehiclePreviewTooltip',
'SpawnsTooltip', 'SpawnsTooltip',
'UsersTooltip', 'UsersTooltip',
'HtmlTooltip' 'HtmlTooltip',
'TrainInfoTooltip'
] as const; ] as const;
export type TooltipType = (typeof tooltipKeys)[number]; export type TooltipType = (typeof tooltipKeys)[number];
@@ -33,6 +34,7 @@ export const useTooltipStore = defineStore('tooltipStore', {
this.content = ''; this.content = '';
}, },
// Tooltip handler reading attributes of DOM elements
handle(e: MouseEvent) { handle(e: MouseEvent) {
const targetEl = e const targetEl = e
.composedPath() .composedPath()
@@ -44,6 +46,7 @@ export const useTooltipStore = defineStore('tooltipStore', {
return; return;
} }
// Tooltip content is a string but may be parsed to objects / html in corresponding tooltip type components
const tooltipType = targetEl.getAttribute('data-tooltip-type'); const tooltipType = targetEl.getAttribute('data-tooltip-type');
const tooltipContent = targetEl.getAttribute('data-tooltip-content'); const tooltipContent = targetEl.getAttribute('data-tooltip-content');
+22
View File
@@ -253,3 +253,25 @@ export interface VehicleCargo {
id: string; id: string;
weight: number; weight: number;
} }
export interface TooltipUserTrain {
driverName: string;
trainNo: number;
}
export interface TooltipTrainInfo {
mass: number;
length: number;
speed: number;
signal: string;
distance: number;
connectedTrack: string;
trainNo: number;
driverName: string;
driverLevel: number;
currentStationName: string;
currentStationHash: string;
headVehicleName: string;
stockCount: number;
trainTimetableCategory?: string;
}