Feat: join team
This commit is contained in:
		| @@ -12,6 +12,8 @@ | |||||||
| 	</div> | 	</div> | ||||||
| 	{{else}} | 	{{else}} | ||||||
| 	<!-- user has room id => send him to his room --> | 	<!-- user has room id => send him to his room --> | ||||||
|  | 	<div id="room"> | ||||||
| 	{{template "room" .}} | 	{{template "room" .}} | ||||||
|  | 	</div> | ||||||
| {{end}} | {{end}} | ||||||
| {{end}} | {{end}} | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								components/playerlist.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								components/playerlist.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | {{define "teamlist"}} | ||||||
|  | <div class="playerlist border border-gray-300 rounded-lg p-4"> | ||||||
|  | {{range .}} | ||||||
|  |     <p>{{.}}</p> | ||||||
|  | {{end}} | ||||||
|  | </div> | ||||||
|  | {{end}} | ||||||
| @@ -5,9 +5,15 @@ | |||||||
| <hr /> | <hr /> | ||||||
| <div class="flex justify-center"> | <div class="flex justify-center"> | ||||||
|   <!-- Left Panel --> |   <!-- Left Panel --> | ||||||
|  |   {{template "teamlist" .Room.BlueGuessers}} | ||||||
|  |   {{if eq .State.Team ""}} | ||||||
|   {{template "teampew" "blue"}} |   {{template "teampew" "blue"}} | ||||||
|  |   {{end}} | ||||||
|   <!-- Right Panel --> |   <!-- Right Panel --> | ||||||
|  |   {{if eq .State.Team ""}} | ||||||
|   {{template "teampew" "red"}} |   {{template "teampew" "red"}} | ||||||
|  |   {{end}} | ||||||
|  |   {{template "teamlist" .Room.RedGuessers}} | ||||||
| </div> | </div> | ||||||
| <hr /> | <hr /> | ||||||
| <div id="cardtable"> | <div id="cardtable"> | ||||||
|   | |||||||
| @@ -1,8 +1,7 @@ | |||||||
| {{define "teampew"}} | {{define "teampew"}} | ||||||
| <!-- <div class="w-1/4 p-4 border-r"> --> |  | ||||||
| <div> | <div> | ||||||
| <h2 class="text-xl mb-4">Join {{.}} Team</h2> | <h2 class="text-xl mb-4">Join {{.}} Team</h2> | ||||||
| <form hx-post="/join-team" hx-target="#room-content"> | <form hx-post="/join-team" hx-target="#ancestor"> | ||||||
|     <input type="hidden" name="team" value="{{.}}"> |     <input type="hidden" name="team" value="{{.}}"> | ||||||
|   <div class="mb-1"> |   <div class="mb-1"> | ||||||
|       <button type="submit" name="role" value="guesser" class="w-full bg-{{.}}-500 text-white py-2 px-4 rounded"> |       <button type="submit" name="role" value="guesser" class="w-full bg-{{.}}-500 text-white py-2 px-4 rounded"> | ||||||
|   | |||||||
| @@ -60,6 +60,26 @@ func getStateByCtx(ctx context.Context) (*models.UserState, error) { | |||||||
| 	return us, nil | 	return us, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func saveStateByCtx(ctx context.Context, state *models.UserState) error { | ||||||
|  | 	username, ok := ctx.Value(models.CtxUsernameKey).(string) | ||||||
|  | 	if !ok { | ||||||
|  | 		log.Debug("no username in ctx") | ||||||
|  | 		return errors.New("no username in ctx") | ||||||
|  | 	} | ||||||
|  | 	return saveState(username, state) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func saveFullInfoByUsername(username string, fi *models.FullInfo) error { | ||||||
|  | 	// 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 { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if err := saveRoom(fi.Room); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // cache | // cache | ||||||
|  |  | ||||||
| func saveState(username string, state *models.UserState) error { | func saveState(username string, state *models.UserState) error { | ||||||
|   | |||||||
| @@ -59,7 +59,6 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | |||||||
| 	} | 	} | ||||||
| 	// make sure username does not exists | 	// make sure username does not exists | ||||||
| 	cleanName := utils.RemoveSpacesFromStr(username) | 	cleanName := utils.RemoveSpacesFromStr(username) | ||||||
| 	// TODO: create user in db |  | ||||||
| 	// login user | 	// login user | ||||||
| 	cookie, err := makeCookie(cleanName, r.RemoteAddr) | 	cookie, err := makeCookie(cleanName, r.RemoteAddr) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -73,16 +72,15 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | |||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// session, ok :=r.Context().Value(models.CtxSessionKey).(*models.Session) |  | ||||||
| 	// if !ok{ |  | ||||||
| 	// 	abortWithError(w, "failed to extract session from ctx") |  | ||||||
| 	// 	return |  | ||||||
| 	// } |  | ||||||
| 	// state := models.InitState(cleanName) |  | ||||||
| 	state := models.MakeTestState() | 	state := models.MakeTestState() | ||||||
| 	state.State.Username = cleanName | 	state.State.Username = cleanName | ||||||
| 	// save state to cache | 	// save state to cache | ||||||
| 	saveState(cleanName, state.State) | 	// if err := saveState(cleanName, state.State); err != nil { | ||||||
|  | 	if err := saveFullInfoByUsername(cleanName, state); err != nil { | ||||||
|  | 		log.Error("failed to save state", "error", err) | ||||||
|  | 		abortWithError(w, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	tmpl.ExecuteTemplate(w, "base", state) | 	tmpl.ExecuteTemplate(w, "base", state) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -66,6 +66,19 @@ func HandleRoomEnter(w http.ResponseWriter, r *http.Request) { | |||||||
| 		abortWithError(w, msg) | 		abortWithError(w, msg) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | 	state, err := getStateByCtx(ctx) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Error("failed to get state", "error", err) | ||||||
|  | 		abortWithError(w, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	state.RoomID = room.ID | ||||||
|  | 	// update state | ||||||
|  | 	if err := saveStateByCtx(ctx, state); err != nil { | ||||||
|  | 		log.Error("failed to update state", "error", err) | ||||||
|  | 		abortWithError(w, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	// send msg of created room | 	// send msg of created room | ||||||
| 	// h.Broker.Notifier <- broker.NotificationEvent{ | 	// h.Broker.Notifier <- broker.NotificationEvent{ | ||||||
| 	// 	EventName: models.MsgRoomListUpdate, | 	// 	EventName: models.MsgRoomListUpdate, | ||||||
| @@ -82,23 +95,66 @@ func HandleRoomEnter(w http.ResponseWriter, r *http.Request) { | |||||||
|  |  | ||||||
| func HandleJoinTeam(w http.ResponseWriter, r *http.Request) { | func HandleJoinTeam(w http.ResponseWriter, r *http.Request) { | ||||||
| 	// parse payload | 	// parse payload | ||||||
| 	team := r.URL.Query().Get("team") | 	// team := r.URL.Query().Get("team") | ||||||
| 	role := r.URL.Query().Get("role") | 	// role := r.URL.Query().Get("role") | ||||||
|  | 	r.ParseForm() | ||||||
|  | 	team := r.PostFormValue("team") | ||||||
|  | 	role := r.PostFormValue("role") | ||||||
| 	if team == "" || role == "" { | 	if team == "" || role == "" { | ||||||
| 		msg := "missing team or role" | 		msg := "missing team or role" | ||||||
| 		log.Error(msg) | 		log.Error(msg) | ||||||
| 		abortWithError(w, msg) | 		abortWithError(w, msg) | ||||||
| 		// error |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// get username | 	// get username | ||||||
| 	// get state | 	fi, _ := getFullInfoByCtx(r.Context()) | ||||||
| 	// get room | 	// get room | ||||||
|  | 	if role == "mime" { | ||||||
|  | 		if team == "blue" { | ||||||
|  | 			fi.Room.BlueMime = fi.State.Username | ||||||
|  | 			fi.State.Team = "blue" | ||||||
|  | 			fi.State.Role = "mime" | ||||||
|  | 		} else if team == "red" { | ||||||
|  | 			fi.Room.RedMime = fi.State.Username | ||||||
|  | 			fi.State.Team = "red" | ||||||
|  | 			fi.State.Role = "mime" | ||||||
|  | 		} else { | ||||||
|  | 			msg := "uknown team:" + team | ||||||
|  | 			log.Error(msg) | ||||||
|  | 			abortWithError(w, msg) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} else if role == "guesser" { | ||||||
|  | 		if team == "blue" { | ||||||
|  | 			fi.Room.BlueGuessers = append(fi.Room.BlueGuessers, fi.State.Username) | ||||||
|  | 			fi.State.Team = "red" | ||||||
|  | 			fi.State.Role = "guesser" | ||||||
|  | 		} else if team == "red" { | ||||||
|  | 			fi.Room.RedGuessers = append(fi.Room.RedGuessers, fi.State.Username) | ||||||
|  | 			fi.State.Team = "red" | ||||||
|  | 			fi.State.Role = "guesser" | ||||||
|  | 		} else { | ||||||
|  | 			msg := "uknown team:" + team | ||||||
|  | 			log.Error(msg) | ||||||
|  | 			abortWithError(w, msg) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		msg := "uknown role:" + role | ||||||
|  | 		log.Error(msg) | ||||||
|  | 		abortWithError(w, msg) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if err := saveFullInfoByUsername(fi.State.Username, fi); err != nil { | ||||||
|  | 		log.Error("failed to save state", "error", err) | ||||||
|  | 		abortWithError(w, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	// return html | 	// return html | ||||||
| 	tmpl, err := template.ParseGlob("components/*.html") | 	tmpl, err := template.ParseGlob("components/*.html") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	tmpl.ExecuteTemplate(w, "base", nil) | 	tmpl.ExecuteTemplate(w, "base", fi) | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.go
									
									
									
									
									
								
							| @@ -23,7 +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) | 	mux.HandleFunc("POST /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) | ||||||
|   | |||||||
| @@ -11,11 +11,11 @@ const ( | |||||||
| 	// UserTeam | 	// UserTeam | ||||||
| 	UserTeamBlue = "blue" | 	UserTeamBlue = "blue" | ||||||
| 	UserTeamRed  = "red" | 	UserTeamRed  = "red" | ||||||
| 	UserTeamNone = "none" | 	UserTeamNone = "" | ||||||
| 	//UserRole | 	//UserRole | ||||||
| 	UserRoleMime    = "mime" | 	UserRoleMime    = "mime" | ||||||
| 	UserRoleGuesser = "guesser" | 	UserRoleGuesser = "guesser" | ||||||
| 	UserRoleNone    = "none" | 	UserRoleNone    = "" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func StrToUserTeam(s string) UserTeam { | func StrToUserTeam(s string) UserTeam { | ||||||
| @@ -80,6 +80,8 @@ func MakeTestState() *FullInfo { | |||||||
| 		CreatedAt:    time.Now(), | 		CreatedAt:    time.Now(), | ||||||
| 		CreatorName:  "test-name", | 		CreatorName:  "test-name", | ||||||
| 		Cards:        cards, | 		Cards:        cards, | ||||||
|  | 		RedGuessers:  []string{"Adam", "Eve"}, | ||||||
|  | 		BlueGuessers: []string{"Abel", "Kain"}, | ||||||
| 	} | 	} | ||||||
| 	us := &UserState{ | 	us := &UserState{ | ||||||
| 		Username: "test-name", | 		Username: "test-name", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder