You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-12-02 22:49:09 +02:00
Electron: Improved the way new note are created, and automatically add a title. Made saving and loading notes more reliable.
This commit is contained in:
@@ -24,25 +24,29 @@ shared.saveNoteButton_press = async function(comp) {
|
||||
}
|
||||
|
||||
let isNew = !note.id;
|
||||
let titleWasAutoAssigned = false;
|
||||
|
||||
if (isNew && !note.title) {
|
||||
note.title = Note.defaultTitle(note);
|
||||
titleWasAutoAssigned = true;
|
||||
}
|
||||
|
||||
let options = {};
|
||||
let options = { userSideValidation: true };
|
||||
if (!isNew) {
|
||||
options.fields = BaseModel.diffObjectsFields(comp.state.lastSavedNote, note);
|
||||
}
|
||||
|
||||
const savedNote = ('fields' in options) && !options.fields.length ? Object.assign({}, note) : await Note.save(note, { userSideValidation: true });
|
||||
const hasAutoTitle = comp.state.newAndNoTitleChangeNoteId || (isNew && !note.title);
|
||||
if (hasAutoTitle) {
|
||||
note.title = Note.defaultTitle(note);
|
||||
if (options.fields && options.fields.indexOf('title') < 0) options.fields.push('title');
|
||||
}
|
||||
|
||||
const savedNote = ('fields' in options) && !options.fields.length ? Object.assign({}, note) : await Note.save(note, options);
|
||||
|
||||
const stateNote = comp.state.note;
|
||||
|
||||
// Note was reloaded while being saved.
|
||||
if (!isNew && (!stateNote || stateNote.id !== savedNote.id)) return;
|
||||
|
||||
// Re-assign any property that might have changed during saving (updated_time, etc.)
|
||||
note = Object.assign(note, savedNote);
|
||||
|
||||
if (stateNote) {
|
||||
if (stateNote.id === note.id) {
|
||||
// But we preserve the current title and body because
|
||||
// the user might have changed them between the time
|
||||
// saveNoteButton_press was called and the note was
|
||||
@@ -50,17 +54,30 @@ shared.saveNoteButton_press = async function(comp) {
|
||||
//
|
||||
// If the title was auto-assigned above, we don't restore
|
||||
// it from the state because it will be empty there.
|
||||
if (!titleWasAutoAssigned) note.title = stateNote.title;
|
||||
if (!hasAutoTitle) note.title = stateNote.title;
|
||||
note.body = stateNote.body;
|
||||
}
|
||||
|
||||
comp.setState({
|
||||
let newState = {
|
||||
lastSavedNote: Object.assign({}, note),
|
||||
note: note,
|
||||
});
|
||||
};
|
||||
|
||||
if (isNew) newState.newAndNoTitleChangeNoteId = note.id;
|
||||
|
||||
comp.setState(newState);
|
||||
|
||||
if (isNew) Note.updateGeolocation(note.id);
|
||||
comp.refreshNoteMetadata();
|
||||
|
||||
if (isNew) {
|
||||
// Clear the newNote item now that the note has been saved, and
|
||||
// make sure that the note we're editing is selected.
|
||||
comp.props.dispatch({
|
||||
type: 'NOTE_SELECT',
|
||||
id: savedNote.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
shared.saveOneProperty = async function(comp, name, value) {
|
||||
@@ -89,9 +106,13 @@ shared.saveOneProperty = async function(comp, name, value) {
|
||||
}
|
||||
|
||||
shared.noteComponent_change = function(comp, propName, propValue) {
|
||||
let newState = {}
|
||||
|
||||
let note = Object.assign({}, comp.state.note);
|
||||
note[propName] = propValue;
|
||||
comp.setState({ note: note });
|
||||
newState.note = note;
|
||||
|
||||
comp.setState(newState);
|
||||
}
|
||||
|
||||
shared.refreshNoteMetadata = async function(comp, force = null) {
|
||||
@@ -103,7 +124,7 @@ shared.refreshNoteMetadata = async function(comp, force = null) {
|
||||
|
||||
shared.isModified = function(comp) {
|
||||
if (!comp.state.note || !comp.state.lastSavedNote) return false;
|
||||
let diff = BaseModel.diffObjects(comp.state.note, comp.state.lastSavedNote);
|
||||
let diff = BaseModel.diffObjects(comp.state.lastSavedNote, comp.state.note);
|
||||
delete diff.type_;
|
||||
return !!Object.getOwnPropertyNames(diff).length;
|
||||
}
|
||||
|
||||
@@ -69,8 +69,6 @@ class Note extends BaseItem {
|
||||
}
|
||||
|
||||
static defaultTitle(note) {
|
||||
if (note.title && note.title.length) return note.title;
|
||||
|
||||
if (note.body && note.body.length) {
|
||||
const lines = note.body.trim().split("\n");
|
||||
return lines[0].trim().substr(0, 80).trim();
|
||||
|
||||
@@ -29,6 +29,7 @@ const defaultState = {
|
||||
appState: 'starting',
|
||||
//windowContentSize: { width: 0, height: 0 },
|
||||
hasDisabledSyncItems: false,
|
||||
newNote: null,
|
||||
};
|
||||
|
||||
function arrayHasEncryptedItems(array) {
|
||||
@@ -144,12 +145,14 @@ function changeSelectedNotes(state, action) {
|
||||
|
||||
if (action.type === 'NOTE_SELECT') {
|
||||
newState.selectedNoteIds = noteIds;
|
||||
newState.newNote = null;
|
||||
return newState;
|
||||
}
|
||||
|
||||
if (action.type === 'NOTE_SELECT_ADD') {
|
||||
if (!noteIds.length) return state;
|
||||
newState.selectedNoteIds = ArrayUtils.unique(newState.selectedNoteIds.concat(noteIds));
|
||||
newState.newNote = null;
|
||||
return newState;
|
||||
}
|
||||
|
||||
@@ -164,6 +167,7 @@ function changeSelectedNotes(state, action) {
|
||||
newSelectedNoteIds.push(id);
|
||||
}
|
||||
newState.selectedNoteIds = newSelectedNoteIds;
|
||||
newState.newNote = null;
|
||||
|
||||
return newState;
|
||||
}
|
||||
@@ -177,6 +181,8 @@ function changeSelectedNotes(state, action) {
|
||||
newState = changeSelectedNotes(state, { type: 'NOTE_SELECT_ADD', id: noteIds[0] });
|
||||
}
|
||||
|
||||
newState.newNote = null;
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
@@ -455,6 +461,12 @@ const reducer = (state = defaultState, action) => {
|
||||
newState.hasDisabledSyncItems = true;
|
||||
break;
|
||||
|
||||
case 'NOTE_SET_NEW_ONE':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState.newNote = action.item;
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
error.message = 'In reducer: ' + error.message + ' Action: ' + JSON.stringify(action);
|
||||
|
||||
Reference in New Issue
Block a user