Skip to content

Commit

Permalink
Merge pull request #337 from ijun17/feature-fe-batch-socket
Browse files Browse the repository at this point in the history
[FE] updatePosition ๋ฐ chatMessage ์ด๋ฒคํŠธ ๋ฐฐ์น˜ ์ ์šฉ ๋ฐ ๋””์ž์ธ ๋ณ€๊ฒฝ
  • Loading branch information
ijun17 authored Dec 25, 2024
2 parents 520f4b1 + bad7250 commit 3e40808
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 63 deletions.
26 changes: 23 additions & 3 deletions FE/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions FE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"type": "module",
"scripts": {
"dev": "vite --host",
"build": "tsc -b && NODE_ENV=production vite build",
"build-dev": "tsc -b && NODE_ENV=development vite build",
"build": "tsc -b && cross-env NODE_ENV=production vite build",
"build-dev": "tsc -b && cross-env NODE_ENV=development vite build",
"lint": "eslint .",
"preview": "vite preview"
},
Expand All @@ -32,6 +32,7 @@
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.3",
"autoprefixer": "^10.4.20",
"cross-env": "^7.0.3",
"eslint": "^9.13.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
Expand All @@ -51,4 +52,4 @@
"public"
]
}
}
}
4 changes: 2 additions & 2 deletions FE/src/api/socket/socketEventTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ type UpdateHostResponse = {
export type SocketDataMap = {
chatMessage: {
request: ChatMessageRequest;
response: ChatMessageResponse;
response: ChatMessageResponse | ChatMessageResponse[];
};
updatePosition: {
request: UpdatePositionRequest;
response: UpdatePositionResponse;
response: UpdatePositionResponse | UpdatePositionResponse[];
};
createRoom: {
request: null;
Expand Down
5 changes: 2 additions & 3 deletions FE/src/components/QuizPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ type Props = {

export const QuizPreview = ({ title, description }: Props) => {
return (
<div className="component-default flex items-center gap-4 p-4 rounded-lg shadow-lg bg-white">
<div className="flex items-center gap-4 p-4 rounded-2xl bg-white">
<div className="flex-shrink-0 w-[100px] h-[80px] overflow-hidden rounded-md shadow-md">
<Lottie animationData={snowMan} loop={true} className="w-full h-full object-cover" />
{/* <img src={sampleQuizImage} alt={title} className="w-full h-full object-cover" /> */}
</div>

<div className="flex flex-col justify-center flex-grow">
<h3 className="text-lg font-bold text-gray-800 truncate">{title}</h3>
<h3 className="text-lg font-bold text-gray-800 line-clamp-3">{title}</h3>
<p className="text-sm text-gray-600 line-clamp-2">{description}</p>
</div>
</div>
Expand Down
37 changes: 14 additions & 23 deletions FE/src/features/game/components/AnswerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
// import Lottie from 'lottie-react';
import lottie from 'lottie-web';
// import AnswerBg from '@/assets/lottie/answer_background.json';
import AnswerBg from '@/assets/lottie/congrats.json';
import { useEffect, useState, useRef } from 'react';
import { useQuizStore } from '../data/store/useQuizStore';
import { usePlayerStore } from '../data/store/usePlayerStore';

type AnswerModalProps = {
isOpen: boolean;
answer: number;
};

const AnswerModal: React.FC<AnswerModalProps> = ({ isOpen, answer }) => {
const AnswerModal: React.FC<AnswerModalProps> = ({ isOpen }) => {
const [countdown, setCountdown] = useState(3);
const currentQuiz = useQuizStore((state) => state.currentQuiz);
const isAnswer = usePlayerStore((state) => state.players.get(state.currentPlayerId)?.isAnswer);
const isAlive = usePlayerStore((state) => state.players.get(state.currentPlayerId)?.isAlive);

useEffect(() => {
if (isOpen) {
Expand Down Expand Up @@ -55,17 +53,7 @@ const AnswerModal: React.FC<AnswerModalProps> = ({ isOpen, answer }) => {
if (!isOpen || countdown <= 0) return null;
return (
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-25 z-50 pointer-events-none">
{/* <Lottie
animationData={AnswerBg}
loop={true}
className="absolute inset-0 w-full h-full object-cover opacity-80 pointer-events-none"
style={{
transform: 'scale(1.15)',
minWidth: '100vw',
minHeight: '100vh'
}}
/> */}
{
{isAnswer && (
<div
ref={effectRef}
className="absolute inset-0 w-full h-full object-cover opacity-80 pointer-events-none"
Expand All @@ -75,13 +63,16 @@ const AnswerModal: React.FC<AnswerModalProps> = ({ isOpen, answer }) => {
minHeight: '100vh'
}}
/>
}
)}

<div className="relative z-10 flex flex-col items-center justify-center text-center space-y-4 p-8">
<h2 className="text-4xl font-bold text-black">์ •๋‹ต ๊ณต๊ฐœ</h2>
<p className="text-4xl text-black" style={{ marginBottom: '4rem' }}>
{currentQuiz?.choiceList.find((e) => e.order == answer)?.content}
</p>
<div className="relative z-10 flex flex-col items-center justify-center text-center space-y-4 p-8 text-6xl animate-popup">
{!isAlive ? (
<p className="text-green-500 [text-shadow:_0_0_4px_white]">์ •๋‹ต ๋ฐœํ‘œ</p>
) : isAnswer ? (
<p className="text-green-500 [text-shadow:_0_0_4px_white]">์ •๋‹ต์ž…๋‹ˆ๋‹ค</p>
) : (
<p className="text-red-500 [text-shadow:_0_0_4px_black]">ํ‹€๋ ธ์Šต๋‹ˆ๋‹ค</p>
)}
</div>
</div>
);
Expand Down
5 changes: 3 additions & 2 deletions FE/src/features/game/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ReactElement, useEffect, useRef, useState } from 'react';
const Chat = () => {
const gameId = useRoomStore((state) => state.gameId);
const currentPlayerId = usePlayerStore((state) => state.currentPlayerId);
const currentPlayerName = usePlayerStore((state) => state.currentPlayerName);
const messages = useChatStore((state) => state.messages);
const [inputValue, setInputValue] = useState('');
const players = usePlayerStore((state) => state.players);
Expand Down Expand Up @@ -128,8 +129,8 @@ const Chat = () => {
onScroll={handleScroll}
>
<div>
<div className="flex justify-center mb-4" key="1">
๐ŸŽ‰ QuizGround์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค ๐ŸŽ‰
<div className="flex justify-center mb-4 text-sm" key="1">
๐ŸŽ‰ {currentPlayerName}๋‹˜ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค ๐ŸŽ‰
</div>
{chatList}
{myMessages.map((e, i) => (
Expand Down
8 changes: 4 additions & 4 deletions FE/src/features/game/components/ParticipantDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ const ParticipantDisplay: React.FC<ParticipantDisplayProps> = ({ gameState }) =>
className="flex justify-between mt-2 pb-2 border-b border-default items-center"
key={player.playerId}
>
<div className="font-bold">{player.emoji + ' ' + player.playerName} </div>
<div className="flex-1 truncate">{player.emoji + ' ' + player.playerName} </div>
{player.isHost && (
<span className="text-white bg-red-600 px-2 py-1 rounded-lg shadow-sm text-sm ml-3">
<span className=" text-white bg-red-600 px-2 py-1 rounded-lg shadow-sm text-sm ml-3">
๋ฐฉ์žฅ ๐Ÿ‘‘
</span>
)}
Expand Down Expand Up @@ -68,7 +68,7 @@ const ParticipantDisplay: React.FC<ParticipantDisplayProps> = ({ gameState }) =>
layout
transition={{ type: 'spring', stiffness: 100, damping: 20 }}
>
<div className="font-bold">{player.emoji + ' ' + player.playerName}</div>
<div className="flex-1 truncate">{player.emoji + ' ' + player.playerName}</div>
<motion.div
initial={{ scale: 1 }}
animate={{ scale: 1.1 }}
Expand Down Expand Up @@ -103,7 +103,7 @@ const ParticipantDisplay: React.FC<ParticipantDisplayProps> = ({ gameState }) =>
layout
transition={{ type: 'spring', stiffness: 100, damping: 20 }}
>
<div className="font-bold" style={{ color: player.isAnswer ? 'inherit' : 'red' }}>
<div className="truncate" style={{ color: player.isAnswer ? 'inherit' : 'red' }}>
{(player.isAnswer ? player.emoji : '๐Ÿ‘ป') + ' ' + player.playerName}
</div>
</motion.div>
Expand Down
7 changes: 1 addition & 6 deletions FE/src/features/game/components/QuizHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export const QuizHeader = () => {
const [seconds, setSeconds] = useState(0);
const [isAnswerVisible, setIsAnswerVisible] = useState(false);
const [limitTime, setLimitTime] = useState(0);
const answer = useQuizStore((state) => state.currentAnswer);
useEffect(() => {
if (currentQuiz) {
setSeconds((currentQuiz.endTime - getServerTimestamp()) / 1000);
Expand Down Expand Up @@ -71,11 +70,7 @@ export const QuizHeader = () => {
<div className="flex justify-center items-center font-bold text-2xl flex-grow">
{'Q. ' + currentQuiz.quiz}
</div>
<AnswerModal
isOpen={isAnswerVisible}
// onClose={() => setIsAnswerVisible(false)}
answer={answer}
/>
<AnswerModal isOpen={isAnswerVisible} />
</div>
);
};
6 changes: 4 additions & 2 deletions FE/src/features/game/components/QuizOptionBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export const QuizOptionBoard = () => {
{choiceListVisible &&
choiceList.map((option, i) => (
<div
className={'rounded-lg flex justify-center items-center w-[100%] h-[100%]'}
className={'rounded-lg relative w-[100%] h-[100%] overflow-hidden'}
key={i}
style={{
background: optionColors[i],
Expand All @@ -151,7 +151,9 @@ export const QuizOptionBoard = () => {
textShadow: '-1px 0 white, 0 1px white, 1px 0 white, 0 -1px white'
}}
>
<div className="z-10 font-bold text-3xl text-black">{option.content}</div>
<div className="absolute inset-0 flex items-center justify-center text-center z-10 font-bold text-3xl text-black break-all p-4">
{option.content}
</div>
</div>
))}
</div>
Expand Down
2 changes: 1 addition & 1 deletion FE/src/features/game/components/QuizSetSearchList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const QuizSetSearchList = ({ onClick, search }: Params) => {
{data?.pages.map((page) =>
page?.data.map((e) => (
<div
className="mb-2 rounded-m"
className="mb-2 rounded-m bg-white"
onClick={() => {
setSelectedQuizSet(e);
onClick(e);
Expand Down
16 changes: 14 additions & 2 deletions FE/src/features/game/data/socketListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import { getEmojiByUUID } from '../utils/emoji';

// chat
socketService.on('chatMessage', (data) => {
useChatStore.getState().addMessage(data);
if (Array.isArray(data)) {
data.forEach((e) => {
useChatStore.getState().addMessage(e);
});
} else {
useChatStore.getState().addMessage(data);
}
});

// player
Expand All @@ -34,7 +40,13 @@ socketService.on('joinRoom', (data) => {
});

socketService.on('updatePosition', (data) => {
usePlayerStore.getState().updatePlayerPosition(data.playerId, data.playerPosition);
if (Array.isArray(data)) {
data.forEach((e) => {
usePlayerStore.getState().updatePlayerPosition(e.playerId, e.playerPosition);
});
} else {
usePlayerStore.getState().updatePlayerPosition(data.playerId, data.playerPosition);
}
});

socketService.on('endQuizTime', (data) => {
Expand Down
17 changes: 5 additions & 12 deletions FE/src/index.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
@import url('https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&display=swap');
@font-face {
font-family: 'NPSfontBold';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/[email protected]/NPSfontBold.woff2')
format('woff2');
font-weight: 700;
font-style: bold;
}

@font-face {
font-family: 'NPSfontBold';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_2310@1.0/NPSfontRegular.woff2')
format('woff2');
font-family: 'CookieRun-Regular';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/CookieRun-Regular.woff')
format('woff');
font-weight: 400;
font-style: normal;
}
Expand All @@ -28,9 +21,9 @@

@layer base {
html {
font-family: 'NPSfontBold', 'Noto Color Emoji', ui-sans-serif, system-ui;
font-family: 'CookieRun-Regular', 'Noto Color Emoji', ui-sans-serif, system-ui;
box-sizing: border-box;
color: #5f6e76;
color: #687880;
}
*,
*::before,
Expand Down

0 comments on commit 3e40808

Please sign in to comment.