Merge remote-tracking branch 'upstream/main' into main

This commit is contained in:
Oscar Sjöstedt 2021-10-08 12:39:33 +01:00
commit 1697ae9b53
4 changed files with 360 additions and 115 deletions

View file

@ -23,7 +23,7 @@ Right click at folder and choose images for your playlist folder. Every image fo
### Left/Right expanded cover ### Left/Right expanded cover
In profile menu, toggle option "Right expanded cover" to change expaned current track cover image to left or right side, whereever you prefer. In profile menu, toggle option "Right expanded cover" to change expaned current track cover image to left or right side, whereever you prefer.
## Install ## Install / Update
Make sure you are using spicetify >= v2.6.0 and Spotify >= v1.1.67. Make sure you are using spicetify >= v2.6.0 and Spotify >= v1.1.67.
Run these commands: Run these commands:

View file

@ -1,4 +1,4 @@
let current = '2.3' let current = '2.4.1'
/* css is injected so this works with untouched user.css from Dribbblish */ /* css is injected so this works with untouched user.css from Dribbblish */
/* dark theme */ /* dark theme */
@ -178,7 +178,7 @@ let systemDark = parseInt(getComputedStyle(document.documentElement).getProperty
DribbblishShared.config.register({ DribbblishShared.config.register({
type: "select", type: "select",
options: ["System", "Dark", "Light"], data: ["System", "Dark", "Light"],
key: "theme", key: "theme",
name: "Theme", name: "Theme",
description: "Select Dark / Bright mode", description: "Select Dark / Bright mode",
@ -294,7 +294,7 @@ async function songchange() {
recent_date.setMonth(recent_date.getMonth() - 6) recent_date.setMonth(recent_date.getMonth() - 6)
album_date = album_date.toLocaleString('default', album_date>recent_date ? { year: 'numeric', month: 'short' } : { year: 'numeric' }) album_date = album_date.toLocaleString('default', album_date>recent_date ? { year: 'numeric', month: 'short' } : { year: 'numeric' })
album_link = "<a title=\""+Spicetify.Player.data.track.metadata.album_title+"\" href=\""+album_uri+"\" data-uri=\""+album_uri+"\" data-interaction-target=\"album-name\" class=\"tl-cell__content\">"+Spicetify.Player.data.track.metadata.album_title+"</a>" album_link = "<a title=\""+Spicetify.Player.data.track.metadata.album_title+"\" href=\""+album_uri+"\" data-uri=\""+album_uri+"\" data-interaction-target=\"album-name\" class=\"tl-cell__content\">"+Spicetify.Player.data.track.metadata.album_title+"</a>"
nearArtistSpanText = album_link + " • " + album_date nearArtistSpanText = album_link + " • " + album_date
} else if (Spicetify.Player.data.track.uri.includes('spotify:episode')) { } else if (Spicetify.Player.data.track.uri.includes('spotify:episode')) {
// podcast // podcast
@ -375,19 +375,13 @@ hookCoverChange(false);
}).then(data => { }).then(data => {
if (data.tag_name > current) { if (data.tag_name > current) {
upd = document.createElement("div") upd = document.createElement("div")
upd.innerText = `Theme UPD v${data.tag_name} avail.`
upd.classList.add("ellipsis-one-line", "main-type-finale") upd.classList.add("ellipsis-one-line", "main-type-finale")
document.querySelector(".main-userWidget-box").append(upd)
upd.append(`Theme UPD v${data.tag_name} avail.`)
upd.setAttribute("title", `Changes: ${data.name}`) upd.setAttribute("title", `Changes: ${data.name}`)
DribbblishShared.config.register({ upd.style.setProperty("color", "var(--spice-button-active)");
insertOnTop: true, document.querySelector(".main-userWidget-box").append(upd)
type: "button", document.querySelector(".main-userWidget-box").classList.add("update-avail")
name: "Update", new Spicetify.Menu.Item("Update Dribbblish", false, () => window.open("https://github.com/JulienMaille/dribbblish-dynamic-theme/blob/main/README.md#install--update", "_blank")).register();
description: "Open the GitHub Page with Installation instructions / Commands.",
onChange: () => {
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
@ -396,24 +390,25 @@ hookCoverChange(false);
})() })()
/* translucid background cover */ /* translucid background cover */
document.styleSheets[0].addRule('.Root__top-container::before', document.styleSheets[0].insertRule(`
` content: ''; .Root__top-container::before {
background-image: var(--image_url); content: '';
background-repeat: no-repeat; background-image: var(--image_url);
background-size: cover; background-repeat: no-repeat;
background-position: center center; background-size: cover;
position: fixed; background-position: center center;
display: block; position: fixed;
top: 0; display: block;
left: 0; top: 0;
right: 0; left: 0;
bottom: 0; right: 0;
filter: blur(15px); bottom: 0;
pointer-events: none; filter: blur(15px);
backface-visibility: hidden; pointer-events: none;
will-change: transform; backface-visibility: hidden;
opacity: calc(0.07 + 0.03 * var(--is_light, 0)); will-change: transform;
z-index: +3; opacity: calc(0.07 + 0.03 * var(--is_light, 0));
transition: background-image var(--song-transition-speed) linear;`) z-index: +3;
}`)
document.documentElement.style.setProperty('--warning_message', ' '); document.documentElement.style.setProperty('--warning_message', ' ');

View file

@ -1,6 +1,20 @@
// Hide popover message // Hide popover message
// document.getElementById("popover-container").style.height = 0; // document.getElementById("popover-container").style.height = 0;
class ConfigMenu { class ConfigMenu {
/**
* @typedef {Object} DribbblishConfigOptions
* @property {"checkbox" | "select" | "button" | "slider" | "number" | "text"} 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
*/
constructor() { constructor() {
this.config = {}; this.config = {};
this.configButton = new Spicetify.Menu.Item("Dribbblish config", false, () => DribbblishShared.config.open()); this.configButton = new Spicetify.Menu.Item("Dribbblish config", false, () => DribbblishShared.config.open());
@ -14,6 +28,7 @@ class ConfigMenu {
<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> <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> </button>
<h1>Dribbblish Settings</h1> <h1>Dribbblish Settings</h1>
<div class="dribbblish-config-items"></div>
</div> </div>
<div class="dribbblish-config-backdrop"></div> <div class="dribbblish-config-backdrop"></div>
`; `;
@ -31,79 +46,164 @@ class ConfigMenu {
document.getElementById("dribbblish-config").removeAttribute("active"); document.getElementById("dribbblish-config").removeAttribute("active");
} }
/** @private */ /**
addInputHTML({ type, key, name, description, input, insertOnTop }) { * @private
* @param {DribbblishConfigOptions} options
*/
addInputHTML(options) {
let parent;
if (options.area != null) {
if (!document.querySelector(`.dribbblish-config-area[name="${options.area}"]`)) {
const areaElem = document.createElement("div");
areaElem.classList.add("dribbblish-config-area");
areaElem.setAttribute("name", options.area);
areaElem.innerHTML = `<h2>${options.area}</h2>`;
document.querySelector(".dribbblish-config-items").appendChild(areaElem);
}
parent = document.querySelector(`.dribbblish-config-area[name="${options.area}"]`);
} else {
parent = document.querySelector(".dribbblish-config-items");
}
const elem = document.createElement("div"); const elem = document.createElement("div");
elem.classList.add("dribbblish-config-item"); elem.classList.add("dribbblish-config-item");
elem.setAttribute("key", `dribbblish:config:${key}`); elem.setAttribute("key", `dribbblish:config:${options.key}`);
elem.setAttribute("type", type); elem.setAttribute("type", options.type);
elem.innerHTML = /* html */ ` elem.innerHTML = /* html */ `
<h2 class="x-settings-title main-type-cello" as="h2">${name}</h2> <h2 class="x-settings-title main-type-cello${!options.description ? " no-desc" : ""}" as="h2">${options.name}</h2>
<label class="main-type-mesto" as="label" for="dribbblish-config-input-${key}" style="color: var(--spice-subtext);">${description}</label> <label class="main-type-mesto" as="label" for="dribbblish-config-input-${options.key}" style="color: var(--spice-subtext);">${options.description}</label>
<label class="x-toggle-wrapper x-settings-secondColumn"> <label class="x-toggle-wrapper x-settings-secondColumn">
${input} ${options.input}
</label> </label>
`; `;
if (insertOnTop && document.querySelector(".dribbblish-config-item")) {
console.log("before"); if (options.insertOnTop && parent.children.length > 0) {
document.querySelector(".dribbblish-config-container").insertBefore(elem, document.querySelector(".dribbblish-config-item:first-of-type")); parent.insertBefore(elem, parent.children[0]);
} else { } else {
document.querySelector(".dribbblish-config-container").appendChild(elem); parent.appendChild(elem);
} }
} }
register({ type, options, key, name, description, defaultValue, insertOnTop, onChange }) { /**
if (!key) key = cyrb53Hash(name); * @param {DribbblishConfigOptions} options
*/
register(options) {
options = {
...{
area: "Main Settings",
data: {},
key: cyrb53Hash(options.name ?? ""),
name: "",
description: "",
insertOnTop: false,
onAppended: () => {},
onChange: () => {}
},
...options
};
var fireChange = true; var fireChange = true;
if (type == "checkbox") { if (options.type == "checkbox") {
const input = /* html */ ` const input = /* html */ `
<input id="dribbblish-config-input-${key}" class="x-toggle-input" type="checkbox"${this.get(key, defaultValue) ? " checked" : ""}> <input id="dribbblish-config-input-${options.key}" class="x-toggle-input" type="checkbox"${this.get(options.key, options.defaultValue) ? " checked" : ""}>
<span class="x-toggle-indicatorWrapper"> <span class="x-toggle-indicatorWrapper">
<span class="x-toggle-indicator"></span> <span class="x-toggle-indicator"></span>
</span> </span>
`; `;
this.addInputHTML({ type, key, name, description, input, insertOnTop }); this.addInputHTML({ ...options, input });
document.getElementById(`dribbblish-config-input-${key}`).addEventListener("change", (e) => { document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("change", (e) => {
this.set(key, e.target.checked); this.set(options.key, e.target.checked);
onChange(this.get(key)); options.onChange(this.get(options.key));
}); });
} else if (type == "select") { } else if (options.type == "select") {
const input = /* html */ ` const input = /* html */ `
<span class="x-settings-secondColumn"> <select class="main-dropDown-dropDown" id="dribbblish-config-input-${options.key}">
<select class="main-dropDown-dropDown" id="dribbblish-config-input-${key}"> ${options.data.map((option, i) => `<option value="${i}"${this.get(options.key, options.defaultValue) == i ? " selected" : ""}>${option}</option>`).join("")}
${options.map((option, i) => `<option value="${i}"${this.get(key, defaultValue) == i ? " selected" : ""}>${option}</option>`).join("")} </select>
</select>
</span>
`; `;
this.addInputHTML({ type, key, name, description, input, insertOnTop }); this.addInputHTML({ ...options, input });
document.getElementById(`dribbblish-config-input-${key}`).addEventListener("change", (e) => { document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("change", (e) => {
this.set(key, e.target.value); this.set(options.key, e.target.value);
onChange(this.get(key)); options.onChange(this.get(options.key));
}); });
} else if (type == "button") { } else if (options.type == "button") {
const input = /* html */ ` const input = /* html */ `
<span class="x-settings-secondColumn"> <button class="main-buttons-button main-button-primary" type="button" id="dribbblish-config-input-${options.key}">
<button class="main-buttons-button main-button-primary" type="button" id="dribbblish-config-input-${key}"> <div class="x-settings-buttonContainer">
<div class="x-settings-buttonContainer"> <span>${options.name}</span>
<span>${name}</span> </div>
</div> </button>
</button>
</span>
`; `;
this.addInputHTML({ type, key, name, description, input, insertOnTop }); this.addInputHTML({ ...options, input });
document.getElementById(`dribbblish-config-input-${key}`).addEventListener("click", (e) => { document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("click", (e) => {
onChange(true); options.onChange(true);
}); });
fireChange = false; fireChange = false;
} else if (options.type == "number") {
if (options.defaultValue == null) options.defaultValue = 0;
const input = /* html */ `
<input type="number" id="dribbblish-config-input-${options.key}" value="${this.get(options.key, options.defaultValue)}">
`;
this.addInputHTML({ ...options, input });
// Prevent inputting +, - and e. Why is it even possible in the first place?
document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("keypress", (e) => {
if (["+", "-", "e"].includes(e.key)) e.preventDefault();
});
document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("input", (e) => {
if (options.data.min != null && e.target.value < options.data.min) e.target.value = options.data.min;
if (options.data.max != null && e.target.value > options.data.max) e.target.value = options.data.max;
this.set(options.key, e.target.value);
options.onChange(this.get(options.key));
});
} else if (options.type == "text") {
if (options.defaultValue == null) options.defaultValue = "";
const input = /* html */ `
<input type="text" id="dribbblish-config-input-${options.key}" value="${this.get(options.key, options.defaultValue)}">
`;
this.addInputHTML({ ...options, input });
document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("input", (e) => {
// TODO: maybe add an validation function via `data.validate`
this.set(options.key, e.target.value);
options.onChange(this.get(options.key));
});
} else if (options.type == "slider") {
if (options.defaultValue == null) options.defaultValue = 0;
const input = /* html */ `
<input
type="range"
id="dribbblish-config-input-${options.key}"
name="${options.name}"
min="${options.data?.min ?? "0"}"
max="${options.data?.max ?? "100"}"
step="${options.data?.step ?? "1"}"
value="${this.get(options.key, options.defaultValue)}"
tooltip="${this.get(options.key, options.defaultValue)}${options.data?.suffix ?? ""}"
>
`;
this.addInputHTML({ ...options, input });
document.getElementById(`dribbblish-config-input-${options.key}`).addEventListener("input", (e) => {
document.getElementById(`dribbblish-config-input-${options.key}`).setAttribute("tooltip", `${e.target.value}${options.data?.suffix ?? ""}`);
document.getElementById(`dribbblish-config-input-${options.key}`).setAttribute("value", e.target.value);
this.set(options.key, e.target.value);
options.onChange(e.target.value);
});
} else { } else {
throw new Error(`Config Type "${type}" invalid`); throw new Error(`Config Type "${options.type}" invalid`);
} }
if (fireChange) onChange(this.get(key, defaultValue)); options.onAppended();
if (fireChange) options.onChange(this.get(options.key, options.defaultValue));
} }
get(key, defaultValue) { get(key, defaultValue) {
@ -111,7 +211,8 @@ class ConfigMenu {
if (val == null) return defaultValue; if (val == null) return defaultValue;
if (val == "true" || val == "false") return val == "true"; // Boolean if (val == "true" || val == "false") return val == "true"; // Boolean
if (!isNaN(val) && !isNaN(parseInt(val))) return parseInt(val); // Number if (!isNaN(val) && /\d+\.\d+/.test(val) && !isNaN(parseFloat(val))) return parseFloat(val); // Float
if (!isNaN(val) && /\d+/.test(val) && !isNaN(parseInt(val))) return parseInt(val); // Int
return val; // String return val; // String
} }
@ -158,22 +259,26 @@ DribbblishShared.config.register({
}); });
DribbblishShared.config.register({ DribbblishShared.config.register({
type: "select", type: "slider",
options: ["No fade", "0.25s", "0.5s", "1s", "5s"], data: {
"min": 0,
"max": 10,
"step": 0.1,
"suffix": "s"
},
key: "fadeDuration", key: "fadeDuration",
name: "Color Fade Duration", name: "Color Fade Duration",
description: "Select the duration of the color fading transition", description: "Select the duration of the color fading transition",
defaultValue: 0, defaultValue: 0.5,
onChange: (val) => { onChange: (val) => {
let values = ["0s", "0.25s", "0.5s", "1s", "5s"]; document.documentElement.style.setProperty("--song-transition-speed", val+"s");
document.documentElement.style.setProperty("--song-transition-speed", values[val]);
} }
}); });
waitForElement(["#main"], () => { waitForElement(["#main"], () => {
DribbblishShared.config.register({ DribbblishShared.config.register({
type: "select", type: "select",
options: ["None", "None (With Top Padding)", "Solid", "Transparent"], data: ["None", "None (With Top Padding)", "Solid", "Transparent"],
key: "winTopBar", key: "winTopBar",
name: "Windows Top Bar", name: "Windows Top Bar",
description: "Have different top Bars (or none at all)", description: "Have different top Bars (or none at all)",
@ -219,10 +324,7 @@ function cyrb53Hash(str, seed = 0) {
return 4294967296 * (2097151 & h2) + (h1 >>> 0); return 4294967296 * (2097151 & h2) + (h1 >>> 0);
} }
waitForElement([ waitForElement([`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`, `.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"] li`], ([root, firstItem]) => {
`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"]`,
`.main-rootlist-rootlistPlaylistsScrollNode ul[tabindex="0"] li`
], ([root, firstItem]) => {
const listElem = firstItem.parentElement; const listElem = firstItem.parentElement;
root.classList.add("dribs-playlist-list"); root.classList.add("dribs-playlist-list");
@ -232,7 +334,7 @@ waitForElement([
let link = item.querySelector("a"); let link = item.querySelector("a");
if (!link) continue; if (!link) continue;
let [_, app, uid ] = link.pathname.split("/"); let [_, app, uid] = link.pathname.split("/");
let uri; let uri;
if (app === "playlist") { if (app === "playlist") {
uri = Spicetify.URI.playlistV2URI(uid); uri = Spicetify.URI.playlistV2URI(uid);
@ -244,14 +346,11 @@ waitForElement([
img.classList.add("playlist-picture"); img.classList.add("playlist-picture");
link.prepend(img); link.prepend(img);
} }
img.src = base64 || "/images/tracklist-row-song-fallback.svg"; img.src = base64 || "/images/tracklist-row-song-fallback.svg";
continue; continue;
} }
Spicetify.CosmosAsync.get( Spicetify.CosmosAsync.get(`sp://core-playlist/v1/playlist/${uri.toURI()}/metadata`, { policy: { picture: true } }).then((res) => {
`sp://core-playlist/v1/playlist/${uri.toURI()}/metadata`,
{ policy: { picture: true } }
).then(res => {
const meta = res.metadata; const meta = res.metadata;
let img = link.querySelector("img"); let img = link.querySelector("img");
if (!img) { if (!img) {
@ -267,13 +366,12 @@ waitForElement([
DribbblishShared.loadPlaylistImage = loadPlaylistImage; DribbblishShared.loadPlaylistImage = loadPlaylistImage;
loadPlaylistImage(); loadPlaylistImage();
new MutationObserver(loadPlaylistImage) new MutationObserver(loadPlaylistImage).observe(listElem, { childList: true });
.observe(listElem, {childList: true});
}); });
waitForElement([".main-rootlist-rootlist", ".main-rootlist-wrapper > :nth-child(2) > :first-child"], ([rootlist]) => { waitForElement([".main-rootlist-rootlist", ".main-rootlist-wrapper > :nth-child(2) > :first-child", "#spicetify-show-list"], ([rootlist]) => {
function checkSidebarPlaylistScroll() { function checkSidebarPlaylistScroll() {
const topDist = rootlist.getBoundingClientRect().top - document.querySelector(".main-rootlist-wrapper > :nth-child(2) > :first-child").getBoundingClientRect().top; const topDist = rootlist.getBoundingClientRect().top - document.querySelector("#spicetify-show-list:not(:empty), .main-rootlist-wrapper > :nth-child(2) > :first-child").getBoundingClientRect().top;
const bottomDist = document.querySelector(".main-rootlist-wrapper > :nth-child(2) > :last-child").getBoundingClientRect().bottom - rootlist.getBoundingClientRect().bottom; const bottomDist = document.querySelector(".main-rootlist-wrapper > :nth-child(2) > :last-child").getBoundingClientRect().bottom - rootlist.getBoundingClientRect().bottom;
rootlist.classList.remove("no-top-shadow", "no-bottom-shadow"); rootlist.classList.remove("no-top-shadow", "no-bottom-shadow");

188
user.css
View file

@ -92,12 +92,81 @@ body {
input { input {
background-color: unset !important; background-color: unset !important;
border-bottom: solid 1px var(--spice-text) !important;
border-radius: 0 !important; border-radius: 0 !important;
padding: 6px 10px 6px 48px; padding: 6px 10px 6px 48px;
color: var(--spice-text) !important; color: var(--spice-text) !important;
} }
input[type=range] {
-webkit-appearance: none;
background: transparent;
padding: 0px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px;
height: 16px;
margin-top: -4px;
border-radius: 50%;
background-color: var(--spice-text);
}
input[type=range]::-webkit-slider-thumb:hover,
input[type=range]::-webkit-slider-thumb:active {
filter: brightness(80%);
}
input[type=range]::after {
z-index: 9999;
content: attr(tooltip);
position: absolute;
min-width: 50px;
top: -10px;
left: 50%;
transform: translateX(calc(-50%));
padding: 0 5px;
border-radius: 4px;
text-align: center;
color: var(--spice-sidebar-text);
background-color: var(--spice-button);
transition: opacity 0.25s ease;
opacity: 0;
}
input[type=range]:hover::after,
input[type=range]:active::after {
opacity: 1;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8px;
background-color: rgba(var(--spice-rgb-text), .2);
border-radius: 50vw;
}
input[type=number],
input[type=text] {
height: 32px;
border: none;
border-radius: 4px !important;
padding: 0px 10px;
background-color: rgba(var(--spice-rgb-selected-row), .4) !important;
color: var(--spice-subtext) !important;
}
input[type=number]:hover,
input[type=number]:active,
input[type=text]:hover,
input[type=text]:active {
background-color: rgba(var(--spice-rgb-selected-row), .6) !important;
}
.x-searchInput-searchInputSearchIcon, .x-searchInput-searchInputSearchIcon,
.x-searchInput-searchInputClearButton { .x-searchInput-searchInputClearButton {
color: var(--spice-text) !important; color: var(--spice-text) !important;
@ -272,21 +341,31 @@ span.artist-artistVerifiedBadge-badge svg > path:last-of-type {
.view-homeShortcutsGrid-shortcut { .view-homeShortcutsGrid-shortcut {
overflow: hidden; overflow: hidden;
background-color: rgba(var(--spice-rgb-selected-row), 0.4);
}
.view-homeShortcutsGrid-shortcut:hover {
background-color: rgba(var(--spice-rgb-selected-row), 0.6);
} }
.cover-art, .cover-art,
.main-userWidget-box, .main-userWidget-box.upd-avail,
.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-avatar-image, .main-avatar-image,
.main-userWidget-box:not(.upd-avail),
.main-avatar-userIcon, .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;
} }
.main-userWidget-box {
background-color: transparent;
}
.main-avatar-avatar.main-avatar-withBadge:after { .main-avatar-avatar.main-avatar-withBadge:after {
box-shadow: 0 0 0 2px var(--spice-sidebar); box-shadow: 0 0 0 2px var(--spice-sidebar);
background-color: var(--spice-notification); background-color: var(--spice-notification);
@ -306,11 +385,16 @@ span.artist-artistVerifiedBadge-badge svg > path:last-of-type {
min-width: 518px; min-width: 518px;
} }
.main-buddyFeed-findFriendsButton {
color: var(--spice-sidebar-text);
}
.main-connectBar-connectBar { .main-connectBar-connectBar {
border-radius: 0 0 var(--main-corner-radius) var(--main-corner-radius); border-radius: 0 0 var(--main-corner-radius) var(--main-corner-radius);
border: 2px solid var(--spice-main); border: 2px solid var(--spice-main);
border-top: 0; border-top: 0;
color: var(--spice-sidebar-text); background-color: var(--spice-button) !important;
color: var(--spice-text) !important;
} }
.Root__nav-bar { .Root__nav-bar {
@ -447,6 +531,14 @@ html.sidebar-hide-text .GlueDropTarget span {
display: none; display: none;
} }
.x-toggle-indicatorWrapper {
background-color: var(--spice-shadow);
}
input:hover:not([disabled]):not(:active)~.x-toggle-indicatorWrapper {
background-color: var(--spice-button-active);
}
/** */ /** */
.main-topBar-historyButtons .main-topBar-button { .main-topBar-historyButtons .main-topBar-button {
background-color: unset; background-color: unset;
@ -617,15 +709,20 @@ html.sidebar-hide-text .main-rootlist-rootlistItem {
height: 2px; height: 2px;
} }
.main-navBar-navBarLink { .main-rootlist-rootlistPlaylistsScrollNode {
height: 56px; padding: 0px;
} }
.main-navBar-navBarLink .icon,
.main-collectionLinkButton-icon, .main-collectionLinkButton-icon,
.main-createPlaylistButton-icon, .main-createPlaylistButton-icon {
.main-collectionLinkButton-icon { margin: 0px;
margin-right: 24px; }
.main-navBar-navBarLink,
.main-collectionLinkButton-collectionLinkButton,
.main-createPlaylistButton-button {
gap: 24px;
height: 56px;
} }
li.GlueDropTarget { li.GlueDropTarget {
@ -718,10 +815,11 @@ li.GlueDropTarget {
z-index: 1; z-index: 1;
position: relative; position: relative;
max-width: 80%; max-width: 80%;
background-color: rgba(var(--spice-rgb-main), 0.85); background-color: rgba(var(--spice-rgb-main), 0.9);
backdrop-filter: blur(3px); backdrop-filter: blur(3px);
padding: 20px 15px; padding: 20px 15px;
border-radius: var(--main-corner-radius); border-radius: var(--main-corner-radius);
box-shadow: 0 0 10px 3px #0000003b;
display: flex; display: flex;
gap: 5px; gap: 5px;
flex-direction: column; flex-direction: column;
@ -729,10 +827,21 @@ li.GlueDropTarget {
justify-content: center; justify-content: center;
} }
#dribbblish-config .dribbblish-config-items {
max-height: 60vh;
overflow-y: auto;
padding: 0px 50px;
}
.dribbblish-config-area > h2 {
text-align: center;
}
#dribbblish-config .dribbblish-config-item { #dribbblish-config .dribbblish-config-item {
position: relative; position: relative;
width: 100%; width: 100%;
padding: 0px 50px; padding: 5px 0px;
height: min-content;
display: grid; display: grid;
grid-template-columns: 1fr auto; grid-template-columns: 1fr auto;
grid-template-rows: 1fr 1fr; grid-template-rows: 1fr 1fr;
@ -744,10 +853,19 @@ li.GlueDropTarget {
#dribbblish-config .dribbblish-config-item > .x-settings-title { #dribbblish-config .dribbblish-config-item > .x-settings-title {
grid-area: header; grid-area: header;
margin: 0px;
height: min-content;
position: relative;
bottom: 0px;
}
#dribbblish-config .dribbblish-config-item > .x-settings-title.no-desc {
bottom: -10px;
} }
#dribbblish-config .dribbblish-config-item > .main-type-mesto { #dribbblish-config .dribbblish-config-item > .main-type-mesto {
grid-area: description; grid-area: description;
height: min-content;
} }
#dribbblish-config .dribbblish-config-item > .x-settings-secondColumn { #dribbblish-config .dribbblish-config-item > .x-settings-secondColumn {
@ -829,6 +947,16 @@ li.GlueDropTarget {
opacity: 1; opacity: 1;
} }
.main-collectionLinkButton-collectionLinkText,
.main-createPlaylistButton-text,
.main-navBar-navBarLink > span {
font-size: 14px;
font-weight: 400;
letter-spacing: normal;
line-height: 20px;
text-transform: none;
}
.main-likedSongsButton-likedSongsIcon, .main-likedSongsButton-likedSongsIcon,
.main-yourEpisodesButton-yourEpisodesIcon, .main-yourEpisodesButton-yourEpisodesIcon,
.main-createPlaylistButton-createPlaylistIcon { .main-createPlaylistButton-createPlaylistIcon {
@ -904,22 +1032,35 @@ span.main-userWidget-displayName,
padding: 0px 8px; padding: 0px 8px;
} }
.main-navBar-navBar, .main-navBar-navBar .main-rootlist-wrapper > div:nth-child(2),
.main-rootlist-wrapper > div:nth-child(2), .main-navBar-entryPoints,
.main-navBar-entryPoints { #spicetify-show-list,
.main-rootlist-rootlistContent .os-content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; gap: 5px;
} }
#spicetify-show-list:empty {
display: none;
}
.main-rootlist-wrapper > div:nth-child(2) > li img, .main-rootlist-wrapper > div:nth-child(2) > li img,
.main-navBar-navBarLink > .icon { .main-navBar-navBarLink > .icon {
z-index: 100; z-index: 100;
} }
.main-collectionLinkButton-collectionLinkButton,
.main-createPlaylistButton-button {
position: relative;
}
.main-navBar-navBarItem:hover::before, .main-navBar-navBarItem:hover::before,
.main-rootlist-rootlistItem:hover::before, .main-rootlist-rootlistItem:hover::before,
.main-rootlist-rootlistItemLinkActive::before { .main-rootlist-rootlistItemLinkActive::before,
.main-collectionLinkButton-collectionLinkButton:hover::before,
.main-collectionLinkButton-selected::before,
.main-createPlaylistButton-button:hover::before {
content: ""; content: "";
position: absolute; position: absolute;
inset: 0px; inset: 0px;
@ -928,7 +1069,8 @@ span.main-userWidget-displayName,
pointer-events: none; pointer-events: none;
} }
.main-navBar-navBarLinkActive { .main-navBar-navBarLinkActive,
.main-collectionLinkButton-selected {
border-radius: var(--image-radius); border-radius: var(--image-radius);
background-color: rgba(var(--spice-rgb-main), 0.4); background-color: rgba(var(--spice-rgb-main), 0.4);
} }
@ -947,7 +1089,7 @@ div.GlueDropTarget.personal-library >* {
} }
div.GlueDropTarget.personal-library >*.active { div.GlueDropTarget.personal-library >*.active {
background: var(--spice-button); background: transparent;
} }
/** Big cover, small cover */ /** Big cover, small cover */
@ -1016,9 +1158,19 @@ html.right-expanded-cover.buddyfeed-visible .main-coverSlotExpanded-container {
border-radius: 5px; border-radius: 5px;
} }
.main-buttons-button {
color: var(--spice-main);
}
.main-dropDown-dropDown, .main-dropDown-dropDown,
.x-sortBox-sortDropdown { .x-sortBox-sortDropdown {
background-color: rgba(var(--spice-rgb-selected-row), .1) !important; background-color: rgba(var(--spice-rgb-selected-row), .4) !important;
color: var(--spice-subtext);
}
.main-dropDown-dropDown:hover,
.x-sortBox-sortDropdown:hover {
background-color: rgba(var(--spice-rgb-selected-row), .6) !important;
} }
.connect-device-list-item:focus, .connect-device-list-item:focus,