Refactor settings menu
Adds support for dynamically adding items
This commit is contained in:
parent
0bbd7b506a
commit
5e259f50f8
|
@ -18,7 +18,23 @@ import path from 'path';
|
|||
|
||||
export default new class Settings {
|
||||
constructor() {
|
||||
this.settings = [];
|
||||
this.settings = defaultSettings.map(_set => {
|
||||
const set = new SettingsSet(_set);
|
||||
|
||||
set.on('setting-updated', event => {
|
||||
const { category, setting, value, old_value } = event;
|
||||
Logger.log('Settings', `${set.id}/${category.id}/${setting.id} was changed from ${old_value} to ${value}`);
|
||||
Events.emit('setting-updated', event);
|
||||
Events.emit(`setting-updated-${set.id}_${category.id}_${setting.id}`, event);
|
||||
});
|
||||
|
||||
set.on('settings-updated', async (event) => {
|
||||
await this.saveSettings();
|
||||
Events.emit('settings-updated', event);
|
||||
});
|
||||
|
||||
return set;
|
||||
});
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
|
@ -29,22 +45,12 @@ export default new class Settings {
|
|||
const user_config = await FileUtils.readJsonFromFile(settingsPath);
|
||||
const { settings, scss, css, css_editor_files, scss_error, css_editor_bounds } = user_config;
|
||||
|
||||
this.settings = defaultSettings.map(set => {
|
||||
const newSet = new SettingsSet(set);
|
||||
newSet.merge(settings.find(s => s.id === newSet.id));
|
||||
newSet.setSaved();
|
||||
newSet.on('setting-updated', event => {
|
||||
const { category, setting, value, old_value } = event;
|
||||
Logger.log('Settings', `${newSet.id}/${category.id}/${setting.id} was changed from ${old_value} to ${value}`);
|
||||
Events.emit('setting-updated', event);
|
||||
Events.emit(`setting-updated-${newSet.id}_${category.id}_${setting.id}`, event);
|
||||
});
|
||||
newSet.on('settings-updated', async (event) => {
|
||||
await this.saveSettings();
|
||||
Events.emit('settings-updated', event);
|
||||
});
|
||||
return newSet;
|
||||
});
|
||||
for (let set of this.settings) {
|
||||
const newSet = settings.find(s => s.id === set.id);
|
||||
if (!newSet) continue;
|
||||
set.merge(newSet);
|
||||
set.setSaved();
|
||||
}
|
||||
|
||||
CssEditor.setState(scss, css, css_editor_files, scss_error);
|
||||
CssEditor.editor_bounds = css_editor_bounds || {};
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* BetterDiscord Menu 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 { Utils } from 'common';
|
||||
|
||||
let items = 0;
|
||||
|
||||
const BdMenuItems = new class {
|
||||
|
||||
constructor() {
|
||||
window.bdmenu = this;
|
||||
|
||||
this.items = [];
|
||||
|
||||
this.addSettingsSet('Internal', 'core', 'Core');
|
||||
this.addSettingsSet('Internal', 'ui', 'UI');
|
||||
this.addSettingsSet('Internal', 'emotes', 'Emotes');
|
||||
|
||||
this.add({category: 'Internal', contentid: 'css', text: 'CSS Editor'});
|
||||
this.add({category: 'External', contentid: 'plugins', text: 'Plugins'});
|
||||
this.add({category: 'External', contentid: 'themes', text: 'Themes'});
|
||||
}
|
||||
|
||||
add(item) {
|
||||
item.id = items++;
|
||||
item.contentid = item.contentid || (items++ + '');
|
||||
item.active = false;
|
||||
item.hidden = item.hidden || false;
|
||||
item._type = item._type || 'button';
|
||||
|
||||
this.items.push(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
addSettingsSet(category, set, text) {
|
||||
return this.add({
|
||||
category, set,
|
||||
text: text || set.text
|
||||
});
|
||||
}
|
||||
|
||||
addVueComponent(category, text, component) {
|
||||
return this.add({
|
||||
category, text, component
|
||||
});
|
||||
}
|
||||
|
||||
remove(item) {
|
||||
Utils.removeFromArray(this.items, item);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export { BdMenuItems };
|
|
@ -86,4 +86,5 @@ export default class {
|
|||
|
||||
return vueInstance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
<MiClose size="17"/>
|
||||
<span class="bd-x-text">ESC</span>
|
||||
</div>
|
||||
<SidebarItem v-for="item in sidebarItems" :item="item" :key="item.id" :onClick="itemOnClick" />
|
||||
<template v-for="(category, text) in sidebar">
|
||||
<SidebarItem :item="{text, type: 'header'}" />
|
||||
<SidebarItem v-for="item in category" :item="item" :key="item.id" :onClick="itemOnClick" />
|
||||
</template>
|
||||
</Sidebar>
|
||||
<div slot="sidebarfooter" class="bd-info">
|
||||
<span class="bd-vtext">v2.0.0a by Jiiks/JsSucks</span>
|
||||
|
@ -31,19 +34,21 @@
|
|||
</div>
|
||||
</div>
|
||||
<ContentColumn slot="content">
|
||||
<div v-for="set in Settings.settings" v-if="!set.hidden && activeContent(set.id) || animatingContent(set.id)" :class="{active: activeContent(set.id), animating: animatingContent(set.id)}">
|
||||
<SettingsWrapper :headertext="set.headertext">
|
||||
<SettingsPanel :settings="set" :schemes="set.schemes" />
|
||||
<div v-for="item in sidebarItems" v-if="activeContent(item.contentid) || animatingContent(item.contentid)" :class="{active: activeContent(item.contentid), animating: animatingContent(item.contentid)}">
|
||||
<template v-if="item.component">
|
||||
<component :is="item.component" :SettingsWrapper="SettingsWrapper" />
|
||||
</template>
|
||||
|
||||
<SettingsWrapper v-if="typeof item.set === 'string'" :headertext="Settings.getSet(item.set).headertext">
|
||||
<SettingsPanel :settings="Settings.getSet(item.set)" :schemes="Settings.getSet(item.set).schemes" />
|
||||
</SettingsWrapper>
|
||||
</div>
|
||||
<div v-if="activeContent('css') || animatingContent('css')" :class="{active: activeContent('css'), animating: animatingContent('css')}">
|
||||
<CssEditorView />
|
||||
</div>
|
||||
<div v-if="activeContent('plugins') || animatingContent('plugins')" :class="{active: activeContent('plugins'), animating: animatingContent('plugins')}">
|
||||
<PluginsView />
|
||||
</div>
|
||||
<div v-if="activeContent('themes') || animatingContent('themes')" :class="{active: activeContent('themes'), animating: animatingContent('themes')}">
|
||||
<ThemesView />
|
||||
<SettingsWrapper v-else-if="item.set" :headertext="item.set.headertext">
|
||||
<SettingsPanel :settings="item.set" :schemes="item.set.schemes" />
|
||||
</SettingsWrapper>
|
||||
|
||||
<CssEditorView v-if="item.contentid === 'css'" />
|
||||
<PluginsView v-if="item.contentid === 'plugins'" />
|
||||
<ThemesView v-if="item.contentid === 'themes'" />
|
||||
</div>
|
||||
</ContentColumn>
|
||||
</SidebarView>
|
||||
|
@ -53,32 +58,22 @@
|
|||
// Imports
|
||||
import { shell } from 'electron';
|
||||
import { Settings } from 'modules';
|
||||
import { BdMenuItems } from 'ui';
|
||||
import { SidebarView, Sidebar, SidebarItem, ContentColumn } from './sidebar';
|
||||
import { SettingsWrapper, SettingsPanel, CssEditorView, PluginsView, ThemesView } from './bd';
|
||||
import { SvgX, MiGithubCircle, MiWeb, MiClose, MiTwitterCircle } from './common';
|
||||
|
||||
// Constants
|
||||
const sidebarItems = [
|
||||
{ text: 'Internal', _type: 'header' },
|
||||
{ id: 0, contentid: "core", text: 'Core', active: false, _type: 'button' },
|
||||
{ id: 1, contentid: "ui", text: 'UI', active: false, _type: 'button' },
|
||||
{ id: 2, contentid: "emotes", text: 'Emotes', active: false, _type: 'button' },
|
||||
{ id: 3, contentid: "css", text: 'CSS Editor', active: false, _type: 'button' },
|
||||
{ text: 'External', _type: 'header' },
|
||||
{ id: 4, contentid: "plugins", text: 'Plugins', active: false, _type: 'button' },
|
||||
{ id: 5, contentid: "themes", text: 'Themes', active: false, _type: 'button' }
|
||||
];
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sidebarItems,
|
||||
BdMenuItems,
|
||||
activeIndex: -1,
|
||||
lastActiveIndex: -1,
|
||||
animating: false,
|
||||
first: true,
|
||||
Settings,
|
||||
timeout: null
|
||||
timeout: null,
|
||||
SettingsWrapper
|
||||
}
|
||||
},
|
||||
props: ['active', 'close'],
|
||||
|
@ -87,6 +82,20 @@
|
|||
SettingsWrapper, SettingsPanel, CssEditorView, PluginsView, ThemesView,
|
||||
MiGithubCircle, MiWeb, MiClose, MiTwitterCircle
|
||||
},
|
||||
computed: {
|
||||
sidebarItems() {
|
||||
return this.BdMenuItems.items;
|
||||
},
|
||||
sidebar() {
|
||||
const categories = {};
|
||||
for (let item of this.sidebarItems) {
|
||||
if (item.hidden) continue;
|
||||
const category = categories[item.category] || (categories[item.category] = []);
|
||||
category.push(item);
|
||||
}
|
||||
return categories;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
itemOnClick(id) {
|
||||
if (this.animating || id === this.activeIndex) return;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export { default as DOM } from './dom';
|
||||
export { default as BdUI } from './bdui';
|
||||
export { default as VueInjector } from './vueinjector';
|
||||
export * from './bdmenu';
|
||||
export { default as Modals } from './modals';
|
||||
export { default as ProfileBadges } from './profilebadges';
|
||||
|
|
|
@ -159,6 +159,13 @@ export class Utils {
|
|||
|
||||
return object;
|
||||
}
|
||||
|
||||
static removeFromArray(array, item) {
|
||||
let index;
|
||||
while ((index = array.indexOf(item)) > -1)
|
||||
array.splice(index, 1);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
export class FileUtils {
|
||||
|
|
Loading…
Reference in New Issue