Enha: state to hold room_id instead of whole room

This commit is contained in:
Grail Finder
2025-05-08 10:25:38 +03:00
parent 3ade7310a7
commit b20f7ac6b7
12 changed files with 110 additions and 35 deletions

View File

@ -2,7 +2,7 @@
<!-- Center Panel --> <!-- Center Panel -->
<div class="flex justify-center"> <div class="flex justify-center">
<div class="grid grid-cols-2 sm:grid-cols-5 gap-2"> <div class="grid grid-cols-2 sm:grid-cols-5 gap-2">
{{range .Room.Cards}} {{range .Cards}}
{{template "cardword" .}} {{template "cardword" .}}
{{end}} {{end}}
</div> </div>

View File

@ -1,11 +1,11 @@
{{define "main"}} {{define "main"}}
<!-- user has no username -> login form --> <!-- user has no username -> login form -->
{{ if eq .Username "" }} {{ if not . }}
{{template "login"}} {{template "login"}}
<!-- user has name but no room id => suggest to create room --> <!-- user has name but no room id => suggest to create room -->
{{ else if eq .Room.ID "" }} {{ else if eq .State.RoomID "" }}
<div id="hello-user"> <div id="hello-user">
<p>Hello {{.Username}}</p> <p>Hello {{.State.Username}}</p>
</div> </div>
<div id="create-room" class="create-room-div"> <div id="create-room" class="create-room-div">
<button button id="create-form-btn" type="submit" class="justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" hx-get="/room/createform" hx-swap="outerHTML">SHOW ROOM CREATE FORM</button> <button button id="create-form-btn" type="submit" class="justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" hx-get="/room/createform" hx-swap="outerHTML">SHOW ROOM CREATE FORM</button>

View File

@ -1,6 +1,6 @@
{{define "room"}} {{define "room"}}
<div id="hello-user"> <div id="hello-user">
<p>Hello {{.Username}}</p> <p>Hello {{.State.Username}}</p>
</div> </div>
<hr /> <hr />
<div class="flex justify-center"> <div class="flex justify-center">
@ -11,6 +11,6 @@
</div> </div>
<hr /> <hr />
<div id="cardtable"> <div id="cardtable">
{{template "cardtable" .}} {{template "cardtable" .Room}}
</div> </div>
{{end}} {{end}}

4
go.mod
View File

@ -4,7 +4,5 @@ go 1.24
require ( require (
github.com/BurntSushi/toml v1.5.0 github.com/BurntSushi/toml v1.5.0
honnef.co/go/tools v0.6.1 github.com/rs/xid v1.6.0
) )
require golang.org/x/tools v0.30.0 // indirect

6
go.sum
View File

@ -1,6 +1,4 @@
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=
honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=

View File

@ -8,7 +8,25 @@ import (
) )
func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error) { func createRoom(ctx context.Context, req *models.RoomReq) (*models.Room, error) {
return nil, nil creator, ok := ctx.Value(models.CtxUsernameKey).(string)
if !ok {
err := errors.New("failed to extract user from ctx")
return nil, err
}
room := req.CreateRoom(creator)
if err := saveRoom(room); err != nil {
return nil, err
}
return room, nil
}
func saveRoom(room *models.Room) error {
data, err := json.Marshal(room)
if err != nil {
return err
}
memcache.Set(models.CacheRoomPrefix+room.ID, data)
return nil
} }
func getRoomByID(roomID string) (*models.Room, error) { func getRoomByID(roomID string) (*models.Room, error) {
@ -86,3 +104,19 @@ func getAllNames() []string {
} }
return names return names
} }
func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) {
state, err := getStateByCtx(ctx)
if err != nil {
return nil, err
}
room, err := getRoomByID(state.RoomID)
if err != nil {
return nil, err
}
resp := &models.FullInfo{
State: state,
Room: room,
}
return resp, nil
}

View File

@ -80,9 +80,9 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) {
// } // }
// state := models.InitState(cleanName) // state := models.InitState(cleanName)
state := models.MakeTestState() state := models.MakeTestState()
state.Username = cleanName state.State.Username = cleanName
// save state to cache // save state to cache
saveState(cleanName, state) saveState(cleanName, state.State)
tmpl.ExecuteTemplate(w, "base", state) tmpl.ExecuteTemplate(w, "base", state)
} }

View File

@ -79,3 +79,26 @@ func HandleRoomEnter(w http.ResponseWriter, r *http.Request) {
} }
tmpl.ExecuteTemplate(w, "base", room) tmpl.ExecuteTemplate(w, "base", room)
} }
func HandleJoinTeam(w http.ResponseWriter, r *http.Request) {
// parse payload
team := r.URL.Query().Get("team")
role := r.URL.Query().Get("role")
if team == "" || role == "" {
msg := "missing team or role"
log.Error(msg)
abortWithError(w, msg)
// error
return
}
// get username
// get state
// get room
// return html
tmpl, err := template.ParseGlob("components/*.html")
if err != nil {
abortWithError(w, err.Error())
return
}
tmpl.ExecuteTemplate(w, "base", nil)
}

View File

@ -2,7 +2,6 @@ package handlers
import ( import (
"golias/config" "golias/config"
"golias/models"
"golias/pkg/cache" "golias/pkg/cache"
"html/template" "html/template"
"log/slog" "log/slog"
@ -63,13 +62,8 @@ func HandleHome(w http.ResponseWriter, r *http.Request) {
abortWithError(w, err.Error()) abortWithError(w, err.Error())
return return
} }
userState, _ := getStateByCtx(r.Context()) fi, _ := getFullInfoByCtx(r.Context())
if userState == nil { if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil {
userState = &models.UserState{} log.Error("failed to exec templ;", "error", err, "templ", "base")
} }
// if err != nil {
// abortWithError(w, err.Error())
// return
// }
tmpl.ExecuteTemplate(w, "base", userState)
} }

View File

@ -23,6 +23,7 @@ func ListenToRequests(port string) error {
mux.HandleFunc("GET /", handlers.HandleHome) mux.HandleFunc("GET /", handlers.HandleHome)
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("GET /join-team", handlers.HandleJoinTeam)
//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

@ -1,6 +1,10 @@
package models package models
import "time" import (
"time"
"github.com/rs/xid"
)
type WordColor string type WordColor string
@ -28,10 +32,10 @@ func StrToWordColor(s string) WordColor {
} }
type Room struct { type Room struct {
ID string `json:"id" db:"id"` ID string `json:"id" db:"id"`
CreatedAt time.Time `json:"created_at" db:"created_at"` CreatedAt time.Time `json:"created_at" db:"created_at"`
RoomName string `json:"room_name"` // RoomName string `json:"room_name"`
RoomPass string `json:"room_pass"` RoomPass string `json:"room_pass"`
RoomLink string RoomLink string
CreatorName string `json:"creator_name"` CreatorName string `json:"creator_name"`
PlayerList []string `json:"player_list"` PlayerList []string `json:"player_list"`
@ -70,3 +74,22 @@ type RoomReq struct {
RoomName string `json:"room_name" form:"room_name"` RoomName string `json:"room_name" form:"room_name"`
// GameSettings // GameSettings
} }
func (rr *RoomReq) CreateRoom(creator string) *Room {
roomID := xid.New().String()
return &Room{
// RoomName: ,
RoomPass: rr.RoomPass,
ID: roomID,
CreatedAt: time.Now(),
PlayerList: []string{creator},
CreatorName: creator,
}
}
// ====
type FullInfo struct {
State *UserState
Room *Room
}

View File

@ -42,12 +42,12 @@ func StrToUserRole(s string) UserRole {
type UserState struct { type UserState struct {
Username string Username string
Room Room RoomID string
Team UserTeam Team UserTeam
Role UserRole Role UserRole
} }
func MakeTestState() *UserState { func MakeTestState() *FullInfo {
cards := []WordCard{ cards := []WordCard{
{Word: "hamster", Color: "blue"}, {Word: "hamster", Color: "blue"},
{Word: "child", Color: "red"}, {Word: "child", Color: "red"},
@ -75,17 +75,21 @@ func MakeTestState() *UserState {
{Word: "tomato", Color: "red"}, {Word: "tomato", Color: "red"},
{Word: "cloud", Color: "white"}, {Word: "cloud", Color: "white"},
} }
room := Room{ room := &Room{
ID: "test-id", ID: "test-id",
CreatedAt: time.Now(), CreatedAt: time.Now(),
CreatorName: "test-name", CreatorName: "test-name",
Cards: cards, Cards: cards,
} }
return &UserState{ us := &UserState{
Username: "test-name", Username: "test-name",
Team: UserTeamNone, Team: UserTeamNone,
Role: UserRoleNone, Role: UserRoleNone,
Room: room, RoomID: "test-id",
}
return &FullInfo{
State: us,
Room: room,
} }
} }