Feature/paste image from buffer (#251)
Editor: Paste images from clipboard
This commit is contained in:
parent
f85a3e84fe
commit
f593d95358
|
@ -212,7 +212,6 @@
|
|||
"Nothing here yet": "There's nothing here yet",
|
||||
"Nothing is here": "There is nothing here",
|
||||
"Notifications": "Notifications",
|
||||
"Registered since {{date}}": "Registered since {{date}}",
|
||||
"Or continue with social network": "Or continue with social network",
|
||||
"Or paste a link to an image": "Or paste a link to an image",
|
||||
"Ordered list": "Ordered list",
|
||||
|
@ -250,6 +249,7 @@
|
|||
"Quotes": "Quotes",
|
||||
"Reason uknown": "Reason unknown",
|
||||
"Recent": "Fresh",
|
||||
"Registered since {{date}}": "Registered since {{date}}",
|
||||
"Remove link": "Remove link",
|
||||
"Reply": "Reply",
|
||||
"Report": "Complain",
|
||||
|
@ -327,6 +327,7 @@
|
|||
"Upload": "Upload",
|
||||
"Upload error": "Upload error",
|
||||
"Upload video": "Upload video",
|
||||
"Uploading image": "Uploading image",
|
||||
"Username": "Username",
|
||||
"Userpic": "Userpic",
|
||||
"Users": "Users",
|
||||
|
|
|
@ -222,7 +222,6 @@
|
|||
"Nothing here yet": "Здесь пока ничего нет",
|
||||
"Nothing is here": "Здесь ничего нет",
|
||||
"Notifications": "Уведомления",
|
||||
"Registered since {{date}}": "На сайте c {{date}}",
|
||||
"Or continue with social network": "Или войдите через соцсеть",
|
||||
"Or paste a link to an image": "Или вставьте ссылку на изображение",
|
||||
"Ordered list": "Нумерованный список",
|
||||
|
@ -264,6 +263,7 @@
|
|||
"Quotes": "Цитаты",
|
||||
"Reason uknown": "Причина неизвестна",
|
||||
"Recent": "Свежее",
|
||||
"Registered since {{date}}": "На сайте c {{date}}",
|
||||
"Release date...": "Дата выхода...",
|
||||
"Remove link": "Убрать ссылку",
|
||||
"Reply": "Ответить",
|
||||
|
@ -345,6 +345,7 @@
|
|||
"Upload": "Загрузить",
|
||||
"Upload error": "Ошибка загрузки",
|
||||
"Upload video": "Загрузить видео",
|
||||
"Uploading image": "Загружаем изображение",
|
||||
"Username": "Имя пользователя",
|
||||
"Userpic": "Аватар",
|
||||
"Users": "Пользователи",
|
||||
|
|
|
@ -44,6 +44,9 @@ import { EditorFloatingMenu } from './EditorFloatingMenu'
|
|||
import './Prosemirror.scss'
|
||||
import { Image } from '@tiptap/extension-image'
|
||||
import { Footnote } from './extensions/Footnote'
|
||||
import { handleFileUpload } from '../../utils/handleFileUpload'
|
||||
import { imageProxy } from '../../utils/imageProxy'
|
||||
import { useSnackbar } from '../../context/snackbar'
|
||||
|
||||
type Props = {
|
||||
shoutId: number
|
||||
|
@ -51,6 +54,17 @@ type Props = {
|
|||
onChange: (text: string) => void
|
||||
}
|
||||
|
||||
const allowedImageTypes = new Set([
|
||||
'image/bmp',
|
||||
'image/gif',
|
||||
'image/jpeg',
|
||||
'image/jpg',
|
||||
'image/png',
|
||||
'image/tiff',
|
||||
'image/webp',
|
||||
'image/x-icon'
|
||||
])
|
||||
|
||||
const yDocs: Record<string, Doc> = {}
|
||||
const providers: Record<string, HocuspocusProvider> = {}
|
||||
|
||||
|
@ -61,6 +75,10 @@ export const Editor = (props: Props) => {
|
|||
const [isCommonMarkup, setIsCommonMarkup] = createSignal(false)
|
||||
const [shouldShowTextBubbleMenu, setShouldShowTextBubbleMenu] = createSignal(false)
|
||||
|
||||
const {
|
||||
actions: { showSnackbar }
|
||||
} = useSnackbar()
|
||||
|
||||
const docName = `shout-${props.shoutId}`
|
||||
|
||||
if (!yDocs[docName]) {
|
||||
|
@ -114,12 +132,73 @@ export const Editor = (props: Props) => {
|
|||
content: 'figcaption image'
|
||||
})
|
||||
|
||||
const handleClipboardPaste = async () => {
|
||||
try {
|
||||
const clipboardItems = await navigator.clipboard.read()
|
||||
|
||||
if (clipboardItems.length === 0) return
|
||||
const [clipboardItem] = clipboardItems
|
||||
const { types } = clipboardItem
|
||||
const imageType = types.find((type) => allowedImageTypes.has(type))
|
||||
|
||||
if (!imageType) return
|
||||
const blob = await clipboardItem.getType(imageType)
|
||||
const extension = imageType.split('/')[1]
|
||||
const file = new File([blob], `clipboardImage.${extension}`)
|
||||
|
||||
const uplFile = {
|
||||
source: blob.toString(),
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
file
|
||||
}
|
||||
|
||||
showSnackbar({ body: t('Uploading image') })
|
||||
const result = await handleFileUpload(uplFile)
|
||||
|
||||
editor()
|
||||
.chain()
|
||||
.focus()
|
||||
.insertContent({
|
||||
type: 'capturedImage',
|
||||
content: [
|
||||
{
|
||||
type: 'figcaption',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: result.originalFilename
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'image',
|
||||
attrs: {
|
||||
src: imageProxy(result.url)
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
.run()
|
||||
} catch (error) {
|
||||
console.log('!!! Paste image Error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const { initialContent } = props
|
||||
|
||||
const editor = createTiptapEditor(() => ({
|
||||
element: editorElRef.current,
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: 'articleEditor'
|
||||
},
|
||||
transformPastedHTML(html) {
|
||||
return html.replaceAll(/<img.*?>/g, '')
|
||||
},
|
||||
handlePaste: () => {
|
||||
handleClipboardPaste()
|
||||
return false
|
||||
}
|
||||
},
|
||||
extensions: [
|
||||
|
@ -246,6 +325,7 @@ export const Editor = (props: Props) => {
|
|||
TrailingNode,
|
||||
Article
|
||||
],
|
||||
enablePasteRules: [Link],
|
||||
content: initialContent ?? null
|
||||
}))
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export const renderUploadedImage = (editor: Editor, image: UploadedFile) => {
|
|||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: image.originalFilename
|
||||
text: image.originalFilename ?? ''
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue
Block a user