From 0599159a9927419397fc3ee12ce00102a325f8b6 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Fri, 24 Jun 2022 20:19:05 -0400 Subject: [PATCH 01/48] =?UTF-8?q?=F0=9F=9A=A7=20Initial=20support=20for=20?= =?UTF-8?q?mono-manifest=20themes=20(no=20stars=20yet)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Grid.tsx | 28 +++++------ src/constants.ts | 4 +- src/extensions/extension.tsx | 27 +++-------- src/logic/FetchRemotes.ts | 90 ++++++++++++++++-------------------- 4 files changed, 60 insertions(+), 89 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 2448d6f0..a2373da9 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -5,8 +5,8 @@ import { LOCALSTORAGE_KEYS, ITEMS_PER_REQUEST } from "../constants"; import { openModal } from "../logic/LaunchModals"; import { getExtensionRepos, fetchExtensionManifest, - getThemeRepos, fetchThemeManifest, - fetchCssSnippets, getBlacklist, + getThemeRepos, buildThemeCardData, + fetchCssSnippets, getBlacklist, getThemesMonoManifest, } from "../logic/FetchRemotes"; import LoadMoreIcon from "./Icons/LoadMoreIcon"; import LoadingIcon from "./Icons/LoadingIcon"; @@ -224,30 +224,24 @@ export default class Grid extends React.Component< // Don't need to return a page number because // installed extension do them all in one go, since it's local } case "Themes": { - const pageOfRepos = await getThemeRepos(this.requestPage, this.BLACKLIST, query); - for (const repo of pageOfRepos.items) { + const allThemes = await getThemesMonoManifest(); + console.log(allThemes); + + for (const theme of allThemes) { + const themeCardData = await buildThemeCardData(theme); - const themes = await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); + // TODO: do we need this queue stuff any more // I believe this stops the requests when switching tabs? if (this.requestQueue.length > 1 && queue !== this.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")); - } + // TODO: it's complaining about the argument type here... + this.appendCard(themeCardData, "theme"); } - // First request is null, so coerces to 1 - const currentPage = this.requestPage > -1 && this.requestPage ? this.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"); + console.log("Parsed themes"); break; } case "Snippets": { const snippets = await fetchCssSnippets(); diff --git a/src/constants.ts b/src/constants.ts index 7971eb36..aa4999b8 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -31,5 +31,5 @@ export const CUSTOM_APP_PATH = "/marketplace"; export const MAX_TAGS = 4; 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"; \ No newline at end of file +export const THEMES_URL = "https://raw.githubusercontent.com/spicetify/spicetify-themes/generated-manifest/manifest.json"; +export const BLACKLIST_URL = "https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/blacklist.json"; diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index fb8d39c4..b681333a 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -19,7 +19,7 @@ import { } from "../logic/Utils"; import { getBlacklist, - fetchThemeManifest, + buildThemeCardData, fetchExtensionManifest, } from "../logic/FetchRemotes"; @@ -187,24 +187,11 @@ async function loadPageRecursive(type: RepoType, pageNum: number) { // TODO: does this work? // The recursion isn't super clean... - // Begin by getting the themes and extensions from github - // const [extensionReposArray, themeReposArray] = await Promise.all([ - await Promise.all([ - loadPageRecursive("extension", 1), - loadPageRecursive("theme", 1), - ]); - - // let extensionsNextPage = 1; - // let themesNextPage = 1; - // do { - // extensionReposArray = await loadPage("extension", extensionsNextPage); - // appendInformationToLocalStorage(extensionReposArray, "extension"); - // } while (extensionsNextPage); - - // do { - // themeReposArray = await loadPage("theme", themesNextPage); - // appendInformationToLocalStorage(themeReposArray, "theme"); - // } while (themesNextPage); + // TODO: re-enable this once everything works with mono-manifest... + // await Promise.all([ + // loadPageRecursive("extension", 1), + // loadPageRecursive("theme", 1), + // ]); })(); async function appendInformationToLocalStorage(array, type: RepoType) { @@ -212,7 +199,7 @@ async function appendInformationToLocalStorage(array, type: RepoType) { for (const repo of array.items) { // console.log(repo); const data = (type === "theme") - ? await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count) + ? await buildThemeCardData(repo.contents_url, repo.default_branch, repo.stargazers_count) : await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); if (data) { addToSessionStorage(data); diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 1fdc672c..927b10e7 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -1,6 +1,6 @@ import { CardItem, Snippet } from "../types/marketplace-types"; import { processAuthors, addToSessionStorage } from "./Utils"; -import { ITEMS_PER_REQUEST, BLACKLIST_URL, SNIPPETS_URL } from "../constants"; +import { ITEMS_PER_REQUEST, BLACKLIST_URL, SNIPPETS_URL, THEMES_URL } from "../constants"; // 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 @@ -131,6 +131,7 @@ export async function fetchExtensionManifest(contents_url: string, branch: strin } // TODO: can we add a return type here? +// TODO: Update these docs /** * Fetch themes from a repo and format data for generating cards * @param contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") @@ -138,58 +139,42 @@ export async function fetchExtensionManifest(contents_url: string, branch: strin * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function fetchThemeManifest(contents_url: string, branch: string, stars: number) { +export async function buildThemeCardData(manifest: any) { // TODO: add type try { - let manifests; - const regex_result = contents_url.match(/https:\/\/api\.github\.com\/repos\/(?.+)\/(?.+)\/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]; + // TODO: figure this out... + const [ user, repo, selectedBranch ] = ["spicetify", "spicetify-themes", "generated-manifest"]; // Manifest is initially parsed - // const parsedManifests: ThemeCardItem[] = manifests.reduce((accum, manifest) => { - const parsedManifests: CardItem[] = 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?.name && manifest?.usercss && manifest?.description) { - accum.push(item); - } - return accum; - }, []); - return parsedManifests; + const parsedManifest: CardItem[] = { + manifest, + title: manifest.name, + subtitle: manifest.description, + authors: processAuthors(manifest.authors, "user..."), // TODO: do we need a fallback? + // TODO: do we need these? + 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: 0, // TODO: get stars working + 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, + }; + return parsedManifest; } catch (err) { // console.warn(contents_url, err); @@ -227,6 +212,11 @@ export async function getThemeRepos(page = 1, BLACKLIST:string[] = [], query?: s return filteredResults; } +export const getThemesMonoManifest = async () => { + const manifest = await fetch(THEMES_URL).then(res => res.json()).catch(() => null); + return manifest; +}; + /** * It fetches the blacklist.json file from the GitHub repository and returns the array of blocked repos. * @returns String array of blacklisted repos From 711695dcca0f8feee8db37ed44ecce974fef4d52 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Fri, 24 Jun 2022 20:29:16 -0400 Subject: [PATCH 02/48] Fix some linting --- src/components/Grid.tsx | 6 +++--- src/extensions/extension.tsx | 4 ++-- src/logic/FetchRemotes.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 5b3206fc..dca423cf 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -8,8 +8,8 @@ import { LOCALSTORAGE_KEYS, ITEMS_PER_REQUEST, MARKETPLACE_VERSION, LATEST_RELEA import { openModal } from "../logic/LaunchModals"; import { getTaggedRepos, - fetchExtensionManifest, fetchThemeManifest, fetchAppManifest, - fetchCssSnippets, getBlacklist, + fetchExtensionManifest, fetchAppManifest, + fetchCssSnippets, fetchBlacklist, getThemesMonoManifest, buildThemeCardData, } from "../logic/FetchRemotes"; import LoadMoreIcon from "./Icons/LoadMoreIcon"; @@ -429,7 +429,7 @@ export default class Grid extends React.Component< } // Load blacklist - this.BLACKLIST = await getBlacklist(); + this.BLACKLIST = await fetchBlacklist(); this.newRequest(ITEMS_PER_REQUEST); } diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index 969c55e7..e51b7e91 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -18,7 +18,7 @@ import { sleep, } from "../logic/Utils"; import { - getBlacklist, + fetchBlacklist, buildThemeCardData, fetchExtensionManifest, } from "../logic/FetchRemotes"; @@ -187,7 +187,7 @@ async function loadPageRecursive(type: RepoType, pageNum: number) { (async function initializePreload() { console.log("Preloading extensions and themes..."); window.sessionStorage.clear(); - const BLACKLIST = await getBlacklist(); + const BLACKLIST = await fetchBlacklist(); window.sessionStorage.setItem("marketplace:blacklist", JSON.stringify(BLACKLIST)); // TODO: does this work? diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index c2c224b1..dbc5dd72 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -265,7 +265,7 @@ export const getThemesMonoManifest = async () => { * It fetches the blacklist.json file from the GitHub repository and returns the array of blocked repos. * @returns String array of blacklisted repos */ -export const getBlacklist = async () => { +export const fetchBlacklist = async () => { const json = await fetch(BLACKLIST_URL).then(res => res.json()).catch(() => ({})); return json.repos as string[] | undefined; }; From f2595aea3978d900b2ee82af35b452f3473591e2 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Fri, 24 Jun 2022 20:53:17 -0400 Subject: [PATCH 03/48] =?UTF-8?q?=F0=9F=9A=A7=20Initial=20mono-manifest=20?= =?UTF-8?q?support=20for=20custom=20apps=20(Using=20a=20local=20manifest?= =?UTF-8?q?=20since=20there=20is=20no=20repo)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/manifests/apps.ts | 22 ++++++++++ src/components/Grid.tsx | 34 +++++---------- src/logic/FetchRemotes.ts | 82 +++++++++++++++---------------------- 3 files changed, 67 insertions(+), 71 deletions(-) create mode 100644 resources/manifests/apps.ts diff --git a/resources/manifests/apps.ts b/resources/manifests/apps.ts new file mode 100644 index 00000000..293aabe2 --- /dev/null +++ b/resources/manifests/apps.ts @@ -0,0 +1,22 @@ +export default [ + { + "name": "Name That Tune!!1", + "description": "Heardle.app made for Spicetify", + + // TODO: Get the image working (once there is a repo?) + "preview": "https://github.com/theRealPadster/name-that-tune/raw/main/docs/preview.png", + // TODO: Get the readme working (once there is a repo?) + "readme": "README.md", + + "authors": [ + { + "name": "theRealPadster", + "url": "https://github.com/theRealPadster", + }, + ], + "tags": [ + "game", + "beta", + ], + }, +]; diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index dca423cf..836eac29 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -8,9 +8,10 @@ import { LOCALSTORAGE_KEYS, ITEMS_PER_REQUEST, MARKETPLACE_VERSION, LATEST_RELEA import { openModal } from "../logic/LaunchModals"; import { getTaggedRepos, - fetchExtensionManifest, fetchAppManifest, + fetchExtensionManifest, fetchCssSnippets, fetchBlacklist, getThemesMonoManifest, buildThemeCardData, + getAppsMonoManifest, buildAppCardData, } from "../logic/FetchRemotes"; import LoadMoreIcon from "./Icons/LoadMoreIcon"; import LoadingIcon from "./Icons/LoadingIcon"; @@ -262,37 +263,24 @@ export default class Grid extends React.Component< console.log("Parsed themes"); break; } case "Apps": { - const pageOfRepos = await getTaggedRepos("spicetify-apps", this.requestPage, this.BLACKLIST, query); - for (const repo of pageOfRepos.items) { + const allApps = await getAppsMonoManifest(); + console.log(allApps); - const apps = await fetchAppManifest( - repo.contents_url, - repo.default_branch, - repo.stargazers_count, - ); + for (const app of allApps) { + const appCardData = await buildAppCardData(app); + + // TODO: do we need this queue stuff any more? // I believe this stops the requests when switching tabs? if (this.requestQueue.length > 1 && queue !== this.requestQueue[0]) { // Stop this queue from continuing to fetch and append to cards list return -1; } - if (apps && apps.length) { - apps.forEach((app) => { - Object.assign(app, { lastUpdated: repo.pushed_at }); - this.appendCard(app, "app"); - }); - } + // TODO: it's complaining about the argument type here... + this.appendCard(appCardData, "app"); } - // First request is null, so coerces to 1 - const currentPage = this.requestPage > -1 && this.requestPage ? this.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} apps`); - if (remainingResults > 0) return currentPage + 1; - else console.log("No more app results"); + console.log("Parsed apps"); break; } case "Snippets": { const snippets = await fetchCssSnippets(); diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index dbc5dd72..904d3032 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -3,6 +3,7 @@ import { processAuthors, addToSessionStorage } from "./Utils"; import { ITEMS_PER_REQUEST, BLACKLIST_URL, THEMES_URL } from "../constants"; import { RepoTopic } from "../types/marketplace-types"; import snippetsJSON from "../../resources/snippets"; +import appsManifest from "../../resources/manifests/apps"; // 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 @@ -189,6 +190,7 @@ export async function buildThemeCardData(manifest: any) { // TODO: add type } } +// TODO: Update these docs /** * Fetch custom apps from a repo and format data for generating cards * @param contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") @@ -196,59 +198,37 @@ export async function buildThemeCardData(manifest: any) { // TODO: add type * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function fetchAppManifest(contents_url: string, branch: string, stars: number) { +export async function buildAppCardData(manifest: any) { // TODO: add type 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\/(?.+)\/(?.+)\/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]; + // TODO: figure this out... + // TODO: Update these once we get a repo for apps + const [ user, repo, selectedBranch ] = ["spicetify", "spicetify-themes", "generated-manifest"]; // Manifest is initially parsed - const parsedManifests: CardItem[] = manifests.reduce((accum, manifest) => { - const selectedBranch = manifest.branch || branch; - // TODO: tweak saved items - 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}`, - // Custom Apps don't have an entry point; they're just listed so they can link out from the card - // 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) { - accum.push(item); - } - // else { - // console.error("Invalid manifest:", manifest); - // } + const parsedManifest: CardItem[] = { + manifest, + title: manifest.name, + subtitle: manifest.description, + authors: processAuthors(manifest.authors, "user..."), // TODO: do we need a fallback? + user, + repo, + branch: selectedBranch, - return accum; - }, []); + imageURL: manifest.preview && manifest.preview.startsWith("http") + ? manifest.preview + : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.preview}`, + // Custom Apps don't have an entry point; they're just listed so they can link out from the card + // 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: 0, // TODO: get stars working + tags: manifest.tags, + }; - return parsedManifests; + return parsedManifest; } catch (err) { // console.warn(contents_url, err); @@ -261,6 +241,12 @@ export const getThemesMonoManifest = async () => { return manifest; }; +export const getAppsMonoManifest = async () => { + // const manifest = await fetch(THEMES_URL).then(res => res.json()).catch(() => null); + const manifest = appsManifest; + return manifest; +}; + /** * It fetches the blacklist.json file from the GitHub repository and returns the array of blocked repos. * @returns String array of blacklisted repos From 1f1f8a213ecbcc0bf0450935ba5b0061d47d9a3b Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sat, 25 Jun 2022 11:15:03 -0400 Subject: [PATCH 04/48] Fix some type errors --- src/components/Grid.tsx | 6 ++---- src/logic/FetchRemotes.ts | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 836eac29..6147601d 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -256,8 +256,7 @@ export default class Grid extends React.Component< return -1; } - // TODO: it's complaining about the argument type here... - this.appendCard(themeCardData, "theme"); + if (themeCardData) this.appendCard(themeCardData, "theme"); } console.log("Parsed themes"); @@ -276,8 +275,7 @@ export default class Grid extends React.Component< return -1; } - // TODO: it's complaining about the argument type here... - this.appendCard(appCardData, "app"); + if (appCardData) this.appendCard(appCardData, "app"); } console.log("Parsed apps"); diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 904d3032..179bc176 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -153,7 +153,7 @@ export async function buildThemeCardData(manifest: any) { // TODO: add type const [ user, repo, selectedBranch ] = ["spicetify", "spicetify-themes", "generated-manifest"]; // Manifest is initially parsed - const parsedManifest: CardItem[] = { + const parsedManifest: CardItem = { manifest, title: manifest.name, subtitle: manifest.description, @@ -182,6 +182,7 @@ export async function buildThemeCardData(manifest: any) { // TODO: add type : null, include: manifest.include, }; + return parsedManifest; } catch (err) { @@ -205,7 +206,7 @@ export async function buildAppCardData(manifest: any) { // TODO: add type const [ user, repo, selectedBranch ] = ["spicetify", "spicetify-themes", "generated-manifest"]; // Manifest is initially parsed - const parsedManifest: CardItem[] = { + const parsedManifest: CardItem = { manifest, title: manifest.name, subtitle: manifest.description, From e39df53452fa7598e385771e80656cc851cd0a57 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sat, 25 Jun 2022 11:15:30 -0400 Subject: [PATCH 05/48] Naming --- src/components/Grid.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 6147601d..92bece13 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -247,7 +247,7 @@ export default class Grid extends React.Component< console.log(allThemes); for (const theme of allThemes) { - const themeCardData = await buildThemeCardData(theme); + const cardData = await buildThemeCardData(theme); // TODO: do we need this queue stuff any more? // I believe this stops the requests when switching tabs? @@ -256,7 +256,7 @@ export default class Grid extends React.Component< return -1; } - if (themeCardData) this.appendCard(themeCardData, "theme"); + if (cardData) this.appendCard(cardData, "theme"); } console.log("Parsed themes"); @@ -266,7 +266,7 @@ export default class Grid extends React.Component< console.log(allApps); for (const app of allApps) { - const appCardData = await buildAppCardData(app); + const cardData = await buildAppCardData(app); // TODO: do we need this queue stuff any more? // I believe this stops the requests when switching tabs? @@ -275,7 +275,7 @@ export default class Grid extends React.Component< return -1; } - if (appCardData) this.appendCard(appCardData, "app"); + if (cardData) this.appendCard(cardData, "app"); } console.log("Parsed apps"); From 256254f52429914fc7f6b3250fd0241af2ecea03 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sat, 25 Jun 2022 11:17:26 -0400 Subject: [PATCH 06/48] Fix type errors --- src/logic/FetchRemotes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 179bc176..46479c37 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -1,4 +1,4 @@ -import { CardItem, Snippet } from "../types/marketplace-types"; +import { CardItem, Manifest, Snippet } from "../types/marketplace-types"; import { processAuthors, addToSessionStorage } from "./Utils"; import { ITEMS_PER_REQUEST, BLACKLIST_URL, THEMES_URL } from "../constants"; import { RepoTopic } from "../types/marketplace-types"; @@ -147,7 +147,7 @@ export async function fetchExtensionManifest(contents_url: string, branch: strin * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function buildThemeCardData(manifest: any) { // TODO: add type +export async function buildThemeCardData(manifest: Manifest) { try { // TODO: figure this out... const [ user, repo, selectedBranch ] = ["spicetify", "spicetify-themes", "generated-manifest"]; @@ -199,7 +199,7 @@ export async function buildThemeCardData(manifest: any) { // TODO: add type * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function buildAppCardData(manifest: any) { // TODO: add type +export async function buildAppCardData(manifest: Manifest) { try { // TODO: figure this out... // TODO: Update these once we get a repo for apps From 74ed0d7998c4cbf5b7135f46bda7e0c6e0aea705 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sat, 25 Jun 2022 11:23:18 -0400 Subject: [PATCH 07/48] More type fixes --- src/logic/FetchRemotes.ts | 6 +++--- src/types/marketplace-types.d.ts | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 46479c37..af8bc3c5 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -169,7 +169,7 @@ export async function buildThemeCardData(manifest: Manifest) { ? manifest.readme : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`, stars: 0, // TODO: get stars working - tags: manifest.tags, + tags: manifest.tags || [], // theme stuff cssURL: manifest.usercss.startsWith("http") ? manifest.usercss @@ -179,7 +179,7 @@ export async function buildThemeCardData(manifest: Manifest) { ? ( manifest.schemes.startsWith("http") ? manifest.schemes : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.schemes}` ) - : null, + : undefined, include: manifest.include, }; @@ -226,7 +226,7 @@ export async function buildAppCardData(manifest: Manifest) { ? manifest.readme : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`, stars: 0, // TODO: get stars working - tags: manifest.tags, + tags: manifest.tags || [], }; return parsedManifest; diff --git a/src/types/marketplace-types.d.ts b/src/types/marketplace-types.d.ts index 157fcfe7..ba916b24 100644 --- a/src/types/marketplace-types.d.ts +++ b/src/types/marketplace-types.d.ts @@ -69,8 +69,8 @@ export type Manifest = { // TODO: split these into different types? tags?: string[]; - usercss?: string; - schemes?: string[]; + usercss?: string; // URL for usercss + schemes?: string; // URL for schemes include?: string[]; }; @@ -85,7 +85,7 @@ export type CardItem = { repo: string; branch: string; imageURL: string; - extensionURL: string; + extensionURL?: string; readmeURL: string; stars: number; tags: string[]; @@ -99,8 +99,8 @@ export type CardItem = { // TODO: clean this up somehow // It complains bitterly in Card.tsx // if I don't have all the same properties as CardItem - code: undefined; - description: undefined; + code?: undefined; + description?: undefined; }; // TODO: use this in `fetchThemeManifest()` From ea7b22aa77a8cccd5f9fd49ea47b989cdb3c1725 Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 13:28:55 -0400 Subject: [PATCH 08/48] Change to use ES2021 --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 0e3329b5..86d90839 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ "skipLibCheck": true, "noImplicitAny": false, "lib": [ - "ES2021.String", + "ES2021", "dom" ] }, From 73498afdbddadcaa06c8b0c048b99b45969e8c7c Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 14:03:34 -0400 Subject: [PATCH 09/48] Begin implementing github topic fetch option --- src/components/Modals/Settings/index.tsx | 1 + src/constants.ts | 1 + src/extensions/extension.tsx | 25 ++- src/logic/FetchRemotes.ts | 4 +- src/logic/FetchTopicRemotes.ts | 275 +++++++++++++++++++++++ src/types/marketplace-types.d.ts | 2 + 6 files changed, 303 insertions(+), 5 deletions(-) create mode 100644 src/logic/FetchTopicRemotes.ts diff --git a/src/components/Modals/Settings/index.tsx b/src/components/Modals/Settings/index.tsx index 338d667e..3b21abf5 100644 --- a/src/components/Modals/Settings/index.tsx +++ b/src/components/Modals/Settings/index.tsx @@ -46,6 +46,7 @@ const SettingsModal = ({ CONFIG, updateAppConfig } : Props) => { +

Tabs

{modalConfig.tabs.map(({ name }, index) => { diff --git a/src/constants.ts b/src/constants.ts index 8be4c47f..86ead95e 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -13,6 +13,7 @@ export const LOCALSTORAGE_KEYS = { // Theme installed store the localsorage key of the theme (e.g. marketplace:installed:NYRI4/Comfy-spicetify/user.css) "themeInstalled": "marketplace:theme-installed", "colorShift": "marketplace:colorShift", + "githubTopics": "marketplace:githubTopics", }; // Initalize topbar tabs diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index e51b7e91..0f5c22aa 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -22,6 +22,10 @@ import { buildThemeCardData, fetchExtensionManifest, } from "../logic/FetchRemotes"; +import { + fetchThemeManifestFromTopic, + fetchExtensionManifestFromTopic +} from "../logic/FetchTopicRemotes"; (async () => { while (!(Spicetify?.LocalStorage && Spicetify?.showNotification)) { @@ -171,6 +175,8 @@ async function queryRepos(type: RepoType, pageNum = 1) { */ async function loadPageRecursive(type: RepoType, pageNum: number) { const pageOfRepos = await queryRepos(type, pageNum); + console.log(pageOfRepos); + // TODO: Once we migrate to the mono-manifest repo, implement the option for enabling topics search here appendInformationToLocalStorage(pageOfRepos, type); // Sets the amount of items that have thus been fetched @@ -194,16 +200,27 @@ async function loadPageRecursive(type: RepoType, pageNum: number) { // The recursion isn't super clean... // TODO: re-enable this once everything works with mono-manifest... - // await Promise.all([ - // loadPageRecursive("extension", 1), - // loadPageRecursive("theme", 1), - // ]); + await Promise.all([ + loadPageRecursive("extension", 1), + loadPageRecursive("theme", 1), + ]); })(); async function appendInformationToLocalStorage(array, type: RepoType) { // This system should make it so themes and extensions are stored concurrently for (const repo of array.items) { + if(LOCALSTORAGE_KEYS.githubTopics){ + for (const repo of array.items) { // console.log(repo); + const data = (type === "theme") + ? await fetchThemeManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count) + : await fetchExtensionManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count); + if (data) { + addToSessionStorage(data); + await sleep(5000); + } + } + } const data = (type === "theme") ? await buildThemeCardData(repo.contents_url, repo.default_branch, repo.stargazers_count) : await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index af8bc3c5..baa6c26b 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -171,7 +171,7 @@ export async function buildThemeCardData(manifest: Manifest) { stars: 0, // TODO: get stars working tags: manifest.tags || [], // theme stuff - cssURL: manifest.usercss.startsWith("http") + cssURL: manifest.usercss?.startsWith("http") ? manifest.usercss : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.usercss}`, // TODO: clean up indentation etc @@ -181,6 +181,7 @@ export async function buildThemeCardData(manifest: Manifest) { ) : undefined, include: manifest.include, + lastUpdated : "" }; return parsedManifest; @@ -227,6 +228,7 @@ export async function buildAppCardData(manifest: Manifest) { : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`, stars: 0, // TODO: get stars working tags: manifest.tags || [], + lastUpdated: "" }; return parsedManifest; diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts new file mode 100644 index 00000000..74e3a33f --- /dev/null +++ b/src/logic/FetchTopicRemotes.ts @@ -0,0 +1,275 @@ +import { CardItem, Snippet } from "../types/marketplace-types"; +import { processAuthors, addToSessionStorage } from "./Utils"; +import { ITEMS_PER_REQUEST, BLACKLIST_URL } from "../constants"; +import { RepoTopic } from "../types/marketplace-types"; + +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 +// https://docs.github.com/en/rest/reference/search#search-repositories + +/** + * Query GitHub for all repos with the requested topic + * @param tag The tag ("topic") to search for + * @param page The query page number + * @returns Array of search results (filtered through the blacklist) + */ +export async function getTaggedRepos(tag: RepoTopic, page = 1, BLACKLIST:string[] = [], query?: string) { + // www is needed or it will block with "cross-origin" error. + let url = query + ? `https://api.github.com/search/repositories?q=${encodeURIComponent(`${query}+topic:${tag}`)}&per_page=${ITEMS_PER_REQUEST}` + : `https://api.github.com/search/repositories?q=${encodeURIComponent(`topic:${tag}`)}&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."); + return; + } + 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 user Owner username +* @param repo Repo name +* @param branch Default branch name (e.g. main or master) +* @returns The manifest object +*/ +async function getRepoManifest(user: string, repo: string, branch: string) { + 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 contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") +* @param branch The repo's default branch (e.g. main or master) +* @param stars The number of stars the repo has +* @returns Extension info for card (or null) +*/ +export async function fetchExtensionManifestFromTopic(contents_url: string, branch: string, stars: number, hideInstalled = false) { + 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\/(?.+)\/(?.+)\/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: CardItem[] = 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 (!(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 contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") +* @param branch The repo's default branch (e.g. main or master) +* @param stars The number of stars the repo has +* @returns Extension info for card (or null) +*/ +export async function fetchThemeManifestFromTopic(contents_url: string, branch: string, stars: number) { + try { + let manifests; + const regex_result = contents_url.match(/https:\/\/api\.github\.com\/repos\/(?.+)\/(?.+)\/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: ThemeCardItem[] = manifests.reduce((accum, manifest) => { + const parsedManifests: CardItem[] = 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?.name && manifest?.usercss && manifest?.description) { + accum.push(item); + } + return accum; + }, []); + return parsedManifests; + } + catch (err) { + // console.warn(contents_url, err); + return null; + } +} + +/** +* Fetch custom apps from a repo and format data for generating cards +* @param contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") +* @param branch The repo's default branch (e.g. main or master) +* @param stars The number of stars the repo has +* @returns Extension info for card (or null) +*/ +export async function fetchAppManifest(contents_url: string, branch: string, stars: number) { + 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\/(?.+)\/(?.+)\/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: CardItem[] = manifests.reduce((accum, manifest) => { + const selectedBranch = manifest.branch || branch; + // TODO: tweak saved items + 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}`, + // Custom Apps don't have an entry point; they're just listed so they can link out from the card + // 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) { + accum.push(item); + } + // else { + // console.error("Invalid manifest:", manifest); + // } + + return accum; + }, []); + + return parsedManifests; + } + catch (err) { + // console.warn(contents_url, err); + return null; + } +} + + diff --git a/src/types/marketplace-types.d.ts b/src/types/marketplace-types.d.ts index ba916b24..04d70b07 100644 --- a/src/types/marketplace-types.d.ts +++ b/src/types/marketplace-types.d.ts @@ -72,6 +72,7 @@ export type Manifest = { usercss?: string; // URL for usercss schemes?: string; // URL for schemes include?: string[]; + lastUpdated: undefined; }; // From fetchExtensionManifest @@ -122,6 +123,7 @@ export type VisualConfig = { // 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: boolean; + githubTopics: boolean; } // example colour scheme From 316ba7420aa57f1464c5cf26e0506e46edeba876 Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 14:08:07 -0400 Subject: [PATCH 10/48] Resolve linting errors --- src/extensions/extension.tsx | 32 ++++++++++++++++---------------- src/logic/FetchRemotes.ts | 4 ++-- src/logic/FetchTopicRemotes.ts | 9 +++------ 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index 0f5c22aa..28174462 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -24,7 +24,7 @@ import { } from "../logic/FetchRemotes"; import { fetchThemeManifestFromTopic, - fetchExtensionManifestFromTopic + fetchExtensionManifestFromTopic, } from "../logic/FetchTopicRemotes"; (async () => { @@ -200,26 +200,26 @@ async function loadPageRecursive(type: RepoType, pageNum: number) { // The recursion isn't super clean... // TODO: re-enable this once everything works with mono-manifest... - await Promise.all([ - loadPageRecursive("extension", 1), - loadPageRecursive("theme", 1), - ]); + await Promise.all([ + loadPageRecursive("extension", 1), + loadPageRecursive("theme", 1), + ]); })(); async function appendInformationToLocalStorage(array, type: RepoType) { // This system should make it so themes and extensions are stored concurrently for (const repo of array.items) { - if(LOCALSTORAGE_KEYS.githubTopics){ - for (const repo of array.items) { - // console.log(repo); - const data = (type === "theme") - ? await fetchThemeManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count) - : await fetchExtensionManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count); - if (data) { - addToSessionStorage(data); - await sleep(5000); - } - } + if (LOCALSTORAGE_KEYS.githubTopics) { + for (const repo of array.items) { + // console.log(repo); + const data = (type === "theme") + ? await fetchThemeManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count) + : await fetchExtensionManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count); + if (data) { + addToSessionStorage(data); + await sleep(5000); + } + } } const data = (type === "theme") ? await buildThemeCardData(repo.contents_url, repo.default_branch, repo.stargazers_count) diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index baa6c26b..905e5084 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -181,7 +181,7 @@ export async function buildThemeCardData(manifest: Manifest) { ) : undefined, include: manifest.include, - lastUpdated : "" + lastUpdated: "", }; return parsedManifest; @@ -228,7 +228,7 @@ export async function buildAppCardData(manifest: Manifest) { : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`, stars: 0, // TODO: get stars working tags: manifest.tags || [], - lastUpdated: "" + lastUpdated: "", }; return parsedManifest; diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index 74e3a33f..09c4d6c9 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -1,9 +1,7 @@ -import { CardItem, Snippet } from "../types/marketplace-types"; -import { processAuthors, addToSessionStorage } from "./Utils"; -import { ITEMS_PER_REQUEST, BLACKLIST_URL } from "../constants"; -import { RepoTopic } from "../types/marketplace-types"; -import snippetsJSON from "../../resources/snippets"; +import { processAuthors, addToSessionStorage } from "./Utils"; +import { CardItem, RepoTopic } from "../types/marketplace-types"; +import { ITEMS_PER_REQUEST } from "../constants"; // 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 @@ -272,4 +270,3 @@ export async function fetchAppManifest(contents_url: string, branch: string, sta } } - From 41827f79778d80a267f5636fd6a08603adb01947 Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 15:01:03 -0400 Subject: [PATCH 11/48] Finish implementing optionality for themes --- src/app.tsx | 1 + src/components/Grid.tsx | 35 ++++++++++++++++++++++++++++------ src/extensions/extension.tsx | 18 ++++++++--------- src/logic/FetchTopicRemotes.ts | 7 ++----- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index 36bc2120..78c0c815 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -80,6 +80,7 @@ class App extends React.Component { // 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(getLocalStorageDataFromKey("marketplace:followers", false)), + githubTopics: JSON.parse(getLocalStorageDataFromKey("marketplace:githubTopics", false)), }, tabs, activeTab: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.activeTab, tabs[0]), diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 92bece13..a30add43 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -23,6 +23,7 @@ import Card from "./Card/Card"; import Button from "./Button"; import DownloadIcon from "./Icons/DownloadIcon"; import Changelog from "./Modals/Changelog"; +import { fetchThemeManifestFromTopic, fetchExtensionManifestFromTopic, getTaggedReposFromTopic } from "../logic/FetchTopicRemotes"; export default class Grid extends React.Component< { @@ -181,7 +182,13 @@ export default class Grid extends React.Component< async loadPage(queue: never[], query?: string) { switch (this.CONFIG.activeTab) { case "Extensions": { - const pageOfRepos = await getTaggedRepos("spicetify-extensions", this.requestPage, this.BLACKLIST, query); + let pageOfRepos; + if (this.CONFIG.visual.githubTopics) { + pageOfRepos = await getTaggedReposFromTopic("spicetify-extensions", this.requestPage, this.BLACKLIST, query); + } else { + pageOfRepos = await getTaggedRepos("spicetify-extensions", this.requestPage, this.BLACKLIST, query); + } + for (const repo of pageOfRepos.items) { const extensions = await fetchExtensionManifest( repo.contents_url, @@ -200,6 +207,7 @@ export default class Grid extends React.Component< // console.log(`${repo.name} has ${extensions.length} extensions:`, extensions); extensions.forEach((extension) => { Object.assign(extension, { lastUpdated: repo.pushed_at }); + console.log(extension); this.appendCard(extension, "extension"); }); } @@ -243,11 +251,22 @@ export default class Grid extends React.Component< // Don't need to return a page number because // installed extension do them all in one go, since it's local } case "Themes": { - const allThemes = await getThemesMonoManifest(); - console.log(allThemes); + let allThemes; + if (this.CONFIG.visual.githubTopics) { + const topicResponse = await getTaggedReposFromTopic("spicetify-themes", this.requestPage, this.BLACKLIST, query); + allThemes= topicResponse.items; + } else { + allThemes = await getThemesMonoManifest(); + } for (const theme of allThemes) { - const cardData = await buildThemeCardData(theme); + let cardData; + + if (this.CONFIG.visual.githubTopics) { + cardData = await fetchThemeManifestFromTopic(theme.contents_url, theme.default_branch, theme.stargazers_count); + } else { + cardData = await buildThemeCardData(theme); + } // TODO: do we need this queue stuff any more? // I believe this stops the requests when switching tabs? @@ -256,10 +275,14 @@ export default class Grid extends React.Component< return -1; } - if (cardData) this.appendCard(cardData, "theme"); + if (cardData && !this.CONFIG.visual.githubTopics) this.appendCard(cardData, "theme"); + if (cardData && this.CONFIG.visual.githubTopics) { + Object.assign(cardData[0], { lastUpdated: theme.pushed_at }); + this.appendCard(cardData[0], "extension"); + } } - console.log("Parsed themes"); + break; } case "Apps": { const allApps = await getAppsMonoManifest(); diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index 28174462..48f90dbf 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -175,13 +175,11 @@ async function queryRepos(type: RepoType, pageNum = 1) { */ async function loadPageRecursive(type: RepoType, pageNum: number) { const pageOfRepos = await queryRepos(type, pageNum); - console.log(pageOfRepos); // TODO: Once we migrate to the mono-manifest repo, implement the option for enabling topics search here appendInformationToLocalStorage(pageOfRepos, type); // Sets the amount of items that have thus been fetched const soFarResults = ITEMS_PER_REQUEST * (pageNum - 1) + pageOfRepos.page_count; - console.log({ pageOfRepos }); const remainingResults = pageOfRepos.total_count - soFarResults; // If still have more results, recursively fetch next page @@ -220,13 +218,15 @@ async function appendInformationToLocalStorage(array, type: RepoType) { await sleep(5000); } } + } else { + const data = (type === "theme") + ? await buildThemeCardData(repo.contents_url, repo.default_branch, repo.stargazers_count) + : await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); + if (data) { + addToSessionStorage(data); + await sleep(5000); + } } - const data = (type === "theme") - ? await buildThemeCardData(repo.contents_url, repo.default_branch, repo.stargazers_count) - : await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); - if (data) { - addToSessionStorage(data); - await sleep(5000); - } + } } diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index 09c4d6c9..eb5aaa8b 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -13,7 +13,7 @@ import { ITEMS_PER_REQUEST } from "../constants"; * @param page The query page number * @returns Array of search results (filtered through the blacklist) */ -export async function getTaggedRepos(tag: RepoTopic, page = 1, BLACKLIST:string[] = [], query?: string) { +export async function getTaggedReposFromTopic(tag: RepoTopic, page = 1, BLACKLIST:string[] = [], query?: string) { // www is needed or it will block with "cross-origin" error. let url = query ? `https://api.github.com/search/repositories?q=${encodeURIComponent(`${query}+topic:${tag}`)}&per_page=${ITEMS_PER_REQUEST}` @@ -62,7 +62,6 @@ async function getRepoManifest(user: string, repo: string, branch: string) { () => addToSessionStorage([url], "noManifests"), ); if (manifest) window.sessionStorage.setItem(`${user}-${repo}`, JSON.stringify(manifest)); - return manifest; } @@ -151,9 +150,7 @@ export async function fetchThemeManifestFromTopic(contents_url: string, branch: // 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]; @@ -198,7 +195,7 @@ export async function fetchThemeManifestFromTopic(contents_url: string, branch: return parsedManifests; } catch (err) { - // console.warn(contents_url, err); + console.warn(contents_url, err); return null; } } From f5c90e801be8e1d16926c8b621702b15d4b233eb Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 16:56:31 -0400 Subject: [PATCH 12/48] Change card type --- src/components/Grid.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index a30add43..ca471202 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -207,7 +207,6 @@ export default class Grid extends React.Component< // console.log(`${repo.name} has ${extensions.length} extensions:`, extensions); extensions.forEach((extension) => { Object.assign(extension, { lastUpdated: repo.pushed_at }); - console.log(extension); this.appendCard(extension, "extension"); }); } @@ -278,7 +277,7 @@ export default class Grid extends React.Component< if (cardData && !this.CONFIG.visual.githubTopics) this.appendCard(cardData, "theme"); if (cardData && this.CONFIG.visual.githubTopics) { Object.assign(cardData[0], { lastUpdated: theme.pushed_at }); - this.appendCard(cardData[0], "extension"); + this.appendCard(cardData[0], "theme"); } } console.log("Parsed themes"); @@ -286,7 +285,6 @@ export default class Grid extends React.Component< break; } case "Apps": { const allApps = await getAppsMonoManifest(); - console.log(allApps); for (const app of allApps) { const cardData = await buildAppCardData(app); From 96d65df827c220d2d017dfdbb641b4226b20aed4 Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 17:00:31 -0400 Subject: [PATCH 13/48] Add logic to check if enabled before calling loadPageRecursive() --- src/extensions/extension.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index 48f90dbf..53ca7818 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -198,10 +198,13 @@ async function loadPageRecursive(type: RepoType, pageNum: number) { // The recursion isn't super clean... // TODO: re-enable this once everything works with mono-manifest... - await Promise.all([ - loadPageRecursive("extension", 1), - loadPageRecursive("theme", 1), - ]); + if (LOCALSTORAGE_KEYS.githubTopics) { + await Promise.all([ + loadPageRecursive("extension", 1), + loadPageRecursive("theme", 1), + ]); + } + })(); async function appendInformationToLocalStorage(array, type: RepoType) { From d8565c65598e1ee44d2001b241576d272dda5fba Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 17:06:58 -0400 Subject: [PATCH 14/48] Fill in documentation links --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5c72a669..fd67a656 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ All types of contributions are encouraged and valued. See the [Table of Contents ## I Have a Question -> If you want to ask a question, we assume that you have read the available [Documentation](). +> If you want to ask a question, we assume that you have read the available [Documentation](https://github.com/spicetify/spicetify-marketplace/wiki). Before you ask a question, it is best to search for existing [Issues](https://github.com/spicetify/spicetify-marketplaceissues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. @@ -68,7 +68,7 @@ Depending on how large the project is, you may want to outsource the questioning A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. - Make sure that you are using the latest version. -- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](). If you are looking for support, you might want to check [this section](#i-have-a-question)). +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://github.com/spicetify/spicetify-marketplace/wiki). If you are looking for support, you might want to check [this section](#i-have-a-question)). - To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/spicetify/spicetify-marketplaceissues?q=label%3Abug). - Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. - Collect information about the bug: @@ -108,7 +108,7 @@ This section guides you through submitting an enhancement suggestion for Spiceti #### Before Submitting an Enhancement - Make sure that you are using the latest version. -- Read the [documentation]() carefully and find out if the functionality is already covered, maybe by an individual configuration. +- Read the [documentation](https://github.com/spicetify/spicetify-marketplace/wiki) carefully and find out if the functionality is already covered, maybe by an individual configuration. - Perform a [search](https://github.com/spicetify/spicetify-marketplaceissues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. - Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. From f0a6acd2991e7c81ccb96ba0e023dda616fcbdf6 Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 17:11:33 -0400 Subject: [PATCH 15/48] Remove unnecessary conditional --- src/extensions/extension.tsx | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index 53ca7818..1b102e8d 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -210,26 +210,14 @@ async function loadPageRecursive(type: RepoType, pageNum: number) { async function appendInformationToLocalStorage(array, type: RepoType) { // This system should make it so themes and extensions are stored concurrently for (const repo of array.items) { - if (LOCALSTORAGE_KEYS.githubTopics) { - for (const repo of array.items) { - // console.log(repo); - const data = (type === "theme") - ? await fetchThemeManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count) - : await fetchExtensionManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count); - if (data) { - addToSessionStorage(data); - await sleep(5000); - } - } - } else { - const data = (type === "theme") - ? await buildThemeCardData(repo.contents_url, repo.default_branch, repo.stargazers_count) - : await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); - if (data) { - addToSessionStorage(data); - await sleep(5000); - } + // console.log(repo); + const data = (type === "theme") + ? await fetchThemeManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count) + : await fetchExtensionManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count); + if (data) { + addToSessionStorage(data); + await sleep(5000); } - } + } From 86e5c7a8e49a0549ca29691ca96d7908c8aa3c3a Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 17:12:06 -0400 Subject: [PATCH 16/48] Remove unnecessary imports --- src/extensions/extension.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index 1b102e8d..b1206830 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -19,8 +19,6 @@ import { } from "../logic/Utils"; import { fetchBlacklist, - buildThemeCardData, - fetchExtensionManifest, } from "../logic/FetchRemotes"; import { fetchThemeManifestFromTopic, From be885d438d628e97edd2e788737e4b4ac1359f62 Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Sat, 25 Jun 2022 17:48:53 -0400 Subject: [PATCH 17/48] Patch multimanifest support --- src/components/Grid.tsx | 9 ++++++--- src/extensions/extension.tsx | 2 +- src/logic/FetchTopicRemotes.ts | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index ca471202..d9aca447 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -186,6 +186,7 @@ export default class Grid extends React.Component< if (this.CONFIG.visual.githubTopics) { pageOfRepos = await getTaggedReposFromTopic("spicetify-extensions", this.requestPage, this.BLACKLIST, query); } else { + // Do whatever you need to here for the monomanifest system pageOfRepos = await getTaggedRepos("spicetify-extensions", this.requestPage, this.BLACKLIST, query); } @@ -260,7 +261,6 @@ export default class Grid extends React.Component< for (const theme of allThemes) { let cardData; - if (this.CONFIG.visual.githubTopics) { cardData = await fetchThemeManifestFromTopic(theme.contents_url, theme.default_branch, theme.stargazers_count); } else { @@ -276,8 +276,11 @@ export default class Grid extends React.Component< if (cardData && !this.CONFIG.visual.githubTopics) this.appendCard(cardData, "theme"); if (cardData && this.CONFIG.visual.githubTopics) { - Object.assign(cardData[0], { lastUpdated: theme.pushed_at }); - this.appendCard(cardData[0], "theme"); + for (const item of cardData) { + + Object.assign(item, { lastUpdated: theme.pushed_at }); + this.appendCard(item, "theme"); + } } } console.log("Parsed themes"); diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index b1206830..e4024996 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -208,7 +208,7 @@ async function loadPageRecursive(type: RepoType, pageNum: number) { async function appendInformationToLocalStorage(array, type: RepoType) { // This system should make it so themes and extensions are stored concurrently for (const repo of array.items) { - // console.log(repo); + console.log(repo); const data = (type === "theme") ? await fetchThemeManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count) : await fetchExtensionManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count); diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index eb5aaa8b..9a736beb 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -195,7 +195,7 @@ export async function fetchThemeManifestFromTopic(contents_url: string, branch: return parsedManifests; } catch (err) { - console.warn(contents_url, err); + //console.warn(contents_url, err); return null; } } From 451e2f25f4dbd094387dbcb68f8c779a00e5ea0f Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sun, 26 Jun 2022 15:40:34 -0400 Subject: [PATCH 18/48] =?UTF-8?q?=F0=9F=94=A5=20=E2=99=BB=EF=B8=8F=20Remov?= =?UTF-8?q?e=20some=20duplicated=20code=20and=20do=20some=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Grid.tsx | 39 +++++----- src/extensions/extension.tsx | 8 +- src/logic/FetchRemotes.ts | 134 +-------------------------------- src/logic/FetchTopicRemotes.ts | 9 ++- 4 files changed, 33 insertions(+), 157 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index d9aca447..8607cc0d 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -6,13 +6,6 @@ import { CardItem, CardType, Config, SchemeIni, Snippet, TabItemConfig } from ". import { getLocalStorageDataFromKey, generateSchemesOptions, injectColourScheme } from "../logic/Utils"; import { LOCALSTORAGE_KEYS, ITEMS_PER_REQUEST, MARKETPLACE_VERSION, LATEST_RELEASE } from "../constants"; import { openModal } from "../logic/LaunchModals"; -import { - getTaggedRepos, - fetchExtensionManifest, - fetchCssSnippets, fetchBlacklist, - getThemesMonoManifest, buildThemeCardData, - getAppsMonoManifest, buildAppCardData, -} from "../logic/FetchRemotes"; import LoadMoreIcon from "./Icons/LoadMoreIcon"; import LoadingIcon from "./Icons/LoadingIcon"; import SettingsIcon from "./Icons/SettingsIcon"; @@ -23,7 +16,16 @@ import Card from "./Card/Card"; import Button from "./Button"; import DownloadIcon from "./Icons/DownloadIcon"; import Changelog from "./Modals/Changelog"; -import { fetchThemeManifestFromTopic, fetchExtensionManifestFromTopic, getTaggedReposFromTopic } from "../logic/FetchTopicRemotes"; +import { + fetchCssSnippets, fetchBlacklist, + getThemesMonoManifest, buildThemeCardData, + getAppsMonoManifest, buildAppCardData, +} from "../logic/FetchRemotes"; +import { + getTaggedRepos, + fetchExtensionManifest, + fetchThemeManifest, +} from "../logic/FetchTopicRemotes"; export default class Grid extends React.Component< { @@ -184,9 +186,10 @@ export default class Grid extends React.Component< case "Extensions": { let pageOfRepos; if (this.CONFIG.visual.githubTopics) { - pageOfRepos = await getTaggedReposFromTopic("spicetify-extensions", this.requestPage, this.BLACKLIST, query); + pageOfRepos = await getTaggedRepos("spicetify-extensions", this.requestPage, this.BLACKLIST, query); } else { // Do whatever you need to here for the monomanifest system + // Whoch should be nothing, since it won't have to load multiple pages... pageOfRepos = await getTaggedRepos("spicetify-extensions", this.requestPage, this.BLACKLIST, query); } @@ -253,7 +256,7 @@ export default class Grid extends React.Component< } case "Themes": { let allThemes; if (this.CONFIG.visual.githubTopics) { - const topicResponse = await getTaggedReposFromTopic("spicetify-themes", this.requestPage, this.BLACKLIST, query); + const topicResponse = await getTaggedRepos("spicetify-themes", this.requestPage, this.BLACKLIST, query); allThemes= topicResponse.items; } else { allThemes = await getThemesMonoManifest(); @@ -262,7 +265,7 @@ export default class Grid extends React.Component< for (const theme of allThemes) { let cardData; if (this.CONFIG.visual.githubTopics) { - cardData = await fetchThemeManifestFromTopic(theme.contents_url, theme.default_branch, theme.stargazers_count); + cardData = await fetchThemeManifest(theme.contents_url, theme.default_branch, theme.stargazers_count); } else { cardData = await buildThemeCardData(theme); } @@ -274,12 +277,14 @@ export default class Grid extends React.Component< return -1; } - if (cardData && !this.CONFIG.visual.githubTopics) this.appendCard(cardData, "theme"); - if (cardData && this.CONFIG.visual.githubTopics) { - for (const item of cardData) { - - Object.assign(item, { lastUpdated: theme.pushed_at }); - this.appendCard(item, "theme"); + if (cardData) { + if (this.CONFIG.visual.githubTopics) { + for (const item of cardData) { + Object.assign(item, { lastUpdated: theme.pushed_at }); + this.appendCard(item, "theme"); + } + } else { + this.appendCard(cardData, "theme"); } } } diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index e4024996..9594d402 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -21,8 +21,8 @@ import { fetchBlacklist, } from "../logic/FetchRemotes"; import { - fetchThemeManifestFromTopic, - fetchExtensionManifestFromTopic, + fetchThemeManifest, + fetchExtensionManifest, } from "../logic/FetchTopicRemotes"; (async () => { @@ -210,8 +210,8 @@ async function appendInformationToLocalStorage(array, type: RepoType) { for (const repo of array.items) { console.log(repo); const data = (type === "theme") - ? await fetchThemeManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count) - : await fetchExtensionManifestFromTopic(repo.contents_url, repo.default_branch, repo.stargazers_count); + ? await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count) + : await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); if (data) { addToSessionStorage(data); await sleep(5000); diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 905e5084..bdb78754 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -1,7 +1,6 @@ import { CardItem, Manifest, Snippet } from "../types/marketplace-types"; -import { processAuthors, addToSessionStorage } from "./Utils"; -import { ITEMS_PER_REQUEST, BLACKLIST_URL, THEMES_URL } from "../constants"; -import { RepoTopic } from "../types/marketplace-types"; +import { processAuthors } from "./Utils"; +import { BLACKLIST_URL, THEMES_URL } from "../constants"; import snippetsJSON from "../../resources/snippets"; import appsManifest from "../../resources/manifests/apps"; @@ -9,135 +8,6 @@ import appsManifest from "../../resources/manifests/apps"; // 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 requested topic - * @param tag The tag ("topic") to search for - * @param page The query page number - * @returns Array of search results (filtered through the blacklist) - */ -export async function getTaggedRepos(tag: RepoTopic, page = 1, BLACKLIST:string[] = [], query?: string) { - // www is needed or it will block with "cross-origin" error. - let url = query - ? `https://api.github.com/search/repositories?q=${encodeURIComponent(`${query}+topic:${tag}`)}&per_page=${ITEMS_PER_REQUEST}` - : `https://api.github.com/search/repositories?q=${encodeURIComponent(`topic:${tag}`)}&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."); - return; - } - 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 user Owner username -* @param repo Repo name -* @param branch Default branch name (e.g. main or master) -* @returns The manifest object -*/ -async function getRepoManifest(user: string, repo: string, branch: string) { - 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 contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") -* @param branch The repo's default branch (e.g. main or master) -* @param stars The number of stars the repo has -* @returns Extension info for card (or null) -*/ -export async function fetchExtensionManifest(contents_url: string, branch: string, stars: number, hideInstalled = false) { - 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\/(?.+)\/(?.+)\/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: CardItem[] = 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 (!(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? // TODO: Update these docs /** diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index 9a736beb..847887a6 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -13,7 +13,7 @@ import { ITEMS_PER_REQUEST } from "../constants"; * @param page The query page number * @returns Array of search results (filtered through the blacklist) */ -export async function getTaggedReposFromTopic(tag: RepoTopic, page = 1, BLACKLIST:string[] = [], query?: string) { +export async function getTaggedRepos(tag: RepoTopic, page = 1, BLACKLIST:string[] = [], query?: string) { // www is needed or it will block with "cross-origin" error. let url = query ? `https://api.github.com/search/repositories?q=${encodeURIComponent(`${query}+topic:${tag}`)}&per_page=${ITEMS_PER_REQUEST}` @@ -50,7 +50,7 @@ export async function getTaggedReposFromTopic(tag: RepoTopic, page = 1, BLACKLIS * @param branch Default branch name (e.g. main or master) * @returns The manifest object */ -async function getRepoManifest(user: string, repo: string, branch: string) { +export async function getRepoManifest(user: string, repo: string, branch: string) { const sessionStorageItem = window.sessionStorage.getItem(`${user}-${repo}`); const failedSessionStorageItems = window.sessionStorage.getItem("noManifests"); if (sessionStorageItem) return JSON.parse(sessionStorageItem); @@ -62,6 +62,7 @@ async function getRepoManifest(user: string, repo: string, branch: string) { () => addToSessionStorage([url], "noManifests"), ); if (manifest) window.sessionStorage.setItem(`${user}-${repo}`, JSON.stringify(manifest)); + return manifest; } @@ -73,7 +74,7 @@ async function getRepoManifest(user: string, repo: string, branch: string) { * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function fetchExtensionManifestFromTopic(contents_url: string, branch: string, stars: number, hideInstalled = false) { +export async function fetchExtensionManifest(contents_url: string, branch: string, stars: number, hideInstalled = false) { try { // TODO: use the original search full_name ("theRealPadster/spicetify-hide-podcasts") or something to get the url better? let manifests; @@ -143,7 +144,7 @@ export async function fetchExtensionManifestFromTopic(contents_url: string, bran * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function fetchThemeManifestFromTopic(contents_url: string, branch: string, stars: number) { +export async function fetchThemeManifest(contents_url: string, branch: string, stars: number) { try { let manifests; const regex_result = contents_url.match(/https:\/\/api\.github\.com\/repos\/(?.+)\/(?.+)\/contents/); From f0573d12c3dc0914207c24a82d96965540a78b3f Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sun, 26 Jun 2022 15:57:00 -0400 Subject: [PATCH 19/48] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Use=20`buildThemeCar?= =?UTF-8?q?dData`=20for=20topic=20and=20mono-manifest=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Grid.tsx | 2 +- src/logic/FetchRemotes.ts | 21 +++++++++-------- src/logic/FetchTopicRemotes.ts | 42 +++++++++------------------------- 3 files changed, 24 insertions(+), 41 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 8607cc0d..e9a18760 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -267,7 +267,7 @@ export default class Grid extends React.Component< if (this.CONFIG.visual.githubTopics) { cardData = await fetchThemeManifest(theme.contents_url, theme.default_branch, theme.stargazers_count); } else { - cardData = await buildThemeCardData(theme); + cardData = buildThemeCardData(theme); } // TODO: do we need this queue stuff any more? diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index bdb78754..95d83b1f 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -17,37 +17,40 @@ import appsManifest from "../../resources/manifests/apps"; * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function buildThemeCardData(manifest: Manifest) { +// The optional params are only used when using github topics +export function buildThemeCardData(manifest: Manifest, user?: string, repo?: string, branch?: string, stars?: number) { try { // TODO: figure this out... - const [ user, repo, selectedBranch ] = ["spicetify", "spicetify-themes", "generated-manifest"]; + if (!user) user = "spicetify"; + if (!repo) repo = "spicetify-themes"; + if (!branch) branch = "generated-manifest"; // Manifest is initially parsed const parsedManifest: CardItem = { manifest, title: manifest.name, subtitle: manifest.description, - authors: processAuthors(manifest.authors, "user..."), // TODO: do we need a fallback? + authors: processAuthors(manifest.authors, user === "spicetify" ? "user..." : user), // TODO: we need a fallback... // TODO: do we need these? user, repo, - branch: selectedBranch, + branch, imageURL: manifest.preview && manifest.preview.startsWith("http") ? manifest.preview - : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.preview}`, + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.preview}`, readmeURL: manifest.readme && manifest.readme.startsWith("http") ? manifest.readme - : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`, - stars: 0, // TODO: get stars working + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.readme}`, + stars: stars ?? 0, // TODO: get stars working tags: manifest.tags || [], // theme stuff cssURL: manifest.usercss?.startsWith("http") ? manifest.usercss - : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.usercss}`, + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${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}` + manifest.schemes.startsWith("http") ? manifest.schemes : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.schemes}` ) : undefined, include: manifest.include, diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index 847887a6..dfd21c34 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -2,6 +2,7 @@ import { processAuthors, addToSessionStorage } from "./Utils"; import { CardItem, RepoTopic } from "../types/marketplace-types"; import { ITEMS_PER_REQUEST } from "../constants"; +import { buildThemeCardData } from "./FetchRemotes"; // 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 @@ -74,7 +75,12 @@ export async function getRepoManifest(user: string, repo: string, branch: string * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function fetchExtensionManifest(contents_url: string, branch: string, stars: number, hideInstalled = false) { +export async function fetchExtensionManifest( + contents_url: string, + branch: string, + stars: number, + hideInstalled = false, +) { try { // TODO: use the original search full_name ("theRealPadster/spicetify-hide-podcasts") or something to get the url better? let manifests; @@ -156,41 +162,15 @@ export async function fetchThemeManifest(contents_url: string, branch: string, s if (!Array.isArray(manifests)) manifests = [manifests]; // Manifest is initially parsed - // const parsedManifests: ThemeCardItem[] = manifests.reduce((accum, manifest) => { const parsedManifests: CardItem[] = 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?.name && manifest?.usercss && manifest?.description) { - accum.push(item); + const item = buildThemeCardData(manifest, user, repo, selectedBranch, stars); + if (item) accum.push(item); } + return accum; }, []); return parsedManifests; From 7cb545a95e406071cd03caef61375ffbbfcda370 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sun, 26 Jun 2022 16:04:11 -0400 Subject: [PATCH 20/48] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Code=20deduplication?= =?UTF-8?q?=20for=20`buildAppCardData`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Grid.tsx | 2 +- src/logic/FetchRemotes.ts | 20 +++++++++++--------- src/logic/FetchTopicRemotes.ts | 32 ++++---------------------------- 3 files changed, 16 insertions(+), 38 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index e9a18760..a00a0666 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -295,7 +295,7 @@ export default class Grid extends React.Component< const allApps = await getAppsMonoManifest(); for (const app of allApps) { - const cardData = await buildAppCardData(app); + const cardData = buildAppCardData(app); // TODO: do we need this queue stuff any more? // I believe this stops the requests when switching tabs? diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 95d83b1f..e10939a4 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -73,33 +73,35 @@ export function buildThemeCardData(manifest: Manifest, user?: string, repo?: str * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ -export async function buildAppCardData(manifest: Manifest) { +// The optional params are only used when using github topics +export function buildAppCardData(manifest: Manifest, user?: string, repo?: string, branch?: string, stars?: number) { try { // TODO: figure this out... // TODO: Update these once we get a repo for apps - const [ user, repo, selectedBranch ] = ["spicetify", "spicetify-themes", "generated-manifest"]; + if (!user) user = "spicetify"; + if (!repo) repo = "spicetify-themes"; + if (!branch) branch = "generated-manifest"; // Manifest is initially parsed const parsedManifest: CardItem = { manifest, title: manifest.name, subtitle: manifest.description, - authors: processAuthors(manifest.authors, "user..."), // TODO: do we need a fallback? + authors: processAuthors(manifest.authors, user === "spicetify" ? "user..." : user), // TODO: we need a fallback... user, repo, - branch: selectedBranch, - + branch, imageURL: manifest.preview && manifest.preview.startsWith("http") ? manifest.preview - : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.preview}`, + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.preview}`, // Custom Apps don't have an entry point; they're just listed so they can link out from the card // extensionURL: manifest.main.startsWith("http") // ? manifest.main - // : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.main}`, + // : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.main}`, readmeURL: manifest.readme && manifest.readme.startsWith("http") ? manifest.readme - : `https://raw.githubusercontent.com/${user}/${repo}/${selectedBranch}/${manifest.readme}`, - stars: 0, // TODO: get stars working + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.readme}`, + stars: stars ?? 0, // TODO: get stars working tags: manifest.tags || [], lastUpdated: "", }; diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index dfd21c34..03bec780 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -2,7 +2,7 @@ import { processAuthors, addToSessionStorage } from "./Utils"; import { CardItem, RepoTopic } from "../types/marketplace-types"; import { ITEMS_PER_REQUEST } from "../constants"; -import { buildThemeCardData } from "./FetchRemotes"; +import { buildThemeCardData, buildAppCardData } from "./FetchRemotes"; // 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 @@ -205,37 +205,13 @@ export async function fetchAppManifest(contents_url: string, branch: string, sta // Manifest is initially parsed const parsedManifests: CardItem[] = manifests.reduce((accum, manifest) => { const selectedBranch = manifest.branch || branch; - // TODO: tweak saved items - 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}`, - // Custom Apps don't have an entry point; they're just listed so they can link out from the card - // 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) { - accum.push(item); + // TODO: tweak saved items + const item = buildAppCardData(manifest, user, repo, selectedBranch, stars); + if (item) accum.push(item); } - // else { - // console.error("Invalid manifest:", manifest); - // } return accum; }, []); From 7cc8baeb88972b310b86663ec4a49217cfc5612b Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sun, 26 Jun 2022 16:11:06 -0400 Subject: [PATCH 21/48] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Consolidate=20getMon?= =?UTF-8?q?oManifest=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Grid.tsx | 12 +++++------- src/logic/FetchRemotes.ts | 21 +++++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index a00a0666..941de2d4 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -17,14 +17,12 @@ import Button from "./Button"; import DownloadIcon from "./Icons/DownloadIcon"; import Changelog from "./Modals/Changelog"; import { - fetchCssSnippets, fetchBlacklist, - getThemesMonoManifest, buildThemeCardData, - getAppsMonoManifest, buildAppCardData, + fetchBlacklist, fetchCssSnippets, fetchMonoManifest, + buildThemeCardData, buildAppCardData, } from "../logic/FetchRemotes"; import { getTaggedRepos, - fetchExtensionManifest, - fetchThemeManifest, + fetchExtensionManifest, fetchThemeManifest, } from "../logic/FetchTopicRemotes"; export default class Grid extends React.Component< @@ -259,7 +257,7 @@ export default class Grid extends React.Component< const topicResponse = await getTaggedRepos("spicetify-themes", this.requestPage, this.BLACKLIST, query); allThemes= topicResponse.items; } else { - allThemes = await getThemesMonoManifest(); + allThemes = await fetchMonoManifest("theme"); } for (const theme of allThemes) { @@ -292,7 +290,7 @@ export default class Grid extends React.Component< break; } case "Apps": { - const allApps = await getAppsMonoManifest(); + const allApps = await fetchMonoManifest("app"); for (const app of allApps) { const cardData = buildAppCardData(app); diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index e10939a4..4de17ff2 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -1,4 +1,4 @@ -import { CardItem, Manifest, Snippet } from "../types/marketplace-types"; +import { CardItem, Manifest, RepoType, Snippet } from "../types/marketplace-types"; import { processAuthors } from "./Utils"; import { BLACKLIST_URL, THEMES_URL } from "../constants"; import snippetsJSON from "../../resources/snippets"; @@ -114,15 +114,16 @@ export function buildAppCardData(manifest: Manifest, user?: string, repo?: strin } } -export const getThemesMonoManifest = async () => { - const manifest = await fetch(THEMES_URL).then(res => res.json()).catch(() => null); - return manifest; -}; - -export const getAppsMonoManifest = async () => { - // const manifest = await fetch(THEMES_URL).then(res => res.json()).catch(() => null); - const manifest = appsManifest; - return manifest; +export const fetchMonoManifest = async (type: RepoType) => { + // TODO: clean this up to use a lookup map or something... + if (type === "theme") { + const manifest = await fetch(THEMES_URL).then(res => res.json()).catch(() => null); + return manifest; + } else if (type === "app") { + // const manifest = await fetch(APPS_URL).then(res => res.json()).catch(() => null); + const manifest = appsManifest; + return manifest; + } }; /** From cf09e5437509346995ec3af57eae9c00fed2c068 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sun, 26 Jun 2022 16:22:02 -0400 Subject: [PATCH 22/48] Add `buildExtensionCardData` --- src/logic/FetchRemotes.ts | 54 ++++++++++++++++++++++++++++++++++ src/logic/FetchTopicRemotes.ts | 39 +++++------------------- 2 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 4de17ff2..70765644 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -65,6 +65,60 @@ export function buildThemeCardData(manifest: Manifest, user?: string, repo?: str } } +// TODO: can we add a return type here? +// TODO: Update these docs +/** +* Fetch extensions from a repo and format data for generating cards +* @param contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") +* @param branch The repo's default branch (e.g. main or master) +* @param stars The number of stars the repo has +* @returns Extension info for card (or null) +*/ +// The optional params are only used when using github topics +export async function buildExtensionCardData( + manifest: Manifest, + user?: string, + repo?: string, + branch?: string, + stars?: number, +) { + try { + // TODO: figure this out... + if (!user) user = "spicetify"; + if (!repo) repo = "spicetify-themes"; + if (!branch) branch = "generated-manifest"; + + // Manifest is initially parsed + const parsedManifest: CardItem = { + manifest, + title: manifest.name, + subtitle: manifest.description, + authors: processAuthors(manifest.authors, user === "spicetify" ? "user..." : user), // TODO: we need a fallback... + user, + repo, + branch, + imageURL: manifest.preview && manifest.preview.startsWith("http") + ? manifest.preview + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.preview}`, + extensionURL: manifest.main.startsWith("http") + ? manifest.main + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.main}`, + readmeURL: manifest.readme && manifest.readme.startsWith("http") + ? manifest.readme + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.readme}`, + stars: stars ?? 0, // TODO: get stars working + tags: manifest.tags || [], + lastUpdated: "", + }; + + return parsedManifest; + } + catch (err) { + // console.warn(contents_url, err); + return null; + } +} + // TODO: Update these docs /** * Fetch custom apps from a repo and format data for generating cards diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index 03bec780..12fa70a9 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -1,8 +1,8 @@ -import { processAuthors, addToSessionStorage } from "./Utils"; +import { addToSessionStorage } from "./Utils"; import { CardItem, RepoTopic } from "../types/marketplace-types"; import { ITEMS_PER_REQUEST } from "../constants"; -import { buildThemeCardData, buildAppCardData } from "./FetchRemotes"; +import { buildThemeCardData, buildExtensionCardData, buildAppCardData } from "./FetchRemotes"; // 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 @@ -79,7 +79,7 @@ export async function fetchExtensionManifest( contents_url: string, branch: string, stars: number, - hideInstalled = false, + hideInstalled = false, // TODO: we may want to add support for hideInstalled in the other tabs... ) { try { // TODO: use the original search full_name ("theRealPadster/spicetify-hide-podcasts") or something to get the url better? @@ -97,39 +97,17 @@ export async function fetchExtensionManifest( // Manifest is initially parsed const parsedManifests: CardItem[] = 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 - ) { + if (manifest && manifest.name && manifest.description && manifest.main) { // Add to list unless we're hiding installed items and it's installed if (!(hideInstalled && localStorage.getItem("marketplace:installed:" + `${user}/${repo}/${manifest.main}`)) - ) accum.push(item); + ) { + const item = buildExtensionCardData(manifest, user, repo, selectedBranch, stars); + if (item) accum.push(item); + } } - // else { - // console.error("Invalid manifest:", manifest); - // } return accum; }, []); @@ -223,4 +201,3 @@ export async function fetchAppManifest(contents_url: string, branch: string, sta return null; } } - From c186d6135361de0a7759b14550cfefb0de034eb7 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Sun, 26 Jun 2022 16:27:05 -0400 Subject: [PATCH 23/48] =?UTF-8?q?=F0=9F=9A=A7=20Add=20extension=20mono-man?= =?UTF-8?q?ifest=20handling=20(not=20implemented)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/manifests/extensions.ts | 5 +++++ src/logic/FetchRemotes.ts | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 resources/manifests/extensions.ts diff --git a/resources/manifests/extensions.ts b/resources/manifests/extensions.ts new file mode 100644 index 00000000..e11aa059 --- /dev/null +++ b/resources/manifests/extensions.ts @@ -0,0 +1,5 @@ +export default [ + { + // TODO: add something here to test + }, +]; diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 70765644..5658ba8a 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -2,7 +2,10 @@ import { CardItem, Manifest, RepoType, Snippet } from "../types/marketplace-type import { processAuthors } from "./Utils"; import { BLACKLIST_URL, THEMES_URL } from "../constants"; import snippetsJSON from "../../resources/snippets"; + +// TODO: Remove these once there are repos for them import appsManifest from "../../resources/manifests/apps"; +import extensionsManifest from "../../resources/manifests/extensions"; // 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 @@ -173,10 +176,16 @@ export const fetchMonoManifest = async (type: RepoType) => { if (type === "theme") { const manifest = await fetch(THEMES_URL).then(res => res.json()).catch(() => null); return manifest; + } else if (type === "extension") { + // const manifest = await fetch(EXTENSIONS_URL).then(res => res.json()).catch(() => null); + const manifest = extensionsManifest; + return manifest; } else if (type === "app") { // const manifest = await fetch(APPS_URL).then(res => res.json()).catch(() => null); const manifest = appsManifest; return manifest; + } else { + return []; } }; From aa0410182a31162d4057df420e58288943f083d5 Mon Sep 17 00:00:00 2001 From: CharlieS1103 Date: Tue, 28 Jun 2022 01:58:21 -0400 Subject: [PATCH 24/48] Normalize the marketplace controls colors --- src/styles/components/_devtools.scss | 2 +- src/styles/components/_dropdown.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/components/_devtools.scss b/src/styles/components/_devtools.scss index 25e8c083..44a40557 100644 --- a/src/styles/components/_devtools.scss +++ b/src/styles/components/_devtools.scss @@ -47,5 +47,5 @@ .devtools-icon { width: 18px; - fill: var(--spice-button) + fill: var(--spice-text) } diff --git a/src/styles/components/_dropdown.scss b/src/styles/components/_dropdown.scss index ec6cdc8a..f5434824 100644 --- a/src/styles/components/_dropdown.scss +++ b/src/styles/components/_dropdown.scss @@ -1,6 +1,6 @@ @use '../constants.scss'; -$dropdown-text: rgba(var(--spice-rgb-text), .7); +$dropdown-text: var(--spice-text); $dropdown-text-hover: rgb(var(--spice-rgb-text)); $dropdown-bg: var(--spice-sidebar); $dropdown-radius: constants.$btn-radius; From f0ce736989d04029c4ec65360a9cb0f6a1d180d4 Mon Sep 17 00:00:00 2001 From: Nam Anh Date: Tue, 28 Jun 2022 15:27:24 +0700 Subject: [PATCH 25/48] refactor(FetchRemotes): use lookups --- src/components/Grid.tsx | 6 +++--- src/logic/FetchRemotes.ts | 23 ++++++++--------------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 941de2d4..35259c55 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -261,7 +261,7 @@ export default class Grid extends React.Component< } for (const theme of allThemes) { - let cardData; + let cardData: CardItem | Snippet | CardItem[] | null; if (this.CONFIG.visual.githubTopics) { cardData = await fetchThemeManifest(theme.contents_url, theme.default_branch, theme.stargazers_count); } else { @@ -277,12 +277,12 @@ export default class Grid extends React.Component< if (cardData) { if (this.CONFIG.visual.githubTopics) { - for (const item of cardData) { + for (const item of cardData as CardItem[]) { Object.assign(item, { lastUpdated: theme.pushed_at }); this.appendCard(item, "theme"); } } else { - this.appendCard(cardData, "theme"); + this.appendCard(cardData as CardItem, "theme"); } } } diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 5658ba8a..1975f8cf 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -172,21 +172,14 @@ export function buildAppCardData(manifest: Manifest, user?: string, repo?: strin } export const fetchMonoManifest = async (type: RepoType) => { - // TODO: clean this up to use a lookup map or something... - if (type === "theme") { - const manifest = await fetch(THEMES_URL).then(res => res.json()).catch(() => null); - return manifest; - } else if (type === "extension") { - // const manifest = await fetch(EXTENSIONS_URL).then(res => res.json()).catch(() => null); - const manifest = extensionsManifest; - return manifest; - } else if (type === "app") { - // const manifest = await fetch(APPS_URL).then(res => res.json()).catch(() => null); - const manifest = appsManifest; - return manifest; - } else { - return []; - } + const manifest = { + theme: await fetch(THEMES_URL).then(res => res.json()).catch((err) => {console.error(err); return [];}), + // extension: await fetch(EXTENSIONS_URL).then(res => res.json()).catch(console.error(err); return [];), + extension: extensionsManifest as Manifest[], + // app: await fetch(APPS_URL).then(res => res.json()).catch(console.error(err); return [];), + app: appsManifest as Manifest[], + }; + return manifest[type] || []; }; /** From 798e6d4aacde152783bb4047957d1c76f4e9edcf Mon Sep 17 00:00:00 2001 From: Nam Anh Date: Tue, 28 Jun 2022 15:29:28 +0700 Subject: [PATCH 26/48] feat(Settings): add annotation --- src/components/Modals/Settings/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modals/Settings/index.tsx b/src/components/Modals/Settings/index.tsx index 3b21abf5..25c63931 100644 --- a/src/components/Modals/Settings/index.tsx +++ b/src/components/Modals/Settings/index.tsx @@ -46,7 +46,7 @@ const SettingsModal = ({ CONFIG, updateAppConfig } : Props) => { - +

Tabs

{modalConfig.tabs.map(({ name }, index) => { From c225f8055605816a2ea52a271d965bb2cfdb2f06 Mon Sep 17 00:00:00 2001 From: Nam Anh Date: Tue, 28 Jun 2022 16:16:22 +0700 Subject: [PATCH 27/48] feat(Grid): allow switching fetch method for Apps --- src/components/Grid.tsx | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 35259c55..c5c50004 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -22,7 +22,7 @@ import { } from "../logic/FetchRemotes"; import { getTaggedRepos, - fetchExtensionManifest, fetchThemeManifest, + fetchExtensionManifest, fetchThemeManifest, fetchAppManifest, } from "../logic/FetchTopicRemotes"; export default class Grid extends React.Component< @@ -287,13 +287,24 @@ export default class Grid extends React.Component< } } console.log("Parsed themes"); - break; } case "Apps": { - const allApps = await fetchMonoManifest("app"); + let allApps; + if (this.CONFIG.visual.githubTopics) { + const topicResponse = await getTaggedRepos("spicetify-apps", this.requestPage, this.BLACKLIST, query); + allApps = topicResponse.items; + } + else { + allApps = await fetchMonoManifest("app"); + } for (const app of allApps) { - const cardData = buildAppCardData(app); + let cardData; + if (this.CONFIG.visual.githubTopics) { + cardData = await fetchAppManifest(app.contents_url, app.default_branch, app.stargazers_count); + } else { + cardData = buildAppCardData(app); + } // TODO: do we need this queue stuff any more? // I believe this stops the requests when switching tabs? @@ -302,9 +313,17 @@ export default class Grid extends React.Component< return -1; } - if (cardData) this.appendCard(cardData, "app"); + if (cardData) { + if (this.CONFIG.visual.githubTopics) { + for (const item of cardData as CardItem[]) { + Object.assign(item, { lastUpdated: app.pushed_at }); + this.appendCard(item, "app"); + } + } else { + this.appendCard(cardData as CardItem, "app"); + } + } } - console.log("Parsed apps"); break; } case "Snippets": { From 15382411443218e2dac5ed4a658604e9f9f53c58 Mon Sep 17 00:00:00 2001 From: Nam Anh Date: Tue, 28 Jun 2022 16:45:56 +0700 Subject: [PATCH 28/48] refactor(Grid): merge duplicate functions --- src/components/Grid.tsx | 138 ++++++++++++---------------------------- 1 file changed, 41 insertions(+), 97 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index c5c50004..a6fbc05c 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -2,7 +2,7 @@ import React from "react"; import semver from "semver"; import { Option } from "react-dropdown"; -import { CardItem, CardType, Config, SchemeIni, Snippet, TabItemConfig } from "../types/marketplace-types"; +import { CardItem, CardType, Config, RepoTopic, RepoType, SchemeIni, Snippet, TabItemConfig } from "../types/marketplace-types"; import { getLocalStorageDataFromKey, generateSchemesOptions, injectColourScheme } from "../logic/Utils"; import { LOCALSTORAGE_KEYS, ITEMS_PER_REQUEST, MARKETPLACE_VERSION, LATEST_RELEASE } from "../constants"; import { openModal } from "../logic/LaunchModals"; @@ -18,7 +18,7 @@ import DownloadIcon from "./Icons/DownloadIcon"; import Changelog from "./Modals/Changelog"; import { fetchBlacklist, fetchCssSnippets, fetchMonoManifest, - buildThemeCardData, buildAppCardData, + buildThemeCardData, buildAppCardData, buildExtensionCardData, } from "../logic/FetchRemotes"; import { getTaggedRepos, @@ -181,51 +181,7 @@ export default class Grid extends React.Component< // TODO: maybe we should rename `loadPage()`, since it's slightly confusing when we have github pages as well async loadPage(queue: never[], query?: string) { switch (this.CONFIG.activeTab) { - case "Extensions": { - let pageOfRepos; - if (this.CONFIG.visual.githubTopics) { - pageOfRepos = await getTaggedRepos("spicetify-extensions", this.requestPage, this.BLACKLIST, query); - } else { - // Do whatever you need to here for the monomanifest system - // Whoch should be nothing, since it won't have to load multiple pages... - pageOfRepos = await getTaggedRepos("spicetify-extensions", this.requestPage, this.BLACKLIST, query); - } - - for (const repo of pageOfRepos.items) { - const extensions = await fetchExtensionManifest( - repo.contents_url, - repo.default_branch, - repo.stargazers_count, - this.CONFIG.visual.hideInstalled, - ); - - // I believe this stops the requests when switching tabs? - if (this.requestQueue.length > 1 && queue !== this.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) => { - Object.assign(extension, { lastUpdated: repo.pushed_at }); - this.appendCard(extension, "extension"); - }); - } - } - - // First result is null or -1 so it coerces to 1 - const currentPage = this.requestPage > -1 && this.requestPage ? this.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"); - break; - } case "Installed": { + case "Installed": { const installedStuff = { theme: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.installedThemes, []), extension: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.installedExtensions, []), @@ -251,59 +207,46 @@ export default class Grid extends React.Component< // Don't need to return a page number because // installed extension do them all in one go, since it's local - } case "Themes": { - let allThemes; + } case "Themes": + case "Extensions": + case "Apps": { + const type = this.CONFIG.activeTab.slice(0, -1).toLowerCase() as Omit; + let allRepos; if (this.CONFIG.visual.githubTopics) { - const topicResponse = await getTaggedRepos("spicetify-themes", this.requestPage, this.BLACKLIST, query); - allThemes= topicResponse.items; + const topicResponse = await getTaggedRepos(`spicetify-${type}s` as RepoTopic, this.requestPage, this.BLACKLIST, query); + allRepos = topicResponse.items; } else { - allThemes = await fetchMonoManifest("theme"); + allRepos = await fetchMonoManifest(type as RepoType); } - for (const theme of allThemes) { - let cardData: CardItem | Snippet | CardItem[] | null; - if (this.CONFIG.visual.githubTopics) { - cardData = await fetchThemeManifest(theme.contents_url, theme.default_branch, theme.stargazers_count); - } else { - cardData = buildThemeCardData(theme); - } - - // TODO: do we need this queue stuff any more? - // I believe this stops the requests when switching tabs? - if (this.requestQueue.length > 1 && queue !== this.requestQueue[0]) { - // Stop this queue from continuing to fetch and append to cards list - return -1; - } - - if (cardData) { - if (this.CONFIG.visual.githubTopics) { - for (const item of cardData as CardItem[]) { - Object.assign(item, { lastUpdated: theme.pushed_at }); - this.appendCard(item, "theme"); - } - } else { - this.appendCard(cardData as CardItem, "theme"); - } - } - } - console.log("Parsed themes"); - break; - } case "Apps": { - let allApps; - if (this.CONFIG.visual.githubTopics) { - const topicResponse = await getTaggedRepos("spicetify-apps", this.requestPage, this.BLACKLIST, query); - allApps = topicResponse.items; - } - else { - allApps = await fetchMonoManifest("app"); - } - - for (const app of allApps) { + for (const repo of allRepos) { let cardData; if (this.CONFIG.visual.githubTopics) { - cardData = await fetchAppManifest(app.contents_url, app.default_branch, app.stargazers_count); + switch (type) { + case "theme": + cardData = await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); + break; + case "extension": + cardData = await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); + break; + case "app": + cardData = await fetchAppManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); + break; + } } else { - cardData = buildAppCardData(app); + switch (type) { + case "theme": + cardData = buildThemeCardData(repo); + break; + case "extension": + cardData = buildExtensionCardData(repo); + break; + case "app": + cardData = buildAppCardData(repo); + break; + default: + throw new Error(`Unknown type: ${type}`); + } } // TODO: do we need this queue stuff any more? @@ -314,17 +257,18 @@ export default class Grid extends React.Component< } if (cardData) { + console.log(cardData); if (this.CONFIG.visual.githubTopics) { for (const item of cardData as CardItem[]) { - Object.assign(item, { lastUpdated: app.pushed_at }); - this.appendCard(item, "app"); + Object.assign(item, { lastUpdated: repo.pushed_at }); + this.appendCard(item, type as CardType); } } else { - this.appendCard(cardData as CardItem, "app"); + this.appendCard(cardData as CardItem, type as CardType); } } } - console.log("Parsed apps"); + console.log(`Parsed ${this.CONFIG.activeTab.toLowerCase()}`); break; } case "Snippets": { const snippets = await fetchCssSnippets(); From 337bb2554d6f8e3db823ea180594ff3f2aa926aa Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 28 Jun 2022 09:26:11 -0400 Subject: [PATCH 29/48] Make order of extension/theme/app functions consistent with tabs --- src/components/Grid.tsx | 2 +- src/logic/FetchRemotes.ts | 50 +++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index a6fbc05c..5dd138de 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -18,7 +18,7 @@ import DownloadIcon from "./Icons/DownloadIcon"; import Changelog from "./Modals/Changelog"; import { fetchBlacklist, fetchCssSnippets, fetchMonoManifest, - buildThemeCardData, buildAppCardData, buildExtensionCardData, + buildExtensionCardData, buildThemeCardData, buildAppCardData, } from "../logic/FetchRemotes"; import { getTaggedRepos, diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 1975f8cf..994dae97 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -14,14 +14,20 @@ import extensionsManifest from "../../resources/manifests/extensions"; // TODO: can we add a return type here? // TODO: Update these docs /** -* Fetch themes from a repo and format data for generating cards +* Fetch extensions from a repo and format data for generating cards * @param contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") * @param branch The repo's default branch (e.g. main or master) * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ // The optional params are only used when using github topics -export function buildThemeCardData(manifest: Manifest, user?: string, repo?: string, branch?: string, stars?: number) { +export async function buildExtensionCardData( + manifest: Manifest, + user?: string, + repo?: string, + branch?: string, + stars?: number, +) { try { // TODO: figure this out... if (!user) user = "spicetify"; @@ -34,29 +40,20 @@ export function buildThemeCardData(manifest: Manifest, user?: string, repo?: str title: manifest.name, subtitle: manifest.description, authors: processAuthors(manifest.authors, user === "spicetify" ? "user..." : user), // TODO: we need a fallback... - // TODO: do we need these? user, repo, branch, imageURL: manifest.preview && manifest.preview.startsWith("http") ? manifest.preview : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.preview}`, + extensionURL: manifest.main.startsWith("http") + ? manifest.main + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.main}`, readmeURL: manifest.readme && manifest.readme.startsWith("http") ? manifest.readme : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.readme}`, stars: stars ?? 0, // TODO: get stars working tags: manifest.tags || [], - // theme stuff - cssURL: manifest.usercss?.startsWith("http") - ? manifest.usercss - : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.usercss}`, - // TODO: clean up indentation etc - schemesURL: manifest.schemes - ? ( - manifest.schemes.startsWith("http") ? manifest.schemes : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.schemes}` - ) - : undefined, - include: manifest.include, lastUpdated: "", }; @@ -71,20 +68,14 @@ export function buildThemeCardData(manifest: Manifest, user?: string, repo?: str // TODO: can we add a return type here? // TODO: Update these docs /** -* Fetch extensions from a repo and format data for generating cards +* Fetch themes from a repo and format data for generating cards * @param contents_url The repo's GitHub API contents_url (e.g. "https://api.github.com/repos/theRealPadster/spicetify-hide-podcasts/contents/{+path}") * @param branch The repo's default branch (e.g. main or master) * @param stars The number of stars the repo has * @returns Extension info for card (or null) */ // The optional params are only used when using github topics -export async function buildExtensionCardData( - manifest: Manifest, - user?: string, - repo?: string, - branch?: string, - stars?: number, -) { +export function buildThemeCardData(manifest: Manifest, user?: string, repo?: string, branch?: string, stars?: number) { try { // TODO: figure this out... if (!user) user = "spicetify"; @@ -97,20 +88,29 @@ export async function buildExtensionCardData( title: manifest.name, subtitle: manifest.description, authors: processAuthors(manifest.authors, user === "spicetify" ? "user..." : user), // TODO: we need a fallback... + // TODO: do we need these? user, repo, branch, imageURL: manifest.preview && manifest.preview.startsWith("http") ? manifest.preview : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.preview}`, - extensionURL: manifest.main.startsWith("http") - ? manifest.main - : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.main}`, readmeURL: manifest.readme && manifest.readme.startsWith("http") ? manifest.readme : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.readme}`, stars: stars ?? 0, // TODO: get stars working tags: manifest.tags || [], + // theme stuff + cssURL: manifest.usercss?.startsWith("http") + ? manifest.usercss + : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.usercss}`, + // TODO: clean up indentation etc + schemesURL: manifest.schemes + ? ( + manifest.schemes.startsWith("http") ? manifest.schemes : `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${manifest.schemes}` + ) + : undefined, + include: manifest.include, lastUpdated: "", }; From 531bc668c4e75acf5cb0d3fb746f200ad4e74d14 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 28 Jun 2022 09:38:59 -0400 Subject: [PATCH 30/48] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=F0=9F=9A=A7=20Refac?= =?UTF-8?q?tor=20`fetchMonoManifest`=20temporarily=20to=20be=20more=20effi?= =?UTF-8?q?cient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants.ts | 2 ++ src/logic/FetchRemotes.ts | 27 +++++++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 86ead95e..592582db 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -35,7 +35,9 @@ export const CUSTOM_APP_PATH = "/marketplace"; // Used in Card.tsx export const MAX_TAGS = 4; +export const EXTENSIONS_URL = "TODO"; export const THEMES_URL = "https://raw.githubusercontent.com/spicetify/spicetify-themes/generated-manifest/manifest.json"; +export const APPS_URL = "TODO"; export const SNIPPETS_PAGE_URL = "https://github.com/spicetify/spicetify-marketplace/blob/main/resources/snippets.ts"; diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 994dae97..bb960c71 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -1,6 +1,6 @@ import { CardItem, Manifest, RepoType, Snippet } from "../types/marketplace-types"; import { processAuthors } from "./Utils"; -import { BLACKLIST_URL, THEMES_URL } from "../constants"; +import { BLACKLIST_URL, EXTENSIONS_URL, THEMES_URL, APPS_URL } from "../constants"; import snippetsJSON from "../../resources/snippets"; // TODO: Remove these once there are repos for them @@ -172,14 +172,25 @@ export function buildAppCardData(manifest: Manifest, user?: string, repo?: strin } export const fetchMonoManifest = async (type: RepoType) => { - const manifest = { - theme: await fetch(THEMES_URL).then(res => res.json()).catch((err) => {console.error(err); return [];}), - // extension: await fetch(EXTENSIONS_URL).then(res => res.json()).catch(console.error(err); return [];), - extension: extensionsManifest as Manifest[], - // app: await fetch(APPS_URL).then(res => res.json()).catch(console.error(err); return [];), - app: appsManifest as Manifest[], + /* TODO: swap this in place when we have URLs for everything + const urls = { + extension: EXTENSIONS_URL, + theme: THEMES_URL, + app: APPS_URL, }; - return manifest[type] || []; + + const manifest = await fetch(urls[type]).then(res => res.json()).catch((err) => {console.error(err); return [];}); + return manifest; + */ + + switch (type) { + case "theme": + return await fetch(THEMES_URL).then(res => res.json()).catch((err) => {console.error(err); return [];}); + case "extension": + return extensionsManifest as Manifest[]; + case "app": + return appsManifest as Manifest[]; + } }; /** From 3f5fb6f160092b2b736d6ae4e6568442f7261e1d Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 28 Jun 2022 20:45:38 -0400 Subject: [PATCH 31/48] Use same spice-text var for dropdown hover --- src/styles/components/_dropdown.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/components/_dropdown.scss b/src/styles/components/_dropdown.scss index f5434824..04aba21a 100644 --- a/src/styles/components/_dropdown.scss +++ b/src/styles/components/_dropdown.scss @@ -1,7 +1,7 @@ @use '../constants.scss'; $dropdown-text: var(--spice-text); -$dropdown-text-hover: rgb(var(--spice-rgb-text)); +$dropdown-text-hover: var(--spice-text); $dropdown-bg: var(--spice-sidebar); $dropdown-radius: constants.$btn-radius; From a284f93c614349bf3b74d2dfd785ce2ab6d9e149 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 28 Jun 2022 21:16:22 -0400 Subject: [PATCH 32/48] Add arrow-parens rule, Rearrange extensions/themes/apps to line up with tabs --- src/components/Grid.tsx | 25 +++++++++++++------------ src/logic/FetchRemotes.ts | 4 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/components/Grid.tsx b/src/components/Grid.tsx index 5dd138de..dc6e4987 100644 --- a/src/components/Grid.tsx +++ b/src/components/Grid.tsx @@ -207,8 +207,9 @@ export default class Grid extends React.Component< // Don't need to return a page number because // installed extension do them all in one go, since it's local - } case "Themes": + } case "Extensions": + case "Themes": case "Apps": { const type = this.CONFIG.activeTab.slice(0, -1).toLowerCase() as Omit; let allRepos; @@ -223,24 +224,24 @@ export default class Grid extends React.Component< let cardData; if (this.CONFIG.visual.githubTopics) { switch (type) { - case "theme": - cardData = await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); - break; case "extension": cardData = await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); break; + case "theme": + cardData = await fetchThemeManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); + break; case "app": cardData = await fetchAppManifest(repo.contents_url, repo.default_branch, repo.stargazers_count); break; } } else { switch (type) { - case "theme": - cardData = buildThemeCardData(repo); - break; case "extension": cardData = buildExtensionCardData(repo); break; + case "theme": + cardData = buildThemeCardData(repo); + break; case "app": cardData = buildAppCardData(repo); break; @@ -257,7 +258,7 @@ export default class Grid extends React.Component< } if (cardData) { - console.log(cardData); + // console.log(cardData); if (this.CONFIG.visual.githubTopics) { for (const item of cardData as CardItem[]) { Object.assign(item, { lastUpdated: repo.pushed_at }); @@ -308,7 +309,7 @@ export default class Grid extends React.Component< } if (this.requestPage === -1) { - this.requestQueue = this.requestQueue.filter(a => a !== queue); + this.requestQueue = this.requestQueue.filter((a) => a !== queue); return; } @@ -370,8 +371,8 @@ export default class Grid extends React.Component< */ async componentDidMount() { // Checks for new Marketplace updates - fetch(LATEST_RELEASE).then(res => res.json()).then( - result => { + fetch(LATEST_RELEASE).then((res) => res.json()).then( + (result) => { this.setState({ version: result[0].name, }); @@ -382,7 +383,7 @@ export default class Grid extends React.Component< console.error(err); } }, - error => { + (error) => { console.error("Failed to check for updates", error); }, ); diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index bb960c71..9b5f2a1c 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -185,7 +185,7 @@ export const fetchMonoManifest = async (type: RepoType) => { switch (type) { case "theme": - return await fetch(THEMES_URL).then(res => res.json()).catch((err) => {console.error(err); return [];}); + return await fetch(THEMES_URL).then((res) => res.json()).catch((err) => {console.error(err); return [];}); case "extension": return extensionsManifest as Manifest[]; case "app": @@ -198,7 +198,7 @@ export const fetchMonoManifest = async (type: RepoType) => { * @returns String array of blacklisted repos */ export const fetchBlacklist = async () => { - const json = await fetch(BLACKLIST_URL).then(res => res.json()).catch(() => ({})); + const json = await fetch(BLACKLIST_URL).then((res) => res.json()).catch(() => ({})); return json.repos as string[] | undefined; }; From 4de06a48b7fa20de16c8f690c3cfa845a71f9d53 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 28 Jun 2022 21:16:29 -0400 Subject: [PATCH 33/48] Forgot the rule --- .eslintrc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index c84015ec..9845de5d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -48,6 +48,9 @@ module.exports = { "comma-spacing": [ "error", { "before": false, "after": true }, ], + "arrow-parens": [ + "error", "always", + ], "no-trailing-spaces": "error", "keyword-spacing": "error", "no-multiple-empty-lines": [ From 0c9e2618aff5adfbb780ac8a5e1025968704fe51 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 28 Jun 2022 21:22:14 -0400 Subject: [PATCH 34/48] Make really long function params more readable, arrow-parens --- src/components/Card/Card.tsx | 2 +- src/components/Icons/LoadMoreIcon.tsx | 4 +--- src/components/Icons/LoadingIcon.tsx | 16 ---------------- src/components/Modals/Snippet/index.tsx | 4 ++-- src/components/Modals/ThemeDevTools/index.tsx | 4 ++-- src/components/TabBar.tsx | 6 +++--- src/extensions/extension.tsx | 6 +++--- src/logic/FetchRemotes.ts | 16 ++++++++++++++-- src/logic/FetchTopicRemotes.ts | 6 +++--- src/logic/Utils.ts | 8 ++++---- 10 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/components/Card/Card.tsx b/src/components/Card/Card.tsx index 20b669f6..6c0a3afe 100644 --- a/src/components/Card/Card.tsx +++ b/src/components/Card/Card.tsx @@ -113,7 +113,7 @@ export default class Card extends React.Component res.json()); + const repoData = await fetch(url).then((res) => res.json()); const { stargazers_count, pushed_at } = repoData; const stateUpdate = { stars: 0, lastUpdated: undefined }; diff --git a/src/components/Icons/LoadMoreIcon.tsx b/src/components/Icons/LoadMoreIcon.tsx index 736441bd..6b3108fd 100644 --- a/src/components/Icons/LoadMoreIcon.tsx +++ b/src/components/Icons/LoadMoreIcon.tsx @@ -1,8 +1,6 @@ import React from "react"; -export default class LoadMoreIcon extends React.Component< -{onClick: () => void} -> { +export default class LoadMoreIcon extends React.Component<{onClick: () => void}> { render() { return (
diff --git a/src/components/Icons/LoadingIcon.tsx b/src/components/Icons/LoadingIcon.tsx index 22c2d191..73c7015b 100644 --- a/src/components/Icons/LoadingIcon.tsx +++ b/src/components/Icons/LoadingIcon.tsx @@ -1,22 +1,6 @@ import React from "react"; const LoadingIcon = () => { - // return React.createElement("svg", { - // width: "100px", height: "100px", viewBox: "0 0 100 100", preserveAspectRatio: "xMidYMid", - // }, React.createElement("circle", { - // cx: "50", cy: "50", r: "0", fill: "none", stroke: "currentColor", "stroke-width": "2", - // }, React.createElement("animate", { - // attributeName: "r", repeatCount: "indefinite", dur: "1s", values: "0;40", keyTimes: "0;1", keySplines: "0 0.2 0.8 1", calcMode: "spline", begin: "0s", - // }), React.createElement("animate", { - // attributeName: "opacity", repeatCount: "indefinite", dur: "1s", values: "1;0", keyTimes: "0;1", keySplines: "0.2 0 0.8 1", calcMode: "spline", begin: "0s", - // })), React.createElement("circle", { - // cx: "50", cy: "50", r: "0", fill: "none", stroke: "currentColor", "stroke-width": "2", - // }, React.createElement("animate", { - // attributeName: "r", repeatCount: "indefinite", dur: "1s", values: "0;40", keyTimes: "0;1", keySplines: "0 0.2 0.8 1", calcMode: "spline", begin: "-0.5s", - // }), React.createElement("animate", { - // attributeName: "opacity", repeatCount: "indefinite", dur: "1s", values: "1;0", keyTimes: "0;1", keySplines: "0.2 0 0.8 1", calcMode: "spline", begin: "-0.5s", - // }))); - return ( diff --git a/src/components/Modals/Snippet/index.tsx b/src/components/Modals/Snippet/index.tsx index c29e7569..b999c748 100644 --- a/src/components/Modals/Snippet/index.tsx +++ b/src/components/Modals/Snippet/index.tsx @@ -90,8 +90,8 @@ const SnippetModal = (props: { content?: CardProps, type: ModalType }) => {
setCode(code)} - highlight={code => highlight(code, languages.css)} + onValueChange={(code) => setCode(code)} + highlight={(code) => highlight(code, languages.css)} textareaId="marketplace-custom-css" textareaClassName="snippet-code-editor" readOnly={props.type === "VIEW_SNIPPET"} diff --git a/src/components/Modals/ThemeDevTools/index.tsx b/src/components/Modals/ThemeDevTools/index.tsx index 40871919..3c333dfc 100644 --- a/src/components/Modals/ThemeDevTools/index.tsx +++ b/src/components/Modals/ThemeDevTools/index.tsx @@ -28,8 +28,8 @@ const ThemeDevToolsModal = () => {
setCode(code)} - highlight={code => highlight(code, languages.ini)} + onValueChange={(code) => setCode(code)} + highlight={(code) => highlight(code, languages.ini)} textareaId="color-ini-editor" textareaClassName="color-ini-editor" readOnly={!themeManifest} diff --git a/src/components/TabBar.tsx b/src/components/TabBar.tsx index 6aacf820..a573ce04 100644 --- a/src/components/TabBar.tsx +++ b/src/components/TabBar.tsx @@ -135,7 +135,7 @@ const TabBar = React.memo( if (!tabBarRef.current) return; const children = Array.from(tabBarRef.current.children); - const tabbarItemSizes = children.map(child => child.clientWidth); + const tabbarItemSizes = children.map((child) => child.clientWidth); setChildrenSizes(tabbarItemSizes); }, [links]); @@ -177,7 +177,7 @@ const TabBar = React.memo(
    {options .filter((_, id) => !droplistItem.includes(id)) - .map(item => ( + .map((item) => ( ( ))} {droplistItem.length || childrenSizes.length === 0 ? ( options[i]).filter(i => i)} + items={droplistItem.map((i) => options[i]).filter((i) => i)} switchTo={switchCallback} /> ) : null} diff --git a/src/extensions/extension.tsx b/src/extensions/extension.tsx index 9594d402..61124d90 100644 --- a/src/extensions/extension.tsx +++ b/src/extensions/extension.tsx @@ -27,7 +27,7 @@ import { (async () => { while (!(Spicetify?.LocalStorage && Spicetify?.showNotification)) { - await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise((resolve) => setTimeout(resolve, 100)); } // https://github.com/satya164/react-simple-code-editor/issues/86 @@ -151,7 +151,7 @@ async function queryRepos(type: RepoType, pageNum = 1) { else if (type === "theme") url += `&q=${encodeURIComponent("topic:spicetify-themes")}`; if (pageNum) url += `&page=${pageNum}`; - const allRepos = await fetch(url).then(res => res.json()).catch(() => []); + const allRepos = await fetch(url).then((res) => res.json()).catch(() => []); if (!allRepos.items) { Spicetify.showNotification("Too Many Requests, Cool Down."); } @@ -159,7 +159,7 @@ async function queryRepos(type: RepoType, pageNum = 1) { const filteredResults = { ...allRepos, page_count: allRepos.items.length, - items: allRepos.items.filter(item => !BLACKLIST?.includes(item.html_url)), + items: allRepos.items.filter((item) => !BLACKLIST?.includes(item.html_url)), }; return filteredResults; diff --git a/src/logic/FetchRemotes.ts b/src/logic/FetchRemotes.ts index 9b5f2a1c..c32ed559 100644 --- a/src/logic/FetchRemotes.ts +++ b/src/logic/FetchRemotes.ts @@ -75,7 +75,13 @@ export async function buildExtensionCardData( * @returns Extension info for card (or null) */ // The optional params are only used when using github topics -export function buildThemeCardData(manifest: Manifest, user?: string, repo?: string, branch?: string, stars?: number) { +export function buildThemeCardData( + manifest: Manifest, + user?: string, + repo?: string, + branch?: string, + stars?: number, +) { try { // TODO: figure this out... if (!user) user = "spicetify"; @@ -131,7 +137,13 @@ export function buildThemeCardData(manifest: Manifest, user?: string, repo?: str * @returns Extension info for card (or null) */ // The optional params are only used when using github topics -export function buildAppCardData(manifest: Manifest, user?: string, repo?: string, branch?: string, stars?: number) { +export function buildAppCardData( + manifest: Manifest, + user?: string, + repo?: string, + branch?: string, + stars?: number, +) { try { // TODO: figure this out... // TODO: Update these once we get a repo for apps diff --git a/src/logic/FetchTopicRemotes.ts b/src/logic/FetchTopicRemotes.ts index 12fa70a9..69fd571b 100644 --- a/src/logic/FetchTopicRemotes.ts +++ b/src/logic/FetchTopicRemotes.ts @@ -26,7 +26,7 @@ export async function getTaggedRepos(tag: RepoTopic, page = 1, BLACKLIST:string[ // 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(() => []); + const allRepos = await fetch(url).then((res) => res.json()).catch(() => []); if (!allRepos.items) { Spicetify.showNotification("Too Many Requests, Cool Down."); return; @@ -36,7 +36,7 @@ export async function getTaggedRepos(tag: RepoTopic, page = 1, BLACKLIST:string[ // 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)), + items: allRepos.items.filter((item) => !BLACKLIST.includes(item.html_url)), }; return filteredResults; @@ -59,7 +59,7 @@ export async function getRepoManifest(user: string, repo: string, branch: string 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( + const manifest = await fetch(url).then((res) => res.json()).catch( () => addToSessionStorage([url], "noManifests"), ); if (manifest) window.sessionStorage.setItem(`${user}-${repo}`, JSON.stringify(manifest)); diff --git a/src/logic/Utils.ts b/src/logic/Utils.ts index 74289438..83f3cda7 100644 --- a/src/logic/Utils.ts +++ b/src/logic/Utils.ts @@ -182,7 +182,7 @@ export const processAuthors = (authors: Author[], user: string) => { export const generateSchemesOptions = (schemes: SchemeIni) => { // e.g. [ { key: "red", value: "Red" }, { key: "dark", value: "Dark" } ] if (!schemes) return []; - return Object.keys(schemes).map(schemeName => ( + return Object.keys(schemes).map((schemeName) => ( { key: schemeName, value: schemeName } as SortBoxOption )); }; @@ -308,7 +308,7 @@ export const parseCSS = async (themeData: CardItem) => { const assetsUrl = userCssUrl.replace("/user.css", "/assets/"); console.log("Parsing CSS: ", userCssUrl); - let css = await fetch(`${userCssUrl}?time=${Date.now()}`).then(res => res.text()); + let css = await fetch(`${userCssUrl}?time=${Date.now()}`).then((res) => res.text()); // console.log("Parsed CSS: ", css); const urls = css.matchAll(/url\(['|"](?.+?)['|"]\)/gm) || []; @@ -351,7 +351,7 @@ export const getParamsFromGithubRaw = (url: string) => { export function addToSessionStorage(items, key?) { if (!items) return; - items.forEach(item => { + 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); @@ -411,5 +411,5 @@ export async function getMarkdownHTML(markdown: string, user: string, repo: stri // This function is used to sleep for a certain amount of time export function sleep(ms: number | undefined) { - return new Promise(resolve => setTimeout(resolve, ms)); + return new Promise((resolve) => setTimeout(resolve, ms)); } From 3869c579bf560102a6b7d4dac6996c1b79225507 Mon Sep 17 00:00:00 2001 From: Isaac Maier Date: Tue, 28 Jun 2022 21:33:55 -0400 Subject: [PATCH 35/48] Add classes for some inline css --- src/components/Icons/LoadMoreIcon.tsx | 11 +++-------- src/components/Icons/ThemeDeveloperToolsIcon.tsx | 4 ++-- src/components/Modals/Snippet/index.tsx | 2 +- src/styles/components/_add-snippet-modal.scss | 4 ++++ src/styles/components/_grid.scss | 13 +++++++++++++ 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/components/Icons/LoadMoreIcon.tsx b/src/components/Icons/LoadMoreIcon.tsx index 6b3108fd..d539e019 100644 --- a/src/components/Icons/LoadMoreIcon.tsx +++ b/src/components/Icons/LoadMoreIcon.tsx @@ -3,14 +3,9 @@ import React from "react"; export default class LoadMoreIcon extends React.Component<{onClick: () => void}> { render() { return ( -
    -

    »

    - Load more +
    +

    »

    + Load more
    ); } diff --git a/src/components/Icons/ThemeDeveloperToolsIcon.tsx b/src/components/Icons/ThemeDeveloperToolsIcon.tsx index 0ef63642..518a7152 100644 --- a/src/components/Icons/ThemeDeveloperToolsIcon.tsx +++ b/src/components/Icons/ThemeDeveloperToolsIcon.tsx @@ -3,8 +3,8 @@ import React from "react"; const ThemeDeveloperToolsIcon = () => { return ( - - + + ); }; diff --git a/src/components/Modals/Snippet/index.tsx b/src/components/Modals/Snippet/index.tsx index b999c748..65f0b4a0 100644 --- a/src/components/Modals/Snippet/index.tsx +++ b/src/components/Modals/Snippet/index.tsx @@ -130,7 +130,7 @@ const SnippetModal = (props: { content?: CardProps, type: ModalType }) => { Snippet Preview { props.type !== "VIEW_SNIPPET" && "(optional)" } {imageURL && -