2019-06-10 01:04:39 +02:00
|
|
|
import {SettingsConfig} from "data";
|
2019-06-19 21:24:05 +02:00
|
|
|
import Logger from "./logger";
|
2019-05-31 07:53:11 +02:00
|
|
|
import DataStore from "./datastore";
|
2019-05-30 17:44:05 +02:00
|
|
|
import Events from "./emitter";
|
2019-06-19 21:24:05 +02:00
|
|
|
import DiscordModules from "./discordmodules";
|
2019-06-25 22:36:34 +02:00
|
|
|
import Strings from "./strings";
|
2019-05-31 07:53:11 +02:00
|
|
|
|
2019-06-04 21:17:23 +02:00
|
|
|
export default new class SettingsManager {
|
2019-05-29 05:48:41 +02:00
|
|
|
|
|
|
|
constructor() {
|
2019-06-10 01:04:39 +02:00
|
|
|
this.state = {};
|
2019-06-09 22:30:33 +02:00
|
|
|
this.collections = [];
|
2019-06-08 08:35:43 +02:00
|
|
|
this.panels = [];
|
2019-06-25 22:36:34 +02:00
|
|
|
this.updateStrings = this.updateStrings.bind(this);
|
2019-05-29 05:48:41 +02:00
|
|
|
}
|
|
|
|
|
2019-05-31 07:53:11 +02:00
|
|
|
initialize() {
|
2019-06-28 22:44:08 +02:00
|
|
|
this.registerCollection("settings", "Settings", SettingsConfig);
|
2019-06-25 22:36:34 +02:00
|
|
|
Events.on("strings-updated", this.updateStrings);
|
2019-06-23 06:11:50 +02:00
|
|
|
// this.patchSections();
|
2019-06-09 22:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
registerCollection(id, name, settings, button = null) {
|
2019-06-19 21:24:05 +02:00
|
|
|
if (this.collections.find(c => c.id == id)) return Logger.error("Settings", "Already have a collection with id " + id);
|
2019-06-09 22:30:33 +02:00
|
|
|
this.collections.push({
|
|
|
|
type: "collection",
|
|
|
|
id: id,
|
|
|
|
name: name,
|
|
|
|
settings: settings,
|
|
|
|
button: button
|
|
|
|
});
|
2019-06-28 22:44:08 +02:00
|
|
|
this.setupCollection(id);
|
|
|
|
this.loadCollection(id);
|
2019-06-26 05:17:16 +02:00
|
|
|
this.updateStrings();
|
2019-06-09 22:30:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
removeCollection(id) {
|
|
|
|
const location = this.collections.findIndex(c => c.id == id);
|
2019-06-19 21:24:05 +02:00
|
|
|
if (!location < 0) return Logger.error("Settings", "No collection with id " + id);
|
2019-06-09 22:30:33 +02:00
|
|
|
this.collections.splice(location, 1);
|
2019-06-08 08:35:43 +02:00
|
|
|
}
|
2019-06-05 06:30:24 +02:00
|
|
|
|
2019-06-23 06:11:50 +02:00
|
|
|
// TODO: Move this to SettingsRenderer and also add a registerContentPanel
|
2019-06-10 05:40:35 +02:00
|
|
|
registerPanel(id, name, options) {
|
2019-06-19 21:24:05 +02:00
|
|
|
if (this.panels.find(p => p.id == id)) return Logger.error("Settings", "Already have a panel with id " + id);
|
2019-06-10 05:40:35 +02:00
|
|
|
const {element, onClick, order = 1} = options;
|
2019-06-26 20:34:01 +02:00
|
|
|
const section = {id, order, label: name, section: id};
|
2019-06-10 22:37:50 +02:00
|
|
|
if (onClick) section.clickListener = onClick;
|
|
|
|
if (element) section.element = element instanceof DiscordModules.React.Component ? () => DiscordModules.React.createElement(element, {}) : typeof(element) == "function" ? element : () => element;
|
2019-06-08 08:35:43 +02:00
|
|
|
this.panels.push(section);
|
2019-06-05 06:30:24 +02:00
|
|
|
}
|
|
|
|
|
2019-06-10 05:40:35 +02:00
|
|
|
removePanel(id) {
|
|
|
|
const location = this.panels.findIndex(c => c.id == id);
|
2019-06-19 21:24:05 +02:00
|
|
|
if (!location < 0) return Logger.error("Settings", "No collection with id " + id);
|
2019-06-10 05:40:35 +02:00
|
|
|
this.panels.splice(location, 1);
|
|
|
|
}
|
|
|
|
|
2019-06-06 21:57:25 +02:00
|
|
|
getPath(path, collectionId = "", categoryId = "") {
|
|
|
|
const collection = path.length == 3 ? path[0] : collectionId;
|
|
|
|
const category = path.length == 3 ? path[1] : path.length == 2 ? path[0] : categoryId;
|
|
|
|
const setting = path[path.length - 1];
|
|
|
|
return {collection, category, setting};
|
|
|
|
}
|
|
|
|
|
2019-06-28 22:44:08 +02:00
|
|
|
setupCollection(id) {
|
|
|
|
const collection = this.collections.find(c => c.id == id);
|
|
|
|
if (!collection) return;
|
|
|
|
const categories = collection.settings;
|
|
|
|
if (!this.state[collection.id]) this.state[collection.id] = {};
|
|
|
|
for (let cc = 0; cc < categories.length; cc++) {
|
|
|
|
const category = categories[cc];
|
|
|
|
if (category.type != "category") {if (!this.state[collection.id].hasOwnProperty(category.id)) this.state[collection.id][category.id] = category.value;}
|
|
|
|
else {
|
|
|
|
if (!this.state[collection.id].hasOwnProperty(category.id)) this.state[collection.id][category.id] = {};
|
|
|
|
for (let s = 0; s < category.settings.length; s++) {
|
|
|
|
const setting = category.settings[s];
|
|
|
|
if (!this.state[collection.id][category.id].hasOwnProperty(setting.id)) this.state[collection.id][category.id][setting.id] = setting.value;
|
|
|
|
if (setting.hasOwnProperty("disabled")) continue;
|
|
|
|
if (!setting.enableWith && !setting.disableWith) continue;
|
|
|
|
const pathString = setting.enableWith || setting.disableWith;
|
|
|
|
const path = this.getPath(pathString.split("."), collection.id, category.id);
|
|
|
|
Object.defineProperty(setting, "disabled", {
|
|
|
|
get: () => {
|
|
|
|
const other = this.state[path.collection][path.category][path.setting];
|
|
|
|
return setting.enableWith ? !other : other;
|
2019-06-10 22:37:50 +02:00
|
|
|
}
|
2019-06-28 22:44:08 +02:00
|
|
|
});
|
2019-06-05 06:30:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-31 07:53:11 +02:00
|
|
|
saveSettings() {
|
2019-06-28 22:44:08 +02:00
|
|
|
for (const collection in this.state) this.saveCollection(collection);
|
2019-05-31 07:53:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
loadSettings() {
|
2019-06-28 22:44:08 +02:00
|
|
|
for (const collection in this.state) this.loadCollection(collection);
|
|
|
|
}
|
|
|
|
|
|
|
|
saveCollection(collection) {
|
|
|
|
DataStore.setData(collection, this.state[collection]);
|
|
|
|
}
|
|
|
|
|
2019-06-30 05:09:48 +02:00
|
|
|
loadCollection(id) {
|
|
|
|
const previousState = DataStore.getData(id);
|
|
|
|
if (!previousState) return this.saveCollection(id);
|
|
|
|
for (const category in this.state[id]) {
|
|
|
|
if (!previousState[category]) Object.assign(previousState, {[category]: this.state[id][category]});
|
|
|
|
for (const setting in this.state[id][category]) {
|
2019-06-28 22:44:08 +02:00
|
|
|
if (previousState[category][setting] == undefined) continue;
|
2019-06-30 05:09:48 +02:00
|
|
|
const settingObj = this.getSetting(id, category, setting);
|
|
|
|
if (settingObj.type == "switch") this.state[id][category][setting] = previousState[category][setting];
|
|
|
|
if (settingObj.type == "dropdown") {
|
|
|
|
const exists = settingObj.options.some(o => o.value == previousState[category][setting]);
|
|
|
|
if (exists) this.state[id][category][setting] = previousState[category][setting];
|
|
|
|
}
|
2019-06-06 21:57:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-30 05:09:48 +02:00
|
|
|
this.saveCollection(id); // in case new things were added
|
2019-05-31 07:53:11 +02:00
|
|
|
}
|
|
|
|
|
2019-06-06 21:57:25 +02:00
|
|
|
onSettingChange(collection, category, id, value) {
|
|
|
|
this.state[collection][category][id] = value;
|
|
|
|
Events.dispatch("setting-updated", collection, category, id, value);
|
2019-06-28 22:44:08 +02:00
|
|
|
this.saveCollection(collection);
|
2019-06-06 06:28:43 +02:00
|
|
|
}
|
|
|
|
|
2019-06-06 21:57:25 +02:00
|
|
|
getSetting(collection, category, id) {
|
2019-06-09 22:30:33 +02:00
|
|
|
if (arguments.length == 2) return this.collections[0].find(c => c.id == arguments[0]).settings.find(s => s.id == arguments[1]);
|
2019-06-30 05:09:48 +02:00
|
|
|
return this.collections.find(c => c.id == collection).settings.find(c => c.id == category).settings.find(s => s.id == id);
|
2019-06-06 06:28:43 +02:00
|
|
|
}
|
|
|
|
|
2019-06-06 21:57:25 +02:00
|
|
|
get(collection, category, id) {
|
2019-06-09 22:30:33 +02:00
|
|
|
if (arguments.length == 2) {
|
|
|
|
id = category;
|
|
|
|
category = collection;
|
|
|
|
collection = "settings";
|
|
|
|
}
|
|
|
|
if (!this.state[collection] || !this.state[collection][category]) return false;
|
2019-06-06 21:57:25 +02:00
|
|
|
return this.state[collection][category][id];
|
|
|
|
}
|
|
|
|
|
2019-06-10 05:40:35 +02:00
|
|
|
set(collection, category, id, value) {
|
|
|
|
if (arguments.length == 3) {
|
|
|
|
value = id;
|
|
|
|
id = category;
|
|
|
|
category = collection;
|
|
|
|
collection = "settings";
|
|
|
|
}
|
|
|
|
return this.onSettingChange(collection, category, id, value);
|
|
|
|
}
|
|
|
|
|
2019-06-06 21:57:25 +02:00
|
|
|
on(collection, category, identifier, callback) {
|
|
|
|
const handler = (col, cat, id, value) => {
|
|
|
|
if (col !== collection || cat !== category || id !== identifier) return;
|
|
|
|
callback(value);
|
|
|
|
};
|
|
|
|
Events.on("setting-updated", handler);
|
|
|
|
return () => {Events.off("setting-updated", handler);};
|
2019-06-06 06:28:43 +02:00
|
|
|
}
|
2019-06-25 22:36:34 +02:00
|
|
|
|
|
|
|
updateStrings() {
|
|
|
|
// Update settings collections
|
|
|
|
for (let c = 0; c < this.collections.length; c++) {
|
|
|
|
const collection = this.collections[c];
|
|
|
|
const CS = Strings.Collections[collection.id];
|
|
|
|
if (!CS) continue;
|
|
|
|
collection.name = CS.name || collection.name;
|
|
|
|
const categories = this.collections[c].settings;
|
|
|
|
for (let cat = 0; cat < categories.length; cat++) {
|
|
|
|
const category = categories[cat];
|
|
|
|
const CatStr = CS[category.id];
|
|
|
|
if (!CatStr) continue;
|
|
|
|
category.name = CatStr.name || category.name;
|
|
|
|
for (let s = 0; s < category.settings.length; s++) {
|
|
|
|
const setting = category.settings[s];
|
|
|
|
const SetStr = CatStr[setting.id];
|
|
|
|
if (!SetStr) continue;
|
|
|
|
setting.name = SetStr.name || setting.name;
|
|
|
|
setting.note = SetStr.note || setting.note;
|
2019-06-30 05:09:48 +02:00
|
|
|
if (!setting.options) continue;
|
|
|
|
for (const opt of setting.options) {
|
|
|
|
opt.label = SetStr.options[opt.id] || SetStr.options[opt.value] || opt.label;
|
|
|
|
}
|
2019-06-25 22:36:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update panel labels
|
|
|
|
for (let p = 0; p < this.panels.length; p++) {
|
|
|
|
const panel = this.panels[p];
|
|
|
|
const Str = Strings.Panels[panel.id];
|
2019-06-26 20:34:01 +02:00
|
|
|
panel.label = Str || panel.label;
|
2019-06-25 22:36:34 +02:00
|
|
|
}
|
|
|
|
}
|
2019-05-29 05:48:41 +02:00
|
|
|
};
|