Я надеюсь, что с тобой все в порядке. Я работаю над таким средством, как текстовый редактор, использую для этого Tiptap и реализую его с помощью реакции. Одна вещь, в которой я застрял, — это загрузка изображений. Я хочу реализовать загрузку изображения, используя расширение изображения или что-то еще вроде этого:
Я хочу добиться чего-то вроде этой системы, но не смог приблизиться к решению. Я искал об этом и нашел эту суть на github, но это не помогло мне создать такое расширение с функцией загрузки. ССЫЛКА НА GISTUB GIST
Поэтому мне нужна ваша помощь, чтобы добиться этого. Спасибо за помощь.
🤔 А знаете ли вы, что...
React использует компонентную архитектуру для организации кода.
Я наконец нашел решение для этого.
Поскольку я использую tiptap
с react
и хотел, чтобы пользователи могли писать подписи к изображениям, я решил использовать функцию node view
расширений tiptap
. Я добавил addNodeView
в Tiptap Image extension
, чтобы визуализировать мой компонент (вам нужно расширить расширение Image
. Вы можете прочитать о расширении расширения Tiptap здесь):
addNodeView() {
return ReactNodeViewRenderer(ImageNode);
}
Вы можете прочитать о создании и рендеринге представлений узлов в Tiptap с использованием vue, React, vanilla JS и т. д. в документации Tiptap здесь
На следующем шаге я добавил uploadImageHandler
к существующим атрибутам расширения изображения. Так:
addAttributes() {
return {
...this.parent(),
uploadImageHandler: { default: undefined },
};
}
Поэтому, если вы хотите добавить изображение с помощью editor.commands.setImage
, добавьте к нему функцию обработчика загрузки изображения. И обязательно не добавляйте uploadImageHandler в атрибуты HTML элемента рендеринга. Чтобы сделать это, вы можете сделать что-то вроде этого (код может быть немного другим для вас, потому что я визуализирую HTML, связанный с заголовком):
renderHTML({ HTMLAttributes }) {
return [
'figure',
[
'img',
//This line removed uploadImageHandler from attributes
mergeAttributes(HTMLAttributes, { uploadImageHandler: undefined }),
],
['figcaption', HTMLAttributes.caption],
];
}
В реквизитах компонента рендеринга будет реквизит node
, и вы сможете получить доступ к атрибутам следующим образом:
const { src, alt, caption, uploadImageHandler } = node.attrs;
Затем я добавил useEffect
, чтобы начать загрузку после рендеринга компонента:
useEffect(() => {
//src can be a base64 string. Only upload the image when the src is base64
if (uploadImageHandler && src?.startsWith('data') && !isUploading) {
setIsUploading(true);
uploadImageHandler().then(imgUrl => {
//you can use updateAttributes from the component props
updateAttributes({ src: imgUrl });
setIsUploading(false);
});
}
}, [uploadImageHandler, src, isUploading]);
Мой uploadImageHandler
выглядит так:
const uploadImageHandler = (imgSrc, imgType) => async () => {
const { Image, PreSignedURL } = await getPreSignedUrl(imgType);
await uploadImage({ url: PreSignedURL, image: imgSrc });
return Image;
};
Я передаю эту функцию editor.commands.setImage
вот так:
editor.commands.setImage({
src: reader.result,
uploadImageHandler: uploadImageHandler(reader.result, imageFile.type),
});
Другое решение — выполнить uploadImageHandler
в событии onload
элемента img
. В зависимости от того, что вы хотите, вы можете выбрать одно из этих двух решений. Решение onload
не сильно отличается от решения, которое я объяснил. Я не мог поделиться всеми частями своих кодов, но я думаю, что вы можете реализовать функцию загрузки изображений с частями кодов, которыми я поделился, и тем, что я объяснил. Я надеюсь, что это полезно для вас.