Mobile: Fixed handling of provisional notes

pull/2728/head
Laurent Cozic 2020-03-06 18:49:30 +00:00
parent 972e5aed8a
commit 51ce7c939d
5 changed files with 55 additions and 41 deletions

View File

@ -1,6 +1,7 @@
const React = require('react');
const { StyleSheet } = require('react-native');
const Note = require('lib/models/Note');
const Icon = require('react-native-vector-icons/Ionicons').default;
const ReactNativeActionButton = require('react-native-action-button').default;
const { connect } = require('react-redux');
@ -33,24 +34,25 @@ class ActionButtonComponent extends React.Component {
}
}
newTodo_press() {
async newNoteNavigate(folderId, isTodo) {
const newNote = await Note.save({
parent_id: folderId,
is_todo: isTodo ? 1 : 0,
}, { provisional: true });
this.props.dispatch({
type: 'NAV_GO',
routeName: 'Note',
noteId: null,
folderId: this.props.parentFolderId,
itemType: 'todo',
noteId: newNote.id,
});
}
newTodo_press() {
this.newNoteNavigate(this.props.parentFolderId, true);
}
newNote_press() {
this.props.dispatch({
type: 'NAV_GO',
routeName: 'Note',
noteId: null,
folderId: this.props.parentFolderId,
itemType: 'note',
});
this.newNoteNavigate(this.props.parentFolderId, false);
}
render() {

View File

@ -99,7 +99,9 @@ class NoteScreenComponent extends BaseScreenComponent {
const r = await saveDialog();
if (r) return r;
if (!this.state.note.id) {
const isProvisionalNote = this.props.provisionalNoteIds.includes(this.props.noteId);
if (isProvisionalNote) {
return false;
}

View File

@ -19,6 +19,20 @@ shared.noteExists = async function(noteId) {
return !!existingNote;
};
// Note has been deleted while user was modifying it. In that case, we
// just save a new note so that user can keep editing.
shared.handleNoteDeletedWhileEditing_ = async (note) => {
if (await shared.noteExists(note.id)) return null;
reg.logger().info('Note has been deleted while it was being edited - recreating it.');
let newNote = Object.assign({}, note);
delete newNote.id;
newNote = await Note.save(newNote);
return Note.load(newNote.id);
};
shared.saveNoteButton_press = async function(comp, folderId = null, options = null) {
options = Object.assign({}, {
autoTitle: true,
@ -28,9 +42,8 @@ shared.saveNoteButton_press = async function(comp, folderId = null, options = nu
let note = Object.assign({}, comp.state.note);
// Note has been deleted while user was modifying it. In that case, we
// just save a new note by clearing the note ID.
if (note.id && !(await shared.noteExists(note.id))) delete note.id;
const recreatedNote = await shared.handleNoteDeletedWhileEditing_(note);
if (recreatedNote) note = recreatedNote;
if (folderId) {
note.parent_id = folderId;
@ -60,7 +73,7 @@ shared.saveNoteButton_press = async function(comp, folderId = null, options = nu
const stateNote = comp.state.note;
// Note was reloaded while being saved.
if (!stateNote || stateNote.id !== savedNote.id) return releaseMutex();
if (!recreatedNote && (!stateNote || stateNote.id !== savedNote.id)) return releaseMutex();
// Re-assign any property that might have changed during saving (updated_time, etc.)
note = Object.assign(note, savedNote);
@ -116,26 +129,18 @@ shared.saveNoteButton_press = async function(comp, folderId = null, options = nu
shared.saveOneProperty = async function(comp, name, value) {
let note = Object.assign({}, comp.state.note);
// Note has been deleted while user was modifying it. In that, we
// just save a new note by clearing the note ID.
if (note.id && !(await shared.noteExists(note.id))) delete note.id;
const recreatedNote = await shared.handleNoteDeletedWhileEditing_(note);
if (recreatedNote) note = recreatedNote;
// reg.logger().info('Saving note property: ', note.id, name, value);
let toSave = { id: note.id };
toSave[name] = value;
toSave = await Note.save(toSave);
note[name] = toSave[name];
if (note.id) {
let toSave = { id: note.id };
toSave[name] = value;
toSave = await Note.save(toSave);
note[name] = toSave[name];
comp.setState({
lastSavedNote: Object.assign({}, note),
note: note,
});
} else {
note[name] = value;
comp.setState({ note: note });
}
comp.setState({
lastSavedNote: Object.assign({}, note),
note: note,
});
};
shared.noteComponent_change = function(comp, propName, propValue) {
@ -190,14 +195,15 @@ shared.isModified = function(comp) {
};
shared.initState = async function(comp) {
let note = null;
const isProvisionalNote = comp.props.provisionalNoteIds.includes(comp.props.noteId);
const note = await Note.load(comp.props.noteId);
let mode = 'view';
if (!comp.props.noteId) {
note = comp.props.itemType == 'todo' ? Note.newTodo(comp.props.folderId) : Note.new(comp.props.folderId);
if (isProvisionalNote) {
// note = comp.props.itemType == 'todo' ? Note.newTodo(comp.props.folderId) : Note.new(comp.props.folderId);
mode = 'edit';
comp.scheduleFocusUpdate();
} else {
note = await Note.load(comp.props.noteId);
}
const folder = Folder.byId(comp.props.folders, note.parent_id);
@ -217,7 +223,7 @@ shared.initState = async function(comp) {
}
// eslint-disable-next-line require-atomic-updates
comp.lastLoadedNoteId_ = note ? note.id : null;
comp.lastLoadedNoteId_ = note.id;
};
shared.toggleIsTodo_onPress = function(comp) {

View File

@ -29,10 +29,11 @@ const reduxSharedMiddleware = async function(store, next, action) {
refreshTags = true;
}
if (action.type === 'NOTE_SELECT') {
if (action.type === 'NOTE_SELECT' || action.type === 'NAV_BACK') {
const noteIds = newState.provisionalNoteIds.slice();
for (const noteId of noteIds) {
if (action.id === noteId) continue;
reg.logger().info('Provisional was not modified - deleting it');
await Note.delete(noteId);
}
}

View File

@ -12,6 +12,9 @@ import { YellowBox, AppRegistry } from 'react-native';
YellowBox.ignoreWarnings([
'Require cycle: node_modules/react-native-',
'Require cycle: node_modules/rn-fetch-blob',
'Warning: componentWillReceiveProps has been renamed',
'Warning: componentWillUpdate has been renamed',
'Warning: componentWillMount has been renamed',
]);
const { Root } = require('./root.js');