Merge pull request #154 from samuelthomas2774/settings
Fix settingsset.findSetting and arraysetting.items
This commit is contained in:
commit
ccb5a1ce56
|
@ -8,27 +8,9 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { AsyncEventEmitter } from 'common';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
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) {
|
||||
|
@ -57,6 +39,6 @@ export default class ExtModule {
|
|||
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 ExtModuleEvents(this)) }
|
||||
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
|
||||
|
||||
}
|
||||
|
|
|
@ -8,36 +8,17 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { Utils, FileUtils } from 'common';
|
||||
import { Utils, FileUtils, AsyncEventEmitter } from 'common';
|
||||
import { Modals } from 'ui';
|
||||
import { EventEmitter } from 'events';
|
||||
import PluginManager from './pluginmanager';
|
||||
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 {
|
||||
|
||||
constructor(pluginInternals) {
|
||||
this.__pluginInternals = pluginInternals;
|
||||
this.saveSettings = this.saveSettings.bind(this);
|
||||
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);
|
||||
|
@ -70,29 +51,12 @@ export default class Plugin {
|
|||
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 PluginEvents(this)) }
|
||||
|
||||
getSetting(setting_id, category_id) {
|
||||
for (let category of this.config) {
|
||||
if (category_id && category.category !== category_id) continue;
|
||||
for (let setting of category.settings) {
|
||||
if (setting.id !== setting_id) continue;
|
||||
return setting.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
|
||||
|
||||
showSettingsModal() {
|
||||
return Modals.contentSettings(this);
|
||||
}
|
||||
|
||||
async saveSettings(newSettings) {
|
||||
const updatedSettings = this.settings.merge(newSettings);
|
||||
|
||||
await this.saveConfiguration();
|
||||
return updatedSettings;
|
||||
}
|
||||
|
||||
async saveConfiguration() {
|
||||
try {
|
||||
await FileUtils.writeFile(`${this.pluginPath}/user.config.json`, JSON.stringify({
|
||||
|
|
|
@ -13,34 +13,15 @@ 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 } from 'common';
|
||||
import { Utils, FileUtils, ClientIPC, ClientLogger as Logger, AsyncEventEmitter } from 'common';
|
||||
import filewatcher from 'filewatcher';
|
||||
|
||||
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.config && this.config.length > 0;
|
||||
this.saveSettings = this.saveSettings.bind(this);
|
||||
this.saveConfiguration = this.saveConfiguration.bind(this);
|
||||
this.enable = this.enable.bind(this);
|
||||
this.disable = this.disable.bind(this);
|
||||
|
||||
|
@ -79,22 +60,12 @@ export default class Theme {
|
|||
get themeConfig() { return this.config }
|
||||
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
|
||||
get css() { return this.data.css }
|
||||
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new ThemeEvents(this)) }
|
||||
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
|
||||
|
||||
showSettingsModal() {
|
||||
return Modals.contentSettings(this);
|
||||
}
|
||||
|
||||
async saveSettings(newSettings) {
|
||||
const updatedSettings = this.settings.merge(newSettings);
|
||||
|
||||
// As the theme's configuration has changed it needs recompiling
|
||||
// When the compiled CSS has been saved it will also save the configuration
|
||||
await this.recompile();
|
||||
|
||||
return this.settingsUpdated(updatedSettings);
|
||||
}
|
||||
|
||||
async saveConfiguration() {
|
||||
try {
|
||||
await FileUtils.writeFile(`${this.themePath}/user.config.json`, JSON.stringify({
|
||||
|
|
|
@ -101,17 +101,6 @@ export default class SettingsSet {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first setting that matches the id in any category
|
||||
*/
|
||||
findFirst(settingId) {
|
||||
for (let cat of this.categories) {
|
||||
const found = cat.settings.find(s => s.id === settingId);
|
||||
if (found) return found;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first category where calling {function} returns true.
|
||||
* @param {Function} function A function to call to filter categories
|
||||
|
@ -146,7 +135,7 @@ export default class SettingsSet {
|
|||
*/
|
||||
findSetting(f) {
|
||||
for (let category of this.categories) {
|
||||
const setting = category.findSetting(f);
|
||||
const setting = category.find(f);
|
||||
if (setting) return setting;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export default class ArraySetting extends Setting {
|
|||
this.args.schemes = this.schemes.map(scheme => new SettingsScheme(scheme));
|
||||
this.args.items = this.value ? this.value.map(item => this.createItem(item.args || item)) : [];
|
||||
|
||||
this.updateValue(false, false);
|
||||
this._setValue(this.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,43 +131,48 @@ export default class ArraySetting extends Setting {
|
|||
* @return {SettingsSet} The new set
|
||||
*/
|
||||
createItem(item) {
|
||||
if (item instanceof SettingsSet)
|
||||
return item;
|
||||
|
||||
const set = new SettingsSet({
|
||||
settings: Utils.deepclone(this.settings),
|
||||
schemes: this.schemes
|
||||
}, item ? item.args || item : undefined);
|
||||
|
||||
// if (item) set.merge(item.args || item);
|
||||
set.setSaved();
|
||||
set.on('settings-updated', () => this.updateValue());
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this setting.
|
||||
* This is only intended for use by settings.
|
||||
* @param {SettingsSetting} value The new value of this setting
|
||||
* @param {Boolean} emit_multi Whether to emit a SettingsUpdatedEvent
|
||||
* @param {Boolean} emit Whether to emit a SettingUpdatedEvent
|
||||
* @return {Promise}
|
||||
* Function to be called after the value changes.
|
||||
* This can be overridden by other settings types.
|
||||
* @param {SettingUpdatedEvent} updatedSetting
|
||||
*/
|
||||
setValue(value, emit_multi = true, emit = true) {
|
||||
this.args.items = value ? value.map(item => this.createItem(item)) : [];
|
||||
this.updateValue(emit_multi, emit);
|
||||
setValueHook(updatedSetting) {
|
||||
this.args.items = updatedSetting.value ? updatedSetting.value.map(item => this.createItem(item)) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value of this array setting.
|
||||
* This only exists for use by array settings.
|
||||
* @param {Boolean} emit_multi Whether to emit a SettingsUpdatedEvent
|
||||
* @param {Boolean} emit Whether to emit a SettingUpdatedEvent
|
||||
* @return {Promise}
|
||||
*/
|
||||
updateValue(emit_multi = true, emit = true) {
|
||||
return this.__proto__.__proto__.setValue.call(this, this.items.map(item => {
|
||||
getValue() {
|
||||
return this.items.map(item => {
|
||||
if (!item) return;
|
||||
item.setSaved();
|
||||
return item.strip();
|
||||
}), emit_multi, emit);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value of this array setting.
|
||||
* This only exists for use by array settings.
|
||||
* @return {Promise}
|
||||
*/
|
||||
updateValue(emit_multi = true, emit = true) {
|
||||
return this.setValue(this.getValue(), emit_multi, emit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -107,75 +107,75 @@ export default class Setting {
|
|||
*/
|
||||
_merge(newSetting) {
|
||||
const value = newSetting.args ? newSetting.args.value : newSetting.value;
|
||||
const old_value = this.args.value;
|
||||
if (Utils.compare(value, old_value)) return [];
|
||||
this.args.value = value;
|
||||
this.changed = !Utils.compare(this.args.value, this.args.saved_value);
|
||||
|
||||
return [{
|
||||
setting: this, setting_id: this.id,
|
||||
value, old_value
|
||||
}];
|
||||
return this._setValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges another setting into this setting.
|
||||
* @param {SettingsSetting} newSetting The setting to merge into this setting
|
||||
* @param {Boolean} emit_multi Whether to emit a SettingsUpdatedEvent
|
||||
* @param {Boolean} emit Whether to emit a SettingUpdatedEvent
|
||||
* @return {Promise}
|
||||
*/
|
||||
async merge(newSetting, emit_multi = true, emit = true) {
|
||||
const value = newSetting.args ? newSetting.args.value : newSetting.value;
|
||||
const updatedSettings = this._merge(newSetting);
|
||||
if (!updatedSettings.length) return [];
|
||||
const updatedSetting = updatedSettings[0];
|
||||
|
||||
if (emit)
|
||||
await this.emit('setting-updated', updatedSetting);
|
||||
|
||||
if (emit_multi)
|
||||
await this.emit('settings-updated', new SettingsUpdatedEvent({
|
||||
updatedSettings
|
||||
}));
|
||||
|
||||
return updatedSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this setting.
|
||||
* This only exists for use by the constructor and SettingsCategory.
|
||||
*/
|
||||
_setValue(value) {
|
||||
const old_value = this.args.value;
|
||||
if (Utils.compare(value, old_value)) return [];
|
||||
this.args.value = value;
|
||||
this.changed = !Utils.compare(this.args.value, this.args.saved_value);
|
||||
|
||||
const updatedSetting = {
|
||||
const updatedSetting = new SettingUpdatedEvent({
|
||||
setting: this, setting_id: this.id,
|
||||
value, old_value
|
||||
};
|
||||
});
|
||||
|
||||
if (emit)
|
||||
await this.emit('setting-updated', new SettingUpdatedEvent(updatedSetting));
|
||||
|
||||
if (emit_multi)
|
||||
await this.emit('settings-updated', new SettingsUpdatedEvent({
|
||||
updatedSettings: [updatedSetting]
|
||||
}));
|
||||
this.setValueHook(updatedSetting);
|
||||
|
||||
return [updatedSetting];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to be called after the value changes.
|
||||
* This can be overridden by other settings types.
|
||||
* @param {SettingUpdatedEvent} updatedSetting
|
||||
*/
|
||||
setValueHook(updatedSetting) {}
|
||||
|
||||
/**
|
||||
* Sets the value of this setting.
|
||||
* This is only intended for use by settings.
|
||||
* @param {Any} value The new value of this setting
|
||||
* @param {Boolean} emit_multi Whether to emit a SettingsUpdatedEvent
|
||||
* @param {Boolean} emit Whether to emit a SettingUpdatedEvent
|
||||
* @return {Promise}
|
||||
*/
|
||||
setValue(value, emit_multi = true, emit = true) {
|
||||
const old_value = this.args.value;
|
||||
if (Utils.compare(value, old_value)) return [];
|
||||
this.args.value = value;
|
||||
this.changed = !Utils.compare(this.args.value, this.args.saved_value);
|
||||
|
||||
const updatedSetting = {
|
||||
setting: this, setting_id: this.id,
|
||||
value, old_value
|
||||
};
|
||||
async setValue(value, emit_multi = true, emit = true) {
|
||||
const updatedSettings = this._setValue(value);
|
||||
if (!updatedSettings.length) return [];
|
||||
|
||||
if (emit)
|
||||
this.emit('setting-updated', new SettingUpdatedEvent(updatedSetting));
|
||||
await this.emit('setting-updated', updatedSettings[0]);
|
||||
|
||||
if (emit_multi)
|
||||
this.emit('settings-updated', new SettingsUpdatedEvent({
|
||||
updatedSettings: [updatedSetting]
|
||||
await this.emit('settings-updated', new SettingsUpdatedEvent({
|
||||
updatedSettings
|
||||
}));
|
||||
|
||||
return [updatedSetting];
|
||||
return updatedSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,4 +12,22 @@ import Setting from './basesetting';
|
|||
|
||||
export default class NumberSetting extends Setting {
|
||||
|
||||
/**
|
||||
* The current value.
|
||||
*/
|
||||
get value() {
|
||||
return this.args.value * this.multi;
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
this.setValue(value / this.multi);
|
||||
}
|
||||
|
||||
/**
|
||||
* A number to multiply the value by.
|
||||
*/
|
||||
get multi() {
|
||||
return this.args.multi || 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,17 @@ import Setting from './basesetting';
|
|||
|
||||
export default class SliderSetting extends Setting {
|
||||
|
||||
/**
|
||||
* The current value.
|
||||
*/
|
||||
get value() {
|
||||
return this.args.value * this.multi;
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
this.setValue(value / this.multi);
|
||||
}
|
||||
|
||||
/**
|
||||
* The value to use when the setting doesn't have a value.
|
||||
*/
|
||||
|
@ -47,6 +58,13 @@ export default class SliderSetting extends Setting {
|
|||
return this.args.unit || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* A number to multiply the value by.
|
||||
*/
|
||||
get multi() {
|
||||
return this.args.multi || 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* An object mapping points on the slider to labels.
|
||||
*/
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<div class="bd-title">
|
||||
<h3 v-if="setting.text">{{setting.text}}</h3>
|
||||
<div class="bd-number">
|
||||
<input type="number" :value="setting.value" :min="setting.min" :max="setting.max" :step="setting.step" @keyup.stop @input="input"/>
|
||||
<input type="number" :value="setting.value / setting.multi" :min="setting.min" :max="setting.max" :step="setting.step" @keyup.stop @input="input"/>
|
||||
<div class="bd-number-spinner bd-flex bd-flex-col">
|
||||
<div class="bd-arrow" @click="changeBy(true)"><div class="bd-up-arrow"></div></div>
|
||||
<div class="bd-arrow" @click="changeBy(false)"><div class="bd-down-arrow"></div></div>
|
||||
|
@ -31,11 +31,11 @@
|
|||
let number = parseFloat(e.target.value)
|
||||
if (Number.isNaN(number)) return;
|
||||
|
||||
this.change(number);
|
||||
this.change(number * this.setting.multi);
|
||||
},
|
||||
changeBy(positive) {
|
||||
let step = this.setting.step == undefined ? 1 : this.settings.step;
|
||||
this.change(this.setting.value + (positive ? step : -step));
|
||||
this.change((this.setting.value + (positive ? step : -step)) * this.setting.multi);
|
||||
},
|
||||
handleWheel() {} // No idea why this works but it does
|
||||
},
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
<div class="bd-slider-bar-filled" :style="{width: `${getPointPosition() * 100}%`}"></div>
|
||||
</div>
|
||||
<div class="bd-slider-thumb-wrap">
|
||||
<div class="bd-slider-thumb" v-tooltip="{content: (setting.value || '0') + setting.unit, show: toolTip, trigger: 'manual'}" :style="{left: `${getPointPosition() * 100}%`}"></div>
|
||||
<div class="bd-slider-thumb" v-tooltip="{content: (value || '0') + setting.unit, show: toolTip, trigger: 'manual'}" :style="{left: `${getPointPosition() * 100}%`}"></div>
|
||||
</div>
|
||||
<input type="range" :value="setting.value" :min="setting.min || 0" :max="setting.max || 100" :step="setting.step || 1" @keyup.stop @input="input" />
|
||||
<input type="range" :value="value" :min="setting.min || 0" :max="setting.max || 100" :step="setting.step || 1" @keyup.stop @input="input" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -39,14 +39,19 @@
|
|||
toolTip: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
value() {
|
||||
return this.setting.value / this.setting.multi;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
input(e) {
|
||||
let number = parseFloat(e.target.value);
|
||||
if (Number.isNaN(number)) return;
|
||||
this.change(number);
|
||||
this.change(number * this.setting.multi);
|
||||
},
|
||||
getPointPosition(value) {
|
||||
return ((value || this.setting.value) - (this.setting.min || 0)) / ((this.setting.max || 100) - (this.setting.min || 0));
|
||||
return ((value || this.value) - (this.setting.min || 0)) / ((this.setting.max || 100) - (this.setting.min || 0));
|
||||
},
|
||||
showTooltip() {
|
||||
this.toolTip = true;
|
||||
|
|
Loading…
Reference in New Issue