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] FIX: 버그 수정 #253 #254

Merged
merged 14 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from 12 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
8 changes: 4 additions & 4 deletions src/backend/auth-server/src/auth/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ export const TOKEN_TYPE = {
} as const;

export const TOKEN_EXPIRATION_TIME = {
ACCESS: 300, // 5분
REFRESH: 3600, // 1시간
// ACCESS: 3600, // 1시간
// REFRESH: 604800, // 7일
// ACCESS: 300, // 5분
// REFRESH: 3600, // 1시간
ACCESS: 3600, // 1시간
REFRESH: 604800, // 7일
} as const;

export const RAW_TOKEN_TYPE = {
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { queryClient } from '@/lib/react-query';
import { useUserStore } from './stores/useUserStore';

const ProtectedRoute = ({ children }: { children: JSX.Element }) => {
const { user } = useUserStore();
const user = useUserStore(state => state.user);

if (!user) {
return <Navigate to="/login" replace />;
Expand Down
33 changes: 33 additions & 0 deletions src/frontend/src/api/endpoints/room/room.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export const roomApi = {
}
},

// 엘라스틱서치 검색
searchFromElastic: async (keyword: string) => {
try {
const { data } = await instance.get<ElasticSearchDto>(`/search`, { params: { keyword } });
Expand All @@ -167,4 +168,36 @@ export const roomApi = {
throw error;
}
},

// 방 초대 수락
acceptInvitation: async (roomId: number, me: number, senderId: number, roomCode: string) => {
try {
const { data } = await instance.post(`/rooms/invitations/accept`, {
senderId,
receiverId: me,
roomId,
roomCode,
});
return data;
} catch (error) {
logAxiosError(error, ErrorType.ROOM, '방 초대 수락 실패');
throw error;
}
},

// 방 초대 거절
rejectInvitation: async (roomId: number, me: number, senderId: number, roomCode: string) => {
try {
const { data } = await instance.post(`/rooms/invitations/reject`, {
senderId,
receiverId: me,
roomId,
roomCode,
});
return data;
} catch (error) {
logAxiosError(error, ErrorType.ROOM, '방 초대 거절 실패');
throw error;
}
},
};
1 change: 1 addition & 0 deletions src/frontend/src/components/LeftNavBar/index.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const ButtonWrapper = styled.div`
`;

export const ButtonBox = styled.div<{ $isActive: boolean }>`
position: relative;
width: 40px;
height: 40px;
display: flex;
Expand Down
5 changes: 5 additions & 0 deletions src/frontend/src/components/LeftNavBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import PlaylistLineIcon from '@/assets/img/PlaylistLine.svg';
import UsersFillIcon from '@/assets/img/UsersFill.svg';
import UsersLineIcon from '@/assets/img/UsersLine.svg';
import { ButtonBox, ButtonContainer, ButtonWrapper } from './index.css';
import { NotificationCount } from '@/ui/Common.css';
import { useMyRoomsStore } from '@/stores/useMyRoomsStore';

export const LeftNavBar = () => {
const location = useLocation();
const isHome = location.pathname === '/';
const isMyRoom = location.pathname === '/my-room';
const isFriend = location.pathname === '/friend';
const newChatCount = useMyRoomsStore((state) => state.newChatCount);


return (
<ButtonContainer>
Expand All @@ -27,6 +31,7 @@ export const LeftNavBar = () => {
<Link to="/my-room">
<ButtonBox $isActive={isMyRoom}>
<img src={isMyRoom ? PlaylistFillIcon : PlaylistLineIcon} alt="my Room" />
{newChatCount > 0 && <NotificationCount>{newChatCount}</NotificationCount>}
</ButtonBox>
<p>MY</p>
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const RegisterSuccessModal = ({ onCancel }: IRegisterSuccessModal) => {
const navigate = useNavigate();

const handleConfirm = () => {
if (window.webkit?.messageHandlers?.messageHandler) {
window.webkit.messageHandlers.messageHandler.postMessage('LoginSuccess');
}
navigate('/login');
onCancel();
};
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/components/RoomDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useCurrentRoomStore } from '@/stores/useCurrentRoomStore';
import DefaultProfile from '@/assets/img/DefaultProfile.svg';

export const RoomDetail = () => {
const { currentRoom } = useCurrentRoomStore();
const currentRoom = useCurrentRoomStore(state => state.currentRoom);
const roomInfo = currentRoom?.roomDetails.roomInfo[0];

const handleDescription = () => {
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/pages/MyRoomPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
export const MyRoomPage = () => {
const { data } = useMyRooms();
const { user } = useUserStore();
const { myRooms, setMyRooms, clearMyRooms } = useMyRoomsStore();
const { myRooms, setMyRooms, clearMyRooms, resetNewChatCount } = useMyRoomsStore();
const showSkeleton = useDelayedLoading(data);

useEffect(() => {
if (data) {
setMyRooms(data);
resetNewChatCount();
} else {
clearMyRooms();
}
}, [clearMyRooms, setMyRooms, data]);

Check warning on line 24 in src/frontend/src/pages/MyRoomPage/index.tsx

View workflow job for this annotation

GitHub Actions / frontend-ci

React Hook useEffect has a missing dependency: 'resetNewChatCount'. Either include it or remove the dependency array

if (showSkeleton) {
return <MyRoomSkeleton />;
Expand Down
9 changes: 7 additions & 2 deletions src/frontend/src/pages/RoomPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@
import { useVideoStore } from '@/stores/useVideoStore';
import { getVideoQueueFromPlaylist } from '@/utils/playlistUtils';
import { useWebSocketStore } from '@/stores/useWebSocketStore';
import { useMyRoomsStore } from '@/stores/useMyRoomsStore';

export const RoomPage = () => {
const [searchParams] = useSearchParams();
const roomCode = searchParams.get('code');
const { data: room } = useCurrentRoom(roomCode);
console.log('RoomPage:', room);
const { setVideoQueue } = useVideoStore();
const { subscribeRoomPlaylistUpdate } = useWebSocketStore();
const { roomId } = useCurrentRoomStore();
const roomId = useCurrentRoomStore(state => state.roomId);

useEffect(() => {
if (room) {
Expand All @@ -35,8 +37,11 @@
}
return () => {
useCurrentRoomStore.getState().clearCurrentRoom();
if (roomId) {
useMyRoomsStore.getState().subscribeRoom(roomId);
}
};
}, [room]);
}, []);

Check warning on line 44 in src/frontend/src/pages/RoomPage/index.tsx

View workflow job for this annotation

GitHub Actions / frontend-ci

React Hook useEffect has missing dependencies: 'room' and 'roomId'. Either include them or remove the dependency array

// YouTube API를 이용하여 영상 정보(제목 & 유튜버) 가져오기
const fetchVideoDetails = async (videoIds: string[]) => {
Expand Down
6 changes: 5 additions & 1 deletion src/frontend/src/sentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ Sentry.init({

// Set `tracePropagationTargets` to control for which URLs trace propagation should be enabled
// tracePropagationTargets: [/^\//, /^https:\/\/yourserver\.io\/api/],
tracePropagationTargets: ['localhost'],
tracePropagationTargets: [
'localhost',
/^http:\/\/kicktube\.site/,
/^http:\/\/13\.231\.39\.189:8000\/api/,
],

// Capture Replay for 100% of all sessions,
// plus for 100% of sessions with an error
Expand Down
10 changes: 10 additions & 0 deletions src/frontend/src/stores/useAuthStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import axios from 'axios';
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { useFriendStore } from './useFriendStore';
import { useNotificationStore } from './useNotificationStore';
import { useUserStore } from './useUserStore';
import { useMyRoomsStore } from './useMyRoomsStore';
import { useWebSocketStore } from './useWebSocketStore';

const instance = axios.create({
baseURL: import.meta.env.VITE_API_URL,
Expand Down Expand Up @@ -31,6 +36,11 @@ export const useAuthStore = create(
},
clear: () => {
set({ accessToken: null });
useFriendStore.getState().clear();
useNotificationStore.getState().clear();
useMyRoomsStore.getState().clearMyRooms();
useUserStore.getState().clearProfile();
useWebSocketStore.getState().disconnect();
},
}),
{
Expand Down
39 changes: 34 additions & 5 deletions src/frontend/src/stores/useMyRoomsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ import { useCurrentRoomStore } from './useCurrentRoomStore';

interface MyRoomsStore {
myRooms: MyRoomDto[];
newChatCount: number;
setMyRooms: (rooms: MyRoomDto[]) => void;
fetchMyRooms: () => Promise<MyRoomDto[]>;
subscribeRoom: (roomId: number) => void;
subscribeRooms: (roomIds: number[]) => void;
resetNewChatCount: () => void;
clearMyRooms: () => void;
}

export const useMyRoomsStore = create(
persist<MyRoomsStore>(
set => ({
(set, get) => ({
myRooms: [],

newChatCount: 0,
newChatRooms: {},
// 내 방 목록 설정
setMyRooms: (rooms: MyRoomDto[]) => set({ myRooms: rooms }),

Expand All @@ -30,19 +35,43 @@ export const useMyRoomsStore = create(
console.log('myRooms', myRooms);
const myRoomIds = myRooms.map(room => room.roomId);
const currentRoomId = useCurrentRoomStore.getState().roomId;
if (currentRoomId) { // 현재 /rooom에서 방을 보고 있다면 구독을 currentRoomStore에서 처리
if (currentRoomId) {
// 현재 /rooom에서 방을 보고 있다면 구독을 currentRoomStore에서 처리
myRoomIds.splice(myRoomIds.indexOf(currentRoomId), 1);
}
useWebSocketStore.getState().subscribeRooms(myRoomIds);
get().subscribeRooms(myRoomIds);
return myRooms;
} catch (error) {
console.error('Failed to fetch rooms:', error);
return [];
}
},

// 방 채팅 구독
subscribeRoom: (roomId: number) => {
const destination = `/topic/room/${roomId}/chat`;
useWebSocketStore.getState().subTopic(destination, message => {
console.log('subscribeRoomChat', message);
set(state => ({
newChatCount: state.newChatCount + 1,
}));
});
},

// 내가 속한 방 채팅 구독
subscribeRooms: (roomIds: number[]) => {
if (!roomIds) return;
roomIds.forEach(roomId => {
get().subscribeRoom(roomId);
});
},

resetNewChatCount: () => {
set({ newChatCount: 0 });
},

// 내 방 목록 초기화
clearMyRooms: () => set({ myRooms: [] }),
clearMyRooms: () => set({ myRooms: [], newChatCount: 0 }),
}),
{
name: 'my-rooms-storage',
Expand Down
24 changes: 8 additions & 16 deletions src/frontend/src/stores/useWebSocketStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ interface WebSocketStore {
disconnect: () => void;

subTopic: <T>(destination: string, callback: (message: T) => void) => void;
subscribeRoom: (roomId: number) => void;
subscribeRooms: (roomIds: number[]) => void;
subscribeInvitations: <T>(userId: number, callback: (message: T) => void) => void;
subscribeFriendConnection: <T>(userId: number, callback: (message: T) => void) => void;
subscribeRoomUserInfo: (
Expand All @@ -45,6 +43,7 @@ interface WebSocketStore {
playlist: { order: number; url: string; title: string; youtuber: string }[];
}) => void,
) => void;
unsubscribe: (destination: string) => void;
unsubscribeAll: () => void;
pubTopic: (destination: string, message: string) => void;
}
Expand Down Expand Up @@ -173,14 +172,6 @@ export const useWebSocketStore = create<WebSocketStore>((set, get) => ({
get().subTopic(destination, callback);
},

// 방 채팅 구독
subscribeRoom: (roomId: number) => {
const destination = `/topic/room/${roomId}/chat`;
get().subTopic(destination, message => {
console.log('subscribeRoomChat', message);
});
},

// 채팅방 내 신규 유저 정보 구독
subscribeRoomUserInfo: (
roomId: number,
Expand Down Expand Up @@ -212,12 +203,13 @@ export const useWebSocketStore = create<WebSocketStore>((set, get) => ({
get().subTopic(destination, callback);
},

// 내가 속한 방 채팅 구독
subscribeRooms: (roomIds: number[]) => {
if (!roomIds) return;
roomIds.forEach(roomId => {
get().subscribeRoom(roomId);
});
unsubscribe: (destination: string) => {
const { client } = get();
if (!client) return;

const subscription = get().subscriptions.get(destination);
subscription?.unsubscribe();
get().subscriptions.delete(destination);
},

// 구독 해제
Expand Down
20 changes: 20 additions & 0 deletions src/frontend/src/types/window.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
interface WebKitMessageHandler {
postMessage: (message: string) => void;
}

interface WebKitMessageHandlers {
closeModal: WebKitMessageHandler;
[key: string]: WebKitMessageHandler;
}

interface WebKit {
messageHandlers: WebKitMessageHandlers;
}

declare global {
interface Window {
webkit?: WebKit;
}
}

export {};
16 changes: 16 additions & 0 deletions src/frontend/src/ui/Common.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,19 @@ export const SkeletonBase = styled.div`
export const Divider = styled.div`
height: 1rem;
`;

export const NotificationCount = styled.div`
position: absolute;
top: 2px;
right: 2px;
width: 18px;
height: 18px;
border-radius: 50%;
background-color: var(--palette-status-negative);
color: var(--palette-static-white);
font-size: 0.75rem;
font-weight: 600;
display: flex;
justify-content: center;
align-items: center;
`;
Loading