mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
rozbudowany szczegółówy RJ pociągu
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<svg width="160" height="150" viewBox="0 0 160 150" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="160" height="150" viewBox="0 0 160 150" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M10.163 139L80 12.4204L149.837 139H80H10.163Z" stroke="white" stroke-width="12"/>
|
<path d="M10.163 139L80 12.4204L149.837 139H80H10.163Z" stroke="salmon" stroke-width="15"/>
|
||||||
<path d="M85.4488 50.3354V80.6619C85.4488 83.8784 85.2898 87.0418 84.9717 90.1522C84.6536 93.2273 84.2294 96.4968 83.6992 99.9606H74.8451C74.315 96.4968 73.8908 93.2273 73.5727 90.1522C73.2546 87.0418 73.0955 83.8784 73.0955 80.6619V50.3354H85.4488ZM71.0808 119.789C71.0808 118.694 71.2752 117.651 71.664 116.661C72.0882 115.672 72.6537 114.823 73.3606 114.117C74.1029 113.41 74.9689 112.844 75.9585 112.42C76.9482 111.996 78.0086 111.784 79.1396 111.784C80.2354 111.784 81.278 111.996 82.2677 112.42C83.2574 112.844 84.1057 113.41 84.8126 114.117C85.5195 114.823 86.085 115.672 86.5092 116.661C86.9333 117.651 87.1454 118.694 87.1454 119.789C87.1454 120.921 86.9333 121.981 86.5092 122.971C86.085 123.925 85.5195 124.756 84.8126 125.462C84.1057 126.169 83.2574 126.717 82.2677 127.106C81.278 127.53 80.2354 127.742 79.1396 127.742C78.0086 127.742 76.9482 127.53 75.9585 127.106C74.9689 126.717 74.1029 126.169 73.3606 125.462C72.6537 124.756 72.0882 123.925 71.664 122.971C71.2752 121.981 71.0808 120.921 71.0808 119.789Z" fill="#FFFBFB"/>
|
<path d="M85.4488 50.3354V80.6619C85.4488 83.8784 85.2898 87.0418 84.9717 90.1522C84.6536 93.2273 84.2294 96.4968 83.6992 99.9606H74.8451C74.315 96.4968 73.8908 93.2273 73.5727 90.1522C73.2546 87.0418 73.0955 83.8784 73.0955 80.6619V50.3354H85.4488ZM71.0808 119.789C71.0808 118.694 71.2752 117.651 71.664 116.661C72.0882 115.672 72.6537 114.823 73.3606 114.117C74.1029 113.41 74.9689 112.844 75.9585 112.42C76.9482 111.996 78.0086 111.784 79.1396 111.784C80.2354 111.784 81.278 111.996 82.2677 112.42C83.2574 112.844 84.1057 113.41 84.8126 114.117C85.5195 114.823 86.085 115.672 86.5092 116.661C86.9333 117.651 87.1454 118.694 87.1454 119.789C87.1454 120.921 86.9333 121.981 86.5092 122.971C86.085 123.925 85.5195 124.756 84.8126 125.462C84.1057 126.169 83.2574 126.717 82.2677 127.106C81.278 127.53 80.2354 127.742 79.1396 127.742C78.0086 127.742 76.9482 127.53 75.9585 127.106C74.9689 126.717 74.1029 126.169 73.3606 125.462C72.6537 124.756 72.0882 123.925 71.664 122.971C71.2752 121.981 71.0808 120.921 71.0808 119.789Z" fill="white"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
+7
-6
@@ -33,16 +33,17 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, watch } from 'vue';
|
import { defineComponent, watch } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import packageInfo from '.././package.json';
|
||||||
|
|
||||||
import Clock from './components/App/Clock.vue';
|
import Clock from './components/App/Clock.vue';
|
||||||
|
|
||||||
import packageInfo from '.././package.json';
|
|
||||||
|
|
||||||
import { useMainStore } from './store/mainStore';
|
import { useMainStore } from './store/mainStore';
|
||||||
|
|
||||||
import StatusIndicator from './components/App/StatusIndicator.vue';
|
import StatusIndicator from './components/App/StatusIndicator.vue';
|
||||||
import TrainModal from './components/Global/TrainModal.vue';
|
|
||||||
import AppHeader from './components/App/AppHeader.vue';
|
import AppHeader from './components/App/AppHeader.vue';
|
||||||
import axios from 'axios';
|
import TrainModal from './components/TrainsView/TrainModal.vue';
|
||||||
|
|
||||||
import StorageManager from './managers/storageManager';
|
import StorageManager from './managers/storageManager';
|
||||||
import { useApiStore } from './store/apiStore';
|
import { useApiStore } from './store/apiStore';
|
||||||
import { Status } from './typings/common';
|
import { Status } from './typings/common';
|
||||||
@@ -51,8 +52,8 @@ export default defineComponent({
|
|||||||
components: {
|
components: {
|
||||||
Clock,
|
Clock,
|
||||||
StatusIndicator,
|
StatusIndicator,
|
||||||
TrainModal,
|
AppHeader,
|
||||||
AppHeader
|
TrainModal
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
|||||||
@@ -1,123 +0,0 @@
|
|||||||
<template>
|
|
||||||
<span class="stop-date">
|
|
||||||
<span
|
|
||||||
class="date arrival"
|
|
||||||
v-if="!stop.beginsHere"
|
|
||||||
:class="{
|
|
||||||
delayed: stop.arrivalDelay > 0 && (stop.confirmed || stop.stopped),
|
|
||||||
preponed: stop.arrivalDelay < 0 && (stop.confirmed || stop.stopped),
|
|
||||||
'on-time': stop.arrivalDelay == 0 && stop.confirmed
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<span v-if="stop.arrivalDelay != 0 && (stop.confirmed || stop.stopped)">
|
|
||||||
<s>{{ timestampToString(stop.arrivalTimestamp) }}</s>
|
|
||||||
{{ timestampToString(stop.arrivalRealTimestamp) }}
|
|
||||||
({{ stop.arrivalDelay > 0 ? '+' : '' }}{{ stop.arrivalDelay }})
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else>
|
|
||||||
{{ timestampToString(stop.arrivalTimestamp) }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span
|
|
||||||
class="date stop"
|
|
||||||
v-if="stop.stopTime || stop.stopped"
|
|
||||||
:class="stop.stopType.replace(', ', '-')"
|
|
||||||
>
|
|
||||||
{{ stop.stopTime }} {{ stop.stopType == '' ? 'pt' : stop.stopType }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span
|
|
||||||
class="date departure"
|
|
||||||
v-if="!stop.terminatesHere && (stop.stopTime != 0 || stop.stopped)"
|
|
||||||
:class="{
|
|
||||||
delayed: stop.departureDelay > 0 && stop.confirmed,
|
|
||||||
preponed: stop.departureDelay < 0 && stop.confirmed
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<span v-if="stop.departureDelay != 0 && stop.confirmed">
|
|
||||||
<s>{{ timestampToString(stop.departureTimestamp) }}</s>
|
|
||||||
{{ timestampToString(stop.departureRealTimestamp) }}
|
|
||||||
|
|
||||||
({{ stop.departureDelay > 0 ? '+' : '' }}{{ stop.departureDelay }})
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else>
|
|
||||||
{{ timestampToString(stop.departureTimestamp) }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { PropType, defineComponent } from 'vue';
|
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
|
||||||
import { TrainStop } from '../../store/typings';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
mixins: [dateMixin],
|
|
||||||
|
|
||||||
props: {
|
|
||||||
stop: {
|
|
||||||
type: Object as PropType<TrainStop>,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
$preponedClr: lime;
|
|
||||||
$delayedClr: salmon;
|
|
||||||
$dateClr: #525151;
|
|
||||||
$stopExchangeClr: #db8e29;
|
|
||||||
$stopDefaultClr: #252525;
|
|
||||||
|
|
||||||
.stop-date {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.date {
|
|
||||||
background: $dateClr;
|
|
||||||
padding: 0.3em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stop {
|
|
||||||
&.ph,
|
|
||||||
&.ph-pm,
|
|
||||||
&.pm {
|
|
||||||
background: $stopExchangeClr;
|
|
||||||
}
|
|
||||||
|
|
||||||
background: $stopDefaultClr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrival,
|
|
||||||
.departure {
|
|
||||||
&.delayed {
|
|
||||||
s {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: $delayedClr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.preponed {
|
|
||||||
s {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: $preponedClr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<span class="stop-label" :data-sbl="stop.isSBL">
|
||||||
|
<span class="name" v-html="stop.nameHtml"></span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="date arrival"
|
||||||
|
v-if="stop.position != 'begin'"
|
||||||
|
:class="{
|
||||||
|
delayed: stop.arrivalDelay > 0 && stop.status != 'unconfirmed',
|
||||||
|
preponed: stop.arrivalDelay < 0 && stop.status != 'unconfirmed',
|
||||||
|
'on-time': stop.arrivalDelay == 0 && stop.status == 'confirmed'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span v-if="stop.arrivalDelay != 0 && stop.status != 'unconfirmed'">
|
||||||
|
<s>{{ timestampToString(stop.arrivalScheduled) }}</s>
|
||||||
|
{{ timestampToString(stop.arrivalReal) }}
|
||||||
|
({{ stop.arrivalDelay > 0 ? '+' : '' }}{{ stop.arrivalDelay }})
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span v-else>
|
||||||
|
{{ timestampToString(stop.arrivalScheduled) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="date stop"
|
||||||
|
v-if="stop.duration || stop.status == 'stopped'"
|
||||||
|
:class="stop.type.replace(', ', '-')"
|
||||||
|
>
|
||||||
|
{{ stop.duration }} {{ stop.type == '' ? 'pt' : stop.type }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="date departure"
|
||||||
|
v-if="stop.position != 'end' && (stop.duration != 0 || stop.status == 'stopped')"
|
||||||
|
:class="{
|
||||||
|
delayed: stop.departureDelay > 0 && stop.status == 'confirmed',
|
||||||
|
preponed: stop.departureDelay < 0 && stop.status == 'confirmed'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span v-if="stop.departureDelay != 0 && stop.status == 'confirmed'">
|
||||||
|
<s>{{ timestampToString(stop.departureScheduled) }}</s>
|
||||||
|
{{ timestampToString(stop.departureReal) }}
|
||||||
|
|
||||||
|
({{ stop.departureDelay > 0 ? '+' : '' }}{{ stop.departureDelay }})
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span v-else>
|
||||||
|
{{ timestampToString(stop.departureScheduled) }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { PropType, defineComponent } from 'vue';
|
||||||
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
|
import { TrainScheduleStop } from './TrainSchedule.vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
mixins: [dateMixin],
|
||||||
|
|
||||||
|
props: {
|
||||||
|
stop: {
|
||||||
|
type: Object as PropType<TrainScheduleStop>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$preponedClr: lime;
|
||||||
|
$delayedClr: salmon;
|
||||||
|
$dateClr: #525151;
|
||||||
|
$stopExchangeClr: #db8e29;
|
||||||
|
$stopDefaultClr: #252525;
|
||||||
|
$stopNameClr: #22a8d1;
|
||||||
|
|
||||||
|
.stop-label {
|
||||||
|
&[data-sbl='true'] {
|
||||||
|
.date {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
background: none;
|
||||||
|
color: #aaa;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
background: $stopNameClr;
|
||||||
|
padding: 0.3em 0.5em;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.misc {
|
||||||
|
background: gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
background: $dateClr;
|
||||||
|
padding: 0.3em 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stop {
|
||||||
|
&.ph,
|
||||||
|
&.ph-pm,
|
||||||
|
&.pm {
|
||||||
|
background: $stopExchangeClr;
|
||||||
|
}
|
||||||
|
|
||||||
|
background: $stopDefaultClr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrival,
|
||||||
|
.departure {
|
||||||
|
&.delayed {
|
||||||
|
s {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $delayedClr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.preponed {
|
||||||
|
s {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $preponedClr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -15,19 +15,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
import modalTrainMixin from '../../mixins/modalTrainMixin';
|
||||||
import trainInfoMixin from '../../mixins/trainInfoMixin';
|
import TrainInfo from './TrainInfo.vue';
|
||||||
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
import TrainSchedule from './TrainSchedule.vue';
|
||||||
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { TrainInfo, TrainSchedule },
|
components: { TrainInfo, TrainSchedule },
|
||||||
mixins: [trainInfoMixin, modalTrainMixin],
|
mixins: [modalTrainMixin],
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isTopBarVisible: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
activated() {
|
activated() {
|
||||||
const contentEl = this.$refs['content'] as HTMLElement;
|
const contentEl = this.$refs['content'] as HTMLElement;
|
||||||
@@ -2,83 +2,139 @@
|
|||||||
<div class="train-schedule" @click="toggleShowState">
|
<div class="train-schedule" @click="toggleShowState">
|
||||||
<StockList :trainStockList="train.stockList" />
|
<StockList :trainStockList="train.stockList" />
|
||||||
|
|
||||||
<!-- <div class="train-stock"> -->
|
|
||||||
<!-- <ul>
|
|
||||||
<li v-for="(stockName, i) in train.stockList" :key="i">
|
|
||||||
<p>{{ stockName.split(':')[0].split('_').splice(0, 2).join(' ') }} {{ stockName.split(':')[1] }}</p>
|
|
||||||
<TrainThumbnail :name="stockName" />
|
|
||||||
</li>
|
|
||||||
</ul> -->
|
|
||||||
<!-- </div> -->
|
|
||||||
|
|
||||||
<div class="schedule-wrapper" v-if="train.timetableData">
|
<div class="schedule-wrapper" v-if="train.timetableData">
|
||||||
<ul class="stop_list">
|
<div class="stops">
|
||||||
<li
|
<div
|
||||||
v-for="(stop, i) in train.timetableData.followingStops"
|
v-for="(stop, i) in scheduleStops"
|
||||||
:key="i"
|
:key="i"
|
||||||
class="stop"
|
class="stop"
|
||||||
:class="addClasses(stop, i)"
|
:data-status="stop.status"
|
||||||
|
:data-position="stop.position"
|
||||||
|
:data-delayed="stop.departureDelay > 0"
|
||||||
|
:data-stop-type="stop.type"
|
||||||
|
:data-minor-stop-active="stop.isActive"
|
||||||
|
:data-last-confirmed="stop.isLastConfirmed"
|
||||||
|
:data-track-count="stop.arrivalTrackCount ?? stop.departureTrackCount"
|
||||||
>
|
>
|
||||||
<span class="stop_info">
|
<span class="stop_info">
|
||||||
<div class="indicator"></div>
|
<span class="distance">
|
||||||
|
{{ stop.distance.toFixed(1) }}
|
||||||
<div class="progress-bar"></div>
|
|
||||||
|
|
||||||
<div class="stop-bar"></div>
|
|
||||||
|
|
||||||
<span class="distance" v-if="stop.stopDistance">
|
|
||||||
{{ Math.floor(stop.stopDistance) }}
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="stop-name" v-html="stop.stopName"> </span>
|
<div class="progress">
|
||||||
|
<div class="node"></div>
|
||||||
|
<div class="line line_stop" v-if="stop.status == 'stopped'"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<StopDate :stop="stop" />
|
<StopLabel :stop="stop" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="stop_line" v-if="i < train.timetableData!.followingStops.length - 1">
|
<div class="stop_line" v-if="i < scheduleStops.length - 1">
|
||||||
<div class="progress-bar"></div>
|
<!-- Grid placeholder -->
|
||||||
|
<div class="line-speed">
|
||||||
<div v-if="stop.comments" style="color: salmon">
|
<div>{{ stop.departureSpeed }}</div>
|
||||||
<b>{{ stop.stopNameRAW }} </b>: <span v-html="stop.comments"></span>
|
<div>{{ stop.arrivalSpeed }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span
|
<div class="progress">
|
||||||
v-if="
|
<div class="line line_connection"></div>
|
||||||
stop.departureLine == train.timetableData!.followingStops[i + 1].arrivalLine &&
|
</div>
|
||||||
!/sbl/gi.test(stop.departureLine!)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ stop.departureLine }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-else-if="!/sbl/gi.test(stop.departureLine!)">
|
<div class="bottom-line-info">
|
||||||
{{ stop.departureLine }} /
|
<!-- <div>
|
||||||
{{ train.timetableData!.followingStops[i + 1].arrivalLine }}
|
{{ stop.sceneryName }}
|
||||||
</span>
|
</div> -->
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stop_line" v-else>
|
<div class="info-comments" v-if="stop.comments" style="color: salmon">
|
||||||
<div v-if="stop.comments" style="color: salmon">
|
<img src="/images/icon-warning.svg" alt="icon-warning" width="20" />
|
||||||
<b>{{ stop.stopNameRAW }} </b>: <span v-html="stop.comments"></span>
|
<b v-html="stop.comments"></b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Routes -->
|
||||||
|
<span
|
||||||
|
v-if="
|
||||||
|
stop.departureLine == train.timetableData!.followingStops[i + 1].arrivalLine &&
|
||||||
|
!/sbl/gi.test(stop.departureLine!)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ stop.departureLine }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span v-else-if="!/sbl/gi.test(stop.departureLine!)">
|
||||||
|
<div>{{ stop.departureLine }}</div>
|
||||||
|
<div
|
||||||
|
class="scenery-change-name"
|
||||||
|
v-if="
|
||||||
|
i < scheduleStops.length - 1 &&
|
||||||
|
stop.sceneryName != scheduleStops[i + 1].sceneryName
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ scheduleStops[i + 1].sceneryName }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ train.timetableData!.followingStops[i + 1].arrivalLine }}
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- || {{ stop.departureSpeed || '---' }} || {{ stop.arrivalSpeed || '---' }} -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import dateMixin from '../../mixins/dateMixin';
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
import Train from '../../scripts/interfaces/Train';
|
import Train from '../../scripts/interfaces/Train';
|
||||||
import { useMainStore } from '../../store/mainStore';
|
import StopLabel from './StopLabel.vue';
|
||||||
import StopDate from '../Global/StopDate.vue';
|
|
||||||
import StockList from '../Global/StockList.vue';
|
import StockList from '../Global/StockList.vue';
|
||||||
import { TrainStop } from '../../store/typings';
|
import { useMainStore } from '../../store/mainStore';
|
||||||
|
import { useApiStore } from '../../store/apiStore';
|
||||||
|
|
||||||
|
export interface TrainScheduleStop {
|
||||||
|
nameHtml: string;
|
||||||
|
nameRaw: string;
|
||||||
|
|
||||||
|
status: 'confirmed' | 'unconfirmed' | 'stopped';
|
||||||
|
type: string;
|
||||||
|
position: 'begin' | 'end' | 'en-route';
|
||||||
|
|
||||||
|
arrivalScheduled: number;
|
||||||
|
arrivalReal: number;
|
||||||
|
|
||||||
|
departureScheduled: number;
|
||||||
|
departureReal: number;
|
||||||
|
|
||||||
|
departureDelay: number;
|
||||||
|
arrivalDelay: number;
|
||||||
|
|
||||||
|
duration: number | null;
|
||||||
|
|
||||||
|
isActive: boolean;
|
||||||
|
isLastConfirmed: boolean;
|
||||||
|
isSBL: boolean;
|
||||||
|
|
||||||
|
sceneryName: string | null;
|
||||||
|
sceneryHash: string;
|
||||||
|
distance: number;
|
||||||
|
|
||||||
|
departureLine: string | null;
|
||||||
|
arrivalLine: string | null;
|
||||||
|
|
||||||
|
arrivalSpeed: number | null;
|
||||||
|
departureSpeed: number | null;
|
||||||
|
|
||||||
|
arrivalTrackCount: number | null;
|
||||||
|
departureTrackCount: number | null;
|
||||||
|
|
||||||
|
comments: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { StopDate, StockList },
|
components: { StopLabel, StockList },
|
||||||
props: {
|
props: {
|
||||||
train: {
|
train: {
|
||||||
type: Object as PropType<Train>,
|
type: Object as PropType<Train>,
|
||||||
@@ -90,62 +146,151 @@ export default defineComponent({
|
|||||||
|
|
||||||
emits: ['click'],
|
emits: ['click'],
|
||||||
|
|
||||||
setup(props) {
|
data() {
|
||||||
return {
|
return {
|
||||||
store: useMainStore(),
|
store: useMainStore(),
|
||||||
|
apiStore: useApiStore()
|
||||||
lastConfirmed: computed(() => {
|
|
||||||
return props.train.timetableData!.followingStops.findIndex(
|
|
||||||
(stop, i, stops) => stop.confirmed && !stops[i + 1]?.confirmed && !stops[i + 1]?.stopped
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
activeMinorStops: computed(() => {
|
|
||||||
const lastMajorConfirmed = props.train.timetableData!.followingStops.findIndex(
|
|
||||||
(stop, i, stops) => stop.confirmed && !stops[i + 1]?.confirmed
|
|
||||||
);
|
|
||||||
|
|
||||||
const activeMinorStopList: number[] = [];
|
|
||||||
if (lastMajorConfirmed + 1 >= props.train.timetableData!.followingStops.length)
|
|
||||||
return activeMinorStopList;
|
|
||||||
|
|
||||||
for (
|
|
||||||
let i = lastMajorConfirmed + 1;
|
|
||||||
i < props.train.timetableData!.followingStops.length;
|
|
||||||
i++
|
|
||||||
) {
|
|
||||||
if (/po\.|sbl/gi.test(props.train.timetableData!.followingStops[i].stopNameRAW))
|
|
||||||
activeMinorStopList.push(i);
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return activeMinorStopList;
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
scheduleStops(): TrainScheduleStop[] {
|
||||||
|
let currentSceneryIndex = 0;
|
||||||
|
let lastTrackCount = 2;
|
||||||
|
|
||||||
|
return (
|
||||||
|
this.train.timetableData?.followingStops.map((stop, i, arr) => {
|
||||||
|
if (
|
||||||
|
i > 0 &&
|
||||||
|
stop.arrivalLine &&
|
||||||
|
stop.arrivalLine != arr[i - 1].departureLine &&
|
||||||
|
!/sbl/gi.test(stop.arrivalLine)
|
||||||
|
)
|
||||||
|
currentSceneryIndex++;
|
||||||
|
|
||||||
|
const sceneryInfo = this.apiStore.sceneryData.find(
|
||||||
|
(sd) =>
|
||||||
|
sd.name.toLocaleLowerCase() ==
|
||||||
|
this.timetableSceneryNames[currentSceneryIndex].toLocaleLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
const nextSceneryInfo = this.apiStore.sceneryData.find(
|
||||||
|
(sd) =>
|
||||||
|
sd.name.toLocaleLowerCase() ==
|
||||||
|
this.timetableSceneryNames[currentSceneryIndex + 1]?.toLocaleLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
const arrivalLineInfo = nextSceneryInfo?.routesInfo.find(
|
||||||
|
(r) => r.routeName == arr[i + 1]?.arrivalLine
|
||||||
|
);
|
||||||
|
|
||||||
|
const departureLineInfo = sceneryInfo?.routesInfo.find(
|
||||||
|
(r) => r.routeName == stop.departureLine
|
||||||
|
);
|
||||||
|
|
||||||
|
// let nextOuterLineName = '';
|
||||||
|
// for(let j = i; i < arr.length - 2; i++) {
|
||||||
|
// if(arr[j].departureLine && arr[j].departureLine != arr[j+1].arrivalLine) {
|
||||||
|
// nextOuterLineName = arr[j].departureLine!;
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
lastTrackCount = departureLineInfo?.routeTracks ?? lastTrackCount;
|
||||||
|
|
||||||
|
return {
|
||||||
|
nameHtml: stop.stopName,
|
||||||
|
nameRaw: stop.stopNameRAW,
|
||||||
|
|
||||||
|
arrivalScheduled: stop.arrivalTimestamp,
|
||||||
|
arrivalReal: stop.arrivalRealTimestamp,
|
||||||
|
|
||||||
|
departureScheduled: stop.departureTimestamp,
|
||||||
|
departureReal: stop.departureRealTimestamp,
|
||||||
|
|
||||||
|
departureDelay: stop.departureDelay,
|
||||||
|
arrivalDelay: stop.arrivalDelay,
|
||||||
|
|
||||||
|
duration: stop.stopTime,
|
||||||
|
|
||||||
|
comments: stop.comments ?? null,
|
||||||
|
|
||||||
|
arrivalLine: stop.arrivalLine,
|
||||||
|
departureLine: stop.departureLine,
|
||||||
|
|
||||||
|
arrivalSpeed: arrivalLineInfo?.routeSpeed ?? null,
|
||||||
|
departureSpeed: departureLineInfo?.routeSpeed ?? null,
|
||||||
|
|
||||||
|
arrivalTrackCount: arrivalLineInfo?.routeTracks ?? null,
|
||||||
|
departureTrackCount: departureLineInfo?.routeTracks ?? lastTrackCount,
|
||||||
|
|
||||||
|
type: stop.stopType,
|
||||||
|
distance: stop.stopDistance,
|
||||||
|
isActive: this.activeMinorStops.includes(i),
|
||||||
|
isLastConfirmed: this.lastConfirmed === i && !stop.terminatesHere,
|
||||||
|
isSBL: /sbl/gi.test(stop.stopName),
|
||||||
|
position: stop.beginsHere ? 'begin' : stop.terminatesHere ? 'end' : 'en-route',
|
||||||
|
sceneryHash: '',
|
||||||
|
sceneryName: this.timetableSceneryNames[currentSceneryIndex],
|
||||||
|
status: stop.confirmed ? 'confirmed' : stop.stopped ? 'stopped' : 'unconfirmed'
|
||||||
|
};
|
||||||
|
}) ?? []
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
lastConfirmed() {
|
||||||
|
return this.train.timetableData?.followingStops.findIndex(
|
||||||
|
(stop, i, stops) => stop.confirmed && !stops[i + 1]?.confirmed && !stops[i + 1]?.stopped
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
activeMinorStops() {
|
||||||
|
if (!this.train.timetableData) return [];
|
||||||
|
|
||||||
|
const lastMajorConfirmed = this.train.timetableData.followingStops.findIndex(
|
||||||
|
(stop, i, stops) => stop.confirmed && !stops[i + 1]?.confirmed
|
||||||
|
);
|
||||||
|
|
||||||
|
const activeMinorStopList: number[] = [];
|
||||||
|
if (lastMajorConfirmed + 1 >= this.train.timetableData.followingStops.length)
|
||||||
|
return activeMinorStopList;
|
||||||
|
|
||||||
|
for (
|
||||||
|
let i = lastMajorConfirmed + 1;
|
||||||
|
i < this.train.timetableData!.followingStops.length;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
|
if (/po\.|sbl/gi.test(this.train.timetableData!.followingStops[i].stopNameRAW))
|
||||||
|
activeMinorStopList.push(i);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return activeMinorStopList;
|
||||||
|
},
|
||||||
|
|
||||||
|
timetableSceneryNames() {
|
||||||
|
if (!this.train.timetableData?.sceneries) return [];
|
||||||
|
|
||||||
|
return this.train.timetableData?.sceneries
|
||||||
|
.map(
|
||||||
|
(sceneryHash) =>
|
||||||
|
this.store.onlineSceneryList.find((st) => st.hash === sceneryHash)?.name ??
|
||||||
|
this.apiStore.sceneryData.find((sd) => sd.hash === sceneryHash)?.name ??
|
||||||
|
sceneryHash
|
||||||
|
)
|
||||||
|
.reverse();
|
||||||
|
},
|
||||||
|
|
||||||
|
timetableOuterRoutes() {
|
||||||
|
// for (let i = 0; i < this.scheduleStops.length; i++) {}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
toggleShowState() {
|
toggleShowState() {
|
||||||
this.$emit('click');
|
this.$emit('click');
|
||||||
},
|
|
||||||
|
|
||||||
addClasses(stop: TrainStop, index: number) {
|
|
||||||
return {
|
|
||||||
confirmed: stop.confirmed,
|
|
||||||
stopped: stop.stopped,
|
|
||||||
begin: stop.beginsHere,
|
|
||||||
end: stop.terminatesHere,
|
|
||||||
delayed: stop.departureDelay > 0,
|
|
||||||
sbl: /sbl/gi.test(stop.stopName),
|
|
||||||
[stop.stopType.replaceAll(', ', '-')]:
|
|
||||||
stop.stopType.match(new RegExp('ph|pm|pt')) && !stop.confirmed && !stop.beginsHere,
|
|
||||||
'minor-stop-active': this.activeMinorStops.includes(index),
|
|
||||||
'last-confirmed': index == this.lastConfirmed && !stop.terminatesHere
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
onImageError(e: Event) {
|
|
||||||
const imageEl = e.target as HTMLImageElement;
|
|
||||||
imageEl.src = '/images/icon-unknown.png';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -155,17 +300,16 @@ export default defineComponent({
|
|||||||
@import '../../styles/responsive.scss';
|
@import '../../styles/responsive.scss';
|
||||||
|
|
||||||
$barClr: #b1b1b1;
|
$barClr: #b1b1b1;
|
||||||
$confirmedClr: #18d818;
|
$confirmedClr: #4ae24a;
|
||||||
$stoppedClr: #f55f31;
|
$stoppedClr: #f55f31;
|
||||||
$haltClr: #f8bb36;
|
$haltClr: #f8bb36;
|
||||||
$stopNameClr: #22a8d1;
|
|
||||||
|
|
||||||
@keyframes blink {
|
@keyframes blink {
|
||||||
from {
|
from {
|
||||||
background-color: $barClr;
|
border-color: $barClr;
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
background-color: $confirmedClr;
|
border-color: $confirmedClr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,216 +325,184 @@ $stopNameClr: #22a8d1;
|
|||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar {
|
.stops {
|
||||||
position: absolute;
|
|
||||||
z-index: 10;
|
|
||||||
|
|
||||||
top: -1px;
|
|
||||||
left: -17px;
|
|
||||||
|
|
||||||
height: 100%;
|
|
||||||
width: 3px;
|
|
||||||
|
|
||||||
background-color: $barClr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stop-name {
|
|
||||||
background: $stopNameClr;
|
|
||||||
padding: 0.3em 0.5em;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&.misc {
|
|
||||||
background: gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stop-comment {
|
|
||||||
background: forestgreen;
|
|
||||||
padding: 0.3em 0.5em;
|
|
||||||
|
|
||||||
max-width: 250px;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
width: 2em;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.stop_list {
|
|
||||||
margin-left: 2.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.stop_list > li.stop {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow-y: hidden;
|
||||||
|
gap: 0.25em;
|
||||||
|
|
||||||
padding: 0 0.5em;
|
padding: 0.25em 0;
|
||||||
|
}
|
||||||
|
|
||||||
&.sbl {
|
.stop {
|
||||||
.stop-date {
|
// Begin stop
|
||||||
display: none;
|
&[data-position='begin'] {
|
||||||
}
|
.node {
|
||||||
|
border-color: lightgreen;
|
||||||
.stop-name {
|
|
||||||
background: none;
|
|
||||||
color: #aaa;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&[class*='ph'] > .stop_info > .indicator {
|
// End stop
|
||||||
border-color: $stopNameClr;
|
&[data-position='end'] {
|
||||||
|
.node {
|
||||||
|
border-color: salmon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&[class*='pt'] > .stop_info > .indicator {
|
// Stop types
|
||||||
|
&[data-stop-type*='pt'] .node {
|
||||||
border-color: #818181;
|
border-color: #818181;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.begin {
|
&[data-stop-type*='ph'] .node {
|
||||||
.stop_info > .indicator {
|
border-color: $haltClr;
|
||||||
border-color: lightgreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stop_info > .progress-bar {
|
|
||||||
background: lightgreen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.end {
|
&[data-minor-stop-active='true'] {
|
||||||
.stop_info > .indicator {
|
.progress > .line {
|
||||||
border-color: salmon;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stop_info > .progress-bar {
|
|
||||||
background: salmon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.minor-stop-active {
|
|
||||||
.stop_info > .progress-bar {
|
|
||||||
animation: 0.5s ease-in-out alternate infinite blink;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stop_line > .progress-bar {
|
|
||||||
animation: 0.5s ease-in-out alternate infinite blink;
|
animation: 0.5s ease-in-out alternate infinite blink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.last-confirmed {
|
// Last confirmed outpost / checkpoint
|
||||||
.stop_line > .progress-bar {
|
&[data-last-confirmed='true'] {
|
||||||
|
.progress > .line_connection {
|
||||||
animation: 0.5s ease-in-out alternate infinite blink;
|
animation: 0.5s ease-in-out alternate infinite blink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.confirmed {
|
// Confirmed status
|
||||||
.stop_info {
|
&[data-status='confirmed'] {
|
||||||
> .progress-bar {
|
.progress > .node {
|
||||||
background-color: $confirmedClr;
|
border-color: $confirmedClr;
|
||||||
}
|
|
||||||
|
|
||||||
> .indicator {
|
|
||||||
border-color: $confirmedClr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.progress > .line {
|
||||||
.stop_line > .progress-bar {
|
border-left: 2px solid $confirmedClr;
|
||||||
background-color: $confirmedClr;
|
border-right: 2px solid $confirmedClr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.stopped {
|
// Stopped status
|
||||||
.stop_info {
|
&[data-status='stopped'] {
|
||||||
> .indicator {
|
.progress > .node {
|
||||||
border-color: $stoppedClr;
|
border-color: $stoppedClr;
|
||||||
}
|
|
||||||
|
|
||||||
> .stop-bar {
|
|
||||||
background: $stoppedClr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stop_line {
|
&[data-track-count='2'] {
|
||||||
font-size: 0.8em;
|
.progress > .line {
|
||||||
color: #ccc;
|
width: 6px;
|
||||||
|
|
||||||
padding: 0.35em 0;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.line-segment {
|
|
||||||
color: $barClr;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.stop_info {
|
.stop_info,
|
||||||
display: flex;
|
.stop_line {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 30px 40px auto 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
position: relative;
|
.line-speed {
|
||||||
text-align: center;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: gold;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
flex-wrap: wrap;
|
.stop_info {
|
||||||
}
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.stop-bar {
|
.stop_line {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #ccc;
|
||||||
|
margin-top: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #d6d6d6;
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
& > .node {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
|
||||||
left: -17px;
|
|
||||||
|
|
||||||
z-index: 10;
|
|
||||||
|
|
||||||
width: 3px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.distance {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translate(-100%, -50%);
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
margin-left: -1.75rem;
|
z-index: 15;
|
||||||
|
|
||||||
font-size: 0.75em;
|
|
||||||
color: #d6d6d6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.indicator {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 11;
|
|
||||||
|
|
||||||
top: 50%;
|
|
||||||
left: -1rem;
|
|
||||||
|
|
||||||
transform: translate(-47%, -50%);
|
|
||||||
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
||||||
width: 15px;
|
width: 15px;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
|
|
||||||
background: var(--clr-secondary);
|
background-color: var(--clr-secondary);
|
||||||
border: 3px solid $barClr;
|
border: 4px solid $barClr;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > .line {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
// background-color: $barClr;
|
||||||
|
border-left: 2px solid $barClr;
|
||||||
|
border-right: 2px solid $barClr;
|
||||||
|
|
||||||
|
&.line_connection {
|
||||||
|
top: -1em;
|
||||||
|
height: calc(100% + 2em);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.line_stop {
|
||||||
|
border-color: $stoppedClr;
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-comments {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25em;
|
||||||
|
|
||||||
|
margin: 0.25em 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 1.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-line-info {
|
||||||
|
.scenery-change-name {
|
||||||
|
position: relative;
|
||||||
|
margin: 0.25em 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
height: 2px;
|
||||||
|
width: 30px;
|
||||||
|
background-color: #aaa;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
right: calc(100% + 5px);
|
||||||
|
transform: translate(0, -50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { PropType, defineComponent } from 'vue';
|
||||||
|
import dateMixin from '../../mixins/dateMixin';
|
||||||
|
import { TrainScheduleStop } from './TrainSchedule.vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
mixins: [dateMixin],
|
||||||
|
|
||||||
|
props: {
|
||||||
|
stop: {
|
||||||
|
type: Object as PropType<TrainScheduleStop>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -44,6 +44,7 @@ export interface StationJSONData {
|
|||||||
lines: string;
|
lines: string;
|
||||||
project: string;
|
project: string;
|
||||||
projectUrl: string;
|
projectUrl: string;
|
||||||
|
hash: string;
|
||||||
|
|
||||||
reqLevel: number;
|
reqLevel: number;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user