nicolas-arnaud
2 years ago
13 changed files with 201 additions and 78 deletions
@ -0,0 +1,99 @@ |
|||||
|
import { |
||||
|
Body, |
||||
|
Controller, |
||||
|
Delete, |
||||
|
Get, |
||||
|
NotFoundException, |
||||
|
Param, |
||||
|
Post, |
||||
|
} from "@nestjs/common"; |
||||
|
//import { channel, Channel } from "diagnostics_channel";
|
||||
|
import { Channel } from './entity/channel.entity'; |
||||
|
import { ChannelService } from "./chat.service"; |
||||
|
import { CreateChannelDto } from "./dto/create-channel.dto"; |
||||
|
import { UsersService } from "src/users/users.service"; |
||||
|
import { UpdateChannelDto } from "./dto/update-channel.dto"; |
||||
|
import { User } from "src/users/entity/user.entity"; |
||||
|
|
||||
|
@Controller("chat") |
||||
|
export class ChatController { |
||||
|
private readonly channelService: ChannelService; |
||||
|
private readonly usersService: UsersService; |
||||
|
|
||||
|
@Get("channels/:id") |
||||
|
getChannelsForUser(@Param("id") id: number): Promise<Array<Channel>> { |
||||
|
return this.channelService.getChannelsForUser(id); |
||||
|
} |
||||
|
|
||||
|
@Post("channels") |
||||
|
async createChannel(@Body() channel: CreateChannelDto) { |
||||
|
return await this.channelService.createChannel(channel); |
||||
|
} |
||||
|
|
||||
|
@Delete("channels/:id") |
||||
|
async deleteChannel(@Param("id") id: number) { |
||||
|
return await this.channelService.removeChannel(id); |
||||
|
} |
||||
|
|
||||
|
@Post("channels/:id/owner") |
||||
|
async moveOwner(@Param("id") id: number, @Body() userId: number) { |
||||
|
const channel = await this.channelService.getChannel(id); |
||||
|
const user: User | null = await this.usersService.findUser(userId); |
||||
|
if (user == null) throw new NotFoundException(`User #${userId} not found`); |
||||
|
channel.owner = user; |
||||
|
this.channelService.update(channel); |
||||
|
} |
||||
|
|
||||
|
@Post("channels/:id/admin") |
||||
|
async addAdmin(@Param("id") id: number, @Body() userId: number) { |
||||
|
const channel = await this.channelService.getChannel(id); |
||||
|
const user: User | null = await this.usersService.findUser(userId); |
||||
|
if (user == null) throw new NotFoundException(`User #${userId} not found`); |
||||
|
channel.admins.push(user); |
||||
|
this.channelService.update(channel); |
||||
|
} |
||||
|
|
||||
|
@Delete("channels/:id/admin") |
||||
|
async removeAdmin(@Param("id") id: number, @Body() userId: number) { |
||||
|
const channel = await this.channelService.getChannel(id); |
||||
|
channel.admins = channel.admins.filter((a) => { |
||||
|
return a.ftId !== userId; |
||||
|
}); |
||||
|
this.channelService.update(channel); |
||||
|
} |
||||
|
|
||||
|
@Post("channels/:id/ban") |
||||
|
async addBan(@Param("id") id: number, @Body() userId: number) { |
||||
|
const channel = await this.channelService.getChannel(id); |
||||
|
const user: User | null = await this.usersService.findUser(userId); |
||||
|
if (user == null) throw new NotFoundException(`User #${userId} not found`); |
||||
|
channel.banned.push(user); |
||||
|
this.channelService.update(channel); |
||||
|
} |
||||
|
|
||||
|
@Delete("channels/:id/ban") |
||||
|
async removeBan(@Param("id") id: number, @Body() userId: number) { |
||||
|
const channel = await this.channelService.getChannel(id); |
||||
|
channel.banned = channel.banned.filter((a) => { |
||||
|
return a.ftId !== userId; |
||||
|
}); |
||||
|
this.channelService.update(channel); |
||||
|
} |
||||
|
|
||||
|
@Post("channels/:id/mute") |
||||
|
async addMute(@Param("id") id: number, @Body() userId: number) { |
||||
|
const channel = await this.channelService.getChannel(id); |
||||
|
const user: User | null = await this.usersService.findUser(userId); |
||||
|
if (user == null) throw new NotFoundException(`User #${userId} not found`); |
||||
|
channel.mute.push(user); |
||||
|
this.channelService.update(channel); |
||||
|
} |
||||
|
@Delete("channels/:id/mute") |
||||
|
async removeMute(@Param("id") id: number, @Body() userId: number) { |
||||
|
const channel = await this.channelService.getChannel(id); |
||||
|
channel.mute = channel.mute.filter((a) => { |
||||
|
return a.ftId !== userId; |
||||
|
}); |
||||
|
this.channelService.update(channel); |
||||
|
} |
||||
|
} |
@ -1,56 +1,56 @@ |
|||||
import { Injectable } from '@nestjs/common' |
import { Injectable, NotFoundException } from '@nestjs/common'; |
||||
import { InjectRepository } from '@nestjs/typeorm' |
import { InjectRepository } from '@nestjs/typeorm'; |
||||
import { Repository } from 'typeorm' |
import { Channel } from './entity/channel.entity'; |
||||
import { type User } from 'src/users/entity/user.entity' |
import { User } from 'src/users/entity/user.entity'; |
||||
import { Channel } from './entity/channel.entity' |
import { Repository } from 'typeorm'; |
||||
import { Message } from './entity/message.entity' |
import { CreateChannelDto } from './dto/create-channel.dto'; |
||||
|
import { UsersService } from 'src/users/users.service'; |
||||
|
|
||||
@Injectable() |
@Injectable() |
||||
export class ChatService { |
export class ChannelService { |
||||
constructor( |
constructor( |
||||
@InjectRepository(Channel) |
@InjectRepository(Channel) |
||||
private readonly ChannelRepository: Repository<Channel>, |
private readonly ChannelRepository: Repository<Channel>, |
||||
@InjectRepository(Message) |
private readonly usersService: UsersService, |
||||
private readonly MessageRepository: Repository<Message> |
|
||||
) {} |
) {} |
||||
|
|
||||
async createChannel (Channel: Channel, creator: User): Promise<Channel> { |
async createChannel(channel: CreateChannelDto): Promise<Channel> { |
||||
const newChannel = await this.addCreatorToChannel(Channel, creator) |
const newChannel = this.ChannelRepository.create({ |
||||
return await this.ChannelRepository.save(newChannel) |
name: channel.name, |
||||
|
password: channel.password, |
||||
|
}); |
||||
|
let user: User| null = await this.usersService.findUser(channel.owner); |
||||
|
if (user == null) throw new NotFoundException(`User #${channel.owner} not found`) |
||||
|
newChannel.owner = user; |
||||
|
return await this.ChannelRepository.save(newChannel); |
||||
} |
} |
||||
|
|
||||
async getChannelsForUser (userId: number): Promise<Channel[]> { |
async getChannelsForUser(ftId: number): Promise<Array<Channel>> { |
||||
return await this.ChannelRepository.find({}) // where userId is in User[] of channel?
|
const query = await this.ChannelRepository.createQueryBuilder('room') |
||||
|
.innerJoin('room.users', 'users') |
||||
|
.where('users.ftId = :ftId', { ftId }) |
||||
|
.leftJoinAndSelect('room.users', 'all_users') |
||||
|
.orderBy('room.id', 'DESC') // TODO: order by last message
|
||||
|
.getRawMany(); |
||||
|
return query; //where userId is in User[] of channel?
|
||||
} |
} |
||||
|
|
||||
async addCreatorToChannel (Channel: Channel, creator: User): Promise<Channel> { |
async addUserToChannel(channel: Channel, user: User): Promise<Channel> { |
||||
Channel.users.push(creator) |
channel.owner = user; |
||||
return Channel |
return await this.ChannelRepository.save(channel); |
||||
} |
} |
||||
|
|
||||
async createMessage (message: Message): Promise<Message> { |
async getChannel(id: number): Promise<Channel> { |
||||
return await this.MessageRepository.save( |
const channel = await this.ChannelRepository.findOneBy({ id }); |
||||
this.MessageRepository.create(message) |
if (!channel) throw new NotFoundException(`Channel #${id} not found`); |
||||
) |
return channel; |
||||
} |
} |
||||
|
|
||||
async deleteBySocketId (socketId: string) { |
async update(channel: Channel) { |
||||
return await this.ChannelRepository.delete({}) // for disconnect
|
this.ChannelRepository.update(channel.id, channel); |
||||
} |
} |
||||
|
async removeChannel(id: number) { |
||||
async getChannel (id: number): Promise<Channel | null> { |
await this.ChannelRepository.delete(id); |
||||
return await this.ChannelRepository.findOneBy({ id }) |
|
||||
} |
|
||||
|
|
||||
async findMessagesInChannelForUser ( |
|
||||
channel: Channel, |
|
||||
user: User |
|
||||
): Promise<Message[]> { |
|
||||
return await this.MessageRepository.createQueryBuilder('message') |
|
||||
.where('message.channel = :chan', { chan: channel }) |
|
||||
.andWhere('message.author NOT IN (:...blocked)', { |
|
||||
blocked: user.blocked |
|
||||
}) |
|
||||
.getMany() |
|
||||
} |
} |
||||
} |
} |
||||
|
|
||||
|
@ -0,0 +1,10 @@ |
|||||
|
import { IsNumber } from 'class-validator'; |
||||
|
|
||||
|
export class ConnectionDto { |
||||
|
@IsNumber() |
||||
|
UserId: number; |
||||
|
@IsNumber() |
||||
|
ChannelId: number; |
||||
|
@IsNumber() |
||||
|
SocketId: number; |
||||
|
} |
@ -1,13 +1,13 @@ |
|||||
import { IsPositive, IsAlpha, IsString, IsOptional } from 'class-validator' |
import { IsPositive, IsAlpha, IsString, IsOptional } from 'class-validator'; |
||||
|
|
||||
export class CreateChannelDto { |
export class CreateChannelDto { |
||||
@IsString() |
@IsString() |
||||
@IsAlpha() |
@IsAlpha() |
||||
name: string |
name: string; |
||||
|
|
||||
@IsPositive() |
@IsPositive() |
||||
owner: number |
owner: number; |
||||
|
|
||||
@IsOptional() |
@IsOptional() |
||||
password: string |
password: string; |
||||
} |
} |
@ -0,0 +1,12 @@ |
|||||
|
import { IsNumber, IsString } from 'class-validator'; |
||||
|
|
||||
|
export class CreateMessageDto { |
||||
|
@IsString() |
||||
|
text: string; |
||||
|
|
||||
|
@IsNumber() |
||||
|
UserId: number; |
||||
|
|
||||
|
@IsNumber() |
||||
|
ChannelId: number; |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
import { PartialType } from '@nestjs/mapped-types'; |
||||
|
import { CreateChannelDto } from './create-channel.dto'; |
||||
|
import { IsOptional, IsString } from 'class-validator'; |
||||
|
|
||||
|
export class UpdateChannelDto extends PartialType(CreateChannelDto) { |
||||
|
id: number; |
||||
|
@IsOptional() |
||||
|
users: [number]; |
||||
|
@IsOptional() |
||||
|
messages: [number]; |
||||
|
@IsOptional() |
||||
|
owners: [number]; //user id
|
||||
|
@IsOptional() |
||||
|
banned: [number]; //user id
|
||||
|
@IsOptional() |
||||
|
muted: [number]; //user id
|
||||
|
@IsString() |
||||
|
@IsOptional() |
||||
|
password: string; |
||||
|
} |
@ -1,24 +0,0 @@ |
|||||
import { PartialType } from '@nestjs/mapped-types' |
|
||||
import { CreateChannelDto } from './createChannel.dto' |
|
||||
import { type Message } from '../entity/message.entity' |
|
||||
import { type User } from 'src/users/entity/user.entity' |
|
||||
import { IsString } from 'class-validator' |
|
||||
|
|
||||
export class UpdateChannelDto extends PartialType(CreateChannelDto) { |
|
||||
id: number |
|
||||
|
|
||||
users: [User] |
|
||||
|
|
||||
messages: [Message] |
|
||||
|
|
||||
owners: [number] // ftId
|
|
||||
|
|
||||
admins: [number] |
|
||||
|
|
||||
banned: [number] // ftId
|
|
||||
|
|
||||
muted: [number] // ftId
|
|
||||
|
|
||||
@IsString() |
|
||||
password: string |
|
||||
} |
|
Loading…
Reference in new issue