sidebar fixes

This commit is contained in:
maddalax 2024-10-03 11:38:40 -05:00
parent deb87dceed
commit aa6d311fa8
6 changed files with 37 additions and 34 deletions

View file

@ -45,6 +45,27 @@ func (m *Manager) StartListener() {
} }
} }
func (m *Manager) dispatchConnectedUsers(roomId string, predicate func(conn ws.SocketConnection) bool) {
connectedUsers := make([]db.User, 0)
// backfill all existing clients to the connected client
m.socketManager.ForEachSocket(roomId, func(conn ws.SocketConnection) {
if !predicate(conn) {
return
}
user, err := m.queries.GetUserBySessionId(context.Background(), conn.Id)
if err != nil {
return
}
connectedUsers = append(connectedUsers, user)
})
m.socketManager.ForEachSocket(roomId, func(conn ws.SocketConnection) {
m.socketManager.SendText(conn.Id, h.Render(ConnectedUsers(connectedUsers, conn.Id)))
})
}
func (m *Manager) OnConnected(e ws.SocketEvent) { func (m *Manager) OnConnected(e ws.SocketEvent) {
room, _ := m.service.GetRoom(e.RoomId) room, _ := m.service.GetRoom(e.RoomId)
@ -62,26 +83,10 @@ func (m *Manager) OnConnected(e ws.SocketEvent) {
fmt.Printf("User %s connected to %s\n", user.Name, e.RoomId) fmt.Printf("User %s connected to %s\n", user.Name, e.RoomId)
// backfill all existing clients to the connected client m.dispatchConnectedUsers(e.RoomId, func(conn ws.SocketConnection) bool {
m.socketManager.ForEachSocket(e.RoomId, func(conn ws.SocketConnection) { return true
user, err := m.queries.GetUserBySessionId(context.Background(), conn.Id)
if err != nil {
return
}
isMe := conn.Id == e.Id
fmt.Printf("Sending connected user %s to %s\n", user.Name, e.Id)
m.socketManager.SendText(e.Id, h.Render(ConnectedUsers(user.Name, isMe)))
}) })
// send the connected user to all existing clients
m.socketManager.BroadcastText(
e.RoomId,
h.Render(ConnectedUsers(user.Name, false)),
func(conn ws.SocketConnection) bool {
return conn.Id != e.Id
},
)
m.backFill(e.Id, e.RoomId) m.backFill(e.Id, e.RoomId)
} }
@ -95,7 +100,7 @@ func (m *Manager) OnDisconnected(e ws.SocketEvent) {
return return
} }
fmt.Printf("User %s disconnected from %s\n", user.Name, room.ID) fmt.Printf("User %s disconnected from %s\n", user.Name, room.ID)
m.socketManager.BroadcastText(room.ID, h.Render(ConnectedUser(user.Name, true, false)), func(conn ws.SocketConnection) bool { m.dispatchConnectedUsers(e.RoomId, func(conn ws.SocketConnection) bool {
return conn.Id != e.Id return conn.Id != e.Id
}) })
} }

View file

@ -1,6 +1,7 @@
package chat package chat
import ( import (
"chat/internal/db"
"fmt" "fmt"
"github.com/maddalax/htmgo/framework/h" "github.com/maddalax/htmgo/framework/h"
"strings" "strings"
@ -27,22 +28,19 @@ func MessageRow(message *Message) *h.Element {
) )
} }
func ConnectedUsers(username string, isMe bool) *h.Element { func ConnectedUsers(users []db.User, myId string) *h.Element {
return h.Ul( return h.Ul(
h.Attribute("hx-swap", "none"), h.Attribute("hx-swap-oob", "outerHTML"),
h.Attribute("hx-swap-oob", "beforeend"),
h.Id("connected-users"), h.Id("connected-users"),
h.Class("flex flex-col"), h.Class("flex flex-col"),
// This would be populated dynamically with connected users h.List(users, func(user db.User, index int) *h.Element {
ConnectedUser(username, false, isMe), return connectedUser(user.Name, user.SessionID == myId)
}),
) )
} }
func ConnectedUser(username string, remove bool, isMe bool) *h.Element { func connectedUser(username string, isMe bool) *h.Element {
id := fmt.Sprintf("connected-user-%s", strings.ReplaceAll(username, "#", "-")) id := fmt.Sprintf("connected-user-%s", strings.ReplaceAll(username, "#", "-"))
if remove {
return h.Div(h.Id(id), h.Attribute("hx-swap-oob", "delete"))
}
return h.Li( return h.Li(
h.Id(id), h.Id(id),
h.ClassX("truncate text-slate-700", h.ClassMap{ h.ClassX("truncate text-slate-700", h.ClassMap{

View file

@ -2,6 +2,7 @@ package pages
import ( import (
"chat/chat" "chat/chat"
"chat/internal/db"
"chat/partials" "chat/partials"
"fmt" "fmt"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
@ -111,7 +112,7 @@ func UserSidebar() *h.Element {
h.Class("pt-[67px] min-w-48 w-48 bg-neutral-200 p-4 flex flex-col justify-between gap-3 rounded-l-lg"), h.Class("pt-[67px] min-w-48 w-48 bg-neutral-200 p-4 flex flex-col justify-between gap-3 rounded-l-lg"),
h.Div( h.Div(
h.H3F("Connected Users", h.Class("text-lg font-bold")), h.H3F("Connected Users", h.Class("text-lg font-bold")),
chat.ConnectedUsers("", false), chat.ConnectedUsers(make([]db.User, 0), ""),
), ),
h.A( h.A(
h.Class("cursor-pointer"), h.Class("cursor-pointer"),

View file

@ -195,10 +195,8 @@ func (manager *SocketManager) writeTextRaw(writer WriterChan, event string, mess
} else { } else {
data = fmt.Sprintf("data: %s\n\n", message) data = fmt.Sprintf("data: %s\n\n", message)
} }
fmt.Printf("writing to channel:\n")
select { select {
case writer <- data: case writer <- data:
fmt.Println("Sent to the channel")
case <-time.After(timeout): case <-time.After(timeout):
fmt.Printf("could not send %s to channel after %s\n", data, timeout) fmt.Printf("could not send %s to channel after %s\n", data, timeout)
} }

File diff suppressed because one or more lines are too long

View file

@ -55,12 +55,13 @@ function connectEventSource(ele: Element, url: string) {
} }
eventSource.onmessage = function(event) { eventSource.onmessage = function(event) {
const settleInfo = api.makeSettleInfo(ele);
htmx.trigger(ele, "htmx:sseBeforeMessage", {event: event}); htmx.trigger(ele, "htmx:sseBeforeMessage", {event: event});
const response = event.data const response = event.data
const fragment = api.makeFragment(response) as DocumentFragment; const fragment = api.makeFragment(response) as DocumentFragment;
const children = Array.from(fragment.children); const children = Array.from(fragment.children);
for (let child of children) { for (let child of children) {
api.oobSwap(api.getAttributeValue(child, 'hx-swap-oob') || 'true', child, {tasks: []}); api.oobSwap(api.getAttributeValue(child, 'hx-swap-oob') || 'true', child, settleInfo);
// support htmgo eval__ scripts // support htmgo eval__ scripts
if(child.tagName === 'SCRIPT' && child.id.startsWith("__eval")) { if(child.tagName === 'SCRIPT' && child.id.startsWith("__eval")) {
document.body.appendChild(child); document.body.appendChild(child);