Browse Source

some routes change

master
nicolas-arnaud 2 years ago
parent
commit
6d0799ae4d
  1. 32
      back/volume/src/users/users.controller.ts
  2. 170
      back/volume/src/users/users.service.ts
  3. 23
      front/volume/src/App.svelte
  4. 3
      front/volume/src/Auth.ts
  5. 2
      front/volume/src/components/Channels.svelte
  6. 0
      front/volume/src/components/Chat.svelte
  7. 10
      front/volume/src/components/Friends.svelte
  8. 11
      front/volume/src/components/Leaderboard.svelte
  9. 30
      front/volume/src/components/Profile.svelte
  10. 4
      front/volume/src/components/Spectate.svelte

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

@ -62,13 +62,13 @@ export class UsersController {
return await this.usersService.getInvits(profile.id)
}
@Get('leader')
@Get('leaderboard')
@UseGuards(AuthenticatedGuard)
async getLeader (): Promise<User[]> {
return await this.usersService.getLeader()
async getLeaderboard (): Promise<User[]> {
return await this.usersService.getLeaderboard()
}
@Get('leader/:id')
@Get('rank/:id')
@UseGuards(AuthenticatedGuard)
async getRank (@Param('id', ParseIntPipe) id: number): Promise<number> {
return await this.usersService.getRank(id)
@ -110,7 +110,7 @@ export class UsersController {
description: 'A new avatar for the user',
type: AvatarUploadDto
})
async addAvatar (
async changeAvatar (
@FtUser() profile: Profile,
@UploadedFile() file: Express.Multer.File
): Promise<void> {
@ -131,16 +131,20 @@ export class UsersController {
return await this.usersService.findUserByName(username)
}
@Get('invit/:id')
@Get('invit/:username')
@UseGuards(AuthenticatedGuard)
async invitUser (
@FtUser() profile: Profile,
@Param('id', ParseIntPipe) id: number
@Param('username') username: string
): Promise<NotFoundException | null | undefined> {
if (profile.id === id) {
const target = (await this.usersService.findUserByName(username))!;
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, id)
return await this.usersService.invit(profile.id, target.id)
}
@Get('avatar/:id')
@ -185,15 +189,11 @@ export class UsersController {
@Post()
@UseGuards(AuthenticatedGuard)
async create (
async updateUser (
@Body() payload: UserDto,
@FtUser() profile: Profile
): Promise<User | null> {
const user = await this.usersService.findUser(profile.id)
if (user != null) {
const user = (await this.usersService.findUser(profile.id))!
return await this.usersService.update(user, payload)
} else {
return await this.usersService.create(payload)
}
}
}

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

@ -1,11 +1,16 @@
import { 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'
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";
@Injectable()
@Catch(QueryFailedError, EntityNotFoundError)
@ -15,96 +20,96 @@ export class UsersService {
) {}
save(user: User) {
this.usersRepository.save(user)
this.usersRepository.save(user);
}
async findUsers(): Promise<User[]> {
return await this.usersRepository.find({})
return await this.usersRepository.find({});
}
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 * * * * *')
@Cron("0 * * * * *")
async updateStatus() {
const users = await this.usersRepository.find({})
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
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' } })
return await this.usersRepository.find({ where: { status: "online" } });
}
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[]> {
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)
this.usersRepository.merge(user, changes);
return await this.usersRepository.save(user);
}
async addAvatar(ftId: number, filename: string) {
return await this.usersRepository.update(
{ ftId },
{
avatar: filename
avatar: filename,
}
)
);
}
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[]> {
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[]> {
@ -112,68 +117,53 @@ export class UsersService {
where: { ftId },
relations: {
results: {
players: true
}
}
})
if (user != null) return user.results
return []
players: true,
},
},
});
if (user != null) return user.results;
return [];
}
async getLeader (): 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.getLeader()
return leader.findIndex((user) => user.ftId === ftId)
const leader = await this.getLeaderboard();
return leader.findIndex((user) => user.ftId === ftId);
}
async invit(ftId: number, targetFtId: number): Promise<any> {
const user = await this.usersRepository.findOne({
const user: User = (await this.usersRepository.findOne({
where: { ftId },
relations: {
followers: true,
friends: true
}
})
if (user == null) {
return new NotFoundException(`Error: user id ${ftId} isn't in our db.`)
}
if (user.friends.findIndex((friend) => friend.ftId === targetFtId) !== -1) {
return null
}
const target = await this.usersRepository.findOne({
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
}
})
if (target == null) {
return new NotFoundException(
`Error: user id ${targetFtId} isn't in our db.`
)
}
friends: true,
},
}))!;
const id = user.followers.findIndex(
(follower) => follower.ftId === targetFtId
)
);
if (id !== -1) {
console.log(
`Friend relation complete between ${user.username} and ${target.username}`
)
user.friends.push(target)
if (user.ftId !== target.ftId) target.friends.push(user)
user.followers.slice(id, 1)
await this.usersRepository.save(user)
} else {
console.log(`You asked ${target.username} to be your friend.`)
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);
}
}

23
front/volume/src/App.svelte

@ -1,19 +1,22 @@
<script lang="ts">
import { onMount } from "svelte";
import Navbar from "./components/NavBar.svelte";
import Profile from "./components/Profile.svelte";
import MatchHistory from "./components/MatchHistory.svelte";
import type { Match } from "./components/MatchHistory.svelte";
import Friends, { addFriend } from "./components/Friends.svelte";
import type { Friend } from "./components/Friends.svelte";
import Spectate from "./components/Spectate.svelte";
import type { SpectateType } from "./components/Spectate.svelte";
import Pong from "./components/Pong/Pong.svelte";
import Chat2 from "./components/Chat2.svelte";
import Chat from "./components/Chat.svelte";
import Channels from "./components/Channels.svelte";
import type { ChannelsType } from "./components/Channels.svelte";
import Leaderboard from "./components/Leaderboard.svelte";
import type { Player } from "./components/Leaderboard.svelte";
import Pong from "./components/Pong/Pong.svelte";
import type { Player } from "./components/Profile.svelte";
import type { Match } from "./components/MatchHistory.svelte";
import type { Friend } from "./components/Friends.svelte";
import type { SpectateType } from "./components/Spectate.svelte";
import type { ChannelsType } from "./components/Channels.svelte";
import { store, getUser, login, logout, API_URL } from "./Auth";
import FakeLogin from "./FakeLogin.svelte";
@ -30,7 +33,7 @@
isProfileOpen = true;
}
let userProfile;
let userProfile: Player;
let isIdProfileOpen = false;
async function openIdProfile(event: CustomEvent<string>) {
console.log("Opening profile: " + event.detail);
@ -129,7 +132,7 @@
let leaderboard: Player[] = [];
export async function getLeader(): Promise<Player[]> {
let response = await fetch(API_URL + "/leader", {
let response = await fetch(API_URL + "/leaderboard", {
credentials: "include",
mode: "cors",
});
@ -181,7 +184,7 @@
on:click={() => (selectedChannel = undefined)}
on:keydown={() => (selectedChannel = undefined)}
>
<Chat2
<Chat
chatMessages={selectedChannel.messages}
on:view-profile={openIdProfile}
on:add-friend={addFriend}

3
front/volume/src/Auth.ts

@ -7,8 +7,7 @@ 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, {

2
front/volume/src/components/Channels.svelte

@ -1,5 +1,5 @@
<script lang="ts" context="module">
import type { chatMessagesType } from "./Chat2.svelte";
import type { chatMessagesType } from "./Chat.svelte";
export interface ChannelsType {
id: string;
name: string;

0
front/volume/src/components/Chat2.svelte → front/volume/src/components/Chat.svelte

10
front/volume/src/components/Friends.svelte

@ -12,20 +12,14 @@
? event.target.querySelector('input[type="text"]').value
: event.detail;
let response = await fetch(API_URL + "/user/" + username, {
credentials: "include",
mode: "cors",
});
let target = await response.json();
response = await fetch(API_URL + "/invit/" + target.ftId, {
const response = await fetch(API_URL + "/invit/" + username, {
credentials: "include",
mode: "cors",
});
if (response.ok) {
alert("Invitation send.");
} else {
alert("Invitation refused.");
alert("Invitation failed.");
}
}
</script>

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

@ -1,15 +1,6 @@
<script lang="ts" context="module">
export interface Player {
username: string;
wins: number;
looses: number;
matchs: number;
winrate: number;
rank: number;
}
</script>
<script lang="ts">
import type Player from './Profile.svelte'
export let leaderboard: Array<Player> = [];
</script>

30
front/volume/src/components/Profile.svelte

@ -1,15 +1,20 @@
<script lang="ts" context="module">
export interface Player {
username: string;
wins: number;
looses: number;
matchs: number;
winrate: number;
rank: number;
is2faEnabled: boolean;
}
</script>
<script lang="ts">
import { API_URL, store, logout } from "../Auth";
export let edit = 0;
export let user = {
username: "",
wins: 0,
looses: 0,
winrate: 0,
rank: -1,
is2faEnabled: false,
};
export let edit: number;
export let user: any;
async function handleSubmit() {
let response = await fetch(API_URL, {
@ -45,7 +50,7 @@
<img src={API_URL + "/avatar"} alt="avatar" class="profile-img" />
{:else}
<form
action={API_URL + "/avatar"}
action={`${API_URL}/avatar/${user.id}`}
method="post"
enctype="multipart/form-data"
id="upload_avatar"
@ -136,15 +141,12 @@
display: flex;
justify-content: center;
}
.profile-body > p {
display: flex;
justify-content: center;
}
.profile-body > img {
display: flex;
justify-content: center;
}
.username {
text-align: center;
}

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

@ -8,7 +8,9 @@
<script lang="ts">
export let spectate: Array<SpectateType> = [];
export let watch = (id: string) => {};
export let watch = (id: string) => {
console.log(id);
};
</script>
<div class="overlay">

Loading…
Cancel
Save