Move options to vuex

Co-Authored-By: Tim Miller-Williams <timmw@users.noreply.github.com>
This commit is contained in:
Pavel Djundik 2019-11-03 20:05:19 +02:00
parent 743ae987ec
commit c26de4cf6a
14 changed files with 124 additions and 92 deletions

View file

@ -4,9 +4,9 @@
id="chat"
:data-id="channel.id"
:class="{
'hide-motd': !this.$root.settings.motd,
'colored-nicks': this.$root.settings.coloredNicks,
'show-seconds': this.$root.settings.showSeconds,
'hide-motd': !$store.state.settings.motd,
'colored-nicks': $store.state.settings.coloredNicks,
'show-seconds': $store.state.settings.showSeconds,
}"
>
<div

View file

@ -92,7 +92,7 @@ export default {
},
},
mounted() {
if (this.$root.settings.autocomplete) {
if (this.$store.state.settings.autocomplete) {
require("../js/autocompletion").enable(this.$refs.input);
}

View file

@ -207,8 +207,8 @@ export default {
case "error":
defaultState =
this.link.error === "image-too-big"
? this.$root.settings.media
: this.$root.settings.links;
? this.$store.state.settings.media
: this.$store.state.settings.links;
break;
case "loading":
@ -216,11 +216,11 @@ export default {
break;
case "link":
defaultState = this.$root.settings.links;
defaultState = this.$store.state.settings.links;
break;
default:
defaultState = this.$root.settings.media;
defaultState = this.$store.state.settings.media;
}
this.link.shown = this.link.shown && defaultState;

View file

@ -90,7 +90,7 @@ export default {
},
computed: {
messageTime() {
const format = this.$root.settings.showSeconds
const format = this.$store.state.settings.showSeconds
? constants.timeFormats.msgWithSeconds
: constants.timeFormats.msgDefault;

View file

@ -80,14 +80,14 @@ export default {
}
// If actions are hidden, just return a message list with them excluded
if (this.$root.settings.statusMessages === "hidden") {
if (this.$store.state.settings.statusMessages === "hidden") {
return this.channel.messages.filter(
(message) => !constants.condensedTypes.includes(message.type)
);
}
// If actions are not condensed, just return raw message list
if (this.$root.settings.statusMessages !== "condensed") {
if (this.$store.state.settings.statusMessages !== "condensed") {
return this.channel.messages;
}

View file

@ -10,7 +10,7 @@
<div class="col-sm-6">
<label class="opt">
<input
v-model="$store.state.serverConfiguration.advanced"
:checked="$store.state.settings.advanced"
type="checkbox"
name="advanced"
/>
@ -37,8 +37,7 @@
<div
v-if="
!$store.state.serverConfiguration.public &&
$store.state.serverConfiguration.advanced
!$store.state.serverConfiguration.public && $store.state.settings.advanced
"
class="col-sm-12"
>
@ -56,21 +55,21 @@
</h2>
<label class="opt">
<input
v-model="$root.settings.syncSettings"
:checked="$store.state.settings.syncSettings"
type="checkbox"
name="syncSettings"
/>
Synchronize settings with other clients
</label>
<p v-if="!$root.settings.syncSettings" class="sync-warning-override">
<p v-if="!$store.state.settings.syncSettings" class="sync-warning-override">
<strong>Warning</strong> Checking this box will override the settings of
this client with those stored on the server.
</p>
<p v-if="!$root.settings.syncSettings" class="sync-warning-base">
<p v-if="!$store.state.settings.syncSettings" class="sync-warning-base">
<strong>Warning</strong> No settings have been synced before. Enabling this
will sync all settings of this client as the base for other clients.
</p>
<div v-if="$root.settings.syncSettings" class="opt force-sync-button">
<div v-if="$store.state.settings.syncSettings" class="opt force-sync-button">
<button type="button" class="btn" @click="onForceSyncClick">
Force sync settings
</button>
@ -83,14 +82,14 @@
</div>
<div class="col-sm-6">
<label class="opt">
<input v-model="$root.settings.motd" type="checkbox" name="motd" />
<input :checked="$store.state.settings.motd" type="checkbox" name="motd" />
Show <abbr title="Message Of The Day">MOTD</abbr>
</label>
</div>
<div class="col-sm-6">
<label class="opt">
<input
v-model="$root.settings.showSeconds"
:checked="$store.state.settings.showSeconds"
type="checkbox"
name="showSeconds"
/>
@ -114,7 +113,7 @@
<div class="col-sm-12">
<label class="opt">
<input
v-model="$root.settings.statusMessages"
:checked="$store.state.settings.statusMessages === 'shown'"
type="radio"
name="statusMessages"
value="shown"
@ -123,7 +122,7 @@
</label>
<label class="opt">
<input
v-model="$root.settings.statusMessages"
:checked="$store.state.settings.statusMessages === 'condensed'"
type="radio"
name="statusMessages"
value="condensed"
@ -132,7 +131,7 @@
</label>
<label class="opt">
<input
v-model="$root.settings.statusMessages"
:checked="$store.state.settings.statusMessages === 'hidden'"
type="radio"
name="statusMessages"
value="hidden"
@ -146,7 +145,7 @@
<div class="col-sm-12">
<label class="opt">
<input
v-model="$root.settings.coloredNicks"
:checked="$store.state.settings.coloredNicks"
type="checkbox"
name="coloredNicks"
/>
@ -154,21 +153,21 @@
</label>
<label class="opt">
<input
v-model="$root.settings.autocomplete"
:checked="$store.state.settings.autocomplete"
type="checkbox"
name="autocomplete"
/>
Enable autocomplete
</label>
</div>
<div v-if="$store.state.serverConfiguration.advanced" class="col-sm-12">
<div v-if="$store.state.settings.advanced" class="col-sm-12">
<label class="opt">
<label for="nickPostfix" class="sr-only"
>Nick autocomplete postfix (e.g. <code>, </code>)</label
>
<label for="nickPostfix" class="sr-only">
Nick autocomplete postfix (e.g. <code>, </code>)
</label>
<input
id="nickPostfix"
v-model="$root.settings.nickPostfix"
:value="$store.state.settings.nickPostfix"
type="text"
name="nickPostfix"
class="input"
@ -184,7 +183,7 @@
<label for="theme-select" class="sr-only">Theme</label>
<select
id="theme-select"
v-model="$root.settings.theme"
:value="$store.state.settings.theme"
name="theme"
class="input"
>
@ -198,19 +197,27 @@
</select>
</div>
<template v-if="$store.state.serverConfiguration.prefetch">
<template v-if="$store.state.settings.prefetch">
<div class="col-sm-12">
<h2>Link previews</h2>
</div>
<div class="col-sm-6">
<label class="opt">
<input type="checkbox" name="media" />
<input
:checked="$store.state.settings.media"
type="checkbox"
name="media"
/>
Auto-expand media
</label>
</div>
<div class="col-sm-6">
<label class="opt">
<input v-model="$root.settings.links" type="checkbox" name="links" />
<input
:checked="$store.state.settings.links"
type="checkbox"
name="links"
/>
Auto-expand websites
</label>
</div>
@ -276,7 +283,7 @@
<div class="col-sm-12">
<label class="opt">
<input
v-model="$root.settings.notification"
:checked="$store.state.settings.notification"
type="checkbox"
name="notification"
/>
@ -289,10 +296,10 @@
</div>
</div>
<div v-if="$store.state.serverConfiguration.advanced" class="col-sm-12">
<div v-if="$store.state.settings.advanced" class="col-sm-12">
<label class="opt">
<input
v-model="$root.settings.notifyAllMessages"
:checked="$store.state.settings.notifyAllMessages"
type="checkbox"
name="notifyAllMessages"
/>
@ -300,14 +307,14 @@
</label>
</div>
<div v-if="$store.state.serverConfiguration.advanced" class="col-sm-12">
<div v-if="$store.state.settings.advanced" class="col-sm-12">
<label class="opt">
<label for="highlights" class="sr-only"
>Custom highlights (comma-separated keywords)</label
>
<label for="highlights" class="sr-only">
Custom highlights (comma-separated keywords)
</label>
<input
id="highlights"
v-model="$root.settings.highlights"
:value="$store.state.settings.highlights"
type="text"
name="highlights"
class="input"
@ -327,9 +334,9 @@
<h2>Change password</h2>
</div>
<div class="col-sm-12 password-container">
<label for="old_password_input" class="sr-only"
>Enter current password</label
>
<label for="old_password_input" class="sr-only">
Enter current password
</label>
<RevealPassword v-slot:default="slotProps">
<input
id="old_password_input"
@ -341,9 +348,9 @@
</RevealPassword>
</div>
<div class="col-sm-12 password-container">
<label for="new_password_input" class="sr-only"
>Enter desired new password</label
>
<label for="new_password_input" class="sr-only">
Enter desired new password
</label>
<RevealPassword v-slot:default="slotProps">
<input
id="new_password_input"
@ -355,9 +362,9 @@
</RevealPassword>
</div>
<div class="col-sm-12 password-container">
<label for="verify_password_input" class="sr-only"
>Repeat new password</label
>
<label for="verify_password_input" class="sr-only">
Repeat new password
</label>
<RevealPassword v-slot:default="slotProps">
<input
id="verify_password_input"
@ -387,16 +394,16 @@
</div>
</div>
<div v-if="$store.state.serverConfiguration.advanced" class="col-sm-12">
<div v-if="$store.state.settings.advanced" class="col-sm-12">
<h2>Custom Stylesheet</h2>
</div>
<div v-if="$store.state.serverConfiguration.advanced" class="col-sm-12">
<label for="user-specified-css-input" class="sr-only"
>Custom stylesheet. You can override any style with CSS here.</label
>
<div v-if="$store.state.settings.advanced" class="col-sm-12">
<label for="user-specified-css-input" class="sr-only">
Custom stylesheet. You can override any style with CSS here.
</label>
<textarea
id="user-specified-css-input"
v-model="$root.settings.userStyles"
:value="$store.state.settings.userStyles"
class="input"
name="userStyles"
placeholder="/* You can override any style with CSS here */"
@ -416,7 +423,7 @@
<div id="session-list">
<p v-if="$store.state.sessions.length == 0">Loading</p>
<p v-else-if="$store.getters.otherSessions.length == 0">
<em>You are not currently logged in to any other device.</em>'
<em>You are not currently logged in to any other device.</em>
</p>
<template v-else>
<Session

View file

@ -6,7 +6,6 @@ const Mousetrap = require("mousetrap");
const {Textcomplete, Textarea} = require("textcomplete");
const emojiMap = require("./libs/simplemap.json");
const constants = require("./constants");
const {vueApp} = require("./vue");
const store = require("./store").default;
let input;
@ -62,7 +61,7 @@ const nicksStrategy = {
},
replace([, original], position = 1) {
// If no postfix specified, return autocompleted nick as-is
if (!vueApp.settings.nickPostfix) {
if (!store.state.settings.nickPostfix) {
return original;
}
@ -72,7 +71,7 @@ const nicksStrategy = {
}
// If nick is first in the input, append specified postfix
return original + vueApp.settings.nickPostfix;
return original + store.state.settings.nickPostfix;
},
index: 1,
};

View file

@ -3,7 +3,6 @@
const $ = require("jquery");
const storage = require("./localStorage");
const socket = require("./socket");
const {vueApp} = require("./vue");
const store = require("./store").default;
require("../js/autocompletion");
@ -13,7 +12,7 @@ const $userStyles = $("#user-specified-css");
const noCSSparamReg = /[?&]nocss/;
// Default settings
const settings = vueApp.settings;
const settings = store.state.settings;
const noSync = ["syncSettings"];
@ -28,7 +27,7 @@ let userSettings = JSON.parse(storage.get("settings")) || false;
if (!userSettings) {
// Enable sync by default if there are no user defined settings.
settings.syncSettings = true;
store.commit("settings/syncSettings", true);
} else {
for (const key in settings) {
// Older The Lounge versions converted highlights to an array, turn it back into a string
@ -41,7 +40,7 @@ if (!userSettings) {
typeof userSettings[key] !== "undefined" &&
typeof settings[key] === typeof userSettings[key]
) {
settings[key] = userSettings[key];
store.commit(`settings/${key}`, userSettings[key]);
}
}
}
@ -118,7 +117,7 @@ function settingSetEmit(name, value) {
// When sync is `true` the setting will also be sent to the backend for syncing.
function updateSetting(name, value, sync) {
settings[name] = value;
store.commit(`settings/${name}`, value);
storage.set("settings", JSON.stringify(settings));
applySetting(name, value);

View file

@ -41,7 +41,7 @@ socket.on("configuration", function(data) {
// If localStorage contains a theme that does not exist on this server, switch
// back to its default theme.
const currentTheme = data.themes.find((t) => t.name === options.settings.theme);
const currentTheme = data.themes.find((t) => t.name === store.state.settings.theme);
if (currentTheme === undefined) {
options.processSetting("theme", data.defaultTheme, true);

View file

@ -2,7 +2,6 @@
const $ = require("jquery");
const socket = require("../socket");
const options = require("../options");
const cleanIrcMessage = require("../libs/handlebars/ircmessageparser/cleanIrcMessage");
const webpush = require("../webpush");
const {vueApp} = require("../vue");
@ -99,9 +98,9 @@ socket.on("msg", function(data) {
function notifyMessage(targetId, channel, activeChannel, msg) {
const button = $("#sidebar .chan[data-id='" + targetId + "']");
if (msg.highlight || (options.settings.notifyAllMessages && msg.type === "message")) {
if (msg.highlight || (store.state.settings.notifyAllMessages && msg.type === "message")) {
if (!document.hasFocus() || !activeChannel || activeChannel.channel !== channel) {
if (options.settings.notification) {
if (store.state.settings.notification) {
try {
pop.play();
} catch (exception) {
@ -110,7 +109,7 @@ function notifyMessage(targetId, channel, activeChannel, msg) {
}
if (
options.settings.desktopNotifications &&
store.state.settings.desktopNotifications &&
"Notification" in window &&
Notification.permission === "granted"
) {

View file

@ -2,11 +2,12 @@
const socket = require("../socket");
const options = require("../options");
const store = require("../store").default;
function evaluateSetting(name, value) {
if (
options.settings.syncSettings &&
options.settings[name] !== value &&
store.state.settings.syncSettings &&
store.state.settings[name] !== value &&
!options.noSync.includes(name)
) {
options.processSetting(name, value, true);

View file

@ -0,0 +1,37 @@
function createMutator(propertyName) {
return [
propertyName,
(state, value) => {
state[propertyName] = value;
},
];
}
function createMutators(keys) {
return Object.fromEntries(keys.map(createMutator));
}
const state = {
syncSettings: false,
advanced: false,
autocomplete: true,
nickPostfix: "",
coloredNicks: true,
desktopNotifications: false,
highlights: "",
links: true,
motd: true,
notification: true,
notifyAllMessages: false,
showSeconds: false,
statusMessages: "condensed",
theme: document.getElementById("theme").dataset.serverTheme,
media: true,
userStyles: "",
};
export default {
namespaced: true,
state,
mutations: createMutators(Object.keys(state)),
};

View file

@ -1,10 +1,15 @@
import Vue from "vue";
import Vuex from "vuex";
import settings from "./store-settings";
const storage = require("./localStorage");
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
settings,
},
state: {
activeChannel: null,
currentUserVisibleError: null,
@ -54,7 +59,10 @@ const store = new Vuex.Store({
state.networks = networks;
},
removeNetwork(state, networkId) {
state.networks.splice(store.state.networks.findIndex((n) => n.uuid === networkId), 1);
state.networks.splice(
store.state.networks.findIndex((n) => n.uuid === networkId),
1
);
},
sortNetworks(state, sortFn) {
state.networks.sort(sortFn);

View file

@ -23,24 +23,6 @@ const vueApp = new Vue({
el: "#viewport",
data: {
initialized: false,
settings: {
syncSettings: false,
advanced: false,
autocomplete: true,
nickPostfix: "",
coloredNicks: true,
desktopNotifications: false,
highlights: "",
links: true,
motd: true,
notification: true,
notifyAllMessages: false,
showSeconds: false,
statusMessages: "condensed",
theme: document.getElementById("theme").dataset.serverTheme,
media: true,
userStyles: "",
},
},
router,
mounted() {