Add settings section to edit window options

This commit is contained in:
Samuel Elliott 2018-07-05 01:26:04 +01:00
parent f8f519e882
commit 55cd75b5f4
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
7 changed files with 223 additions and 8 deletions

View File

@ -65,6 +65,18 @@
"value": false
}
]
},
{
"id": "window-preferences",
"name": "Window Preferences",
"type": "drawer",
"settings": [
{
"id": "window-preferences",
"type": "custom",
"component": "WindowPreferences"
}
]
}
]
},

View File

@ -5,3 +5,4 @@
@import './tooltips.scss';
@import './settings-schemes.scss';
@import './updater.scss';
@import './window-preferences';

View File

@ -0,0 +1,5 @@
.bd-window-preferences {
.bd-window-preferences-disabled p {
color: #f6f6f7;
}
}

View File

@ -0,0 +1,192 @@
/**
* BetterDiscord Window Preferences Component
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
<template>
<div class="bd-window-preferences">
<div v-if="disabled" class="bd-form-item bd-window-preferences-disabled">
<p>You can't edit your window preferences here as you are using a JavaScript file to set window preferences.</p>
<FormButton @click="openFile">Open</FormButton>
<p class="bd-hint">This will open {{ filePath }} in your system's default editor.</p>
</div>
<div v-else-if="settingsSet" class="bd-form-item">
<component :is="SettingsPanel" :settings="settingsSet" />
<p class="bd-hint">You must fully restart Discord for changes here to take effect.</p>
<FormButton @click="restart">Restart</FormButton>
<FormButton @click="openFile">Open</FormButton>
<p class="bd-hint">This will open {{ filePath }} in your system's default editor.</p>
</div>
<div v-else>
<p>Loading...</p>
</div>
</div>
</template>
<script>
import { Globals } from 'modules';
import { SettingsSet } from 'structs';
import { Utils, FileUtils, ClientLogger as Logger } from 'common';
import path from 'path';
import { remote, shell } from 'electron';
import SettingsPanel from '../SettingsPanel.vue';
import { FormButton } from '../../common';
export default {
props: ['setting'],
data() {
return {
saved: {},
settingsSet: null,
disabled: false,
// TODO: fix recursive dependency somewhere
SettingsPanel
};
},
components: {
// SettingsPanel,
FormButton
},
computed: {
filePath() {
return Globals.require.resolve(path.join(Globals.getPath('data'), 'window'));
}
},
methods: {
openFile() {
return shell.openExternal('file://' + this.filePath);
},
restart() {
remote.app.relaunch();
remote.app.quit();
},
async listener(event) {
const newPreferences = Utils.deepclone(this.saved);
if (event.category.id === 'default' && event.setting.id === 'transparent') {
newPreferences.transparent = event.value;
if (event.value) delete newPreferences.backgroundColor;
}
if (event.category.id === 'default' && event.setting.id === 'background-colour') {
newPreferences.backgroundColor = event.value;
}
if (event.category.id === 'default' && event.setting.id === 'frame') {
newPreferences.frame = event.value;
}
if (event.category.id === 'advanced' && event.setting.id === 'experimental-features') {
if (!newPreferences.webPreferences) newPreferences.webPreferences = {};
newPreferences.webPreferences.experimentalFeatures = event.value;
}
if (event.category.id === 'advanced' && event.setting.id === 'preload') {
if (!newPreferences.webPreferences) newPreferences.webPreferences = {};
newPreferences.webPreferences.preload = event.value;
}
if (event.category.id === 'advanced' && event.setting.id === 'webview-tag') {
if (!newPreferences.webPreferences) newPreferences.webPreferences = {};
newPreferences.webPreferences.webviewTag = event.value;
}
try {
await FileUtils.writeJsonToFile(this.filePath, newPreferences, true);
await this.update();
} catch (err) {
Logger.err('WindowPreferences', ['Failed to update window preferences:', err]);
}
},
async update() {
this.saved = await FileUtils.readJsonFromFile(this.filePath) || {};
this.settingsSet.getSetting('default', 'transparent').value = this.saved.transparent;
this.settingsSet.getSetting('default', 'background-colour').value = this.saved.backgroundColor;
this.settingsSet.getSetting('default', 'frame').value = this.saved.frame;
this.settingsSet.getSetting('advanced', 'experimental-features').value = this.saved.webPreferences && this.saved.webPreferences.experimentalFeatures;
this.settingsSet.getSetting('advanced', 'preload').value = this.saved.webPreferences && this.saved.webPreferences.preload;
this.settingsSet.getSetting('advanced', 'webview-tag').value = this.saved.webPreferences && this.saved.webPreferences.webviewTag;
this.settingsSet.setSaved();
}
},
async created() {
if (this.filePath !== path.join(Globals.getPath('data'), 'window.json')) {
this.disabled = true;
return;
}
this.settingsSet = new SettingsSet({});
const category = await this.settingsSet.addCategory({id: 'default'});
await category.addSetting({
id: 'transparent',
type: 'bool',
text: 'Transparent',
hint: 'Removes the window background. This requires the background colour option to be disabled, and a theme to remove any higher backgrounds.'
});
await category.addSetting({
id: 'background-colour',
type: 'colour',
text: 'Background colour',
hint: 'Sets the background colour under any elements.'
});
await category.addSetting({
id: 'frame',
type: 'bool',
text: 'Frame',
hint: 'Shows the desktop environment\'s default window frame.'
});
const advanced = await this.settingsSet.addCategory({
id: 'advanced',
name: 'Advanced',
type: 'drawer'
});
await advanced.addSetting({
id: 'experimental-features',
type: 'bool',
text: 'Experimental features',
hint: 'Enables Chromium\'s experimental features.'
});
await advanced.addSetting({
id: 'preload',
type: 'text',
text: 'Preload script',
hint: 'The path of a JavaScript file relative to the BetterDiscord data directory to run before the window is loaded.'
});
await advanced.addSetting({
id: 'webview-tag',
type: 'bool',
text: 'Webview tag',
hint: 'Enables the webview tag. If you enable this you should use a preload script to restrict how the webview tag can be used.'
});
try {
await this.update();
} catch (err) {
Logger.err('WindowPreferences', ['Failed to read window preferences:', err]);
}
this.settingsSet.on('setting-updated', this.listener);
},
unmounted() {
if (this.settingsSet) this.settingsSet.removeListener('setting-updated', this.listener);
}
}
</script>

View File

@ -0,0 +1 @@
export { default as WindowPreferences } from './WindowPreferences.vue';

View File

@ -31,6 +31,7 @@
import SettingsPanel from '../SettingsPanel.vue';
import Drawer from '../../common/Drawer.vue';
import Button from '../../common/Button.vue';
import * as InternalSettings from '../internal-settings';
import path from 'path';
export default {
@ -41,12 +42,12 @@
},
computed: {
component() {
if (typeof this.setting.file === 'string') {
if (this.setting.path && typeof this.setting.file === 'string') {
const component = Globals.require(path.join(this.setting.path, this.setting.file));
return this.setting.component ? component[this.setting.component] : component.default ? component.default : component;
}
if (typeof this.setting.function === 'string') {
if (this.setting.path && typeof this.setting.function === 'string') {
const plugin = PluginManager.getPluginByPath(this.setting.path);
if (!plugin) return;
const component = plugin[this.setting.function](this.setting, this.change);
@ -55,16 +56,18 @@
return component;
}
if (typeof this.setting.component === 'string') {
if (this.setting.path && typeof this.setting.component === 'string') {
const plugin = PluginManager.getPluginByPath(this.setting.path);
if (!plugin) return;
const component = plugin[this.setting.component];
return component;
if (plugin && plugin[this.setting.component]) return plugin[this.setting.component];
}
if (typeof this.setting.component === 'object') {
return this.setting.component;
}
if (typeof this.setting.component === 'string' && InternalSettings[this.setting.component]) {
return InternalSettings[this.setting.component];
}
}
},
methods: {

View File

@ -345,10 +345,11 @@ export class FileUtils {
* Writes to a file as JSON.
* @param {String} path The file's path
* @param {Any} data The file's new contents
* @param {Boolean} pretty Whether to pretty print the JSON object
* @return {Promise}
*/
static async writeJsonToFile(path, json) {
return this.writeFile(path, JSON.stringify(json));
static async writeJsonToFile(path, json, pretty) {
return this.writeFile(path, JSON.stringify(json, null, pretty ? 4 : 0) + '\n');
}
/**