From cf8c257e4599e2cb4e61e3a5a11148cf70b67b86 Mon Sep 17 00:00:00 2001 From: yubinquitous Date: Fri, 15 Dec 2023 17:05:57 +0900 Subject: [PATCH] =?UTF-8?q?WIP:=20/channels/accept=20=EB=A6=AC=ED=84=B4=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20/channels?= =?UTF-8?q?/notice=20=EA=B5=AC=ED=98=84=20=EC=A7=84=ED=96=89=20=EC=A4=91?= =?UTF-8?q?=20#52?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/channels/channels.controller.ts | 6 ++- src/channels/channels.gateway.ts | 46 +++++++++++++------ .../dto/channel-notice.response.dto.ts | 6 +++ src/channels/dto/event-message-on.dto.ts | 5 -- src/common/enum.ts | 9 ++++ 5 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 src/channels/dto/channel-notice.response.dto.ts diff --git a/src/channels/channels.controller.ts b/src/channels/channels.controller.ts index 8aebb5d..fb6d282 100644 --- a/src/channels/channels.controller.ts +++ b/src/channels/channels.controller.ts @@ -311,14 +311,16 @@ export class ChannelsController { }) async acceptInvitation( @GetUser() user: User, - @Body('channelInvitationId', ParseIntPipe, PositiveIntPipe) + @Body('invitationId', ParseIntPipe, PositiveIntPipe) invitationId: number, ) { const createChannelUserParamDto: ChannelInvitationParamDto = { invitedUserId: user.id, invitationId: invitationId, }; - await this.channelsService.acceptInvitation(createChannelUserParamDto); + return await this.channelsService.acceptInvitation( + createChannelUserParamDto, + ); } @Delete('/refuse/:channelInvitationId') diff --git a/src/channels/channels.gateway.ts b/src/channels/channels.gateway.ts index dd5532a..962bb97 100644 --- a/src/channels/channels.gateway.ts +++ b/src/channels/channels.gateway.ts @@ -1,4 +1,3 @@ -import { BlocksRepository } from './../users/blocks.repository'; import { InjectRedis } from '@liaoliaots/nestjs-redis'; import { Logger, UseFilters, UsePipes, ValidationPipe } from '@nestjs/common'; import { @@ -14,16 +13,17 @@ import { import Redis from 'ioredis'; import { Server, Socket } from 'socket.io'; import { AuthService } from 'src/auth/auth.service'; -import { UserStatus } from 'src/common/enum'; -import { EVENT_GAME_INVITATION, EVENT_USER_STATUS } from 'src/common/events'; +import { ChannelEventType, UserStatus } from 'src/common/enum'; +import { EVENT_USER_STATUS } from 'src/common/events'; import { WSBadRequestException } from 'src/common/exception/custom-exception'; import { WsExceptionFilter } from 'src/common/exception/custom-ws-exception.filter'; +import { GatewayCreateChannelInvitationParamDto } from 'src/game/dto/gateway-create-channelInvitation-param-dto'; import { FriendsRepository } from 'src/users/friends.repository'; import { UsersRepository } from 'src/users/users.repository'; +import { BlocksRepository } from './../users/blocks.repository'; import { ChannelUsersRepository } from './channel-users.repository'; +import { ChannelNoticeResponseDto } from './dto/channel-notice.response.dto'; import { EventMessageOnDto } from './dto/event-message-on.dto'; -import { GatewayCreateGameInvitationParamDto } from '../game/dto/gateway-create-invitation-param.dto'; -import { GatewayCreateChannelInvitationParamDto } from 'src/game/dto/gateway-create-channelInvitation-param-dto'; @WebSocketGateway({ namespace: 'channels' }) @UseFilters(WsExceptionFilter) @@ -140,7 +140,7 @@ export class ChannelsGateway throw WSBadRequestException('유저 정보가 일치하지 않습니다.'); // TODO: exception 발생해도 서버 죽지 않는지 확인 } - const { channelId, message, notice } = data; + const { channelId, message } = data; // 채널유저 유효성 검사 const channelUser = await this.channelUsersRepository.findOne({ @@ -154,8 +154,8 @@ export class ChannelsGateway nickname: user.nickname, message, channelId, - notice, }; + // mute된 유저의 socketId List를 가져온다. const muteRedisKey = `mute:${channelId}:${user.id}`; const isMutedChannelUser = await this.redis.exists(muteRedisKey); @@ -209,16 +209,23 @@ export class ChannelsGateway // 채널에 leave한다. client.leave(channelId.toString()); - this.server - .to(channelId.toString()) - .emit('message', `${user.nickname}님이 퇴장하셨습니다.`); + // this.server + // .to(channelId.toString()) + // .emit('message', `${user.nickname}님이 퇴장하셨습니다.`); + // 채널의 다른 유저들에게 퇴장을 알린다. + this.channelNoticeMessage(channelId, { + nickname: user.nickname, + eventType: ChannelEventType.EXIT, + }); // 어느 채널에 퇴장했는지 알려주기 위해 front에 emit한다. client.emit('leaveChannelRoom', channelId.toString()); } // 알람 구현을 위한 메소드(한명에게만 알람) - async PrivateAlert(gatewayInvitationDto : GatewayCreateChannelInvitationParamDto) { + async PrivateAlert( + gatewayInvitationDto: GatewayCreateChannelInvitationParamDto, + ) { const invitedUser = await this.usersRepository.findOne({ where: { id: gatewayInvitationDto.invitedUserId }, }); @@ -232,10 +239,11 @@ export class ChannelsGateway const invitationEmitDto = { invitationId: gatewayInvitationDto.invitationId, - invitingUserId: invitingUser.nickname + invitingUserId: invitingUser.nickname, }; if ( - !invitedUser || !invitingUser || + !invitedUser || + !invitingUser || invitedUser.status === UserStatus.OFFLINE || invitingUser.status === UserStatus.OFFLINE || !invitedUser.channelSocketId @@ -250,5 +258,15 @@ export class ChannelsGateway this.server .to(invitedUser.channelSocketId) .emit('privateAlert', invitationEmitDto); - } + } + + // 채널에 소켓 전송 + channelNoticeMessage( + channelId: number, + channelNoticeResponseDto: ChannelNoticeResponseDto, + ) { + this.server + .to(channelId.toString()) + .emit('notice', channelNoticeResponseDto); + } } diff --git a/src/channels/dto/channel-notice.response.dto.ts b/src/channels/dto/channel-notice.response.dto.ts new file mode 100644 index 0000000..66e0240 --- /dev/null +++ b/src/channels/dto/channel-notice.response.dto.ts @@ -0,0 +1,6 @@ +import { ChannelEventType } from 'src/common/enum'; + +export type ChannelNoticeResponseDto = { + nickname: string; + eventType: ChannelEventType; +}; diff --git a/src/channels/dto/event-message-on.dto.ts b/src/channels/dto/event-message-on.dto.ts index 6d6fef0..26b126c 100644 --- a/src/channels/dto/event-message-on.dto.ts +++ b/src/channels/dto/event-message-on.dto.ts @@ -9,9 +9,4 @@ export class EventMessageOnDto { @IsPositive() @IsNotEmpty() channelId: number; - - @IsString() - @IsNotEmpty() - // 따로 리터럴이 지정되지 않으면 디폴트로 'MESSAGE'가 들어간다. - notice: 'ADMIN' | 'BAN' | 'KICK' | 'MUTE'| 'JOIN' | 'EXIT' | 'MESSAGE' = 'MESSAGE'; } diff --git a/src/common/enum.ts b/src/common/enum.ts index e0787f4..c7552ae 100644 --- a/src/common/enum.ts +++ b/src/common/enum.ts @@ -30,3 +30,12 @@ export enum ChannelUserType { ADMIN = 'ADMIN', MEMBER = 'MEMBER', } + +export enum ChannelEventType { + JOIN = 'JOIN', + BAN = 'BAN', + EXIT = 'EXIT', + KICK = 'KICK', + MUTE = 'MUTE', + ADMIN = 'ADMIN', +}