diff --git a/.gitignore b/.gitignore index 5280ec6..1fb9454 100644 --- a/.gitignore +++ b/.gitignore @@ -142,3 +142,6 @@ out .svelte-kit # End of https://www.toptal.com/developers/gitignore/api/node + +# .idea directory from Jetbrains +.idea diff --git a/LuckyLP.js b/LuckyLP.js index 88157da..e94f477 100644 --- a/LuckyLP.js +++ b/LuckyLP.js @@ -1,3 +1,2 @@ -var LuckyLP=(()=>{var e,t,l=Object.create,c=Object.defineProperty,s=Object.getOwnPropertyDescriptor,m=Object.getOwnPropertyNames,u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty,a=(e,t,a)=>{a=null!=e?l(u(e)):{};var i=!t&&e&&e.__esModule?a:c(a,"default",{value:e,enumerable:!0}),o=e,n=void 0,r=void 0;if(o&&"object"==typeof o||"function"==typeof o)for(let e of m(o))f.call(i,e)||e===n||c(i,e,{get:()=>o[e],enumerable:!(r=s(o,e))||r.enumerable});return i},i=(e={"external-global-plugin:react"(e,t){t.exports=Spicetify.React}},function(){return t||(0,e[m(e)[0]])((t={exports:{}}).exports,t),t.exports}),o=a(i()),n=a(i()),r=()=>n.default.createElement("svg",{role:"img",height:"16",width:"16","aria-hidden":"true",viewBox:"0 0 16 16","data-encore-id":"icon",className:"Svg-img-16-icon x-filterBox-searchIcon"},n.default.createElement("path",{d:"M13.151.922a.75.75 0 1 0-1.06 1.06L13.109 3H11.16a3.75 3.75 0 0 0-2.873 1.34l-6.173 7.356A2.25 2.25 0 0 1 .39 12.5H0V14h.391a3.75 3.75 0 0 0 2.873-1.34l6.173-7.356a2.25 2.25 0 0 1 1.724-.804h1.947l-1.017 1.018a.75.75 0 0 0 1.06 1.06L15.98 3.75 13.15.922zM.391 3.5H0V2h.391c1.109 0 2.16.49 2.873 1.34L4.89 5.277l-.979 1.167-1.796-2.14A2.25 2.25 0 0 0 .39 3.5z"}),n.default.createElement("path",{d:"m7.5 10.723.98-1.167.957 1.14a2.25 2.25 0 0 0 1.724.804h1.947l-1.017-1.018a.75.75 0 1 1 1.06-1.06l2.829 2.828-2.829 2.828a.75.75 0 1 1-1.06-1.06L13.109 13H11.16a3.75 3.75 0 0 1-2.873-1.34l-.787-.938z"})),d=async()=>{try{var e,t,a,i=await Spicetify.CosmosAsync.get("https://api.spotify.com/v1/me/albums?limit=1");return i&&null!=i&&i.total?(e=i.total,o=e,t=Math.floor(Math.random()*(o+1)),a=(await Spicetify.CosmosAsync.get("https://api.spotify.com/v1/me/albums?limit=1&offset="+(t-1))).items[0],Spicetify.Platform.History.push("/album/"+a.album.id),a):!1}catch(e){return!1}var o},p=async()=>{Spicetify.showNotification("Choosing random album...");var e,t=await d();!1!==t?(e=t.album.artists.map(e=>e.name).join(","),Spicetify.showNotification(`Chosen album: ${t.album.name} by ${e}`)):Spicetify.showNotification("Random album cannot be chosen.",!0)},y=Spicetify.ReactComponent.TooltipWrapper,b=Spicetify.ReactDOM,h=()=>{var e=document.querySelector(".collection-searchBar-searchBar");e&&b.render(b.createPortal(o.default.createElement(y,{label:"Get Random Saved Album",showDelay:200},o.default.createElement("div",{className:"x-filterBox-filterInputContainer random-saved-album-container",role:"button"},o.default.createElement("div",{className:"x-filterBox-overlay"},o.default.createElement("span",{className:"x-filterBox-searchIconContainer"},o.default.createElement(r,null))),o.default.createElement("button",{type:"button",onClick:p,id:"random-saved-album-btn",className:"x-filterBox-expandButton"},o.default.createElement(r,null)))),e),document.createElement("div"))},v=new MutationObserver(()=>{h()}),g={characterData:!1,attributes:!1,childList:!0,subtree:!1},x=()=>{var e=document.querySelector(".contentSpacing");e&&v.observe(e,g)};var S=async function(){for(;!(null!=Spicetify&&Spicetify.showNotification||null!=Spicetify&&Spicetify.Platform);)await new Promise(e=>setTimeout(e,500));Spicetify.Platform.History.listen(()=>{"/collection/albums"===Spicetify.Platform.History.location.pathname?x():v.disconnect()})};(async()=>{await S()})()})();(async()=>{var e;document.getElementById("LuckyLP")||((e=document.createElement("style")).id="LuckyLP",e.textContent=String.raw` - .random-saved-album-container{display:flex;align-items:center;justify-content:center;position:relative;margin-left:8px}.random-saved-album-container button{display:flex;align-items:center;position:relative} - `.trim(),document.head.appendChild(e))})(); \ No newline at end of file +var LuckyLP=(()=>{var t=()=>{return"/"===Spicetify.Platform.History.location.pathname},a=()=>{return Spicetify.Platform.History.location.pathname.startsWith("/album/")},i=async()=>{try{var t,a,i,o=await Spicetify.CosmosAsync.get("https://api.spotify.com/v1/me/albums?limit=1");return o&&null!=o&&o.total?(t=o.total,e=t,a=Math.floor(Math.random()*(e+1)),i=(await Spicetify.CosmosAsync.get("https://api.spotify.com/v1/me/albums?limit=1&offset="+(a-1))).items[0],Spicetify.Platform.History.push("/album/"+i.album.id),i):!1}catch(t){return!1}var e},o=async()=>{Spicetify.showNotification("Choosing random album...");var t,a=await i();!1!==a?(t=a.album.artists.map(t=>t.name).join(","),Spicetify.showNotification(`Chosen album: ${a.album.name} by ${t}`)):Spicetify.showNotification("Random album cannot be chosen.",!0)},e=()=>` + `,n=()=>{document.getElementById("random-saved-album-btn")||(new Spicetify.Topbar.Button("Get Random Saved Album",`${e}`,o).element.id="random-saved-album-btn")},m=()=>{var t=document.getElementById("random-saved-album-btn");t&&t.remove()},l=()=>{(t()||a()?n:m)()};var s=async function(){for(;!(null!=Spicetify&&Spicetify.showNotification||null!=Spicetify&&Spicetify.Platform);)await new Promise(t=>setTimeout(t,500));l(),Spicetify.Platform.History.listen(()=>{l()})};(async()=>{await s()})()})(); \ No newline at end of file diff --git a/README.md b/README.md index 0da37d3..b66de4b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # LuckyLP - Spicetify Extension -LuckyLP is a Spicetify Extension which allows to easily choose random album from your album collection. Just press the "Get Random Saved Album" button located in the header section of album collection page. +LuckyLP is a Spicetify Extension which allows to easily choose random album from your album collection. Just press the _"Get Random Saved Album"_ button located in the navigation section of home or album page. +> **Note:** This extension only works with +> - Spicetify v2.20.0 and above +> - Spotify 1.2.15.828.g79f41970 and above ## Installation @@ -23,10 +26,12 @@ spicetify config extensions LuckyLP.js spicetify apply ``` -## Screeshots +## Screeshot ![Screenshot 1](/screenshots/Screenshot_1.png) +![Screenshot 2](/screenshots/Screenshot_2.png) + ## Docs Check out [Spicetify's docs](https://spicetify.app/docs/development/spicetify-creator/the-basics)! diff --git a/manifest.json b/manifest.json index c1c0509..ee55cb5 100644 --- a/manifest.json +++ b/manifest.json @@ -1,11 +1,11 @@ { "name": "LuckyLP", - "description": "Spicetify extension to add 'Get Random Saved Album' in user's Album Collection", - "preview": "screenshots/Screenshot_2.png", + "description": "Spicetify extension to add 'Get Random Saved Album' in user's Home Page", + "preview": "screenshots/Extension_prev.png", "main": "LuckyLP.js", "readme": "README.md", "authors": [ { "name": "Akasiek", "url": "https://github.com/Akasiek" } ], "tags": ["album collection"] -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index 23ef2f0..ea7ca15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lucky-lp", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "lucky-lp", - "version": "1.0.0", + "version": "2.0.0", "license": "MIT", "dependencies": { "prettier": "^2.8.6" diff --git a/package.json b/package.json index 69b9c9b..b6d9390 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lucky-lp", - "version": "1.2.1", + "version": "2.0.0", "private": true, "scripts": { "build": "spicetify-creator", diff --git a/screenshots/Extension_prev.png b/screenshots/Extension_prev.png new file mode 100644 index 0000000..6565792 Binary files /dev/null and b/screenshots/Extension_prev.png differ diff --git a/screenshots/Screenshot_1.png b/screenshots/Screenshot_1.png index fa857c9..fe13706 100644 Binary files a/screenshots/Screenshot_1.png and b/screenshots/Screenshot_1.png differ diff --git a/screenshots/Screenshot_2.png b/screenshots/Screenshot_2.png index 901d8f8..d8d51bc 100644 Binary files a/screenshots/Screenshot_2.png and b/screenshots/Screenshot_2.png differ diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..1ef7fcc --- /dev/null +++ b/src/app.ts @@ -0,0 +1,26 @@ +import { isAlbumPage, isHomePage } from "./util"; +import { addButton, removeButton } from "./button"; + +const toggleButton = () => { + if (isHomePage() || isAlbumPage()) { + addButton(); + } else { + removeButton(); + } +}; + +async function main() { + while (!Spicetify?.showNotification && !Spicetify?.Platform) { + await new Promise((resolve) => setTimeout(resolve, 500)); + } + + // Show button on app load + toggleButton(); + + // Show button depending on navigation + Spicetify.Platform.History.listen(() => { + toggleButton(); + }); +} + +export default main; diff --git a/src/app.tsx b/src/app.tsx deleted file mode 100644 index 8b5e024..0000000 --- a/src/app.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from "react"; -import startObserver, { disconnectObserver } from "./observer"; -import { isAlbumCollectionPage } from "./util"; -import "./style.scss"; - -async function main() { - while (!Spicetify?.showNotification && !Spicetify?.Platform) { - await new Promise((resolve) => setTimeout(resolve, 500)); - } - - Spicetify.Platform.History.listen(() => { - if (isAlbumCollectionPage()) { - startObserver(); - } else { - disconnectObserver(); - } - }); -} - -export default main; diff --git a/src/button.ts b/src/button.ts new file mode 100644 index 0000000..4f401c3 --- /dev/null +++ b/src/button.ts @@ -0,0 +1,28 @@ +import ShuffleIcon from "./shuffleIcon"; +import { handleClick } from "./util"; + +const renderButton = () => { + const randomBtn = new Spicetify.Topbar.Button( + "Get Random Saved Album", + `${ShuffleIcon}`, + handleClick + ); + + randomBtn.element.id = "random-saved-album-btn"; +}; + +export const addButton = () => { + const btn = document.getElementById("random-saved-album-btn"); + + if (!btn) { + renderButton(); + } +}; + +export const removeButton = () => { + const btn = document.getElementById("random-saved-album-btn"); + + if (btn) { + btn.remove(); + } +}; diff --git a/src/button.tsx b/src/button.tsx deleted file mode 100644 index 89ac04e..0000000 --- a/src/button.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import ShuffleIcon from "./shuffleIcon"; -import { handleClick } from "./util"; -import TooltipWrapper = Spicetify.ReactComponent.TooltipWrapper; - -const reactDom = Spicetify.ReactDOM as typeof ReactDOM; - -const createButton = () => ( - -
-
- - - -
- -
-
-); - -const renderButton = () => { - const btnSection = document.querySelector(".collection-searchBar-searchBar"); - - if (btnSection) { - reactDom.render( - reactDom.createPortal(createButton(), btnSection), - document.createElement("div") - ); - } -}; -export default renderButton; diff --git a/src/observer.ts b/src/observer.ts deleted file mode 100644 index 87df434..0000000 --- a/src/observer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import renderButton from "./button"; - -const mutate = () => { - renderButton(); -}; - -const observer = new MutationObserver(mutate); - -const config = { - characterData: false, - attributes: false, - childList: true, - subtree: false, -}; - -const startObserver = () => { - const mainElement = document.querySelector(".contentSpacing"); - if (mainElement) { - observer.observe(mainElement, config); - } -}; - -export const disconnectObserver = () => observer.disconnect(); - -export default startObserver; diff --git a/src/shuffleIcon.ts b/src/shuffleIcon.ts new file mode 100644 index 0000000..bd53150 --- /dev/null +++ b/src/shuffleIcon.ts @@ -0,0 +1,5 @@ +const ShuffleIcon = () => + ` + `; + +export default ShuffleIcon; diff --git a/src/shuffleIcon.tsx b/src/shuffleIcon.tsx deleted file mode 100644 index 49134e8..0000000 --- a/src/shuffleIcon.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; - -const ShuffleIcon = () => ( - -); - -export default ShuffleIcon; diff --git a/src/style.scss b/src/style.scss deleted file mode 100644 index 3236ffc..0000000 --- a/src/style.scss +++ /dev/null @@ -1,14 +0,0 @@ -.random-saved-album-container { - display: flex; - align-items: center; - justify-content: center; - position: relative; - - margin-left: 8px; - - button { - display: flex; - align-items: center; - position: relative; - } -} diff --git a/src/util.ts b/src/util.ts index de1e54e..f454298 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,8 +1,13 @@ import { IAlbum, ISavedAlbums } from "./types/api"; -export const isAlbumCollectionPage = () => { +export const isHomePage = () => { const pathname = Spicetify.Platform.History.location.pathname; - return pathname === "/collection/albums"; + return pathname === "/"; +}; + +export const isAlbumPage = () => { + const pathname = Spicetify.Platform.History.location.pathname; + return pathname.startsWith("/album/"); }; const getRandomAlbumIndex = (total: number): number =>