From 946488446d8464b09c36622c9bc6de6b5dcc0068 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 19 Mar 2024 18:17:58 -0400 Subject: [PATCH 1/3] Fetch snippets from the GitHub repo at runtime --- .../snippets.ts => resources/snippets.json | 124 +++++++++--------- src/components/Grid.tsx | 6 +- src/constants.ts | 3 + src/logic/FetchRemotes.ts | 8 +- 4 files changed, 74 insertions(+), 67 deletions(-) rename src/resources/snippets.ts => resources/snippets.json (85%) diff --git a/src/resources/snippets.ts b/resources/snippets.json similarity index 85% rename from src/resources/snippets.ts rename to resources/snippets.json index 02f54c10..80fc48e9 100644 --- a/src/resources/snippets.ts +++ b/resources/snippets.json @@ -1,332 +1,332 @@ -export default [ +[ { "title": "Rounded 'Now Playing' Bar", "description": "Adds rounded corners to the 'Now Playing' bar so it matches the rest of the User Interface.", "code": ":root{ --border-radius-1: 8px; } .Root__now-playing-bar, .Root__now-playing-bar footer { border-radius: var(--border-radius-1) !important; }", - "preview": "resources/assets/snippets/rounded-now-playing.png", + "preview": "resources/assets/snippets/rounded-now-playing.png" }, { "title": "Rounded Images", "description": "Adds rounded corners to the cover art, playlist covers, cards and other images", "code": "/* Expanded Cover Art Image (+ position fix) */\n .main-navBar-navBar > :nth-child(3) {\n margin: 0 0 0 1px;\n border-radius: 6px;\n }\n \n /* Collapsed Cover Art Image */\n .cover-art-image,\n .artist-artistOverview-sideBlock > div > section > div:nth-child(3) > section:nth-child(2) > div > img,\n .view-homeShortcutsGrid-image {\n border-radius: 4px;\n }\n \n /*\n Playlist Header\n Search Category Card Image\n List Cards\n Local Files Card\n Placeholder Profile Card\n Artist Overview Side Block\n */\n .main-entityHeader-shadow,\n .x-categoryCard-image,\n .main-cardImage-image,\n .main-cardImage-imageWrapper,\n .main-entityHeader-imagePlaceholder > div,\n .artist-artistOverview-sideBlock > div > section {\n border-radius: 6px;\n }\n \n /* Circled Artist + Profile Cards (force) */\n .main-cardImage-circular,\n .main-entityHeader-imagePlaceholder,\n .main-entityHeader-circle {\n border-radius: 50% !important;\n }\n \n /* Track List Image */\n .main-trackList-rowImage {\n border-radius: 3px;\n }", - "preview": "resources/assets/snippets/rounded-images.png", + "preview": "resources/assets/snippets/rounded-images.png" }, { "title": "Fix 'Episodes' Icon", "description": "Makes the 'Your Episodes' button icon monochromatic like the rest of the icons.", "code": ".main-yourEpisodesButton-yourEpisodesIcon { background: var(--spice-text); color: var(--spice-sidebar); }", - "preview": "resources/assets/snippets/fixed-episodes-icon.png", + "preview": "resources/assets/snippets/fixed-episodes-icon.png" }, { "title": "Fix 'Liked' Icon", "description": "Fix the colours of the Liked icon in sidebar", "code": ".main-likedSongsButton-likedSongsIcon {\n color: var(--spice-sidebar);\n background: var(--spice-text);\n}", - "preview": "resources/assets/snippets/fix-liked-icon.png", + "preview": "resources/assets/snippets/fix-liked-icon.png" }, { "title": "Fix 'DJ' Icon", "description": "Makes the DJ icon match themes better", "code": ".main-collectionLinkButton-icon > div { background: var(--spice-text); color: var(--spice-sidebar); }", - "preview": "resources/assets/snippets/fix-DJ-icon.png", + "preview": "resources/assets/snippets/fix-DJ-icon.png" }, { "title": "Auto-hide Friends", "description": "Collapse the friends activity sidebar on small screens", "code": ".Root__right-sidebar {\n transition: width 0.3s;\n}\n@media screen and (max-width: 1200px) {\n .Root__right-sidebar {\n width: 0;\n }\n .Root__right-sidebar .LayoutResizer__resize-bar {\n display: none;\n }\n}", - "preview": "resources/assets/snippets/auto-hide-friends.png", + "preview": "resources/assets/snippets/auto-hide-friends.png" }, { "title": "Smooth Reveal Playlist Gradient", "description": "Reveals the playlist gradient header gradient with a fade in effect", "code": ".main-entityHeader-overlay,\n.main-actionBarBackground-background,\n.main-entityHeader-overlay,\n.main-entityHeader-backgroundColor {\n -webkit-transition: 3s;\n}", - "preview": "resources/assets/snippets/smooth-playlist-reveal-gradient.png", + "preview": "resources/assets/snippets/smooth-playlist-reveal-gradient.png" }, { "title": "Remove connect bar", "description": "Remove connect bar that causes progress bar displacement when listening on different devices", "code": ".main-connectBar-connectBar {\n display: none !important;}", - "preview": "resources/assets/snippets/remove-connect-bar.png", + "preview": "resources/assets/snippets/remove-connect-bar.png" }, { "title": "Fix main view width", "description": "Makes main view fill up all available space", "code": ".contentSpacing {\n max-width: 100% !important;\n}", - "preview": "resources/assets/snippets/fix-main-view-width.png", + "preview": "resources/assets/snippets/fix-main-view-width.png" }, { "title": "Left aligned heart icons", "description": "Moves the heart icon to the left side of the track title in track views", "code": ".main-trackList-rowSectionStart {\n margin-left: 38px !important;\n}\n.main-trackList-rowHeartButton {\n position: absolute !important;\n left: 48px !important;\n}", - "preview": "resources/assets/snippets/left-aligned-heart-icons.png", + "preview": "resources/assets/snippets/left-aligned-heart-icons.png" }, { "title": "Hover Panels", "description": "Have your playlist, right sidebar, and controls bar be hoverable.", "code": ".Root__nav-bar {\n position: absolute;\n width: 35px;\n opacity: 0;\n bottom: 0;\n left: 0;\n top: 0;\n z-index: 12;\n transition: width 400ms, opacity 250ms ease-out;\n}\n.main-yourLibraryX-entryPoints {\n background: var(--spice-sidebar);\n}\n.Root__nav-bar:hover {\n width: 250px;\n opacity: 1;\n transition: width 250ms, opacity 400ms ease-in;\n}\n.LayoutResizer__resize-bar {\n cursor: none;\n}\n.Root__top-bar {\n opacity: 0;\n transition: visibility 5s, opacity 1s linear;\n}\n.Root__top-bar:hover {\n transition-delay: 0.5s;\n opacity: 1;\n transition: visibility 5s, opacity 0.5s linear;\n}\n.main-topBar-container {\n -webkit-padding-end: 32px;\n padding: 16px 85px;\n padding-inline-end: 32px;\n max-width: none;\n}\n.main-buddyFeed-container:hover {\n width: 350px !important;\n opacity: 1 !important;\n transition: width 250ms, opacity 400ms ease-in;\n}\n.main-buddyFeed-container {\n position: absolute;\n right: -5px;\n top: 0;\n bottom: 84px;\n width: 50px !important;\n opacity: 0 !important;\n transition: width 400ms, opacity 250ms ease-out;\n}\n.main-trackList-trackListHeader {\n top: 0 !important;\n}\n.main-yourLibraryX-navItem {\n overflow: hidden;\n}\n.main-coverSlotCollapsed-navAltContainer {\n overflow: visible;\n}\n.LayoutResizer__resize-bar {\n display: none;\n}\n:root {\n --left-sidebar-width: 35px !important;\n --right-sidebar-width: 50px !important;\n}", - "preview": "resources/assets/snippets/hover-panels.png", + "preview": "resources/assets/snippets/hover-panels.png" }, { "title": "Fix progress bar displacement", "description": "Fixes the progress bar displacement for a few themes. Better version of @CharlieS1103 Snippet", "code": ".main-connectBar-connectBar {\n overflow: visible !important;\n position: absolute !important;\n display: flex !important;\n align-items: unset !important;\n left: 80% !important;\n height: 20px !important;\n bottom: 1% !important;\n padding: 2px !important;\n background-color: transparent !important;\n color: var(--spice-text) !important;\n}\n.control-button::after {\n display: none !important;\n}", - "preview": "resources/assets/snippets/fix-progress-bar.png", + "preview": "resources/assets/snippets/fix-progress-bar.png" }, { "title": "Fix playlist hover effect", "description": "Fixes the hover effect on the playlist titles in some themes", "code": ".main-rootlist-rootlistItemOverlay {\n display: none;\n}", - "preview": "resources/assets/snippets/fix-playlist-hover.png", + "preview": "resources/assets/snippets/fix-playlist-hover.png" }, { "title": "Disable Homepage Recommendations", "description": "Removes all recommendations from the homepage", "code": "[data-testid='home-page'] .main-home-content > *:not(.view-homeShortcutsGrid-shortcuts, .main-shelf-shelf:has([href=\"/genre/recently-played\"], [href=\"/section/0JQ5DAnM3wGh0gz1MXnu3z\"])) {\n display: none !important;\n}", - "preview": "resources/assets/snippets/disable-recommendations.png", + "preview": "resources/assets/snippets/disable-recommendations.png" }, { "title": "Circular Album Art", "description": "Makes the now playing album art be circular (like a vinyl)", "code": ".cover-art { clip-path: circle(50% at 50% 50%);}", - "preview": "resources/assets/snippets/circular-album-art.png", + "preview": "resources/assets/snippets/circular-album-art.png" }, { "title": "Always show forward button", "description": "The navigate forward button hides itself when the window width is smaller. This snipppet makes it so that it is always shown.", "code": ".main-topBar-historyButtons .main-topBar-forward {\n display: inline-flex !important;\n}", - "preview": "resources/assets/snippets/always-show-forward.png", + "preview": "resources/assets/snippets/always-show-forward.png" }, { "title": "Right Side Cover Art", "description": "Cover art on right side with animation", "code": ".main-nowPlayingWidget-nowPlaying > .ellipsis-one-line,\n.main-trackInfo-container {\n margin-left: 74px;\n}\n.main-coverSlotExpanded-container {\n position: fixed;\n top: calc(100% - 305px);\n left: calc(100% - 220px);\n width: 200px;\n height: 200px;\n visibility: hidden;\n transform-origin: center;\n animation: 1s coverExpandedIn;\n animation-fill-mode: forwards;\n}\n.Q4cc5RktWgz2H8_vDrIS {\n display: none;\n}\n.main-coverSlotCollapsed-container {\n position: fixed;\n top: -12px;\n left: 0px;\n width: 56px;\n height: 56px;\n visibility: visible;\n z-index: 1;\n}\n.cover-art .cover-art-image,\n.main-coverSlotCollapsed-container {\n transform-origin: center;\n transition-timing-function: ease-in;\n transition: width 0.5s 0.2s, height 0.5s 0.2s, top 0.3s, left 0.5s,\n box-shadow 0.5s;\n}\n.main-coverSlotCollapsed-container[aria-hidden='true'] {\n left: calc(100vw - 164px);\n top: -240px;\n width: 200px;\n height: 200px;\n visibility: hidden;\n animation: 1s coverExpandedOut;\n}\n.main-coverSlotCollapsed-container[aria-hidden='false'] {\n transition-timing-function: ease-out !important;\n transition: width 0.5s 0.2s, height 0.5s 0.2s, top 0.5s 0.1s, left 0.3s,\n box-shadow 0.5s !important;\n}\n.main-coverSlotCollapsed-container[aria-hidden='true']\n .cover-art\n .cover-art-image,\n.main-nowPlayingWidget-coverExpanded\n .main-coverSlotCollapsed-container\n .cover-art\n .cover-art-image {\n width: 200px;\n height: 200px;\n}\n.main-nowPlayingBar-left {\n z-index: 2;\n}\n.main-nowPlayingBar-center {\n z-index: 1;\n}\n.cover-art.shadow {\n box-shadow: 0 0 10px rgba(var(--spice-rgb-shadow), 1) !important;\n}\n@keyframes coverExpandedIn {\n 99% {\n visibility: hidden;\n }\n 100% {\n visibility: visible;\n }\n}\n@keyframes coverExpandedOut {\n 99% {\n visibility: visible;\n }\n 100% {\n visibility: hidden;\n }\n}", - "preview": "resources/assets/snippets/right-cover-art.png", + "preview": "resources/assets/snippets/right-cover-art.png" }, { "title": "Better lyrics style", "description": "Spotify lyrics are focused and beautified", "code": ".lyrics-lyrics-contentContainer .lyrics-lyricsContent-lyric.lyrics-lyricsContent-highlight { filter: blur(1.5px); padding: 15px; font-size: 110%; } .lyrics-lyrics-contentContainer .lyrics-lyricsContent-lyric.lyrics-lyricsContent-active { filter: none; padding: 20px; font-size: 130%; } .lyrics-lyrics-contentContainer .lyrics-lyricsContent-lyric { filter: blur(1.5px); padding: 15px; font-size: 110%; } .lyrics-lyrics-contentContainer .lyrics-lyricsContent-lyric.lyrics-lyricsContent-unsynced { filter: none; padding: 10px; font-size: 100%; }", - "preview": "resources/assets/snippets/better-lyrics-style.png", + "preview": "resources/assets/snippets/better-lyrics-style.png" }, { "title": "Fix now playing icon color", "description": "Fixes the now playing icon color", - "code": `.main-trackList-playingIcon { -webkit-mask-image: url("data:image/svg+xml,%3Csvg id='playing-icon' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 24'%3E%3Cdefs%3E%3Cstyle%3E %23playing-icon %7B fill: %2320BC54; %7D @keyframes play %7B 0%25 %7Btransform: scaleY(1);%7D 3.3%25 %7Btransform: scaleY(0.9583);%7D 6.6%25 %7Btransform: scaleY(0.9166);%7D 9.9%25 %7Btransform: scaleY(0.8333);%7D 13.3%25 %7Btransform: scaleY(0.7083);%7D 16.6%25 %7Btransform: scaleY(0.5416);%7D 19.9%25 %7Btransform: scaleY(0.4166);%7D 23.3%25 %7Btransform: scaleY(0.25);%7D 26.6%25 %7Btransform: scaleY(0.1666);%7D 29.9%25 %7Btransform: scaleY(0.125);%7D 33.3%25 %7Btransform: scaleY(0.125);%7D 36.6%25 %7Btransform: scaleY(0.1666);%7D 39.9%25 %7Btransform: scaleY(0.1666);%7D 43.3%25 %7Btransform: scaleY(0.2083);%7D 46.6%25 %7Btransform: scaleY(0.2916);%7D 49.9%25 %7Btransform: scaleY(0.375);%7D 53.3%25 %7Btransform: scaleY(0.5);%7D 56.6%25 %7Btransform: scaleY(0.5833);%7D 59.9%25 %7Btransform: scaleY(0.625);%7D 63.3%25 %7Btransform: scaleY(0.6666);%7D 66.6%25 %7Btransform: scaleY(0.6666);%7D 69.9%25 %7Btransform: scaleY(0.6666);%7D 73.3%25 %7Btransform: scaleY(0.6666);%7D 76.6%25 %7Btransform: scaleY(0.7083);%7D 79.9%25 %7Btransform: scaleY(0.75);%7D 83.3%25 %7Btransform: scaleY(0.8333);%7D 86.6%25 %7Btransform: scaleY(0.875);%7D 89.9%25 %7Btransform: scaleY(0.9166);%7D 93.3%25 %7Btransform: scaleY(0.9583);%7D 96.6%25 %7Btransform: scaleY(1);%7D %7D %23bar1 %7B transform-origin: bottom; animation: play 0.9s -0.51s infinite; %7D %23bar2 %7B transform-origin: bottom; animation: play 0.9s infinite; %7D %23bar3 %7B transform-origin: bottom; animation: play 0.9s -0.15s infinite; %7D %23bar4 %7B transform-origin: bottom; animation: play 0.9s -0.75s infinite; %7D %3C/style%3E%3C/defs%3E%3Ctitle%3Eplaying-icon%3C/title%3E%3Crect id='bar1' class='cls-1' width='4' height='24'/%3E%3Crect id='bar2' class='cls-1' x='6' width='4' height='24'/%3E%3Crect id='bar3' class='cls-1' x='12' width='4' height='24'/%3E%3Crect id='bar4' class='cls-1' x='18' width='4' height='24'/%3E%3C/svg%3E"); background: var(--spice-button); content-visibility: hidden; -webkit-mask-repeat: no-repeat; }`, - "preview": "resources/assets/snippets/fix-now-playing-icon.png", + "code": ".main-trackList-playingIcon { -webkit-mask-image: url(\"data:image/svg+xml,%3Csvg id='playing-icon' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 24'%3E%3Cdefs%3E%3Cstyle%3E %23playing-icon %7B fill: %2320BC54; %7D @keyframes play %7B 0%25 %7Btransform: scaleY(1);%7D 3.3%25 %7Btransform: scaleY(0.9583);%7D 6.6%25 %7Btransform: scaleY(0.9166);%7D 9.9%25 %7Btransform: scaleY(0.8333);%7D 13.3%25 %7Btransform: scaleY(0.7083);%7D 16.6%25 %7Btransform: scaleY(0.5416);%7D 19.9%25 %7Btransform: scaleY(0.4166);%7D 23.3%25 %7Btransform: scaleY(0.25);%7D 26.6%25 %7Btransform: scaleY(0.1666);%7D 29.9%25 %7Btransform: scaleY(0.125);%7D 33.3%25 %7Btransform: scaleY(0.125);%7D 36.6%25 %7Btransform: scaleY(0.1666);%7D 39.9%25 %7Btransform: scaleY(0.1666);%7D 43.3%25 %7Btransform: scaleY(0.2083);%7D 46.6%25 %7Btransform: scaleY(0.2916);%7D 49.9%25 %7Btransform: scaleY(0.375);%7D 53.3%25 %7Btransform: scaleY(0.5);%7D 56.6%25 %7Btransform: scaleY(0.5833);%7D 59.9%25 %7Btransform: scaleY(0.625);%7D 63.3%25 %7Btransform: scaleY(0.6666);%7D 66.6%25 %7Btransform: scaleY(0.6666);%7D 69.9%25 %7Btransform: scaleY(0.6666);%7D 73.3%25 %7Btransform: scaleY(0.6666);%7D 76.6%25 %7Btransform: scaleY(0.7083);%7D 79.9%25 %7Btransform: scaleY(0.75);%7D 83.3%25 %7Btransform: scaleY(0.8333);%7D 86.6%25 %7Btransform: scaleY(0.875);%7D 89.9%25 %7Btransform: scaleY(0.9166);%7D 93.3%25 %7Btransform: scaleY(0.9583);%7D 96.6%25 %7Btransform: scaleY(1);%7D %7D %23bar1 %7B transform-origin: bottom; animation: play 0.9s -0.51s infinite; %7D %23bar2 %7B transform-origin: bottom; animation: play 0.9s infinite; %7D %23bar3 %7B transform-origin: bottom; animation: play 0.9s -0.15s infinite; %7D %23bar4 %7B transform-origin: bottom; animation: play 0.9s -0.75s infinite; %7D %3C/style%3E%3C/defs%3E%3Ctitle%3Eplaying-icon%3C/title%3E%3Crect id='bar1' class='cls-1' width='4' height='24'/%3E%3Crect id='bar2' class='cls-1' x='6' width='4' height='24'/%3E%3Crect id='bar3' class='cls-1' x='12' width='4' height='24'/%3E%3Crect id='bar4' class='cls-1' x='18' width='4' height='24'/%3E%3C/svg%3E\"); background: var(--spice-button); content-visibility: hidden; -webkit-mask-repeat: no-repeat; }", + "preview": "resources/assets/snippets/fix-now-playing-icon.png" }, { "title": "Hide playing gif", "description": "Hides the gif that shows the music playing", "code": ".main-trackList-playingIcon{display: none}", - "preview": "resources/assets/snippets/hide-playing-gif.png", + "preview": "resources/assets/snippets/hide-playing-gif.png" }, { "title": "Pointers", "description": "Clickable elements are now a pointer", "code": "button, .show-followButton-button, .main-dropDown-dropDown, .x-toggle-wrapper, .main-playlistEditDetailsModal-closeBtn, .main-trackList-rowPlayPauseButton, .main-rootlist-rootlistItemLink:link, .main-rootlist-rootlistItemLink:visited, .x-sortBox-sortDropdown, .main-contextMenu-menuItemButton, .main-trackList-column, .main-moreButton-button, .x-downloadButton-button, .main-playButton-PlayButton, .main-coverSlotExpandedCollapseButton-chevron, .main-coverSlotCollapsed-chevron, .control-button:focus, .control-button:hover, .main-repeatButton-button, .main-skipForwardButton-button, .main-playPauseButton-button, .main-skipBackButton-button, .main-shuffleButton-button, .main-addButton-button, .progress-bar__slider, .playback-bar, .main-editImageButton-image, .X1lXSiVj0pzhQCUo_72A { cursor: pointer !important; }", - "preview": "resources/assets/snippets/pointer.png", + "preview": "resources/assets/snippets/pointer.png" }, { "title": "Remove Top gradient", "description": "Removes gradient from home page and playlist page", "code": ".main-entityHeader-backgroundColor { display: none !important; } .main-actionBarBackground-background { display: none !important; } .main-home-homeHeader { display: none !important; }", - "preview": "resources/assets/snippets/remove-gradient.png", + "preview": "resources/assets/snippets/remove-gradient.png" }, { "title": "Fix Liked Button", "description": "Fixes Liked Button colors", - "code": `#_R_G *:not([fill="none"]) { fill: var(--spice-button) !important; } #_R_G *:not([stroke="none"]) { stroke: var(--spice-button); } .main-addButton-button[aria-checked="false"] { color: rgba(var(--spice-rgb-selected-row), 0.7); } .control-button-heart[aria-checked="true"], .main-addButton-button, .main-addButton-active:focus, .main-addButton-active:hover { color: var(--spice-button); }`, - "preview": "resources/assets/snippets/fix-liked-button.png", + "code": "#_R_G *:not([fill=\"none\"]) { fill: var(--spice-button) !important; } #_R_G *:not([stroke=\"none\"]) { stroke: var(--spice-button); } .main-addButton-button[aria-checked=\"false\"] { color: rgba(var(--spice-rgb-selected-row), 0.7); } .control-button-heart[aria-checked=\"true\"], .main-addButton-button, .main-addButton-active:focus, .main-addButton-active:hover { color: var(--spice-button); }", + "preview": "resources/assets/snippets/fix-liked-button.png" }, { "title": "Hide Sidebar ScrollBar", "description": "Hides Sidebar ScrollBar near playlist section", "code": ".os-scrollbar:nth-child(6) .os-scrollbar-handle { visibility: hidden; }", - "preview": "resources/assets/snippets/hide-sidebar-scrollbar.png", + "preview": "resources/assets/snippets/hide-sidebar-scrollbar.png" }, { "title": "Modern ScrollBar", "description": "Thin rounded modern scrollbar", "code": ".os-theme-spotify.os-host-transition > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle { border-radius: 4px; width: 6px; background-color: var(--spice-button-disabled); } .os-theme-spotify.os-host-transition > .os-scrollbar-vertical > .os-scrollbar-track { width: 6px; }", - "preview": "resources/assets/snippets/modern-scrollbar.png", + "preview": "resources/assets/snippets/modern-scrollbar.png" }, { "title": "Remove liked and Episodes icon", "description": "Removes the liked and episodes icon from the sidebar", - "code": `.main-collectionLinkButton-collectionLinkButton[href="/collection/tracks"], .main-collectionLinkButton-collectionLinkButton[href="/collection/episodes"] {display: none;}`, - "preview": "resources/assets/snippets/remove-ep-likes.png", + "code": ".main-collectionLinkButton-collectionLinkButton[href=\"/collection/tracks\"], .main-collectionLinkButton-collectionLinkButton[href=\"/collection/episodes\"] {display: none;}", + "preview": "resources/assets/snippets/remove-ep-likes.png" }, { "title": "Rotating Cover Art", "description": "Adds circular mask to cover art and rotation", - "code": `@keyframes rotating { from { transform: rotate(0deg); } to { transform: rotate(360deg); }} .cover-art { animation: rotating 10s linear infinite; clip-path: circle(50% at 50% 50%);}`, - "preview": "resources/assets/snippets/rotating-coverart.png", + "code": "@keyframes rotating { from { transform: rotate(0deg); } to { transform: rotate(360deg); }} .cover-art { animation: rotating 10s linear infinite; clip-path: circle(50% at 50% 50%);}", + "preview": "resources/assets/snippets/rotating-coverart.png" }, { "title": "Hide liked songs card", "description": "Hides the sometimes unfitting liked Songs card in the Your Libary tab", "code": ".collection-collectionEntityHeroCard-likedSongs{ display: none; }", - "preview": "resources/assets/snippets/hide-likedSongs-card.png", + "preview": "resources/assets/snippets/hide-likedSongs-card.png" }, { "title": "Fix playlist and folder position", "description": "Replaces the playlists section in the left side bar to align with all the other category icons for the new UI. Screenshot includes 'Playlist icons' snippet", "code": ".playlist-item__img.folder, .playlist-item__img { margin-right: 16px; } .main-rootlist-rootlist { --left-sidebar-item-height: 32px; --left-sidebar-item-indentation-width: 10px; } div.GlueDropTarget.personal-library > * { height: 32px !important; }", - "preview": "resources/assets/snippets/fix-playlist-and-folder-position.png", + "preview": "resources/assets/snippets/fix-playlist-and-folder-position.png" }, { "title": "Remove recently played from homepage", "description": "Removes the recently played shelf from the home page", "code": ".main-shelf-shelf:has([href='/genre/recently-played']) { display: none !important; }", - "preview": "resources/assets/snippets/remove-recently-played.png", + "preview": "resources/assets/snippets/remove-recently-played.png" }, { "title": "Make custom app icons thicker", "description": "Gives icons from the sticky list a thicker border", "code": "#spicetify-sticky-list>li:nth-child(1n+1)>a>div.icon.collection-icon>svg:not(.lucide-crown) { stroke: currentcolor; stroke-width: 11px; } .collection-icon { color: unset; }", - "preview": "resources/assets/snippets/thicker-sticky-list-icons.png", + "preview": "resources/assets/snippets/thicker-sticky-list-icons.png" }, { "title": "Pretty Lyrics", "description": "Gets rid of the ugly background colour on the lyrics page and makes it consistent with themes. Works best with dark themes.", "code": ".lyrics-lyrics-background { display: none; } .lyrics-lyrics-contentWrapper>*:not(.lyrics-lyricsContent-active, .lyrics-lyricsContent-highlight, .lyrics-lyricsContent-provider, .lyrics-lyricsContent-description, .lyrics-lyricsContent-unsynced) { color: #FFFFFF4D !important; } .lyrics-lyrics-contentWrapper>*:not(.lyrics-lyricsContent-active, .lyrics-lyricsContent-highlight, .lyrics-lyricsContent-provider, .lyrics-lyricsContent-description, .lyrics-lyricsContent-unsynced):hover { color: #FFFFFF !important; } .lyrics-lyricsContent-highlight { color: #FFFFFF66; } .lyrics-lyricsContent-unsynced { color: #FFFFFF !important; } .lyrics-lyricsContent-unsynced:hover { color: #FFFFFF !important; } .lyrics-lyricsContent-provider, .lyrics-lyricsContent-description { color: #FFFFFFB6 !important; }", - "preview": "resources/assets/snippets/pretty-lyrics.png", + "preview": "resources/assets/snippets/pretty-lyrics.png" }, { "title": "Oneko", "description": "Adds Oneko onto your playback bar!", "code": ".player-controls .playback-progressbar::before { content: ''; width: 32px; height: 32px; bottom: calc(100% - 7px); right: 10px; position: absolute; image-rendering: pixelated; background-image: url('https://raw.githubusercontent.com/adryd325/oneko.js/14bab15a755d0e35cd4ae19c931d96d306f99f42/oneko.gif'); animation: oneko 1s infinite; } @keyframes oneko { 0%, 50% { background-position: -64px 0; } 50.0001%, 100% { background-position: -64px -32px; } }", - "preview": "resources/assets/snippets/oneko.png", + "preview": "resources/assets/snippets/oneko.png" }, { "title": "Remove Popular sections from homepage", "description": "Thanks Spotify, but I have a music taste", "code": ".main-shelf-shelf.Shelf:has([href='/section/0JQ5DAuChZYPe9iDhh2mJz'], [href='/section/0JQ5DAnM3wGh0gz1MXnu4h'], [href='/section/0JQ5DAnM3wGh0gz1MXnu3B'], [href='/section/0JQ5DAnM3wGh0gz1MXnu3D']) { display: none !important; }", - "preview": "resources/assets/snippets/remove-popular.png", + "preview": "resources/assets/snippets/remove-popular.png" }, { "title": "Dark Lyrics", "description": "Replaces the highly saturated lyrics backgrounds with a very subtle dark gradient", "code": ".lyrics-lyrics-background { background-image: linear-gradient(315deg,var(--lyrics-color-background),black); background-size: 500%; } .lyrics-lyricsContent-lyric.lyrics-lyricsContent-highlight { color: white; } .lyrics-lyricsContent-lyric { color: #424242; }", - "preview": "resources/assets/snippets/dark-lyrics.png", + "preview": "resources/assets/snippets/dark-lyrics.png" }, { "title": "Thicker Bars", "description": "Makes the song progress and volume bar thicker", "code": ".x-progressBar-progressBarBg { height: 100% !important; } .x-progressBar-sliderArea { height: 100% !important; } .x-progressBar-fillColor { height: 100% !important; }", - "preview": "resources/assets/snippets/thicker-bars.png", + "preview": "resources/assets/snippets/thicker-bars.png" }, { "title": "Hide friends activity button", "description": "Hides the friends activity button next to your profile picture", "code": "button.encore-over-media-set.main-topBar-buddyFeed {display: none;}", - "preview": "resources/assets/snippets/hide-friends-activity-button.png", + "preview": "resources/assets/snippets/hide-friends-activity-button.png" }, { "title": "Fullscreen hide playing from", "description": "Hides the playing from card while in fullscreen view", "code": ".npv-header.npv-header {display: none;}", - "preview": "resources/assets/snippets/fullscreen-hide-playing-from.png", + "preview": "resources/assets/snippets/fullscreen-hide-playing-from.png" }, { "title": "Fullscreen hide next up", "description": "Hides the next up card while in fullscreen view (appears shortly before switching to the next song)", "code": ".npv-up-next.fade-in-and-out-transition-enter-done {display: none;}", - "preview": "resources/assets/snippets/fullscreen-hide-next-up.png", + "preview": "resources/assets/snippets/fullscreen-hide-next-up.png" }, { "title": "Hide profile username", "description": "Hides your username next to your profile picture", "code": ".main-userWidget-displayName {display: none !important;}", - "preview": "resources/assets/snippets/hide-profile-username.png", + "preview": "resources/assets/snippets/hide-profile-username.png" }, { "title": "Hide now playing view button", "description": "Hides the now playing view button from the playbar", "code": "button:has(path[d='M11.196 8 6 5v6l5.196-3z']) {display: none;}", - "preview": "resources/assets/snippets/hide-now-playing-view-button.png", + "preview": "resources/assets/snippets/hide-now-playing-view-button.png" }, { "title": "Hide play count", "description": "Hides the play count on songs/albums etc so you can give each songs its chance without thinking about numbers", "code": ".main-trackList-playsHeader,.main-trackList-rowPlayCount {display: none}", - "preview": "resources/assets/snippets/hide-play-count.png", + "preview": "resources/assets/snippets/hide-play-count.png" }, { "title": "Hide recent searches", "description": "Hides the recent searches section on the search page", "code": ".main-shelf-shelf:has(.x-searchHistoryEntries-searchHistoryEntry) {display: none;}", - "preview": "resources/assets/snippets/hide-recent-searches.png", + "preview": "resources/assets/snippets/hide-recent-searches.png" }, { "title": "Duck", "description": "Adds dancing duck onto your playback bar!", "code": ".player-controls .playback-progressbar::before { content: ''; width: 32px; height: 32px; bottom: calc(100% - 7px); right: 10px; position: absolute; image-rendering: pixelated; background-size: 32px 32px; background-image: url('https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExZzdsM2Y2aHh3cTQ2Z3JzbXAzMXJrZjdiM3IwMXhnaTFnc295ZnRkZCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9cw/cCOVfFwDI3awdse5A3/giphy.gif'); }", - "preview": "resources/assets/snippets/duck.png", + "preview": "resources/assets/snippets/duck.png" }, { "title": "Duotone Album Art", "description": "Changes the album art into a duotone version with two colors of your choice", "code": ":root{--gmaa-base:#191414;--gmaa-bg-blend:lighten;--gmaa-blur:0;--gmaa-fg-blend:multiply;--gmaa-foreground:#1cb955;--gmaa-opacity:.74;--gmaa-spacing:0}.cover-art{background-color:var(--gmaa-base);display:flex;flex:1 1 100%;height:100%;overflow:hidden;position:relative}.cover-art img{filter:grayscale(100%) contrast(1) blur(var(--gmaa-blur));flex:1 0 100%;height:100%;max-width:100%;mix-blend-mode:var(--gmaa-bg-blend);object-fit:cover;opacity:var(--gmaa-opacity);position:relative;width:100%}.cover-art::before{background-color:var(--gmaa-foreground);bottom:0;content:'';height:100%;left:0;mix-blend-mode:var(--gmaa-fg-blend);position:absolute;right:0;top:0;width:100%;z-index:1}.cover-art-icon{display:none;visibility:hidden}", - "preview": "resources/assets/snippets/duotone-album-art.png", + "preview": "resources/assets/snippets/duotone-album-art.png" }, { "title": "Thin Library Sidebar Rows", "description": "Single-line rows in the library sidebar, like the pre-2023 UI", "code": ".main-yourLibraryX-listItemGroup {grid-template-rows: none !important;} .main-yourLibraryX-listItemGroup * {padding-block: 0;}.main-yourLibraryX-listItem [role=\"group\"] {min-block-size: 0 !important;} .main-yourLibraryX-listItem .HeaderArea .Column {flex-direction: row; gap: 0.5em;} .main-yourLibraryX-listItem .HeaderArea * {padding-top: 0 !important; padding-bottom: 0 !important;} .main-yourLibraryX-listItem .x-entityImage-imageContainer, .main-yourLibraryX-rowCover {width: 1.6em !important; height: 1.6em !important;} .main-yourLibraryX-listRowSubtitle {padding-top: 0px;}", - "preview": "resources/assets/snippets/thin-library-sidebar-rows.png", + "preview": "resources/assets/snippets/thin-library-sidebar-rows.png" }, { "title": "Default Progress Bar", "description": "Return progress bar to default size and location on themes that change it", "code": ".playback-bar {position: relative !important; display: block !important; --playback-bar-grid-gap: 8px !important; -webkit-box-orient: horizontal !important; -webkit-box-direction: normal !important; -webkit-box-pack: justify !important; -webkit-box-align: center !important; align-items: center !important; display: -webkit-box !important; display: flex !important; flex-direction: row !important; gap: var(--playback-bar-grid-gap) !important; justify-content: space-between !important; height: 12px !important;} .x-progressBar-progressBarBg {--progress-bar-height: 6px !important; --progress-bar-radius: 10px !important;} :root .Root__now-playing-bar .playback-bar > div {height: 17.59px !important;} .player-controls__buttons--new-icons { margin-bottom: 12px !importan;} .main-nowPlayingBar-nowPlayingBar {padding-bottom: 0px !important;}", - "preview": "resources/assets/snippets/default-progress-bar.png", + "preview": "resources/assets/snippets/default-progress-bar.png" }, { "title": "Fix Listening On", "description": "Fix listening on for some themes that move it up or make the text not visible", "code": ".Svg-presentation-essentialBase-small-icon-autoMirror {fill: var(--spice-text);} .TypeElement-mesto-textBase-type {color: var(--spice-text) !important;} .main-devicePicker-indicator {display: none !important;} .main-nowPlayingBar-container {height: 72px !important;} .main-connectBar-connectBar {position: absolute !important; align-items: center !important; top: 42px !important; height: 32px !important; align-self: center !important; background-color: transparent !important; width: 30% !important;}", - "preview": "resources/assets/snippets/fix-listening-on.png", + "preview": "resources/assets/snippets/fix-listening-on.png" }, { "title": "Smooth Progress/Volume Bar", "description": "Makes the Progress/Volume bar glide", "code": "@property --progress-bar-transform { inherits: true; initial-value: 0%; syntax: ''; } .progress-bar { transition: --progress-bar-transform 1s linear !important; } .progress-bar--isDragging { transition-duration: 150ms !important; }", - "preview": "resources/assets/snippets/smooth-progress-bar.png", + "preview": "resources/assets/snippets/smooth-progress-bar.png" }, { "title": "Centered Lyrics", "description": "Centers the lyrics on the lyrics page", "code": ".lyrics-lyrics-contentWrapper { text-align: center; }", - "preview": "resources/assets/snippets/centered-lyrics.png", + "preview": "resources/assets/snippets/centered-lyrics.png" }, { "title": "Hide lyrics button", "description": "Hides the lyrics button in the playbar", "code": ".main-nowPlayingBar-lyricsButton { display: none; }", - "preview": "resources/assets/snippets/hide-lyrics-button.png", + "preview": "resources/assets/snippets/hide-lyrics-button.png" }, { "title": "Hide download button", "description": "Hide download button in EPs and albums", "code": ".x-downloadButton-DownloadButton { display: none; }", - "preview": "resources/assets/snippets/hide-download-button.png", + "preview": "resources/assets/snippets/hide-download-button.png" }, { "title": "Smaller right sidebar covert art", "description": "Makes the right sidebar cover art smaller and move the track info to the right", "code": ":root { --right-sidebar-cover-art-size: 85px; } \n.main-nowPlayingView-coverArt { width: var(--right-sidebar-cover-art-size); } \n.main-nowPlayingView-coverArtContainer { min-height: unset !important; height: var(--right-sidebar-cover-art-size) !important; } \n.main-nowPlayingView-nowPlayingGrid { flex-direction: unset; } \n.main-nowPlayingView-contextItemInfo .main-trackInfo-name { font-size: 1.25rem; } \n.main-nowPlayingView-contextItemInfo .main-trackInfo-artists { font-size: 0.85rem; }", - "preview": "resources/assets/snippets/smaller-right-sidebar-cover.png", + "preview": "resources/assets/snippets/smaller-right-sidebar-cover.png" }, { "title": "Remove top spacing", "description": "Remove top spacing where should be the Window action buttons. Useful for tiling window managers.", "code": ".Root__top-container:has([class*='yourLibraryX']) { padding-top: 8px; }", - "preview": "resources/assets/snippets/remove-top-spacing.png", + "preview": "resources/assets/snippets/remove-top-spacing.png" }, { "title": "Switch Sidebars", "description": "Move the navigation panel to the right and the information sidebar to the left.", "code": ".Root__top-container .Root__nav-bar { grid-area: right-sidebar !important; } .Root__top-container .Root__right-sidebar { grid-area: left-sidebar !important; }", - "preview": "resources/assets/snippets/switch-sidebars.png", - }, -]; + "preview": "resources/assets/snippets/switch-sidebars.png" + } +] diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 1dc3cdce..41baf84d 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -88,6 +88,7 @@ class Grid extends React.Component< CONFIG: Config; updateAppConfig: (CONFIG: Config) => void; BLACKLIST: string[] | undefined; + SNIPPETS: Snippet[] | undefined; // TODO: should I put this in Grid state? getInstalledTheme() { @@ -373,7 +374,7 @@ class Grid extends React.Component< else console.debug("No more app results"); break; } case "Snippets": { - const snippets = await fetchCssSnippets(); + const snippets = this.SNIPPETS; if (this.requestQueue.length > 1 && queue !== this.requestQueue[0]) { // Stop this queue from continuing to fetch and append to cards list @@ -509,8 +510,9 @@ class Grid extends React.Component< } } - // Load blacklist + // Load blacklist and snippets this.BLACKLIST = await getBlacklist(); + this.SNIPPETS = await fetchCssSnippets(); this.newRequest(ITEMS_PER_REQUEST); } diff --git a/src/constants.ts b/src/constants.ts index 0942823f..41c63b49 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -42,6 +42,9 @@ export const MAX_TAGS = 4; export const SNIPPETS_PAGE_URL = "https://github.com/spicetify/spicetify-marketplace/blob/main/src/resources/snippets.ts"; +export const SNIPPETS_URL = + "https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/snippets.json"; + export const BLACKLIST_URL = "https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/blacklist.json"; diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 9e17f387..8199466e 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -1,9 +1,8 @@ import { t } from "i18next"; -import { BLACKLIST_URL, ITEMS_PER_REQUEST } from "../constants"; +import { BLACKLIST_URL, SNIPPETS_URL, ITEMS_PER_REQUEST } from "../constants"; import { RepoTopic, CardItem, Snippet } from "../types/marketplace-types"; import { addToSessionStorage, processAuthors } from "./Utils"; -import snippetsJSON from "../resources/snippets"; // TODO: add sort type, order, etc? // https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-for-repositories#search-by-topic @@ -303,10 +302,13 @@ export const getBlacklist = async () => { }; /** -* It fetches the snippets.json file from the Github repository and returns it as a JSON object. +* It fetches the snippets.json file from the Github repository and returns it as an array of snippets. * @returns Array of snippets */ export const fetchCssSnippets = async () => { + const snippetsJSON = await fetch(SNIPPETS_URL).then(res => res.json()).catch(() => ({})) as Snippet[] | undefined; + if (!snippetsJSON) return []; + const snippets = snippetsJSON.reduce((accum, snippet) => { const snip = { ...snippet } as Snippet; From a939377e8b37822b1d28edd39a3035c433ae9282 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 19 Mar 2024 18:18:14 -0400 Subject: [PATCH 2/3] Add launch.json for development --- .vscode/launch.json | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..d8614a6a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,36 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "pnpm run watch", + "runtimeExecutable": "pnpm", + "runtimeArgs": [ + "run", + "watch" + ], + "internalConsoleOptions": "openOnSessionStart" + }, + { + "type": "node", + "request": "launch", + "name": "spicetify watch -a", + "runtimeExecutable": "spicetify", + "runtimeArgs": [ + "watch", + "-a" + ], + "internalConsoleOptions": "openOnSessionStart" + } + ], + "compounds": [ + { + "name": "Watch app build and Spicetify", + "configurations": ["pnpm run watch", "spicetify watch -a"] + } + ] +} From 8e08eb60866ce510f50db77e348f63a6e2a1cf26 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Wed, 20 Mar 2024 08:55:26 -0400 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=90=9B=20Make=20it=20handle=20fetch?= =?UTF-8?q?=20errors=20properly=20(it's=20an=20array)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/logic/FetchRemotes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 8199466e..bbcbbf26 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -306,8 +306,8 @@ export const getBlacklist = async () => { * @returns Array of snippets */ export const fetchCssSnippets = async () => { - const snippetsJSON = await fetch(SNIPPETS_URL).then(res => res.json()).catch(() => ({})) as Snippet[] | undefined; - if (!snippetsJSON) return []; + const snippetsJSON = await fetch(SNIPPETS_URL).then(res => res.json()).catch(() => []) as Snippet[]; + if (!snippetsJSON.length) return []; const snippets = snippetsJSON.reduce((accum, snippet) => { const snip = { ...snippet } as Snippet;