htmgo/examples/chat/pages/chat.$id.go

142 lines
3.1 KiB
Go
Raw Normal View History

2024-10-01 01:32:42 +00:00
package pages
import (
2024-10-01 03:49:03 +00:00
"chat/chat"
2024-10-01 03:08:52 +00:00
"fmt"
"github.com/go-chi/chi/v5"
2024-10-01 01:32:42 +00:00
"github.com/maddalax/htmgo/framework/h"
"github.com/maddalax/htmgo/framework/js"
2024-10-01 17:42:01 +00:00
"time"
2024-10-01 01:32:42 +00:00
)
func ChatRoom(ctx *h.RequestContext) *h.Page {
2024-10-01 03:08:52 +00:00
roomId := chi.URLParam(ctx.Request, "id")
2024-10-01 01:32:42 +00:00
return h.NewPage(
RootPage(
h.Div(
h.JoinExtensions(
h.TriggerChildren(),
h.HxExtension("ws"),
),
2024-10-01 17:09:22 +00:00
2024-10-01 03:08:52 +00:00
h.Attribute("ws-connect", fmt.Sprintf("/ws/chat/%s", roomId)),
2024-10-01 17:09:22 +00:00
h.HxOnWsOpen(
js.ConsoleLog("Connected to chat room"),
),
h.HxOnWsClose(
2024-10-01 17:56:16 +00:00
js.EvalJs(fmt.Sprintf(`
2024-10-01 17:09:22 +00:00
const reason = e.detail.event.reason
if(['invalid room', 'no session'].includes(reason)) {
2024-10-01 17:56:16 +00:00
window.location.href = '/?roomId=%s';
2024-10-01 17:42:01 +00:00
} else if(e.detail.event.code === 1011) {
window.location.reload()
2024-10-01 17:09:22 +00:00
} else {
2024-10-01 17:42:01 +00:00
console.error('Connection closed:', e.detail.event)
2024-10-01 17:09:22 +00:00
}
2024-10-01 17:56:16 +00:00
`, roomId)),
2024-10-01 17:09:22 +00:00
),
2024-10-01 03:49:03 +00:00
h.Class("flex flex-row min-h-screen bg-neutral-100"),
2024-10-01 03:08:52 +00:00
// Sidebar for connected users
UserSidebar(),
2024-10-01 01:32:42 +00:00
h.Div(
2024-10-01 17:42:01 +00:00
h.Class("flex flex-col flex-grow bg-white rounded p-4"),
// Room name at the top, fixed
CachedRoomHeader(ctx),
// Padding to push chat content below the fixed room name
h.Div(h.Class("pt-[50px]")),
2024-10-01 03:08:52 +00:00
2024-10-01 17:09:22 +00:00
h.HxAfterWsMessage(
js.EvalJsOnSibling("#messages",
`element.scrollTop = element.scrollHeight;`),
),
2024-10-01 03:08:52 +00:00
// Chat Messages
2024-10-01 01:32:42 +00:00
h.Div(
h.Id("messages"),
2024-10-01 17:42:01 +00:00
h.Class("flex flex-col gap-4 overflow-auto grow w-full"),
2024-10-01 03:08:52 +00:00
),
// Chat Input at the bottom
h.Div(
h.Class("mt-auto"),
2024-10-01 17:42:01 +00:00
Form(),
2024-10-01 01:32:42 +00:00
),
),
),
),
)
}
2024-10-01 17:42:01 +00:00
var CachedRoomHeader = h.CachedT(time.Hour, func(ctx *h.RequestContext) *h.Element {
return roomNameHeader(ctx)
})
func roomNameHeader(ctx *h.RequestContext) *h.Element {
roomId := chi.URLParam(ctx.Request, "id")
service := chat.NewService(ctx.ServiceLocator())
room, err := service.GetRoom(roomId)
if err != nil {
return h.Div()
}
return h.Div(
h.Class("bg-neutral-700 text-white p-3 shadow-sm w-full fixed top-0 left-0 flex justify-center z-10"),
h.H2F(room.Name, h.Class("text-lg font-bold")),
2024-10-01 17:56:16 +00:00
h.Div(
h.Class("absolute right-5 top-3 cursor-pointer"),
h.Text("Share"),
h.OnClick(
js.EvalJs(`
alert("Share this url with your friends:\n " + window.location.href)
`),
),
),
2024-10-01 17:42:01 +00:00
)
}
2024-10-01 03:08:52 +00:00
func UserSidebar() *h.Element {
return h.Div(
2024-10-01 17:42:01 +00:00
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.H3F("Connected Users", h.Class("text-lg font-bold")),
chat.ConnectedUsers(""),
),
h.A(
h.Class("cursor-pointer"),
h.Href("/"),
h.Text("Leave Room"),
),
2024-10-01 03:08:52 +00:00
)
}
2024-10-01 01:32:42 +00:00
func MessageInput() *h.Element {
return h.Input("text",
h.Id("message-input"),
h.Required(),
2024-10-01 17:42:01 +00:00
h.Class("p-4 rounded-md border border-slate-200 w-full focus:outline-none focus:ring focus:ring-slate-200"),
2024-10-01 01:32:42 +00:00
h.Name("message"),
2024-10-01 17:42:01 +00:00
h.MaxLength(1000),
2024-10-01 03:08:52 +00:00
h.Placeholder("Type a message..."),
2024-10-01 17:09:22 +00:00
h.HxAfterWsSend(
2024-10-01 01:32:42 +00:00
js.SetValue(""),
),
)
}
2024-10-01 17:42:01 +00:00
func Form() *h.Element {
2024-10-01 01:32:42 +00:00
return h.Div(
2024-10-01 03:08:52 +00:00
h.Class("flex gap-4 items-center"),
2024-10-01 01:32:42 +00:00
h.Form(
h.Attribute("ws-send", ""),
2024-10-01 03:08:52 +00:00
h.Class("flex flex-grow"),
2024-10-01 01:32:42 +00:00
MessageInput(),
),
)
}