Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image upload from file system #89

Closed
billyshena opened this issue Nov 14, 2018 · 11 comments
Closed

Image upload from file system #89

billyshena opened this issue Nov 14, 2018 · 11 comments
Labels
Type: Feature The issue or pullrequest is a new feature

Comments

@billyshena
Copy link

Hey guys ! I was wondering how to rewrite the image plugin to let the user choose from filesystem (instead of asking the url).
Should I write a Plugin with ProseMirror to make this work ?

Thanks,

@philippkuehn philippkuehn added the Type: Feature The issue or pullrequest is a new feature label Nov 20, 2018
@ilicmarko
Copy link

What I did is use the existing image command. I made a drag'n'drop area, when the user uploads and image it gets sent to the server after the server uploads the image I get the URL and add it with the image command. Here is a quick snippet:

<ImageModal ref="imageModal" @onClose="addCommand"/>

I have a simple button to call the modal, please note that the button should be under EditorMenuBar because you need the command.

<button class="menubar-button" @click="showImageModal(commands.image)">
    <Icon name="image"/>
</button>

What show image modal does is simply open the modal and assign that command:

showImageModal(command) {
    this.$refs.imageModal.showModal({command})
}

Here is a cut down version of what ImageModal.vue does:

droparea.addEventListener('drop', (e) => {
  let files = e.dataTransfer.files

  if (files.length > 0) {
    const image = files[0]

    const activeEmailID = this.activeEmailId

    this.$store.dispatch('uploadInlineImage', {image, activeEmailID}).then(url => {
    	// Get the uploaded URL
      this.url = url

      // Prepare data for sending to parent
      const data = {
        command: this.command,
        data: {
          src: this.url,
          alt: this.alt,
          title: this.title,
        }
      }
      
      this.$emit('onClose', data)
      this.resetData()
      this.$modal.hide(this.modalName)
    })
  }
})

When a drop happens, the image will get uploaded then I extract the URL and pack it with the command to emit to parent. If you remember there was and event listener on the modal called addCommand

addCommand(data) {
  if (data.command !== null) {
    data.command(data.data)
  }
}

Simple call the passed command for data inside it.


Hopefully you understand how I did it. I had a particulate case where I insert links and videos the same way. This flow can be shortened a bit.

@osman-mohamad
Copy link

@ilicmarko what if I want the image to be embedded in the html as base64encoded string ?

@ilicmarko
Copy link

ilicmarko commented Dec 13, 2018

@osman-mohamad I don't really get what you are asking. Because if you had a base64 string it doesn't make a difference at all. Because you are still going to embed it as <img src="{{SOMETHING}}">, you can see that {{SOMETHING}} can be anything URL or a base64 string.

If you are asking me how to upload an image, convert it to base64 and insert it in, then this is not the right issue for this. Because this a backend part of the operation, your server needs to return this data in shape and form you want.

@osman-mohamad
Copy link

@ilicmarko I do not want to upload it and convert it to base64 . I want to allow user to select file from filesystem . then the file converted to base64 in JavaScript side and send it as a part of the html output.

@ilicmarko
Copy link

@osman-mohamad As I said what you are asking doesn't have to do anything with this plugin nor the issue. In the example above I showed you how to get the dragged file content and that is where this issue should end because after that it doesn't concern the plugin (this repo) if you are going to upload it, convert it into base64 or whatever type of processing you are doing.

There are a few ways how to convert to base64 like file readers or Canvas. Look it up and take that string to send it to the image command an that is it. http://bfy.tw/LNDE.

Not trying to be rude by lets not fill up the thread with non-related questions/solutions.

@osman-mohamad
Copy link

thank you

@ilicmarko
Copy link

Here is working sandbox that demonstrates how to upload an image.

https://codesandbox.io/s/j3p0z44155

Please note: This is just an example, there is no working backend, therefore it will add a random image.

@philippkuehn
Copy link
Contributor

Thank you @ilicmarko for your example. I think the official images example covers the two most basic ways to add images.

  1. add a image url and store the image as a url
  2. drop image and store the image as a base64 encoded string

It's up to you to build a layer on top of that for uploading to a server or whatever.

@slava-vishnyakov
Copy link

Actually the most important part for me was how to store dropped image on server.
Here's a gist with my solution. I'd actually prefer if the tiptap-extensions/Image had the third parameter so you can just add this as extension new Image(null, null, upload_function) (that's how I do it in the gist).

How to upload images with TipTap editor

@fdrissi
Copy link

fdrissi commented Sep 12, 2021

I have created this gist , you can find how I did it with react. I am leaving this here if anyone needs it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Feature The issue or pullrequest is a new feature
Projects
None yet
Development

No branches or pull requests

7 participants
@slava-vishnyakov @philippkuehn @ilicmarko @billyshena @osman-mohamad @fdrissi and others