Browse Source

front

master
Pheuw1 2 years ago
parent
commit
da76ca3f17
  1. 4
      back/volume/src/chat/chat.service.ts
  2. 26
      back/volume/src/users/users.controller.ts
  3. 38
      front/volume/package-lock.json
  4. 3
      front/volume/package.json
  5. 77
      front/volume/src/components/Channels.svelte
  6. 150
      front/volume/src/components/Chat.svelte

4
back/volume/src/chat/chat.service.ts

@ -1,4 +1,4 @@
import { Inject, Injectable, NotFoundException } from '@nestjs/common'
import { Injectable, NotFoundException } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import { Repository } from 'typeorm'
@ -69,7 +69,7 @@ export class ChatService {
channel.muted = channel.muted.filter((data) => {
return data[0] - Date.now() > 0
})
this.ChannelRepository.save(channel)
void this.ChannelRepository.save(channel)
})
}

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

@ -17,9 +17,10 @@ import {
import { FileInterceptor } from '@nestjs/platform-express'
import { diskStorage } from 'multer'
import { type User } from './entity/user.entity'
import { UsersService } from './users.service'
import { UserDto, AvatarUploadDto } from './dto/user.dto'
import { type User } from "./entity/user.entity";
import { UsersService } from "./users.service";
import { UserDto, AvatarUploadDto } from "./dto/user.dto";
import { PongService } from "src/pong/pong.service";
import { AuthenticatedGuard } from 'src/auth/42-auth.guard'
import { Profile42 } from 'src/auth/42.decorator'
@ -36,19 +37,18 @@ export class UsersController {
@Post('block/:id')
@UseGuards(AuthenticatedGuard)
async blockUser (
@Profile42() profile: Profile,
@Param('id', ParseIntPipe) id: number
) {
const user = (await this.usersService.findUser(id)) as User
@Post("block/:id")
async blockUser(@Profile42() profile :Profile, @Param('id') id:number) {
const user = await this.usersService.findUser(id) as User
user.blocked.push((await this.usersService.findUser(+profile.id)) as User)
this.usersService.save(user)
}
@Post('unblock/:id')
@UseGuards(AuthenticatedGuard)
async unblockUser (@Param('id', ParseIntPipe) id: number) {
const user = (await this.usersService.findUser(id)) as User
@Post("unblock/:id")
async unblockUser(@Profile42() profile :Profile, @Param('id') id:number) {
const user = await this.usersService.findUser(id) as User
user.blocked = user.blocked.filter((usr: User) => {
return usr.id !== id
})
@ -100,10 +100,10 @@ export class UsersController {
}
})
)
@ApiConsumes('multipart/form-data')
@ApiConsumes("multipart/form-data")
@ApiBody({
description: 'A new avatar for the user',
type: AvatarUploadDto
description: "A new avatar for the user",
type: AvatarUploadDto,
})
async changeAvatar (
@Profile42() profile: Profile,

38
front/volume/package-lock.json

@ -18,7 +18,8 @@
},
"devDependencies": {
"prettier": "^2.8.4",
"svelte-check": "^2.10.3"
"svelte-check": "^2.10.3",
"svelte-select": "^5.5.2"
}
},
"node_modules/@esbuild/android-arm": {
@ -351,6 +352,21 @@
"node": ">=12"
}
},
"node_modules/@floating-ui/core": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.4.tgz",
"integrity": "sha512-SQOeVbMwb1di+mVWWJLpsUTToKfqVNioXys011beCAhyOIFtS+GQoW4EQSneuxzmQKddExDwQ+X0hLl4lJJaSQ==",
"dev": true
},
"node_modules/@floating-ui/dom": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.4.tgz",
"integrity": "sha512-4+k+BLhtWj+peCU60gp0+rHeR8+Ohqx6kjJf/lHMnJ8JD5Qj6jytcq1+SZzRwD7rvHKRhR7TDiWWddrNrfwQLg==",
"dev": true,
"dependencies": {
"@floating-ui/core": "^1.2.3"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
@ -1340,6 +1356,16 @@
"svelte": "^3.24.0"
}
},
"node_modules/svelte-floating-ui": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/svelte-floating-ui/-/svelte-floating-ui-1.2.8.tgz",
"integrity": "sha512-8Ifi5CD2Ui7FX7NjJRmutFtXjrB8T/FMNoS2H8P81t5LHK4I9G4NIs007rLWG/nRl7y+zJUXa3tWuTjYXw/O5A==",
"dev": true,
"dependencies": {
"@floating-ui/core": "^1.1.0",
"@floating-ui/dom": "^1.1.0"
}
},
"node_modules/svelte-hmr": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
@ -1426,6 +1452,16 @@
"sourcemap-codec": "^1.4.8"
}
},
"node_modules/svelte-select": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/svelte-select/-/svelte-select-5.5.2.tgz",
"integrity": "sha512-uvTOJyrrD5OnSCAv9A+gLtIeeYHL5PUw3YpnuBkmfp7a3IHUyjgNNM4GIf462Lh9QEEEM3nD0R0E+G/Jp1iq1w==",
"dev": true,
"dependencies": {
"@floating-ui/dom": "^1.2.1",
"svelte-floating-ui": "1.2.8"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",

3
front/volume/package.json

@ -12,7 +12,8 @@
},
"devDependencies": {
"prettier": "^2.8.4",
"svelte-check": "^2.10.3"
"svelte-check": "^2.10.3",
"svelte-select": "^5.5.2"
},
"dependencies": {
"@sveltejs/vite-plugin-svelte": "^2.0.2",

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

@ -1,4 +1,5 @@
<script lang="ts" context="module">
export interface ChannelsType {
id: number;
name: string;
@ -9,10 +10,14 @@
import { onMount } from "svelte";
import { API_URL, store } from "../Auth";
import { io } from "../socket";
import Select from 'svelte-select';
</script>
<script lang="ts">
//--------------------------------------------------------------------------------/
let channelMode = "";
const channelOptions = ['public','private','direct'];
const joinChannel = async (id: number) => {
io.emit("joinChannel", id, $store.ftId);
@ -21,7 +26,6 @@
let channels: Array<ChannelsType> = [];
onMount(async () => {
const res = await fetch(API_URL + "/channels", {
cors: "include",
credentials: "include",
mode: "cors",
});
@ -44,14 +48,8 @@
const createChannel = async () => {
const name = prompt("Enter a name for the new channel:");
if (name) {
const privacy = prompt(
"Enter a privacy setting for the new channel (public/private):"
);
if (privacy !== "public" && privacy !== "private") {
alert("Invalid privacy setting");
return;
}
let password = "";
if (channelMode !== 'direct')
password = prompt("Enter a password for the new channel:");
const response = await fetch(API_URL + "/channels", {
credentials: "include",
@ -64,7 +62,7 @@
name: name,
owner: $store.ftId,
password: password,
isPrivate: privacy === "private",
isPrivate: channelMode === "private",
}),
});
if (response.ok) {
@ -157,20 +155,31 @@
{#each channels.slice(0, 10) as _channels}
<li>
<span>{_channels.name}</span>
<button on:click={() => selectChat(_channels.id)}>Enter</button>
<button on:click={() => selectChat(_channels.id)}>🔌</button>
<button
on:click={() => removeChannel(_channels.id)}
on:keydown={() => removeChannel(_channels.id)}>delete</button
on:keydown={() => removeChannel(_channels.id)}>🗑️</button
>
<button on:click={() => inviteChannel(_channels.id)}>invite</button>
<button on:click={() => inviteChannel(_channels.id)}>🤝</button>
<button on:click={() => changePassword(_channels.id)}
>Set - Change - Remove Password</button
>Edit Password</button
>
</li>{/each}
{:else}
<p>No channels available</p>
{/if}
<button on:click={createChannel}>Create Channel</button>
<div>
<select bind:value={channelMode} >
{#each channelOptions as option}
<option value={option} selected={channelMode === option}>
{option}
</option>
{/each}
</select>
{#if channelMode!= ''}
<button class="button" on:click={createChannel}>Create Channel</button>
{/if}
</div>
</div>
</div>
</div>
@ -194,4 +203,44 @@
padding: 1rem;
width: 300px;
}
select {
width: 100%;
height: 15%;
padding: 5px;
border-radius: 4px;
background: #eee;
border: none;
outline: grey;
display: inline-block;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
cursor: pointer;
}
.button {
color: white;
margin:0 auto;
margin: auto;
width: 45%;
height: 15%;
padding: 5px;
border-radius: 4px;
background: #6B8E23;
border: none;
outline: grey;
display:block;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
cursor: pointer;
}
span {
color: rgb(0, 0, 0);
font-size: 150%; /* Taille de la police en pourcentage */
position: relative; /* Positionnement relatif */
padding: 10px;
top: 2px;
}
</style>

150
front/volume/src/components/Chat.svelte

@ -3,15 +3,17 @@
id: number;
author: string;
text: string;
}
import { createEventDispatcher, onDestroy, onMount } from "svelte";
import { store, API_URL } from "../Auth";
import { io } from "../socket";
import type { ChannelsType } from "./Channels.svelte";
import type User from "./Profile.svelte";
}
import { createEventDispatcher, onDestroy, onMount } from "svelte";
import { store, API_URL } from "../Auth";
import { io } from "../socket"
import type { ChannelsType } from "./Channels.svelte";
import type User from "./Profile.svelte";
</script>
//--------------------------------------------------------------------------------/
<script lang="ts">
let blockedUsers: Array<User> = [];
let chatMembers: Array<User> = [];
let chatMessages: Array<chatMessagesType> = [];
@ -24,12 +26,6 @@
});
if (res.ok) blockedUsers = await res.json();
res = await fetch(API_URL + "/channels/" + channel.id + "/members", {
credentials: "include",
mode: "cors",
});
if (res.ok) chatMembers = await res.json();
io.on("messages", (msgs: Array<chatMessagesType>) => {
chatMessages = msgs;
});
@ -228,25 +224,27 @@
//--------------------------------------------------------------------------------/
</script>
<div class="overlay">
<div class="overlay" >
<div class="chat" on:click|stopPropagation on:keydown|stopPropagation>
<div class="messages">
{#each chatMessages as message}
<p class="message">
{#if !blockedUsers.filter((user) => user.username == message.author).length}
<div class="messages" >
{ #each chatMessages as message }
<p class="message" >
{ #if !blockedUsers.filter((user) => user.username == message.author).length }
<span
class="message-name"
on:click={() => openProfile(message.author)}
on:keydown={() => openProfile(message.author)}
style="cursor: pointer;"
on:click = {() => openProfile(message.author)}
on:keydown = {() => openProfile(message.author)}
style = "cursor: pointer;"
>
{message.author}
{ message.author }
</span>: {message.text}
{/if}
{
/if}
</p>
{/each}
{
/each}
</div>
{#if showProfileMenu}
{ #if showProfileMenu }
<div
class="profile-menu"
on:click|stopPropagation
@ -254,53 +252,51 @@
>
<ul>
<li>
<button on:click={() => dispatch("send-message", selectedUser)}>
Send Message
</button>
<button on:click = {() => dispatch("send-message", selectedUser)
}
> Send Message </button
>
</li>
<li>
<button on:click={() => dispatch("view-profile", selectedUser)}>
View Profile
</button>
<button on:click = {() => dispatch("view-profile", selectedUser)
}
> View Profile </button
>
</li>
<li>
<button on:click={() => dispatch("add-friend", selectedUser)}>
Add Friend
</button>
<button on:click = {() => dispatch("add-friend", selectedUser)}
> Add Friend </button
>
</li>
<li>
<button on:click={() => dispatch("invite-to-game", selectedUser)}>
Invite to Game
</button>
<button on:click = {() => dispatch("invite-to-game", selectedUser)}
> Invite to Game </button
>
</li>
<li>
{#if !blockedUsers.filter((user) => (user.username = selectedUser)).length}
<button on:click={() => blockUser(selectedUser)}>
Block User
</button>
{:else}
<button on:click={() => unblockUser(selectedUser)}>
Unblock User
</button>
{/if}
{ #if !blockedUsers.filter((user) => user.username = selectedUser).length }
<button on:click = {() => blockUser(selectedUser)}> Block User </button>
{:else }
<button on:click = {() => unblockUser(selectedUser)}> Unblock User </button>
{
/if}
</li>
<li><button on:click={closeProfileMenu}> Close </button></li>
<li> <button on:click = { closeProfileMenu } > Close </button></li >
</ul>
</div>
{/if}
<form on:submit|preventDefault={sendMessage}>
<input type="text" placeholder="Type a message..." bind:value={newText} />
{
/if}
<form on:submit|preventDefault={ sendMessage }>
<input type="text" placeholder = "Type a message..." bind:value={ newText } />
<button>
<img src="img/send.png" alt="send" />
<img src="img/send.png" alt = "send" />
</button>
</form>
<button
on:click|stopPropagation={toggleChatMembers}
on:keydown|stopPropagation
on:click|stopPropagation={ toggleChatMembers }
on:keydown|stopPropagation > Chat Members </button
>
Chat Members
</button>
{#if showChatMembers}
{ #if showChatMembers }
<div
class="chatMembers"
on:click|stopPropagation
@ -308,37 +304,39 @@
>
<div>
<ul>
{#each chatMembers as member}
{ #each chatMembers as member }
<li>
<p>
{member.username}
<button on:click={() => banUser(member.username)}>
ban
</button>
<button on:click={() => kickUser(member.username)}>
kick
</button>
<button on:click={() => muteUser(member.username)}>
mute
</button>
<button on:click={() => adminUser(member.username)}>
promote
</button>
<button on:click={() => removeAdminUser(member.username)}>
demote
</button>
{ member.username }
<button on:click = {() => banUser(member.username)
}> ban </button>
<button on:click = {() => kickUser(member.username)
}
> kick </button
>
<button on:click = {() => muteUser(member.username)}
> mute </button
>
<button on:click = {() => adminUser(member.username)}
> promote </button
>
<button on:click = {() => removeAdminUser(member.username)}
> demote </button
>
</p>
<p>
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
</p>
</li>
{/each}
{
/each}
</ul>
</div>
</div>
{/if}
{
/if}
</div>
</div>
</div>
<style>
.overlay {

Loading…
Cancel
Save