1
0
Fork 0
dotfiles/dot_config/spicetify/CustomApps/spicetify-marketplace/index.js
Florian RICHER efb95c2bb2 Add dot_config/spicetify/CustomApps/spicetify-marketplace-tmp/.keep
Add dot_config/spicetify/CustomApps/spicetify-marketplace/CONTRIBUTING.md
Add dot_config/spicetify/CustomApps/spicetify-marketplace/LICENSE
Add dot_config/spicetify/CustomApps/spicetify-marketplace/README.md
Add dot_config/spicetify/CustomApps/spicetify-marketplace/blacklist.json
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_eslintrc.json
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_github/ISSUE_TEMPLATE/bug_report.yml
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_github/ISSUE_TEMPLATE/config.yml
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_github/ISSUE_TEMPLATE/feature_request.yml
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_github/ISSUE_TEMPLATE/malicious_extension_report.yml
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_github/dependabot.yml
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_github/workflows/lint.yml
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_gitignore
Add dot_config/spicetify/CustomApps/spicetify-marketplace/dot_nvmrc
Add dot_config/spicetify/CustomApps/spicetify-marketplace/executable_install.sh
Add dot_config/spicetify/CustomApps/spicetify-marketplace/extension.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/index.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/install.ps1
Add dot_config/spicetify/CustomApps/spicetify-marketplace/manifest.json
Add dot_config/spicetify/CustomApps/spicetify-marketplace/package-lock.json
Add dot_config/spicetify/CustomApps/spicetify-marketplace/package.json
Add dot_config/spicetify/CustomApps/spicetify-marketplace/snippets.json
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/AddSnippetModal.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/Card.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/Icons.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/OptionsMenu.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/ReadmePage.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/ReloadModal.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/Settings.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/SortBox.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/TabBar.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/src/Utils.js
Add dot_config/spicetify/CustomApps/spicetify-marketplace/style.css
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/components/add-snippet-modal.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/components/card.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/components/fixes.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/components/grid.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/components/readme-pages.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/components/reload-modal.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/components/settings.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/styles/style.scss
Add dot_config/spicetify/CustomApps/spicetify-marketplace/tsconfig.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_executable_index.html
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_executable_login.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_executable_login.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_executable_manifest.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_executable_vendor~login.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_executable_vendor~login.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIAraOnly-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIAraOnly-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIAraOnly-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIAraOnly-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUICyrOnly-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUICyrOnly-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUICyrOnly-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUICyrOnly-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIHbrOnly-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIHbrOnly-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIHbrOnly-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIHbrOnly-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIv3T-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIv3T-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIv3T-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_CircularSpUIv3T-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_fonts/private_executable_spoticon_regular_2.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable___longest.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_af.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_am.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ar.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_az.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_bg.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_bho.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_bn.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_cs.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_da.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_de.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_el.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_en.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_es-419.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_es.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_et.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_fa.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_fi.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_fil.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_fr-CA.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_fr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_gu.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_he.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_hi.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_hr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_hu.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_id.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_is.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_it.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ja.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_kn.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ko.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_lt.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_lv.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ml.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_mr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ms.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_nb.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ne.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_nl.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_or.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_pa-IN.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_pa-PK.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_pl.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_pt-BR.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_pt-PT.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ro.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ru.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_sk.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_sl.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_sr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_sv.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_sw.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ta.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_te.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_th.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_tr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_uk.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_ur.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_vi.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_zh-CN.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_zh-TW.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_i18n/private_executable_zu.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_executable_background.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_executable_eye.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_executable_logo.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_executable_scrollbar-buttons.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_content-rtl.avif
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_content-small-rtl.avif
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_content-small.avif
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_content.avif
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_controls.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_footer-left.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_footer-right.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_fake-web-player/private_executable_side.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_social-buttons/private_executable_apple.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_social-buttons/private_executable_facebook.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_login/private_images/private_social-buttons/private_executable_google.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_12.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_185.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_188.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_188.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_258.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_258.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_375.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_375.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_381.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_396.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_448.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_479.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_479.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_696.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_774.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_774.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_818.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_818.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_blank.html
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_collection-music-download.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_in-app-messaging-preview.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_in-app-messaging-preview.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_index.html
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_licenses.html
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_manifest.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_vendor~xpui.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_vendor~xpui.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-desktop-modals.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-desktop-modals.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-desktop-routes-debug-utils.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-desktop-routes-debug-utils.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-desktop-routes-homepage-takeover-ad.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-desktop-routes-homepage-takeover-ad.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-album.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-all-episode-sponsors.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-all-episode-sponsors.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-all-show-sponsors.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-artist.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-artist.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-blend.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-blend.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-collection-concerts.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-collection-concerts.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-collection-local-files.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-collection-local-files.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-concert.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-concert.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-create-playlist.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-download-page.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-download-page.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-enhanced-playlist.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-enhanced-playlist.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-episode.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-episode.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-folder.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-folder.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-offline-browse.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-offline-browse.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-playlist.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-playlist.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-profile.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-profile.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-queue.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-queue.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-track-v2.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-track-v2.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-track.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-view.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui-routes-view.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui.css
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_executable_xpui.js
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIAraOnly-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIAraOnly-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIAraOnly-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIAraOnly-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUICyrOnly-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUICyrOnly-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUICyrOnly-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUICyrOnly-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIHbrOnly-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIHbrOnly-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIHbrOnly-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIHbrOnly-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIv3T-Black.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIv3T-Bold.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIv3T-Book.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_fonts/private_executable_CircularSpUIv3T-Light.woff2
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable___longest.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_af.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_am.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ar.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_az.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_bg.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_bho.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_bn.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_cs.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_da.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_de.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_el.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_en.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_es-419.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_es.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_et.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_fa.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_fi.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_fil.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_fr-CA.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_fr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_gu.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_he.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_hi.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_hr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_hu.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_id.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_is.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_it.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ja.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_kn.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ko.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_lt.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_lv.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ml.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_mr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ms.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_nb.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ne.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_nl.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_or.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_pa-IN.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_pa-PK.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_pl.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_pt-BR.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_pt-PT.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ro.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ru.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_sk.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_sl.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_sr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_sv.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_sw.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ta.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_te.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_th.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_tr.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_uk.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_ur.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_vi.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_zh-CN.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_zh-TW.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_i18n/private_executable_zu.json
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_devices/private_executable_mac.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_connect-to-devices-white.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_connect_header@1x.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_equaliser-animated-green.gif
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_equaliser-green.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_hifi-button-off.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_hifi-button-on.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_hifi.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_playlist-folder-filled.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_station-header-wave.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_station-wave.svg
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_sw_saber_ahsoka1.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_sw_saber_anakin.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_sw_saber_leia.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_sw_saber_luke.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_sw_saber_mace.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_sw_saber_rey.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_sw_saber_vader.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_xpui/private_images/private_executable_tracklist-placeholder.png
Add dot_config/spicetify/private_Extracted/private_Raw/private_zlink/private_executable_index.html
Add dot_config/spicetify/private_Extracted/private_Raw/private_zlink/private_executable_manifest.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_executable_index.html
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_executable_login.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_executable_login.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_executable_manifest.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_executable_vendor~login.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_executable_vendor~login.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_fonts/.keep
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable___longest.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_af.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_am.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ar.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_az.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_bg.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_bho.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_bn.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_cs.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_da.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_de.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_el.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_en.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_es-419.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_es.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_et.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_fa.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_fi.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_fil.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_fr-CA.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_fr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_gu.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_he.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_hi.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_hr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_hu.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_id.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_is.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_it.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ja.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_kn.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ko.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_lt.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_lv.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ml.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_mr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ms.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_nb.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ne.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_nl.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_or.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_pa-IN.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_pa-PK.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_pl.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_pt-BR.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_pt-PT.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ro.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ru.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_sk.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_sl.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_sr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_sv.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_sw.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ta.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_te.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_th.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_tr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_uk.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_ur.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_vi.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_zh-CN.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_zh-TW.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_i18n/private_executable_zu.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_images/private_fake-web-player/.keep
Add dot_config/spicetify/private_Extracted/private_Themed/private_login/private_images/private_social-buttons/.keep
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_12.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_185.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_188.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_188.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_258.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_258.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_375.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_375.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_381.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_396.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_448.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_479.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_479.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_696.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_774.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_774.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_818.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_818.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_blank.html
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_collection-music-download.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_in-app-messaging-preview.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_in-app-messaging-preview.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_index.html
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_licenses.html
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_manifest.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_vendor~xpui.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_vendor~xpui.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-desktop-modals.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-desktop-modals.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-desktop-routes-debug-utils.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-desktop-routes-debug-utils.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-desktop-routes-homepage-takeover-ad.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-desktop-routes-homepage-takeover-ad.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-album.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-all-episode-sponsors.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-all-episode-sponsors.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-all-show-sponsors.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-artist.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-artist.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-blend.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-blend.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-collection-concerts.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-collection-concerts.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-collection-local-files.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-collection-local-files.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-concert.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-concert.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-create-playlist.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-download-page.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-download-page.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-enhanced-playlist.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-enhanced-playlist.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-episode.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-episode.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-folder.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-folder.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-offline-browse.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-offline-browse.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-playlist.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-playlist.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-profile.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-profile.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-queue.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-queue.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-track-v2.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-track-v2.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-track.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-view.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui-routes-view.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui.css
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_executable_xpui.js
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_fonts/.keep
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable___longest.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_af.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_am.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ar.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_az.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_bg.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_bho.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_bn.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_cs.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_da.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_de.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_el.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_en.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_es-419.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_es.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_et.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_fa.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_fi.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_fil.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_fr-CA.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_fr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_gu.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_he.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_hi.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_hr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_hu.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_id.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_is.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_it.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ja.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_kn.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ko.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_lt.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_lv.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ml.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_mr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ms.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_nb.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ne.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_nl.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_or.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_pa-IN.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_pa-PK.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_pl.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_pt-BR.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_pt-PT.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ro.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ru.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_sk.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_sl.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_sr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_sv.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_sw.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ta.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_te.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_th.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_tr.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_uk.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_ur.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_vi.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_zh-CN.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_zh-TW.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_i18n/private_executable_zu.json
Add dot_config/spicetify/private_Extracted/private_Themed/private_xpui/private_images/private_devices/.keep
Add dot_config/spicetify/private_Extracted/private_Themed/private_zlink/private_executable_index.html
Add dot_config/spicetify/private_Extracted/private_Themed/private_zlink/private_executable_manifest.json
2022-05-09 01:04:16 +02:00

838 lines
34 KiB
JavaScript

/// <reference types="react" />
/// <reference types="react-dom" />
/// <reference path="../spicetify-cli/globals.d.ts" />
/// <reference path="../spicetify-cli/jsHelper/spicetifyWrapper.js" />
/// <reference path="src/Card.js" />
/// <reference path="src/Icons.js" />
/// <reference path="src/Settings.js" />
/// <reference path="src/SortBox.js" />
/// <reference path="src/TabBar.js" />
/// <reference path="src/ReadmePage.js" />
/// <reference path="src/Utils.js" />
/* eslint-disable no-redeclare, no-unused-vars */
/** @type {React} */
const react = Spicetify.React;
/** @type {import("react-dom")} */
const reactDOM = Spicetify.ReactDOM;
const {
URI,
React: { useState, useEffect, useCallback },
// @ts-ignore
Platform: { History },
} = Spicetify;
/* eslint-enable no-redeclare, no-unused-vars */
// eslint-disable-next-line no-redeclare
const LOCALSTORAGE_KEYS = {
"installedExtensions": "marketplace:installed-extensions",
"installedSnippets": "marketplace:installed-snippets",
"installedThemes": "marketplace:installed-themes",
"activeTab": "marketplace:active-tab",
"tabs": "marketplace:tabs",
"sortBy": "marketplace:sort-by",
// Theme installed store the localsorage key of the theme (e.g. marketplace:installed:NYRI4/Comfy-spicetify/user.css)
"themeInstalled": "marketplace:theme-installed",
};
// Define a function called "render" to specify app entry point
// This function will be used to mount app to main view.
// eslint-disable-next-line no-unused-vars
function render() {
const { location } = Spicetify.Platform.History;
// If page state set to display readme, render it
// (This location state data comes from Card.openReadme())
if (location.pathname === "/spicetify-marketplace/readme") {
return react.createElement(ReadmePage, {
title: "Spicetify Marketplace - Readme",
data: location.state.data,
});
} // Otherwise, render the main Grid
else {
return react.createElement(Grid, { title: "Spicetify Marketplace" });
}
}
// Initalize topbar tabs
// Data initalized in TabBar.js
// eslint-disable-next-line no-redeclare
const ALL_TABS = [
{ name: "Extensions", enabled: true },
{ name: "Themes", enabled: true },
{ name: "Snippets", enabled: true },
{ name: "Installed", enabled: true },
];
let tabsString = localStorage.getItem(LOCALSTORAGE_KEYS.tabs);
let tabs = [];
try {
tabs = JSON.parse(tabsString);
if (!Array.isArray(tabs)) {
throw new Error("Could not parse marketplace tabs key");
} else if (tabs.length === 0) {
throw new Error("Empty marketplace tabs key");
} else if (tabs.filter(tab => !tab).length > 0) {
throw new Error("Falsey marketplace tabs key");
}
} catch {
tabs = ALL_TABS;
localStorage.setItem(LOCALSTORAGE_KEYS.tabs, JSON.stringify(tabs));
}
// Get active theme
let schemes = [];
let activeScheme = null;
try {
const installedThemeKey = localStorage.getItem(LOCALSTORAGE_KEYS.themeInstalled);
if (installedThemeKey) {
const installedThemeDataStr = localStorage.getItem(installedThemeKey);
if (!installedThemeDataStr) throw new Error("No installed theme data");
const installedTheme = JSON.parse(installedThemeDataStr);
schemes = installedTheme.schemes;
activeScheme = installedTheme.activeScheme;
} else {
console.log("No theme set as installed");
}
} catch (err) {
console.error(err);
}
// eslint-disable-next-line no-redeclare
const CONFIG = {
// Fetch the settings and set defaults. Used in Settings.js
visual: {
stars: JSON.parse(localStorage.getItem("marketplace:stars")) ?? true,
tags: JSON.parse(localStorage.getItem("marketplace:tags")) ?? true,
hideInstalled: JSON.parse(localStorage.getItem("marketplace:hideInstalled")) ?? false,
colorShift: JSON.parse(localStorage.getItem("marketplace:colorShift")) ?? false,
// Legacy from reddit app...
type: JSON.parse(localStorage.getItem("marketplace:type")) ?? false,
// I was considering adding watchers as "followers" but it looks like the value is a duplicate
// of stargazers, and the subscribers_count isn't returned in the main API call we make
// https://github.community/t/bug-watchers-count-is-the-duplicate-of-stargazers-count/140865/4
followers: JSON.parse(localStorage.getItem("marketplace:followers")) ?? false,
},
tabs,
activeTab: localStorage.getItem(LOCALSTORAGE_KEYS.activeTab),
theme: {
activeThemeKey: localStorage.getItem(LOCALSTORAGE_KEYS.themeInstalled) || null,
schemes,
activeScheme,
},
};
if (!CONFIG.activeTab || !CONFIG.tabs.filter(tab => tab.name === CONFIG.activeTab).length) {
CONFIG.activeTab = CONFIG.tabs[0].name;
}
// Fetches the sorting options, fetched from SortBox.js
// eslint-disable-next-line no-redeclare
let sortConfig = {
by: localStorage.getItem(LOCALSTORAGE_KEYS.sortBy) || "top",
};
let cardList = [];
let endOfList = false;
let lastScroll = 0;
let requestQueue = [];
let requestPage = null;
// Max GitHub API items per page
// https://docs.github.com/en/rest/reference/search#search-repositories
const ITEMS_PER_REQUEST = 100;
let BLACKLIST = [];
// eslint-disable-next-line no-redeclare, no-unused-vars
let gridUpdateTabs, gridUpdatePostsVisual;
class Grid extends react.Component {
constructor(props) {
super(props);
Object.assign(this, props);
this.state = {
cards: [],
tabs: CONFIG.tabs,
rest: true,
endOfList: endOfList,
schemes: CONFIG.theme.schemes,
activeScheme: CONFIG.theme.activeScheme,
activeThemeKey: CONFIG.theme.activeThemeKey,
};
}
// TODO: should I put this in Grid state?
getInstalledTheme() {
const installedThemeKey = localStorage.getItem(LOCALSTORAGE_KEYS.themeInstalled);
if (!installedThemeKey) return null;
const installedThemeDataStr = localStorage.getItem(installedThemeKey);
if (!installedThemeDataStr) return null;
const installedTheme = JSON.parse(installedThemeDataStr);
return installedTheme;
}
newRequest(amount) {
cardList = [];
const queue = [];
requestQueue.unshift(queue);
this.loadAmount(queue, amount);
}
/**
* @param {Object} item
* @param {"extension" | "theme" | "snippet"} type The type of card
*/
appendCard(item, type) {
item.visual = CONFIG.visual;
// Set key prop so items don't get stuck when switching tabs
item.key = `${CONFIG.activeTab}:${item.title}`;
item.type = type;
// Pass along the functions to update Grid state on apply
item.updateColourSchemes = this.updateColourSchemes.bind(this);
item.updateActiveTheme = this.setActiveTheme.bind(this);
// This isn't used other than to trigger a re-render
item.activeThemeKey = this.state.activeThemeKey;
cardList.push(react.createElement(Card, item));
this.setState({ cards: cardList });
}
// TODO: this isn't currently used, but it will be used for sorting (based on the SortBox component)
updateSort(sortByValue) {
if (sortByValue) {
sortConfig.by = sortByValue;
localStorage.setItem(LOCALSTORAGE_KEYS.sortBy, sortByValue);
}
requestPage = null;
cardList = [];
this.setState({
cards: [],
rest: false,
endOfList: false,
});
endOfList = false;
this.newRequest(ITEMS_PER_REQUEST);
}
updateTabs() {
this.setState({
tabs: [...CONFIG.tabs],
});
}
updatePostsVisual() {
cardList = cardList.map(card => {
return react.createElement(Card, card.props);
});
this.setState({ cards: [...cardList] });
}
switchTo(value) {
CONFIG.activeTab = value;
localStorage.setItem(LOCALSTORAGE_KEYS.activeTab, value);
cardList = [];
requestPage = null;
this.setState({
cards: [],
rest: false,
endOfList: false,
});
endOfList = false;
this.newRequest(ITEMS_PER_REQUEST);
}
// This is called from loadAmount in a loop until it has the requested amount of cards or runs out of results
// Returns the next page number to fetch, or null if at end
// TODO: maybe we should rename `loadPage()`, since it's slightly confusing when we have github pages as well
async loadPage(queue) {
if (CONFIG.activeTab === "Extensions") {
let pageOfRepos = await getExtensionRepos(requestPage);
for (const repo of pageOfRepos.items) {
let extensions = await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count);
// I believe this stops the requests when switching tabs?
if (requestQueue.length > 1 && queue !== requestQueue[0]) {
// Stop this queue from continuing to fetch and append to cards list
return -1;
}
if (extensions && extensions.length) {
// console.log(`${repo.name} has ${extensions.length} extensions:`, extensions);
extensions.forEach((extension) => this.appendCard(extension, "extension"));
}
}
// First result is null or -1 so it coerces to 1
const currentPage = requestPage > -1 && requestPage ? requestPage : 1;
// Sets the amount of items that have thus been fetched
const soFarResults = ITEMS_PER_REQUEST * (currentPage - 1) + pageOfRepos.page_count;
const remainingResults = pageOfRepos.total_count - soFarResults;
// If still have more results, return next page number to fetch
console.log(`Parsed ${soFarResults}/${pageOfRepos.total_count} extensions`);
if (remainingResults > 0) return currentPage + 1;
else console.log("No more extension results");
} else if (CONFIG.activeTab === "Installed") {
const installedStuff = {
theme: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.installedThemes, []),
extension: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.installedExtensions, []),
snippet: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.installedSnippets, []),
};
for (const type in installedStuff) {
if (installedStuff[type].length) {
installedStuff[type].forEach(async (itemKey) => {
// TODO: err handling
const extension = JSON.parse(localStorage.getItem(itemKey));
// I believe this stops the requests when switching tabs?
if (requestQueue.length > 1 && queue !== requestQueue[0]) {
// Stop this queue from continuing to fetch and append to cards list
return -1;
}
// @ts-ignore
this.appendCard(extension, type);
});
}
}
// Don't need to return a page number because
// installed extension do them all in one go, since it's local
} else if (CONFIG.activeTab == "Themes") {
let pageOfRepos = await getThemeRepos(requestPage);
for (const repo of pageOfRepos.items) {
let themes = await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count);
// I believe this stops the requests when switching tabs?
if (requestQueue.length > 1 && queue !== requestQueue[0]) {
// Stop this queue from continuing to fetch and append to cards list
return -1;
}
if (themes && themes.length) {
themes.forEach((theme) => this.appendCard(theme, "theme"));
}
}
// First request is null, so coerces to 1
const currentPage = requestPage > -1 && requestPage ? requestPage : 1;
// -1 because the page number is 1-indexed
const soFarResults = ITEMS_PER_REQUEST * (currentPage - 1) + pageOfRepos.page_count;
const remainingResults = pageOfRepos.total_count - soFarResults;
console.log(`Parsed ${soFarResults}/${pageOfRepos.total_count} themes`);
if (remainingResults > 0) return currentPage + 1;
else console.log("No more theme results");
} else if (CONFIG.activeTab == "Snippets") {
let snippets = await fetchCssSnippets();
if (requestQueue.length > 1 && queue !== requestQueue[0]) {
// Stop this queue from continuing to fetch and append to cards list
return -1;
}
if (snippets && snippets.length) {
snippets.forEach((snippet) => this.appendCard(snippet, "snippet"));
}
}
this.setState({ rest: true, endOfList: true });
endOfList = true;
return null;
}
/**
* Load a new set of extensions
* @param {any} queue An array of the extensions to be loaded
* @param {number} [quantity] Amount of extensions to be loaded per page. (Defaults to ITEMS_PER_REQUEST constant)
*/
async loadAmount(queue, quantity = ITEMS_PER_REQUEST) {
this.setState({ rest: false });
quantity += cardList.length;
requestPage = await this.loadPage(queue);
while (
requestPage &&
requestPage !== -1 &&
cardList.length < quantity &&
!this.state.endOfList
) {
requestPage = await this.loadPage(queue);
}
if (requestPage === -1) {
requestQueue = requestQueue.filter(a => a !== queue);
return;
}
// Remove this queue from queue list
requestQueue.shift();
this.setState({ rest: true });
}
/**
* Load more items if there are more items to load.
* @returns {void}
*/
loadMore() {
if (this.state.rest && !endOfList) {
this.loadAmount(requestQueue[0], ITEMS_PER_REQUEST);
}
}
/**
* Update the colour schemes in the state + dropdown, and inject the active one
* @param {any} schemes Object with the colour schemes
* @param {string} activeScheme The name of the active colour scheme (a key in the schemes object)
*/
updateColourSchemes(schemes, activeScheme) {
console.log("updateColourSchemes", schemes, activeScheme);
CONFIG.theme.schemes = schemes;
CONFIG.theme.activeScheme = activeScheme;
if (schemes && schemes[activeScheme]) {
this.injectColourScheme(CONFIG.theme.schemes[activeScheme]);
} else {
// Reset schemes if none sent
this.injectColourScheme(null);
}
// Save to localstorage
const installedThemeKey = localStorage.getItem(LOCALSTORAGE_KEYS.themeInstalled);
const installedThemeDataStr = localStorage.getItem(installedThemeKey);
const installedThemeData = JSON.parse(installedThemeDataStr);
installedThemeData.activeScheme = activeScheme;
localStorage.setItem(installedThemeKey, JSON.stringify(installedThemeData));
this.setState({
schemes,
activeScheme,
});
}
// NOTE: Keep in sync with extension.js
injectColourScheme (scheme) {
// Remove any existing Spicetify scheme
const existingColorsCSS = document.querySelector("link[href='colors.css']");
if (existingColorsCSS) existingColorsCSS.remove();
// Remove any existing marketplace scheme
const existingMarketplaceSchemeCSS = document.querySelector("style.marketplaceCSS.marketplaceScheme");
if (existingMarketplaceSchemeCSS) existingMarketplaceSchemeCSS.remove();
if (scheme) {
// Add new marketplace scheme
const schemeTag = document.createElement("style");
schemeTag.classList.add("marketplaceCSS");
schemeTag.classList.add("marketplaceScheme");
let injectStr = ":root {";
const themeIniKeys = Object.keys(scheme);
themeIniKeys.forEach((key) => {
injectStr += `--spice-${key}: #${scheme[key]};`;
injectStr += `--spice-rgb-${key}: ${hexToRGB(scheme[key])};`;
});
injectStr += "}";
schemeTag.innerHTML = injectStr;
document.head.appendChild(schemeTag);
} else {
// Re-add default user.css
let originalColorsCSS = document.createElement("link");
originalColorsCSS.setAttribute("rel", "stylesheet");
originalColorsCSS.setAttribute("href", "colors.css");
originalColorsCSS.classList.add("userCSS");
document.head.appendChild(originalColorsCSS);
}
}
/**
* The componentDidMount() method is called when the component is first loaded.
* It checks if the cardList is already loaded. If it is, it checks if the lastScroll value is
greater than 0.
* If it is, it scrolls to the lastScroll value. If it isn't, it scrolls to the top of the page.
* If the cardList isn't loaded, it loads the cardList.
*/
async componentDidMount() {
gridUpdateTabs = this.updateTabs.bind(this);
gridUpdatePostsVisual = this.updatePostsVisual.bind(this);
const viewPort = document.querySelector(".os-viewport");
this.checkScroll = this.isScrolledBottom.bind(this);
viewPort.addEventListener("scroll", this.checkScroll);
if (cardList.length) { // Already loaded
if (lastScroll > 0) {
viewPort.scrollTo(0, lastScroll);
}
return;
}
// Load blacklist
BLACKLIST = await getBlacklist();
this.newRequest(ITEMS_PER_REQUEST);
}
/**
* When the component is unmounted, remove the scroll event listener.
* @returns {void}
*/
componentWillUnmount() {
gridUpdateTabs = gridUpdatePostsVisual = null;
const viewPort = document.querySelector(".os-viewport");
lastScroll = viewPort.scrollTop;
viewPort.removeEventListener("scroll", this.checkScroll);
}
/**
* If the user has scrolled to the bottom of the page, load more posts.
* @param event - The event object that is passed to the callback function.
* @returns {void}
*/
isScrolledBottom(event) {
const viewPort = event.target;
if ((viewPort.scrollTop + viewPort.clientHeight) >= viewPort.scrollHeight) {
// At bottom, load more posts
this.loadMore();
}
}
setActiveTheme(themeKey) {
CONFIG.theme.activeThemeKey = themeKey;
this.setState({ activeThemeKey: themeKey });
}
// TODO: clean this up. It worked when I was using state, but state seems like pointless overhead.
getActiveScheme() {
return this.state.activeScheme;
}
render() {
return react.createElement("section", {
className: "contentSpacing",
},
react.createElement("div", {
className: "marketplace-header",
}, react.createElement("h1", null, this.props.title),
// Start of marketplace-header__right
react.createElement("div", {
className: "marketplace-header__right",
},
// Show colour scheme dropdown if there is a theme with schemes installed
this.state.activeScheme ? react.createElement(SortBox, {
onChange: (value) => this.updateColourSchemes(this.state.schemes, value),
// TODO: Make this compatible with the changes to the theme install process: need to create a method to update the scheme options without a full reload.
sortBoxOptions: generateSchemesOptions(this.state.schemes),
// It doesn't work when I directly use CONFIG.theme.activeScheme in the sortBySelectedFn
// because it hardcodes the value into the fn
sortBySelectedFn: (a) => a.key === this.getActiveScheme(),
}) : null,
react.createElement("button", {
className: "marketplace-settings-button",
id: "marketplace-settings-button",
onClick: openConfig,
}, SETTINGS_ICON),
// End of marketplace-header__right
),
// TODO: Add search bar and sort functionality
// react.createElement("div", {
// className: "searchbar--bar__wrapper",
// }, react.createElement("input", {
// className: "searchbar-bar",
// type: "text",
// placeholder: "Search for Extensions?",
// })),
),
[ // Add a header and grid for each card type if it has any cards
{ handle: "extension", name: "Extensions" },
{ handle: "theme", name: "Themes" },
{ handle: "snippet", name: "Snippets" },
].map((cardType) => {
const cardsOfType = cardList.filter((card) => card.props.type === cardType.handle)
.map((card) => {
// Clone the cards and update the prop to trigger re-render
// TODO: is it possible to only re-render the theme cards whose status have changed?
const cardElement = react.cloneElement(card, {
activeThemeKey: this.state.activeThemeKey,
});
return cardElement;
});
if (cardsOfType.length) {
return [
// Add a header for the card type
react.createElement("h2",
{ className: "marketplace-card-type-heading" },
cardType.name),
// Add the grid and cards
react.createElement("div", {
className: "marketplace-grid main-gridContainer-gridContainer main-gridContainer-fixedWidth",
"data-tab": CONFIG.activeTab,
style: {
"--minimumColumnWidth": "180px",
"--column-width": "minmax(var(--minimumColumnWidth),1fr)",
"--column-count": "auto-fill",
"--grid-gap": "24px",
},
}, cardsOfType)];
} else {
return null;
}
}), react.createElement("footer", {
style: {
margin: "auto",
textAlign: "center",
},
}, !this.state.endOfList && (this.state.rest ? react.createElement(LoadMoreIcon, { onClick: this.loadMore.bind(this) }) : react.createElement(LoadingIcon)),
// Add snippets button if on snippets tab
CONFIG.activeTab === "Snippets" ? react.createElement("button", {
className: "marketplace-add-snippet-btn main-buttons-button main-button-secondary",
onClick: openAddSnippetModal,
}, "+Add CSS") : null,
), react.createElement(TopBarContent, {
switchCallback: this.switchTo.bind(this),
links: CONFIG.tabs,
activeLink: CONFIG.activeTab,
}));
}
}
// 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
// https://docs.github.com/en/rest/reference/search#search-repositories
/**
* Query GitHub for all repos with the "spicetify-extensions" topic
* @param {number} page The query page number
* @returns Array of search results (filtered through the blacklist)
*/
async function getExtensionRepos(page = 1) {
// www is needed or it will block with "cross-origin" error.
let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify-extensions")}&per_page=${ITEMS_PER_REQUEST}`;
// We can test multiple pages with this URL (58 results), as well as broken iamges etc.
// let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify")}`;
if (page) url += `&page=${page}`;
// Sorting params (not implemented for Marketplace yet)
// if (sortConfig.by.match(/top|controversial/) && sortConfig.time) {
// url += `&t=${sortConfig.time}`
const allRepos = await fetch(url).then(res => res.json()).catch(() => []);
if (!allRepos.items) {
Spicetify.showNotification("Too Many Requests, Cool Down.");
}
const filteredResults = {
...allRepos,
// Include count of all items on the page, since we're filtering the blacklist below,
// which can mess up the paging logic
page_count: allRepos.items.length,
items: allRepos.items.filter(item => !BLACKLIST.includes(item.html_url)),
};
return filteredResults;
}
// TODO: add try/catch here?
// TODO: can we add a return type here?
/**
* Get the manifest object for a repo
* @param {string} user Owner username
* @param {string} repo Repo name
* @param {string} branch Default branch name (e.g. main or master)
* @returns The manifest object
*/
async function getRepoManifest(user, repo, branch) {
const sessionStorageItem = window.sessionStorage.getItem(`${user}-${repo}`);
const failedSessionStorageItems = window.sessionStorage.getItem("noManifests");
if (sessionStorageItem) {
return JSON.parse(sessionStorageItem);
}
const url = `https://raw.githubusercontent.com/${user}/${repo}/${branch}/manifest.json`;
if (failedSessionStorageItems.includes(url)) {
return null;
}
const manifest = await fetch(url).then(res => res.json()).catch(() => addToSessionStorage([url], "noManifests"));
if (manifest) {
window.sessionStorage.setItem(`${user}-${repo}`, JSON.stringify(manifest));
}
return manifest;
}
// TODO: can we add a return type here?
/**
* Fetch extensions from a repo and format data for generating cards
* @param {string} contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}")
* @param {string} branch The repo's default branch (e.g. main or master)
* @param {number} stars The number of stars the repo has
* @returns Extension info for card (or null)
*/
async function fetchExtensionManifest(contents_url, branch, stars) {
try {
// TODO: use the original search full_name ("theRealPadster/spicetify-hide-podcasts") or something to get the url better?
let manifests;
const regex_result = contents_url.match(/https:\/\/api\.github\.com\/repos\/(?<user>.+)\/(?<repo>.+)\/contents/);
// TODO: err handling?
if (!regex_result || !regex_result.groups) return null;
const { user, repo } = regex_result.groups;
manifests = await getRepoManifest(user, repo, branch);
// If the manifest returned is not an array, initialize it as one
if (!Array.isArray(manifests)) manifests = [manifests];
// Manifest is initially parsed
const parsedManifests = manifests.reduce((accum, manifest) => {
const selectedBranch = manifest.branch || branch;
const item = {
manifest,
title: manifest.name,
subtitle: manifest.description,
authors: processAuthors(manifest.authors, user),
user,
repo,
branch: selectedBranch,
imageURL: manifest.preview && manifest.preview.startsWith("http")
? manifest.preview
: `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.preview}`,
extensionURL: manifest.main.startsWith("http")
? manifest.main
: `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.main}`,
readmeURL: manifest.readme && manifest.readme.startsWith("http")
? manifest.readme
: `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`,
stars,
tags: manifest.tags,
};
// If manifest is valid, add it to the list
if (manifest && manifest.name && manifest.description && manifest.main
) {
// Add to list unless we're hiding installed items and it's installed
if (!(CONFIG.visual.hideInstalled
&& localStorage.getItem("marketplace:installed:" + `${user}/${repo}/${manifest.main}`))
) {
accum.push(item);
}
}
// else {
// console.error("Invalid manifest:", manifest);
// }
return accum;
}, []);
return parsedManifests;
}
catch (err) {
// console.warn(contents_url, err);
return null;
}
}
// TODO: can we add a return type here?
/**
* Fetch themes from a repo and format data for generating cards
* @param {string} contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}")
* @param {string} branch The repo's default branch (e.g. main or master)
* @param {number} stars The number of stars the repo has
* @returns Extension info for card (or null)
*/
async function fetchThemeManifest(contents_url, branch, stars) {
try {
let manifests;
const regex_result = contents_url.match(/https:\/\/api\.github\.com\/repos\/(?<user>.+)\/(?<repo>.+)\/contents/);
// TODO: err handling?
if (!regex_result || !regex_result.groups) return null;
let { user, repo } = regex_result.groups;
manifests = await getRepoManifest(user, repo, branch);
// If the manifest returned is not an array, initialize it as one
if (!Array.isArray(manifests)) manifests = [manifests];
// Manifest is initially parsed
const parsedManifests = manifests.reduce((accum, manifest) => {
const selectedBranch = manifest.branch || branch;
const item = {
manifest,
title: manifest.name,
subtitle: manifest.description,
authors: processAuthors(manifest.authors, user),
user,
repo,
branch: selectedBranch,
imageURL: manifest.preview && manifest.preview.startsWith("http")
? manifest.preview
: `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.preview}`,
readmeURL: manifest.readme && manifest.readme.startsWith("http")
? manifest.readme
: `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`,
stars,
tags: manifest.tags,
// theme stuff
cssURL: manifest.usercss.startsWith("http")
? manifest.usercss
: `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.usercss}`,
// TODO: clean up indentation etc
schemesURL: manifest.schemes
? (
manifest.schemes.startsWith("http") ? manifest.schemes : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.schemes}`
)
: null,
include: manifest.include,
};
// If manifest is valid, add it to the list
if (manifest && manifest.name && manifest.usercss && manifest.description) {
accum.push(item);
}
return accum;
}, []);
return parsedManifests;
}
catch (err) {
// console.warn(contents_url, err);
return null;
}
}
/**
* Query the GitHub API for a page of theme repos (having "spicetify-themes" topic)
* @param {number} page The page to get (defaults to 1)
* @returns Array of GitHub API results, filtered through the blacklist
*/
async function getThemeRepos(page = 1) {
let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify-themes")}&per_page=${ITEMS_PER_REQUEST}`;
// We can test multiple pages with this URL (58 results), as well as broken iamges etc.
// let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify")}`;
if (page) url += `&page=${page}`;
// Sorting params (not implemented for Marketplace yet)
// if (sortConfig.by.match(/top|controversial/) && sortConfig.time) {
// url += `&t=${sortConfig.time}`
const allThemes = await fetch(url).then(res => res.json()).catch(() => []);
if (!allThemes.items) {
Spicetify.showNotification("Too Many Requests, Cool Down.");
}
const filteredResults = {
...allThemes,
// Include count of all items on the page, since we're filtering the blacklist below,
// which can mess up the paging logic
page_count: allThemes.items.length,
items: allThemes.items.filter(item => !BLACKLIST.includes(item.html_url)),
};
return filteredResults;
}
function addToSessionStorage(items, key) {
if (!items || items == null) return;
items.forEach(item => {
if (!key) key = `${items.user}-${items.repo}`;
// If the key already exists, it will append to it instead of overwriting it
const existing = window.sessionStorage.getItem(key);
const parsed = existing ? JSON.parse(existing) : [];
parsed.push(item);
window.sessionStorage.setItem(key, JSON.stringify(parsed));
});
}