Feat: enter room: login with link
This commit is contained in:
		| @@ -1,9 +1,13 @@ | |||||||
| {{define "main"}} | {{define "main"}} | ||||||
| 	<!-- user has no username -> login form --> | 	Start of main temp | ||||||
| 	{{ if not . }} | 	{{ if not . }} | ||||||
|  | 		login temp | ||||||
| 		{{template "login"}} | 		{{template "login"}} | ||||||
| 	<!-- user has name but no room id => suggest to create room --> | 	{{ else if ne .LinkLogin "" }} | ||||||
|  | 		got to linklogin | ||||||
|  | 		{{template "linklogin" .LinkLogin}} | ||||||
| 	{{ else if eq .State.RoomID "" }} | 	{{ else if eq .State.RoomID "" }} | ||||||
|  | 		empty state roomid | ||||||
| 		<div id="hello-user"> | 		<div id="hello-user"> | ||||||
| 			<p>Hello {{.State.Username}}</p> | 			<p>Hello {{.State.Username}}</p> | ||||||
| 		</div> | 		</div> | ||||||
| @@ -14,7 +18,7 @@ | |||||||
| 		{{template "roomlist" .List}} | 		{{template "roomlist" .List}} | ||||||
| 		</div> | 		</div> | ||||||
| 	{{else}} | 	{{else}} | ||||||
| 	<!-- instead of having room div; better to replace ancestor completely with room --> | 		else | ||||||
| 		<div id="room"> | 		<div id="room"> | ||||||
| 		{{template "room" .}} | 		{{template "room" .}} | ||||||
| 		</div> | 		</div> | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								components/linklogin.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								components/linklogin.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | {{define "linklogin"}} | ||||||
|  | <div id="logindiv"> | ||||||
|  |   You're about to join room#{{.}}; but first! | ||||||
|  |   <form class="space-y-6" hx-post="/login" hx-target="#ancestor"> | ||||||
|  |       <label For="username" class="block text-sm font-medium leading-6 text-white-900">tell us your username</label> | ||||||
|  |       <div class="mt-2"> | ||||||
|  |         <input id="username" name="username" hx-target="#login_notice" hx-swap="outerHTML" hx-post="/check/name" hx-trigger="input changed delay:400ms" autocomplete="username" required class="block w-full rounded-md border-0 bg-white py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 text-center"/> | ||||||
|  |         <input type="hidden" name="room_id" value={{.}}> | ||||||
|  |       </div> | ||||||
|  |   <div id="login_notice">this name looks available</div> | ||||||
|  |     <div> | ||||||
|  |       <button type="submit" class="flex w-full 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">Sign in</button> | ||||||
|  |     </div> | ||||||
|  |   </form> | ||||||
|  | </div> | ||||||
|  | {{end}} | ||||||
| @@ -60,6 +60,7 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | |||||||
| 		abortWithError(w, msg) | 		abortWithError(w, msg) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | 	roomID := r.PostFormValue("room_id") | ||||||
| 	// make sure username does not exists | 	// make sure username does not exists | ||||||
| 	cleanName := utils.RemoveSpacesFromStr(username) | 	cleanName := utils.RemoveSpacesFromStr(username) | ||||||
| 	// login user | 	// login user | ||||||
| @@ -75,12 +76,29 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | |||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// state := models.MakeTestState(cleanName) |  | ||||||
| 	// state.State.Username = cleanName |  | ||||||
| 	userstate := models.InitState(cleanName) | 	userstate := models.InitState(cleanName) | ||||||
| 	fi := &models.FullInfo{ | 	fi := &models.FullInfo{ | ||||||
| 		State: userstate, | 		State: userstate, | ||||||
| 	} | 	} | ||||||
|  | 	// check if room_id provided and exists | ||||||
|  | 	if roomID != "" { | ||||||
|  | 		log.Debug("got room_id in login", "room_id", roomID) | ||||||
|  | 		room, err := getRoomByID(roomID) | ||||||
|  | 		if err != nil { | ||||||
|  | 			abortWithError(w, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		room.PlayerList = append(room.PlayerList, fi.State.Username) | ||||||
|  | 		fi.State.RoomID = room.ID | ||||||
|  | 		fi.Room = room | ||||||
|  | 		fi.List = nil | ||||||
|  | 		// save full info instead | ||||||
|  | 		if err := saveFullInfo(fi); err != nil { | ||||||
|  | 			abortWithError(w, err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		log.Debug("no room_id in login") | ||||||
| 		fi.List = listPublicRooms() | 		fi.List = listPublicRooms() | ||||||
| 		// save state to cache | 		// save state to cache | ||||||
| 		if err := saveState(cleanName, userstate); err != nil { | 		if err := saveState(cleanName, userstate); err != nil { | ||||||
| @@ -89,6 +107,7 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { | |||||||
| 			abortWithError(w, err.Error()) | 			abortWithError(w, err.Error()) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 	tmpl.ExecuteTemplate(w, "base", fi) | 	tmpl.ExecuteTemplate(w, "base", fi) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										110
									
								
								handlers/game.go
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								handlers/game.go
									
									
									
									
									
								
							| @@ -49,55 +49,52 @@ func HandleCreateRoom(w http.ResponseWriter, r *http.Request) { | |||||||
| 	tmpl.ExecuteTemplate(w, "base", fi) | 	tmpl.ExecuteTemplate(w, "base", fi) | ||||||
| } | } | ||||||
|  |  | ||||||
| func HandleRoomEnter(w http.ResponseWriter, r *http.Request) { | // DEPRACATED: duplication of HandleJoinRoom | ||||||
| 	// parse payload | // func HandleRoomEnter(w http.ResponseWriter, r *http.Request) { | ||||||
| 	roomID := r.URL.Query().Get("id") | // 	// parse payload | ||||||
| 	if roomID == "" { | // 	roomID := r.URL.Query().Get("id") | ||||||
| 		// error | // 	if roomID == "" { | ||||||
| 		return | // 		msg := "room id not provided" | ||||||
| 	} | // 		log.Error(msg) | ||||||
| 	// create a room | // 		abortWithError(w, msg) | ||||||
| 	room, err := getRoomByID(roomID) | // 		return | ||||||
| 	if err != nil { | // 	} | ||||||
| 		msg := "failed to find the room" | // 	tmpl, err := template.ParseGlob("components/*.html") | ||||||
| 		log.Error(msg, "error", err, "room_id", roomID) | // 	if err != nil { | ||||||
| 		abortWithError(w, msg) | // 		abortWithError(w, err.Error()) | ||||||
| 		return | // 		return | ||||||
| 	} | // 	} | ||||||
| 	ctx := context.WithValue(r.Context(), "current_room", room.ID) | // 	// create a room | ||||||
| 	ctx, err = updateRoomInSession(ctx, room.ID) | // 	room, err := getRoomByID(roomID) | ||||||
| 	if err != nil { | // 	if err != nil { | ||||||
| 		msg := "failed to set current room to session" | // 		msg := "failed to find the room" | ||||||
| 		log.Error(msg, "error", err) | // 		log.Error(msg, "error", err, "room_id", roomID) | ||||||
| 		abortWithError(w, msg) | // 		abortWithError(w, msg) | ||||||
| 		return | // 		return | ||||||
| 	} | // 	} | ||||||
| 	state, err := getStateByCtx(ctx) | // 	state, err := getStateByCtx(r.Context()) | ||||||
| 	if err != nil { | // 	// INFO: if non-loggined user join: prompt to login | ||||||
| 		log.Error("failed to get state", "error", err) | // 	if err != nil { | ||||||
| 		abortWithError(w, err.Error()) | // 		log.Error("failed to get state", "error", err) | ||||||
| 		return | // 		// abortWithError(w, err.Error()) | ||||||
| 	} | // 		tmpl.ExecuteTemplate(w, "login", nil) | ||||||
| 	state.RoomID = room.ID | // 		return | ||||||
| 	// update state | // 	} | ||||||
| 	if err := saveStateByCtx(ctx, state); err != nil { | // 	state.RoomID = room.ID | ||||||
| 		log.Error("failed to update state", "error", err) | // 	// update state | ||||||
| 		abortWithError(w, err.Error()) | // 	if err := saveStateByCtx(r.Context(), state); err != nil { | ||||||
| 		return | // 		log.Error("failed to update state", "error", err) | ||||||
| 	} | // 		abortWithError(w, err.Error()) | ||||||
| 	// send msg of created room | // 		return | ||||||
| 	// h.Broker.Notifier <- broker.NotificationEvent{ | // 	} | ||||||
| 	// 	EventName: models.MsgRoomListUpdate, | // 	// send msg of created room | ||||||
| 	// 	Payload:   fmt.Sprintf("%s created a room named %s", r.CreatorName, r.RoomName), | // 	// h.Broker.Notifier <- broker.NotificationEvent{ | ||||||
|  | // 	// 	EventName: models.MsgRoomListUpdate, | ||||||
|  | // 	// 	Payload:   fmt.Sprintf("%s created a room named %s", r.CreatorName, r.RoomName), | ||||||
|  | // 	// } | ||||||
|  | // 	// return html | ||||||
|  | // 	tmpl.ExecuteTemplate(w, "base", room) | ||||||
| // } | // } | ||||||
| 	// return html |  | ||||||
| 	tmpl, err := template.ParseGlob("components/*.html") |  | ||||||
| 	if err != nil { |  | ||||||
| 		abortWithError(w, err.Error()) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	tmpl.ExecuteTemplate(w, "base", room) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func HandleJoinTeam(w http.ResponseWriter, r *http.Request) { | func HandleJoinTeam(w http.ResponseWriter, r *http.Request) { | ||||||
| 	r.ParseForm() | 	r.ParseForm() | ||||||
| @@ -239,11 +236,20 @@ func HandleJoinRoom(w http.ResponseWriter, r *http.Request) { | |||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	fi, err := getFullInfoByCtx(r.Context()) | 	tmpl, err := template.ParseGlob("components/*.html") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | 	fi, err := getFullInfoByCtx(r.Context()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// INFO: if non-loggined user join: prompt to login | ||||||
|  | 		fi = &models.FullInfo{} | ||||||
|  | 		fi.LinkLogin = roomID | ||||||
|  | 		tmpl.ExecuteTemplate(w, "base", fi) | ||||||
|  | 		// abortWithError(w, err.Error()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	room.PlayerList = append(room.PlayerList, fi.State.Username) | 	room.PlayerList = append(room.PlayerList, fi.State.Username) | ||||||
| 	fi.State.RoomID = room.ID | 	fi.State.RoomID = room.ID | ||||||
| 	fi.Room = room | 	fi.Room = room | ||||||
| @@ -252,12 +258,6 @@ func HandleJoinRoom(w http.ResponseWriter, r *http.Request) { | |||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// return html |  | ||||||
| 	tmpl, err := template.ParseGlob("components/*.html") |  | ||||||
| 	if err != nil { |  | ||||||
| 		abortWithError(w, err.Error()) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	tmpl.ExecuteTemplate(w, "room", fi) | 	tmpl.ExecuteTemplate(w, "room", fi) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.go
									
									
									
									
									
								
							| @@ -23,7 +23,7 @@ func ListenToRequests(port string) error { | |||||||
| 	mux.HandleFunc("GET /ping", handlers.HandlePing) | 	mux.HandleFunc("GET /ping", handlers.HandlePing) | ||||||
| 	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("POST /join-team", handlers.HandleJoinTeam) | 	mux.HandleFunc("POST /join-team", handlers.HandleJoinTeam) | ||||||
| 	mux.HandleFunc("GET /end-turn", handlers.HandleEndTurn) | 	mux.HandleFunc("GET /end-turn", handlers.HandleEndTurn) | ||||||
| 	mux.HandleFunc("POST /room-create", handlers.HandleCreateRoom) | 	mux.HandleFunc("POST /room-create", handlers.HandleCreateRoom) | ||||||
|   | |||||||
| @@ -245,6 +245,7 @@ type FullInfo struct { | |||||||
| 	State     *UserState | 	State     *UserState | ||||||
| 	Room      *Room | 	Room      *Room | ||||||
| 	List      []*Room | 	List      []*Room | ||||||
|  | 	LinkLogin string // room_id | ||||||
| } | } | ||||||
|  |  | ||||||
| func (f *FullInfo) ExitRoom() *Room { | func (f *FullInfo) ExitRoom() *Room { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder