mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 21:38:13 +00:00
Zmiana wyglądu widoków i rozłożenia elementów na stronie (1.6.0a)
This commit is contained in:
@@ -132,6 +132,62 @@
|
|||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&_badges {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 3px 10px;
|
||||||
|
margin: 0.5em 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (max-width: 850px) {
|
||||||
|
// display: flex;
|
||||||
|
// top: 100%;
|
||||||
|
// right: 1em;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
bottom: 0;
|
||||||
|
top: auto;
|
||||||
|
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
// margin: 0 0.25em;
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.paypal {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.discord {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
// COUNTER
|
// COUNTER
|
||||||
|
|||||||
+16
@@ -64,6 +64,20 @@
|
|||||||
/
|
/
|
||||||
<router-link class="route" active-class="route-active" to="/journal">{{ $t('app.journal') }} </router-link>
|
<router-link class="route" active-class="route-active" to="/journal">{{ $t('app.journal') }} </router-link>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span class="header_badges">
|
||||||
|
<a href="https://www.paypal.com/paypalme/spythere" target="_blank" class="badge paypal">
|
||||||
|
<img :src="icons.paypal" alt="icon paypal">
|
||||||
|
<span>PAYPAL</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://discord.gg/x2mpNN3svk" target="_blank" class="badge discord">
|
||||||
|
<img :src="icons.discord" alt="icon discord">
|
||||||
|
<span>STACJOWNIK</span>
|
||||||
|
</a>
|
||||||
|
<!-- <img src="https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white" alt="">
|
||||||
|
<img src="https://img.shields.io/badge/Discord-7289DA?style=for-the-badge&logo=discord&logoColor=white" alt=""> -->
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -151,6 +165,8 @@ export default defineComponent({
|
|||||||
en: require('@/assets/icon-en.jpg'),
|
en: require('@/assets/icon-en.jpg'),
|
||||||
pl: require('@/assets/icon-pl.svg'),
|
pl: require('@/assets/icon-pl.svg'),
|
||||||
error: require('@/assets/icon-error.svg'),
|
error: require('@/assets/icon-error.svg'),
|
||||||
|
paypal: require('@/assets/icon-paypal.svg'),
|
||||||
|
discord: require('@/assets/icon-discord.png'),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="scenery-history">
|
<div class="scenery-history">
|
||||||
<h2>{{ $t('journal.title') }}</h2>
|
<div class="history-title">
|
||||||
|
<img :src="icons.history" alt="icon history" />
|
||||||
|
<h2>{{ $t('journal.title') }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<transition name="history-list-anim" mode="out-in">
|
<transition name="history-list-anim" mode="out-in">
|
||||||
<ul :key="dispatcherTimeline.length">
|
<ul :key="dispatcherTimeline.length">
|
||||||
@@ -19,25 +22,24 @@
|
|||||||
@keydown.space="toggleTimeline(i)"
|
@keydown.space="toggleTimeline(i)"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
{{ timeline.date }} <img :src="timeline.showTimeline ? icons.ascArrow : icons.descArrow" alt="arrow" />
|
{{ timeline.date }}
|
||||||
|
<!-- <img :src="timeline.showTimeline ? icons.ascArrow : icons.descArrow" alt="arrow" /> -->
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<transition name="unfold-anim" @enter="enter" @afterEnter="afterEnter" @leave="leave">
|
<!-- <transition name="unfold-anim" @enter="enter" @afterEnter="afterEnter" @leave="leave"> -->
|
||||||
<div class="dispatcher-list" v-if="timeline.showTimeline">
|
<!-- <div class="dispatcher-list" v-if="timeline.showTimeline"> -->
|
||||||
<div class="dispatcher-item" v-for="dispatcher in timeline.dispatchers" :key="dispatcher.dispatcherFrom">
|
<div class="dispatcher-item" v-for="dispatcher in timeline.dispatchers" :key="dispatcher.dispatcherFrom">
|
||||||
<span>
|
<b>{{ dispatcher.dispatcherName }}</b>
|
||||||
<span class="dispatcher-from text--primary">
|
<span>
|
||||||
{{ timestampToString(dispatcher.dispatcherFrom, true) }}
|
<span class="dispatcher-from text--primary">
|
||||||
</span>
|
{{ timestampToString(dispatcher.dispatcherFrom, true) }}
|
||||||
>
|
</span>
|
||||||
<span class="dispatcher-to text--primary">
|
>
|
||||||
{{ timestampToString(dispatcher.dispatcherTo, true) }}</span
|
<span class="dispatcher-to text--primary"> {{ timestampToString(dispatcher.dispatcherTo, true) }}</span>
|
||||||
>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
<b>{{ dispatcher.dispatcherName }}</b>
|
<!-- </div> -->
|
||||||
</div>
|
<!-- </transition> -->
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</transition>
|
</transition>
|
||||||
@@ -87,8 +89,7 @@ export default defineComponent({
|
|||||||
isLoaded: false,
|
isLoaded: false,
|
||||||
|
|
||||||
icons: {
|
icons: {
|
||||||
ascArrow: require('@/assets/icon-arrow-asc.svg'),
|
history: require('@/assets/icon-history.svg'),
|
||||||
descArrow: require('@/assets/icon-arrow-desc.svg'),
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
props: {
|
props: {
|
||||||
@@ -118,7 +119,7 @@ export default defineComponent({
|
|||||||
showTimeline: false,
|
showTimeline: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
timelineDay.dispatchers.push(dispatcher);
|
timelineDay.dispatchers.unshift(dispatcher);
|
||||||
|
|
||||||
if (!acc.find((timeline) => timeline.date == dateStr)) acc.push(timelineDay);
|
if (!acc.find((timeline) => timeline.date == dateStr)) acc.push(timelineDay);
|
||||||
|
|
||||||
@@ -202,6 +203,20 @@ export default defineComponent({
|
|||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
font-size: 1.2em;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
width: 1.3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
height: 600px;
|
height: 600px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
@@ -218,12 +233,15 @@ li {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
background: #444;
|
background: #2a2a2a;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
margin: 0 auto 0.5em auto;
|
margin: 0 auto 0.5em auto;
|
||||||
|
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 1.3em;
|
width: 1.3em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
@@ -246,13 +264,12 @@ li {
|
|||||||
margin: 0.5em auto;
|
margin: 0.5em auto;
|
||||||
|
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
border-radius: 0.5em;
|
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
|
||||||
width: 90%;
|
width: 90%;
|
||||||
max-width: 400px;
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="scenery-info">
|
<div class="scenery-info">
|
||||||
<section v-if="!timetableOnly">
|
<section v-if="!timetableOnly">
|
||||||
<!-- info stats -->
|
<!-- info stats -->
|
||||||
<scenery-info-stats :station="station" />
|
<!-- <scenery-info-stats :station="station" /> -->
|
||||||
|
|
||||||
<!-- info icons -->
|
<!-- info icons -->
|
||||||
<scenery-info-icons :station="station" />
|
<scenery-info-icons :station="station" />
|
||||||
@@ -32,7 +32,7 @@ import SceneryInfoIcons from './SceneryInfo/SceneryInfoIcons.vue';
|
|||||||
import SceneryInfoStats from './SceneryInfo/SceneryInfoStats.vue';
|
import SceneryInfoStats from './SceneryInfo/SceneryInfoStats.vue';
|
||||||
import SceneryInfoUserList from './SceneryInfo/SceneryInfoUserList.vue';
|
import SceneryInfoUserList from './SceneryInfo/SceneryInfoUserList.vue';
|
||||||
import SceneryInfoSpawnList from './SceneryInfo/SceneryInfoSpawnList.vue';
|
import SceneryInfoSpawnList from './SceneryInfo/SceneryInfoSpawnList.vue';
|
||||||
import SceneryInfoRoutes from "./SceneryInfo/SceneryInfoRoutes.vue";
|
import SceneryInfoRoutes from './SceneryInfo/SceneryInfoRoutes.vue';
|
||||||
|
|
||||||
import Station from '@/scripts/interfaces/Station';
|
import Station from '@/scripts/interfaces/Station';
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ export default defineComponent({
|
|||||||
SceneryInfoStats,
|
SceneryInfoStats,
|
||||||
SceneryInfoUserList,
|
SceneryInfoUserList,
|
||||||
SceneryInfoSpawnList,
|
SceneryInfoSpawnList,
|
||||||
SceneryInfoRoutes
|
SceneryInfoRoutes,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
@@ -51,11 +51,11 @@ export default defineComponent({
|
|||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
timetableOnly: Boolean
|
timetableOnly: Boolean,
|
||||||
},
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
onlineFrom: -1
|
onlineFrom: -1,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -80,10 +80,9 @@ h3.section-header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.info-lists {
|
.info-lists {
|
||||||
display: flex;
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 550px));
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="info-dispatcher">
|
<section class="info-dispatcher">
|
||||||
<div class="dispatcher" v-if="station.onlineInfo">
|
<div class="dispatcher" v-if="station.onlineInfo">
|
||||||
<span
|
<span class="dispatcher_level" :style="calculateExpStyle(station.onlineInfo.dispatcherExp)">
|
||||||
class="dispatcher_level"
|
|
||||||
:style="calculateExpStyle(station.onlineInfo.dispatcherExp)"
|
|
||||||
>
|
|
||||||
{{ station.onlineInfo.dispatcherExp > 1 ? station.onlineInfo.dispatcherExp : 'L' }}
|
{{ station.onlineInfo.dispatcherExp > 1 ? station.onlineInfo.dispatcherExp : 'L' }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="dispatcher_name">{{ station.onlineInfo.dispatcherName }}</span>
|
<span class="dispatcher_name">{{ station.onlineInfo.dispatcherName }}</span>
|
||||||
|
|
||||||
|
<span class="dispatcher_likes text--primary">
|
||||||
|
<img :src="icons.like" alt="icon-like" />
|
||||||
|
<span>{{ station.onlineInfo?.dispatcherRate || '0' }}</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="status-badge" v-if="station.onlineInfo && onlineFrom > 0">
|
<span class="status-badge" v-if="station.onlineInfo && onlineFrom > 0">
|
||||||
OD {{ new Date(onlineFrom).toLocaleTimeString('pl-PL', { hour: "2-digit", minute: "2-digit" }) }}
|
OD {{ new Date(onlineFrom).toLocaleTimeString('pl-PL', { hour: '2-digit', minute: '2-digit' }) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="status-badge" v-if="station.onlineInfo" :class="station.onlineInfo.statusID">
|
<span class="status-badge" v-if="station.onlineInfo" :class="station.onlineInfo.statusID">
|
||||||
{{ $t(`status.${station.onlineInfo.statusID}`) }}
|
{{ $t(`status.${station.onlineInfo.statusID}`) }}
|
||||||
{{ station.onlineInfo.statusID == 'online' ? timestampToString(station.onlineInfo.statusTimestamp) : '' }}
|
{{ station.onlineInfo.statusID == 'online' ? timestampToString(station.onlineInfo.statusTimestamp) : '' }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="status-badge free" v-else>
|
<span class="status-badge free" v-else>
|
||||||
@@ -34,7 +36,7 @@ import Station from '@/scripts/interfaces/Station';
|
|||||||
import dateMixin from '@/mixins/dateMixin';
|
import dateMixin from '@/mixins/dateMixin';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
mixins: [styleMixin, dateMixin ],
|
mixins: [styleMixin, dateMixin],
|
||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as () => Station,
|
||||||
@@ -43,15 +45,15 @@ export default defineComponent({
|
|||||||
|
|
||||||
onlineFrom: {
|
onlineFrom: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: -1
|
default: -1,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
icons: {
|
icons: {
|
||||||
spawn: require('@/assets/icon-spawn.svg'),
|
spawn: require('@/assets/icon-spawn.svg'),
|
||||||
}
|
like: require('@/assets/icon-like.svg'),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -81,12 +83,21 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
&_name {
|
&_name {
|
||||||
margin-right: 1em;
|
margin-right: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&_likes {
|
||||||
|
img {
|
||||||
|
height: 0.7em;
|
||||||
|
margin-right: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
margin-right: 1.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-badge {
|
.status-badge {
|
||||||
font-size: 1.2em;
|
font-size: 1.25em;
|
||||||
margin: 0.5em 0.25em;
|
margin: 0.5em 0.25em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export default defineComponent({
|
|||||||
.info-icons {
|
.info-icons {
|
||||||
img {
|
img {
|
||||||
width: 3.5em;
|
width: 3.5em;
|
||||||
margin: 0 0.5em;
|
margin: 1em 0.5em;
|
||||||
|
|
||||||
border: 2px solid #4e4e4e;
|
border: 2px solid #4e4e4e;
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
<span class="track-specs">
|
<span class="track-specs">
|
||||||
{{ route.tracks }}tor
|
{{ route.tracks }}tor
|
||||||
<img v-if="route.catenary" :src="icons.trackCatenary" alt="icon track catenary" />
|
<img v-if="route.catenary" :src="icons.trackCatenary" alt="icon track catenary" />
|
||||||
<img v-else :src="icons.trackNoCatenary" alt="icon track no catenary" >
|
<img v-else :src="icons.trackNoCatenary" alt="icon track no catenary" />
|
||||||
|
|
||||||
<img v-if="route.TWB" :src="icons.trackTWB" alt="icon track twb" />
|
<img v-if="route.TWB" :src="icons.trackTWB" alt="icon track twb" />
|
||||||
<img v-if="route.SBL" :src="icons.trackSBL" alt="icon track sbl" />
|
<img v-if="route.SBL" :src="icons.trackSBL" alt="icon track sbl" />
|
||||||
@@ -46,12 +46,12 @@ export default defineComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
icons: {
|
icons: {
|
||||||
trackTWB: require("@/assets/icon-track-twb.svg"),
|
trackTWB: require('@/assets/icon-track-twb.svg'),
|
||||||
trackSBL: require("@/assets/icon-track-sbl.svg"),
|
trackSBL: require('@/assets/icon-track-sbl.svg'),
|
||||||
trackCatenary: require("@/assets/icon-track-catenary.svg"),
|
trackCatenary: require('@/assets/icon-track-catenary.svg'),
|
||||||
trackNoCatenary: require("@/assets/icon-track-nocatenary.svg"),
|
trackNoCatenary: require('@/assets/icon-track-nocatenary.svg'),
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -90,5 +90,4 @@ export default defineComponent({
|
|||||||
vertical-align: text-bottom;
|
vertical-align: text-bottom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="info-spawn-list">
|
<section class="info-spawn-list">
|
||||||
<h3 class="spawn-header section-header">
|
<h3 class="spawn-header section-header">
|
||||||
{{ $t('scenery.spawns') }}
|
|
||||||
<img :src="icons.spawn" alt="icon-spawn" />
|
<img :src="icons.spawn" alt="icon-spawn" />
|
||||||
|
{{ $t('scenery.spawns') }}
|
||||||
|
<span class="text--primary">{{ station.onlineInfo?.spawns.length || '0' }}</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<span v-if="station.onlineInfo">
|
<span v-if="station.onlineInfo">
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="info-user-list">
|
<section class="info-user-list">
|
||||||
<h3 class="user-header section-header">
|
<h3 class="user-header section-header">
|
||||||
{{ $t('scenery.users') }}
|
|
||||||
<img :src="icons.user" alt="icon-user" />
|
<img :src="icons.user" alt="icon-user" />
|
||||||
|
{{ $t('scenery.users') }}
|
||||||
|
<span class="text--primary">{{ station.onlineInfo?.currentUsers || '0' }}/{{ station.onlineInfo?.maxUsers || '0' }}</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -83,6 +84,8 @@ $terminated: red;
|
|||||||
$disconnected: slategray;
|
$disconnected: slategray;
|
||||||
|
|
||||||
.info-user-list {
|
.info-user-list {
|
||||||
|
padding: 0.5em;
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="scenery-timetable">
|
<div class="scenery-timetable">
|
||||||
<h3 class="timetable-header">
|
<h3 class="timetable-header">
|
||||||
|
<img :src="icons.timetable" alt="icon-timetable" />
|
||||||
<span>{{ $t('scenery.timetables') }}</span>
|
<span>{{ $t('scenery.timetables') }}</span>
|
||||||
|
|
||||||
|
<span class="timetable-count">
|
||||||
|
<span class="text--primary">{{ station.onlineInfo?.scheduledTrains?.length || '0' }}</span>
|
||||||
|
/
|
||||||
|
<span class="text--grayed">
|
||||||
|
{{ station.onlineInfo?.scheduledTrains?.filter((train) => train.stopInfo.confirmed).length || '0' }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
<a :href="currentURL + '&timetable_only=1'" v-if="!timetableOnly" target="_blank" class="timetable-only">
|
<a :href="currentURL + '&timetable_only=1'" v-if="!timetableOnly" target="_blank" class="timetable-only">
|
||||||
<img :src="viewIcon" alt="icon-view" :title="$t('timetables.timetable-only')" />
|
<img :src="viewIcon" alt="icon-view" :title="$t('timetables.timetable-only')" />
|
||||||
</a>
|
</a>
|
||||||
@@ -60,7 +69,11 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="general-status">
|
<span class="general-status">
|
||||||
<span :class="scheduledTrain.stopStatus">{{ $t(`timetables.${scheduledTrain.stopStatus}`) }} </span>
|
<span :class="scheduledTrain.stopStatus">
|
||||||
|
{{ $t(`timetables.${scheduledTrain.stopStatus}`) }}
|
||||||
|
<span v-if="scheduledTrain.stopStatus == 'arriving'">z: {{ scheduledTrain.prevStationName }}</span>
|
||||||
|
<span v-if="scheduledTrain.stopStatus.startsWith('departed')">do: {{ scheduledTrain.nextStationName }}</span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -90,7 +103,7 @@
|
|||||||
<span class="schedule-stop">
|
<span class="schedule-stop">
|
||||||
<span class="stop-time" v-if="scheduledTrain.stopInfo.stopTime">
|
<span class="stop-time" v-if="scheduledTrain.stopInfo.stopTime">
|
||||||
{{ scheduledTrain.stopInfo.stopTime }}
|
{{ scheduledTrain.stopInfo.stopTime }}
|
||||||
{{ scheduledTrain.stopInfo.stopType }}
|
{{ scheduledTrain.stopInfo.stopType || 'pt' }}
|
||||||
</span>
|
</span>
|
||||||
<span class="stop-arrow arrow"></span>
|
<span class="stop-arrow arrow"></span>
|
||||||
</span>
|
</span>
|
||||||
@@ -134,6 +147,7 @@ import { GETTERS } from '@/constants/storeConstants';
|
|||||||
import { DataStatus } from '@/scripts/enums/DataStatus';
|
import { DataStatus } from '@/scripts/enums/DataStatus';
|
||||||
import { ComputedRef } from 'vue';
|
import { ComputedRef } from 'vue';
|
||||||
import dateMixin from '@/mixins/dateMixin';
|
import dateMixin from '@/mixins/dateMixin';
|
||||||
|
import TrainStop from '@/scripts/interfaces/TrainStop';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { SelectBox },
|
components: { SelectBox },
|
||||||
@@ -143,6 +157,7 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
station: {
|
station: {
|
||||||
type: Object as () => Station,
|
type: Object as () => Station,
|
||||||
|
required: true,
|
||||||
},
|
},
|
||||||
timetableOnly: {
|
timetableOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -154,6 +169,7 @@ export default defineComponent({
|
|||||||
listOpen: false,
|
listOpen: false,
|
||||||
icons: {
|
icons: {
|
||||||
warning: require('@/assets/icon-warning.svg'),
|
warning: require('@/assets/icon-warning.svg'),
|
||||||
|
timetable: require('@/assets/icon-timetable.svg'),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -282,10 +298,10 @@ h3 {
|
|||||||
a {
|
a {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
&-count {
|
||||||
cursor: pointer;
|
margin-left: 0.5em;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
@@ -356,7 +372,7 @@ h3 {
|
|||||||
|
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
|
|
||||||
> .checkpoint_item {
|
.checkpoint_item {
|
||||||
&.current {
|
&.current {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $accentCol;
|
color: $accentCol;
|
||||||
@@ -417,7 +433,8 @@ h3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.general-status {
|
.general-status {
|
||||||
margin-left: 0.5em;
|
margin-left: 1em;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
span.arriving {
|
span.arriving {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
@@ -464,8 +481,8 @@ h3 {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.stop-time {
|
.stop-time {
|
||||||
font-size: 0.7em;
|
font-size: 0.85em;
|
||||||
margin: 5px 0;
|
margin: 0.5em 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
p<template>
|
||||||
<div class="train-schedule" @click="toggleShowState">
|
<div class="train-schedule" @click="toggleShowState">
|
||||||
<div class="schedule-wrapper">
|
<div class="schedule-wrapper">
|
||||||
<ul class="stop_list">
|
<ul class="stop_list">
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ export default interface ScheduledTrain {
|
|||||||
|
|
||||||
terminatesAt: string;
|
terminatesAt: string;
|
||||||
beginsAt: string;
|
beginsAt: string;
|
||||||
nearestStop: string;
|
|
||||||
|
prevStationName: string;
|
||||||
|
nextStationName: string;
|
||||||
|
|
||||||
stopLabel: string;
|
stopLabel: string;
|
||||||
stopStatus: string;
|
stopStatus: string;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import ScheduledTrain from "../interfaces/ScheduledTrain";
|
||||||
import Train from "../interfaces/Train";
|
import Train from "../interfaces/Train";
|
||||||
import TrainStop from "../interfaces/TrainStop";
|
import TrainStop from "../interfaces/TrainStop";
|
||||||
|
|
||||||
@@ -106,10 +107,29 @@ export const getTrainStopStatus = (stopInfo: TrainStop, currentStationName: stri
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export function getScheduledTrain(train: Train, trainStop: TrainStop, stationName: string) {
|
export function getScheduledTrain(train: Train, trainStopIndex: number, stationName: string): ScheduledTrain {
|
||||||
const timetable = train.timetableData!;
|
const timetable = train.timetableData!;
|
||||||
|
const followingStops = timetable.followingStops;
|
||||||
|
const trainStop = followingStops[trainStopIndex];
|
||||||
|
|
||||||
const trainStopStatus = getTrainStopStatus(trainStop, train.currentStationName, stationName);
|
const trainStopStatus = getTrainStopStatus(trainStop, train.currentStationName, stationName);
|
||||||
|
|
||||||
|
let prevStationName = "", nextStationName = "";
|
||||||
|
|
||||||
|
for (let i = trainStopIndex - 1; i >= 0; i--) {
|
||||||
|
if (followingStops[i].stopName.startsWith("<strong>")) {
|
||||||
|
prevStationName = followingStops[i].stopNameRAW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = trainStopIndex + 1; i < followingStops.length; i++) {
|
||||||
|
if (followingStops[i].stopName.startsWith("<strong>")) {
|
||||||
|
nextStationName = followingStops[i].stopNameRAW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
trainNo: train.trainNo,
|
trainNo: train.trainNo,
|
||||||
driverName: train.driverName,
|
driverName: train.driverName,
|
||||||
@@ -119,7 +139,10 @@ export function getScheduledTrain(train: Train, trainStop: TrainStop, stationNam
|
|||||||
category: timetable.category,
|
category: timetable.category,
|
||||||
beginsAt: timetable.followingStops[0].stopNameRAW,
|
beginsAt: timetable.followingStops[0].stopNameRAW,
|
||||||
terminatesAt: timetable.followingStops[timetable.followingStops.length - 1].stopNameRAW,
|
terminatesAt: timetable.followingStops[timetable.followingStops.length - 1].stopNameRAW,
|
||||||
nearestStop: "",
|
|
||||||
|
nextStationName,
|
||||||
|
prevStationName,
|
||||||
|
|
||||||
stopInfo: trainStop,
|
stopInfo: trainStop,
|
||||||
stopLabel: trainStopStatus.stopLabel,
|
stopLabel: trainStopStatus.stopLabel,
|
||||||
stopStatus: trainStopStatus.stopStatus,
|
stopStatus: trainStopStatus.stopStatus,
|
||||||
|
|||||||
+15
-72
@@ -5,13 +5,10 @@ import { createStore, useStore as baseUseStore, Store } from 'vuex'
|
|||||||
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import Station from "@/scripts/interfaces/Station";
|
|
||||||
import Train from "@/scripts/interfaces/Train";
|
import Train from "@/scripts/interfaces/Train";
|
||||||
|
|
||||||
import { StoreData } from "@/scripts/interfaces/StoreData";
|
import { StoreData } from "@/scripts/interfaces/StoreData";
|
||||||
|
|
||||||
import StationAPIData from '@/scripts/interfaces/api/StationAPIData';
|
|
||||||
import TrainAPIData from '@/scripts/interfaces/api/TrainAPIData';
|
|
||||||
|
|
||||||
import { ACTIONS, MUTATIONS } from "@/constants/storeConstants";
|
import { ACTIONS, MUTATIONS } from "@/constants/storeConstants";
|
||||||
import { DataStatus } from "@/scripts/enums/DataStatus";
|
import { DataStatus } from "@/scripts/enums/DataStatus";
|
||||||
@@ -20,68 +17,10 @@ import { getLocoURL, getScheduledTrain, getStatusID, getStatusTimestamp, parseSp
|
|||||||
import { URLs } from '@/scripts/utils/apiURLs';
|
import { URLs } from '@/scripts/utils/apiURLs';
|
||||||
import ScheduledTrain from '@/scripts/interfaces/ScheduledTrain';
|
import ScheduledTrain from '@/scripts/interfaces/ScheduledTrain';
|
||||||
import StationRoutes from '@/scripts/interfaces/StationRoutes';
|
import StationRoutes from '@/scripts/interfaces/StationRoutes';
|
||||||
import { connect, io, Socket } from 'socket.io-client';
|
import { io } from 'socket.io-client';
|
||||||
|
import { APIData, State, StationJSONData } from './types';
|
||||||
const connectToDevAPI = true;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface State {
|
|
||||||
stationList: Station[],
|
|
||||||
trainList: Train[],
|
|
||||||
|
|
||||||
lastDispatcherStatuses: { hash: string; statusTimestamp: number; statusID: string; }[],
|
|
||||||
|
|
||||||
sceneryData: any[][],
|
|
||||||
|
|
||||||
region: { id: string; value: string };
|
|
||||||
trainCount: number;
|
|
||||||
stationCount: number;
|
|
||||||
|
|
||||||
dataConnectionStatus: DataStatus;
|
|
||||||
webSocket?: Socket;
|
|
||||||
|
|
||||||
sceneryDataStatus: DataStatus;
|
|
||||||
timetableDataStatus: DataStatus;
|
|
||||||
dispatcherDataStatus: DataStatus;
|
|
||||||
trainsDataStatus: DataStatus;
|
|
||||||
|
|
||||||
listenerLaunched: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface APIData {
|
|
||||||
stations?: StationAPIData[],
|
|
||||||
dispatchers?: string[][],
|
|
||||||
trains?: TrainAPIData[],
|
|
||||||
|
|
||||||
stationsSWDRStatus: string;
|
|
||||||
trainsSWDRStatus: string;
|
|
||||||
dispatchersSWDRStatus: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StationJSONData {
|
|
||||||
name: string;
|
|
||||||
url: string;
|
|
||||||
lines: string;
|
|
||||||
project: string;
|
|
||||||
|
|
||||||
reqLevel: number;
|
|
||||||
|
|
||||||
// supportersOnly: boolean;
|
|
||||||
|
|
||||||
signalType: string;
|
|
||||||
controlType: string;
|
|
||||||
|
|
||||||
SUP: boolean;
|
|
||||||
|
|
||||||
routes: string;
|
|
||||||
checkpoints: string | null;
|
|
||||||
|
|
||||||
default: boolean;
|
|
||||||
nonPublic: boolean;
|
|
||||||
unavailable: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const connectToDevAPI = false;
|
||||||
|
|
||||||
export const key: InjectionKey<Store<State>> = Symbol()
|
export const key: InjectionKey<Store<State>> = Symbol()
|
||||||
|
|
||||||
@@ -269,18 +208,22 @@ export const store = createStore<State>({
|
|||||||
|
|
||||||
if (stopInfoIndex == -1) return acc;
|
if (stopInfoIndex == -1) return acc;
|
||||||
|
|
||||||
const trainStop = timetable.followingStops[stopInfoIndex];
|
const scheduledStopTrain = getScheduledTrain(train, stopInfoIndex, stationAPI.stationName);
|
||||||
const scheduledStopTrain = getScheduledTrain(train, trainStop, stationAPI.stationName);
|
|
||||||
|
|
||||||
if (station && station.generalInfo?.checkpoints && station.generalInfo.checkpoints.length > 0) {
|
if (station && station.generalInfo?.checkpoints && station.generalInfo.checkpoints.length > 0) {
|
||||||
for (const checkpoint of station.generalInfo.checkpoints) {
|
for (const checkpoint of station.generalInfo.checkpoints) {
|
||||||
timetable.followingStops
|
const index = timetable.followingStops.findIndex(stop => stop.stopNameRAW.toLowerCase() == checkpoint.checkpointName.toLowerCase());
|
||||||
.filter(trainStop => trainStop.stopNameRAW.toLowerCase() === checkpoint.checkpointName.toLowerCase())
|
|
||||||
.forEach(trainCheckpointStop => {
|
|
||||||
const scheduledCheckpointTrain = getScheduledTrain(train, trainCheckpointStop, stationAPI.stationName);
|
|
||||||
|
|
||||||
checkpoint.scheduledTrains.push(scheduledCheckpointTrain);
|
if (index == -1) continue;
|
||||||
});
|
|
||||||
|
const scheduledCheckpointTrain = getScheduledTrain(train, index, stationAPI.stationName);
|
||||||
|
checkpoint.scheduledTrains.push(scheduledCheckpointTrain);
|
||||||
|
|
||||||
|
// timetable.followingStops
|
||||||
|
// .filter(trainStop => trainStop.stopNameRAW.toLowerCase() === checkpoint.checkpointName.toLowerCase())
|
||||||
|
// .forEach((trainCheckpointStop, i) => {
|
||||||
|
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import { DataStatus } from "@/scripts/enums/DataStatus";
|
||||||
|
import StationAPIData from "@/scripts/interfaces/api/StationAPIData";
|
||||||
|
import TrainAPIData from "@/scripts/interfaces/api/TrainAPIData";
|
||||||
|
import Station from "@/scripts/interfaces/Station";
|
||||||
|
import Train from "@/scripts/interfaces/Train";
|
||||||
|
import { Socket } from "socket.io-client";
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
stationList: Station[],
|
||||||
|
trainList: Train[],
|
||||||
|
|
||||||
|
lastDispatcherStatuses: { hash: string; statusTimestamp: number; statusID: string; }[],
|
||||||
|
|
||||||
|
sceneryData: any[][],
|
||||||
|
|
||||||
|
region: { id: string; value: string };
|
||||||
|
trainCount: number;
|
||||||
|
stationCount: number;
|
||||||
|
|
||||||
|
dataConnectionStatus: DataStatus;
|
||||||
|
webSocket?: Socket;
|
||||||
|
|
||||||
|
sceneryDataStatus: DataStatus;
|
||||||
|
timetableDataStatus: DataStatus;
|
||||||
|
dispatcherDataStatus: DataStatus;
|
||||||
|
trainsDataStatus: DataStatus;
|
||||||
|
|
||||||
|
listenerLaunched: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface APIData {
|
||||||
|
stations?: StationAPIData[],
|
||||||
|
dispatchers?: string[][],
|
||||||
|
trains?: TrainAPIData[],
|
||||||
|
|
||||||
|
stationsSWDRStatus: string;
|
||||||
|
trainsSWDRStatus: string;
|
||||||
|
dispatchersSWDRStatus: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StationJSONData {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
lines: string;
|
||||||
|
project: string;
|
||||||
|
|
||||||
|
reqLevel: number;
|
||||||
|
|
||||||
|
// supportersOnly: boolean;
|
||||||
|
|
||||||
|
signalType: string;
|
||||||
|
controlType: string;
|
||||||
|
|
||||||
|
SUP: boolean;
|
||||||
|
|
||||||
|
routes: string;
|
||||||
|
checkpoints: string | null;
|
||||||
|
|
||||||
|
default: boolean;
|
||||||
|
nonPublic: boolean;
|
||||||
|
unavailable: boolean;
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
@mixin midScreen() {
|
@mixin midScreen() {
|
||||||
@media only screen and (max-width: 950px) {
|
@media only screen and (max-width: 1150px) {
|
||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ $sceneryBgCol: #333;
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
width: 75%;
|
width: 75%;
|
||||||
max-width: 950px;
|
max-width: 1200px;
|
||||||
|
|
||||||
@include midScreen {
|
@include midScreen {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
|
|||||||
@@ -11,16 +11,6 @@
|
|||||||
@resetFilters="resetFilters"
|
@resetFilters="resetFilters"
|
||||||
ref="filterCardRef"
|
ref="filterCardRef"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="paypal-link">
|
|
||||||
<a target="_blank" href="https://paypal.me/spythere">
|
|
||||||
<img
|
|
||||||
src="https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white"
|
|
||||||
alt="PayPal image"
|
|
||||||
style="width: 7em"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StationTable
|
<StationTable
|
||||||
@@ -199,21 +189,6 @@ export default defineComponent({
|
|||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.paypal-link {
|
|
||||||
flex-grow: 2;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
img {
|
|
||||||
vertical-align: middle;
|
|
||||||
border-radius: 0.5em;
|
|
||||||
transition: box-shadow 150ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover img,
|
|
||||||
a:focus img {
|
|
||||||
box-shadow: 0 0 10px 4px #04477e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include smallScreen {
|
@include smallScreen {
|
||||||
.options-bar {
|
.options-bar {
|
||||||
|
|||||||
Reference in New Issue
Block a user