Skip to content

Commit

Permalink
Merge pull request codestates-seb#389 from shimdokite/hotfix
Browse files Browse the repository at this point in the history
[FE] πŸ› μ±„νŒ… μž…μž₯ λ©”μ‹œμ§€ 이슈 ν•΄κ²°
  • Loading branch information
nalsae authored May 9, 2024
2 parents 01a7151 + cb5fa29 commit 03ed643
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 116 deletions.
9 changes: 3 additions & 6 deletions client/src/api/axios.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import axios, { AxiosResponse } from 'axios';

import LocalStorage from './localStorage';

import checkForToken from '@/utils/checkForToken';
import LocalStorage from '@/utils/localStorage';

const { authVerify, storageData } = checkForToken();

const accessToken =
typeof window !== 'undefined' ? storageData.state.accessToken : null;
const refreshToken =
typeof window !== 'undefined' ? storageData.state.refreshToken : null;
const accessToken = storageData?.state.accessToken;
const refreshToken = storageData?.state.refreshToken;

export const instance = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
Expand Down
62 changes: 54 additions & 8 deletions client/src/components/inquiry/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
'use client';

import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { useEffect, useRef, useState } from 'react';
import InfiniteScroll from 'react-infinite-scroller';

import { CompatClient, Stomp, StompSubscription } from '@stomp/stompjs';
import SockJS from 'sockjs-client';

import useUserStore from '@/stores/userStore';
import useChatStore from '@/stores/chatStore';

import useScrollToBottom from '@/hooks/useScrollToBottom';

import useChatMessageQuery from '@/hooks/query/useChatMessageQuery';
import useNewChatAndExistChatConnect from '@/hooks/useNewChatAndExistChatConnect';

import { ChatInput, ChatBox } from '.';

import checkForToken from '@/utils/checkForToken';

import { ChatInfo } from '@/types/data';

interface ChatProps {
role: 'user' | 'admin';
}

export default function Chat({ role }: ChatProps) {
const client = useRef<CompatClient>();

const [connected, setConnected] = useState(false);
const [chat, setChat] = useState<ChatInfo[]>([]);

const router = useRouter();

const { roomId, message, isNewChatConnect, setMessage } = useChatStore();
const { userId, displayName, setClear } = useUserStore();
const { roomId, message, setMessage } = useChatStore();
const { accessToken, refreshToken, userId, displayName, setClear } =
useUserStore();

const { setConnected, setChat, client, scrollRef, chat, connected } =
useNewChatAndExistChatConnect(isNewChatConnect);
const scrollRef = useScrollToBottom(chat);

const {
data: messageList,
Expand All @@ -35,6 +46,10 @@ export default function Chat({ role }: ChatProps) {

const { authVerify } = checkForToken();

const url = process.env.NEXT_PUBLIC_API_URL;

let subscription: StompSubscription | undefined;

const newMessge = {
senderId: +userId,
chatRoomId: roomId,
Expand All @@ -49,7 +64,9 @@ export default function Chat({ role }: ChatProps) {
authVerify() === 'Refresh Token Expired'
) {
return (
alert('토큰이 λ§Œλ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ 둜그인 ν•΄μ£Όμ‹œκΈΈ λ°”λžλ‹ˆλ‹€.'),
alert(
'토큰이 λ§Œλ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‘œκ·Έμ•„μ›ƒ ν›„ λ‹€μ‹œ 둜그인 ν•΄μ£Όμ‹œκΈΈ λ°”λžλ‹ˆλ‹€.',
),
setConnected(false),
setClear(),
setMessage(''),
Expand All @@ -58,7 +75,6 @@ export default function Chat({ role }: ChatProps) {
}

client?.current?.send(`/pub/chatRoom/send`, {}, JSON.stringify(newMessge));

setMessage('');
};

Expand All @@ -68,6 +84,36 @@ export default function Chat({ role }: ChatProps) {
}
}, [messageList]);

useEffect(() => {
client.current = Stomp.over(() => new SockJS(`${url}/wss`));
client.current.debug = () => {};
client.current.connect(
{
Authorization: accessToken,
refresh: refreshToken,
},
() => {
subscription = client?.current?.subscribe(
`/sub/chatRoom/${roomId}`,
(payload) => {
const receivedMessage: ChatInfo = JSON.parse(payload.body);

setChat((previousChat) => [...previousChat, receivedMessage]);
},
);

setConnected(true);
},
);

return () => {
client.current?.disconnect(() => {
subscription?.unsubscribe();
setConnected(false);
});
};
}, []);

return (
<section className="w-full">
<div
Expand Down
72 changes: 65 additions & 7 deletions client/src/components/inquiry/NewChat.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,55 @@
'use client';

import { useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { CompatClient, Stomp, StompSubscription } from '@stomp/stompjs';
import SockJS from 'sockjs-client';

import useUserStore from '@/stores/userStore';
import useChatStore from '@/stores/chatStore';

import useNewChatAndExistChatConnect from '@/hooks/useNewChatAndExistChatConnect';
import useScrollToBottom from '@/hooks/useScrollToBottom';

import { ChatInput, ChatBox } from '.';

import checkForToken from '@/utils/checkForToken';

import { ChatInfo } from '@/types/data';

interface NewChatProps {
role: 'user' | 'admin';
}

export default function NewChat({ role }: NewChatProps) {
const client = useRef<CompatClient>();

const [connected, setConnected] = useState(false);
const [chat, setChat] = useState<ChatInfo[]>([]);

const router = useRouter();

const { message, roomId, isNewChatConnect, setMessage } = useChatStore();
const { displayName, userId, setClear } = useUserStore();
const { message, setMessage, roomId } = useChatStore();
const { accessToken, refreshToken, displayName, userId, setClear } =
useUserStore();

const { setConnected, client, scrollRef, chat, connected } =
useNewChatAndExistChatConnect(isNewChatConnect);
const scrollRef = useScrollToBottom(chat);

const { authVerify } = checkForToken();

const url = process.env.NEXT_PUBLIC_API_URL;

let subscription: StompSubscription | undefined;

const entryMessage = () => {
const adminId = 101;

client?.current?.send(
`/pub/chatRoom/enter`,
{},
JSON.stringify({ senderId: +userId, chatRoomId: +roomId, adminId }),
);
};

const newMessge = {
senderId: +userId,
chatRoomId: roomId,
Expand All @@ -40,7 +64,9 @@ export default function NewChat({ role }: NewChatProps) {
authVerify() === 'Refresh Token Expired'
) {
return (
alert('토큰이 λ§Œλ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ 둜그인 ν•΄μ£Όμ‹œκΈΈ λ°”λžλ‹ˆλ‹€.'),
alert(
'토큰이 λ§Œλ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‘œκ·Έμ•„μ›ƒ ν›„ λ‹€μ‹œ 둜그인 ν•΄μ£Όμ‹œκΈΈ λ°”λžλ‹ˆλ‹€.',
),
setConnected(false),
setClear(),
setMessage(''),
Expand All @@ -49,10 +75,42 @@ export default function NewChat({ role }: NewChatProps) {
}

client?.current?.send(`/pub/chatRoom/send`, {}, JSON.stringify(newMessge));

setMessage('');
};

useEffect(() => {
if (roomId) {
client.current = Stomp.over(() => new SockJS(`${url}/wss`));
client.current.debug = () => {};
client.current.connect(
{
Authorization: accessToken,
refresh: refreshToken,
},
() => {
subscription = client?.current?.subscribe(
`/sub/chatRoom/${roomId}`,
(payload) => {
const receivedMessage: ChatInfo = JSON.parse(payload.body);

setChat((previousChat) => [...previousChat, receivedMessage]);
},
);

entryMessage();
setConnected(true);
},
);
}

return () => {
client.current?.disconnect(() => {
subscription?.unsubscribe();
setConnected(false);
});
};
}, [roomId]);

return (
<section className="w-full">
<div
Expand Down
81 changes: 0 additions & 81 deletions client/src/hooks/useNewChatAndExistChatConnect.ts

This file was deleted.

17 changes: 17 additions & 0 deletions client/src/hooks/useScrollToBottom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect, useRef } from 'react';

import { ChatInfo } from '@/types/data';

const useScrollToBottom = (chat: ChatInfo[]) => {
const scrollRef = useRef<HTMLDivElement | null>(null);

useEffect(() => {
if (!scrollRef.current) return;

scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}, [chat]);

return scrollRef;
};

export default useScrollToBottom;
9 changes: 0 additions & 9 deletions client/src/stores/chatStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,20 @@ import { ChatList } from '@/types/data';

interface ChatState {
chatList: ChatList[];

selected: string;
message: string;
title: string;
roomId: string;
questionerId: string;
isOpen: boolean;
isNewChatConnect: boolean;

setChatList: (chatList: ChatList[]) => void;

setSelected: (selected: string) => void;
setMessage: (message: string) => void;
setTitle: (title: string) => void;
setRoomId: (roomId: string) => void;
setQuestionerId: (questionerId: string) => void;
setIsOpen: (isOpen: boolean) => void;
setIsNewChatConnect: (isNewChat: boolean) => void;
}

const useChatStore = create<ChatState>((set) => ({
Expand All @@ -34,7 +30,6 @@ const useChatStore = create<ChatState>((set) => ({
questionerId: '',

isOpen: false,
isNewChatConnect: false,

setChatList: (chatList) => {
set(() => ({ chatList }));
Expand Down Expand Up @@ -63,10 +58,6 @@ const useChatStore = create<ChatState>((set) => ({
setIsOpen(isOpen) {
set({ isOpen, selected: 'home' });
},

setIsNewChatConnect(isNewChatConnect) {
set({ isNewChatConnect });
},
}));

export default useChatStore;
Loading

0 comments on commit 03ed643

Please sign in to comment.