Add theme toggle
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
import { ActionTypes } from '../reducers'
|
||||
import { ActionTypes, AppState, CustomAction } from '../reducers'
|
||||
import { Dispatch } from 'redux';
|
||||
|
||||
export const showError = (error?: string) => ({
|
||||
error,
|
||||
type: ActionTypes.showError,
|
||||
})
|
||||
|
||||
export const toggleTheme = () => (dispatch: Dispatch<CustomAction>, getState: () => AppState) => {
|
||||
dispatch({
|
||||
type: getState().globalState.theme === 'light' ? ActionTypes.setDarkTheme : ActionTypes.setLightTheme,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -106,12 +106,13 @@ class BrokerStatistics extends React.Component<Props, {}> {
|
||||
|
||||
public renderStat(tree: q.Tree<TopicViewModel>, stat: Stats) {
|
||||
const node = tree.findNode(stat.topic)
|
||||
if (!node) {
|
||||
if (!node || !node.message) {
|
||||
return null
|
||||
}
|
||||
|
||||
let value = (node.message && node.message.value) ? parseFloat(Base64Message.toUnicodeString(node.message.value)) : NaN
|
||||
value = !isNaN(value) ? abbreviate(value) : value
|
||||
const str = node.message.value ? Base64Message.toUnicodeString(node.message.value) : ''
|
||||
let value = (node.message && node.message.value) ? parseFloat(str) : NaN
|
||||
value = !isNaN(value) ? abbreviate(value) : str
|
||||
|
||||
return (
|
||||
<div key={stat.title}>
|
||||
|
||||
@@ -4,7 +4,7 @@ import ChevronRight from '@material-ui/icons/ChevronRight'
|
||||
import { AppState } from '../reducers'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { connect } from 'react-redux'
|
||||
import { settingsActions } from '../actions'
|
||||
import { settingsActions, globalActions } from '../actions'
|
||||
import { shell } from 'electron'
|
||||
import { StyleRulesCallback, withStyles } from '@material-ui/core/styles'
|
||||
import { TopicOrder } from '../reducers/Settings'
|
||||
@@ -70,6 +70,7 @@ const styles: StyleRulesCallback = theme => ({
|
||||
|
||||
interface Props {
|
||||
actions: typeof settingsActions
|
||||
globalActions: typeof globalActions
|
||||
autoExpandLimit: number
|
||||
classes: any
|
||||
highlightTopicUpdates: boolean
|
||||
@@ -77,6 +78,7 @@ interface Props {
|
||||
store?: any
|
||||
topicOrder: TopicOrder
|
||||
visible: boolean
|
||||
theme: 'light' | 'dark'
|
||||
}
|
||||
|
||||
class Settings extends React.Component<Props, {}> {
|
||||
@@ -112,6 +114,7 @@ class Settings extends React.Component<Props, {}> {
|
||||
{this.renderNodeOrder()}
|
||||
{this.renderHighlightTopicUpdates()}
|
||||
{this.selectTopicsOnMouseOver()}
|
||||
{this.toggleTheme()}
|
||||
</div>
|
||||
<Tooltip placement="top" title="App Author">
|
||||
<Typography className={classes.author} onClick={this.openGithubPage}>
|
||||
@@ -173,6 +176,12 @@ class Settings extends React.Component<Props, {}> {
|
||||
return this.renderSwitch('Quick Preview', selectTopicWithMouseOver, toggle, 'Select topics on mouse over')
|
||||
}
|
||||
|
||||
private toggleTheme() {
|
||||
const { globalActions, theme } = this.props
|
||||
|
||||
return this.renderSwitch('Theme', theme === 'light', globalActions.toggleTheme, 'Select a theme')
|
||||
}
|
||||
|
||||
private renderAutoExpand() {
|
||||
const { classes, autoExpandLimit } = this.props
|
||||
|
||||
@@ -233,12 +242,14 @@ const mapStateToProps = (state: AppState) => {
|
||||
visible: state.settings.visible,
|
||||
highlightTopicUpdates: state.settings.highlightTopicUpdates,
|
||||
selectTopicWithMouseOver: state.settings.selectTopicWithMouseOver,
|
||||
theme: state.globalState.theme,
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (dispatch: any) => {
|
||||
return {
|
||||
actions: bindActionCreators(settingsActions, dispatch),
|
||||
globalActions: bindActionCreators(globalActions, dispatch),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ class Publish extends React.Component<Props, State> {
|
||||
private history() {
|
||||
const items = this.state.history.reverse().map(message => ({
|
||||
title: message.topic,
|
||||
value: message.payload,
|
||||
value: message.payload || '',
|
||||
}))
|
||||
|
||||
return <History items={items} onClick={this.didSelectHistoryEntry} />
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import * as React from 'react'
|
||||
import * as ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import Demo from './components/demo'
|
||||
import reducers from './reducers'
|
||||
import Demo from './components/Demo'
|
||||
import reducers, { AppState } from './reducers'
|
||||
import reduxThunk from 'redux-thunk'
|
||||
import { applyMiddleware, compose, createStore } from 'redux'
|
||||
import { batchDispatchMiddleware } from 'redux-batched-actions'
|
||||
import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles'
|
||||
import { Provider } from 'react-redux'
|
||||
import { createMuiTheme, MuiThemeProvider, Theme } from '@material-ui/core/styles'
|
||||
import { Provider, connect } from 'react-redux'
|
||||
import './tracking'
|
||||
|
||||
|
||||
|
||||
|
||||
const composeEnhancers = /*(window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || */ compose
|
||||
const store = createStore(
|
||||
reducers,
|
||||
@@ -24,12 +21,6 @@ const store = createStore(
|
||||
),
|
||||
)
|
||||
|
||||
const theme = createMuiTheme({
|
||||
palette: {
|
||||
type: 'dark',
|
||||
},
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
const splash = document.getElementById('splash')
|
||||
if (splash) {
|
||||
@@ -38,12 +29,42 @@ setTimeout(() => {
|
||||
}
|
||||
}, 300)
|
||||
|
||||
function createTheme(type: 'light' | 'dark') {
|
||||
if (type === 'dark') {
|
||||
return createMuiTheme({
|
||||
palette: {
|
||||
type: 'dark',
|
||||
},
|
||||
})
|
||||
} else {
|
||||
return createMuiTheme({
|
||||
palette: {
|
||||
type: 'light',
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function ApplicationRenderer(props: {theme: 'light' | 'dark'}) {
|
||||
return (
|
||||
<MuiThemeProvider theme={createTheme(props.theme)}>
|
||||
<App />
|
||||
<Demo />
|
||||
</MuiThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return {
|
||||
theme: state.globalState.theme,
|
||||
}
|
||||
}
|
||||
|
||||
const Application = connect(mapStateToProps)(ApplicationRenderer)
|
||||
|
||||
ReactDOM.render(
|
||||
<MuiThemeProvider theme={theme}>
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
<Demo />
|
||||
</Provider>
|
||||
</MuiThemeProvider>,
|
||||
document.getElementById('app'),
|
||||
<Provider store={store}>
|
||||
<Application />
|
||||
</Provider>,
|
||||
document.getElementById('app'),
|
||||
)
|
||||
|
||||
@@ -6,11 +6,12 @@ import { settingsReducer, SettingsState } from './Settings'
|
||||
import { trackEvent } from '../tracking'
|
||||
import { treeReducer, TreeState } from './Tree'
|
||||
|
||||
|
||||
export enum ActionTypes {
|
||||
showUpdateNotification = 'SHOW_UPDATE_NOTIFICATION',
|
||||
showUpdateDetails = 'SHOW_UPDATE_DETAILS',
|
||||
showError = 'SHOW_ERROR',
|
||||
setDarkTheme = 'GLOBAL_SET_DARK_THEME',
|
||||
setLightTheme = 'GLOBAL_SET_LIGHT_THEME',
|
||||
}
|
||||
|
||||
export interface CustomAction extends Action {
|
||||
@@ -33,13 +34,15 @@ export interface GlobalState {
|
||||
showUpdateNotification?: boolean
|
||||
showUpdateDetails: boolean
|
||||
error?: string
|
||||
theme: 'light' | 'dark'
|
||||
}
|
||||
|
||||
const initialBigState: GlobalState = {
|
||||
const initialGlobalState: GlobalState = {
|
||||
showUpdateDetails: false,
|
||||
theme: 'dark',
|
||||
}
|
||||
|
||||
const globalState: Reducer<GlobalState | undefined, CustomAction> = (state = initialBigState, action) => {
|
||||
const globalState: Reducer<GlobalState | undefined, CustomAction> = (state = initialGlobalState, action) => {
|
||||
if (!state) {
|
||||
throw Error('No initial state')
|
||||
}
|
||||
@@ -58,6 +61,18 @@ const globalState: Reducer<GlobalState | undefined, CustomAction> = (state = ini
|
||||
error: action.error,
|
||||
}
|
||||
|
||||
case ActionTypes.setDarkTheme:
|
||||
return {
|
||||
...state,
|
||||
theme: 'dark',
|
||||
}
|
||||
|
||||
case ActionTypes.setLightTheme:
|
||||
return {
|
||||
...state,
|
||||
theme: 'light',
|
||||
}
|
||||
|
||||
case ActionTypes.showUpdateDetails:
|
||||
if (action.showUpdateDetails === undefined) {
|
||||
return state
|
||||
|
||||
Reference in New Issue
Block a user