Move some settings to Vue

This commit is contained in:
Pavel Djundik 2019-02-20 11:10:18 +02:00
parent 09e12affe8
commit 71f54f6a5d
7 changed files with 115 additions and 134 deletions

View File

@ -19,44 +19,42 @@
<NetworkList :networks="networks" :active-channel="activeChannel" /> <NetworkList :networks="networks" :active-channel="activeChannel" />
</div> </div>
<footer id="footer"> <footer id="footer">
<span class="tooltipped tooltipped-n tooltipped-no-touch" aria-label="Sign in" <span
><button class="tooltipped tooltipped-n tooltipped-no-touch"
aria-label="Sign in"><button
class="icon sign-in" class="icon sign-in"
data-target="#sign-in" data-target="SignIn"
aria-label="Sign in" aria-label="Sign in"
role="tab" role="tab"
aria-controls="sign-in" aria-controls="sign-in"
aria-selected="false" aria-selected="false" /></span>
/></span>
<span <span
class="tooltipped tooltipped-n tooltipped-no-touch" class="tooltipped tooltipped-n tooltipped-no-touch"
aria-label="Connect to network" aria-label="Connect to network"><button
><button
class="icon connect" class="icon connect"
data-target="#connect" data-target="Connect"
aria-label="Connect to network" aria-label="Connect to network"
role="tab" role="tab"
aria-controls="connect" aria-controls="connect"
aria-selected="false" aria-selected="false" /></span>
/></span> <span
<span class="tooltipped tooltipped-n tooltipped-no-touch" aria-label="Settings" class="tooltipped tooltipped-n tooltipped-no-touch"
><button aria-label="Settings"><button
class="icon settings" class="icon settings"
data-target="#settings" data-target="Settings"
aria-label="Settings" aria-label="Settings"
role="tab" role="tab"
aria-controls="settings" aria-controls="settings"
aria-selected="false" aria-selected="false" /></span>
/></span> <span
<span class="tooltipped tooltipped-n tooltipped-no-touch" aria-label="Help" class="tooltipped tooltipped-n tooltipped-no-touch"
><button aria-label="Help"><button
class="icon help" class="icon help"
data-target="#help" data-target="Help"
aria-label="Help" aria-label="Help"
role="tab" role="tab"
aria-controls="help" aria-controls="help"
aria-selected="false" aria-selected="false" /></span>
/></span>
</footer> </footer>
</aside> </aside>
<div id="sidebar-overlay" /> <div id="sidebar-overlay" />
@ -78,6 +76,7 @@ const throttle = require("lodash/throttle");
import NetworkList from "./NetworkList.vue"; import NetworkList from "./NetworkList.vue";
import Chat from "./Chat.vue"; import Chat from "./Chat.vue";
import SignIn from "./Windows/SignIn.vue"; import SignIn from "./Windows/SignIn.vue";
import Settings from "./Windows/Settings.vue";
export default { export default {
name: "App", name: "App",
@ -85,6 +84,7 @@ export default {
NetworkList, NetworkList,
Chat, Chat,
SignIn, SignIn,
Settings,
}, },
props: { props: {
activeWindow: String, activeWindow: String,

View File

@ -40,8 +40,8 @@
class="btn">Open irc:// URLs with The Lounge</button> class="btn">Open irc:// URLs with The Lounge</button>
</div> </div>
{{#unless public}}
<div <div
v-if="!this.$root.serverConfiguration.public"
class="col-sm-12" class="col-sm-12"
data-advanced> data-advanced>
<h2> <h2>
@ -64,13 +64,13 @@
<p 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> <p 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 class="opt force-sync-button"> <div class="opt force-sync-button">
<button <button
id="forceSync"
type="button" type="button"
class="btn">Force sync settings</button> class="btn"
@click="onForceSyncClick">Force sync settings</button>
<p>This will override any settings already synced to the server.</p> <p>This will override any settings already synced to the server.</p>
</div> </div>
</div> </div>
{{/unless}}
<div class="col-sm-12"> <div class="col-sm-12">
<h2>Messages</h2> <h2>Messages</h2>
</div> </div>
@ -169,14 +169,15 @@
id="theme-select" id="theme-select"
name="theme" name="theme"
class="input"> class="input">
{{#each themes}} <option
<option value="{{name}}"> v-for="theme in this.$root.serverConfiguration.themes"
{{ displayName }} :key="theme.name">
{{ theme.displayName }}
</option> </option>
{{/each}}
</select> </select>
</div> </div>
{{#if prefetch}}
<template v-if="this.$root.serverConfiguration.prefetch">
<div class="col-sm-12"> <div class="col-sm-12">
<h2>Link previews</h2> <h2>Link previews</h2>
</div> </div>
@ -196,8 +197,9 @@
Auto-expand websites Auto-expand websites
</label> </label>
</div> </div>
{{/if}} </template>
{{#unless public}}
<template v-if="!this.$root.serverConfiguration.public">
<div class="col-sm-12"> <div class="col-sm-12">
<h2>Push Notifications</h2> <h2>Push Notifications</h2>
</div> </div>
@ -209,19 +211,20 @@
disabled disabled
data-text-alternate="Unsubscribe from push notifications">Subscribe to push notifications</button> data-text-alternate="Unsubscribe from push notifications">Subscribe to push notifications</button>
<div <div
id="pushNotificationsHttps" v-if="this.$root.pushNotificationState === 'nohttps'"
class="error"> class="error">
<strong>Warning</strong>: <strong>Warning</strong>:
Push notifications are only supported over HTTPS connections. Push notifications are only supported over HTTPS connections.
</div> </div>
<div <div
id="pushNotificationsUnsupported" v-if="this.$root.pushNotificationState === 'unsupported'"
class="error"> class="error">
<strong>Warning</strong>: <strong>Warning</strong>:
<span>Push notifications are not supported by your browser.</span> <span>Push notifications are not supported by your browser.</span>
</div> </div>
</div> </div>
{{/unless}} </template>
<div class="col-sm-12"> <div class="col-sm-12">
<h2>Browser Notifications</h2> <h2>Browser Notifications</h2>
</div> </div>
@ -233,12 +236,13 @@
name="desktopNotifications"> name="desktopNotifications">
Enable browser notifications<br> Enable browser notifications<br>
<div <div
id="warnUnsupportedDesktopNotifications" v-if="this.$root.desktopNotificationState === 'unsupported'"
class="error"> class="error">
<strong>Warning</strong>: <strong>Warning</strong>:
Notifications are not supported by your browser. Notifications are not supported by your browser.
</div> </div>
<div <div
v-if="this.$root.desktopNotificationState === 'blocked'"
id="warnBlockedDesktopNotifications" id="warnBlockedDesktopNotifications"
class="error"> class="error">
<strong>Warning</strong>: <strong>Warning</strong>:
@ -287,9 +291,9 @@
</label> </label>
</div> </div>
{{#unless public}} <div
{{#unless ldapEnabled}} v-if="!this.$root.serverConfiguration.public && !this.$root.serverConfiguration.ldapEnabled"
<div id="change-password"> id="change-password">
<form <form
action="" action=""
method="post" method="post"
@ -307,7 +311,6 @@
name="old_password" name="old_password"
class="input" class="input"
placeholder="Enter current password"> placeholder="Enter current password">
{{> ../reveal-password}}
</div> </div>
<div class="col-sm-12 password-container"> <div class="col-sm-12 password-container">
<label <label
@ -319,7 +322,6 @@
name="new_password" name="new_password"
class="input" class="input"
placeholder="Enter desired new password"> placeholder="Enter desired new password">
{{> ../reveal-password}}
</div> </div>
<div class="col-sm-12 password-container"> <div class="col-sm-12 password-container">
<label <label
@ -331,7 +333,6 @@
name="verify_password" name="verify_password"
class="input" class="input"
placeholder="Repeat new password"> placeholder="Repeat new password">
{{> ../reveal-password}}
</div> </div>
<div class="col-sm-12 feedback" /> <div class="col-sm-12 feedback" />
<div class="col-sm-12"> <div class="col-sm-12">
@ -341,8 +342,7 @@
</div> </div>
</form> </form>
</div> </div>
{{/unless}}
{{/unless}}
<div <div
class="col-sm-12" class="col-sm-12"
data-advanced> data-advanced>
@ -356,14 +356,16 @@
class="sr-only">Custom stylesheet. You can override any style with CSS here.</label> class="sr-only">Custom stylesheet. You can override any style with CSS here.</label>
<textarea <textarea
id="user-specified-css-input" id="user-specified-css-input"
v-model="$root.settings.userStyles"
class="input" class="input"
name="userStyles" name="userStyles"
placeholder="/* You can override any style with CSS here */" /> placeholder="/* You can override any style with CSS here */" />
</div> </div>
</div> </div>
{{#unless public}} <div
<div class="session-list"> v-if="!this.$root.serverConfiguration.public"
class="session-list">
<h2>Sessions</h2> <h2>Sessions</h2>
<h3>Current session</h3> <h3>Current session</h3>
@ -372,7 +374,6 @@
<h3>Other sessions</h3> <h3>Other sessions</h3>
<div id="session-list" /> <div id="session-list" />
</div> </div>
{{/unless}}
</div> </div>
</div> </div>
@ -410,6 +411,10 @@ export default {
socket.emit("auth", values); socket.emit("auth", values);
}, },
onForceSyncClick() {
const options = require("../../js/options");
options.syncAllSettings(true);
},
}, },
}; };
</script> </script>

View File

@ -141,22 +141,18 @@ window.vueMounted = () => {
if ($(window).outerWidth() <= utils.mobileViewportPixels) { if ($(window).outerWidth() <= utils.mobileViewportPixels) {
slideoutMenu.toggle(false); slideoutMenu.toggle(false);
} }
} else {
vueApp.activeChannel = null;
vueApp.activeWindow = target;
} }
const lastActive = $("#windows > .active");
lastActive.removeClass("active");
const chan = $(target)
.addClass("active")
.trigger("show");
utils.synchronizeNotifiedState(); utils.synchronizeNotifiedState();
if (self.hasClass("chan")) { if (self.hasClass("chan")) {
vueApp.$nextTick(() => $("#chat-container").addClass("active")); vueApp.$nextTick(() => $("#chat-container").addClass("active"));
} }
/* TODO: move to ChatInput.vue
const chanChat = chan.find(".chat"); const chanChat = chan.find(".chat");
if (chanChat.length > 0 && channel.type !== "special") { if (chanChat.length > 0 && channel.type !== "special") {
@ -165,6 +161,7 @@ window.vueMounted = () => {
// See https://github.com/thelounge/thelounge/issues/2257 // See https://github.com/thelounge/thelounge/issues/2257
$("#input").trigger("ontouchstart" in window ? "blur" : "focus"); $("#input").trigger("ontouchstart" in window ? "blur" : "focus");
} }
*/
if (channel && channel.channel.usersOutdated) { if (channel && channel.channel.usersOutdated) {
channel.channel.usersOutdated = false; channel.channel.usersOutdated = false;

View File

@ -6,7 +6,6 @@ const socket = require("./socket");
const {vueApp} = require("./vue"); const {vueApp} = require("./vue");
require("../js/autocompletion"); require("../js/autocompletion");
const $windows = $("#windows");
const $settings = $("#settings"); const $settings = $("#settings");
const $theme = $("#theme"); const $theme = $("#theme");
const $userStyles = $("#user-specified-css"); const $userStyles = $("#user-specified-css");
@ -18,8 +17,6 @@ const noCSSparamReg = /[?&]nocss/;
let $syncWarningOverride; let $syncWarningOverride;
let $syncWarningBase; let $syncWarningBase;
let $forceSyncButton; let $forceSyncButton;
let $warningUnsupported;
let $warningBlocked;
// Default settings // Default settings
const settings = vueApp.settings; const settings = vueApp.settings;
@ -85,10 +82,10 @@ module.exports = {
// When notifications are not supported, this is never called (because // When notifications are not supported, this is never called (because
// checkbox state can not be changed). // checkbox state can not be changed).
function updateDesktopNotificationStatus() { function updateDesktopNotificationStatus() {
if (Notification.permission === "denied") { if (Notification.permission === "granted") {
$warningBlocked.show(); vueApp.desktopNotificationState = "granted";
} else { } else {
$warningBlocked.hide(); vueApp.desktopNotificationState = "blocked";
} }
} }
@ -114,10 +111,10 @@ function applySetting(name, value) {
} else if (name === "userStyles" && !noCSSparamReg.test(window.location.search)) { } else if (name === "userStyles" && !noCSSparamReg.test(window.location.search)) {
$userStyles.html(value); $userStyles.html(value);
} else if (name === "desktopNotifications") { } else if (name === "desktopNotifications") {
if ("Notification" in window && value && Notification.permission !== "granted") { updateDesktopNotificationStatus();
if (("Notification" in window) && value && Notification.permission !== "granted") {
Notification.requestPermission(updateDesktopNotificationStatus); Notification.requestPermission(updateDesktopNotificationStatus);
} else if (!value) {
$warningBlocked.hide();
} }
} else if (name === "advanced") { } else if (name === "advanced") {
$("#settings [data-advanced]").toggle(settings[name]); $("#settings [data-advanced]").toggle(settings[name]);
@ -180,9 +177,7 @@ function syncAllSettings(force = false) {
// If `save` is set to true it will pass the setting to `updateSetting()` processSetting // If `save` is set to true it will pass the setting to `updateSetting()` processSetting
function processSetting(name, value, save) { function processSetting(name, value, save) {
if (name === "userStyles") { if (name === "highlights") {
$settings.find("#user-specified-css-input").val(value);
} else if (name === "highlights") {
$settings.find(`input[name=${name}]`).val(value); $settings.find(`input[name=${name}]`).val(value);
} else if (name === "nickPostfix") { } else if (name === "nickPostfix") {
$settings.find(`input[name=${name}]`).val(value); $settings.find(`input[name=${name}]`).val(value);
@ -205,14 +200,10 @@ function processSetting(name, value, save) {
} }
function initialize() { function initialize() {
$warningBlocked = $settings.find("#warnBlockedDesktopNotifications");
$warningUnsupported = $settings.find("#warnUnsupportedDesktopNotifications");
$syncWarningOverride = $settings.find(".sync-warning-override"); $syncWarningOverride = $settings.find(".sync-warning-override");
$syncWarningBase = $settings.find(".sync-warning-base"); $syncWarningBase = $settings.find(".sync-warning-base");
$forceSyncButton = $settings.find(".force-sync-button"); $forceSyncButton = $settings.find(".force-sync-button");
$warningBlocked.hide();
module.exports.initialized = true; module.exports.initialized = true;
// Settings have now entirely updated, apply settings to the client. // Settings have now entirely updated, apply settings to the client.
@ -222,11 +213,10 @@ function initialize() {
// If browser does not support notifications // If browser does not support notifications
// display proper message in settings. // display proper message in settings.
if ("Notification" in window) { if (("Notification" in window)) {
$warningUnsupported.hide(); updateDesktopNotificationStatus();
$windows.on("show", "#settings", updateDesktopNotificationStatus);
} else { } else {
$warningUnsupported.show(); vueApp.desktopNotificationState = "unsupported";
} }
$settings.on("change", "input, select, textarea", function(e) { $settings.on("change", "input, select, textarea", function(e) {
@ -249,10 +239,6 @@ function initialize() {
} }
}); });
$settings.find("#forceSync").on("click", () => {
syncAllSettings(true);
});
// Local init is done, let's sync // Local init is done, let's sync
// We always ask for synced settings even if it is disabled. // 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. // Settings can be mandatory to sync and it is used to determine sync base state.

View File

@ -6,7 +6,6 @@ const templates = require("../../views");
const options = require("../options"); const options = require("../options");
const webpush = require("../webpush"); const webpush = require("../webpush");
const connect = $("#connect"); const connect = $("#connect");
const utils = require("../utils");
const upload = require("../upload"); const upload = require("../upload");
const {vueApp} = require("../vue"); const {vueApp} = require("../vue");
@ -33,9 +32,7 @@ socket.on("configuration", function(data) {
return; return;
} }
$("#settings").html(templates.windows.settings(data)); vueApp.serverConfiguration = data;
$("#help").html(templates.windows.help(data));
$("#changelog").html(templates.windows.changelog());
$("#settings").on("show", () => { $("#settings").on("show", () => {
$("#session-list").html("<p>Loading…</p>"); $("#session-list").html("<p>Loading…</p>");

View File

@ -25,6 +25,9 @@ const vueApp = new Vue({
isFileUploadEnabled: false, isFileUploadEnabled: false,
isNotified: false, isNotified: false,
networks: [], networks: [],
pushNotificationState: "unsupported",
desktopNotificationState: "unsupported",
serverConfiguration: {},
settings: { settings: {
syncSettings: false, syncSettings: false,
advanced: false, advanced: false,

View File

@ -3,6 +3,7 @@
const $ = require("jquery"); const $ = require("jquery");
const storage = require("./localStorage"); const storage = require("./localStorage");
const socket = require("./socket"); const socket = require("./socket");
const {vueApp} = require("./vue");
let pushNotificationsButton; let pushNotificationsButton;
let clientSubscribed = null; let clientSubscribed = null;
@ -43,11 +44,10 @@ module.exports.initialize = () => {
pushNotificationsButton = $("#pushNotifications"); pushNotificationsButton = $("#pushNotifications");
if (!isAllowedServiceWorkersHost()) { if (!isAllowedServiceWorkersHost()) {
vueApp.pushNotificationState = "nohttps";
return; return;
} }
$("#pushNotificationsHttps").hide();
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
navigator.serviceWorker navigator.serviceWorker
.register("service-worker.js") .register("service-worker.js")
@ -59,9 +59,7 @@ module.exports.initialize = () => {
} }
return registration.pushManager.getSubscription().then((subscription) => { return registration.pushManager.getSubscription().then((subscription) => {
$("#pushNotificationsUnsupported").hide(); vueApp.pushNotificationState = "supported";
pushNotificationsButton.prop("disabled", false).on("click", onPushButton);
clientSubscribed = !!subscription; clientSubscribed = !!subscription;
@ -69,9 +67,8 @@ module.exports.initialize = () => {
alternatePushButton(); alternatePushButton();
} }
}); });
}) }).catch(() => {
.catch((err) => { vueApp.pushNotificationState = "unsupported";
$("#pushNotificationsUnsupported span").text(err);
}); });
} }
}; };
@ -126,11 +123,7 @@ function onPushButton() {
}) })
) )
.catch((err) => { .catch((err) => {
$("#pushNotificationsUnsupported") vueApp.pushNotificationState = "unsupported";
.find("span")
.text(`An error has occurred: ${err}`)
.end()
.show();
}); });
return false; return false;