5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-07-03 13:26:07 +00:00
panel/app/javascript/packs/imageUpload.js
2019-11-20 12:01:09 -03:00

105 lines
2.9 KiB
JavaScript

import { DirectUpload } from "@rails/activestorage"
import {Plugin} from "prosemirror-state"
import {Decoration, DecorationSet} from "prosemirror-view"
let placeholderPlugin = new Plugin({
state: {
init() { return DecorationSet.empty },
apply(tr, set) {
// Adjust decoration positions to changes made by the transaction
set = set.map(tr.mapping, tr.doc)
// See if the transaction adds or removes any placeholders
let action = tr.getMeta(this)
if (action && action.add) {
let widget = document.createElement(
action.add.blobUrl ? 'img' : 'placeholder'
)
// mostrar imágen en cache mientras tanto
if (action.add.blobUrl) {
widget.src = action.add.blobUrl
widget.classList.add('sutty-editor-loading-image')
}
let deco = Decoration.widget(action.add.pos, widget, {id: action.add.id})
set = set.add(tr.doc, [deco])
} else if (action && action.remove) {
set = set.remove(
set.find(
null, null,
spec => spec.id == action.remove.id,
),
)
}
return set
}
},
props: {
decorations(state) { return this.getState(state) }
}
})
export {placeholderPlugin}
function findPlaceholder(state, id) {
let decos = placeholderPlugin.getState(state)
let found = decos.find(null, null, spec => spec.id == id)
return found.length ? found[0].from : null
}
// XXX: buscar una manera mejor de pasar el schema
export function startImageUpload (view, file, schema) {
const altText = window.prompt('descripción de imágen', '')
let id = {}
const blobUrl = URL.createObjectURL(file)
// Replace the selection with a placeholder
let tr = view.state.tr
if (!tr.selection.empty) tr.deleteSelection()
tr.setMeta(placeholderPlugin, {
add: {id, pos: tr.selection.from, blobUrl},
})
view.dispatch(tr)
uploadFile(file).then(url => {
let pos = findPlaceholder(view.state, id)
// If the content around the placeholder has been deleted, drop
// the image
if (pos == null) return
// Otherwise, insert it at the placeholder's position, and remove
// the placeholder
view.dispatch(
view.state.tr
.replaceWith(pos, pos, schema.nodes.image.create({
src: url,
alt: altText.length ? altText : undefined,
}))
.setMeta(placeholderPlugin, {remove: {id}})
)
}, () => {
// On failure, just clean up the placeholder
view.dispatch(tr.setMeta(placeholderPlugin, {remove: {id}}))
})
}
export function uploadFile (file) {
return new Promise((resolve, reject) => {
const upload = new DirectUpload(
file,
location.origin + '/rails/active_storage/direct_uploads',
)
upload.create((error, blob) => {
if (error) {
reject(error)
} else {
const url = `${location.origin}/rails/active_storage/blobs/${blob.signed_id}/${blob.filename}`
resolve(url)
}
})
})
}