291 lines
7.9 KiB
Go
291 lines
7.9 KiB
Go
package routes
|
|
|
|
import (
|
|
"bytes"
|
|
"embed"
|
|
"fmt"
|
|
"html/template"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"sunshine.industries/some-automoderation/rooms"
|
|
"sunshine.industries/some-automoderation/sessions"
|
|
)
|
|
|
|
const roomPath = "/room/"
|
|
const raiseHandPath = "/rooms/raise/"
|
|
const subscribeRoomPath = "/rooms/subscribe"
|
|
|
|
// registering all routes for page and logic of /room/:roomName
|
|
func registerPageRoutes(
|
|
templateFs *embed.FS,
|
|
sessionSM sessions.SessionManagement,
|
|
roomsM rooms.RoomManager,
|
|
) {
|
|
http.Handle(roomPath, // ending in / captures all following path sections, i.e room name
|
|
authedPageMiddleware(
|
|
sessionSM,
|
|
http.StripPrefix(roomPath, roomPageRoute(templateFs, roomsM))))
|
|
|
|
http.Handle(raiseHandPath, // ending in / captures all following path sections, i.e gesture num
|
|
authedPageMiddleware(
|
|
sessionSM,
|
|
http.StripPrefix(raiseHandPath, raiseGestureHandRoute(roomsM))))
|
|
|
|
http.Handle("/rooms/releaseHand",
|
|
authedPageMiddleware(sessionSM, releaseHandRoute(roomsM)))
|
|
|
|
http.Handle(subscribeRoomPath,
|
|
authedPageMiddleware(
|
|
sessionSM,
|
|
http.StripPrefix(subscribeRoomPath, streamingRoomStates(templateFs, roomsM))))
|
|
|
|
http.HandleFunc("/rooms/preview-templates", roomTemplatesPreview(templateFs))
|
|
}
|
|
|
|
func streamingRoomStates(
|
|
templateFs *embed.FS,
|
|
roomsM rooms.RoomManager,
|
|
) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
r.ParseForm()
|
|
roomName := r.FormValue("roomName")
|
|
defer log.Printf("/rooms/subscribe/%s stream ended\n", roomName)
|
|
|
|
session, found := getContextSession(r.Context())
|
|
if !found {
|
|
log.Printf("/rooms/raiseGesture session not found, should be impossible")
|
|
// TODO return error i guess
|
|
return
|
|
}
|
|
if session.RoomId != roomName {
|
|
// not authorized
|
|
log.Printf("/rooms/streamingRoom got unauth with session.RoomId (%s) != roomName (%s)", session.RoomId, roomName)
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
log.Printf("Starting stream for room %s for %d\n", roomName, session.PersonId)
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
w.Header().Set("Connection", "keep-alive")
|
|
w.Header().Set("Content-Type", "text/event-stream")
|
|
|
|
templFile := "templates/room.gohtml"
|
|
tmpl := template.Must(template.ParseFS(templateFs, templFile))
|
|
|
|
roomStream := roomsM.Subscribe(r.Context(), roomName)
|
|
for room := range roomStream {
|
|
// log.Printf("/rooms/streamingRoom iterating with %+v", room)
|
|
fmt.Fprint(w, "data: ")
|
|
|
|
var buffer bytes.Buffer
|
|
|
|
err := tmpl.ExecuteTemplate(&buffer, "simpleRoomShow", room)
|
|
if err != nil {
|
|
log.Printf("/rooms/subscribe/%s got error on template %s", roomName, err)
|
|
}
|
|
|
|
templateStr := buffer.String()
|
|
templateLine := strings.ReplaceAll(templateStr, "\n", "")
|
|
fmt.Fprint(w, templateLine)
|
|
|
|
fmt.Fprint(w, "\n\n")
|
|
w.(http.Flusher).Flush()
|
|
}
|
|
}
|
|
}
|
|
|
|
// if currently speaking? i guess first lower the hand and then raise new
|
|
func raiseGestureHandRoute(
|
|
roomsM rooms.RoomManager,
|
|
) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
gestureInd, err := strconv.Atoi(r.URL.Path)
|
|
gesture, found := rooms.GestureFromInt(gestureInd)
|
|
if err != nil || !found {
|
|
log.Printf("/rooms/raiseGesture error %s gettin hand symbol index from path %s\n", err, r.URL.Path)
|
|
return
|
|
}
|
|
log.Printf("/rooms/raiseGesture successfully got gesture %d : %s", gesture, gesture.String())
|
|
session, found := getContextSession(r.Context())
|
|
if !found {
|
|
log.Printf("/rooms/raiseGesture session not found, should be impossible")
|
|
// TODO return error i guess
|
|
return
|
|
}
|
|
var outerClosureRoom rooms.Room
|
|
err = roomsM.Update(r.Context(), session.RoomId, func(fromRoom rooms.Room) (toRoom rooms.Room) {
|
|
toRoom = fromRoom.RaiseHand(session.PersonId, gesture)
|
|
outerClosureRoom = toRoom
|
|
return toRoom
|
|
})
|
|
if err != nil {
|
|
log.Printf("/rooms/raiseGesture error saving hand: %s\n", err)
|
|
return
|
|
// TODO return error i guess
|
|
}
|
|
log.Printf(">> i attempt to get room with closure: %+v\n", outerClosureRoom)
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
// then htmx style i'll need to re-render the room, i suppose
|
|
// oh, not really, the SSE should send the updated room state
|
|
}
|
|
}
|
|
|
|
func releaseHandRoute(
|
|
roomsM rooms.RoomManager,
|
|
) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
session, found := getContextSession(r.Context())
|
|
if !found {
|
|
log.Printf("/rooms/releaseHand session not found, should be impossible")
|
|
// TODO return error i guess
|
|
return
|
|
}
|
|
err := roomsM.Update(r.Context(), session.RoomId, func(fromRoom rooms.Room) (toRoom rooms.Room) {
|
|
toRoom = fromRoom
|
|
toRoom.ReleaseHand(session.PersonId)
|
|
return toRoom
|
|
})
|
|
if err != nil {
|
|
log.Printf("/rooms/releaseHand error saving hand: %s\n", err)
|
|
return
|
|
// TODO return error i guess
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
}
|
|
|
|
func roomPageRoute(
|
|
templateFs *embed.FS,
|
|
roomsM rooms.RoomManager,
|
|
) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
roomName := r.URL.Path
|
|
if roomName == "" {
|
|
log.Printf("access to empty room")
|
|
// TODO return error i suppose
|
|
w.Header().Add("HX-Redirect", "/")
|
|
return
|
|
}
|
|
|
|
// check session,
|
|
session, found := getContextSession(r.Context())
|
|
if !found {
|
|
log.Printf("session not found %t", found)
|
|
// TODO here will be rendering of
|
|
// 'create this room' or 'join this room'
|
|
// but yeah, let's just use auth middle that redirects to /
|
|
w.Header().Add("HX-Redirect", "/")
|
|
return
|
|
}
|
|
if session.RoomId != roomName {
|
|
log.Printf("session found %+v, but for wrong room, trying to access %s", session, roomName)
|
|
w.Header().Add("HX-Redirect", "/")
|
|
return
|
|
}
|
|
|
|
room, found, err := roomsM.Get(roomName)
|
|
if err != nil || !found {
|
|
log.Printf("/room room for name %s not found or err: %s / found %s", roomName, err, found)
|
|
// TODO here should be append to error place
|
|
w.Header().Add("HX-Redirect", "/")
|
|
return
|
|
}
|
|
|
|
// now we should have a session for this specific room
|
|
fmt.Printf("all checks for room %s passed with %+v", roomName, session)
|
|
|
|
templFile := "templates/room.gohtml"
|
|
baseFile := "templates/base.gohtml"
|
|
tmpl := template.Must(template.ParseFS(templateFs, templFile, baseFile))
|
|
|
|
type GestureData struct {
|
|
Name string
|
|
Url string
|
|
}
|
|
var gesturesData []GestureData
|
|
for gesture := rooms.ChangeTopic; gesture <= rooms.Meta; gesture++ {
|
|
gesturesData = append(gesturesData, GestureData{
|
|
Name: gesture.String(),
|
|
Url: fmt.Sprintf("%s%d", raiseHandPath, gesture),
|
|
})
|
|
}
|
|
|
|
contentData := struct {
|
|
Room rooms.Room
|
|
Gestures []GestureData
|
|
}{
|
|
Room: room,
|
|
Gestures: gesturesData,
|
|
}
|
|
data := pageData{
|
|
Base: baseData{
|
|
Title: "room-lala-from-base",
|
|
},
|
|
Content: contentData,
|
|
Header: headerData{
|
|
Title: room.Name,
|
|
},
|
|
}
|
|
|
|
err = tmpl.ExecuteTemplate(w, "full-page", data)
|
|
if err != nil {
|
|
log.Printf("/room/%s my error in executing template, huh\n %s", roomName, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func roomTemplatesPreview(
|
|
templateFs *embed.FS,
|
|
) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
type BrickData struct {
|
|
ColorClass template.CSS
|
|
Name string
|
|
}
|
|
|
|
contentData := struct {
|
|
Bricks []BrickData
|
|
}{
|
|
Bricks: []BrickData{
|
|
{
|
|
Name: "expand",
|
|
ColorClass: "--expand-color",
|
|
},
|
|
{
|
|
Name: "probing question",
|
|
ColorClass: "--probing-q-color",
|
|
},
|
|
{
|
|
Name: "change topic",
|
|
ColorClass: "--change-topic-color",
|
|
},
|
|
{
|
|
Name: "clarifying question",
|
|
ColorClass: "--clarifying-q-color",
|
|
},
|
|
{
|
|
Name: "meta",
|
|
ColorClass: "--meta-color",
|
|
},
|
|
},
|
|
}
|
|
|
|
pageData := pageData{
|
|
Header: headerData{Title: "look at the room templates"},
|
|
Content: contentData,
|
|
}
|
|
|
|
baseFile := "templates/base.gohtml"
|
|
tmpl := template.Must(template.ParseFS(templateFs, baseFile, "templates/tableTemplates.gohtml"))
|
|
err := tmpl.ExecuteTemplate(w, "full-page", pageData)
|
|
if err != nil {
|
|
log.Printf("yoyo, error %s", err)
|
|
}
|
|
|
|
}
|
|
}
|