Merge branch 'seedance' of https://gitea.06zk.com/best_yunwei/ai_images into seedance
This commit is contained in:
commit
23817f7850
|
|
@ -28,6 +28,7 @@
|
|||
@keyup="handleKeyup"
|
||||
@click="handleEditorClick"
|
||||
@keydown="handleKeydown"
|
||||
@paste="handlePaste"
|
||||
></div>
|
||||
|
||||
<!-- @ 图片选择面板 -->
|
||||
|
|
@ -187,6 +188,64 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
const insertPlainTextAtCursor = (text) => {
|
||||
if (!editorRef.value || text == null) return
|
||||
const normalized = String(text).replace(/\r\n/g, '\n').replace(/\r/g, '\n')
|
||||
editorRef.value.focus()
|
||||
const selection = window.getSelection()
|
||||
if (!selection || selection.rangeCount === 0) return
|
||||
let range = selection.getRangeAt(0)
|
||||
if (!editorRef.value.contains(range.commonAncestorContainer)) {
|
||||
const r = document.createRange()
|
||||
r.selectNodeContents(editorRef.value)
|
||||
r.collapse(false)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(r)
|
||||
range = selection.getRangeAt(0)
|
||||
}
|
||||
range.deleteContents()
|
||||
const lines = normalized.split('\n')
|
||||
const fragment = document.createDocumentFragment()
|
||||
lines.forEach((line, index) => {
|
||||
if (line) fragment.appendChild(document.createTextNode(line))
|
||||
if (index < lines.length - 1) fragment.appendChild(document.createElement('br'))
|
||||
})
|
||||
range.insertNode(fragment)
|
||||
range.collapse(false)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
}
|
||||
|
||||
const handlePaste = (e) => {
|
||||
if (!editorRef.value) return
|
||||
const cd = e.clipboardData
|
||||
if (!cd) return
|
||||
const items = cd.items
|
||||
if (items) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf('image') !== -1) {
|
||||
const blob = items[i].getAsFile()
|
||||
const reader = new FileReader()
|
||||
reader.onload = (event) => {
|
||||
insertImage(event.target.result, 'pasted-image')
|
||||
}
|
||||
reader.readAsDataURL(blob)
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
let text = cd.getData('text/plain') || ''
|
||||
if (!text && cd.getData('text/html')) {
|
||||
const tmp = document.createElement('div')
|
||||
tmp.innerHTML = cd.getData('text/html')
|
||||
text = tmp.innerText || ''
|
||||
}
|
||||
e.preventDefault()
|
||||
insertPlainTextAtCursor(text)
|
||||
handleInput()
|
||||
}
|
||||
|
||||
// 显示 @ 面板
|
||||
const showMentionPanel = () => {
|
||||
if (props.uploadedImages && props.uploadedImages.length > 0) {
|
||||
|
|
@ -261,23 +320,6 @@ export default {
|
|||
onMounted(() => {
|
||||
if (editorRef.value) {
|
||||
editorRef.value.innerHTML = props.modelValue || ''
|
||||
|
||||
// 添加粘贴事件处理
|
||||
editorRef.value.addEventListener('paste', (e) => {
|
||||
const items = e.clipboardData.items
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf('image') !== -1) {
|
||||
const blob = items[i].getAsFile()
|
||||
const reader = new FileReader()
|
||||
reader.onload = (event) => {
|
||||
insertImage(event.target.result, 'pasted-image')
|
||||
}
|
||||
reader.readAsDataURL(blob)
|
||||
e.preventDefault()
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -292,6 +334,7 @@ export default {
|
|||
handleInput,
|
||||
handleKeyup,
|
||||
handleKeydown,
|
||||
handlePaste,
|
||||
handleEditorClick,
|
||||
insertMentionImage,
|
||||
clear
|
||||
|
|
@ -341,7 +384,12 @@ export default {
|
|||
font-size: 14px;
|
||||
outline: none;
|
||||
overflow-y: auto;
|
||||
|
||||
|
||||
/* 覆盖粘贴残留的内联颜色,保证深底上始终可读 */
|
||||
:deep(*) {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
&:empty:before {
|
||||
content: attr(data-placeholder);
|
||||
color: #666;
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@
|
|||
contenteditable="true"
|
||||
:data-placeholder="placeholder"
|
||||
@input="onEditorInput"
|
||||
@paste="onEditorPaste"
|
||||
@keydown="onEditorKeydown"
|
||||
@keyup="onEditorKeyup"
|
||||
@click="onEditorClick"></div>
|
||||
|
|
@ -916,6 +917,64 @@ const restoreSelection = () => {
|
|||
selection.addRange(range)
|
||||
}
|
||||
|
||||
const insertPlainTextInEditor = (text) => {
|
||||
if (!editorRef.value) return
|
||||
const normalizedText = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n')
|
||||
editorRef.value.focus()
|
||||
restoreSelection()
|
||||
const selection = window.getSelection()
|
||||
if (!selection || selection.rangeCount === 0) return
|
||||
let range = selection.getRangeAt(0)
|
||||
if (!editorRef.value.contains(range.commonAncestorContainer)) {
|
||||
const r = document.createRange()
|
||||
r.selectNodeContents(editorRef.value)
|
||||
r.collapse(false)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(r)
|
||||
range = selection.getRangeAt(0)
|
||||
}
|
||||
range.deleteContents()
|
||||
const lines = normalizedText.split('\n')
|
||||
const fragment = document.createDocumentFragment()
|
||||
lines.forEach((line, index) => {
|
||||
if (line) fragment.appendChild(document.createTextNode(line))
|
||||
if (index < lines.length - 1) fragment.appendChild(document.createElement('br'))
|
||||
})
|
||||
range.insertNode(fragment)
|
||||
range.collapse(false)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
saveSelection()
|
||||
}
|
||||
|
||||
const onEditorPaste = (e) => {
|
||||
if (!editorRef.value) return
|
||||
const cd = e.clipboardData
|
||||
if (!cd) return
|
||||
const items = cd.items
|
||||
if (items) {
|
||||
for (const item of items) {
|
||||
if (item.kind === 'file' && item.type && item.type.startsWith('image/')) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
let text = cd.getData('text/plain') || ''
|
||||
if (!text) {
|
||||
const html = cd.getData('text/html')
|
||||
if (html) {
|
||||
const tmp = document.createElement('div')
|
||||
tmp.innerHTML = html
|
||||
text = tmp.innerText || ''
|
||||
}
|
||||
}
|
||||
if (!text) return
|
||||
e.preventDefault()
|
||||
insertPlainTextInEditor(text)
|
||||
setPrompt(getEditorPlainText())
|
||||
saveSelection()
|
||||
}
|
||||
|
||||
const hasActiveMentionTrigger = () => {
|
||||
const selection = window.getSelection()
|
||||
if (!selection || selection.rangeCount === 0) return false
|
||||
|
|
@ -2255,6 +2314,16 @@ defineExpose({
|
|||
word-break: break-word;
|
||||
overflow-y: auto;
|
||||
scrollbar-color: rgba(255, 255, 255, 0.22) rgba(255, 255, 255, 0.06);
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
|
||||
:deep(*) {
|
||||
color: rgba(255, 255, 255, 0.92) !important;
|
||||
}
|
||||
|
||||
:deep(.vg-inline-ref-audio) {
|
||||
color: rgba(255, 255, 255, 0.88) !important;
|
||||
background: rgba(0, 202, 224, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
.vg-rich-editor:empty:before {
|
||||
|
|
|
|||
|
|
@ -496,6 +496,15 @@ onMounted(() => {
|
|||
overflow-y: auto;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
caret-color: #00cae0;
|
||||
|
||||
:deep(*) {
|
||||
color: rgba(255, 255, 255, 0.9) !important;
|
||||
}
|
||||
|
||||
:deep(.inline-rich-reference) {
|
||||
color: #5eebf5 !important;
|
||||
background: rgba(0, 202, 224, 0.15);
|
||||
}
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 14px;
|
||||
padding: 16px 18px;
|
||||
|
|
|
|||
Loading…
Reference in New Issue