diff --git a/resources/components/popper.html b/resources/components/popper.html
index 133678d..82cfe63 100644
--- a/resources/components/popper.html
+++ b/resources/components/popper.html
@@ -1,6 +1,6 @@
-
-
-
+
+
+
diff --git a/resources/components/stop.html b/resources/components/stop.html
index c102e4a..a45f8a4 100644
--- a/resources/components/stop.html
+++ b/resources/components/stop.html
@@ -20,7 +20,7 @@
-
+
diff --git a/resources/styles/_common.scss b/resources/styles/_common.scss
index 0bf12fd..0e8f0e2 100644
--- a/resources/styles/_common.scss
+++ b/resources/styles/_common.scss
@@ -44,6 +44,21 @@
.flex {
display: flex;
align-items: center;
+
+ > .text {
+ margin-left: .2rem;
+ margin-right: .2rem;
+ display: inline-block;
+ margin-bottom: 0;
+
+ &:last-child, & + .text {
+ margin-right: 0;
+ }
+
+ &:first-child {
+ margin-left: 0;
+ }
+ }
}
.section {
@@ -53,6 +68,15 @@
@extend .alert;
@extend .alert-dark;
+ > * {
+ font-size: medium;
+ }
+
+ @include direct-headings {
+ @extend .flex;
+ margin-bottom: 0;
+ }
+
font-size: medium;
background: transparent;
padding-top: .5rem;
diff --git a/resources/styles/_popper.scss b/resources/styles/_popper.scss
index 597c344..a243a9a 100644
--- a/resources/styles/_popper.scss
+++ b/resources/styles/_popper.scss
@@ -55,11 +55,11 @@
@mixin triangle-right($size, $color, $border: none) { @include triangle(right, $size, $color, $border); }
.popper {
- $arrow-base: 10px;
+ $arrow-base: 8px;
$arrow-color: white;
$arrow-border: black;
- $popper-padding: 2px;
+ $popper-padding: .5rem;
padding: $popper-padding;
background: white;
@@ -73,12 +73,22 @@
border-radius: 2px;
- .popper-arrow {
+ .popper__arrow {
position: absolute;
width: 0;
height: 0;
}
+ &.popper--no-padding {
+ padding: 0;
+ }
+
+ .popper__heading {
+ font-size: $font-size-sm;
+ font-weight: bold;
+ margin-bottom: .5rem;
+ }
+
@mixin placement($placement) {
$opposite: (
left: right,
@@ -90,14 +100,14 @@
&[x-placement*="#{$placement}"] {
margin-#{map-get($opposite, $placement)}: $arrow-base;
- .popper-arrow {
+ .popper__arrow {
#{map-get($opposite, $placement)}: 0;
@include triangle(map-get($opposite, $placement), $arrow-base, $arrow-color, $arrow-border);
}
}
}
- &.has-arrow {
+ &.popper--arrow {
@include placement("left");
@include placement("right");
@include placement("top");
diff --git a/resources/styles/main.scss b/resources/styles/main.scss
index 39f951e..464a07a 100644
--- a/resources/styles/main.scss
+++ b/resources/styles/main.scss
@@ -1,6 +1,7 @@
$border-radius: 0;
$border-radius-lg: $border-radius;
$border-radius-sm: $border-radius;
+
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@@ -24,6 +25,18 @@ $container-max-widths: map-merge($container-max-widths, ( xl: 1320px ));
@import "~bootstrap/scss/bootstrap";
+@mixin headings {
+ h1, h2, h3, h4, h5, h6 {
+ @content
+ }
+}
+
+@mixin direct-headings {
+ > h1, > h2, > h3, > h4, > h5, > h6 {
+ @content
+ }
+}
+
@import "common";
@import "stop";
@import "departure";
diff --git a/resources/ts/app.ts b/resources/ts/app.ts
index 3cc64e6..f11bb0c 100644
--- a/resources/ts/app.ts
+++ b/resources/ts/app.ts
@@ -32,6 +32,8 @@ Vue.use(Vuex);
components
};
+ let intervals = { messages: null, departures: null };
+
window['app'] = new Vue({
el: '#app',
store: store,
@@ -39,7 +41,22 @@ Vue.use(Vuex);
stops: [],
sections: {
messages: true
- }
+ },
+ settings: {
+ messages: false,
+ departures: false
+ },
+ autorefresh: {
+ messages: {
+ active: true,
+ interval: 60
+ },
+ departures: {
+ active: true,
+ interval: 10
+ }
+ },
+
},
computed: {
messages(this: any) {
@@ -58,7 +75,26 @@ Vue.use(Vuex);
watch: {
stops(this: any, stops) {
this.updateDepartures({ stops });
- }
+ },
+ autorefresh: { immediate: true, handler(this: any, settings) {
+ if (intervals.messages) {
+ clearInterval(intervals.messages);
+ intervals.messages = null;
+ }
+
+ if (intervals.departures) {
+ clearInterval(intervals.departures);
+ intervals.messages = null;
+ }
+
+ if (settings.messages.active) {
+ intervals.messages = setInterval(() => this.updateMessages(), Math.max(5, settings.messages.interval) * 1000);
+ }
+
+ if (settings.departures.active) {
+ intervals.departures = setInterval(() => this.updateDepartures({ stops: this.stops }), Math.max(5, settings.departures.interval) * 1000);
+ }
+ } }
},
methods: {
...mapActions({
diff --git a/resources/ts/components/utils.ts b/resources/ts/components/utils.ts
index f15599c..c47af1b 100644
--- a/resources/ts/components/utils.ts
+++ b/resources/ts/components/utils.ts
@@ -19,8 +19,14 @@ export class PopperComponent extends Vue {
@Prop(Boolean)
public lazy: boolean;
+ public hovered: boolean = false;
+
private _popper;
+ get show() {
+ return this.visible || this.hovered;
+ }
+
mounted() {
const reference = this.$parent.$refs[this.reference] as HTMLElement;
@@ -30,6 +36,12 @@ export class PopperComponent extends Vue {
arrow: { enabled: this.arrow, element: this.$refs['arrow'] as Element }
}
});
+
+ this.$nextTick(() => this._popper.update())
+ }
+
+ updated() {
+ this._popper.update();
}
@Watch('visible')
@@ -68,6 +80,7 @@ export class FoldComponent extends Vue {
this.observer.disconnect();
}
+
@Watch('visible')
private resize() {
const inner = this.$refs['inner'] as HTMLDivElement;
diff --git a/resources/ts/filters.ts b/resources/ts/filters.ts
index 1051cc5..384b026 100644
--- a/resources/ts/filters.ts
+++ b/resources/ts/filters.ts
@@ -1,4 +1,4 @@
-import { signed } from "./utils";
+import { set, signed } from "./utils";
import Vue from 'vue';
import { condition } from "./decorators";
@@ -11,11 +11,11 @@ Vue.directive('hover', (el, binding, node) => {
}
if (typeof binding.value === 'boolean') {
- node.context[binding.expression] = hovered;
+ set(node.context, binding.expression, hovered);
}
if (typeof binding.arg !== 'undefined') {
- node.context[binding.arg] = hovered;
+ set(node.context, binding.arg, hovered);
}
};
diff --git a/resources/ts/utils.ts b/resources/ts/utils.ts
index 8fa607c..010c6d7 100644
--- a/resources/ts/utils.ts
+++ b/resources/ts/utils.ts
@@ -40,4 +40,22 @@ export function signed(number: number): string {
export function ensureArray(x: T[]|T): T[] {
return x instanceof Array ? x : [ x ];
-}
\ No newline at end of file
+}
+
+export function set(object: any, path: string, value: any) {
+ const segments = path.split('.');
+ while (segments.length > 1) {
+ object = object[segments.shift()];
+ }
+
+ object[segments.shift()] = value;
+}
+
+export function get(object: any, path: string): any {
+ const segments = path.split('.');
+ while (segments.length > 1) {
+ object = object[segments.shift()];
+ }
+
+ return object[segments.shift()];
+}
diff --git a/templates/app.html.twig b/templates/app.html.twig
index 2f82145..5c0b417 100644
--- a/templates/app.html.twig
+++ b/templates/app.html.twig
@@ -6,29 +6,67 @@