Skip to content
Open
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
1,006 changes: 771 additions & 235 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest"
},
"dependencies": {
"@stomp/stompjs": "^7.3.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.27.0"
"react-router-dom": "^6.27.0",
"sockjs-client": "^1.6.1"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.15",
"vite": "^5.4.11"
"vite": "^5.4.11",
"vitest": "^2.1.9"
}
}
7 changes: 6 additions & 1 deletion src/app/App.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import React from 'react';
import { AppRoutes } from './routes.jsx';
import { ChatNotificationGate } from '../features/chat/ChatNotificationGate.jsx';

export default function App() {
return <AppRoutes />;
return (
<ChatNotificationGate>
<AppRoutes />
</ChatNotificationGate>
);
}

4 changes: 2 additions & 2 deletions src/app/routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export function AppRoutes() {
<Route path="/dorm-rules/general" element={<DormRulesScreen />} />
<Route path="/rooms/:id" element={<RoomDetailScreen />} />
<Route path="/rooms/:id/apply" element={<ApplyMessageScreen />} />
<Route path="/chat/group" element={<ChatDetailScreen />} />
<Route path="/chat/dm" element={<ChatDMScreen />} />
<Route path="/chat/group/:chatRoomNo" element={<ChatDetailScreen />} />
<Route path="/chat/dm/:chatRoomNo" element={<ChatDMScreen />} />

{/* Flow screens */}
<Route path="/checklist" element={<ChecklistEditScreen mode="personal" />} />
Expand Down
30 changes: 30 additions & 0 deletions src/features/chat/ChatNotificationGate.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { subscribe } from '../../shared/api/chatSocket';
import { getCachedUserNo } from '../../shared/api/auth';

// 로그인 상태에서 개인 알림 큐를 구독. 방 삭제/강퇴 시 사용자에게 알리고 채팅 목록으로 보낸다.
export function ChatNotificationGate({ children }) {
const navigate = useNavigate();

React.useEffect(() => {
if (!getCachedUserNo()) return;
let alive = true;
let unsub = () => {};

subscribe('/user/queue/notification', (msg) => {
if (!alive) return;
if (msg.type === 'ROOM_DELETED') {
alert('방이 삭제되어 채팅방이 닫혔어요.');
navigate('/chat');
} else if (msg.type === 'KICKED_FROM_ROOM') {
alert('방에서 내보내져 채팅방이 닫혔어요.');
navigate('/chat');
}
}).then((fn) => { if (alive) unsub = fn; else fn(); });

return () => { alive = false; unsub(); };
}, [navigate]);

return children;
}
2 changes: 1 addition & 1 deletion src/features/chat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ export {
ChatListScreen,
ChatDetailScreen,
ChatBubble,
ChatMessageItem,
ChatComposer,
ChatAttachmentCard,
formatChatTime,
} from './pages/Chat.jsx';

Loading