Updated config Interface

This commit is contained in:
Send_Nukez 2021-10-06 07:39:12 +02:00
parent db1ad17ffa
commit 507d283d00
3 changed files with 279 additions and 120 deletions

View file

@ -176,7 +176,14 @@ function toggleDark(setDark) {
/* Init with current system light/dark mode */ /* Init with current system light/dark mode */
let systemDark = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--system_is_dark")) == 1; let systemDark = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--system_is_dark")) == 1;
DribbblishShared.config.registerSelect("Theme", "theme", ["System", "Dark", "Light"], 0, (val) => { DribbblishShared.config.register({
type: "select",
options: ["System", "Dark", "Light"],
key: "theme",
name: "Theme",
description: "Select Dark / Bright mode",
defaultValue: 0,
onChange: (val) => {
switch (val) { switch (val) {
case 0: case 0:
toggleDark(systemDark); toggleDark(systemDark);
@ -188,6 +195,7 @@ DribbblishShared.config.registerSelect("Theme", "theme", ["System", "Dark", "Lig
toggleDark(false); toggleDark(false);
break; break;
} }
}
}); });
function updateColors(textColHex, sideColHex) { function updateColors(textColHex, sideColHex) {
@ -321,11 +329,15 @@ hookCoverChange(false);
document.querySelector(".main-userWidget-box").append(upd) document.querySelector(".main-userWidget-box").append(upd)
upd.append(`Theme UPD v${data.tag_name} avail.`) upd.append(`Theme UPD v${data.tag_name} avail.`)
upd.setAttribute("title", `Changes: ${data.name}`) upd.setAttribute("title", `Changes: ${data.name}`)
DribbblishShared.configButton.addItem( DribbblishShared.config.register({
new Spicetify.Menu.Item("Update", false, (self) => { insertOnTop: true,
type: "button",
name: "Update",
description: "Open the GitHub Page with Installation instructions / Commands.",
onChange: () => {
window.open("https://github.com/JulienMaille/dribbblish-dynamic-theme#install", "_blank"); window.open("https://github.com/JulienMaille/dribbblish-dynamic-theme#install", "_blank");
}) }
); });
} }
}).catch(err => { }).catch(err => {
// Do something for an error here // Do something for an error here

View file

@ -1,108 +1,174 @@
// Hide popover message // Hide popover message
// document.getElementById("popover-container").style.height = 0; // document.getElementById("popover-container").style.height = 0;
const DribbblishShared = { class ConfigMenu {
configButton: new Spicetify.Menu.SubMenu("Dribbblish", []), constructor() {
config: { this.config = {};
register: (name, key, defaultValue, update) => { this.configButton = new Spicetify.Menu.Item("Dribbblish config", false, () => DribbblishShared.config.open());
const menuItem = new Spicetify.Menu.Item(name, defaultValue, (self) => { this.configButton.register();
self.setState(!self.isEnabled);
DribbblishShared.config.toggle(key); const container = document.createElement("div");
container.id = "dribbblish-config";
container.innerHTML = /* html */ `
<div class="dribbblish-config-container">
<button aria-label="Close" class="dribbblish-config-close main-trackCreditsModal-closeBtn">
<svg width="18" height="18" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M31.098 29.794L16.955 15.65 31.097 1.51 29.683.093 15.54 14.237 1.4.094-.016 1.508 14.126 15.65-.016 29.795l1.414 1.414L15.54 17.065l14.144 14.143" fill="currentColor" fill-rule="evenodd"></path></svg>
</button>
<h1>Dribbblish Settings</h1>
</div>
<div class="dribbblish-config-backdrop"></div>
`;
document.body.appendChild(container);
document.querySelector(".dribbblish-config-close").addEventListener("click", () => DribbblishShared.config.close());
document.querySelector(".dribbblish-config-backdrop").addEventListener("click", () => DribbblishShared.config.close());
}
open() {
document.getElementById("dribbblish-config").setAttribute("active", "");
}
close() {
document.getElementById("dribbblish-config").removeAttribute("active");
}
/** @private */
addInputHTML({ type, key, name, description, input, insertOnTop }) {
const elem = document.createElement("div");
elem.classList.add("dribbblish-config-item");
elem.setAttribute("key", `dribbblish:config:${key}`);
elem.setAttribute("type", type);
elem.innerHTML = /* html */ `
<h2 class="x-settings-title main-type-cello" as="h2">${name}</h2>
<label class="main-type-mesto" as="label" for="dribbblish-config-input-${key}" style="color: var(--spice-subtext);">${description}</label>
<label class="x-toggle-wrapper x-settings-secondColumn">
${input}
</label>
`;
if (insertOnTop && document.querySelector(".dribbblish-config-item")) {
console.log("before");
document.querySelector(".dribbblish-config-container").insertBefore(elem, document.querySelector(".dribbblish-config-item:first-of-type"));
} else {
document.querySelector(".dribbblish-config-container").appendChild(elem);
}
}
register({ type, options, key, name, description, defaultValue, insertOnTop, onChange }) {
if (!key) key = cyrb53Hash(name);
var fireChange = true;
if (type == "checkbox") {
const input = /* html */ `
<input id="dribbblish-config-input-${key}" class="x-toggle-input" type="checkbox"${this.get(key, defaultValue) ? " checked" : ""}>
<span class="x-toggle-indicatorWrapper">
<span class="x-toggle-indicator"></span>
</span>
`;
this.addInputHTML({ type, key, name, description, input, insertOnTop });
document.getElementById(`dribbblish-config-input-${key}`).addEventListener("change", (e) => {
this.set(key, e.target.checked);
onChange(this.get(key));
}); });
DribbblishShared.configButton.addItem(menuItem); } else if (type == "select") {
const input = /* html */ `
<span class="x-settings-secondColumn">
<select class="main-dropDown-dropDown" id="dribbblish-config-input-${key}">
${options.map((option, i) => `<option value="${i}"${this.get(key, defaultValue) == i ? " selected" : ""}>${option}</option>`).join("")}
</select>
</span>
`;
this.addInputHTML({ type, key, name, description, input, insertOnTop });
if (localStorage.getItem(`dribbblish:config:${key}`) == null) localStorage.setItem(`dribbblish:config:${key}`, defaultValue); document.getElementById(`dribbblish-config-input-${key}`).addEventListener("change", (e) => {
this.set(key, e.target.value);
DribbblishShared.configData[key] = { onChange(this.get(key));
menuItem,
update
};
DribbblishShared.config.update(key);
},
registerSelect: (name, key, choices, defaultChoice, update) => {
const menuItem = new Spicetify.Menu.SubMenu(name, []);
const menuItems = choices.map((choice, i) => {
const subItem = new Spicetify.Menu.Item(choice, i == defaultChoice, (self) => {
self.setState(!self.isEnabled);
DribbblishShared.config.set(key, i);
}); });
menuItem.addItem(subItem); } else if (type == "button") {
return subItem; const input = /* html */ `
<span class="x-settings-secondColumn">
<button class="main-buttons-button main-button-primary" type="button" id="dribbblish-config-input-${key}">
<div class="x-settings-buttonContainer">
<span>${name}</span>
</div>
</button>
</span>
`;
this.addInputHTML({ type, key, name, description, input, insertOnTop });
document.getElementById(`dribbblish-config-input-${key}`).addEventListener("click", (e) => {
onChange(true);
}); });
DribbblishShared.configButton.addItem(menuItem); fireChange = false;
menuItem.register(); } else {
throw new Error(`Config Type "${type}" invalid`);
}
if (localStorage.getItem(`dribbblish:config:${key}`) == null) localStorage.setItem(`dribbblish:config:${key}`, defaultChoice); if (fireChange) onChange(this.get(key, defaultValue));
}
DribbblishShared.configData[key] = { get(key, defaultValue) {
subItems: menuItems,
menuItem,
update
};
DribbblishShared.config.update(key);
},
get: (key) => {
const val = localStorage.getItem(`dribbblish:config:${key}`); const val = localStorage.getItem(`dribbblish:config:${key}`);
if (val == "true" || val == "false") return val == "true"; if (val == null) return defaultValue;
if (!isNaN(val) && !isNaN(parseInt(val))) return parseInt(val);
}, if (val == "true" || val == "false") return val == "true"; // Boolean
set: (key, val) => { if (!isNaN(val) && !isNaN(parseInt(val))) return parseInt(val); // Number
if (DribbblishShared.configData[key].hasOwnProperty("subItems")) { return val; // String
DribbblishShared.configData[key].subItems.forEach((item, i) => {
item.setState(val == i);
});
} else {
DribbblishShared.configData[key].menuItem.setState(val);
} }
set(key, val) {
localStorage.setItem(`dribbblish:config:${key}`, val); localStorage.setItem(`dribbblish:config:${key}`, val);
DribbblishShared.config.update(key); }
}, }
toggle: (key) => {
DribbblishShared.config.set(key, !DribbblishShared.config.get(key));
if (DribbblishShared.configData[key].hasOwnProperty("subItems")) { class _DribbblishShared {
// Can't toggle lists constructor() {
} else { this.config = new ConfigMenu();
DribbblishShared.configData[key].menuItem.setState(DribbblishShared.config.get(key));
} }
},
update: (key) => {
const val = DribbblishShared.config.get(key);
if (DribbblishShared.configData[key].hasOwnProperty("subItems")) {
DribbblishShared.configData[key].subItems.forEach((item, i) => {
item.setState(val == i);
});
} else {
DribbblishShared.configData[key].menuItem.setState(val);
} }
DribbblishShared.configData[key].update(val); const DribbblishShared = new _DribbblishShared();
}
},
configData: {}
};
DribbblishShared.configButton.register();
// Initialize Config DribbblishShared.config.register({
DribbblishShared.config.register("Right expanded cover", "rightBigCover", true, (value) => { type: "checkbox",
if (value) { key: "rightBigCover",
name: "Right expanded cover",
description: "Have the expanded cover Image on the right instead of onn the left.",
defaultValue: true,
onChange: (val) => {
if (val) {
document.documentElement.classList.add("right-expanded-cover"); document.documentElement.classList.add("right-expanded-cover");
} else { } else {
document.documentElement.classList.remove("right-expanded-cover"); document.documentElement.classList.remove("right-expanded-cover");
} }
}
}); });
DribbblishShared.config.register("Round Sidebar Icons", "roundSidebarIcons", false, (value) => { DribbblishShared.config.register({
if (value) { type: "checkbox",
key: "roundSidebarIcons",
name: "Round Sidebar Icons",
description: "If the Sidebar Iconns should be round instead of square",
defaultValue: false,
onChange: (val) => {
if (val) {
document.documentElement.style.setProperty("--sidebar-icons-border-radius", "50%"); document.documentElement.style.setProperty("--sidebar-icons-border-radius", "50%");
} else { } else {
document.documentElement.style.setProperty("--sidebar-icons-border-radius", "var(--image-radius)"); document.documentElement.style.setProperty("--sidebar-icons-border-radius", "var(--image-radius)");
} }
}
}); });
DribbblishShared.config.open();
waitForElement(["#main"], () => { waitForElement(["#main"], () => {
DribbblishShared.config.registerSelect("Windows Top Bar", "winTopBar", ["None", "None (With Top Padding)", "Solid", "Transparent"], 0, (value) => { DribbblishShared.config.register({
switch (value) { type: "select",
options: ["None", "None (With Top Padding)", "Solid", "Transparent"],
key: "winTopBar",
name: "Windows Top Bar",
description: "Have differennt top Bars (Ore none at all)",
defaultValue: 0,
onChange: (val) => {
switch (val) {
case 0: case 0:
document.getElementById("main").setAttribute("top-bar", "none"); document.getElementById("main").setAttribute("top-bar", "none");
break; break;
@ -116,18 +182,32 @@ waitForElement(["#main"], () => {
document.getElementById("main").setAttribute("top-bar", "transparent"); document.getElementById("main").setAttribute("top-bar", "transparent");
break; break;
} }
}
}); });
}); });
function waitForElement(els, func, timeout = 100) { function waitForElement(els, func, timeout = 100) {
const queries = els.map(el => document.querySelector(el)); const queries = els.map((el) => document.querySelector(el));
if (queries.every(a => a)) { if (queries.every((a) => a)) {
func(queries); func(queries);
} else if (timeout > 0) { } else if (timeout > 0) {
setTimeout(waitForElement, 300, els, func, --timeout); setTimeout(waitForElement, 300, els, func, --timeout);
} }
} }
function cyrb53Hash(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
waitForElement([ waitForElement([
`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`, `.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`,
`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"] li` `.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"] li`

View file

@ -274,14 +274,14 @@ span.artist-artistVerifiedBadge-badge svg > path:last-of-type {
} }
.cover-art, .cover-art,
.main-userWidget-box,
.view-homeShortcutsGrid-shortcut, .view-homeShortcutsGrid-shortcut,
:not(.view-homeShortcutsGrid-imageWrapper) > .main-image-image:not(.main-avatar-image) { :not(.view-homeShortcutsGrid-imageWrapper) > .main-image-image:not(.main-avatar-image) {
border-radius: var(--image-radius) !important; border-radius: var(--image-radius) !important;
} }
.main-userWidget-box,
.main-avatar-userIcon,
.main-avatar-image, .main-avatar-image,
.main-avatar-userIcon,
.view-homeShortcutsGrid-shortcutLink { .view-homeShortcutsGrid-shortcutLink {
border-radius: var(--sidebar-icons-border-radius) !important; border-radius: var(--sidebar-icons-border-radius) !important;
} }
@ -699,6 +699,73 @@ li.GlueDropTarget {
pointer-events: none; pointer-events: none;
} }
#dribbblish-config {
display: none;
z-index: 99999;
position: absolute;
inset: 0px;
align-items: center;
justify-content: center;
color: var(--spice-text);
}
#dribbblish-config[active] {
display: flex;
}
#dribbblish-config .dribbblish-config-container {
z-index: 1;
position: relative;
max-width: 80%;
background-color: rgba(var(--spice-rgb-main), 0.85);
backdrop-filter: blur(3px);
padding: 20px 15px;
border-radius: var(--main-corner-radius);
display: flex;
gap: 5px;
flex-direction: column;
align-items: center;
justify-content: center;
}
#dribbblish-config .dribbblish-config-item {
position: relative;
width: 100%;
padding: 0px 50px;
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: 1fr 1fr;
gap: 0px 10px;
grid-template-areas:
"header input"
"description input";
}
#dribbblish-config .dribbblish-config-item > .x-settings-title {
grid-area: header;
}
#dribbblish-config .dribbblish-config-item > .main-type-mesto {
grid-area: description;
}
#dribbblish-config .dribbblish-config-item > .x-settings-secondColumn {
grid-area: input;
}
#dribbblish-config .dribbblish-config-close {
position: absolute;
top: 15px;
right: 15px;
}
#dribbblish-config .dribbblish-config-backdrop {
position: absolute;
content: "";
inset: 0px;
backdrop-filter: blur(3px) brightness(60%);
}
/** Rearrange player bar */ /** Rearrange player bar */
.main-nowPlayingBar-left { .main-nowPlayingBar-left {
order: 1; order: 1;