From f413f22fd0367d0b7c6834e1ac571d2a7856882c Mon Sep 17 00:00:00 2001 From: Haaaan1 Date: Mon, 6 May 2024 23:23:53 +0200 Subject: [PATCH 1/3] Fix enter room logic --- src/components/views/Lobby.tsx | 120 ++++--------------- src/helpers/toastService.js | 2 +- src/styles/views/Lobby.scss | 210 +++++++++++++++------------------ 3 files changed, 118 insertions(+), 214 deletions(-) diff --git a/src/components/views/Lobby.tsx b/src/components/views/Lobby.tsx index c5b5071..3e13ce2 100644 --- a/src/components/views/Lobby.tsx +++ b/src/components/views/Lobby.tsx @@ -13,19 +13,14 @@ import "styles/ui/Popup.scss"; import { MAX_USERNAME_LENGTH, MAX_ROOM_NAME_LENGTH } from "../../constants/constants"; import SockJS from "sockjs-client"; import { over } from "stompjs"; +import { showToast} from "../../helpers/toastService"; const DEFAULT_MAX_PLAYERS = 5; const DEFAULT_MIN_PLAYERS = 2; type PlayerProps = { user: User; }; -type RoomComponentProps = { - room: Room; -}; -type RoomListProps = { - rooms: Room[]; -}; const Player: React.FC = ({ user }) => (
= ({ user }) => (
{user.username}
); -const RoomComponent: React.FC = ({ room }) => ( -
-
- {room.roomPlayersList.map((user) => ( - - ))} -
-
-
{room.theme}
-
- {room.status} -
-
-
-); -const RoomList: React.FC = ({ rooms }) => ( -
- {rooms.map((room) => ( - - ))} -
-); + interface FormFieldProps { label: string; placeholder?: string; @@ -70,37 +41,10 @@ interface FormFieldProps { disabled?: boolean; } -const FormField: React.FC = (props) => { - return ( -
- - props.onChange(e.target.value)} - disabled={props.disabled} - /> -
- ); -}; Player.propTypes = { user: PropTypes.object, }; -const mockRoomPlayers: User[] = [ - - { id: "1", username: "Alice", avatar: "grinning-face-with-sweat", name: "Alice Wonderland", status: "ONLINE", registerDate: new Date("2021-08-01"), birthday: new Date("1990-01-01") }, - { id: "2", username: "Bob", avatar: "grinning-face-with-sweat", name: "Bob Builder", status: "OFFLINE", registerDate: new Date("2021-09-01"), birthday: new Date("1985-02-02") }, - { id: "3", username: "Han", avatar: "grinning-face-with-sweat", name: "Alice Wonderland", status: "ONLINE", registerDate: new Date("2021-08-01"), birthday: new Date("1990-01-01") }, - { id: "4", username: "Li", avatar: "grinning-face-with-sweat", name: "Bob Builder", status: "OFFLINE", registerDate: new Date("2021-09-01"), birthday: new Date("1985-02-02") }, - { id: "5", username: "Liuz", avatar: "grinning-face-with-sweat", name: "Bob Builder", status: "OFFLINE", registerDate: new Date("2021-09-01"), birthday: new Date("1985-02-02") }, - -]; - const avatarList: string[] = [ "angry-face", "angry-face-with-horns", @@ -154,31 +98,6 @@ const avatarList: string[] = [ "flushed-face" ] -const mockRooms: Room[] = [ - { - id: "1", - roomOwnerId: "1", - roomPlayersList: mockRoomPlayers, - theme: "Advanced", - status: "In Game", - maxPlayersNum: 4, - alivePlayersList: mockRoomPlayers, - currentPlayerIndex: 0, - playToOuted: false, - }, - { - id: "2", - roomOwnerId: "2", - roomPlayersList: mockRoomPlayers, - theme: "Food", - status: "Free", - maxPlayersNum: 4, - alivePlayersList: mockRoomPlayers, - currentPlayerIndex: 1, - playToOuted: false, - }, -]; - const Lobby = () => { const navigate = useNavigate(); const roomCreationPopRef = useRef(null); @@ -193,8 +112,6 @@ const Lobby = () => { const [maxRoomPlayers, SetMaxRoomPlayers] = useState(DEFAULT_MIN_PLAYERS); const [roomTheme, setRoomTheme] = useState(""); const stompClientRef = useRef(null); - // const needReloadRooms = useRef(false); - // const RELOAD_TIME = 3000; const logout = async () => { const id = sessionStorage.getItem("id"); @@ -206,7 +123,7 @@ const Lobby = () => { console.log(response); sessionStorage.clear(); } catch (error) { - alert(`Something went wrong during the logout: \n${handleError(error)}`); + showToast("Something went wrong during the logout: \n${handleError(error)}", "error"); } navigate("/login"); }; @@ -230,7 +147,6 @@ const Lobby = () => { } useEffect(() => { - const connectWebSocket = () => { const baseurl = getDomain(); let Sock = new SockJS(`${baseurl}/ws`); @@ -323,7 +239,7 @@ const Lobby = () => { const createRoom = async () => { // if not chrome, alert the user if (!navigator.userAgent.includes("Chrome")) { - alert("Your browser is currently not supported, please use Chrome to play this game!"); + showToast("Your browser is currently not supported, please use Chrome to play this game!","error"); return; } @@ -459,21 +375,27 @@ const Lobby = () => { return rooms.map((Room) => (
{ e.preventDefault(); - + + if(Room.roomPlayersList.length === Room.roomMaxNum) { + showToast("Room is Full, please enter another room!", "error"); + + return; + } + + if(Room.status === "INGAME") { + showToast("Game is already started, please enter another room!", "error"); + + return; + } + const currentId = sessionStorage.getItem("id"); enterRoom(Room.roomId, currentId) .then(() => { - //alert(currentId); - if(Room.roomPlayersList.length===Room.maxPlayersNum) - alert("Room is Full, please enter another room!"); - else if(Room.status==="In Game") - alert("Game is already started, please enter another room!"); - else - navigate(`/rooms/${Room.roomId}/${Room.roomName}`); + navigate(`/rooms/${Room.roomId}/${Room.roomName}`); }) .catch(error => { - console.error(`Something went wrong during the enterRoom: \n${error}`); - alert(`Something went wrong during the enterRoom: \n${error}`); + console.error(`Something went wrong during the enterRoom: \n${error}\\`); + showToast("Something went wrong during the enterRoom: \n${error}"); }); }}> @@ -490,7 +412,7 @@ const Lobby = () => {
{Room.theme}
{Room.status} diff --git a/src/helpers/toastService.js b/src/helpers/toastService.js index 90ecc15..400420f 100644 --- a/src/helpers/toastService.js +++ b/src/helpers/toastService.js @@ -4,6 +4,6 @@ import { DEFAULT_TIMEOUT } from "../constants/constants" export function showToast(message, type = "info", duration = DEFAULT_TIMEOUT) { toast(message, { type: type, - autoClose: duration, // 设置消息显示的持续时间,单位是毫秒 + autoClose: duration, }); } \ No newline at end of file diff --git a/src/styles/views/Lobby.scss b/src/styles/views/Lobby.scss index fab7a4d..c2dee16 100644 --- a/src/styles/views/Lobby.scss +++ b/src/styles/views/Lobby.scss @@ -17,27 +17,27 @@ align-items: center; box-shadow: $dropShadow; } - &.room-list::-webkit-scrollbar{ - width: 10px; - height: 10px; + &.room-list::-webkit-scrollbar { + width: 10px; + height: 10px; - &-track{ - background: $whiteYellow; - border-radius: 5px; - } + &-track { + background: $whiteYellow; + border-radius: 5px; + } - &-thumb{ - background: $greyBlue; - -webkit-border-radius: 10px; - border-radius: 10px; - } + &-thumb { + background: $greyBlue; + -webkit-border-radius: 10px; + border-radius: 10px; } - &.room-list-wrapper{ - position: absolute; // 使用绝对定位 - right: 3%; // 定位到右边 - top: 10%; // 从顶部留下10%的空间以居中显示 - width: 40%; // 宽度为视口宽度的40% - height: 80%; // 高度为视口高度的80% + } + &.room-list-wrapper { + position: absolute; // Using absolute positioning + right: 3%; // Positioned to the right + top: 10%; // 10% from the top to center + width: 40%; // 40% of the viewport width + height: 80%; // 80% of the viewport height display: flex; flex-direction: column; background-color: $classicYellow; @@ -46,15 +46,15 @@ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); overflow-y: hidden; } - &.room-list{ + &.room-list { display: flex; flex-direction: column; flex-grow: 1; overflow-y: auto; - &.btn-container{ + &.btn-container { all: initial; // avoid the inherited styles - position: relative; // absolute pos relative to the parent - background-color: transparent; // use Btn's color + position: relative; // absolute position relative to the parent + background-color: transparent; // use button's color display: flex; flex-direction: row; align-items: flex-end; @@ -65,7 +65,7 @@ left: 0%; margin-top: 30px; flex-grow: 1; - .create-room-btn{ + .create-room-btn { bottom: 0%; min-width: fit-content; width: 20%; @@ -78,12 +78,12 @@ font-size: 1.3em; background-color: $darkBlue; color: white; - // dont capitalize the text + // don't capitalize the text text-transform: none; // make the text bold font-weight: bolder; } - .reload-room-btn{ + .reload-room-btn { margin-left: 20px; bottom: 0%; min-width: fit-content; @@ -97,7 +97,7 @@ font-size: 1.3em; background-color: $darkBlue; color: white; - // dont capitalize the text + // don't capitalize the text text-transform: none; // make the text bold font-weight: bolder; @@ -118,7 +118,7 @@ margin: 0.5em 0; } } -.room-container{ +.room-container { display: flex; margin-bottom: 20px; background: white; @@ -137,7 +137,7 @@ text-align: center; //overflow: hidden; - .room-header{ + .room-header { margin-left: 10px; flex-shrink: 0; // Allow both children to grow and take up equal space display: flex; @@ -148,34 +148,18 @@ text-align: center; } - - //.room-players { - // width: 70%; - // align-items: flex-start; // Align the players to the start of the flex container - // flex: 1 1 auto; // Allow both children to grow and take up equal space - // display: flex; - // flex-direction: row; // Stack the children of these containers vertically - // //align-items: center; // Center the items horizontally - // justify-content: center; // Center the items vertically - // padding: 10px; - // overflow-x: auto; - // white-space: nowrap; - //} - .room-header { flex-shrink: 0; flex-grow: 0; display: flex; margin-left: 10px; - flex-direction: column; /* 堆叠子元素 */ - align-items: center; /* 水平居中 */ - justify-content: center; /* 垂直居中 */ + flex-direction: column; /* Stack children vertically */ + align-items: center; /* Horizontally center */ + justify-content: center; /* Vertically center */ text-align: center; - padding: 10px; // Align the room details to the end of the flex container + padding: 10px; // Align room details to the end of the flex container } - - .room-footer { display: flex; justify-content: space-between; @@ -185,25 +169,24 @@ .room-theme { font-weight: bold; } - } } .avatar-list { display: flex; - flex-wrap: wrap; // 允许头像列表换行 - justify-content: flex-start; // 头像左对齐 - margin: 0 -10px; // 用于抵消每个头像的外边距,可以根据实际需求调整 + flex-wrap: wrap; // Allow avatar list to wrap + justify-content: flex-start; // Align avatars to the left + margin: 0 -10px; // Offset for each avatar's margin, adjustable as needed .player { - width: 20%; // 四个头像一行,每个占总宽的25% - padding-left: 10%; // 每个头像周围的间距,可以根据实际需求调整 - box-sizing: border-box; // 包括padding在内的宽度计算方式 + width: 20%; // Four avatars per row, each taking 25% of total width + padding-left: 10%; // Padding around each avatar, adjustable as needed + box-sizing: border-box; // Include padding in width calculation i { - display: block; // 确保图标块状显示 - font-size: 3.8rem; // 图标大小 - cursor: pointer; // 鼠标悬停时显示指针 - margin: 10px 0; // 上下间距,可以根据需要调整 + display: block; // Ensure icons are block-level + font-size: 3.8rem; // Icon size + cursor: pointer; // Show pointer on hover + margin: 10px 0; // Vertical spacing, adjustable as needed } } } @@ -216,7 +199,7 @@ width: 40px; height: 40px; border-radius: 50%; - background-color: #D9D9D9; // 默认背景色 + background-color: #D9D9D9; // Default background color } .player-username { @@ -229,16 +212,16 @@ align-items: flex-start; // Align the players to the start of the flex container flex: 1 1 auto; // Allow both children to grow and take up equal space display: flex; - flex-direction: row; // Stack the children of these containers vertically - //align-items: center; // Center the items horizontally - //justify-content: center; // Center the items vertically + flex-direction: row; // Stack children vertically + //align-items: center; // Horizontally center items + //justify-content: center; // Vertically center items padding: 10px; overflow-x: auto; white-space: nowrap; } .status-container { - width: 18%; /* 或者任何固定宽度 */ - display: inline-block; /* 或者 block,取决于你的布局需求 */ + width: 18%; /* Or any fixed width */ + display: inline-block; /* Or block, depending on your layout needs */ } .room-status { padding: 4px; @@ -288,36 +271,36 @@ text-align: center; } -.user-container{ +.user-container { text-align: center; - position: absolute; // 使用绝对定位 - left: 3%; // 定位到zuo边 - top: 10%; // 从顶部留下10%的空间以居中显示 - width: 100px; // 宽度为视口宽度的40% - height: 100px; // 高度为视口高度的80% + position: absolute; // Using absolute positioning + left: 3%; // Positioned to the left + top: 10%; // 10% from the top to center + width: 100px; // 40% of the viewport width + height: 100px; // 80% of the viewport height background: #D9D9D9; border-radius: $borderRadius; } .title-container { - position: absolute; // 使用绝对定位 - left: 15%; // 定位到zuo边 - top: 25%; // 从顶部留下10%的空间以居中显示 - font-size: 15vw; /* 设定容器的字体大小 */ + position: absolute; + left: 15%; + top: 25%; + font-size: 15vw; } .big-title { - /* 绝对定位可能不再需要,取决于布局需求 */ + color: $classicYellow; font-family: "Acme", sans-serif; } .information { position: absolute; - top: 0; /* 顶部对齐 */ - right: 0; /* 右侧对齐 */ - width: 1.5rem; /* 定宽,可以用rem来调整 */ - height: 2rem; /* 定高,保持图标正方形 */ - font-size: 1.5rem; /* 可以根据需要调整 */ + top: 0; + right: 0; + width: 1.5rem; + height: 2rem; + font-size: 1.5rem; font-weight: bold; //display: flex; text-align: center; @@ -325,20 +308,20 @@ color: white; background: $classicYellow; border-radius: $borderRadius; - //padding: 0.25rem; /* 小间距增加点击区域 */ + //padding: 0.25rem; cursor: pointer; } -.intro-popup{ +.intro-popup { height:60%; //width: 500px; - &.btn-container{ + &.btn-container { width: 200px; display: flex; flex-direction: row; justify-content: center; align-items: flex-end; //margin-top: 10%; - Button{ + Button { height: auto; font-size: 1em; padding: 0.6em; @@ -348,17 +331,17 @@ } } } -.intro-cnt{ +.intro-cnt { width: 450px; } -.profile-popup{ +.profile-popup { height:60%; - &.content{ + &.content { display: flex; flex-direction: column; flex-grow: 1; font-size: 1.5em; - .title{ + .title { font-size: 1.5em; margin-bottom: 20px; display: inline; @@ -366,30 +349,30 @@ } .avatar-container { display: flex; - justify-content: center; /* 水平居中 */ + justify-content: center; /* Horizontally center */ margin-bottom: 3rem; } } - &.header-cnt{ + &.header-cnt { display: flex; flex-direction: row; flex-grow: 1; font-size: 2em; - .title{ + .title { font-size: 1.5em; margin-bottom: 20px; display: inline; text-align: center; } } - &.btn-container{ + &.btn-container { display: flex; flex-direction: row; justify-content: center; align-items: flex-end; margin-top: 10%; - Button{ + Button { height: auto; font-size: 1em; padding: 0.6em; @@ -419,17 +402,17 @@ } } -.room-creation-popup{ +.room-creation-popup { height: 60%; - &.content{ + &.content { display: flex; flex-direction: column; flex-grow: 1; font-size: 2em; - .title{ + .title { font-size: 1.5em; margin-bottom: 20px; - display: inline; + display:inline; text-align: center; } input { @@ -444,7 +427,7 @@ color: $textColor; } } - .theme-dropdown{ + .theme-dropdown { position: relative; display: flex; align-items: center; @@ -453,26 +436,26 @@ height: 100px; margin-top: 20px; margin-bottom: 40px; - select{ - appearance: none; - -webkit-appearance: none; - -moz-appearance: none; - background-color: $classicYellow; - text-align: center; - border-radius: 0.75em; - option{ - background-color: $classicYellow; //TODO: firefox not supporting this - outline: none; - text-align: center; - } + select { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + background-color: $classicYellow; + text-align: center; + border-radius: 0.75em; + option { + background-color: $classicYellow; //TODO: firefox not supporting this + outline: none; + text-align: center; + } } } - &.btn-container{ + &.btn-container { display: flex; flex-direction: row; justify-content: center; align-items: flex-end; - Button{ + Button { height: auto; font-size: 1em; padding: 0.6em; @@ -513,4 +496,3 @@ } } - From a5e69bc31dc07e185e018b2a2d367dc03193406f Mon Sep 17 00:00:00 2001 From: Shaochang Tan <478710209@qq.com> Date: Tue, 7 May 2024 23:00:11 +0200 Subject: [PATCH 2/3] Fix one can change his name to empty bug. fix #129 --- src/components/views/Lobby.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/Lobby.tsx b/src/components/views/Lobby.tsx index e75a90e..f1f7639 100644 --- a/src/components/views/Lobby.tsx +++ b/src/components/views/Lobby.tsx @@ -505,7 +505,7 @@ const Lobby = () => { value={username} onChange={(e) => { const inputValue = e.target.value; // 获取输入值 - if (inputValue.length <= MAX_USERNAME_LENGTH) { // 检查输入值的长度 + if (inputValue.length <= MAX_USERNAME_LENGTH && inputValue.length > 0) { // 检查输入值的长度 setUsername(inputValue); // 如果长度小于或等于20,更新状态 } }} From 69c96e43decc59a5d4c6baee98ec5230688c3075 Mon Sep 17 00:00:00 2001 From: Shaochang Tan <478710209@qq.com> Date: Tue, 7 May 2024 23:15:02 +0200 Subject: [PATCH 3/3] disable edit btn when name is empty or not changed --- src/components/views/Lobby.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/views/Lobby.tsx b/src/components/views/Lobby.tsx index f1f7639..1b9b177 100644 --- a/src/components/views/Lobby.tsx +++ b/src/components/views/Lobby.tsx @@ -522,8 +522,10 @@ const Lobby = () => { }}> Cancel -