Skip to content

Commit

Permalink
chore: Merge branch 'develop' into feature/#141
Browse files Browse the repository at this point in the history
  • Loading branch information
kwaksj329 committed Nov 27, 2024
2 parents 0cc131b + eee2047 commit 8770ec2
Show file tree
Hide file tree
Showing 19 changed files with 352 additions and 106 deletions.
47 changes: 16 additions & 31 deletions .github/workflows/client-ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,41 +39,26 @@ jobs:
working-directory: ./client
run: pnpm test | true

deploy:
needs: ci
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: '9'

- name: Install Dependencies
run: pnpm install --frozen-lockfile

- name: Build Core Package
working-directory: ./core
run: pnpm build

- name: Build Client
working-directory: ./client
env:
VITE_API_URL: ${{secrets.VITE_API_URL}}
VITE_SOCKET_URL: ${{secrets.VITE_SOCKET_URL}}
run: pnpm build

- name: Upload to Object Storage
env:
AWS_ACCESS_KEY_ID: ${{ secrets.NCP_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.NCP_SECRET_KEY }}
run: |
aws s3 sync ./client/dist s3://${{ secrets.NCP_BUCKET }}/ \
--endpoint-url https://kr.object.ncloudstorage.com \
--region kr-standard
deploy:
needs: ci
runs-on: ubuntu-latest
steps:
- name: Deploy to Server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: mira
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /home/mira/web30-stop-troublepainter
git pull origin develop
docker compose build nginx
docker compose up -d nginx
19 changes: 10 additions & 9 deletions .github/workflows/server-ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
file: ./Dockerfile.nestjs
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/troublepainter:latest
build-args: |
Expand All @@ -74,11 +74,12 @@ jobs:
username: mira
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/troublepainter:latest
docker stop troublepainter || true
docker rm troublepainter || true
docker run -d --name troublepainter -p 3000:3000 -e REDIS_HOST=${{ secrets.REDIS_HOST }} -e REDIS_PORT=${{ secrets.REDIS_PORT }} -e CLOVA_API_KEY=${{ secrets.CLOVA_API_KEY }} -e CLOVA_GATEWAY_KEY=${{ secrets.CLOVA_GATEWAY_KEY }} --restart unless-stopped ${{ secrets.DOCKERHUB_USERNAME }}/troublepainter:latest
cd /home/mira/web30-stop-troublepainter
git pull origin develop
echo "REDIS_HOST=${{ secrets.REDIS_HOST }}" > .env
echo "REDIS_PORT=${{ secrets.REDIS_PORT }}" >> .env
echo "CLOVA_API_KEY=${{ secrets.CLOVA_API_KEY }}" >> .env
echo "CLOVA_GATEWAY_KEY=${{ secrets.CLOVA_GATEWAY_KEY }}" >> .env
docker compose up -d
2 changes: 1 addition & 1 deletion Dockerfile → Dockerfile.nestjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RUN pnpm --filter @troublepainter/core build
RUN pnpm --filter server build

FROM node:20-alpine AS production
WORKDIR /app
WORKDIR /app

COPY --from=builder /app/pnpm-workspace.yaml ./
COPY --from=builder /app/server/package.json ./server/package.json
Expand Down
18 changes: 18 additions & 0 deletions Dockerfile.nginx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:20-alpine AS builder

RUN corepack enable && corepack prepare [email protected] --activate

WORKDIR /app

COPY . .

RUN pnpm install --frozen-lockfile && pnpm build

FROM nginx:alpine

COPY nginx.conf /etc/nginx/templates/default.conf.template
COPY --from=builder /app/client/dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
9 changes: 7 additions & 2 deletions client/src/components/chat/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { FormEvent, useState } from 'react';
import type { ChatResponse } from '@troublepainter/core';
import { RoomStatus, type ChatResponse } from '@troublepainter/core';
import { ChatBubble } from '@/components/chat/ChatBubbleUI';
import { Input } from '@/components/ui/Input';
import { chatSocketHandlers } from '@/handlers/socket/chatSocket.handler';
import { gameSocketHandlers } from '@/handlers/socket/gameSocket.handler';
import { useChatSocket } from '@/hooks/socket/useChatSocket';
import { useScrollToBottom } from '@/hooks/useScrollToBottom';
import { useChatSocketStore } from '@/stores/socket/chatSocket.store';
Expand All @@ -11,7 +12,7 @@ import { useGameSocketStore } from '@/stores/socket/gameSocket.store';
export const Chat = () => {
const [inputMessage, setInputMessage] = useState('');
const { messages, isConnected, currentPlayerId } = useChatSocket();
const { players } = useGameSocketStore();
const { players, room } = useGameSocketStore();
const { actions } = useChatSocketStore();
const { containerRef } = useScrollToBottom([messages]);

Expand All @@ -30,6 +31,10 @@ export const Chat = () => {
};
actions.addMessage(messageData);

if (room?.status === RoomStatus.GUESSING) {
void gameSocketHandlers.checkAnswer({ answer: inputMessage });
}

setInputMessage('');
};

Expand Down
14 changes: 5 additions & 9 deletions client/src/components/modal/RoleModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ import { useModal } from '@/hooks/useModal';
import { useGameSocketStore } from '@/stores/socket/gameSocket.store';

const RoleModal = () => {
const { players, currentPlayerId, room } = useGameSocketStore();
const { isModalOpened, closeModal, handleKeyDown, openModal } = useModal(3000);

const myRole = players.find((player) => player.playerId === currentPlayerId)?.role || null;

if (!myRole) return null;
const { roundAssignedRole, room } = useGameSocketStore();
const { isModalOpened, closeModal, handleKeyDown, openModal } = useModal(5000);

useEffect(() => {
if (myRole) openModal();
}, [myRole, room?.currentRound]);
if (roundAssignedRole) openModal();
}, [roundAssignedRole, room?.currentRound]);

return (
<Modal
Expand All @@ -25,7 +21,7 @@ const RoleModal = () => {
className="w-80"
>
<span className="flex min-h-28 items-center justify-center text-3xl text-violet-950">
{PLAYING_ROLE_TEXT[myRole]}
{roundAssignedRole ? PLAYING_ROLE_TEXT[roundAssignedRole] : ''}
</span>
</Modal>
);
Expand Down
48 changes: 48 additions & 0 deletions client/src/components/modal/RoundEndModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useEffect } from 'react';
import { PlayerRole } from '@troublepainter/core';
import { Modal } from '../ui/Modal';
import { useModal } from '@/hooks/useModal';
import { useGameSocketStore } from '@/stores/socket/gameSocket.store';

const RoundEndModal = () => {
const { room, roundWinner, players, timers } = useGameSocketStore();
const { isModalOpened, openModal, closeModal } = useModal();

useEffect(() => {
if (roundWinner) openModal();
}, [roundWinner]);

useEffect(() => {
if (timers.ENDING === 0) closeModal();
}, [timers.ENDING]);

const devil = players.find((player) => player.role === PlayerRole.DEVIL);

return (
<Modal
title={room?.currentWord || ''}
isModalOpened={isModalOpened}
className="max-w-[26.875rem] sm:max-w-[61.75rem]"
>
<div className="flex min-h-[12rem] items-center justify-center sm:min-h-[15.75rem]">
<p className="text-center text-2xl sm:m-2 sm:text-3xl">
{roundWinner?.role === PlayerRole.DEVIL ? (
<> 정답을 맞춘 구경꾼이 없습니다</>
) : (
<>
구경꾼 <span className="text-violet-600">{roundWinner?.nickname}</span>이 정답을 맞혔습니다
</>
)}
</p>
</div>
<div className="min-h-[4rem] rounded-md bg-violet-50 p-4 sm:m-2">
<p className="text-center text-xl text-violet-950 sm:text-2xl">
방해꾼은 <span className="text-violet-600">{devil?.nickname}</span>였습니다.
</p>
<span>{timers.ENDING}</span> {/* 임시 */}
</div>
</Modal>
);
};

export default RoundEndModal;
8 changes: 3 additions & 5 deletions client/src/components/player/PlayerCardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@ import { PlayerCard } from '@/components/ui/player-card/PlayerCard';
import { useGameSocketStore } from '@/stores/socket/gameSocket.store';

const PlayerCardList = () => {
const { players, currentPlayerId, room } = useGameSocketStore();
const { players, room, roundAssignedRole, currentPlayerId } = useGameSocketStore();

if (!players?.length) return null;

const myRole = players.find((player) => player.playerId === currentPlayerId)?.role || undefined;

const getPlayerRole = (playerRole: PlayerRole | undefined, myRole: PlayerRole | undefined) => {
const getPlayerRole = (playerRole: PlayerRole | undefined, myRole: PlayerRole | null) => {
if (myRole === PlayerRole.GUESSER) return playerRole === PlayerRole.GUESSER ? playerRole : null;
return playerRole;
};

return (
<>
{players.map((player) => {
const playerRole = getPlayerRole(player.role, myRole) || null;
const playerRole = getPlayerRole(player.role, roundAssignedRole) || null;

return (
<PlayerCard
Expand Down
6 changes: 4 additions & 2 deletions client/src/components/setting/Setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ const Setting = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => {
}, [roomSettings]);

useEffect(() => {
if (!isHost) return;
void gameSocketHandlers.updateSettings({ settings: selectedValues });
if (!isHost || !selectedValues || !selectedValues.drawTime) return;
void gameSocketHandlers.updateSettings({
settings: { ...selectedValues, drawTime: selectedValues.drawTime + 5 },
});
}, [selectedValues]);

const handleChange = (key: SettingKey) => (value: string) => {
Expand Down
15 changes: 13 additions & 2 deletions client/src/handlers/socket/gameSocket.handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {
CRDTMessage,
CheckAnswerRequest,
JoinRoomRequest,
JoinRoomResponse,
ReconnectRequest,
Expand Down Expand Up @@ -37,12 +38,22 @@ export const gameSocketHandlers = {
});
},

gameStart: (request: { roomId: string; playerId: string }): Promise<void> => {
gameStart: (): Promise<void> => {
const socket = useSocketStore.getState().sockets.game;
if (!socket) throw new Error('Socket not connected');

return new Promise((resolve) => {
socket.emit('gameStart', request);
socket.emit('gameStart');
resolve();
});
},

checkAnswer: (request: CheckAnswerRequest): Promise<void> => {
const socket = useSocketStore.getState().sockets.game;
if (!socket) throw new Error('Socket not connected');

return new Promise((resolve) => {
socket.emit('checkAnswer', request);
resolve();
});
},
Expand Down
Loading

0 comments on commit 8770ec2

Please sign in to comment.