change search engine
This commit is contained in:
parent
cfed0ac06d
commit
58baa8d935
|
@ -1,4 +1,4 @@
|
||||||
import { SourceGroup, ViewType, ThemeSettings, SchemaTypes } from "../schema-types"
|
import { SourceGroup, ViewType, ThemeSettings, SearchEngines } from "../schema-types"
|
||||||
import { ipcRenderer } from "electron"
|
import { ipcRenderer } from "electron"
|
||||||
|
|
||||||
const settingsBridge = {
|
const settingsBridge = {
|
||||||
|
@ -75,6 +75,13 @@ const settingsBridge = {
|
||||||
ipcRenderer.invoke("set-fetch-interval", interval)
|
ipcRenderer.invoke("set-fetch-interval", interval)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSearchEngine: (): SearchEngines => {
|
||||||
|
return ipcRenderer.sendSync("get-search-engine")
|
||||||
|
},
|
||||||
|
setSearchEngine: (engine: SearchEngines) => {
|
||||||
|
ipcRenderer.invoke("set-search-engine", engine)
|
||||||
|
},
|
||||||
|
|
||||||
getAll: () => {
|
getAll: () => {
|
||||||
return ipcRenderer.sendSync("get-all-settings") as Object
|
return ipcRenderer.sendSync("get-all-settings") as Object
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import intl from "react-intl-universal"
|
import intl from "react-intl-universal"
|
||||||
import QRCode from "qrcode.react"
|
import QRCode from "qrcode.react"
|
||||||
import { cutText, googleSearch } from "../scripts/utils"
|
import { cutText, webSearch, getSearchEngineName } from "../scripts/utils"
|
||||||
import { ContextualMenu, IContextualMenuItem, ContextualMenuItemType, DirectionalHint } from "office-ui-fabric-react/lib/ContextualMenu"
|
import { ContextualMenu, IContextualMenuItem, ContextualMenuItemType, DirectionalHint } from "office-ui-fabric-react/lib/ContextualMenu"
|
||||||
import { ContextMenuType } from "../scripts/models/app"
|
import { ContextMenuType } from "../scripts/models/app"
|
||||||
import { RSSItem } from "../scripts/models/item"
|
import { RSSItem } from "../scripts/models/item"
|
||||||
|
@ -45,6 +45,19 @@ const renderShareQR = (item: IContextualMenuItem) => (
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function getSearchItem(text: string): IContextualMenuItem {
|
||||||
|
const engine = window.settings.getSearchEngine()
|
||||||
|
return {
|
||||||
|
key: "searchText",
|
||||||
|
text: intl.get("context.search", {
|
||||||
|
text: cutText(text, 15),
|
||||||
|
engine: getSearchEngineName(engine)
|
||||||
|
}),
|
||||||
|
iconProps: { iconName: "Search" },
|
||||||
|
onClick: () => webSearch(text, engine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class ContextMenu extends React.Component<ContextMenuProps> {
|
export class ContextMenu extends React.Component<ContextMenuProps> {
|
||||||
getItems = (): IContextualMenuItem[] => {
|
getItems = (): IContextualMenuItem[] => {
|
||||||
switch (this.props.type) {
|
switch (this.props.type) {
|
||||||
|
@ -137,12 +150,7 @@ export class ContextMenu extends React.Component<ContextMenuProps> {
|
||||||
iconProps: { iconName: "Copy" },
|
iconProps: { iconName: "Copy" },
|
||||||
onClick: () => { window.utils.writeClipboard(this.props.text) }
|
onClick: () => { window.utils.writeClipboard(this.props.text) }
|
||||||
},
|
},
|
||||||
{
|
getSearchItem(this.props.text)
|
||||||
key: "searchText",
|
|
||||||
text: intl.get("context.search", { text: cutText(this.props.text, 15) }),
|
|
||||||
iconProps: { iconName: "Search" },
|
|
||||||
onClick: () => { googleSearch(this.props.text) }
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
case ContextMenuType.View: return [
|
case ContextMenuType.View: return [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import intl from "react-intl-universal"
|
import intl from "react-intl-universal"
|
||||||
import { urlTest, byteToMB, calculateItemSize } from "../../scripts/utils"
|
import { urlTest, byteToMB, calculateItemSize, getSearchEngineName } from "../../scripts/utils"
|
||||||
import { ThemeSettings } from "../../schema-types"
|
import { ThemeSettings, SearchEngines } from "../../schema-types"
|
||||||
import { getThemeSettings, setThemeSettings, exportAll } from "../../scripts/settings"
|
import { getThemeSettings, setThemeSettings, exportAll } from "../../scripts/settings"
|
||||||
import { Stack, Label, Toggle, TextField, DefaultButton, ChoiceGroup, IChoiceGroupOption, loadTheme, Dropdown, IDropdownOption, PrimaryButton } from "@fluentui/react"
|
import { Stack, Label, Toggle, TextField, DefaultButton, ChoiceGroup, IChoiceGroupOption, loadTheme, Dropdown, IDropdownOption, PrimaryButton } from "@fluentui/react"
|
||||||
import DangerButton from "../utils/danger-button"
|
import DangerButton from "../utils/danger-button"
|
||||||
|
@ -73,6 +73,16 @@ class AppTab extends React.Component<AppTabProps, AppTabState> {
|
||||||
this.props.setFetchInterval(item.key as number)
|
this.props.setFetchInterval(item.key as number)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchEngineOptions = (): IDropdownOption[] => [
|
||||||
|
SearchEngines.Google, SearchEngines.Bing, SearchEngines.Baidu, SearchEngines.DuckDuckGo
|
||||||
|
].map(engine => ({
|
||||||
|
key: engine,
|
||||||
|
text: getSearchEngineName(engine)
|
||||||
|
}))
|
||||||
|
onSearchEngineChanged = (item: IDropdownOption) => {
|
||||||
|
window.settings.setSearchEngine(item.key as number)
|
||||||
|
}
|
||||||
|
|
||||||
deleteOptions = (): IDropdownOption[] => [
|
deleteOptions = (): IDropdownOption[] => [
|
||||||
{ key: "7", text: intl.get("app.daysAgo", { days: 7 }) },
|
{ key: "7", text: intl.get("app.daysAgo", { days: 7 }) },
|
||||||
{ key: "14", text: intl.get("app.daysAgo", { days: 14 }) },
|
{ key: "14", text: intl.get("app.daysAgo", { days: 14 }) },
|
||||||
|
@ -153,6 +163,17 @@ class AppTab extends React.Component<AppTabProps, AppTabState> {
|
||||||
</Stack.Item>
|
</Stack.Item>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
|
<Label>{intl.get("searchEngine.name")}</Label>
|
||||||
|
<Stack horizontal>
|
||||||
|
<Stack.Item>
|
||||||
|
<Dropdown
|
||||||
|
defaultSelectedKey={window.settings.getSearchEngine()}
|
||||||
|
options={this.searchEngineOptions()}
|
||||||
|
onChanged={this.onSearchEngineChanged}
|
||||||
|
style={{width: 200}} />
|
||||||
|
</Stack.Item>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
<Stack horizontal verticalAlign="baseline">
|
<Stack horizontal verticalAlign="baseline">
|
||||||
<Stack.Item grow>
|
<Stack.Item grow>
|
||||||
<Label>{intl.get("app.enableProxy")}</Label>
|
<Label>{intl.get("app.enableProxy")}</Label>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Store = require("electron-store")
|
import Store = require("electron-store")
|
||||||
import { SchemaTypes, SourceGroup, ViewType, ThemeSettings } from "../schema-types"
|
import { SchemaTypes, SourceGroup, ViewType, ThemeSettings, SearchEngines } from "../schema-types"
|
||||||
import { ipcMain, session, nativeTheme, BrowserWindow, app } from "electron"
|
import { ipcMain, session, nativeTheme, app } from "electron"
|
||||||
import { WindowManager } from "./window"
|
import { WindowManager } from "./window"
|
||||||
|
|
||||||
export const store = new Store<SchemaTypes>()
|
export const store = new Store<SchemaTypes>()
|
||||||
|
@ -128,3 +128,11 @@ ipcMain.on("get-fetch-interval", (event) => {
|
||||||
ipcMain.handle("set-fetch-interval", (_, interval: number) => {
|
ipcMain.handle("set-fetch-interval", (_, interval: number) => {
|
||||||
store.set(FETCH_INTEVAL_STORE_KEY, interval)
|
store.set(FETCH_INTEVAL_STORE_KEY, interval)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const SEARCH_ENGINE_STORE_KEY = "searchEngine"
|
||||||
|
ipcMain.on("get-search-engine", (event) => {
|
||||||
|
event.returnValue = store.get(SEARCH_ENGINE_STORE_KEY, SearchEngines.Google)
|
||||||
|
})
|
||||||
|
ipcMain.handle("set-search-engine", (_, engine: SearchEngines) => {
|
||||||
|
store.set(SEARCH_ENGINE_STORE_KEY, engine)
|
||||||
|
})
|
||||||
|
|
|
@ -28,6 +28,10 @@ export const enum ThemeSettings {
|
||||||
Dark = "dark"
|
Dark = "dark"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const enum SearchEngines {
|
||||||
|
Google, Bing, Baidu, DuckDuckGo
|
||||||
|
}
|
||||||
|
|
||||||
export type SchemaTypes = {
|
export type SchemaTypes = {
|
||||||
version: string
|
version: string
|
||||||
theme: ThemeSettings
|
theme: ThemeSettings
|
||||||
|
@ -39,4 +43,5 @@ export type SchemaTypes = {
|
||||||
fontSize: number
|
fontSize: number
|
||||||
menuOn: boolean
|
menuOn: boolean
|
||||||
fetchInterval: number
|
fetchInterval: number
|
||||||
|
searchEngine: SearchEngines
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
"copyTitle": "Copy title",
|
"copyTitle": "Copy title",
|
||||||
"copyURL": "Copy link",
|
"copyURL": "Copy link",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
"search": "Search \"{text}\" on Google",
|
"search": "Search \"{text}\" on {engine}",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
"cardView": "Card view",
|
"cardView": "Card view",
|
||||||
"listView": "List view",
|
"listView": "List view",
|
||||||
|
@ -85,6 +85,13 @@
|
||||||
"showHidden": "Show hidden articles",
|
"showHidden": "Show hidden articles",
|
||||||
"manageSources": "Manage sources"
|
"manageSources": "Manage sources"
|
||||||
},
|
},
|
||||||
|
"searchEngine": {
|
||||||
|
"name": "Search engine",
|
||||||
|
"google": "Google",
|
||||||
|
"bing": "Bing",
|
||||||
|
"baidu": "Baidu",
|
||||||
|
"duckduckgo": "DuckDuckGo"
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"writeError": "An error has occurred while writing the file.",
|
"writeError": "An error has occurred while writing the file.",
|
||||||
"name": "Settings",
|
"name": "Settings",
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
"copyTitle": "Copiar título",
|
"copyTitle": "Copiar título",
|
||||||
"copyURL": "Copiar enlace",
|
"copyURL": "Copiar enlace",
|
||||||
"copy": "Copiar",
|
"copy": "Copiar",
|
||||||
"search": "Buscar \"{text}\" en Google",
|
"search": "Buscar \"{text}\" en {engine}",
|
||||||
"view": "Ver",
|
"view": "Ver",
|
||||||
"cardView": "Vista en modo tarjeta",
|
"cardView": "Vista en modo tarjeta",
|
||||||
"listView": "Vista en modo listado",
|
"listView": "Vista en modo listado",
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
"copyTitle": "Copier le titre",
|
"copyTitle": "Copier le titre",
|
||||||
"copyURL": "Copier le lien",
|
"copyURL": "Copier le lien",
|
||||||
"copy": "Copier",
|
"copy": "Copier",
|
||||||
"search": "Rechercher \"{text}\" sur Google",
|
"search": "Rechercher \"{text}\" sur {engine}",
|
||||||
"view": "Affichage",
|
"view": "Affichage",
|
||||||
"cardView": "Vue par carte",
|
"cardView": "Vue par carte",
|
||||||
"listView": "Vue par liste",
|
"listView": "Vue par liste",
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
"copyTitle": "复制标题",
|
"copyTitle": "复制标题",
|
||||||
"copyURL": "复制链接",
|
"copyURL": "复制链接",
|
||||||
"copy": "复制",
|
"copy": "复制",
|
||||||
"search": "使用 Google 搜索“{text}”",
|
"search": "使用 {engine} 搜索“{text}”",
|
||||||
"view": "视图",
|
"view": "视图",
|
||||||
"cardView": "卡片视图",
|
"cardView": "卡片视图",
|
||||||
"listView": "列表视图",
|
"listView": "列表视图",
|
||||||
|
@ -85,6 +85,11 @@
|
||||||
"showHidden": "显示隐藏文章",
|
"showHidden": "显示隐藏文章",
|
||||||
"manageSources": "管理订阅源"
|
"manageSources": "管理订阅源"
|
||||||
},
|
},
|
||||||
|
"searchEngine": {
|
||||||
|
"name": "搜索引擎",
|
||||||
|
"bing": "必应",
|
||||||
|
"baidu": "百度"
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"writeError": "写入文件时发生错误",
|
"writeError": "写入文件时发生错误",
|
||||||
"name": "选项",
|
"name": "选项",
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { AnyAction } from "redux"
|
||||||
import { RootState } from "./reducer"
|
import { RootState } from "./reducer"
|
||||||
import Parser from "@yang991178/rss-parser"
|
import Parser from "@yang991178/rss-parser"
|
||||||
import Url from "url"
|
import Url from "url"
|
||||||
|
import { SearchEngines } from "../schema-types"
|
||||||
|
|
||||||
export enum ActionStatus {
|
export enum ActionStatus {
|
||||||
Request, Success, Failure, Intermediate
|
Request, Success, Failure, Intermediate
|
||||||
|
@ -108,7 +109,30 @@ export const cutText = (s: string, length: number) => {
|
||||||
return (s.length <= length) ? s : s.slice(0, length) + "…"
|
return (s.length <= length) ? s : s.slice(0, length) + "…"
|
||||||
}
|
}
|
||||||
|
|
||||||
export const googleSearch = (text: string) => window.utils.openExternal("https://www.google.com/search?q=" + encodeURIComponent(text))
|
export function getSearchEngineName(engine: SearchEngines) {
|
||||||
|
switch (engine) {
|
||||||
|
case SearchEngines.Google:
|
||||||
|
return intl.get("searchEngine.google")
|
||||||
|
case SearchEngines.Bing:
|
||||||
|
return intl.get("searchEngine.bing")
|
||||||
|
case SearchEngines.Baidu:
|
||||||
|
return intl.get("searchEngine.baidu")
|
||||||
|
case SearchEngines.DuckDuckGo:
|
||||||
|
return intl.get("searchEngine.duckduckgo")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function webSearch(text: string, engine=SearchEngines.Google) {
|
||||||
|
switch (engine) {
|
||||||
|
case SearchEngines.Google:
|
||||||
|
return window.utils.openExternal("https://www.google.com/search?q=" + encodeURIComponent(text))
|
||||||
|
case SearchEngines.Bing:
|
||||||
|
return window.utils.openExternal("https://www.bing.com/search?q=" + encodeURIComponent(text))
|
||||||
|
case SearchEngines.Baidu:
|
||||||
|
return window.utils.openExternal("https://www.baidu.com/s?wd=" + encodeURIComponent(text))
|
||||||
|
case SearchEngines.DuckDuckGo:
|
||||||
|
return window.utils.openExternal("https://duckduckgo.com/?q=" + encodeURIComponent(text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function mergeSortedArrays<T>(a: T[], b: T[], cmp: ((x: T, y: T) => number)): T[] {
|
export function mergeSortedArrays<T>(a: T[], b: T[], cmp: ((x: T, y: T) => number)): T[] {
|
||||||
let merged = new Array<T>()
|
let merged = new Array<T>()
|
||||||
|
|
Loading…
Reference in New Issue