KI-AGENT: Bildvorschau im Chat authentifiziert laden

This commit is contained in:
2026-05-19 10:55:36 +02:00
parent 26ffc4421a
commit 0ac22d346f

View File

@@ -17,6 +17,7 @@ const matrixMembers = ref([])
const matrixMessageDraft = ref("") const matrixMessageDraft = ref("")
const matrixMessagesViewport = ref(null) const matrixMessagesViewport = ref(null)
const matrixAttachmentInput = ref(null) const matrixAttachmentInput = ref(null)
const matrixAttachmentObjectUrls = ref({})
const roomCreateOpen = ref(false) const roomCreateOpen = ref(false)
const collapsedRoomGroups = ref({}) const collapsedRoomGroups = ref({})
const matrixCallOpen = ref(false) const matrixCallOpen = ref(false)
@@ -56,6 +57,7 @@ let matrixMessagesRequestActive = false
let matrixMembersRequestActive = false let matrixMembersRequestActive = false
let matrixLiveKitRoom = null let matrixLiveKitRoom = null
const matrixCallVideoElements = new Map() const matrixCallVideoElements = new Map()
const matrixAttachmentPreviewRequests = new Set()
const canUseMatrixChat = computed(() => const canUseMatrixChat = computed(() =>
Boolean(status.value?.reachable && status.value?.provisioningConfigured) Boolean(status.value?.reachable && status.value?.provisioningConfigured)
@@ -286,6 +288,7 @@ const mergeMatrixMessages = (incomingMessages) => {
matrixMessages.value = Array.from(byId.values()) matrixMessages.value = Array.from(byId.values())
.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)) .sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0))
loadAttachmentPreviews()
} }
const scrollMessagesToBottom = async () => { const scrollMessagesToBottom = async () => {
@@ -845,6 +848,7 @@ const sendMatrixMessage = async () => {
matrixMessages.value = matrixMessages.value.map((item) => matrixMessages.value = matrixMessages.value.map((item) =>
item.id === optimisticId ? message : item item.id === optimisticId ? message : item
) )
loadAttachmentPreviews()
} catch (error) { } catch (error) {
matrixMessages.value = matrixMessages.value.map((item) => matrixMessages.value = matrixMessages.value.map((item) =>
item.id === optimisticId ? { ...item, pending: false, failed: true } : item item.id === optimisticId ? { ...item, pending: false, failed: true } : item
@@ -967,6 +971,37 @@ const matrixMediaProxyUrl = (attachment) => {
return `/api/communication/matrix/media?${params.toString()}` return `/api/communication/matrix/media?${params.toString()}`
} }
const attachmentObjectUrl = (attachment) =>
attachment?.url ? matrixAttachmentObjectUrls.value[attachment.url] || "" : ""
const ensureAttachmentObjectUrl = async (attachment) => {
if (!attachment?.url || matrixAttachmentObjectUrls.value[attachment.url] || matrixAttachmentPreviewRequests.has(attachment.url)) return
matrixAttachmentPreviewRequests.add(attachment.url)
try {
const blob = await $api(matrixMediaProxyUrl(attachment), {
responseType: "blob"
})
const objectUrl = URL.createObjectURL(blob)
matrixAttachmentObjectUrls.value = {
...matrixAttachmentObjectUrls.value,
[attachment.url]: objectUrl
}
} catch (error) {
// Fällt nur auf den Link zurück; der Chat selbst soll weiter funktionieren.
} finally {
matrixAttachmentPreviewRequests.delete(attachment.url)
}
}
const loadAttachmentPreviews = () => {
for (const message of matrixMessages.value) {
if (message.attachment?.isImage && message.attachment.url) {
ensureAttachmentObjectUrl(message.attachment)
}
}
}
const formatLastUpdated = computed(() => { const formatLastUpdated = computed(() => {
if (!lastUpdated.value) return "Noch nicht aktualisiert" if (!lastUpdated.value) return "Noch nicht aktualisiert"
@@ -990,6 +1025,7 @@ onBeforeUnmount(() => {
stopMatrixAutoRefresh() stopMatrixAutoRefresh()
stopMatrixCallDurationTimer() stopMatrixCallDurationTimer()
leaveMatrixCall() leaveMatrixCall()
Object.values(matrixAttachmentObjectUrls.value).forEach((objectUrl) => URL.revokeObjectURL(objectUrl))
}) })
</script> </script>
@@ -1404,8 +1440,8 @@ onBeforeUnmount(() => {
:class="message.own ? 'border-white/20' : 'border-default'" :class="message.own ? 'border-white/20' : 'border-default'"
> >
<img <img
v-if="message.attachment.isImage && message.attachment.url" v-if="message.attachment.isImage && attachmentObjectUrl(message.attachment)"
:src="matrixMediaProxyUrl(message.attachment)" :src="attachmentObjectUrl(message.attachment)"
:alt="message.attachment.fileName || message.body" :alt="message.attachment.fileName || message.body"
class="max-h-72 w-full object-contain" class="max-h-72 w-full object-contain"
> >