Feat: end turn endpoint

This commit is contained in:
Grail Finder
2025-05-08 20:04:09 +03:00
parent 3cc2ecb93d
commit 8baf03595e
7 changed files with 51 additions and 6 deletions

View File

@ -1,6 +1,7 @@
{{define "room"}} {{define "room"}}
<div id="hello-user"> <div id="hello-user">
<p>Hello {{.State.Username}};</p> <p>Hello {{.State.Username}};</p>
<p>Turn of the {{.Room.TeamTurn}} team</p>
<p> <p>
{{if eq .State.Team ""}} {{if eq .State.Team ""}}
join the team! join the team!
@ -26,4 +27,7 @@
<div id="cardtable"> <div id="cardtable">
{{template "cardtable" .Room}} {{template "cardtable" .Room}}
</div> </div>
<div>
<button hx-get="/end-turn" hx-target="#room" class="bg-amber-100 text-black px-4 py-2 rounded">End Turn</button>
</div>
{{end}} {{end}}

View File

@ -70,9 +70,9 @@ func saveStateByCtx(ctx context.Context, state *models.UserState) error {
return saveState(username, state) return saveState(username, state)
} }
func saveFullInfoByUsername(username string, fi *models.FullInfo) error { func saveFullInfo(fi *models.FullInfo) error {
// INFO: unfortunately working no transactions; so case are possible where first object is updated but the second is not // INFO: unfortunately working no transactions; so case are possible where first object is updated but the second is not
if err := saveState(username, fi.State); err != nil { if err := saveState(fi.State.Username, fi.State); err != nil {
return err return err
} }
if err := saveRoom(fi.Room); err != nil { if err := saveRoom(fi.Room); err != nil {
@ -194,7 +194,7 @@ func joinTeam(ctx context.Context, role, team string) (*models.FullInfo, error)
err := errors.New("uknown role:" + role) err := errors.New("uknown role:" + role)
return nil, err return nil, err
} }
if err := saveFullInfoByUsername(fi.State.Username, fi); err != nil { if err := saveFullInfo(fi); err != nil {
return nil, err return nil, err
} }
return fi, nil return fi, nil

View File

@ -76,7 +76,7 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) {
state.State.Username = cleanName state.State.Username = cleanName
// save state to cache // save state to cache
// if err := saveState(cleanName, state.State); err != nil { // if err := saveState(cleanName, state.State); err != nil {
if err := saveFullInfoByUsername(cleanName, state); err != nil { if err := saveFullInfo(state); err != nil {
log.Error("failed to save state", "error", err) log.Error("failed to save state", "error", err)
abortWithError(w, err.Error()) abortWithError(w, err.Error())
return return
@ -144,8 +144,8 @@ func cacheSetSession(key string, session *models.Session) error {
return err return err
} }
memcache.Set(key, sesb) memcache.Set(key, sesb)
// expire in 10 min // TODO: to config
memcache.Expire(key, 10*60) memcache.Expire(key, 60*60)
return nil return nil
} }

View File

@ -2,6 +2,7 @@ package handlers
import ( import (
"context" "context"
"errors"
"golias/models" "golias/models"
"html/template" "html/template"
"net/http" "net/http"
@ -125,3 +126,30 @@ func HandleJoinTeam(w http.ResponseWriter, r *http.Request) {
} }
tmpl.ExecuteTemplate(w, "base", fi) tmpl.ExecuteTemplate(w, "base", fi)
} }
func HandleEndTurn(w http.ResponseWriter, r *http.Request) {
// get username
fi, err := getFullInfoByCtx(r.Context())
if err != nil {
abortWithError(w, err.Error())
return
}
// check if one who pressed it is from the team who has the turn
if fi.Room.TeamTurn != string(fi.State.Team) {
err = errors.New("unexpected team turn:" + fi.Room.TeamTurn)
abortWithError(w, err.Error())
return
}
fi.Room.ChangeTurn()
if err := saveFullInfo(fi); err != nil {
abortWithError(w, err.Error())
return
}
// return html
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
tmpl.ExecuteTemplate(w, "base", fi)
}

View File

@ -24,6 +24,7 @@ func ListenToRequests(port string) error {
mux.HandleFunc("POST /login", handlers.HandleFrontLogin) mux.HandleFunc("POST /login", handlers.HandleFrontLogin)
mux.HandleFunc("GET /room", handlers.HandleRoomEnter) mux.HandleFunc("GET /room", handlers.HandleRoomEnter)
mux.HandleFunc("POST /join-team", handlers.HandleJoinTeam) mux.HandleFunc("POST /join-team", handlers.HandleJoinTeam)
mux.HandleFunc("GET /end-turn", handlers.HandleEndTurn)
//elements //elements
mux.HandleFunc("GET /room/createform", handlers.HandleShowCreateForm) mux.HandleFunc("GET /room/createform", handlers.HandleShowCreateForm)
mux.HandleFunc("GET /room/hideform", handlers.HandleHideCreateForm) mux.HandleFunc("GET /room/hideform", handlers.HandleHideCreateForm)

View File

@ -59,6 +59,17 @@ type Room struct {
RedTurn bool // false is blue turn RedTurn bool // false is blue turn
} }
func (r *Room) ChangeTurn() {
switch r.TeamTurn {
case "blue":
r.TeamTurn = "red"
case "red":
r.TeamTurn = "blue"
default:
r.TeamTurn = "blue"
}
}
type WordCard struct { type WordCard struct {
Word string Word string
Color WordColor Color WordColor

View File

@ -84,6 +84,7 @@ func MakeTestState() *FullInfo {
Cards: cards, Cards: cards,
RedTeam: redTeam, RedTeam: redTeam,
BlueTeam: blueTeam, BlueTeam: blueTeam,
TeamTurn: "blue",
} }
us := &UserState{ us := &UserState{
Username: "test-name", Username: "test-name",