Fix updating tree nodes when settings change

This commit is contained in:
Thomas Nordquist
2019-04-07 22:56:10 +02:00
parent 3e47b07ba7
commit 436b569e93
12 changed files with 85 additions and 126 deletions

View File

@@ -157,7 +157,7 @@ function autoExpandLimitForTree(tree: q.Tree<TopicViewModel>) {
export const toggleTheme = () => (dispatch: Dispatch<any>, getState: () => AppState) => { export const toggleTheme = () => (dispatch: Dispatch<any>, getState: () => AppState) => {
dispatch({ dispatch({
type: getState().settings.theme === 'light' ? ActionTypes.SETTINGS_SET_THEME_DARK : ActionTypes.SETTINGS_SET_THEME_LIGHT, type: getState().settings.get('theme') === 'light' ? ActionTypes.SETTINGS_SET_THEME_DARK : ActionTypes.SETTINGS_SET_THEME_LIGHT,
}) })
dispatch(storeSettings()) dispatch(storeSettings())
} }

View File

@@ -131,10 +131,10 @@ const mapDispatchToProps = (dispatch: any) => {
const mapStateToProps = (state: AppState) => { const mapStateToProps = (state: AppState) => {
return { return {
settingsVisible: state.settings.visible, settingsVisible: state.settings.get('visible'),
connectionId: state.connection.connectionId, connectionId: state.connection.connectionId,
error: state.globalState.error, error: state.globalState.error,
highlightTopicUpdates: state.settings.highlightTopicUpdates, highlightTopicUpdates: state.settings.get('highlightTopicUpdates'),
launching: state.globalState.launching, launching: state.globalState.launching,
} }
} }

View File

@@ -142,7 +142,7 @@ class TitleBar extends React.Component<Props, {}> {
const mapStateToProps = (state: AppState) => { const mapStateToProps = (state: AppState) => {
return { return {
topicFilter: state.settings.topicFilter, topicFilter: state.settings.get('topicFilter'),
} }
} }

View File

@@ -236,12 +236,12 @@ class Settings extends React.Component<Props, {}> {
const mapStateToProps = (state: AppState) => { const mapStateToProps = (state: AppState) => {
return { return {
autoExpandLimit: state.settings.autoExpandLimit, autoExpandLimit: state.settings.get('autoExpandLimit'),
topicOrder: state.settings.topicOrder, topicOrder: state.settings.get('topicOrder'),
visible: state.settings.visible, visible: state.settings.get('visible'),
highlightTopicUpdates: state.settings.highlightTopicUpdates, highlightTopicUpdates: state.settings.get('highlightTopicUpdates'),
selectTopicWithMouseOver: state.settings.selectTopicWithMouseOver, selectTopicWithMouseOver: state.settings.get('selectTopicWithMouseOver'),
theme: state.settings.theme, theme: state.settings.get('theme'),
} }
} }

View File

@@ -163,7 +163,7 @@ const mapDispatchToProps = (dispatch: any) => {
const mapStateToProps = (state: AppState) => { const mapStateToProps = (state: AppState) => {
return { return {
valueRendererDisplayMode: state.settings.valueRendererDisplayMode, valueRendererDisplayMode: state.settings.get('valueRendererDisplayMode'),
node: state.tree.selectedTopic, node: state.tree.selectedTopic,
} }
} }

View File

@@ -105,7 +105,7 @@ class ValueRenderer extends React.Component<Props, State> {
const mapStateToProps = (state: AppState) => { const mapStateToProps = (state: AppState) => {
return { return {
renderMode: state.settings.valueRendererDisplayMode, renderMode: state.settings.get('valueRendererDisplayMode'),
} }
} }

View File

@@ -4,7 +4,8 @@ import TreeNode from './TreeNode'
import { AppState } from '../../reducers' import { AppState } from '../../reducers'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { TopicOrder } from '../../reducers/Settings' import { Record } from 'immutable'
import { SettingsState } from '../../reducers/Settings'
import { TopicViewModel } from '../../model/TopicViewModel' import { TopicViewModel } from '../../model/TopicViewModel'
import { treeActions } from '../../actions' import { treeActions } from '../../actions'
@@ -21,11 +22,8 @@ interface Props {
tree?: q.Tree<TopicViewModel> tree?: q.Tree<TopicViewModel>
filter: string filter: string
host?: string host?: string
topicOrder: TopicOrder
autoExpandLimit: number
highlightTopicUpdates: boolean
selectTopicWithMouseOver: boolean
paused: boolean paused: boolean
settings: Record<SettingsState>
} }
interface State { interface State {
@@ -109,18 +107,14 @@ class Tree extends React.PureComponent<Props, State> {
<div style={style}> <div style={style}>
<TreeNode <TreeNode
key={tree.hash()} key={tree.hash()}
animateChages={true}
isRoot={true} isRoot={true}
treeNode={tree} treeNode={tree}
name={this.props.host} name={this.props.host}
collapsed={false} collapsed={false}
performanceCallback={this.performanceCallback} performanceCallback={this.performanceCallback}
autoExpandLimit={this.props.autoExpandLimit} settings={this.props.settings}
topicOrder={this.props.topicOrder}
lastUpdate={tree.lastUpdate} lastUpdate={tree.lastUpdate}
didSelectTopic={this.props.actions.selectTopic} didSelectTopic={this.props.actions.selectTopic}
highlightTopicUpdates={this.props.highlightTopicUpdates}
selectTopicWithMouseOver={this.props.selectTopicWithMouseOver}
/> />
</div> </div>
) )
@@ -133,10 +127,7 @@ const mapStateToProps = (state: AppState) => {
paused: state.tree.paused, paused: state.tree.paused,
filter: state.tree.filter, filter: state.tree.filter,
host: state.connection.host, host: state.connection.host,
autoExpandLimit: state.settings.autoExpandLimit, settings: state.settings,
topicOrder: state.settings.topicOrder,
highlightTopicUpdates: state.settings.highlightTopicUpdates,
selectTopicWithMouseOver: state.settings.selectTopicWithMouseOver,
} }
} }

View File

@@ -2,8 +2,9 @@ import * as q from '../../../../backend/src/Model'
import * as React from 'react' import * as React from 'react'
import TreeNodeSubnodes from './TreeNodeSubnodes' import TreeNodeSubnodes from './TreeNodeSubnodes'
import TreeNodeTitle from './TreeNodeTitle' import TreeNodeTitle from './TreeNodeTitle'
import { Record } from 'immutable'
import { SettingsState } from '../../reducers/Settings'
import { Theme, withStyles } from '@material-ui/core/styles' import { Theme, withStyles } from '@material-ui/core/styles'
import { TopicOrder } from '../../reducers/Settings'
import { TopicViewModel } from '../../model/TopicViewModel' import { TopicViewModel } from '../../model/TopicViewModel'
const debounce = require('lodash.debounce') const debounce = require('lodash.debounce')
@@ -41,7 +42,6 @@ const styles = (theme: Theme) => {
} }
interface Props { interface Props {
animateChages: boolean
isRoot?: boolean isRoot?: boolean
treeNode: q.TreeNode<TopicViewModel> treeNode: q.TreeNode<TopicViewModel>
name?: string | undefined name?: string | undefined
@@ -49,13 +49,10 @@ interface Props {
performanceCallback?: ((ms: number) => void) | undefined performanceCallback?: ((ms: number) => void) | undefined
classes: any classes: any
className?: string className?: string
topicOrder: TopicOrder
autoExpandLimit: number
lastUpdate: number lastUpdate: number
didSelectTopic: any didSelectTopic: any
highlightTopicUpdates: boolean
selectTopicWithMouseOver: boolean
theme: Theme theme: Theme
settings: Record<SettingsState>
} }
interface State { interface State {
@@ -127,10 +124,6 @@ class TreeNode extends React.Component<Props, State> {
|| this.state.selected !== newState.selected || this.state.selected !== newState.selected
} }
private propsHasChanged(newProps: Props) {
return this.props.autoExpandLimit !== newProps.autoExpandLimit
}
private toggle() { private toggle() {
this.setState({ collapsedOverride: !this.collapsed() }) this.setState({ collapsedOverride: !this.collapsed() })
} }
@@ -140,7 +133,7 @@ class TreeNode extends React.Component<Props, State> {
return this.state.collapsedOverride return this.state.collapsedOverride
} }
return this.props.treeNode.edgeCount() > this.props.autoExpandLimit return this.props.treeNode.edgeCount() > this.props.settings.get('autoExpandLimit')
} }
private didSelectTopic = () => { private didSelectTopic = () => {
@@ -156,7 +149,7 @@ class TreeNode extends React.Component<Props, State> {
private mouseOver = (event: React.MouseEvent) => { private mouseOver = (event: React.MouseEvent) => {
event.stopPropagation() event.stopPropagation()
this.setHover(true) this.setHover(true)
if (this.props.selectTopicWithMouseOver && this.props.treeNode && this.props.treeNode.message && this.props.treeNode.message.value) { if (this.props.settings.get('selectTopicWithMouseOver') && this.props.treeNode && this.props.treeNode.message && this.props.treeNode.message.value) {
this.props.didSelectTopic(this.props.treeNode) this.props.didSelectTopic(this.props.treeNode)
} }
} }
@@ -178,15 +171,11 @@ class TreeNode extends React.Component<Props, State> {
return ( return (
<TreeNodeSubnodes <TreeNodeSubnodes
animateChanges={this.props.animateChages}
collapsed={this.collapsed()} collapsed={this.collapsed()}
treeNode={this.props.treeNode} treeNode={this.props.treeNode}
autoExpandLimit={this.props.autoExpandLimit}
topicOrder={this.props.topicOrder}
lastUpdate={this.props.treeNode.lastUpdate} lastUpdate={this.props.treeNode.lastUpdate}
didSelectTopic={this.props.didSelectTopic} didSelectTopic={this.props.didSelectTopic}
highlightTopicUpdates={this.props.highlightTopicUpdates} settings={this.props.settings}
selectTopicWithMouseOver={this.props.selectTopicWithMouseOver}
/> />
) )
} }
@@ -212,7 +201,7 @@ class TreeNode extends React.Component<Props, State> {
public shouldComponentUpdate(nextProps: Props, nextState: State) { public shouldComponentUpdate(nextProps: Props, nextState: State) {
const shouldRenderToRemoveCssAnimation = this.cssAnimationWasSetAt !== undefined const shouldRenderToRemoveCssAnimation = this.cssAnimationWasSetAt !== undefined
return this.stateHasChanged(nextState) return this.stateHasChanged(nextState)
|| this.propsHasChanged(nextProps) || this.props.settings !== nextProps.settings
|| (this.dirtyEdges || this.dirtyMessage || this.dirtySubnodes) || (this.dirtyEdges || this.dirtyMessage || this.dirtySubnodes)
|| this.animationDirty || this.animationDirty
|| shouldRenderToRemoveCssAnimation || shouldRenderToRemoveCssAnimation
@@ -236,7 +225,7 @@ class TreeNode extends React.Component<Props, State> {
const isDirty = this.dirtyEdges || this.dirtyMessage || this.dirtySubnodes const isDirty = this.dirtyEdges || this.dirtyMessage || this.dirtySubnodes
this.dirtyEdges = this.dirtyMessage = this.dirtySubnodes = false this.dirtyEdges = this.dirtyMessage = this.dirtySubnodes = false
const shouldStartAnimation = (isDirty && !this.animationDirty) && !this.props.isRoot && this.props.highlightTopicUpdates const shouldStartAnimation = (isDirty && !this.animationDirty) && !this.props.isRoot && this.props.settings.get('highlightTopicUpdates')
const animationName = this.props.theme.palette.type === 'light' ? 'updateLight' : 'updateDark' const animationName = this.props.theme.palette.type === 'light' ? 'updateLight' : 'updateDark'
const animation = shouldStartAnimation ? { willChange: 'auto', translateZ: 0, animation: `${animationName} 0.5s` } : {} const animation = shouldStartAnimation ? { willChange: 'auto', translateZ: 0, animation: `${animationName} 0.5s` } : {}
this.animationDirty = shouldStartAnimation this.animationDirty = shouldStartAnimation

View File

@@ -1,24 +1,20 @@
import * as React from 'react'
import * as q from '../../../../backend/src/Model' import * as q from '../../../../backend/src/Model'
import * as React from 'react'
import TreeNode from './TreeNode' import TreeNode from './TreeNode'
import { TopicOrder } from '../../reducers/Settings' import { Record } from 'immutable'
import { SettingsState, TopicOrder } from '../../reducers/Settings'
import { Theme, withStyles } from '@material-ui/core' import { Theme, withStyles } from '@material-ui/core'
import { TopicViewModel } from '../../model/TopicViewModel' import { TopicViewModel } from '../../model/TopicViewModel'
export interface Props { export interface Props {
animateChanges: boolean
treeNode: q.TreeNode<TopicViewModel> treeNode: q.TreeNode<TopicViewModel>
filter?: string filter?: string
collapsed?: boolean | undefined collapsed?: boolean | undefined
classes: any classes: any
lastUpdate: number lastUpdate: number
topicOrder: TopicOrder
selectedTopic?: q.TreeNode<TopicViewModel> selectedTopic?: q.TreeNode<TopicViewModel>
autoExpandLimit: number
didSelectTopic: any didSelectTopic: any
highlightTopicUpdates: boolean settings: Record<SettingsState>
selectTopicWithMouseOver: boolean
} }
interface State { interface State {
@@ -33,7 +29,8 @@ class TreeNodeSubnodes extends React.Component<Props, State> {
} }
private sortedNodes(): Array<q.TreeNode<TopicViewModel>> { private sortedNodes(): Array<q.TreeNode<TopicViewModel>> {
const { topicOrder, treeNode } = this.props const { settings, treeNode } = this.props
const topicOrder = settings.get('topicOrder')
let edges = treeNode.edgeArray let edges = treeNode.edgeArray
if (topicOrder === TopicOrder.abc) { if (topicOrder === TopicOrder.abc) {
@@ -76,15 +73,11 @@ class TreeNodeSubnodes extends React.Component<Props, State> {
return ( return (
<TreeNode <TreeNode
key={`${node.hash()}-${this.props.filter}`} key={`${node.hash()}-${this.props.filter}`}
animateChages={this.props.animateChanges}
treeNode={node} treeNode={node}
className={this.props.classes.listItem} className={this.props.classes.listItem}
topicOrder={this.props.topicOrder}
autoExpandLimit={this.props.autoExpandLimit}
lastUpdate={node.lastUpdate} lastUpdate={node.lastUpdate}
didSelectTopic={this.props.didSelectTopic} didSelectTopic={this.props.didSelectTopic}
highlightTopicUpdates={this.props.highlightTopicUpdates} settings={this.props.settings}
selectTopicWithMouseOver={this.props.selectTopicWithMouseOver}
/> />
) )
}) })

View File

@@ -64,7 +64,7 @@ function ApplicationRenderer(props: {theme: 'light' | 'dark'}) {
const mapStateToProps = (state: AppState) => { const mapStateToProps = (state: AppState) => {
return { return {
theme: state.settings.theme, theme: state.settings.get('theme'),
} }
} }

View File

@@ -1,5 +1,5 @@
import { Action } from 'redux'
import { createReducer } from './lib' import { createReducer } from './lib'
import { Record } from 'immutable'
export enum TopicOrder { export enum TopicOrder {
none = 'none', none = 'none',
@@ -21,7 +21,15 @@ export interface SettingsState {
theme: 'light' | 'dark' theme: 'light' | 'dark'
} }
export type Action = SetAutoExpandLimit | ToggleVisibility | SetTopicOrder | FilterTopics | TogglehighlightTopicUpdates | SetValueRendererDisplayMode | SetTheme export type Actions = SetAutoExpandLimitAction
& DidLoadSettingsAction
& ToggleVisibilityAction
& SetTopicOrderAction
& FilterTopicsAction
& ToggleHighlightTopicUpdatesAction
& SetValueRendererDisplayModeAction
& SetTheme
& SetSelectTopicWithMouseOverAction
export enum ActionTypes { export enum ActionTypes {
SETTINGS_SET_AUTO_EXPAND_LIMIT = 'SETTINGS_SET_AUTO_EXPAND_LIMIT', SETTINGS_SET_AUTO_EXPAND_LIMIT = 'SETTINGS_SET_AUTO_EXPAND_LIMIT',
@@ -36,131 +44,108 @@ export enum ActionTypes {
SETTINGS_SET_THEME_DARK = 'SETTINGS_SET_THEME_DARK', SETTINGS_SET_THEME_DARK = 'SETTINGS_SET_THEME_DARK',
} }
const initialState: SettingsState = { const initialState = Record<SettingsState>({
autoExpandLimit: 0, autoExpandLimit: 0,
topicOrder: TopicOrder.none, topicOrder: TopicOrder.none,
visible: false, visible: false,
highlightTopicUpdates: true, highlightTopicUpdates: true,
valueRendererDisplayMode: 'diff', valueRendererDisplayMode: 'diff',
selectTopicWithMouseOver: false, selectTopicWithMouseOver: false,
theme: 'dark', theme: 'light',
})
const setTheme = (theme: 'light' | 'dark') => (state: Record<SettingsState>) => {
return state.set('theme', theme)
} }
const setTheme = (theme: 'light' | 'dark') => (state: SettingsState) => { const reducerActions: {[s: string]: (state: Record<SettingsState>, action: Actions) => Record<SettingsState>} = {
return {
...state,
theme,
}
}
export const settingsReducer = createReducer(initialState, {
SETTINGS_SET_AUTO_EXPAND_LIMIT: setAutoExpandLimit, SETTINGS_SET_AUTO_EXPAND_LIMIT: setAutoExpandLimit,
SETTINGS_TOGGLE_VISIBILITY: toggleVisibility, SETTINGS_TOGGLE_VISIBILITY: toggleVisibility,
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, SETTINGS_DID_LOAD_SETTINGS: didLoadSettings,
SETTINGS_SET_VALUE_RENDERER_DISPLAY_MODE: setValueRendererDisplayMode, SETTINGS_SET_VALUE_RENDERER_DISPLAY_MODE: setValueRendererDisplayMode,
SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER: setSelectTopicWithMouseOver, SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER: setSelectTopicWithMouseOver,
SETTINGS_SET_THEME_LIGHT: setTheme('light'), SETTINGS_SET_THEME_LIGHT: setTheme('light'),
SETTINGS_SET_THEME_DARK: setTheme('dark'), SETTINGS_SET_THEME_DARK: setTheme('dark'),
}) }
export const settingsReducer = createReducer(initialState(), reducerActions)
export interface SetTheme { export interface SetTheme {
type: ActionTypes.SETTINGS_SET_THEME_LIGHT | ActionTypes.SETTINGS_SET_THEME_DARK type: ActionTypes.SETTINGS_SET_THEME_LIGHT | ActionTypes.SETTINGS_SET_THEME_DARK
theme: 'light' theme: 'light'
} }
export interface DidLoadSettings { export interface DidLoadSettingsAction {
type: ActionTypes.SETTINGS_DID_LOAD_SETTINGS type: ActionTypes.SETTINGS_DID_LOAD_SETTINGS
settings: Partial<SettingsState> settings: Partial<SettingsState>
} }
function didLoadSettings(state: SettingsState, action: DidLoadSettings) { function didLoadSettings(state: Record<SettingsState>, action: DidLoadSettingsAction) {
return { return state.merge(action.settings)
...state,
...action.settings,
}
} }
export interface SetSelectTopicWithMouseOver { export interface SetSelectTopicWithMouseOverAction {
type: ActionTypes.SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER type: ActionTypes.SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER
selectTopicWithMouseOver: boolean selectTopicWithMouseOver: boolean
} }
export function setSelectTopicWithMouseOver(state: SettingsState, action: SetSelectTopicWithMouseOver) { export function setSelectTopicWithMouseOver(state: Record<SettingsState>, action: SetSelectTopicWithMouseOverAction) {
return { return state.set('selectTopicWithMouseOver', !state.get('selectTopicWithMouseOver'))
...state,
selectTopicWithMouseOver: action.selectTopicWithMouseOver,
}
} }
export interface SetValueRendererDisplayMode { export interface SetValueRendererDisplayModeAction {
type: ActionTypes.SETTINGS_SET_VALUE_RENDERER_DISPLAY_MODE type: ActionTypes.SETTINGS_SET_VALUE_RENDERER_DISPLAY_MODE
valueRendererDisplayMode: ValueRendererDisplayMode valueRendererDisplayMode: ValueRendererDisplayMode
} }
export function setValueRendererDisplayMode(state: SettingsState, action: SetValueRendererDisplayMode) { export function setValueRendererDisplayMode(state: Record<SettingsState>, action: SetValueRendererDisplayModeAction) {
return { return state.set('valueRendererDisplayMode', action.valueRendererDisplayMode)
...state,
valueRendererDisplayMode: action.valueRendererDisplayMode,
}
} }
export interface SetAutoExpandLimit { export interface SetAutoExpandLimitAction {
type: ActionTypes.SETTINGS_SET_AUTO_EXPAND_LIMIT type: ActionTypes.SETTINGS_SET_AUTO_EXPAND_LIMIT
autoExpandLimit: number autoExpandLimit: number
} }
function setAutoExpandLimit(state: SettingsState, action: SetAutoExpandLimit) { function setAutoExpandLimit(state: Record<SettingsState>, action: SetAutoExpandLimitAction) {
return { return state.set('autoExpandLimit', action.autoExpandLimit)
...state,
autoExpandLimit: action.autoExpandLimit,
}
} }
export interface TogglehighlightTopicUpdates { export interface ToggleHighlightTopicUpdatesAction {
type: ActionTypes.SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY type: ActionTypes.SETTINGS_TOGGLE_HIGHLIGHT_ACTIVITY
} }
function togglehighlightTopicUpdates(state: SettingsState, _action: TogglehighlightTopicUpdates) { function toggleHighlightTopicUpdates(state: Record<SettingsState>, action: ToggleHighlightTopicUpdatesAction) {
return { return state.set('highlightTopicUpdates', !state.get('highlightTopicUpdates'))
...state,
highlightTopicUpdates: !state.highlightTopicUpdates,
}
} }
export interface ToggleVisibility { export interface ToggleVisibilityAction {
type: ActionTypes.SETTINGS_TOGGLE_VISIBILITY type: ActionTypes.SETTINGS_TOGGLE_VISIBILITY
} }
function toggleVisibility(state: SettingsState, action: ToggleVisibility) { // Todo: Should not be part of the settings store, it would require all tree nodes to re-render when toggeling settings
return { function toggleVisibility(state: Record<SettingsState>, action: ToggleVisibilityAction) {
...state, return state.set('visible', !state.get('visible'))
visible: !state.visible,
}
} }
function setTopicOrder(state: SettingsState, action: SetTopicOrder) { export interface SetTopicOrderAction {
return {
...state,
topicOrder: action.topicOrder,
}
}
export interface SetTopicOrder {
type: ActionTypes.SETTINGS_SET_TOPIC_ORDER type: ActionTypes.SETTINGS_SET_TOPIC_ORDER
topicOrder: string topicOrder: TopicOrder
} }
function filterTopics(state: SettingsState, action: FilterTopics) { function setTopicOrder(state: Record<SettingsState>, action: SetTopicOrderAction) {
return { return state.set('topicOrder', action.topicOrder)
...state,
topicFilter: action.topicFilter,
}
} }
export interface FilterTopics { export interface FilterTopicsAction {
type: ActionTypes.SETTINGS_FILTER_TOPICS type: ActionTypes.SETTINGS_FILTER_TOPICS
topicFilter: string topicFilter: string
} }
// @Todo: move to tree reducer, should not be persisted / is no application setting
function filterTopics(state: Record<SettingsState>, action: FilterTopicsAction) {
return state.set('topicFilter', action.topicFilter)
}

View File

@@ -2,6 +2,7 @@ import { Action, combineReducers, Reducer } from 'redux'
import { connectionManagerReducer, ConnectionManagerState } from './ConnectionManager' import { connectionManagerReducer, ConnectionManagerState } from './ConnectionManager'
import { connectionReducer, ConnectionState } from './Connection' import { connectionReducer, ConnectionState } from './Connection'
import { publishReducer, PublishState } from './Publish' import { publishReducer, PublishState } from './Publish'
import { Record } from 'immutable'
import { settingsReducer, SettingsState } from './Settings' import { settingsReducer, SettingsState } from './Settings'
import { trackEvent } from '../utils/tracking' import { trackEvent } from '../utils/tracking'
import { treeReducer, TreeState } from './Tree' import { treeReducer, TreeState } from './Tree'
@@ -23,7 +24,7 @@ export interface CustomAction extends Action {
export interface AppState { export interface AppState {
globalState: GlobalState globalState: GlobalState
tree: TreeState tree: TreeState
settings: SettingsState, settings: Record<SettingsState>,
publish: PublishState publish: PublishState
connection: ConnectionState connection: ConnectionState
connectionManager: ConnectionManagerState connectionManager: ConnectionManagerState