fix bug quileditor
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { FC, useEffect, useRef } from 'react'
|
import { FC, useCallback, useEffect, useRef } from 'react'
|
||||||
import Quill from 'quill'
|
import Quill from 'quill'
|
||||||
import VideoBlot, { getEmbedUrl } from './VideoBlot'
|
import VideoBlot, { getEmbedUrl } from './VideoBlot'
|
||||||
import 'quill/dist/quill.snow.css'
|
import 'quill/dist/quill.snow.css'
|
||||||
@@ -27,57 +27,62 @@ const QuillEditor: FC<QuillEditorProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const editorRef = useRef<HTMLDivElement>(null)
|
const editorRef = useRef<HTMLDivElement>(null)
|
||||||
const quillRef = useRef<Quill | null>(null)
|
const quillRef = useRef<Quill | null>(null)
|
||||||
|
const defaultAltTextRef = useRef(defaultAltText)
|
||||||
|
const onChangeRef = useRef(onChange)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!editorRef.current) return
|
defaultAltTextRef.current = defaultAltText || 'تصویر'
|
||||||
|
}, [defaultAltText])
|
||||||
|
|
||||||
// تابع سفارشی برای مدیریت آپلود تصویر
|
useEffect(() => {
|
||||||
const imageHandler = () => {
|
onChangeRef.current = onChange
|
||||||
const input = document.createElement('input')
|
}, [onChange])
|
||||||
input.setAttribute('type', 'file')
|
|
||||||
input.setAttribute('accept', 'image/*')
|
|
||||||
input.click()
|
|
||||||
|
|
||||||
input.onchange = async () => {
|
const imageHandler = useCallback(() => {
|
||||||
const file = input.files?.[0]
|
const input = document.createElement('input')
|
||||||
if (file && quillRef.current) {
|
input.setAttribute('type', 'file')
|
||||||
// درخواست alt text از کاربر
|
input.setAttribute('accept', 'image/*')
|
||||||
const altText = prompt('متن جایگزین (Alt Text) تصویر را وارد کنید:', defaultAltText)
|
input.click()
|
||||||
|
|
||||||
if (altText !== null) { // اگر کاربر Cancel نکرد
|
input.onchange = async () => {
|
||||||
const reader = new FileReader()
|
const file = input.files?.[0]
|
||||||
reader.onload = (e) => {
|
if (file && quillRef.current) {
|
||||||
const imageUrl = e.target?.result as string
|
const altText = prompt('متن جایگزین (Alt Text) تصویر را وارد کنید:', defaultAltTextRef.current)
|
||||||
const range = quillRef.current?.getSelection(true)
|
|
||||||
|
|
||||||
if (range && quillRef.current) {
|
if (altText !== null) {
|
||||||
// درج تصویر
|
const reader = new FileReader()
|
||||||
quillRef.current.insertEmbed(range.index, 'image', imageUrl)
|
reader.onload = (e) => {
|
||||||
|
const imageUrl = e.target?.result as string
|
||||||
|
const range = quillRef.current?.getSelection(true)
|
||||||
|
|
||||||
// اضافه کردن alt text به تصویر
|
if (range && quillRef.current) {
|
||||||
setTimeout(() => {
|
quillRef.current.insertEmbed(range.index, 'image', imageUrl)
|
||||||
const images = quillRef.current?.root.querySelectorAll('img')
|
|
||||||
if (images && images.length > 0) {
|
|
||||||
const lastImage = images[images.length - 1]
|
|
||||||
lastImage.setAttribute('alt', altText || defaultAltText)
|
|
||||||
}
|
|
||||||
|
|
||||||
// فراخوانی onChange برای ذخیره تغییرات
|
setTimeout(() => {
|
||||||
if (quillRef.current) {
|
const images = quillRef.current?.root.querySelectorAll('img')
|
||||||
onChange?.(quillRef.current.root.innerHTML)
|
if (images && images.length > 0) {
|
||||||
}
|
const lastImage = images[images.length - 1]
|
||||||
}, 0)
|
const cleanedAlt = altText.trim()
|
||||||
|
lastImage.setAttribute('alt', cleanedAlt || defaultAltTextRef.current)
|
||||||
|
}
|
||||||
|
|
||||||
quillRef.current.setSelection(range.index + 1)
|
if (quillRef.current) {
|
||||||
}
|
onChangeRef.current?.(quillRef.current.root.innerHTML)
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
quillRef.current.setSelection(range.index + 1)
|
||||||
}
|
}
|
||||||
reader.readAsDataURL(file)
|
|
||||||
}
|
}
|
||||||
|
reader.readAsDataURL(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!editorRef.current || quillRef.current) return
|
||||||
|
|
||||||
// پیکربندی toolbar سفارشی
|
|
||||||
const toolbarOptions = [
|
const toolbarOptions = [
|
||||||
['bold', 'italic', 'underline'],
|
['bold', 'italic', 'underline'],
|
||||||
[{ 'header': 1 }, { 'header': 2 }, { 'header': 3 }],
|
[{ 'header': 1 }, { 'header': 2 }, { 'header': 3 }],
|
||||||
@@ -102,25 +107,28 @@ const QuillEditor: FC<QuillEditorProps> = ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// تنظیم محتوای اولیه
|
|
||||||
if (value) {
|
if (value) {
|
||||||
quill.root.innerHTML = value
|
quill.clipboard.dangerouslyPasteHTML(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// مدیریت تغییرات
|
const handleTextChange = () => {
|
||||||
quill.on('text-change', () => {
|
|
||||||
const html = quill.root.innerHTML
|
const html = quill.root.innerHTML
|
||||||
onChange?.(html)
|
onChangeRef.current?.(html)
|
||||||
})
|
}
|
||||||
|
|
||||||
|
quill.on('text-change', handleTextChange)
|
||||||
|
|
||||||
quillRef.current = quill
|
quillRef.current = quill
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
quill.off('text-change', handleTextChange)
|
||||||
quillRef.current = null
|
quillRef.current = null
|
||||||
|
if (editorRef.current) {
|
||||||
|
editorRef.current.innerHTML = ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [placeholder, defaultAltText])
|
}, [imageHandler, placeholder, value])
|
||||||
|
|
||||||
// بروزرسانی محتوا از خارج
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (quillRef.current && value !== quillRef.current.root.innerHTML) {
|
if (quillRef.current && value !== quillRef.current.root.innerHTML) {
|
||||||
quillRef.current.root.innerHTML = value
|
quillRef.current.root.innerHTML = value
|
||||||
|
|||||||
Reference in New Issue
Block a user