diff --git a/data/search.json b/data/search.json index 38e306a..4137634 100644 --- a/data/search.json +++ b/data/search.json @@ -1,64 +1,67 @@ { - "providers": [ - { - "name": "Allmusic", - "url": "https://www.allmusic.com/search/all/", - "prefix": "/a" - }, - { - "name": "Discogs", - "url": "https://www.discogs.com/search/?q=", - "prefix": "/di" - }, - { - "name": "Duck Duck Go", - "url": "https://duckduckgo.com/?q=", - "prefix": "/d" - }, - { - "name": "iMDB", - "url": "https://www.imdb.com/find?q=", - "prefix": "/i" - }, - { - "name": "TheMovieDB", - "url": "https://www.themoviedb.org/search?query=", - "prefix": "/m" - }, - { - "name": "Reddit", - "url": "https://www.reddit.com/search?q=", - "prefix": "/r" - }, - { - "name": "Qwant", - "url": "https://www.qwant.com/?q=", - "prefix": "/q" - }, - { - "name": "Soundcloud", - "url": "https://soundcloud.com/search?q=", - "prefix": "/so" - }, - { - "name": "Spotify", - "url": "https://open.spotify.com/search/results/", - "prefix": "/s" - }, - { - "name": "TheTVDB", - "url": "https://www.thetvdb.com/search?q=", - "prefix": "/tv" - }, - { - "name": "Trakt", - "url": "https://trakt.tv/search?query=", - "prefix": "/t" - }, - { - "name": "YouTube", - "url": "https://youtube.com/results?search_query=", - "prefix": "/yt" - } - ] + "search": { + "defaultProvider": "https://google.com/search?q=", + "providers": [ + { + "name": "Allmusic", + "url": "https://www.allmusic.com/search/all/", + "prefix": "/a" + }, + { + "name": "Discogs", + "url": "https://www.discogs.com/search/?q=", + "prefix": "/di" + }, + { + "name": "Duck Duck Go", + "url": "https://duckduckgo.com/?q=", + "prefix": "/d" + }, + { + "name": "iMDB", + "url": "https://www.imdb.com/find?q=", + "prefix": "/i" + }, + { + "name": "TheMovieDB", + "url": "https://www.themoviedb.org/search?query=", + "prefix": "/m" + }, + { + "name": "Reddit", + "url": "https://www.reddit.com/search?q=", + "prefix": "/r" + }, + { + "name": "Qwant", + "url": "https://www.qwant.com/?q=", + "prefix": "/q" + }, + { + "name": "Soundcloud", + "url": "https://soundcloud.com/search?q=", + "prefix": "/so" + }, + { + "name": "Spotify", + "url": "https://open.spotify.com/search/results/", + "prefix": "/s" + }, + { + "name": "TheTVDB", + "url": "https://www.thetvdb.com/search?q=", + "prefix": "/tv" + }, + { + "name": "Trakt", + "url": "https://trakt.tv/search?query=", + "prefix": "/t" + }, + { + "name": "YouTube", + "url": "https://youtube.com/results?search_query=", + "prefix": "/yt" + } + ] + } } diff --git a/src/app.tsx b/src/app.tsx index a92dd02..da2f2d5 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -42,13 +42,14 @@ const App = () => { <>
- - {(!themeData.error || !searchProviderData.error) && ( - - )} + + {!themeData.error || + (!searchProviderData.error && ( + + ))} {!appData.error && ( diff --git a/src/components/searchBar.tsx b/src/components/searchBar.tsx index 8e200a8..d1931c5 100644 --- a/src/components/searchBar.tsx +++ b/src/components/searchBar.tsx @@ -43,12 +43,17 @@ export interface ISearchProviderProps { prefix: string; } -export interface ISearchBarProps { +export interface ISearchProps { + defaultProvider: string; providers: Array | undefined; } +interface ISearchBarProps { + search: ISearchProps; +} + export const handleQueryWithProvider = ( - providers: Array | undefined, + search: ISearchProps, query: string, ) => { let queryArray: Array = query.split(" "); @@ -59,8 +64,8 @@ export const handleQueryWithProvider = ( let searchQuery: string = queryArray.join(" "); let providerFound: boolean = false; - if (providers) { - providers.forEach((provider: ISearchProviderProps) => { + if (search.providers) { + search.providers.forEach((provider: ISearchProviderProps) => { if (provider.prefix === prefix) { providerFound = true; window.location.href = provider.url + searchQuery; @@ -68,15 +73,14 @@ export const handleQueryWithProvider = ( }); } - if (!providerFound) - window.location.href = "https://google.com/search?q=" + query; + if (!providerFound) window.location.href = search.defaultProvider + query; }; /** * Renders a search bar - * @param {ISearchBarProps} props - The search providers for the search bar to use + * @param {ISearchBarProps} search - The search providers for the search bar to use */ -const SearchBar = ({ providers }: ISearchBarProps) => { +const SearchBar = ({ search }: ISearchBarProps) => { let [input, setInput] = useState(""); let [buttonsHidden, setButtonsHidden] = useState(true); @@ -86,9 +90,9 @@ const SearchBar = ({ providers }: ISearchBarProps) => { var query: string = input || ""; if (query.split(" ")[0].includes("/")) { - handleQueryWithProvider(providers, query); + handleQueryWithProvider(search, query); } else { - window.location.href = "https://google.com/search?q=" + query; + window.location.href = search.defaultProvider + query; } e.preventDefault(); diff --git a/src/components/settings.tsx b/src/components/settings.tsx index 8e507fc..3cba6bc 100644 --- a/src/components/settings.tsx +++ b/src/components/settings.tsx @@ -3,12 +3,8 @@ import styled from "styled-components"; import Select, { ValueType } from "react-select"; -import { ISearchProviderProps } from "./searchBar"; -import selectedTheme, { - defaultTheme, - setTheme, - IThemeProps, -} from "../lib/theme"; +import { ISearchProps } from "./searchBar"; +import selectedTheme, { setTheme, IThemeProps } from "../lib/theme"; import { Button, SubHeadline } from "./elements"; import Modal from "./modal"; @@ -21,6 +17,7 @@ export const FormContainer = styled.div` export const Table = styled.table` font-weight: 400; background: none; + width: 100%; color: ${selectedTheme.mainColor}; `; @@ -35,7 +32,7 @@ export const TableCell = styled.td` export const HeadCell = styled.th` font-weight: 700; - background: none; + text-align: left; `; export const Section = styled.div` @@ -48,6 +45,16 @@ export const SectionHeadline = styled(SubHeadline)` margin-bottom: 0.5rem; `; +const Text = styled.p` + font-weight: 700; + color: ${selectedTheme.accentColor}; +`; + +const Code = styled.p` + font-family: monospace; + color: ${selectedTheme.accentColor}; +`; + export const SelectorStyle: any = { container: (base: any): any => ({ ...base, @@ -108,18 +115,18 @@ export const SelectorStyle: any = { interface ISettingsProps { themes: Array | undefined; - providers: Array | undefined; + search: ISearchProps | undefined; } /** * Handles the settings-modal * @param {Array} themes - the list of themes a user can select between - * @param {Array} providers - the list of search providers + * @param {ISearchProps} search - the list of search providers */ -const Settings = ({ themes, providers }: ISettingsProps) => { - const [newTheme, setNewTheme] = useState(defaultTheme); +const Settings = ({ themes, search }: ISettingsProps) => { + const [newTheme, setNewTheme] = useState(); - if (themes || providers) { + if (themes || search) { return ( {themes && ( @@ -137,7 +144,9 @@ const Settings = ({ themes, providers }: ISettingsProps) => { /> @@ -150,23 +159,31 @@ const Settings = ({ themes, providers }: ISettingsProps) => { )} - {providers && ( + {search && (
Search Providers - - - - Search Provider - Prefix - - {providers.map((provider, index) => ( - - {provider.name} - {provider.prefix} - - ))} - -
+ <> + Default Search Provider + {search.defaultProvider} + + <> + {search.providers && ( + + + + Search Provider + Prefix + + {search.providers.map((provider, index) => ( + + {provider.name} + {provider.prefix} + + ))} + +
+ )} +
)}
diff --git a/src/data/search.json b/src/data/search.json index 38e306a..4137634 100644 --- a/src/data/search.json +++ b/src/data/search.json @@ -1,64 +1,67 @@ { - "providers": [ - { - "name": "Allmusic", - "url": "https://www.allmusic.com/search/all/", - "prefix": "/a" - }, - { - "name": "Discogs", - "url": "https://www.discogs.com/search/?q=", - "prefix": "/di" - }, - { - "name": "Duck Duck Go", - "url": "https://duckduckgo.com/?q=", - "prefix": "/d" - }, - { - "name": "iMDB", - "url": "https://www.imdb.com/find?q=", - "prefix": "/i" - }, - { - "name": "TheMovieDB", - "url": "https://www.themoviedb.org/search?query=", - "prefix": "/m" - }, - { - "name": "Reddit", - "url": "https://www.reddit.com/search?q=", - "prefix": "/r" - }, - { - "name": "Qwant", - "url": "https://www.qwant.com/?q=", - "prefix": "/q" - }, - { - "name": "Soundcloud", - "url": "https://soundcloud.com/search?q=", - "prefix": "/so" - }, - { - "name": "Spotify", - "url": "https://open.spotify.com/search/results/", - "prefix": "/s" - }, - { - "name": "TheTVDB", - "url": "https://www.thetvdb.com/search?q=", - "prefix": "/tv" - }, - { - "name": "Trakt", - "url": "https://trakt.tv/search?query=", - "prefix": "/t" - }, - { - "name": "YouTube", - "url": "https://youtube.com/results?search_query=", - "prefix": "/yt" - } - ] + "search": { + "defaultProvider": "https://google.com/search?q=", + "providers": [ + { + "name": "Allmusic", + "url": "https://www.allmusic.com/search/all/", + "prefix": "/a" + }, + { + "name": "Discogs", + "url": "https://www.discogs.com/search/?q=", + "prefix": "/di" + }, + { + "name": "Duck Duck Go", + "url": "https://duckduckgo.com/?q=", + "prefix": "/d" + }, + { + "name": "iMDB", + "url": "https://www.imdb.com/find?q=", + "prefix": "/i" + }, + { + "name": "TheMovieDB", + "url": "https://www.themoviedb.org/search?query=", + "prefix": "/m" + }, + { + "name": "Reddit", + "url": "https://www.reddit.com/search?q=", + "prefix": "/r" + }, + { + "name": "Qwant", + "url": "https://www.qwant.com/?q=", + "prefix": "/q" + }, + { + "name": "Soundcloud", + "url": "https://soundcloud.com/search?q=", + "prefix": "/so" + }, + { + "name": "Spotify", + "url": "https://open.spotify.com/search/results/", + "prefix": "/s" + }, + { + "name": "TheTVDB", + "url": "https://www.thetvdb.com/search?q=", + "prefix": "/tv" + }, + { + "name": "Trakt", + "url": "https://trakt.tv/search?query=", + "prefix": "/t" + }, + { + "name": "YouTube", + "url": "https://youtube.com/results?search_query=", + "prefix": "/yt" + } + ] + } } diff --git a/src/lib/fetcher.tsx b/src/lib/fetcher.tsx index f1b2ac2..8899a26 100644 --- a/src/lib/fetcher.tsx +++ b/src/lib/fetcher.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect, useState } from "react"; -import { ISearchProviderProps } from "../components/searchBar"; +import { ISearchProps } from "../components/searchBar"; import { IBookmarkGroupProps } from "../components/bookmarks"; import { IAppCategoryProps } from "../components/appCategory"; import { IAppProps } from "../components/app"; @@ -22,8 +22,8 @@ export const handleResponse = (response: Response) => { throw new Error(errorMessage); }; -export interface ISearchProviderDataProps { - providers: Array; +export interface ISearchDataProps { + search: ISearchProps; error: string | boolean; } @@ -67,7 +67,10 @@ export const defaults = { error: false, }, search: { - providers: [], + search: { + defaultProvider: "https://google.com/search?q=", + providers: [], + }, error: false, }, theme: { @@ -209,7 +212,7 @@ export const useFetcher = () => { ); const [searchProviderData, setSearchProviderData] = - useState(defaults.search); + useState(defaults.search); const [themeData, setThemeData] = useState(defaults.theme); @@ -233,7 +236,7 @@ export const useFetcher = () => { ]: [ IAppDataProps, IBookmarkDataProps, - ISearchProviderDataProps, + ISearchDataProps, IThemeDataProps, IImprintDataProps, IGreeterDataProps, diff --git a/src/test/components/imprint.spec.tsx b/src/test/components/imprint.spec.tsx index 51810b5..5afc709 100644 --- a/src/test/components/imprint.spec.tsx +++ b/src/test/components/imprint.spec.tsx @@ -26,14 +26,15 @@ const props: IImprintProps = { }; describe("imprint.tsx", () => { + const location: Location = window.location; + beforeEach(() => { - delete global.window.location; - global.window = Object.create(window); - global.window.location = { - port: "123", - protocol: "http:", - hostname: "localhost", - href: "test", + // @ts-ignore + delete window.location; + + window.location = { + ...location, + reload: jest.fn(), }; }); diff --git a/src/test/components/searchBar.spec.tsx b/src/test/components/searchBar.spec.tsx index c9e80e1..79fae2d 100644 --- a/src/test/components/searchBar.spec.tsx +++ b/src/test/components/searchBar.spec.tsx @@ -2,29 +2,32 @@ import { fireEvent, render } from "@testing-library/react"; import SearchBar, { handleQueryWithProvider, ISearchProviderProps, - ISearchBarProps, + ISearchProps, } from "../../components/searchBar"; -const providers: Array = [ - { - name: "Allmusic", - url: "https://www.allmusic.com/search/all/", - prefix: "/a", - }, - { - name: "Discogs", - url: "https://www.discogs.com/search/?q=", - prefix: "/di", - }, - { - name: "Duck Duck Go", - url: "https://duckduckgo.com/?q=", - prefix: "/d", - }, -]; +const props: ISearchProps = { + defaultProvider: "https://test.com?q=", + providers: [ + { + name: "Allmusic", + url: "https://www.allmusic.com/search/all/", + prefix: "/a", + }, + { + name: "Discogs", + url: "https://www.discogs.com/search/?q=", + prefix: "/di", + }, + { + name: "Duck Duck Go", + url: "https://duckduckgo.com/?q=", + prefix: "/d", + }, + ], +}; const setup = () => { - const searchBar = render(); + const searchBar = render(); const input = searchBar.getByTestId("search-input"); const clearButton = searchBar.getByTestId("search-clear"); const submitButton = searchBar.getByTestId("search-submit"); @@ -37,37 +40,44 @@ const setup = () => { }; }; +const location: Location = window.location; + describe("searchBar.tsx", () => { beforeEach(() => { - delete global.window.location; - global.window = Object.create(window); - global.window.location = { - port: "123", - protocol: "http:", - hostname: "localhost", + // @ts-ignore + delete window.location; + + window.location = { + ...location, + reload: jest.fn(), }; }); it("Tests SearchBar rendering", () => { - const { asFragment } = render(); + const { asFragment } = render(); expect(asFragment).toMatchSnapshot(); }); it("Tests handleQueryWithProvider", () => { - providers.forEach((provider: ISearchProviderProps) => { - handleQueryWithProvider(providers, provider.prefix + " test"); + props.providers?.forEach((provider: ISearchProviderProps) => { + handleQueryWithProvider(props, provider.prefix + " test"); expect(window.location.href).toEqual(provider.url + "test"); }); }); it("Tests handleQueryWithProvider default", () => { - handleQueryWithProvider(providers, "test"); - expect(window.location.href).toEqual("https://google.com/search?q=test"); + handleQueryWithProvider(props, "test"); + expect(window.location.href).toEqual(props.defaultProvider + "test"); }); it("Tests handleQueryWithProvider without providers", () => { - handleQueryWithProvider(undefined, "test"); - expect(window.location.href).toEqual("https://google.com/search?q=test"); + const test: ISearchProps = { + defaultProvider: "https://test.com?q=", + providers: undefined, + }; + + handleQueryWithProvider(test, "test"); + expect(window.location.href).toEqual(test.defaultProvider + "test"); }); it("Tests SearchBar component with default search", () => { @@ -75,7 +85,7 @@ describe("searchBar.tsx", () => { fireEvent.change(input, { target: { value: "test" } }); fireEvent.click(submitButton); - expect(window.location.href).toEqual("https://google.com/search?q=test"); + expect(window.location.href).toEqual(props.defaultProvider + "test"); }); it("Tests SearchBar component with other search", () => { @@ -96,6 +106,6 @@ describe("searchBar.tsx", () => { fireEvent.click(clearButton); fireEvent.click(submitButton); - expect(window.location.href).toEqual("https://google.com/search?q="); + expect(window.location.href).toEqual(props.defaultProvider); }); }); diff --git a/src/test/components/settings.spec.tsx b/src/test/components/settings.spec.tsx index df9d728..850eb1e 100644 --- a/src/test/components/settings.spec.tsx +++ b/src/test/components/settings.spec.tsx @@ -9,7 +9,7 @@ import Settings, { SectionHeadline, SelectorStyle, } from "../../components/settings"; -import { ISearchProviderProps } from "../../components/searchBar"; +import { ISearchProps } from "../../components/searchBar"; import { IThemeProps } from "../../lib/theme"; const themes: Array = [ @@ -29,46 +29,48 @@ const themes: Array = [ }, ]; -const providers: Array = [ - { - name: "Allmusic", - url: "https://www.allmusic.com/search/all/", - prefix: "/a", - }, - { - name: "Discogs", - url: "https://www.discogs.com/search/?q=", - prefix: "/di", - }, - { - name: "Duck Duck Go", - url: "https://duckduckgo.com/?q=", - prefix: "/d", - }, -]; +const search: ISearchProps = { + defaultProvider: "https://test.com?q=", + providers: [ + { + name: "Allmusic", + url: "https://www.allmusic.com/search/all/", + prefix: "/a", + }, + { + name: "Discogs", + url: "https://www.discogs.com/search/?q=", + prefix: "/di", + }, + { + name: "Duck Duck Go", + url: "https://duckduckgo.com/?q=", + prefix: "/d", + }, + ], +}; const propsList = [ { themes: themes, - providers: providers, + search: search, }, { themes: themes, - providers: undefined, + search: undefined, }, { themes: undefined, - providers: providers, + search: search, }, { themes: undefined, - providers: undefined, + search: undefined, }, ]; describe("settings.tsx", () => { const location: Location = window.location; - 8; beforeEach(() => { // @ts-ignore @@ -115,7 +117,7 @@ describe("settings.tsx", () => { it("Tests settings rendering", () => { propsList.forEach((props) => { const settings = render( - , + , ); expect(settings.asFragment).toMatchSnapshot(); @@ -125,10 +127,7 @@ describe("settings.tsx", () => { // TODO: Finish this test it("Tests theme setting", () => { const settings = render( - , + , ); const toggleButton = settings.getByTestId("toggle-button");