Enha: state to hold room_id instead of whole room
This commit is contained in:
		| @@ -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> | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.sum
									
									
									
									
									
								
							| @@ -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= |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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) |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								main.go
									
									
									
									
									
								
							| @@ -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) | ||||||
|   | |||||||
| @@ -1,6 +1,10 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import "time" | import ( | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/rs/xid" | ||||||
|  | ) | ||||||
|  |  | ||||||
| type WordColor string | type WordColor string | ||||||
|  |  | ||||||
| @@ -30,7 +34,7 @@ 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"` | ||||||
| @@ -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 | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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,16 +75,20 @@ 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, | ||||||
|  | 		RoomID:   "test-id", | ||||||
|  | 	} | ||||||
|  | 	return &FullInfo{ | ||||||
|  | 		State: us, | ||||||
| 		Room:  room, | 		Room:  room, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder