From 221706239205e353e704581eca10d5daf4a3b5e2 Mon Sep 17 00:00:00 2001 From: Motschen Date: Mon, 1 May 2023 11:45:57 +0200 Subject: [PATCH] Add JavaScript based wallpaper changer This is entirely optional, but allows easy changing of wallpapers without editing the css. Thanks to @harbassan for letting me use parts of their code (https://github.com/harbassan/spicetify-galaxy/issues/28) --- color.ini | 2 +- manifest.json | 30 +++++--- theme.js | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++ user.css | 121 ++++++++++++++++++++++++++++++-- 4 files changed, 327 insertions(+), 14 deletions(-) create mode 100644 theme.js diff --git a/color.ini b/color.ini index 314d7ba..293c0b1 100644 --- a/color.ini +++ b/color.ini @@ -42,7 +42,7 @@ notification = 1a181e notification-error = fb7c7c misc = 0c0e14 -[summer] +[lush] text = ffffff subtext = 68fdab main = 0c0e14 diff --git a/manifest.json b/manifest.json index db4ab98..80a03ab 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,22 @@ -{ - "name": "Retroblur", - "description": "Theme with a background, blur, animations, gradients and reflections.", - "preview": "preview/dream.jpg", - "usercss": "user.css", - "schemes": "color.ini", - "readme": "README.md" -} +[ + { + "name": "Retroblur", + "description": "Theme with a background, blur, animations, gradients and reflections.", + "preview": "preview/dream.jpg", + "usercss": "user.css", + "schemes": "color.ini", + "include": ["https://raw.githubusercontent.com/Motschen/Retroblur/fresh/theme.js"], + "tags": ["retro", "blur", "animations", "gradients"], + "readme": "README.md" + }, + { + "name": "Retroblur Classic", + "description": "Theme with a background, blur, animations and reflections.", + "preview": "preview/playlist.png", + "usercss": "user.css", + "schemes": "color.ini", + "readme": "README.md", + "tags": ["retro", "blur", "animations"], + "branch": "main" + } +] \ No newline at end of file diff --git a/theme.js b/theme.js new file mode 100644 index 0000000..386ab55 --- /dev/null +++ b/theme.js @@ -0,0 +1,188 @@ +/* Based on https://github.com/harbassan/spicetify-galaxy/blob/main/galaxy.js + Credits to harbassan +*/ +(function retroblur() { + const YouTubeSVG = `` + if (!(Spicetify.Player.data && Spicetify.Platform)) { + setTimeout(retroblur, 100); + return; + } + + console.log("retroblur wallpaper changer running"); + + Object.keys(localStorage).forEach(item => { + if (item.includes("retroblur:temp")) localStorage.removeItem(item); + }); + + const config = {} + + function parseOptions() { + config.matchWallpaperToTheme = JSON.parse(localStorage.getItem("matchWallpaperToTheme")); + } + parseOptions() + + let isDim = false; + + function loopOptions(page) { + setBg(startImage); + } + + var defImage = `https://github.com/Motschen/Retroblur/blob/main/assets/background_purple.jpg?raw=true`; + console.log(getComputedStyle(document.body).getPropertyValue("--spice-button")) + switch (getComputedStyle(document.body).getPropertyValue("--spice-button")) { + case " #00bbff": { + console.log("setting default wallpaper to water"); + defImage = "https://images.unsplash.com/photo-1502933691298-84fc14542831?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"; + break; + } + case " #b0fd68": { + console.log("setting default wallpaper to lush"); + defImage = "https://images3.alphacoders.com/356/35627.jpg"; + break; + } + case " #ceeb26": { + console.log("setting default wallpaper to sun"); + defImage = "https://images.unsplash.com/photo-1516370873344-fb7c61054fa9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"; + break; + } + case " #ebb726": { + console.log("setting default wallpaper to sunset"); + defImage = "https://4kwallpapers.com/images/walls/thumbs_3t/4928.jpg"; + break; + } + case " #a10003": { + console.log("setting default wallpaper to mercy"); + defImage = "https://images3.alphacoders.com/356/35627.jpg"; + break; + } + } + let startImage = localStorage.getItem("retroblur:startupBg") || defImage; + if (config.matchWallpaperToTheme) startImage = defImage; + + function setBg(imageData) { + var image = imageData; + if (config.matchWallpaperToTheme) image = defImage; + document.body.style.backgroundImage = "url("+image+")"; + console.log("setBG"+image) + } + + // input for custom background images + const bannerInput = document.createElement("input"); + bannerInput.type = "file"; + bannerInput.className = "banner-input"; + bannerInput.accept = ["image/jpeg", "image/apng", "image/avif", "image/gif", "image/png", "image/svg+xml", "image/webp"].join(","); + + // when user selects a custom background image + bannerInput.onchange = () => { + if (!bannerInput.files.length) return; + + const file = bannerInput.files[0]; + const reader = new FileReader(); + reader.onload = event => { + const result = event.target.result; + try { + localStorage.setItem("retroblur:startupBg", result); + } catch { + Spicetify.showNotification("File too large"); + return; + } + document.querySelector("#wallpaper-select img").src = result; + }; + reader.readAsDataURL(file); + }; + + const wallpaperEdit = new Spicetify.Menu.Item( + "Edit Wallpaper", + false, + () => { + const content = document.createElement("div"); + content.innerHTML = ` +
+
+
+
+
+
`; + + const optionList = document.createElement("div"); + + function createOption(name, desc, defVal) { + const optionRow = document.createElement("div"); + optionRow.classList.add("retroblurOptionRow"); + optionRow.innerHTML = ` + ${desc} + `; + optionRow.setAttribute("name", name); + optionRow.querySelector("button").addEventListener("click", () => { + optionRow.querySelector(".toggle").classList.toggle("enabled"); + }); + const isEnabled = JSON.parse(localStorage.getItem(name)) ?? defVal; + optionRow.querySelector(".toggle").classList.toggle("enabled", isEnabled); + optionList.append(optionRow); + } + + const srcInput = document.createElement("input"); + srcInput.type = "text"; + srcInput.classList.add("main-playlistEditDetailsModal-textElement", "main-playlistEditDetailsModal-titleInput"); + srcInput.id = "src-input"; + srcInput.placeholder = "Wallpaper image URL (recommended)"; + content.append(srcInput); + + createOption("matchWallpaperToTheme", "Match wallpaper to the color scheme", true); + + content.append(optionList); + + img = content.querySelector("img"); + img.src = localStorage.getItem("retroblur:startupBg") || defImage; + const editButton = content.querySelector(".main-editImageButton-image.main-editImageButton-overlay"); + editButton.onclick = () => { + bannerInput.click(); + }; + const removeButton = content.querySelector(".main-playlistEditDetailsModal-imageDropDownButton"); + removeButton.onclick = () => { + content.querySelector("img").src = defImage; + }; + + const saveButton = document.createElement("button"); + saveButton.id = "wallpaper-save"; + saveButton.innerHTML = "Save"; + + saveButton.addEventListener("click", () => { + // update changed bg image + startImage = srcInput.value || content.querySelector("img").src; + localStorage.setItem("retroblur:startupBg", startImage); + + // save options to local storage + [...optionList.children].forEach(option => { + localStorage.setItem(option.getAttribute("name"), option.querySelector(".toggle").classList.contains("enabled")); + console.log(`retroblur: ${option.getAttribute("name")} set to ${option.querySelector(".toggle").classList.contains("enabled")}`); + }); + parseOptions(); + loopOptions("/") + }); + + content.append(saveButton); + + const issueButton = document.createElement("a"); + issueButton.classList.add("issue-button"); + issueButton.innerHTML = "Report Issue"; + issueButton.href = "https://github.com/Motschen/Retroblur/issues"; + content.append(issueButton); + + Spicetify.PopupModal.display({ title: "Retroblur Settings", content: content }); + }, + YouTubeSVG + ).register() + + let trackContextMenu = new Spicetify.ContextMenu.Item("Edit Wallpaper", () => {}, true, YouTubeSVG) + trackContextMenu.register() + + // startup parse + loopOptions("/"); + })(); \ No newline at end of file diff --git a/user.css b/user.css index e9e6bed..9cf5994 100644 --- a/user.css +++ b/user.css @@ -13,11 +13,11 @@ -> Here are some cartoon wallpapers that suit their theme well: Bridge (Dream): https://github.com/Motschen/Retroblur/blob/fresh/assets/background_purple.jpg?raw=true Bridge (Mercy): https://github.com/Motschen/Retroblur/blob/fresh/assets/background_red.jpg?raw=true - Bridge (Summer): https://github.com/Motschen/Retroblur/blob/fresh/assets/background_green.jpg?raw=true + Bridge (Lush): https://github.com/Motschen/Retroblur/blob/fresh/assets/background_green.jpg?raw=true Bridge (Sun): https://github.com/Motschen/Retroblur/blob/fresh/assets/background_yellow.jpg?raw=true Bridge (Water: https://github.com/Motschen/Retroblur/blob/fresh/assets/background_blue.jpg?raw=true Bridge Wallpaper Source: https://wallpapercave.com/wp/wp5003466.jpg - Forest (Summer): https://i.imgur.com/hnpaDeR.jpg + Forest (Lush): https://i.imgur.com/hnpaDeR.jpg -> Here are some real life wallpapers that suit their theme well: Beach (Sun): https://wallpapercave.com/wp/wp5922621.jpg @@ -27,7 +27,7 @@ Source: https://4kwallpapers.com/flowers/red-flower-red-rose-10670.html Evening Clouds (Sunset): https://4kwallpapers.com/images/walls/thumbs_3t/4928.jpg Source: https://4kwallpapers.com/nature/sunset-mountain-range-silhouette-landscape-orange-sky-4928.html - Waterfalls (Summer): https://images3.alphacoders.com/356/35627.jpg + Waterfalls (Lush): https://images3.alphacoders.com/356/35627.jpg Source: https://wall.alphacoders.com/big.php?i=35627 Surfing (Sun): https://images.unsplash.com/photo-1516370873344-fb7c61054fa9?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80 Source: https://unsplash.com/de/fotos/xarhNpLSHTk @@ -37,7 +37,7 @@ body { /* Set the wallpaper link below */ /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ - background-image: url("https://github.com/Motschen/Retroblur/blob/fresh/assets/background_purple.jpg?raw=true") !important; + background-image: linear-gradient(left, #000000, #000000); /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ background-repeat: no-repeat; background-size: 100%; @@ -594,8 +594,9 @@ path[d="M23 0C10.298 0 0 10.297 0 23c0 12.702 10.298 23 23 23 12.703 0 23-10.298 } */ /* modals */ .main-trackCreditsModal-container, .main-aboutRecsModal-container, .main-playlistEditDetailsModal-container, .profile-userEditDetails-container, .artist-artistAbout-modal { - + background-color: rgba(30, 30, 30, 0.4); border-radius: var(--border-radius-1) !important; + backdrop-filter: blur(14px); } .main-playlistEditDetailsModal-titleInput, .main-playlistEditDetailsModal-descriptionTextarea, .main-playlistEditDetailsModal-titleInput:focus, .main-playlistEditDetailsModal-descriptionTextarea:focus, .playlist-inlineSearchBox-filterInput { background-color: rgba(30, 30, 30, 0.4) !important; @@ -902,6 +903,7 @@ CANVAS!!! background-size: 200% 200%; animation: gradientFade 3s linear infinite alternate; } +#wallpaper-save, .ButtonInner-lg-iconOnly, .playlist-item__img.folder, .main-rootlist-rootlistItemLinkActive, .main-rootlist-rootlistItemLinkActive:hover, .VBBDTqhWgM6gWFAMJSUV, .VBBDTqhWgM6gWFAMJSUV:hover, @@ -912,6 +914,7 @@ CANVAS!!! background-size: 200% 200% !important; animation: gradientFade 3s ease infinite alternate; } +#wallpaper-save:hover, .main-rootlist-rootlistItemLinkActive, .main-rootlist-rootlistItemLinkActive:hover, .VBBDTqhWgM6gWFAMJSUV, .VBBDTqhWgM6gWFAMJSUV:hover, .ac0df040748287f39652cc42e3b762ba-scss._926f2bd73c2ddb23fb86b430a2f48707-scss, .main-collectionLinkButton-selected, .main-collectionLinkButton-collectionLinkButton.active, .main-navBar-navBarLinkActive, .main-navBar-navBarLinkActive:hover, .main-navBar-navBarLinkActive:active, .main-navBar-navBarLinkActive:focus { @@ -984,4 +987,112 @@ CANVAS!!! .Button-sm-16-buttonTertiary-iconOnly-useBrowserDefaultFocusStyle, .main-shuffleButton-button.main-shuffleButton-active, .control-button { color: var(--spice-subtext) !important; +} +/* +------------------- +HOME POPUP +------------------- +*/ +#wallpaper-select { + width: 100%; + height: 200px; + margin-bottom: 20px; +} +div[aria-label="Retroblur Settings"] .main-trackCreditsModal-mainSection { + overflow-y: hidden; + padding: 24px; +} +.main-trackCreditsModal-container { + max-height: 620px; +} +.main-trackCreditsModal-originalCredits { + padding-bottom: 0; +} +.main-userWidget-dropDownMenu li.main-contextMenu-menuItem > div { + left: calc(225px + 185px) !important; + width: 225px; +} +.retroblurOptionRow { + display: flex; + justify-content: space-between; + align-items: initial; +} +button.retroblurOptionToggle { + display: flex; + background-color: transparent; + border: hidden; +} +span.toggleWrapper { + width: 42px; + height: 24px; + background-color: var(--spice-button); + border-radius: 12px; + display: flex; + align-items: center; +} +span.toggleWrapper:disabled { + background-color: gray; +} +span.toggle { + width: 20px; + height: 20px; + border-radius: 10px; + background-color: black; + margin-left: 2px; +} +span.toggle.enabled { + margin-left: 20px; +} +#src-input { + margin-bottom: 15px; +} +#wallpaper-save { + margin-top: 15px; + box-sizing: border-box; + font-family: var(--font-family, spotify-circular),Helvetica,Arial,sans-serif; + -webkit-tap-highlight-color: transparent; + font-size: 1rem; + line-height: 1.5rem; + font-weight: 700; + background-color: transparent; + border: 0; + border-radius: 500px; + display: inline-block; + position: relative; + text-align: center; + text-decoration: none; + text-transform: none; + touch-action: manipulation; + transition-duration: 33ms; + transition-property: background-color,border-color,color,box-shadow,filter,transform; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + vertical-align: middle; + transform: translate3d(0,0,0); + padding: 0; + min-inline-size: 0px; + align-self: center; + position: relative; + border-radius: 500px; + font-size: inherit; + padding-block: 12px; + padding-inline: 32px; + color: black; + background-color: var(--spice-button); +} +/* report issue link */ +.issue-button { + display: initial; + vertical-align: -webkit-baseline-middle; + font-size: 0.8em; + width: fit-content; + margin-left: 210px; +} +#wallpaper-select > div.main-playlistEditDetailsModal-imageDropDownContainer > button > svg, +#wallpaper-select > div.main-playlistEditDetailsModal-imageChangeButton > div > button > div { + fill: var(--spice-text) +} +#wallpaper-select > div.main-playlistEditDetailsModal-imageChangeButton > div > button { + border-radius: 10px; } \ No newline at end of file