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,17 +176,25 @@ 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({
switch (val) { type: "select",
case 0: options: ["System", "Dark", "Light"],
toggleDark(systemDark); key: "theme",
break; name: "Theme",
case 1: description: "Select Dark / Bright mode",
toggleDark(true); defaultValue: 0,
break; onChange: (val) => {
case 2: switch (val) {
toggleDark(false); case 0:
break; toggleDark(systemDark);
break;
case 1:
toggleDark(true);
break;
case 2:
toggleDark(false);
break;
}
} }
}); });
@ -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,133 +1,213 @@
// 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);
});
DribbblishShared.configButton.addItem(menuItem);
if (localStorage.getItem(`dribbblish:config:${key}`) == null) localStorage.setItem(`dribbblish:config:${key}`, defaultValue); 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>
`;
DribbblishShared.configData[key] = { document.body.appendChild(container);
menuItem, document.querySelector(".dribbblish-config-close").addEventListener("click", () => DribbblishShared.config.close());
update document.querySelector(".dribbblish-config-backdrop").addEventListener("click", () => DribbblishShared.config.close());
}; }
DribbblishShared.config.update(key); open() {
}, document.getElementById("dribbblish-config").setAttribute("active", "");
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);
return subItem;
});
DribbblishShared.configButton.addItem(menuItem);
menuItem.register();
if (localStorage.getItem(`dribbblish:config:${key}`) == null) localStorage.setItem(`dribbblish:config:${key}`, defaultChoice); close() {
document.getElementById("dribbblish-config").removeAttribute("active");
}
DribbblishShared.configData[key] = { /** @private */
subItems: menuItems, addInputHTML({ type, key, name, description, input, insertOnTop }) {
menuItem, const elem = document.createElement("div");
update elem.classList.add("dribbblish-config-item");
}; elem.setAttribute("key", `dribbblish:config:${key}`);
elem.setAttribute("type", type);
DribbblishShared.config.update(key); elem.innerHTML = /* html */ `
}, <h2 class="x-settings-title main-type-cello" as="h2">${name}</h2>
get: (key) => { <label class="main-type-mesto" as="label" for="dribbblish-config-input-${key}" style="color: var(--spice-subtext);">${description}</label>
const val = localStorage.getItem(`dribbblish:config:${key}`); <label class="x-toggle-wrapper x-settings-secondColumn">
if (val == "true" || val == "false") return val == "true"; ${input}
if (!isNaN(val) && !isNaN(parseInt(val))) return parseInt(val); </label>
}, `;
set: (key, val) => { if (insertOnTop && document.querySelector(".dribbblish-config-item")) {
if (DribbblishShared.configData[key].hasOwnProperty("subItems")) { console.log("before");
DribbblishShared.configData[key].subItems.forEach((item, i) => { document.querySelector(".dribbblish-config-container").insertBefore(elem, document.querySelector(".dribbblish-config-item:first-of-type"));
item.setState(val == i); } else {
}); document.querySelector(".dribbblish-config-container").appendChild(elem);
} else {
DribbblishShared.configData[key].menuItem.setState(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")) {
// Can't toggle lists
} else {
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);
} }
}, }
configData: {}
};
DribbblishShared.configButton.register();
// Initialize Config register({ type, options, key, name, description, defaultValue, insertOnTop, onChange }) {
DribbblishShared.config.register("Right expanded cover", "rightBigCover", true, (value) => { if (!key) key = cyrb53Hash(name);
if (value) { var fireChange = true;
document.documentElement.classList.add("right-expanded-cover");
} else { if (type == "checkbox") {
document.documentElement.classList.remove("right-expanded-cover"); 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));
});
} 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 });
document.getElementById(`dribbblish-config-input-${key}`).addEventListener("change", (e) => {
this.set(key, e.target.value);
onChange(this.get(key));
});
} else if (type == "button") {
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);
});
fireChange = false;
} else {
throw new Error(`Config Type "${type}" invalid`);
}
if (fireChange) onChange(this.get(key, defaultValue));
}
get(key, defaultValue) {
const val = localStorage.getItem(`dribbblish:config:${key}`);
if (val == null) return defaultValue;
if (val == "true" || val == "false") return val == "true"; // Boolean
if (!isNaN(val) && !isNaN(parseInt(val))) return parseInt(val); // Number
return val; // String
}
set(key, val) {
localStorage.setItem(`dribbblish:config:${key}`, val);
}
}
class _DribbblishShared {
constructor() {
this.config = new ConfigMenu();
}
}
const DribbblishShared = new _DribbblishShared();
DribbblishShared.config.register({
type: "checkbox",
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");
} else {
document.documentElement.classList.remove("right-expanded-cover");
}
} }
}); });
DribbblishShared.config.register("Round Sidebar Icons", "roundSidebarIcons", false, (value) => { DribbblishShared.config.register({
if (value) { type: "checkbox",
document.documentElement.style.setProperty("--sidebar-icons-border-radius", "50%"); key: "roundSidebarIcons",
} else { name: "Round Sidebar Icons",
document.documentElement.style.setProperty("--sidebar-icons-border-radius", "var(--image-radius)"); 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%");
} else {
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",
case 0: options: ["None", "None (With Top Padding)", "Solid", "Transparent"],
document.getElementById("main").setAttribute("top-bar", "none"); key: "winTopBar",
break; name: "Windows Top Bar",
case 1: description: "Have differennt top Bars (Ore none at all)",
document.getElementById("main").setAttribute("top-bar", "none-padding"); defaultValue: 0,
break; onChange: (val) => {
case 2: switch (val) {
document.getElementById("main").setAttribute("top-bar", "solid"); case 0:
break; document.getElementById("main").setAttribute("top-bar", "none");
case 3: break;
document.getElementById("main").setAttribute("top-bar", "transparent"); case 1:
break; document.getElementById("main").setAttribute("top-bar", "none-padding");
break;
case 2:
document.getElementById("main").setAttribute("top-bar", "solid");
break;
case 3:
document.getElementById("main").setAttribute("top-bar", "transparent");
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;