Bläddra i källkod

Added option to set secondary search provider

Paweł Malak 3 år sedan
förälder
incheckning
16121ff547

+ 1 - 0
CHANGELOG.md

@@ -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

+ 16 - 11
client/src/components/SearchBar/SearchBar.tsx

@@ -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') {

+ 29 - 1
client/src/components/Settings/GeneralSettings/GeneralSettings.tsx

@@ -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

+ 1 - 0
client/src/interfaces/Config.ts

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

+ 1 - 0
client/src/interfaces/Forms.ts

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

+ 3 - 2
client/src/interfaces/SearchResult.ts

@@ -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;
 }

+ 26 - 11
client/src/utility/searchParser.ts

@@ -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);
+  };
+
+  const primarySearch = findProvider(prefix);
+  const secondarySearch = findProvider(config.secondarySearchProvider);
 
-  // If search provider was found
-  if (query) {
-    result.query = query;
-    result.search = search;
+  // 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;
   }
 

+ 1 - 0
client/src/utility/templateObjects/configTemplate.ts

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

+ 1 - 0
utils/init/initialConfig.json

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