feat(webui): templates + static assets; SSE broadcast; link cards; link summary endpoint; raw soju client store; UI polish
- Switch UI to Go html/templates and embedded /static (Pico.css-compatible) - Add Server.Broadcast and normalize SSE channel keys to lowercase - Implement /api/linkcard (OG/Twitter) and /api/linksummary (24h cache) - Wire Store into raw soju client for CHATHISTORY LATEST fallback
This commit is contained in:
parent
cbd798dfd5
commit
8a6111aeb5
8 changed files with 537 additions and 293 deletions
|
|
@ -223,10 +223,11 @@ func main() {
|
|||
Password: cfg.Password,
|
||||
Channels: cfg.Channels,
|
||||
BackfillLatest: backfill,
|
||||
Store: st,
|
||||
OnPrivmsg: func(channel, author, text, msgid string, at time.Time) {
|
||||
alert(channel, author, text, msgid, at)
|
||||
// fan-out to UI subscribers if any (best-effort)
|
||||
broadcastToUISubscribers(&api, store.Message{Channel: channel, Author: author, Body: text, Time: at.UTC(), MsgID: msgid})
|
||||
api.Broadcast(strings.ToLower(channel), store.Message{Channel: channel, Author: author, Body: text, Time: at.UTC(), MsgID: msgid})
|
||||
},
|
||||
ConnectedGauge: &metrics.ConnectedGauge,
|
||||
}
|
||||
|
|
@ -292,25 +293,3 @@ func main() {
|
|||
<-ctx.Done()
|
||||
logger.Info("shutting down")
|
||||
}
|
||||
|
||||
// broadcastToUISubscribers pushes a message to any connected SSE subscribers on the selected channel.
|
||||
func broadcastToUISubscribers(api *httpapi.Server, m store.Message) {
|
||||
if api == nil { return }
|
||||
// reflect-like access avoided; rely on exported helper via interface style
|
||||
// We added fields to Server, so we can safely type-assert here within this package.
|
||||
// Iterate subscribers with internal lock via small helper method.
|
||||
type subAccess interface{ Broadcast(channel string, m store.Message) }
|
||||
if b, ok := any(api).(subAccess); ok { b.Broadcast(strings.ToLower(m.Channel), m); return }
|
||||
// Fallback: best effort using unexported fields via a minimal shim function added below
|
||||
broadcastShim(api, m)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func broadcastShim(api *httpapi.Server, m store.Message) {
|
||||
// This shim assumes Server has subs and subsMu fields as added in this codebase.
|
||||
// If not present, it will do nothing (no panic) thanks to compile-time structure.
|
||||
// Since we are in the same module, we can update together.
|
||||
// WARNING: keep in sync with httpapi.Server struct.
|
||||
// Using an internal copy of the logic to avoid import cycles.
|
||||
// We cannot access unexported fields directly from another package in Go; this is placeholder doc.
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue