mirror of
https://github.com/Lissy93/dashy.git
synced 2024-11-28 05:14:08 +03:00
🔀 Merge pull request #185 from Lissy93/FEATURE/web-search
[FEATURE] Web Search Functionality
This commit is contained in:
commit
56272e5dbb
5
.github/CHANGELOG.md
vendored
5
.github/CHANGELOG.md
vendored
@ -1,5 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## ✨ 1.6.9 - Web Search Feature [PR #185](https://github.com/Lissy93/dashy/pull/185)
|
||||||
|
- Adds ability to search the web directly from Dashy by pressing enter on the search bar
|
||||||
|
- Adds configuration options, for setting default search engine, opening method and disabling
|
||||||
|
- Adds text under search bar, implements into minimal view also
|
||||||
|
|
||||||
## ⚡️ 1.6.8 - Improved Loading Experience [PR #183](https://github.com/Lissy93/dashy/pull/183)
|
## ⚡️ 1.6.8 - Improved Loading Experience [PR #183](https://github.com/Lissy93/dashy/pull/183)
|
||||||
- During app initialization, show the build progress and status message
|
- During app initialization, show the build progress and status message
|
||||||
- While requests are being made, show loader at top of screen
|
- While requests are being made, show loader at top of screen
|
||||||
|
5
.github/CODEOWNERS
vendored
5
.github/CODEOWNERS
vendored
@ -4,12 +4,11 @@
|
|||||||
# Each line starts with file pattern, followed by one or more owners
|
# Each line starts with file pattern, followed by one or more owners
|
||||||
# Codeowners Docs: https://github.blog/2017-07-06-introducing-code-owners/
|
# Codeowners Docs: https://github.blog/2017-07-06-introducing-code-owners/
|
||||||
|
|
||||||
# Repo Owner
|
# Repo Owners
|
||||||
* @lissy93
|
* @lissy93
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
src/assets/locales/de.json @niklashere
|
src/assets/locales/fr.json @EVOTk
|
||||||
src/assets/locales/nl.json @evroon
|
|
||||||
|
|
||||||
# Bot PR Permissions
|
# Bot PR Permissions
|
||||||
docs/assets/CONTRIBUTORS.svg @liss-bot
|
docs/assets/CONTRIBUTORS.svg @liss-bot
|
||||||
|
12
README.md
12
README.md
@ -327,6 +327,8 @@ You can change the view from the UI, using the switch icon in the top-right corn
|
|||||||
|
|
||||||
## Searching and Shortcuts 🔎
|
## Searching and Shortcuts 🔎
|
||||||
|
|
||||||
|
> For full documentation on searching, see: [**Searching & Shortcuts**](./docs/searching.md)
|
||||||
|
|
||||||
Quickly finding and launching applications is the primary aim of Dashy. To that end instant search and customizable keyboard shortcuts are built-in.
|
Quickly finding and launching applications is the primary aim of Dashy. To that end instant search and customizable keyboard shortcuts are built-in.
|
||||||
|
|
||||||
To start filtering, just start typing. No need to select the search bar or use any special key. You can then use either the tab key or arrow keys to select and move between results, and hit enter to launch the currently selected application. You can also use `Alt + Enter` on a selected app to launch it in a popup modal, `Ctrl + Enter` to open in new tab, or right-click on it to see all opening methods.
|
To start filtering, just start typing. No need to select the search bar or use any special key. You can then use either the tab key or arrow keys to select and move between results, and hit enter to launch the currently selected application. You can also use `Alt + Enter` on a selected app to launch it in a popup modal, `Ctrl + Enter` to open in new tab, or right-click on it to see all opening methods.
|
||||||
@ -353,6 +355,16 @@ Example:
|
|||||||
hotkey: 8
|
hotkey: 8
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To search the web directly through Dashy, just press enter after typing your query. Options for web search are set under `appConfig.webSearch`. There is built in support for [10+ search engines](./docs/searching.md#setting-search-engine), or [use your own custom provider](./docs/searching.md#using-custom-search-engine) or self-hosted instance.
|
||||||
|
To disable web search all together, set: `webSearch: { disableWebSearch: true }`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
appConfig:
|
||||||
|
webSearch:
|
||||||
|
searchEngine: duckduckgo
|
||||||
|
openingMethod: newtab
|
||||||
|
```
|
||||||
|
|
||||||
Hit `Esc` at anytime to close any open apps, clear the search field, or hide any modals.
|
Hit `Esc` at anytime to close any open apps, clear the search field, or hide any modals.
|
||||||
|
|
||||||
**[⬆️ Back to Top](#dashy)**
|
**[⬆️ Back to Top](#dashy)**
|
||||||
|
@ -60,6 +60,7 @@ To disallow any changes from being written to disk via the UI config editor, set
|
|||||||
**`startingView`** | `enum` | _Optional_ | Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI. Can be either `default`, `minimal` or `workspace`. Defaults to `default`
|
**`startingView`** | `enum` | _Optional_ | Which page to load by default, and on the base page or domain root. You can still switch to different views from within the UI. Can be either `default`, `minimal` or `workspace`. Defaults to `default`
|
||||||
**`statusCheck`** | `boolean` | _Optional_ | When set to `true`, Dashy will ping each of your services and display their status as a dot next to each item. This can be overridden by setting `statusCheck` under each item. Defaults to `false`
|
**`statusCheck`** | `boolean` | _Optional_ | When set to `true`, Dashy will ping each of your services and display their status as a dot next to each item. This can be overridden by setting `statusCheck` under each item. Defaults to `false`
|
||||||
**`statusCheckInterval`** | `boolean` | _Optional_ | The number of seconds between checks. If set to `0` then service will only be checked on initial page load, which is usually the desired functionality. If value is less than `10` you may experience a hit in performance. Defaults to `0`
|
**`statusCheckInterval`** | `boolean` | _Optional_ | The number of seconds between checks. If set to `0` then service will only be checked on initial page load, which is usually the desired functionality. If value is less than `10` you may experience a hit in performance. Defaults to `0`
|
||||||
|
**`webSearch`** | `object` | _Optional_ | Configuration options for the web search feature, set your default search engine, opening method or disable web search. See [`webSearch`](#appconfigwebsearch-optional)
|
||||||
**`backgroundImg`** | `string` | _Optional_ | Path to an optional full-screen app background image. This can be either remote (http) or local (/). Note that this will slow down initial load
|
**`backgroundImg`** | `string` | _Optional_ | Path to an optional full-screen app background image. This can be either remote (http) or local (/). Note that this will slow down initial load
|
||||||
**`enableFontAwesome`** | `boolean` | _Optional_ | Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons
|
**`enableFontAwesome`** | `boolean` | _Optional_ | Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons
|
||||||
**`fontAwesomeKey`** | `string` | _Optional_ | If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. `13014ae648`)
|
**`fontAwesomeKey`** | `string` | _Optional_ | If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. `13014ae648`)
|
||||||
@ -115,6 +116,17 @@ For more info, see the **[Authentication Docs](/docs/authentication.md)**
|
|||||||
|
|
||||||
**[⬆️ Back to Top](#configuring)**
|
**[⬆️ Back to Top](#configuring)**
|
||||||
|
|
||||||
|
### `appConfig.webSearch` _(optional)_
|
||||||
|
|
||||||
|
**Field** | **Type** | **Required**| **Description**
|
||||||
|
--- | --- | --- | ---
|
||||||
|
**`disableWebSearch`** | `string` | _Optional_ | Web search is enabled by default, but can be disabled by setting this property to `true`
|
||||||
|
**`searchEngine`** | `string` | _Optional_ | Set the key name for your search engine. Can also use a custom engine by setting this property to `custom`. Currently supported: `duckduckgo`, `google`, `whoogle`, `qwant`, `startpage`, `searx-bar` and `searx-info`. Defaults to `duckduckgo`
|
||||||
|
**`customSearchEngine`** | `string` | _Optional_ | You can also use a custom search engine, or your own self-hosted instance. This requires `searchEngine: custom` to be set. Then add the URL of your service, with GET query string included here
|
||||||
|
**`openingMethod`** | `string` | _Optional_ | Set your preferred opening method for search results: `newtab`, `sametab`, `workspace`. Defaults to `newtab`
|
||||||
|
|
||||||
|
|
||||||
|
**[⬆️ Back to Top](#configuring)**
|
||||||
|
|
||||||
### `appConfig.hideComponents` _(optional)_
|
### `appConfig.hideComponents` _(optional)_
|
||||||
|
|
||||||
|
@ -47,7 +47,37 @@ For apps that you use regularly, you can set a custom keybinding. Use the `hotke
|
|||||||
|
|
||||||
In the above example, pressing <kbd>2</kbd> will launch Bookstack. Or hitting <kbd>3</kbd> will open Git in the workspace view.
|
In the above example, pressing <kbd>2</kbd> will launch Bookstack. Or hitting <kbd>3</kbd> will open Git in the workspace view.
|
||||||
|
|
||||||
|
## Web Search
|
||||||
|
It's possible to search the web directly from Dashy, which might be useful if you're using Dashy as your start page. This can be done by typing your query as normal, and then pressing <kbd>⏎</kbd>. Web search options are configured under `appConfig.webSearch`.
|
||||||
|
|
||||||
|
#### Setting Search Engine
|
||||||
|
Set your default search engine using the `webSearch.searchEngine` property. This defaults to DuckDuckGo. Search engine must be referenced by their key, the following providers are supported:
|
||||||
|
- [`duckduckgo`](https://duckduckgo.com), [`google`](https://google.com), [`whoogle`](https://whoogle.sdf.org), [`qwant`](https://www.qwant.com), [`startpage`](https://www.startpage.com), [`searx-bar`](https://searx.bar), [`searx-info`](https://searx.info)
|
||||||
|
- [`searx-tiekoetter`](https://searx.tiekoetter.com), [`searx-bissisoft`](https://searx.bissisoft.com), [`ecosia`](https://www.ecosia.org), [`metager`](https://metager.org/meta), [`swisscows`](https://swisscows.com), [`mojeek`](https://www.mojeek.com)
|
||||||
|
- [`wikipedia`](https://en.wikipedia.org), [`wolframalpha`](https://www.wolframalpha.com), [`stackoverflow`](https://stackoverflow.com), [`github`](https://github.com), [`reddit`](https://www.reddit.com), [`youtube`](https://youtube.com), [`bbc`](https://www.bbc.co.uk)
|
||||||
|
|
||||||
|
#### Using Custom Search Engine
|
||||||
|
You can also use a custom search engine, that isn't included in the above list (like a self-hosted instance of [Whoogle](https://github.com/benbusby/whoogle-search) or [Searx](https://searx.github.io/searx/)). Set `searchEngine: custom`, and then specify the URL (plus query params) to you're search engine under `customSearchEngine`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```yaml
|
||||||
|
appConfig:
|
||||||
|
webSearch:
|
||||||
|
searchEngine: custom
|
||||||
|
customSearchEngine: 'https://searx.local/search?q='
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Setting Opening Method
|
||||||
|
In a similar way to opening apps, you can specify where you would like search results to be opened. This is done under the `openingMethod` attribute, and can be set to either `newtab`, `sametab` or `workspace`. By default results are opened in a new tab.
|
||||||
|
|
||||||
|
#### Disabling Web Search
|
||||||
|
Web search can be disabled, by setting `disableWebSearch`, for example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
appConfig:
|
||||||
|
webSearch: { disableWebSearch: true }
|
||||||
|
```
|
||||||
|
|
||||||
## Clearing Search
|
## Clearing Search
|
||||||
You can clear your search term at any time, by pressing <kbd>Esc</kbd>.
|
You can clear your search term at any time, resting the UI to it's initial state, by pressing <kbd>Esc</kbd>.
|
||||||
This can also be used to close an open pop-up modal.
|
This can also be used to close any open pop-up modals.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Dashy",
|
"name": "Dashy",
|
||||||
"version": "1.6.8",
|
"version": "1.6.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "server",
|
"main": "server",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
"search": {
|
"search": {
|
||||||
"search-label": "Search",
|
"search-label": "Search",
|
||||||
"search-placeholder": "Start typing to filter",
|
"search-placeholder": "Start typing to filter",
|
||||||
"clear-search-tooltip": "Clear Search"
|
"clear-search-tooltip": "Clear Search",
|
||||||
|
"enter-to-search-web": "Press enter to search the web"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Dashy",
|
"title": "Dashy",
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
"search": {
|
"search": {
|
||||||
"search-label": "Recherche",
|
"search-label": "Recherche",
|
||||||
"search-placeholder": "Commencez à taper pour filtrer",
|
"search-placeholder": "Commencez à taper pour filtrer",
|
||||||
"clear-search-tooltip": "Effacer la recherche"
|
"clear-search-tooltip": "Effacer la recherche",
|
||||||
|
"enter-to-search-web": "Appuyez sur entrée pour rechercher sur le Web"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "Dashy",
|
"title": "Dashy",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<form>
|
<form @submit.prevent="searchSubmitted">
|
||||||
|
<div class="minimal-search-wrap">
|
||||||
<input
|
<input
|
||||||
id="filter-tiles"
|
id="filter-tiles"
|
||||||
v-model="input"
|
v-model="input"
|
||||||
@ -7,7 +8,12 @@
|
|||||||
class="minimal-search"
|
class="minimal-search"
|
||||||
:placeholder="$t('search.search-placeholder')"
|
:placeholder="$t('search.search-placeholder')"
|
||||||
v-on:input="userIsTypingSomething"
|
v-on:input="userIsTypingSomething"
|
||||||
@keydown.esc="clearFilterInput" />
|
@keydown.esc="clearFilterInput"
|
||||||
|
/>
|
||||||
|
<p v-if="webSearchEnabled && input.length > 0" class="web-search-note">
|
||||||
|
{{ $t('search.enter-to-search-web') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<i v-if="input.length > 0"
|
<i v-if="input.length > 0"
|
||||||
class="clear-search"
|
class="clear-search"
|
||||||
:title="$t('search.clear-search-tooltip')"
|
:title="$t('search.clear-search-tooltip')"
|
||||||
@ -17,11 +23,19 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
import router from '@/router';
|
||||||
import ArrowKeyNavigation from '@/utils/ArrowKeyNavigation';
|
import ArrowKeyNavigation from '@/utils/ArrowKeyNavigation';
|
||||||
|
import ErrorHandler from '@/utils/ErrorHandler';
|
||||||
import { getCustomKeyShortcuts } from '@/utils/ConfigHelpers';
|
import { getCustomKeyShortcuts } from '@/utils/ConfigHelpers';
|
||||||
|
import {
|
||||||
|
searchEngineUrls,
|
||||||
|
defaultSearchEngine,
|
||||||
|
defaultSearchOpeningMethod,
|
||||||
|
} from '@/utils/defaults';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MinimalSearch',
|
name: 'MinimalSearch',
|
||||||
|
inject: ['config'],
|
||||||
props: {
|
props: {
|
||||||
active: Boolean,
|
active: Boolean,
|
||||||
},
|
},
|
||||||
@ -32,6 +46,15 @@ export default {
|
|||||||
getCustomKeyShortcuts,
|
getCustomKeyShortcuts,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
webSearchEnabled() {
|
||||||
|
const { appConfig } = this.config;
|
||||||
|
if (appConfig && appConfig.webSearch) {
|
||||||
|
return !appConfig.webSearch.disableWebSearch;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/* Emmits users's search term up to parent */
|
/* Emmits users's search term up to parent */
|
||||||
userIsTypingSomething() {
|
userIsTypingSomething() {
|
||||||
@ -44,6 +67,7 @@ export default {
|
|||||||
document.activeElement.blur(); // Remove focus
|
document.activeElement.blur(); // Remove focus
|
||||||
this.akn.resetIndex(); // Reset current element index
|
this.akn.resetIndex(); // Reset current element index
|
||||||
},
|
},
|
||||||
|
/* Launches a given app when hotkey pressed */
|
||||||
handleHotKey(key) {
|
handleHotKey(key) {
|
||||||
const usersHotKeys = this.getCustomKeyShortcuts();
|
const usersHotKeys = this.getCustomKeyShortcuts();
|
||||||
usersHotKeys.forEach((hotkey) => {
|
usersHotKeys.forEach((hotkey) => {
|
||||||
@ -52,6 +76,7 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/* Filter results as user types */
|
||||||
startFiltering(event) {
|
startFiltering(event) {
|
||||||
const currentElem = document.activeElement.id;
|
const currentElem = document.activeElement.id;
|
||||||
const { key, keyCode } = event;
|
const { key, keyCode } = event;
|
||||||
@ -72,6 +97,42 @@ export default {
|
|||||||
this.clearFilterInput();
|
this.clearFilterInput();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/* Open web search results in users desired method */
|
||||||
|
launchWebSearch(url, method) {
|
||||||
|
switch (method) {
|
||||||
|
case 'newtab':
|
||||||
|
window.open(url, '_blank');
|
||||||
|
break;
|
||||||
|
case 'sametab':
|
||||||
|
window.open(url, '_self');
|
||||||
|
break;
|
||||||
|
case 'workspace':
|
||||||
|
router.push({ name: 'workspace', query: { url } });
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ErrorHandler(`Unknown opening method: ${method}`);
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* If web search enabled, then launch search results when enter is pressed */
|
||||||
|
searchSubmitted() {
|
||||||
|
// Get search preferences from appConfig
|
||||||
|
const { appConfig } = this.config;
|
||||||
|
const searchPrefs = appConfig.webSearch || {};
|
||||||
|
if (this.webSearchEnabled) { // Only proceed if user hasn't disabled web search
|
||||||
|
const openingMethod = searchPrefs.openingMethod || defaultSearchOpeningMethod;
|
||||||
|
// Get search engine, and make URL
|
||||||
|
const searchEngine = searchPrefs.searchEngine || defaultSearchEngine;
|
||||||
|
let searchUrl = searchEngineUrls[searchEngine];
|
||||||
|
if (!searchUrl) ErrorHandler(`Search engine not found - ${searchEngine}`);
|
||||||
|
if (searchEngine === 'custom' && searchPrefs.customSearchEngine) {
|
||||||
|
searchUrl = searchPrefs.customSearchEngine;
|
||||||
|
}
|
||||||
|
// Append users encoded query onto search URL, and launch
|
||||||
|
searchUrl += encodeURIComponent(this.input);
|
||||||
|
this.launchWebSearch(searchUrl, openingMethod);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('keydown', this.startFiltering);
|
window.addEventListener('keydown', this.startFiltering);
|
||||||
@ -89,6 +150,17 @@ export default {
|
|||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
.minimal-search-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
p.web-search-note {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--minimal-view-search-color);
|
||||||
|
opacity: var(--dimming-factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
input {
|
input {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
@ -107,7 +179,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.clear-search {
|
.clear-search {
|
||||||
//position: absolute;
|
|
||||||
color: var(--minimal-view-search-color);
|
color: var(--minimal-view-search-color);
|
||||||
padding: 0.15rem 0.5rem 0.2rem 0.5rem;
|
padding: 0.15rem 0.5rem 0.2rem 0.5rem;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<form>
|
<form @submit.prevent="searchSubmitted">
|
||||||
<label for="filter-tiles">{{ $t('search.search-label') }}</label>
|
<label for="filter-tiles">{{ $t('search.search-label') }}</label>
|
||||||
|
<div class="search-wrap">
|
||||||
<input
|
<input
|
||||||
id="filter-tiles"
|
id="filter-tiles"
|
||||||
v-model="input"
|
v-model="input"
|
||||||
@ -8,6 +9,10 @@
|
|||||||
:placeholder="$t('search.search-placeholder')"
|
:placeholder="$t('search.search-placeholder')"
|
||||||
v-on:input="userIsTypingSomething"
|
v-on:input="userIsTypingSomething"
|
||||||
@keydown.esc="clearFilterInput" />
|
@keydown.esc="clearFilterInput" />
|
||||||
|
<p v-if="webSearchEnabled && input.length > 0" class="web-search-note">
|
||||||
|
{{ $t('search.enter-to-search-web') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<i v-if="input.length > 0"
|
<i v-if="input.length > 0"
|
||||||
class="clear-search"
|
class="clear-search"
|
||||||
:title="$t('search.clear-search-tooltip')"
|
:title="$t('search.clear-search-tooltip')"
|
||||||
@ -16,12 +21,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import router from '@/router';
|
||||||
import ArrowKeyNavigation from '@/utils/ArrowKeyNavigation';
|
import ArrowKeyNavigation from '@/utils/ArrowKeyNavigation';
|
||||||
|
import ErrorHandler from '@/utils/ErrorHandler';
|
||||||
import { getCustomKeyShortcuts } from '@/utils/ConfigHelpers';
|
import { getCustomKeyShortcuts } from '@/utils/ConfigHelpers';
|
||||||
|
import { searchEngineUrls, defaultSearchEngine, defaultSearchOpeningMethod } from '@/utils/defaults';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FilterTile',
|
name: 'FilterTile',
|
||||||
|
inject: ['config'],
|
||||||
props: {
|
props: {
|
||||||
active: Boolean,
|
active: Boolean,
|
||||||
},
|
},
|
||||||
@ -32,6 +40,15 @@ export default {
|
|||||||
getCustomKeyShortcuts,
|
getCustomKeyShortcuts,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
webSearchEnabled() {
|
||||||
|
const { appConfig } = this.config;
|
||||||
|
if (appConfig && appConfig.webSearch) {
|
||||||
|
return !appConfig.webSearch.disableWebSearch;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
window.addEventListener('keydown', (event) => {
|
window.addEventListener('keydown', (event) => {
|
||||||
const currentElem = document.activeElement.id;
|
const currentElem = document.activeElement.id;
|
||||||
@ -74,6 +91,40 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
launchWebSearch(url, method) {
|
||||||
|
switch (method) {
|
||||||
|
case 'newtab':
|
||||||
|
window.open(url, '_blank');
|
||||||
|
break;
|
||||||
|
case 'sametab':
|
||||||
|
window.open(url, '_self');
|
||||||
|
break;
|
||||||
|
case 'workspace':
|
||||||
|
router.push({ name: 'workspace', query: { url } });
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ErrorHandler(`Unknown opening method: ${method}`);
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
searchSubmitted() {
|
||||||
|
// Get search preferences from appConfig
|
||||||
|
const { appConfig } = this.config;
|
||||||
|
const searchPrefs = appConfig.webSearch || {};
|
||||||
|
if (this.webSearchEnabled) { // Only proceed if user hasn't disabled web search
|
||||||
|
const openingMethod = searchPrefs.openingMethod || defaultSearchOpeningMethod;
|
||||||
|
// Get search engine, and make URL
|
||||||
|
const searchEngine = searchPrefs.searchEngine || defaultSearchEngine;
|
||||||
|
let searchUrl = searchEngineUrls[searchEngine];
|
||||||
|
if (!searchUrl) ErrorHandler(`Search engine not found - ${searchEngine}`);
|
||||||
|
if (searchEngine === 'custom' && searchPrefs.customSearchEngine) {
|
||||||
|
searchUrl = searchPrefs.customSearchEngine;
|
||||||
|
}
|
||||||
|
// Append users encoded query onto search URL, and launch
|
||||||
|
searchUrl += encodeURIComponent(this.input);
|
||||||
|
this.launchWebSearch(searchUrl, openingMethod);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -94,6 +145,17 @@ export default {
|
|||||||
border-radius: 0 0 var(--curve-factor-navbar) 0;
|
border-radius: 0 0 var(--curve-factor-navbar) 0;
|
||||||
padding: 0 0.2rem 0.2rem 0;
|
padding: 0 0.2rem 0.2rem 0;
|
||||||
background: var(--search-container-background);
|
background: var(--search-container-background);
|
||||||
|
.search-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
p.web-search-note {
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--minimal-view-search-color);
|
||||||
|
opacity: var(--dimming-factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
label {
|
label {
|
||||||
display: inline;
|
display: inline;
|
||||||
color: var(--search-label-color);
|
color: var(--search-label-color);
|
||||||
@ -120,7 +182,7 @@ export default {
|
|||||||
.clear-search {
|
.clear-search {
|
||||||
//position: absolute;
|
//position: absolute;
|
||||||
color: var(--settings-text-color);
|
color: var(--settings-text-color);
|
||||||
padding: 0 0.4rem;
|
padding: 0 0.3rem 0.1rem 0.3rem;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
opacity: var(--dimming-factor);
|
opacity: var(--dimming-factor);
|
||||||
@ -130,7 +192,7 @@ export default {
|
|||||||
top: 1rem;
|
top: 1rem;
|
||||||
border: 1px solid var(--settings-text-color);
|
border: 1px solid var(--settings-text-color);
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin: 0.5rem;
|
margin: 0.25rem;
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
background: var(--background-darker);
|
background: var(--background-darker);
|
||||||
|
@ -216,6 +216,53 @@
|
|||||||
"default": 0,
|
"default": 0,
|
||||||
"description": "How often to recheck statuses. If set to 0, status will only be checked on page load"
|
"description": "How often to recheck statuses. If set to 0, status will only be checked on page load"
|
||||||
},
|
},
|
||||||
|
"webSearch": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Configure options for web search",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"disableWebSearch": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": "false",
|
||||||
|
"description": "If set to true, web search will be disabled all together"
|
||||||
|
},
|
||||||
|
"searchEngine": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "duckduckgo",
|
||||||
|
"description": "Set your default search engine. Reference provider by key, see docs for all supported search engines, or set to custom to use your own",
|
||||||
|
"examples": [
|
||||||
|
"duckduckgo",
|
||||||
|
"google",
|
||||||
|
"whoogle",
|
||||||
|
"qwant",
|
||||||
|
"startpage",
|
||||||
|
"searx-bar",
|
||||||
|
"searx-info",
|
||||||
|
"ecosia",
|
||||||
|
"metager",
|
||||||
|
"wikipedia",
|
||||||
|
"wolframalpha",
|
||||||
|
"stackoverflow",
|
||||||
|
"bbc",
|
||||||
|
"custom"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"customSearchEngine": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Set the URL of a self-hosted or custom search engine, including GET query params. You must also set searchEngine: custom"
|
||||||
|
},
|
||||||
|
"openingMethod": {
|
||||||
|
"enum": [
|
||||||
|
"newtab",
|
||||||
|
"sametab",
|
||||||
|
"modal",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
"default": "newtab",
|
||||||
|
"description": "Set where you would like search results to open to"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "Settings for enabling authentication",
|
"description": "Settings for enabling authentication",
|
||||||
|
@ -152,6 +152,35 @@ module.exports = {
|
|||||||
localPath: '/item-icons',
|
localPath: '/item-icons',
|
||||||
faviconName: 'favicon.ico',
|
faviconName: 'favicon.ico',
|
||||||
},
|
},
|
||||||
|
/* URLs for web search engines */
|
||||||
|
searchEngineUrls: {
|
||||||
|
// Common
|
||||||
|
duckduckgo: 'https://duckduckgo.com/?q=',
|
||||||
|
google: 'https://google.com/search?q=',
|
||||||
|
whoogle: 'https://whoogle.sdf.org/search?q=',
|
||||||
|
qwant: 'https://www.qwant.com/?q=',
|
||||||
|
startpage: 'https://www.startpage.com/do/search?query=',
|
||||||
|
// Niche
|
||||||
|
'searx-bar': 'https://searx.bar/search?q=',
|
||||||
|
'searx-info': 'https://searx.info/search?q=',
|
||||||
|
'searx-tiekoetter': 'https://searx.tiekoetter.com/search?q=',
|
||||||
|
'searx-bissisoft': 'https://searx.bissisoft.com/search?q=',
|
||||||
|
ecosia: 'https://www.ecosia.org/search?q=',
|
||||||
|
metager: 'https://metager.org/meta/meta.ger3?eingabe=',
|
||||||
|
swisscows: 'https://swisscows.com/web?query=',
|
||||||
|
mojeek: 'https://www.mojeek.com/search?q=',
|
||||||
|
peekier: 'https://peekier.com/#!',
|
||||||
|
// Specific
|
||||||
|
wikipedia: 'https://en.wikipedia.org/w/?search=',
|
||||||
|
stackoverflow: 'https://stackoverflow.com/search?q=',
|
||||||
|
wolframalpha: 'https://www.wolframalpha.com/input/?i=',
|
||||||
|
reddit: 'https://www.reddit.com/search/?q=',
|
||||||
|
youtube: 'https://youtube.com/results?q=',
|
||||||
|
github: 'https://github.com/search?q=',
|
||||||
|
bbc: 'https://www.bbc.co.uk/search?q=',
|
||||||
|
},
|
||||||
|
defaultSearchEngine: 'duckduckgo',
|
||||||
|
defaultSearchOpeningMethod: 'newtab',
|
||||||
/* Available built-in colors for the theme builder */
|
/* Available built-in colors for the theme builder */
|
||||||
swatches: [
|
swatches: [
|
||||||
['#eb5cad', '#985ceb', '#5346f3', '#5c90eb'],
|
['#eb5cad', '#985ceb', '#5346f3', '#5c90eb'],
|
||||||
|
Loading…
Reference in New Issue
Block a user