Schedule indicatory

This commit is contained in:
2021-07-08 18:30:06 +02:00
parent 8abed60244
commit e97c3a9209
2 changed files with 391 additions and 332 deletions
+386 -329
View File
@@ -1,329 +1,386 @@
<template> <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">
<li <li
v-for="(stop, i) in followingStops" v-for="(stop, i) in followingStops"
:key="i" :key="i"
:class="addClasses(stop, i)" :class="addClasses(stop, i)"
> >
<span class="stop_info"> <span class="stop_info">
<div class="indicator"></div> <div class="indicator"></div>
<div class="progress-bar"></div> <div class="progress-bar"></div>
<div class="stop-bar"></div> <div class="stop-bar"></div>
<span class="distance" v-if="stop.stopDistance"> <span class="distance" v-if="stop.stopDistance">
{{ Math.floor(stop.stopDistance) }} {{ Math.floor(stop.stopDistance) }}
</span> </span>
<span class="stop-name" v-html="stop.stopName"></span> <span class="stop-name" v-html="stop.stopName"></span>
<span class="stop-date"> <span class="stop-date">
<span <span
class="date arrival" class="date arrival"
v-if="!stop.beginsHere" v-if="!stop.beginsHere"
:class="{ :class="{
delayed: stop.arrivalDelay > 0 && stop.confirmed, delayed: stop.arrivalDelay > 0 && stop.confirmed,
preponed: stop.arrivalDelay < 0 && stop.confirmed, preponed: stop.arrivalDelay < 0 && stop.confirmed,
}" }"
> >
p. p.
{{ {{
stylizeTime( stylizeTime(
stop.confirmed stop.confirmed
? stop.arrivalRealTimeString || "" ? stop.arrivalRealTimeString || ""
: stop.arrivalTimeString || "", : stop.arrivalTimeString || "",
stop.arrivalDelay, stop.arrivalDelay,
stop.confirmed stop.confirmed
) )
}} }}
</span> </span>
<span <span
class="date stop" class="date stop"
v-if="stop.stopTime" v-if="stop.stopTime"
:class="stop.stopType.replace(', ', '-')" :class="stop.stopType.replace(', ', '-')"
> >
{{ stop.stopTime }} {{ stop.stopType }} {{ stop.stopTime }} {{ stop.stopType }}
</span> </span>
<span <span
class="date departure" class="date departure"
v-if="!stop.terminatesHere && stop.stopTime != 0" v-if="!stop.terminatesHere && stop.stopTime != 0"
:class="{ :class="{
delayed: stop.departureDelay > 0 && stop.confirmed, delayed: stop.departureDelay > 0 && stop.confirmed,
preponed: stop.departureDelay < 0 && stop.confirmed, preponed: stop.departureDelay < 0 && stop.confirmed,
}" }"
> >
o. o.
{{ {{
stylizeTime( stylizeTime(
stop.confirmed stop.confirmed
? stop.departureRealTimeString || "" ? stop.departureRealTimeString || ""
: stop.departureTimeString || "", : stop.departureTimeString || "",
stop.departureDelay, stop.departureDelay,
stop.confirmed stop.confirmed
) )
}} }}
</span> </span>
</span> </span>
</span> </span>
<div class="stop_line"> <div class="stop_line">
<div class="progress-bar"></div> <div class="progress-bar"></div>
<span v-if="i < followingStops.length - 1"> <span v-if="i < followingStops.length - 1">
<span <span
v-if="stop.departureLine == followingStops[i + 1].arrivalLine" v-if="stop.departureLine == followingStops[i + 1].arrivalLine"
> >
{{ stop.departureLine }} {{ stop.departureLine }}
</span> </span>
<span v-else> <span v-else>
{{ stop.departureLine }} / {{ stop.departureLine }} /
{{ followingStops[i + 1].arrivalLine }} {{ followingStops[i + 1].arrivalLine }}
</span> </span>
</span> </span>
</div> </div>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import TrainStop from "@/scripts/interfaces/TrainStop"; import TrainStop from "@/scripts/interfaces/TrainStop";
import { defineComponent } from "@vue/runtime-core"; import { computed, defineComponent } from "@vue/runtime-core";
export default defineComponent({ export default defineComponent({
props: { props: {
followingStops: { followingStops: {
type: Array as () => TrainStop[], type: Array as () => TrainStop[],
required: true, required: true,
}, },
}, },
emits: ["click"], emits: ["click"],
methods: { setup(props) {
stylizeTime(timeString: string, delay: number, confirmed: boolean) { return {
return ( lastConfirmed: computed(() => {
timeString + return props.followingStops.findIndex(
(delay != 0 && confirmed (stop, i, stops) =>
? " (" + (delay > 0 ? "+" : "") + delay.toString() + ")" stop.confirmed && !stops[i + 1]?.confirmed && !stops[i + 1]?.stopped
: "") );
); }),
}, activeMinorStops: computed(() => {
const lastMajorConfirmed = props.followingStops.findIndex(
toggleShowState() { (stop, i, stops) => stop.confirmed && !stops[i + 1]?.confirmed
this.$emit("click"); );
},
const activeMinorStopList: number[] = [];
addClasses(stop: TrainStop, index: number) { if (lastMajorConfirmed + 1 >= props.followingStops.length)
return { return activeMinorStopList;
confirmed: stop.confirmed,
stopped: stop.stopped, for (
beginning: stop.beginsHere, let i = lastMajorConfirmed + 1;
delayed: stop.departureDelay > 0, i < props.followingStops.length;
"minor-stop": i++
this.followingStops[index - 1]?.confirmed && ) {
stop.stopNameRAW.includes("po"), if (props.followingStops[i].stopNameRAW.includes("po."))
"last-confirmed": activeMinorStopList.push(i);
stop.confirmed && !this.followingStops[index + 1]?.confirmed, else break;
}; }
},
}, return activeMinorStopList;
}); }),
</script> };
},
<style lang="scss" scoped>
@keyframes blink { methods: {
from { stylizeTime(timeString: string, delay: number, confirmed: boolean) {
background-color: white; return (
} timeString +
to { (delay != 0 && confirmed
background-color: lime; ? " (" + (delay > 0 ? "+" : "") + delay.toString() + ")"
} : "")
} );
},
.train-schedule {
max-height: 600px; toggleShowState() {
margin-top: 2em; this.$emit("click");
},
overflow-y: auto;
} addClasses(stop: TrainStop, index: number) {
return {
.schedule-wrapper { confirmed: stop.confirmed,
margin-left: 2.5rem; stopped: stop.stopped,
} beginning: stop.beginsHere,
delayed: stop.departureDelay > 0,
.progress-bar { [stop.stopType.replaceAll(", ", "-")]:
position: absolute; stop.stopType.match(new RegExp("ph|pm|pt")) && !stop.confirmed,
"minor-stop-active": this.activeMinorStops.includes(index),
top: 0; "last-confirmed": index == this.lastConfirmed,
left: -1rem; };
},
transform: translateX(-1px); },
});
height: 100%; </script>
width: 2px;
<style lang="scss" scoped>
background-color: white; $barClr: #d4d4d4;
} $confirmedClr: #18d818;
$stoppedClr: #ff4500;
ul.stop_list > li { $haltClr: #48c5eb;
position: relative;
$preponedClr: #008b00;
display: flex; $delayedClr: #e93f3f;
flex-direction: column; $dateClr: #525151;
$stopExchangeClr: #db8e29;
padding: 0 0.5em; $stopDefaultClr: #252525;
$stopNameClr: #22a8d1;
&.minor-stop {
.stop_info > .progress-bar { @keyframes blink {
animation: 0.5s ease-in-out alternate infinite blink; from {
} background-color: $barClr;
}
.stop_line > .progress-bar { to {
animation: 0.5s ease-in-out alternate infinite blink; background-color: $confirmedClr;
} }
} }
&.last-confirmed { .train-schedule {
& > .stop_line > .progress-bar { max-height: 600px;
animation: 0.5s ease-in-out alternate infinite blink; margin-top: 2em;
}
} overflow-y: auto;
}
&.confirmed {
& > .stop_line > .progress-bar { .schedule-wrapper {
background-color: lime; margin-left: 2.5rem;
} }
& > .stop_info > .progress-bar { .progress-bar {
background-color: lime; position: absolute;
} z-index: 10;
& > .stop_info > .indicator { top: -1px;
border-color: lime; /* left: -1rem; */
} left: -17px;
}
/* transform: translate(-1px, -1px); */
&.stopped { /* transform: translateX(-4spx, -1px); */
& > .stop_info {
& > .indicator { height: 100%;
border-color: orangered; width: 3px;
}
background-color: $barClr;
& > .stop-bar { }
background: orangered;
} ul.stop_list > li {
} position: relative;
}
display: flex;
.stop_line { flex-direction: column;
font-size: 0.8em;
color: #ccc; padding: 0 0.5em;
padding: 0.35em 0; &[class*="ph"] > .stop_info > .indicator {
border-color: $stopExchangeClr;
position: relative; }
.line-segment { &[class*="pt"] > .stop_info > .indicator {
color: white; border-color: #818181;
font-weight: 500; }
}
} &.minor-stop-active {
.stop_info > .progress-bar {
.stop_info { animation: 0.5s ease-in-out alternate infinite blink;
display: flex; }
position: relative; .stop_line > .progress-bar {
text-align: center; animation: 0.5s ease-in-out alternate infinite blink;
}
padding: 0.15em 0; }
}
&.last-confirmed {
.stop-bar { .stop_line > .progress-bar {
position: absolute; animation: 0.5s ease-in-out alternate infinite blink;
top: 0; }
left: -1rem; }
transform: translateX(-1px); &.confirmed {
.stop_info {
z-index: 2; > .progress-bar {
background-color: $confirmedClr;
width: 2px; }
height: 100%;
} > .indicator {
border-color: $confirmedClr;
.distance { }
position: absolute; }
top: 50%; .stop_line > .progress-bar {
transform: translate(-100%, -50%); background-color: $confirmedClr;
}
margin-left: -1.75rem; }
font-size: 0.85em; &.stopped {
color: #d6d6d6; .stop_info {
} > .indicator {
border-color: $stoppedClr;
.indicator { }
position: absolute;
z-index: 3; > .stop-bar {
background: $stoppedClr;
top: 50%; }
left: -1rem; }
}
transform: translate(-50%, -50%);
.stop_line {
text-align: right; font-size: 0.8em;
color: #ccc;
width: 15px;
height: 15px; padding: 0.35em 0;
background: var(--clr-secondary); position: relative;
border: 2px solid white;
border-radius: 100%; .line-segment {
} color: $barClr;
font-weight: 500;
.stop-name { }
background: var(--clr-accent); }
padding: 0.3em 0.5em;
.stop_info {
display: flex; display: flex;
align-items: center;
} position: relative;
text-align: center;
.stop-date {
display: flex; padding: 0.15em 0;
align-items: center; }
.date { .stop-bar {
background: #494949; position: absolute;
padding: 0.3em 0.5em; top: 0;
} left: -1rem;
.stop { transform: translate(-1px, -1px);
&.ph,
&.ph-pm { z-index: 10;
background: #db8e29;
} width: 3px;
height: 100%;
background: #252525; }
}
.distance {
.arrival, position: absolute;
.departure {
&.delayed { top: 50%;
background: #f80334; transform: translate(-100%, -50%);
}
margin-left: -1.75rem;
&.preponed {
background: rgb(0, 139, 0); font-size: 0.85em;
} color: #d6d6d6;
} }
}
} .indicator {
</style> position: absolute;
z-index: 11;
top: 50%;
left: -1rem;
transform: translate(-47%, -50%);
text-align: right;
width: 15px;
height: 15px;
background: var(--clr-secondary);
border: 3px solid $barClr;
border-radius: 100%;
}
.stop-name {
background: $stopNameClr;
padding: 0.3em 0.5em;
display: flex;
align-items: center;
}
.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 {
background: $delayedClr;
}
&.preponed {
background: $preponedClr;
}
}
}
}
</style>
+5 -3
View File
@@ -163,8 +163,10 @@
<div <div
class="train_extended-info" class="train_extended-info"
v-if="train.timetableData" v-if="
v-show="showedSchedule == train.timetableData.timetableId" train.timetableData &&
showedSchedule == train.timetableData.timetableId
"
> >
<TrainSchedule <TrainSchedule
:followingStops="train.timetableData.followingStops" :followingStops="train.timetableData.followingStops"
@@ -439,7 +441,7 @@ img.train-image {
display: flex; display: flex;
align-items: center; align-items: center;
background-color: var(--clr-accent); background-color: #22a8d1;
border-radius: 0.5em; border-radius: 0.5em;
padding: 0.1em 0.35em; padding: 0.1em 0.35em;
} }