1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-30 20:39:46 +02:00

Compare commits

..

3 Commits

Author SHA1 Message Date
Laurent Cozic
d2acf314f5 Android release v1.0.329 2020-04-20 10:13:04 +01:00
Laurent Cozic
b803984773 Android: Fixes #3041: Fixed text scrolling issue on older devices 2020-04-20 22:31:21 +00:00
Laurent Cozic
d2582f4fdf Revert "Restored note history feature by Naveen M V <naveenmv7@gmail.com>"
This reverts commit 61d3582357.

For rational see https://github.com/laurent22/joplin/pull/2819#issuecomment-616148984
2020-04-19 17:14:57 +01:00
11 changed files with 70 additions and 425 deletions

View File

@@ -1,138 +0,0 @@
require('app-module-path').addPath(__dirname);
const { asyncTest, id, ids, createNTestFolders, createNTestNotes, TestApp } = require('test-utils.js');
const { time } = require('lib/time-utils.js');
let testApp = null;
const goBackWard = (state) => {
const lastItem = state.backwardHistoryNotes[state.backwardHistoryNotes.length - 1];
testApp.dispatch({ type: 'FOLDER_AND_NOTE_SELECT', noteId: lastItem.id, folderId: lastItem.parent_id, historyAction: 'pop' });
};
const goForward = (state) => {
const lastItem = state.forwardHistoryNotes[state.forwardHistoryNotes.length - 1];
testApp.dispatch({ type: 'FOLDER_AND_NOTE_SELECT', noteId: lastItem.id, folderId: lastItem.parent_id, historyAction: 'push' });
};
describe('integration_ForwardBackwardNoteHistory', function() {
beforeEach(async (done) => {
testApp = new TestApp();
await testApp.start(['--no-welcome']);
done();
});
afterEach(async (done) => {
if (testApp !== null) await testApp.destroy();
testApp = null;
done();
});
it('should save history when navigating through notes', asyncTest(async () => {
// setup
const folders = await createNTestFolders(2);
await time.msleep(100);
const notes0 = await createNTestNotes(5, folders[0]);
// let notes1 = await createNTestNotes(5, folders[1]);
await time.msleep(100);
testApp.dispatch({ type: 'FOLDER_SELECT', id: id(folders[0]) });
await time.msleep(100);
let state = testApp.store().getState();
expect(state.backwardHistoryNotes).toEqual([]);
expect(state.forwardHistoryNotes).toEqual([]);
testApp.dispatch({ type: 'NOTE_SELECT', id: notes0[3].id, historyAction: 'goto' });
await time.msleep(100);
testApp.dispatch({ type: 'NOTE_SELECT', id: notes0[2].id, historyAction: 'goto' });
await time.msleep(100);
testApp.dispatch({ type: 'NOTE_SELECT', id: notes0[1].id, historyAction: 'goto' });
await time.msleep(100);
testApp.dispatch({ type: 'NOTE_SELECT', id: notes0[0].id, historyAction: 'goto' });
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4], notes0[3], notes0[2], notes0[1]]));
expect(ids(state.forwardHistoryNotes)).toEqual([]);
goBackWard(state);
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4], notes0[3], notes0[2]]));
expect(ids(state.forwardHistoryNotes)).toEqual(ids([notes0[0]]));
goBackWard(state);
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4], notes0[3]]));
expect(ids(state.forwardHistoryNotes)).toEqual(ids([notes0[0], notes0[1]]));
goForward(state);
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4], notes0[3], notes0[2]]));
expect(ids(state.forwardHistoryNotes)).toEqual(ids([notes0[0]]));
testApp.dispatch({ type: 'NOTE_SELECT', id: notes0[4].id, historyAction: 'goto' });
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4], notes0[3], notes0[2], notes0[1]]));
expect(ids(state.forwardHistoryNotes)).toEqual([]);
}));
it('should save history when navigating through notebooks', asyncTest(async () => {
const folders = await createNTestFolders(2);
await time.msleep(100);
const notes0 = await createNTestNotes(5, folders[0]);
const notes1 = await createNTestNotes(5, folders[1]);
await time.msleep(100);
testApp.dispatch({ type: 'FOLDER_SELECT', id: id(folders[0]) });
await time.msleep(100);
let state = testApp.store().getState();
expect(state.backwardHistoryNotes).toEqual([]);
expect(state.forwardHistoryNotes).toEqual([]);
testApp.dispatch({ type: 'FOLDER_SELECT', id: id(folders[1]), historyAction: 'goto' });
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4]])); // notes0[4] was last created
expect(ids(state.forwardHistoryNotes)).toEqual([]);
testApp.dispatch({ type: 'FOLDER_SELECT', id: id(folders[0]), historyAction: 'goto' });
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4], notes1[4]]));
expect(state.forwardHistoryNotes).toEqual([]);
goBackWard(state);
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4]]));
expect(ids(state.forwardHistoryNotes)).toEqual(ids([notes0[4]]));
goForward(state);
await time.msleep(100);
state = testApp.store().getState();
expect(ids(state.backwardHistoryNotes)).toEqual(ids([notes0[4], notes1[4]]));
expect(state.forwardHistoryNotes).toEqual([]);
}));
});

View File

@@ -36,41 +36,6 @@ function initTestState(folders, selectedFolderIndex, notes, selectedNoteIndexes,
return state;
}
function goToNote(notes, selectedNoteIndexes, state) {
if (selectedNoteIndexes != null) {
const selectedIds = [];
for (let i = 0; i < selectedNoteIndexes.length; i++) {
selectedIds.push(notes[selectedNoteIndexes[i]].id);
}
state = reducer(state, { type: 'NOTE_SELECT', ids: selectedIds, historyAction: 'goto' });
}
return state;
}
function goBackWard(state) {
if (!state.backwardHistoryNotes.length) return state;
const lastItem = state.backwardHistoryNotes[state.backwardHistoryNotes.length - 1];
state = reducer(state, {
type: 'FOLDER_AND_NOTE_SELECT',
noteId: lastItem.id ,
folderId: lastItem.parent_id ,
historyAction: 'pop',
});
return state;
}
function goForward(state) {
if (!state.forwardHistoryNotes.length) return state;
const nextItem = state.forwardHistoryNotes[state.forwardHistoryNotes.length - 1];
state = reducer(state, {
type: 'FOLDER_AND_NOTE_SELECT',
noteId: nextItem.id ,
folderId: nextItem.parent_id ,
historyAction: 'push',
});
return state;
}
function createExpectedState(items, keepIndexes, selectedIndexes) {
const expected = { items: [], selectedIds: [] };
@@ -380,118 +345,4 @@ describe('Reducer', function() {
expect(state.selectedNoteIds).toEqual(expected.selectedIds);
}));
it('should remove deleted note from history', asyncTest(async () => {
// create 1 folder
const folders = await createNTestFolders(1);
// create 5 notes
const notes = await createNTestNotes(5, folders[0]);
// select the 1st folder and the 1st note
let state = initTestState(folders, 0, notes, [0]);
// select second note
state = goToNote(notes, [1], state);
// select third note
state = goToNote(notes, [2], state);
// select fourth note
state = goToNote(notes, [3], state);
// expect history to contain first, second and third note
expect(state.backwardHistoryNotes.length).toEqual(3);
expect(getIds(state.backwardHistoryNotes)).toEqual(getIds(notes.slice(0, 3)));
// delete third note
state = reducer(state, { type: 'NOTE_DELETE', id: notes[2].id });
// expect history to not contain third note
expect(getIds(state.backwardHistoryNotes)).not.toContain(notes[2].id);
}));
it('should remove all notes of a deleted notebook from history', asyncTest(async () => {
const folders = await createNTestFolders(2);
const notes = [];
for (let i = 0; i < folders.length; i++) {
notes.push(...await createNTestNotes(3, folders[i]));
}
let state = initTestState(folders, 0, notes.slice(0,3), [0]);
state = goToNote(notes, [1], state);
state = goToNote(notes, [2], state);
// go to second folder
state = reducer(state, { type: 'FOLDER_SELECT', id: folders[1].id, historyAction: 'goto' });
expect(getIds(state.backwardHistoryNotes)).toEqual(getIds(notes.slice(0, 3)));
// delete the first folder
state = reducer(state, { type: 'FOLDER_DELETE', id: folders[0].id });
expect(getIds(state.backwardHistoryNotes)).toEqual([]);
}));
it('should maintain history correctly when going backward and forward', asyncTest(async () => {
const folders = await createNTestFolders(2);
const notes = [];
for (let i = 0; i < folders.length; i++) {
notes.push(...await createNTestNotes(5, folders[i]));
}
let state = initTestState(folders, 0, notes.slice(0,5), [0]);
state = goToNote(notes, [1], state);
state = goToNote(notes, [2], state);
state = goToNote(notes, [3], state);
state = goToNote(notes, [4], state);
expect(getIds(state.backwardHistoryNotes)).toEqual(getIds(notes.slice(0, 4)));
state = goBackWard(state);
expect(getIds(state.backwardHistoryNotes)).toEqual(getIds(notes.slice(0,3)));
expect(getIds(state.forwardHistoryNotes)).toEqual(getIds(notes.slice(4, 5)));
state = goBackWard(state);
expect(getIds(state.backwardHistoryNotes)).toEqual(getIds(notes.slice(0,2)));
// because we push the last seen note to stack.
expect(getIds(state.forwardHistoryNotes)).toEqual(getIds([notes[4], notes[3]]));
state = goForward(state);
expect(getIds(state.backwardHistoryNotes)).toEqual(getIds(notes.slice(0,3)));
expect(getIds(state.forwardHistoryNotes)).toEqual(getIds([notes[4]]));
state = goForward(state);
expect(getIds(state.backwardHistoryNotes)).toEqual(getIds(notes.slice(0,4)));
expect(getIds(state.forwardHistoryNotes)).toEqual([]);
}));
it('should remember the last seen note of a notebook', asyncTest(async () => {
const folders = await createNTestFolders(2);
const notes = [];
for (let i = 0; i < folders.length; i++) {
notes.push(...await createNTestNotes(5, folders[i]));
}
let state = initTestState(folders, 0, notes.slice(0,5), [0]);
state = goToNote(notes, [1], state);
state = goToNote(notes, [2], state);
state = goToNote(notes, [3], state);
state = goToNote(notes, [4], state); // last seen note is notes[4]
// go to second folder
state = reducer(state, { type: 'FOLDER_SELECT', id: folders[1].id, historyAction: 'goto' });
state = goToNote(notes, [5], state);
state = goToNote(notes, [6], state);
// return to first folder
state = reducer(state, { type: 'FOLDER_SELECT', id: folders[0].id, historyAction: 'goto' });
expect(state.lastSelectedNotesIds.Folder[folders[0].id]).toEqual([notes[4].id]);
// return to second folder
state = reducer(state, { type: 'FOLDER_SELECT', id: folders[1].id, historyAction: 'goto' });
expect(state.lastSelectedNotesIds.Folder[folders[1].id]).toEqual([notes[6].id]);
}));
});

View File

@@ -179,7 +179,6 @@ class MainScreenComponent extends React.Component {
this.props.dispatch({
type: 'FOLDER_SELECT',
id: folder.id,
historyAction: 'goto',
});
}
}

View File

@@ -114,7 +114,6 @@ class NoteListComponent extends React.Component {
this.props.dispatch({
type: 'NOTE_SELECT',
id: item.id,
historyAction: 'goto',
});
}
};

View File

@@ -866,7 +866,10 @@ class NoteTextComponent extends React.Component {
folderId: item.parent_id,
noteId: item.id,
hash: resourceUrlInfo.hash,
historyAction: 'goto',
historyNoteAction: {
id: this.state.note.id,
parent_id: this.state.note.parent_id,
},
});
} else {
throw new Error(`Unsupported item type: ${item.type_}`);
@@ -1707,39 +1710,24 @@ class NoteTextComponent extends React.Component {
});
}
toolbarItems.push({
tooltip: _('Back'),
iconName: 'fa-arrow-left',
enabled: (this.props.backwardHistoryNotes.length > 0),
onClick: () => {
if (!this.props.backwardHistoryNotes.length) return;
const lastItem = this.props.backwardHistoryNotes[this.props.backwardHistoryNotes.length - 1];
this.props.dispatch({
type: 'FOLDER_AND_NOTE_SELECT',
folderId: lastItem.parent_id,
noteId: lastItem.id,
if (this.props.historyNotes.length) {
toolbarItems.push({
tooltip: _('Back'),
iconName: 'fa-arrow-left',
onClick: () => {
if (!this.props.historyNotes.length) return;
historyAction: 'pop',
});
},
});
const lastItem = this.props.historyNotes[this.props.historyNotes.length - 1];
toolbarItems.push({
tooltip: _('Front'),
iconName: 'fa-arrow-right',
enabled: (this.props.forwardHistoryNotes.length > 0),
onClick: () => {
if (!this.props.forwardHistoryNotes.length) return;
const nextItem = this.props.forwardHistoryNotes[this.props.forwardHistoryNotes.length - 1];
this.props.dispatch({
type: 'FOLDER_AND_NOTE_SELECT',
folderId: nextItem.parent_id,
noteId: nextItem.id,
historyAction: 'push',
});
},
});
this.props.dispatch({
type: 'FOLDER_AND_NOTE_SELECT',
folderId: lastItem.parent_id,
noteId: lastItem.id,
historyNoteAction: 'pop',
});
},
});
}
if (note.markup_language === MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN && editorIsVisible) {
toolbarItems.push({
@@ -2316,8 +2304,7 @@ const mapStateToProps = state => {
watchedNoteFiles: state.watchedNoteFiles,
customCss: state.customCss,
lastEditorScrollPercents: state.lastEditorScrollPercents,
backwardHistoryNotes: state.backwardHistoryNotes,
forwardHistoryNotes: state.forwardHistoryNotes,
historyNotes: state.historyNotes,
templates: state.templates,
provisionalNoteIds: state.provisionalNoteIds,
};

View File

@@ -417,7 +417,6 @@ class SideBarComponent extends React.Component {
this.props.dispatch({
type: 'FOLDER_SELECT',
id: folder ? folder.id : null,
historyAction: 'goto',
});
}

View File

@@ -302,7 +302,6 @@ class Dialog extends React.PureComponent {
type: 'FOLDER_AND_NOTE_SELECT',
folderId: item.parent_id,
noteId: item.id,
historyAction: 'goto',
});
} else if (this.state.listType === BaseModel.TYPE_TAG) {
this.props.dispatch({
@@ -313,7 +312,6 @@ class Dialog extends React.PureComponent {
this.props.dispatch({
type: 'FOLDER_SELECT',
id: item.id,
historyAction: 'goto',
});
}
}

View File

@@ -32,7 +32,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/
Operating System | Download | Alt. Download
-----------------|----------|----------------
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.328/joplin-v1.0.328.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.328/joplin-v1.0.328-32bit.apk)
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.329/joplin-v1.0.329.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.329/joplin-v1.0.329-32bit.apk)
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://joplinapp.org/images/BadgeIOS.png'/></a> | -
## Terminal application

View File

@@ -120,8 +120,8 @@ android {
applicationId "net.cozic.joplin"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 2097564
versionName "1.0.328"
versionCode 2097565
versionName "1.0.329"
ndk {
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}

View File

@@ -1,5 +1,5 @@
const React = require('react');
const { Platform, Clipboard, Keyboard, View, TextInput, StyleSheet, Linking, Image, Share, Dimensions } = require('react-native');
const { Platform, Clipboard, Keyboard, View, TextInput, StyleSheet, Linking, Image, Share } = require('react-native');
const { connect } = require('react-redux');
const { uuid } = require('lib/uuid.js');
const { MarkdownEditor } = require('../../../MarkdownEditor/index.js');
@@ -210,17 +210,21 @@ class NoteScreenComponent extends BaseScreenComponent {
if (this.styles_[cacheKey]) return this.styles_[cacheKey];
this.styles_ = {};
const dimensions = Dimensions.get('window');
// TODO: Clean up these style names and nesting
const styles = {
bodyTextInput: {
flex: 1,
paddingLeft: theme.marginLeft,
paddingRight: theme.marginRight,
// Add extra space to allow scrolling past end of document, and also to fix this:
// https://github.com/laurent22/joplin/issues/1437
paddingBottom: Math.round(dimensions.height / 4),
// 2020-04-20: removed bottom padding because it doesn't work properly in Android
// Instead of being inside the scrollable area, the padding is outside thus
// restricting the view.
// See https://github.com/laurent22/joplin/issues/3041#issuecomment-616267739
// paddingBottom: Math.round(dimensions.height / 4),
textAlignVertical: 'top',
color: theme.color,
backgroundColor: theme.backgroundColor,
@@ -968,7 +972,13 @@ class NoteScreenComponent extends BaseScreenComponent {
}}
/>
: (
:
// Note: In theory ScrollView can be used to provide smoother scrolling of the TextInput.
// However it causes memory or rendering issues on older Android devices, probably because
// the whole text input has to be in memory for the scrollview to work. So we keep it as
// a plain TextInput for now.
// See https://github.com/laurent22/joplin/issues/3041
(
<TextInput autoCapitalize="sentences" style={this.styles().bodyTextInput} ref="noteBodyTextField" multiline={true} value={note.body} onChangeText={text => this.body_changeText(text)} blurOnSubmit={false} selectionColor={theme.textSelectionColor} keyboardAppearance={theme.keyboardAppearance} placeholder={_('Add body')} placeholderTextColor={theme.colorFaded} />
);
}

View File

@@ -51,8 +51,7 @@ const defaultState = {
resourceFetcher: {
toFetchCount: 0,
},
backwardHistoryNotes: [],
forwardHistoryNotes: [],
historyNotes: [],
plugins: {},
provisionalNoteIds: [],
editorNoteStatuses: {},
@@ -114,20 +113,6 @@ stateUtils.lastSelectedNoteIds = function(state) {
return output ? output : [];
};
stateUtils.getLastSeenNote = function(state) {
const selectedNoteIds = state.selectedNoteIds;
const notes = state.notes;
if (selectedNoteIds != null && selectedNoteIds.length > 0) {
const currNote = notes.find(note => note.id === selectedNoteIds[0]);
if (currNote != null) {
return {
id: currNote.id,
parent_id: currNote.parent_id,
};
}
}
};
function arrayHasEncryptedItems(array) {
for (let i = 0; i < array.length; i++) {
if (array[i].encryption_applied) return true;
@@ -218,15 +203,6 @@ function handleItemDelete(state, action) {
const newState = Object.assign({}, state);
newState[listKey] = newItems;
if (listKey === 'notes') {
newState.backwardHistoryNotes = newState.backwardHistoryNotes.filter(note => note.id != action.id);
newState.forwardHistoryNotes = newState.forwardHistoryNotes.filter(note => note.id != action.id);
}
if (listKey === 'folders') {
newState.backwardHistoryNotes = newState.backwardHistoryNotes.filter(note => note.parent_id != action.id);
newState.forwardHistoryNotes = newState.forwardHistoryNotes.filter(note => note.parent_id != action.id);
}
const newIds = [];
for (let i = 0; i < newSelectedIndexes.length; i++) {
newIds.push(newItems[newSelectedIndexes[i]].id);
@@ -286,25 +262,9 @@ function defaultNotesParentType(state, exclusion) {
function changeSelectedFolder(state, action, options = null) {
if (!options) options = {};
if (!('clearNoteHistory' in options)) options.clearNoteHistory = true;
const newState = Object.assign({}, state);
// Save the last seen note so that back will return to it.
if (action.type === 'FOLDER_SELECT' && action.historyAction == 'goto') {
const backwardHistoryNotes = newState.backwardHistoryNotes.slice();
let forwardHistoryNotes = newState.forwardHistoryNotes.slice();
// Don't update history if going to the same note again.
const lastSeenNote = stateUtils.getLastSeenNote(state);
if (lastSeenNote != null && action.id != lastSeenNote.id) {
forwardHistoryNotes = [];
backwardHistoryNotes.push(Object.assign({}, lastSeenNote));
}
newState.backwardHistoryNotes = backwardHistoryNotes;
newState.forwardHistoryNotes = forwardHistoryNotes;
}
newState.selectedFolderId = 'folderId' in action ? action.folderId : action.id;
if (!newState.selectedFolderId) {
newState.notesParentType = defaultNotesParentType(state, 'Folder');
@@ -314,6 +274,7 @@ function changeSelectedFolder(state, action, options = null) {
if (newState.selectedFolderId === state.selectedFolderId && newState.notesParentType === state.notesParentType) return state;
if (options.clearNoteHistory) newState.historyNotes = [];
if (options.clearSelectedNoteIds) newState.selectedNoteIds = [];
return newState;
@@ -333,6 +294,7 @@ function recordLastSelectedNoteIds(state, noteIds) {
function changeSelectedNotes(state, action, options = null) {
if (!options) options = {};
if (!('clearNoteHistory' in options)) options.clearNoteHistory = true;
let noteIds = [];
if (action.id) noteIds = [action.id];
@@ -342,37 +304,9 @@ function changeSelectedNotes(state, action, options = null) {
let newState = Object.assign({}, state);
if (action.type === 'NOTE_SELECT') {
if (JSON.stringify(newState.selectedNoteIds) === JSON.stringify(noteIds)) return state;
newState.selectedNoteIds = noteIds;
newState.selectedNoteHash = action.hash ? action.hash : '';
const backwardHistoryNotes = newState.backwardHistoryNotes.slice();
let forwardHistoryNotes = newState.forwardHistoryNotes.slice();
// The historyAction property is only used for user-initiated actions and tells how
// the history stack should be handled. That property should not be present for
// programmatic navigation. Possible values are:
// - "goto": When going to a note, but not via the back/forward arrows.
// - "pop": When clicking on the Back arrow
// - "push": When clicking on the Forward arrow
const lastSeenNote = stateUtils.getLastSeenNote(state);
if (action.historyAction == 'goto' && lastSeenNote != null && action.id != lastSeenNote.id) {
forwardHistoryNotes = [];
backwardHistoryNotes.push(Object.assign({}, lastSeenNote));
} else if (action.historyAction === 'pop' && lastSeenNote != null) {
if (forwardHistoryNotes.length === 0 || lastSeenNote.id != forwardHistoryNotes[forwardHistoryNotes.length - 1].id) {
forwardHistoryNotes.push(Object.assign({}, lastSeenNote));
}
backwardHistoryNotes.pop();
} else if (action.historyAction === 'push' && lastSeenNote != null) {
if (backwardHistoryNotes.length === 0 || lastSeenNote.id != backwardHistoryNotes[backwardHistoryNotes.length - 1].id) {
backwardHistoryNotes.push(Object.assign({}, lastSeenNote));
}
forwardHistoryNotes.pop();
}
newState.backwardHistoryNotes = backwardHistoryNotes;
newState.forwardHistoryNotes = forwardHistoryNotes;
} else if (action.type === 'NOTE_SELECT_ADD') {
if (!noteIds.length) return state;
newState.selectedNoteIds = ArrayUtils.unique(newState.selectedNoteIds.concat(noteIds));
@@ -401,6 +335,8 @@ function changeSelectedNotes(state, action, options = null) {
newState = recordLastSelectedNoteIds(newState, newState.selectedNoteIds);
if (options.clearNoteHistory) newState.historyNotes = [];
return newState;
}
@@ -491,9 +427,24 @@ const reducer = (state = defaultState, action) => {
case 'FOLDER_AND_NOTE_SELECT':
{
newState = changeSelectedFolder(state, action);
newState = changeSelectedFolder(state, action, { clearNoteHistory: false });
const noteSelectAction = Object.assign({}, action, { type: 'NOTE_SELECT' });
newState = changeSelectedNotes(newState, noteSelectAction);
newState = changeSelectedNotes(newState, noteSelectAction, { clearNoteHistory: false });
if (action.historyNoteAction) {
const historyNotes = newState.historyNotes.slice();
if (typeof action.historyNoteAction === 'object') {
historyNotes.push(Object.assign({}, action.historyNoteAction));
} else if (action.historyNoteAction === 'pop') {
historyNotes.pop();
}
newState.historyNotes = historyNotes;
} else if (newState !== state) {
// Clear the note history if folder and selected note have actually been changed. For example
// they won't change if they are already selected. That way, the "Back" button to go to the
// previous note wll stay.
newState.historyNotes = [];
}
}
break;
@@ -800,25 +751,14 @@ const reducer = (state = defaultState, action) => {
break;
case 'SEARCH_SELECT':
{
newState = Object.assign({}, state);
newState.selectedSearchId = action.id;
if (!action.id) {
newState.notesParentType = defaultNotesParentType(state, 'Search');
} else {
newState.notesParentType = 'Search';
}
// Update history when searching
const lastSeenNote = stateUtils.getLastSeenNote(state);
if (lastSeenNote != null && (state.backwardHistoryNotes.length === 0 ||
state.backwardHistoryNotes[state.backwardHistoryNotes.length - 1].id != lastSeenNote.id)) {
newState.forwardHistoryNotes = [];
newState.backwardHistoryNotes.push(Object.assign({},lastSeenNote));
}
newState.selectedNoteIds = [];
newState = Object.assign({}, state);
newState.selectedSearchId = action.id;
if (!action.id) {
newState.notesParentType = defaultNotesParentType(state, 'Search');
} else {
newState.notesParentType = 'Search';
}
newState.selectedNoteIds = [];
break;
case 'APP_STATE_SET':