Added option to set secondary search provider

This commit is contained in:
Paweł Malak 2022-03-25 14:28:40 +01:00
parent 2c0491a5b0
commit 16121ff547
9 changed files with 79 additions and 25 deletions

View File

@ -1,5 +1,6 @@
### v2.3.0 (TBA)
- Added custom theme editor ([#246](https://github.com/pawelmalak/flame/issues/246))
- Added option to set secondary search provider ([#295](https://github.com/pawelmalak/flame/issues/295))
- Fixed bug where pressing Enter with empty search bar would redirect to search results ([#325](https://github.com/pawelmalak/flame/issues/325))
- Fixed bug where user could create empty app or bookmark which was causing page to go blank ([#332](https://github.com/pawelmalak/flame/issues/332))
- Added new theme: Mint

View File

@ -64,16 +64,22 @@ export const SearchBar = (props: Props): JSX.Element => {
};
const searchHandler = (e: KeyboardEvent<HTMLInputElement>) => {
const { isLocal, search, query, isURL, sameTab, rawQuery } = searchParser(
inputRef.current.value
);
const {
isLocal,
encodedURL,
primarySearch,
secondarySearch,
isURL,
sameTab,
rawQuery,
} = searchParser(inputRef.current.value);
if (isLocal) {
setLocalSearch(search);
setLocalSearch(encodedURL);
}
if (e.code === 'Enter' || e.code === 'NumpadEnter') {
if (!query.prefix) {
if (!primarySearch.prefix) {
// Prefix not found -> emit notification
createNotification({
title: 'Error',
@ -91,21 +97,20 @@ export const SearchBar = (props: Props): JSX.Element => {
redirectUrl(bookmarkSearchResult[0].bookmarks[0].url, sameTab);
} else {
// no local results -> search the internet with the default search provider if query is not empty
if (!/^ *$/.test(rawQuery)) {
let template = query.template;
let template = primarySearch.template;
if (query.prefix === 'l') {
template = 'https://duckduckgo.com/?q=';
if (primarySearch.prefix === 'l') {
template = secondarySearch.template;
}
const url = `${template}${search}`;
const url = `${template}${encodedURL}`;
redirectUrl(url, sameTab);
}
}
} else {
// Valid query -> redirect to search results
const url = `${query.template}${search}`;
const url = `${primarySearch.template}${encodedURL}`;
redirectUrl(url, sameTab);
}
} else if (e.code === 'Escape') {

View File

@ -167,7 +167,7 @@ export const GeneralSettings = (): JSX.Element => {
{/* === SEARCH OPTIONS === */}
<SettingsHeadline text="Search" />
<InputGroup>
<label htmlFor="defaultSearchProvider">Default search provider</label>
<label htmlFor="defaultSearchProvider">Primary search provider</label>
<select
id="defaultSearchProvider"
name="defaultSearchProvider"
@ -186,6 +186,34 @@ export const GeneralSettings = (): JSX.Element => {
</select>
</InputGroup>
{formData.defaultSearchProvider === 'l' && (
<InputGroup>
<label htmlFor="secondarySearchProvider">
Secondary search provider
</label>
<select
id="secondarySearchProvider"
name="secondarySearchProvider"
value={formData.secondarySearchProvider}
onChange={(e) => inputChangeHandler(e)}
>
{[...queries, ...customQueries].map((query: Query, idx) => {
const isCustom = idx >= queries.length;
return (
<option key={idx} value={query.prefix}>
{isCustom && '+'} {query.name}
</option>
);
})}
</select>
<span>
Will be used when "Local search" is primary search provider and
there are not any local results
</span>
</InputGroup>
)}
<InputGroup>
<label htmlFor="searchSameTab">
Open search results in the same tab

View File

@ -17,6 +17,7 @@ export interface Config {
hideCategories: boolean;
hideSearch: boolean;
defaultSearchProvider: string;
secondarySearchProvider: string;
dockerApps: boolean;
dockerHost: string;
kubernetesApps: boolean;

View File

@ -10,6 +10,7 @@ export interface WeatherForm {
export interface GeneralForm {
defaultSearchProvider: string;
secondarySearchProvider: string;
searchSameTab: boolean;
pinAppsByDefault: boolean;
pinCategoriesByDefault: boolean;

View File

@ -4,7 +4,8 @@ export interface SearchResult {
isLocal: boolean;
isURL: boolean;
sameTab: boolean;
search: string;
query: Query;
encodedURL: string;
primarySearch: Query;
secondarySearch: Query;
rawQuery: string;
}

View File

@ -1,5 +1,5 @@
import { queries } from './searchQueries.json';
import { Query, SearchResult } from '../interfaces';
import { SearchResult } from '../interfaces';
import { store } from '../store/store';
import { isUrlOrIp } from '.';
@ -8,8 +8,13 @@ export const searchParser = (searchQuery: string): SearchResult => {
isLocal: false,
isURL: false,
sameTab: false,
search: '',
query: {
encodedURL: '',
primarySearch: {
name: '',
prefix: '',
template: '',
},
secondarySearch: {
name: '',
prefix: '',
template: '',
@ -25,20 +30,26 @@ export const searchParser = (searchQuery: string): SearchResult => {
// Match prefix and query
const splitQuery = searchQuery.match(/^\/([a-z]+)[ ](.+)$/i);
// Extract prefix
const prefix = splitQuery ? splitQuery[1] : config.defaultSearchProvider;
const search = splitQuery
// Encode url
const encodedURL = splitQuery
? encodeURIComponent(splitQuery[2])
: encodeURIComponent(searchQuery);
const query = [...queries, ...customQueries].find(
(q: Query) => q.prefix === prefix
);
// Find primary search engine template
const findProvider = (prefix: string) => {
return [...queries, ...customQueries].find((q) => q.prefix === prefix);
};
// If search provider was found
if (query) {
result.query = query;
result.search = search;
const primarySearch = findProvider(prefix);
const secondarySearch = findProvider(config.secondarySearchProvider);
// If search providers were found
if (primarySearch) {
result.primarySearch = primarySearch;
result.encodedURL = encodedURL;
if (prefix === 'l') {
result.isLocal = true;
@ -46,6 +57,10 @@ export const searchParser = (searchQuery: string): SearchResult => {
result.sameTab = config.searchSameTab;
}
if (secondarySearch) {
result.secondarySearch = secondarySearch;
}
return result;
}

View File

@ -17,6 +17,7 @@ export const configTemplate: Config = {
hideCategories: false,
hideSearch: false,
defaultSearchProvider: 'l',
secondarySearchProvider: 'd',
dockerApps: false,
dockerHost: 'localhost',
kubernetesApps: false,

View File

@ -15,6 +15,7 @@
"hideCategories": false,
"hideSearch": false,
"defaultSearchProvider": "l",
"secondarySearchProvider": "d",
"dockerApps": false,
"dockerHost": "localhost",
"kubernetesApps": false,