How to use editorActions.insertImage


(st anthony) #1

Bug report

ref: https://gist.github.com/NathanFlurry/2eaad9a9b9baac917cf7640e42605519

const editorActions = inkdrop.flux.getActions("editor");
const editorStore = inkdrop.flux.getStore("editor");
const fs = require("fs")
editorActions.insertImage 

Info

  • Platform: (macOS)
  • Platform version: (osx 10.13.6)
  • App Version: (3.25.3)

Reproduce

i want to import image to note,i found the insertImage API,but it failed both in plugin and Developer Tools.


(Takuya Matsuyama) #2

Hi Anthony,

Thank you for the question.
So you are trying to create a plugin?
The signature of insertImage is:

function insertImage({ file, nativeImage, position })
  • file: an instance of File class of HTML5
  • nativeImage: Electron’s nativeImage
  • position: Object with props: {line: number, ch: number}

Either file or nativeImage should be given.

However, please note that I’m currently rebuilding the app and the API will be changed in the new version.


(st anthony) #3

insertImage is ok
but how can i save the image ?

  fn = '/tmp/a1.md';
  const editorActions = inkdrop.flux.getActions("editor");
	const editorStore = inkdrop.flux.getStore("editor");
  await editorActions.create();
  const markDown = _fs2.default.readFileSync(fn, 'utf-8');
  const { title, body } = getTitleAndBodyFromMarkdown(fn, markDown);
  const { tags, createdAt, updatedAt } = getMetaFromMarkdown(body);
  const state = editorStore.getState();
  const newDocument = Object.assign(Object.assign({}, state.document), {
			title: "test a100",
			body: "test line1\ntest line2"
		});
  await editorActions.update({ document: newDocument, changed: true });
  const image = nativeImage.createFromPath('/tmp/1.jpg');
  await editorActions.insertImage({nativeImage: image , position:{line: 1, ch: 2} });
  
	//await editorActions.save({ document: newDocument });


(Takuya Matsuyama) #4

You have to save the note first before inserting the image.
The image will be saved automatically by calling insertImage.


(st anthony) #5

if i save the note first, then i got two documents

image

the demo code:

  const newDocument = Object.assign(Object.assign({}, state.document), {
			title: "test a100",
			body: "test line1\ntest line2"
		});
  await editorActions.update({ document: newDocument, changed: true });
	await editorActions.save({ document: newDocument });
  const image = nativeImage.createFromPath('/tmp/1.jpg');
  await editorActions.insertImage({nativeImage: image , position:{line: 1, ch: 2} });

(Takuya Matsuyama) #6

That’s because insertImage tries to insert an image to the currently editing note.
So you have to open the note you created with editorActions.open({ noteId }) after saving it.

I know it is not useful but the API is actually for internal use and not yet ready for plugins.
The API will be re-designed in the new version.


(st anthony) #7

But I have a lot of markdown files to import(about 3000+). I just need to import once time. After importing, I use inkdrop to edit, and the generated documents will no longer need to be imported.

So I can’t wait for the new version.

I paid for it and bought the pro version,sync with VPS CouchDB between iphone and mac osx.


(st anthony) #8

if you have the API like xxx.insertImageToStore:


    const uris = body.match("<markdown image regex> ") || [];
    for (let i = 0; i < uris.length; ++i) {
      const uri = uris[i];
     let image = nativeImage.createImageFromPath(fs.path.join(...., uri)); 
    //got the image link inkdrop://xxx-xxx 
   // or the code directly like  ![clipboard.png](inkdrop://file:0ZMJ1fRePw)
     const imageCode = xxx.insertImageToStore(image); 
      if (imageCode) {
        body = body.replace(uri, imageCode)
      }
    }

the import plugin will be ok soon


(st anthony) #9

I just want import my markdown files ( 3000+ ).
I’m a programmer ,but not web developer。So I encountered some difficulties.

I saw the API called k(?).createImageAttachment, could you tell me the usage ?


@craftzdog


(Takuya Matsuyama) #10

createImageAttachment is not able to access from plugins.
Well, how to create an image document is as following, but it is using low level APIs, so be sure that you might break your database.

const app = require('electron').remote.app
const image = nativeImage.createFromPath(...)
const buffer = image.toPNG()

// create an attachment document
const att = {
	_id: app.db.local.files.createId(),
	name: 'imported-file.png',
	createdAt: +new Date(),
	contentType: 'image/png',
	contentLength: buffer.length,
	_attachments: {
		index: {
			content_type: 'image/png',
			data: buffer.toString('base64')
		}
	}
}

// save
app.db.local.files.put(att)

// get markdown
const markdown = `![${att.name}](inkdrop://${att._id})`

be careful to run it.


(st anthony) #11

fine,you are right

when i use demo code to create image document, i got the bug.

the error url is : https://www.xxx.xxx:6984/inkdrop-notes/_bulk_docs

I guess the _bulk_docs post request lost several parameters(like username, password) .

i will try to remove the security(couchdb password),and try again

function createImageDocument(fn){
  if(!_fs2.default.existsSync(fn)){
    throw new Error('image path: ' + fn + ' is not exists');
  }
  const image = nativeImage.createFromPath(fn);
  if(image === null){
    throw new Error('image : ' + fn + ' is not valid');
  }
  const buffer = image.toPNG();
  if(typeof(buffer) !== 'object'){
    throw new Error("image : " + fn + ' toPNG failed');
  }
  // create an attachment document
  const att = {
    _id: app.db.local.files.createId(),
    name: 'imported-file.png',
    createdAt: +new Date(),
    contentType: 'image/png',
    contentLength: buffer.length,
    _attachments: {
      index: {
        content_type: 'image/png',
        data: buffer.toString('base64')
      }
    }
  }

  app.db.local.files.put(att)
  const markdown =  `![${att.name}](inkdrop://${att._id})`;
  throw new Error("markdown is : " + markdown);
  return markdown
}

(st anthony) #12

the database is broken.
I gave up.


(Takuya Matsuyama) #13

That’s too bad. But I’m afraid that it is all I can do at the moment.
I’m working hard on rebuilding the app; here is today’s my progress:

I hope you will try again once it’s out.