This commit is contained in:
Team3
2026-06-01 18:37:00 +02:00
parent e7af2b1150
commit cb088c9d2d

View File

@@ -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>