diff --git a/Dribbblish/color.ini b/Dribbblish/color.ini
index bdf4d1b..718537a 100644
--- a/Dribbblish/color.ini
+++ b/Dribbblish/color.ini
@@ -3,13 +3,13 @@ text = FFFFFF
subtext = F0F0F0
sidebar-text = FFFFFF
main = 000000
-sidebar = 1ed760
+sidebar = 24b558
player = 000000
card = 000000
shadow = 202020
selected-row = 797979
-button = 1ed760
-button-active = 1ed760
+button = 24b558
+button-active = 24b558
button-disabled = 535353
tab-active = 166632
notification = 1db954
@@ -116,7 +116,7 @@ sidebar = 6F3C89
player = 0A0E14
card = 0A0E14
shadow = 3a2645
-selected-row = EBDFFF
+selected-row = 645275
button = c76af6
button-active = 6F3C89
button-disabled = 535353
@@ -207,10 +207,10 @@ player = 161616
card = 161616
shadow = 252525
selected-row = 202020
-button = 0064e1
-button-active = 0064e1
+button = 3281ea
+button-active = 0284e8
button-disabled = 303030
-tab-active = 0064e1
-notification = 0064e1
+tab-active = ebbcba
+notification = 3281ea
notification-error = b10c0c
misc = 252525
diff --git a/Dribbblish/theme.js b/Dribbblish/theme.js
index bcca18e..66b7949 100644
--- a/Dribbblish/theme.js
+++ b/Dribbblish/theme.js
@@ -7,20 +7,17 @@ function waitForElement(els, func, timeout = 100) {
}
}
+let DribbblishShared = {};
+
// back shadow
waitForElement([".Root__top-container"], ([topContainer]) => {
const shadow = document.createElement("div");
shadow.id = "dribbblish-back-shadow";
topContainer.prepend(shadow);
-
- // check if element has two children
- const mainNav = topContainer.querySelector(".main-navBar-mainNav");
- if (mainNav && mainNav.childElementCount === 1) {
- document.documentElement.classList.add("legacy-nav");
- legacy();
- }
});
+// Spicetify.Platform.ConnectAPI.state.connectionStatus;
+
// add fade effect on playlist/folder list
waitForElement([".main-navBar-mainNav .os-viewport.os-viewport-native-scrollbars-invisible"], ([scrollNode]) => {
scrollNode.setAttribute("fade", "bottom");
@@ -35,6 +32,8 @@ waitForElement([".main-navBar-mainNav .os-viewport.os-viewport-native-scrollbars
});
});
+let version;
+
(function Dribbblish() {
// dynamic playback time tooltip
const progBar = document.querySelector(".playback-bar");
@@ -45,6 +44,18 @@ waitForElement([".main-navBar-mainNav .os-viewport.os-viewport-native-scrollbars
return;
}
+ version = Spicetify.Platform.PlatformData.event_sender_context_information.client_version_int;
+
+ if (version < 121200000) {
+ document.documentElement.classList.add("legacy");
+ legacy();
+ } else if (version >= 121200000 && version < 121400000) {
+ document.documentElement.classList.add("legacy-gridChange");
+ legacy();
+ } else if (version >= 121400000) {
+ document.documentElement.classList.add("ylx");
+ }
+
const tooltip = document.createElement("div");
tooltip.className = "prog-tooltip";
progBar.append(tooltip);
@@ -64,30 +75,173 @@ waitForElement([".main-navBar-mainNav .os-viewport.os-viewport-native-scrollbars
}
Spicetify.Player.addEventListener("onprogress", updateProgTime);
updateProgTime({ data: Spicetify.Player.getProgress() });
+
+ waitForElement(
+ [`.main-yourLibraryX-libraryRootlist`, `.main-rootlist-wrapper > div:nth-child(2)`, "li.main-yourLibraryX-listItem"],
+ ([rootlist, listElement]) => {
+ listElement.classList.add("dribs-playlist-list");
+
+ const loadFolderImages = items => {
+ if (!items) items = listElement.children;
+ for (const item of items) {
+ let id = item.querySelector("div > div:nth-child(2)").id;
+ if (!id.includes("folder")) continue;
+
+ id = id.split(":")[4];
+ console.log(id);
+
+ const base64 = localStorage.getItem("dribbblish:folder-image:" + id);
+
+ const img_container = item.querySelector(".HeaderSideArea .x-entityImage-imageContainer");
+
+ if (!base64) {
+ if (img_container.querySelector("img")) img_container.children[0].remove();
+ continue;
+ }
+
+ img_container.children[0].remove();
+ const img = document.createElement("img");
+ img.classList.add("main-image-image", "x-entityImage-image", "main-image-loaded");
+ img.src = base64;
+ img_container.append(img);
+ }
+ };
+
+ const getNewEls = mutationsList => {
+ for (const mutation of mutationsList) {
+ if (mutation.type === "childList") {
+ if (!mutation.addedNodes.length) continue;
+ loadFolderImages(mutation.addedNodes);
+ }
+ }
+ };
+
+ const refresh = mutationsList => {
+ console.log("refresh");
+ for (const mutation of mutationsList) {
+ if (mutation.type === "attributes" && mutation.attributeName === "class") {
+ loadFolderImages(listElement.children);
+ }
+ }
+ };
+
+ loadFolderImages();
+
+ new MutationObserver(getNewEls).observe(listElement, { childList: true });
+ new MutationObserver(refresh).observe(rootlist, { attributes: true, attributeFilter: ["class"] });
+
+ DribbblishShared.loadFolderImages = loadFolderImages;
+ }
+ );
+
+ // filepicker for custom folder images
+ const filePickerForm = document.createElement("form");
+ filePickerForm.setAttribute("aria-hidden", true);
+ filePickerForm.innerHTML = '';
+ document.body.appendChild(filePickerForm);
+ /** @type {HTMLInputElement} */
+ const filePickerInput = filePickerForm.childNodes[0];
+ filePickerInput.accept = ["image/jpeg", "image/apng", "image/avif", "image/gif", "image/png", "image/svg+xml", "image/webp"].join(",");
+
+ filePickerInput.onchange = () => {
+ if (!filePickerInput.files.length) return;
+
+ const file = filePickerInput.files[0];
+ const reader = new FileReader();
+ reader.onload = event => {
+ const result = event.target.result;
+ const id = Spicetify.URI.from(filePickerInput.uri).id;
+ try {
+ localStorage.setItem("dribbblish:folder-image:" + id, result);
+ } catch {
+ Spicetify.showNotification("File too large");
+ }
+ if (version < 121200000) {
+ DribbblishShared.loadPlaylistImage?.call();
+ } else {
+ DribbblishShared.loadFolderImages?.call();
+ }
+ };
+ reader.readAsDataURL(file);
+ };
+
+ // context menu items for custom folder images
+ new Spicetify.ContextMenu.Item(
+ "Remove folder image",
+ ([uri]) => {
+ const id = Spicetify.URI.from(uri).id;
+ localStorage.removeItem("dribbblish:folder-image:" + id);
+ if (version < 121200000) {
+ DribbblishShared.loadPlaylistImage?.call();
+ } else {
+ DribbblishShared.loadFolderImages?.call();
+ }
+ },
+ ([uri]) => Spicetify.URI.isFolder(uri),
+ "x"
+ ).register();
+ new Spicetify.ContextMenu.Item(
+ "Choose folder image",
+ ([uri]) => {
+ filePickerInput.uri = uri;
+ filePickerForm.reset();
+ filePickerInput.click();
+ },
+ ([uri]) => Spicetify.URI.isFolder(uri),
+ "edit"
+ ).register();
})();
// LEGACY NAVBAR ONLY
-
function legacy() {
if (!Spicetify.Platform) {
setTimeout(legacy, 300);
return;
}
- let DribbblishShared = {};
-
// allow resizing of the navbar
- waitForElement([".Root__nav-bar .LayoutResizer__resize-bar"], ([resizer]) => {
- console.log(resizer);
+ waitForElement([".Root__nav-bar .LayoutResizer__input"], ([resizer]) => {
const observer = new MutationObserver(updateVariable);
- observer.observe(resizer, { attributes: true, attributeFilter: ["class"] });
+ observer.observe(resizer, { attributes: true, attributeFilter: ["value"] });
function updateVariable() {
- if (resizer.classList.contains("LayoutResizer__resize-bar-east")) {
- document.documentElement.style.setProperty("--left-sidebar-width", "72px");
+ let value = resizer.value;
+ if (value < 121) {
+ value = 72;
document.documentElement.classList.add("left-sidebar-collapsed");
} else {
document.documentElement.classList.remove("left-sidebar-collapsed");
}
+ document.documentElement.style.setProperty("--nav-bar-width", value + "px");
+ }
+ updateVariable();
+ });
+
+ // allow resizing of the buddy feed
+ waitForElement([".Root__right-sidebar .LayoutResizer__input"], ([resizer]) => {
+ const observer = new MutationObserver(updateVariable);
+ observer.observe(resizer, { attributes: true, attributeFilter: ["value"] });
+ function updateVariable() {
+ let value = resizer.value;
+ let min_value = version < 121200000 ? 321 : 281;
+ if (value < min_value) {
+ value = 72;
+ document.documentElement.classList.add("buddyFeed-hide-text");
+ } else {
+ document.documentElement.classList.remove("buddyFeed-hide-text");
+ }
+ }
+ updateVariable();
+ });
+
+ waitForElement([".main-nowPlayingBar-container"], ([nowPlayingBar]) => {
+ const observer = new MutationObserver(updateVariable);
+ observer.observe(nowPlayingBar, { childList: true });
+ function updateVariable() {
+ if (nowPlayingBar.childElementCount === 2) {
+ document.documentElement.classList.add("connected");
+ } else {
+ document.documentElement.classList.remove("connected");
+ }
}
updateVariable();
});
@@ -150,53 +304,4 @@ function legacy() {
new MutationObserver(loadPlaylistImage).observe(listElem, { childList: true });
});
-
- // filepicker for custom folder images
- const filePickerForm = document.createElement("form");
- filePickerForm.setAttribute("aria-hidden", true);
- filePickerForm.innerHTML = '';
- document.body.appendChild(filePickerForm);
- /** @type {HTMLInputElement} */
- const filePickerInput = filePickerForm.childNodes[0];
- filePickerInput.accept = ["image/jpeg", "image/apng", "image/avif", "image/gif", "image/png", "image/svg+xml", "image/webp"].join(",");
-
- filePickerInput.onchange = () => {
- if (!filePickerInput.files.length) return;
-
- const file = filePickerInput.files[0];
- const reader = new FileReader();
- reader.onload = event => {
- const result = event.target.result;
- const id = Spicetify.URI.from(filePickerInput.uri).id;
- try {
- localStorage.setItem("dribbblish:folder-image:" + id, result);
- } catch {
- Spicetify.showNotification("File too large");
- }
- DribbblishShared.loadPlaylistImage?.call();
- };
- reader.readAsDataURL(file);
- };
-
- // context menu items for custom folder images
- new Spicetify.ContextMenu.Item(
- "Remove folder image",
- ([uri]) => {
- const id = Spicetify.URI.from(uri).id;
- localStorage.removeItem("dribbblish:folder-image:" + id);
- DribbblishShared.loadPlaylistImage?.call();
- },
- ([uri]) => Spicetify.URI.isFolder(uri),
- "x"
- ).register();
- new Spicetify.ContextMenu.Item(
- "Choose folder image",
- ([uri]) => {
- filePickerInput.uri = uri;
- filePickerForm.reset();
- filePickerInput.click();
- },
- ([uri]) => Spicetify.URI.isFolder(uri),
- "edit"
- ).register();
}
diff --git a/Dribbblish/user.css b/Dribbblish/user.css
index e94b7d5..5860be5 100644
--- a/Dribbblish/user.css
+++ b/Dribbblish/user.css
@@ -3,6 +3,8 @@
--bar-cover-art-size: 40px;
--scrollbar-vertical-size: 10px;
--scrollbar-horizontal-size: 10px;
+ --bar-height: 90px;
+ --main-gap: 10px;
}
@font-face {
@@ -61,18 +63,18 @@ body {
grid-area: main-view !important;
}
-.Root__right-sidebar {
- padding-left: 8px;
- grid-area: right-sidebar !important;
+.legacy .Root__top-container:not(:has(> .Root__right-sidebar)) {
+ padding-right: var(--main-gap);
}
+
+.ylx .Root__top-container:not(:has(> .Root__right-sidebar > aside)) {
+ padding-right: var(--main-gap);
+}
+
.Root__right-sidebar:not(:has(> aside)) {
padding-left: 0;
}
-.Root__right-sidebar > aside {
- border-radius: var(--corner-radius) !important;
- box-shadow: 0 0 10px 3px #0000003b;
-}
.Root__nav-bar {
grid-area: left-sidebar !important;
}
@@ -395,6 +397,25 @@ li > div::after {
transition: none;
}
+/* right sidebar text */
+.Root__right-sidebar {
+ --text-base: var(--spice-sidebar-text);
+ --background-tinted-base: var(--spice-tab-active);
+}
+
+.Root__right-sidebar a,
+.Root__right-sidebar .main-trackInfo-artists a,
+.artist-artistOnTour-timeAndVenue.artist-artistOnTour-condensed,
+.Root__right-sidebar .main-nowPlayingView-creditsSource,
+.Root__right-sidebar .main-nowPlayingView-playNextButton,
+.Root__right-sidebar .main-nowPlayingView-playNext {
+ color: var(--spice-sidebar-text);
+}
+
+.main-nowPlayingView-content {
+ --text-subdued: var(--spice-sidebar-text);
+}
+
/* add main backshadow */
#dribbblish-back-shadow {
z-index: 5;
@@ -463,45 +484,164 @@ input {
background-color: var(--spice-main);
}
-/* LEGACY NAVBAR ONLY */
-.legacy-nav .Root__top-container {
- padding: 8px;
+/* v1.2.14 */
+.main-yourLibraryX-libraryContainer.main-yourLibraryX-libraryIsExpanded.main-yourLibraryX-libraryIsCollapsed,
+.main-yourLibraryX-libraryRootlist.main-yourLibraryX-libraryIsExpanded:not(.main-yourLibraryX-libraryIsCollapsed) {
+ padding-bottom: 0;
+}
+
+[dir="ltr"] .main-nowPlayingWidget-coverExpanded {
+ transform: none;
+}
+
+.ylx .main-coverSlotExpanded-container {
+ bottom: calc(var(--main-gap) + 70px + 10px);
+ left: calc(var(--nav-bar-width) + 10px);
+}
+.ylx.connected .main-coverSlotExpanded-container {
+ bottom: calc(var(--main-gap) + 70px + 24px + 10px);
+}
+
+/* v1.2.12 -> 1.2.13 */
+.main-buddyFeed-container {
+ background-color: inherit;
+ box-shadow: none;
+}
+.legacy-gridChange .main-coverSlotExpanded-container {
+ left: calc(var(--nav-bar-width) + 10px);
+}
+
+/* v1.2.0 --> 1.2.11 */
+.legacy .Root__top-container {
+ grid-template-areas:
+ "left-sidebar top-bar right-sidebar"
+ "left-sidebar main-view right-sidebar"
+ "left-sidebar now-playing-bar right-sidebar" !important;
+}
+.Root__top-container {
+ padding: 10px 0;
background-color: var(--spice-sidebar);
}
-.legacy-nav .Root__main-view {
+.Root__right-sidebar {
+ background-color: var(--spice-sidebar);
+}
+.Root__main-view {
background-color: var(--spice-main);
}
-.legacy-nav .main-rootlist-rootlistDivider {
+.main-rootlist-rootlistDivider {
background-color: transparent;
}
-.legacy-nav .main-rootlist-rootlistDividerGradient {
+.main-buddyFeed-activityMetadata .main-buddyFeed-username a,
+.main-buddyFeed-activityMetadata .main-buddyFeed-artistAndTrackName a,
+.main-buddyFeed-activityMetadata .main-buddyFeed-usernameAndTimestamp,
+.main-buddyFeed-activityMetadata .main-buddyFeed-playbackContextLink {
+ color: var(--spice-sidebar-text) !important;
+}
+.main-buddyFeed-activityMetadata .main-buddyFeed-artistAndTrackName {
+ color: var(--spice-sidebar-text);
+}
+.collection-icon,
+.premiumSpotifyIcon,
+.search-icon {
+ color: var(--spice-sidebar-text) !important;
+}
+.main-confirmDialog-container {
+ background-color: var(--spice-card);
+}
+.main-confirmDialog-container .TypeElement-canon-textBase {
+ color: var(--spice-text);
+}
+.main-confirmDialog-buttonContainer button span {
+ color: var(--spice-card);
+}
+.main-coverSlotExpanded-container {
+ position: fixed;
+ z-index: 2;
+ width: 250px;
+ height: 250px;
+ bottom: calc(var(--main-gap) + var(--bar-height) + 10px);
+ left: calc(var(--nav-bar-width) + 20px);
+}
+.connected .main-coverSlotExpanded-container {
+ bottom: calc(var(--main-gap) + var(--bar-height) + 24px + 10px);
+}
+.left-sidebar-collapsed .main-coverSlotExpanded-container {
+ left: 82px;
+}
+.main-coverSlotExpanded-container img {
+ border-radius: 4px;
+}
+.cover-art {
+ border-radius: 4px;
+}
+.left-sidebar-collapsed .Root__nav-bar {
+ width: 72px;
+}
+.left-sidebar-collapsed .main-rootlist-statusIcons {
+ display: none;
+}
+.main-navBar-navBarLinkActive {
+ background-color: var(--spice-tab-active);
+}
+.Root__nav-bar .main-rootlist-rootlist .os-scrollbar-handle {
+ display: none;
+}
+.Root__top-container:has(> .Root__top-container--right-sidebar-hidden) {
+ padding-right: 10px;
+}
+/* buddy feed w/ hidden text*/
+.buddyFeed-hide-text .Root__top-container:not(:has(> .Root__top-container--right-sidebar-hidden)) .Root__right-sidebar {
+ width: 72px !important;
+}
+.buddyFeed-hide-text .NdQkQZhcYIEcJnRdAYcQ,
+.buddyFeed-hide-text .main-buddyFeed-header {
+ display: none;
+}
+.buddyFeed-hide-text .main-buddyFeed-friendActivity {
+ padding: 0 0 0 4px;
+}
+.buddyFeed-hide-text .main-buddyFeed-activityMetadata {
+ visibility: hidden;
+}
+.buddyFeed-hide-text .main-avatar-avatar > div > div > div {
+ display: flex;
+ justify-content: center;
+ padding-top: 7px;
+}
+.buddyFeed-hide-text .main-avatar-avatar,
+.buddyFeed-hide-text .main-avatar-avatar div,
+.buddyFeed-hide-text .main-buddyFeed-overlay {
+ width: 32px !important;
+ height: 32px !important;
+}
+.main-rootlist-rootlistDividerGradient {
background: none;
}
-.legacy-nav .main-collectionLinkButton-collectionLinkButton .main-collectionLinkButton-icon,
-.legacy-nav .main-collectionLinkButton-collectionLinkButton .main-collectionLinkButton-collectionLinkText {
+.main-collectionLinkButton-collectionLinkButton .main-collectionLinkButton-icon,
+.main-collectionLinkButton-collectionLinkButton .main-collectionLinkButton-collectionLinkText {
opacity: 1;
}
-.legacy-nav .main-collectionLinkButton-collectionLinkButton,
-.legacy-nav .main-createPlaylistButton-button {
- color: var(--spice-subtext);
+.main-collectionLinkButton-collectionLinkButton,
+.main-createPlaylistButton-button {
+ color: var(--spice-sidebar-text);
opacity: 1;
}
-.legacy-nav .main-likedSongsButton-likedSongsIcon {
+.main-likedSongsButton-likedSongsIcon {
background: none;
}
-.legacy-nav .main-likedSongsButton-likedSongsIcon > svg {
+.main-likedSongsButton-likedSongsIcon > svg {
height: 20px !important;
width: 20px !important;
}
/* style added sidebar images */
-.legacy-nav .main-rootlist-rootlistItem a {
+.main-rootlist-rootlistItem a {
align-items: center;
border-radius: 4px;
display: flex;
height: 56px;
gap: 12px;
}
-.legacy-nav img.playlist-picture {
+img.playlist-picture {
width: 32px;
height: 32px;
flex: 0 0 32px;
@@ -509,47 +649,99 @@ input {
background-position: center;
border-radius: 50%;
}
-.legacy-nav img.playlist-picture[src$=".svg"] {
+img.playlist-picture[src$=".svg"] {
width: 24px;
height: 24px;
border-radius: 0;
}
-.legacy-nav .Root__nav-bar .main-rootlist-wrapper {
+.legacy .Root__nav-bar .main-rootlist-wrapper,
+.legacy-gridChange .Root__nav-bar .main-rootlist-wrapper {
height: fit-content !important;
contain: none !important;
}
-.legacy-nav .main-navBar-mainNav li:has(> div > .active) {
+.main-navBar-mainNav li:has(> div > .active) {
background-color: var(--spice-tab-active);
}
-.legacy-nav .main-collectionLinkButton-selected.active {
+.main-collectionLinkButton-selected.active {
background-color: var(--spice-tab-active) !important;
}
-.legacy-nav .main-navBar-mainNav li {
+.legacy .main-navBar-mainNav li,
+.legacy-gridChange .main-navBar-mainNav li {
background-color: transparent !important;
}
-.legacy-nav a.active {
+/* a.active {
+ background-color: var(--spice-tab-active) !important;
+} */
+.main-rootlist-rootlistItem:has(> .main-rootlist-rootlistItemLinkActive) {
background-color: var(--spice-tab-active) !important;
}
-.legacy-nav .main-rootlist-rootlistItem:has(> .main-rootlist-rootlistItemLinkActive) {
- background-color: var(--spice-tab-active) !important;
-}
-.legacy-nav .main-rootlist-rootlistItemLink {
+.main-rootlist-rootlistItemLink {
padding-left: 12px;
}
-.legacy-nav .main-rootlist-rootlistItem {
+.main-rootlist-rootlistItem {
margin-left: 8px;
margin-right: 8px;
- padding-left: 0;
- padding-right: 8px;
+ padding-left: 0 !important;
+ padding-right: 8px !important;
border-radius: 4px;
}
-.legacy-nav .dribs-playlist-list {
+.dribs-playlist-list {
overflow: hidden;
}
-.legacy-nav.left-sidebar-collapsed .main-rootlist-expandArrow {
+.left-sidebar-collapsed .main-rootlist-expandArrow {
display: none;
}
-.legacy-nav .main-navBar-navBarLink,
-.legacy-nav .main-collectionLinkButton-collectionLinkButton {
+.main-navBar-navBarLink,
+.main-collectionLinkButton-collectionLinkButton,
+.main-createPlaylistButton-button {
height: 56px !important;
}
+
+.Button-md-buttonSecondary-useBrowserDefaultFocusStyle {
+ border: 1px solid var(--spice-text);
+}
+.Button-md-buttonPrimary-useBrowserDefaultFocusStyle .ButtonInner-md {
+ color: var(--spice-text);
+}
+/* sidebar speaker icon */
+.CCeu9OfWSwIAJqA49n84 {
+ color: var(--spice-sidebar-text);
+}
+.legacy .Root__right-sidebar .os-content {
+ overflow-x: hidden;
+}
+.Root__right-sidebar .os-scrollbar-horizontal {
+ display: none;
+}
+.UyzJidwrGk3awngSGIwv,
+.poz9gZKE7xqFwgk231J4,
+.xWm_uA0Co4SXVxaO7wlB {
+ color: var(--spice-text);
+}
+.main-navBar-navBarLink {
+ color: var(--spice-sidebar-text);
+}
+.main-navBar-navBarLink:focus,
+.main-navBar-navBarLink:hover {
+ color: var(--spice-sidebar-text);
+}
+.main-createPlaylistButton-createPlaylistIcon {
+ background-color: var(--spice-sidebar-text);
+}
+.main-rootlist-rootlistItemLink:link,
+.main-rootlist-rootlistItemLink:visited {
+ color: var(--spice-sidebar-text) !important;
+}
+.main-rootlist-expandArrow {
+ color: var(--spice-sidebar-text);
+}
+.main-buddyFeed-actions button,
+.main-buddyFeed-titleContainer {
+ color: var(--spice-sidebar-text) !important;
+}
+.main-tag-container {
+ background-color: var(--spice-subtext);
+}
+.main-buddyFeed-content {
+ height: fit-content;
+}