Browse Source

some more linting

master
nicolas-arnaud 2 years ago
parent
commit
60fcdcc48d
  1. 88
      back/volume/src/chat/chat.gateway.ts
  2. 8
      back/volume/src/users/users.controller.ts
  3. 181
      back/volume/src/users/users.service.ts
  4. 16
      front/Dockerfile
  5. 14
      front/volume/src/App.svelte
  6. 4
      front/volume/src/Auth.ts
  7. 6
      front/volume/src/components/Leaderboard.svelte
  8. 4
      front/volume/src/components/MatchHistory.svelte

88
back/volume/src/chat/chat.gateway.ts

@ -1,100 +1,100 @@
import { UnauthorizedException, UseGuards } from "@nestjs/common";
import { UnauthorizedException, UseGuards } from '@nestjs/common'
import {
type OnGatewayConnection,
type OnGatewayDisconnect,
MessageBody,
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
} from "@nestjs/websockets";
import { Socket, Server } from "socket.io";
WebSocketServer
} from '@nestjs/websockets'
import { Socket, Server } from 'socket.io'
import { ChatService } from "./chat.service";
import { type User } from "src/users/entity/user.entity";
import { UsersService } from "src/users/users.service";
import { Channel } from "./entity/channel.entity";
import { Message } from "./entity/message.entity";
import { ChatService } from './chat.service'
import { type User } from 'src/users/entity/user.entity'
import { UsersService } from 'src/users/users.service'
import { Channel } from './entity/channel.entity'
import { Message } from './entity/message.entity'
import { CreateChannelDto } from "./dto/createChannel.dto";
import { CreateChannelDto } from './dto/createChannel.dto'
@WebSocketGateway({
cors: { origin: /^(http|ws):\/\/localhost(:\d+)?$/ },
cors: { origin: /^(http|ws):\/\/localhost(:\d+)?$/ }
})
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer()
server: Server;
server: Server
constructor(
constructor (
private readonly userService: UsersService,
private readonly chatService: ChatService
) {}
async handleConnection(socket: Socket) {
async handleConnection (socket: Socket) {
try {
const user: User | null = await this.userService.findUser(
socket.data.user.ftId
);
)
if (user == null) {
socket.emit("Error", new UnauthorizedException());
socket.emit('Error', new UnauthorizedException())
// socket.disconnect();
return;
return
} else {
socket.data.user = user;
const channels = await this.chatService.getChannelsForUser(user.id);
socket.data.user = user
const channels = await this.chatService.getChannelsForUser(user.id)
// Only emit rooms to the specific connected client
return this.server.to(socket.id).emit("channel", channels);
return this.server.to(socket.id).emit('channel', channels)
}
} catch {
socket.emit("Error", new UnauthorizedException());
socket.emit('Error', new UnauthorizedException())
// socket.disconnect();
}
}
handleDisconnect(socket: Socket) {
handleDisconnect (socket: Socket) {
// socket.disconnect()
}
@SubscribeMessage("createChannel")
async onCreateChannel(
@SubscribeMessage('createChannel')
async onCreateChannel (
socket: Socket,
@MessageBody() channeldto: CreateChannelDto
): Promise<Channel | null> {
const channel = new Channel();
channel.name = channeldto.name;
const owner = await this.userService.findUser(channeldto.owner);
if (owner == null) return null;
channel.owners.push(owner);
channel.password = channeldto.password;
const channel = new Channel()
channel.name = channeldto.name
const owner = await this.userService.findUser(channeldto.owner)
if (owner == null) return null
channel.owners.push(owner)
channel.password = channeldto.password
/// ...///
return await this.chatService.createChannel(channel, socket.data.user);
return await this.chatService.createChannel(channel, socket.data.user)
}
@SubscribeMessage("joinChannel")
async onJoinChannel(socket: Socket, channel: Channel) {
@SubscribeMessage('joinChannel')
async onJoinChannel (socket: Socket, channel: Channel) {
// add user to channel
const messages = await this.chatService.findMessagesInChannelForUser(
channel,
socket.data.user
);
this.server.to(socket.id).emit("messages", messages);
)
this.server.to(socket.id).emit('messages', messages)
}
@SubscribeMessage("leaveChannel")
async onLeaveChannel(socket: Socket) {
await this.chatService.deleteBySocketId(socket.id);
@SubscribeMessage('leaveChannel')
async onLeaveChannel (socket: Socket) {
await this.chatService.deleteBySocketId(socket.id)
}
@SubscribeMessage("addMessage")
async onAddMessage(socket: Socket, message: Message) {
@SubscribeMessage('addMessage')
async onAddMessage (socket: Socket, message: Message) {
const createdMessage: Message = await this.chatService.createMessage({
...message,
author: socket.data.user,
});
author: socket.data.user
})
const channel = await this.chatService.getChannel(
createdMessage.channel.id
);
)
if (channel != null) {
const users = await this.userService.findOnlineInChannel(channel);
const users = await this.userService.findOnlineInChannel(channel)
}
/// TODO: Send message to users
}

8
back/volume/src/users/users.controller.ts

@ -137,12 +137,12 @@ export class UsersController {
@FtUser() profile: Profile,
@Param('username') username: string
): Promise<NotFoundException | null | undefined> {
const target = (await this.usersService.findUserByName(username))!;
const target = (await this.usersService.findUserByName(username))!
if (!target)
throw new BadRequestException("Target unknown.")
if (profile.id === target.ftId)
if (!target) throw new BadRequestException('Target unknown.')
if (profile.id === target.ftId) {
throw new BadRequestException("You can't invit yourself.")
}
return await this.usersService.invit(profile.id, target.id)
}

181
back/volume/src/users/users.service.ts

@ -2,168 +2,169 @@ import {
BadRequestException,
Catch,
Injectable,
NotFoundException,
} from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { EntityNotFoundError, QueryFailedError, Repository } from "typeorm";
import { User } from "./entity/user.entity";
import { type UserDto } from "./dto/user.dto";
import { type Channel } from "src/chat/entity/channel.entity";
import type Result from "src/pong/entity/result.entity";
import { Cron } from "@nestjs/schedule";
NotFoundException
} from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { EntityNotFoundError, QueryFailedError, Repository } from 'typeorm'
import { User } from './entity/user.entity'
import { type UserDto } from './dto/user.dto'
import { type Channel } from 'src/chat/entity/channel.entity'
import type Result from 'src/pong/entity/result.entity'
import { Cron } from '@nestjs/schedule'
@Injectable()
@Catch(QueryFailedError, EntityNotFoundError)
export class UsersService {
constructor(
constructor (
@InjectRepository(User) private readonly usersRepository: Repository<User>
) {}
save(user: User) {
this.usersRepository.save(user);
save (user: User) {
this.usersRepository.save(user)
}
async findUsers(): Promise<User[]> {
return await this.usersRepository.find({});
async findUsers (): Promise<User[]> {
return await this.usersRepository.find({})
}
async findUserByName(username: string): Promise<User | null> {
async findUserByName (username: string): Promise<User | null> {
const user = await this.usersRepository.findOne({
where: { username },
relations: { results: true },
});
return user;
relations: { results: true }
})
return user
}
@Cron("0 * * * * *")
async updateStatus() {
const users = await this.usersRepository.find({});
@Cron('0 * * * * *')
async updateStatus () {
const users = await this.usersRepository.find({})
users.forEach((usr) => {
if (Date.now() - usr.lastAccess > 60000) {
usr.status = "offline";
this.usersRepository.save(usr);
usr.status = 'offline'
this.usersRepository.save(usr)
}
});
})
}
async findUser(ftId: number): Promise<User | null> {
const user = await this.usersRepository.findOneBy({ ftId });
if (user == null) return null;
user.lastAccess = Date.now();
user.status = "online";
this.usersRepository.save(user);
return user;
async findUser (ftId: number): Promise<User | null> {
const user = await this.usersRepository.findOneBy({ ftId })
if (user == null) return null
user.lastAccess = Date.now()
user.status = 'online'
this.usersRepository.save(user)
return user
}
async findOnlineUsers(): Promise<User[]> {
return await this.usersRepository.find({ where: { status: "online" } });
async findOnlineUsers (): Promise<User[]> {
return await this.usersRepository.find({ where: { status: 'online' } })
}
async create(userData: UserDto) {
async create (userData: UserDto) {
try {
const newUser = this.usersRepository.create(userData);
return await this.usersRepository.save(newUser);
const newUser = this.usersRepository.create(userData)
return await this.usersRepository.save(newUser)
} catch (err) {
throw new Error(`Error creating user ${err}`);
throw new Error(`Error creating user ${err}`)
}
}
async findOnlineInChannel(channel: Channel): Promise<User[]> {
async findOnlineInChannel (channel: Channel): Promise<User[]> {
return await this.usersRepository
.createQueryBuilder("user")
.where("user.channel = :chan", { chan: channel })
.andWhere("user.status := status)", { status: "online" })
.getMany();
.createQueryBuilder('user')
.where('user.channel = :chan', { chan: channel })
.andWhere('user.status := status)', { status: 'online' })
.getMany()
}
async update(user: User, changes: UserDto): Promise<User | null> {
this.usersRepository.merge(user, changes);
return await this.usersRepository.save(user);
async update (user: User, changes: UserDto): Promise<User | null> {
this.usersRepository.merge(user, changes)
return await this.usersRepository.save(user)
}
async addAvatar(ftId: number, filename: string) {
async addAvatar (ftId: number, filename: string) {
return await this.usersRepository.update(
{ ftId },
{
avatar: filename,
avatar: filename
}
);
)
}
async getFriends(ftId: number): Promise<User[]> {
async getFriends (ftId: number): Promise<User[]> {
const user = await this.usersRepository.findOne({
where: { ftId },
relations: {
friends: true,
},
});
if (user != null) return user.friends;
return [];
friends: true
}
})
if (user != null) return user.friends
return []
}
async getInvits(ftId: number): Promise<User[]> {
async getInvits (ftId: number): Promise<User[]> {
const user = await this.usersRepository.findOne({
where: { ftId },
relations: {
followers: true,
},
});
if (user != null) return user.followers;
return [];
followers: true
}
})
if (user != null) return user.followers
return []
}
async getResults(ftId: number): Promise<Result[]> {
async getResults (ftId: number): Promise<Result[]> {
const user = await this.usersRepository.findOne({
where: { ftId },
relations: {
results: {
players: true,
},
},
});
if (user != null) return user.results;
return [];
players: true
}
}
})
if (user != null) return user.results
return []
}
async getLeaderboard(): Promise<User[]> {
async getLeaderboard (): Promise<User[]> {
return await this.usersRepository.find({
order: {
winrate: "DESC",
},
});
winrate: 'DESC'
}
})
}
async getRank(ftId: number): Promise<number> {
const leader = await this.getLeaderboard();
return leader.findIndex((user) => user.ftId === ftId);
async getRank (ftId: number): Promise<number> {
const leader = await this.getLeaderboard()
return leader.findIndex((user) => user.ftId === ftId)
}
async invit(ftId: number, targetFtId: number): Promise<any> {
async invit (ftId: number, targetFtId: number): Promise<any> {
const user: User = (await this.usersRepository.findOne({
where: { ftId },
relations: {
followers: true,
friends: true,
},
}))!;
if (user.friends.findIndex((friend) => friend.ftId === targetFtId) !== -1)
return new BadRequestException("You are already friends.");
friends: true
}
}))!
if (user.friends.findIndex((friend) => friend.ftId === targetFtId) !== -1) {
return new BadRequestException('You are already friends.')
}
const target = (await this.usersRepository.findOne({
where: { ftId: targetFtId },
relations: {
followers: true,
friends: true,
},
}))!;
friends: true
}
}))!
const id = user.followers.findIndex(
(follower) => follower.ftId === targetFtId
);
)
if (id !== -1) {
user.friends.push(target);
if (user.ftId !== target.ftId) target.friends.push(user);
user.followers.slice(id, 1);
await this.usersRepository.save(user);
} else target.followers.push(user);
await this.usersRepository.save(target);
user.friends.push(target)
if (user.ftId !== target.ftId) target.friends.push(user)
user.followers.slice(id, 1)
await this.usersRepository.save(user)
} else target.followers.push(user)
await this.usersRepository.save(target)
}
}

16
front/Dockerfile

@ -4,4 +4,18 @@ RUN apk update && apk upgrade && apk add npm
WORKDIR /var/www/html
COPY entrypoint.sh /tmp/entrypoint.sh
ENTRYPOINT ["sh", "/tmp/entrypoint.sh"]
COPY ../.env .env
ENTRYPOINT npm install; \
if [[ $NODE_ENV == "production" ]]; then \
npm run build && npm run preview; \
elif [[ $NODE_ENV == "development" ]]; then \
npm run dev; \
elif [[ $NODE_ENV == "debug" ]]; then \
npm run dev; \
elif [[ $NODE_ENV == "check" ]]; then \
npm run format && npm run check; echo "=== FINISH ===" \
else echo "Nothing to do for that NODE_ENV context."; \
fi;

14
front/volume/src/App.svelte

@ -17,7 +17,7 @@
import type { SpectateType } from "./components/Spectate.svelte";
import type { ChannelsType } from "./components/Channels.svelte";
import { store, getUser, login, logout, API_URL } from "./Auth";
import { store, getUser, login, API_URL } from "./Auth";
import FakeLogin from "./FakeLogin.svelte";
// PROFILE
@ -27,7 +27,6 @@
setInterval(() => {
getUser();
}, 15000);
let isProfileOpen = false;
function clickProfile() {
isProfileOpen = true;
@ -51,17 +50,17 @@
// HISTORY
let matches: Array<Match>;
let isHistoryOpen = false;
function clickHistory() {
async function clickHistory() {
isHistoryOpen = true;
getHistory();
matches = await getHistory();
}
export async function getHistory(): Promise<void> {
export async function getHistory(): Promise<Array<Match>> {
let response = await fetch(API_URL + "/history/" + $store.ftId, {
credentials: "include",
mode: "cors",
});
matches = await response.json();
return await response.json();
}
// FRIENDS
@ -130,7 +129,8 @@
selectedChannel = channel;
};
let leaderboard: Player[] = [];
let leaderboard: Array<Player> = [];
export async function getLeader(): Promise<Player[]> {
let response = await fetch(API_URL + "/leaderboard", {
credentials: "include",

4
front/volume/src/Auth.ts

@ -7,7 +7,9 @@ store.subscribe((value) => {
else localStorage.removeItem("user");
});
export const API_URL = `http://${import.meta.env.VITE_HOST}:${import.meta.env.VITE_BACK_PORT}`
export const API_URL = `http://${import.meta.env.VITE_HOST}:${
import.meta.env.VITE_BACK_PORT
}`;
export async function getUser() {
const res = await fetch(API_URL, {

6
front/volume/src/components/Leaderboard.svelte

@ -1,7 +1,7 @@
<script lang="ts">
import type Player from './Profile.svelte'
export let leaderboard: Array<Player> = [];
import type { Player } from "./Profile.svelte";
export let leaderboard: Array<Player>;
</script>
<div class="overlay">

4
front/volume/src/components/MatchHistory.svelte

@ -1,7 +1,7 @@
<script lang="ts" context="module">
import type user from "./Profile.svelte";
import type Player from "./Profile.svelte";
export interface Match {
players: Array<user>;
players: Array<Player>;
score: Array<number>;
date: Date;
}

Loading…
Cancel
Save