From 1bded3121e20726310f37a85befbffd89af4d680 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Tue, 13 Feb 2018 22:18:09 +0000 Subject: [PATCH 01/15] Add event structs --- client/src/structs/events/event.js | 28 +++++++++++++++ client/src/structs/events/index.js | 1 + client/src/structs/events/settingupdated.js | 39 +++++++++++++++++++++ client/src/structs/structs.js | 1 + 4 files changed, 69 insertions(+) create mode 100644 client/src/structs/events/event.js create mode 100644 client/src/structs/events/index.js create mode 100644 client/src/structs/events/settingupdated.js diff --git a/client/src/structs/events/event.js b/client/src/structs/events/event.js new file mode 100644 index 00000000..8b33372c --- /dev/null +++ b/client/src/structs/events/event.js @@ -0,0 +1,28 @@ +/** + * BetterDiscord Base Event Struct + * 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. +*/ + +export default class Event { + + constructor(args) { + this.args = args; + + this.__eventInfo = { + args: arguments, + type: this.__eventType + }; + } + + get event() { + return this.__eventInfo; + } + + get __eventType() { return null; } + +} diff --git a/client/src/structs/events/index.js b/client/src/structs/events/index.js new file mode 100644 index 00000000..287f7741 --- /dev/null +++ b/client/src/structs/events/index.js @@ -0,0 +1 @@ +export { default as SettingUpdatedEvent } from './settingupdated'; diff --git a/client/src/structs/events/settingupdated.js b/client/src/structs/events/settingupdated.js new file mode 100644 index 00000000..0cc8ea08 --- /dev/null +++ b/client/src/structs/events/settingupdated.js @@ -0,0 +1,39 @@ +/** + * BetterDiscord Setting Updated Event Struct + * 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. +*/ + +import Event from './event'; + +export default class SettingUpdatedEvent extends Event { + + get set() { + return this.args.set_id; + } + + get category() { + return this.args.category_id; + } + + get setting() { + return this.args.setting_id; + } + + get value() { + return this.args.value; + } + + get old_value() { + return this.args.old_value; + } + + get __eventType() { + return 'setting-updated'; + } + +} diff --git a/client/src/structs/structs.js b/client/src/structs/structs.js index 93ae819e..4e35157f 100644 --- a/client/src/structs/structs.js +++ b/client/src/structs/structs.js @@ -1 +1,2 @@ export * from './error'; +export * from './events/index'; From 79af725f7f33c70ebf715dd4a16129cf27ab844b Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Tue, 13 Feb 2018 22:28:58 +0000 Subject: [PATCH 02/15] Move error event struct --- client/src/modules/contentmanager.js | 4 ++-- client/src/structs/{ => events}/error.js | 10 ++++++---- client/src/structs/events/event.js | 6 ++++-- client/src/structs/events/index.js | 1 + client/src/structs/structs.js | 1 - client/src/ui/components/bd/modals/ErrorModal.vue | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) rename client/src/structs/{ => events}/error.js (81%) diff --git a/client/src/modules/contentmanager.js b/client/src/modules/contentmanager.js index a4835847..d7069696 100644 --- a/client/src/modules/contentmanager.js +++ b/client/src/modules/contentmanager.js @@ -12,7 +12,7 @@ import Globals from './globals'; import { FileUtils, ClientLogger as Logger } from 'common'; import path from 'path'; import { Events } from 'modules'; -import { Error } from 'structs'; +import { ErrorEvent } from 'structs'; import { Modals } from 'ui'; export default class { @@ -38,7 +38,7 @@ export default class { try { await this.preloadContent(dir); } catch (err) { - this.errors.push(new Error({ + this.errors.push(new ErrorEvent({ module: this.moduleName, message: `Failed to load ${dir}`, err diff --git a/client/src/structs/error.js b/client/src/structs/events/error.js similarity index 81% rename from client/src/structs/error.js rename to client/src/structs/events/error.js index df6a8c16..04f8bf8f 100644 --- a/client/src/structs/error.js +++ b/client/src/structs/events/error.js @@ -8,10 +8,12 @@ * LICENSE file in the root directory of this source tree. */ -export class Error { +import Event from './event'; + +export default class ErrorEvent extends Event { constructor(args) { - this.args = args; + super(args); this.showStack = false; // For error modal } @@ -31,8 +33,8 @@ export class Error { return this.err.stack; } - get _type() { - return 'err'; + get __eventType() { + return 'error'; } } diff --git a/client/src/structs/events/event.js b/client/src/structs/events/event.js index 8b33372c..1159910e 100644 --- a/client/src/structs/events/event.js +++ b/client/src/structs/events/event.js @@ -11,8 +11,6 @@ export default class Event { constructor(args) { - this.args = args; - this.__eventInfo = { args: arguments, type: this.__eventType @@ -23,6 +21,10 @@ export default class Event { return this.__eventInfo; } + get args() { + return this.event.args[0]; + } + get __eventType() { return null; } } diff --git a/client/src/structs/events/index.js b/client/src/structs/events/index.js index 287f7741..354e4192 100644 --- a/client/src/structs/events/index.js +++ b/client/src/structs/events/index.js @@ -1 +1,2 @@ export { default as SettingUpdatedEvent } from './settingupdated'; +export { default as ErrorEvent } from './error'; diff --git a/client/src/structs/structs.js b/client/src/structs/structs.js index 4e35157f..4042b56e 100644 --- a/client/src/structs/structs.js +++ b/client/src/structs/structs.js @@ -1,2 +1 @@ -export * from './error'; export * from './events/index'; diff --git a/client/src/ui/components/bd/modals/ErrorModal.vue b/client/src/ui/components/bd/modals/ErrorModal.vue index 8764248b..dec525ea 100644 --- a/client/src/ui/components/bd/modals/ErrorModal.vue +++ b/client/src/ui/components/bd/modals/ErrorModal.vue @@ -4,7 +4,7 @@
-
+
{{content.message}} Hide Stacktrace From 8b85c829d67d30b6ecf7d8745a15f8decf210a4e Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Tue, 13 Feb 2018 22:30:58 +0000 Subject: [PATCH 03/15] Add setting updated event --- client/src/modules/settings.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/client/src/modules/settings.js b/client/src/modules/settings.js index 872ce3e4..7671f6d6 100644 --- a/client/src/modules/settings.js +++ b/client/src/modules/settings.js @@ -11,7 +11,9 @@ import defaultSettings from '../data/user.settings.default'; import Globals from './globals'; import CssEditor from './csseditor'; +import Events from './events'; import { FileUtils, ClientLogger as Logger } from 'common'; +import { SettingUpdatedEvent } from 'structs'; import path from 'path'; export default class { @@ -122,8 +124,9 @@ export default class { if (setting.id !== setting_id) continue; if (setting.value === value) return true; + let old_value = setting.value; setting.value = value; - this.settingUpdated(set_id, category_id, setting_id, value); + this.settingUpdated(set_id, category_id, setting_id, value, old_value); return true; } } @@ -132,8 +135,12 @@ export default class { return false; } - static settingUpdated(set_id, category_id, setting_id, value) { - Logger.log('Settings', `${set_id}/${category_id}/${setting_id} was set to ${value}`); + static settingUpdated(set_id, category_id, setting_id, value, old_value) { + Logger.log('Settings', `${set_id}/${category_id}/${setting_id} was changed from ${old_value} to ${value}`); + + const event = new SettingUpdatedEvent({ set_id, category_id, setting_id, value, old_value }); + Events.emit('setting-updated', event); + Events.emit(`setting-updated-${set_id}_{$category_id}_${setting_id}`, event); } static get getSettings() { From 210d085caf9c578fce11aa8457ca93f55005c82a Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Tue, 13 Feb 2018 22:33:17 +0000 Subject: [PATCH 04/15] =?UTF-8?q?Fix=20=E2=80=9Ccannot=20read=20property?= =?UTF-8?q?=20=E2=80=98width=E2=80=99=20of=20undefined=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/modules/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/modules/settings.js b/client/src/modules/settings.js index 7671f6d6..16c6e64e 100644 --- a/client/src/modules/settings.js +++ b/client/src/modules/settings.js @@ -45,7 +45,7 @@ export default class { } CssEditor.updateScss(scss, true); - CssEditor.editor_bounds = css_editor_bounds; + CssEditor.editor_bounds = css_editor_bounds || {}; } catch (err) { // There was an error loading settings // This probably means that the user doesn't have any settings yet From 9b9162346b195427ca364df042086c17d332b3e4 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Tue, 13 Feb 2018 22:37:24 +0000 Subject: [PATCH 05/15] Add internal settings access to the plugin API --- client/src/modules/pluginapi.js | 10 ++++++++++ tests/plugins/Example/index.js | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/client/src/modules/pluginapi.js b/client/src/modules/pluginapi.js index c62e142b..0ebc547f 100644 --- a/client/src/modules/pluginapi.js +++ b/client/src/modules/pluginapi.js @@ -9,6 +9,7 @@ */ import { ClientLogger as Logger } from 'common'; +import Settings from './settings'; import PluginManager from './pluginmanager'; import ThemeManager from './thememanager'; import Events from './events'; @@ -66,6 +67,15 @@ export default class PluginApi { } } + getSetting(set, category, setting) { + return Settings.get(set, category, setting); + } + get Settings() { + return { + get: this.getSetting.bind(this) + }; + } + async getPlugin(plugin_id) { // This should require extra permissions return await PluginManager.waitForPlugin(plugin_id); diff --git a/tests/plugins/Example/index.js b/tests/plugins/Example/index.js index 832e106b..ee5fb848 100644 --- a/tests/plugins/Example/index.js +++ b/tests/plugins/Example/index.js @@ -7,7 +7,12 @@ module.exports = (Plugin, Api, Vendor) => { onStart() { Events.subscribe('TEST_EVENT', this.eventTest); Logger.log('onStart'); - Logger.log(`Setting "default-0" value: ${this.getSetting('default-0')}`); + Logger.log(`Plugin setting "default-0" value: ${this.getSetting('default-0')}`); + Logger.log(`Internal setting "core/default/test-setting" value: ${Api.Settings.get('core', 'default', 'test-setting')}`); + + Events.subscribe('setting-updated', setting => { + console.log('Received internal setting update:', setting); + }); const exampleModule = new (Api.import('Example Module')); Logger.log(`2+4=${exampleModule.add(2, 4)}`); From 08271deea1c814bdfec441d0c69d0a034d4972cc Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Tue, 13 Feb 2018 23:23:52 +0000 Subject: [PATCH 06/15] Add plugin settings events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Moved the Theme class to it’s own file --- client/src/modules/contentmanager.js | 6 +- client/src/modules/extmodule.js | 23 ++- client/src/modules/extmodulemanager.js | 3 +- client/src/modules/plugin.js | 58 +++++-- client/src/modules/pluginmanager.js | 7 +- client/src/modules/theme.js | 166 +++++++++++++++++++ client/src/modules/thememanager.js | 122 +------------- client/src/structs/events/index.js | 1 + client/src/structs/events/settingsupdated.js | 23 +++ tests/plugins/Example/index.js | 15 +- 10 files changed, 278 insertions(+), 146 deletions(-) create mode 100644 client/src/modules/theme.js create mode 100644 client/src/structs/events/settingsupdated.js diff --git a/client/src/modules/contentmanager.js b/client/src/modules/contentmanager.js index d7069696..aaebcb10 100644 --- a/client/src/modules/contentmanager.js +++ b/client/src/modules/contentmanager.js @@ -29,7 +29,7 @@ export default class { return this._contentPath ? this._contentPath : (this._contentPath = Globals.getObject('paths').find(path => path.id === this.pathId).path); } - static async loadAllContent(supressErrors) { + static async loadAllContent(suppressErrors) { try { await FileUtils.ensureDirectory(this.contentPath); const directories = await FileUtils.listDirectory(this.contentPath); @@ -48,7 +48,7 @@ export default class { } } - if (this.errors.length && !supressErrors) { + if (this.errors.length && !suppressErrors) { Modals.error({ header: `${this.moduleName} - ${this.errors.length} ${this.contentType}${this.errors.length !== 1 ? 's' : ''} failed to load`, module: this.moduleName, @@ -154,7 +154,7 @@ export default class { mainPath } - const content = await this.loadContent(paths, configs, readConfig.info, readConfig.main, readConfig.type); + const content = await this.loadContent(paths, configs, readConfig.info, readConfig.main); if (reload) this.localContent[index] = content; else this.localContent.push(content); return content; diff --git a/client/src/modules/extmodule.js b/client/src/modules/extmodule.js index 7973037f..47081ac3 100644 --- a/client/src/modules/extmodule.js +++ b/client/src/modules/extmodule.js @@ -8,6 +8,25 @@ * LICENSE file in the root directory of this source tree. */ +class ExtModuleEvents { + constructor(extmodule) { + this.extmodule = extmodule; + this.emitter = new EventEmitter(); + } + + on(eventname, callback) { + this.emitter.on(eventname, callback); + } + + off(eventname, callback) { + this.emitter.removeListener(eventname, callback); + } + + emit(...args) { + this.emitter.emit(...args); + } +} + export default class ExtModule { constructor(pluginInternals) { @@ -31,5 +50,7 @@ export default class ExtModule { get pluginPath() { return this.paths.contentPath } get dirName() { return this.paths.dirName } get enabled() { return true } - get pluginConfig() { return this.userConfig.config || [] } + get config() { return this.userConfig.config || [] } + get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new ExtModuleEvents(this)) } + } diff --git a/client/src/modules/extmodulemanager.js b/client/src/modules/extmodulemanager.js index a9e0f8fe..1edbea1c 100644 --- a/client/src/modules/extmodulemanager.js +++ b/client/src/modules/extmodulemanager.js @@ -38,11 +38,10 @@ export default class extends ContentManager { static get refreshModules() { return this.refreshContent } static get loadContent() { return this.loadModule } - static async loadModule(paths, configs, info, main, type) { + static async loadModule(paths, configs, info, main) { return new ExtModule({ configs, info, main, paths: { contentPath: paths.contentPath, dirName: paths.dirName, mainPath: paths.mainPath } }); } - static get findModule() { return this.findContent } static get getModuleIndex() { return this.getContentIndex } static get getModuleByName() { return this.getContentByName } diff --git a/client/src/modules/plugin.js b/client/src/modules/plugin.js index 9ce047fd..c4ae5c9d 100644 --- a/client/src/modules/plugin.js +++ b/client/src/modules/plugin.js @@ -10,6 +10,27 @@ import { FileUtils } from 'common'; import { Modals } from 'ui'; +import { EventEmitter } from 'events'; +import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs'; + +class PluginEvents { + constructor(plugin) { + this.plugin = plugin; + this.emitter = new EventEmitter(); + } + + on(eventname, callback) { + this.emitter.on(eventname, callback); + } + + off(eventname, callback) { + this.emitter.removeListener(eventname, callback); + } + + emit(...args) { + this.emitter.emit(...args); + } +} export default class Plugin { @@ -29,15 +50,17 @@ export default class Plugin { get main() { return this.__pluginInternals.main } get defaultConfig() { return this.configs.defaultConfig } get userConfig() { return this.configs.userConfig } - get id() { return this.info.id || this.info.name.replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-') } + get id() { return this.info.id || this.name.replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-') } get name() { return this.info.name } get authors() { return this.info.authors } get version() { return this.info.version } get pluginPath() { return this.paths.contentPath } get dirName() { return this.paths.dirName } get enabled() { return this.userConfig.enabled } - get pluginConfig() { return this.userConfig.config || [] } + get config() { return this.userConfig.config || [] } + get pluginConfig() { return this.config } get exports() { return this._exports ? this._exports : (this._exports = this.getExports()) } + get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new PluginEvents(this)) } getSetting(setting_id, category_id) { for (let category of this.pluginConfig) { @@ -54,21 +77,34 @@ export default class Plugin { } async saveSettings(newSettings) { - for (let category of newSettings) { - const oldCategory = this.pluginConfig.find(c => c.category === category.category); - for (let setting of category.settings) { - const oldSetting = oldCategory.settings.find(s => s.id === setting.id); - if (oldSetting.value === setting.value) continue; - oldSetting.value = setting.value; - if (this.settingChanged) this.settingChanged(category.category, setting.id, setting.value); + const updatedSettings = []; + + for (let newCategory of newSettings) { + const category = this.pluginConfig.find(c => c.category === newCategory.category); + for (let newSetting of newCategory.settings) { + const setting = category.settings.find(s => s.id === newSetting.id); + if (setting.value === newSetting.value) continue; + + let old_value = setting.value; + setting.value = newSetting.value; + updatedSettings.push({ category_id: category.category, setting_id: setting.id, value: setting.value, old_value }); + this.settingUpdated(category.category, setting.id, setting.value, old_value); } } this.saveConfiguration(); + return this.settingsUpdated(updatedSettings); + } - if (this.settingsChanged) this.settingsChanged(this.pluginConfig); + settingUpdated(category_id, setting_id, value, old_value) { + const event = new SettingUpdatedEvent({ category_id, setting_id, value, old_value }); + this.events.emit('setting-updated', event); + this.events.emit(`setting-updated_{$category_id}_${setting_id}`, event); + } - return this.pluginConfig; + settingsUpdated(updatedSettings) { + const event = new SettingsUpdatedEvent({ settings: updatedSettings.map(s => new SettingUpdatedEvent(s)) }); + this.events.emit('settings-updated', event); } async saveConfiguration() { diff --git a/client/src/modules/pluginmanager.js b/client/src/modules/pluginmanager.js index 4b3416a5..6c99634f 100644 --- a/client/src/modules/pluginmanager.js +++ b/client/src/modules/pluginmanager.js @@ -15,7 +15,6 @@ import Vendor from './vendor'; import { ClientLogger as Logger } from 'common'; import { Events } from 'modules'; - export default class extends ContentManager { static get localPlugins() { @@ -34,8 +33,8 @@ export default class extends ContentManager { return 'plugins'; } - static async loadAllPlugins(supressErrors) { - const loadAll = await this.loadAllContent(supressErrors); + static async loadAllPlugins(suppressErrors) { + const loadAll = await this.loadAllContent(suppressErrors); this.localPlugins.forEach(plugin => { if (plugin.enabled) plugin.start(); }); @@ -45,7 +44,7 @@ export default class extends ContentManager { static get refreshPlugins() { return this.refreshContent } static get loadContent() { return this.loadPlugin } - static async loadPlugin(paths, configs, info, main, type) { + static async loadPlugin(paths, configs, info, main) { const plugin = window.require(paths.mainPath)(Plugin, new PluginApi(info), Vendor); const instance = new plugin({ configs, info, main, paths: { contentPath: paths.contentPath, dirName: paths.dirName, mainPath: paths.mainPath } }); return instance; diff --git a/client/src/modules/theme.js b/client/src/modules/theme.js new file mode 100644 index 00000000..a80c3c7e --- /dev/null +++ b/client/src/modules/theme.js @@ -0,0 +1,166 @@ +/** + * BetterDiscord Theme Module + * 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. +*/ + +import ThemeManager from './thememanager'; +import { DOM, Modals } from 'ui'; +import { FileUtils, ClientIPC } from 'common'; + +class ThemeEvents { + constructor(theme) { + this.theme = theme; + this.emitter = new EventEmitter(); + } + + on(eventname, callback) { + this.emitter.on(eventname, callback); + } + + off(eventname, callback) { + this.emitter.removeListener(eventname, callback); + } + + emit(...args) { + this.emitter.emit(...args); + } +} + +export default class Theme { + + constructor(themeInternals) { + this.__themeInternals = themeInternals; + this.hasSettings = this.themeConfig && this.themeConfig.length > 0; + this.saveSettings = this.saveSettings.bind(this); + this.enable = this.enable.bind(this); + this.disable = this.disable.bind(this); + } + + get configs() { return this.__themeInternals.configs } + get info() { return this.__themeInternals.info } + get icon() { return this.info.icon } + get paths() { return this.__themeInternals.paths } + get main() { return this.__themeInternals.main } + get defaultConfig() { return this.configs.defaultConfig } + get userConfig() { return this.configs.userConfig } + get id() { return this.info.id || this.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/\s+/g, '-') } + get name() { return this.info.name } + get authors() { return this.info.authors } + get version() { return this.info.version } + get themePath() { return this.paths.contentPath } + get dirName() { return this.paths.dirName } + get enabled() { return this.userConfig.enabled } + get config() { return this.userConfig.config || [] } + get themeConfig() { return this.config } + get css() { return this.userConfig.css } + get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new ThemeEvents(this)) } + + showSettingsModal() { + return Modals.themeSettings(this); + } + + async saveSettings(newSettings) { + const updatedSettings = []; + + for (let newCategory of newSettings) { + const category = this.pluginConfig.find(c => c.category === newCategory.category); + for (let newSetting of newCategory.settings) { + const setting = category.settings.find(s => s.id === newSetting.id); + if (setting.value === newSetting.value) continue; + + let old_value = setting.value; + setting.value = newSetting.value; + updatedSettings.push({ category_id: category.category, setting_id: setting.id, value: setting.value, old_value }); + this.settingUpdated(category.category, setting.id, setting.value, old_value); + } + } + + // As the theme's configuration has changed it needs recompiling + // When the compiled CSS has been save it will also save the configuration + await this.recompile(); + + return this.settingsUpdated(updatedSettings); + } + + settingUpdated(category_id, setting_id, value, old_value) { + const event = new SettingUpdatedEvent({ category_id, setting_id, value, old_value }); + this.events.emit('setting-updated', event); + this.events.emit(`setting-updated_{$category_id}_${setting_id}`, event); + } + + settingsUpdated(updatedSettings) { + const event = new SettingsUpdatedEvent({ settings: updatedSettings.map(s => new SettingUpdatedEvent(s)) }); + this.events.emit('settings-updated', event); + } + + async saveConfiguration() { + try { + await FileUtils.writeFile(`${this.themePath}/user.config.json`, JSON.stringify({ + enabled: this.enabled, + config: this.themeConfig.map(category => { + return { + category: category.category, + settings: category.settings.map(setting => { + return { + id: setting.id, + value: setting.value + }; + }) + }; + }), + css: this.css + })); + } catch (err) { + throw err; + } + } + + enable() { + if (!this.enabled) { + this.userConfig.enabled = true; + this.saveConfiguration(); + } + DOM.injectTheme(this.css, this.id); + } + + disable() { + this.userConfig.enabled = false; + this.saveConfiguration(); + DOM.deleteTheme(this.id); + } + + async compile() { + console.log('Compiling CSS'); + + let css = ''; + if (this.info.type === 'sass') { + css = await ClientIPC.send('bd-compileSass', { + data: ThemeManager.getConfigAsSCSS(this.themeConfig), + path: this.paths.mainPath.replace(/\\/g, '/') + }); + console.log(css); + } else { + css = await FileUtils.readFile(this.paths.mainPath); + } + + return css; + } + + async recompile() { + const css = await this.compile(); + this.userConfig.css = css; + + await this.saveConfiguration(); + + if (this.enabled) { + DOM.deleteTheme(this.id); + DOM.injectTheme(this.css, this.id); + } + } + +} diff --git a/client/src/modules/thememanager.js b/client/src/modules/thememanager.js index 1b9bf2c6..669b23c3 100644 --- a/client/src/modules/thememanager.js +++ b/client/src/modules/thememanager.js @@ -9,126 +9,7 @@ */ import ContentManager from './contentmanager'; -import { DOM, Modals } from 'ui'; -import { FileUtils, ClientIPC } from 'common'; - -class Theme { - - constructor(themeInternals) { - this.__themeInternals = themeInternals; - this.hasSettings = this.themeConfig && this.themeConfig.length > 0; - this.saveSettings = this.saveSettings.bind(this); - this.enable = this.enable.bind(this); - this.disable = this.disable.bind(this); - } - - get configs() { return this.__themeInternals.configs } - get info() { return this.__themeInternals.info } - get icon() { return this.info.icon } - get paths() { return this.__themeInternals.paths } - get main() { return this.__themeInternals.main } - get defaultConfig() { return this.configs.defaultConfig } - get userConfig() { return this.configs.userConfig } - get name() { return this.info.name } - get authors() { return this.info.authors } - get version() { return this.info.version } - get themePath() { return this.paths.contentPath } - get dirName() { return this.paths.dirName } - get enabled() { return this.userConfig.enabled } - get themeConfig() { return this.userConfig.config } - get css() { return this.userConfig.css } - get id() { return this.name.toLowerCase().replace(/\s+/g, '-') } - - showSettingsModal() { - return Modals.themeSettings(this); - } - - async saveSettings(newSettings) { - for (let category of newSettings) { - const oldCategory = this.themeConfig.find(c => c.category === category.category); - for (let setting of category.settings) { - const oldSetting = oldCategory.settings.find(s => s.id === setting.id); - if (oldSetting.value === setting.value) continue; - oldSetting.value = setting.value; - if (this.settingChanged) this.settingChanged(category.category, setting.id, setting.value); - } - } - - // As the theme's configuration has changed it needs recompiling - // When the compiled CSS has been save it will also save the configuration - await this.recompile(); - - if (this.settingsChanged) this.settingsChanged(this.themeConfig); - - return this.pluginConfig; - } - - async saveConfiguration() { - try { - await FileUtils.writeFile(`${this.themePath}/user.config.json`, JSON.stringify({ - enabled: this.enabled, - config: this.themeConfig.map(category => { - return { - category: category.category, - settings: category.settings.map(setting => { - return { - id: setting.id, - value: setting.value - }; - }) - }; - }), - css: this.css - })); - } catch (err) { - throw err; - } - } - - enable() { - if (!this.enabled) { - this.userConfig.enabled = true; - this.saveConfiguration(); - } - DOM.injectTheme(this.css, this.id); - } - - disable() { - this.userConfig.enabled = false; - this.saveConfiguration(); - DOM.deleteTheme(this.id); - } - - async compile() { - console.log('Compiling CSS'); - - let css = ''; - if (this.info.type === 'sass') { - css = await ClientIPC.send('bd-compileSass', { - data: ThemeManager.getConfigAsSCSS(this.themeConfig), - path: this.paths.mainPath.replace(/\\/g, '/') - }); - console.log(css); - } else { - css = await FileUtils.readFile(this.paths.mainPath); - } - - return css; - } - - async recompile() { - const css = await this.compile(); - this.userConfig.css = css; - - await this.saveConfiguration(); - - if (this.enabled) { - DOM.deleteTheme(this.id); - DOM.injectTheme(this.css, this.id); - } - } - -} +import Theme from './theme'; export default class ThemeManager extends ContentManager { @@ -213,7 +94,6 @@ export default class ThemeManager extends ContentManager { if (typeof value === 'string') { return `$${name}: ${setting.scss_raw ? value : `'${setting.value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'')}'`};`; } - } } diff --git a/client/src/structs/events/index.js b/client/src/structs/events/index.js index 354e4192..f10d1e35 100644 --- a/client/src/structs/events/index.js +++ b/client/src/structs/events/index.js @@ -1,2 +1,3 @@ export { default as SettingUpdatedEvent } from './settingupdated'; +export { default as SettingsUpdatedEvent } from './settingsupdated'; export { default as ErrorEvent } from './error'; diff --git a/client/src/structs/events/settingsupdated.js b/client/src/structs/events/settingsupdated.js new file mode 100644 index 00000000..99470ea7 --- /dev/null +++ b/client/src/structs/events/settingsupdated.js @@ -0,0 +1,23 @@ +/** + * BetterDiscord Settings Updated Event Struct + * 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. +*/ + +import Event from './event'; + +export default class SettingsUpdatedEvent extends Event { + + get updatedSettings() { + return this.args.updatedSettings; + } + + get __eventType() { + return 'settings-updated'; + } + +} diff --git a/tests/plugins/Example/index.js b/tests/plugins/Example/index.js index ee5fb848..48beaddf 100644 --- a/tests/plugins/Example/index.js +++ b/tests/plugins/Example/index.js @@ -7,11 +7,18 @@ module.exports = (Plugin, Api, Vendor) => { onStart() { Events.subscribe('TEST_EVENT', this.eventTest); Logger.log('onStart'); - Logger.log(`Plugin setting "default-0" value: ${this.getSetting('default-0')}`); - Logger.log(`Internal setting "core/default/test-setting" value: ${Api.Settings.get('core', 'default', 'test-setting')}`); - Events.subscribe('setting-updated', setting => { - console.log('Received internal setting update:', setting); + Logger.log(`Plugin setting "default-0" value: ${this.getSetting('default-0')}`); + this.events.on('setting-updated', event => { + console.log('Received plugin setting update:', event); + }); + this.events.on('settings-updated', event => { + console.log('Received plugin settings update:', event); + }); + + Logger.log(`Internal setting "core/default/test-setting" value: ${Api.Settings.get('core', 'default', 'test-setting')}`); + Events.subscribe('setting-updated', event => { + console.log('Received internal setting update:', event); }); const exampleModule = new (Api.import('Example Module')); From 227b2cc0d820900a98029f254c87314276365f66 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Tue, 13 Feb 2018 23:36:40 +0000 Subject: [PATCH 07/15] Fix events for themes and extmodules --- client/src/modules/extmodule.js | 2 ++ client/src/modules/theme.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/client/src/modules/extmodule.js b/client/src/modules/extmodule.js index 47081ac3..3ebc9ee4 100644 --- a/client/src/modules/extmodule.js +++ b/client/src/modules/extmodule.js @@ -8,6 +8,8 @@ * LICENSE file in the root directory of this source tree. */ +import { EventEmitter } from 'events'; + class ExtModuleEvents { constructor(extmodule) { this.extmodule = extmodule; diff --git a/client/src/modules/theme.js b/client/src/modules/theme.js index a80c3c7e..d269926f 100644 --- a/client/src/modules/theme.js +++ b/client/src/modules/theme.js @@ -9,6 +9,8 @@ */ import ThemeManager from './thememanager'; +import { EventEmitter } from 'events'; +import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs'; import { DOM, Modals } from 'ui'; import { FileUtils, ClientIPC } from 'common'; From 4329517b0fc7e13524ab37d26867bd8f137c62d1 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 09:42:29 +0200 Subject: [PATCH 08/15] add a depend error test plugin --- tests/plugins/Depend Error Test/config.json | 16 ++++++++++++++++ tests/plugins/Depend Error Test/index.js | 12 ++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/plugins/Depend Error Test/config.json create mode 100644 tests/plugins/Depend Error Test/index.js diff --git a/tests/plugins/Depend Error Test/config.json b/tests/plugins/Depend Error Test/config.json new file mode 100644 index 00000000..79cdbab9 --- /dev/null +++ b/tests/plugins/Depend Error Test/config.json @@ -0,0 +1,16 @@ +{ + "info": { + "id": "depend-error", + "name": "Depend Error", + "authors": [ "Jiiks" ], + "version": 1.0, + "description": "Depend Error Plugin Description", + "icon": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FscXVlXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg==" + }, + "main": "index.js", + "type": "plugin", + "dependencies": { + "Nonexistent Module": "1.0" + }, + "defaultConfig": [] +} diff --git a/tests/plugins/Depend Error Test/index.js b/tests/plugins/Depend Error Test/index.js new file mode 100644 index 00000000..1e277b54 --- /dev/null +++ b/tests/plugins/Depend Error Test/index.js @@ -0,0 +1,12 @@ +module.exports = (Plugin, Api, Vendor) => { + + return class extends Plugin { + onStart() { + return true; + } + + onStop() { + return true; + } + } +} From 4fba4049e1af878b77010e33d0c8a1bdbeae1ac8 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 09:56:55 +0200 Subject: [PATCH 09/15] Check that plugin dependencies exist --- client/src/modules/pluginmanager.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/client/src/modules/pluginmanager.js b/client/src/modules/pluginmanager.js index 6c99634f..cb241637 100644 --- a/client/src/modules/pluginmanager.js +++ b/client/src/modules/pluginmanager.js @@ -9,6 +9,7 @@ */ import ContentManager from './contentmanager'; +import ExtModuleManager from './extmodulemanager'; import Plugin from './plugin'; import PluginApi from './pluginapi'; import Vendor from './vendor'; @@ -44,8 +45,22 @@ export default class extends ContentManager { static get refreshPlugins() { return this.refreshContent } static get loadContent() { return this.loadPlugin } - static async loadPlugin(paths, configs, info, main) { - const plugin = window.require(paths.mainPath)(Plugin, new PluginApi(info), Vendor); + static async loadPlugin(paths, configs, info, main, dependencies) { + + const deps = []; + if (dependencies) { + for (const [key, value] of Object.entries(dependencies)) { + const extModule = ExtModuleManager.findModule(key); + if (!extModule) { + throw { + 'message': `Dependency: ${key}:${value} is not loaded` + }; + } + deps.push(extModule); + } + } + + const plugin = window.require(paths.mainPath)(Plugin, new PluginApi(info), Vendor, deps); const instance = new plugin({ configs, info, main, paths: { contentPath: paths.contentPath, dirName: paths.dirName, mainPath: paths.mainPath } }); return instance; } From b23a5ba7ac5b9d9c2f2ca3823a0ca72a08a8d556 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 10:05:34 +0200 Subject: [PATCH 10/15] Pass deps to plugins directly. Should be used when a plugin must have a module to function. --- client/src/modules/contentmanager.js | 2 +- client/src/modules/pluginmanager.js | 2 +- tests/plugins/Example/config.json | 3 +++ tests/plugins/Example/index.js | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/client/src/modules/contentmanager.js b/client/src/modules/contentmanager.js index aaebcb10..d13f9442 100644 --- a/client/src/modules/contentmanager.js +++ b/client/src/modules/contentmanager.js @@ -154,7 +154,7 @@ export default class { mainPath } - const content = await this.loadContent(paths, configs, readConfig.info, readConfig.main); + const content = await this.loadContent(paths, configs, readConfig.info, readConfig.main, readConfig.dependencies); if (reload) this.localContent[index] = content; else this.localContent.push(content); return content; diff --git a/client/src/modules/pluginmanager.js b/client/src/modules/pluginmanager.js index cb241637..105e7125 100644 --- a/client/src/modules/pluginmanager.js +++ b/client/src/modules/pluginmanager.js @@ -56,7 +56,7 @@ export default class extends ContentManager { 'message': `Dependency: ${key}:${value} is not loaded` }; } - deps.push(extModule); + deps[key] = extModule.__require; } } diff --git a/tests/plugins/Example/config.json b/tests/plugins/Example/config.json index ee96edbe..1ae4e604 100644 --- a/tests/plugins/Example/config.json +++ b/tests/plugins/Example/config.json @@ -9,6 +9,9 @@ }, "main": "index.js", "type": "plugin", + "dependencies": { + "Example Module": "1.0" + }, "defaultConfig": [ { "category_default_comment": "default category has no header and is always displayed first", diff --git a/tests/plugins/Example/index.js b/tests/plugins/Example/index.js index 48beaddf..74042970 100644 --- a/tests/plugins/Example/index.js +++ b/tests/plugins/Example/index.js @@ -1,4 +1,4 @@ -module.exports = (Plugin, Api, Vendor) => { +module.exports = (Plugin, Api, Vendor, Dependencies) => { const { $, moment, _ } = Vendor; const { Events, Logger } = Api; @@ -21,7 +21,7 @@ module.exports = (Plugin, Api, Vendor) => { console.log('Received internal setting update:', event); }); - const exampleModule = new (Api.import('Example Module')); + const exampleModule = new Dependencies['Example Module']; Logger.log(`2+4=${exampleModule.add(2, 4)}`); return true; } From 287e2c9cd21e5672bc8fbc49c5e870406572c230 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 14:55:06 +0200 Subject: [PATCH 11/15] Some commenting --- client/src/modules/contentmanager.js | 46 +++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/client/src/modules/contentmanager.js b/client/src/modules/contentmanager.js index d13f9442..c53bbaf1 100644 --- a/client/src/modules/contentmanager.js +++ b/client/src/modules/contentmanager.js @@ -15,21 +15,40 @@ import { Events } from 'modules'; import { ErrorEvent } from 'structs'; import { Modals } from 'ui'; +/** + * Base class for external content managing + */ export default class { + /** + * Any errors that happened + * returns {Array} + */ static get errors() { return this._errors || (this._errors = []); } + /** + * Locallly stored content + * returns {Array} + */ static get localContent() { return this._localContent ? this._localContent : (this._localContent = []); } + /** + * Local path for content + * returns {String} + */ static get contentPath() { return this._contentPath ? this._contentPath : (this._contentPath = Globals.getObject('paths').find(path => path.id === this.pathId).path); } - static async loadAllContent(suppressErrors) { + /** + * Load all locally stored content + * @param {bool} suppressErrors Suppress any errors that occur during loading of content + */ + static async loadAllContent(suppressErrors = false) { try { await FileUtils.ensureDirectory(this.contentPath); const directories = await FileUtils.listDirectory(this.contentPath); @@ -64,6 +83,9 @@ export default class { } } + /** + * Refresh locally stored content + */ static async refreshContent() { if (!this.localContent.length) return this.loadAllContent(); @@ -97,6 +119,12 @@ export default class { } } + /** + * Common loading procedure for loading content before passing it to the actual loader + * @param {any} dirName Base directory for content + * @param {any} reload Is content being reloaded + * @param {any} index Index of content in {localContent} + */ static async preloadContent(dirName, reload = false, index) { try { const contentPath = path.join(this.contentPath, dirName); @@ -164,16 +192,28 @@ export default class { } } + /** + * Read content config file + * @param {any} configPath Config file path + */ static async readConfig(configPath) { configPath = path.resolve(configPath, 'config.json'); return FileUtils.readJsonFromFile(configPath); } + /** + * Read content user config file + * @param {any} configPath User config file path + */ static async readUserConfig(configPath) { configPath = path.resolve(configPath, 'user.config.json'); return FileUtils.readJsonFromFile(configPath); } + /** + * Wildcard content finder + * @param {any} wild Content name | id | path | dirname + */ //TODO make this nicer static findContent(wild) { let content = this.getContentByName(wild); @@ -191,6 +231,10 @@ export default class { static getContentByPath(path) { return this.localContent.find(c => c.contentPath === path) } static getContentByDirName(dirName) { return this.localContent.find(c => c.dirName === dirName) } + /** + * Wait for content to load + * @param {any} content_id + */ static waitForContent(content_id) { return new Promise((resolve, reject) => { const check = () => { From a37bccfbb2e1f052c0743e4f21c307bf05bec83a Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 15:00:15 +0200 Subject: [PATCH 12/15] Some commenting --- client/src/modules/csseditor.js | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/client/src/modules/csseditor.js b/client/src/modules/csseditor.js index c6614417..9f686ded 100644 --- a/client/src/modules/csseditor.js +++ b/client/src/modules/csseditor.js @@ -12,8 +12,14 @@ import { ClientIPC } from 'common'; import Settings from './settings'; import { DOM } from 'ui'; +/** + * Custom css editor communications + */ export default class { + /** + * Init css editor + */ static init() { ClientIPC.on('bd-get-scss', () => this.sendToEditor('set-scss', { scss: this.scss })); ClientIPC.on('bd-update-scss', (e, scss) => this.updateScss(scss)); @@ -25,10 +31,18 @@ export default class { }); } + /** + * Show css editor, flashes if already visible + */ static async show() { await ClientIPC.send('openCssEditor', this.editor_bounds); } + /** + * Update css in client + * @param {String} scss scss to compile + * @param {bool} sendSource send to css editor instance + */ static updateScss(scss, sendSource) { if (sendSource) this.sendToEditor('set-scss', { scss }); @@ -46,31 +60,57 @@ export default class { }); } + /** + * Save css to file + */ static async save() { Settings.saveSettings(); } + /** + * Save current editor bounds + * @param {Rectangle} bounds editor bounds + */ static saveEditorBounds(bounds) { this.editor_bounds = bounds; Settings.saveSettings(); } + /** + * Send scss to core for compilation + * @param {String} scss scss string + */ static async compile(scss) { return await ClientIPC.send('bd-compileSass', { data: scss }); } + /** + * Send css to open editor + * @param {any} channel + * @param {any} data + */ static async sendToEditor(channel, data) { return await ClientIPC.send('sendToCssEditor', { channel, data }); } + /** + * Current uncompiled scss + */ static get scss() { return this._scss || ''; } + /** + * Set current scss + */ static set scss(scss) { this.updateScss(scss, true); } + /** + * Inject compiled css to head + * {DOM} + */ static set css(css) { DOM.injectStyle(css, 'bd-customcss'); } From b1f4fb637ef8f79ff3eb0a26bd9d1b65d74ef7fc Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 15:32:19 +0200 Subject: [PATCH 13/15] add a base for content config object --- client/src/modules/contentconfig.js | 31 +++++++++++++++++++++++++++++ client/src/modules/eventhook.js | 26 ++++++++++++++++++------ client/src/modules/plugin.js | 15 ++++---------- 3 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 client/src/modules/contentconfig.js diff --git a/client/src/modules/contentconfig.js b/client/src/modules/contentconfig.js new file mode 100644 index 00000000..b5c23cca --- /dev/null +++ b/client/src/modules/contentconfig.js @@ -0,0 +1,31 @@ +/** + * BetterDiscord Content Config Utility + * 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. +*/ + + +export default class ContentConfig { + + constructor(data) { + this.data = data; + } + + map(cb) { + return this.data.map(cb); + } + + strip() { + return this.map(cat => ({ + category: cat.category, + settings: cat.settings.map(setting => ({ + id: setting.id, value: setting.value + })) + })); + } + +} diff --git a/client/src/modules/eventhook.js b/client/src/modules/eventhook.js index 7b5f8ca8..399fa6ac 100644 --- a/client/src/modules/eventhook.js +++ b/client/src/modules/eventhook.js @@ -17,6 +17,10 @@ import { } from '../structs/socketstructs'; +/** + * Discord socket event hook + * @extends {EventListener} + */ export default class extends EventListener { bindings() { @@ -29,14 +33,16 @@ export default class extends EventListener { ]; } - hook() { + hook() {} - } - - get eventsModule() { - - } + get eventsModule() {} + /** + * Discord emit overload + * @param {any} e + * @param {any} action + * @param {any} data + */ emit(e, action, data) { switch (e) { case 'dispatch': @@ -44,6 +50,11 @@ export default class extends EventListener { } } + /** + * Emit callback + * @param {any} e Event Action + * @param {any} d Event Args + */ dispatch(e, d) { Events.emit('raw-event', { type: e, data: d }); @@ -77,6 +88,9 @@ export default class extends EventListener { } } + /** + * All known socket actions + */ get actions() { return { READY: 'READY', // Socket ready diff --git a/client/src/modules/plugin.js b/client/src/modules/plugin.js index c4ae5c9d..75a2566a 100644 --- a/client/src/modules/plugin.js +++ b/client/src/modules/plugin.js @@ -11,6 +11,7 @@ import { FileUtils } from 'common'; import { Modals } from 'ui'; import { EventEmitter } from 'events'; +import ContentConfig from './contentconfig'; import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs'; class PluginEvents { @@ -108,20 +109,12 @@ export default class Plugin { } async saveConfiguration() { + window.testConfig = new ContentConfig(this.pluginConfig); try { + const config = new ContentConfig(this.pluginConfig).strip(); await FileUtils.writeFile(`${this.pluginPath}/user.config.json`, JSON.stringify({ enabled: this.enabled, - config: this.pluginConfig.map(category => { - return { - category: category.category, - settings: category.settings.map(setting => { - return { - id: setting.id, - value: setting.value - }; - }) - }; - }) + config })); } catch (err) { throw err; From df7d9fa0da8541633cc42b5a8994e640834a3d03 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 15:35:35 +0200 Subject: [PATCH 14/15] User ContentConfig and bug fix --- client/src/modules/theme.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/client/src/modules/theme.js b/client/src/modules/theme.js index d269926f..355e7985 100644 --- a/client/src/modules/theme.js +++ b/client/src/modules/theme.js @@ -13,6 +13,7 @@ import { EventEmitter } from 'events'; import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs'; import { DOM, Modals } from 'ui'; import { FileUtils, ClientIPC } from 'common'; +import ContentConfig from './contentconfig'; class ThemeEvents { constructor(theme) { @@ -70,7 +71,7 @@ export default class Theme { const updatedSettings = []; for (let newCategory of newSettings) { - const category = this.pluginConfig.find(c => c.category === newCategory.category); + const category = this.themeConfig.find(c => c.category === newCategory.category); for (let newSetting of newCategory.settings) { const setting = category.settings.find(s => s.id === newSetting.id); if (setting.value === newSetting.value) continue; @@ -102,19 +103,10 @@ export default class Theme { async saveConfiguration() { try { + const config = new ContentConfig(this.themeConfig).strip(); await FileUtils.writeFile(`${this.themePath}/user.config.json`, JSON.stringify({ enabled: this.enabled, - config: this.themeConfig.map(category => { - return { - category: category.category, - settings: category.settings.map(setting => { - return { - id: setting.id, - value: setting.value - }; - }) - }; - }), + config, css: this.css })); } catch (err) { From 57e73050cd05289bf28a1b00290e1f67de4f43dd Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 14 Feb 2018 15:36:18 +0200 Subject: [PATCH 15/15] User const --- client/src/modules/plugin.js | 2 +- client/src/modules/theme.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/modules/plugin.js b/client/src/modules/plugin.js index 75a2566a..25cca7a7 100644 --- a/client/src/modules/plugin.js +++ b/client/src/modules/plugin.js @@ -86,7 +86,7 @@ export default class Plugin { const setting = category.settings.find(s => s.id === newSetting.id); if (setting.value === newSetting.value) continue; - let old_value = setting.value; + const old_value = setting.value; setting.value = newSetting.value; updatedSettings.push({ category_id: category.category, setting_id: setting.id, value: setting.value, old_value }); this.settingUpdated(category.category, setting.id, setting.value, old_value); diff --git a/client/src/modules/theme.js b/client/src/modules/theme.js index 355e7985..5cf124e9 100644 --- a/client/src/modules/theme.js +++ b/client/src/modules/theme.js @@ -76,7 +76,7 @@ export default class Theme { const setting = category.settings.find(s => s.id === newSetting.id); if (setting.value === newSetting.value) continue; - let old_value = setting.value; + const old_value = setting.value; setting.value = newSetting.value; updatedSettings.push({ category_id: category.category, setting_id: setting.id, value: setting.value, old_value }); this.settingUpdated(category.category, setting.id, setting.value, old_value);