From bb86ffac8b51abb8ccf14bdfd4c8c9a8e82e3aef Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 24 Apr 2020 00:01:04 +0200 Subject: [PATCH] added suggestion to search --- src/components/Search.tsx | 76 ++++++++++++++++++++++++--- src/components/Sugestion.tsx | 17 ++++++ src/functions/getGoogleSuggestions.ts | 17 ++++++ src/style/search.scss | 21 +++++--- src/style/suggestion.scss | 12 +++++ src/types/GoogleSuggestions.ts | 31 +++++++++++ src/types/Suggestion.ts | 12 +++++ 7 files changed, 172 insertions(+), 14 deletions(-) create mode 100644 src/components/Sugestion.tsx create mode 100644 src/functions/getGoogleSuggestions.ts create mode 100644 src/style/suggestion.scss create mode 100644 src/types/GoogleSuggestions.ts create mode 100644 src/types/Suggestion.ts diff --git a/src/components/Search.tsx b/src/components/Search.tsx index e8c88ff..de05c2d 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -1,40 +1,102 @@ import * as React from "react"; import "../style/search.scss"; +import Sugestion from "./Sugestion"; +import { Suggestion, SuggestionType } from "../types/suggestion"; +import getGoogleSuggestions from "../functions/getGoogleSuggestions"; -class Search extends React.Component { +interface State { + sugestions: Suggestion[]; +} + +class Search extends React.Component<{}, State> { private searchInput = React.createRef() constructor(props) { super(props); + + this.state = { + sugestions: [] + }; } handleQuery(query: string) { this.search(query); } - search(query: string){ + search(query: string) { const url = new URL("https://duckduckgo.com/"); const param = new URLSearchParams(); - param.append("q",query); + param.append("q", query); url.search = param.toString(); window.location.href = url.toString(); } - onKeyDown(event: React.KeyboardEvent) { + async sugest(input: string) { + if (input === "") { + this.setState({ + sugestions: [] + }); + } else { + const results = await getGoogleSuggestions(input); + + const newSuggestionState: Suggestion[] = results.suggestions.map((e) => { + return { + display: e, + type: SuggestionType.QUERY + }; + }); + + this.setState({ + sugestions: newSuggestionState + }); + } + + + } + + onKeyDown(event: React.KeyboardEvent) { if (event.key === 'Enter') { this.handleQuery(this.searchInput.current.value); + } else if (event.key === "ArrowDown") { + console.log("down"); + } else if (event.key === "ArrowUp") { + console.log("up"); + } + } + + onChange() { + this.sugest(this.searchInput.current.value); + } + + onSugestionClick(e: Suggestion) { + if (e.type === SuggestionType.QUERY) { + this.search(e.display); + } else { + window.location.href = e.url; } } render(): JSX.Element { return
- this.onKeyDown(e)} + onKeyDown={(e) => this.onKeyDown(e)} + onChange={() => this.onChange()} ref={this.searchInput} - /> + autoComplete="off" + /> + +
+ {this.state.sugestions.map((e) => { + return { this.onSugestionClick(e); }} + />; + })} +
; } diff --git a/src/components/Sugestion.tsx b/src/components/Sugestion.tsx new file mode 100644 index 0000000..49ebe62 --- /dev/null +++ b/src/components/Sugestion.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +import "../style/suggestion.scss"; +import { Suggestion } from "../types/suggestion"; + +interface Props { + suggestion: Suggestion; + onClick: (event: React.MouseEvent) => void; +} + +const Sugestion = (props: Props) => { + return
+ {props.suggestion.display} +
; +}; + +export default Sugestion; diff --git a/src/functions/getGoogleSuggestions.ts b/src/functions/getGoogleSuggestions.ts new file mode 100644 index 0000000..177980a --- /dev/null +++ b/src/functions/getGoogleSuggestions.ts @@ -0,0 +1,17 @@ +import GoogleSuggestions from "../types/GoogleSuggestions"; + +export default async (query: string): Promise => { + const url = new URL(" http://suggestqueries.google.com/complete/search"); + const param = new URLSearchParams(); + param.append("q", query); + param.append("client", "firefox"); // TODO check if the result are different on different clients + url.search = param.toString(); + + const response = await fetch(url.toString()); + const results = await response.json(); + + return { + query: results[0], + suggestions: results[1] + }; +}; diff --git a/src/style/search.scss b/src/style/search.scss index 5b0c9a6..56e5261 100644 --- a/src/style/search.scss +++ b/src/style/search.scss @@ -1,12 +1,19 @@ .search-component{ - text-align: center; - margin-top: 2em; - margin-bottom: 2em; - + margin: 2em auto 2em auto; + width: 50%; + position: relative; + input[type=text]{ - width: 40%; + width: 100%; border: none; - padding: 0.5em 1.5em; + padding: 0.5em 1em; + box-sizing: border-box; } -} \ No newline at end of file + + .suggestion-area{ + position: absolute; + right: 0; + left: 0; + } +} diff --git a/src/style/suggestion.scss b/src/style/suggestion.scss new file mode 100644 index 0000000..dd492f3 --- /dev/null +++ b/src/style/suggestion.scss @@ -0,0 +1,12 @@ +.suggestion-component{ + padding: 0.2em 1em; + background-color: white; + color: black; + border: 1px solid #d4d4d4; + border-top: none; + cursor: pointer; + + &:hover { + background-color: #d4d4d4; + } +} diff --git a/src/types/GoogleSuggestions.ts b/src/types/GoogleSuggestions.ts new file mode 100644 index 0000000..46a2075 --- /dev/null +++ b/src/types/GoogleSuggestions.ts @@ -0,0 +1,31 @@ +/* + Example if client == chrome: + [ + "hello w", + ["hello world","hello world anime","hello world java","hello world c","hello world python","hello world html","hello world mhw","hello welcome home"], + ["","","","","","","",""], + [], + { + "google:clientdata":{"bpc":false,"tlw":false}, + "google:suggestrelevance":[1250,1050,850,700,601,600,551,550], + "google:suggesttype":["QUERY","QUERY","QUERY","QUERY","QUERY","QUERY","QUERY","QUERY"], + "google:verbatimrelevance":851 + } + ] + + Example if client == firefox: + [ + "hello wo", + [ + "hello world","hello world anime","hello world java","hello world c","hello world python","hello world html", + "hello world mhw","hello world anime stream","hello world programm","hello world anime ger sub" + ] + ] +*/ + +interface GoogleSuggestions { + query: string; + suggestions: string[]; +} + +export default GoogleSuggestions; diff --git a/src/types/Suggestion.ts b/src/types/Suggestion.ts new file mode 100644 index 0000000..0d5223f --- /dev/null +++ b/src/types/Suggestion.ts @@ -0,0 +1,12 @@ +enum SuggestionType { + QUICK, + QUERY +} + +interface Suggestion { + display: string; + type: SuggestionType; + url?: string; +} + +export { SuggestionType, Suggestion };