Added base content class
This commit is contained in:
parent
e5078f4160
commit
3ab4fd8a9a
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
* BetterDiscord Content Base
|
||||
* 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 { Utils, FileUtils, AsyncEventEmitter } from 'common';
|
||||
import { Modals } from 'ui';
|
||||
|
||||
export default class Content {
|
||||
|
||||
constructor(internals) {
|
||||
this.__internals = internals;
|
||||
|
||||
this.settings.on('setting-updated', event => this.events.emit('setting-updated', event));
|
||||
this.settings.on('settings-updated', event => this.events.emit('settings-updated', event));
|
||||
this.settings.on('settings-updated', event => this.__settingsUpdated(event));
|
||||
|
||||
// Add hooks
|
||||
if (this.onstart) this.on('start', event => this.onstart(event));
|
||||
if (this.onStart) this.on('start', event => this.onStart(event));
|
||||
if (this.onstop) this.on('stop', event => this.onstop(event));
|
||||
if (this.onStop) this.on('stop', event => this.onStop(event));
|
||||
if (this.onunload) this.on('unload', event => this.onunload(event));
|
||||
if (this.onUnload) this.on('unload', event => this.onUnload(event));
|
||||
if (this.settingUpdated) this.on('setting-updated', event => this.settingUpdated(event));
|
||||
if (this.settingsUpdated) this.on('settings-updated', event => this.settingsUpdated(event));
|
||||
}
|
||||
|
||||
get type() { return undefined }
|
||||
get configs() { return this.__internals.configs }
|
||||
get info() { return this.__internals.info }
|
||||
get paths() { return this.__internals.paths }
|
||||
get main() { return this.__internals.main }
|
||||
get defaultConfig() { return this.configs.defaultConfig }
|
||||
get userConfig() { return this.configs.userConfig }
|
||||
get configSchemes() { return this.configs.schemes }
|
||||
get id() { return this.info.id || this.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-') }
|
||||
get name() { return this.info.name }
|
||||
get icon() { return this.info.icon }
|
||||
get description() { return this.info.description }
|
||||
get authors() { return this.info.authors }
|
||||
get version() { return this.info.version }
|
||||
get contentPath() { return this.paths.contentPath }
|
||||
get dirName() { return this.paths.dirName }
|
||||
get enabled() { return this.userConfig.enabled }
|
||||
get settings() { return this.userConfig.config }
|
||||
get config() { return this.settings.categories }
|
||||
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
|
||||
get events() { return this.EventEmitter || (this.EventEmitter = new AsyncEventEmitter()) }
|
||||
|
||||
/**
|
||||
* Opens a settings modal for this content.
|
||||
*/
|
||||
showSettingsModal() {
|
||||
return Modals.contentSettings(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this content has any settings.
|
||||
*/
|
||||
get hasSettings() {
|
||||
return !!this.settings.findSetting(() => true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the content's current configuration.
|
||||
*/
|
||||
async saveConfiguration() {
|
||||
try {
|
||||
await FileUtils.writeFile(`${this.contentPath}/user.config.json`, JSON.stringify({
|
||||
enabled: this.enabled,
|
||||
config: this.settings.strip().settings,
|
||||
data: this.data
|
||||
}));
|
||||
|
||||
this.settings.setSaved();
|
||||
} catch (err) {
|
||||
Logger.err(this.name, ['Failed to save configuration', err]);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when settings are updated.
|
||||
* This can be overridden by other content types.
|
||||
*/
|
||||
__settingsUpdated(event) {
|
||||
return this.saveConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the content.
|
||||
* @param {Boolean} save Whether to save the new enabled state
|
||||
* @return {Promise}
|
||||
*/
|
||||
async enable(save = true) {
|
||||
if (this.enabled) return;
|
||||
await this.emit('enable');
|
||||
await this.emit('start');
|
||||
|
||||
this.userConfig.enabled = true;
|
||||
if (save) await this.saveConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the content.
|
||||
* @param {Boolean} save Whether to save the new enabled state
|
||||
* @return {Promise}
|
||||
*/
|
||||
async disable(save = true) {
|
||||
if (!this.enabled) return;
|
||||
await this.emit('stop');
|
||||
await this.emit('disable');
|
||||
|
||||
this.userConfig.enabled = false;
|
||||
if (save) await this.saveConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an event listener.
|
||||
* @param {String} event The event to add the listener to
|
||||
* @param {Function} callback The function to call when the event is emitted
|
||||
*/
|
||||
on(...args) {
|
||||
return this.events.on(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an event listener.
|
||||
* @param {String} event The event to remove the listener from
|
||||
* @param {Function} callback The bound callback (optional)
|
||||
*/
|
||||
off(...args) {
|
||||
return this.events.removeListener(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an event listener that removes itself when called, therefore only being called once.
|
||||
* @param {String} event The event to add the listener to
|
||||
* @param {Function} callback The function to call when the event is emitted
|
||||
* @return {Promise|undefined}
|
||||
*/
|
||||
once(...args) {
|
||||
return this.events.once(...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits an event.
|
||||
* @param {String} event The event to emit
|
||||
* @param {Any} data Data to be passed to listeners
|
||||
* @return {Promise|undefined}
|
||||
*/
|
||||
emit(...args) {
|
||||
return this.events.emit(...args);
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import Content from './content';
|
||||
import Globals from './globals';
|
||||
import { Utils, FileUtils, ClientLogger as Logger } from 'common';
|
||||
import path from 'path';
|
||||
|
@ -245,17 +246,19 @@ export default class {
|
|||
if (!content) throw {message: `Could not find a ${this.contentType} from ${content}.`};
|
||||
|
||||
try {
|
||||
if (content.enabled && content.disable) content.disable(false);
|
||||
if (content.enabled && content.stop) content.stop(false);
|
||||
if (content.onunload) content.onunload(reload);
|
||||
if (content.onUnload) content.onUnload(reload);
|
||||
await content.disable(false);
|
||||
await content.emit('unload', reload);
|
||||
|
||||
const index = this.getContentIndex(content);
|
||||
|
||||
delete window.require.cache[window.require.resolve(content.paths.mainPath)];
|
||||
|
||||
if (reload) {
|
||||
const newcontent = await this.preloadContent(content.dirName, true, index);
|
||||
if (newcontent.enabled && newcontent.start) newcontent.start(false);
|
||||
if (newcontent.enabled) {
|
||||
newcontent.userConfig.enabled = false;
|
||||
newcontent.start(false);
|
||||
}
|
||||
return newcontent;
|
||||
} else this.localContent.splice(index, 1);
|
||||
} catch (err) {
|
||||
|
@ -268,7 +271,7 @@ export default class {
|
|||
* Reload content
|
||||
* @param {any} content Content to reload
|
||||
*/
|
||||
static async reloadContent(content) {
|
||||
static reloadContent(content) {
|
||||
return this.unloadContent(content, true);
|
||||
}
|
||||
|
||||
|
@ -295,12 +298,20 @@ export default class {
|
|||
* @param {any} content Object to check
|
||||
*/
|
||||
static isThisContent(content) {
|
||||
return false;
|
||||
return content instanceof Content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first content where calling {function} returns true.
|
||||
* @param {Function} function A function to call to filter content
|
||||
*/
|
||||
static find(f) {
|
||||
return this.localContent.find(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wildcard content finder
|
||||
* @param {any} wild Content name | id | path | dirname
|
||||
* @param {any} wild Content ID / directory name / path / name
|
||||
* @param {bool} nonunique Allow searching attributes that may not be unique
|
||||
*/
|
||||
static findContent(wild, nonunique) {
|
||||
|
@ -313,10 +324,10 @@ export default class {
|
|||
}
|
||||
|
||||
static getContentIndex(content) { return this.localContent.findIndex(c => c === content) }
|
||||
static getContentByName(name) { return this.localContent.find(c => c.name === name) }
|
||||
static getContentById(id) { return this.localContent.find(c => c.id === id) }
|
||||
static getContentByPath(path) { return this.localContent.find(c => c.contentPath === path) }
|
||||
static getContentByDirName(dirName) { return this.localContent.find(c => c.dirName === dirName) }
|
||||
static getContentByPath(path) { return this.localContent.find(c => c.contentPath === path) }
|
||||
static getContentByName(name) { return this.localContent.find(c => c.name === name) }
|
||||
|
||||
/**
|
||||
* Wait for content to load
|
||||
|
|
|
@ -8,37 +8,15 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { AsyncEventEmitter } from 'common';
|
||||
import { EventEmitter } from 'events';
|
||||
import Content from './content';
|
||||
|
||||
export default class ExtModule {
|
||||
export default class ExtModule extends Content {
|
||||
|
||||
constructor(pluginInternals) {
|
||||
this.__pluginInternals = pluginInternals;
|
||||
constructor(internals) {
|
||||
super(internals);
|
||||
this.__require = window.require(this.paths.mainPath);
|
||||
this.hasSettings = false;
|
||||
}
|
||||
|
||||
get type() { return 'module' }
|
||||
get configs() { return this.__pluginInternals.configs }
|
||||
get info() { return this.__pluginInternals.info }
|
||||
get icon() { return this.info.icon }
|
||||
get paths() { return this.__pluginInternals.paths }
|
||||
get main() { return this.__pluginInternals.main }
|
||||
get defaultConfig() { return this.configs.defaultConfig }
|
||||
get userConfig() { return this.configs.userConfig }
|
||||
get configSchemes() { return this.configs.schemes }
|
||||
get id() { return this.info.id || this.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-') }
|
||||
get name() { return this.info.name }
|
||||
get description() { return this.info.description }
|
||||
get authors() { return this.info.authors }
|
||||
get version() { return this.info.version }
|
||||
get contentPath() { return this.paths.contentPath }
|
||||
get modulePath() { return this.paths.contentPath }
|
||||
get dirName() { return this.paths.dirName }
|
||||
get enabled() { return true }
|
||||
get config() { return this.userConfig.config || [] }
|
||||
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
|
||||
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
|
||||
|
||||
}
|
||||
|
|
|
@ -8,93 +8,19 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { Utils, FileUtils, AsyncEventEmitter } from 'common';
|
||||
import { Modals } from 'ui';
|
||||
import { EventEmitter } from 'events';
|
||||
import PluginManager from './pluginmanager';
|
||||
import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs';
|
||||
import Content from './content';
|
||||
|
||||
export default class Plugin {
|
||||
|
||||
constructor(pluginInternals) {
|
||||
this.__pluginInternals = pluginInternals;
|
||||
this.saveConfiguration = this.saveConfiguration.bind(this);
|
||||
this.hasSettings = this.config && this.config.length > 0;
|
||||
this.start = this.start.bind(this);
|
||||
this.stop = this.stop.bind(this);
|
||||
|
||||
this.settings.on('setting-updated', event => this.events.emit('setting-updated', event));
|
||||
this.settings.on('settings-updated', event => this.events.emit('settings-updated', event));
|
||||
this.settings.on('settings-updated', event => this.saveConfiguration());
|
||||
}
|
||||
export default class Plugin extends Content {
|
||||
|
||||
get type() { return 'plugin' }
|
||||
get configs() { return this.__pluginInternals.configs }
|
||||
get info() { return this.__pluginInternals.info }
|
||||
get icon() { return this.info.icon }
|
||||
get paths() { return this.__pluginInternals.paths }
|
||||
get main() { return this.__pluginInternals.main }
|
||||
get defaultConfig() { return this.configs.defaultConfig }
|
||||
get userConfig() { return this.configs.userConfig }
|
||||
get configSchemes() { return this.configs.schemes }
|
||||
get id() { return this.info.id || this.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-') }
|
||||
get name() { return this.info.name }
|
||||
get description() { return this.info.description }
|
||||
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 }
|
||||
get settings() { return this.userConfig.config }
|
||||
get config() { return this.settings.settings }
|
||||
|
||||
// Don't use - these will eventually be removed!
|
||||
get pluginPath() { return this.contentPath }
|
||||
get pluginConfig() { return this.config }
|
||||
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
|
||||
get exports() { return this._exports ? this._exports : (this._exports = this.getExports()) }
|
||||
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
|
||||
|
||||
showSettingsModal() {
|
||||
return Modals.contentSettings(this);
|
||||
}
|
||||
|
||||
async saveConfiguration() {
|
||||
try {
|
||||
await FileUtils.writeFile(`${this.pluginPath}/user.config.json`, JSON.stringify({
|
||||
enabled: this.enabled,
|
||||
config: this.settings.strip().settings,
|
||||
data: this.data
|
||||
}));
|
||||
|
||||
this.settings.setSaved();
|
||||
} catch (err) {
|
||||
console.error(`Plugin ${this.id} configuration failed to save`, err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
start(save = true) {
|
||||
if (this.onstart && !this.onstart()) return false;
|
||||
if (this.onStart && !this.onStart()) return false;
|
||||
|
||||
if (!this.enabled) {
|
||||
this.userConfig.enabled = true;
|
||||
if (save) this.saveConfiguration();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
stop(save = true) {
|
||||
if (this.onstop && !this.onstop()) return false;
|
||||
if (this.onStop && !this.onStop()) return false;
|
||||
|
||||
if (this.enabled) {
|
||||
this.userConfig.enabled = false;
|
||||
if (save) this.saveConfiguration();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
get start() { return this.enable }
|
||||
get stop() { return this.disable }
|
||||
|
||||
unload() {
|
||||
PluginManager.unloadPlugin(this);
|
||||
|
|
|
@ -41,11 +41,13 @@ export default class extends ContentManager {
|
|||
const loadAll = await this.loadAllContent(true);
|
||||
this.loaded = true;
|
||||
for (let plugin of this.localPlugins) {
|
||||
if (!plugin.enabled) continue;
|
||||
plugin.userConfig.enabled = false;
|
||||
|
||||
try {
|
||||
if (plugin.enabled) plugin.start();
|
||||
plugin.start(false);
|
||||
} catch (err) {
|
||||
// Disable the plugin but don't save it - the next time BetterDiscord is started the plugin will attempt to start again
|
||||
plugin.userConfig.enabled = false;
|
||||
this.errors.push(new ErrorEvent({
|
||||
module: this.moduleName,
|
||||
message: `Failed to start ${plugin.name}`,
|
||||
|
@ -72,7 +74,6 @@ export default class extends ContentManager {
|
|||
|
||||
static get loadContent() { return this.loadPlugin }
|
||||
static async loadPlugin(paths, configs, info, main, dependencies, permissions) {
|
||||
|
||||
if (permissions && permissions.length > 0) {
|
||||
for (let perm of permissions) {
|
||||
console.log(`Permission: ${Permissions.permissionText(perm).HEADER} - ${Permissions.permissionText(perm).BODY}`);
|
||||
|
@ -107,7 +108,10 @@ export default class extends ContentManager {
|
|||
}
|
||||
});
|
||||
|
||||
if (instance.enabled && this.loaded) instance.start();
|
||||
if (instance.enabled && this.loaded) {
|
||||
instance.userConfig.enabled = false;
|
||||
instance.start(false);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,26 +8,17 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import Content from './content';
|
||||
import Settings from './settings';
|
||||
import ThemeManager from './thememanager';
|
||||
import { EventEmitter } from 'events';
|
||||
import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs';
|
||||
import { DOM, Modals } from 'ui';
|
||||
import { Utils, FileUtils, ClientIPC, ClientLogger as Logger, AsyncEventEmitter } from 'common';
|
||||
import { DOM } from 'ui';
|
||||
import { FileUtils, ClientIPC, ClientLogger as Logger } from 'common';
|
||||
import filewatcher from 'filewatcher';
|
||||
|
||||
export default class Theme {
|
||||
export default class Theme extends Content {
|
||||
|
||||
constructor(themeInternals) {
|
||||
this.__themeInternals = themeInternals;
|
||||
this.hasSettings = this.config && this.config.length > 0;
|
||||
this.saveConfiguration = this.saveConfiguration.bind(this);
|
||||
this.enable = this.enable.bind(this);
|
||||
this.disable = this.disable.bind(this);
|
||||
|
||||
this.settings.on('setting-updated', event => this.events.emit('setting-updated', event));
|
||||
this.settings.on('settings-updated', event => this.events.emit('settings-updated', event));
|
||||
this.settings.on('settings-updated', event => this.recompile());
|
||||
constructor(internals) {
|
||||
super(internals);
|
||||
|
||||
const watchfiles = Settings.getSetting('css', 'default', 'watch-files');
|
||||
if (watchfiles.value) this.watchfiles = this.files;
|
||||
|
@ -37,63 +28,39 @@ export default class Theme {
|
|||
});
|
||||
}
|
||||
|
||||
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 loaded() { return this.__themeInternals.loaded }
|
||||
get defaultConfig() { return this.configs.defaultConfig }
|
||||
get userConfig() { return this.configs.userConfig }
|
||||
get configSchemes() { return this.configs.schemes }
|
||||
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 description() { return this.info.description }
|
||||
get authors() { return this.info.authors }
|
||||
get version() { return this.info.version }
|
||||
get contentPath() { return this.paths.contentPath }
|
||||
get themePath() { return this.paths.contentPath }
|
||||
get dirName() { return this.paths.dirName }
|
||||
get enabled() { return this.userConfig.enabled }
|
||||
get settings() { return this.userConfig.config }
|
||||
get config() { return this.settings.settings }
|
||||
get themeConfig() { return this.config }
|
||||
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
|
||||
get type() { return 'theme' }
|
||||
get css() { return this.data.css }
|
||||
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
|
||||
|
||||
showSettingsModal() {
|
||||
return Modals.contentSettings(this);
|
||||
// Don't use - these will eventually be removed!
|
||||
get themePath() { return this.contentPath }
|
||||
get themeConfig() { return this.config }
|
||||
|
||||
/**
|
||||
* Called when settings are updated.
|
||||
* This can be overridden by other content types.
|
||||
*/
|
||||
__settingsUpdated(event) {
|
||||
return this.recompile();
|
||||
}
|
||||
|
||||
async saveConfiguration() {
|
||||
try {
|
||||
await FileUtils.writeFile(`${this.themePath}/user.config.json`, JSON.stringify({
|
||||
enabled: this.enabled,
|
||||
config: this.settings.strip().settings,
|
||||
data: this.data
|
||||
}));
|
||||
|
||||
this.settings.setSaved();
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
enable(save = true) {
|
||||
if (!this.enabled) {
|
||||
this.userConfig.enabled = true;
|
||||
if (save) this.saveConfiguration();
|
||||
}
|
||||
/**
|
||||
* This is called when the theme is enabled.
|
||||
*/
|
||||
onstart() {
|
||||
DOM.injectTheme(this.css, this.id);
|
||||
}
|
||||
|
||||
disable(save = true) {
|
||||
this.userConfig.enabled = false;
|
||||
if (save) this.saveConfiguration();
|
||||
/**
|
||||
* This is called when the theme is disabled.
|
||||
*/
|
||||
onstop() {
|
||||
DOM.deleteTheme(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the theme and returns an object containing the CSS and an array of files that were included.
|
||||
* @return {Promise}
|
||||
*/
|
||||
async compile() {
|
||||
console.log('Compiling CSS');
|
||||
|
||||
|
@ -117,11 +84,15 @@ export default class Theme {
|
|||
};
|
||||
} else {
|
||||
return {
|
||||
css: FileUtils.readFile(this.paths.mainPath)
|
||||
css: await FileUtils.readFile(this.paths.mainPath)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the theme and updates and saves the CSS and the list of include files.
|
||||
* @return {Promise}
|
||||
*/
|
||||
async recompile() {
|
||||
const data = await this.compile();
|
||||
this.data.css = data.css;
|
||||
|
@ -136,7 +107,7 @@ export default class Theme {
|
|||
}
|
||||
|
||||
/**
|
||||
* An array of files that are imported in custom CSS.
|
||||
* An array of files that are imported in the theme's SCSS.
|
||||
* @return {Array} Files being watched
|
||||
*/
|
||||
get files() {
|
||||
|
@ -144,7 +115,7 @@ export default class Theme {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets all files that are imported in custom CSS.
|
||||
* Sets all files that are imported in the theme's SCSS.
|
||||
* @param {Array} files Files to watch
|
||||
*/
|
||||
set files(files) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<Card :item="plugin">
|
||||
<SettingSwitch v-if="plugin.type === 'plugin'" slot="toggle" :checked="plugin.enabled" :change="togglePlugin" />
|
||||
<ButtonGroup slot="controls">
|
||||
<Button v-tooltip="'Settings'" v-if="plugin.hasSettings" :onClick="() => showSettings(plugin)"><MiSettings size="18" /></Button>
|
||||
<Button v-tooltip="'Settings (shift + click to open settings without cloning the set)'" v-if="plugin.hasSettings" :onClick="showSettings"><MiSettings size="18" /></Button>
|
||||
<Button v-tooltip="'Reload'" :onClick="reloadPlugin"><MiRefresh size="18" /></Button>
|
||||
<Button v-tooltip="'Edit'" :onClick="editPlugin"><MiPencil size="18" /></Button>
|
||||
<Button v-tooltip="'Uninstall (shift + click to unload)'" :onClick="deletePlugin" type="err"><MiDelete size="18" /></Button>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<div class="bd-flex bd-flex-col bd-pluginsview">
|
||||
<div v-if="local" class="bd-flex bd-flex-grow bd-flex-col bd-plugins-container bd-local-plugins">
|
||||
<PluginCard v-for="plugin in localPlugins" :plugin="plugin" :key="plugin.id" :togglePlugin="() => togglePlugin(plugin)" :reloadPlugin="() => reloadPlugin(plugin)" :deletePlugin="e => deletePlugin(plugin, e.shiftKey)" :showSettings="() => showSettings(plugin)" />
|
||||
<PluginCard v-for="plugin in localPlugins" :plugin="plugin" :key="plugin.id" :togglePlugin="() => togglePlugin(plugin)" :reloadPlugin="() => reloadPlugin(plugin)" :deletePlugin="e => deletePlugin(plugin, e.shiftKey)" :showSettings="e => showSettings(plugin, e.shiftKey)" />
|
||||
</div>
|
||||
<div v-if="!local" class="bd-online-ph">
|
||||
<h3>Coming Soon</h3>
|
||||
|
@ -93,8 +93,10 @@
|
|||
console.error(err);
|
||||
}
|
||||
},
|
||||
showSettings(plugin) {
|
||||
return Modals.contentSettings(plugin);
|
||||
showSettings(plugin, dont_clone) {
|
||||
return Modals.contentSettings(plugin, null, {
|
||||
dont_clone
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<Card :item="theme">
|
||||
<SettingSwitch slot="toggle" :checked="theme.enabled" :change="toggleTheme" />
|
||||
<ButtonGroup slot="controls">
|
||||
<Button v-tooltip="'Settings'" v-if="theme.hasSettings" :onClick="showSettings"><MiSettings size="18" /></Button>
|
||||
<Button v-tooltip="'Settings (shift + click to open settings without cloning the set)'" v-if="theme.hasSettings" :onClick="e => showSettings(theme, e.shiftKey)"><MiSettings size="18" /></Button>
|
||||
<Button v-tooltip="'Recompile (shift + click to reload)'" :onClick="reloadTheme"><MiRefresh size="18" /></Button>
|
||||
<Button v-tooltip="'Edit'" :onClick="editTheme"><MiPencil size="18" /></Button>
|
||||
<Button v-tooltip="'Uninstall (shift + click to unload)'" :onClick="deleteTheme" type="err"><MiDelete size="18" /></Button>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<div class="bd-flex bd-flex-col bd-themesview">
|
||||
<div v-if="local" class="bd-flex bd-flex-grow bd-flex-col bd-themes-container bd-local-themes">
|
||||
<ThemeCard v-for="theme in localThemes" :theme="theme" :key="theme.id" :toggleTheme="() => toggleTheme(theme)" :reloadTheme="e => reloadTheme(theme, e.shiftKey)" :showSettings="() => showSettings(theme)" :deleteTheme="e => deleteTheme(theme, e.shiftKey)" />
|
||||
<ThemeCard v-for="theme in localThemes" :theme="theme" :key="theme.id" :toggleTheme="() => toggleTheme(theme)" :reloadTheme="e => reloadTheme(theme, e.shiftKey)" :showSettings="e => showSettings(theme, e.shiftKey)" :deleteTheme="e => deleteTheme(theme, e.shiftKey)" />
|
||||
</div>
|
||||
<div v-if="!local" class="bd-online-ph">
|
||||
<h3>Coming Soon</h3>
|
||||
|
@ -94,8 +94,10 @@
|
|||
console.error(err);
|
||||
}
|
||||
},
|
||||
showSettings(theme) {
|
||||
return Modals.contentSettings(theme);
|
||||
showSettings(theme, dont_clone) {
|
||||
return Modals.contentSettings(theme, null, {
|
||||
dont_clone
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,18 +57,6 @@
|
|||
if (this.setting.disabled || this.setting.min && this.setting.items.length <= this.setting.min) return;
|
||||
this.setting.removeItem(item);
|
||||
},
|
||||
changeInItem(item, category_id, setting_id, value) {
|
||||
console.log('Setting', item, category_id, setting_id, 'to', value);
|
||||
|
||||
const category = item.settings.find(c => c.category === category_id);
|
||||
if (!category) return;
|
||||
|
||||
const setting = category.settings.find(s => s.id === setting_id);
|
||||
if (!setting || Utils.compare(setting.value, value)) return;
|
||||
|
||||
setting.value = value;
|
||||
setting.changed = !Utils.compare(setting.value, setting.old_value);
|
||||
},
|
||||
showModal(item, index) {
|
||||
Modals.settings(item, this.setting.headertext ? this.setting.headertext.replace(/%n/, index + 1) : this.setting.text + ` #${index + 1}`);
|
||||
},
|
||||
|
|
|
@ -240,8 +240,8 @@ export default class Modals {
|
|||
* @param {String} headertext A string that will be displayed in the modal header
|
||||
* @return {Modal}
|
||||
*/
|
||||
static contentSettings(content, headertext) {
|
||||
return this.settings(content.settings, headertext ? headertext : content.name + ' Settings');
|
||||
static contentSettings(content, headertext, options) {
|
||||
return this.settings(content.settings, headertext ? headertext : content.name + ' Settings', options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue