diff --git a/resources/components/stop.html b/resources/components/stop.html
index e021e16..47ea0b0 100644
--- a/resources/components/stop.html
+++ b/resources/components/stop.html
@@ -20,7 +20,7 @@
-
+
diff --git a/resources/ts/app.ts b/resources/ts/app.ts
index f398b8f..0bdb0d6 100644
--- a/resources/ts/app.ts
+++ b/resources/ts/app.ts
@@ -11,7 +11,7 @@ window['Popper'] = Popper;
// dependencies
import Vue from "vue";
-import Vuex, { mapActions, mapState, Store } from 'vuex';
+import Vuex, { mapActions, mapMutations, mapState, Store } from 'vuex';
Vue.use(Vuex);
@@ -25,12 +25,13 @@ Vue.use(Vuex);
import('bootstrap'),
]);
- store.dispatch('messages/update');
-
// here goes "public" API
- window['czydojade'] = {
+ window['czydojade'] = Object.assign({}, window['czydojade'], {
components
- };
+ });
+
+ store.dispatch('messages/update');
+ store.dispatch('load', window['czydojade'].state);
let intervals = { messages: null, departures: null };
@@ -38,7 +39,6 @@ Vue.use(Vuex);
el: '#app',
store: store,
data: {
- stops: [],
sections: {
messages: true
},
@@ -70,6 +70,14 @@ Vue.use(Vuex);
return {
state: this.$store.state.departures.state
};
+ },
+ stops: {
+ get(this: Vue) {
+ return this.$store.state.stops;
+ },
+ set(this: Vue, value) {
+ this.$store.commit('updateStops', value);
+ }
}
},
watch: {
@@ -104,7 +112,13 @@ Vue.use(Vuex);
...mapActions({
updateMessages: 'messages/update',
updateDepartures: 'departures/update'
- })
+ }),
+ ...mapMutations({
+ updateStops: 'updateStops'
+ }),
+ save(this: Vue) {
+ this.$store.dispatch('save').then(x => console.log(x));
+ }
},
mounted() {
this.$el.classList.remove('not-ready');
diff --git a/resources/ts/components/utils.ts b/resources/ts/components/utils.ts
index c4b4923..3fed9f1 100644
--- a/resources/ts/components/utils.ts
+++ b/resources/ts/components/utils.ts
@@ -68,7 +68,7 @@ export class PopperComponent extends Vue {
window.dispatchEvent(new Event('resize'));
}
- destroyed() {
+ beforeDestroy() {
this._popper.destroy();
}
}
@@ -94,7 +94,7 @@ export class FoldComponent extends Vue {
});
}
- destroyed() {
+ beforeDestroy() {
this.observer.disconnect();
}
diff --git a/resources/ts/filters.ts b/resources/ts/filters.ts
index d828ae4..edf0d3f 100644
--- a/resources/ts/filters.ts
+++ b/resources/ts/filters.ts
@@ -4,55 +4,74 @@ import { condition } from "./decorators";
Vue.filter('signed', signed);
-Vue.directive('hover', (el, binding, node) => {
- const update = (hovered: boolean, e: Event) => {
- if (typeof binding.value === 'function') {
- binding.value(hovered, e);
- }
-
- if (typeof binding.value === 'boolean') {
- set(node.context, binding.expression, hovered);
- }
-
- if (typeof binding.arg !== 'undefined') {
- set(node.context, binding.arg, hovered);
- }
- };
-
- const activate = event => update(true, event);
- const deactivate = event => update(false, event);
-
- el.addEventListener('mouseenter', activate);
- el.addEventListener('click', activate);
- el.addEventListener('keydown', condition.decorate(deactivate, e => e.keyCode == 27));
- el.addEventListener('mouseleave', deactivate);
- el.addEventListener('focusout', deactivate);
-});
-
-Vue.directive('responsive', (el, binding) => {
- const breakpoints = typeof binding.value === 'object' ? binding.value : {
- 'xs': 0,
- 'sm': 576,
- 'md': 768,
- 'lg': 1024,
- 'xl': 1200,
- };
-
- const resize = () => {
- const width = el.scrollWidth;
- el.classList.remove(...Object.keys(breakpoints).map(breakpoint => `size-${breakpoint}`));
-
- for (let [ breakpoint, size ] of Object.entries(breakpoints)) {
- if (width < size) {
- break;
+Vue.directive('hover', {
+ bind(el, binding, node) {
+ const update = (hovered: boolean, e: Event) => {
+ if (typeof binding.value === 'function') {
+ binding.value(hovered, e);
}
- el.classList.add(`size-${breakpoint}`);
- }
- };
+ if (typeof binding.value === 'boolean') {
+ set(node.context, binding.expression, hovered);
+ }
- resize();
- if (!binding.modifiers['once']) {
- window.addEventListener('resize', resize);
+ if (typeof binding.arg !== 'undefined') {
+ set(node.context, binding.arg, hovered);
+ }
+ };
+
+ const activate = event => update(true, event);
+ const deactivate = event => update(false, event);
+ const keyboard = condition.decorate(deactivate, e => e.keyCode == 27);
+
+ binding['events'] = { activate, deactivate, keyboard };
+
+ el.addEventListener('mouseenter', activate);
+ el.addEventListener('click', activate);
+ el.addEventListener('keydown', keyboard);
+ el.addEventListener('mouseleave', deactivate);
+ el.addEventListener('focusout', deactivate);
+ },
+ unbind(el, binding) {
+ const { activate, deactivate, keyboard } = binding['events'];
+
+ el.removeEventListener('mouseenter', activate);
+ el.removeEventListener('click', activate);
+ el.removeEventListener('keydown', keyboard);
+ el.removeEventListener('mouseleave', deactivate);
+ el.removeEventListener('focusout', deactivate);
+ }
+});
+
+Vue.directive('responsive', {
+ inserted(el, binding) {
+ const breakpoints = typeof binding.value === 'object' ? binding.value : {
+ 'xs': 0,
+ 'sm': 576,
+ 'md': 768,
+ 'lg': 1024,
+ 'xl': 1200,
+ };
+
+ const resize = binding['resize'] = () => {
+ const width = el.scrollWidth;
+ el.classList.remove(...Object.keys(breakpoints).map(breakpoint => `size-${breakpoint}`));
+
+ for (let [ breakpoint, size ] of Object.entries(breakpoints)) {
+ if (width < size) {
+ break;
+ }
+
+ el.classList.add(`size-${breakpoint}`);
+ }
+ };
+ resize();
+
+ if (!binding.modifiers['once']) {
+ window.addEventListener('resize', resize);
+ }
+ },
+ unbind(el, binding) {
+ window.removeEventListener('resize', binding['resize']);
}
});
diff --git a/resources/ts/model/stop.ts b/resources/ts/model/stop.ts
index e50a744..415acd3 100644
--- a/resources/ts/model/stop.ts
+++ b/resources/ts/model/stop.ts
@@ -11,4 +11,4 @@ export type StopGroup = Stop[];
export type StopGroups = {
[name: string]: StopGroup;
-}
\ No newline at end of file
+}
diff --git a/resources/ts/store/index.ts b/resources/ts/store/index.ts
index 149e700..f629d16 100644
--- a/resources/ts/store/index.ts
+++ b/resources/ts/store/index.ts
@@ -2,7 +2,9 @@ import Vuex from 'vuex';
import messages from './messages';
import departures from './departures';
+import { state, mutations, actions } from "./root";
export default new Vuex.Store({
+ state, mutations, actions,
modules: { messages, departures }
})
\ No newline at end of file
diff --git a/resources/ts/store/root.ts b/resources/ts/store/root.ts
index 566fbcb..57b1120 100644
--- a/resources/ts/store/root.ts
+++ b/resources/ts/store/root.ts
@@ -1,9 +1,36 @@
-import { Module } from "vuex";
+import { Stop } from "../model";
+import { ActionTree, MutationTree } from "vuex";
+import urls from "../urls";
-const state = { };
+export interface RootState {
+ stops: Stop[],
+}
-export type RootState = typeof state;
+export interface SavedState {
+ version: 1,
+ stops: string[],
+}
-export default >{
- state
-}
\ No newline at end of file
+export const state: RootState = {
+ stops: []
+};
+
+export const mutations: MutationTree = {
+ updateStops: (state, stops) => state.stops = stops,
+};
+
+export const actions: ActionTree = {
+ async load({ commit }, { stops }: SavedState) {
+ if (stops.length > 0) {
+ const response = await fetch(urls.prepare(urls.stops.all, { id: stops }));
+
+ if (response.ok) {
+ commit('updateStops', await response.json());
+ }
+ }
+ },
+ save: async ({ state }): Promise => ({
+ version: 1,
+ stops: state.stops.map(stop => stop.id)
+ })
+};
\ No newline at end of file
diff --git a/src/Provider/Dummy/DummyDepartureRepository.php b/src/Provider/Dummy/DummyDepartureRepository.php
new file mode 100644
index 0000000..5210943
--- /dev/null
+++ b/src/Provider/Dummy/DummyDepartureRepository.php
@@ -0,0 +1,56 @@
+reference = $reference;
+ }
+
+ public function getForStop(Stop $stop): Collection
+ {
+ return collect([
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ],
+ ])->map(function ($departure) use ($stop) {
+ list($symbol, $type, $display, $vehicle) = $departure;
+ $scheduled = new Carbon();
+ $estimated = (clone $scheduled)->addSeconds(40);
+
+ return Departure::createFromArray([
+ 'scheduled' => $scheduled,
+ 'estimated' => $estimated,
+ 'stop' => $stop,
+ 'display' => $display,
+ 'vehicle' => $this->reference->get(Vehicle::class, $vehicle),
+ 'line' => Line::createFromArray(['symbol' => $symbol, 'type' => $type]),
+ ]);
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/Provider/Dummy/DummyProvider.php b/src/Provider/Dummy/DummyProvider.php
index 7e33693..eb88b36 100644
--- a/src/Provider/Dummy/DummyProvider.php
+++ b/src/Provider/Dummy/DummyProvider.php
@@ -12,9 +12,23 @@ use App\Provider\TrackRepository;
class DummyProvider implements Provider
{
+ private $departures;
+ private $stops;
+
+ /**
+ * DummyProvider constructor.
+ *
+ * @param $departures
+ */
+ public function __construct(DummyDepartureRepository $departures, DummyStopRepository $stops)
+ {
+ $this->departures = $departures;
+ $this->stops = $stops;
+ }
+
public function getDepartureRepository(): DepartureRepository
{
- throw new NotSupportedException();
+ return $this->departures;
}
public function getLineRepository(): LineRepository
@@ -24,7 +38,7 @@ class DummyProvider implements Provider
public function getStopRepository(): StopRepository
{
- throw new NotSupportedException();
+ return $this->stops;
}
public function getMessageRepository(): MessageRepository
diff --git a/src/Provider/Dummy/DummyStopRepository.php b/src/Provider/Dummy/DummyStopRepository.php
new file mode 100644
index 0000000..cdb8ecb
--- /dev/null
+++ b/src/Provider/Dummy/DummyStopRepository.php
@@ -0,0 +1,49 @@
+reference = $reference;
+ }
+
+ public function getAll(): Collection
+ {
+ return collect();
+ }
+
+ public function getAllGroups(): Collection
+ {
+ return collect();
+ }
+
+ public function getById($id): ?Stop
+ {
+ return Stop::createFromArray(['id' => $id, 'name' => 'lorem']);
+ }
+
+ public function getManyById($ids): Collection
+ {
+ return collect($ids)->map(f\ref([ $this, 'getById' ]));
+ }
+
+ public function findGroupsByName(string $name): Collection
+ {
+ return collect();
+ }
+}
\ No newline at end of file
diff --git a/templates/app.html.twig b/templates/app.html.twig
index a35c0d9..221839e 100644
--- a/templates/app.html.twig
+++ b/templates/app.html.twig
@@ -12,12 +12,12 @@
Komunikaty {{ '{{ messages.count }}' }}
-