diff --git a/api/services/chrome-web-store/[query].ts b/api/services/chrome-web-store/[query].ts new file mode 100644 index 0000000..ab339ce --- /dev/null +++ b/api/services/chrome-web-store/[query].ts @@ -0,0 +1,34 @@ +import { send, sendError, fetch } from '../../../util/http'; +import { VercelRequest, VercelResponse } from '@vercel/node'; + +export default async function handler( + req: VercelRequest, + res: VercelResponse +): Promise { + const { query } = req.query; + + if (!query || typeof query !== 'string') { + return sendError(res, new Error('No query given')); + } + + const term = encodeURIComponent(query); + + try { + const response = await fetch( + `https://chrome.google.com/webstore/ajax/item?hl=en&pv=20210820&count=112&category=extensions&searchTerm=${term}`, + 'POST' + ); + const body = await response.text(); + const json = JSON.parse(body.slice(5)); + console.log(json[1][1][0]); + const items = json[1][1].map((item: any) => ({ + id: item[0], + name: item[1], + description: item[6], + url: item[37], + })); + send(res, { result: items.slice(0, 10) }); + } catch (err: any) { + sendError(res, err); + } +} diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index fbdeb14..88a312b 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -43,7 +43,8 @@ "spectrum": "Spectrum", "reddit": "Reddit", "twitter": "Twitter", - "cloudflare": "Cloudflare Pages" + "cloudflare": "Cloudflare Pages", + "chromeWebStore": "Chrome Web Store" }, "showMore": "show more", "title": "Grab a slick name for your new app", diff --git a/src/components/Welcome.tsx b/src/components/Welcome.tsx index 055762a..576025d 100644 --- a/src/components/Welcome.tsx +++ b/src/components/Welcome.tsx @@ -16,7 +16,7 @@ import { } from 'react-icons/fa'; import { IoIosBeer, IoMdAppstore } from 'react-icons/io'; import { MdDomain } from 'react-icons/md'; -import { RiBuilding2Fill, RiNpmjsFill } from 'react-icons/ri'; +import { RiBuilding2Fill, RiChromeFill, RiNpmjsFill } from 'react-icons/ri'; import { SiAppstore, SiArchlinux, @@ -60,6 +60,7 @@ const supportedProviders: Record = { githubSearch: , appStore: , playStore: , + chromeWebStore: , nta: , }; diff --git a/src/components/cards/index.tsx b/src/components/cards/index.tsx index b88592a..cb07058 100644 --- a/src/components/cards/index.tsx +++ b/src/components/cards/index.tsx @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; import { mobile } from '../../util/css'; import AppStoreCard from './providers/AppStore'; +import ChromeWebStoreCard from './providers/ChromeWebStore'; import CloudflareCard from './providers/Cloudflare'; import CratesioCard from './providers/Cratesio'; import DomainCard from './providers/Domains'; @@ -64,6 +65,7 @@ const Index: React.FC<{ query: string }> = ({ query }) => { + {language === 'ja' ? : null} diff --git a/src/components/cards/providers/ChromeWebStore.tsx b/src/components/cards/providers/ChromeWebStore.tsx new file mode 100644 index 0000000..c6526c5 --- /dev/null +++ b/src/components/cards/providers/ChromeWebStore.tsx @@ -0,0 +1,54 @@ +import useFetch from 'fetch-suspense'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { RiChromeFill } from 'react-icons/ri'; +import { Card, Result } from '../core'; + +const Search: React.FC<{ query: string }> = ({ query }) => { + const { t } = useTranslation(); + const response = useFetch( + `/api/services/chrome-web-store/${encodeURIComponent(query)}` + ) as { + result: Array<{ + name: string; + url: string; + description: string; + id: string; + }>; + }; + const apps = response.result; + + return ( + <> + {apps && apps.length > 0 ? ( + apps.map((app) => ( + } + key={app.id} + /> + )) + ) : ( + } + /> + )} + + ); +}; + +const ChromeWebStoreCard: React.FC<{ query: string }> = ({ query }) => { + const { t } = useTranslation(); + + return ( + + + + ); +}; + +export default ChromeWebStoreCard; diff --git a/src/util/i18n.ts b/src/util/i18n.ts index bf2979f..df73cdc 100644 --- a/src/util/i18n.ts +++ b/src/util/i18n.ts @@ -5,7 +5,7 @@ import XHR from 'i18next-xhr-backend'; import LanguageDetector from 'i18next-browser-languagedetector'; import { initReactI18next } from 'react-i18next'; -const TRANSLATION_VERSION = '10'; +const TRANSLATION_VERSION = '11'; i18n .use(Backend)