From b9145b5b85784d22144de191a0042047779be43d Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Wed, 21 Feb 2018 15:58:45 +0000 Subject: [PATCH] Add custom settings --- client/src/modules/contentmanager.js | 21 +++--- client/src/modules/plugin.js | 1 + .../src/styles/partials/generic/drawers.scss | 13 +++- .../styles/partials/generic/forms/main.scss | 10 +++ client/src/styles/partials/generic/index.scss | 1 + .../styles/partials/generic/preformatted.scss | 20 ++++++ client/src/ui/components/bd/setting/Array.vue | 2 + .../src/ui/components/bd/setting/Custom.vue | 68 +++++++++++++++++++ .../src/ui/components/bd/setting/Setting.vue | 5 +- tests/plugins/Example/component.js | 4 ++ tests/plugins/Example/config.json | 45 ++++++++++++ tests/plugins/Example/index.js | 38 +++++++++++ 12 files changed, 214 insertions(+), 14 deletions(-) create mode 100644 client/src/styles/partials/generic/preformatted.scss create mode 100644 client/src/ui/components/bd/setting/Custom.vue create mode 100644 tests/plugins/Example/component.js diff --git a/client/src/modules/contentmanager.js b/client/src/modules/contentmanager.js index f617389d..cdf89451 100644 --- a/client/src/modules/contentmanager.js +++ b/client/src/modules/contentmanager.js @@ -151,19 +151,20 @@ export default class { try { const readUserConfig = await this.readUserConfig(contentPath); userConfig.enabled = readUserConfig.enabled || false; - userConfig.config = readConfig.defaultConfig.map(config => { - const userSet = readUserConfig.config.find(c => c.category === config.category); + userConfig.config = readConfig.defaultConfig.map(category => { + let newCategory = readUserConfig.config.find(c => c.category === category.category); // return userSet || config; - if (!userSet) return config; + if (!newCategory) newCategory = {settings: []}; - config.settings = config.settings.map(setting => { - const userSetting = userSet.settings.find(s => s.id === setting.id); - if (!userSetting) return setting; + category.settings = category.settings.map(setting => { + if (setting.type === 'array' || setting.type === 'custom') setting.path = contentPath; + const newSetting = newCategory.settings.find(s => s.id === setting.id); + if (!newSetting) return setting; - setting.value = userSetting.value; + setting.value = newSetting.value; return setting; }); - return config; + return category; }); userConfig.css = readUserConfig.css || null; // userConfig.config = readUserConfig.config; @@ -175,13 +176,13 @@ export default class { defaultConfig: readConfig.defaultConfig, schemes: readConfig.configSchemes, userConfig - } + }; const paths = { contentPath, dirName, mainPath - } + }; const content = await this.loadContent(paths, configs, readConfig.info, readConfig.main, readConfig.dependencies); if (reload) this.localContent[index] = content; diff --git a/client/src/modules/plugin.js b/client/src/modules/plugin.js index 0a4aa768..9ada7016 100644 --- a/client/src/modules/plugin.js +++ b/client/src/modules/plugin.js @@ -56,6 +56,7 @@ export default class Plugin { get name() { return this.info.name } get authors() { return this.info.authors } get version() { return this.info.version } + get contentPath() { return this.paths.contentPath } get pluginPath() { return this.paths.contentPath } get dirName() { return this.paths.dirName } get enabled() { return this.userConfig.enabled } diff --git a/client/src/styles/partials/generic/drawers.scss b/client/src/styles/partials/generic/drawers.scss index b2854af7..0575e2cf 100644 --- a/client/src/styles/partials/generic/drawers.scss +++ b/client/src/styles/partials/generic/drawers.scss @@ -1,7 +1,14 @@ .bd-drawer { - border-bottom: 1px solid rgba(114, 118, 126, 0.3); margin-bottom: 15px; + .bd-settings-category > & { + border-bottom: 1px solid rgba(114, 118, 126, 0.3); + + .bd-drawer-contents > .bd-form-item:last-child > .bd-form-divider:last-child { + display: none; + } + } + .bd-form-header { margin-top: 0; cursor: pointer; @@ -44,7 +51,7 @@ } &.bd-drawer-open { - .bd-drawer-open-button { + > .bd-drawer-header .bd-drawer-open-button { .bd-chevron-1 { svg { transform: rotate(90deg) @@ -59,7 +66,7 @@ } } - .bd-drawer-contents { + > .bd-drawer-contents-wrap > .bd-drawer-contents { transform: scaleY(1) translateY(0%); margin-top: 0%; opacity: 1; diff --git a/client/src/styles/partials/generic/forms/main.scss b/client/src/styles/partials/generic/forms/main.scss index efb9bc1a..b4a2627c 100644 --- a/client/src/styles/partials/generic/forms/main.scss +++ b/client/src/styles/partials/generic/forms/main.scss @@ -38,3 +38,13 @@ } } } + +.bd-form-customsetting { + &.bd-form-customsetting-debug + .bd-form-divider { + margin-top: 0; + } + + > .bd-drawer { + margin-bottom: 0; + } +} diff --git a/client/src/styles/partials/generic/index.scss b/client/src/styles/partials/generic/index.scss index db30a069..e3614c84 100644 --- a/client/src/styles/partials/generic/index.scss +++ b/client/src/styles/partials/generic/index.scss @@ -6,3 +6,4 @@ @import './forms/index.scss'; @import './material-buttons.scss'; @import './drawers.scss'; +@import './preformatted.scss'; diff --git a/client/src/styles/partials/generic/preformatted.scss b/client/src/styles/partials/generic/preformatted.scss new file mode 100644 index 00000000..0581c294 --- /dev/null +++ b/client/src/styles/partials/generic/preformatted.scss @@ -0,0 +1,20 @@ +.bd-pre-wrap { + background: rgba(0, 0, 0, 0.1); + border: 1px solid rgba(0, 0, 0, 0.3); + border-radius: 3px; + color: #b9bbbe; + white-space: pre-wrap; + font-family: monospace; + overflow-y: auto; + + &:focus { + color: #fff; + border-color: #040405; + } + + @include scrollbar; +} + +.bd-pre { + padding: 11px; +} diff --git a/client/src/ui/components/bd/setting/Array.vue b/client/src/ui/components/bd/setting/Array.vue index 4ccb8a5c..ee533255 100644 --- a/client/src/ui/components/bd/setting/Array.vue +++ b/client/src/ui/components/bd/setting/Array.vue @@ -104,8 +104,10 @@ for (let newCategory of newSettings) { const category = settings.find(c => c.category === newCategory.category); + if (!category) continue; for (let newSetting of newCategory.settings) { const setting = category.settings.find(s => s.id === newSetting.id); + if (!setting) continue; setting.value = setting.old_value = newSetting.value; setting.changed = false; } diff --git a/client/src/ui/components/bd/setting/Custom.vue b/client/src/ui/components/bd/setting/Custom.vue new file mode 100644 index 00000000..7fee204f --- /dev/null +++ b/client/src/ui/components/bd/setting/Custom.vue @@ -0,0 +1,68 @@ +/** + * BetterDiscord Custom Setting 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. +*/ + + + + diff --git a/client/src/ui/components/bd/setting/Setting.vue b/client/src/ui/components/bd/setting/Setting.vue index 753ea17a..1008908b 100644 --- a/client/src/ui/components/bd/setting/Setting.vue +++ b/client/src/ui/components/bd/setting/Setting.vue @@ -19,6 +19,7 @@ +
@@ -33,6 +34,7 @@ import SliderSetting from './Slider.vue'; import FileSetting from './File.vue'; import ArraySetting from './Array.vue'; + import CustomSetting from './Custom.vue'; export default { props: [ @@ -48,7 +50,8 @@ MultilineTextSetting, SliderSetting, FileSetting, - ArraySetting + ArraySetting, + CustomSetting }, computed: { changed() { diff --git a/tests/plugins/Example/component.js b/tests/plugins/Example/component.js new file mode 100644 index 00000000..c82c1359 --- /dev/null +++ b/tests/plugins/Example/component.js @@ -0,0 +1,4 @@ +module.exports.default = { + template: "
Test custom setting {{ setting.id }}. This is from component.js in the plugin/theme's directory. (It can use functions.)
", + props: ['setting', 'change'] +}; diff --git a/tests/plugins/Example/config.json b/tests/plugins/Example/config.json index 25ca74e5..b32022b0 100644 --- a/tests/plugins/Example/config.json +++ b/tests/plugins/Example/config.json @@ -194,6 +194,51 @@ } ] }, + { + "category": "custom-settings", + "category_name": "Custom settings", + "type": "drawer", + "settings": [ + { + "id": "custom-1", + "type": "custom", + "value": false, + "component": { + "template": "
Test custom setting {{ setting.id }}. This is included inline with the plugin/theme's config. (Which means it can't use any functions, but can still bind functions to events.)
", + "props": [ + "setting", + "change" + ] + }, + "debug": true + }, + { + "id": "custom-2", + "type": "custom", + "value": false, + "file": "component.js" + }, + { + "id": "custom-3", + "type": "custom", + "value": false, + "component": "settingscomponent" + }, + { + "id": "custom-4", + "type": "custom", + "value": false, + "function": "getSettingsComponent" + }, + { + "id": "custom-5", + "type": "custom", + "value": false, + "function": "getSettingsComponentHTMLElement", + "debug": true + } + ] + }, { "category_header_comment": "Setting a category other than default has a header with category name as the text", "category": "test-category", diff --git a/tests/plugins/Example/index.js b/tests/plugins/Example/index.js index 74042970..c1aef744 100644 --- a/tests/plugins/Example/index.js +++ b/tests/plugins/Example/index.js @@ -56,6 +56,44 @@ module.exports = (Plugin, Api, Vendor, Dependencies) => { if (!this.enabled) return; Logger.log([ 'Settings updated', settings ]); } + + get settingscomponent() { + const plugin = this; + return this._settingscomponent ? this._settingscomponent : this._settingscomponent = { + template: "
Test custom setting {{ setting.id }}. This is from Plugin.settingscomponent.
Plugin ID: {{ plugin.id }}
", + props: ['setting', 'change'], + data() { return { plugin }; } + }; + } + + getSettingsComponent(setting, change) { + return this._settingscomponent2 ? this._settingscomponent2 : this.settingscomponent2 = { + template: "
Test custom setting {{ setting.id }}. This is from Plugin.getSettingsComponent().
", + props: ['setting', 'change'] + }; + } + + getSettingsComponentHTMLElement(setting, change) { + const el = document.createElement('div'); + el.setAttribute('style', 'margin-bottom: 15px; background-color: rgba(0, 0, 0, 0.2); border: 1px dashed rgba(255, 255, 255, 0.2); padding: 10px; color: #f6f6f7; font-weight: 500; font-size: 15px;'); + el.textContent = `Test custom setting ${setting.id}. This is from Plugin.getSettingsComponentHTMLElement(). Current value: ${setting.value}.`; + + const button1 = document.createElement('button'); + button1.setAttribute('class', 'bd-button bd-button-primary'); + button1.setAttribute('style', 'display: inline-block; margin-left: 10px;'); + button1.addEventListener('click', () => change(1)); + button1.textContent = 'Set value to 1'; + el.appendChild(button1); + + const button2 = document.createElement('button'); + button2.setAttribute('class', 'bd-button bd-button-primary'); + button2.setAttribute('style', 'display: inline-block; margin-left: 10px;'); + button2.addEventListener('click', () => change(2)); + button2.textContent = 'Set value to 2'; + el.appendChild(button2); + + return el; + } } }