Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] πŸš€ νŽ˜μ–΄λ£Έ μ’…λ£Œ μƒνƒœ STOMP κ΅¬ν˜„ #1120

Merged
merged 3 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions frontend/src/hooks/PairRoom/usePairRoomStatusSocket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

import useSocketStore from '@/stores/socketStore';
import useToastStore from '@/stores/toastStore';

import type { PairRoomStatus } from '@/apis/http/pairRoom';
import { subscribeTopic } from '@/apis/websocket/websocket';

const usePairRoomStatusSocket = (defaultStatus: PairRoomStatus) => {
const navigate = useNavigate();

const { client, isConnected, accessCode } = useSocketStore();
const { addToast } = useToastStore();

const [status, setStatus] = useState<PairRoomStatus>(defaultStatus);

const handleStatus = (status: PairRoomStatus) => setStatus(status);

useEffect(() => {
if (defaultStatus === 'COMPLETED') {
navigate(`/room/${accessCode}/completed`, { state: { valid: true }, replace: true });
}

if (status === 'COMPLETED') {
addToast({ status: 'WARNING', message: 'νŽ˜μ–΄λ£Έμ΄ μ’…λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.' });
navigate(`/room/${accessCode}/retrospectForm`, { state: { valid: true } });
}
}, [status]);

useEffect(() => {
if (client && isConnected) {
subscribeTopic<{ status: PairRoomStatus }>(client, `/topic/${accessCode}/pair-room/status`, (body) =>
handleStatus(body.status),
);
}

return () => {
if (client && isConnected) {
client.unsubscribe(`/topic/${accessCode}/pair-room/status`);
}
};
}, [client]);

return { status };
};

export default usePairRoomStatusSocket;
5 changes: 3 additions & 2 deletions frontend/src/hooks/PairRoom/useReferenceSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import useSocketStore from '@/stores/socketStore';
import { Reference } from '@/apis/http/referenceLink';
import { subscribeTopic } from '@/apis/websocket/websocket';

const useReference = (defaultReferences: Reference[]) => {
const useReference = (defaultReferences: Reference[], categoryName: string) => {
const { client, isConnected, accessCode } = useSocketStore();

const [references, setReferences] = useState<Reference[]>(defaultReferences);

const handleReferences = (references: Reference[]) => setReferences(references);
const handleReferences = (references: Reference[]) =>
setReferences(references.filter((reference) => reference.categoryName === categoryName));

useEffect(() => {
if (client && isConnected) {
Expand Down
8 changes: 0 additions & 8 deletions frontend/src/hooks/PairRoom/useTimerSocket.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState, useRef, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

import { AlarmSound } from '@/assets';

Expand All @@ -12,15 +11,13 @@ import { subscribeTopic } from '@/apis/websocket/websocket';
import useNotification from '@/hooks/PairRoom/useNotification';

enum TimerStatus {
COMPLETE = 'complete',
START = 'start',
RUNNING = 'running',
PAUSE = 'pause',
UPDATE = 'update',
}

const useTimer = (defaultTime: number, defaultTimeLeft: number, onTimerStop: () => void) => {
const navigate = useNavigate();
const durationRef = useRef(defaultTime);

const { client, isConnected, accessCode } = useSocketStore();
Expand Down Expand Up @@ -65,11 +62,6 @@ const useTimer = (defaultTime: number, defaultTimeLeft: number, onTimerStop: ()

const handleTimerStatusEvent = (status: TimerStatus, data: number | null) => {
switch (status) {
case TimerStatus.COMPLETE:
navigate(`/room/${accessCode}/retrospectForm`, { state: { valid: true } });
addToast({ status: 'WARNING', message: 'νŽ˜μ–΄λ£Έμ΄ μ’…λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.' });
break;

case TimerStatus.START:
setIsActive(true);
addToast({ status: 'SUCCESS', message: '타이머가 μ‹œμž‘λ˜μ—ˆμŠ΅λ‹ˆλ‹€.' });
Expand Down
29 changes: 14 additions & 15 deletions frontend/src/pages/PairRoom/PairRoom.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useParams } from 'react-router-dom';

import Loading from '@/pages/Loading/Loading';

Expand All @@ -14,45 +14,44 @@ import useSocketStore from '@/stores/socketStore';

import useModal from '@/hooks/_common/useModal';
import usePairRoom from '@/hooks/PairRoom/usePairRoom';
import usePairRoomStatusSocket from '@/hooks/PairRoom/usePairRoomStatusSocket';

import usePairRoomMutation from '@/queries/PairRoom/usePairRoomMutation';
import usePairRoomQuery from '@/queries/PairRoom/usePairRoomQuery';

import * as S from './PairRoom.styles';

const PairRoom = () => {
const navigate = useNavigate();
const { accessCode } = useParams();

// μ›Ήμ†ŒμΌ“ μ—°κ²°
usePairRoom();
const { isConnected } = useSocketStore();

const [driver, setDriver] = useState('');
const [navigator, setNavigator] = useState('');
const [isCardOpen, setIsCardOpen] = useState(false);

const {
driver: latestDriver,
navigator: latestNavigator,
status,
status: defaultStatus,
missionUrl,
duration,
remainingTime,
duration: defaultTime,
remainingTime: defaultTimeLeft,
isFetching,
todos,
references,
categories,
} = usePairRoomQuery(accessCode || '');

// μ›Ήμ†ŒμΌ“ μ—°κ²°
usePairRoom();
const { isConnected } = useSocketStore();

// νŽ˜μ–΄λ£Έ μƒνƒœ μ›Ήμ†ŒμΌ“
usePairRoomStatusSocket(defaultStatus);

const { updatePairRoleMutation } = usePairRoomMutation();

const { isModalOpen, closeModal } = useModal(true);

useEffect(() => {
if (status === 'COMPLETED') navigate(`/room/${accessCode}/completed`, { state: { valid: true }, replace: true });
}, [status]);

useEffect(() => {
setDriver(latestDriver);
setNavigator(latestNavigator);
Expand All @@ -68,8 +67,8 @@ const PairRoom = () => {
<S.Container>
<PairRoleCard driver={driver} navigator={navigator} />
<TimerCard
defaultTime={duration}
defaultTimeLeft={remainingTime}
defaultTime={defaultTime}
defaultTimeLeft={defaultTimeLeft}
onTimerStop={() => updatePairRoleMutation({ accessCode: accessCode || '' })}
/>
</S.Container>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/queries/PairRoom/usePairRoomQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect } from 'react';

import { useQuery, useQueryClient } from '@tanstack/react-query';

import { getPairRoom } from '@/apis/http/pairRoom';
import { getPairRoom, PairRoomStatus } from '@/apis/http/pairRoom';

import { QUERY_KEYS } from '@/constants/queryKeys';

Expand All @@ -26,7 +26,7 @@ const usePairRoomQuery = (accessCode: string) => {
return {
driver: pairRoom?.driver || '',
navigator: pairRoom?.navigator || '',
status: pairRoom?.status || '',
status: (pairRoom?.status as PairRoomStatus) || '',
missionUrl: pairRoom?.missionUrl || '',
duration: pairRoom?.duration || 0,
remainingTime: pairRoom?.remainingTime || 0,
Expand Down
Loading