mirror of
https://github.com/yang991178/fluent-reader.git
synced 2025-02-23 06:57:50 +01:00
add settings context bridge
This commit is contained in:
parent
e1a5de5963
commit
b4c1ddd587
71
src/bridges/settings.ts
Normal file
71
src/bridges/settings.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { SourceGroup, ViewType, ThemeSettings } from "../schema-types"
|
||||||
|
import { ipcRenderer } from "electron"
|
||||||
|
|
||||||
|
const SettingsBridge = {
|
||||||
|
saveGroups: (groups: SourceGroup[]) => {
|
||||||
|
ipcRenderer.invoke("set-groups", groups)
|
||||||
|
},
|
||||||
|
loadGroups: (): SourceGroup[] => {
|
||||||
|
return ipcRenderer.sendSync("get-groups")
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultMenu: (): boolean => {
|
||||||
|
return ipcRenderer.sendSync("get-menu")
|
||||||
|
},
|
||||||
|
setDefaultMenu: (state: boolean) => {
|
||||||
|
ipcRenderer.invoke("set-menu", state)
|
||||||
|
},
|
||||||
|
|
||||||
|
getProxyStatus: (): boolean => {
|
||||||
|
return ipcRenderer.sendSync("get-proxy-status")
|
||||||
|
},
|
||||||
|
toggleProxyStatus: () => {
|
||||||
|
ipcRenderer.send("toggle-proxy-status")
|
||||||
|
},
|
||||||
|
getProxy: (): string => {
|
||||||
|
return ipcRenderer.sendSync("get-proxy")
|
||||||
|
},
|
||||||
|
setProxy: (address: string = null) => {
|
||||||
|
ipcRenderer.invoke("set-proxy", address)
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultView: (): ViewType => {
|
||||||
|
return ipcRenderer.sendSync("get-view")
|
||||||
|
},
|
||||||
|
setDefaultView: (viewType: ViewType) => {
|
||||||
|
ipcRenderer.invoke("set-view", viewType)
|
||||||
|
},
|
||||||
|
|
||||||
|
getThemeSettings: (): ThemeSettings => {
|
||||||
|
return ipcRenderer.sendSync("get-theme")
|
||||||
|
},
|
||||||
|
setThemeSettings: (theme: ThemeSettings) => {
|
||||||
|
ipcRenderer.invoke("set-theme", theme)
|
||||||
|
},
|
||||||
|
shouldUseDarkColors: (): boolean => {
|
||||||
|
return ipcRenderer.sendSync("get-theme-dark-color")
|
||||||
|
},
|
||||||
|
addThemeUpdateListener: (callback: (shouldDark: boolean) => any) => {
|
||||||
|
ipcRenderer.on("theme-updated", (_, shouldDark) => {
|
||||||
|
callback(shouldDark)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
setLocaleSettings: (option: string) => {
|
||||||
|
ipcRenderer.invoke("set-locale", option)
|
||||||
|
},
|
||||||
|
getLocaleSettings: (): string => {
|
||||||
|
return ipcRenderer.sendSync("get-locale-settings")
|
||||||
|
},
|
||||||
|
getCurrentLocale: (): string => {
|
||||||
|
return ipcRenderer.sendSync("get-locale")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
settings: typeof SettingsBridge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SettingsBridge
|
@ -6,7 +6,7 @@ import { ContextualMenu, IContextualMenuItem, ContextualMenuItemType, Directiona
|
|||||||
import { ContextMenuType } from "../scripts/models/app"
|
import { ContextMenuType } from "../scripts/models/app"
|
||||||
import { RSSItem } from "../scripts/models/item"
|
import { RSSItem } from "../scripts/models/item"
|
||||||
import { ContextReduxProps } from "../containers/context-menu-container"
|
import { ContextReduxProps } from "../containers/context-menu-container"
|
||||||
import { ViewType } from "../scripts/models/page"
|
import { ViewType } from "../schema-types"
|
||||||
import { FilterType } from "../scripts/models/feed"
|
import { FilterType } from "../scripts/models/feed"
|
||||||
|
|
||||||
export type ContextMenuProps = ContextReduxProps & {
|
export type ContextMenuProps = ContextReduxProps & {
|
||||||
|
@ -2,7 +2,7 @@ import * as React from "react"
|
|||||||
import { RSSItem } from "../../scripts/models/item"
|
import { RSSItem } from "../../scripts/models/item"
|
||||||
import { FeedReduxProps } from "../../containers/feed-container"
|
import { FeedReduxProps } from "../../containers/feed-container"
|
||||||
import { RSSFeed } from "../../scripts/models/feed"
|
import { RSSFeed } from "../../scripts/models/feed"
|
||||||
import { ViewType } from "../../scripts/models/page"
|
import { ViewType } from "../../schema-types"
|
||||||
import CardsFeed from "./cards-feed"
|
import CardsFeed from "./cards-feed"
|
||||||
import ListFeed from "./list-feed"
|
import ListFeed from "./list-feed"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import * as React from "react"
|
|||||||
import intl from "react-intl-universal"
|
import intl from "react-intl-universal"
|
||||||
import { Icon } from "@fluentui/react/lib/Icon"
|
import { Icon } from "@fluentui/react/lib/Icon"
|
||||||
import { Nav, INavLink, INavLinkGroup } from "office-ui-fabric-react/lib/Nav"
|
import { Nav, INavLink, INavLinkGroup } from "office-ui-fabric-react/lib/Nav"
|
||||||
import { SourceGroup } from "../scripts/models/group"
|
import { SourceGroup } from "../schema-types"
|
||||||
import { SourceState, RSSSource } from "../scripts/models/source"
|
import { SourceState, RSSSource } from "../scripts/models/source"
|
||||||
import { ALL } from "../scripts/models/feed"
|
import { ALL } from "../scripts/models/feed"
|
||||||
import { AnimationClassNames, Stack } from "@fluentui/react"
|
import { AnimationClassNames, Stack } from "@fluentui/react"
|
||||||
|
@ -2,7 +2,7 @@ import * as React from "react"
|
|||||||
import { FeedContainer } from "../containers/feed-container"
|
import { FeedContainer } from "../containers/feed-container"
|
||||||
import { AnimationClassNames, Icon, FocusTrapZone } from "@fluentui/react"
|
import { AnimationClassNames, Icon, FocusTrapZone } from "@fluentui/react"
|
||||||
import ArticleContainer from "../containers/article-container"
|
import ArticleContainer from "../containers/article-container"
|
||||||
import { ViewType } from "../scripts/models/page"
|
import { ViewType } from "../schema-types"
|
||||||
import ArticleSearch from "./utils/article-search"
|
import ArticleSearch from "./utils/article-search"
|
||||||
|
|
||||||
type PageProps = {
|
type PageProps = {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
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 } from "../../scripts/utils"
|
||||||
import { getProxy, getProxyStatus, toggleProxyStatus, setProxy, getThemeSettings, setThemeSettings, ThemeSettings, getLocaleSettings, exportAll } from "../../scripts/settings"
|
import { ThemeSettings } from "../../schema-types"
|
||||||
|
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 { remote } from "electron"
|
import { remote } from "electron"
|
||||||
import DangerButton from "../utils/danger-button"
|
import DangerButton from "../utils/danger-button"
|
||||||
@ -25,8 +26,8 @@ class AppTab extends React.Component<AppTabProps, AppTabState> {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
pacStatus: getProxyStatus(),
|
pacStatus: window.settings.getProxyStatus(),
|
||||||
pacUrl: getProxy(),
|
pacUrl: window.settings.getProxy(),
|
||||||
themeSettings: getThemeSettings(),
|
themeSettings: getThemeSettings(),
|
||||||
itemSize: null,
|
itemSize: null,
|
||||||
cacheSize: null,
|
cacheSize: null,
|
||||||
@ -86,10 +87,10 @@ class AppTab extends React.Component<AppTabProps, AppTabState> {
|
|||||||
]
|
]
|
||||||
|
|
||||||
toggleStatus = () => {
|
toggleStatus = () => {
|
||||||
toggleProxyStatus()
|
window.settings.toggleProxyStatus()
|
||||||
this.setState({
|
this.setState({
|
||||||
pacStatus: getProxyStatus(),
|
pacStatus: window.settings.getProxyStatus(),
|
||||||
pacUrl: getProxy()
|
pacUrl: window.settings.getProxy()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ class AppTab extends React.Component<AppTabProps, AppTabState> {
|
|||||||
|
|
||||||
setUrl = (event: React.FormEvent) => {
|
setUrl = (event: React.FormEvent) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (urlTest(this.state.pacUrl)) setProxy(this.state.pacUrl)
|
if (urlTest(this.state.pacUrl)) window.settings.setProxy(this.state.pacUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
onThemeChange = (_, option: IChoiceGroupOption) => {
|
onThemeChange = (_, option: IChoiceGroupOption) => {
|
||||||
@ -127,7 +128,7 @@ class AppTab extends React.Component<AppTabProps, AppTabState> {
|
|||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<Stack.Item>
|
<Stack.Item>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
defaultSelectedKey={getLocaleSettings()}
|
defaultSelectedKey={window.settings.getLocaleSettings()}
|
||||||
options={this.languageOptions()}
|
options={this.languageOptions()}
|
||||||
onChanged={option => this.props.setLanguage(String(option.key))}
|
onChanged={option => this.props.setLanguage(String(option.key))}
|
||||||
style={{width: 200}} />
|
style={{width: 200}} />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import intl from "react-intl-universal"
|
import intl from "react-intl-universal"
|
||||||
import { SourceGroup } from "../../scripts/models/group"
|
import { SourceGroup } from "../../schema-types"
|
||||||
import { SourceState, RSSSource } from "../../scripts/models/source"
|
import { SourceState, RSSSource } from "../../scripts/models/source"
|
||||||
import { IColumn, Selection, SelectionMode, DetailsList, Label, Stack,
|
import { IColumn, Selection, SelectionMode, DetailsList, Label, Stack,
|
||||||
TextField, PrimaryButton, DefaultButton, Dropdown, IDropdownOption, CommandBarButton, MarqueeSelection, IDragDropEvents, IDragDropContext } from "@fluentui/react"
|
TextField, PrimaryButton, DefaultButton, Dropdown, IDropdownOption, CommandBarButton, MarqueeSelection, IDragDropEvents, IDragDropContext } from "@fluentui/react"
|
||||||
|
@ -4,8 +4,8 @@ import { RootState } from "../scripts/reducer"
|
|||||||
import { ContextMenuType, closeContextMenu, toggleSettings } from "../scripts/models/app"
|
import { ContextMenuType, closeContextMenu, toggleSettings } from "../scripts/models/app"
|
||||||
import { ContextMenu } from "../components/context-menu"
|
import { ContextMenu } from "../components/context-menu"
|
||||||
import { RSSItem, markRead, markUnread, toggleStarred, toggleHidden, markAllRead } from "../scripts/models/item"
|
import { RSSItem, markRead, markUnread, toggleStarred, toggleHidden, markAllRead } from "../scripts/models/item"
|
||||||
import { showItem, switchView, ViewType, switchFilter, toggleFilter } from "../scripts/models/page"
|
import { showItem, switchView, switchFilter, toggleFilter } from "../scripts/models/page"
|
||||||
import { setDefaultView } from "../scripts/settings"
|
import { ViewType } from "../schema-types"
|
||||||
import { FilterType } from "../scripts/models/feed"
|
import { FilterType } from "../scripts/models/feed"
|
||||||
|
|
||||||
const getContext = (state: RootState) => state.app.contextMenu
|
const getContext = (state: RootState) => state.app.contextMenu
|
||||||
@ -57,7 +57,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
dispatch(toggleHidden(item))
|
dispatch(toggleHidden(item))
|
||||||
},
|
},
|
||||||
switchView: (viewType: ViewType) => {
|
switchView: (viewType: ViewType) => {
|
||||||
setDefaultView(viewType)
|
window.settings.setDefaultView(viewType)
|
||||||
dispatch(switchView(viewType))
|
dispatch(switchView(viewType))
|
||||||
},
|
},
|
||||||
switchFilter: (filter: FilterType) => dispatch(switchFilter(filter)),
|
switchFilter: (filter: FilterType) => dispatch(switchFilter(filter)),
|
||||||
|
@ -4,7 +4,8 @@ import { RootState } from "../scripts/reducer"
|
|||||||
import { markRead, RSSItem, itemShortcuts } from "../scripts/models/item"
|
import { markRead, RSSItem, itemShortcuts } from "../scripts/models/item"
|
||||||
import { openItemMenu } from "../scripts/models/app"
|
import { openItemMenu } from "../scripts/models/app"
|
||||||
import { loadMore, RSSFeed } from "../scripts/models/feed"
|
import { loadMore, RSSFeed } from "../scripts/models/feed"
|
||||||
import { showItem, ViewType } from "../scripts/models/page"
|
import { showItem } from "../scripts/models/page"
|
||||||
|
import { ViewType } from "../schema-types"
|
||||||
import { Feed } from "../components/feeds/feed"
|
import { Feed } from "../components/feeds/feed"
|
||||||
|
|
||||||
interface FeedContainerProps {
|
interface FeedContainerProps {
|
||||||
|
@ -3,8 +3,10 @@ import { createSelector } from "reselect"
|
|||||||
import { RootState } from "../scripts/reducer"
|
import { RootState } from "../scripts/reducer"
|
||||||
import { Menu } from "../components/menu"
|
import { Menu } from "../components/menu"
|
||||||
import { toggleMenu, openGroupMenu } from "../scripts/models/app"
|
import { toggleMenu, openGroupMenu } from "../scripts/models/app"
|
||||||
import { SourceGroup, toggleGroupExpansion } from "../scripts/models/group"
|
import { toggleGroupExpansion } from "../scripts/models/group"
|
||||||
import { selectAllArticles, selectSources, toggleSearch, ViewType } from "../scripts/models/page"
|
import { SourceGroup } from "../schema-types"
|
||||||
|
import { selectAllArticles, selectSources, toggleSearch } from "../scripts/models/page"
|
||||||
|
import { ViewType } from "../schema-types"
|
||||||
import { initFeeds } from "../scripts/models/feed"
|
import { initFeeds } from "../scripts/models/feed"
|
||||||
import { RSSSource } from "../scripts/models/source"
|
import { RSSSource } from "../scripts/models/source"
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ import { createSelector } from "reselect"
|
|||||||
import { RootState } from "../scripts/reducer"
|
import { RootState } from "../scripts/reducer"
|
||||||
import { fetchItems, markAllRead } from "../scripts/models/item"
|
import { fetchItems, markAllRead } from "../scripts/models/item"
|
||||||
import { toggleMenu, toggleLogMenu, toggleSettings, openViewMenu } from "../scripts/models/app"
|
import { toggleMenu, toggleLogMenu, toggleSettings, openViewMenu } from "../scripts/models/app"
|
||||||
import { ViewType, toggleSearch } from "../scripts/models/page"
|
import { toggleSearch } from "../scripts/models/page"
|
||||||
|
import { ViewType } from "../schema-types"
|
||||||
import Nav from "../components/nav"
|
import Nav from "../components/nav"
|
||||||
|
|
||||||
const getState = (state: RootState) => state.app
|
const getState = (state: RootState) => state.app
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import intl from "react-intl-universal"
|
import intl from "react-intl-universal"
|
||||||
import { connect } from "react-redux"
|
import { connect } from "react-redux"
|
||||||
import { setLocaleSettings, importAll } from "../../scripts/settings"
|
import { importAll } from "../../scripts/settings"
|
||||||
import { initIntl, saveSettings } from "../../scripts/models/app"
|
import { initIntl, saveSettings } from "../../scripts/models/app"
|
||||||
import * as db from "../../scripts/db"
|
import * as db from "../../scripts/db"
|
||||||
import AppTab from "../../components/settings/app"
|
import AppTab from "../../components/settings/app"
|
||||||
@ -9,7 +9,7 @@ import { remote } from "electron"
|
|||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
setLanguage: (option: string) => {
|
setLanguage: (option: string) => {
|
||||||
setLocaleSettings(option)
|
window.settings.setLocaleSettings(option)
|
||||||
dispatch(initIntl())
|
dispatch(initIntl())
|
||||||
},
|
},
|
||||||
deleteArticles: (days: number) => new Promise((resolve) => {
|
deleteArticles: (days: number) => new Promise((resolve) => {
|
||||||
|
@ -2,8 +2,9 @@ import { connect } from "react-redux"
|
|||||||
import { createSelector } from "reselect"
|
import { createSelector } from "reselect"
|
||||||
import { RootState } from "../../scripts/reducer"
|
import { RootState } from "../../scripts/reducer"
|
||||||
import GroupsTab from "../../components/settings/groups"
|
import GroupsTab from "../../components/settings/groups"
|
||||||
import { createSourceGroup, SourceGroup, updateSourceGroup, addSourceToGroup,
|
import { createSourceGroup, updateSourceGroup, addSourceToGroup,
|
||||||
deleteSourceGroup, removeSourceFromGroup, reorderSourceGroups } from "../../scripts/models/group"
|
deleteSourceGroup, removeSourceFromGroup, reorderSourceGroups } from "../../scripts/models/group"
|
||||||
|
import { SourceGroup } from "../../schema-types"
|
||||||
|
|
||||||
const getSources = (state: RootState) => state.sources
|
const getSources = (state: RootState) => state.sources
|
||||||
const getGroups = (state: RootState) => state.groups
|
const getGroups = (state: RootState) => state.groups
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { app, ipcMain, BrowserWindow, Menu, nativeTheme } from "electron"
|
import { app, ipcMain, BrowserWindow, Menu, nativeTheme } from "electron"
|
||||||
import windowStateKeeper = require("electron-window-state")
|
import windowStateKeeper = require("electron-window-state")
|
||||||
import Store = require("electron-store")
|
import { ThemeSettings } from "./schema-types"
|
||||||
import performUpdate from "./scripts/update-scripts"
|
import { store, setThemeListener } from "./main/settings"
|
||||||
|
import performUpdate from "./main/update-scripts"
|
||||||
|
import path = require("path")
|
||||||
|
|
||||||
if (!process.mas) {
|
if (!process.mas) {
|
||||||
const locked = app.requestSingleInstanceLock()
|
const locked = app.requestSingleInstanceLock()
|
||||||
@ -11,14 +13,12 @@ if (!process.mas) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mainWindow: BrowserWindow
|
let mainWindow: BrowserWindow
|
||||||
let store: Store
|
|
||||||
let restarting: boolean
|
let restarting: boolean
|
||||||
|
|
||||||
function init(setTheme = true) {
|
function init(setTheme = true) {
|
||||||
restarting = false
|
restarting = false
|
||||||
store = new Store()
|
|
||||||
performUpdate(store)
|
performUpdate(store)
|
||||||
if (setTheme) nativeTheme.themeSource = store.get("theme", "system")
|
if (setTheme) nativeTheme.themeSource = store.get("theme", ThemeSettings.Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
init()
|
init()
|
||||||
@ -46,7 +46,8 @@ function createWindow() {
|
|||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
webviewTag: true,
|
webviewTag: true,
|
||||||
enableRemoteModule: true
|
enableRemoteModule: true,
|
||||||
|
preload: path.join(app.getAppPath(), (app.isPackaged ? "dist/" : "") + "preload.js")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
mainWindowState.manage(mainWindow)
|
mainWindowState.manage(mainWindow)
|
||||||
@ -54,9 +55,10 @@ function createWindow() {
|
|||||||
mainWindow.show()
|
mainWindow.show()
|
||||||
mainWindow.focus()
|
mainWindow.focus()
|
||||||
if (!app.isPackaged) mainWindow.webContents.openDevTools()
|
if (!app.isPackaged) mainWindow.webContents.openDevTools()
|
||||||
});
|
})
|
||||||
|
setThemeListener(mainWindow)
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
mainWindow.loadFile((app.isPackaged ? "dist/" : "") + "index.html")
|
mainWindow.loadFile((app.isPackaged ? "dist/" : "") + "index.html", )
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.platform === "darwin") {
|
if (process.platform === "darwin") {
|
||||||
|
@ -7,10 +7,10 @@ import { initializeIcons } from "@fluentui/react/lib/Icons"
|
|||||||
import { rootReducer, RootState } from "./scripts/reducer"
|
import { rootReducer, RootState } from "./scripts/reducer"
|
||||||
import Root from "./components/root"
|
import Root from "./components/root"
|
||||||
import { AppDispatch } from "./scripts/utils"
|
import { AppDispatch } from "./scripts/utils"
|
||||||
import { setProxy, applyThemeSettings } from "./scripts/settings"
|
import { applyThemeSettings } from "./scripts/settings"
|
||||||
import { initApp } from "./scripts/models/app"
|
import { initApp } from "./scripts/models/app"
|
||||||
|
|
||||||
setProxy()
|
window.settings.setProxy()
|
||||||
|
|
||||||
applyThemeSettings()
|
applyThemeSettings()
|
||||||
initializeIcons("icons/")
|
initializeIcons("icons/")
|
||||||
|
103
src/main/settings.ts
Normal file
103
src/main/settings.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import Store = require("electron-store")
|
||||||
|
import { SchemaTypes, SourceGroup, ViewType, ThemeSettings } from "../schema-types"
|
||||||
|
import { ipcMain, session, nativeTheme, BrowserWindow, app } from "electron"
|
||||||
|
|
||||||
|
export const store = new Store<SchemaTypes>()
|
||||||
|
|
||||||
|
const GROUPS_STORE_KEY = "sourceGroups"
|
||||||
|
ipcMain.handle("set-groups", (_, groups: SourceGroup[]) => {
|
||||||
|
store.set(GROUPS_STORE_KEY, groups)
|
||||||
|
})
|
||||||
|
ipcMain.on("get-groups", (event) => {
|
||||||
|
event.returnValue = store.get(GROUPS_STORE_KEY, [])
|
||||||
|
})
|
||||||
|
|
||||||
|
const MENU_STORE_KEY = "menuOn"
|
||||||
|
ipcMain.on("get-menu", (event) => {
|
||||||
|
event.returnValue = store.get(MENU_STORE_KEY, false)
|
||||||
|
})
|
||||||
|
ipcMain.handle("set-menu", (_, state: boolean) => {
|
||||||
|
store.set(MENU_STORE_KEY, state)
|
||||||
|
})
|
||||||
|
|
||||||
|
const PAC_STORE_KEY = "pac"
|
||||||
|
const PAC_STATUS_KEY = "pacOn"
|
||||||
|
function getProxyStatus() {
|
||||||
|
return store.get(PAC_STATUS_KEY, false)
|
||||||
|
}
|
||||||
|
function toggleProxyStatus() {
|
||||||
|
store.set(PAC_STATUS_KEY, !getProxyStatus())
|
||||||
|
setProxy()
|
||||||
|
}
|
||||||
|
function getProxy() {
|
||||||
|
return store.get(PAC_STORE_KEY, "")
|
||||||
|
}
|
||||||
|
function setProxy(address = null) {
|
||||||
|
if (!address) {
|
||||||
|
address = getProxy()
|
||||||
|
} else {
|
||||||
|
store.set(PAC_STORE_KEY, address)
|
||||||
|
}
|
||||||
|
if (getProxyStatus()) {
|
||||||
|
let rules = { pacScript: address }
|
||||||
|
session.defaultSession.setProxy(rules)
|
||||||
|
session.fromPartition("sandbox").setProxy(rules)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipcMain.on("get-proxy-status", (event) => {
|
||||||
|
event.returnValue = getProxyStatus()
|
||||||
|
})
|
||||||
|
ipcMain.on("toggle-proxy-status", () => {
|
||||||
|
toggleProxyStatus()
|
||||||
|
})
|
||||||
|
ipcMain.on("get-proxy", (event) => {
|
||||||
|
event.returnValue = getProxy()
|
||||||
|
})
|
||||||
|
ipcMain.handle("set-proxy", (_, address = null) => {
|
||||||
|
setProxy(address)
|
||||||
|
})
|
||||||
|
|
||||||
|
const VIEW_STORE_KEY = "view"
|
||||||
|
ipcMain.on("get-view", (event) => {
|
||||||
|
event.returnValue = store.get(VIEW_STORE_KEY, ViewType.Cards)
|
||||||
|
})
|
||||||
|
ipcMain.handle("set-view", (_, viewType: ViewType) => {
|
||||||
|
store.set(VIEW_STORE_KEY, viewType)
|
||||||
|
})
|
||||||
|
|
||||||
|
const THEME_STORE_KEY = "theme"
|
||||||
|
ipcMain.on("get-theme", (event) => {
|
||||||
|
event.returnValue = store.get(THEME_STORE_KEY, ThemeSettings.Default)
|
||||||
|
})
|
||||||
|
ipcMain.handle("set-theme", (_, theme: ThemeSettings) => {
|
||||||
|
store.set(THEME_STORE_KEY, theme)
|
||||||
|
nativeTheme.themeSource = theme
|
||||||
|
})
|
||||||
|
ipcMain.on("get-theme-dark-color", (event) => {
|
||||||
|
event.returnValue = nativeTheme.shouldUseDarkColors
|
||||||
|
})
|
||||||
|
export function setThemeListener(window: BrowserWindow) {
|
||||||
|
nativeTheme.removeAllListeners()
|
||||||
|
nativeTheme.on("updated", () => {
|
||||||
|
let contents = window.webContents
|
||||||
|
if (!contents.isDestroyed()) {
|
||||||
|
contents.send("theme-updated", nativeTheme.shouldUseDarkColors)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const LOCALE_STORE_KEY = "locale"
|
||||||
|
ipcMain.handle("set-locale", (_, option: string) => {
|
||||||
|
store.set(LOCALE_STORE_KEY, option)
|
||||||
|
})
|
||||||
|
function getLocaleSettings() {
|
||||||
|
return store.get(LOCALE_STORE_KEY, "default")
|
||||||
|
}
|
||||||
|
ipcMain.on("get-locale-settings", (event) => {
|
||||||
|
event.returnValue = getLocaleSettings()
|
||||||
|
})
|
||||||
|
ipcMain.on("get-locale", (event) => {
|
||||||
|
let setting = getLocaleSettings()
|
||||||
|
let locale = setting === "default" ? app.getLocale() : setting
|
||||||
|
event.returnValue = locale
|
||||||
|
})
|
@ -1,7 +1,8 @@
|
|||||||
import { app } from "electron"
|
import { app } from "electron"
|
||||||
import Store = require("electron-store")
|
import Store = require("electron-store")
|
||||||
|
import { SchemaTypes } from "../schema-types"
|
||||||
|
|
||||||
export default function performUpdate(store: Store) {
|
export default function performUpdate(store: Store<SchemaTypes>) {
|
||||||
let version = store.get("version", null)
|
let version = store.get("version", null)
|
||||||
let currentVersion = app.getVersion()
|
let currentVersion = app.getVersion()
|
||||||
|
|
4
src/preload.ts
Normal file
4
src/preload.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { contextBridge } from "electron"
|
||||||
|
import SettingsBridge from "./bridges/settings"
|
||||||
|
|
||||||
|
window.settings = SettingsBridge
|
41
src/schema-types.ts
Normal file
41
src/schema-types.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
export class SourceGroup {
|
||||||
|
isMultiple: boolean
|
||||||
|
sids: number[]
|
||||||
|
name?: string
|
||||||
|
expanded?: boolean
|
||||||
|
index?: number // available only from groups tab container
|
||||||
|
|
||||||
|
constructor(sids: number[], name: string = null) {
|
||||||
|
name = (name && name.trim()) || "订阅源组"
|
||||||
|
if (sids.length == 1) {
|
||||||
|
this.isMultiple = false
|
||||||
|
} else {
|
||||||
|
this.isMultiple = true
|
||||||
|
this.name = name
|
||||||
|
this.expanded = true
|
||||||
|
}
|
||||||
|
this.sids = sids
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ViewType {
|
||||||
|
Cards, List, Customized
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ThemeSettings {
|
||||||
|
Default = "system",
|
||||||
|
Light = "light",
|
||||||
|
Dark = "dark"
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SchemaTypes = {
|
||||||
|
version: string
|
||||||
|
theme: ThemeSettings
|
||||||
|
pac: string
|
||||||
|
pacOn: boolean
|
||||||
|
view: ViewType
|
||||||
|
locale: string
|
||||||
|
sourceGroups: SourceGroup[]
|
||||||
|
fontSize: number
|
||||||
|
menuOn: boolean
|
||||||
|
}
|
22
src/scripts/PromiseConstructor.d.ts
vendored
22
src/scripts/PromiseConstructor.d.ts
vendored
@ -1,22 +0,0 @@
|
|||||||
interface PromiseFulfilledResult<T> {
|
|
||||||
status: "fulfilled";
|
|
||||||
value: T;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PromiseRejectedResult {
|
|
||||||
status: "rejected";
|
|
||||||
reason: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
type PromiseSettledResult<T> = PromiseFulfilledResult<T> | PromiseRejectedResult;
|
|
||||||
|
|
||||||
declare interface PromiseConstructor {
|
|
||||||
/**
|
|
||||||
* Creates a Promise that is resolved with an array of results when all
|
|
||||||
* of the provided Promises resolve or reject.
|
|
||||||
* @param values An array of Promises.
|
|
||||||
* @returns A new Promise.
|
|
||||||
*/
|
|
||||||
allSettled<T extends readonly unknown[] | readonly [unknown]>(values: T):
|
|
||||||
Promise<{ -readonly [P in keyof T]: PromiseSettledResult<T[P] extends PromiseLike<infer U> ? U : T[P]> }>;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import { ThemeSettings } from "./settings"
|
|
||||||
import { SourceGroup } from "./models/group"
|
|
||||||
|
|
||||||
// Using schema breaks unsafe-eval. Unused.
|
|
||||||
/* export const schema: {[key in keyof schemaTypes]: Schema} = {
|
|
||||||
theme: { type: "string", default: "system" },
|
|
||||||
pac: { type: "string", default: "" },
|
|
||||||
pacOn: { type: "boolean", default: false },
|
|
||||||
view: { type: "number", default: 0 },
|
|
||||||
locale: { type: "string", default: "default" },
|
|
||||||
sourceGroups: { type: "array", default: [] }
|
|
||||||
} */
|
|
||||||
|
|
||||||
export type schemaTypes = {
|
|
||||||
version: string
|
|
||||||
theme: ThemeSettings
|
|
||||||
pac: string
|
|
||||||
pacOn: boolean
|
|
||||||
view: number
|
|
||||||
locale: string
|
|
||||||
sourceGroups: SourceGroup[]
|
|
||||||
fontSize: number
|
|
||||||
menuOn: boolean
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ import { ActionStatus, AppThunk, getWindowBreakpoint } from "../utils"
|
|||||||
import { INIT_FEEDS, FeedActionTypes, ALL, initFeeds } from "./feed"
|
import { INIT_FEEDS, FeedActionTypes, ALL, initFeeds } from "./feed"
|
||||||
import { SourceGroupActionTypes, UPDATE_SOURCE_GROUP, ADD_SOURCE_TO_GROUP, DELETE_SOURCE_GROUP, REMOVE_SOURCE_FROM_GROUP, REORDER_SOURCE_GROUPS } from "./group"
|
import { SourceGroupActionTypes, UPDATE_SOURCE_GROUP, ADD_SOURCE_TO_GROUP, DELETE_SOURCE_GROUP, REMOVE_SOURCE_FROM_GROUP, REORDER_SOURCE_GROUPS } from "./group"
|
||||||
import { PageActionTypes, SELECT_PAGE, PageType, selectAllArticles } from "./page"
|
import { PageActionTypes, SELECT_PAGE, PageType, selectAllArticles } from "./page"
|
||||||
import { getCurrentLocale, setDefaultMenu, getDefaultMenu } from "../settings"
|
import { getCurrentLocale } from "../settings"
|
||||||
import locales from "../i18n/_locales"
|
import locales from "../i18n/_locales"
|
||||||
import * as db from "../db"
|
import * as db from "../db"
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ export class AppState {
|
|||||||
fetchingItems = false
|
fetchingItems = false
|
||||||
fetchingProgress = 0
|
fetchingProgress = 0
|
||||||
fetchingTotal = 0
|
fetchingTotal = 0
|
||||||
menu = getWindowBreakpoint() && getDefaultMenu()
|
menu = getWindowBreakpoint() && window.settings.getDefaultMenu()
|
||||||
menuKey = ALL
|
menuKey = ALL
|
||||||
title = ""
|
title = ""
|
||||||
settings = {
|
settings = {
|
||||||
@ -152,7 +152,7 @@ export function openGroupMenu(sids: number[], event: React.MouseEvent): ContextM
|
|||||||
export function toggleMenu(): AppThunk {
|
export function toggleMenu(): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch({ type: TOGGLE_MENU })
|
dispatch({ type: TOGGLE_MENU })
|
||||||
setDefaultMenu(getState().app.menu)
|
window.settings.setDefaultMenu(getState().app.menu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,43 +1,12 @@
|
|||||||
import fs = require("fs")
|
import fs = require("fs")
|
||||||
import intl from "react-intl-universal"
|
import intl from "react-intl-universal"
|
||||||
import { SourceActionTypes, ADD_SOURCE, DELETE_SOURCE, addSource, RSSSource } from "./source"
|
import { SourceActionTypes, ADD_SOURCE, DELETE_SOURCE, addSource, RSSSource } from "./source"
|
||||||
|
import { SourceGroup } from "../../schema-types"
|
||||||
import { ActionStatus, AppThunk, domParser, AppDispatch } from "../utils"
|
import { ActionStatus, AppThunk, domParser, AppDispatch } from "../utils"
|
||||||
import { saveSettings } from "./app"
|
import { saveSettings } from "./app"
|
||||||
import { store } from "../settings"
|
|
||||||
import { fetchItemsIntermediate, fetchItemsRequest, fetchItemsSuccess } from "./item"
|
import { fetchItemsIntermediate, fetchItemsRequest, fetchItemsSuccess } from "./item"
|
||||||
import { remote } from "electron"
|
import { remote } from "electron"
|
||||||
|
|
||||||
const GROUPS_STORE_KEY = "sourceGroups"
|
|
||||||
|
|
||||||
export class SourceGroup {
|
|
||||||
isMultiple: boolean
|
|
||||||
sids: number[]
|
|
||||||
name?: string
|
|
||||||
expanded?: boolean
|
|
||||||
index?: number // available only from groups tab container
|
|
||||||
|
|
||||||
constructor(sids: number[], name: string = null) {
|
|
||||||
name = (name && name.trim()) || "订阅源组"
|
|
||||||
if (sids.length == 1) {
|
|
||||||
this.isMultiple = false
|
|
||||||
} else {
|
|
||||||
this.isMultiple = true
|
|
||||||
this.name = name
|
|
||||||
this.expanded = true
|
|
||||||
}
|
|
||||||
this.sids = sids
|
|
||||||
}
|
|
||||||
|
|
||||||
static save(groups: SourceGroup[]) {
|
|
||||||
store.set(GROUPS_STORE_KEY, groups)
|
|
||||||
}
|
|
||||||
|
|
||||||
static load(): SourceGroup[] {
|
|
||||||
return store.get(GROUPS_STORE_KEY, [])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CREATE_SOURCE_GROUP = "CREATE_SOURCE_GROUP"
|
export const CREATE_SOURCE_GROUP = "CREATE_SOURCE_GROUP"
|
||||||
export const ADD_SOURCE_TO_GROUP = "ADD_SOURCE_TO_GROUP"
|
export const ADD_SOURCE_TO_GROUP = "ADD_SOURCE_TO_GROUP"
|
||||||
export const REMOVE_SOURCE_FROM_GROUP = "REMOVE_SOURCE_FROM_GROUP"
|
export const REMOVE_SOURCE_FROM_GROUP = "REMOVE_SOURCE_FROM_GROUP"
|
||||||
@ -100,7 +69,7 @@ export function createSourceGroup(name: string): AppThunk<number> {
|
|||||||
let group = new SourceGroup([], name)
|
let group = new SourceGroup([], name)
|
||||||
dispatch(createSourceGroupDone(group))
|
dispatch(createSourceGroupDone(group))
|
||||||
let groups = getState().groups
|
let groups = getState().groups
|
||||||
SourceGroup.save(groups)
|
window.settings.saveGroups(groups)
|
||||||
return groups.length - 1
|
return groups.length - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +85,7 @@ function addSourceToGroupDone(groupIndex: number, sid: number): SourceGroupActio
|
|||||||
export function addSourceToGroup(groupIndex: number, sid: number): AppThunk {
|
export function addSourceToGroup(groupIndex: number, sid: number): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(addSourceToGroupDone(groupIndex, sid))
|
dispatch(addSourceToGroupDone(groupIndex, sid))
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +100,7 @@ function removeSourceFromGroupDone(groupIndex: number, sids: number[]): SourceGr
|
|||||||
export function removeSourceFromGroup(groupIndex: number, sids: number[]): AppThunk {
|
export function removeSourceFromGroup(groupIndex: number, sids: number[]): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(removeSourceFromGroupDone(groupIndex, sids))
|
dispatch(removeSourceFromGroupDone(groupIndex, sids))
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +114,7 @@ function deleteSourceGroupDone(groupIndex: number): SourceGroupActionTypes {
|
|||||||
export function deleteSourceGroup(groupIndex: number): AppThunk {
|
export function deleteSourceGroup(groupIndex: number): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(deleteSourceGroupDone(groupIndex))
|
dispatch(deleteSourceGroupDone(groupIndex))
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +129,7 @@ function updateSourceGroupDone(group: SourceGroup): SourceGroupActionTypes {
|
|||||||
export function updateSourceGroup(group: SourceGroup): AppThunk {
|
export function updateSourceGroup(group: SourceGroup): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(updateSourceGroupDone(group))
|
dispatch(updateSourceGroupDone(group))
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +143,7 @@ function reorderSourceGroupsDone(groups: SourceGroup[]): SourceGroupActionTypes
|
|||||||
export function reorderSourceGroups(groups: SourceGroup[]): AppThunk {
|
export function reorderSourceGroups(groups: SourceGroup[]): AppThunk {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(reorderSourceGroupsDone(groups))
|
dispatch(reorderSourceGroupsDone(groups))
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +153,7 @@ export function toggleGroupExpansion(groupIndex: number): AppThunk {
|
|||||||
type: TOGGLE_GROUP_EXPANSION,
|
type: TOGGLE_GROUP_EXPANSION,
|
||||||
groupIndex: groupIndex
|
groupIndex: groupIndex
|
||||||
})
|
})
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +268,7 @@ export function exportOPML(path: string): AppThunk {
|
|||||||
export type GroupState = SourceGroup[]
|
export type GroupState = SourceGroup[]
|
||||||
|
|
||||||
export function groupReducer(
|
export function groupReducer(
|
||||||
state = SourceGroup.load(),
|
state = window.settings.loadGroups(),
|
||||||
action: SourceActionTypes | SourceGroupActionTypes
|
action: SourceActionTypes | SourceGroupActionTypes
|
||||||
): GroupState {
|
): GroupState {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { ALL, SOURCE, loadMore, FeedFilter, FilterType, initFeeds, FeedActionTypes, INIT_FEED } from "./feed"
|
import { ALL, SOURCE, loadMore, FeedFilter, FilterType, initFeeds, FeedActionTypes, INIT_FEED } from "./feed"
|
||||||
import { getWindowBreakpoint, AppThunk, ActionStatus } from "../utils"
|
import { getWindowBreakpoint, AppThunk, ActionStatus } from "../utils"
|
||||||
import { getDefaultView } from "../settings"
|
|
||||||
import { RSSItem, markRead } from "./item"
|
import { RSSItem, markRead } from "./item"
|
||||||
import { SourceActionTypes, DELETE_SOURCE } from "./source"
|
import { SourceActionTypes, DELETE_SOURCE } from "./source"
|
||||||
import { toggleMenu } from "./app"
|
import { toggleMenu } from "./app"
|
||||||
|
import { ViewType } from "../../schema-types"
|
||||||
|
|
||||||
export const SELECT_PAGE = "SELECT_PAGE"
|
export const SELECT_PAGE = "SELECT_PAGE"
|
||||||
export const SWITCH_VIEW = "SWITCH_VIEW"
|
export const SWITCH_VIEW = "SWITCH_VIEW"
|
||||||
@ -17,10 +17,6 @@ export enum PageType {
|
|||||||
AllArticles, Sources, Page
|
AllArticles, Sources, Page
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ViewType {
|
|
||||||
Cards, List, Customized
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SelectPageAction {
|
interface SelectPageAction {
|
||||||
type: typeof SELECT_PAGE
|
type: typeof SELECT_PAGE
|
||||||
pageType: PageType
|
pageType: PageType
|
||||||
@ -205,7 +201,7 @@ export function performSearch(query: string): AppThunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PageState {
|
export class PageState {
|
||||||
viewType = getDefaultView()
|
viewType = window.settings.getDefaultView()
|
||||||
filter = new FeedFilter()
|
filter = new FeedFilter()
|
||||||
feedId = ALL
|
feedId = ALL
|
||||||
itemId = null as string
|
itemId = null as string
|
||||||
|
@ -3,7 +3,6 @@ import intl from "react-intl-universal"
|
|||||||
import * as db from "../db"
|
import * as db from "../db"
|
||||||
import { fetchFavicon, ActionStatus, AppThunk, parseRSS } from "../utils"
|
import { fetchFavicon, ActionStatus, AppThunk, parseRSS } from "../utils"
|
||||||
import { RSSItem, insertItems, ItemActionTypes, FETCH_ITEMS, MARK_READ, MARK_UNREAD, MARK_ALL_READ } from "./item"
|
import { RSSItem, insertItems, ItemActionTypes, FETCH_ITEMS, MARK_READ, MARK_UNREAD, MARK_ALL_READ } from "./item"
|
||||||
import { SourceGroup } from "./group"
|
|
||||||
import { saveSettings } from "./app"
|
import { saveSettings } from "./app"
|
||||||
import { remote } from "electron"
|
import { remote } from "electron"
|
||||||
import { SourceRule } from "./rule"
|
import { SourceRule } from "./rule"
|
||||||
@ -249,7 +248,7 @@ export function addSource(url: string, name: string = null, batch = false): AppT
|
|||||||
return RSSSource.checkItems(inserted, feed.items)
|
return RSSSource.checkItems(inserted, feed.items)
|
||||||
.then(items => insertItems(items))
|
.then(items => insertItems(items))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
return inserted.sid
|
return inserted.sid
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -310,7 +309,7 @@ export function deleteSource(source: RSSSource, batch = false): AppThunk<Promise
|
|||||||
resolve()
|
resolve()
|
||||||
} else {
|
} else {
|
||||||
dispatch(deleteSourceDone(source))
|
dispatch(deleteSourceDone(source))
|
||||||
SourceGroup.save(getState().groups)
|
window.settings.saveGroups(getState().groups)
|
||||||
if (!batch) dispatch(saveSettings())
|
if (!batch) dispatch(saveSettings())
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
|
@ -1,54 +1,12 @@
|
|||||||
import { remote, ipcRenderer } from "electron"
|
import { remote, ipcRenderer } from "electron"
|
||||||
import { ViewType } from "./models/page"
|
|
||||||
import { IPartialTheme, loadTheme } from "@fluentui/react"
|
import { IPartialTheme, loadTheme } from "@fluentui/react"
|
||||||
import locales from "./i18n/_locales"
|
import locales from "./i18n/_locales"
|
||||||
import Store = require("electron-store")
|
import Store = require("electron-store")
|
||||||
import { schemaTypes } from "./config-schema"
|
import { ThemeSettings, SchemaTypes } from "../schema-types"
|
||||||
import fs = require("fs")
|
import fs = require("fs")
|
||||||
import intl from "react-intl-universal"
|
import intl from "react-intl-universal"
|
||||||
|
|
||||||
export const store = new Store<schemaTypes>()
|
export const store = new Store<SchemaTypes>()
|
||||||
|
|
||||||
const MENU_STORE_KEY = "menuOn"
|
|
||||||
export function getDefaultMenu() {
|
|
||||||
return store.get(MENU_STORE_KEY, false)
|
|
||||||
}
|
|
||||||
export function setDefaultMenu(state: boolean) {
|
|
||||||
store.set(MENU_STORE_KEY, state)
|
|
||||||
}
|
|
||||||
|
|
||||||
const PAC_STORE_KEY = "pac"
|
|
||||||
const PAC_STATUS_KEY = "pacOn"
|
|
||||||
export function getProxyStatus() {
|
|
||||||
return store.get(PAC_STATUS_KEY, false)
|
|
||||||
}
|
|
||||||
export function toggleProxyStatus() {
|
|
||||||
store.set(PAC_STATUS_KEY, !getProxyStatus())
|
|
||||||
setProxy()
|
|
||||||
}
|
|
||||||
export function getProxy() {
|
|
||||||
return store.get(PAC_STORE_KEY, "")
|
|
||||||
}
|
|
||||||
export function setProxy(address = null) {
|
|
||||||
if (!address) {
|
|
||||||
address = getProxy()
|
|
||||||
} else {
|
|
||||||
store.set(PAC_STORE_KEY, address)
|
|
||||||
}
|
|
||||||
if (getProxyStatus()) {
|
|
||||||
let rules = { pacScript: address }
|
|
||||||
remote.getCurrentWebContents().session.setProxy(rules)
|
|
||||||
remote.session.fromPartition("sandbox").setProxy(rules)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const VIEW_STORE_KEY = "view"
|
|
||||||
export const getDefaultView = (): ViewType => {
|
|
||||||
return store.get(VIEW_STORE_KEY, ViewType.Cards)
|
|
||||||
}
|
|
||||||
export const setDefaultView = (viewType: ViewType) => {
|
|
||||||
store.set(VIEW_STORE_KEY, viewType)
|
|
||||||
}
|
|
||||||
|
|
||||||
const lightTheme: IPartialTheme = {
|
const lightTheme: IPartialTheme = {
|
||||||
defaultFontStyle: { fontFamily: '"Segoe UI", "Source Han Sans SC Regular", "Microsoft YaHei", sans-serif' }
|
defaultFontStyle: { fontFamily: '"Segoe UI", "Source Han Sans SC Regular", "Microsoft YaHei", sans-serif' }
|
||||||
@ -56,63 +14,50 @@ const lightTheme: IPartialTheme = {
|
|||||||
const darkTheme: IPartialTheme = {
|
const darkTheme: IPartialTheme = {
|
||||||
...lightTheme,
|
...lightTheme,
|
||||||
palette: {
|
palette: {
|
||||||
neutralLighterAlt: '#282828',
|
neutralLighterAlt: "#282828",
|
||||||
neutralLighter: '#313131',
|
neutralLighter: "#313131",
|
||||||
neutralLight: '#3f3f3f',
|
neutralLight: "#3f3f3f",
|
||||||
neutralQuaternaryAlt: '#484848',
|
neutralQuaternaryAlt: "#484848",
|
||||||
neutralQuaternary: '#4f4f4f',
|
neutralQuaternary: "#4f4f4f",
|
||||||
neutralTertiaryAlt: '#6d6d6d',
|
neutralTertiaryAlt: "#6d6d6d",
|
||||||
neutralTertiary: '#c8c8c8',
|
neutralTertiary: "#c8c8c8",
|
||||||
neutralSecondary: '#d0d0d0',
|
neutralSecondary: "#d0d0d0",
|
||||||
neutralSecondaryAlt: '#d2d0ce',
|
neutralSecondaryAlt: "#d2d0ce",
|
||||||
neutralPrimaryAlt: '#dadada',
|
neutralPrimaryAlt: "#dadada",
|
||||||
neutralPrimary: '#ffffff',
|
neutralPrimary: "#ffffff",
|
||||||
neutralDark: '#f4f4f4',
|
neutralDark: "#f4f4f4",
|
||||||
black: '#f8f8f8',
|
black: "#f8f8f8",
|
||||||
white: '#1f1f1f',
|
white: "#1f1f1f",
|
||||||
themePrimary: '#3a96dd',
|
themePrimary: "#3a96dd",
|
||||||
themeLighterAlt: '#020609',
|
themeLighterAlt: "#020609",
|
||||||
themeLighter: '#091823',
|
themeLighter: "#091823",
|
||||||
themeLight: '#112d43',
|
themeLight: "#112d43",
|
||||||
themeTertiary: '#235a85',
|
themeTertiary: "#235a85",
|
||||||
themeSecondary: '#3385c3',
|
themeSecondary: "#3385c3",
|
||||||
themeDarkAlt: '#4ba0e1',
|
themeDarkAlt: "#4ba0e1",
|
||||||
themeDark: '#65aee6',
|
themeDark: "#65aee6",
|
||||||
themeDarker: '#8ac2ec',
|
themeDarker: "#8ac2ec",
|
||||||
accent: '#3a96dd'
|
accent: "#3a96dd"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export enum ThemeSettings {
|
|
||||||
Default = "system",
|
|
||||||
Light = "light",
|
|
||||||
Dark = "dark"
|
|
||||||
}
|
|
||||||
const THEME_STORE_KEY = "theme"
|
const THEME_STORE_KEY = "theme"
|
||||||
export function setThemeSettings(theme: ThemeSettings) {
|
export function setThemeSettings(theme: ThemeSettings) {
|
||||||
store.set(THEME_STORE_KEY, theme)
|
window.settings.setThemeSettings(theme)
|
||||||
remote.nativeTheme.themeSource = theme
|
|
||||||
applyThemeSettings()
|
applyThemeSettings()
|
||||||
}
|
}
|
||||||
export function getThemeSettings(): ThemeSettings {
|
export function getThemeSettings(): ThemeSettings {
|
||||||
return store.get(THEME_STORE_KEY, ThemeSettings.Default)
|
return window.settings.getThemeSettings()
|
||||||
}
|
}
|
||||||
export function applyThemeSettings() {
|
export function applyThemeSettings() {
|
||||||
loadTheme(remote.nativeTheme.shouldUseDarkColors ? darkTheme : lightTheme)
|
loadTheme(window.settings.shouldUseDarkColors() ? darkTheme : lightTheme)
|
||||||
}
|
}
|
||||||
remote.nativeTheme.on("updated", () => {
|
window.settings.addThemeUpdateListener((shouldDark) => {
|
||||||
applyThemeSettings()
|
loadTheme(shouldDark ? darkTheme : lightTheme)
|
||||||
})
|
})
|
||||||
|
|
||||||
const LOCALE_STORE_KEY = "locale"
|
|
||||||
export function setLocaleSettings(option: string) {
|
|
||||||
store.set(LOCALE_STORE_KEY, option)
|
|
||||||
}
|
|
||||||
export function getLocaleSettings() {
|
|
||||||
return store.get(LOCALE_STORE_KEY, "default")
|
|
||||||
}
|
|
||||||
export function getCurrentLocale() {
|
export function getCurrentLocale() {
|
||||||
let set = getLocaleSettings()
|
let locale = window.settings.getCurrentLocale()
|
||||||
let locale = set === "default" ? remote.app.getLocale() : set
|
|
||||||
return (locale in locales) ? locale : "en-US"
|
return (locale in locales) ? locale : "en-US"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,25 @@ module.exports = [
|
|||||||
filename: 'electron.js'
|
filename: 'electron.js'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
mode: 'production',
|
||||||
|
entry: './src/preload.ts',
|
||||||
|
target: 'electron-preload',
|
||||||
|
module: {
|
||||||
|
rules: [{
|
||||||
|
test: /\.ts$/,
|
||||||
|
include: /src/,
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.js']
|
||||||
|
},
|
||||||
|
use: [{ loader: 'ts-loader' }]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: __dirname + '/dist',
|
||||||
|
filename: 'preload.js'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
entry: './src/index.tsx',
|
entry: './src/index.tsx',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user