diff --git a/src/js/ConfigMenu.js b/src/js/ConfigMenu.js
index b01c1b2..815bcc6 100644
--- a/src/js/ConfigMenu.js
+++ b/src/js/ConfigMenu.js
@@ -1,5 +1,7 @@
import svgUndo from "../svg/undo.svg";
+const IGNORED_TYPES = ["button"];
+
export default class ConfigMenu {
/**
* @typedef {Object} DribbblishConfigItem
@@ -7,7 +9,7 @@ export default class ConfigMenu {
* @property {String|DribbblishConfigArea} [area={name: "Main Settings", order: 0}]
* @property {any} [data={}]
* @property {Number} [order=0] order < 0 = Higher up | order > 0 = Lower Down
- * @property {String} key
+ * @property {String} [key] defaults to $AREA_$NAME. e.g: About_Info
* @property {String} name
* @property {String} [description=""]
* @property {any} [defaultValue]
@@ -98,14 +100,24 @@ export default class ConfigMenu {
elem.setAttribute("hidden", options.hidden);
if (options.childOf) elem.setAttribute("parent", options.childOf);
elem.innerHTML = /* html */ `
-
- ${options.name}
- ${["button"].includes(options.type) ? "" : /* html */ ``}
-
-
-
+ ${
+ options.name != null && options.description != null
+ ? /* html */ `
+
+ `
+ : ""
+ }
+
+
+
`;
if (options.insertOnTop && parent.children.length > 0) {
@@ -152,6 +164,7 @@ export default class ConfigMenu {
// Set Defaults
options = { ...defaultOptions, ...options };
if (typeof options.area == "string") options.area = { name: options.area, order: 0 };
+ if (options.key == null) options.key = `${options.area.name}_${options.name}`.split(" ").join("_");
options.description = options.description
.split("\n")
.filter((line) => line.trim() != "")
@@ -407,4 +420,15 @@ export default class ConfigMenu {
getOptions(key) {
return this.#config[key];
}
+
+ export() {
+ const obj = {};
+ Object.entries(this.#config).forEach(([key, val]) => {
+ if (IGNORED_TYPES.includes(val.type)) return;
+ if (!obj.hasOwnProperty(val.area.name)) obj[val.area.name] = {};
+ obj[val.area.name][key] = this.get(key);
+ });
+
+ return obj;
+ }
}
diff --git a/src/js/main.js b/src/js/main.js
index ded9a62..6d18dbc 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -347,10 +347,12 @@ DribbblishShared.config.register({
// waitForElement because Spicetify is not initialized at startup
waitForElement(["#main"], () => {
+ DribbblishShared.config.registerArea({ name: "About", order: 999, toggleable: false });
+
DribbblishShared.config.register({
- area: { name: "About", order: 999, toggleable: false },
+ area: "About",
type: "button",
- key: "aboutDribbblish",
+ key: "aboutDribbblishInfo",
name: "Info",
description: `
OS: ${capitalizeFirstLetter(Spicetify.Platform.PlatformData.os_name)} v${Spicetify.Platform.PlatformData.os_version}
@@ -359,11 +361,81 @@ waitForElement(["#main"], () => {
Dribbblish: v${process.env.DRIBBBLISH_VERSION}-${process.env.COMMIT_HASH}
`,
data: "Copy",
- onChange: (val) => {
- copyToClipboard(DribbblishShared.config.getOptions("aboutDribbblish").description);
+ onChange: () => {
+ copyToClipboard(DribbblishShared.config.getOptions("aboutDribbblishInfo").description);
Spicetify.showNotification("Copied Versions");
}
});
+
+ DribbblishShared.config.register({
+ area: "About",
+ type: "button",
+ key: "aboutDribbblishBugs",
+ name: "Report Bugs",
+ data: "Create Report",
+ onChange: () => {
+ const reportBody = `
+ **Describe the bug**
+ A clear and concise description of what the bug is.
+
+ **To Reproduce**
+ Steps to reproduce the behavior:
+
+ **Screenshots**
+ If applicable, add screenshots to help explain your problem.
+
+ **Logs**
+ Add logs from console. To do that
+ 1. Run \`spicetify enable-devtool\` in terminal
+ 2. Spotify will be restarted
+ 3. Hit Ctrl + Shift + I to open DevTools window
+ 4. Navigate to tab Console
+ 5. Copy console window content.
+
+ \`\`\`console
+ (Please paste here console logs or attach a screenshot)
+ \`\`\`
+
+ ---
+
+ ### Info for Contributors:
+
+ **Versions**
+ ${DribbblishShared.config.getOptions("aboutDribbblishInfo").description}
+
+ **Extensions**
+ ${$(`script[src^="extensions/"]`)
+ .toArray()
+ .map((e) => `- ${e.src.split("/").slice(-1)[0]}`)
+ .join("\n")}
+
+ **Settings**
+ \`\`\`json
+ ${JSON.stringify(DribbblishShared.config.export(), null, 4)}
+ \`\`\`
+ `
+ .split("\n")
+ .map((line) => line.replace(/^ {16}/, ""))
+ .join("\n");
+
+ const reportURL = new URL("https://github.com/JulienMaille/dribbblish-dynamic-theme/issues/new");
+ reportURL.searchParams.set("labels", "bug");
+ reportURL.searchParams.set("body", reportBody);
+
+ window.open(reportURL.toString(), "_blank");
+ }
+ });
+
+ DribbblishShared.config.register({
+ area: "About",
+ type: "button",
+ key: "aboutDribbblishChangelog",
+ name: "Changelog",
+ data: "Open",
+ onChange: () => window.open("https://github.com/JulienMaille/dribbblish-dynamic-theme/releases", "_blank")
+ });
+
+ // TODO: Add Export / Import buttons for config
});
function capitalizeFirstLetter(string) {
diff --git a/src/styles/ConfigMenu.scss b/src/styles/ConfigMenu.scss
index dff2078..05ecd60 100644
--- a/src/styles/ConfigMenu.scss
+++ b/src/styles/ConfigMenu.scss
@@ -87,11 +87,10 @@
position: relative;
width: 100%;
height: min-content;
- display: grid;
- grid-template-columns: 1fr auto;
- grid-template-rows: auto auto;
- gap: 5px 10px;
- grid-template-areas: "header input" "description input";
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 10px;
&[parent] {
padding-left: 16px;
@@ -101,38 +100,49 @@
display: none;
}
- > {
- .x-settings-title {
- display: flex;
- gap: 10px;
- align-items: center;
- grid-area: header;
- margin: 0px;
- height: min-content;
- position: relative;
- bottom: 0px;
+ .dribbblish-config-item-header {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 5px;
- &.no-desc {
- bottom: -10px;
+ > {
+ & [empty="true"] {
+ display: none;
}
- .dribbblish-config-item-reset {
- padding: 0px;
- color: spiceColor("text");
- width: 1em;
- height: 1em;
+ .x-settings-title {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ grid-area: header;
+ margin: 0px;
+ height: min-content;
+ position: relative;
+ bottom: 0px;
+
+ .dribbblish-config-item-reset {
+ padding: 0px;
+ color: spiceColor("text");
+ width: 1em;
+ height: 1em;
+ }
+ }
+
+ .main-type-mesto {
+ grid-area: description;
+ height: min-content;
+ color: spiceColor("subtext");
+ }
+
+ .x-settings-secondColumn {
+ grid-area: input;
}
}
+ }
- .main-type-mesto {
- grid-area: description;
- height: min-content;
- color: spiceColor("subtext");
- }
-
- .x-settings-secondColumn {
- grid-area: input;
- }
+ .dribbblish-config-item-input {
+ min-width: fit-content;
}
}
}