Persist and restore settings

This commit is contained in:
Thomas Nordquist
2019-02-18 13:50:58 +01:00
parent 590c24a3bd
commit 160b0b5a04
6 changed files with 84 additions and 24 deletions

View File

@@ -11,7 +11,7 @@ import { AppState } from './reducers'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { default as SplitPane } from 'react-split-pane' import { default as SplitPane } from 'react-split-pane'
import { globalActions } from './actions' import { globalActions, settingsActions } from './actions'
import { Theme, withStyles } from '@material-ui/core/styles' import { Theme, withStyles } from '@material-ui/core/styles'
const Settings = React.lazy(() => import('./components/Settings')) const Settings = React.lazy(() => import('./components/Settings'))
@@ -22,7 +22,8 @@ interface Props {
classes: any classes: any
settingsVisible: boolean settingsVisible: boolean
error?: string error?: string
actions: any actions: typeof globalActions
settingsActions: typeof settingsActions
} }
class App extends React.PureComponent<Props, {}> { class App extends React.PureComponent<Props, {}> {
@@ -31,6 +32,10 @@ class App extends React.PureComponent<Props, {}> {
this.state = { } this.state = { }
} }
public componentDidMount() {
this.props.settingsActions.loadSettings()
}
private renderError() { private renderError() {
if (this.props.error) { if (this.props.error) {
const error = typeof this.props.error === 'string' ? this.props.error : JSON.stringify(this.props.error) const error = typeof this.props.error === 'string' ? this.props.error : JSON.stringify(this.props.error)
@@ -143,6 +148,7 @@ const styles = (theme: Theme) => {
const mapDispatchToProps = (dispatch: any) => { const mapDispatchToProps = (dispatch: any) => {
return { return {
actions: bindActionCreators(globalActions, dispatch), actions: bindActionCreators(globalActions, dispatch),
settingsActions: bindActionCreators(settingsActions, dispatch),
} }
} }

View File

@@ -44,7 +44,7 @@ class RemoteStorage implements PersistantStorage {
}) })
} }
public store<Model>(identifier: StorageIdentifier<Model>, data: Model): Promise<void> { public store<Model>(identifier: StorageIdentifier<Model>, data: Model): Promise<void> {
const transactionId = v4() const transactionId = v4()
const expectation = this.expectAck(transactionId) const expectation = this.expectAck(transactionId)
rendererEvents.emit(storageStoreEvent, { data, transactionId, store: identifier.id }) rendererEvents.emit(storageStoreEvent, { data, transactionId, store: identifier.id })

View File

@@ -35,6 +35,7 @@ export const loadConnectionSettings = () => async (dispatch: Dispatch<any>, getS
export const saveConnectionSettings = () => async (dispatch: Dispatch<any>, getState: () => AppState) => { export const saveConnectionSettings = () => async (dispatch: Dispatch<any>, getState: () => AppState) => {
try { try {
console.log('store settings')
await persistantStorage.store(storedConnectionsIdentifier, getState().connectionManager.connections) await persistantStorage.store(storedConnectionsIdentifier, getState().connectionManager.connections)
} catch (error) { } catch (error) {
dispatch(showError(error)) dispatch(showError(error))

View File

@@ -1,37 +1,76 @@
import { Action, ActionTypes, TopicOrder } from '../reducers/Settings'
import { ActionTypes as TreeActionTypes } from '../reducers/Tree'
import { Dispatch } from 'redux'
import { showTree } from './Tree'
import { AppState } from '../reducers'
import * as q from '../../../backend/src/Model' import * as q from '../../../backend/src/Model'
import { batchActions } from 'redux-batched-actions' import { AppState } from '../reducers'
import { autoExpandLimitSet } from '../components/Settings' import { autoExpandLimitSet } from '../components/Settings'
import { batchActions } from 'redux-batched-actions'
import { default as persistantStorage, StorageIdentifier } from '../PersistantStorage'
import { Dispatch } from 'redux'
import { showError } from './Global'
import { showTree } from './Tree'
import { TopicViewModel } from '../TopicViewModel' import { TopicViewModel } from '../TopicViewModel'
import {
ActionTypes,
SettingsState,
TopicOrder,
} from '../reducers/Settings'
export const setAutoExpandLimit = (autoExpandLimit: number = 0): Action => { const settingsIdentifier: StorageIdentifier<Partial<SettingsState>> = {
return { id: 'Settings',
}
export const loadSettings = () => async (dispatch: Dispatch<any>, _getState: () => AppState) => {
try {
const settings = await persistantStorage.load(settingsIdentifier)
dispatch({
settings,
type: ActionTypes.SETTINGS_DID_LOAD_SETTINGS,
})
} catch (error) {
dispatch(showError(error))
}
}
export const storeSettings = () => async (dispatch: Dispatch<any>, getState: () => AppState) => {
const settings = {
...getState().settings,
topicFilter: undefined,
visible: undefined,
}
try {
await persistantStorage.store(settingsIdentifier, settings)
} catch (error) {
dispatch(showError(error))
}
}
export const setAutoExpandLimit = (autoExpandLimit: number = 0) => (dispatch: Dispatch<any>, getState: () => AppState) => {
dispatch({
autoExpandLimit, autoExpandLimit,
type: ActionTypes.SETTINGS_SET_AUTO_EXPAND_LIMIT, type: ActionTypes.SETTINGS_SET_AUTO_EXPAND_LIMIT,
} })
dispatch(storeSettings())
} }
export const toggleSettingsVisibility = (): Action => { export const toggleSettingsVisibility = () => (dispatch: Dispatch<any>, _getState: () => AppState) => {
return { dispatch({
type: ActionTypes.SETTINGS_TOGGLE_VISIBILITY, type: ActionTypes.SETTINGS_TOGGLE_VISIBILITY,
} })
dispatch(storeSettings())
} }
export const togglehighlightTopicUpdates = (): Action => { export const togglehighlightTopicUpdates = () => (dispatch: Dispatch<any>, _getState: () => AppState) => {
return { dispatch({
type: ActionTypes.SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY, type: ActionTypes.SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY,
} })
dispatch(storeSettings())
} }
export const setTopicOrder = (topicOrder: TopicOrder = TopicOrder.none): Action => { export const setTopicOrder = (topicOrder: TopicOrder = TopicOrder.none) => (dispatch: Dispatch<any>, _getState: () => AppState) => {
return { dispatch({
topicOrder, topicOrder,
type: ActionTypes.SETTINGS_SET_TOPIC_ORDER, type: ActionTypes.SETTINGS_SET_TOPIC_ORDER,
} })
dispatch(storeSettings())
} }
export const filterTopics = (filterStr: string) => (dispatch: Dispatch<any>, getState: () => AppState) => { export const filterTopics = (filterStr: string) => (dispatch: Dispatch<any>, getState: () => AppState) => {

View File

@@ -23,6 +23,7 @@ export enum ActionTypes {
SETTINGS_SET_TOPIC_ORDER = 'SETTINGS_SET_TOPIC_ORDER', SETTINGS_SET_TOPIC_ORDER = 'SETTINGS_SET_TOPIC_ORDER',
SETTINGS_FILTER_TOPICS = 'SETTINGS_FILTER_TOPICS', SETTINGS_FILTER_TOPICS = 'SETTINGS_FILTER_TOPICS',
SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY = 'SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY', SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY = 'SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY',
SETTINGS_DID_LOAD_SETTINGS = 'SETTINGS_DID_LOAD_SETTINGS',
} }
const initialState: SettingsState = { const initialState: SettingsState = {
@@ -38,8 +39,21 @@ export const settingsReducer = createReducer(initialState, {
SETTINGS_SET_TOPIC_ORDER: setTopicOrder, SETTINGS_SET_TOPIC_ORDER: setTopicOrder,
SETTINGS_FILTER_TOPICS: filterTopics, SETTINGS_FILTER_TOPICS: filterTopics,
SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY: togglehighlightTopicUpdates, SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY: togglehighlightTopicUpdates,
SETTINGS_DID_LOAD_SETTINGS: didLoadSettings,
}) })
export interface DidLoadSettings {
type: ActionTypes.SETTINGS_DID_LOAD_SETTINGS
settings: Partial<SettingsState>
}
function didLoadSettings(state: SettingsState, action: DidLoadSettings) {
return {
...state,
...action.settings,
}
}
export interface SetAutoExpandLimit { export interface SetAutoExpandLimit {
type: ActionTypes.SETTINGS_SET_AUTO_EXPAND_LIMIT type: ActionTypes.SETTINGS_SET_AUTO_EXPAND_LIMIT
autoExpandLimit: number autoExpandLimit: number

View File

@@ -33,8 +33,8 @@ export default class ConfigStorage {
await db.set(event.store, event.data).write() await db.set(event.store, event.data).write()
backendEvents.emit(ack, undefined) backendEvents.emit(ack, undefined)
} catch (error) { } catch (error) {
console.error(error)
backendEvents.emit(ack, { error, transactionId: event.transactionId, store: event.store }) backendEvents.emit(ack, { error, transactionId: event.transactionId, store: event.store })
throw error
} }
}) })
@@ -45,8 +45,8 @@ export default class ConfigStorage {
const data = await db.get(event.store).value() const data = await db.get(event.store).value()
backendEvents.emit(responseEvent, { data, transactionId: event.transactionId, store: event.store }) backendEvents.emit(responseEvent, { data, transactionId: event.transactionId, store: event.store })
} catch (error) { } catch (error) {
console.error(error)
backendEvents.emit(responseEvent, { error, transactionId: event.transactionId, store: event.store }) backendEvents.emit(responseEvent, { error, transactionId: event.transactionId, store: event.store })
throw error
} }
}) })
@@ -60,8 +60,8 @@ export default class ConfigStorage {
backendEvents.emit(makeStorageAcknoledgementEvent(event.transactionId), undefined) backendEvents.emit(makeStorageAcknoledgementEvent(event.transactionId), undefined)
} catch (error) { } catch (error) {
backendEvents.emit(makeStorageAcknoledgementEvent(event.transactionId), { error, transactionId: event.transactionId }) backendEvents.emit(makeStorageAcknoledgementEvent(event.transactionId), { error, transactionId: event.transactionId })
throw error
} }
}) })
} }
} }