Rework settings such that all behavior for each setting is kept together
Behavior includes: default value, whether setting should be synced, and an optional 'apply' callback which is called when setting is changed in Vuex.
This commit is contained in:
parent
703848919c
commit
25da9dd63e
@ -463,7 +463,6 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
options: null,
|
|
||||||
canRegisterProtocol: false,
|
canRegisterProtocol: false,
|
||||||
passwordChangeStatus: null,
|
passwordChangeStatus: null,
|
||||||
passwordErrors: {
|
passwordErrors: {
|
||||||
@ -476,8 +475,6 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.options = require("../../js/options"); // TODO: do this in a smarter way
|
|
||||||
|
|
||||||
socket.emit("sessions:get");
|
socket.emit("sessions:get");
|
||||||
|
|
||||||
// Enable protocol handler registration if supported
|
// Enable protocol handler registration if supported
|
||||||
@ -507,7 +504,7 @@ export default {
|
|||||||
value = event.target.value;
|
value = event.target.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.options.updateSetting(name, value, true);
|
this.$store.dispatch("settings/update", {name, value, sync: true});
|
||||||
},
|
},
|
||||||
changePassword() {
|
changePassword() {
|
||||||
const allFields = new FormData(this.$refs.settingsForm);
|
const allFields = new FormData(this.$refs.settingsForm);
|
||||||
@ -540,8 +537,7 @@ export default {
|
|||||||
socket.emit("change-password", data);
|
socket.emit("change-password", data);
|
||||||
},
|
},
|
||||||
onForceSyncClick() {
|
onForceSyncClick() {
|
||||||
const options = require("../../js/options");
|
this.$store.dispatch("settings/syncAll", true);
|
||||||
options.syncAllSettings(true);
|
|
||||||
},
|
},
|
||||||
registerProtocol() {
|
registerProtocol() {
|
||||||
const uri = document.location.origin + document.location.pathname + "?uri=%s";
|
const uri = document.location.origin + document.location.pathname + "?uri=%s";
|
||||||
|
@ -1,178 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const $ = require("jquery");
|
|
||||||
const storage = require("./localStorage");
|
|
||||||
const socket = require("./socket");
|
|
||||||
const store = require("./store").default;
|
|
||||||
require("../js/autocompletion");
|
|
||||||
|
|
||||||
const $theme = $("#theme");
|
|
||||||
const $userStyles = $("#user-specified-css");
|
|
||||||
|
|
||||||
const noCSSparamReg = /[?&]nocss/;
|
|
||||||
|
|
||||||
// Default settings
|
|
||||||
const settings = store.state.settings;
|
|
||||||
|
|
||||||
const noSync = ["syncSettings"];
|
|
||||||
|
|
||||||
// alwaysSync is reserved for settings that should be synced
|
|
||||||
// to the server regardless of the clients sync setting.
|
|
||||||
const alwaysSync = ["highlights"];
|
|
||||||
|
|
||||||
const defaultThemeColor = document.querySelector('meta[name="theme-color"]').content;
|
|
||||||
|
|
||||||
// Process usersettings from localstorage.
|
|
||||||
let userSettings = JSON.parse(storage.get("settings")) || false;
|
|
||||||
|
|
||||||
if (!userSettings) {
|
|
||||||
// Enable sync by default if there are no user defined settings.
|
|
||||||
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
|
|
||||||
if (key === "highlights" && typeof userSettings[key] === "object") {
|
|
||||||
userSettings[key] = userSettings[key].join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the setting in local storage has the same type that the code expects
|
|
||||||
if (
|
|
||||||
typeof userSettings[key] !== "undefined" &&
|
|
||||||
typeof settings[key] === typeof userSettings[key]
|
|
||||||
) {
|
|
||||||
store.commit(`settings/${key}`, userSettings[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply custom CSS and themes on page load
|
|
||||||
// Done here and not on init because on slower devices and connections
|
|
||||||
// it can take up to several seconds before init is called.
|
|
||||||
if (typeof userSettings.userStyles === "string" && !noCSSparamReg.test(window.location.search)) {
|
|
||||||
$userStyles.html(userSettings.userStyles);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
typeof userSettings.theme === "string" &&
|
|
||||||
$theme.attr("href") !== `themes/${userSettings.theme}.css`
|
|
||||||
) {
|
|
||||||
$theme.attr("href", `themes/${userSettings.theme}.css`);
|
|
||||||
}
|
|
||||||
|
|
||||||
userSettings = null;
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
alwaysSync,
|
|
||||||
noSync,
|
|
||||||
settings,
|
|
||||||
syncAllSettings,
|
|
||||||
processSetting,
|
|
||||||
initialize,
|
|
||||||
updateSetting,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Updates the checkbox and warning in settings.
|
|
||||||
// When notifications are not supported, this is never called (because
|
|
||||||
// checkbox state can not be changed).
|
|
||||||
function updateDesktopNotificationStatus() {
|
|
||||||
if (Notification.permission === "granted") {
|
|
||||||
store.commit("desktopNotificationState", "granted");
|
|
||||||
} else {
|
|
||||||
store.commit("desktopNotificationState", "blocked");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applySetting(name, value) {
|
|
||||||
if (name === "theme") {
|
|
||||||
const themeUrl = `themes/${value}.css`;
|
|
||||||
|
|
||||||
if ($theme.attr("href") !== themeUrl) {
|
|
||||||
$theme.attr("href", themeUrl);
|
|
||||||
const newTheme = store.state.serverConfiguration.themes.filter(
|
|
||||||
(theme) => theme.name === value
|
|
||||||
)[0];
|
|
||||||
let themeColor = defaultThemeColor;
|
|
||||||
|
|
||||||
if (newTheme.themeColor) {
|
|
||||||
themeColor = newTheme.themeColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelector('meta[name="theme-color"]').content = themeColor;
|
|
||||||
}
|
|
||||||
} else if (name === "userStyles" && !noCSSparamReg.test(window.location.search)) {
|
|
||||||
$userStyles.html(value);
|
|
||||||
} else if (name === "desktopNotifications") {
|
|
||||||
updateDesktopNotificationStatus();
|
|
||||||
|
|
||||||
if ("Notification" in window && value && Notification.permission !== "granted") {
|
|
||||||
Notification.requestPermission(updateDesktopNotificationStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function settingSetEmit(name, value) {
|
|
||||||
socket.emit("setting:set", {name, value});
|
|
||||||
}
|
|
||||||
|
|
||||||
// When sync is `true` the setting will also be sent to the backend for syncing.
|
|
||||||
function updateSetting(name, value, sync) {
|
|
||||||
store.commit(`settings/${name}`, value);
|
|
||||||
storage.set("settings", JSON.stringify(settings));
|
|
||||||
applySetting(name, value);
|
|
||||||
|
|
||||||
// Sync is checked, request settings from server.
|
|
||||||
if (name === "syncSettings" && value) {
|
|
||||||
socket.emit("setting:get");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.syncSettings && !noSync.includes(name) && sync) {
|
|
||||||
settingSetEmit(name, value);
|
|
||||||
} else if (alwaysSync.includes(name) && sync) {
|
|
||||||
settingSetEmit(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncAllSettings(force = false) {
|
|
||||||
// Sync all settings if sync is enabled or force is true.
|
|
||||||
if (settings.syncSettings || force) {
|
|
||||||
for (const name in settings) {
|
|
||||||
if (!noSync.includes(name)) {
|
|
||||||
settingSetEmit(name, settings[name]);
|
|
||||||
} else if (alwaysSync.includes(name)) {
|
|
||||||
settingSetEmit(name, settings[name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If `save` is set to true it will pass the setting to `updateSetting()` processSetting
|
|
||||||
function processSetting(name, value, save) {
|
|
||||||
// No need to also call processSetting when `save` is true.
|
|
||||||
// updateSetting does take care of that.
|
|
||||||
if (save) {
|
|
||||||
// Sync is false as applySetting is never called as the result of a user changing the setting.
|
|
||||||
updateSetting(name, value, false);
|
|
||||||
} else {
|
|
||||||
applySetting(name, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initialize() {
|
|
||||||
// Settings have now entirely updated, apply settings to the client.
|
|
||||||
for (const name in settings) {
|
|
||||||
processSetting(name, settings[name], false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If browser does not support notifications
|
|
||||||
// display proper message in settings.
|
|
||||||
if ("Notification" in window) {
|
|
||||||
updateDesktopNotificationStatus();
|
|
||||||
} else {
|
|
||||||
store.commit("desktopNotificationState", "unsupported");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local init is done, let's sync
|
|
||||||
// We always ask for synced settings even if it is disabled.
|
|
||||||
// Settings can be mandatory to sync and it is used to determine sync base state.
|
|
||||||
socket.emit("setting:get");
|
|
||||||
}
|
|
113
client/js/settings.js
Normal file
113
client/js/settings.js
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
const socket = require("./socket");
|
||||||
|
|
||||||
|
const defaultSettingConfig = {
|
||||||
|
apply() {},
|
||||||
|
default: null,
|
||||||
|
sync: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const config = normalizeConfig({
|
||||||
|
syncSettings: {
|
||||||
|
default: true,
|
||||||
|
sync: "never",
|
||||||
|
apply(store, value) {
|
||||||
|
value && socket.emit("setting:get");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
advanced: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
autocomplete: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
nickPostfix: {
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
coloredNicks: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
desktopNotifications: {
|
||||||
|
default: false,
|
||||||
|
apply(store, value) {
|
||||||
|
store.commit("refreshDesktopNotificationState", null, {root: true});
|
||||||
|
|
||||||
|
if ("Notification" in window && value && Notification.permission !== "granted") {
|
||||||
|
Notification.requestPermission(() =>
|
||||||
|
store.commit("refreshDesktopNotificationState", null, {root: true})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
highlights: {
|
||||||
|
default: "",
|
||||||
|
sync: "always",
|
||||||
|
},
|
||||||
|
links: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
motd: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
notification: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
notifyAllMessages: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
showSeconds: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
statusMessages: {
|
||||||
|
default: "condensed",
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
default: document.getElementById("theme").dataset.serverTheme,
|
||||||
|
apply(store, value) {
|
||||||
|
const themeEl = document.getElementById("theme");
|
||||||
|
const themeUrl = `themes/${value}.css`;
|
||||||
|
|
||||||
|
if (themeEl.attributes.href.value === themeUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
themeEl.attributes.href.value = themeUrl;
|
||||||
|
const newTheme = store.state.serverConfiguration.themes.filter(
|
||||||
|
(theme) => theme.name === value
|
||||||
|
)[0];
|
||||||
|
const themeColor =
|
||||||
|
newTheme.themeColor || document.querySelector('meta[name="theme-color"]').content;
|
||||||
|
document.querySelector('meta[name="theme-color"]').content = themeColor;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
media: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
userStyles: {
|
||||||
|
default: "",
|
||||||
|
apply(store, value) {
|
||||||
|
if (!/[?&]nocss/.test(window.location.search)) {
|
||||||
|
document.getElementById("user-specified-css").innerHTML = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function createState() {
|
||||||
|
const state = {};
|
||||||
|
|
||||||
|
for (const settingName in config) {
|
||||||
|
state[settingName] = config[settingName].default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeConfig(obj) {
|
||||||
|
const newConfig = {};
|
||||||
|
|
||||||
|
for (const settingName in obj) {
|
||||||
|
newConfig[settingName] = {...defaultSettingConfig, ...obj[settingName]};
|
||||||
|
}
|
||||||
|
|
||||||
|
return newConfig;
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
const socket = require("../socket");
|
const socket = require("../socket");
|
||||||
const options = require("../options");
|
|
||||||
const webpush = require("../webpush");
|
const webpush = require("../webpush");
|
||||||
const upload = require("../upload");
|
const upload = require("../upload");
|
||||||
const store = require("../store").default;
|
const store = require("../store").default;
|
||||||
@ -25,11 +24,15 @@ socket.once("configuration", function(data) {
|
|||||||
store.commit("isFileUploadEnabled", data.fileUpload);
|
store.commit("isFileUploadEnabled", data.fileUpload);
|
||||||
store.commit("serverConfiguration", data);
|
store.commit("serverConfiguration", data);
|
||||||
|
|
||||||
|
// 'theme' setting depends on serverConfiguration.themes so
|
||||||
|
// settings cannot be applied before this point
|
||||||
|
store.dispatch("settings/applyAll");
|
||||||
|
|
||||||
if (data.fileUpload) {
|
if (data.fileUpload) {
|
||||||
upload.initialize(data.fileUploadMaxFileSize);
|
upload.initialize(data.fileUploadMaxFileSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
options.initialize();
|
socket.emit("setting:get");
|
||||||
webpush.initialize();
|
webpush.initialize();
|
||||||
|
|
||||||
// If localStorage contains a theme that does not exist on this server, switch
|
// If localStorage contains a theme that does not exist on this server, switch
|
||||||
@ -37,7 +40,7 @@ socket.once("configuration", function(data) {
|
|||||||
const currentTheme = data.themes.find((t) => t.name === store.state.settings.theme);
|
const currentTheme = data.themes.find((t) => t.name === store.state.settings.theme);
|
||||||
|
|
||||||
if (currentTheme === undefined) {
|
if (currentTheme === undefined) {
|
||||||
options.processSetting("theme", data.defaultTheme, true);
|
store.commit("settings/update", {name: "theme", value: data.defaultTheme, sync: true});
|
||||||
} else if (currentTheme.themeColor) {
|
} else if (currentTheme.themeColor) {
|
||||||
document.querySelector('meta[name="theme-color"]').content = currentTheme.themeColor;
|
document.querySelector('meta[name="theme-color"]').content = currentTheme.themeColor;
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,20 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const socket = require("../socket");
|
const socket = require("../socket");
|
||||||
const options = require("../options");
|
|
||||||
const store = require("../store").default;
|
const store = require("../store").default;
|
||||||
|
|
||||||
function evaluateSetting(name, value) {
|
|
||||||
if (
|
|
||||||
store.state.settings.syncSettings &&
|
|
||||||
store.state.settings[name] !== value &&
|
|
||||||
!options.noSync.includes(name)
|
|
||||||
) {
|
|
||||||
options.processSetting(name, value, true);
|
|
||||||
} else if (options.alwaysSync.includes(name)) {
|
|
||||||
options.processSetting(name, value, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.on("setting:new", function(data) {
|
socket.on("setting:new", function(data) {
|
||||||
const name = data.name;
|
const name = data.name;
|
||||||
const value = data.value;
|
const value = data.value;
|
||||||
evaluateSetting(name, value);
|
store.dispatch("settings/update", {name, value, sync: false});
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("setting:all", function(settings) {
|
socket.on("setting:all", function(settings) {
|
||||||
if (Object.keys(settings).length === 0) {
|
if (Object.keys(settings).length === 0) {
|
||||||
options.syncAllSettings();
|
store.dispatch("settings/syncAll");
|
||||||
} else {
|
} else {
|
||||||
for (const name in settings) {
|
for (const name in settings) {
|
||||||
evaluateSetting(name, settings[name]);
|
store.dispatch("settings/update", {name, value: settings[name], sync: false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,37 +1,100 @@
|
|||||||
function createMutator(propertyName) {
|
const storage = require("./localStorage");
|
||||||
return [
|
const socket = require("./socket");
|
||||||
propertyName,
|
import {config, createState} from "./settings";
|
||||||
(state, value) => {
|
|
||||||
state[propertyName] = value;
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMutators(keys) {
|
export function createSettingsStore(store) {
|
||||||
return Object.fromEntries(keys.map(createMutator));
|
return {
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
namespaced: true,
|
||||||
state,
|
state: assignStoredSettings(createState(), loadFromLocalStorage()),
|
||||||
mutations: createMutators(Object.keys(state)),
|
mutations: {
|
||||||
};
|
set(state, {name, value}) {
|
||||||
|
state[name] = value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
syncAll({state}, force = false) {
|
||||||
|
if (state.syncSettings === false || force === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const name in state) {
|
||||||
|
if (config[name].sync !== "never" || config[name].sync === "always") {
|
||||||
|
socket.emit("setting:set", {name, value: state[name]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applyAll({state}) {
|
||||||
|
for (const settingName in config) {
|
||||||
|
config[settingName].apply(store, state[settingName]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update({state, commit}, {name, value, sync = false}) {
|
||||||
|
if (state[name] === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const settingConfig = config[name];
|
||||||
|
|
||||||
|
if (
|
||||||
|
sync === false &&
|
||||||
|
(state.syncSettings === false || settingConfig.sync === "never")
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
commit("set", {name, value});
|
||||||
|
storage.set("settings", JSON.stringify(state));
|
||||||
|
settingConfig.apply(store, value);
|
||||||
|
|
||||||
|
if (!sync) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(state.syncSettings && settingConfig.sync !== "never") ||
|
||||||
|
settingConfig.sync === "always"
|
||||||
|
) {
|
||||||
|
socket.emit("setting:set", {name, value});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadFromLocalStorage() {
|
||||||
|
const storedSettings = JSON.parse(storage.get("settings")) || false;
|
||||||
|
|
||||||
|
if (!storedSettings) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Older The Lounge versions converted highlights to an array, turn it back into a string
|
||||||
|
if (typeof storedSettings.highlights === "object") {
|
||||||
|
storedSettings.highlights = storedSettings.highlights.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return storedSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Essentially Object.assign but does not overwrite and only assigns
|
||||||
|
* if key exists in both supplied objects and types match
|
||||||
|
*
|
||||||
|
* @param {object} defaultSettings
|
||||||
|
* @param {object} storedSettings
|
||||||
|
*/
|
||||||
|
function assignStoredSettings(defaultSettings, storedSettings) {
|
||||||
|
const newSettings = {...defaultSettings};
|
||||||
|
|
||||||
|
for (const key in defaultSettings) {
|
||||||
|
// Make sure the setting in local storage has the same type that the code expects
|
||||||
|
if (
|
||||||
|
typeof storedSettings[key] !== "undefined" &&
|
||||||
|
typeof defaultSettings[key] === typeof storedSettings[key]
|
||||||
|
) {
|
||||||
|
newSettings[key] = storedSettings[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newSettings;
|
||||||
|
}
|
||||||
|
@ -1,20 +1,27 @@
|
|||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import Vuex from "vuex";
|
import Vuex from "vuex";
|
||||||
import settings from "./store-settings";
|
import {createSettingsStore} from "./store-settings";
|
||||||
|
|
||||||
const storage = require("./localStorage");
|
const storage = require("./localStorage");
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
function detectDesktopNotificationState() {
|
||||||
|
if (!("Notification" in window)) {
|
||||||
|
return "unsupported";
|
||||||
|
} else if (Notification.permission === "granted") {
|
||||||
|
return "granted";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "blocked";
|
||||||
|
}
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
const store = new Vuex.Store({
|
||||||
modules: {
|
|
||||||
settings,
|
|
||||||
},
|
|
||||||
state: {
|
state: {
|
||||||
appLoaded: false,
|
appLoaded: false,
|
||||||
activeChannel: null,
|
activeChannel: null,
|
||||||
currentUserVisibleError: null,
|
currentUserVisibleError: null,
|
||||||
desktopNotificationState: "unsupported",
|
desktopNotificationState: detectDesktopNotificationState(),
|
||||||
isAutoCompleting: false,
|
isAutoCompleting: false,
|
||||||
isConnected: false,
|
isConnected: false,
|
||||||
isFileUploadEnabled: false,
|
isFileUploadEnabled: false,
|
||||||
@ -41,8 +48,8 @@ const store = new Vuex.Store({
|
|||||||
currentUserVisibleError(state, error) {
|
currentUserVisibleError(state, error) {
|
||||||
state.currentUserVisibleError = error;
|
state.currentUserVisibleError = error;
|
||||||
},
|
},
|
||||||
desktopNotificationState(state, desktopNotificationState) {
|
refreshDesktopNotificationState(state) {
|
||||||
state.desktopNotificationState = desktopNotificationState;
|
state.desktopNotificationState = detectDesktopNotificationState();
|
||||||
},
|
},
|
||||||
isAutoCompleting(state, isAutoCompleting) {
|
isAutoCompleting(state, isAutoCompleting) {
|
||||||
state.isAutoCompleting = isAutoCompleting;
|
state.isAutoCompleting = isAutoCompleting;
|
||||||
@ -129,4 +136,8 @@ const store = new Vuex.Store({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Settings module is registered dynamically because it benefits
|
||||||
|
// from a direct reference to the store
|
||||||
|
store.registerModule("settings", createSettingsStore(store));
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
Loading…
Reference in New Issue
Block a user