Move messaging settings to vuex store

This commit is contained in:
Kacper Donat 2020-03-19 20:22:50 +01:00
parent 10756226f1
commit cde6507197
11 changed files with 157 additions and 78 deletions

View File

@ -1,15 +1,29 @@
<ul class="messages list-unstyled">
<li class="message alert" :class="`alert-${type(message)}`" v-for="message in messages">
<ui-icon :icon="`message-${type(message)}`" fixed-width />
{{ message.message }}
<div class="messages mb-2">
<ul class="list-unstyled mb-0">
<li class="message alert" :class="`alert-${type(message)}`" v-for="message in messages">
<ui-icon :icon="`message-${message.type}`" fixed-width/>
{{ message.message }}
<div class="message__info">
<small class="message__date">
Komunikat ważny od
{{ message.validFrom.format('HH:mm') }}
do
{{ message.validTo.format('HH:mm') }}
</small>
<div class="message__info">
<small class="message__date">
Komunikat ważny od
{{ message.validFrom.format('HH:mm') }}
do
{{ message.validTo.format('HH:mm') }}
</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>
</li>
</ul>
</template>
</div>

View 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>

View File

@ -4,6 +4,7 @@ import { Component, Watch } from "vue-property-decorator";
import { Mutation, Action } from 'vuex-class'
import { Stop } from "../model";
import { DeparturesSettingsState } from "../store/settings/departures";
import { MessagesSettingsState } from "../store/settings/messages";
@Component({ store })
export class Application extends Vue {
@ -18,13 +19,6 @@ export class Application extends Vue {
picker: 'search'
};
private autorefresh = {
messages: {
active: true,
interval: 60
}
};
private intervals = { messages: null, departures: null };
get messages() {
@ -55,6 +49,7 @@ export class Application extends Vue {
created() {
this.initDeparturesRefreshInterval();
this.initMessagesRefreshInterval();
}
private initDeparturesRefreshInterval() {
@ -76,6 +71,25 @@ export class Application extends Vue {
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('departures/update') updateDepartures: () => void;
@ -87,16 +101,4 @@ export class Application extends Vue {
onStopUpdate() {
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);
}
}
}

View File

@ -12,3 +12,4 @@ export * from './trip'
export * from './ui'
export * from './settings'
export { Departures } from "../store";
export { Messages } from "../store";

View File

@ -1,18 +1,26 @@
import Vue from 'vue';
import { Component } from "vue-property-decorator";
import { Message } from "../model/message";
import { namespace } from 'vuex-class';
import store from '../store'
const { State } = namespace('messages');
import store, { Messages, MessagesSettings } from '../store'
@Component({ template: require("../../components/messages.html"), store })
export class MessagesComponent extends Vue {
@State messages: Message[];
@Messages.State('messages')
public allMessages: Message[];
public icon(message: Message) {
switch (message.type) {
}
@MessagesSettings.State
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) {

View File

@ -1 +1,2 @@
export * from "./departures"
export * from "./messages"

View 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);

View File

@ -1,11 +1,10 @@
import { RootState, SavedState } from "./root";
import { Module, Plugin, Store } from "vuex";
import * as utils from "../utils";
import { RootState } from "./root";
import { Module } from "vuex";
import { Stop } from "../model";
export interface Favourite {
id: string;
name: string;
name: string;
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;

View File

@ -2,21 +2,24 @@ import Vuex from 'vuex';
import messages, { MessagesState } from './messages';
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 VuexPersistence from "vuex-persist";
import { namespace } from "vuex-class";
import departureSettings from "./settings/departures";
export type State = {
messages: MessagesState;
departures: DeparturesState;
favourites: FavouritesState;
"departures-settings": DeparturesSettingsState,
"messages-settings": MessagesSettingsState,
} & RootState;
const localStoragePersist = new VuexPersistence<State>({
modules: ['favourites', 'departures-settings'],
modules: ['favourites', 'departures-settings', 'messages-settings'],
});
const sessionStoragePersist = new VuexPersistence<State>({
@ -24,17 +27,16 @@ const sessionStoragePersist = new VuexPersistence<State>({
storage: window.sessionStorage
});
const store = new Vuex.Store({
const store = new Vuex.Store<RootState>({
state, mutations, actions,
modules: {
messages,
departures,
favourites,
'departures-settings': departureSettings
'departures-settings': departureSettings,
'messages-settings': messagesSettings,
},
plugins: [
// todo: remove after some time
localStorageSaver('favourites.favourites', 'favourites'),
localStoragePersist.plugin,
sessionStoragePersist.plugin,
]
@ -44,4 +46,6 @@ export default store;
export const Favourites = namespace('favourites');
export const DeparturesSettings = namespace('departures-settings');
export const MessagesSettings = namespace('messages-settings');
export const Departures = namespace('departures');
export const Messages = namespace('messages');

View 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;

View File

@ -29,25 +29,7 @@
<portal to="popups">
<popper reference="settings-messages" v-if="visibility.messages" arrow placement="left-start" @leave="visibility.messages = false">
<h3 class="popper__heading flex">
<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>
<settings-messages></settings-messages>
</popper>
</portal>
</header>