feat: raising hand endpoint

This commit is contained in:
efim 2023-11-12 08:31:42 +00:00
parent 16df084928
commit 34d610a8c8
5 changed files with 122 additions and 7 deletions

View File

@ -30,6 +30,22 @@ func (r *Room)InitMaps() {
} }
} }
// if you have no hand raised - select any hand
// if you are not speaking and have a hand raise - just exchange
// if you are speaking - change nothing
// if nobody is speaking, set this person as a first speaker
func (r *Room) RaiseHand(p PersonId, gesture HandGesture) Room {
if (r.CurrentSpeaker == p) {
// if person already speaking, should first end speaking
return *r
}
r.ParticipantHands[p] = gesture
if r.CurrentSpeaker == PersonId(0) {
r.CurrentSpeaker = p
}
return *r
}
// and how would i organize? // and how would i organize?
// i should have map[HandGesture]ParticipantId as mark. for 'from where to go clockwise if returning a level lover' // i should have map[HandGesture]ParticipantId as mark. for 'from where to go clockwise if returning a level lover'
// now i want methods that for some person raise some hand, so i guess it adds what? to map[ParticipantId]HandGesture // now i want methods that for some person raise some hand, so i guess it adds what? to map[ParticipantId]HandGesture
@ -161,6 +177,13 @@ const (
Meta Meta
) )
func GestureFromInt(num int) (HandGesture, bool) {
if (num >= int(ChangeTopic) && num <= int(Meta)) {
return HandGesture(num), true
}
return HandGesture(0), false
}
// String() method to print the name of the days // String() method to print the name of the days
func (g HandGesture) String() string { func (g HandGesture) String() string {
return [...]string{"Change Topic", "Probing Quesion", "Expand", "Clarifying Quesion", "Meta"}[g] return [...]string{"Change Topic", "Probing Quesion", "Expand", "Clarifying Quesion", "Meta"}[g]

View File

@ -13,6 +13,16 @@ import (
type PersonId int type PersonId int
func (p PersonId) MarshalBinary() ([]byte, error) {
bytes, err := json.Marshal(p)
return bytes, err
}
func (p *PersonId) UnmarshalBinary(data []byte) error {
err := json.Unmarshal(data, p)
return err
}
// TODO move to rooms i guess // TODO move to rooms i guess
func RandomPersonId() PersonId { func RandomPersonId() PersonId {
randInt := rand.Int() randInt := rand.Int()
@ -81,6 +91,7 @@ func (redisRM RedisRM) Update(ctx context.Context, roomName string, f func(fromR
return err return err
} }
savedRoom.InitMaps()
room := f(savedRoom) room := f(savedRoom)
_, err = tx.Pipelined(ctx, func(pipe redis.Pipeliner) error { _, err = tx.Pipelined(ctx, func(pipe redis.Pipeliner) error {

View File

@ -1,12 +1,14 @@
package routes package routes
import ( import (
"context"
"embed" "embed"
"fmt" "fmt"
"html/template" "html/template"
"log" "log"
"math/rand" "math/rand"
"net/http" "net/http"
"strconv"
"time" "time"
"sunshine.industries/some-automoderation/rooms" "sunshine.industries/some-automoderation/rooms"
@ -14,6 +16,7 @@ import (
) )
const roomPath = "/room/" const roomPath = "/room/"
const raiseHandPath = "/rooms/raise/"
// registering all routes for page and logic of /room/:roomName // registering all routes for page and logic of /room/:roomName
func registerPageRoutes( func registerPageRoutes(
@ -23,11 +26,15 @@ func registerPageRoutes(
) { ) {
http.HandleFunc("/rooms/random", streamingBsRoute()) http.HandleFunc("/rooms/random", streamingBsRoute())
http.Handle(roomPath, http.Handle(roomPath, // ending in / captures all following path sections, i.e room name
authedPageMiddleware( authedPageMiddleware(
sessionSM, sessionSM,
http.StripPrefix(roomPath, roomPageRoute(templateFs, roomsM)))) 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 { func streamingBsRoute() http.HandlerFunc {
@ -57,6 +64,44 @@ func streamingBsRoute() http.HandlerFunc {
} }
} }
// 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( func roomPageRoute(
templateFs *embed.FS, templateFs *embed.FS,
roomsM rooms.RoomManager, roomsM rooms.RoomManager,
@ -92,10 +137,24 @@ func roomPageRoute(
templFile := "templates/room.gohtml" templFile := "templates/room.gohtml"
tmpl := template.Must(template.ParseFS(templateFs, templFile)) 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 { pageData := struct {
RoomName string RoomName string
Gestures []GestureData
}{ }{
RoomName: roomName, RoomName: roomName,
Gestures: gesturesData,
} }
err := tmpl.Execute(w, pageData) err := tmpl.Execute(w, pageData)

View File

@ -598,11 +598,20 @@ video {
border-width: 1px; border-width: 1px;
} }
.border-2 {
border-width: 2px;
}
.border-black { .border-black {
--tw-border-opacity: 1; --tw-border-opacity: 1;
border-color: rgb(0 0 0 / var(--tw-border-opacity)); border-color: rgb(0 0 0 / var(--tw-border-opacity));
} }
.border-blue-700 {
--tw-border-opacity: 1;
border-color: rgb(29 78 216 / var(--tw-border-opacity));
}
.bg-amber-400 { .bg-amber-400 {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(251 191 36 / var(--tw-bg-opacity)); background-color: rgb(251 191 36 / var(--tw-bg-opacity));
@ -627,6 +636,11 @@ video {
background-color: rgb(194 65 12 / 0.25); background-color: rgb(194 65 12 / 0.25);
} }
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.p-4 { .p-4 {
padding: 1rem; padding: 1rem;
} }

View File

@ -31,12 +31,12 @@
<![endif]--> <![endif]-->
<div class="h-full w-full grid"> <div class="h-full w-full grid">
<script src="https://unpkg.com/htmx.org/dist/ext/sse.js"></script> <script src="https://unpkg.com/htmx.org/dist/ext/sse.js"></script>
<div id="state-receival" class="bg-blue-300 hidden md:block" <!-- <div id="state-receival" class="bg-blue-300 hidden md:block" -->
hx-ext="sse" sse-connect="/rooms/random" <!-- hx-ext="sse" sse-connect="/rooms/random" -->
> <!-- > -->
<div> yoyo </div> <!-- <div> yoyo </div> -->
<div sse-swap="message"> qweopop </div> <!-- <div sse-swap="message"> qweopop </div> -->
</div> <!-- </div> -->
<!-- should be done with custom event for screen change --> <!-- should be done with custom event for screen change -->
<!-- <div id="state-receival" class="bg-blue-100 md:hidden" --> <!-- <div id="state-receival" class="bg-blue-100 md:hidden" -->
<!-- hx-ext="sse" sse-connect="/rooms/random?mobile=true" --> <!-- hx-ext="sse" sse-connect="/rooms/random?mobile=true" -->
@ -46,6 +46,14 @@
<!-- </div> --> <!-- </div> -->
<div id="controls" class="bg-green-300"> <div id="controls" class="bg-green-300">
koko koko
{{ range .Gestures }}
<button
hx-get="{{ .Url }}"
class="bg-white rounded border-blue-700 border-2"
>
{{ .Name }}
</button>
{{ end }}
</div> </div>
</div> </div>