From 6f8005a2cac2abb27f8db959ee9e8ae0319c52db Mon Sep 17 00:00:00 2001 From: Lena Morita Date: Thu, 17 Oct 2019 02:06:02 +0900 Subject: [PATCH] Add option to hide menu bar (#1215) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #293 Based on #1216 This adds an option to auto-hide the menu bar on Windows/Linux Electron. The option will be in Settings ▸ Display. screen shot 2019-02-21 at 23 26 17 We have to be careful not to get the user stuck in a situation where they can't bring back the menu bar, so we'll show the Settings button and footer links in the Navigation Bar when auto-hide is enabled. --- desktop/app.js | 5 ++ lib/app.jsx | 7 ++- lib/dialog-renderer/index.jsx | 3 ++ lib/dialogs/settings/index.jsx | 16 ++++++- lib/dialogs/settings/panels/display.jsx | 20 ++++++++ lib/navigation-bar/index.jsx | 61 +++++++++++++++---------- lib/navigation-bar/style.scss | 7 --- lib/state/settings/actions.js | 15 ++++++ lib/state/settings/reducer.js | 3 ++ 9 files changed, 102 insertions(+), 35 deletions(-) diff --git a/desktop/app.js b/desktop/app.js index bdafe3ec3..4e3b3e6b2 100644 --- a/desktop/app.js +++ b/desktop/app.js @@ -109,6 +109,11 @@ module.exports = function main() { }); }); + ipcMain.on('setAutoHideMenuBar', function(event, autoHideMenuBar) { + mainWindow.setAutoHideMenuBar(autoHideMenuBar || false); + mainWindow.setMenuBarVisibility(!autoHideMenuBar); + }); + mainWindowState.manage(mainWindow); mainWindow.webContents.on('new-window', function(event, linkUrl) { diff --git a/lib/app.jsx b/lib/app.jsx index b51f04b54..8f68ba854 100644 --- a/lib/app.jsx +++ b/lib/app.jsx @@ -68,6 +68,7 @@ function mapDispatchToProps(dispatch, { noteBucket }) { 'setNoteDisplay', 'setMarkdown', 'setAccountName', + 'toggleAutoHideMenuBar', 'toggleFocusMode', 'toggleSpellCheck', ]), @@ -145,6 +146,7 @@ export const App = connect( componentDidMount() { ipc.on('appCommand', this.onAppCommand); + ipc.send('setAutoHideMenuBar', this.props.settings.autoHideMenuBar); ipc.send('settingsUpdate', this.props.settings); this.props.noteBucket @@ -435,7 +437,9 @@ export const App = connect( {isDevConfig && } {isAuthorized ? (
- {state.showNavigation && } + {state.showNavigation && ( + + )}
); diff --git a/lib/dialog-renderer/index.jsx b/lib/dialog-renderer/index.jsx index 4660744c2..6560c6876 100644 --- a/lib/dialog-renderer/index.jsx +++ b/lib/dialog-renderer/index.jsx @@ -13,6 +13,7 @@ export const DialogRenderer = props => { closeDialog, dialogs, isElectron, + isMacApp, } = props; const renderDialog = dialog => { @@ -40,6 +41,7 @@ export const DialogRenderer = props => { dialog={dialog} requestClose={closeThisDialog} isElectron={isElectron} + isMacApp={isMacApp} {...appProps} /> @@ -56,6 +58,7 @@ DialogRenderer.propTypes = { closeDialog: PropTypes.func.isRequired, dialogs: PropTypes.array.isRequired, isElectron: PropTypes.bool.isRequired, + isMacApp: PropTypes.bool.isRequired, }; export default DialogRenderer; diff --git a/lib/dialogs/settings/index.jsx b/lib/dialogs/settings/index.jsx index a47f32eaf..760b39cf5 100644 --- a/lib/dialogs/settings/index.jsx +++ b/lib/dialogs/settings/index.jsx @@ -26,6 +26,7 @@ export class SettingsDialog extends Component { dialog: PropTypes.shape({ title: PropTypes.string.isRequired }), onSignOut: PropTypes.func.isRequired, isElectron: PropTypes.bool.isRequired, + isMacApp: PropTypes.bool.isRequired, onSetWPToken: PropTypes.func.isRequired, requestClose: PropTypes.func.isRequired, settings: PropTypes.object.isRequired, @@ -118,7 +119,14 @@ export class SettingsDialog extends Component { }; render() { - const { buckets, dialog, requestClose, settings } = this.props; + const { + buckets, + dialog, + isElectron, + isMacApp, + requestClose, + settings, + } = this.props; const { analyticsEnabled } = this.props.appState.preferences; return ( @@ -132,7 +140,11 @@ export class SettingsDialog extends Component { this.onToggleShareAnalyticsPreference } /> - + diff --git a/lib/dialogs/settings/panels/display.jsx b/lib/dialogs/settings/panels/display.jsx index 082581ebe..444173a87 100644 --- a/lib/dialogs/settings/panels/display.jsx +++ b/lib/dialogs/settings/panels/display.jsx @@ -15,7 +15,10 @@ const DisplayPanel = props => { const { actions, activeTheme, + autoHideMenuBar, buckets: { noteBucket }, + isElectron, + isMacApp, lineLength, loadNotes, noteDisplay, @@ -108,6 +111,19 @@ const DisplayPanel = props => { + + {isElectron && !isMacApp && ( + + + + )} ); }; @@ -115,9 +131,12 @@ const DisplayPanel = props => { DisplayPanel.propTypes = { actions: PropTypes.object.isRequired, activeTheme: PropTypes.string.isRequired, + autoHideMenuBar: PropTypes.bool, buckets: PropTypes.shape({ noteBucket: PropTypes.object.isRequired, }), + isElectron: PropTypes.bool.isRequired, + isMacApp: PropTypes.bool.isRequired, lineLength: PropTypes.string.isRequired, loadNotes: PropTypes.func.isRequired, loadTags: PropTypes.func.isRequired, @@ -130,6 +149,7 @@ DisplayPanel.propTypes = { const mapStateToProps = ({ settings }) => { return { activeTheme: settings.theme, + autoHideMenuBar: settings.autoHideMenuBar, lineLength: settings.lineLength, noteDisplay: settings.noteDisplay, sortIsReversed: settings.sortReversed, diff --git a/lib/navigation-bar/index.jsx b/lib/navigation-bar/index.jsx index 720c6205e..61a2fb919 100644 --- a/lib/navigation-bar/index.jsx +++ b/lib/navigation-bar/index.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, Fragment } from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import onClickOutside from 'react-onclickoutside'; @@ -18,7 +18,9 @@ export class NavigationBar extends Component { static displayName = 'NavigationBar'; static propTypes = { + autoHideMenuBar: PropTypes.bool, dialogs: PropTypes.array.isRequired, + isElectron: PropTypes.bool.isRequired, isOffline: PropTypes.bool.isRequired, onAbout: PropTypes.func.isRequired, onOutsideClick: PropTypes.func.isRequired, @@ -65,6 +67,8 @@ export class NavigationBar extends Component { render() { const { + autoHideMenuBar, + isElectron, isOffline, onAbout, onSettings, @@ -91,29 +95,35 @@ export class NavigationBar extends Component {
-
- } - label="Settings" - onClick={onSettings} - /> -
-
- - -
+ + {(!isElectron || autoHideMenuBar) && ( + +
+ } + label="Settings" + onClick={onSettings} + /> +
+
+ + +
+
+ )} +
@@ -122,7 +132,8 @@ export class NavigationBar extends Component { } } -const mapStateToProps = ({ appState: state }) => ({ +const mapStateToProps = ({ appState: state, settings }) => ({ + autoHideMenuBar: settings.autoHideMenuBar, dialogs: state.dialogs, isOffline: state.isOffline, selectedTag: state.tag, diff --git a/lib/navigation-bar/style.scss b/lib/navigation-bar/style.scss index b4587b46f..00bd661de 100644 --- a/lib/navigation-bar/style.scss +++ b/lib/navigation-bar/style.scss @@ -50,13 +50,6 @@ color: $studio-gray-80; } -.is-electron { - .navigation-bar__tools, - .navigation-bar__footer { - display: none; - } -} - .navigation-bar__footer-item { margin-right: 10px; diff --git a/lib/state/settings/actions.js b/lib/state/settings/actions.js index 9e593a504..509351157 100644 --- a/lib/state/settings/actions.js +++ b/lib/state/settings/actions.js @@ -1,3 +1,7 @@ +import { getIpcRenderer } from '../../utils/electron'; + +const ipc = getIpcRenderer(); + export const setFontSize = fontSize => ({ type: 'setFontSize', fontSize, @@ -83,3 +87,14 @@ export const toggleSpellCheck = () => (dispatch, getState) => { spellCheckEnabled: !getState().settings.spellCheckEnabled, }); }; + +export const toggleAutoHideMenuBar = () => (dispatch, getState) => { + const newValue = !getState().settings.autoHideMenuBar; + + ipc.send('setAutoHideMenuBar', newValue); + + dispatch({ + type: 'setAutoHideMenuBar', + autoHideMenuBar: newValue, + }); +}; diff --git a/lib/state/settings/reducer.js b/lib/state/settings/reducer.js index 400de1b8b..020282e9b 100644 --- a/lib/state/settings/reducer.js +++ b/lib/state/settings/reducer.js @@ -2,6 +2,7 @@ import { clamp } from 'lodash'; export const initialState = { accountName: null, + autoHideMenuBar: false, focusModeEnabled: false, fontSize: 16, lineLength: 'narrow', @@ -19,6 +20,8 @@ function reducer(state = initialState, action) { switch (action.type) { case 'setAccountName': return { ...state, accountName: action.accountName }; + case 'setAutoHideMenuBar': + return { ...state, autoHideMenuBar: action.autoHideMenuBar }; case 'setFocusMode': return { ...state, focusModeEnabled: action.focusModeEnabled }; case 'setFontSize':