Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
9 changes: 9 additions & 0 deletions backend/src/room/dto/move-index.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { IsNotEmpty, IsNumber } from "class-validator";

export class MoveIndexDto {
@IsNotEmpty()
roomId: string;

@IsNumber()
index: number;
}
6 changes: 6 additions & 0 deletions backend/src/room/dto/room-id.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { IsNotEmpty } from "class-validator";

export class RoomIdDto {
@IsNotEmpty()
roomId: string;
}
2 changes: 2 additions & 0 deletions backend/src/room/dto/room.dto.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

질문지 내용이 없는 것 같습니다

Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ export interface RoomDto {
title: string;
category: string[];
inProgress: boolean;
currentIndex: number;
host: Connection;
status: RoomStatus;
participants: number;
maxParticipants: number;
maxQuestionListLength: number;
createdAt: number;
connectionMap: Record<string, Connection>;
}
6 changes: 6 additions & 0 deletions backend/src/room/room.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,18 @@ export class RoomEntity extends Entity {
@Field({ type: "boolean" })
inProgress: boolean;

@Field({ type: "number" })
currentIndex: number;

@Field({ type: "string" })
status: RoomStatus;

@Field({ type: "number" })
maxParticipants: number;

@Field({ type: "number" })
maxQuestionListLength: number;

@Field({ type: "number", sortable: true })
createdAt: number;

Expand Down
10 changes: 10 additions & 0 deletions backend/src/room/room.events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ export const LISTEN_EVENT = {
LEAVE: "client:room__leave",
FINISH: "client:room__finish",
REACTION: "client:room__reaction",
START_PROGRESS: "client:study__start_progress",
STOP_PROGRESS: "client:study__stop_progress",
NEXT_QUESTION: "client:study__next_question",
CURRENT_INDEX: "client:study__current_index",
MOVE_INDEX: "client:study__move_index",
} as const;

export const EMIT_EVENT = {
Expand All @@ -14,4 +19,9 @@ export const EMIT_EVENT = {
FINISH: "server:room__finish",
CHANGE_HOST: "server:room__change_host",
REACTION: "server:room__reaction",
START_PROGRESS: "server:study__start_progress",
STOP_PROGRESS: "server:study__stop_progress",
NEXT_QUESTION: "server:study__next_question",
CURRENT_INDEX: "server:study__current_index",
MOVE_INDEX: "server:study__move_index",
} as const;
73 changes: 70 additions & 3 deletions backend/src/room/room.gateway.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
WebSocketGateway,
ConnectedSocket,
MessageBody,
OnGatewayDisconnect,
SubscribeMessage,
MessageBody,
ConnectedSocket,
WebSocketGateway,
} from "@nestjs/websockets";
import "dotenv/config";
import { Socket } from "socket.io";
Expand All @@ -20,6 +20,8 @@ import { RoomCreateService } from "@/room/services/room-create.service";
import { RoomJoinService } from "@/room/services/room-join.service";
import { websocketConfig } from "@/websocket/websocket.config";
import { FinishRoomDto } from "@/room/dto/finish-room.dto";
import { RoomIdDto } from "@/room/dto/room-id.dto";
import { MoveIndexDto } from "@/room/dto/move-index.dto";

@WebSocketGateway(websocketConfig)
export class RoomGateway implements OnGatewayDisconnect {
Expand Down Expand Up @@ -84,4 +86,69 @@ export class RoomGateway implements OnGatewayDisconnect {
reactionType: dto.reactionType,
});
}

@SubscribeMessage(LISTEN_EVENT.START_PROGRESS)
public async handleStartProgress(
@ConnectedSocket() client: Socket,
@MessageBody() dto: RoomIdDto
) {
return this.toggleProgress(dto.roomId, client.id, true, EMIT_EVENT.START_PROGRESS);
}

@SubscribeMessage(LISTEN_EVENT.STOP_PROGRESS)
public async handleStopProgress(
@ConnectedSocket() client: Socket,
@MessageBody() dto: RoomIdDto
) {
return this.toggleProgress(dto.roomId, client.id, false, EMIT_EVENT.STOP_PROGRESS);
}

@SubscribeMessage(LISTEN_EVENT.NEXT_QUESTION)
public async handleNextQuestion(
@ConnectedSocket() client: Socket,
@MessageBody() dto: RoomIdDto
) {
this.socketService.emitToRoom(dto.roomId, EMIT_EVENT.NEXT_QUESTION, {
currentIndex: await this.roomService.increaseIndex(dto.roomId, client.id),
});
}

@SubscribeMessage(LISTEN_EVENT.CURRENT_INDEX)
public async handleCurrentIndex(
@ConnectedSocket() client: Socket,
@MessageBody() dto: RoomIdDto
) {
this.socketService.emitToRoom(dto.roomId, EMIT_EVENT.CURRENT_INDEX, {
currentIndex: await this.roomService.getIndex(dto.roomId),
});
}

@SubscribeMessage(LISTEN_EVENT.MOVE_INDEX)
public async handleMoveIndex(
@ConnectedSocket() client: Socket,
@MessageBody() dto: MoveIndexDto
) {
this.socketService.emitToRoom(dto.roomId, EMIT_EVENT.MOVE_INDEX, {
currentIndex: await this.roomService.setIndex(dto.roomId, client.id, dto.index),
});
}

private async toggleProgress(
roomId: string,
socketId: string,
toStatus: boolean,
eventName: string
) {
try {
const status = await this.roomService.setProgress(roomId, socketId, toStatus);
this.socketService.emitToRoom(roomId, eventName, {
status: "success",
inProgress: status,
});
} catch {
this.socketService.emitToRoom(roomId, eventName, {
status: "error",
});
}
}
}
6 changes: 6 additions & 0 deletions backend/src/room/room.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export class RoomRepository {
createdAt: room.createdAt,
host: JSON.parse(room.host),
maxParticipants: room.maxParticipants,
maxQuestionListLength: room.maxQuestionListLength,
currentIndex: room.currentIndex,
status: room.status,
title: room.title,
id: room.id,
Expand All @@ -43,6 +45,8 @@ export class RoomRepository {
inProgress: room.inProgress,
connectionMap,
createdAt: room.createdAt,
currentIndex: room.currentIndex,
maxQuestionListLength: room.maxQuestionListLength,
host: JSON.parse(room.host),
participants: Object.keys(connectionMap).length,
maxParticipants: room.maxParticipants,
Expand All @@ -59,8 +63,10 @@ export class RoomRepository {
room.inProgress = dto.inProgress;
room.title = dto.title;
room.status = dto.status;
room.currentIndex = dto.currentIndex;
room.connectionMap = JSON.stringify(dto.connectionMap);
room.maxParticipants = dto.maxParticipants;
room.maxQuestionListLength = dto.maxQuestionListLength;
room.createdAt = Date.now();
room.host = JSON.stringify(dto.host);

Expand Down
2 changes: 2 additions & 0 deletions backend/src/room/services/room-create.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export class RoomCreateService {
participants: 0,
questionListContents,
createdAt: currentTime,
maxQuestionListLength: questionListContents.length,
currentIndex: 0,
host: {
socketId: dto.socketId,
nickname,
Expand Down
46 changes: 46 additions & 0 deletions backend/src/room/services/room.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,52 @@ export class RoomService {
.sort((a, b) => b.createdAt - a.createdAt);
}

public async setProgress(roomId: string, socketId: string, status: boolean) {
const room = await this.roomRepository.getRoom(roomId);

if (!room) throw new Error("cannot set progress");
if (room.host.socketId !== socketId) throw new Error("only host can set process");

room.inProgress = status;
if (!room.inProgress) room.currentIndex = 0;
await this.roomRepository.setRoom(room);
return status;
}

public async setIndex(roomId: string, socketId: string, index: number) {
const room = await this.roomRepository.getRoom(roomId);

// TODO : 리팩토링 할 필요가 있어보임.
if (
!room ||
!room.inProgress ||
room.host.socketId !== socketId ||
index < 0 ||
index >= room.maxQuestionListLength
)
return -1;

room.currentIndex = index;
await this.roomRepository.setRoom(room);
return index;
}

public async getIndex(roomId: string) {
return (await this.roomRepository.getRoom(roomId)).currentIndex;
}

public async increaseIndex(roomId: string, socketId: string) {
const room = await this.roomRepository.getRoom(roomId);

if (!room || room.host.socketId !== socketId || !room.inProgress) return -1;

const index = await this.setIndex(roomId, socketId, (await this.getIndex(roomId)) + 1);

if (index === -1) return room.maxQuestionListLength - 1;

return index;
}

public async finishRoom(roomId: string) {
await this.roomRepository.removeRoom(roomId);
return roomId;
Expand Down