Skip to content
Snippets Groups Projects
Unverified Commit 5267b61b authored by Neda Moshki's avatar Neda Moshki Committed by GitHub
Browse files

Merge pull request #18 from KIT-PSE/feat/hand-signal

Implement hand signal
parents bdbb1aac e5cbc3f7
No related branches found
No related tags found
No related merge requests found
......@@ -3,11 +3,10 @@ import { CategoryService } from './category.service';
import { CategoryController } from './category.controller';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { Category } from './category.entity';
import { ChannelModule } from '../channel/channel.module';
@Global()
@Module({
imports: [MikroOrmModule.forFeature([Category]), ChannelModule],
imports: [MikroOrmModule.forFeature([Category])],
providers: [CategoryService],
controllers: [CategoryController],
exports: [CategoryService],
......
......@@ -4,7 +4,6 @@ import { InjectRepository } from '@mikro-orm/nestjs';
import { Category } from './category.entity';
import { EntityRepository } from '@mikro-orm/mysql';
import { User } from '../user/user.entity';
import { ChannelService } from '../channel/channel.service';
@Injectable()
export class CategoryService {
......@@ -12,24 +11,12 @@ export class CategoryService {
private readonly em: EntityManager,
@InjectRepository(Category)
private readonly repository: EntityRepository<Category>,
private readonly channels: ChannelService,
) {}
public async allFromUser(user: User): Promise<Category[]> {
const categories = await user.categories.loadItems({
return user.categories.loadItems({
populate: ['rooms'],
});
for (const category of categories) {
for (const room of category.rooms) {
const channel = this.channels.getChannelFromRoom(room);
if (channel) {
room.channelId = channel.id;
}
}
}
return categories;
}
public async get(id: number, owner: User): Promise<Category> {
......
......@@ -92,18 +92,19 @@ export class ChannelGateway implements OnGatewayConnection {
}
private channelState(channel: Channel) {
const teacher = channel.teacher && {
const teacher = {
id: channel.teacher.client.id,
user: channel.teacher.user,
video: channel.teacher.video,
audio: channel.teacher.audio,
};
const students = Array.from(channel.students.values()).map((student) => ({
id: student.client?.id,
const students = channel.students.map((student) => ({
id: student.client.id,
name: student.name,
video: student.video,
audio: student.audio,
handSignal: student.handSignal,
}));
return {
......@@ -178,6 +179,24 @@ export class ChannelGateway implements OnGatewayConnection {
return true;
}
@SubscribeMessage('update-handSignal')
@UseRequestContext()
public async updateHandSignal(
@ConnectedSocket() client: Socket,
@MessageBody() payload: { handSignal: boolean },
) {
const channel = await this.channels.fromClientOrFail(client);
channel.updateHandSignal(client, payload.handSignal);
this.server.to(channel.id).emit('update-handSignal', {
id: client.id,
handSignal: payload.handSignal,
});
return true;
}
public async handleConnection(client: Socket) {
/*
* This is a workaround for getting the client's rooms in the disconnecting event.
......
......@@ -4,7 +4,6 @@ import { WsException } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { Channel } from './channel';
import { RoomService } from '../room/room.service';
import { Room } from '../room/room.entity';
@Injectable()
export class ChannelService {
......@@ -34,12 +33,7 @@ export class ChannelService {
throw new WsException('Room not found');
}
let channelId;
do {
channelId = Math.floor(100000 + Math.random() * 900000).toString();
} while (this.exists(channelId));
const channel = new Channel(room, server, channelId);
const channel = new Channel(room, server);
await channel.joinAsTeacher(client, user);
this.channels[channel.id] = channel;
......@@ -65,7 +59,6 @@ export class ChannelService {
await channel.joinAsStudent(client, name);
channel.clearCloseTimeout();
this.logger.debug(`Joined ${channel} as student ${name}`);
return channel;
......@@ -90,7 +83,6 @@ export class ChannelService {
await channel.joinAsTeacher(client, user);
channel.clearCloseTimeout();
this.logger.debug(`Joined ${channel} as teacher ${user}`);
return channel;
......@@ -108,11 +100,9 @@ export class ChannelService {
}
if (channel?.isEmpty()) {
channel.clearCloseTimeout();
channel.setCloseTimeout(() => {
delete this.channels[channelId];
this.logger.debug(`Closed ${channel}`);
});
channel.close();
delete this.channels[channelId];
this.logger.debug(`Closed ${channel}`);
}
}
......@@ -134,12 +124,4 @@ export class ChannelService {
return channel.getUser(otherId).client;
}
public getChannelFromRoom(room: Room): Channel {
for (const channel of Object.values(this.channels)) {
if (channel.room.id === room.id) {
return channel;
}
}
}
}
......@@ -15,6 +15,7 @@ export interface Teacher extends ChannelUser {
export interface Student extends ChannelUser {
name: string;
handSignal: boolean;
}
export class Channel {
......@@ -32,7 +33,13 @@ export class Channel {
public async joinAsStudent(client: Socket, name: string) {
await client.join(this.id);
const student = { name, client, video: true, audio: true };
const student = {
name,
client,
video: true,
audio: true,
handSignal: false,
};
this.students.set(client.id, student);
client.broadcast.to(this.id).emit('student-joined', {
......@@ -40,6 +47,7 @@ export class Channel {
name: student.name,
video: true,
audio: true,
handSignal: false,
});
}
......@@ -100,6 +108,16 @@ export class Channel {
throw new WsException(`User not found in ${this}`);
}
public getStudent(clientId: string): Student {
const student = this.students.get(clientId);
if (student) {
return student;
}
throw new WsException(`User not found in ${this}`);
}
public changeName(client: Socket, name: string) {
const student = this.students.get(client.id);
......@@ -117,6 +135,14 @@ export class Channel {
}
}
public updateHandSignal(client: Socket, handSignal: boolean) {
const student = this.getStudent(client.id);
if (student) {
student.handSignal = handSignal;
}
}
public toString(): string {
return `Channel{${this.id}}`;
}
......
......@@ -21,9 +21,6 @@ export class Room {
@Property({ onUpdate: () => new Date() })
updatedAt: Date = new Date();
@Property()
channelId?: string;
constructor(name: string, category: Category, password?: string) {
this.name = name;
this.category = category;
......
import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common';
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AdminGuard } from '../common/guards/admin.guard';
import { AuthGuard } from '../auth/auth.guard';
import { UserService } from './user.service';
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
constructor(private readonly user: UserService) {}
@UseGuards(AuthGuard, AdminGuard)
@Get('findAll')
public async findAll() {
return await this.userService.findAll();
}
const users = await this.user.findAll();
@UseGuards(AuthGuard, AdminGuard)
@Post('changeRole')
public async changeRole(@Body() data: { id: number }) {
return await this.userService.changeRole(data.id);
return users;
}
}
......@@ -48,21 +48,4 @@ export class UserService {
public async delete(id: number): Promise<void> {
await this.repository.nativeDelete({ id });
}
public async changeRole(id: number): Promise<User> {
const user = await this.repository.findOne({ id });
if (!user) {
throw new Error('User not found');
}
if (user.role === 'admin') {
user.role = 'user';
} else if (user.role === 'user') {
user.role = 'admin';
}
await this.em.persistAndFlush(user);
return user;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment