chat semi working
This commit is contained in:
parent
27b5de93ea
commit
5233bbb234
4 changed files with 79 additions and 15 deletions
|
|
@ -33,10 +33,9 @@ func (m *Manager) StartListener() {
|
|||
case event := <-c:
|
||||
switch event.Type {
|
||||
case ws.ConnectedEvent:
|
||||
fmt.Printf("User %s connected\n", event.Id)
|
||||
m.backFill(event.Id, event.RoomId)
|
||||
m.OnConnected(event)
|
||||
case ws.DisconnectedEvent:
|
||||
fmt.Printf("User %s disconnected\n", event.Id)
|
||||
m.OnDisconnected(event)
|
||||
case ws.MessageEvent:
|
||||
m.onMessage(event)
|
||||
}
|
||||
|
|
@ -44,6 +43,38 @@ func (m *Manager) StartListener() {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Manager) OnConnected(e ws.SocketEvent) {
|
||||
fmt.Printf("User %s connected to room %s\n", e.Id, e.RoomId)
|
||||
user, err := m.queries.GetUserBySessionId(context.Background(), e.Id)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.socketManager.BroadcastText(h.Render(ConnectedUsers(user.Name)))
|
||||
m.socketManager.ForEachSocket(e.RoomId, func(conn ws.SocketConnection) {
|
||||
if conn.Id == e.Id {
|
||||
return
|
||||
}
|
||||
user, err := m.queries.GetUserBySessionId(context.Background(), conn.Id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
m.socketManager.SendText(e.Id, h.Render(ConnectedUsers(user.Name)))
|
||||
})
|
||||
|
||||
go m.backFill(e.Id, e.RoomId)
|
||||
}
|
||||
|
||||
func (m *Manager) OnDisconnected(e ws.SocketEvent) {
|
||||
fmt.Printf("User %s disconnected\n", e.Id)
|
||||
user, err := m.queries.GetUserBySessionId(context.Background(), e.Id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
m.socketManager.BroadcastText(h.Render(ConnectedUser(user.Name, true)))
|
||||
}
|
||||
|
||||
func (m *Manager) backFill(socketId string, roomId string) {
|
||||
messages, _ := m.queries.GetLastMessages(context.Background(), db.GetLastMessagesParams{
|
||||
ChatRoomID: roomId,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package chat
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -18,3 +20,26 @@ func MessageRow(message *Message) *h.Element {
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
func ConnectedUsers(username string) *h.Element {
|
||||
return h.Ul(
|
||||
h.Attribute("hx-swap", "none"),
|
||||
h.Attribute("hx-swap-oob", "beforeend"),
|
||||
h.Id("connected-users"),
|
||||
h.Class("flex flex-col gap-2"),
|
||||
// This would be populated dynamically with connected users
|
||||
ConnectedUser(username, false),
|
||||
)
|
||||
}
|
||||
|
||||
func ConnectedUser(username string, remove bool) *h.Element {
|
||||
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(
|
||||
h.Id(id),
|
||||
h.Class("text-slate-700"),
|
||||
h.Text(username),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package pages
|
||||
|
||||
import (
|
||||
"chat/chat"
|
||||
"fmt"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
|
|
@ -18,14 +19,14 @@ func ChatRoom(ctx *h.RequestContext) *h.Page {
|
|||
h.HxExtension("ws"),
|
||||
),
|
||||
h.Attribute("ws-connect", fmt.Sprintf("/ws/chat/%s", roomId)),
|
||||
h.Class("flex flex-row gap-4 min-h-screen bg-neutral-100"),
|
||||
h.Class("flex flex-row min-h-screen bg-neutral-100"),
|
||||
|
||||
// Sidebar for connected users
|
||||
UserSidebar(),
|
||||
|
||||
// Chat Area
|
||||
h.Div(
|
||||
h.Class("flex flex-col flex-grow gap-4 bg-white shadow-md rounded-lg p-4"),
|
||||
h.Class("flex flex-col flex-grow gap-4 bg-white rounded p-4"),
|
||||
|
||||
h.OnEvent("hx-on::ws-after-message",
|
||||
// language=JavaScript
|
||||
|
|
@ -52,15 +53,9 @@ func ChatRoom(ctx *h.RequestContext) *h.Page {
|
|||
|
||||
func UserSidebar() *h.Element {
|
||||
return h.Div(
|
||||
h.Class("w-64 bg-slate-200 p-4 flex flex-col gap-4 rounded-l-lg"),
|
||||
h.Class("w-48 bg-slate-200 p-4 flex flex-col gap-3 rounded-l-lg"),
|
||||
h.H2F("Connected Users", h.Class("text-lg font-bold")),
|
||||
h.Ul(
|
||||
h.Class("flex flex-col gap-2"),
|
||||
// This would be populated dynamically with connected users
|
||||
h.Li(h.Text("User 1"), h.Class("text-slate-700")),
|
||||
h.Li(h.Text("User 2"), h.Class("text-slate-700")),
|
||||
h.Li(h.Text("User 3"), h.Class("text-slate-700")),
|
||||
),
|
||||
chat.ConnectedUsers(""),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,15 @@ func NewSocketManager() *SocketManager {
|
|||
}
|
||||
}
|
||||
|
||||
func (manager *SocketManager) ForEachSocket(roomId string, cb func(conn SocketConnection)) {
|
||||
manager.sockets.Range(func(id string, conn SocketConnection) bool {
|
||||
if conn.RoomId == roomId {
|
||||
cb(conn)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (manager *SocketManager) Listen(listener chan SocketEvent) {
|
||||
if manager.listeners == nil {
|
||||
manager.listeners = make([]chan SocketEvent, 0)
|
||||
|
|
@ -71,10 +80,14 @@ func (manager *SocketManager) Add(roomId string, id string, conn *websocket.Conn
|
|||
Conn: conn,
|
||||
RoomId: roomId,
|
||||
})
|
||||
s, ok := manager.sockets.Load(id)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
manager.dispatch(SocketEvent{
|
||||
Id: id,
|
||||
Id: s.Id,
|
||||
Type: ConnectedEvent,
|
||||
RoomId: roomId,
|
||||
RoomId: s.RoomId,
|
||||
Payload: map[string]any{},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue