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:
hello with data %d! waited %d. mobile is %s
\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) } } }