Matrix-Chat: Bildnachrichten darstellen

This commit is contained in:
Kai
2026-02-17 18:11:51 +01:00
parent a643b7773e
commit 3d6535098f
4 changed files with 54 additions and 12 deletions

View File

@@ -159,8 +159,10 @@ func (m *MatrixClient) mapEventToMessage(ctx context.Context, ev *event.Event) (
switch ev.Type { switch ev.Type {
case event.EventMessage: case event.EventMessage:
if body, ok := extractBody(ev); ok { if msg, ok := m.extractMessage(ev); ok {
return MatrixMessage{Sender: sender, Body: body, Timestamp: ts}, true msg.Sender = sender
msg.Timestamp = ts
return msg, true
} }
return MatrixMessage{}, false return MatrixMessage{}, false
case event.EventEncrypted: case event.EventEncrypted:
@@ -176,8 +178,10 @@ func (m *MatrixClient) mapEventToMessage(ctx context.Context, ev *event.Event) (
cancel() cancel()
} }
if err == nil && decrypted != nil { if err == nil && decrypted != nil {
if body, ok := extractBody(decrypted); ok { if msg, ok := m.extractMessage(decrypted); ok {
return MatrixMessage{Sender: sender, Body: body, Timestamp: ts}, true msg.Sender = sender
msg.Timestamp = ts
return msg, true
} }
} }
} }
@@ -195,20 +199,46 @@ func (m *MatrixClient) formatTimestamp(tsMillis int64) string {
return time.UnixMilli(tsMillis).In(loc).Format("02.01.2006 15:04") return time.UnixMilli(tsMillis).In(loc).Format("02.01.2006 15:04")
} }
func extractBody(ev *event.Event) (string, bool) { func (m *MatrixClient) extractMessage(ev *event.Event) (MatrixMessage, bool) {
if ev == nil { if ev == nil {
return "", false return MatrixMessage{}, false
} }
_ = ev.Content.ParseRaw(ev.Type) _ = ev.Content.ParseRaw(ev.Type)
msg := ev.Content.AsMessage() msg := ev.Content.AsMessage()
if msg.MsgType != event.MsgText && msg.MsgType != event.MsgNotice { switch msg.MsgType {
return "", false case event.MsgText, event.MsgNotice:
body := strings.TrimSpace(msg.Body)
if body == "" {
return MatrixMessage{}, false
}
return MatrixMessage{Body: body}, true
case event.MsgImage:
imageURL := m.mxcToHTTP(string(msg.URL))
if imageURL == "" {
// Encrypted file attachments need additional media decryption path.
return MatrixMessage{Body: "[Bild konnte nicht direkt dargestellt werden]"}, true
} }
body := strings.TrimSpace(msg.Body) body := strings.TrimSpace(msg.Body)
if body == "" { if body == "" {
return "", false body = "Bild"
} }
return body, true return MatrixMessage{Body: body, ImageURL: imageURL}, true
default:
return MatrixMessage{}, false
}
}
func (m *MatrixClient) mxcToHTTP(mxc string) string {
raw := strings.TrimSpace(mxc)
if raw == "" || !strings.HasPrefix(raw, "mxc://") {
return ""
}
trimmed := strings.TrimPrefix(raw, "mxc://")
parts := strings.SplitN(trimmed, "/", 2)
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return ""
}
return fmt.Sprintf("%s/_matrix/media/v3/download/%s/%s", m.HomeserverURL, url.PathEscape(parts[0]), url.PathEscape(parts[1]))
} }
func shortMatrixSender(sender string) string { func shortMatrixSender(sender string) string {

View File

@@ -190,4 +190,5 @@ type MatrixMessage struct {
Sender string Sender string
Body string Body string
Timestamp string Timestamp string
ImageURL string
} }

View File

@@ -274,6 +274,14 @@ button:hover { background: linear-gradient(180deg, #7cbc19, #5e8a12); }
word-break: break-word; word-break: break-word;
} }
.matrix-image {
display: block;
max-width: 100%;
height: auto;
border-radius: 8px;
border: 1px solid #d7decb;
}
.matrix-card { .matrix-card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@@ -94,6 +94,9 @@
{{range .MatrixMessages}} {{range .MatrixMessages}}
<li> <li>
<div><strong>{{.Sender}}</strong></div> <div><strong>{{.Sender}}</strong></div>
{{if .ImageURL}}
<div><img src="{{.ImageURL}}" alt="{{.Body}}" class="matrix-image" loading="lazy"></div>
{{end}}
<div class="matrix-body">{{.Body}}</div> <div class="matrix-body">{{.Body}}</div>
<div class="muted">{{.Timestamp}}</div> <div class="muted">{{.Timestamp}}</div>
</li> </li>