saving attachments when editing

This commit is contained in:
zadam 2023-01-24 09:19:49 +01:00
parent f59e19d93b
commit c474e65cae
9 changed files with 43 additions and 25 deletions

View File

@ -74,16 +74,16 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
const {note} = this.noteContext; const {note} = this.noteContext;
const {noteId} = note; const {noteId} = note;
const content = await this.getTypeWidget().getContent(); const data = await this.getTypeWidget().getData();
// for read only notes // for read only notes
if (content === undefined) { if (data === undefined) {
return; return;
} }
protectedSessionHolder.touchProtectedSessionIfNecessary(note); protectedSessionHolder.touchProtectedSessionIfNecessary(note);
await server.put(`notes/${noteId}/content`, {content}, this.componentId); await server.put(`notes/${noteId}/data`, data, this.componentId);
}); });
appContext.addBeforeUnloadListener(this); appContext.addBeforeUnloadListener(this);

View File

@ -246,7 +246,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget {
* gets data from widget container that will be sent via spacedUpdate.scheduleUpdate(); * gets data from widget container that will be sent via spacedUpdate.scheduleUpdate();
* this is automatically called after this.saveData(); * this is automatically called after this.saveData();
*/ */
async getContent() { async getData() {
const elements = this.excalidrawRef.current.getSceneElements(); const elements = this.excalidrawRef.current.getSceneElements();
const appState = this.excalidrawRef.current.getAppState(); const appState = this.excalidrawRef.current.getAppState();
@ -277,14 +277,21 @@ export default class ExcalidrawTypeWidget extends TypeWidget {
}) })
const content = { const content = {
_meta: "This note has type `canvas`. It uses excalidraw and stores an exported svg alongside.", elements,
elements, // excalidraw appState,
appState, // excalidraw files: activeFiles
files: activeFiles, // excalidraw
svg: svgString, // not needed for excalidraw, used for note_short, content, and image api
}; };
return JSON.stringify(content); return {
content: JSON.stringify(content),
attachments: [
{
name: 'canvasSvg',
mime: 'image/svg+xml',
content: svgString
}
]
};
} }
/** /**

View File

@ -96,8 +96,10 @@ export default class EditableCodeTypeWidget extends TypeWidget {
} }
} }
getContent() { getData() {
return this.codeEditor.getValue(); return {
content: this.codeEditor.getValue()
};
} }
focus() { focus() {

View File

@ -185,12 +185,14 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
}); });
} }
getContent() { getData() {
const content = this.watchdog.editor.getData(); const content = this.watchdog.editor.getData();
// if content is only tags/whitespace (typically <p>&nbsp;</p>), then just make it empty // if content is only tags/whitespace (typically <p>&nbsp;</p>), then just make it empty
// this is important when setting new note to code // this is important when setting new note to code
return utils.isHtmlEmpty(content) ? '' : content; return {
content: utils.isHtmlEmpty(content) ? '' : content
};
} }
focus() { focus() {

View File

@ -586,8 +586,11 @@ export default class RelationMapTypeWidget extends TypeWidget {
}; };
} }
getContent() { getData() {
return JSON.stringify(this.mapData); // TODO: save also image as attachment
return {
content: JSON.stringify(this.mapData)
};
} }
async relationMapCreateChildNoteEvent({ntxId}) { async relationMapCreateChildNoteEvent({ntxId}) {

View File

@ -39,9 +39,9 @@ export default class TypeWidget extends NoteContextAwareWidget {
} }
/** /**
* @returns {Promise|*} promise resolving content or directly the content * @returns {Promise<Object>|*} promise resolving note data. Note data is an object with content and attachments.
*/ */
getContent() {} getData() {}
focus() {} focus() {}

View File

@ -53,11 +53,11 @@ function createNote(req) {
}; };
} }
function updateNoteContent(req) { function updateNoteData(req) {
const {content} = req.body; const {content, attachments} = req.body;
const {noteId} = req.params; const {noteId} = req.params;
return noteService.updateNoteContent(noteId, content); return noteService.updateNoteData(noteId, content, attachments);
} }
function deleteNote(req) { function deleteNote(req) {
@ -327,7 +327,7 @@ function forceSaveNoteRevision(req) {
module.exports = { module.exports = {
getNote, getNote,
updateNoteContent, updateNoteData,
deleteNote, deleteNote,
undeleteNote, undeleteNote,
createNote, createNote,

View File

@ -118,7 +118,7 @@ function register(app) {
apiRoute(GET, '/api/autocomplete', autocompleteApiRoute.getAutocomplete); apiRoute(GET, '/api/autocomplete', autocompleteApiRoute.getAutocomplete);
apiRoute(GET, '/api/notes/:noteId', notesApiRoute.getNote); apiRoute(GET, '/api/notes/:noteId', notesApiRoute.getNote);
apiRoute(PUT, '/api/notes/:noteId/content', notesApiRoute.updateNoteContent); apiRoute(PUT, '/api/notes/:noteId/data', notesApiRoute.updateNoteData);
apiRoute(DELETE, '/api/notes/:noteId', notesApiRoute.deleteNote); apiRoute(DELETE, '/api/notes/:noteId', notesApiRoute.deleteNote);
apiRoute(PUT, '/api/notes/:noteId/undelete', notesApiRoute.undeleteNote); apiRoute(PUT, '/api/notes/:noteId/undelete', notesApiRoute.undeleteNote);
apiRoute(POST, '/api/notes/:noteId/revision', notesApiRoute.forceSaveNoteRevision); apiRoute(POST, '/api/notes/:noteId/revision', notesApiRoute.forceSaveNoteRevision);

View File

@ -592,7 +592,7 @@ function saveNoteRevisionIfNeeded(note) {
} }
} }
function updateNoteContent(noteId, content) { function updateNoteData(noteId, content, attachments = []) {
const note = becca.getNote(noteId); const note = becca.getNote(noteId);
if (!note.isContentAvailable()) { if (!note.isContentAvailable()) {
@ -604,6 +604,10 @@ function updateNoteContent(noteId, content) {
content = saveLinks(note, content); content = saveLinks(note, content);
note.setContent(content); note.setContent(content);
for (const {name, mime, content} of attachments) {
note.saveNoteAttachment(name, mime, content);
}
} }
/** /**
@ -998,7 +1002,7 @@ sqlInit.dbReady.then(() => {
module.exports = { module.exports = {
createNewNote, createNewNote,
createNewNoteWithTarget, createNewNoteWithTarget,
updateNoteContent, updateNoteData,
undeleteNote, undeleteNote,
protectNoteRecursively, protectNoteRecursively,
scanForLinks, scanForLinks,