diff --git a/package.json b/package.json index 10b3be84..c962cb80 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,14 @@ "@types/react-beautiful-dnd": "^13.1.8", "axios": "^1.6.2", "date-fns": "^3.1.0", + "lodash": "^4.17.21", "msw": "0.36.3", "path": "^0.12.7", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", "react-dom": "^18.2.0", "react-hook-form": "^7.49.2", + "react-icons": "^5.0.1", "react-infinite-scroller": "^1.2.6", "react-kakao-maps-sdk": "^1.1.24", "react-modal": "^3.16.1", @@ -52,6 +54,7 @@ "websocket": "^1.0.34" }, "devDependencies": { + "@types/lodash": "^4.14.202", "@types/react": "^18.2.43", "@types/react-date-range": "^1.4.9", "@types/react-dom": "^18.2.17", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0720f243..abcef86b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ dependencies: date-fns: specifier: ^3.1.0 version: 3.1.0 + lodash: + specifier: ^4.17.21 + version: 4.17.21 msw: specifier: 0.36.3 version: 0.36.3 @@ -77,6 +80,9 @@ dependencies: react-hook-form: specifier: ^7.49.2 version: 7.49.3(react@18.2.0) + react-icons: + specifier: ^5.0.1 + version: 5.0.1(react@18.2.0) react-infinite-scroller: specifier: ^1.2.6 version: 1.2.6(react@18.2.0) @@ -127,6 +133,9 @@ dependencies: version: 1.0.34 devDependencies: + '@types/lodash': + specifier: ^4.14.202 + version: 4.14.202 '@types/react': specifier: ^18.2.43 version: 18.2.45 @@ -3022,6 +3031,10 @@ packages: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} + dev: true + /@types/node@20.10.5: resolution: {integrity: sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==} dependencies: @@ -5145,6 +5158,14 @@ packages: react: 18.2.0 dev: false + /react-icons@5.0.1(react@18.2.0): + resolution: {integrity: sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==} + peerDependencies: + react: '*' + dependencies: + react: 18.2.0 + dev: false + /react-infinite-scroller@1.2.6(react@18.2.0): resolution: {integrity: sha512-mGdMyOD00YArJ1S1F3TVU9y4fGSfVVl6p5gh/Vt4u99CJOptfVu/q5V/Wlle72TMgYlBwIhbxK5wF0C/R33PXQ==} peerDependencies: diff --git a/src/@types/service.ts b/src/@types/service.ts index bae375b2..5f9ff5d2 100644 --- a/src/@types/service.ts +++ b/src/@types/service.ts @@ -97,12 +97,27 @@ export type subBudgetRes = { } | null; }; +export type subCursorRes = { + status: number; + message: string; + data: { + color: string; + tripId: string; + visitDate: string; + memberId: number; + name: string; + x: number; + y: number; + } | null; +}; + export type SocketContextType = { tripInfo: subInfoRes | null; tripItem: subItemRes | null; tripPath: subPathRes | null; tripMember: subMemberRes | null; tripBudget: subBudgetRes | null; + tripCursor: subCursorRes | null; tripId: string; callBackPub: (callback: () => void) => void; }; diff --git a/src/@types/socket.types.ts b/src/@types/socket.types.ts index a8167cc8..09e5e725 100644 --- a/src/@types/socket.types.ts +++ b/src/@types/socket.types.ts @@ -82,6 +82,20 @@ type subBudgetMessage = (response: { }; }) => void; +type subCursorMessage = (response: { + status: number; + message: string; + data: { + color: string; + tripId: string; + visitDate: string; + memberId: number; + name: string; + x: number; + y: number; + }; +}) => void; + interface pubInfo { startDate: string; endDate: string; @@ -138,3 +152,10 @@ interface pubGetPathAndItems { interface pubUpdateBudget { budget: number; } + +interface pubCursor { + token: string; + visitDate: string; + x: number; + y: number; +} diff --git a/src/api/socket.ts b/src/api/socket.ts index c5c437b4..2f22446e 100644 --- a/src/api/socket.ts +++ b/src/api/socket.ts @@ -61,6 +61,18 @@ export const subBudget = ( }); }; +// 커서 공유 +export const subCursor = ( + tripId: string, + visitDate: string, + subCursorMessage: subCursorMessage, +) => { + socketClient.subscribe(`/sub/${tripId}/cursor/${visitDate}`, (message) => { + const res = JSON.parse(message.body); + subCursorMessage(res); + }); +}; + // 소켓 전송 // 여정 기본 정보 변경 이벤트 발생시 export const pubInfo = (pubInfo: pubInfo, tripId: string) => { @@ -101,6 +113,7 @@ export const pubUpdateTripItem = ( destination: `/pub/trips/${tripId}/updateTripItemOrder`, body: JSON.stringify(pubUpdateTripItem), }); + console.log('실행'); }; // 여행 날짜별 교통 수단 변경 이벤트 발생시 (01/16 업데이트) @@ -187,3 +200,11 @@ export const pubUpdateBudget = ( body: JSON.stringify(pubUpdateBudget), }); }; + +// 커서공유 +export const pubCursor = (pubCursor: pubCursor, tripId: string) => { + socketClient.publish({ + destination: `/pub/trips/${tripId}/cursor`, + body: JSON.stringify(pubCursor), + }); +}; diff --git a/src/components/DetailSectionTop/DetailAddSchedule.tsx b/src/components/DetailSectionTop/DetailAddSchedule.tsx index 656d82a7..0b39bba6 100644 --- a/src/components/DetailSectionTop/DetailAddSchedule.tsx +++ b/src/components/DetailSectionTop/DetailAddSchedule.tsx @@ -193,7 +193,7 @@ const DetailAddSchedule = () => { key={index} className="flex w-[99px] items-start">