some-automoderation/routes/room_page.go

166 lines
4.7 KiB
Go

package routes
import (
"context"
"embed"
"fmt"
"html/template"
"log"
"math/rand"
"net/http"
"strconv"
"time"
"sunshine.industries/some-automoderation/rooms"
"sunshine.industries/some-automoderation/sessions"
)
const roomPath = "/room/"
const raiseHandPath = "/rooms/raise/"
// registering all routes for page and logic of /room/:roomName
func registerPageRoutes(
templateFs *embed.FS,
sessionSM sessions.SessionManagement,
roomsM rooms.RoomManager,
) {
http.HandleFunc("/rooms/random", streamingBsRoute())
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(templateFs, roomsM))))
}
func streamingBsRoute() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
queryParam := r.FormValue("mobile")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("Content-Type", "text/event-stream")
startTime, endTime := 0, 0
for {
select {
case <-r.Context().Done():
log.Printf("canlecced streaming!")
return
default:
log.Printf("another step in streaming bs")
data := "data: <div>hello with data %d! waited %d. mobile is %s</div> \n\n"
startTime = time.Now().Nanosecond()
diff := endTime - startTime
fmt.Fprintf(w, data, rand.Intn(100), diff, queryParam)
w.(http.Flusher).Flush()
time.Sleep(3 * time.Second)
endTime = time.Now().Nanosecond()
}
}
}
}
// if currently speaking? i guess first lower the hand and then raise new
func raiseGestureHandRoute(
templateFs *embed.FS,
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(context.TODO(), 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 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
}
// 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"
tmpl := template.Must(template.ParseFS(templateFs, templFile))
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),
})
}
pageData := struct {
RoomName string
Gestures []GestureData
}{
RoomName: roomName,
Gestures: gesturesData,
}
err := tmpl.Execute(w, pageData)
if err != nil {
log.Printf("/room/%s my error in executing template, huh\n %s", roomName, err)
}
}
}