Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lobby UI updates #178

Merged
merged 15 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/components/ui/CustomNumberInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import "../../styles/ui/CustomNumberInput.scss";

interface CustomNumberInputProps {
min: number;
max: number;
value: number;
onChange: (value: number) => void;
}

const CustomNumberInput: React.FC<CustomNumberInputProps> = ({ min, max, value, onChange }) => {
const handleDecrement = () => {
if (value > min) {
onChange(value - 1);
}
};

const handleIncrement = () => {
if (value < max) {
onChange(value + 1);
}
};

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = parseInt(e.target.value, 10);
if (!isNaN(newValue) && newValue >= min && newValue <= max) {
onChange(newValue);
}
};

return (
<div className="custom-number-input">
<button onClick={handleDecrement} disabled={value <= min}>-</button>
<input
type="number"
value={value}
onChange={handleChange}
readOnly
min={min}
max={max}
/>
<button onClick={handleIncrement} disabled={value >= max}>+</button>
</div>
);
};

export default CustomNumberInput;
45 changes: 24 additions & 21 deletions src/components/views/Lobby.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useCallback, useRef, useEffect, useState } from "react";
import { api } from "helpers/api";
import CustomNumberInput from "components/ui/CustomNumberInput";
import { Button } from "components/ui/Button";
import { throttle } from "lodash";
import { useNavigate } from "react-router-dom";
Expand Down Expand Up @@ -286,7 +287,6 @@ const Lobby = () => {
: changeAvatarPopRef.current.showModal();
};


const toggleInfoPop = () => {
// if the ref is not set, do nothing
if (!infoPopRef.current) {
Expand Down Expand Up @@ -402,21 +402,30 @@ const Lobby = () => {
return rooms.map((Room) => {
const playerSlots = [];

// 生成玩家头像或空白框,总数等于房间最大玩家数
// generate players avatar
for (let i = 0; i < Room.roomMaxNum; i++) {
if (i < Room.roomPlayersList.length) {
const user = Room.roomPlayersList[i];
playerSlots.push(
<div className="player" key={i}>
<i className={`twa twa-${user.avatar}`} style={{ fontSize: "3.8rem" }} />
<i className={`twa twa-${user.avatar}`}
style={{
fontSize: "3.5rem",
marginTop:"5px"
}}
/>
<div className="name">{user.userName}</div>
</div>
);
} else {
// 空白框
// plus avatar
playerSlots.push(
<div className="player" key={i}>

<div className="plus-player" key={i}>
<i className="twa twa-plus" style={{
fontSize: "3rem",
marginTop: "18.5px",
opacity: "0.4"
}} />
</div>
);
}
Expand Down Expand Up @@ -462,11 +471,9 @@ const Lobby = () => {
cursor: "pointer"
}} />
<div className="name">{user.username}</div>
<div className="btn-logout-container">
<Button className="logout-btn" onClick={logout}>Logout</Button>
</div>
</div>
)}
<Button className="logout-btn" onClick={logout}>Logout</Button>
<div className="title-container">
<div className="big-title">Kaeps</div>
<div className="information" onClick={toggleInfoPop}>i</div>
Expand Down Expand Up @@ -500,6 +507,7 @@ const Lobby = () => {
>
Edit
</Button>
<Button className="out" onClick={logout}>Logout</Button>
</>)
}
>
Expand Down Expand Up @@ -585,23 +593,18 @@ const Lobby = () => {
value={roomName}
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_ROOM_NAME_LENGTH) { // 检查输入值的长度
setRoomName(inputValue); // 如果长度小于或等于 MAX_ROOM_NAME_LENGTH,更新状态
if (inputValue.length <= MAX_ROOM_NAME_LENGTH) {
setRoomName(inputValue);
}
}}
/>
<div>Number of Maximum Players: </div>
<input
type="number"
placeholder={`Between ${DEFAULT_MIN_PLAYERS} and ${DEFAULT_MAX_PLAYERS}`}
value={maxRoomPlayers}
onChange={e => {
const value = parseInt(e.target.value);
// console.error("Value:", value);
SetMaxRoomPlayers(value);
}}
<CustomNumberInput
className="custom-number-input"
min={DEFAULT_MIN_PLAYERS}
max={DEFAULT_MAX_PLAYERS}
value={maxRoomPlayers}
onChange={SetMaxRoomPlayers}
/>
<Dropdown
className="theme-dropdown"
Expand Down Expand Up @@ -648,7 +651,7 @@ const Lobby = () => {
<li><strong>Turns:</strong> The game is played in rounds. Each round has one speaker and several challengers. Players alternate roles as the Speaker to ensure fairness.</li>
</ul>
<p>Click <b>GUIDE</b> for more detailed instructions.</p>
<p>Join a room or create one to play with friends!</p>
<p className="important-note">Before you start, please enable your browser&apos;s microphone privacy settings.</p>

</div>
</Popup>
Expand Down
22 changes: 14 additions & 8 deletions src/components/views/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState } from "react";
import { api, handleError } from "helpers/api";
import { api } from "helpers/api";
import User from "models/User";
import {Link, useNavigate} from "react-router-dom";
import { Button } from "components/ui/Button";
import "styles/views/Login.scss";
import BaseContainer from "components/ui/BaseContainer";
import PropTypes from "prop-types";
import { MAX_USERNAME_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { MAX_USERNAME_LENGTH, MAX_PASSWORD_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { showToast} from "../../helpers/toastService";

/*
Expand All @@ -24,7 +24,7 @@ const FormField = (props) => {
placeholder="enter here.."
value={props.value}
type={props.type}
onChange={(e) => props.onChange(e.target.value)}
onChange={(e) => props.onChange(e)}
/>
</div>
);
Expand Down Expand Up @@ -58,7 +58,7 @@ const Login = () => {
showToast("Login successful!", "success");
navigate("/lobby");
} catch (error) {
let message = "An unexpected error occurred during login.";
let message;
if (error.response) {
switch (error.response.status) {
case HTTP_STATUS.NOT_FOUND:
Expand Down Expand Up @@ -87,16 +87,22 @@ const Login = () => {
label="Username"
value={username}
type="text"
onChange={(un: string) => {
if (un.length <= MAX_USERNAME_LENGTH) setUsername(un)
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_USERNAME_LENGTH) {
setUsername(inputValue);
}
}}
/>
<FormField
label="Password"
value={password}
type="password"
onChange={(n: any) => {
if (n.length <= MAX_USERNAME_LENGTH) setPassword(n)
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_PASSWORD_LENGTH) {
setPassword(inputValue);
}
}}
/>
<div className="login button-container">
Expand Down
24 changes: 15 additions & 9 deletions src/components/views/Register.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useState } from "react";
import { api, handleError } from "helpers/api";
import { api } from "helpers/api";
import User from "models/User";
import {Link, useNavigate} from "react-router-dom";
import { Button } from "components/ui/Button";
import "styles/views/Register.scss";
import BaseContainer from "components/ui/BaseContainer";
import PropTypes from "prop-types";
import { MAX_USERNAME_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { MAX_USERNAME_LENGTH, MAX_PASSWORD_LENGTH, HTTP_STATUS } from "../../constants/constants";
import { showToast} from "../../helpers/toastService";
/*
It is possible to add multiple components inside a single file,
Expand All @@ -24,7 +24,7 @@ const FormField = (props) => {
placeholder="enter here.."
value={props.value}
type={props.type}
onChange={(e) => props.onChange(e.target.value)}
onChange={(e) => props.onChange(e)}
/>
</div>
);
Expand Down Expand Up @@ -58,7 +58,7 @@ const Register = () => {
showToast("Register successful!\nWelcome to this guide for newbies!", "success");
navigate("/guide");
} catch (error) {
let message = "An unexpected error occurred during Register.";
let message;
if (error.response) {
switch (error.response.status) {
case HTTP_STATUS.CONFLICT:
Expand All @@ -84,22 +84,28 @@ const Register = () => {
label="Username"
value={username}
type="text"
onChange={(un: string) => {
if (un.length <= MAX_USERNAME_LENGTH) setUsername(un);
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_USERNAME_LENGTH) {
setUsername(inputValue);
}
}}
/>
<FormField
label="Password"
value={password}
type="password"
onChange={(n: any) => {
if (n.length <= MAX_USERNAME_LENGTH) setPassword(n)
onChange={(e) => {
const inputValue = e.target.value.replace(/[^\w\s]/gi, "");
if (inputValue.length <= MAX_PASSWORD_LENGTH) {
setPassword(inputValue);
}
}}
/>
<div className="register button-container">
<Button
disabled={!username || !password ||password.indexOf(" ") !== CHAR_NOT_FOUND || username.indexOf(" ") !== CHAR_NOT_FOUND }
width="75%"
width="100%"
onClick={() => doRegister()}
style={{ color: "black"}}
>
Expand Down
Loading
Loading