First Commit

This commit is contained in:
phntxx 2021-04-22 11:15:41 +02:00
parent 007567a6d0
commit 3138c18021
6 changed files with 195 additions and 161 deletions

View file

@ -1,64 +1,67 @@
{ {
"providers": [ "search": {
{ "defaultProvider": "https://google.com/search?q=",
"name": "Allmusic", "providers": [
"url": "https://www.allmusic.com/search/all/", {
"prefix": "/a" "name": "Allmusic",
}, "url": "https://www.allmusic.com/search/all/",
{ "prefix": "/a"
"name": "Discogs", },
"url": "https://www.discogs.com/search/?q=", {
"prefix": "/di" "name": "Discogs",
}, "url": "https://www.discogs.com/search/?q=",
{ "prefix": "/di"
"name": "Duck Duck Go", },
"url": "https://duckduckgo.com/?q=", {
"prefix": "/d" "name": "Duck Duck Go",
}, "url": "https://duckduckgo.com/?q=",
{ "prefix": "/d"
"name": "iMDB", },
"url": "https://www.imdb.com/find?q=", {
"prefix": "/i" "name": "iMDB",
}, "url": "https://www.imdb.com/find?q=",
{ "prefix": "/i"
"name": "TheMovieDB", },
"url": "https://www.themoviedb.org/search?query=", {
"prefix": "/m" "name": "TheMovieDB",
}, "url": "https://www.themoviedb.org/search?query=",
{ "prefix": "/m"
"name": "Reddit", },
"url": "https://www.reddit.com/search?q=", {
"prefix": "/r" "name": "Reddit",
}, "url": "https://www.reddit.com/search?q=",
{ "prefix": "/r"
"name": "Qwant", },
"url": "https://www.qwant.com/?q=", {
"prefix": "/q" "name": "Qwant",
}, "url": "https://www.qwant.com/?q=",
{ "prefix": "/q"
"name": "Soundcloud", },
"url": "https://soundcloud.com/search?q=", {
"prefix": "/so" "name": "Soundcloud",
}, "url": "https://soundcloud.com/search?q=",
{ "prefix": "/so"
"name": "Spotify", },
"url": "https://open.spotify.com/search/results/", {
"prefix": "/s" "name": "Spotify",
}, "url": "https://open.spotify.com/search/results/",
{ "prefix": "/s"
"name": "TheTVDB", },
"url": "https://www.thetvdb.com/search?q=", {
"prefix": "/tv" "name": "TheTVDB",
}, "url": "https://www.thetvdb.com/search?q=",
{ "prefix": "/tv"
"name": "Trakt", },
"url": "https://trakt.tv/search?query=", {
"prefix": "/t" "name": "Trakt",
}, "url": "https://trakt.tv/search?query=",
{ "prefix": "/t"
"name": "YouTube", },
"url": "https://youtube.com/results?search_query=", {
"prefix": "/yt" "name": "YouTube",
} "url": "https://youtube.com/results?search_query=",
] "prefix": "/yt"
}
]
}
} }

View file

@ -36,11 +36,11 @@ const App = () => {
<> <>
<GlobalStyle /> <GlobalStyle />
<div> <div>
<SearchBar providers={searchProviderData?.providers} /> <SearchBar search={searchProviderData?.search} />
{!themeData.error && !searchProviderData.error && ( {!themeData.error && !searchProviderData.error && (
<Settings <Settings
themes={themeData?.themes} themes={themeData?.themes}
providers={searchProviderData?.providers} search={searchProviderData?.search}
/> />
)} )}
<Greeter data={greeterData.greeter} /> <Greeter data={greeterData.greeter} />

View file

@ -44,15 +44,20 @@ export interface ISearchProviderProps {
prefix: string; prefix: string;
} }
interface ISearchBarProps { export interface ISearchProps {
defaultProvider: string;
providers: Array<ISearchProviderProps> | undefined; providers: Array<ISearchProviderProps> | undefined;
} }
interface ISearchBarProps {
search: ISearchProps;
}
/** /**
* Renders a search bar * 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<string>(""); let [input, setInput] = useState<string>("");
let [buttonsHidden, setButtonsHidden] = useState<boolean>(true); let [buttonsHidden, setButtonsHidden] = useState<boolean>(true);
@ -64,7 +69,7 @@ const SearchBar = ({ providers }: ISearchBarProps) => {
if (query.split(" ")[0].includes("/")) { if (query.split(" ")[0].includes("/")) {
handleQueryWithProvider(query); handleQueryWithProvider(query);
} else { } else {
window.location.href = "https://google.com/search?q=" + query; window.location.href = search.defaultProvider + query;
} }
e.preventDefault(); e.preventDefault();
@ -79,8 +84,8 @@ const SearchBar = ({ providers }: ISearchBarProps) => {
let searchQuery: string = queryArray.join(" "); let searchQuery: string = queryArray.join(" ");
let providerFound: boolean = false; let providerFound: boolean = false;
if (providers) { if (search.providers) {
providers.forEach((provider: ISearchProviderProps) => { search.providers.forEach((provider: ISearchProviderProps) => {
if (provider.prefix === prefix) { if (provider.prefix === prefix) {
providerFound = true; providerFound = true;
window.location.href = provider.url + searchQuery; window.location.href = provider.url + searchQuery;
@ -89,7 +94,7 @@ const SearchBar = ({ providers }: ISearchBarProps) => {
} }
if (!providerFound) if (!providerFound)
window.location.href = "https://google.com/search?q=" + query; window.location.href = search.defaultProvider + query;
}; };
return ( return (

View file

@ -3,7 +3,7 @@ import styled from "styled-components";
import Select, { ValueType } from "react-select"; import Select, { ValueType } from "react-select";
import { ISearchProviderProps } from "./searchBar"; import { ISearchProps } from "./searchBar";
import selectedTheme, { setTheme, IThemeProps } from "../lib/theme"; import selectedTheme, { setTheme, IThemeProps } from "../lib/theme";
import { Button, SubHeadline } from "./elements"; import { Button, SubHeadline } from "./elements";
@ -17,6 +17,7 @@ const FormContainer = styled.div`
const Table = styled.table` const Table = styled.table`
font-weight: 400; font-weight: 400;
background: none; background: none;
width: 100%;
color: ${selectedTheme.mainColor}; color: ${selectedTheme.mainColor};
`; `;
@ -25,13 +26,12 @@ const TableRow = styled.tr`
`; `;
const TableCell = styled.td` const TableCell = styled.td`
background: none;
padding-top: 0.5rem; padding-top: 0.5rem;
`; `;
const HeadCell = styled.th` const HeadCell = styled.th`
font-weight: 700; font-weight: 700;
background: none; text-align: left;
`; `;
const Section = styled.div` const Section = styled.div`
@ -44,6 +44,16 @@ const SectionHeadline = styled(SubHeadline)`
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
`; `;
const Text = styled.p`
font-weight: 700;
color: ${selectedTheme.accentColor};
`;
const Code = styled.p`
font-family: monospace;
color: ${selectedTheme.accentColor};
`;
const SelectorStyle: any = { const SelectorStyle: any = {
container: (base: any): any => ({ container: (base: any): any => ({
...base, ...base,
@ -104,18 +114,18 @@ const SelectorStyle: any = {
interface ISettingsProps { interface ISettingsProps {
themes: Array<IThemeProps> | undefined; themes: Array<IThemeProps> | undefined;
providers: Array<ISearchProviderProps> | undefined; search: ISearchProps | undefined;
} }
/** /**
* Handles the settings-modal * Handles the settings-modal
* @param {Array<IThemeProps>} themes - the list of themes a user can select between * @param {Array<IThemeProps>} themes - the list of themes a user can select between
* @param {Array<ISearchProviderProps>} providers - the list of search providers * @param {ISearchProps} search - the list of search providers
*/ */
const Settings = ({ themes, providers }: ISettingsProps) => { const Settings = ({ themes, search }: ISettingsProps) => {
const [newTheme, setNewTheme] = useState<IThemeProps>(); const [newTheme, setNewTheme] = useState<IThemeProps>();
if (themes && providers) { if (themes && search) {
return ( return (
<Modal element="icon" icon="settings" title="Settings"> <Modal element="icon" icon="settings" title="Settings">
{themes && ( {themes && (
@ -137,23 +147,33 @@ const Settings = ({ themes, providers }: ISettingsProps) => {
</FormContainer> </FormContainer>
</Section> </Section>
)} )}
{providers && ( {search && (
<Section> <Section>
<SectionHeadline>Search Providers</SectionHeadline> <SectionHeadline>Search Providers</SectionHeadline>
<Table> <>
<tbody> <Text>Default Search Provider</Text>
<TableRow> <Code>{search.defaultProvider}</Code>
<HeadCell>Search Provider</HeadCell> </>
<HeadCell>Prefix</HeadCell> <>
</TableRow> {
{providers.map((provider, index) => ( search.providers && (
<TableRow key={provider.name + index}> <Table>
<TableCell>{provider.name}</TableCell> <tbody>
<TableCell>{provider.prefix}</TableCell> <TableRow>
</TableRow> <HeadCell>Search Provider</HeadCell>
))} <HeadCell>Prefix</HeadCell>
</tbody> </TableRow>
</Table> {search.providers.map((provider, index) => (
<TableRow key={provider.name + index}>
<TableCell>{provider.name}</TableCell>
<TableCell>{provider.prefix}</TableCell>
</TableRow>
))}
</tbody>
</Table>
)
}
</>
</Section> </Section>
)} )}
</Modal> </Modal>

View file

@ -1,64 +1,67 @@
{ {
"providers": [ "search": {
{ "defaultProvider": "https://google.com/search?q=",
"name": "Allmusic", "providers": [
"url": "https://www.allmusic.com/search/all/", {
"prefix": "/a" "name": "Allmusic",
}, "url": "https://www.allmusic.com/search/all/",
{ "prefix": "/a"
"name": "Discogs", },
"url": "https://www.discogs.com/search/?q=", {
"prefix": "/di" "name": "Discogs",
}, "url": "https://www.discogs.com/search/?q=",
{ "prefix": "/di"
"name": "Duck Duck Go", },
"url": "https://duckduckgo.com/?q=", {
"prefix": "/d" "name": "Duck Duck Go",
}, "url": "https://duckduckgo.com/?q=",
{ "prefix": "/d"
"name": "iMDB", },
"url": "https://www.imdb.com/find?q=", {
"prefix": "/i" "name": "iMDB",
}, "url": "https://www.imdb.com/find?q=",
{ "prefix": "/i"
"name": "TheMovieDB", },
"url": "https://www.themoviedb.org/search?query=", {
"prefix": "/m" "name": "TheMovieDB",
}, "url": "https://www.themoviedb.org/search?query=",
{ "prefix": "/m"
"name": "Reddit", },
"url": "https://www.reddit.com/search?q=", {
"prefix": "/r" "name": "Reddit",
}, "url": "https://www.reddit.com/search?q=",
{ "prefix": "/r"
"name": "Qwant", },
"url": "https://www.qwant.com/?q=", {
"prefix": "/q" "name": "Qwant",
}, "url": "https://www.qwant.com/?q=",
{ "prefix": "/q"
"name": "Soundcloud", },
"url": "https://soundcloud.com/search?q=", {
"prefix": "/so" "name": "Soundcloud",
}, "url": "https://soundcloud.com/search?q=",
{ "prefix": "/so"
"name": "Spotify", },
"url": "https://open.spotify.com/search/results/", {
"prefix": "/s" "name": "Spotify",
}, "url": "https://open.spotify.com/search/results/",
{ "prefix": "/s"
"name": "TheTVDB", },
"url": "https://www.thetvdb.com/search?q=", {
"prefix": "/tv" "name": "TheTVDB",
}, "url": "https://www.thetvdb.com/search?q=",
{ "prefix": "/tv"
"name": "Trakt", },
"url": "https://trakt.tv/search?query=", {
"prefix": "/t" "name": "Trakt",
}, "url": "https://trakt.tv/search?query=",
{ "prefix": "/t"
"name": "YouTube", },
"url": "https://youtube.com/results?search_query=", {
"prefix": "/yt" "name": "YouTube",
} "url": "https://youtube.com/results?search_query=",
] "prefix": "/yt"
}
]
}
} }

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { ISearchProviderProps } from "../components/searchBar"; import { ISearchProps } from "../components/searchBar";
import { IBookmarkGroupProps } from "../components/bookmarkGroup"; import { IBookmarkGroupProps } from "../components/bookmarkGroup";
import { IAppCategoryProps } from "../components/appCategory"; import { IAppCategoryProps } from "../components/appCategory";
import { IAppProps } from "../components/app"; import { IAppProps } from "../components/app";
@ -22,8 +22,8 @@ const handleResponse = (response: Response) => {
throw new Error(errorMessage); throw new Error(errorMessage);
}; };
export interface ISearchProviderDataProps { export interface ISearchDataProps {
providers: Array<ISearchProviderProps>; search: ISearchProps;
error: string | boolean; error: string | boolean;
} }
@ -67,7 +67,10 @@ const defaults = {
error: false, error: false,
}, },
search: { search: {
providers: [], search: {
defaultProvider: "https://google.com/search?q=",
providers: [],
},
error: false, error: false,
}, },
theme: { theme: {
@ -199,7 +202,7 @@ export const useFetcher = () => {
const [ const [
searchProviderData, searchProviderData,
setSearchProviderData, setSearchProviderData,
] = useState<ISearchProviderDataProps>(defaults.search); ] = useState<ISearchDataProps>(defaults.search);
const [themeData, setThemeData] = useState<IThemeDataProps>(defaults.theme); const [themeData, setThemeData] = useState<IThemeDataProps>(defaults.theme);
@ -211,7 +214,7 @@ export const useFetcher = () => {
const callback = useCallback(() => { const callback = useCallback(() => {
(inProduction ? fetchProduction : fetchDevelopment).then( (inProduction ? fetchProduction : fetchDevelopment).then(
([appData, bookmarkData, searchData, themeData, imprintData, greeterData]: [IAppDataProps, IBookmarkDataProps, ISearchProviderDataProps, IThemeDataProps, IImprintDataProps, IGreeterDataProps]) => { ([appData, bookmarkData, searchData, themeData, imprintData, greeterData]: [IAppDataProps, IBookmarkDataProps, ISearchDataProps, IThemeDataProps, IImprintDataProps, IGreeterDataProps]) => {
setAppData((appData.error) ? appData : { ...appData, error: false }); setAppData((appData.error) ? appData : { ...appData, error: false });
setBookmarkData((bookmarkData.error) ? bookmarkData : { ...bookmarkData, error: false }); setBookmarkData((bookmarkData.error) ? bookmarkData : { ...bookmarkData, error: false });
setSearchProviderData((searchData.error) ? searchData : { ...searchData, error: false }); setSearchProviderData((searchData.error) ? searchData : { ...searchData, error: false });