From 47a5a15d8e25513c9e2b7f8ff724ccf3acd6878d Mon Sep 17 00:00:00 2001 From: Send_Nukez Date: Tue, 12 Oct 2021 06:36:50 +0200 Subject: [PATCH] refactor config & add ability for config items to have children wich can be hidden depending on parent's value --- dribbblish.js | 176 +++++++++++++++++++++++++++++++------------------- user.css | 9 +++ 2 files changed, 120 insertions(+), 65 deletions(-) diff --git a/dribbblish.js b/dribbblish.js index d3efb30..7c461bf 100644 --- a/dribbblish.js +++ b/dribbblish.js @@ -4,19 +4,43 @@ class ConfigMenu { /** * @typedef {Object} DribbblishConfigOptions * @property {"checkbox" | "select" | "button" | "slider" | "number" | "text" | "time"} type - * @property {String?} area - * @property {any?} data - * @property {String?} key - * @property {String?} name - * @property {String?} description - * @property {any?} defaultValue - * @property {Boolean?} insertOnTop - * @property {Function?} onAppended - * @property {Function?} onChange + * @property {String} [area="Main Settings"] + * @property {any} [data={}] + * @property {String} key + * @property {String} name + * @property {String} [description=""] + * @property {any} [defaultValue] + * @property {Boolean} [hidden=false] + * @property {Boolean} [insertOnTop=false] + * @property {Boolean} [fireInitialChange=true] + * @property {showChildren} [showChildren] + * @property {onAppended} [onAppended] + * @property {onChange} [onChange] + * @property {DribbblishConfigOptions[]} [children=[]] */ + /** + * @callback showChildren + * @param {any} value + * @returns {Boolean | String[]} + */ + + /** + * @callback onAppended + * @returns {void} + */ + + /** + * @callback onChange + * @param {any} value + * @returns {void} + */ + + /** @type {Object.} */ + #config; + constructor() { - this.config = {}; + this.#config = {}; this.configButton = new Spicetify.Menu.Item("Dribbblish config", false, () => DribbblishShared.config.open()); this.configButton.register(); @@ -62,8 +86,10 @@ class ConfigMenu { const elem = document.createElement("div"); elem.classList.add("dribbblish-config-item"); - elem.setAttribute("key", `dribbblish:config:${options.key}`); + elem.setAttribute("key", options.key); elem.setAttribute("type", options.type); + elem.setAttribute("hidden", options.hidden); + if (options.childOf) elem.setAttribute("parent", options.childOf); elem.innerHTML = /* html */ `

${options.name}

@@ -83,24 +109,37 @@ class ConfigMenu { * @param {DribbblishConfigOptions} options */ register(options) { - options = { - ...{ - area: "Main Settings", - data: {}, - key: cyrb53Hash(options.name ?? ""), - name: "", - description: "", - insertOnTop: false, - onAppended: () => {}, - onChange: () => {} - }, - ...options + const defaultOptions = { + hidden: false, + area: "Main Settings", + data: {}, + name: "", + description: "", + insertOnTop: false, + fireInitialChange: true, + showChildren: () => true, + onAppended: () => {}, + onChange: () => {}, + children: [] }; - var fireChange = true; + // Set Defaults + options = { ...defaultOptions, ...options }; + options._onChange = options.onChange; + options.onChange = (val) => { + options._onChange(val); + const show = options.showChildren(val); + options.children.forEach((child) => this.setHidden(child.key, !show)); + }; + options.children = options.children.map((child) => { + return { ...defaultOptions, ...child, area: options.area, childOf: options.key }; + }); + + this.#config[options.key] = options; + this.#config[options.key].value = localStorage.getItem(`dribbblish:config:${options.key}`) ?? JSON.stringify(options.defaultValue); if (options.type == "checkbox") { const input = /* html */ ` - + @@ -113,21 +152,23 @@ class ConfigMenu { }); } else if (options.type == "select") { // Validate - const val = this.get(options.key, options.defaultValue); - if (val < 0 || val > options.data.length - 1) this.set(options.key, options.defaultValue); + const val = this.get(options.key); + if (val < 0 || val > options.data.length - 1) this.set(options.key); const input = /* html */ ` `; this.addInputHTML({ ...options, input }); document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("change", (e) => { - this.set(options.key, e.target.value); + this.set(options.key, Number(e.target.value)); options.onChange(this.get(options.key)); }); } else if (options.type == "button") { + options.fireInitialChange = false; + const input = /* html */ `