From da21580785f52e0457a76a8d25a3ae80281f16ba Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 28 Jun 2019 00:51:02 +0100 Subject: [PATCH] Mobile: Added 'All notes' screen; Cleaned up header bar buttons; Removed 'body' from note preview object to improve memory usage --- .../lib/components/screen-header.js | 5 +- .../lib/components/screens/folder.js | 2 + .../lib/components/screens/notes.js | 11 +++- .../lib/components/screens/search.js | 2 + .../lib/components/side-menu-content.js | 50 +++++++++++++------ ReactNativeClient/lib/joplin-database.js | 4 ++ ReactNativeClient/lib/models/Note.js | 3 +- ReactNativeClient/root.js | 5 ++ 8 files changed, 62 insertions(+), 20 deletions(-) diff --git a/ReactNativeClient/lib/components/screen-header.js b/ReactNativeClient/lib/components/screen-header.js index 9f099eb35..fff8de9bf 100644 --- a/ReactNativeClient/lib/components/screen-header.js +++ b/ReactNativeClient/lib/components/screen-header.js @@ -124,7 +124,7 @@ class ScreenHeaderComponent extends Component { titleText: { flex: 1, textAlignVertical: 'center', - marginLeft: 0, + marginLeft: 10, color: theme.raisedHighlightedColor, fontWeight: 'bold', fontSize: theme.fontSize, @@ -376,10 +376,11 @@ class ScreenHeaderComponent extends Component { const showSideMenuButton = this.props.showSideMenuButton !== false && !this.props.noteSelectionEnabled; const showSearchButton = this.props.showSearchButton !== false && !this.props.noteSelectionEnabled; const showContextMenuButton = this.props.showContextMenuButton !== false; + const showBackButton = this.props.showBackButton !== false; const titleComp = createTitleComponent(); const sideMenuComp = !showSideMenuButton ? null : sideMenuButton(this.styles(), () => this.sideMenuButton_press()); - const backButtonComp = backButton(this.styles(), () => this.backButton_press(), !this.props.historyCanGoBack); + const backButtonComp = !showBackButton ? null : backButton(this.styles(), () => this.backButton_press(), !this.props.historyCanGoBack); const searchButtonComp = !showSearchButton ? null : searchButton(this.styles(), () => this.searchButton_press()); const deleteButtonComp = this.props.noteSelectionEnabled ? deleteButton(this.styles(), () => this.deleteButton_press()) : null; const sortButtonComp = this.props.sortButton_press ? sortButton(this.styles(), () => this.props.sortButton_press()) : null; diff --git a/ReactNativeClient/lib/components/screens/folder.js b/ReactNativeClient/lib/components/screens/folder.js index 4aa1d7d4f..ebed831ee 100644 --- a/ReactNativeClient/lib/components/screens/folder.js +++ b/ReactNativeClient/lib/components/screens/folder.js @@ -112,6 +112,8 @@ class FolderScreenComponent extends BaseScreenComponent { showSaveButton={true} saveButtonDisabled={saveButtonDisabled} onSaveButtonPress={() => this.saveFolderButton_press()} + showSideMenuButton={false} + showSearchButton={false} /> this.title_changeText(text)} /> { this.dialogbox = dialogbox }}/> diff --git a/ReactNativeClient/lib/components/screens/notes.js b/ReactNativeClient/lib/components/screens/notes.js index 040c120ea..998687b41 100644 --- a/ReactNativeClient/lib/components/screens/notes.js +++ b/ReactNativeClient/lib/components/screens/notes.js @@ -85,6 +85,7 @@ class NotesScreenComponent extends BaseScreenComponent { if (newProps.notesOrder !== this.props.notesOrder || newProps.selectedFolderId != this.props.selectedFolderId || newProps.selectedTagId != this.props.selectedTagId || + newProps.selectedSmartFilterId != this.props.selectedSmartFilterId || newProps.notesParentType != this.props.notesParentType) { await this.refreshNotes(newProps); } @@ -111,10 +112,12 @@ class NotesScreenComponent extends BaseScreenComponent { if (source == props.notesSource) return; let notes = []; - if (props.notesParentType == 'Folder') { + if (props.notesParentType === 'Folder') { notes = await Note.previews(props.selectedFolderId, options); - } else { + } else if (props.notesParentType === 'Tag') { notes = await Tag.notes(props.selectedTagId, options); + } else if (props.notesParentType === 'SmartFilter') { + notes = await Note.previews(null, options); } this.props.dispatch({ @@ -172,6 +175,8 @@ class NotesScreenComponent extends BaseScreenComponent { output = Folder.byId(props.folders, props.selectedFolderId); } else if (props.notesParentType == 'Tag') { output = Tag.byId(props.tags, props.selectedTagId); + } else if (props.notesParentType == 'SmartFilter') { + output = { id: this.props.selectedSmartFilterId, title: _('All notes') }; } else { return null; throw new Error('Invalid parent type: ' + props.notesParentType); @@ -209,6 +214,7 @@ class NotesScreenComponent extends BaseScreenComponent { diff --git a/ReactNativeClient/lib/components/side-menu-content.js b/ReactNativeClient/lib/components/side-menu-content.js index 17b636c64..203526b74 100644 --- a/ReactNativeClient/lib/components/side-menu-content.js +++ b/ReactNativeClient/lib/components/side-menu-content.js @@ -86,16 +86,28 @@ class SideMenuContentComponent extends Component { } folder_press(folder) { - this.props.dispatch({ type: 'SIDE_MENU_CLOSE' }); + if (folder === 'all') { + this.props.dispatch({ type: 'SIDE_MENU_CLOSE' }); - this.props.dispatch({ - type: 'NAV_GO', - routeName: 'Notes', - folderId: folder.id, - }); + this.props.dispatch({ + type: 'NAV_GO', + routeName: 'Notes', + smartFilterId: 'c3176726992c11e9ac940492261af972', + }); + } else { + this.props.dispatch({ type: 'SIDE_MENU_CLOSE' }); + + this.props.dispatch({ + type: 'NAV_GO', + routeName: 'Notes', + folderId: folder.id, + }); + } } async folder_longPress(folder) { + if (folder === 'all') return; + const buttons = []; Alert.alert( @@ -201,20 +213,24 @@ class SideMenuContentComponent extends Component { const iconWrapperStyle = { paddingLeft: 10, paddingRight: 10 }; if (selected) iconWrapperStyle.backgroundColor = theme.selectedColor; - const iconName = this.props.collapsedFolderIds.indexOf(folder.id) >= 0 ? 'md-arrow-dropdown' : 'md-arrow-dropup'; - const iconComp = + let iconWrapper = null; - const iconWrapper = !hasChildren ? null : ( - { if (hasChildren) this.folder_togglePress(folder) }}> - { iconComp } - - ); + if (folder !== 'all') { + const iconName = this.props.collapsedFolderIds.indexOf(folder.id) >= 0 ? 'md-arrow-dropdown' : 'md-arrow-dropup'; + const iconComp = + + iconWrapper = !hasChildren ? null : ( + { if (hasChildren) this.folder_togglePress(folder) }}> + { iconComp } + + ); + } return ( - + { this.folder_press(folder) }} onLongPress={() => { this.folder_longPress(folder) }}> - {Folder.displayTitle(folder)} + {folder === 'all' ? _('All notes') : Folder.displayTitle(folder)} { iconWrapper } @@ -297,6 +313,10 @@ class SideMenuContentComponent extends Component { // using padding. So instead creating blank elements for padding bottom and top. items.push(); + items.push(this.renderFolderItem('all', this.props.notesParentType === 'SmartFilter', false, 0)); + + items.push(this.makeDivider('divider_all')); + if (this.props.folders.length) { const result = shared.renderFolders(this.props, this.renderFolderItem); const folderItems = result.items; diff --git a/ReactNativeClient/lib/joplin-database.js b/ReactNativeClient/lib/joplin-database.js index b807040bf..bce17da21 100644 --- a/ReactNativeClient/lib/joplin-database.js +++ b/ReactNativeClient/lib/joplin-database.js @@ -194,6 +194,10 @@ class JoplinDatabase extends Database { queries.push('DELETE FROM settings WHERE key="sync.5.context"'); queries.push('DELETE FROM settings WHERE key="sync.6.context"'); queries.push('DELETE FROM settings WHERE key="sync.7.context"'); + + queries.push('DELETE FROM settings WHERE key="revisionService.lastProcessedChangeId"'); + queries.push('DELETE FROM settings WHERE key="resourceService.lastProcessedChangeId"'); + queries.push('DELETE FROM settings WHERE key="searchEngine.lastProcessedChangeId"'); await this.transactionExecBatch(queries); } diff --git a/ReactNativeClient/lib/models/Note.js b/ReactNativeClient/lib/models/Note.js index 671f0c6e5..5f9ab6563 100644 --- a/ReactNativeClient/lib/models/Note.js +++ b/ReactNativeClient/lib/models/Note.js @@ -250,7 +250,8 @@ class Note extends BaseItem { } static previewFields() { - return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time', 'user_updated_time', 'user_created_time', 'encryption_applied']; + // return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time', 'user_updated_time', 'user_created_time', 'encryption_applied']; + return ['id', 'title', 'is_todo', 'todo_completed', 'parent_id', 'updated_time', 'user_updated_time', 'user_created_time', 'encryption_applied']; } static previewFieldsSql(fields = null) { diff --git a/ReactNativeClient/root.js b/ReactNativeClient/root.js index 5e5b3e1cf..1811e7834 100644 --- a/ReactNativeClient/root.js +++ b/ReactNativeClient/root.js @@ -249,6 +249,11 @@ const appReducer = (state = appDefaultState, action) => { newState.notesParentType = 'Tag'; } + if ('smartFilterId' in action) { + newState.smartFilterId = action.smartFilterId; + newState.notesParentType = 'SmartFilter'; + } + if ('itemType' in action) { newState.selectedItemType = action.itemType; }