From 885858dcb4d4a901ef43e47789b1eafeb7788f00 Mon Sep 17 00:00:00 2001 From: Tommy Bergeron Date: Wed, 30 Oct 2019 05:40:34 -0400 Subject: [PATCH] Desktop: Resolves #1988: Add menu item to toggle note list (#1991) * Add menu item to toggle note list #1988 * Hiding the noteList now fully works + standardized casing for noteList #1988 * hiding verticalResizer to fully hide note list and its extra border #1988 * curly braces on the same line #1988 * fa-tasks is "less" worse as an icon for toggle note list #1988 * liking this icon a whole lot more * removed useless width tweak --- ElectronClient/app/app.js | 24 ++++++++++++++++++++ ElectronClient/app/gui/MainScreen.jsx | 30 ++++++++++++++++++++++--- ElectronClient/app/gui/Root.jsx | 5 +++++ ElectronClient/app/gui/SideBar.jsx | 1 + ReactNativeClient/lib/models/Setting.js | 1 + 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/ElectronClient/app/app.js b/ElectronClient/app/app.js index 4b444207da..2fbe63d246 100644 --- a/ElectronClient/app/app.js +++ b/ElectronClient/app/app.js @@ -44,6 +44,7 @@ const appDefaultState = Object.assign({}, defaultState, { windowCommand: null, noteVisiblePanes: ['editor', 'viewer'], sidebarVisibility: true, + noteListVisibility: true, windowContentSize: bridge().windowContentSize(), watchedNoteFiles: [], lastEditorScrollPercents: {}, @@ -154,6 +155,16 @@ class Application extends BaseApplication { newState.sidebarVisibility = action.visibility; break; + case 'NOTELIST_VISIBILITY_TOGGLE': + newState = Object.assign({}, state); + newState.noteListVisibility = !state.noteListVisibility; + break; + + case 'NOTELIST_VISIBILITY_SET': + newState = Object.assign({}, state); + newState.noteListVisibility = action.visibility; + break; + case 'NOTE_FILE_WATCHER_ADD': if (newState.watchedNoteFiles.indexOf(action.id) < 0) { @@ -245,6 +256,10 @@ class Application extends BaseApplication { Setting.setValue('sidebarVisibility', newState.sidebarVisibility); } + if (['NOTELIST_VISIBILITY_TOGGLE', 'NOTELIST_VISIBILITY_SET'].indexOf(action.type) >= 0) { + Setting.setValue('noteListVisibility', newState.noteListVisibility); + } + if (action.type.indexOf('NOTE_SELECT') === 0 || action.type.indexOf('FOLDER_SELECT') === 0) { this.updateMenuItemStates(); } @@ -864,6 +879,15 @@ class Application extends BaseApplication { name: 'toggleSidebar', }); }, + }, { + label: _('Toggle note list'), + screens: ['Main'], + click: () => { + this.dispatch({ + type: 'WINDOW_COMMAND', + name: 'toggleNoteList', + }); + }, }, { label: _('Toggle editor layout'), screens: ['Main'], diff --git a/ElectronClient/app/gui/MainScreen.jsx b/ElectronClient/app/gui/MainScreen.jsx index e27e30b5c9..5cce85b800 100644 --- a/ElectronClient/app/gui/MainScreen.jsx +++ b/ElectronClient/app/gui/MainScreen.jsx @@ -69,6 +69,12 @@ class MainScreenComponent extends React.Component { }); } + toggleNoteList() { + this.props.dispatch({ + type: 'NOTELIST_VISIBILITY_TOGGLE', + }); + } + async doCommand(command) { if (!command) return; @@ -245,6 +251,8 @@ class MainScreenComponent extends React.Component { this.toggleVisiblePanes(); } else if (command.name === 'toggleSidebar') { this.toggleSidebar(); + } else if (command.name === 'toggleNoteList') { + this.toggleNoteList(); } else if (command.name === 'showModalMessage') { this.setState({ modalLayer: { @@ -331,8 +339,8 @@ class MainScreenComponent extends React.Component { } } - styles(themeId, width, height, messageBoxVisible, isSidebarVisible, sidebarWidth, noteListWidth) { - const styleKey = [themeId, width, height, messageBoxVisible, +isSidebarVisible, sidebarWidth, noteListWidth].join('_'); + styles(themeId, width, height, messageBoxVisible, isSidebarVisible, isNoteListVisible, sidebarWidth, noteListWidth) { + const styleKey = [themeId, width, height, messageBoxVisible, +isSidebarVisible, +isNoteListVisible, sidebarWidth, noteListWidth].join('_'); if (styleKey === this.styleKey_) return this.styles_; const theme = themeStyle(themeId); @@ -381,6 +389,11 @@ class MainScreenComponent extends React.Component { verticalAlign: 'top', }; + if (isNoteListVisible === false) { + this.styles_.noteList.display = 'none'; + this.styles_.verticalResizer.display = 'none'; + } + this.styles_.noteText = { width: Math.floor(width - this.styles_.sideBar.width - this.styles_.noteList.width - 10), height: rowHeight, @@ -421,7 +434,8 @@ class MainScreenComponent extends React.Component { const notes = this.props.notes; const messageBoxVisible = this.props.hasDisabledSyncItems || this.props.showMissingMasterKeyMessage; const sidebarVisibility = this.props.sidebarVisibility; - const styles = this.styles(this.props.theme, style.width, style.height, messageBoxVisible, sidebarVisibility, this.props.sidebarWidth, this.props.noteListWidth); + const noteListVisibility = this.props.noteListVisibility; + const styles = this.styles(this.props.theme, style.width, style.height, messageBoxVisible, sidebarVisibility, noteListVisibility, this.props.sidebarWidth, this.props.noteListWidth); const onConflictFolder = this.props.selectedFolderId === Folder.conflictFolderId(); const headerItems = []; @@ -435,6 +449,15 @@ class MainScreenComponent extends React.Component { }, }); + headerItems.push({ + title: _('Toggle note list'), + iconName: 'fa-align-justify', + iconRotation: noteListVisibility ? 0 : 90, + onClick: () => { + this.doCommand({ name: 'toggleNoteList' }); + }, + }); + headerItems.push({ title: _('New note'), iconName: 'fa-file-o', @@ -578,6 +601,7 @@ const mapStateToProps = state => { windowCommand: state.windowCommand, noteVisiblePanes: state.noteVisiblePanes, sidebarVisibility: state.sidebarVisibility, + noteListVisibility: state.noteListVisibility, folders: state.folders, notes: state.notes, hasDisabledSyncItems: state.hasDisabledSyncItems, diff --git a/ElectronClient/app/gui/Root.jsx b/ElectronClient/app/gui/Root.jsx index bc01c024c3..c33346392a 100644 --- a/ElectronClient/app/gui/Root.jsx +++ b/ElectronClient/app/gui/Root.jsx @@ -53,6 +53,11 @@ async function initialize() { type: 'SIDEBAR_VISIBILITY_SET', visibility: Setting.value('sidebarVisibility'), }); + + store.dispatch({ + type: 'NOTELIST_VISIBILITY_SET', + visibility: Setting.value('noteListVisibility'), + }); } class RootComponent extends React.Component { diff --git a/ElectronClient/app/gui/SideBar.jsx b/ElectronClient/app/gui/SideBar.jsx index 86f4d12967..af64888dab 100644 --- a/ElectronClient/app/gui/SideBar.jsx +++ b/ElectronClient/app/gui/SideBar.jsx @@ -807,6 +807,7 @@ const mapStateToProps = state => { resourceFetcher: state.resourceFetcher, windowCommand: state.windowCommand, sidebarVisibility: state.sidebarVisibility, + noteListVisibility: state.noteListVisibility, }; }; diff --git a/ReactNativeClient/lib/models/Setting.js b/ReactNativeClient/lib/models/Setting.js index 00755d73c6..c2a7c96014 100644 --- a/ReactNativeClient/lib/models/Setting.js +++ b/ReactNativeClient/lib/models/Setting.js @@ -405,6 +405,7 @@ class Setting extends BaseModel { }, noteVisiblePanes: { value: ['editor', 'viewer'], type: Setting.TYPE_ARRAY, public: false, appTypes: ['desktop'] }, sidebarVisibility: { value: true, type: Setting.TYPE_BOOL, public: false, appTypes: ['desktop'] }, + noteListVisibility: { value: true, type: Setting.TYPE_BOOL, public: false, appTypes: ['desktop'] }, tagHeaderIsExpanded: { value: true, type: Setting.TYPE_BOOL, public: false, appTypes: ['desktop'] }, folderHeaderIsExpanded: { value: true, type: Setting.TYPE_BOOL, public: false, appTypes: ['desktop'] }, editor: { value: '', type: Setting.TYPE_STRING, subType: 'file_path_and_args', public: true, appTypes: ['cli', 'desktop'], label: () => _('Text editor command'), description: () => _('The editor command (may include arguments) that will be used to open a note. If none is provided it will try to auto-detect the default editor.') },