Merge pull request #134 from Spythere/development

v1.30.3
This commit is contained in:
Spythere
2025-07-05 02:20:55 +02:00
committed by GitHub
13 changed files with 201 additions and 176 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "stacjownik",
"version": "1.30.2",
"version": "1.30.3",
"private": true,
"type": "module",
"scripts": {
+55 -16
View File
@@ -1,5 +1,13 @@
<template>
<section class="info-header">
<button
class="btn btn-return"
:title="$t('scenery.return-btn')"
@click="onReturnButtonClick"
>
<img src="/images/icon-back.svg" alt="return button" />
</button>
<a class="scenery-name" :href="station?.generalInfo?.url" target="_blank">
{{ stationName.replace(/_/g, ' ') }}
</a>
@@ -12,39 +20,64 @@
</section>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue';
<script lang="ts" setup>
import { onMounted, PropType, ref } from 'vue';
import { ActiveScenery, Station } from '../../typings/common';
import { useRoute, useRouter } from 'vue-router';
export default defineComponent({
props: {
station: {
type: Object as PropType<Station>
},
const route = useRoute();
const router = useRouter();
stationName: {
type: String,
required: true
},
const prevPath = ref('/');
onlineScenery: {
type: Object as PropType<ActiveScenery>
}
onMounted(() => {
prevPath.value = (route.meta['prevPath'] as string) ?? '/';
});
defineProps({
station: {
type: Object as PropType<Station>
},
stationName: {
type: String,
required: true
},
onlineScenery: {
type: Object as PropType<ActiveScenery>
}
});
function onReturnButtonClick() {
router.push(prevPath.value);
}
</script>
<style lang="scss" scoped>
@use '../../styles/responsive';
@use 'sass:color';
.info-header {
margin-top: 1em;
.btn-return {
$bgColor: #2b2b2b;
background-color: $bgColor;
margin-bottom: 0.5em;
img {
width: 2em;
}
&:hover {
background-color: color.adjust($color: $bgColor, $lightness: 15%);
}
}
.scenery-name {
font-weight: bold;
font-size: 3em;
text-align: center;
text-transform: uppercase;
}
@@ -58,4 +91,10 @@ export default defineComponent({
color: #aaa;
font-size: 1.2em;
}
@include responsive.smallScreen {
.scenery-name {
font-size: 2.5em;
}
}
</style>
@@ -44,6 +44,7 @@
{{ 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.routeLength" class="length">
{{ (route.routeLength / 1000).toFixed(1) + 'km' }}
</span>
+71 -22
View File
@@ -93,18 +93,56 @@
<span class="timetable-general">
<span class="general-info">
<div class="info-train">
<b
data-tooltip-type="BaseTooltip"
:data-tooltip-content="getCategoryExplanation(row.train.timetableData!.category)"
class="text--primary tooltip-help"
>
{{ row.train.timetableData!.category }}
</b>
<span>&nbsp;</span>
<b>{{ row.train.trainNo }}</b>
<span>&nbsp;&bull;&nbsp;</span>
<span>{{ row.train.driverName }}</span>
<!-- Cargo warnings & details badges -->
<span
class="train-badge twr"
v-if="row.train.timetableData!.twr"
data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('warnings.TWR')"
>
TWR
</span>
<span
class="train-badge tn"
v-if="row.train.timetableData!.hasDangerousCargo"
data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('warnings.TN')"
>
TN
</span>
<span
class="train-badge pn"
v-if="row.train.timetableData!.hasExtraDeliveries"
data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('warnings.PN')"
>
PN
</span>
<!-- Train info -->
<span>
<b
data-tooltip-type="BaseTooltip"
:data-tooltip-content="
getCategoryExplanation(row.train.timetableData!.category)
"
class="text--primary tooltip-help"
>
{{ row.train.timetableData!.category }}
</b>
<b>&nbsp;{{ row.train.trainNo }}</b>
</span>
<span>&bull;</span>
<span>{{ row.train.driverName }}</span>
<span>&bull;</span>
<b style="color: #ddd">{{ row.train.stockList[0] }}</b>
<!-- Train stop comments -->
<span
class="stop-comments-icon"
v-if="row.checkpointStop.comments"
data-tooltip-type="BaseTooltip"
:data-tooltip-content="row.checkpointStop.comments"
@@ -352,6 +390,7 @@ export default defineComponent({
<style lang="scss" scoped>
@use '../../styles/responsive';
@use '../../styles/animations';
@use '../../styles/badge';
.scenery-timetable {
height: 100%;
@@ -468,21 +507,31 @@ export default defineComponent({
.general-info {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.info-number {
color: var(--clr-primary);
}
.info-train {
display: flex;
flex-wrap: wrap;
gap: 0.25em;
}
.info-route {
width: 100%;
}
.info-train > .train-badge {
font-size: 0.85em;
}
img {
height: 0.9em;
vertical-align: middle;
margin: 0 0.25em;
}
.info-number {
color: var(--clr-primary);
}
.info-route {
width: 100%;
}
.stop-comments-icon > img {
width: 1.2em;
vertical-align: middle;
}
.schedule {
@@ -2,11 +2,9 @@
<div class="general-status">
<span
:class="computedScheduledTrain.status"
data-tooltip-type="HtmlTooltip"
:data-tooltip-content="computedScheduledTrain.stopStatusDescription"
@click.prevent="() => {}"
v-html="computedScheduledTrain.stopStatusIndicator"
>
{{ computedScheduledTrain.stopStatusIndicator }}
</span>
</div>
</template>
@@ -28,48 +26,37 @@ export default defineComponent({
computedScheduledTrain() {
const { status, prevElement, currentElement, nextElement } = this.sceneryTimetableRow;
const prevDepartureIndicator = prevElement?.departureRouteExt
? `(${prevElement.departureRouteExt}) ${prevElement.stationName}`
: '---';
const nextArrivalIndicator = nextElement?.arrivalRouteExt
? `(${nextElement.arrivalRouteExt}) ${nextElement.stationName}`
: `${currentElement.stationName}`;
let stopStatusDescription = '',
stopStatusIndicator = '';
let stopStatusIndicator = '';
switch (status) {
case StopStatus.ARRIVING:
stopStatusIndicator = `${this.$t('timetables.from')}: ${prevDepartureIndicator}`;
stopStatusDescription = this.$t('timetables.desc-arriving', {
prevStationName: prevElement?.stationName ?? '',
prevDepartureLine: prevElement?.departureRouteExt ?? ''
});
if (prevElement) {
stopStatusIndicator = this.$t('timetables.desc-arriving', {
prevStationName: prevElement?.stationName ?? '',
prevDepartureLine: prevElement?.departureRouteExt ?? ''
});
} else {
stopStatusIndicator = this.$t('timetables.desc-beginning');
}
break;
case StopStatus.ONLINE:
case StopStatus.STOPPED:
stopStatusIndicator = nextElement?.arrivalRouteExt
? `${this.$t('timetables.to')}: ${nextArrivalIndicator}`
: `${this.$t('timetables.desc-end')}`;
stopStatusDescription = nextElement?.arrivalRouteExt
? this.$t(`timetables.desc-${status}`, {
nextStationName: nextElement?.stationName,
nextArrivalLine: nextElement?.arrivalRouteExt
})
: '';
: this.$t(`timetables.desc-end`);
break;
case StopStatus.DEPARTED:
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
if (!nextElement?.stationName) {
stopStatusDescription = this.$t('timetables.desc-departed-ends', {
stopStatusIndicator = this.$t('timetables.desc-departed-ends', {
nextStationName: currentElement.stationName
});
} else {
stopStatusDescription = this.$t('timetables.desc-departed', {
stopStatusIndicator = this.$t('timetables.desc-departed', {
nextStationName: nextElement?.stationName ?? currentElement.stationName,
nextArrivalLine: nextElement?.arrivalRouteExt
});
@@ -78,16 +65,14 @@ export default defineComponent({
break;
case StopStatus.DEPARTED_AWAY:
stopStatusIndicator = `${this.$t('timetables.to')}: ${nextArrivalIndicator}`;
stopStatusDescription = this.$t('timetables.desc-departed-away', {
stopStatusIndicator = this.$t('timetables.desc-departed-away', {
nextStationName: nextElement?.stationName,
nextArrivalLine: nextElement?.arrivalRouteExt
});
break;
case StopStatus.TERMINATED:
stopStatusIndicator = `X ${this.$t('timetables.desc-terminated')}`;
stopStatusDescription = this.$t('timetables.desc-terminated');
stopStatusIndicator = this.$t('timetables.desc-terminated');
break;
default:
@@ -95,7 +80,6 @@ export default defineComponent({
}
return {
...this.sceneryTimetableRow,
stopStatusDescription,
stopStatusIndicator
};
}
@@ -106,7 +90,6 @@ export default defineComponent({
<style lang="scss" scoped>
.general-status {
margin-top: 0.5em;
cursor: help;
span.arriving {
color: #ccc;
@@ -114,17 +97,14 @@ export default defineComponent({
span.departed {
color: lime;
font-weight: bold;
&-away {
font-weight: bold;
color: #5ecc5e;
}
}
span.stopped {
color: #ffa600;
font-weight: bold;
}
span.online {
@@ -133,7 +113,6 @@ export default defineComponent({
span.terminated {
color: salmon;
font-weight: bold;
}
}
</style>
+31 -14
View File
@@ -57,7 +57,14 @@
<span>{{ stop.departureLine }}</span>
<span v-if="stop.departureLineInfo">
<span> | {{ stop.departureLineInfo.routeSpeed }}</span>
<span>
|
{{
stop.departureLineInfo.routeSpeedExit
? `${stop.departureLineInfo.routeSpeedExit} (${stop.departureLineInfo.routeSpeed})`
: stop.departureLineInfo.routeSpeed
}}</span
>
<img
:src="
@@ -85,13 +92,13 @@
</div>
<div
v-if="stop.sceneryName != scheduleStops[i + 1]?.sceneryName"
v-if="stop.nextPointRef && stop.sceneryName != stop.nextPointRef.sceneryName"
class="scenery-change-name"
>
<span>{{ scheduleStops[i + 1].sceneryName }}</span>
<span>{{ stop.nextPointRef.sceneryName }}</span>
<i
v-if="!scheduleStops[i + 1].isSceneryOnline"
v-if="!stop.nextPointRef.isSceneryOnline"
class="fa-solid fa-ban fa-sm"
data-tooltip-type="BaseTooltip"
:data-tooltip-content="$t('app.tooltip-scenery-offline')"
@@ -101,30 +108,33 @@
<div
class="scenery-route"
v-if="stop.sceneryName != scheduleStops[i + 1]?.sceneryName"
v-if="stop.nextPointRef && stop.sceneryName != stop.nextPointRef.sceneryName"
>
<span> {{ scheduleStops[i + 1].arrivalLine }}</span>
<span> {{ stop.nextPointRef.arrivalLine }}</span>
<span v-if="scheduleStops[i + 1].arrivalLineInfo">
<span> | {{ scheduleStops[i + 1].arrivalLineInfo!.routeSpeed }} </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
>
<img
:src="
scheduleStops[i + 1].arrivalLineInfo?.isElectric
stop.nextPointRef.arrivalLineInfo?.isElectric
? '/images/icon-catenary.svg'
: '/images/icon-we4a.png'
"
data-tooltip-type="BaseTooltip"
:data-tooltip-content="
$t(
`trains.${!scheduleStops[i + 1].arrivalLineInfo?.isElectric ? 'no-' : ''}catenary-tooltip`
`trains.${!stop.nextPointRef.arrivalLineInfo?.isElectric ? 'no-' : ''}catenary-tooltip`
)
"
width="14"
/>
<img
v-if="scheduleStops[i + 1].arrivalLineInfo!.isRouteSBL"
v-if="stop.nextPointRef.arrivalLineInfo!.isRouteSBL"
src="/images/icon-sbl-transparent.svg"
width="14"
data-tooltip-type="BaseTooltip"
@@ -228,7 +238,7 @@ export default defineComponent({
departureLineInfo = pathData.departureLineData;
}
for (const stop of followingStops) {
followingStops.forEach((stop, i) => {
let isExternal = false;
if (stop.arrivalLine === currentPath.arrivalRouteExt) {
@@ -287,7 +297,9 @@ export default defineComponent({
status: stop.confirmed ? 'confirmed' : stop.stopped ? 'stopped' : 'unconfirmed',
sceneryName: currentPath.stationName,
isSceneryOnline: pathData?.isOnline ?? false
isSceneryOnline: pathData?.isOnline ?? false,
nextPointRef: null
};
if (internalRouteInfo) {
@@ -309,6 +321,11 @@ export default defineComponent({
stopRows.push(rowData);
// Assign this row data object to the last one as reference
if (i != 0) {
stopRows[i - 1].nextPointRef = rowData;
}
if (stop.departureLine === currentPath.departureRouteExt) {
// Reverse search for last scenery checkpoint
if (pathData?.departureLineData) {
@@ -328,7 +345,7 @@ export default defineComponent({
currentPath = timetablePath[++currentPathIndex];
pathData = this.getPathSceneryData(currentPath);
}
}
});
return stopRows;
},
+2
View File
@@ -196,4 +196,6 @@ export interface TrainSchedulePoint {
isSBL: boolean;
sceneryName: string | null;
isSceneryOnline: boolean;
nextPointRef: TrainSchedulePoint | null;
}
+11 -10
View File
@@ -543,7 +543,7 @@
"no-users": "NO ACTIVE PLAYERS",
"no-spawns": "NO OPEN SPAWNS",
"no-scenery": "Oops! This scenery doesn't exist!",
"return-btn": "Return",
"return-btn": "BACK TO THE LAST SITE",
"history-btn": "View the dispatcher history",
"info-btn": "Return to the scenery view",
"authors-title": "Scenery author | Scenery authors",
@@ -589,15 +589,16 @@
"terminated": "Timetable terminated",
"begins": "BEGINS HERE",
"terminates": "TERMINATES\nHERE",
"from": "FROM",
"to": "TO",
"desc-arriving": "The train is not here yet.\nIt's going to come from: <b>{prevStationName} (route {prevDepartureLine})</b>",
"desc-online": "The train is at the station.\nIt's going to leave to: <b>{nextStationName} (route {nextArrivalLine})</b>",
"desc-stopped": "The train is at the station and is stopped.\nIt's going to leave towards: <b>{nextStationName} (route {nextArrivalLine})</b>",
"desc-next-arrival": "Leaves towards: <b>{nextStationName} (route {nextArrivalLine})</b>",
"desc-departed": "The train is at the station and it's been departed.\nLeaves towards: <b>{nextStationName} (route {nextArrivalLine})</b>",
"desc-departed-ends": "The train is at the station and it's been departed.\nLeaves towards station: <b>{nextStationName}</b>",
"desc-departed-away": "The train has been departed to:\n<b>{nextStationName} (route {nextArrivalLine})</b>",
"from": "Arrives from",
"to": "Departs to",
"desc-beginning": "The train begins here",
"desc-arriving": "<i>Arrives from: <b>{prevStationName} ({prevDepartureLine})</b></i>",
"desc-online": "On scenery / <i>direction: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-stopped": "On scenery - stopped / <i>direction: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-next-arrival": "On scenery / <i>direction: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-departed": "On scenery / <i>departed to: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-departed-ends": "On scenery / <i>departed to: <b>{nextStationName}</b></i>",
"desc-departed-away": "<i>Departed to: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-end": "The train terminates here",
"desc-terminated": "The train has been terminated"
},
+12 -11
View File
@@ -529,7 +529,7 @@
"no-users": "BRAK AKTYWNYCH GRACZY",
"no-spawns": "BRAK OTWARTYCH SPAWNÓW",
"no-scenery": "Ups! Ta sceneria nie istnieje!",
"return-btn": "Powrót",
"return-btn": "POWRÓT DO POPRZEDNIEJ STRONY",
"history-btn": "Przejdź do widoku historii dyżurnych ruchu",
"info-btn": "Wróć do widoku scenerii",
"authors-title": "Autor scenerii | Autorzy scenerii",
@@ -575,17 +575,18 @@
"terminated": "Rozkład jazdy zakończony",
"begins": "ROZPOCZYNA\nBIEG",
"terminates": "KOŃCZY BIEG",
"from": "Z",
"to": "DO",
"desc-arriving": "Pociągu nie ma jeszcze na tej scenerii.\nPrzyjedzie z: <b>{prevStationName} (szlak {prevDepartureLine})</b>",
"desc-online": "Pociąg jest na tej scenerii.\nOdjedzie w kierunku: <b>{nextStationName} (szlak {nextArrivalLine})</b>",
"desc-stopped": "Pociąg jest na tej scenerii i odbywa postój.\nOdjedzie w kierunku: <b>{nextStationName} (szlak {nextArrivalLine})</b>",
"desc-next-arrival": "Odjeżdża do:\n<b>{nextStationName} (szlak {nextArrivalLine})</b>",
"desc-departed": "Pociąg jest na tej scenerii i został odprawiony.\nOdjeżdża w kierunku: <b>{nextStationName} (szlak {nextArrivalLine})</b>",
"desc-departed-ends": "Pociąg jest na tej scenerii i został odprawiony.\nOdjechał w kierunku stacji: <b>{nextStationName}</b>",
"desc-departed-away": "Pociąg został odprawiony i odjechał do:\n<b>{nextStationName} (szlak {nextArrivalLine})</b>",
"from": "Przyjedzie z",
"to": "Odjeżdża do",
"desc-beginning": "Pociąg rozpoczyna bieg",
"desc-arriving": "<i>Przyjedzie z: <b>{prevStationName} ({prevDepartureLine})</b></i>",
"desc-online": "Na scenerii / <i>kierunek: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-stopped": "Na scenerii - postój / <i>kierunek: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-next-arrival": "Na scenerii / <i>kierunek: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-departed": "Na scenerii / <i>odprawiony do: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-departed-ends": "Na scenerii / <i>odprawiony do: <b>{nextStationName}</b></i>",
"desc-departed-away": "<i>Odprawiony do: <b>{nextStationName} ({nextArrivalLine})</b></i>",
"desc-end": "Pociąg kończy bieg",
"desc-terminated": "Pociąg skończył bieg"
"desc-terminated": "Pociąg zakończył bieg"
},
"history": {
"title": "DZIENNIK ROZKŁADÓW JAZDY"
-42
View File
@@ -297,48 +297,6 @@ a.a-button {
}
}
.return-btn {
display: none;
justify-content: center;
align-items: center;
position: fixed;
right: 2.5rem;
bottom: 4rem;
z-index: 100;
width: 3.5rem;
font-size: 3rem;
background-color: #555;
outline: 3px solid #222;
color: white;
border-radius: 50%;
cursor: pointer;
&:hover {
background-color: #3c3c3c;
}
img {
width: 1.3em;
}
@include responsive.smallScreen {
bottom: 1em;
right: 0;
left: 50%;
width: 1em;
height: 1em;
transform: translateX(-50%);
}
}
// Basic tooltip
[data-tooltip] {
cursor: help;
+1
View File
@@ -142,6 +142,7 @@ export interface StationRoutesInfo {
isRouteSBL: boolean;
routeLength: number;
routeSpeed: number;
routeSpeedExit?: number;
routeTracks: number;
hidden?: boolean;
realLineNo?: number;
-23
View File
@@ -2,12 +2,6 @@
<div class="scenery-view">
<div class="scenery-wrapper" ref="card-wrapper">
<div class="scenery-left">
<div class="scenery-actions">
<button class="back-btn" :title="$t('scenery.return-btn')" @click="onReturnButtonClick">
<img src="/images/icon-back.svg" alt="return button" />
</button>
</div>
<SceneryHeader
:stationName="station"
:station="stationInfo"
@@ -63,14 +57,11 @@ import SceneryTimetablesHistory from '../components/SceneryView/SceneryTimetable
import SceneryDispatchersHistory from '../components/SceneryView/SceneryDispatchersHistory.vue';
import { useApiStore } from '../store/apiStore';
import { ref } from 'vue';
import { Status } from '../typings/common';
const route = useRoute();
const router = useRouter();
const prevPath = ref('/');
const props = defineProps({
region: {
type: String,
@@ -101,10 +92,6 @@ const viewModes = [
}
];
onMounted(() => {
prevPath.value = (route.meta['prevPath'] as string) ?? '/';
});
const currentMode = computed(() => {
return route.query.view?.toString() ?? 'SceneryTimetable';
});
@@ -139,21 +126,11 @@ function setViewMode(componentName: string) {
}
});
}
function onReturnButtonClick() {
router.push(prevPath.value);
}
</script>
<style lang="scss" scoped>
@use '../styles/responsive';
button.back-btn {
img {
width: 2em;
}
}
.scenery {
&-view {
display: flex;
+1 -1
View File
@@ -3202,7 +3202,7 @@ sharp@*, sharp@^0.33.5:
showdown@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz"
resolved "https://registry.yarnpkg.com/showdown/-/showdown-2.1.0.tgz#1251f5ed8f773f0c0c7bfc8e6fd23581f9e545c5"
integrity sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==
dependencies:
commander "^9.0.0"