Move messaging settings to vuex store
This commit is contained in:
parent
10756226f1
commit
cde6507197
@ -1,15 +1,29 @@
|
|||||||
<ul class="messages list-unstyled">
|
<div class="messages mb-2">
|
||||||
<li class="message alert" :class="`alert-${type(message)}`" v-for="message in messages">
|
<ul class="list-unstyled mb-0">
|
||||||
<ui-icon :icon="`message-${type(message)}`" fixed-width />
|
<li class="message alert" :class="`alert-${type(message)}`" v-for="message in messages">
|
||||||
{{ message.message }}
|
<ui-icon :icon="`message-${message.type}`" fixed-width/>
|
||||||
|
{{ message.message }}
|
||||||
|
|
||||||
<div class="message__info">
|
<div class="message__info">
|
||||||
<small class="message__date">
|
<small class="message__date">
|
||||||
Komunikat ważny od
|
Komunikat ważny od
|
||||||
{{ message.validFrom.format('HH:mm') }}
|
{{ message.validFrom.format('HH:mm') }}
|
||||||
do
|
do
|
||||||
{{ message.validTo.format('HH:mm') }}
|
{{ message.validTo.format('HH:mm') }}
|
||||||
</small>
|
</small>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<template v-if="nonDisplayedCount > 0">
|
||||||
|
<div class="flex">
|
||||||
|
<button class="btn btn-action btn-sm flex-space-left" @click="showAll = !showAll">
|
||||||
|
<template v-if="showAll">
|
||||||
|
<ui-icon icon="chevron-up"/> {{ nonDisplayedCount }} mniej
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<ui-icon icon="chevron-down"/> {{ nonDisplayedCount }} więcej
|
||||||
|
</template>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</template>
|
||||||
</ul>
|
</div>
|
||||||
|
31
resources/components/settings/messages.html
Normal file
31
resources/components/settings/messages.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<fragment>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="flex">
|
||||||
|
<label class="text" for="departures-auto-refresh-interval">
|
||||||
|
<ui-icon icon="refresh" fixed-width/>
|
||||||
|
autoodświeżanie
|
||||||
|
</label>
|
||||||
|
<ui-switch id="departures-auto-refresh" :value="autorefresh" @input="update({ autorefresh: $event })" class="flex-space-left"/>
|
||||||
|
</div>
|
||||||
|
<div class="flex " v-if="autorefresh">
|
||||||
|
<label for="departures-auto-refresh-interval" class="text">
|
||||||
|
<span class="sr-only">częstotliwość odświeżania</span>
|
||||||
|
co
|
||||||
|
</label>
|
||||||
|
<div class="input-group input-group-sm">
|
||||||
|
<input type="text" class="form-control form-control-sm form-control-simple" id="departures-auto-refresh-interval"
|
||||||
|
:value="autorefreshInterval" @input="update({ autorefreshInterval: Number.parseInt($event.target.value) })" />
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="input-group-text" aria-label="sekund">s</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="text" for="departures-count">
|
||||||
|
<ui-icon icon="messages" fixed-width/>
|
||||||
|
wyświetlanych komunikatów
|
||||||
|
</label>
|
||||||
|
<ui-numeric-input id="departures-count" :value="displayedEntriesCount" @input="update({ displayedEntriesCount: $event })" :min="1" />
|
||||||
|
</div>
|
||||||
|
</fragment>
|
@ -4,6 +4,7 @@ import { Component, Watch } from "vue-property-decorator";
|
|||||||
import { Mutation, Action } from 'vuex-class'
|
import { Mutation, Action } from 'vuex-class'
|
||||||
import { Stop } from "../model";
|
import { Stop } from "../model";
|
||||||
import { DeparturesSettingsState } from "../store/settings/departures";
|
import { DeparturesSettingsState } from "../store/settings/departures";
|
||||||
|
import { MessagesSettingsState } from "../store/settings/messages";
|
||||||
|
|
||||||
@Component({ store })
|
@Component({ store })
|
||||||
export class Application extends Vue {
|
export class Application extends Vue {
|
||||||
@ -18,13 +19,6 @@ export class Application extends Vue {
|
|||||||
picker: 'search'
|
picker: 'search'
|
||||||
};
|
};
|
||||||
|
|
||||||
private autorefresh = {
|
|
||||||
messages: {
|
|
||||||
active: true,
|
|
||||||
interval: 60
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private intervals = { messages: null, departures: null };
|
private intervals = { messages: null, departures: null };
|
||||||
|
|
||||||
get messages() {
|
get messages() {
|
||||||
@ -55,6 +49,7 @@ export class Application extends Vue {
|
|||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.initDeparturesRefreshInterval();
|
this.initDeparturesRefreshInterval();
|
||||||
|
this.initMessagesRefreshInterval();
|
||||||
}
|
}
|
||||||
|
|
||||||
private initDeparturesRefreshInterval() {
|
private initDeparturesRefreshInterval() {
|
||||||
@ -76,6 +71,25 @@ export class Application extends Vue {
|
|||||||
departuresAutorefreshCallback();
|
departuresAutorefreshCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private initMessagesRefreshInterval() {
|
||||||
|
const messagesAutorefreshCallback = () => {
|
||||||
|
const {autorefresh, autorefreshInterval} = this.$store.state['messages-settings'] as MessagesSettingsState;
|
||||||
|
|
||||||
|
if (this.intervals.messages) {
|
||||||
|
clearInterval(this.intervals.messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (autorefresh) {
|
||||||
|
this.intervals.messages = setInterval(() => this.updateMessages(), Math.max(5, autorefreshInterval) * 1000)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$store.watch(({"messages-settings": state}) => state.autorefresh, messagesAutorefreshCallback);
|
||||||
|
this.$store.watch(({"messages-settings": state}) => state.autorefreshInterval, messagesAutorefreshCallback);
|
||||||
|
|
||||||
|
messagesAutorefreshCallback();
|
||||||
|
}
|
||||||
|
|
||||||
@Action('messages/update') updateMessages: () => void;
|
@Action('messages/update') updateMessages: () => void;
|
||||||
@Action('departures/update') updateDepartures: () => void;
|
@Action('departures/update') updateDepartures: () => void;
|
||||||
|
|
||||||
@ -87,16 +101,4 @@ export class Application extends Vue {
|
|||||||
onStopUpdate() {
|
onStopUpdate() {
|
||||||
this.updateDepartures();
|
this.updateDepartures();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch('autorefresh', { immediate: true, deep: true })
|
|
||||||
onAutorefreshUpdate(settings) {
|
|
||||||
if (this.intervals.messages) {
|
|
||||||
clearInterval(this.intervals.messages);
|
|
||||||
this.intervals.messages = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.messages.active) {
|
|
||||||
this.intervals.messages = setInterval(() => this.updateMessages(), Math.max(5, settings.messages.interval) * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,3 +12,4 @@ export * from './trip'
|
|||||||
export * from './ui'
|
export * from './ui'
|
||||||
export * from './settings'
|
export * from './settings'
|
||||||
export { Departures } from "../store";
|
export { Departures } from "../store";
|
||||||
|
export { Messages } from "../store";
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { Component } from "vue-property-decorator";
|
import { Component } from "vue-property-decorator";
|
||||||
import { Message } from "../model/message";
|
import { Message } from "../model/message";
|
||||||
import { namespace } from 'vuex-class';
|
import store, { Messages, MessagesSettings } from '../store'
|
||||||
import store from '../store'
|
|
||||||
|
|
||||||
const { State } = namespace('messages');
|
|
||||||
|
|
||||||
@Component({ template: require("../../components/messages.html"), store })
|
@Component({ template: require("../../components/messages.html"), store })
|
||||||
export class MessagesComponent extends Vue {
|
export class MessagesComponent extends Vue {
|
||||||
@State messages: Message[];
|
@Messages.State('messages')
|
||||||
|
public allMessages: Message[];
|
||||||
|
|
||||||
public icon(message: Message) {
|
@MessagesSettings.State
|
||||||
switch (message.type) {
|
public displayedEntriesCount: number;
|
||||||
}
|
|
||||||
|
public showAll: boolean = false;
|
||||||
|
|
||||||
|
get messages() {
|
||||||
|
return this.showAll
|
||||||
|
? this.allMessages
|
||||||
|
: this.allMessages.slice(0, this.displayedEntriesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
get nonDisplayedCount(): number {
|
||||||
|
return Math.max(this.allMessages.length - this.displayedEntriesCount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public type(message: Message) {
|
public type(message: Message) {
|
||||||
|
@ -1 +1,2 @@
|
|||||||
export * from "./departures"
|
export * from "./departures"
|
||||||
|
export * from "./messages"
|
||||||
|
21
resources/ts/components/settings/messages.ts
Normal file
21
resources/ts/components/settings/messages.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Component } from "vue-property-decorator";
|
||||||
|
import store, { MessagesSettings } from "../../store";
|
||||||
|
import Vue from "vue";
|
||||||
|
import { MessagesSettingsState } from "../../store/settings/messages";
|
||||||
|
|
||||||
|
@Component({template: require("../../../components/settings/messages.html"), store})
|
||||||
|
export class SettingsMessages extends Vue {
|
||||||
|
@MessagesSettings.State
|
||||||
|
public autorefresh: boolean;
|
||||||
|
|
||||||
|
@MessagesSettings.State
|
||||||
|
public autorefreshInterval: number;
|
||||||
|
|
||||||
|
@MessagesSettings.State
|
||||||
|
public displayedEntriesCount: number;
|
||||||
|
|
||||||
|
@MessagesSettings.Mutation
|
||||||
|
public update: (state: Partial<MessagesSettingsState>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.component('SettingsMessages', SettingsMessages);
|
@ -1,11 +1,10 @@
|
|||||||
import { RootState, SavedState } from "./root";
|
import { RootState } from "./root";
|
||||||
import { Module, Plugin, Store } from "vuex";
|
import { Module } from "vuex";
|
||||||
import * as utils from "../utils";
|
|
||||||
import { Stop } from "../model";
|
import { Stop } from "../model";
|
||||||
|
|
||||||
export interface Favourite {
|
export interface Favourite {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
stops: Stop[];
|
stops: Stop[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,12 +27,4 @@ const favourites: Module<FavouritesState, RootState> = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const localStorageSaver = (path: string, key: string): Plugin<any> => (store: Store<any>) => {
|
|
||||||
utils.set(store.state, path, JSON.parse(window.localStorage.getItem(key) || '[]'));
|
|
||||||
|
|
||||||
store.subscribe((mutation, state) => {
|
|
||||||
window.localStorage.setItem(key, JSON.stringify(utils.get(state, path)));
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
export default favourites;
|
export default favourites;
|
||||||
|
@ -2,21 +2,24 @@ import Vuex from 'vuex';
|
|||||||
|
|
||||||
import messages, { MessagesState } from './messages';
|
import messages, { MessagesState } from './messages';
|
||||||
import departures, { DeparturesState } from './departures'
|
import departures, { DeparturesState } from './departures'
|
||||||
import favourites, { FavouritesState, localStorageSaver } from './favourites'
|
import favourites, { FavouritesState } from './favourites'
|
||||||
|
import departureSettings, { DeparturesSettingsState } from "./settings/departures";
|
||||||
|
import messagesSettings, { MessagesSettingsState } from "./settings/messages";
|
||||||
|
|
||||||
import { actions, mutations, RootState, state } from "./root";
|
import { actions, mutations, RootState, state } from "./root";
|
||||||
import VuexPersistence from "vuex-persist";
|
import VuexPersistence from "vuex-persist";
|
||||||
import { namespace } from "vuex-class";
|
import { namespace } from "vuex-class";
|
||||||
import departureSettings from "./settings/departures";
|
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
messages: MessagesState;
|
messages: MessagesState;
|
||||||
departures: DeparturesState;
|
departures: DeparturesState;
|
||||||
favourites: FavouritesState;
|
favourites: FavouritesState;
|
||||||
|
"departures-settings": DeparturesSettingsState,
|
||||||
|
"messages-settings": MessagesSettingsState,
|
||||||
} & RootState;
|
} & RootState;
|
||||||
|
|
||||||
const localStoragePersist = new VuexPersistence<State>({
|
const localStoragePersist = new VuexPersistence<State>({
|
||||||
modules: ['favourites', 'departures-settings'],
|
modules: ['favourites', 'departures-settings', 'messages-settings'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const sessionStoragePersist = new VuexPersistence<State>({
|
const sessionStoragePersist = new VuexPersistence<State>({
|
||||||
@ -24,17 +27,16 @@ const sessionStoragePersist = new VuexPersistence<State>({
|
|||||||
storage: window.sessionStorage
|
storage: window.sessionStorage
|
||||||
});
|
});
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store<RootState>({
|
||||||
state, mutations, actions,
|
state, mutations, actions,
|
||||||
modules: {
|
modules: {
|
||||||
messages,
|
messages,
|
||||||
departures,
|
departures,
|
||||||
favourites,
|
favourites,
|
||||||
'departures-settings': departureSettings
|
'departures-settings': departureSettings,
|
||||||
|
'messages-settings': messagesSettings,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
// todo: remove after some time
|
|
||||||
localStorageSaver('favourites.favourites', 'favourites'),
|
|
||||||
localStoragePersist.plugin,
|
localStoragePersist.plugin,
|
||||||
sessionStoragePersist.plugin,
|
sessionStoragePersist.plugin,
|
||||||
]
|
]
|
||||||
@ -44,4 +46,6 @@ export default store;
|
|||||||
|
|
||||||
export const Favourites = namespace('favourites');
|
export const Favourites = namespace('favourites');
|
||||||
export const DeparturesSettings = namespace('departures-settings');
|
export const DeparturesSettings = namespace('departures-settings');
|
||||||
|
export const MessagesSettings = namespace('messages-settings');
|
||||||
export const Departures = namespace('departures');
|
export const Departures = namespace('departures');
|
||||||
|
export const Messages = namespace('messages');
|
||||||
|
24
resources/ts/store/settings/messages.ts
Normal file
24
resources/ts/store/settings/messages.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { Module } from "vuex";
|
||||||
|
import { RootState } from "../root";
|
||||||
|
|
||||||
|
export type MessagesSettingsState = {
|
||||||
|
autorefresh: boolean;
|
||||||
|
autorefreshInterval?: number;
|
||||||
|
displayedEntriesCount?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messagesSettings: Module<MessagesSettingsState, RootState> = {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
autorefresh: true,
|
||||||
|
autorefreshInterval: 60,
|
||||||
|
displayedEntriesCount: 2
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
update(state: MessagesSettingsState, patch: Partial<MessagesSettingsState>) {
|
||||||
|
Object.assign(state, patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default messagesSettings;
|
@ -29,25 +29,7 @@
|
|||||||
|
|
||||||
<portal to="popups">
|
<portal to="popups">
|
||||||
<popper reference="settings-messages" v-if="visibility.messages" arrow placement="left-start" @leave="visibility.messages = false">
|
<popper reference="settings-messages" v-if="visibility.messages" arrow placement="left-start" @leave="visibility.messages = false">
|
||||||
<h3 class="popper__heading flex">
|
<settings-messages></settings-messages>
|
||||||
<label class="text" for="messages-auto-refresh">
|
|
||||||
<ui-icon icon="refresh" fixed-width></ui-icon>
|
|
||||||
autoodświeżanie
|
|
||||||
</label>
|
|
||||||
<ui-switch id="messages-auto-refresh" v-model="autorefresh.messages.active" class="flex-space-left"></ui-switch>
|
|
||||||
</h3>
|
|
||||||
<div class="flex" v-if="autorefresh.messages.active">
|
|
||||||
<label for="messages-auto-refresh-interval" class="text">
|
|
||||||
<span class="sr-only">częstotliwość odświeżania</span>
|
|
||||||
co
|
|
||||||
</label>
|
|
||||||
<div class="input-group input-group-sm">
|
|
||||||
<input type="text" class="form-control form-control-sm form-control-simple" id="messages-auto-refresh-interval" v-model="autorefresh.messages.interval"/>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<span class="input-group-text" aria-label="sekund">s</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</popper>
|
</popper>
|
||||||
</portal>
|
</portal>
|
||||||
</header>
|
</header>
|
||||||
|
Loading…
Reference in New Issue
Block a user