Skip to content

Commit

Permalink
Merge pull request #181 from kyrie25/search
Browse files Browse the repository at this point in the history
feat(index): add search function
  • Loading branch information
CharlieS1103 authored May 8, 2022
2 parents 5adcd15 + 75ed9b2 commit 75f5da1
Showing 1 changed file with 70 additions and 17 deletions.
87 changes: 70 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/// <reference types="react-dom" />
/// <reference path="../spicetify-cli/globals.d.ts" />
/// <reference path="../spicetify-cli/jsHelper/spicetifyWrapper.js" />
/// <reference path="src/AddSnippetModal.js" />
/// <reference path="src/Card.js" />
/// <reference path="src/Icons.js" />
/// <reference path="src/Settings.js" />
Expand Down Expand Up @@ -142,6 +143,10 @@ const ITEMS_PER_REQUEST = 100;

let BLACKLIST = [];

// Search variables
let searchQuery = "";
let requested = false;

// eslint-disable-next-line no-redeclare, no-unused-vars
let gridUpdateTabs, gridUpdatePostsVisual;

Expand All @@ -150,6 +155,7 @@ class Grid extends react.Component {
super(props);
Object.assign(this, props);
this.state = {
searchValue: "",
cards: [],
tabs: CONFIG.tabs,
rest: true,
Expand All @@ -158,6 +164,8 @@ class Grid extends react.Component {
activeScheme: CONFIG.theme.activeScheme,
activeThemeKey: CONFIG.theme.activeThemeKey,
};

this.handleSearch = this.handleSearch.bind(this);
}

// TODO: should I put this in Grid state?
Expand Down Expand Up @@ -248,7 +256,8 @@ class Grid extends react.Component {
// Returns the next page number to fetch, or null if at end
// TODO: maybe we should rename `loadPage()`, since it's slightly confusing when we have github pages as well
async loadPage(queue) {
if (CONFIG.activeTab === "Extensions") {
switch (CONFIG.activeTab) {
case "Extensions": {
let pageOfRepos = await getExtensionRepos(requestPage);
for (const repo of pageOfRepos.items) {
let extensions = await fetchExtensionManifest(repo.contents_url, repo.default_branch, repo.stargazers_count);
Expand All @@ -275,7 +284,8 @@ class Grid extends react.Component {
console.log(`Parsed ${soFarResults}/${pageOfRepos.total_count} extensions`);
if (remainingResults > 0) return currentPage + 1;
else console.log("No more extension results");
} else if (CONFIG.activeTab === "Installed") {
break;
} case "Installed": {
const installedStuff = {
theme: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.installedThemes, []),
extension: getLocalStorageDataFromKey(LOCALSTORAGE_KEYS.installedExtensions, []),
Expand All @@ -298,10 +308,10 @@ class Grid extends react.Component {
});
}
}

break;
// Don't need to return a page number because
// installed extension do them all in one go, since it's local
} else if (CONFIG.activeTab == "Themes") {
} case "Themes": {
let pageOfRepos = await getThemeRepos(requestPage);
for (const repo of pageOfRepos.items) {

Expand All @@ -326,7 +336,8 @@ class Grid extends react.Component {
console.log(`Parsed ${soFarResults}/${pageOfRepos.total_count} themes`);
if (remainingResults > 0) return currentPage + 1;
else console.log("No more theme results");
} else if (CONFIG.activeTab == "Snippets") {
break;
} case "Snippets": {
let snippets = await fetchCssSnippets();

if (requestQueue.length > 1 && queue !== requestQueue[0]) {
Expand All @@ -336,8 +347,8 @@ class Grid extends react.Component {
if (snippets && snippets.length) {
snippets.forEach((snippet) => this.appendCard(snippet, "snippet"));
}

}
break;
}}

this.setState({ rest: true, endOfList: true });
endOfList = true;
Expand Down Expand Up @@ -509,6 +520,25 @@ class Grid extends react.Component {
return this.state.activeScheme;
}

/**
* @param {import("react").KeyboardEvent} event
*/
handleSearch (event) {
if (event.key === "Enter") {
this.setState({ endOfList: false });
this.newRequest(ITEMS_PER_REQUEST);
requested = true;
} else if ( // Refreshes result when user deletes all queries
((event.key === "Backspace") || (event.key === "Delete")) &&
requested &&
this.state.searchValue.trim() === ""
) {
this.setState({ endOfList: false });
this.newRequest(ITEMS_PER_REQUEST);
requested = false;
}
}

render() {
return react.createElement("section", {
className: "contentSpacing",
Expand Down Expand Up @@ -537,21 +567,36 @@ class Grid extends react.Component {
}, SETTINGS_ICON),
// End of marketplace-header__right
),
// TODO: Add search bar and sort functionality
// react.createElement("div", {
// className: "searchbar--bar__wrapper",
// }, react.createElement("input", {
// className: "searchbar-bar",
// type: "text",
// placeholder: "Search for Extensions?",
// })),
react.createElement("div", {
className: "searchbar--bar__wrapper",
}, react.createElement("input", {
className: "searchbar-bar",
type: "text",
placeholder: "Search",
value: this.state.searchValue,
onChange: (event) => {
this.setState({ searchValue: event.target.value });
searchQuery = event.target.value;
},
onKeyDown: (event) => this.handleSearch(event),
})),
),
[ // Add a header and grid for each card type if it has any cards
{ handle: "extension", name: "Extensions" },
{ handle: "theme", name: "Themes" },
{ handle: "snippet", name: "Snippets" },
].map((cardType) => {
const cardsOfType = cardList.filter((card) => card.props.type === cardType.handle)
.filter((card) => { // Search filter
const { searchValue } = this.state;
const { title, user } = card.props;

if (
searchValue.trim() === "" ||
title.toLowerCase().includes(searchValue.trim().toLowerCase()) ||
user.toLowerCase().includes(searchValue.trim().toLowerCase())
) return card;
})
.map((card) => {
// Clone the cards and update the prop to trigger re-render
// TODO: is it possible to only re-render the theme cards whose status have changed?
Expand Down Expand Up @@ -611,6 +656,10 @@ class Grid extends react.Component {
async function getExtensionRepos(page = 1) {
// www is needed or it will block with "cross-origin" error.
let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify-extensions")}&per_page=${ITEMS_PER_REQUEST}`;
if (searchQuery?.trim() !== "") {
url = `https://api.github.com/search/repositories?q=${encodeURIComponent(`${searchQuery}+topic:spicetify-extensions`)}&per_page=${ITEMS_PER_REQUEST}`;

}

// We can test multiple pages with this URL (58 results), as well as broken iamges etc.
// let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify")}`;
Expand All @@ -621,6 +670,7 @@ async function getExtensionRepos(page = 1) {
const allRepos = await fetch(url).then(res => res.json()).catch(() => []);
if (!allRepos.items) {
Spicetify.showNotification("Too Many Requests, Cool Down.");
return null;
}
const filteredResults = {
...allRepos,
Expand Down Expand Up @@ -804,7 +854,9 @@ async function fetchThemeManifest(contents_url, branch, stars) {
*/
async function getThemeRepos(page = 1) {
let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify-themes")}&per_page=${ITEMS_PER_REQUEST}`;

if (searchQuery?.trim() !== "") {
url = `https://api.github.com/search/repositories?q=${encodeURIComponent(`${searchQuery}+topic:spicetify-themes`)}&per_page=${ITEMS_PER_REQUEST}`;
}
// We can test multiple pages with this URL (58 results), as well as broken iamges etc.
// let url = `https://api.github.com/search/repositories?q=${encodeURIComponent("topic:spicetify")}`;
if (page) url += `&page=${page}`;
Expand All @@ -814,6 +866,7 @@ async function getThemeRepos(page = 1) {
const allThemes = await fetch(url).then(res => res.json()).catch(() => []);
if (!allThemes.items) {
Spicetify.showNotification("Too Many Requests, Cool Down.");
return null;
}
const filteredResults = {
...allThemes,
Expand All @@ -826,7 +879,7 @@ async function getThemeRepos(page = 1) {
return filteredResults;
}
function addToSessionStorage(items, key) {
if (!items || items == null) return;
if (!items) return;
items.forEach(item => {
if (!key) key = `${items.user}-${items.repo}`;
// If the key already exists, it will append to it instead of overwriting it
Expand Down

0 comments on commit 75f5da1

Please sign in to comment.