diff --git a/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx b/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx index 188328d15c..dccd6eb57c 100644 --- a/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx +++ b/packages/app-mobile/components/NoteEditor/ImageEditor/ImageEditor.tsx @@ -1,4 +1,4 @@ -const React = require('react'); +import * as React from 'react'; import { _ } from '@joplin/lib/locale'; import Logger from '@joplin/utils/Logger'; import Setting from '@joplin/lib/models/Setting'; @@ -18,7 +18,7 @@ import { OnMessageEvent } from '../../ExtendedWebView/types'; const logger = Logger.create('ImageEditor'); -type OnSaveCallback = (svgData: string)=> void; +type OnSaveCallback = (svgData: string)=> Promise; type OnCancelCallback = ()=> void; interface Props { @@ -231,6 +231,15 @@ const ImageEditor = (props: Props) => { })); }; + const saveThenClose = (drawing) => { + window.ReactNativeWebView.postMessage( + JSON.stringify({ + action: 'save-and-close', + data: drawing.outerHTML, + }), + ); + }; + try { if (window.editorControl === undefined) { ${shim.injectedJs('svgEditorBundle')} @@ -239,6 +248,7 @@ const ImageEditor = (props: Props) => { { saveDrawing, closeEditor, + saveThenClose, updateEditorTemplate, setImageHasChanges, }, @@ -308,13 +318,16 @@ const ImageEditor = (props: Props) => { const json = JSON.parse(data); if (json.action === 'save') { await clearAutosave(); - props.onSave(json.data); + await props.onSave(json.data); } else if (json.action === 'autosave') { await writeAutosave(json.data); } else if (json.action === 'save-toolbar') { Setting.setValue('imageeditor.jsdrawToolbar', json.data); } else if (json.action === 'close') { onRequestCloseEditor(json.promptIfUnsaved); + } else if (json.action === 'save-and-close') { + await props.onSave(json.data); + onRequestCloseEditor(json.promptIfUnsaved); } else if (json.action === 'ready-to-load-data') { void onReadyToLoadData(); } else if (json.action === 'set-image-has-changes') { diff --git a/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.ts b/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.ts index 743410c866..301852f4fe 100644 --- a/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.ts +++ b/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.test.ts @@ -22,6 +22,7 @@ const createEditorWithCallbacks = (callbacks: Partial) => const allCallbacks: ImageEditorCallbacks = { saveDrawing: () => {}, + saveThenClose: ()=> {}, closeEditor: ()=> {}, setImageHasChanges: ()=> {}, updateEditorTemplate: ()=> {}, diff --git a/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.ts b/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.ts index 1f35301482..f82b2b2c0f 100644 --- a/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.ts +++ b/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/createJsDrawEditor.ts @@ -91,11 +91,15 @@ export const createJsDrawEditor = ( } }; - const saveNow = () => { - callbacks.saveDrawing(editor.toSVG({ + const getEditorSVG = () => { + return editor.toSVG({ // Grow small images to this minimum size minDimension: 50, - }), false); + }); + }; + + const saveNow = () => { + callbacks.saveDrawing(getEditorSVG(), false); // The image is now up-to-date with the resource setImageHasChanges(false); @@ -177,13 +181,7 @@ export const createJsDrawEditor = ( }, saveNow, saveThenExit: async () => { - saveNow(); - - // Don't show a confirmation dialog -- it's possible that - // the code outside of the WebView still thinks changes haven't - // been saved: - const showConfirmation = false; - callbacks.closeEditor(showConfirmation); + callbacks.saveThenClose(getEditorSVG()); }, }; diff --git a/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.ts b/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.ts index ab930a512e..b0db5d8819 100644 --- a/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.ts +++ b/packages/app-mobile/components/NoteEditor/ImageEditor/js-draw/types.ts @@ -6,6 +6,7 @@ export interface ImageEditorCallbacks { saveDrawing: SaveDrawingCallback; updateEditorTemplate: UpdateEditorTemplateCallback; + saveThenClose: (svgData: SVGElement)=> void; closeEditor: (promptIfUnsaved: boolean)=> void; setImageHasChanges: (hasChanges: boolean)=> void; } diff --git a/packages/app-mobile/components/screens/Note.tsx b/packages/app-mobile/components/screens/Note.tsx index d07affa29a..cdf337162a 100644 --- a/packages/app-mobile/components/screens/Note.tsx +++ b/packages/app-mobile/components/screens/Note.tsx @@ -787,7 +787,7 @@ class NoteScreenComponent extends BaseScreenComponent implements B if (this.editorRef.current) { this.editorRef.current.insertText(newText); } else { - logger.error(`Tried to attach resource ${resource.id} to the note when the editor is not visible!`); + logger.info(`Tried to attach resource ${resource.id} to the note when the editor is not visible -- updating the note body instead.`); } } } else { @@ -900,20 +900,12 @@ class NoteScreenComponent extends BaseScreenComponent implements B }; private drawPicture_onPress = async () => { - if (this.state.mode === 'edit') { - // Create a new empty drawing and attach it now, before the image editor is opened. - // With the present structure of Note.tsx, the we can't use this.editorRef while - // the image editor is open, and thus can't attach drawings at the cursor location. - const resource = await this.attachNewDrawing(''); - await this.editDrawing(resource); - } else { - logger.info('Showing image editor...'); - this.setState({ - showImageEditor: true, - imageEditorResourceFilepath: null, - imageEditorResource: null, - }); - } + logger.info('Showing image editor...'); + this.setState({ + showImageEditor: true, + imageEditorResourceFilepath: null, + imageEditorResource: null, + }); }; private async editDrawing(item: BaseItem) {