diff --git a/src/components/App/App.reducer.js b/src/components/App/App.reducer.js index 56267f8ed..bc3e82409 100644 --- a/src/components/App/App.reducer.js +++ b/src/components/App/App.reducer.js @@ -18,7 +18,8 @@ const initialState = { uiSize: DISPLAY_SIZE_STANDARD, fontSize: DISPLAY_SIZE_STANDARD, hideOutputActive: false, - labelPosition: LABEL_POSITION_BELOW + labelPosition: LABEL_POSITION_BELOW, + darkThemeActive: false }, navigationSettings: { active: false, diff --git a/src/components/Board/Board.component.js b/src/components/Board/Board.component.js index ee7adc6c9..cc977f79c 100644 --- a/src/components/Board/Board.component.js +++ b/src/components/Board/Board.component.js @@ -232,7 +232,8 @@ export class Board extends Component { navigationSettings, deactivateScanner, publishBoard, - emptyVoiceAlert + emptyVoiceAlert, + displaySettings } = this.props; const tiles = this.renderTiles(board.tiles); @@ -275,6 +276,7 @@ export class Board extends Component { userData={userData} publishBoard={publishBoard} showNotification={this.props.showNotification} + dark={displaySettings.darkThemeActive} /> {emptyVoiceAlert && ( @@ -319,6 +321,7 @@ export class Board extends Component { edit={isSelecting && !isSaving} cols={cols} updateTiles={this.updateTiles} + dark={displaySettings.darkThemeActive} > {tiles} diff --git a/src/components/Board/Navbar/Navbar.css b/src/components/Board/Navbar/Navbar.css index 48bde23bb..d153a08c1 100644 --- a/src/components/Board/Navbar/Navbar.css +++ b/src/components/Board/Navbar/Navbar.css @@ -7,6 +7,11 @@ color: #fff; } +.Navbar--dark { + color: #000; + background: #fff; +} + .Navbar__title { display: flex; order: 2; diff --git a/src/components/Board/Navbar/Navbar.js b/src/components/Board/Navbar/Navbar.js index 6520a6d55..6e80477f1 100644 --- a/src/components/Board/Navbar/Navbar.js +++ b/src/components/Board/Navbar/Navbar.js @@ -110,14 +110,17 @@ export class Navbar extends React.Component { onBackClick, onDeactivateScannerClick, onLockClick, - onLockNotify + onLockNotify, + dark } = this.props; const isPublic = board && board.isPublic; const isOwnBoard = board && board.email === userData.email; return ( -
+
{isLocked &&

{title}

}
@@ -211,7 +214,8 @@ Navbar.propTypes = { */ onLockClick: PropTypes.func, isScannerActive: PropTypes.bool, - onDeactivateScannerClick: PropTypes.func + onDeactivateScannerClick: PropTypes.func, + dark: PropTypes.bool }; export default injectIntl(Navbar); diff --git a/src/components/Board/Output/Output.container.js b/src/components/Board/Output/Output.container.js index edf5ece84..45d1fec61 100644 --- a/src/components/Board/Output/Output.container.js +++ b/src/components/Board/Output/Output.container.js @@ -197,7 +197,7 @@ export class OutputContainer extends Component { }; render() { - const { output, navigationSettings } = this.props; + const { output, navigationSettings, dark } = this.props; const tabIndex = output.length ? '0' : '-1'; @@ -211,6 +211,7 @@ export class OutputContainer extends Component { symbols={this.state.translatedOutput} tabIndex={tabIndex} navigationSettings={navigationSettings} + dark={dark} /> ); } @@ -219,7 +220,8 @@ export class OutputContainer extends Component { const mapStateToProps = ({ board, app }) => { return { output: board.output, - navigationSettings: app.navigationSettings + navigationSettings: app.navigationSettings, + dark: app.displaySettings.darkThemeActive }; }; diff --git a/src/components/Board/Output/SymbolOutput/SymbolOutput.css b/src/components/Board/Output/SymbolOutput/SymbolOutput.css index 715635def..b77bd565a 100644 --- a/src/components/Board/Output/SymbolOutput/SymbolOutput.css +++ b/src/components/Board/Output/SymbolOutput/SymbolOutput.css @@ -5,6 +5,11 @@ background: #fff; } +.SymbolOutput--dark { + color: #fff; + background: #303030; +} + .SymbolOutput__value { height: calc(100% - 10px); width: 100px; diff --git a/src/components/Board/Output/SymbolOutput/SymbolOutput.js b/src/components/Board/Output/SymbolOutput/SymbolOutput.js index 3719bbf84..8db3b75ae 100644 --- a/src/components/Board/Output/SymbolOutput/SymbolOutput.js +++ b/src/components/Board/Output/SymbolOutput/SymbolOutput.js @@ -1,6 +1,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; +import classNames from 'classnames'; import ClearIcon from '@material-ui/icons/Clear'; import IconButton from '@material-ui/core/IconButton'; @@ -24,7 +25,8 @@ class SymbolOutput extends PureComponent { /** * Label to display */ - label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]) + label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), + dark: PropTypes.bool }) ) }; @@ -40,6 +42,7 @@ class SymbolOutput extends PureComponent { onRemoveClick, symbols, navigationSettings, + dark, ...other } = this.props; @@ -56,7 +59,9 @@ class SymbolOutput extends PureComponent { }; return ( -
+
{symbols.map(({ image, label }, index) => (
diff --git a/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.component.js b/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.component.js index e9c49596f..09426e8dc 100644 --- a/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.component.js +++ b/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.component.js @@ -45,7 +45,8 @@ const CommunicatorDialog = ({ updateMyBoard, setRootBoard, publishBoard, - showNotification + showNotification, + dark }) => ( } > - + ))} @@ -208,7 +210,8 @@ CommunicatorDialog.propTypes = { copyBoard: PropTypes.func.isRequired, setRootBoard: PropTypes.func.isRequired, publishBoard: PropTypes.func.isRequired, - showNotification: PropTypes.func.isRequired + showNotification: PropTypes.func.isRequired, + dark: PropTypes.bool }; export default CommunicatorDialog; diff --git a/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.container.js b/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.container.js index a95e43423..21462b9a6 100644 --- a/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.container.js +++ b/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.container.js @@ -542,7 +542,7 @@ const mapStateToProps = ({ board, communicator, language, app }, ownProps) => { board => currentCommunicator.boards.indexOf(board.id) >= 0 ); - const { userData } = app; + const { userData, displaySettings } = app; const cboardBoards = board.boards.filter( board => board.email === 'support@cboard.io' ); @@ -555,7 +555,8 @@ const mapStateToProps = ({ board, communicator, language, app }, ownProps) => { cboardBoards, availableBoards: board.boards, userData, - activeBoardId: board.activeBoardId + activeBoardId: board.activeBoardId, + dark: displaySettings.darkThemeActive }; }; diff --git a/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.css b/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.css index f757b28dd..34b99d83c 100644 --- a/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.css +++ b/src/components/Communicator/CommunicatorDialog/CommunicatorDialog.css @@ -11,6 +11,11 @@ color: #fff; } +.is-dark .CommunicatorDialog__tabs { + background-color: #607d8b; + color: #fff; +} + .CommunicatorDialog__tabs [class^='TabIndicator-'] { background-color: #fff; height: 3px; @@ -22,6 +27,10 @@ padding: 0; } +.is-dark .CommunicatorDialog__content { + background-color: #5e5e5e; +} + .CommunicatorDialog__content .CommunicatorDialog__spinner { margin: 40px auto; display: block; @@ -31,6 +40,9 @@ background: #eee; padding: 16px 16px 28px; } +.is-dark .CommunicatorDialog__communicatorData { + background: rgba(36, 36, 36, 0.933); +} .CommunicatorDialog__communicatorData__title { font-size: 1.14rem; @@ -47,12 +59,20 @@ padding: 20px 16px; } +.is-dark .CommunicatorDialog__boards { + background-color: #424242; +} + .CommunicatorDialog__boards__item { display: flex; min-height: 150px; margin-bottom: 10px; } +.is-dark .CommunicatorDialog__boards__item { + background-color: #424242; +} + .CommunicatorDialog__boards__item__data { position: relative; width: 50%; @@ -75,7 +95,7 @@ right: 8px; padding: 5px; min-width: 20px; - background-color: #5e5e5e; + background-color: #838383; } .CommunicatorDialog__boards__item__image_container svg { @@ -86,7 +106,7 @@ .CommunicatorDialog__boards__item__actions { position: relative; width: 10%; - color: #5e5e5e; + color: #838383; } .CommunicatorDialog__boards__item__image img { @@ -107,7 +127,7 @@ right: 8px; padding: 5px; min-width: 20px; - background-color: #5e5e5e; + background-color: #838383; } .CommunicatorDialog__boards__item__image__empty button svg { diff --git a/src/components/Grid/Grid.container.js b/src/components/Grid/Grid.container.js index 28c0d37bb..5a27b97ef 100644 --- a/src/components/Grid/Grid.container.js +++ b/src/components/Grid/Grid.container.js @@ -23,7 +23,8 @@ export class GridContainer extends PureComponent { breakpoints: colsRowsShape, gap: PropTypes.number, children: PropTypes.node, - edit: PropTypes.bool + edit: PropTypes.bool, + dark: PropTypes.bool }; static defaultProps = { @@ -119,10 +120,16 @@ export class GridContainer extends PureComponent { }; render() { - const { size, cols, gap, edit, breakpoints, children } = this.props; + const { size, cols, gap, edit, breakpoints, children, dark } = this.props; return ( -
+
{ + this.setState({ + darkThemeActive: !this.state.darkThemeActive + }); + }; + onDisplaySettingsChange(displaySetting, event) { const { target: { value } @@ -176,6 +182,24 @@ class Display extends React.Component { {this.renderRadioGroup('labelPosition')} + + + } + secondary={ + + } + /> + + + + diff --git a/src/components/Settings/Display/Display.container.js b/src/components/Settings/Display/Display.container.js index f7e5d97f4..1dcd8e082 100644 --- a/src/components/Settings/Display/Display.container.js +++ b/src/components/Settings/Display/Display.container.js @@ -7,16 +7,22 @@ import Display from './Display.component'; import API from '../../../api'; export class DisplayContainer extends PureComponent { - updateDisplaySettings = async (displaySettings) => { + updateDisplaySettings = async displaySettings => { try { await API.updateSettings({ display: displaySettings }); - } catch (e) { } + } catch (e) {} this.props.updateDisplaySettingsAction(displaySettings); }; render() { const { history } = this.props; - return ; + return ( + + ); } } diff --git a/src/components/Settings/Display/Display.messages.js b/src/components/Settings/Display/Display.messages.js index 4fc31743b..4ac08dbd0 100644 --- a/src/components/Settings/Display/Display.messages.js +++ b/src/components/Settings/Display/Display.messages.js @@ -63,11 +63,20 @@ export default defineMessages({ 'Whether labels on tiles should be visible, or positioned above or below' }, outputHide: { - id: 'cboard.components.Settings.Navigation.outputHide', + id: 'cboard.components.Settings.Display.outputHide', defaultMessage: 'Hide the output bar' }, outputHideSecondary: { - id: 'cboard.components.Settings.Navigation.outputHideSecondary', + id: 'cboard.components.Settings.Display.outputHideSecondary', defaultMessage: 'Hides the white bar on the top where you build a sentence.' + }, + darkTheme: { + id: 'cboard.components.Settings.Display.darkTheme', + defaultMessage: 'Enable dark theme' + }, + darkThemeSecondary: { + id: 'cboard.components.Settings.Display.darkThemeSecondary', + defaultMessage: + 'The theme specifies the color of the components, darkness of the surfaces, level of shadow, appropriate opacity of ink elements, etc.' } }); diff --git a/src/components/UI/FullScreenDialog/FullScreenDialog.js b/src/components/UI/FullScreenDialog/FullScreenDialog.js index be09281c8..3812c474a 100644 --- a/src/components/UI/FullScreenDialog/FullScreenDialog.js +++ b/src/components/UI/FullScreenDialog/FullScreenDialog.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import { withStyles } from '@material-ui/core/styles'; +import { withStyles, useTheme } from '@material-ui/core/styles'; import AppBar from '@material-ui/core/AppBar'; import Button from '@material-ui/core/Button'; import Dialog from '@material-ui/core/Dialog'; @@ -41,8 +41,14 @@ const styles = { overflow: 'hidden' }, container: { - height: '100%', background: '#f1f1f1', + height: '100%', + overflowY: 'auto', + WebkitOverflowScrolling: 'touch' + }, + containerDark: { + background: '#1111', + height: '100%', overflowY: 'auto', WebkitOverflowScrolling: 'touch' }, @@ -88,6 +94,9 @@ function FullScreenDialog(props) { transition = transitions.UP } = props; + const theme = useTheme(); + const dark = theme.palette.type === 'dark' ? true : false; + return ( -
+
{children}
diff --git a/src/providers/ThemeProvider/ThemeProvider.constants.js b/src/providers/ThemeProvider/ThemeProvider.constants.js new file mode 100644 index 000000000..429e573c4 --- /dev/null +++ b/src/providers/ThemeProvider/ThemeProvider.constants.js @@ -0,0 +1,2 @@ +export const DEFAULT_THEME = 'light'; +export const DARK_THEME = 'dark'; diff --git a/src/providers/ThemeProvider/ThemeProvider.container.js b/src/providers/ThemeProvider/ThemeProvider.container.js index bde518b31..fc2db72a5 100644 --- a/src/providers/ThemeProvider/ThemeProvider.container.js +++ b/src/providers/ThemeProvider/ThemeProvider.container.js @@ -1,20 +1,32 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'; +import blueGrey from '@material-ui/core/colors/blueGrey'; +import amber from '@material-ui/core/colors/amber'; import RTLSupport from './RTLSupport'; export class ThemeProvider extends Component { render() { - const { dir, children } = this.props; + const { dir, children, darkThemeActive } = this.props; - const theme = createMuiTheme({ + const lightTheme = createMuiTheme({ + typography: {}, + direction: dir + }); + + const darkTheme = createMuiTheme({ + palette: { + type: 'dark', + primary: blueGrey, + secondary: amber + }, typography: {}, direction: dir }); return ( - + {children} ); @@ -22,7 +34,8 @@ export class ThemeProvider extends Component { } const mapStateToProps = state => ({ - dir: state.language.dir + dir: state.language.dir, + darkThemeActive: state.app.displaySettings.darkThemeActive }); const mapDispatchToProps = {};