v0.3: Extension #3
@ -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<HTMLInputElement>()
 | 
			
		||||
 | 
			
		||||
	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<HTMLInputElement>) {
 | 
			
		||||
		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 <div className="search-component" >
 | 
			
		||||
			<input type="text" 
 | 
			
		||||
			<input type="text"
 | 
			
		||||
				autoFocus
 | 
			
		||||
				onKeyDown={(e)=>this.onKeyDown(e)}
 | 
			
		||||
				onKeyDown={(e) => this.onKeyDown(e)}
 | 
			
		||||
				onChange={() => this.onChange()}
 | 
			
		||||
				ref={this.searchInput}
 | 
			
		||||
				/>
 | 
			
		||||
				autoComplete="off"
 | 
			
		||||
			/>
 | 
			
		||||
 | 
			
		||||
			<div className="suggestion-area">
 | 
			
		||||
				{this.state.sugestions.map((e) => {
 | 
			
		||||
					return <Sugestion
 | 
			
		||||
						key={e.display}
 | 
			
		||||
						suggestion={e}
 | 
			
		||||
						onClick={() => { this.onSugestionClick(e); }}
 | 
			
		||||
					/>;
 | 
			
		||||
				})}
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								src/components/Sugestion.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/components/Sugestion.tsx
									
									
									
									
									
										Normal file
									
								
							@ -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<HTMLDivElement, MouseEvent>) => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Sugestion = (props: Props) => {
 | 
			
		||||
	return <div className="suggestion-component" onClick={props.onClick}>
 | 
			
		||||
		{props.suggestion.display}
 | 
			
		||||
	</div>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Sugestion;
 | 
			
		||||
							
								
								
									
										17
									
								
								src/functions/getGoogleSuggestions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/functions/getGoogleSuggestions.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
import GoogleSuggestions from "../types/GoogleSuggestions";
 | 
			
		||||
 | 
			
		||||
export default async (query: string): Promise<GoogleSuggestions> => {
 | 
			
		||||
	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]
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
@ -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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	.suggestion-area{
 | 
			
		||||
		position: absolute;
 | 
			
		||||
		right: 0;
 | 
			
		||||
		left: 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								src/style/suggestion.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/style/suggestion.scss
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								src/types/GoogleSuggestions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/types/GoogleSuggestions.ts
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
							
								
								
									
										12
									
								
								src/types/Suggestion.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/types/Suggestion.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
enum SuggestionType {
 | 
			
		||||
	QUICK,
 | 
			
		||||
	QUERY
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Suggestion {
 | 
			
		||||
	display: string;
 | 
			
		||||
	type: SuggestionType;
 | 
			
		||||
	url?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { SuggestionType, Suggestion };
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user