From 6f86a8d471943a71357010460bf9cf85dd7cd49a Mon Sep 17 00:00:00 2001 From: Thomas Nordquist Date: Wed, 3 Apr 2019 01:55:57 +0200 Subject: [PATCH] Add theme toggle --- app/src/actions/Global.ts | 9 ++- app/src/components/BrokerStatistics.tsx | 7 ++- app/src/components/Settings.tsx | 13 +++- .../components/Sidebar/Publish/Publish.tsx | 2 +- app/src/index.tsx | 61 +++++++++++++------ app/src/reducers/index.ts | 21 ++++++- 6 files changed, 84 insertions(+), 29 deletions(-) diff --git a/app/src/actions/Global.ts b/app/src/actions/Global.ts index 88fe2ef..42e25eb 100644 --- a/app/src/actions/Global.ts +++ b/app/src/actions/Global.ts @@ -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, getState: () => AppState) => { + dispatch({ + type: getState().globalState.theme === 'light' ? ActionTypes.setDarkTheme : ActionTypes.setLightTheme, + }) +} diff --git a/app/src/components/BrokerStatistics.tsx b/app/src/components/BrokerStatistics.tsx index 93133ef..5f97127 100644 --- a/app/src/components/BrokerStatistics.tsx +++ b/app/src/components/BrokerStatistics.tsx @@ -106,12 +106,13 @@ class BrokerStatistics extends React.Component { public renderStat(tree: q.Tree, 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 (
diff --git a/app/src/components/Settings.tsx b/app/src/components/Settings.tsx index 452f34b..2210936 100644 --- a/app/src/components/Settings.tsx +++ b/app/src/components/Settings.tsx @@ -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 { @@ -112,6 +114,7 @@ class Settings extends React.Component { {this.renderNodeOrder()} {this.renderHighlightTopicUpdates()} {this.selectTopicsOnMouseOver()} + {this.toggleTheme()}
@@ -173,6 +176,12 @@ class Settings extends React.Component { 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), } } diff --git a/app/src/components/Sidebar/Publish/Publish.tsx b/app/src/components/Sidebar/Publish/Publish.tsx index 17071c4..0322d24 100644 --- a/app/src/components/Sidebar/Publish/Publish.tsx +++ b/app/src/components/Sidebar/Publish/Publish.tsx @@ -284,7 +284,7 @@ class Publish extends React.Component { private history() { const items = this.state.history.reverse().map(message => ({ title: message.topic, - value: message.payload, + value: message.payload || '', })) return diff --git a/app/src/index.tsx b/app/src/index.tsx index e0df202..141a330 100644 --- a/app/src/index.tsx +++ b/app/src/index.tsx @@ -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 ( + + + + + ) +} + +const mapStateToProps = (state: AppState) => { + return { + theme: state.globalState.theme, + } +} + +const Application = connect(mapStateToProps)(ApplicationRenderer) + ReactDOM.render( - - - - - - , - document.getElementById('app'), + + + , + document.getElementById('app'), ) diff --git a/app/src/reducers/index.ts b/app/src/reducers/index.ts index 890f9a6..9b9c089 100644 --- a/app/src/reducers/index.ts +++ b/app/src/reducers/index.ts @@ -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 = (state = initialBigState, action) => { +const globalState: Reducer = (state = initialGlobalState, action) => { if (!state) { throw Error('No initial state') } @@ -58,6 +61,18 @@ const globalState: Reducer = (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