diff --git a/ElectronClient/app/gui/NoteList.jsx b/ElectronClient/app/gui/NoteList.jsx index b3420f5f0..c5111f418 100644 --- a/ElectronClient/app/gui/NoteList.jsx +++ b/ElectronClient/app/gui/NoteList.jsx @@ -13,6 +13,7 @@ const eventManager = require('../eventManager'); const InteropService = require('lib/services/InteropService'); const InteropServiceHelper = require('../InteropServiceHelper.js'); const Search = require('lib/models/Search'); +const { stateUtils } = require('lib/reducer'); const Mark = require('mark.js/dist/mark.min.js'); const SearchEngine = require('lib/services/SearchEngine'); const NoteListUtils = require('./utils/NoteListUtils'); @@ -271,6 +272,16 @@ class NoteListComponent extends React.Component { if (prevProps.windowCommand !== this.props.windowCommand) { this.doCommand(this.props.windowCommand); } + + if (prevProps.selectedNoteIds !== this.props.selectedNoteIds && this.props.selectedNoteIds.length === 1) { + const id = this.props.selectedNoteIds[0]; + for (let i = 0; i < this.props.notes.length; i++) { + if (this.props.notes[i].id === id) { + this.itemListRef.current.makeItemIndexVisible(i); + break; + } + } + } } async onKeyDown(event) { diff --git a/ReactNativeClient/lib/BaseApplication.js b/ReactNativeClient/lib/BaseApplication.js index 2720e2ba1..bcbd5b0b4 100644 --- a/ReactNativeClient/lib/BaseApplication.js +++ b/ReactNativeClient/lib/BaseApplication.js @@ -237,9 +237,30 @@ class BaseApplication { id: state.selectedNoteIds && state.selectedNoteIds.length ? state.selectedNoteIds[0] : null, }); } else { + const lastSelectedNoteIds = stateUtils.lastSelectedNoteIds(state); + const foundIds = []; + for (let i = 0; i < lastSelectedNoteIds.length; i++) { + const noteId = lastSelectedNoteIds[i]; + let found = false; + for (let j = 0; j < notes.length; j++) { + if (notes[j].id === noteId) { + found = true; + break; + } + } + if (found) foundIds.push(noteId); + } + + let selectedNoteId = null; + if (foundIds.length) { + selectedNoteId = foundIds[0]; + } else { + selectedNoteId = notes.length ? notes[0].id : null; + } + this.store().dispatch({ type: 'NOTE_SELECT', - id: notes.length ? notes[0].id : null, + id: selectedNoteId, }); } } diff --git a/ReactNativeClient/lib/reducer.js b/ReactNativeClient/lib/reducer.js index 936e75304..846de6d19 100644 --- a/ReactNativeClient/lib/reducer.js +++ b/ReactNativeClient/lib/reducer.js @@ -16,6 +16,11 @@ const defaultState = { selectedTagId: null, selectedSearchId: null, selectedItemType: 'note', + lastSelectedNotesIds: { + Folder: {}, + Tag: {}, + Search: {}, + }, showSideMenu: false, screens: {}, historyCanGoBack: false, @@ -53,6 +58,23 @@ stateUtils.notesOrder = function(stateSettings) { }]; } +stateUtils.parentItem = function(state) { + const t = state.notesParentType; + let id = null; + if (t === 'Folder') id = state.selectedFolderId; + if (t === 'Tag') id = state.selectedTagId; + if (t === 'Search') id = state.selectedSearchId; + if (!t || !id) return null; + return { type: t, id: id }; +} + +stateUtils.lastSelectedNoteIds = function(state) { + const parent = stateUtils.parentItem(state); + if (!parent) return []; + const output = state.lastSelectedNotesIds[parent.type][parent.id]; + return output ? output : []; +} + function arrayHasEncryptedItems(array) { for (let i = 0; i < array.length; i++) { if (!!array[i].encryption_applied) return true; @@ -183,6 +205,18 @@ function changeSelectedFolder(state, action) { return newState; } +function recordLastSelectedNoteIds(state, noteIds) { + const newOnes = Object.assign({}, state.lastSelectedNotesIds); + const parent = stateUtils.parentItem(state); + if (!parent) return state; + + newOnes[parent.type][parent.id] = noteIds.slice(); + + return Object.assign({}, state, { + lastSelectedNotesIds: newOnes, + }); +} + function changeSelectedNotes(state, action) { let noteIds = []; if (action.id) noteIds = [action.id]; @@ -196,17 +230,11 @@ function changeSelectedNotes(state, action) { if (action.type === 'NOTE_SELECT') { newState.selectedNoteIds = noteIds; newState.newNote = null; - return newState; - } - - if (action.type === 'NOTE_SELECT_ADD') { + } else if (action.type === 'NOTE_SELECT_ADD') { if (!noteIds.length) return state; newState.selectedNoteIds = ArrayUtils.unique(newState.selectedNoteIds.concat(noteIds)); newState.newNote = null; - return newState; - } - - if (action.type === 'NOTE_SELECT_REMOVE') { + } else if (action.type === 'NOTE_SELECT_REMOVE') { if (!noteIds.length) return state; // Nothing to unselect if (state.selectedNoteIds.length <= 1) return state; // Cannot unselect the last note @@ -218,11 +246,7 @@ function changeSelectedNotes(state, action) { } newState.selectedNoteIds = newSelectedNoteIds; newState.newNote = null; - - return newState; - } - - if (action.type === 'NOTE_SELECT_TOGGLE') { + } else if (action.type === 'NOTE_SELECT_TOGGLE') { if (!noteIds.length) return state; if (newState.selectedNoteIds.indexOf(noteIds[0]) >= 0) { @@ -232,11 +256,13 @@ function changeSelectedNotes(state, action) { } newState.newNote = null; - - return newState; + } else { + throw new Error('Unreachable'); } - throw new Error('Unreachable'); + newState = recordLastSelectedNoteIds(newState, newState.selectedNoteIds); + + return newState; } function removeItemFromArray(array, property, value) {