Add theme toggle

This commit is contained in:
Thomas Nordquist
2019-04-03 01:55:57 +02:00
parent 84a92ad522
commit 6f86a8d471
6 changed files with 84 additions and 29 deletions

View File

@@ -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,
})
}

View File

@@ -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}>

View File

@@ -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),
}
}

View File

@@ -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} />

View File

@@ -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'),
)

View File

@@ -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