From f66dc1ffdec9f36c0d732c2bf0ff2f2c60308e98 Mon Sep 17 00:00:00 2001 From: HeoJiye Date: Mon, 27 Nov 2023 11:10:47 +0900 Subject: [PATCH 01/35] =?UTF-8?q?fix:=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 챗GPT를 이용해 간결하게 수정함 - 이전보다 딴소리를 더 많이 하는 것 같아서 간결하게 수정함. --- backend/src/events/constants.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/backend/src/events/constants.ts b/backend/src/events/constants.ts index 5a08d7aa..030ec42c 100644 --- a/backend/src/events/constants.ts +++ b/backend/src/events/constants.ts @@ -37,17 +37,14 @@ export const tarotReadingSystemMessage = ` ###`; export const talkSystemMessage = ` -user와 친근한 반말로 상황에 맞게 대화를 이어나가되, -- user의 고민에 대해 공감성 멘트로 친근한 반말로 대화를 이어나갑니다. -- user가 타로 카드로 알고 싶은 것이 명확해질 때, 정확히 "그럼 ${askTarotCardMessage}"라는 문장만 말합니다. -- user가 무언가를 알려달라고 할 때, 정확히 "그럼 ${askTarotCardMessage}"라는 문장만을 사용합니다. -- "그럼 ${askTarotCardMessage}"라는 문장 이외의 표현으로 타로 카드를 뽑자고 제안하지 않습니다. -- "그럼 ${askTarotCardMessage}"라는 문장 이외의 표현으로 타로 카드를 뽑자고 권유하지 않습니다. -- 타로 카드 해설을 요구하는 system 메세지가 오기 전까지, 타로 해설은 하지 않습니다. -- 타로 카드 해설을 요구하는 system 메세지가 오기 전까지, 타로에 대한 설명은 하지 않습니다. -- assistant의 답변은 30토큰 이하로 제한되며, 간결하게 표현합니다. -- assistant의 답변은 반드시 반말로 합니다. 존댓말을 사용하지 않습니다. -`; +사용자와 친근한 반말로 상황에 맞게 대화를 이어가며, +- user의 고민에 대해 공감성 있는 반말로 대화를 이어가기 +- assistant는 user의 고민을 상담해주는 타로 상담사이다. 역할에 벗어나는 대화를 하지 않기 +- 사용자가 무언가를 알려달라고 하거나 알고 싶은 것이 명확해질 때, 정확히 "그럼 ${askTarotCardMessage}"라는 문장으로만 응답하기 +- "그럼 ${askTarotCardMessage}"라는 문장 이외의 표현으로 타로 카드를 뽑자고 말하지 않기 +- 타로 카드 해설을 요구하는 system 메세지가 오기 전까지, 타로에 대한 설명은 하지 않기 +- 답변은 30토큰 이하로 제한되며, 간결하게 표현하기 +- 답변은 반드시 반말로 작성하기. 존댓말을 사용하지 않기`; export const tarotCardNames = [ 'The Fool', From c3613ed3b7dc4be1336d0faa7d904b40e14f8f3f Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 11:11:44 +0900 Subject: [PATCH 02/35] =?UTF-8?q?fix:=20SSL=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=B5=EC=82=AC=20=EC=A0=84=EC=97=90=20=EB=B6=80=EB=AA=A8=20?= =?UTF-8?q?=EB=94=94=EB=A0=89=ED=86=A0=EB=A6=AC=20=EB=A8=BC=EC=A0=80=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index cd0c27cf..e659617f 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -36,6 +36,7 @@ jobs: - name: Generate SSL files run: | + mkdir -p config/nginx/ssl/ echo "${{ secrets.SSL_OPTIONS }}" > config/nginx/ssl/options-ssl-nginx.conf echo "${{ secrets.SSL_FULLCHAIN }}" > config/nginx/ssl/fullchain.pem echo "${{ secrets.SSL_PRIVKEY }}" > config/nginx/ssl/privkey.pem From 2090308f844c82e003e113d28fd3b99b970a7f29 Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 11:18:11 +0900 Subject: [PATCH 03/35] =?UTF-8?q?feat:=20=EB=A6=AC=EB=AA=A8=ED=8A=B8=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=EC=97=90=20target=20directory=EA=B0=80=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9C=BC?= =?UTF-8?q?=EB=A9=B4=20=EC=83=9D=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index e659617f..222c4bc7 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -42,6 +42,9 @@ jobs: echo "${{ secrets.SSL_PRIVKEY }}" > config/nginx/ssl/privkey.pem echo "${{ secrets.SSL_DHPARAMS }}" > config/nginx/ssl/ssl-dhparams.pem + - name: Create target directory if not exists + run: mkdir -p ~/app/config/nginx/ssl + - name: Copy SSL files to Remote Server uses: appleboy/scp-action@master with: From 6ed27df6c60450fc645a85c3104e4502b3250d6a Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 11:38:19 +0900 Subject: [PATCH 04/35] =?UTF-8?q?fix:=20=EC=98=A4=EB=A5=98=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EB=94=94=EB=B2=84?= =?UTF-8?q?=EA=B9=85=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 222c4bc7..f3934865 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -2,7 +2,7 @@ name: Dockerized CD on: push: - branches: ["dev"] + branches: ["dev", "BE/bugfix/#262-백엔드-배포-깃허브-액션-오류"] jobs: build: @@ -61,6 +61,8 @@ jobs: DOCKER_IMAGE_NAME="${{ secrets.DOCKER_USERNAME }}/magicconch" docker-compose build -t "${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}" cp docker-compose.yml docker-compose.${DOCKER_IMAGE_TAG}.yml + cat docker-compose.${DOCKER_IMAGE_TAG}.yml + ls - name: Copy docker-compose to Remote Server uses: appleboy/scp-action@master @@ -73,7 +75,7 @@ jobs: target: "~/app" - name: Remove local docker-compose copied file - run: rm docker-compose.${{ github.sha }}.yml + run: rm docker-compose.${DOCKER_IMAGE_TAG}.yml - name: Push Docker Images to Registry uses: docker/login-action@v3 From 4306725d08602b166bcae66c95909481066e9b8c Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 11:50:18 +0900 Subject: [PATCH 05/35] fix: DOCKER_IMAGE_TAG -> github.sha --- .github/workflows/docker-cd.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index f3934865..77066327 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -71,8 +71,9 @@ jobs: username: ${{ secrets.SSH_USERNAME }} password: ${{ secrets.SSH_PASSWORD }} port: ${{ secrets.SSH_PORT }} - source: "docker-compose.${DOCKER_IMAGE_TAG}.yml" + source: "docker-compose.${{ github.sha }}.yml" target: "~/app" + debug: true - name: Remove local docker-compose copied file run: rm docker-compose.${DOCKER_IMAGE_TAG}.yml From b464cff03ca1ec07c149cd5464fb875985bc3573 Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 11:52:41 +0900 Subject: [PATCH 06/35] rename: flipcard.mp3 -> flipCard.mp3 --- frontend/public/flipCard.mp3 | Bin 0 -> 30929 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 frontend/public/flipCard.mp3 diff --git a/frontend/public/flipCard.mp3 b/frontend/public/flipCard.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..a67087625caeff1e1cfb176d381c4d0f5fd6eceb GIT binary patch literal 30929 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 Date: Mon, 27 Nov 2023 11:53:32 +0900 Subject: [PATCH 07/35] remove flipcard.mp3 --- frontend/public/flipcard.mp3 | Bin 30929 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 frontend/public/flipcard.mp3 diff --git a/frontend/public/flipcard.mp3 b/frontend/public/flipcard.mp3 deleted file mode 100644 index a67087625caeff1e1cfb176d381c4d0f5fd6eceb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30929 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 Date: Mon, 27 Nov 2023 11:54:41 +0900 Subject: [PATCH 08/35] =?UTF-8?q?fix:=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DOCKER_IMAGE_TAG에 github.sha를 넣었는데 해당 블록에서는 동작하지만 리모트 서버에서는 인식할 수 없어서 github.sha로 수정 --- .github/workflows/docker-cd.yml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 77066327..e16c9478 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -57,12 +57,9 @@ jobs: - name: Build Docker Images run: | - DOCKER_IMAGE_TAG="${{ github.sha }}" DOCKER_IMAGE_NAME="${{ secrets.DOCKER_USERNAME }}/magicconch" - docker-compose build -t "${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG}" - cp docker-compose.yml docker-compose.${DOCKER_IMAGE_TAG}.yml - cat docker-compose.${DOCKER_IMAGE_TAG}.yml - ls + docker-compose build -t "${DOCKER_IMAGE_NAME}:${{ github.sha }}" + cp docker-compose.yml docker-compose.${{ github.sha }}.yml - name: Copy docker-compose to Remote Server uses: appleboy/scp-action@master @@ -73,10 +70,9 @@ jobs: port: ${{ secrets.SSH_PORT }} source: "docker-compose.${{ github.sha }}.yml" target: "~/app" - debug: true - name: Remove local docker-compose copied file - run: rm docker-compose.${DOCKER_IMAGE_TAG}.yml + run: rm docker-compose.${{ github.sha }}.yml - name: Push Docker Images to Registry uses: docker/login-action@v3 @@ -106,8 +102,8 @@ jobs: script: | cd ~/app docker rm -f $(docker ps -aq) - docker-compose -f docker-compose.${DOCKER_IMAGE_TAG}.yml pull - docker-compose -f docker-compose.${DOCKER_IMAGE_TAG}.yml up -d + docker-compose -f docker-compose.${{ github.sha }}.yml pull + docker-compose -f docker-compose.${{ github.sha }}.yml up -d while [ -z "$(docker ps -afq name=was)" ]; do sleep 5 done From dc8f893bd4e72d1a31ba95a443b5a05f86785994 Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 11:57:37 +0900 Subject: [PATCH 09/35] =?UTF-8?q?fix:=20nest=20->=20was=20=EB=AA=85?= =?UTF-8?q?=EC=B9=AD=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index c7f56b50..81724222 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: ports: - "443:443" depends_on: - - nest + - was - certbot certbot: From 920ce99528be493785b82bddf54450980c18ad65 Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 12:11:22 +0900 Subject: [PATCH 10/35] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 3 +-- docker-compose.yml | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index e16c9478..53cc2f5b 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -57,8 +57,7 @@ jobs: - name: Build Docker Images run: | - DOCKER_IMAGE_NAME="${{ secrets.DOCKER_USERNAME }}/magicconch" - docker-compose build -t "${DOCKER_IMAGE_NAME}:${{ github.sha }}" + docker-compose build -t "${{ secrets.DOCKER_USERNAME }}/magicconch:${{ github.sha }}" cp docker-compose.yml docker-compose.${{ github.sha }}.yml - name: Copy docker-compose to Remote Server diff --git a/docker-compose.yml b/docker-compose.yml index 81724222..208c8918 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,6 @@ version: "3.3" services: was: - image: was build: context: . dockerfile: Dockerfile.was @@ -22,7 +21,6 @@ services: - "3000" nginx: - image: nginx build: context: . dockerfile: Dockerfile.nginx From f8959cf826c0ee5dc1aade04628beb860aa5a59a Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 12:27:07 +0900 Subject: [PATCH 11/35] =?UTF-8?q?fix:=20=EB=8F=84=EC=BB=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 53cc2f5b..91bea319 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -103,7 +103,7 @@ jobs: docker rm -f $(docker ps -aq) docker-compose -f docker-compose.${{ github.sha }}.yml pull docker-compose -f docker-compose.${{ github.sha }}.yml up -d - while [ -z "$(docker ps -afq name=was)" ]; do + while [ -z "$(docker ps -afq name=app_was)" ]; do sleep 5 done sleep 60 From 66ac73fdde1053e94244d0ec257b55a7868d5e2a Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 12:40:44 +0900 Subject: [PATCH 12/35] =?UTF-8?q?fix:=20=ED=95=84=ED=84=B0=EB=A7=81=20?= =?UTF-8?q?=EC=8B=9C,=20was=EA=B0=80=20=EB=93=A4=EC=96=B4=EA=B0=84=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=EC=9D=84=20=EC=B0=BE=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 91bea319..4430d88a 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -100,10 +100,10 @@ jobs: port: ${{ secrets.SSH_PORT }} script: | cd ~/app - docker rm -f $(docker ps -aq) + docker rm -f $(docker ps -qa) docker-compose -f docker-compose.${{ github.sha }}.yml pull docker-compose -f docker-compose.${{ github.sha }}.yml up -d - while [ -z "$(docker ps -afq name=app_was)" ]; do + while [ -z "$(docker ps -qaf "name=*was*")" ]; do sleep 5 done sleep 60 From e472444901de8cd38726c13b6f7a3a18f1745826 Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 13:15:28 +0900 Subject: [PATCH 13/35] =?UTF-8?q?fix:=20name=20=ED=95=84=ED=84=B0=EB=A7=81?= =?UTF-8?q?=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 4430d88a..918cf587 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -103,7 +103,7 @@ jobs: docker rm -f $(docker ps -qa) docker-compose -f docker-compose.${{ github.sha }}.yml pull docker-compose -f docker-compose.${{ github.sha }}.yml up -d - while [ -z "$(docker ps -qaf "name=*was*")" ]; do + while [ -z "$(docker ps -qaf "name=was")" ]; do sleep 5 done sleep 60 From 60a5972a6d41fa74bb71d9668305f08af994acca Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 13:19:51 +0900 Subject: [PATCH 14/35] =?UTF-8?q?fix:=20nginx=2080=EB=B2=88=20=ED=8F=AC?= =?UTF-8?q?=ED=8A=B8=20=EB=A7=A4=ED=95=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 208c8918..53fc6b00 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,7 @@ services: context: . dockerfile: Dockerfile.nginx ports: + - "80:80" - "443:443" depends_on: - was From bf3a386d23943c4306ec44ea5bad69b17ef1231a Mon Sep 17 00:00:00 2001 From: HeoJiye Date: Mon, 27 Nov 2023 13:36:01 +0900 Subject: [PATCH 15/35] =?UTF-8?q?feature:=20connectSocket=20reconnect=20op?= =?UTF-8?q?tion=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/business/hooks/useSocket.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/frontend/src/business/hooks/useSocket.ts b/frontend/src/business/hooks/useSocket.ts index db2fb961..8cf03bea 100644 --- a/frontend/src/business/hooks/useSocket.ts +++ b/frontend/src/business/hooks/useSocket.ts @@ -11,14 +11,25 @@ interface SocketTypesMap { }; } +type ConnectSocketOptions = { + reconnect: boolean; +}; + type SocketType = keyof SocketTypesMap; const sockets = {} as Record; export function useSocket(socketType: T) { - function connectSocket(url: string) { + const ConnectSocketDefaultOptions = { + reconnect: false, + }; + + function connectSocket(url: string, { reconnect }: ConnectSocketOptions = ConnectSocketDefaultOptions) { if (sockets[socketType]) { - throw new Error('소켓이 이미 존재합니다.'); + if (!reconnect) { + throw new Error('소켓이 이미 존재합니다.'); + } + sockets[socketType].disconnect(); } sockets[socketType] = io(url); } From 18017cfe37b692640d11b4717479ebb7e21b9f9f Mon Sep 17 00:00:00 2001 From: HeoJiye Date: Mon, 27 Nov 2023 13:37:03 +0900 Subject: [PATCH 16/35] =?UTF-8?q?feat:=20=EC=86=8C=EC=BC=93=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20=EC=97=90=EB=9F=AC=20=EC=8B=9C=20home=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/business/hooks/useSocket.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/src/business/hooks/useSocket.ts b/frontend/src/business/hooks/useSocket.ts index 8cf03bea..53188472 100644 --- a/frontend/src/business/hooks/useSocket.ts +++ b/frontend/src/business/hooks/useSocket.ts @@ -1,3 +1,4 @@ +import { useNavigate } from 'react-router-dom'; import { Socket, io } from 'socket.io-client'; interface SocketTypesMap { @@ -20,6 +21,8 @@ type SocketType = keyof SocketTypesMap; const sockets = {} as Record; export function useSocket(socketType: T) { + const navigate = useNavigate(); + const ConnectSocketDefaultOptions = { reconnect: false, }; @@ -43,10 +46,18 @@ export function useSocket(socketType: T) { } function socketOn(eventName: SocketTypesMap[T]['OnEventName'], eventListener: (args: U) => void) { + if (!sockets[socketType]) { + navigate('/'); + return; + } sockets[socketType].on(eventName, eventListener as any); } function socketEmit(eventName: SocketTypesMap[T]['EmitEventName'], ...eventArgs: unknown[]) { + if (!sockets[socketType]) { + navigate('/'); + return; + } sockets[socketType].emit(eventName, ...eventArgs); } From b3ca942e81597cd4f122199ca345fe0a7599dbc4 Mon Sep 17 00:00:00 2001 From: HeoJiye Date: Mon, 27 Nov 2023 13:37:45 +0900 Subject: [PATCH 17/35] =?UTF-8?q?feat:=20home=EC=97=90=EC=84=9C=20connectS?= =?UTF-8?q?ocket=20reconnect=20=EC=98=B5=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/HomePage/HomePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/HomePage/HomePage.tsx b/frontend/src/pages/HomePage/HomePage.tsx index 697abad1..d81c79d3 100644 --- a/frontend/src/pages/HomePage/HomePage.tsx +++ b/frontend/src/pages/HomePage/HomePage.tsx @@ -10,7 +10,7 @@ function HomePage() { const { connectSocket } = useSocket('AIChat'); const moveAiChat = () => { - connectSocket(import.meta.env.VITE_WAS_URL); + connectSocket(import.meta.env.VITE_WAS_URL, { reconnect: true }); navigate('/chat/ai'); }; From ea4227fd65539fb4d328d01fece35f70f3397955 Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 14:46:44 +0900 Subject: [PATCH 18/35] =?UTF-8?q?feat:=20Dockerfile=EB=8F=84=20=EA=B0=99?= =?UTF-8?q?=EC=9D=B4=20=EB=84=98=EA=B2=A8=EC=A3=BC=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 918cf587..30e8d24e 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -32,7 +32,7 @@ jobs: password: ${{ secrets.SSH_PASSWORD }} port: ${{ secrets.SSH_PORT }} source: ".env" - target: "~/app" + target: "~/app/" - name: Generate SSL files run: | @@ -45,30 +45,34 @@ jobs: - name: Create target directory if not exists run: mkdir -p ~/app/config/nginx/ssl - - name: Copy SSL files to Remote Server + - name: Copy nginx configuration and SSL files to Remote Server uses: appleboy/scp-action@master with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} password: ${{ secrets.SSH_PASSWORD }} port: ${{ secrets.SSH_PORT }} - source: "config/nginx/ssl/*" - target: "~/app/config/nginx/ssl" + source: "config/nginx/*" + target: "~/app/config/nginx/" - name: Build Docker Images run: | docker-compose build -t "${{ secrets.DOCKER_USERNAME }}/magicconch:${{ github.sha }}" cp docker-compose.yml docker-compose.${{ github.sha }}.yml - - name: Copy docker-compose to Remote Server + - name: Copy Dockerfiles to Remote Server uses: appleboy/scp-action@master with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} password: ${{ secrets.SSH_PASSWORD }} port: ${{ secrets.SSH_PORT }} - source: "docker-compose.${{ github.sha }}.yml" - target: "~/app" + source: | + docker-compose.${{ github.sha }}.yml + Dockerfile.nginx + Dockerfile.was + target: "~/app/" + overwrite: true - name: Remove local docker-compose copied file run: rm docker-compose.${{ github.sha }}.yml From dc3be2af8df97a5fc6cd613872f6ff7a0ffd330a Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 15:22:58 +0900 Subject: [PATCH 19/35] =?UTF-8?q?fix:=20scp-action=20=EB=AC=B8=EB=B2=95=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index 30e8d24e..d9ed3b8b 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -67,10 +67,7 @@ jobs: username: ${{ secrets.SSH_USERNAME }} password: ${{ secrets.SSH_PASSWORD }} port: ${{ secrets.SSH_PORT }} - source: | - docker-compose.${{ github.sha }}.yml - Dockerfile.nginx - Dockerfile.was + source: "docker-compose.${{ github.sha }}.yml,Dockerfile.nginx,Dockerfile.was" target: "~/app/" overwrite: true From 1b98bc409ffda7df8a0cbdf00085d0bbb604e567 Mon Sep 17 00:00:00 2001 From: kimyu0218 Date: Mon, 27 Nov 2023 15:26:33 +0900 Subject: [PATCH 20/35] =?UTF-8?q?remove:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=9A=A9=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-cd.yml b/.github/workflows/docker-cd.yml index d9ed3b8b..9c5c8ed2 100644 --- a/.github/workflows/docker-cd.yml +++ b/.github/workflows/docker-cd.yml @@ -2,7 +2,7 @@ name: Dockerized CD on: push: - branches: ["dev", "BE/bugfix/#262-백엔드-배포-깃허브-액션-오류"] + branches: ["dev"] jobs: build: From 205bef1c920f9f1ec0619d06220145a0f2888e7b Mon Sep 17 00:00:00 2001 From: Song_Minhyung Date: Thu, 23 Nov 2023 18:13:32 +0900 Subject: [PATCH 21/35] =?UTF-8?q?feat:=20CamBox=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=ED=8B=80=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/ddung.png | Bin 2727 -> 7175 bytes frontend/public/sponge.png | Bin 2532 -> 7274 bytes frontend/src/business/hooks/useMedia.ts | 2 +- frontend/src/business/hooks/useWebRTC.ts | 6 +++- .../src/pages/HumanChatPage/CamBox/CamBox.tsx | 32 ++++++++++++++++++ .../src/pages/HumanChatPage/CamBox/index.ts | 1 + .../src/pages/HumanChatPage/HumanChatPage.tsx | 27 +++++++-------- frontend/tailwind.config.js | 4 +++ 8 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx create mode 100644 frontend/src/pages/HumanChatPage/CamBox/index.ts diff --git a/frontend/public/ddung.png b/frontend/public/ddung.png index 516796a2606c3c5e7c66b71902e9af954d7d01da..3abdd3a9a5350ee2c6f3c75b3c9677e5c0abfd90 100644 GIT binary patch literal 7175 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 J^}5*j{{jJO;%Wc@ literal 2727 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
    l4 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 I*)H;b0Qww1Z~y=R literal 2532 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 { const stream = await navigator.mediaDevices.getUserMedia({ audio: true, - video: deviceId ? { deviceId } : { facingMode: 'user' }, + video: deviceId ? { deviceId, width: 320, height: 320 } : { facingMode: 'user', width: 320, height: 320 }, }); if (localVideoRef.current) { diff --git a/frontend/src/business/hooks/useWebRTC.ts b/frontend/src/business/hooks/useWebRTC.ts index 259c8f1f..148c6fda 100644 --- a/frontend/src/business/hooks/useWebRTC.ts +++ b/frontend/src/business/hooks/useWebRTC.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { iceServers } from '@constants/urls'; @@ -9,6 +9,7 @@ import { useSocket } from './useSocket'; export function useWebRTC(roomName: string) { const peerConnectionRef = useRef(); const { socketEmit, disconnectSocket } = useSocket('WebRTC'); + const [cameraConnected, setCameraConnected] = useState({ local: false, remote: false }); const { localVideoRef, @@ -44,6 +45,7 @@ export function useWebRTC(roomName: string) { } socketEmit('candidate', e.candidate, roomName); + setCameraConnected(prev => ({ ...prev, remote: true })); }); localStreamRef.current.getTracks().forEach(track => { @@ -53,6 +55,7 @@ export function useWebRTC(roomName: string) { useEffect(() => { const init = async () => { await getMedia(); + setCameraConnected(prev => ({ ...prev, local: true })); initSignalingSocket(); makeConnection(); socketEmit('joinRoom', roomName); @@ -69,6 +72,7 @@ export function useWebRTC(roomName: string) { cameraOptions, localVideoRef, remoteVideoRef, + cameraConnected, toggleAudio, toggleVideo, changeCamera, diff --git a/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx b/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx new file mode 100644 index 00000000..50a2804b --- /dev/null +++ b/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx @@ -0,0 +1,32 @@ +interface CamBoxProps { + videoRef: React.RefObject; + defaultImag: 'ddung' | 'sponge'; + cameraConnected: boolean; +} + +const CamBox = ({ videoRef, defaultImag, cameraConnected }: CamBoxProps) => { + // const a = videoRef.current + // const imageSrc = `${}` + // const existVideo = videoRef.current?.srcObject ? true : false; + // console.log(cameraConnected); + return ( + <> +
    + {/* {!cameraConnected && ( + + )} */} +
    + + ); +}; + +export default CamBox; diff --git a/frontend/src/pages/HumanChatPage/CamBox/index.ts b/frontend/src/pages/HumanChatPage/CamBox/index.ts new file mode 100644 index 00000000..6e6c84db --- /dev/null +++ b/frontend/src/pages/HumanChatPage/CamBox/index.ts @@ -0,0 +1 @@ +export { default } from './CamBox'; diff --git a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx index e31d1de2..d7278a33 100644 --- a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx +++ b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx @@ -5,27 +5,26 @@ import CustomSelect from '@components/CustomSelect'; import { useWebRTC } from '@business/hooks/useWebRTC'; +import CamBox from './CamBox'; + export default function HumanChatPage() { const { roomName } = useParams(); - const { cameraOptions, localVideoRef, remoteVideoRef, toggleAudio, toggleVideo, changeCamera } = useWebRTC( - roomName as string, - ); + const { cameraOptions, localVideoRef, remoteVideoRef, toggleAudio, toggleVideo, changeCamera, cameraConnected } = + useWebRTC(roomName as string); return (
    -
    -
    diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 68624bd7..d6e9f64f 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -53,6 +53,10 @@ export default { tarotHovering: 'tarotHovering 0.5s ease-in-out forwards', tarotLeaving: 'tarotLeaving 0.3s ease-in-out forwards', }, + backgroundImage: { + ddung: "url('/ddung.png')", + sponge: "url('/sponge.png')", + }, }, }, plugins: [ From 7049f4d1f7f6c6df6e64f4c48d402d8cb3f2b4aa Mon Sep 17 00:00:00 2001 From: Song_Minhyung Date: Thu, 23 Nov 2023 22:40:41 +0900 Subject: [PATCH 22/35] =?UTF-8?q?feat:=20=EC=B9=B4=EB=A9=94=EB=9D=BC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=98=EB=A9=B4=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=9E=90=EC=97=90=EA=B2=8C=EB=8F=84=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=EB=90=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/business/hooks/useWebRTC.ts | 26 ++++++++++++++++--- .../src/pages/HumanChatPage/CamBox/CamBox.tsx | 16 +++--------- .../src/pages/HumanChatPage/HumanChatPage.tsx | 21 ++++++++++----- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/frontend/src/business/hooks/useWebRTC.ts b/frontend/src/business/hooks/useWebRTC.ts index 148c6fda..e494b929 100644 --- a/frontend/src/business/hooks/useWebRTC.ts +++ b/frontend/src/business/hooks/useWebRTC.ts @@ -25,10 +25,6 @@ export function useWebRTC(roomName: string) { const { initSignalingSocket, closePeerConnection } = useSignalingSocket({ roomName, peerConnectionRef }); const makeConnection = () => { - if (localStreamRef.current === undefined) { - return; - } - peerConnectionRef.current = new RTCPeerConnection({ iceServers: [{ urls: iceServers }] }); peerConnectionRef.current.addEventListener('track', e => { @@ -47,17 +43,36 @@ export function useWebRTC(roomName: string) { socketEmit('candidate', e.candidate, roomName); setCameraConnected(prev => ({ ...prev, remote: true })); }); + }; + const addTracks = () => { + if (localStreamRef.current === undefined) { + return; + } localStreamRef.current.getTracks().forEach(track => { peerConnectionRef.current?.addTrack(track, localStreamRef.current!); }); }; + + const changeVideoTrack = () => { + const nowTrack = localStreamRef.current?.getVideoTracks()[0]; + const sender = peerConnectionRef.current?.getSenders().find(sender => sender.track?.kind === 'video'); + sender?.replaceTrack(nowTrack!); + }; + + const changeAudioTrack = () => { + const nowTrack = localStreamRef.current?.getAudioTracks()[0]; + const sender = peerConnectionRef.current?.getSenders().find(sender => sender.track?.kind === 'audio'); + sender?.replaceTrack(nowTrack!); + }; + useEffect(() => { const init = async () => { await getMedia(); setCameraConnected(prev => ({ ...prev, local: true })); initSignalingSocket(); makeConnection(); + addTracks(); socketEmit('joinRoom', roomName); }; init(); @@ -76,5 +91,8 @@ export function useWebRTC(roomName: string) { toggleAudio, toggleVideo, changeCamera, + addTracks, + changeVideoTrack, + changeAudioTrack, }; } diff --git a/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx b/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx index 50a2804b..c23cd737 100644 --- a/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx +++ b/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx @@ -1,25 +1,15 @@ interface CamBoxProps { videoRef: React.RefObject; - defaultImag: 'ddung' | 'sponge'; + defaultImage: 'bg-ddung' | 'bg-sponge'; cameraConnected: boolean; } -const CamBox = ({ videoRef, defaultImag, cameraConnected }: CamBoxProps) => { - // const a = videoRef.current - // const imageSrc = `${}` - // const existVideo = videoRef.current?.srcObject ? true : false; - // console.log(cameraConnected); +const CamBox = ({ videoRef, defaultImage, cameraConnected }: CamBoxProps) => { return ( <>
    - {/* {!cameraConnected && ( - - )} */}
    video mic { - changeCamera(value); + onChange={async ({ value }) => { + await changeCamera(value); + changeVideoTrack(); }} options={cameraOptions.map(({ deviceId, label }) => ({ label, value: deviceId }))} /> From 2b906eabafca853dd95da2a3fd19da062b128e44 Mon Sep 17 00:00:00 2001 From: Song_Minhyung Date: Mon, 27 Nov 2023 15:50:46 +0900 Subject: [PATCH 23/35] =?UTF-8?q?fix:=20server=EC=B8=A1=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - joinRoom, roomFull --- signal_server_dev/src/server.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/signal_server_dev/src/server.js b/signal_server_dev/src/server.js index b2d30ccc..4944363d 100644 --- a/signal_server_dev/src/server.js +++ b/signal_server_dev/src/server.js @@ -26,13 +26,12 @@ const MAXIMUM = 2; io.on('connection', socket => { console.log(socket.id, 'connection'); - socket.on('join_room', roomId => { + socket.on('joinRoom', roomId => { // 방이 기존에 생성 됐다면 if (socketRooms[roomId]) { const currentRoomUsersCnt = socketRooms[roomId].length; if (currentRoomUsersCnt === MAXIMUM) { - socket.emit('room_full'); - console.log('full'); + socket.emit('roomFull'); return; } From a5dec7214774ef7dfa7dd7bf1f3b9d5db57fd2c3 Mon Sep 17 00:00:00 2001 From: Song_Minhyung Date: Mon, 27 Nov 2023 16:10:27 +0900 Subject: [PATCH 24/35] feat: CamBox --- .../src/pages/HumanChatPage/CamBox/CamBox.tsx | 21 +++++++++++++++---- .../src/pages/HumanChatPage/HumanChatPage.tsx | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx b/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx index c23cd737..613a1247 100644 --- a/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx +++ b/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx @@ -1,19 +1,32 @@ +import { Icon } from '@iconify/react/dist/iconify.js'; + interface CamBoxProps { videoRef: React.RefObject; defaultImage: 'bg-ddung' | 'bg-sponge'; - cameraConnected: boolean; + cameraConnected?: boolean; + audioConnected?: boolean; } -const CamBox = ({ videoRef, defaultImage, cameraConnected }: CamBoxProps) => { +const CamBox = ({ videoRef, defaultImage, cameraConnected, audioConnected }: CamBoxProps) => { return ( <> -
    +
    ); diff --git a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx index 294a3a8f..233a5fb6 100644 --- a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx +++ b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx @@ -23,7 +23,7 @@ export default function HumanChatPage() { return (
    -
    +
    Date: Mon, 27 Nov 2023 17:32:03 +0900 Subject: [PATCH 25/35] =?UTF-8?q?desing:=20=EA=B8=80=EC=94=A8=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=BB=A4=EC=84=9C?= =?UTF-8?q?=20=EC=98=B5=EC=85=98=20=ED=98=B8=EB=B2=84=EB=A7=81=20=ED=9A=A8?= =?UTF-8?q?=EA=B3=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/tailwind.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 68624bd7..d865e9e5 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -69,6 +69,7 @@ export default { }; const textTheme = { + '.text-point': { color: '#7890E7' }, '.text-strong': { color: '#14212B' }, '.text-bold': { color: '#4B5966' }, '.text-default': { color: '#5E6E76' }, @@ -138,7 +139,7 @@ export default { mixBlendMode: 'difference', background: '#fff', }, - '.cursor:has(~ div button:hover), .cursor:has(~ div input:hover), .cursor:has(~ div a:hover), .cursor:has(~ div audio:hover)': + '.cursor:has(~ div button:hover), .cursor:has(~ div input:hover), .cursor:has(~ div a:hover), .cursor:has(~ div audio:hover), .cursor:has(~ div .option:hover)': { transition: 'transform 0.1s ease-in-out', transform: 'translate(-50%, -50%) scale(2)', From 208c238d664de6754003439f6e86997334249077 Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 17:32:44 +0900 Subject: [PATCH 26/35] =?UTF-8?q?feat:=20=ED=9C=B4=EB=A8=BC=EC=B1=97?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 높이 고정 해제 - 한줄 함수 --- frontend/src/pages/HumanChatPage/HumanChatPage.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx index e31d1de2..945d03c1 100644 --- a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx +++ b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx @@ -28,13 +28,11 @@ export default function HumanChatPage() { playsInline />
    -
    +
    video mic { - changeCamera(value); - }} + onChange={({ value }) => changeCamera(value)} options={cameraOptions.map(({ deviceId, label }) => ({ label, value: deviceId }))} />
    From 4567d8e695844f486b503baeff4d233fd7fa1c18 Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 17:40:35 +0900 Subject: [PATCH 27/35] =?UTF-8?q?design:=20=EC=BB=A4=EC=84=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EA=B0=95=EC=A0=9C=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/tailwind.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/tailwind.css b/frontend/src/tailwind.css index dd2c1a68..3f36daac 100644 --- a/frontend/src/tailwind.css +++ b/frontend/src/tailwind.css @@ -31,7 +31,7 @@ img { *:hover, *::-webkit-media-controls-play-button { - cursor: none; + cursor: none !important; } ::-webkit-scrollbar { From 7193414e6ccaa0f03bd95180c15edf1dd14b7a18 Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 17:41:14 +0900 Subject: [PATCH 28/35] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20sel?= =?UTF-8?q?ect=20&=20option=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/CustomSelect/CustomSelect.tsx | 83 +++++++++++++------ frontend/src/pages/HomePage/HomePage.tsx | 3 +- 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/frontend/src/components/CustomSelect/CustomSelect.tsx b/frontend/src/components/CustomSelect/CustomSelect.tsx index 61a04293..ca93f7fe 100644 --- a/frontend/src/components/CustomSelect/CustomSelect.tsx +++ b/frontend/src/components/CustomSelect/CustomSelect.tsx @@ -1,43 +1,72 @@ -export interface OnChangeSelectFunction { +import { useRef, useState } from 'react'; + +import { Icon } from '@iconify/react'; + +export interface CustomSelectOptions { value: string; label: string; } -export interface CustomSelectOptions extends OnChangeSelectFunction { - selected?: boolean; -} - interface CustomSelectProps { + width?: string; options: CustomSelectOptions[]; - required?: boolean; autoFocus?: boolean; - onChange?: ({ value, label }: OnChangeSelectFunction) => void; + onChange?: ({ value, label }: CustomSelectOptions) => void; } -export default function CustomSelect({ options, required, autoFocus, onChange }: CustomSelectProps) { - const handleChange = (e: React.ChangeEvent) => { - const { selectedIndex, options } = e.target; - const { value, innerText } = options[selectedIndex]; +export default function CustomSelect({ width, autoFocus, onChange }: CustomSelectProps) { + const options: CustomSelectOptions[] = [ + { value: 'test1', label: '카메라1 테스트' }, + { value: 'test2', label: '카메라2 테스트' }, + { value: 'test3', label: '카메라3 테스트' }, + ]; + const [opened, setOpened] = useState(false); + const inputRef = useRef(null); + const [selected, setSelected] = useState(options.length ? options[0] : { value: '', label: '' }); - onChange?.({ value, label: innerText }); + const updateOption = (option: CustomSelectOptions) => { + inputRef.current?.click(); + if (option.value != selected.value) { + setSelected(option); + onChange?.(option); + } }; return ( - setOpened(!opened)} + /> +
    + {selected.label} + +
    +
    - {label} - - ))} - + {options.map(({ value, label }) => ( +

    updateOption({ value, label })} + > + {label} +

    + ))} +
    +
    +
    ); } diff --git a/frontend/src/pages/HomePage/HomePage.tsx b/frontend/src/pages/HomePage/HomePage.tsx index 697abad1..fdf894f1 100644 --- a/frontend/src/pages/HomePage/HomePage.tsx +++ b/frontend/src/pages/HomePage/HomePage.tsx @@ -16,7 +16,8 @@ function HomePage() { }; const moveHumanChat = () => { - navigate('/chat/human'); + // TODO: 실제 roomname 넣기 + navigate('/chat/human/1'); }; return ( From a2fc412507e5a325f4df0193aa6662cf2dda46fe Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 17:46:02 +0900 Subject: [PATCH 29/35] =?UTF-8?q?remove:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=83=80=EC=9E=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/CustomSelect/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/CustomSelect/index.ts b/frontend/src/components/CustomSelect/index.ts index 7c8c3955..34d58547 100644 --- a/frontend/src/components/CustomSelect/index.ts +++ b/frontend/src/components/CustomSelect/index.ts @@ -1,4 +1,4 @@ -import { CustomSelectOptions, OnChangeSelectFunction } from './CustomSelect'; +import { CustomSelectOptions } from './CustomSelect'; export { default } from './CustomSelect'; -export type { CustomSelectOptions, OnChangeSelectFunction }; +export type { CustomSelectOptions }; From 197de0559a26b582c3df3cf2aef0816ae2eab992 Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 17:50:46 +0900 Subject: [PATCH 30/35] =?UTF-8?q?design:=20=EC=98=B5=EC=85=98=EC=9D=98=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=EC=BB=A4=EC=84=9C=20=ED=98=B8?= =?UTF-8?q?=EB=B2=84=EB=A7=81=20=EC=A1=B0=EA=B1=B4=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/CustomSelect/CustomSelect.tsx | 2 +- frontend/tailwind.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/CustomSelect/CustomSelect.tsx b/frontend/src/components/CustomSelect/CustomSelect.tsx index ca93f7fe..5580e2b6 100644 --- a/frontend/src/components/CustomSelect/CustomSelect.tsx +++ b/frontend/src/components/CustomSelect/CustomSelect.tsx @@ -56,7 +56,7 @@ export default function CustomSelect({ width, autoFocus, onChange }: CustomSelec > {options.map(({ value, label }) => (

    Date: Mon, 27 Nov 2023 18:05:24 +0900 Subject: [PATCH 31/35] =?UTF-8?q?refactor:=20CamBox=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/{pages/HumanChatPage => components}/CamBox/CamBox.tsx | 0 frontend/src/{pages/HumanChatPage => components}/CamBox/index.ts | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename frontend/src/{pages/HumanChatPage => components}/CamBox/CamBox.tsx (100%) rename frontend/src/{pages/HumanChatPage => components}/CamBox/index.ts (100%) diff --git a/frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx b/frontend/src/components/CamBox/CamBox.tsx similarity index 100% rename from frontend/src/pages/HumanChatPage/CamBox/CamBox.tsx rename to frontend/src/components/CamBox/CamBox.tsx diff --git a/frontend/src/pages/HumanChatPage/CamBox/index.ts b/frontend/src/components/CamBox/index.ts similarity index 100% rename from frontend/src/pages/HumanChatPage/CamBox/index.ts rename to frontend/src/components/CamBox/index.ts From 38cffae6fc0faa8c01e85e4c336f715588d1b4ab Mon Sep 17 00:00:00 2001 From: Song_Minhyung Date: Mon, 27 Nov 2023 18:07:07 +0900 Subject: [PATCH 32/35] =?UTF-8?q?refactor:=20=EC=9D=B5=EB=AA=85=ED=95=A8?= =?UTF-8?q?=EC=88=98=20->=20changeMyCamera=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/HumanChatPage/HumanChatPage.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx index 233a5fb6..a6698a34 100644 --- a/frontend/src/pages/HumanChatPage/HumanChatPage.tsx +++ b/frontend/src/pages/HumanChatPage/HumanChatPage.tsx @@ -1,12 +1,11 @@ import { useParams } from 'react-router-dom'; import CustomButton from '@components/Buttons/CustomButton'; -import CustomSelect from '@components/CustomSelect'; +import CamBox from '@components/CamBox'; +import CustomSelect, { OnChangeSelectFunction } from '@components/CustomSelect'; import { useWebRTC } from '@business/hooks/useWebRTC'; -import CamBox from './CamBox'; - export default function HumanChatPage() { const { roomName } = useParams(); @@ -21,6 +20,11 @@ export default function HumanChatPage() { changeVideoTrack, } = useWebRTC(roomName as string); + const changeMyCamera = async ({ value }: OnChangeSelectFunction) => { + await changeCamera(value); + changeVideoTrack(); + }; + return (

    @@ -39,10 +43,7 @@ export default function HumanChatPage() { video mic { - await changeCamera(value); - changeVideoTrack(); - }} + onChange={changeMyCamera} options={cameraOptions.map(({ deviceId, label }) => ({ label, value: deviceId }))} />
    From 7d58be0389ea536ce83b6f0507a7b823a1bdc514 Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 18:09:12 +0900 Subject: [PATCH 33/35] =?UTF-8?q?feat:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/CustomSelect/CustomSelect.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/CustomSelect/CustomSelect.tsx b/frontend/src/components/CustomSelect/CustomSelect.tsx index 5580e2b6..2ef4283a 100644 --- a/frontend/src/components/CustomSelect/CustomSelect.tsx +++ b/frontend/src/components/CustomSelect/CustomSelect.tsx @@ -1,4 +1,4 @@ -import { useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Icon } from '@iconify/react'; @@ -14,15 +14,15 @@ interface CustomSelectProps { onChange?: ({ value, label }: CustomSelectOptions) => void; } -export default function CustomSelect({ width, autoFocus, onChange }: CustomSelectProps) { - const options: CustomSelectOptions[] = [ - { value: 'test1', label: '카메라1 테스트' }, - { value: 'test2', label: '카메라2 테스트' }, - { value: 'test3', label: '카메라3 테스트' }, - ]; +export default function CustomSelect({ width, options, autoFocus, onChange }: CustomSelectProps) { + console.log('CustomSelect', options); const [opened, setOpened] = useState(false); const inputRef = useRef(null); - const [selected, setSelected] = useState(options.length ? options[0] : { value: '', label: '' }); + const [selected, setSelected] = useState({ value: '', label: '' }); + + useEffect(() => { + if (options.length) setSelected(options[0]); + }, [options]); const updateOption = (option: CustomSelectOptions) => { inputRef.current?.click(); @@ -34,7 +34,7 @@ export default function CustomSelect({ width, autoFocus, onChange }: CustomSelec return (
    -
    +
    Date: Mon, 27 Nov 2023 18:10:02 +0900 Subject: [PATCH 34/35] =?UTF-8?q?remove:=20=EC=BD=98=EC=86=94=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/CustomSelect/CustomSelect.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/CustomSelect/CustomSelect.tsx b/frontend/src/components/CustomSelect/CustomSelect.tsx index 2ef4283a..c068cf57 100644 --- a/frontend/src/components/CustomSelect/CustomSelect.tsx +++ b/frontend/src/components/CustomSelect/CustomSelect.tsx @@ -15,7 +15,6 @@ interface CustomSelectProps { } export default function CustomSelect({ width, options, autoFocus, onChange }: CustomSelectProps) { - console.log('CustomSelect', options); const [opened, setOpened] = useState(false); const inputRef = useRef(null); const [selected, setSelected] = useState({ value: '', label: '' }); From ffc3f2b1b4d149a40685c0f96154849d14277ad3 Mon Sep 17 00:00:00 2001 From: iQuQi Date: Mon, 27 Nov 2023 18:19:26 +0900 Subject: [PATCH 35/35] =?UTF-8?q?review:=20=20=EB=8A=90=EC=8A=A8=ED=95=9C?= =?UTF-8?q?=20=EB=B9=84=EA=B5=90=EC=97=90=EC=84=9C=20=EC=97=84=EA=B2=A9?= =?UTF-8?q?=ED=95=9C=20=EB=B9=84=EA=B5=90=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/CustomSelect/CustomSelect.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/CustomSelect/CustomSelect.tsx b/frontend/src/components/CustomSelect/CustomSelect.tsx index c068cf57..526627a4 100644 --- a/frontend/src/components/CustomSelect/CustomSelect.tsx +++ b/frontend/src/components/CustomSelect/CustomSelect.tsx @@ -25,7 +25,7 @@ export default function CustomSelect({ width, options, autoFocus, onChange }: Cu const updateOption = (option: CustomSelectOptions) => { inputRef.current?.click(); - if (option.value != selected.value) { + if (option.value !== selected.value) { setSelected(option); onChange?.(option); } @@ -55,7 +55,7 @@ export default function CustomSelect({ width, options, autoFocus, onChange }: Cu > {options.map(({ value, label }) => (