update
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { computed, ref, nextTick } from 'vue'
|
||||
import { computed, ref, nextTick, onMounted, onUnmounted } from 'vue'
|
||||
import { marked } from 'marked'
|
||||
import DOMPurify from 'dompurify'
|
||||
import { htmlUrl, chatGuide, fetchProgress, setProgress } from '../api.js'
|
||||
@@ -25,6 +25,12 @@ function onFrameLoad(e) {
|
||||
if (!doc) return
|
||||
injectStyles(doc)
|
||||
setupProgress(doc)
|
||||
// Klicks im iframe blubbern nicht zum Eltern-document → eigener Listener (same-origin)
|
||||
doc.addEventListener('mousedown', onFrameMouseDown)
|
||||
}
|
||||
|
||||
function onFrameMouseDown() {
|
||||
if (chatOpen.value) closeChat()
|
||||
}
|
||||
|
||||
function injectStyles(doc) {
|
||||
@@ -113,6 +119,7 @@ const input = ref('')
|
||||
const loading = ref(false)
|
||||
const messagesEl = ref(null)
|
||||
const inputEl = ref(null)
|
||||
const panelEl = ref(null)
|
||||
|
||||
function openChat() {
|
||||
chatOpen.value = true
|
||||
@@ -125,6 +132,36 @@ function closeChat() {
|
||||
input.value = ''
|
||||
}
|
||||
|
||||
// Klicks außerhalb des iframes (Sidebar, Ränder) — mousedown vermeidet die Open/Close-Race beim FAB
|
||||
function onDocMouseDown(e) {
|
||||
if (!chatOpen.value) return
|
||||
if (panelEl.value && panelEl.value.contains(e.target)) return
|
||||
closeChat()
|
||||
}
|
||||
|
||||
// Enter öffnet den Chat (wenn zu, nicht in Eingabefeld); ESC schließt ihn
|
||||
function onDocKeyDown(e) {
|
||||
if (e.key === 'Escape' && chatOpen.value) {
|
||||
e.preventDefault()
|
||||
closeChat()
|
||||
return
|
||||
}
|
||||
if (e.key !== 'Enter' || chatOpen.value || !props.previewGuide) return
|
||||
const tag = document.activeElement?.tagName
|
||||
if (tag === 'INPUT' || tag === 'TEXTAREA') return
|
||||
e.preventDefault()
|
||||
openChat()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('mousedown', onDocMouseDown, true)
|
||||
document.addEventListener('keydown', onDocKeyDown)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('mousedown', onDocMouseDown, true)
|
||||
document.removeEventListener('keydown', onDocKeyDown)
|
||||
})
|
||||
|
||||
function extractContext() {
|
||||
try {
|
||||
const doc = frameEl.value?.contentDocument
|
||||
@@ -199,7 +236,7 @@ async function send() {
|
||||
|
||||
<button v-if="previewGuide && !chatOpen" class="chat-fab" title="Fragen zum Guide" @click="openChat">💬</button>
|
||||
|
||||
<div v-if="previewGuide && chatOpen" class="chat-panel">
|
||||
<div v-if="previewGuide && chatOpen" ref="panelEl" class="chat-panel">
|
||||
<header class="chat-header">
|
||||
<span>Fragen zum Guide</span>
|
||||
<button class="chat-close" title="Chat beenden" @click="closeChat">×</button>
|
||||
|
||||
Reference in New Issue
Block a user