Modal plugin settings, use [] instead of {} for plugin configs

This commit is contained in:
Jiiks 2018-01-25 07:13:40 +02:00
parent 17a8c2372b
commit 38783631c5
12 changed files with 173 additions and 36 deletions

View File

@ -17,7 +17,6 @@ class Plugin {
constructor(pluginInternals) {
this.__pluginInternals = pluginInternals;
this.userConfig.enabled = this.userConfig.enabled || false;
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
}
@ -34,6 +33,7 @@ class Plugin {
get pluginPath() { return this.paths.pluginPath }
get dirName() { return this.paths.dirName }
get enabled() { return this.userConfig.enabled }
get pluginConfig() { return this.userConfig.pluginConfig }
start() {
if (this.onStart) {
@ -152,10 +152,17 @@ class PluginManager extends Module {
const mainPath = path.join(pluginPath, readConfig.main);
const userConfigPath = path.join(pluginPath, 'user.config.json');
let userConfig = readConfig.defaultConfig;
const userConfig = {
enabled: false,
pluginConfig: readConfig.defaultConfig
};
try {
const readUserConfig = await FileUtils.readJsonFromFile(userConfigPath);
userConfig = Object.assign({}, userConfig, readUserConfig);
//userConfig = Object.assign({}, userConfig, readUserConfig);
userConfig.pluginConfig = readConfig.defaultConfig.map(config => {
const userSet = readUserConfig.pluginConfig.find(c => c.id === config.id);
return userSet || config;
});
} catch (err) {/*We don't care if this fails it either means that user config doesn't exist or there's something wrong with it so we revert to default config*/}
const configs = {
@ -179,7 +186,7 @@ class PluginManager extends Module {
}
async reloadPlugin(plugin) {
const _plugin = this.findPlugin(plugin);
const _plugin = plugin instanceof Plugin ? plugin : this.findPlugin(plugin);
if (!_plugin) throw { 'message': 'Attempted to reload a plugin that is not loaded?' };
if (!_plugin.stop()) throw { 'message': 'Plugin failed to stop!' };
const index = this.getPluginIndex(_plugin);
@ -209,7 +216,7 @@ class PluginManager extends Module {
getPluginByDirName(dirName) { return this.plugins.find(p => p.dirName === dirName) }
stopPlugin(name) {
const plugin = this.getPluginByName(name);
const plugin = name instanceof Plugin ? name : this.getPluginByName(name);
try {
if (plugin) return plugin.stop();
} catch (err) {
@ -219,7 +226,7 @@ class PluginManager extends Module {
}
startPlugin(name) {
const plugin = this.getPluginByName(name);
const plugin = name instanceof Plugin ? name : this.getPluginByName(name);
try {
if (plugin) return plugin.start();
} catch (err) {
@ -261,4 +268,4 @@ async function pluginManager(pluginName) {
if (window.bdTests) window.bdTests.pluginManager = pluginManager;
else window.bdTests = { pluginManager };
module.exports = { PluginManager: _instance }
module.exports = { PluginManager: _instance, Plugin }

View File

@ -1,6 +1,6 @@
export { Global } from './core/global';
export { Logger, Utils, FileUtils } from './core/utils';
export { PluginManager } from './core/pluginmanager';
export { PluginManager, Plugin } from './core/pluginmanager';
export { Pluging } from './core/plugin';
export { BDIpc } from './core/bdipc';
export { WebpackModules } from './core/webpackmodules';

View File

@ -2,16 +2,28 @@
<script>
/*Imports*/
import { Button, ButtonGroup } from '../generic';
import { Button, ButtonGroup, SettingSwitch } from '../generic';
import MiSettings from 'vue-material-design-icons/settings.vue';
import MiReload from 'vue-material-design-icons/refresh.vue';
import MiEdit from 'vue-material-design-icons/pencil.vue';
import MiDelete from 'vue-material-design-icons/delete.vue';
const components = { MiSettings, Button, ButtonGroup, MiReload, MiEdit, MiDelete };
const components = { MiSettings, Button, ButtonGroup, SettingSwitch, MiReload, MiEdit, MiDelete };
/*Methods*/
function showSettings() {
this.settingsOpen = true;
}
const methods = { };
export default {
props: ['plugin', 'togglePlugin', 'reloadPlugin'],
props: ['plugin', 'togglePlugin', 'reloadPlugin', 'showSettings'],
components,
name: "PluginCard"
name: "PluginCard",
methods,
data() {
return {
'settingsOpen': false
}
}
}
</script>

View File

@ -1,6 +1,6 @@
<template src="./templates/PluginsView.html"></template>
<script>
const { PluginManager } = require('../../../'); //#1 require of 2018~ :3
const { PluginManager, Plugin } = require('../../../'); //#1 require of 2018~ :3
/*Imports*/
import { SettingsWrapper } from './';
@ -29,24 +29,29 @@
function togglePlugin(plugin) {
if (plugin.enabled) {
this.pluginManager.stopPlugin(plugin.name);
this.pluginManager.stopPlugin(plugin);
} else {
this.pluginManager.startPlugin(plugin.name);
}
this.pluginManager.startPlugin(plugin);
}
}
function reloadPlugin(plugin) {
this.pluginManager.reloadPlugin(plugin.name);
}
const methods = { showLocal, showOnline, refreshLocalPlugins, togglePlugin, reloadPlugin };
function showSettings(plugin) {
this.settingsOpen = plugin;
}
const methods = { showLocal, showOnline, refreshLocalPlugins, togglePlugin, reloadPlugin, showSettings };
export default {
components,
data() {
return {
local: true,
pluginManager: PluginManager
pluginManager: PluginManager,
settingsOpen: null
}
},
computed: {
@ -54,10 +59,7 @@
return this.pluginManager.plugins;
}
},
methods,
created: function () {
this.refreshLocalPlugins();
}
methods
}
</script>

View File

@ -7,13 +7,14 @@
<div class="bd-switch" :class="{'bd-checked': plugin.enabled}" />
</label>
</div>
<div class="bd-plugin-body">
<div class="bd-plugin-description">{{plugin.description}}</div>
<div class="bd-plugin-footer">
<div class="bd-plugin-extra">v{{plugin.version}} by {{plugin.authors.join(', ').replace(/,(?!.*,)/gmi, ' and')}}</div>
<div class="bd-controls">
<ButtonGroup>
<Button>
<Button :onClick="() => showSettings(plugin)">
<MiSettings/>
</Button>
<Button :onClick="() => reloadPlugin(plugin)">
@ -29,4 +30,5 @@
</div>
</div>
</div>
</div>

View File

@ -1,10 +1,11 @@
<SettingsWrapper headertext="Plugins">
<div class="bd-flex bd-flex-col bd-pluginsView">
<div class="bd-flex bd-tabheader">
<div class="bd-flex-grow bd-button" :class="{'bd-active': local}" @click="showLocal">
<h3>Local</h3>
<div class="bd-material-button" @click="refreshLocalPlugins">
<refresh />
<refresh/>
</div>
</div>
<div class="bd-flex-grow bd-button" :class="{'bd-active': !local}" @click="showOnline">
@ -15,10 +16,33 @@
</div>
</div>
<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" :reloadPlugin="reloadPlugin"/>
<PluginCard v-for="plugin in localPlugins" :plugin="plugin" :key="plugin.id" :togglePlugin="togglePlugin" :reloadPlugin="reloadPlugin" :showSettings="showSettings"/>
</div>
<div v-if="!local" class="bd-spinner-container">
<div class="bd-spinner-2"></div>
</div>
</div>
<div v-if="settingsOpen !== null" class="bd-backdrop" @click="settingsOpen = null"></div>
<div v-if="settingsOpen !== null" class="bd-modal">
<span>{{settingsOpen.name}} Settings</span>
<div v-for="setting in settingsOpen.pluginConfig" class="bd-plugin-settings-body">
<div class="bd-form-item" v-if="setting.type === 'bool'">
<div class="bd-setting-switch">
<div class="bd-title">
<h3>{{setting.text}}</h3>
<label class="bd-switch-wrapper">
<input type="checkbox" class="bd-switch-checkbox"/>
<div class="bd-switch" :class="{'bd-checked': setting.value}"/>
</label>
</div>
<div class="bd-hint">{{setting.hint}}</div>
</div>
<div class="bd-form-divider"></div>
</div>
<div v-else-if="setting.type === 'text'">
</div>
</div>
</div>
</SettingsWrapper>

View File

@ -4,7 +4,7 @@
<h3>{{setting.title || setting.text}}</h3>
<label class="bd-switch-wrapper" @click="!disabled ? onClick(setting) : null">
<input type="checkbox" class="bd-switch-checkbox" />
<div class="bd-switch" :class="{'bd-checked': (setting.checked || setting.enabled)}" />
<div class="bd-switch" :class="{'bd-checked': (setting.checked || setting.enabled || setting.value)}" />
</label>
</div>
<div class="bd-hint">{{setting.hint}}</div>

View File

@ -11,19 +11,19 @@
</div>
</Sidebar>
<ContentColumn slot="content">
<div :class="{active: activeContent('core'), animating: animatingContent('core')}">
<div v-if="activeContent('core') || animatingContent('core')" :class="{active: activeContent('core'), animating: animatingContent('core')}">
<CoreSettings :settings="coreSettings" :enableSetting="enableSetting" :disableSetting="disableSetting"/>
</div>
<div :class="{active: activeContent('ui'), animating: animatingContent('ui')}">
<div v-if="activeContent('ui') || animatingContent('ui')" :class="{active: activeContent('ui'), animating: animatingContent('ui')}">
<UISettings />
</div>
<div :class="{active: activeContent('css'), animating: animatingContent('css')}">
<div v-if="activeContent('css') || animatingContent('css')" :class="{active: activeContent('css'), animating: animatingContent('css')}">
<CssEditorView />
</div>
<div :class="{active: activeContent('emotes'), animating: animatingContent('emotes')}">
<div v-if="activeContent('emotes') || animatingContent('emotes')" :class="{active: activeContent('emotes'), animating: animatingContent('emotes')}">
<EmoteSettings />
</div>
<div :class="{active: activeContent('plugins'), animating: animatingContent('plugins')}">
<div v-if="activeContent('plugins') || animatingContent('plugins')" :class="{active: activeContent('plugins'), animating: animatingContent('plugins')}">
<PluginsView />
</div>
</ContentColumn>

View File

@ -219,4 +219,35 @@
.bd-switch:before {
background: #888888;
}
}
}
.bd-backdrop {
position: absolute;
right: 0px;
left: 0px;
top: 0px;
bottom: 0px;
background: #000;
opacity: .85;
padding: 20px;
}
.bd-modal {
background: #36393e;
position: absolute;
top: 80px;
left: 40px;
right: 40px;
bottom: 80px;
padding: 15px;
display: flex;
flex-direction: column;
border-radius: 8px;
}
.bd-modal span {
color: #FFF;
font-weight: 700;
margin-bottom: 15px;
padding-bottom: 15px;
}

View File

@ -102,3 +102,60 @@
}
}
}
.bd-plugin-settings-header {
span {
color: #b9bbbe;
font-weight: 700;
padding: 0 20px;
}
}
.bd-plugin-settings-body {
.bd-setting-switch {
.bd-switch-wrapper {
flex: 0 0 auto;
user-select: none;
position: relative;
width: 40px;
height: 20px;
display: block;
input {
position: absolute;
opacity: 0;
cursor: pointer;
width: 100%;
height: 100%;
z-index: 1;
}
.bd-switch {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #72767d;
border-radius: 14px;
transition: background .15s ease-in-out,box-shadow .15s ease-in-out,border .15s ease-in-out;
&:before {
content: "";
display: block;
width: 14px;
height: 14px;
position: absolute;
top: 3px;
left: 3px;
bottom: 3px;
background: #f6f6f7;
border-radius: 10px;
transition: all .15s ease;
box-shadow: 0 3px 1px 0 rgba(0,0,0,.05), 0 2px 2px 0 rgba(0,0,0,.1), 0 3px 3px 0 rgba(0,0,0,.05);
}
}
}
}
}

View File

@ -6,7 +6,9 @@
"description": "Example Plugin 2 Description"
},
"main": "index.js",
"defaultConfig": {
"foo": "bar"
}
"defaultConfig": [
{
"foo": "bar"
}
]
}

View File

@ -11,7 +11,7 @@ module.exports = (Plugin, Api, Vendor) => {
}
onStart() {
console.log('On Start!!!!');
console.log('On Start!');
return true;
}
}