diff --git a/dribbblish-dynamic.js b/dribbblish-dynamic.js index a862823..7ec4003 100644 --- a/dribbblish-dynamic.js +++ b/dribbblish-dynamic.js @@ -174,15 +174,21 @@ function toggleDark(setDark) { } /* Init with current system light/dark mode */ -let systemDark = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--system_is_dark'))==1 -toggleDark(systemDark) +let systemDark = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--system_is_dark")) == 1; -DribbblishShared.configMenu.register() -DribbblishShared.configMenu.addItem(new Spicetify.Menu.Item( - "Dark mode", - systemDark, - (self) => { toggleDark(); self.isEnabled = !self.isEnabled; } -)) +DribbblishShared.config.registerSelect("Theme", "theme", ["System", "Dark", "Light"], 0, (val) => { + switch (val) { + case 0: + toggleDark(systemDark); + break; + case 1: + toggleDark(true); + break; + case 2: + toggleDark(false); + break; + } +}); function updateColors(textColHex, sideColHex) { let isLightBg = isLight(textColorBg) diff --git a/dribbblish.js b/dribbblish.js index 47340c8..cb02215 100644 --- a/dribbblish.js +++ b/dribbblish.js @@ -2,44 +2,122 @@ // document.getElementById("popover-container").style.height = 0; const DribbblishShared = { configMenu: new Spicetify.Menu.SubMenu("Dribbblish", []), - rightBigCover: localStorage.getItem("dribs-right-big-cover") === "true", - osIconDodge: localStorage.getItem("dribs-os-icon-dodge") === "true", - updateConfig: () => { - if (DribbblishShared.rightBigCover) { - document.documentElement.classList.add("right-expanded-cover"); - } else { - document.documentElement.classList.remove("right-expanded-cover"); - } + config: { + register: (name, key, defaultValue, update) => { + const menuItem = new Spicetify.Menu.Item(name, defaultValue, (self) => { + self.setState(!self.isEnabled); + DribbblishShared.config.toggle(key); + }); + DribbblishShared.configMenu.addItem(menuItem); - if (DribbblishShared.osIconDodge) { - document.documentElement.style.setProperty("--os-windows-icon-dodge", 1); - } else { - document.documentElement.style.setProperty("--os-windows-icon-dodge", 0); + if (localStorage.getItem(`dribbblish:config:${key}`) == null) localStorage.setItem(`dribbblish:config:${key}`, defaultValue); + + DribbblishShared.configData[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); + return subItem; + }); + DribbblishShared.configMenu.addItem(menuItem); + menuItem.register(); + + if (localStorage.getItem(`dribbblish:config:${key}`) == null) localStorage.setItem(`dribbblish:config:${key}`, defaultChoice); + + DribbblishShared.configData[key] = { + subItems: menuItems, + menuItem, + update + }; + + DribbblishShared.config.update(key); + }, + get: (key) => { + const val = localStorage.getItem(`dribbblish:config:${key}`); + if (val == "true" || val == "false") return val == "true"; + if (!isNaN(val) && !isNaN(parseInt(val))) return parseInt(val); + }, + set: (key, val) => { + if (DribbblishShared.configData[key].hasOwnProperty("subItems")) { + DribbblishShared.configData[key].subItems.forEach((item, i) => { + item.setState(val == i); + }); + } 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.configMenu.register(); -DribbblishShared.configMenu.addItem( - new Spicetify.Menu.Item("Right expanded cover", DribbblishShared.rightBigCover, (self) => { - self.isEnabled = !self.isEnabled; - DribbblishShared.rightBigCover = self.isEnabled; - localStorage.setItem("dribs-right-big-cover", self.isEnabled); - DribbblishShared.updateConfig(); - }) -); -DribbblishShared.configMenu.register(); -DribbblishShared.configMenu.addItem( - new Spicetify.Menu.Item("OS Icon Dodge", DribbblishShared.osIconDodge, (self) => { - self.isEnabled = !self.isEnabled; - DribbblishShared.osIconDodge = self.isEnabled; - localStorage.setItem("dribs-os-icon-dodge", self.isEnabled); - DribbblishShared.updateConfig(); - }) -); +// Initialize Config +DribbblishShared.config.register("Right expanded cover", "rightBigCover", true, (value) => { + if (value) { + document.documentElement.classList.add("right-expanded-cover"); + } else { + document.documentElement.classList.remove("right-expanded-cover"); + } +}); -DribbblishShared.updateConfig(); +DribbblishShared.config.register("Round Sidebar Icons", "roundSidebarIcons", false, (value) => { + if (value) { + document.documentElement.style.setProperty("--sidebar-icons-border-radius", "50%"); + } else { + document.documentElement.style.setProperty("--sidebar-icons-border-radius", "var(--image-radius)"); + } +}); + +waitForElement(["#main"], () => { + DribbblishShared.config.registerSelect("Windows Top Bar", "winTopBar", ["None", "None (With Top Padding)", "Solid", "Transparent"], 0, (value) => { + switch (value) { + case 0: + document.getElementById("main").setAttribute("top-bar", "none"); + break; + case 1: + 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) { const queries = els.map(el => document.querySelector(el)); diff --git a/user.css b/user.css index a746d35..720ab81 100644 --- a/user.css +++ b/user.css @@ -6,7 +6,8 @@ --scrollbar-vertical-size: 8px; --cover-border-radius: 8px; --playbar-movement-anim-speed: 0.5s; - --os-windows-icon-dodge: 0; + --image-radius: 10px; + --sidebar-icons-border-radius: 50%; } @font-face { @@ -44,6 +45,15 @@ body { letter-spacing: normal; } +.os-scrollbar-handle { + background-color: var(--spice-text) !important; + border-radius: calc(var(--scrollbar-vertical-size) / 2); +} + +.os-scrollbar-handle:hover { + filter: brightness(80%); +} + .main-type-mesto, .main-type-mestoBold, .main-type-ballad, @@ -155,16 +165,6 @@ span.artist-artistVerifiedBadge-badge svg > path:last-of-type { line-height: 120px !important; } -/** Hightlight selected playlist */ -.main-rootlist-rootlistItemLink.main-rootlist-rootlistItemLinkActive { - background: var(--spice-button); - border-radius: 4px; -} - -.main-navBar-navBarLinkActive { - background: var(--spice-button); -} - .main-contextMenu-menu { background-color: var(--spice-button); } @@ -256,6 +256,23 @@ span.artist-artistVerifiedBadge-badge svg > path:last-of-type { height: 32px !important; } +.view-homeShortcutsGrid-shortcut { + overflow: hidden; +} + +.cover-art, +.view-homeShortcutsGrid-shortcut, +:not(.view-homeShortcutsGrid-imageWrapper) > .main-image-image:not(.main-avatar-image) { + border-radius: var(--image-radius) !important; +} + +.main-userWidget-box, +.main-avatar-userIcon, +.main-avatar-image, +.view-homeShortcutsGrid-shortcutLink { + border-radius: var(--sidebar-icons-border-radius) !important; +} + .main-avatar-avatar.main-avatar-withBadge:after { box-shadow: 0 0 0 2px var(--spice-sidebar); background-color: var(--spice-notification); @@ -321,7 +338,8 @@ html { } .main-navBar-navBarItem { - padding: 0 8px; + position: relative; + padding: 0px; } #spicetify-show-list >* { @@ -379,6 +397,28 @@ html.sidebar-hide-text .GlueDropTarget span { margin-top: 0; } +.main-rootlist-rootlist::before, +.main-rootlist-rootlist::after { + z-index: 10; + position: absolute; + content: ""; + left: 0px; + right: 0px; + pointer-events: none; +} + +.main-rootlist-rootlist::before { + top: 0px; + height: 5%; + background: linear-gradient(to bottom, var(--spice-sidebar) 10%, transparent); +} + +.main-rootlist-rootlist::after { + bottom: 0px; + height: 15%; + background: linear-gradient(to top, var(--spice-sidebar) 10%, transparent); +} + .Root__nav-bar .os-scrollbar-vertical, .main-buddyFeed-buddyFeedRoot .os-scrollbar-vertical { display: none; @@ -396,6 +436,7 @@ html.sidebar-hide-text .GlueDropTarget span { fill: var(--spice-button); } +.playback-bar__progress-time, .playback-bar__progress-time-elapsed, .main-playbackBarRemainingTime-container { display: none; @@ -531,7 +572,7 @@ img.playlist-picture { flex: 0 0 32px; background-size: cover; background-position: center; - border-radius: 50%; + border-radius: var(--sidebar-icons-border-radius); } .main-rootlist-rootlistItem a span { @@ -569,20 +610,52 @@ li.GlueDropTarget { } /** OS-specific window controls dodge */ -.spotify__os--is-windows .main-navBar-navBar { - padding-top: calc(var(--os-windows-icon-dodge) * 24px); +#main:not([top-bar^="none"]) .main-topBar-background { + -webkit-app-region: no-drag; } -.spotify__container--is-desktop:not(.fullscreen).spotify__os--is-windows .main-navBar-entryPoints { - padding-top: calc(var(--os-windows-icon-dodge) * 12px + 12px); +#main:not([top-bar="none-padding"]) .main-navBar-navBar, +#main:not([top-bar="none-padding"]) .main-buddyFeed-header, +#main:not([top-bar="none-padding"]) .main-navBar-entryPoints { + padding-top: 8px !important; } -.spotify__os--is-windows .main-buddyFeed-header { - padding-top: calc(var(--os-windows-icon-dodge) * 32px); +#main:not([top-bar^="none"]) { + padding-top: 31px; } -.spotify__container--is-desktop.spotify__os--is-windows[dir=ltr] .main-topBar-container { - padding-right: calc(var(--os-windows-icon-dodge) * 135px + 32px); +#main:not([top-bar^="none"])::before { + z-index: 999; + content: ""; + position: absolute; + top: 0px; + left: 0px; + right: 135px; + height: 31px; + background-color: rgba(0, 0, 0, 0.53); + -webkit-app-region: drag; + pointer-events: none; +} + +#main[top-bar="solid"]::before { + right: 0px; + background-color: black; +} + +#main[top-bar="none-padding"] .spotify__os--is-windows .main-navBar-navBar { + padding-top: 24px; +} + +#main[top-bar="none-padding"] .spotify__container--is-desktop:not(.fullscreen).spotify__os--is-windows .main-navBar-entryPoints { + padding-top: 22px; +} + +#main[top-bar="none-padding"] .spotify__os--is-windows .main-buddyFeed-header { + padding-top: 32px; +} + +#main[top-bar="none-padding"] .spotify__container--is-desktop.spotify__os--is-windows[dir=ltr] .Root__top-bar + .main-buddyFeed-buddyFeedRoot .main-topBar-container { + padding-right: 167px; } .main-topBar-container { @@ -590,18 +663,10 @@ li.GlueDropTarget { } /** Custom elements */ -#dribbblish-sidebar-fade-in { - position: absolute; - bottom: 0; - width: 100%; - height: 15%; - background: linear-gradient(to top, var(--spice-sidebar) 10%, transparent); - z-index: 3; - pointer-events: none; -} .dribs-playlist-list { - padding-bottom: 56px; + padding-bottom: 86px; } + #dribbblish-back-shadow { position: fixed; width: var(--main-view-width); @@ -745,6 +810,41 @@ span.main-userWidget-displayName, .main-navBar-entryPoints { --left-sidebar-padding-left: 24px; --left-sidebar-padding-right: 24px; + + padding: 0px 8px; +} + +.main-navBar-navBar, +.main-rootlist-wrapper > div:nth-child(2), +.main-navBar-entryPoints { + display: flex; + flex-direction: column; + gap: 5px; +} + +.main-rootlist-wrapper > div:nth-child(2) > li img, +.main-navBar-navBarLink > .icon { + z-index: 100; +} + +.main-navBar-navBarItem:hover::before, +.main-rootlist-rootlistItem:hover::before, +.main-rootlist-rootlistItemLinkActive::before { + content: ""; + position: absolute; + inset: 0px; + background-color: rgba(var(--spice-rgb-main), 0.4); + border-radius: var(--image-radius); + pointer-events: none; +} + +.main-navBar-navBarLinkActive { + border-radius: var(--image-radius); + background-color: rgba(var(--spice-rgb-main), 0.4); +} + +.main-navBar-navBar a:hover, .main-navBar-navBar a:hover span { + color: unset !important; } div.GlueDropTarget.personal-library { @@ -879,4 +979,4 @@ html.right-expanded-cover.buddyfeed-visible .main-coverSlotExpanded-container { .main-actionBar-ActionBarRow button:not(.main-playButton-primary) { color: var(--spice-subtext); -} +} \ No newline at end of file