Add custom settings
This commit is contained in:
parent
5be5002ea1
commit
b9145b5b85
|
@ -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;
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -38,3 +38,13 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bd-form-customsetting {
|
||||
&.bd-form-customsetting-debug + .bd-form-divider {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
> .bd-drawer {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
@import './forms/index.scss';
|
||||
@import './material-buttons.scss';
|
||||
@import './drawers.scss';
|
||||
@import './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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
<template>
|
||||
<div class="bd-form-customsetting" :class="{'bd-form-customsetting-debug': setting.debug}">
|
||||
<component :is="component" :setting="setting" :change="change"></component>
|
||||
<Drawer class="bd-form-customsetting-value" label="Custom setting data" v-if="setting.debug">
|
||||
<pre class="bd-pre-wrap"><div class="bd-pre">{{ JSON.stringify(setting, null, 4) }}</div></pre>
|
||||
</Drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { PluginManager } from 'modules';
|
||||
import SettingsPanel from '../SettingsPanel.vue';
|
||||
import Drawer from '../../common/Drawer.vue';
|
||||
import path from 'path';
|
||||
|
||||
export default {
|
||||
props: ['setting', 'change'],
|
||||
components: {
|
||||
Drawer
|
||||
},
|
||||
computed: {
|
||||
component() {
|
||||
if (typeof this.setting.file === 'string') {
|
||||
const component = window.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') {
|
||||
const plugin = PluginManager.getPluginByPath(this.setting.path);
|
||||
if (!plugin) return;
|
||||
const component = plugin[this.setting.function](this.setting, this.change);
|
||||
if (component instanceof HTMLElement)
|
||||
return this.componentFromHTMLElement(component, this.setting, this.change);
|
||||
return component;
|
||||
}
|
||||
if (typeof this.setting.component === 'string') {
|
||||
const plugin = PluginManager.getPluginByPath(this.setting.path);
|
||||
if (!plugin) return;
|
||||
const component = plugin[this.setting.component];
|
||||
return component;
|
||||
}
|
||||
if (typeof this.setting.component === 'object') {
|
||||
return this.setting.component;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
componentFromHTMLElement(htmlelement, setting, change) {
|
||||
return {
|
||||
template: '<div></div>',
|
||||
props: ['setting', 'change'],
|
||||
mounted() {
|
||||
this.$el.appendChild(htmlelement);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -19,6 +19,7 @@
|
|||
<SliderSetting v-if="setting.type === 'slider'" :setting="setting" :change="change"/>
|
||||
<FileSetting v-if="setting.type === 'file'" :setting="setting" :change="change"/>
|
||||
<ArraySetting v-if="setting.type === 'array'" :setting="setting" :change="change" />
|
||||
<CustomSetting v-if="setting.type === 'custom'" :setting="setting" :change="change" />
|
||||
<div class="bd-form-divider"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -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() {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
module.exports.default = {
|
||||
template: "<div 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;\">Test custom setting {{ setting.id }}. This is from component.js in the plugin/theme's directory. (It can use functions.)</div>",
|
||||
props: ['setting', 'change']
|
||||
};
|
|
@ -194,6 +194,51 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"category": "custom-settings",
|
||||
"category_name": "Custom settings",
|
||||
"type": "drawer",
|
||||
"settings": [
|
||||
{
|
||||
"id": "custom-1",
|
||||
"type": "custom",
|
||||
"value": false,
|
||||
"component": {
|
||||
"template": "<div 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;\">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.) <button class=\"bd-button bd-button-primary\" style=\"display: inline-block; margin-left: 10px;\" @click=\"change(1)\">Set value to 1</button> <button class=\"bd-button bd-button-primary\" style=\"display: inline-block; margin-left: 10px;\" @click=\"change(2)\">Set value to 2</button></div>",
|
||||
"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",
|
||||
|
|
|
@ -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: "<div 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;\">Test custom setting {{ setting.id }}. This is from Plugin.settingscomponent.<br />Plugin ID: {{ plugin.id }}</div>",
|
||||
props: ['setting', 'change'],
|
||||
data() { return { plugin }; }
|
||||
};
|
||||
}
|
||||
|
||||
getSettingsComponent(setting, change) {
|
||||
return this._settingscomponent2 ? this._settingscomponent2 : this.settingscomponent2 = {
|
||||
template: "<div 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;\">Test custom setting {{ setting.id }}. This is from Plugin.getSettingsComponent().</div>",
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue