diff --git a/package.json b/package.json
index 27e92cd..9cedec8 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"url": "https://github.com/JulienMaille/dribbblish-dynamic-theme/issues"
},
"devDependencies": {
+ "@material-icons/svg": "^1.0.22",
"clean-webpack-plugin": "^4.0.0",
"sass": "^1.43.4",
"sass-loader": "^12.2.0",
diff --git a/src/icons/arrow-down.svg b/src/icons/arrow-down.svg
deleted file mode 100644
index 68e8fda..0000000
--- a/src/icons/arrow-down.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/chevron-down.light.svg b/src/icons/chevron-down.light.svg
deleted file mode 100644
index a66a34d..0000000
--- a/src/icons/chevron-down.light.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/chevron-down.svg b/src/icons/chevron-down.svg
deleted file mode 100644
index 70ddaf9..0000000
--- a/src/icons/chevron-down.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/code.svg b/src/icons/code.svg
deleted file mode 100644
index 1892947..0000000
--- a/src/icons/code.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/cog.svg b/src/icons/cog.svg
deleted file mode 100644
index 1d22a59..0000000
--- a/src/icons/cog.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/folder-open.light.svg b/src/icons/folder-open.light.svg
deleted file mode 100644
index 9dccaa7..0000000
--- a/src/icons/folder-open.light.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/folder-open.svg b/src/icons/folder-open.svg
deleted file mode 100644
index 58884f9..0000000
--- a/src/icons/folder-open.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/folder.light.svg b/src/icons/folder.light.svg
deleted file mode 100644
index 79f5c39..0000000
--- a/src/icons/folder.light.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/folder.svg b/src/icons/folder.svg
deleted file mode 100644
index f918b31..0000000
--- a/src/icons/folder.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/note.svg b/src/icons/note.svg
deleted file mode 100644
index 74aaa85..0000000
--- a/src/icons/note.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/palette.svg b/src/icons/palette.svg
deleted file mode 100644
index 1dc5586..0000000
--- a/src/icons/palette.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/times.light.svg b/src/icons/times.light.svg
deleted file mode 100644
index a2a32db..0000000
--- a/src/icons/times.light.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/times.svg b/src/icons/times.svg
deleted file mode 100644
index 5c47bc2..0000000
--- a/src/icons/times.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/undo.svg b/src/icons/undo.svg
deleted file mode 100644
index 7397f55..0000000
--- a/src/icons/undo.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/icons/wifi-slash.svg b/src/icons/wifi-slash.svg
deleted file mode 100644
index e02f87a..0000000
--- a/src/icons/wifi-slash.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/src/js/ConfigMenu.js b/src/js/ConfigMenu.js
index 3c34525..01ddf1d 100644
--- a/src/js/ConfigMenu.js
+++ b/src/js/ConfigMenu.js
@@ -1,10 +1,7 @@
import $ from "jquery";
import { renderMD } from "./Util";
-
-import iconTimesLight from "icon/times.light";
-import iconChevronDown from "icon/chevron-down";
-import iconUndo from "icon/undo";
+import { icons } from "./Icons";
export default class ConfigMenu {
/**
@@ -79,7 +76,7 @@ export default class ConfigMenu {
container.id = "dribbblish-config";
container.innerHTML = /* html */ `
-
+
Dribbblish Settings
@@ -122,7 +119,7 @@ export default class ConfigMenu {
@@ -411,7 +408,7 @@ export default class ConfigMenu {
areaElem.innerHTML = /* html */ `
`;
diff --git a/src/js/Dribbblish.js b/src/js/Dribbblish.js
index b0aa996..6885227 100644
--- a/src/js/Dribbblish.js
+++ b/src/js/Dribbblish.js
@@ -1,6 +1,7 @@
import ConfigMenu from "./ConfigMenu";
import Info from "./Info";
import Loader from "./Loader";
+import { icons } from "./Icons";
export default class Dribbblish {
/**
@@ -22,6 +23,9 @@ export default class Dribbblish {
/** @type {Loader} */
loader;
+ /** @type {Icons} */
+ icons;
+
/** @type {Object.} */
#listeners = {};
@@ -32,6 +36,7 @@ export default class Dribbblish {
this.config = new ConfigMenu();
this.info = new Info();
this.loader = new Loader();
+ this.icons = icons;
const interval = setInterval(() => {
if (document.querySelector("#main") == null || Spicetify?.showNotification == undefined || !this.info.isReady()) return;
diff --git a/src/js/Folders.js b/src/js/Folders.js
index 6769041..6be6a08 100644
--- a/src/js/Folders.js
+++ b/src/js/Folders.js
@@ -1,8 +1,5 @@
import { waitForElement, htmlToNode } from "./Util";
-
-import iconFolder from "icon/folder.light";
-import iconFolderOpen from "icon/folder-open.light";
-import iconNote from "icon/note";
+import { icons } from "./Icons";
waitForElement([`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`, `.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"] li`], ([root, firstItem]) => {
const listElem = firstItem.parentElement;
@@ -30,7 +27,7 @@ waitForElement([`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`, `
if (!link.querySelector("img")) elem = document.createElement("img");
elem.src = picture;
} else {
- if (!link.querySelector("svg")) elem = htmlToNode(iconNote().replace(/<\/svg>/, `${title}$1`));
+ if (!link.querySelector("svg")) elem = htmlToNode(icons.get("note", { title }));
}
} else if (app === "folder") {
const base64 = localStorage.getItem("dribbblish:folder-image:" + uid);
@@ -38,7 +35,7 @@ waitForElement([`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`, `
if (!link.querySelector("img")) elem = document.createElement("img");
elem.src = base64;
} else {
- if (!link.querySelector("svg")) elem = htmlToNode(iconFolder().replace(/<\/svg>/, `${title}$1`));
+ if (!link.querySelector("svg")) elem = htmlToNode(icons.get("folder", { title }));
}
} else {
continue;
diff --git a/src/js/Icons.js b/src/js/Icons.js
new file mode 100644
index 0000000..f71a237
--- /dev/null
+++ b/src/js/Icons.js
@@ -0,0 +1,80 @@
+import { parseSync as parseSVG, stringify as stringifySVG } from "svgson";
+
+export default class Icons {
+ /** @typedef {"baseline" | "outline" | "round" | "sharp" | "twotone"} IconStyle */
+
+ /**
+ * @typedef {Object} IconOptions
+ * @property {IconStyle} [style="round"]
+ * @property {Number} [size=16]
+ * @property {Number} [scale=1]
+ * @property {String} [fill="currentColor"]
+ * @property {Boolean} [base64=false]
+ */
+
+ /** @type {Object.>} */
+ #icons;
+
+ constructor() {
+ this.#icons = process.env.DRIBBBLISH_ICONS;
+ }
+
+ /**
+ * @param {String} name icon name lowercase with dashes like `ac-unit`
+ * @param {IconOptions} options
+ * @see https://fonts.google.com/icons?selected=Material+Icons
+ * @returns
+ */
+ get(name, options) {
+ /** @type {IconOptions} */
+ const defaultOptions = {
+ style: "round",
+ size: 16,
+ scale: 1,
+ fill: "currentColor",
+ base64: false
+ };
+ options = { ...defaultOptions, ...options };
+
+ if (!this.#icons.hasOwnProperty(name)) throw new Error(`Icon "${name}" does not exist`);
+ let svg;
+ if (typeof this.#icons[name] == "string") {
+ svg = parseSVG(this.#icons[name]);
+ } else {
+ if (!this.#icons[name].hasOwnProperty(options.style)) throw new Error(`Icon "${name}" does not have style "${options.style}"`);
+ svg = parseSVG(this.#icons[name][options.style]);
+ }
+
+ svg.attributes.type = "dribbblish-icon";
+ svg.attributes.fill = options.fill;
+ svg.attributes.width = options.size;
+ svg.attributes.height = options.size;
+
+ if (options.scale != 1) {
+ svg.children = svg.children.map((child) => {
+ child.attributes.style = `transform: scale(${options.scale}); transform-origin: center;`;
+ return child;
+ });
+ }
+
+ if (options.title != null) {
+ console.log(options);
+ console.log(svg);
+ svg.children.push({
+ name: "title",
+ type: "element",
+ value: "",
+ children: [{ name: "", type: "text", value: options.title, attributes: {}, children: [] }]
+ });
+ console.log(svg);
+ }
+
+ if (options.base64) {
+ return `data:image/svg+xml;base64,${Buffer.from(stringifySVG(svg)).toString("base64")}`;
+ } else {
+ return stringifySVG(svg);
+ }
+ }
+}
+
+export const icons = new Icons();
diff --git a/src/js/Info.js b/src/js/Info.js
index 977cc26..65f92bb 100644
--- a/src/js/Info.js
+++ b/src/js/Info.js
@@ -1,4 +1,5 @@
import $ from "jquery";
+import { icons } from "./Icons";
import { waitForElement } from "./Util";
@@ -7,7 +8,7 @@ export default class Info {
* @typedef {Object} DribbblishInfo
* @property {String} [text]
* @property {String} [tooltip]
- * @property {String} [icon]
+ * @property {String} [icon] svg string or icon name
* @property {DribbblishInfoColor} [color]
* @property {Number} [order=0] order < 0 = More to the Left | order > 0 = More to the Right
* @property {onClick} [onClick]
@@ -74,6 +75,7 @@ export default class Info {
if (bg != null) elem.style.backgroundColor = bg;
}
if (info.order != 0) elem.style.order = info.order;
+ if (!info.icon.startsWith("