Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82633fb869 | |||
|
|
cdd2836e7c | ||
|
|
78c3c19de8 | ||
|
|
f04ea25574 | ||
|
|
6bf99bd55e | ||
| 9cb31f88de | |||
|
|
7ae25c68ba | ||
|
|
b8692d064c | ||
|
|
660088fb74 | ||
| 90c3e3e0b7 | |||
|
|
93ed2a7eff | ||
| b53151ac5f | |||
| 0c04e29cc7 | |||
| f137b84893 | |||
| 8d6e3e95b3 |
10
.env
10
.env
@ -14,22 +14,22 @@
|
|||||||
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
|
NGINX_ENVSUBST_TEMPLATE_SUFFIX=".conf"
|
||||||
|
|
||||||
# BASE_URL=http://localhost
|
# BASE_URL=http://localhost
|
||||||
BASE_URL=92.143.191.152
|
BASE_URL=localhost:8080
|
||||||
REACT_APP_BASE_URL=92.143.191.152
|
REACT_APP_BASE_URL=localhost:8080
|
||||||
REDIRECT_URI=http://92.143.191.152/api/auth/login
|
REDIRECT_URI=http://localhost:8080/api/auth/login
|
||||||
#postgres var
|
#postgres var
|
||||||
# POSTGRES_HOST=127.0.0.1
|
# POSTGRES_HOST=127.0.0.1
|
||||||
# DB_TYPE=postgres
|
# DB_TYPE=postgres
|
||||||
POSTGRES_HOST=postgresql
|
POSTGRES_HOST=postgresql
|
||||||
POSTGRES_USER=postgres
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=pass
|
POSTGRES_PASSWORD=postgres
|
||||||
POSTGRES_DATABASE=postgres
|
POSTGRES_DATABASE=postgres
|
||||||
MODE=DEV
|
MODE=DEV
|
||||||
|
|
||||||
#port
|
#port
|
||||||
API_PORT=3000
|
API_PORT=3000
|
||||||
# REACT_PORT=3000 (current = 8080)
|
# REACT_PORT=3000 (current = 8080)
|
||||||
NGINX_PORT=80
|
NGINX_PORT=8080
|
||||||
PONG_PORT=4000
|
PONG_PORT=4000
|
||||||
CHAT_PORT=4001
|
CHAT_PORT=4001
|
||||||
POSTGRES_PORT=5432
|
POSTGRES_PORT=5432
|
||||||
|
|||||||
153
README.md
Normal file
153
README.md
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
# ft_transcendence
|
||||||
|
|
||||||
|
## Description
|
||||||
|
ft_transcendence est le projet final du tronc commun de l'École 42. Il s'agit de créer une application web complète permettant de jouer au Pong en ligne avec des fonctionnalités modernes comme les tournois, le chat en temps réel, et l'authentification.
|
||||||
|
|
||||||
|
## Fonctionnalités principales
|
||||||
|
- 🎮 **Jeu Pong** en temps réel multijoueur
|
||||||
|
- 🏆 **Système de tournois** avec brackets
|
||||||
|
- 💬 **Chat en temps réel** avec channels
|
||||||
|
- 👤 **Profils utilisateurs** et amis
|
||||||
|
- 🔐 **Authentification 2FA** (Google, 42)
|
||||||
|
- 📊 **Statistiques** et historique des parties
|
||||||
|
- 🎨 **Interface moderne** et responsive
|
||||||
|
- 🔒 **Sécurité** web avancée
|
||||||
|
|
||||||
|
## Technologies utilisées
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- **Framework** : React/Vue.js/Angular ou Vanilla JS
|
||||||
|
- **Styling** : CSS3, Bootstrap/Tailwind
|
||||||
|
- **WebSockets** : Pour le temps réel
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- **Framework** : Django/Flask/Node.js
|
||||||
|
- **Base de données** : PostgreSQL
|
||||||
|
- **API** : REST ou GraphQL
|
||||||
|
- **Authentication** : OAuth2, JWT
|
||||||
|
|
||||||
|
### DevOps
|
||||||
|
- **Containerisation** : Docker & Docker Compose
|
||||||
|
- **Reverse Proxy** : Nginx
|
||||||
|
- **SSL/TLS** : Certificats HTTPS
|
||||||
|
- **Base de données** : PostgreSQL en conteneur
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
```
|
||||||
|
ft_transcendence/
|
||||||
|
├── docker-compose.yml # Orchestration des services
|
||||||
|
├── frontend/ # Application client
|
||||||
|
│ ├── src/
|
||||||
|
│ ├── public/
|
||||||
|
│ └── Dockerfile
|
||||||
|
├── backend/ # API serveur
|
||||||
|
│ ├── api/
|
||||||
|
│ ├── models/
|
||||||
|
│ ├── services/
|
||||||
|
│ └── Dockerfile
|
||||||
|
├── database/ # Configuration PostgreSQL
|
||||||
|
├── nginx/ # Configuration reverse proxy
|
||||||
|
└── ssl/ # Certificats SSL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Modules bonus
|
||||||
|
- **Module Web** : Framework moderne (React/Vue/Angular)
|
||||||
|
- **Module User Management** : Authentification avancée
|
||||||
|
- **Module Gaming** : Variantes de Pong ou autres jeux
|
||||||
|
- **Module AI-Algo** : IA pour jouer contre
|
||||||
|
- **Module Cybersecurity** : Sécurité renforcée
|
||||||
|
- **Module DevOps** : Infrastructure monitoring
|
||||||
|
- **Module Graphics** : Interface 3D avancée
|
||||||
|
|
||||||
|
## Installation et déploiement
|
||||||
|
|
||||||
|
### Prérequis
|
||||||
|
- Docker et Docker Compose
|
||||||
|
- Domaine avec certificat SSL
|
||||||
|
- Clés API (42, Google) pour OAuth
|
||||||
|
|
||||||
|
### Lancement
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd ft_transcendence
|
||||||
|
docker-compose up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
1. Configurer les variables d'environnement
|
||||||
|
2. Générer les certificats SSL
|
||||||
|
3. Configurer OAuth applications
|
||||||
|
4. Initialiser la base de données
|
||||||
|
|
||||||
|
## Gameplay
|
||||||
|
|
||||||
|
### Pong multijoueur
|
||||||
|
- Contrôles clavier fluides
|
||||||
|
- Synchronisation en temps réel
|
||||||
|
- Système de score et timer
|
||||||
|
- Reconnexion automatique
|
||||||
|
|
||||||
|
### Tournois
|
||||||
|
- Création de tournois public/privé
|
||||||
|
- Système d'élimination
|
||||||
|
- Classements et récompenses
|
||||||
|
- Notifications en temps réel
|
||||||
|
|
||||||
|
## Sécurité implémentée
|
||||||
|
- 🔒 **HTTPS** obligatoire
|
||||||
|
- 🛡️ **Protection CSRF/XSS**
|
||||||
|
- 🔑 **Authentification 2FA**
|
||||||
|
- 💾 **Hashage sécurisé** des mots de passe
|
||||||
|
- 🚫 **Protection injection SQL**
|
||||||
|
- 🔐 **Validation** côté serveur
|
||||||
|
- 🍪 **Gestion sécurisée** des sessions
|
||||||
|
|
||||||
|
## Fonctionnalités sociales
|
||||||
|
- **Profils utilisateurs** personnalisables
|
||||||
|
- **Système d'amis** avec invitations
|
||||||
|
- **Chat global** et channels privés
|
||||||
|
- **Statut en ligne** des utilisateurs
|
||||||
|
- **Historique des parties**
|
||||||
|
- **Achievements** et badges
|
||||||
|
|
||||||
|
## Performance et scalabilité
|
||||||
|
- **WebSockets** pour le temps réel
|
||||||
|
- **Cache Redis** pour les sessions
|
||||||
|
- **Optimisation** des requêtes DB
|
||||||
|
- **Load balancing** pour la montée en charge
|
||||||
|
- **Monitoring** des performances
|
||||||
|
|
||||||
|
## Tests et qualité
|
||||||
|
- **Tests unitaires** backend
|
||||||
|
- **Tests d'intégration** API
|
||||||
|
- **Tests end-to-end** Selenium
|
||||||
|
- **Sécurité** avec OWASP ZAP
|
||||||
|
- **Performance** avec JMeter
|
||||||
|
|
||||||
|
## Compétences développées
|
||||||
|
- Architecture d'applications web modernes
|
||||||
|
- Développement full-stack
|
||||||
|
- Sécurité web avancée
|
||||||
|
- DevOps et containerisation
|
||||||
|
- Gestion de projet complexe
|
||||||
|
- Programmation temps réel
|
||||||
|
- UI/UX design
|
||||||
|
|
||||||
|
## Contraintes 42
|
||||||
|
- **Single Page Application** obligatoire
|
||||||
|
- **3 frameworks/langages** différents minimum
|
||||||
|
- **Docker** pour tous les services
|
||||||
|
- **Sécurité** de niveau production
|
||||||
|
- **Code maintenable** et documenté
|
||||||
|
|
||||||
|
## Auteur
|
||||||
|
Alexandre Pommier (apommier) - École 42
|
||||||
|
|
||||||
|
## Équipe (si applicable)
|
||||||
|
- Développeur Frontend
|
||||||
|
- Développeur Backend
|
||||||
|
- DevOps Engineer
|
||||||
|
- Security Specialist
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
Projet académique - École 42
|
||||||
@ -3,14 +3,14 @@ server {
|
|||||||
# listen 80 ssl;
|
# listen 80 ssl;
|
||||||
# listen 443 ssl;
|
# listen 443 ssl;
|
||||||
# listen ${NGINX_PORT};
|
# listen ${NGINX_PORT};
|
||||||
listen 80;
|
listen 8080;
|
||||||
|
|
||||||
location /{
|
location /{
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_pass http://react_app:8080;
|
proxy_pass http://react_app:8001;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /api {
|
location /api {
|
||||||
@ -20,4 +20,18 @@ server {
|
|||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_pass http://api:3000/api;
|
proxy_pass http://api:3000/api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /socket {
|
||||||
|
# Forward requests to socket server running on port 4001
|
||||||
|
if ($request_uri ~ ^/socket/4001) {
|
||||||
|
proxy_pass http://chat:4001;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Forward requests to socket server running on port 4000
|
||||||
|
if ($request_uri ~ ^/socket/4000) {
|
||||||
|
proxy_pass http://pong:4000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
|
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/18 17:45:39 by apommier ### ########.fr */
|
/* Updated: 2023/06/21 01:19:01 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -27,6 +27,7 @@ import { generateOTP } from './users/2fa';
|
|||||||
import { VerifyOTP } from './users/2fa';
|
import { VerifyOTP } from './users/2fa';
|
||||||
import { ValidateOTP } from './users/2fa';
|
import { ValidateOTP } from './users/2fa';
|
||||||
import { privateDecrypt } from 'crypto';
|
import { privateDecrypt } from 'crypto';
|
||||||
|
import { formatWithOptions } from 'util';
|
||||||
|
|
||||||
|
|
||||||
//2fa
|
//2fa
|
||||||
@ -128,6 +129,8 @@ export class AppController {
|
|||||||
async newBlocked(@Request() req, @Body() data: any) {
|
async newBlocked(@Request() req, @Body() data: any) {
|
||||||
// return await this.userService.getFriends(req.user.username);
|
// return await this.userService.getFriends(req.user.username);
|
||||||
console.log(`user= ${req.user.username}`)
|
console.log(`user= ${req.user.username}`)
|
||||||
|
if (data.username === req.user.username)
|
||||||
|
return (0);
|
||||||
const user = await this.userService.findOne(req.user.username)
|
const user = await this.userService.findOne(req.user.username)
|
||||||
return await this.userService.addBlocked(user, data.username);
|
return await this.userService.addBlocked(user, data.username);
|
||||||
}
|
}
|
||||||
@ -136,6 +139,8 @@ export class AppController {
|
|||||||
@Post('/invite')
|
@Post('/invite')
|
||||||
async newInvite(@Request() req, @Body() data: any) {
|
async newInvite(@Request() req, @Body() data: any) {
|
||||||
console.log(`user= ${req.user.username}`)
|
console.log(`user= ${req.user.username}`)
|
||||||
|
if (data.username === req.user.username)
|
||||||
|
return (0);
|
||||||
const user = await this.userService.findOne(data.username)
|
const user = await this.userService.findOne(data.username)
|
||||||
if (!user)
|
if (!user)
|
||||||
return (0);
|
return (0);
|
||||||
@ -215,7 +220,10 @@ export class AppController {
|
|||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/win')
|
@Post('/win')
|
||||||
async addWin(@Request() req, @Body() data: any) {
|
async addWin(@Request() req, @Body() data: any) {
|
||||||
|
console.log("WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIN: ", req.user.username)
|
||||||
const user = await this.userService.findOne(req.user.username);
|
const user = await this.userService.findOne(req.user.username);
|
||||||
|
console.log("User", user)
|
||||||
|
// const user2 = await this.userService.findOne(data.opName);
|
||||||
user.win++;
|
user.win++;
|
||||||
const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor))
|
const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor))
|
||||||
const newRank = user.rank + this.kFactor * (1 - Esp);
|
const newRank = user.rank + this.kFactor * (1 - Esp);
|
||||||
@ -229,14 +237,16 @@ export class AppController {
|
|||||||
newMatch.opScore = data.opScore;
|
newMatch.opScore = data.opScore;
|
||||||
newMatch.opponent = data.opName;
|
newMatch.opponent = data.opName;
|
||||||
newMatch.parent = user;
|
newMatch.parent = user;
|
||||||
|
console.log(`newMatch WIIIN = ${newMatch}`);
|
||||||
await this.userService.saveChild(user, newMatch);
|
await this.userService.saveChild(user, newMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/loss')
|
@Post('/loss')
|
||||||
async addLoss(@Request() req, @Body() data: any) {
|
async addLoss(@Request() req, @Body() data: any) {
|
||||||
|
console.log("LOOOOOOOOOOOOOOOSE: ", req.user.username)
|
||||||
const user = await this.userService.findOne(req.user.username);
|
const user = await this.userService.findOne(req.user.username);
|
||||||
|
console.log("User", user)
|
||||||
user.loss++;
|
user.loss++;
|
||||||
|
|
||||||
const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor))
|
const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor))
|
||||||
@ -251,7 +261,7 @@ export class AppController {
|
|||||||
newMatch.opScore = data.opScore;
|
newMatch.opScore = data.opScore;
|
||||||
newMatch.opponent = data.opName;
|
newMatch.opponent = data.opName;
|
||||||
newMatch.parent = user;
|
newMatch.parent = user;
|
||||||
|
console.log(`newMatch Loose= ${newMatch}`);
|
||||||
await this.userService.saveChild(user, newMatch);
|
await this.userService.saveChild(user, newMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,6 +280,49 @@ export class AppController {
|
|||||||
return await this.userService.getRanking();
|
return await this.userService.getRanking();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/partyInvite')
|
||||||
|
async partyInvite(@Request() req, @Body() data: any)
|
||||||
|
{
|
||||||
|
//find data.username and add invite to list
|
||||||
|
console.log("data post priv invite=", data);
|
||||||
|
const user = await this.userService.findOne(data.username);
|
||||||
|
user.partyInvite = user.partyInvite || [];
|
||||||
|
user.partyInvite.push({ username: req.user.username, gameId: data.gameId });
|
||||||
|
console.log("usr === ", user)
|
||||||
|
await this.userService.save(user);
|
||||||
|
// user.partyInvite.push(data);
|
||||||
|
console.log("invite === ", user.partyInvite)
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Get('/partyInvite')
|
||||||
|
async getPartyInvite(@Request() req, @Body() data: any)
|
||||||
|
{
|
||||||
|
//find data.username and add invite to list
|
||||||
|
const user = await this.userService.findOne(req.user.username);
|
||||||
|
user.partyInvite = user.partyInvite || [];
|
||||||
|
// this.userService.save(user);
|
||||||
|
// user.partyInvite.push(data);
|
||||||
|
// console.log("data invite === ", data.username)
|
||||||
|
return user.partyInvite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/deleteInvite')
|
||||||
|
async deleteInvite(@Request() req, @Body() data: any)
|
||||||
|
{
|
||||||
|
console.log("delete invite user= ", data.username)
|
||||||
|
const user = await this.userService.findOne(req.user.username);
|
||||||
|
|
||||||
|
|
||||||
|
// user.partyInvite = user.partyInvite.filter(item => Object.values(item)[1] !== req.user.username);
|
||||||
|
console.log("user.partyInvite before", user.partyInvite)
|
||||||
|
user.partyInvite = user.partyInvite.filter((item) => Object.values(item)[1] !== data.username);
|
||||||
|
console.log("user.partyInvite after", user.partyInvite)
|
||||||
|
this.userService.save(user);
|
||||||
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/history')
|
@Post('/history')
|
||||||
async getHistory(@Body() data: any)
|
async getHistory(@Body() data: any)
|
||||||
@ -441,6 +494,13 @@ export class AppController {
|
|||||||
return await this.chatService.findAll();
|
return await this.chatService.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/convId')
|
||||||
|
async getConvById(@Body() data: any) {
|
||||||
|
return await this.chatService.findConv(data.convId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/message')
|
@Post('/message')
|
||||||
async postMessage(@Request() req, @Body() data: any) {
|
async postMessage(@Request() req, @Body() data: any) {
|
||||||
@ -481,12 +541,6 @@ export class AppController {
|
|||||||
// res.json(messages);
|
// res.json(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
|
||||||
@Post('/ban')
|
|
||||||
async banUser(@Body() data: any) {
|
|
||||||
return await this.chatService.banUser(data.convId, data.username)
|
|
||||||
}
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/name')
|
@Post('/name')
|
||||||
async setName(@Body() data: any) {
|
async setName(@Body() data: any) {
|
||||||
@ -495,12 +549,6 @@ export class AppController {
|
|||||||
return await this.chatService.setName(data.convId, data.name)
|
return await this.chatService.setName(data.convId, data.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
|
||||||
@Post('/invite')
|
|
||||||
async inviteUser(@Body() data: any) {
|
|
||||||
return await this.chatService.inviteUser(data.convId, data.username)
|
|
||||||
}
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/password')
|
@Post('/password')
|
||||||
async setPassword(@Body() data: any) {
|
async setPassword(@Body() data: any) {
|
||||||
@ -513,12 +561,36 @@ export class AppController {
|
|||||||
return await this.chatService.verifyPassword(data.convId, data.password)
|
return await this.chatService.verifyPassword(data.convId, data.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/invite')
|
||||||
|
async inviteUser(@Body() data: any) {
|
||||||
|
return await this.chatService.inviteUser(data.convId, data.username)
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/ban')
|
||||||
|
async banUser(@Body() data: any) {
|
||||||
|
if (!data.username)
|
||||||
|
return ;
|
||||||
|
return await this.chatService.banUser(data.convId, data.username)
|
||||||
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/admin')
|
@Post('/admin')
|
||||||
async setAdmin(@Body() data: any) {
|
async setAdmin(@Body() data: any) {
|
||||||
|
if (!data.username)
|
||||||
|
return ;
|
||||||
return await this.chatService.setAdmin(data.convId, data.username)
|
return await this.chatService.setAdmin(data.convId, data.username)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Post('/mute')
|
||||||
|
async muteUser(@Body() data: any) {
|
||||||
|
if (!data.username)
|
||||||
|
return ;
|
||||||
|
return await this.chatService.muteUser(data.convId, data.username)
|
||||||
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/isAdmin')
|
@Post('/isAdmin')
|
||||||
async isAdmin(@Request() req, @Body() data: any) {
|
async isAdmin(@Request() req, @Body() data: any) {
|
||||||
@ -526,11 +598,6 @@ export class AppController {
|
|||||||
return await this.chatService.isAdmin(data.convId, req.user.username)
|
return await this.chatService.isAdmin(data.convId, req.user.username)
|
||||||
}
|
}
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
|
||||||
@Post('/mute')
|
|
||||||
async muteUser(@Body() data: any) {
|
|
||||||
return await this.chatService.muteUser(data.convId, data.username)
|
|
||||||
}
|
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Post('/private')
|
@Post('/private')
|
||||||
|
|||||||
@ -58,6 +58,7 @@ export class loginClass {
|
|||||||
console.log(`no user, creating one`);
|
console.log(`no user, creating one`);
|
||||||
user = {
|
user = {
|
||||||
id: null,
|
id: null,
|
||||||
|
partyInvite: null,
|
||||||
password: null,
|
password: null,
|
||||||
username: userName,
|
username: userName,
|
||||||
nickname: userName,
|
nickname: userName,
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/17 01:00:25 by apommier #+# #+# */
|
/* Created: 2023/06/17 01:00:25 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/18 13:14:51 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 16:47:02 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -85,6 +85,7 @@ async banUser(convId: number, username: string) {
|
|||||||
conv.banned = conv.banned || [];
|
conv.banned = conv.banned || [];
|
||||||
if (conv.banned.find(item => item === username))
|
if (conv.banned.find(item => item === username))
|
||||||
return (1);
|
return (1);
|
||||||
|
conv.members = conv.members.filter((item) => item !== username);
|
||||||
conv.banned.push(username);
|
conv.banned.push(username);
|
||||||
this.save(conv);
|
this.save(conv);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
|
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/12 14:51:44 by apommier ### ########.fr */
|
/* Updated: 2023/06/22 20:42:32 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ export const getTypeOrmConfig = (): TypeOrmModuleOptions => ({
|
|||||||
host: process.env.POSTGRES_HOST || 'postgresql',
|
host: process.env.POSTGRES_HOST || 'postgresql',
|
||||||
port: parseInt(process.env.POSTGRES_PORT, 10) || 5432,
|
port: parseInt(process.env.POSTGRES_PORT, 10) || 5432,
|
||||||
username: process.env.POSTGRES_USER || 'postgres',
|
username: process.env.POSTGRES_USER || 'postgres',
|
||||||
password: process.env.POSTGRES_PASSWORD || 'pass',
|
password: process.env.POSTGRES_PASSWORD || 'postgres',
|
||||||
database: process.env.POSTGRES_DATABASE || 'postgres',
|
database: process.env.POSTGRES_DATABASE || 'postgres',
|
||||||
entities: ["dist/**/*.entity.js"],
|
entities: ["dist/**/*.entity.js"],
|
||||||
// entities: [join(__dirname, '**', '*.entity.{ts,js}')]
|
// entities: [join(__dirname, '**', '*.entity.{ts,js}')]
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/17 01:00:20 by apommier #+# #+# */
|
/* Created: 2023/06/17 01:00:20 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/17 01:31:29 by apommier ### ########.fr */
|
/* Updated: 2023/06/23 15:18:19 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,12 @@ export class User {
|
|||||||
@Column('text', { array: true, nullable: true })
|
@Column('text', { array: true, nullable: true })
|
||||||
friendRequest: string[];
|
friendRequest: string[];
|
||||||
|
|
||||||
|
@Column({ type: 'jsonb', nullable: true })
|
||||||
|
partyInvite: Record<string, string>[];
|
||||||
|
|
||||||
|
// @Column('text', { array: true, nullable: true })
|
||||||
|
// friendRequest: string[];
|
||||||
|
|
||||||
@Column('text', { array: true, nullable: true })
|
@Column('text', { array: true, nullable: true })
|
||||||
friends: string[];
|
friends: string[];
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/17 01:00:07 by apommier #+# #+# */
|
/* Created: 2023/06/17 01:00:07 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/17 01:00:08 by apommier ### ########.fr */
|
/* Updated: 2023/06/21 01:31:44 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -47,6 +47,7 @@ export class UsersService {
|
|||||||
|
|
||||||
async saveChild(user: User, match: MatchLog): Promise<User> {
|
async saveChild(user: User, match: MatchLog): Promise<User> {
|
||||||
// user.match = savedChild;
|
// user.match = savedChild;
|
||||||
|
user.children.push(match)
|
||||||
await this.matchRepository.save(match);
|
await this.matchRepository.save(match);
|
||||||
return await this.userRepository.save(user);
|
return await this.userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,16 +8,20 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
|||||||
@WebSocketServer()
|
@WebSocketServer()
|
||||||
server: Server;
|
server: Server;
|
||||||
|
|
||||||
|
|
||||||
private clients: Record<string, Socket> = {};
|
private clients: Record<string, Socket> = {};
|
||||||
// private clientsNames: Record<string, Socket[]> = {};
|
// private clientsNames: Record<string, Socket[]> = {};
|
||||||
private clientsNames: Map<string, string[]> = new Map();
|
private clientsNames: Map<string, string[]> = new Map();
|
||||||
// private games: Map<string, Socket[]> = new Map();// Chat en cours, identifiées par un ID
|
// private games: Map<string, Socket[]> = new Map();// Chat en cours, identifiées par un ID
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
afterInit(server: Server)
|
afterInit(server: Server)
|
||||||
{
|
{
|
||||||
console.log('ChatGateway initialized');
|
console.log('ChatGateway initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
handleConnection(client: Socket, ...args: any[])
|
handleConnection(client: Socket, ...args: any[])
|
||||||
{
|
{
|
||||||
console.log(`Client connected: ${client.id}`);
|
console.log(`Client connected: ${client.id}`);
|
||||||
@ -92,93 +96,82 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
|||||||
console.log("create")
|
console.log("create")
|
||||||
this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value
|
this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value
|
||||||
}
|
}
|
||||||
// let clientLenght = Object.keys(this.clientsNames[payload.username]).length
|
|
||||||
// const clientArray = this.clientsNames.get(payload.username)
|
|
||||||
// let clientLenght = clientArray.
|
|
||||||
// console.log(`lenght= ${clientLenght}`)
|
|
||||||
|
|
||||||
// this.clientsNames[payload.username][clientLenght] = this.clients[client.id];
|
|
||||||
// console.log(`clients: ${Object.keys(this.clientsNames).length}`)
|
|
||||||
// this.clients[clientId] = client;
|
|
||||||
|
|
||||||
//add a new client with socket and name for key
|
|
||||||
//payload.username
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @SubscribeMessage('socket.io')
|
||||||
|
// socketConnect(client: any, payload: any): void {
|
||||||
|
// console.log("/socket.io")
|
||||||
|
// }
|
||||||
|
|
||||||
// @SubscribeMessage('sendMessage')
|
@SubscribeMessage('ban')
|
||||||
// handleMessage(user: any, payload: any): void {
|
banUser(client: any, payload: any): void {
|
||||||
// console.log(`message recceveid: ${payload}`)
|
if (!this.clientsNames.has(payload.username))
|
||||||
// console.log(`message recceveid: ${payload.sender}`)
|
{
|
||||||
// console.log(`message recceveid: ${payload.convId}`)
|
console.log("No user found.");
|
||||||
// console.log(`message recceveid: ${payload.members}`)
|
return;
|
||||||
|
}
|
||||||
|
const bannedClients = this.clientsNames.get(payload.username);
|
||||||
|
bannedClients.forEach(client => {
|
||||||
|
console.log("Banning client:", client);
|
||||||
|
// Perform ban operation on each client, e.g., emit a 'ban' event
|
||||||
|
console.log("clietn socket=", this.clients[client])
|
||||||
|
this.clients[client].emit('ban', payload);
|
||||||
|
});
|
||||||
|
// console.log("/ban")
|
||||||
|
// console.log("in ban username=", payload.username)
|
||||||
|
// if (!this.clientsNames[payload.username])
|
||||||
|
// {
|
||||||
|
// console.log("no user ??")
|
||||||
|
// return ;
|
||||||
|
// }
|
||||||
|
// this.clientsNames[payload.username].forEach()
|
||||||
|
// console.log("client=", this.clientsNames)
|
||||||
|
// this.clients[payload.username].emit('ban', payload)
|
||||||
|
}
|
||||||
|
|
||||||
// console.log(`client id: ${user.id}`)
|
@SubscribeMessage('mute')
|
||||||
|
muteUser(client: any, payload: any): void {
|
||||||
|
if (!this.clientsNames.has(payload.username))
|
||||||
|
{
|
||||||
|
console.log("No user found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const mutedClients = this.clientsNames.get(payload.username);
|
||||||
|
mutedClients.forEach(client => {
|
||||||
|
console.log("Banning client:", client);
|
||||||
|
// Perform ban operation on each client, e.g., emit a 'ban' event
|
||||||
|
console.log("clietn socket=", this.clients[client])
|
||||||
|
this.clients[client].emit('mute', payload);
|
||||||
|
});
|
||||||
|
console.log("/mute")
|
||||||
|
}
|
||||||
|
|
||||||
// this.clientsNames.forEach((clientArray, clientName) => {
|
|
||||||
// console.log(`Clients with name ${clientName}:`);
|
|
||||||
|
|
||||||
// // clientArray.forEach((client) => {
|
|
||||||
// this.clientsNames[clientName]
|
|
||||||
// // .forEach(client => {
|
|
||||||
// // // if(client.id != user.id)
|
|
||||||
// // // {
|
|
||||||
// // console.log("send to someone")
|
|
||||||
// // console.log(client); // Perform actions on each client
|
|
||||||
// // // clients.emit('message', payload)
|
|
||||||
// // client.emit('message')
|
|
||||||
// // // }
|
|
||||||
// // });
|
|
||||||
|
|
||||||
// // .forEach((client) => {
|
|
||||||
// // if(client.id != user.id)
|
|
||||||
// // {
|
|
||||||
// // console.log("send to someone")
|
|
||||||
// // console.log(client); // Perform actions on each client
|
|
||||||
// // // clients.emit('message', payload)
|
|
||||||
// // client.emit('message')
|
|
||||||
// // }
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
@SubscribeMessage('sendMessage')
|
@SubscribeMessage('sendMessage')
|
||||||
handleMessage(client: Socket, payload: any): void {
|
handleMessage(client: Socket, payload: any): void {
|
||||||
// console.log(`message received: ${payload}`);
|
// console.log(`message received: ${payload}`);
|
||||||
console.log(`message sender: ${payload.sender}`);
|
// console.log(`message sender: ${payload.sender}`);
|
||||||
console.log(`client id: ${client.id}`);
|
// console.log(`client id: ${client.id}`);
|
||||||
console.log(`conversation ID: ${payload.convId}`);
|
// console.log(`conversation ID: ${payload.convId}`);
|
||||||
console.log(`members: ${payload.members}`);
|
// console.log(`members: ${payload.members}`);
|
||||||
|
|
||||||
this.clientsNames.forEach((clientArray, clientName) =>
|
this.clientsNames.forEach((clientArray, clientName) =>
|
||||||
{
|
{
|
||||||
console.log(` 5Clients with name ${clientName}:`);
|
// console.log(` 5Clients with name ${clientName}:`);
|
||||||
if (payload.members.includes(clientName))
|
if (payload.members.includes(clientName))
|
||||||
{
|
{
|
||||||
clientArray.forEach((targetClient, index) =>
|
clientArray.forEach((targetClient, index) =>
|
||||||
{
|
{
|
||||||
console.log(`client id: ${client.id}`);
|
// console.log(`client id: ${client.id}`);
|
||||||
console.log(`target: ${targetClient}`);
|
// console.log(`target: ${targetClient}`);
|
||||||
console.log(`target id: ${targetClient}`);
|
// console.log(`target id: ${targetClient}`);
|
||||||
if (targetClient && targetClient !== client.id)
|
if (targetClient && targetClient !== client.id)
|
||||||
{
|
{
|
||||||
console.log("Sending to someone");
|
// console.log("Sending to someone");
|
||||||
console.log(`index= ${index}`);
|
// console.log(`index= ${index}`);
|
||||||
console.log(`target: ${targetClient}`); // Perform actions on each target client
|
// console.log(`target: ${targetClient}`); // Perform actions on each target client
|
||||||
// targetClient.emit('message')
|
|
||||||
// this.clientsNames[clientName].emit('message')
|
|
||||||
// this.clientsNames["apommier"].emit('message')
|
|
||||||
this.clients[targetClient].emit('message', payload)
|
this.clients[targetClient].emit('message', payload)
|
||||||
// console.log(test)
|
|
||||||
// console.log(test)
|
|
||||||
// this.clientsNames[clientName][index].emit('message');
|
|
||||||
// const socket = this.server.sockets.sockets.get(targetClient.id);
|
|
||||||
// if (socket) {
|
|
||||||
// socket.emit('message', payload);
|
|
||||||
// } else {
|
|
||||||
// console.log(`Socket with ID ${client.id} not found.`);
|
|
||||||
// }
|
|
||||||
// targetClient.emit('message', payload);
|
|
||||||
// targetClient.emit('message', payload);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log("not sending");
|
console.log("not sending");
|
||||||
@ -193,41 +186,3 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// for (let key in this.clientsNames) {
|
|
||||||
// if (payload.members.includes(key)) {
|
|
||||||
// console.log("Key exists in the array");
|
|
||||||
// // if (key !== payload.sender)
|
|
||||||
// // {
|
|
||||||
// for (let key2 in this.clientsNames[key])
|
|
||||||
// {
|
|
||||||
// if (client.id !== this.clientsNames[key][key2])
|
|
||||||
// {
|
|
||||||
// console.log("send to someone")
|
|
||||||
// this.clientsNames[key][key2].emit('message', payload)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // }
|
|
||||||
// //if member socket different from mine
|
|
||||||
// //send
|
|
||||||
// } else {
|
|
||||||
// console.log("Key does not exist in the array");
|
|
||||||
// }
|
|
||||||
//if key is in member
|
|
||||||
|
|
||||||
// let socket = this.clients[key];
|
|
||||||
// console.log("Clé:", key);
|
|
||||||
// console.log("Socket:", socket);
|
|
||||||
// }
|
|
||||||
// payload.convId // conv user instead ?
|
|
||||||
//find user to send message to
|
|
||||||
//const res = {
|
|
||||||
//convId: payload.convId
|
|
||||||
//sender: payload.sender
|
|
||||||
|
|
||||||
// }
|
|
||||||
//while (user of conv)//how to get conv user
|
|
||||||
// if (user connected)
|
|
||||||
//send res to user
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,26 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* pong.gateway.ts :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/06/19 15:18:38 by apommier #+# #+# */
|
||||||
|
/* Updated: 2023/06/23 15:19:12 by apommier ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
|
import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
|
||||||
import { Server, Socket } from 'socket.io';
|
import { Server, Socket } from 'socket.io';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
// Connection/Disconnection
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
|
||||||
@WebSocketGateway({ cors: true })
|
@WebSocketGateway({ cors: true })
|
||||||
export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
|
export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
|
||||||
@WebSocketServer() server: Server;
|
@WebSocketServer() server: Server;
|
||||||
@ -31,50 +50,82 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
|
|||||||
|
|
||||||
handleDisconnect(client: Socket)
|
handleDisconnect(client: Socket)
|
||||||
{
|
{
|
||||||
console.log(`Client disconnected: ${client.id}`);
|
console.log(`Normal disconnected: ${client.id}`);
|
||||||
// this.waitingClients.delete(client);
|
|
||||||
this.waitingClients.forEach((waitingClient) => {
|
this.waitingClients.forEach((item) => {
|
||||||
if (waitingClient.client === client) {
|
if (item.client === client)
|
||||||
this.waitingClients.delete(waitingClient);
|
this.waitingClients.delete(item);
|
||||||
}})
|
});
|
||||||
|
|
||||||
|
// Delete the socket from the 'games' map
|
||||||
|
this.games.forEach((sockets, gameId) => {
|
||||||
|
const index = sockets.indexOf(client);
|
||||||
|
if (index !== -1)
|
||||||
|
{
|
||||||
|
if (index === 0)
|
||||||
|
{
|
||||||
|
console.log("emit boy1")
|
||||||
|
sockets[1].emit("pong:win")
|
||||||
|
// sockets[0].emit("/win")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log("emit boy2")
|
||||||
|
sockets[0].emit("pong:win")
|
||||||
|
// sockets[1].emit("/win")
|
||||||
|
}
|
||||||
|
this.games.delete(gameId);
|
||||||
delete this.clients[client.id];
|
delete this.clients[client.id];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
|
console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @SubscribeMessage('pong:matchmaking')
|
|
||||||
// addMatchmaking(client: Socket, payload: any): void
|
|
||||||
// {
|
|
||||||
// console.log("matchmaking");
|
|
||||||
// console.log(payload);
|
|
||||||
// // this.waitingClients.add(client);
|
|
||||||
// this.waitingClients.add(client);
|
|
||||||
// console.log("Adding client to waiting list...");
|
|
||||||
// if (this.waitingClients.size >= 2) {
|
|
||||||
// console.log("Creating new game...");
|
|
||||||
// const players = Array.from(this.waitingClients).slice(0, 2);
|
|
||||||
// players.forEach((player) => {
|
|
||||||
// this.waitingClients.delete(player);
|
|
||||||
// });
|
|
||||||
// const gameId = uuidv4();
|
|
||||||
// this.games.set(gameId, players);
|
|
||||||
// players.forEach((player) => {
|
|
||||||
// player.join(gameId);
|
|
||||||
// console.log(`Player ${player.id} joined game ${gameId}`);
|
|
||||||
// });
|
|
||||||
// players.forEach((player) => {
|
|
||||||
// // const playersIds = game.map(socket => socket.id);
|
|
||||||
// player.emit('pong:gameId', gameId);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// // console.log(`from: ${client.id}`);
|
|
||||||
// }
|
|
||||||
@SubscribeMessage('pong:invite')
|
|
||||||
createPrivateGame(client: Socket, payload: any): void {
|
|
||||||
//after invite accepted ?
|
|
||||||
//set the two user in a game ?
|
|
||||||
|
|
||||||
|
@SubscribeMessage('pong:disconnect')
|
||||||
|
disconnectClient(client: Socket, payload: any): void {
|
||||||
|
console.log("disconnect forced client= ", client.id)
|
||||||
|
|
||||||
|
for (const key in this.clients) {
|
||||||
|
if (this.clients.hasOwnProperty(key) && this.clients[key] === client)
|
||||||
|
delete this.clients[key];
|
||||||
|
}
|
||||||
|
// Delete the socket from the 'waitingClients' set
|
||||||
|
this.waitingClients.forEach((item) => {
|
||||||
|
if (item.client === client)
|
||||||
|
this.waitingClients.delete(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete the socket from the 'games' map
|
||||||
|
this.games.forEach((sockets, gameId) => {
|
||||||
|
const index = sockets.indexOf(client);
|
||||||
|
if (index !== -1)
|
||||||
|
{
|
||||||
|
if (index === 0)
|
||||||
|
{
|
||||||
|
console.log("emit boy1")
|
||||||
|
sockets[1].emit("pong:win")
|
||||||
|
// sockets[0].emit("/win")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log("emit boy2")
|
||||||
|
sockets[0].emit("pong:win")
|
||||||
|
// sockets[1].emit("/win")
|
||||||
|
}
|
||||||
|
this.games.delete(gameId);
|
||||||
|
delete this.clients[client.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
// Matchmaking
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
|
||||||
@SubscribeMessage('pong:matchmaking')
|
@SubscribeMessage('pong:matchmaking')
|
||||||
addMatchmaking(client: Socket, payload: any): void {
|
addMatchmaking(client: Socket, payload: any): void {
|
||||||
@ -91,6 +142,7 @@ addMatchmaking(client: Socket, payload: any): void {
|
|||||||
waitingClient.option === payload.option && waitingClient.client !== client
|
waitingClient.option === payload.option && waitingClient.client !== client
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if (matchingClients.length > 0) {
|
if (matchingClients.length > 0) {
|
||||||
console.log("Creating new game...");
|
console.log("Creating new game...");
|
||||||
const players = [matchingClients[0].client, client]; // Add the current client to the players array
|
const players = [matchingClients[0].client, client]; // Add the current client to the players array
|
||||||
@ -117,44 +169,77 @@ addMatchmaking(client: Socket, payload: any): void {
|
|||||||
player.emit('pong:gameId', gameId);
|
player.emit('pong:gameId', gameId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(`from: ${client.id}`);
|
// console.log(`from: ${client.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @SubscribeMessage('pong:message')
|
|
||||||
// handleMessage(client: Socket, payload: any): void
|
|
||||||
// {
|
|
||||||
// console.log(`from: ${client.id}`);
|
|
||||||
// console.log(payload);
|
|
||||||
|
|
||||||
// const game = this.games.get(payload.gameId);
|
|
||||||
// const playersIds = game.map(socket => socket.id);
|
|
||||||
// // const players = Object.keys(game);
|
|
||||||
|
|
||||||
// // if (Object.keys(this.clients).length === 2)
|
//========================================================================================================
|
||||||
// // {
|
//========================================================================================================
|
||||||
// // const clientIds = Object.keys(this.clients);
|
// Private Match
|
||||||
// // console.log(`id of 0= ${clientIds[0]}`);
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
|
||||||
// // payload.ballX
|
|
||||||
// // payload.ballY
|
|
||||||
// // payload.
|
|
||||||
|
|
||||||
// if (clientIds[0] === payload.id)
|
|
||||||
// {
|
// @SubscribeMessage('pong:invite')
|
||||||
// // console.log("client 0 true");
|
// createPrivateGame(client: Socket, payload: any): void {
|
||||||
// if (payload.ballX <= payload.width / 2)
|
// //after invite accepted ?
|
||||||
// this.clients[clientIds[1]].emit('pong:info', payload);
|
// //set the two user in a game ?
|
||||||
// }
|
|
||||||
// else if (clientIds[1] === payload.id)
|
|
||||||
// {
|
|
||||||
// if (payload.ballX < payload.width / 2)
|
|
||||||
// this.clients[clientIds[0]].emit('pong:info', payload);
|
|
||||||
// // console.log("client 0 true");
|
|
||||||
// }
|
|
||||||
// // }
|
|
||||||
// console.log("END OF HANDLE");
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
@SubscribeMessage('pong:joinParty')
|
||||||
|
joinPrivateParty(client: Socket, payload: any): void {
|
||||||
|
console.log(" join PrivateParty")
|
||||||
|
|
||||||
|
const game = this.games.get(payload.gameId);
|
||||||
|
if (game)
|
||||||
|
{
|
||||||
|
game.push(client);
|
||||||
|
const playersIds = game.map(socket => socket.id);
|
||||||
|
this.clients[playersIds[0]].emit('pong:gameId', payload.gameId);
|
||||||
|
this.clients[playersIds[1]].emit('pong:gameId', payload.gameId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log("emit else")
|
||||||
|
client.emit("pong:win")
|
||||||
|
}
|
||||||
|
// console.log("no game ???")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SubscribeMessage('pong:privateParty')
|
||||||
|
addPrivateParty(client: Socket, payload: any): void {
|
||||||
|
console.log("addPrivateParty")
|
||||||
|
|
||||||
|
const gameId = uuidv4();
|
||||||
|
const players = [client];
|
||||||
|
this.games.set(gameId, players);
|
||||||
|
console.log("game created private")
|
||||||
|
client.emit('pong:privateId', gameId);
|
||||||
|
//create game
|
||||||
|
//emit private gameId to canvas (don't launch canvas)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
// In Game
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@SubscribeMessage('pong:power')
|
@SubscribeMessage('pong:power')
|
||||||
sendPower(client: Socket, payload: any): void
|
sendPower(client: Socket, payload: any): void
|
||||||
{
|
{
|
||||||
@ -191,29 +276,6 @@ addMatchmaking(client: Socket, payload: any): void {
|
|||||||
console.log("END OF HANDLE");
|
console.log("END OF HANDLE");
|
||||||
}
|
}
|
||||||
|
|
||||||
// @SubscribeMessage('pong:forced')
|
|
||||||
// forcedMessage(client: Socket, payload: any): void
|
|
||||||
// {
|
|
||||||
// console.log(`from: ${client.id}`);
|
|
||||||
// console.log(payload);
|
|
||||||
|
|
||||||
// if (Object.keys(this.clients).length === 2)
|
|
||||||
// {
|
|
||||||
// const clientIds = Object.keys(this.clients);
|
|
||||||
// console.log(`id of 0= ${clientIds[0]}`);
|
|
||||||
|
|
||||||
// if (clientIds[0] === payload.id)
|
|
||||||
// {
|
|
||||||
// this.clients[clientIds[1]].emit('pong:info', payload);
|
|
||||||
// }
|
|
||||||
// else if (clientIds[1] === payload.id)
|
|
||||||
// {
|
|
||||||
// this.clients[clientIds[0]].emit('pong:info', payload);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// console.log("END OF HANDLE");
|
|
||||||
// }
|
|
||||||
|
|
||||||
@SubscribeMessage('pong:forced')
|
@SubscribeMessage('pong:forced')
|
||||||
forcedMessage(client: Socket, payload: any): void
|
forcedMessage(client: Socket, payload: any): void
|
||||||
{
|
{
|
||||||
@ -236,29 +298,6 @@ addMatchmaking(client: Socket, payload: any): void {
|
|||||||
console.log("END OF HANDLE");
|
console.log("END OF HANDLE");
|
||||||
}
|
}
|
||||||
|
|
||||||
// @SubscribeMessage('pong:paddle')
|
|
||||||
// handlePaddle(client: Socket, payload: any): void
|
|
||||||
// {
|
|
||||||
// console.log(`from: ${client.id}`);
|
|
||||||
// console.log(payload);
|
|
||||||
|
|
||||||
// if (Object.keys(this.clients).length === 2)
|
|
||||||
// {
|
|
||||||
// const clientIds = Object.keys(this.clients);
|
|
||||||
// console.log(`id of 0= ${clientIds[0]}`);
|
|
||||||
|
|
||||||
// if (clientIds[0] === payload.id)
|
|
||||||
// {
|
|
||||||
// this.clients[clientIds[1]].emit('pong:paddle', payload);
|
|
||||||
// }
|
|
||||||
// else if (clientIds[1] === payload.id)
|
|
||||||
// {
|
|
||||||
// this.clients[clientIds[0]].emit('pong:paddle', payload);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// console.log("END OF HANDLE");
|
|
||||||
// }
|
|
||||||
|
|
||||||
@SubscribeMessage('pong:paddle')
|
@SubscribeMessage('pong:paddle')
|
||||||
handlePaddle(client: Socket, payload: any): void
|
handlePaddle(client: Socket, payload: any): void
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
# REACT_APP_BASE_URL=localhost
|
REACT_APP_BASE_URL=localhost:8080
|
||||||
REACT_APP_BASE_URL=92.143.191.152
|
REACT_APP_API_SECRET=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
|
||||||
|
REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41
|
||||||
|
# REACT_APP_BASE_URL=92.143.191.152
|
||||||
# REACT_APP_BASE_URL=192.168.1.19
|
# REACT_APP_BASE_URL=192.168.1.19
|
||||||
2
containers/react/assets.d.ts
vendored
Normal file
2
containers/react/assets.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
declare module '*.jpg';
|
||||||
|
declare module 'styled-components'
|
||||||
48
containers/react/interfaces.tsx
Normal file
48
containers/react/interfaces.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
export interface User {
|
||||||
|
id: number;
|
||||||
|
otp_enabled: boolean;
|
||||||
|
otp_verified: boolean;
|
||||||
|
otp_base32: string;
|
||||||
|
nickname: string;
|
||||||
|
username: string;
|
||||||
|
photo: Buffer;
|
||||||
|
password: string;
|
||||||
|
win: number;
|
||||||
|
loss: number;
|
||||||
|
rank: number;
|
||||||
|
status: number;
|
||||||
|
userId: number;
|
||||||
|
friendRequest: string[];
|
||||||
|
partyInvite: Record<string, string>[];
|
||||||
|
friends: string[];
|
||||||
|
blocked: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Conv {
|
||||||
|
id: number;
|
||||||
|
members?: string[];
|
||||||
|
name: string
|
||||||
|
group: boolean
|
||||||
|
private: boolean
|
||||||
|
banned?: string[];
|
||||||
|
muted?: string[];
|
||||||
|
admin?: string[];
|
||||||
|
owner?: string;
|
||||||
|
password?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Message {
|
||||||
|
id: number;
|
||||||
|
convId: number;
|
||||||
|
sender: string;
|
||||||
|
text: string;
|
||||||
|
createdAt?: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Matchlog {
|
||||||
|
id: number;
|
||||||
|
opponent: string;
|
||||||
|
myScore: number;
|
||||||
|
opScore: number;
|
||||||
|
parent: User;
|
||||||
|
}
|
||||||
15
containers/react/package-lock.json
generated
15
containers/react/package-lock.json
generated
@ -25,6 +25,9 @@
|
|||||||
"styled-components": "^5.3.10",
|
"styled-components": "^5.3.10",
|
||||||
"typescript": "^3.2.1",
|
"typescript": "^3.2.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@adobe/css-tools": {
|
"node_modules/@adobe/css-tools": {
|
||||||
@ -4535,9 +4538,9 @@
|
|||||||
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
|
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.1.4",
|
"version": "20.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz",
|
||||||
"integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q=="
|
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/parse-json": {
|
"node_modules/@types/parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
@ -24452,9 +24455,9 @@
|
|||||||
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
|
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "20.1.4",
|
"version": "20.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz",
|
||||||
"integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q=="
|
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg=="
|
||||||
},
|
},
|
||||||
"@types/parse-json": {
|
"@types/parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "HOST=0.0.0.0 PORT=8080 react-scripts start",
|
"start": "HOST=0.0.0.0 PORT=8001 react-scripts start",
|
||||||
"start:dev": "npm run start --watch",
|
"start:dev": "npm run start --watch",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
@ -45,5 +45,8 @@
|
|||||||
"last 1 firefox version",
|
"last 1 firefox version",
|
||||||
"last 1 safari version"
|
"last 1 safari version"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg
Normal file
BIN
containers/react/src/assets/Silver-Medal-PNG-Image-0986sd.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 149 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
@ -2,6 +2,7 @@ import Backdrop from "../Sidebar/Backdrop.tsx"
|
|||||||
import { motion } from 'framer-motion'
|
import { motion } from 'framer-motion'
|
||||||
import { AiOutlineCheckCircle } from "react-icons/ai";
|
import { AiOutlineCheckCircle } from "react-icons/ai";
|
||||||
import '../../styles/Messages.css'
|
import '../../styles/Messages.css'
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
const dropIn = {
|
const dropIn = {
|
||||||
@ -16,14 +17,19 @@ const dropIn = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function GreenAlert ({handleClose, text}){
|
interface AlertProps {
|
||||||
|
handleClose: Function,
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function GreenAlert ({handleClose, text}: AlertProps){
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<Backdrop>
|
<Backdrop onClick={handleClose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
className="greenAlert"
|
className="greenAlert"
|
||||||
variant={dropIn}
|
// variant={dropIn}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit"
|
exit="exit"
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import Backdrop from "../Sidebar/Backdrop.tsx"
|
|||||||
import { motion } from 'framer-motion'
|
import { motion } from 'framer-motion'
|
||||||
import { BiErrorCircle } from "react-icons/bi";
|
import { BiErrorCircle } from "react-icons/bi";
|
||||||
import '../../styles/Messages.css'
|
import '../../styles/Messages.css'
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
const dropIn = {
|
const dropIn = {
|
||||||
@ -16,13 +17,18 @@ const dropIn = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function RedAlert ({handleClose, text}) {
|
interface AlertProps {
|
||||||
|
handleClose: Function,
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function RedAlert ({handleClose, text}: AlertProps) {
|
||||||
return(
|
return(
|
||||||
<Backdrop>
|
<Backdrop onClick={handleClose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
className="redAlert"
|
className="redAlert"
|
||||||
variant={dropIn}
|
// variant={dropIn}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit"
|
exit="exit"
|
||||||
|
|||||||
@ -2,6 +2,9 @@ import Backdrop from "../Sidebar/Backdrop.tsx"
|
|||||||
import { motion } from 'framer-motion'
|
import { motion } from 'framer-motion'
|
||||||
import { GrTrophy } from "react-icons/gr";
|
import { GrTrophy } from "react-icons/gr";
|
||||||
import '../../styles/Messages.css'
|
import '../../styles/Messages.css'
|
||||||
|
import React from "react";
|
||||||
|
import { MdQrCodeScanner } from "react-icons/md";
|
||||||
|
import { GiCrownedSkull, GiWingedSword } from "react-icons/gi";
|
||||||
|
|
||||||
const dropIn = {
|
const dropIn = {
|
||||||
hidden: {
|
hidden: {
|
||||||
@ -15,19 +18,40 @@ const dropIn = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function YellowAlert ({handleClose, text}) {
|
interface AlertProps {
|
||||||
|
handleClose: Function,
|
||||||
|
text: string,
|
||||||
|
icon: number
|
||||||
|
}
|
||||||
|
|
||||||
|
function YellowAlert ({handleClose, text, icon}: AlertProps) {
|
||||||
return(
|
return(
|
||||||
<Backdrop>
|
<Backdrop onClick={handleClose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
className="yellowAlert"
|
className="yellowAlert"
|
||||||
variant={dropIn}
|
// variant={dropIn}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit"
|
exit="exit"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
{icon === 0 ? (
|
||||||
<GrTrophy/>
|
<GrTrophy/>
|
||||||
<p>{text}</p>
|
):("")}
|
||||||
|
{icon === 1 ? (
|
||||||
|
<MdQrCodeScanner/>
|
||||||
|
):("")}
|
||||||
|
|
||||||
|
{icon === 2 ? (
|
||||||
|
<GiCrownedSkull/>
|
||||||
|
):("")}
|
||||||
|
|
||||||
|
{icon === 3 ? (
|
||||||
|
<GiWingedSword/>
|
||||||
|
):("")}
|
||||||
|
|
||||||
|
<h5>{text}</h5>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
{setTimeout(handleClose, 3000)}
|
{setTimeout(handleClose, 3000)}
|
||||||
</Backdrop>
|
</Backdrop>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {Routes, Route} from 'react-router-dom';
|
import {Routes, Route} from 'react-router-dom';
|
||||||
import Home from "../pages/Home.jsx";
|
import Home from "../pages/Home.jsx";
|
||||||
import PlayButton from "../pages/PlayButton.js";
|
import PlayButton from "./Game/PlayButton.tsx";
|
||||||
import Field from "../pages/Field";
|
import Field from "../pages/Field";
|
||||||
import Login42 from "../pages/Login42.js";
|
import Login42 from "../pages/Login42.js";
|
||||||
import Messages from "../pages/Messages.jsx";
|
import Messages from "../pages/Messages.jsx";
|
||||||
@ -13,11 +13,11 @@ function AnimatedRoute () {
|
|||||||
return (
|
return (
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
<Routes location={location} key={location.pathname}>
|
<Routes location={location} key={location.pathname}>
|
||||||
<Route exact path="/" element={<Home/>}/>
|
<Route path="/" element={<Home/>}/>
|
||||||
<Route path="/game" element={<PlayButton />}/>
|
<Route path="/game" element={<PlayButton />}/>
|
||||||
<Route exact path="/pong/play" element={<Field />}/>
|
<Route path="/pong/play" element={<Field />}/>
|
||||||
<Route exact path="/login42" element={<Login42 />}/>
|
<Route path="/login42" element={<Login42 />}/>
|
||||||
<Route exact path="/messages" element={<Messages />}/>
|
<Route path="/messages" element={<Messages />}/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import React from 'react';
|
||||||
import '../../styles/field.css';
|
import '../../styles/field.css';
|
||||||
// import { useHistory } from 'react-router-dom';
|
// import { useHistory } from 'react-router-dom';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@ -13,18 +14,18 @@ function PlayButton() {
|
|||||||
const handleButtonClick = () => {
|
const handleButtonClick = () => {
|
||||||
let path = `play?`;
|
let path = `play?`;
|
||||||
|
|
||||||
const superpowerCheckbox = document.querySelector('input[value="superpower"]');
|
const superpowerCheckbox = document.querySelector<HTMLInputElement>('input[value="superpower"]');
|
||||||
if (superpowerCheckbox.checked) {
|
if (superpowerCheckbox && superpowerCheckbox.checked) {
|
||||||
path += 'superpower=true&';
|
path += 'superpower=true&';
|
||||||
}
|
}
|
||||||
|
|
||||||
const obstacleCheckbox = document.querySelector('input[value="obstacle"]');
|
const obstacleCheckbox = document.querySelector<HTMLInputElement>('input[value="obstacle"]');
|
||||||
if (obstacleCheckbox.checked) {
|
if (obstacleCheckbox && obstacleCheckbox.checked) {
|
||||||
path += 'obstacle=true&';
|
path += 'obstacle=true&';
|
||||||
}
|
}
|
||||||
|
|
||||||
const speedCheckbox = document.querySelector('input[value="speed"]');
|
const speedCheckbox = document.querySelector<HTMLInputElement>('input[value="speed"]');
|
||||||
if (speedCheckbox.checked) {
|
if (speedCheckbox && speedCheckbox.checked) {
|
||||||
path += 'speed=true&';
|
path += 'speed=true&';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* Rank.jsx :+: :+: :+: */
|
/* Rank.tsx :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/09 08:49:24 by apommier #+# #+# */
|
/* Created: 2023/06/09 08:49:24 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/09 08:55:22 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 13:06:35 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -15,8 +15,15 @@ import React, { useState, useEffect, useRef } from "react";
|
|||||||
// import {Rank} from '../../DataBase/DataRank.js'
|
// import {Rank} from '../../DataBase/DataRank.js'
|
||||||
import DefaultPicture from '../../assets/profile.jpg'
|
import DefaultPicture from '../../assets/profile.jpg'
|
||||||
import api from '../../script/axiosApi.tsx';
|
import api from '../../script/axiosApi.tsx';
|
||||||
|
import {Matchlog, User} from "../../../interfaces.tsx"
|
||||||
|
// import { Match } from "@testing-library/react";
|
||||||
|
|
||||||
function Rank({user, index}){
|
interface RankProps {
|
||||||
|
user: User
|
||||||
|
index: number
|
||||||
|
}
|
||||||
|
|
||||||
|
function Rank({user, index}: RankProps){
|
||||||
|
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
|
|
||||||
@ -36,10 +43,12 @@ function Rank({user, index}){
|
|||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// console.log(index);
|
||||||
return (
|
return (
|
||||||
<div className='rank_elements'>
|
<div className='rank_elements'>
|
||||||
<div >
|
<div >
|
||||||
<p>{index + 1}</p>
|
{/* <p>{(index + 1).toString()}</p> */}
|
||||||
|
<p>{(index + 1)}</p>
|
||||||
<h4>{user.rank}: {user.nickname}
|
<h4>{user.rank}: {user.nickname}
|
||||||
{profilePicture ? (
|
{profilePicture ? (
|
||||||
<img className="profilePic" src={`data:image/jpeg;base64,${profilePicture}`} />
|
<img className="profilePic" src={`data:image/jpeg;base64,${profilePicture}`} />
|
||||||
@ -49,7 +58,7 @@ function Rank({user, index}){
|
|||||||
{/* <img className="profilePic" src={defaultpic}/> */}
|
{/* <img className="profilePic" src={defaultpic}/> */}
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<h4 className='content'>{user.opponent}</h4>
|
{/* <h4 className='content'>{user.opponent}</h4> */}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,11 +3,12 @@ import React, { useState, useEffect, useRef } from "react";
|
|||||||
import Rank from './Rank.tsx'
|
import Rank from './Rank.tsx'
|
||||||
import defaultpic from '../../assets/profile.jpg'
|
import defaultpic from '../../assets/profile.jpg'
|
||||||
import api from '../../script/axiosApi.tsx';
|
import api from '../../script/axiosApi.tsx';
|
||||||
|
import {User} from "../../../interfaces.tsx"
|
||||||
|
|
||||||
function Ranking(){
|
function Ranking(){
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [ranking, setRanking] = useState([]);
|
const [ranking, setRanking] = useState<User[]>([]);
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
|
|
||||||
@ -41,16 +42,7 @@ function Ranking(){
|
|||||||
// <h1 className='title'>Ranking</h1>
|
// <h1 className='title'>Ranking</h1>
|
||||||
<div className='scroll'>
|
<div className='scroll'>
|
||||||
{ranking.map((user, index) => (
|
{ranking.map((user, index) => (
|
||||||
<Rank user={user} index={index}/>
|
<Rank user={user} index={index} key={user.username}/>
|
||||||
// return (
|
|
||||||
// <div className='rank_elements'>
|
|
||||||
// <div>
|
|
||||||
// <p>{index + 1}</p>
|
|
||||||
// <h4>{user.rank}: {user.nickname} <img className="profilePic" src={defaultpic}/></h4>
|
|
||||||
// </div>
|
|
||||||
// <h4 className='content'>{user.opponent}</h4>
|
|
||||||
// </div>
|
|
||||||
// )
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -4,10 +4,14 @@ import {Link} from 'react-router-dom';
|
|||||||
import DefaultPicture from '../assets/profile.jpg'
|
import DefaultPicture from '../assets/profile.jpg'
|
||||||
import { motion, AnimatePresence } from 'framer-motion'
|
import { motion, AnimatePresence } from 'framer-motion'
|
||||||
import Modal from './Sidebar/Modal.tsx';
|
import Modal from './Sidebar/Modal.tsx';
|
||||||
|
import YellowAlert from './Alert/YellowAlert.tsx';
|
||||||
import '../styles/Header.css';
|
import '../styles/Header.css';
|
||||||
|
|
||||||
import api from '../script/axiosApi.tsx';
|
import api from '../script/axiosApi.tsx';
|
||||||
|
|
||||||
|
import { MdQrCodeScanner } from 'react-icons/md';
|
||||||
|
import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi';
|
||||||
|
|
||||||
function Header() {
|
function Header() {
|
||||||
// const [sidebar, setSidebar] = useState(false);
|
// const [sidebar, setSidebar] = useState(false);
|
||||||
// const showSidebar = () => setSidebar(!sidebar);
|
// const showSidebar = () => setSidebar(!sidebar);
|
||||||
@ -15,6 +19,8 @@ function Header() {
|
|||||||
const close = () => setModalOpen(false);
|
const close = () => setModalOpen(false);
|
||||||
const open = () => setModalOpen(true);
|
const open = () => setModalOpen(true);
|
||||||
|
|
||||||
|
const [success, setSuccess] = useState([]);
|
||||||
|
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -23,6 +29,8 @@ function Header() {
|
|||||||
const user = await api.get("/profile");
|
const user = await api.get("/profile");
|
||||||
const pic = await api.post("/getPicture", {username: user.data.username})
|
const pic = await api.post("/getPicture", {username: user.data.username})
|
||||||
setProfilePicture(pic.data);
|
setProfilePicture(pic.data);
|
||||||
|
// console.log("test ===", user.data)
|
||||||
|
setSuccess(user.data);
|
||||||
// console.log(`profile pic222= ${pic.data}`)
|
// console.log(`profile pic222= ${pic.data}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching profile picture:', error);
|
console.error('Error fetching profile picture:', error);
|
||||||
@ -32,10 +40,6 @@ function Header() {
|
|||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// console.log(`profile pic= ${profilePicture}`)
|
|
||||||
|
|
||||||
// photo.toString('base64')
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='Header'>
|
<div className='Header'>
|
||||||
<motion.div
|
<motion.div
|
||||||
@ -45,6 +49,7 @@ function Header() {
|
|||||||
</Link>
|
</Link>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<div className='end'>
|
<div className='end'>
|
||||||
|
|
||||||
<Link to="/profile" className='menu-bars'>
|
<Link to="/profile" className='menu-bars'>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
@ -62,7 +67,7 @@ function Header() {
|
|||||||
<AnimatePresence
|
<AnimatePresence
|
||||||
initial={false}
|
initial={false}
|
||||||
onExitComplete={() => null}>
|
onExitComplete={() => null}>
|
||||||
{modalOpen && <Modal modalOpen={modalOpen} handleclose={close}/>}
|
{modalOpen && <Modal handleclose={close}/>}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
import io from 'socket.io-client';
|
import io, { Socket } from 'socket.io-client';
|
||||||
import '../../styles/Messages.css'
|
import '../../styles/Messages.css'
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import DefaultPic from '../../assets/profile.jpg'
|
import DefaultPic from '../../assets/profile.jpg'
|
||||||
import api from '../../script/axiosApi.tsx';
|
import api from '../../script/axiosApi.tsx';
|
||||||
import { motion , AnimatePresence} from "framer-motion";
|
import { motion , AnimatePresence} from "framer-motion";
|
||||||
import Modal from "./Modal.tsx";
|
import Modal from "./Modal.tsx";
|
||||||
|
import GameModal from "./GameModal.tsx";
|
||||||
|
|
||||||
import Message from "./Message.tsx"
|
import Message from "./Message.tsx"
|
||||||
// import Input from "./Input";
|
// import Input from "./Input";
|
||||||
@ -17,12 +18,15 @@ import { MdOutlineGroupAdd } from 'react-icons/md';
|
|||||||
import { GrAdd } from 'react-icons/gr';
|
import { GrAdd } from 'react-icons/gr';
|
||||||
import { RiListSettingsLine } from 'react-icons/ri'
|
import { RiListSettingsLine } from 'react-icons/ri'
|
||||||
|
|
||||||
import { Rank } from "../../DataBase/DataRank";
|
// import { Rank } from "../../DataBase/DataRank";
|
||||||
import GreenAlert from "../Alert/GreenAlert.tsx";
|
import GreenAlert from "../Alert/GreenAlert.tsx";
|
||||||
import RedAlert from "../Alert/RedAlert.tsx";
|
import RedAlert from "../Alert/RedAlert.tsx";
|
||||||
import YellowAlert from "../Alert/YellowAlert";
|
import YellowAlert from "../Alert/YellowAlert";
|
||||||
import ModalSetting from "./ModalSetting.tsx";
|
import ModalSetting from "./ModalSetting.tsx";
|
||||||
|
import PartyInvite from "./PartyInvite.tsx";
|
||||||
|
|
||||||
|
// import {User, Conv, Message} from "../../../interfaces.tsx"
|
||||||
|
import {User, Conv} from "../../../interfaces.tsx"
|
||||||
|
|
||||||
const TouchDiv = styled.div`
|
const TouchDiv = styled.div`
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
@ -70,20 +74,31 @@ const SideP = styled.p`
|
|||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
|
|
||||||
|
interface MessageProps {
|
||||||
|
id: number;
|
||||||
|
convId: number;
|
||||||
|
sender: string;
|
||||||
|
text: string;
|
||||||
|
createdAt?: Date;
|
||||||
|
}
|
||||||
|
|
||||||
function Chats(){
|
function Chats(){
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||||
const [conversations, setConversation] = useState([]);
|
const [conversations, setConversation] = useState([]);
|
||||||
const [user, setUser] = useState(null);
|
const [partyInvite, setPartyInvite] = useState([]);
|
||||||
const [currentChat, setCurrentChat] = useState(false); // false is good?
|
const [user, setUser] = useState<User>();
|
||||||
const [isAdmin, setIsAdmin] = useState(false); // false is good?
|
const [currentChat, setCurrentChat] = useState<Conv>(); // false is good?
|
||||||
|
const [isAdmin, setIsAdmin] = useState<boolean>(false); // false is good?
|
||||||
// const [currentChat, setCurrentChat] = useState(false); // false is good?
|
// const [currentChat, setCurrentChat] = useState(false); // false is good?
|
||||||
const [messages, setMessage] = useState([]);
|
const [messages, setMessage] = useState<MessageProps[]>([]);
|
||||||
const [newMessages, setNewMessage] = useState("");
|
const [newMessages, setNewMessage] = useState("");
|
||||||
const [incomingMessage, setIncomingMessage] = useState("");
|
const [incomingMessage, setIncomingMessage] = useState<MessageProps>();
|
||||||
const socket = useRef();
|
|
||||||
|
|
||||||
|
// let socket: Socket;
|
||||||
|
const socket = useRef<Socket | null>(null);
|
||||||
|
// const socket = Socket<DefaultEventsMap, DefaultEventsMap> | null
|
||||||
|
// socket = useRef( useRef<SocketIOClient.Socket | null>(null));
|
||||||
|
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
@ -91,29 +106,55 @@ function Chats(){
|
|||||||
const getConv = async ()=>{
|
const getConv = async ()=>{
|
||||||
try{
|
try{
|
||||||
const convs = await api.get("/conv")
|
const convs = await api.get("/conv")
|
||||||
|
const tmpInvite = await api.get("/partyInvite")
|
||||||
const tmpUser = await api.get("/profile")
|
const tmpUser = await api.get("/profile")
|
||||||
|
const tmpUsers = await api.get("/users");
|
||||||
|
|
||||||
console.log(convs);
|
console.log(convs);
|
||||||
|
|
||||||
|
// console.log("invite data use effect= ", tmpInvite.data);
|
||||||
|
setPartyInvite(tmpInvite.data);
|
||||||
setUser(tmpUser.data);
|
setUser(tmpUser.data);
|
||||||
setConversation(convs.data);
|
setConversation(convs.data);
|
||||||
socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001');
|
setUsers(tmpUsers.data);
|
||||||
console.log(`connection....`);
|
|
||||||
|
// console.log(`connection....`);
|
||||||
|
socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] });
|
||||||
|
// console.log(`connection done`);
|
||||||
socket.current.emit('connection', {username: tmpUser.data.username})
|
socket.current.emit('connection', {username: tmpUser.data.username})
|
||||||
socket.current.on('message', (data) => { //data should be a message ?
|
socket.current.on('message', (data) => { //data should be a message ?)
|
||||||
console.log(`message received data= ${data.sender}`)
|
|
||||||
console.log(`message received data= ${data.convId}`)
|
|
||||||
console.log(`message received data= ${data.sender}`)
|
|
||||||
console.log(`current chat = ${currentChat}`)
|
|
||||||
setIncomingMessage(data);
|
setIncomingMessage(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.current.on('ban', (data) => {
|
||||||
|
// setIncomingMessage(data);
|
||||||
|
console.log("banned hehe");
|
||||||
|
window.location.reload()
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.current.on('mute', (data) => {
|
||||||
|
console.log("muted hehe");
|
||||||
|
//set mute var to true and do nothing
|
||||||
|
});
|
||||||
|
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(err){
|
catch(err){
|
||||||
|
console.log("ERRORRRRR")
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getConv();
|
getConv();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
console.log("Cleanup");
|
||||||
|
if (socket.current)
|
||||||
|
socket.current.disconnect();
|
||||||
|
// cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
|
||||||
|
// cleanup();
|
||||||
|
};
|
||||||
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
@ -133,9 +174,12 @@ function Chats(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
|
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
|
||||||
if (currentChat !== null && currentChat.id === incomingMessage.convId)
|
if (currentChat && incomingMessage && currentChat.id === incomingMessage.convId)
|
||||||
{
|
{
|
||||||
|
console.log("incoming meaasge=",incomingMessage)
|
||||||
|
// if (user && !user.blocked.find(incomingMessage.sender))
|
||||||
|
// setMessage((prev) => [...prev, incomingMessage, key: incomingMessage.id]);
|
||||||
|
// setMessage((prev) => [...prev, { ...incomingMessage, key: incomingMessage.id }]);
|
||||||
setMessage((prev) => [...prev, incomingMessage]);
|
setMessage((prev) => [...prev, incomingMessage]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,10 +190,13 @@ function Chats(){
|
|||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
const getMessage = async ()=>
|
const getMessage = async ()=>
|
||||||
{
|
{
|
||||||
|
if (!currentChat)
|
||||||
|
return ;
|
||||||
const data = {convId: currentChat.id};
|
const data = {convId: currentChat.id};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await api.post('/getMessage', data);
|
const res = await api.post('/getMessage', data);
|
||||||
|
console.log("message of conv=", res.data)
|
||||||
setMessage(res.data);
|
setMessage(res.data);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
|
||||||
@ -158,30 +205,36 @@ function Chats(){
|
|||||||
getMessage();
|
getMessage();
|
||||||
}, [currentChat]);
|
}, [currentChat]);
|
||||||
|
|
||||||
const handleSubmit = async (e)=>{
|
const handleSubmit = async (e: { preventDefault: () => void; })=>{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// console.log(`e= ${e.key}`)
|
// console.log(`e= ${e.key}`)
|
||||||
// console.log(`name= ${user.username}`)
|
// console.log(`name= ${user.username}`)
|
||||||
|
// let message;
|
||||||
|
if (!user || !currentChat)
|
||||||
|
return ;
|
||||||
const message = {
|
const message = {
|
||||||
sender: user.username,
|
sender: user.username,
|
||||||
text: newMessages,
|
text: newMessages,
|
||||||
convId: currentChat.id,
|
convId: currentChat.id,
|
||||||
members: null
|
members: null,
|
||||||
|
id: null,
|
||||||
};
|
};
|
||||||
try{
|
try{
|
||||||
console.log(`id= ${currentChat.id}`)
|
const allowed = await api.post('/allowed', {convId: currentChat.id});
|
||||||
const allowed = await api.post('/allowed', {convId: message.convId, username: user.username});
|
console.log("convid:", currentChat.id);
|
||||||
console.log("allowed= ", allowed.data)
|
|
||||||
if (!allowed.data)
|
if (!allowed.data)
|
||||||
|
{
|
||||||
|
console.log("muted or banned");
|
||||||
return ;
|
return ;
|
||||||
|
}
|
||||||
|
console.log("not muted or banned");
|
||||||
const res = await api.post('/message', message);
|
const res = await api.post('/message', message);
|
||||||
const convMember = await api.post('/member', message);
|
const convMember = await api.post('/member', message);
|
||||||
message.members = convMember.data.members;
|
message.members = convMember.data.members;
|
||||||
console.log(convMember);
|
message.id = res.data.id
|
||||||
// console.log(`currentChat= ${currentChat.id}`)
|
|
||||||
|
|
||||||
setMessage([...messages, res.data]);
|
setMessage([...messages, res.data]);
|
||||||
setNewMessage("");
|
setNewMessage("");
|
||||||
|
if (socket.current)
|
||||||
socket.current.emit('sendMessage', message);
|
socket.current.emit('sendMessage', message);
|
||||||
}
|
}
|
||||||
catch(err){
|
catch(err){
|
||||||
@ -189,27 +242,28 @@ function Chats(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleKeyPress = async (e)=>{
|
const handleKeyPress = async (e: { key: string; })=> {
|
||||||
// console.log(`e in press= ${e.key}`)
|
// console.log(`e in press= ${e.key}`)
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
return ;
|
return ;
|
||||||
// console.log(`name= ${user.username}`)
|
// console.log(`name= ${user.username}`)
|
||||||
|
if (!user || !currentChat)
|
||||||
|
return ;
|
||||||
const message = {
|
const message = {
|
||||||
sender: user.username,
|
sender: user.username,
|
||||||
text: newMessages,
|
text: newMessages,
|
||||||
convId: currentChat.id,
|
convId: currentChat.id,
|
||||||
members: null
|
members: null,
|
||||||
|
id: null,
|
||||||
};
|
};
|
||||||
try{
|
try{
|
||||||
console.log(`id= ${currentChat.id}`)
|
|
||||||
const res = await api.post('/message', message);
|
const res = await api.post('/message', message);
|
||||||
const convMember = await api.post('/member', message);
|
const convMember = await api.post('/member', message);
|
||||||
message.members = convMember.data.members;
|
message.members = convMember.data.members;
|
||||||
console.log(convMember);
|
message.id = res.data.id
|
||||||
// console.log(`currentChat= ${currentChat.id}`)
|
|
||||||
|
|
||||||
setMessage([...messages, res.data]);
|
setMessage([...messages, res.data]);
|
||||||
setNewMessage("");
|
setNewMessage("");
|
||||||
|
if (socket.current)
|
||||||
socket.current.emit('sendMessage', message);
|
socket.current.emit('sendMessage', message);
|
||||||
}
|
}
|
||||||
catch(err){
|
catch(err){
|
||||||
@ -220,7 +274,7 @@ function Chats(){
|
|||||||
|
|
||||||
|
|
||||||
const [friend, setFriend] = useState("");
|
const [friend, setFriend] = useState("");
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
// const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [addFriend, setAddFriend] = useState(false);
|
const [addFriend, setAddFriend] = useState(false);
|
||||||
const [block, setBlock] = useState(false);
|
const [block, setBlock] = useState(false);
|
||||||
|
|
||||||
@ -228,8 +282,32 @@ function Chats(){
|
|||||||
const [showBlockAlert, setShowBlockAlert] = useState(false);
|
const [showBlockAlert, setShowBlockAlert] = useState(false);
|
||||||
|
|
||||||
const [setting, setSetting] = useState(false);
|
const [setting, setSetting] = useState(false);
|
||||||
const close = () => setModalOpen(false);
|
|
||||||
const open = () => setModalOpen(true);
|
const [newGameModalOpen, setNewGameModalOpen] = useState(false);
|
||||||
|
const [newConversationModalOpen, setNewConversationModalOpen] = useState(false);
|
||||||
|
|
||||||
|
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
||||||
|
const [users, setUsers] = useState<User[]>([]);
|
||||||
|
|
||||||
|
|
||||||
|
const openNewGameModal = () => {
|
||||||
|
setNewGameModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeNewGameModal = () => {
|
||||||
|
setNewGameModalOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openNewConversationModal = () => {
|
||||||
|
setNewConversationModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeNewConversationModal = () => {
|
||||||
|
setNewConversationModalOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// const close = () => setModalOpen(false);
|
||||||
|
// const open = () => setModalOpen(true);
|
||||||
// const closeAddFriend = () => setAddFriend(false);
|
// const closeAddFriend = () => setAddFriend(false);
|
||||||
// const closeBlock = () => setBlock(false);
|
// const closeBlock = () => setBlock(false);
|
||||||
const closeSetting = () => setSetting(false);
|
const closeSetting = () => setSetting(false);
|
||||||
@ -239,7 +317,7 @@ function Chats(){
|
|||||||
// const closeBlock = () => setBlock(false);
|
// const closeBlock = () => setBlock(false);
|
||||||
|
|
||||||
|
|
||||||
const handleFriend = (event) => {
|
const handleFriend = (event: { target: { value: React.SetStateAction<string>; }; }) => {
|
||||||
setFriend(event.target.value);
|
setFriend(event.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,6 +369,15 @@ function Chats(){
|
|||||||
setShowBlockAlert(false);
|
setShowBlockAlert(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOptionChange = (selectId: number, selectedOption: string) => {
|
||||||
|
console.log("selected Option=", selectedOption)
|
||||||
|
setSelectTag((prevTags) =>
|
||||||
|
prevTags.map((tag) =>
|
||||||
|
tag.id === selectId ? { ...tag, selectedOption } : tag
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
// HTML
|
// HTML
|
||||||
@ -304,7 +391,7 @@ function Chats(){
|
|||||||
<div className='navbar'>
|
<div className='navbar'>
|
||||||
<img src={DefaultPic} alt="profile" className="pic"/>
|
<img src={DefaultPic} alt="profile" className="pic"/>
|
||||||
<span>
|
<span>
|
||||||
{isLoading ? (
|
{isLoading || !user ? (
|
||||||
<h4>Loading...</h4>
|
<h4>Loading...</h4>
|
||||||
) : (
|
) : (
|
||||||
<h4>{user.nickname}</h4>
|
<h4>{user.nickname}</h4>
|
||||||
@ -356,7 +443,24 @@ function Chats(){
|
|||||||
</div> */}
|
</div> */}
|
||||||
|
|
||||||
<div className="end">
|
<div className="end">
|
||||||
<input className="lookForFriends" type="text" value={friend} onChange={handleFriend} />
|
{selectTags.map((selectTag) => (
|
||||||
|
<div key={selectTag.id}>
|
||||||
|
<select
|
||||||
|
value={selectTag.selectedOption}
|
||||||
|
className="lookForFriends"
|
||||||
|
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
|
||||||
|
>
|
||||||
|
<option value="">{
|
||||||
|
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
|
||||||
|
}</option>
|
||||||
|
{users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.username)).map((item, index) => (
|
||||||
|
<option key={index} value={item.username}>
|
||||||
|
{item.username}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
<TouchDiv>
|
<TouchDiv>
|
||||||
<motion.div onClick={handleAddFriend}>
|
<motion.div onClick={handleAddFriend}>
|
||||||
<MdOutlineGroupAdd />
|
<MdOutlineGroupAdd />
|
||||||
@ -393,7 +497,7 @@ function Chats(){
|
|||||||
initial={false}
|
initial={false}
|
||||||
onExitComplete={() => null}
|
onExitComplete={() => null}
|
||||||
>
|
>
|
||||||
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
|
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id.toString()} socket={socket.current}/>}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</TouchDiv>
|
</TouchDiv>
|
||||||
@ -404,18 +508,37 @@ function Chats(){
|
|||||||
</div>
|
</div>
|
||||||
<div className="messages_box">
|
<div className="messages_box">
|
||||||
<div className="contact">
|
<div className="contact">
|
||||||
<UserChat>
|
|
||||||
|
|
||||||
<motion.div className="newMessage"
|
<UserChat>
|
||||||
onClick={() => (modalOpen ? close() : open())}
|
<motion.div className="newMessage" onClick={openNewGameModal}>
|
||||||
>
|
<GrAdd />
|
||||||
|
<span>New Game</span>
|
||||||
|
</motion.div>
|
||||||
|
{newGameModalOpen && <GameModal handleClose={closeNewGameModal} />}
|
||||||
|
</UserChat>
|
||||||
|
|
||||||
|
<UserChat>
|
||||||
|
<motion.div className="newMessage" onClick={openNewConversationModal}>
|
||||||
<GrAdd />
|
<GrAdd />
|
||||||
<span>New Conversation</span>
|
<span>New Conversation</span>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
{modalOpen && <Modal modalOpen={modalOpen} handleClose={close}/>}
|
{newConversationModalOpen && (
|
||||||
|
<Modal handleClose={closeNewConversationModal} />
|
||||||
|
)}
|
||||||
</UserChat>
|
</UserChat>
|
||||||
{conversations.map((c, index ) => {
|
|
||||||
|
|
||||||
|
{/* {partyInvite.map((c) => {
|
||||||
|
return (
|
||||||
|
|
||||||
|
)})
|
||||||
|
} */}
|
||||||
|
|
||||||
|
{partyInvite.map( i =>(
|
||||||
|
<PartyInvite currentInvite={i}/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{conversations.map((c: Conv, index ) => {
|
||||||
return (
|
return (
|
||||||
<div key={index}
|
<div key={index}
|
||||||
onClick={() => setCurrentChat(c)}>
|
onClick={() => setCurrentChat(c)}>
|
||||||
@ -423,7 +546,7 @@ function Chats(){
|
|||||||
<img className="pic-user" src={DefaultPic} alt="User" />
|
<img className="pic-user" src={DefaultPic} alt="User" />
|
||||||
<div className="infoSideBar">
|
<div className="infoSideBar">
|
||||||
<span>{c.name}</span>
|
<span>{c.name}</span>
|
||||||
<SideP>Desc?</SideP>
|
{/* <SideP>Desc?</SideP> */}
|
||||||
</div>
|
</div>
|
||||||
</UserChat>
|
</UserChat>
|
||||||
</div>
|
</div>
|
||||||
@ -432,12 +555,12 @@ function Chats(){
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
currentChat ? (
|
currentChat && user ? (
|
||||||
<>
|
<>
|
||||||
<div className="messages">
|
<div className="messages">
|
||||||
<div className="scroll">
|
<div className="scroll">
|
||||||
{messages.map(m=>(
|
{messages.map(m=>(
|
||||||
<Message message = {m} own={m.sender === user.username} user={m}/>
|
<Message key={m.id} message= {m} own={m.sender === user.username}/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
{/* <Input/> */}
|
{/* <Input/> */}
|
||||||
|
|||||||
152
containers/react/src/components/Messages/GameModal.tsx
Normal file
152
containers/react/src/components/Messages/GameModal.tsx
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import { motion } from "framer-motion";
|
||||||
|
import Backdrop from "../Sidebar/Backdrop.tsx";
|
||||||
|
import '../../styles/Messages.css';
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import api from "../../script/axiosApi.tsx";
|
||||||
|
import React from "react";
|
||||||
|
import {User} from "../../../interfaces.tsx"
|
||||||
|
// import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
const dropIn = {
|
||||||
|
hidden: { y: "-100vh", opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
y: "0",
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
duration: 0.3,
|
||||||
|
type: "spring",
|
||||||
|
damping: 100,
|
||||||
|
stiffness: 500,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
exit: { y: "100vh", opacity: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
interface ModalGame {
|
||||||
|
handleClose: Function,
|
||||||
|
// convId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const GameModal = ({ handleClose }: ModalGame) => {
|
||||||
|
const [users, setUsers] = useState([]);
|
||||||
|
// const [user, setUser] = useState();
|
||||||
|
const [selectedUser, setSelectedUser] = useState('');
|
||||||
|
// const [convs, setConvs] = useState([]);
|
||||||
|
const [channel, setChannel] = useState('');
|
||||||
|
|
||||||
|
// const history = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchData = async () => {
|
||||||
|
try {
|
||||||
|
const tmpUsers = await api.get("/users");
|
||||||
|
// const tmpUser = await api.get("/profile");
|
||||||
|
// const tmpConvs = await api.get("/convs");
|
||||||
|
setUsers(tmpUsers.data);
|
||||||
|
// setUser(tmpUser.data);
|
||||||
|
// setConvs(tmpConvs.data);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleUserChange = (event: { target: { value: React.SetStateAction<string>; }; }) => {
|
||||||
|
setSelectedUser(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// const joinChannel = async () => {
|
||||||
|
// try {
|
||||||
|
// await api.post("/join", { convId: channel });
|
||||||
|
// } catch (err) {
|
||||||
|
// console.log(err);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleCheckButtonClick = () => {
|
||||||
|
// // Perform your check action here
|
||||||
|
// console.log("Checking user:", selectedUser);
|
||||||
|
// };
|
||||||
|
|
||||||
|
const handleButtonClick = async () => {
|
||||||
|
// let path = `play?`;
|
||||||
|
let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?`;
|
||||||
|
|
||||||
|
|
||||||
|
const superpowerCheckbox = document.querySelector<HTMLInputElement>('input[value="superpower"]');
|
||||||
|
if (superpowerCheckbox && superpowerCheckbox.checked) {
|
||||||
|
path += 'superpower=true&';
|
||||||
|
}
|
||||||
|
|
||||||
|
const obstacleCheckbox = document.querySelector<HTMLInputElement>('input[value="obstacle"]');
|
||||||
|
if (obstacleCheckbox && obstacleCheckbox.checked) {
|
||||||
|
path += 'obstacle=true&';
|
||||||
|
}
|
||||||
|
|
||||||
|
const speedCheckbox = document.querySelector<HTMLInputElement>('input[value="speed"]');
|
||||||
|
if (speedCheckbox && speedCheckbox.checked) {
|
||||||
|
path += 'speed=true&';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedUser.length > 0)
|
||||||
|
path += 'username=' + selectedUser;//important here
|
||||||
|
|
||||||
|
// Remove the trailing '&' character
|
||||||
|
// path = path.slice(0, -1);
|
||||||
|
// console.log(path)
|
||||||
|
|
||||||
|
// await api.post("/partyInvite", {username: selectedUser, gameId})
|
||||||
|
|
||||||
|
// console.log("path= ", path)
|
||||||
|
// history(path, { replace: true });
|
||||||
|
// window.location.replace(path);
|
||||||
|
window.history.pushState({}, '', path);
|
||||||
|
window.location.reload();
|
||||||
|
|
||||||
|
// history(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Backdrop onClick={handleClose}>
|
||||||
|
<motion.div
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
className="modal"
|
||||||
|
// variant={dropIn}
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
exit="exit"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<select value={selectedUser} onChange={handleUserChange}>
|
||||||
|
<option value="">Select a user</option>
|
||||||
|
{users.map((user: User) => (
|
||||||
|
<option key={user.id} value={user.username}>
|
||||||
|
{user.username}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="notClicked" id="canvas_container">
|
||||||
|
{/* <button onClick={handleButtonClick}>Draw on Canvas</button> */}
|
||||||
|
<div className='checkbox'>
|
||||||
|
<p><input type="checkbox" value="superpower"/> Super Power </p>
|
||||||
|
<p><input type="checkbox" value="obstacle"/> Obstacle </p>
|
||||||
|
<p><input type="checkbox" value="speed"/> Faster and Faster </p>
|
||||||
|
</div>
|
||||||
|
<button className="submit" onClick={handleButtonClick} >Play</button>
|
||||||
|
{/* <button className="submit" onClick={handleClose}>Cancel</button> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className="div_submit">
|
||||||
|
<button className="submit" onClick={handleCheckButtonClick}>
|
||||||
|
Invite to play
|
||||||
|
</button>
|
||||||
|
</div> */}
|
||||||
|
</motion.div>
|
||||||
|
</Backdrop>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GameModal;
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import React from 'react';
|
||||||
import { TbSend } from 'react-icons/tb';
|
import { TbSend } from 'react-icons/tb';
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* Message.jsx :+: :+: :+: */
|
/* Message.tsx :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
|
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/12 17:05:08 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 19:05:10 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -17,6 +17,8 @@ import DefaultPicture from '../../assets/profile.jpg'
|
|||||||
// import { useRef } from "react";
|
// import { useRef } from "react";
|
||||||
// import { useEffect } from "react";
|
// import { useEffect } from "react";
|
||||||
import '../../styles/Messages.css'
|
import '../../styles/Messages.css'
|
||||||
|
import {User, Conv, Message} from "../../../interfaces.tsx"
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
const MeStyleP = styled.p`
|
const MeStyleP = styled.p`
|
||||||
background-color: #5843e4;
|
background-color: #5843e4;
|
||||||
@ -26,10 +28,21 @@ const MeStyleP = styled.p`
|
|||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
`
|
`
|
||||||
|
|
||||||
function MessageMe({message, own}){
|
interface MessageMeProps {
|
||||||
|
message: Message;
|
||||||
|
own: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function MessageMe({message, own}: MessageMeProps){
|
||||||
|
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
const scrollRef = useRef();
|
const [sender, setSender] = useState<User>();
|
||||||
|
const [conv, setConv] = useState<Conv>();
|
||||||
|
|
||||||
|
const [user, setUser] = useState<User>();
|
||||||
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
// console.log("Message eher")
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (scrollRef.current)
|
if (scrollRef.current)
|
||||||
@ -39,9 +52,16 @@ function MessageMe({message, own}){
|
|||||||
const fetchProfilePicture = async () => {
|
const fetchProfilePicture = async () => {
|
||||||
try {
|
try {
|
||||||
// const user = await api.get("/profile");
|
// const user = await api.get("/profile");
|
||||||
|
const tmpSender = await api.post("/user", {username: message.sender})
|
||||||
|
const tmpConv = await api.post("/convId", {convId: message.convId})
|
||||||
|
// const tmpSender = await api.post("/user", {username: message.sender})
|
||||||
|
const tmpUser = await api.get("/profile")
|
||||||
const pic = await api.post("/getPicture", {username: message.sender})
|
const pic = await api.post("/getPicture", {username: message.sender})
|
||||||
// console.log(`user naem profile pic222= ${currentUser.username}`)
|
// console.log(`user naem profile pic222= ${currentUser.username}`)
|
||||||
// console.log(` profile pic222= ${pic.data}`)
|
// console.log(` profile pic222= ${pic.data}`)
|
||||||
|
setConv(tmpConv.data);
|
||||||
|
setUser(tmpUser.data);
|
||||||
|
setSender(tmpSender.data);
|
||||||
setProfilePicture(pic.data);
|
setProfilePicture(pic.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching profile picture:', error);
|
console.error('Error fetching profile picture:', error);
|
||||||
@ -50,23 +70,52 @@ function MessageMe({message, own}){
|
|||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const handleButtonClick = () => {
|
||||||
|
if (!sender)
|
||||||
|
return ;
|
||||||
|
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${sender.username}`;
|
||||||
|
// console.log("path= ", path)
|
||||||
|
// history(path, { replace: true });
|
||||||
|
// window.location.replace(path);
|
||||||
|
window.history.pushState({}, '', path);
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!user || !sender || !conv)
|
||||||
|
{
|
||||||
|
// console.log("return")
|
||||||
|
return (<></>);
|
||||||
|
}
|
||||||
|
// console.log("result includes=", conv.banned.includes(user.username))
|
||||||
|
// console.log("result includes=", conv.blocked.includes(user.username))
|
||||||
|
if (user.blocked && user.blocked.includes(message.sender))
|
||||||
|
return (<></>);
|
||||||
|
// else if (conv.banned && conv.banned.includes(user.username))
|
||||||
|
// {
|
||||||
|
// console.log("return2")
|
||||||
|
// return (<></>);
|
||||||
|
// }
|
||||||
|
// console.log("noy return")
|
||||||
|
// if (user.blocked.includes(message.sender))/
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
|
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
|
||||||
<div>
|
<div>
|
||||||
{/* <img className="messageInfo" src={DefaultPic} alt="profile" />
|
|
||||||
*/}
|
|
||||||
{profilePicture ? (
|
{profilePicture ? (
|
||||||
<img className="messageInfo" src={`data:image/jpeg;base64,${profilePicture}`} />
|
<img className="messageInfo" onClick={() => handleButtonClick()} src={`data:image/jpeg;base64,${profilePicture}`} />
|
||||||
) : (
|
) : (
|
||||||
<img className="messageInfo" src={DefaultPicture} alt="Default Profile Picture" />
|
<img className="messageInfo" onClick={() => handleButtonClick()} src={DefaultPicture} alt="Default Profile Picture" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="usernameMesage">{message.senderNickname}</div> */}
|
{/* <div className="usernameMesage">{message.senderNickname}</div> */}
|
||||||
<div className="usernameMesage">{message.sender}</div>
|
{sender ? (
|
||||||
|
<div className="usernameMesage">{sender.nickname}</div>
|
||||||
|
): ""}
|
||||||
<div className="messageContent">
|
<div className="messageContent">
|
||||||
<MeStyleP>{message.text}</MeStyleP>
|
<MeStyleP>{message.text}</MeStyleP>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,8 @@ const MeStyleP = styled.p`
|
|||||||
`
|
`
|
||||||
|
|
||||||
function MessageMe(){
|
function MessageMe(){
|
||||||
const scrollRef = useRef();
|
// const scrollRef = useRef();
|
||||||
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
scrollRef.current?.scrollIntoView({ behavior: "smooth"})
|
scrollRef.current?.scrollIntoView({ behavior: "smooth"})
|
||||||
|
|||||||
@ -14,7 +14,7 @@ const StyleP = styled.p`
|
|||||||
`
|
`
|
||||||
|
|
||||||
function MessageYou(){
|
function MessageYou(){
|
||||||
const scrollRef = useRef();
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
scrollRef.current?.scrollIntoView({ behavior: "smooth"})
|
scrollRef.current?.scrollIntoView({ behavior: "smooth"})
|
||||||
|
|||||||
@ -90,7 +90,7 @@ const Modal = ({handleClose}) => {
|
|||||||
// test
|
// test
|
||||||
await api.post("/conv", data);
|
await api.post("/conv", data);
|
||||||
handleClose();
|
handleClose();
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
@ -100,17 +100,15 @@ const Modal = ({handleClose}) => {
|
|||||||
// let new_name;
|
// let new_name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Backdrop>
|
<Backdrop onClick={handleClose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
className="modal"
|
className="modal"
|
||||||
variant={dropIn}
|
// variant={dropIn}
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit"
|
exit="exit"
|
||||||
>
|
>
|
||||||
{/* <p>New Conversation</p> */}
|
|
||||||
|
|
||||||
{selectTags.map((selectTag) => (
|
{selectTags.map((selectTag) => (
|
||||||
<div key={selectTag.id}>
|
<div key={selectTag.id}>
|
||||||
<select
|
<select
|
||||||
@ -147,7 +145,7 @@ const Modal = ({handleClose}) => {
|
|||||||
>
|
>
|
||||||
<option value="">Select an option</option>
|
<option value="">Select an option</option>
|
||||||
{convs.map((conv) => (
|
{convs.map((conv) => (
|
||||||
!(!conv.group || conv.private || (conv.banned && conv.banned.includes(channel)) || (conv.members && conv.members.includes(user.username))) && (
|
!(!conv.group || conv.private || (conv.banned && conv.banned.includes(user.username)) || (conv.members && conv.members.includes(user.username))) && (
|
||||||
<option key={conv.id} value={conv.id}>
|
<option key={conv.id} value={conv.id}>
|
||||||
{conv.name}
|
{conv.name}
|
||||||
</option>
|
</option>
|
||||||
@ -155,36 +153,16 @@ const Modal = ({handleClose}) => {
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
)}
|
)}
|
||||||
|
{channel.private ? (
|
||||||
|
<input className="mdp" placeholder="password" type="text" />
|
||||||
|
):("")}
|
||||||
|
|
||||||
|
|
||||||
<div className="div_submit">
|
<div className="div_submit">
|
||||||
<Link to='#' className="submit" onClick={ joinChannel }>Join</Link>
|
<Link to='#' className="submit" onClick={ joinChannel }>Join</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* {selectTags.map((selectTag) => (
|
|
||||||
<div key={selectTag.id}>
|
|
||||||
<select
|
|
||||||
value={selectTag.selectedOption}
|
|
||||||
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
|
|
||||||
>
|
|
||||||
<option value="">{
|
|
||||||
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
|
|
||||||
}</option>
|
|
||||||
{convs.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.name)).map((item, index) => (
|
|
||||||
<option key={index} value={item.name}>
|
|
||||||
{item.name}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
))} */}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* <div>
|
|
||||||
<GrAdd onClick={addNewSelectedTag}/>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</Backdrop>
|
</Backdrop>
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import Backdrop from "../Sidebar/Backdrop.tsx";
|
import Backdrop from "../Sidebar/Backdrop.tsx";
|
||||||
import { Rank } from "../../DataBase/DataRank"
|
// import { Rank } from "../../DataBase/DataRank"
|
||||||
import '../../styles/Messages.css'
|
import '../../styles/Messages.css'
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { GrAdd } from "react-icons/gr";
|
import { GrAdd } from "react-icons/gr";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import api from "../../script/axiosApi.tsx";
|
import api from "../../script/axiosApi.tsx";
|
||||||
|
import React from "react";
|
||||||
|
import {User} from "../../../interfaces.tsx"
|
||||||
|
import { Socket } from "socket.io-client";
|
||||||
|
|
||||||
|
|
||||||
const dropIn = {
|
const dropIn = {
|
||||||
@ -24,13 +27,26 @@ const dropIn = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const ModalSetting = ({handleClose, convId}) => {
|
interface ModalSettingProps {
|
||||||
|
handleClose: Function,
|
||||||
|
convId: string,
|
||||||
|
socket: Socket | null,
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
|
||||||
const [password, setPassword] = useState(false);
|
const [password, setPassword] = useState(false);
|
||||||
const [users, setUsers] = useState([]);
|
const [users, setUsers] = useState<User[]>([]);
|
||||||
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
|
||||||
const [selectedUser, setSelectedUser] = useState([]);
|
const [selectedUser, setSelectedUser] = useState("");
|
||||||
const [newName, setNewName] = useState("");
|
const [newName, setNewName] = useState("");
|
||||||
const [newPassword, setNewPassword] = useState("");
|
const [newPassword, setNewPassword] = useState("");
|
||||||
|
const [privateConv, setPrivateConv] = useState(false);
|
||||||
|
const dark = () => setPrivateConv(true);
|
||||||
|
const light = () => setPrivateConv(false);
|
||||||
|
const [mute, setMute] = useState(false);
|
||||||
|
const darkMute = () => setMute(false);
|
||||||
|
const lightMute = () => setMute(true);
|
||||||
|
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
|
|
||||||
@ -51,7 +67,7 @@ const ModalSetting = ({handleClose, convId}) => {
|
|||||||
// const [selectedOptionArray, setSelectedOptionArray] = useState([]);
|
// const [selectedOptionArray, setSelectedOptionArray] = useState([]);
|
||||||
|
|
||||||
|
|
||||||
const handleOptionChange = (selectId, selectedOption) => {
|
const handleOptionChange = (selectId: number, selectedOption: string) => {
|
||||||
console.log("tag= ", selectTags)
|
console.log("tag= ", selectTags)
|
||||||
console.log("option= ", selectedOption)
|
console.log("option= ", selectedOption)
|
||||||
setSelectTag((prevTags) =>
|
setSelectTag((prevTags) =>
|
||||||
@ -62,12 +78,12 @@ const ModalSetting = ({handleClose, convId}) => {
|
|||||||
setSelectedUser(selectedOption)
|
setSelectedUser(selectedOption)
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCheckPass = (e) => {
|
const handleCheckPass = (e: { target: { checked: boolean | ((prevState: boolean) => boolean); }; }) => {
|
||||||
setPassword(e.target.checked);
|
setPassword(e.target.checked);
|
||||||
console.log("password??", e.target.checked)
|
console.log("password??", e.target.checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCheckPriv = (e) => {
|
const handleCheckPriv = (e: { target: { checked: any; }; }) => {
|
||||||
// setPassword(e.target.checked);
|
// setPassword(e.target.checked);
|
||||||
if (e.target.checked)
|
if (e.target.checked)
|
||||||
{
|
{
|
||||||
@ -89,59 +105,72 @@ const ModalSetting = ({handleClose, convId}) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleName = async (e)=>{
|
const handleName = async (e: { key: string; })=>{
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
return ;
|
return ;
|
||||||
try{
|
try{
|
||||||
api.post("/name", {convId: convId, name: newName})
|
api.post("/name", {convId: convId, name: newName})
|
||||||
|
window.location.reload()
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
handleClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePassword = async (e)=>{
|
const handlePassword = async (e: { key: string; })=>{
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
return ;
|
return ;
|
||||||
try{
|
try{
|
||||||
api.post("/password", {convId: convId, password: newPassword})
|
await api.post("/password", {convId: convId, password: newPassword})
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
handleClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBan = () => {
|
const handleBan = async () => {
|
||||||
// console.log("ban option= ", selectedUser)
|
// console.log("ban option= ", selectedUser)
|
||||||
try{
|
try{
|
||||||
api.post("/ban", {convId: convId, username: selectedUser})
|
// console.log("user select=", selectedUser.length)
|
||||||
|
if (!selectedUser.length)
|
||||||
|
return ;
|
||||||
|
await api.post("/ban", {convId: convId, username: selectedUser})
|
||||||
|
if (socket)
|
||||||
|
{
|
||||||
|
console.log("emit to ban server")
|
||||||
|
socket.emit("ban", {username: selectedUser})
|
||||||
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAdmin = () => {
|
const handleAdmin = async () => {
|
||||||
|
if (!selectedUser.length)
|
||||||
|
return ;
|
||||||
try{
|
try{
|
||||||
api.post("/admin", {convId: convId, username: selectedUser})
|
await api.post("/admin", {convId: convId, username: selectedUser})
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMute = () => {
|
const handleMute = async () => {
|
||||||
|
if (!selectedUser.length)
|
||||||
|
return ;
|
||||||
try{
|
try{
|
||||||
api.post("/mute", {convId: convId, username: selectedUser})
|
await api.post("/mute", {convId: convId, username: selectedUser})
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleInvite = () => {
|
const handleInvite = async () => {
|
||||||
try{
|
try{
|
||||||
api.post("/invite", {convId: convId, username: selectedUser})
|
await api.post("/invite", {convId: convId, username: selectedUser})
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
@ -149,11 +178,10 @@ const ModalSetting = ({handleClose, convId}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Backdrop>
|
<Backdrop onClick={handleClose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
className="modalSetting"
|
className="modalSetting"
|
||||||
variant={dropIn}
|
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit"
|
exit="exit"
|
||||||
@ -162,15 +190,19 @@ const ModalSetting = ({handleClose, convId}) => {
|
|||||||
{/* First selection */}
|
{/* First selection */}
|
||||||
<div className="settingFirstPart">
|
<div className="settingFirstPart">
|
||||||
<div>
|
<div>
|
||||||
<p className="checkbox">Private<input class="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p>
|
<div>
|
||||||
|
<Link to="#" onClick={light} className={ privateConv ? "submit" : "darkSubmit"}>Public</Link>
|
||||||
|
<Link to="#" onClick={dark} className={ privateConv ? "darkSubmit" : "submit"}>Private</Link>
|
||||||
|
</div>
|
||||||
|
{/* <p className="checkbox">Private<input className="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p> */}
|
||||||
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p>
|
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p>
|
||||||
|
|
||||||
|
|
||||||
{password ? (
|
{password || privateConv ? (
|
||||||
<input
|
<input
|
||||||
onChange={(e) => setNewPassword(e.target.value)}
|
onChange={(e) => setNewPassword(e.target.value)}
|
||||||
onKeyDown={handlePassword}
|
onKeyDown={handlePassword}
|
||||||
type="text"
|
type="password"
|
||||||
className="in"
|
className="in"
|
||||||
placeholder="Password"/>
|
placeholder="Password"/>
|
||||||
):
|
):
|
||||||
@ -216,11 +248,14 @@ const ModalSetting = ({handleClose, convId}) => {
|
|||||||
<div>
|
<div>
|
||||||
<Link to="#" onClick={handleInvite} className="submit">Send</Link>
|
<Link to="#" onClick={handleInvite} className="submit">Send</Link>
|
||||||
<Link to="#" onClick={handleBan} className="submit">Ban</Link>
|
<Link to="#" onClick={handleBan} className="submit">Ban</Link>
|
||||||
<Link to="#" onClick={handleMute} className="submit">Mute</Link>
|
<Link to="#" onClick={mute ? darkMute : lightMute} className={mute ? "darkSubmit": "submit"}>Mute</Link>
|
||||||
<Link to="#" onClick={handleAdmin} className="submit">Admin</Link>
|
<Link to="#" onClick={handleAdmin} className="submit">Admin</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{mute ? (
|
||||||
|
<input type="text" className="in_howLong" placeholder="How long ?" />
|
||||||
|
):("")}
|
||||||
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</Backdrop>
|
</Backdrop>
|
||||||
|
|||||||
@ -1,10 +1,24 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* PartyInvite.tsx :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2023/06/19 16:44:29 by apommier #+# #+# */
|
||||||
|
/* Updated: 2023/06/20 23:53:01 by apommier ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import api from '../../script/axiosApi.tsx';
|
import api from '../../script/axiosApi.tsx';
|
||||||
import DefaultPicture from '../../assets/profile.jpg'
|
import DefaultPicture from '../../assets/profile.jpg'
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import {User} from "../../../interfaces.tsx"
|
||||||
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
|
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
const UserChat = styled.div `
|
const UserChat = styled.div `
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -25,10 +39,19 @@ const SideP = styled.p`
|
|||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function Friend({currentUser})
|
interface InviteProps {
|
||||||
|
username: string,
|
||||||
|
gameId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UserProps {
|
||||||
|
currentInvite: {username: string, gameId: string}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PartyInvite({currentInvite}: UserProps)
|
||||||
{
|
{
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
const [request, setRequest] = useState(''); //user who invite
|
const [request, setRequest] = useState<User>(); //user who invite
|
||||||
const [clickEvent, setClickEvent] = useState(false);
|
const [clickEvent, setClickEvent] = useState(false);
|
||||||
// const [user, setUser] = useState(null);
|
// const [user, setUser] = useState(null);
|
||||||
|
|
||||||
@ -37,11 +60,11 @@ export default function Friend({currentUser})
|
|||||||
try {
|
try {
|
||||||
// const user = await api.get("/profile");\
|
// const user = await api.get("/profile");\
|
||||||
// const tmpUser = await api.get("/profile")
|
// const tmpUser = await api.get("/profile")
|
||||||
const pic = await api.post("/getPicture", {username: currentUser.username})
|
const pic = await api.post("/getPicture", {username: currentInvite.username})
|
||||||
const tmpRequest = await api.post("/user", {username: currentUser.username})
|
const tmpRequest = await api.post("/user", {username: currentInvite.username})
|
||||||
// setUser(tmpUser.data);
|
// setUser(tmpUser.data);
|
||||||
setRequest(tmpRequest.data);
|
setRequest(tmpRequest.data);
|
||||||
// console.log(`user naem profile pic222= ${currentUser.username}`)
|
// console.log(`user naem profile pic222= ${currentInvite.username}`)
|
||||||
// console.log(` profile pic222= ${pic.data}`)
|
// console.log(` profile pic222= ${pic.data}`)
|
||||||
setProfilePicture(pic.data);
|
setProfilePicture(pic.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -52,18 +75,25 @@ export default function Friend({currentUser})
|
|||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
}, [clickEvent])
|
}, [clickEvent])
|
||||||
|
|
||||||
const handleButtonClick = (user) => {
|
const handleButtonClick = (user: InviteProps) => {
|
||||||
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
|
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
|
||||||
// history(path, { replace: true });
|
// history(path, { replace: true });
|
||||||
// window.location.replace(path);
|
// window.location.replace(path);
|
||||||
window.history.pushState({}, null, path);
|
window.history.pushState({}, '', path);
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const Accept = async (request) => {
|
const Accept = async (request: User) => {
|
||||||
try{
|
try{
|
||||||
await api.post("/friend", {username: request.username})
|
//call canvas ??
|
||||||
setClickEvent(true);
|
// await api.post("/friend", {username: request.username})
|
||||||
|
await api.post("/deleteInvite", {username: request.username})
|
||||||
|
let path = `http://` + process.env.REACT_APP_BASE_URL + `/pong/play?`
|
||||||
|
path += 'username=' + request.username;
|
||||||
|
path += '&gameId=' + currentInvite.gameId;
|
||||||
|
// setClickEvent(true);
|
||||||
|
window.history.pushState({}, '', path);
|
||||||
|
window.location.reload();
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
@ -71,9 +101,10 @@ export default function Friend({currentUser})
|
|||||||
console.log(`request = ${request}`)
|
console.log(`request = ${request}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Refuse = async (request) => {
|
const Refuse = async (request: User) => {
|
||||||
try{
|
try{
|
||||||
await api.post("/refuseInvite", {username: request.username})
|
await api.post("/deleteInvite", {username: request.username})
|
||||||
|
// await api.post("/refuseInvite", {username: request.username})
|
||||||
setClickEvent(true);
|
setClickEvent(true);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@ -84,6 +115,7 @@ export default function Friend({currentUser})
|
|||||||
|
|
||||||
// Vérifier si le contenu doit être caché
|
// Vérifier si le contenu doit être caché
|
||||||
if (clickEvent) {
|
if (clickEvent) {
|
||||||
|
console.log("retrun true")
|
||||||
return null; // Rendre null pour ne pas afficher le contenu
|
return null; // Rendre null pour ne pas afficher le contenu
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,13 +126,13 @@ export default function Friend({currentUser})
|
|||||||
) : (
|
) : (
|
||||||
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
|
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
|
||||||
)}
|
)}
|
||||||
|
{request ? (
|
||||||
<div className="infoSideBar">
|
<div className="infoSideBar">
|
||||||
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
|
<span onClick={() => handleButtonClick(currentInvite)}>{request.nickname}</span>
|
||||||
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/>
|
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/>
|
||||||
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/>
|
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
) : ( "" )}
|
||||||
</UserChat>
|
</UserChat>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +33,7 @@ const ModalEdit = ( handleClose ) => {
|
|||||||
const handler = e =>
|
const handler = e =>
|
||||||
{
|
{
|
||||||
setNickname(e.target.value);
|
setNickname(e.target.value);
|
||||||
|
console.log("testeeeee")
|
||||||
const postNickname = async ()=>{
|
const postNickname = async ()=>{
|
||||||
try{
|
try{
|
||||||
await api.post("/nickname", {nickname: nickname})
|
await api.post("/nickname", {nickname: nickname})
|
||||||
@ -45,6 +46,22 @@ const ModalEdit = ( handleClose ) => {
|
|||||||
};
|
};
|
||||||
postNickname();
|
postNickname();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handlePostNickname = async () =>
|
||||||
|
{
|
||||||
|
console.log("nickname=" ,nickname)
|
||||||
|
try{
|
||||||
|
await api.post("/nickname", {nickname: nickname})
|
||||||
|
window.location.reload();
|
||||||
|
// setUser(tmpUser.data);
|
||||||
|
// setIsLoading(false)
|
||||||
|
}
|
||||||
|
catch(err){
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// function handleClose(){
|
// function handleClose(){
|
||||||
// //do nothing
|
// //do nothing
|
||||||
// }
|
// }
|
||||||
@ -56,10 +73,11 @@ const ModalEdit = ( handleClose ) => {
|
|||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit">
|
exit="exit">
|
||||||
<h2>Type your new name</h2>
|
<h2>Type your new name</h2>
|
||||||
<input className="text" type="text" value={nickname} onChange={handler} handleClose/>
|
<input className="text" maxLength="10" type="text" value={nickname} onChange={handler} handleClose/>
|
||||||
<div onClick={handleClose}>
|
<div>
|
||||||
<div onClick={() => {UserProfile.UserName = nickname;}}>
|
<div className="button" onClick={ () => handlePostNickname()}>
|
||||||
<Link className="button" to={""}>change</Link>
|
change
|
||||||
|
{/* <Link className="button" to={""}>change</Link> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -8,8 +9,9 @@ function Logout(){
|
|||||||
// history(path, { replace: true });
|
// history(path, { replace: true });
|
||||||
// window.location.replace(path);
|
// window.location.replace(path);
|
||||||
// window.history.pushState({}, '', path);
|
// window.history.pushState({}, '', path);
|
||||||
window.history.pushState({}, null, path);
|
window.history.pushState({}, '', path);
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
|
return (<></>)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Logout;
|
export default Logout;
|
||||||
@ -4,6 +4,7 @@
|
|||||||
// import '../DataBase/DataProfileUser.js'
|
// import '../DataBase/DataProfileUser.js'
|
||||||
// import { DBWinLoss } from '../../DataBase/DummyDBWinLoss.js';
|
// import { DBWinLoss } from '../../DataBase/DummyDBWinLoss.js';
|
||||||
import '../../styles/Win_Loss.css'
|
import '../../styles/Win_Loss.css'
|
||||||
|
import { User, Matchlog } from "../../../interfaces.tsx"
|
||||||
// import { UserProfile } from '../../DataBase/DataUserProfile';
|
// import { UserProfile } from '../../DataBase/DataUserProfile';
|
||||||
// import color from '../../utils/style/color.js';
|
// import color from '../../utils/style/color.js';
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ import api from '../../script/axiosApi.tsx';
|
|||||||
|
|
||||||
function WinLoss() {
|
function WinLoss() {
|
||||||
|
|
||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState<User>();
|
||||||
const [history, setHistory] = useState([]);
|
const [history, setHistory] = useState([]);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
@ -88,13 +89,13 @@ function WinLoss() {
|
|||||||
|
|
||||||
|
|
||||||
<div className='tab'>
|
<div className='tab'>
|
||||||
{isLoading ? (
|
{isLoading || !history || !user ? (
|
||||||
<h1>Loading...</h1>
|
<h1>Loading...</h1>
|
||||||
// <span>Loading...</span>
|
// <span>Loading...</span>
|
||||||
) : (
|
) : (
|
||||||
<div className='scroll'>
|
<div className='scroll'>
|
||||||
<h2 className='title'>Match history Win/Loss</h2>
|
<h2 className='title'>Match history Win/Loss</h2>
|
||||||
{history.map((c, index) => {
|
{history.map((c: Matchlog, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={index} className='elements'>
|
<div key={index} className='elements'>
|
||||||
<li key={index}>
|
<li key={index}>
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
|
import React, { MouseEventHandler, ReactNode, HTMLAttributes } from "react";
|
||||||
import { motion } from "framer-motion"
|
import { motion } from "framer-motion"
|
||||||
import "../../styles/Header.css"
|
import "../../styles/Header.css"
|
||||||
|
|
||||||
const Backdrop = ({ children, onClick }) => {
|
interface backProps {
|
||||||
|
children: ReactNode,
|
||||||
|
onClick: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const Backdrop = ({ children, onClick }: backProps) => {
|
||||||
return (
|
return (
|
||||||
<motion.div className="backdrop"
|
<motion.div className="backdrop"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import * as AiIcons from 'react-icons/ai';
|
|||||||
|
|
||||||
|
|
||||||
import "../../styles/Header.css"
|
import "../../styles/Header.css"
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
const dropIn = {
|
const dropIn = {
|
||||||
hidden: {
|
hidden: {
|
||||||
@ -19,27 +20,11 @@ const dropIn = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CloseProps {
|
||||||
|
handleclose: Function;
|
||||||
|
}
|
||||||
|
|
||||||
// function showBar (){
|
const Modal = ({ handleclose }: CloseProps) => {
|
||||||
// return (
|
|
||||||
// {SidebarData.map((item, index) => {
|
|
||||||
// return (
|
|
||||||
// <motion.div
|
|
||||||
// className="nav-menu"
|
|
||||||
// // whileHover={{scale: 1.1}}
|
|
||||||
// >
|
|
||||||
// <li key={index} className={item.cName}>
|
|
||||||
// <Link to={item.path}>
|
|
||||||
// {item.icon}
|
|
||||||
// <span>{item.title}</span>
|
|
||||||
// </Link>
|
|
||||||
// </li>
|
|
||||||
// </motion.div>
|
|
||||||
// )
|
|
||||||
// })}
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
const Modal = ({ handleclose }) => {
|
|
||||||
return (
|
return (
|
||||||
<Backdrop onClick={handleclose}>
|
<Backdrop onClick={handleclose}>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export const SidebarData = [
|
|||||||
cName: 'nav-text'
|
cName: 'nav-text'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Social',
|
title: 'Friend',
|
||||||
path: '/social',
|
path: '/social',
|
||||||
icon: <IoIcons.IoMdPeople />,
|
icon: <IoIcons.IoMdPeople />,
|
||||||
cName: 'nav-text'
|
cName: 'nav-text'
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */
|
/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/18 13:12:26 by apommier ### ########.fr */
|
/* Updated: 2023/06/20 13:41:44 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ import styled from "styled-components";
|
|||||||
import { RxCircle } from "react-icons/rx";
|
import { RxCircle } from "react-icons/rx";
|
||||||
import { CgFontSpacing } from "react-icons/cg";
|
import { CgFontSpacing } from "react-icons/cg";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import {User} from "../../../interfaces.tsx"
|
||||||
|
|
||||||
const UserChat = styled.div `
|
const UserChat = styled.div `
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -37,8 +38,12 @@ const SideP = styled.p`
|
|||||||
color: lightgray;
|
color: lightgray;
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
`
|
`
|
||||||
|
interface UserProps {
|
||||||
|
currentUser: User
|
||||||
|
}
|
||||||
|
|
||||||
export default function Friend({currentUser})
|
// export default function Friend({currentUser})
|
||||||
|
export default function Friend({currentUser}: UserProps)
|
||||||
{
|
{
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
|
|
||||||
@ -58,7 +63,7 @@ export default function Friend({currentUser})
|
|||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
})
|
})
|
||||||
|
|
||||||
function getStatus(friend)
|
function getStatus(friend: User)
|
||||||
{
|
{
|
||||||
let status = friend.status
|
let status = friend.status
|
||||||
console.log(`status= ${status}`)
|
console.log(`status= ${status}`)
|
||||||
@ -73,19 +78,19 @@ export default function Friend({currentUser})
|
|||||||
return statusColor;
|
return statusColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSpectate = (user) => {
|
const handleSpectate = (user: User) => {
|
||||||
//socket connection and add to party with one with username
|
//socket connection and add to party with one with username
|
||||||
console.log(`spectate hehe`)
|
console.log(`spectate hehe`)
|
||||||
console.log(`user= ${user}`)
|
console.log(`user= ${user}`)
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleButtonClick = (user) => {
|
const handleButtonClick = (user: User) => {
|
||||||
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
|
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
|
||||||
console.log("path= ", path)
|
console.log("path= ", path)
|
||||||
// history(path, { replace: true });
|
// history(path, { replace: true });
|
||||||
// window.location.replace(path);
|
// window.location.replace(path);
|
||||||
window.history.pushState({}, null, path);
|
window.history.pushState({}, '', path);
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -97,7 +102,7 @@ export default function Friend({currentUser})
|
|||||||
)}
|
)}
|
||||||
<div className="infoSideBar">
|
<div className="infoSideBar">
|
||||||
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
|
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
|
||||||
<RxCircle icon={RxCircle} color={getStatus(currentUser)} />
|
<RxCircle color={getStatus(currentUser)} />
|
||||||
<button onClick={() => handleSpectate(currentUser)} >Invite</button>
|
<button onClick={() => handleSpectate(currentUser)} >Invite</button>
|
||||||
{getStatus(currentUser) !== 'blue' ? (
|
{getStatus(currentUser) !== 'blue' ? (
|
||||||
<></>
|
<></>
|
||||||
|
|||||||
@ -1,111 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* Friend.jsx :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */
|
|
||||||
/* Updated: 2023/06/15 19:05:14 by apommier ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import api from '../../script/axiosApi.tsx';
|
|
||||||
import DefaultPicture from '../../assets/profile.jpg'
|
|
||||||
import styled from "styled-components";
|
|
||||||
|
|
||||||
import { RxCircle } from "react-icons/rx";
|
|
||||||
import { CgFontSpacing } from "react-icons/cg";
|
|
||||||
|
|
||||||
const UserChat = styled.div `
|
|
||||||
padding: 5px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 5px;
|
|
||||||
color: white;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover{
|
|
||||||
background-color: #3e3c61;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const SideP = styled.p`
|
|
||||||
font-size: 14px;
|
|
||||||
color: lightgray;
|
|
||||||
margin-left: 15px;
|
|
||||||
`
|
|
||||||
|
|
||||||
export default function Friend({currentUser})
|
|
||||||
{
|
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchProfilePicture = async () => {
|
|
||||||
try {
|
|
||||||
// const user = await api.get("/profile");
|
|
||||||
const pic = await api.post("/getPicture", {username: currentUser.username})
|
|
||||||
// console.log(`user naem profile pic222= ${currentUser.username}`)
|
|
||||||
// console.log(` profile pic222= ${pic.data}`)
|
|
||||||
setProfilePicture(pic.data);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching profile picture:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchProfilePicture();
|
|
||||||
})
|
|
||||||
|
|
||||||
function getStatus(friend)
|
|
||||||
{
|
|
||||||
let status = friend.status
|
|
||||||
console.log(`status= ${status}`)
|
|
||||||
let statusColor;
|
|
||||||
|
|
||||||
if (status === 0)
|
|
||||||
statusColor = 'grey';
|
|
||||||
else if (status === 1)
|
|
||||||
statusColor = 'green';
|
|
||||||
else if (status === 2)
|
|
||||||
statusColor = 'blue';
|
|
||||||
return statusColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSpectate = (user) => {
|
|
||||||
//socket connection and add to party with one with username
|
|
||||||
console.log(`spectate hehe`)
|
|
||||||
console.log(`user= ${user}`)
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleButtonClick = (user) => {
|
|
||||||
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
|
|
||||||
console.log("path= ", path)
|
|
||||||
// history(path, { replace: true });
|
|
||||||
// window.location.replace(path);
|
|
||||||
window.history.pushState({}, null, path);
|
|
||||||
window.location.reload(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<UserChat>
|
|
||||||
{profilePicture ? (
|
|
||||||
<img className="pic-user" src={`data:image/jpeg;base64,${profilePicture}`} />
|
|
||||||
) : (
|
|
||||||
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
|
|
||||||
)}
|
|
||||||
<div className="infoSideBar">
|
|
||||||
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
|
|
||||||
<RxCircle icon={RxCircle} color={getStatus(currentUser)} />
|
|
||||||
<button onClick={() => handleSpectate(currentUser)} >Invite</button>
|
|
||||||
{getStatus(currentUser) !== 'blue' ? (
|
|
||||||
<></>
|
|
||||||
) : (
|
|
||||||
<button onClick={() => handleSpectate(currentUser)} >Spectate</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</UserChat>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -5,6 +5,8 @@ import DefaultPicture from '../../assets/profile.jpg'
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
|
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
|
||||||
|
import React from "react";
|
||||||
|
import {User} from "../../../interfaces.tsx"
|
||||||
|
|
||||||
const UserChat = styled.div `
|
const UserChat = styled.div `
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -25,10 +27,14 @@ const SideP = styled.p`
|
|||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
`
|
`
|
||||||
|
|
||||||
export default function Friend({currentUser})
|
interface UserProps {
|
||||||
|
currentUser: User
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Friend({currentUser}: UserProps)
|
||||||
{
|
{
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
const [request, setRequest] = useState(''); //user who invite
|
const [request, setRequest] = useState<User>(); //user who invite
|
||||||
const [clickEvent, setClickEvent] = useState(false);
|
const [clickEvent, setClickEvent] = useState(false);
|
||||||
// const [user, setUser] = useState(null);
|
// const [user, setUser] = useState(null);
|
||||||
|
|
||||||
@ -52,15 +58,15 @@ export default function Friend({currentUser})
|
|||||||
fetchProfilePicture();
|
fetchProfilePicture();
|
||||||
}, [clickEvent])
|
}, [clickEvent])
|
||||||
|
|
||||||
const handleButtonClick = (user) => {
|
const handleButtonClick = (user: User) => {
|
||||||
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
|
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
|
||||||
// history(path, { replace: true });
|
// history(path, { replace: true });
|
||||||
// window.location.replace(path);
|
// window.location.replace(path);
|
||||||
window.history.pushState({}, null, path);
|
window.history.pushState({}, '', path);
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const Accept = async (request) => {
|
const Accept = async (request: User) => {
|
||||||
try{
|
try{
|
||||||
await api.post("/friend", {username: request.username})
|
await api.post("/friend", {username: request.username})
|
||||||
setClickEvent(true);
|
setClickEvent(true);
|
||||||
@ -71,7 +77,7 @@ export default function Friend({currentUser})
|
|||||||
console.log(`request = ${request}`)
|
console.log(`request = ${request}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Refuse = async (request) => {
|
const Refuse = async (request: User) => {
|
||||||
try{
|
try{
|
||||||
await api.post("/refuseInvite", {username: request.username})
|
await api.post("/refuseInvite", {username: request.username})
|
||||||
setClickEvent(true);
|
setClickEvent(true);
|
||||||
@ -94,12 +100,13 @@ export default function Friend({currentUser})
|
|||||||
) : (
|
) : (
|
||||||
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
|
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
|
||||||
)}
|
)}
|
||||||
|
{request ? (
|
||||||
<div className="infoSideBar">
|
<div className="infoSideBar">
|
||||||
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
|
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
|
||||||
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/>
|
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/>
|
||||||
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/>
|
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
) : ( "" )}
|
||||||
</UserChat>
|
</UserChat>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import FriendRequest from './FriendRequest.tsx';
|
|||||||
|
|
||||||
import { ImBlocked } from 'react-icons/im';
|
import { ImBlocked } from 'react-icons/im';
|
||||||
import { MdOutlineGroupAdd } from 'react-icons/md';
|
import { MdOutlineGroupAdd } from 'react-icons/md';
|
||||||
|
import {User} from "../../../interfaces.tsx"
|
||||||
|
|
||||||
// import React from "react";
|
// import React from "react";
|
||||||
|
|
||||||
@ -34,12 +35,11 @@ function Social (){
|
|||||||
|
|
||||||
const [friends, setFriends] = useState([]);
|
const [friends, setFriends] = useState([]);
|
||||||
const [invite, setInvite] = useState([]);
|
const [invite, setInvite] = useState([]);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState<User>();
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
|
|
||||||
const getFriend = async ()=>{
|
const getFriend = async ()=>{
|
||||||
try{
|
try{
|
||||||
const tmpFriends = await api.get("/friends")
|
const tmpFriends = await api.get("/friends")
|
||||||
@ -94,7 +94,7 @@ function Social (){
|
|||||||
<img className="pic" src={DefaultPicture} alt="Default Profile Picture" />
|
<img className="pic" src={DefaultPicture} alt="Default Profile Picture" />
|
||||||
)}
|
)}
|
||||||
<span>
|
<span>
|
||||||
{isLoading ? (
|
{isLoading || !user ? (
|
||||||
<h4>Loading...</h4>
|
<h4>Loading...</h4>
|
||||||
) : (
|
) : (
|
||||||
<h4>{user.nickname}</h4>
|
<h4>{user.nickname}</h4>
|
||||||
|
|||||||
@ -1,13 +1,20 @@
|
|||||||
import { useEffect, useLocation } from 'react';
|
import { useEffect } from 'react';
|
||||||
// import { useState, useRef } from 'react';
|
// import { useState, useRef } from 'react';
|
||||||
import DrawCanvas from './canvas.tsx';
|
import DrawCanvas from './canvas.tsx';
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
import '../styles/field.css';
|
import '../styles/field.css';
|
||||||
|
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
// import { withRouter } from 'react-router-dom';
|
// import { withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
|
interface GameProps {
|
||||||
|
privateParty: boolean,
|
||||||
|
username?: string
|
||||||
|
gameId?: number
|
||||||
|
}
|
||||||
|
|
||||||
function Field()
|
function Field()
|
||||||
{
|
{
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -16,6 +23,7 @@ function Field()
|
|||||||
|
|
||||||
console.log("launch canva hehe")
|
console.log("launch canva hehe")
|
||||||
let Modifiers = 0;
|
let Modifiers = 0;
|
||||||
|
let info: GameProps;
|
||||||
|
|
||||||
if (queryParams.superpower === 'true') {
|
if (queryParams.superpower === 'true') {
|
||||||
Modifiers += 1;
|
Modifiers += 1;
|
||||||
@ -28,81 +36,37 @@ function Field()
|
|||||||
if (queryParams.speed === 'true') {
|
if (queryParams.speed === 'true') {
|
||||||
Modifiers += 4;
|
Modifiers += 4;
|
||||||
}
|
}
|
||||||
// console.log(`modifiers= ${Modifiers}`)
|
|
||||||
// DrawCanvas(Modifiers);
|
|
||||||
// return () => {
|
|
||||||
// console.log("000000000000000000000000000000000")
|
|
||||||
// // socketRef.current.disconnect();
|
|
||||||
// };
|
|
||||||
|
|
||||||
// console.log(`modifiers= ${Modifiers}`)
|
info = {
|
||||||
const cleanup = DrawCanvas(Modifiers);
|
privateParty: false,
|
||||||
|
|
||||||
|
}
|
||||||
|
if (queryParams.username)
|
||||||
|
{
|
||||||
|
console.log("user= ", queryParams.username)
|
||||||
|
info = {
|
||||||
|
privateParty: true,
|
||||||
|
username: queryParams.username as string,
|
||||||
|
gameId: queryParams.gameId as unknown as number
|
||||||
|
}
|
||||||
|
console.log("info of param vefore canvas=", info)
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleanup = DrawCanvas(Modifiers, info);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
console.log("Cleanup");
|
console.log("Cleanup");
|
||||||
cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
|
// cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
|
||||||
|
if (cleanup)
|
||||||
|
cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// const [buttonClicked, setButtonClicked] = useState(false);
|
|
||||||
|
|
||||||
// const handleButtonClick = () => {
|
|
||||||
// drawCanvas();
|
|
||||||
// setButtonClicked(true);
|
|
||||||
// };
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="field" id="canvas_container">
|
<div className="field" id="canvas_container">
|
||||||
<canvas id="myCanvas"></canvas>
|
<canvas id="myCanvas"></canvas>
|
||||||
{/* <button onClick={handleButtonClick}>Draw on Canvas</button> */}
|
|
||||||
{/* {buttonClicked && <canvas id="myCanvas"></canvas>}
|
|
||||||
{!buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button>} */}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Field;
|
export default Field;
|
||||||
// export default withRouter(Field);
|
|
||||||
|
|
||||||
|
|
||||||
// function Field() {
|
|
||||||
// const [buttonClicked, setButtonClicked] = useState(false);
|
|
||||||
|
|
||||||
// const handleButtonClick = () => {
|
|
||||||
// const canvas = document.createElement('canvas');
|
|
||||||
// canvas.id = 'myCanvas';
|
|
||||||
// console.log("button clicked")
|
|
||||||
// document.getElementById('canvas_container').appendChild(canvas);
|
|
||||||
// setButtonClicked(true);
|
|
||||||
// drawCanvas(canvas);
|
|
||||||
// };
|
|
||||||
// setButtonClicked(true);
|
|
||||||
// return (
|
|
||||||
// // <div className="field" id="canvas_container">
|
|
||||||
// <div className={`notClicked ${buttonClicked ? 'clicked' : ''}`} id="canvas_container">
|
|
||||||
// {!buttonClicked && <button className="playButton" onClick={handleButtonClick}>Play</button>}
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export default Field;
|
|
||||||
|
|
||||||
// function draw() {
|
|
||||||
// // Effacer le canvas
|
|
||||||
// ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
// // Dessiner la raquette
|
|
||||||
// ctx.fillRect(canvas.width - paddleWidth, paddleY, paddleWidth, paddleHeight);
|
|
||||||
|
|
||||||
// // Appeler la fonction draw à chaque frame
|
|
||||||
// requestAnimationFrame(draw);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// draw(); // Appeler la fonction draw pour la première fois
|
|
||||||
|
|
||||||
// const canvas = document.getElementById('myCanvas');
|
|
||||||
// canvas.width = 500;
|
|
||||||
// canvas.height = 500;
|
|
||||||
// const ctx = canvas.getContext('2d');
|
|
||||||
// ctx.fillRect(50, 50, 1000, 1000);
|
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
function Head()
|
function Head()
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
@ -7,7 +9,7 @@ function Head()
|
|||||||
<title>BEST PONG EVER</title>
|
<title>BEST PONG EVER</title>
|
||||||
{/* <script src="./script/login.js"></script> */}
|
{/* <script src="./script/login.js"></script> */}
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com"></link>
|
<link rel="preconnect" href="https://fonts.googleapis.com"></link>
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="true"></link>
|
{/* <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="true"></link> */}
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Rubik+Iso&display=swap" rel="stylesheet"></link>
|
<link href="https://fonts.googleapis.com/css2?family=Rubik+Iso&display=swap" rel="stylesheet"></link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* Home.jsx :+: :+: :+: */
|
/* Home.tsx :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2023/06/09 08:19:04 by apommier #+# #+# */
|
/* Created: 2023/06/09 08:19:04 by apommier #+# #+# */
|
||||||
/* Updated: 2023/06/09 08:19:05 by apommier ### ########.fr */
|
/* Updated: 2023/06/23 15:58:14 by apommier ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -21,6 +21,9 @@ import { motion, AnimatePresence } from 'framer-motion'
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import ModalEdit from "../components/Profile/EditName.tsx";
|
import ModalEdit from "../components/Profile/EditName.tsx";
|
||||||
import {AiOutlineHistory} from 'react-icons/ai'
|
import {AiOutlineHistory} from 'react-icons/ai'
|
||||||
|
import { MdQrCodeScanner, MdOutlinePhotoLibrary } from 'react-icons/md';
|
||||||
|
import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi';
|
||||||
|
|
||||||
// import { Link } from "react-router-dom";
|
// import { Link } from "react-router-dom";
|
||||||
// import {UserProfile} from "../DataBase/DataUserProfile";
|
// import {UserProfile} from "../DataBase/DataUserProfile";
|
||||||
// import axios from "axios";
|
// import axios from "axios";
|
||||||
@ -30,8 +33,10 @@ import { IoCloseCircleOutline } from "react-icons/io5";
|
|||||||
|
|
||||||
// import * as React from 'react';
|
// import * as React from 'react';
|
||||||
// import { useState, useEffect, useParams} from "react";
|
// import { useState, useEffect, useParams} from "react";
|
||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef, ChangeEventHandler } from "react";
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
import {User, Conv} from "../../interfaces.tsx"
|
||||||
|
import YellowAlert from '../components/Alert/YellowAlert.tsx';
|
||||||
// axios.get("http://localhost/api")
|
// axios.get("http://localhost/api")
|
||||||
// .then((response) => {
|
// .then((response) => {
|
||||||
// response = response.json()
|
// response = response.json()
|
||||||
@ -43,41 +48,71 @@ import { useParams } from 'react-router-dom';
|
|||||||
|
|
||||||
|
|
||||||
function Profile () {
|
function Profile () {
|
||||||
const [user, setUser] = useState(null);
|
const [user, setUser] = useState<User>();
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
||||||
const [mine, setMine] = useState(false);
|
const [mine, setMine] = useState<boolean>(false);
|
||||||
const close = () => setModalOpen(false);
|
const close = () => setModalOpen(false);
|
||||||
const open = () => setModalOpen(true);
|
const open = () => setModalOpen(true);
|
||||||
|
|
||||||
const { username } = useParams();
|
const { username } = useParams();
|
||||||
|
|
||||||
const [selectedPhoto, setSelectedPhoto] = useState(null);
|
// const [selectedPhoto, setSelectedPhoto] = useState();
|
||||||
|
// const [selectedPhoto, setSelectedPhoto] = useState(null);
|
||||||
|
|
||||||
const [profilePicture, setProfilePicture] = useState('');
|
const [profilePicture, setProfilePicture] = useState('');
|
||||||
|
|
||||||
const handleFileChange = (event) => {
|
const handleFileChange = async (event: { target: { files: any; }; }) => {
|
||||||
// const file = event.target.files[0];
|
// const files = event.target.files;
|
||||||
setSelectedPhoto(event.target.files[0]);
|
// if (files && files.length > 0) {
|
||||||
// try{
|
const photo = (event.target.files[0]);
|
||||||
// api.post("/picture", {picture: URL.createObjectURL(file)})
|
console.log("file selected")
|
||||||
// }
|
if (photo) {
|
||||||
// catch(err){
|
console.log("selected photo")
|
||||||
// console.log(err);
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleUpload = async () => {
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('photo', selectedPhoto);
|
formData.append('photo', photo);
|
||||||
try {
|
try {
|
||||||
await api.post('/picture', formData);
|
await api.post('/picture', formData);
|
||||||
console.log('File uploaded successfully');
|
console.log('File uploaded successfully');
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error uploading file:', error);
|
console.error('Error uploading file:', error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// const handleUpload = async () => {
|
||||||
|
// const formData = new FormData();
|
||||||
|
// formData.append('photo', selectedPhoto);
|
||||||
|
// try {
|
||||||
|
// await api.post('/picture', formData);
|
||||||
|
// console.log('File uploaded successfully');
|
||||||
|
// window.location.reload();
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error uploading file:', error);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleUpload = async (event: React.FormEvent) => {
|
||||||
|
// event.preventDefault()
|
||||||
|
// console.log("up photo")
|
||||||
|
// if (selectedPhoto) {
|
||||||
|
// console.log("selected photo")
|
||||||
|
// const formData = new FormData();
|
||||||
|
// formData.append('photo', selectedPhoto);
|
||||||
|
// try {
|
||||||
|
// await api.post('/picture', formData);
|
||||||
|
// console.log('File uploaded successfully');
|
||||||
|
// window.location.reload();
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error('Error uploading file:', error);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// console.log('No file selected');
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
const getUser = async ()=>{
|
const getUser = async ()=>{
|
||||||
console.log(`username= ${username}`)
|
console.log(`username= ${username}`)
|
||||||
@ -122,7 +157,7 @@ function Profile () {
|
|||||||
<img className="profile-pic" src={DefaultPicture} alt="Default Profile Picture" />
|
<img className="profile-pic" src={DefaultPicture} alt="Default Profile Picture" />
|
||||||
)}
|
)}
|
||||||
<span>
|
<span>
|
||||||
{isLoading ? (
|
{isLoading || !user ? (
|
||||||
<h1>Loading...</h1>
|
<h1>Loading...</h1>
|
||||||
) : (
|
) : (
|
||||||
<h1>{user.nickname}</h1>
|
<h1>{user.nickname}</h1>
|
||||||
@ -133,16 +168,22 @@ function Profile () {
|
|||||||
|
|
||||||
{mine ? (
|
{mine ? (
|
||||||
<div>
|
<div>
|
||||||
<motion.div onClick={() => (modalOpen ? close() : open())}>
|
<motion.div >
|
||||||
<Link to="#" className="edit_name">
|
<Link to="#" className="edit_name" onClick={() => (modalOpen ? close() : open())}>
|
||||||
{modalOpen === true ? <IoCloseCircleOutline/> : <CgEditMarkup/>}
|
{modalOpen === true ? <IoCloseCircleOutline/> : <CgEditMarkup/>}
|
||||||
</Link>
|
</Link>
|
||||||
|
{modalOpen === true ? ("") : (
|
||||||
|
<>
|
||||||
|
<label htmlFor="file-input" className="edit_name"><MdOutlinePhotoLibrary/></label>
|
||||||
|
<input type="file" id="file-input" className="file-input" accept="image/*" onChange={handleFileChange} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<div>
|
{/* <div className="file-upload-container"> */}
|
||||||
<input type="file" accept="image/*" onChange={handleFileChange} />
|
{/* <button onClick={handleUpload} className="upload-button">Upload</button> */}
|
||||||
<button onClick={handleUpload}>Upload</button>
|
{/* <button onClick={handleUpload} className="upload-button">Upload</button> */}
|
||||||
</div>
|
{/* </div> */}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
@ -161,13 +202,49 @@ function Profile () {
|
|||||||
|
|
||||||
function Home () {
|
function Home () {
|
||||||
const [move, setmove ] = useState(false);
|
const [move, setmove ] = useState(false);
|
||||||
|
const [user, setUser] = useState([]);
|
||||||
|
|
||||||
|
const [successQr, setSuccessQr] = useState(false);
|
||||||
|
const [successSword, setSuccessSword] = useState(false);
|
||||||
|
const [successCrown, setSuccessCrown] = useState(false);
|
||||||
|
const closeQr = () => setSuccessQr(false);
|
||||||
|
const closeSword = () => setSuccessSword(false);
|
||||||
|
const closeCrown = () => setSuccessCrown(false);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchSuccess = async () => {
|
||||||
|
try {
|
||||||
|
const tmpUser = await api.get("/profile");
|
||||||
|
setUser(tmpUser.data);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchSuccess();
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div className="page"
|
<motion.div className="page"
|
||||||
initial={{opacity: -1}}
|
initial={{opacity: -1}}
|
||||||
animate={{opacity: 1}}
|
animate={{opacity: 1}}
|
||||||
exit={{opacity: -1}}>
|
exit={{opacity: -1}}>
|
||||||
|
<div>
|
||||||
|
{user.otp_verified ? (
|
||||||
|
<MdQrCodeScanner className='success' onClick={() => setSuccessQr(true)}/>
|
||||||
|
):("")}
|
||||||
|
{user.win >= 2 ? (
|
||||||
|
<GiWingedSword className="success" onClick={() => setSuccessSword(true)}/>
|
||||||
|
):("")}
|
||||||
|
|
||||||
|
{user.win >= 5 ? (
|
||||||
|
<GiCrownedSkull className="success" onClick={() => setSuccessCrown(true)}/>
|
||||||
|
):("")}
|
||||||
|
</div>
|
||||||
<div className="home">
|
<div className="home">
|
||||||
<motion.div animate={{x: move ? -200: 170}}
|
<motion.div animate={{x: move ? -200: 120}}
|
||||||
transition={{type: "tween", duration: 0.5}}>
|
transition={{type: "tween", duration: 0.5}}>
|
||||||
<Profile/>
|
<Profile/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
@ -181,6 +258,19 @@ function Home () {
|
|||||||
onClick={ () => setmove(!move)}>
|
onClick={ () => setmove(!move)}>
|
||||||
<Link to="#" className="history"><AiOutlineHistory/> Match History</Link>
|
<Link to="#" className="history"><AiOutlineHistory/> Match History</Link>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
<AnimatePresence initial={false} onExitComplete={() => null}>
|
||||||
|
{successQr ? (
|
||||||
|
<YellowAlert handleClose={closeQr} text={"Success: You have the 2fa success!"} icon={1} />
|
||||||
|
) : ("")}
|
||||||
|
|
||||||
|
{successCrown ? (
|
||||||
|
<YellowAlert handleClose={closeCrown} text={"Success: 5 victory ? You won king slayer success!"} icon={2}/>
|
||||||
|
) : ("")}
|
||||||
|
|
||||||
|
{successSword ? (
|
||||||
|
<YellowAlert handleClose={closeSword} text={"Success: 2 victory ? You won the noobi warrior success!"} icon={3}/>
|
||||||
|
) : ("")}
|
||||||
|
</AnimatePresence>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
// import GoogleLogin from 'react-google-login';
|
// import GoogleLogin from 'react-google-login';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import React from 'react';
|
||||||
// import setupLogin from '../script/login42';
|
// import setupLogin from '../script/login42';
|
||||||
// import React, { useEffect } from 'react';
|
// import React, { useEffect } from 'react';
|
||||||
|
|
||||||
@ -15,12 +16,15 @@ function Login42()
|
|||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
grant_type: 'authorization_code',
|
grant_type: 'authorization_code',
|
||||||
client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
|
// client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
|
||||||
client_secret: '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',
|
// client_secret: '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',
|
||||||
|
client_id: process.env.REACT_APP_CLIENT_UID,
|
||||||
|
client_secret: process.env.REACT_APP_API_SECRET,
|
||||||
code: code,
|
code: code,
|
||||||
redirect_uri: 'http://' + process.env.REACT_APP_BASE_URL + '/login42',
|
redirect_uri: 'http://' + process.env.REACT_APP_BASE_URL + '/login42',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
axios.post('https://api.intra.42.fr/oauth/token', data)
|
axios.post('https://api.intra.42.fr/oauth/token', data)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
// handle success response
|
// handle success response
|
||||||
@ -34,7 +38,7 @@ function Login42()
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>"COUCOU LOGIN$@ jeje" </p>
|
<p>"COUCOU LOGIN" </p>
|
||||||
{/* <script src="../script/login42.js"></script> */}
|
{/* <script src="../script/login42.js"></script> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { motion } from 'framer-motion'
|
|||||||
|
|
||||||
// import {io} from 'socket.io-client'
|
// import {io} from 'socket.io-client'
|
||||||
|
|
||||||
function Messages(params) {
|
function Messages() {
|
||||||
// const socket = useRef(io("ws://localhost:8900"))
|
// const socket = useRef(io("ws://localhost:8900"))
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import React from 'react';
|
||||||
import '../styles/field.css';
|
import '../styles/field.css';
|
||||||
// import { useHistory } from 'react-router-dom';
|
// import { useHistory } from 'react-router-dom';
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|||||||
@ -29,9 +29,10 @@ const qrCode = new QRCodeStyling({
|
|||||||
|
|
||||||
function QrCode () {
|
function QrCode () {
|
||||||
// const url = "https://www.youtube.com";
|
// const url = "https://www.youtube.com";
|
||||||
const ref = useRef(null);
|
// const ref = useRef(null);
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const [user, setUser] = useState(false);
|
const [user, setUser] = useState(false);
|
||||||
const [url, setUrl] = useState(false);
|
const [url, setUrl] = useState("");
|
||||||
const [secret, setSecret] = useState(false);
|
const [secret, setSecret] = useState(false);
|
||||||
const [code, setCode] = useState('');
|
const [code, setCode] = useState('');
|
||||||
const [activated, setActivated] = useState(false);
|
const [activated, setActivated] = useState(false);
|
||||||
@ -39,8 +40,8 @@ function QrCode () {
|
|||||||
// const history = useHistory();
|
// const history = useHistory();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (ref.current)
|
||||||
qrCode.append(ref.current);
|
qrCode.append(ref.current);
|
||||||
|
|
||||||
const getUser = async ()=>{
|
const getUser = async ()=>{
|
||||||
try{
|
try{
|
||||||
const tmpUser = await api.get("/profile");
|
const tmpUser = await api.get("/profile");
|
||||||
@ -66,13 +67,11 @@ function QrCode () {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
qrCode.update({
|
qrCode.update({data: url});
|
||||||
data: url
|
|
||||||
});
|
|
||||||
}, [url]);
|
}, [url]);
|
||||||
|
|
||||||
|
|
||||||
const handleKeyPress = async (e)=>{
|
const handleKeyPress = async (e: { key: string; })=>{
|
||||||
// console.log(`e in press= ${e.key}`)
|
// console.log(`e in press= ${e.key}`)
|
||||||
if (e.key !== "Enter")
|
if (e.key !== "Enter")
|
||||||
return ;
|
return ;
|
||||||
@ -87,8 +86,8 @@ function QrCode () {
|
|||||||
// history.push('/login')
|
// history.push('/login')
|
||||||
|
|
||||||
const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
||||||
window.history.pushState({}, null, path);
|
window.history.pushState({}, '', path);
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -107,8 +106,8 @@ function QrCode () {
|
|||||||
try {
|
try {
|
||||||
await api.post("/deleteOtp")
|
await api.post("/deleteOtp")
|
||||||
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
||||||
// window.history.pushState({}, null, path);
|
// window.history.pushState({}, '', path);
|
||||||
window.location.reload(false);
|
window.location.reload();
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
@ -139,6 +138,7 @@ function QrCode () {
|
|||||||
<h3>{secret}</h3>
|
<h3>{secret}</h3>
|
||||||
<h1>Or Scan The QRCode</h1>
|
<h1>Or Scan The QRCode</h1>
|
||||||
<div ref={ref} />
|
<div ref={ref} />
|
||||||
|
{/* <div>{ref}</div> */}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,13 @@ import io from 'socket.io-client';
|
|||||||
// const socket = io('http://86.209.110.20:4000');
|
// const socket = io('http://86.209.110.20:4000');
|
||||||
// const socket = io('http://172.29.113.91:4000');
|
// const socket = io('http://172.29.113.91:4000');
|
||||||
|
|
||||||
function DrawCanvas(option) {
|
interface GameProps {
|
||||||
|
privateParty: boolean,
|
||||||
|
username?: string
|
||||||
|
gameId?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
function DrawCanvas(option: number, gameParam: GameProps) {
|
||||||
|
|
||||||
console.log(`option= ${option}`);
|
console.log(`option= ${option}`);
|
||||||
const superpowerModifier = option & 1; // Retrieves the superpower modifier
|
const superpowerModifier = option & 1; // Retrieves the superpower modifier
|
||||||
@ -25,12 +29,39 @@ function DrawCanvas(option) {
|
|||||||
|
|
||||||
// const socketRef = useRef(null);
|
// const socketRef = useRef(null);
|
||||||
// socketRef.current = io('http://localhost:4000');
|
// socketRef.current = io('http://localhost:4000');
|
||||||
const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000');
|
|
||||||
|
function launchGame()
|
||||||
|
{
|
||||||
|
if (!gameParam.privateParty)
|
||||||
|
{
|
||||||
|
console.log("laucnh matchmaking")
|
||||||
|
matchmaking();
|
||||||
|
}
|
||||||
|
else if (!gameParam.gameId)
|
||||||
|
{
|
||||||
|
console.log("laucnh private")
|
||||||
|
privateParty();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log("join private")
|
||||||
|
joinPrivateParty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// const socket = socketRef.current
|
// const socket = socketRef.current
|
||||||
console.log("start function");
|
console.log("start function");
|
||||||
const canvas = document.getElementById('myCanvas');
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
|
|
||||||
|
// let canvas: HTMLElement | null;
|
||||||
|
const canvas = document.getElementById('myCanvas') as HTMLCanvasElement | null;;
|
||||||
|
if (!canvas)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
if(!ctx)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
const socket = io('http://localhost:4000', { transports: ['polling'] });
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// console.log("useeffect?????????????????")
|
// console.log("useeffect?????????????????")
|
||||||
// return () => {
|
// return () => {
|
||||||
@ -49,8 +80,8 @@ function DrawCanvas(option) {
|
|||||||
//socket
|
//socket
|
||||||
let myId = 0;
|
let myId = 0;
|
||||||
let gameId = 0;
|
let gameId = 0;
|
||||||
let opName;
|
let opName: string
|
||||||
let opRank;
|
let opRank: number;
|
||||||
|
|
||||||
//general canvas
|
//general canvas
|
||||||
let running = true;
|
let running = true;
|
||||||
@ -99,46 +130,43 @@ function DrawCanvas(option) {
|
|||||||
|
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
// Socket handler
|
// Socket ON
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
|
|
||||||
function matchmaking()
|
socket.on('pong:win', async () => {
|
||||||
{
|
myScore = maxScore;
|
||||||
console.log(`id ion matcj= ${myId}`)
|
console.log("instant win opponent disconnect")
|
||||||
const info = {
|
// const data = {
|
||||||
id: myId,
|
// myScore: myScore,
|
||||||
option: option,
|
// opScore: hisScore,
|
||||||
};
|
// opName: opName,
|
||||||
socket.emit('pong:matchmaking', info);
|
// opRank: opRank,
|
||||||
}
|
|
||||||
|
|
||||||
// socket.on('pong:gameId', (data) => {
|
|
||||||
// console.log("gameId received")
|
|
||||||
// gameId = data;
|
|
||||||
// // api.get('/profile');
|
|
||||||
|
|
||||||
// let myName;
|
|
||||||
|
|
||||||
// api.get('/profile').then((data) => {
|
|
||||||
// // Faire quelque chose avec les données
|
|
||||||
// console.log(data);
|
|
||||||
// myName = data.data.username;
|
|
||||||
// console.log(`myname= ${myName}`);
|
|
||||||
// }).catch((error) => {
|
|
||||||
// console.log(error);
|
|
||||||
// // exit() ;
|
|
||||||
// return;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// const info = {
|
|
||||||
// id: myId,
|
|
||||||
// name: myName,
|
|
||||||
// gameId: gameId,
|
|
||||||
// };
|
// };
|
||||||
// console.log("emit to name")
|
|
||||||
// socket.emit('pong:name', info);
|
// await api.post('/win', data);
|
||||||
// });
|
console.log("after request1")
|
||||||
|
await api.post('/status', {status: 1});
|
||||||
|
console.log("after request2")
|
||||||
|
//disconnect ?
|
||||||
|
running = false;
|
||||||
|
socket.emit('pong:disconnect', {id: myId});
|
||||||
|
console.log("before reload")
|
||||||
|
// window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
|
||||||
|
// window.location.reload();
|
||||||
|
return ;
|
||||||
|
// console.log("send all ?? win");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('pong:privateId', async (data) => {
|
||||||
|
console.log("private id = ", data)
|
||||||
|
try{
|
||||||
|
await api.post("/partyInvite", {username: gameParam.username, gameId: data});
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('pong:gameId', async (data) => {
|
socket.on('pong:gameId', async (data) => {
|
||||||
console.log("gameId received");
|
console.log("gameId received");
|
||||||
@ -182,6 +210,7 @@ function DrawCanvas(option) {
|
|||||||
console.log("receive id")
|
console.log("receive id")
|
||||||
myId = data;
|
myId = data;
|
||||||
console.log(`id is= ${myId}`)
|
console.log(`id is= ${myId}`)
|
||||||
|
launchGame();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('pong:info', (data) => {
|
socket.on('pong:info', (data) => {
|
||||||
@ -214,9 +243,60 @@ function DrawCanvas(option) {
|
|||||||
// oPaddleY = (data.paddleY / data.height) * canvas.height
|
// oPaddleY = (data.paddleY / data.height) * canvas.height
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('pong:point', (data) => {
|
||||||
|
// hisScore += 1;
|
||||||
|
console.log("gain point");
|
||||||
|
// if (vX != 0)
|
||||||
|
// {
|
||||||
|
// console.log("up point");
|
||||||
|
myScore = data.point;
|
||||||
|
// }
|
||||||
|
vX = 0;
|
||||||
|
vY = 0;
|
||||||
|
ballX = canvas.width / 2;
|
||||||
|
ballY = canvas.height / 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
// Socket EMIT
|
||||||
|
//========================================================================================================
|
||||||
|
//========================================================================================================
|
||||||
|
|
||||||
|
function matchmaking()
|
||||||
|
{
|
||||||
|
console.log(`id ion matcj= ${myId}`)
|
||||||
|
const info = {
|
||||||
|
id: myId,
|
||||||
|
option: option,
|
||||||
|
};
|
||||||
|
socket.emit('pong:matchmaking', info);
|
||||||
|
}
|
||||||
|
|
||||||
|
function privateParty()
|
||||||
|
{
|
||||||
|
console.log(`id private party= ${myId}`)
|
||||||
|
const info = {
|
||||||
|
id: myId,
|
||||||
|
option: option,
|
||||||
|
};
|
||||||
|
socket.emit('pong:privateParty', info);
|
||||||
|
}
|
||||||
|
|
||||||
|
function joinPrivateParty()
|
||||||
|
{
|
||||||
|
console.log(`id private party= ${myId}`)
|
||||||
|
const info = {
|
||||||
|
id: myId,
|
||||||
|
gameId: gameParam.gameId,
|
||||||
|
option: option,
|
||||||
|
};
|
||||||
|
socket.emit('pong:joinParty', info);
|
||||||
|
}
|
||||||
|
|
||||||
function send_info()
|
function send_info()
|
||||||
{
|
{
|
||||||
if (gameId === 0)
|
if (!gameId || !canvas)
|
||||||
return ;
|
return ;
|
||||||
const info = {
|
const info = {
|
||||||
id: myId,
|
id: myId,
|
||||||
@ -234,7 +314,7 @@ function DrawCanvas(option) {
|
|||||||
|
|
||||||
function send_point()
|
function send_point()
|
||||||
{
|
{
|
||||||
if (gameId === 0)
|
if (!gameId || !canvas)
|
||||||
return ;
|
return ;
|
||||||
console.log("send point");
|
console.log("send point");
|
||||||
const info = {
|
const info = {
|
||||||
@ -245,23 +325,9 @@ function DrawCanvas(option) {
|
|||||||
socket.emit('pong:point', info);
|
socket.emit('pong:point', info);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on('pong:point', (data) => {
|
|
||||||
// hisScore += 1;
|
|
||||||
console.log("gain point");
|
|
||||||
// if (vX != 0)
|
|
||||||
// {
|
|
||||||
// console.log("up point");
|
|
||||||
myScore = data.point;
|
|
||||||
// }
|
|
||||||
vX = 0;
|
|
||||||
vY = 0;
|
|
||||||
ballX = canvas.width / 2;
|
|
||||||
ballY = canvas.height / 2;
|
|
||||||
});
|
|
||||||
|
|
||||||
function send_paddle_info()
|
function send_paddle_info()
|
||||||
{
|
{
|
||||||
if (gameId === 0)
|
if (!gameId || !canvas)
|
||||||
return ;
|
return ;
|
||||||
const info = {
|
const info = {
|
||||||
id: myId,
|
id: myId,
|
||||||
@ -275,6 +341,8 @@ function DrawCanvas(option) {
|
|||||||
|
|
||||||
function use_power()
|
function use_power()
|
||||||
{
|
{
|
||||||
|
if (!canvas)
|
||||||
|
return ;
|
||||||
const info = {
|
const info = {
|
||||||
gameId: gameId,
|
gameId: gameId,
|
||||||
width: canvas.width,
|
width: canvas.width,
|
||||||
@ -286,7 +354,7 @@ function DrawCanvas(option) {
|
|||||||
|
|
||||||
function send_forced_info()
|
function send_forced_info()
|
||||||
{
|
{
|
||||||
if (gameId === 0)
|
if (!gameId || !canvas)
|
||||||
return ;
|
return ;
|
||||||
const info = {
|
const info = {
|
||||||
gameId: gameId,
|
gameId: gameId,
|
||||||
@ -311,6 +379,8 @@ function DrawCanvas(option) {
|
|||||||
function drawcenter()
|
function drawcenter()
|
||||||
{
|
{
|
||||||
// ctx.restore();
|
// ctx.restore();
|
||||||
|
if (!ctx || !canvas)
|
||||||
|
return ;
|
||||||
ctx.fillStyle = 'white';
|
ctx.fillStyle = 'white';
|
||||||
ctx.fillRect(canvas.width / 2 - ctx.lineWidth / 2, 0, canvas.width / 300, canvas.height);
|
ctx.fillRect(canvas.width / 2 - ctx.lineWidth / 2, 0, canvas.width / 300, canvas.height);
|
||||||
|
|
||||||
@ -323,11 +393,13 @@ function DrawCanvas(option) {
|
|||||||
ctx.font = canvas.width * 0.1 + "px Arial";
|
ctx.font = canvas.width * 0.1 + "px Arial";
|
||||||
ctx.textAlign = "center";
|
ctx.textAlign = "center";
|
||||||
ctx.textBaseline = "middle";
|
ctx.textBaseline = "middle";
|
||||||
ctx.fillText(myScore, canvas.width/4, canvas.height/8);
|
ctx.fillText(myScore.toString(), canvas.width/4, canvas.height/8);
|
||||||
ctx.fillText(hisScore, canvas.width/1.25, canvas.height/8);
|
ctx.fillText(hisScore.toString(), canvas.width/1.25, canvas.height/8);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawPaddle() {
|
function drawPaddle() {
|
||||||
|
if (!ctx || !canvas)
|
||||||
|
return ;
|
||||||
ctx.fillStyle = 'white';
|
ctx.fillStyle = 'white';
|
||||||
ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
|
ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
|
||||||
ctx.fillRect(canvas.width - paddleX - paddleWidth, oPaddleY, paddleWidth, opPaddleHeight);
|
ctx.fillRect(canvas.width - paddleX - paddleWidth, oPaddleY, paddleWidth, opPaddleHeight);
|
||||||
@ -335,6 +407,8 @@ function DrawCanvas(option) {
|
|||||||
|
|
||||||
function drawball()
|
function drawball()
|
||||||
{
|
{
|
||||||
|
if (!ctx)
|
||||||
|
return ;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(ballX, ballY, ballRadius, 0, 2 * Math.PI);
|
ctx.arc(ballX, ballY, ballRadius, 0, 2 * Math.PI);
|
||||||
// ctx.lineWidth = 2;
|
// ctx.lineWidth = 2;
|
||||||
@ -349,29 +423,52 @@ function DrawCanvas(option) {
|
|||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
|
|
||||||
matchmaking();
|
|
||||||
// while (!gameId)
|
// while (!gameId)
|
||||||
// ;
|
// ;
|
||||||
|
|
||||||
// Define a function to stop the drawing process
|
// Define a function to stop the drawing process
|
||||||
const stopDrawCanvas = () => {
|
const stopDrawCanvas = async () => {
|
||||||
running = false;
|
running = false;
|
||||||
|
|
||||||
|
console.log("stopDrawCanvas 1")
|
||||||
|
|
||||||
|
if (gameParam.privateParty && !gameId) //delete invite
|
||||||
|
{
|
||||||
|
console.log("stopDrawCanvas2")
|
||||||
|
try{
|
||||||
|
// const info = {
|
||||||
|
// id: myId,
|
||||||
|
// option: option,
|
||||||
|
// };
|
||||||
|
|
||||||
|
await api.post("deleteInvite", {username: gameParam.username})
|
||||||
|
}
|
||||||
|
catch (err){
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket.emit('pong:disconnect', {id: myId});
|
||||||
|
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
|
||||||
|
// window.location.reload();
|
||||||
// Perform any necessary cleanup tasks
|
// Perform any necessary cleanup tasks
|
||||||
// ...
|
// ...
|
||||||
};
|
};
|
||||||
|
|
||||||
function draw(timestamp)
|
async function draw(timestamp: number)
|
||||||
{
|
{
|
||||||
console.log("turning");
|
console.log("turning, running= ", running);
|
||||||
if (!running)
|
if (!running)
|
||||||
return ;
|
return ;
|
||||||
if (gameId === 0 )
|
if (!gameId || !canvas )
|
||||||
{
|
{
|
||||||
|
// console.log("nogameid score= ", myScore);
|
||||||
requestAnimationFrame(draw);
|
requestAnimationFrame(draw);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
if (myScore === maxScore || hisScore === maxScore)
|
if (myScore === maxScore || hisScore === maxScore)
|
||||||
{
|
{
|
||||||
|
console.log("maxScore!!!!")
|
||||||
const data = {
|
const data = {
|
||||||
myScore: myScore,
|
myScore: myScore,
|
||||||
opScore: hisScore,
|
opScore: hisScore,
|
||||||
@ -380,17 +477,23 @@ function draw(timestamp)
|
|||||||
};
|
};
|
||||||
if (myScore === maxScore)
|
if (myScore === maxScore)
|
||||||
{
|
{
|
||||||
api.post('/win', data);
|
await api.post('/win', data);
|
||||||
api.post('/status', {status: 1});
|
await api.post('/status', {status: 1});
|
||||||
console.log("send win");
|
//disconnect ?
|
||||||
|
socket.emit('pong:disconnect', {id: myId});
|
||||||
|
|
||||||
|
console.log("send all ?? win");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
api.post('/loss', data);
|
await api.post('/loss', data);
|
||||||
api.post('/status', {status: 1});
|
await api.post('/status', {status: 1});
|
||||||
|
socket.emit('pong:disconnect', {id: myId});
|
||||||
|
//disconnect ?
|
||||||
console.log("send loose");
|
console.log("send loose");
|
||||||
}
|
}
|
||||||
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
|
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
|
||||||
|
// window.location.reload();
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +502,9 @@ function draw(timestamp)
|
|||||||
ballX += vX * deltaTime * canvas.width;
|
ballX += vX * deltaTime * canvas.width;
|
||||||
ballY += vY * deltaTime * canvas.height;
|
ballY += vY * deltaTime * canvas.height;
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
return ;
|
||||||
|
// requestAnimationFrame(draw);
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
drawPaddle();
|
drawPaddle();
|
||||||
drawcenter();
|
drawcenter();
|
||||||
@ -435,14 +541,17 @@ function draw(timestamp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function updatePaddlePosition(newY)
|
function updatePaddlePosition(newY: number)
|
||||||
{
|
{
|
||||||
if (newY >= 0 && newY <= canvas.height - paddleHeight)
|
|
||||||
|
if (canvas && newY >= 0 && newY <= canvas.height - paddleHeight)
|
||||||
paddleY = newY;
|
paddleY = newY;
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_collision()
|
function is_collision()
|
||||||
{
|
{
|
||||||
|
if (!canvas)
|
||||||
|
return ;
|
||||||
if (ballX <= paddleX + paddleWidth + ballRadius)
|
if (ballX <= paddleX + paddleWidth + ballRadius)
|
||||||
{
|
{
|
||||||
if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)//touch paddle
|
if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)//touch paddle
|
||||||
@ -467,15 +576,12 @@ function draw(timestamp)
|
|||||||
ballY = ballRadius + 2
|
ballY = ballRadius + 2
|
||||||
// send_info();
|
// send_info();
|
||||||
}
|
}
|
||||||
// else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
|
|
||||||
// {
|
|
||||||
// vX = -vX;
|
|
||||||
// // send_info();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_out()
|
function is_out()
|
||||||
{
|
{
|
||||||
|
if (!canvas)
|
||||||
|
return ;
|
||||||
if (ballX < 0)
|
if (ballX < 0)
|
||||||
{
|
{
|
||||||
if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
|
if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
|
||||||
@ -495,7 +601,9 @@ function draw(timestamp)
|
|||||||
}
|
}
|
||||||
if (ballX > canvas.width)
|
if (ballX > canvas.width)
|
||||||
{
|
{
|
||||||
console.log("win point")
|
// if (ballX > canvas.width * 2)
|
||||||
|
// socket.emit
|
||||||
|
// console.log("win point")
|
||||||
// if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
|
// if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
|
||||||
// {
|
// {
|
||||||
// console.log('true hehe');
|
// console.log('true hehe');
|
||||||
@ -518,17 +626,10 @@ function draw(timestamp)
|
|||||||
|
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
// Listener
|
// Key/Mouse/Finger Listener
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
//========================================================================================================
|
//========================================================================================================
|
||||||
|
|
||||||
document.addEventListener('resize', event => {
|
|
||||||
// event.height
|
|
||||||
// event.width
|
|
||||||
const { clientWidth, clientHeight } = canvas.parentElement;
|
|
||||||
console.log(`resize detected widht= ${clientWidth} height= ${clientHeight}`)
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', event => {
|
document.addEventListener('mousemove', event => {
|
||||||
const mouseY = event.clientY;
|
const mouseY = event.clientY;
|
||||||
|
|
||||||
|
|||||||
@ -68,8 +68,8 @@ function SuccessToken() {
|
|||||||
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
|
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
|
||||||
|
|
||||||
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
||||||
// window.history.pushState({}, null, path);
|
// window.history.pushState({}, '', path);
|
||||||
// window.location.reload(false);
|
// window.location.reload();
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -197,8 +197,8 @@ function SuccessToken() {
|
|||||||
// // history.push('/login')
|
// // history.push('/login')
|
||||||
|
|
||||||
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
|
||||||
// window.history.pushState({}, null, path);
|
// window.history.pushState({}, '', path);
|
||||||
// window.location.reload(false);
|
// window.location.reload();
|
||||||
|
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
input.qr{
|
input.qr{
|
||||||
width: 20%;
|
width: 20%;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: rgb(66, 66, 66);
|
background-color: rgb(0, 0, 0);
|
||||||
margin : 1%;
|
margin : 1%;
|
||||||
color:white;
|
color:white;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,6 +89,17 @@ span {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
height: 2%;
|
||||||
|
width: 2%;
|
||||||
|
/* border: solid; */
|
||||||
|
margin-top: 1%;
|
||||||
|
margin: 3vh;
|
||||||
|
/* margin-bottom: -12vh; */
|
||||||
|
/* border-color: black; */
|
||||||
|
/* border-radius: 50%; */
|
||||||
|
}
|
||||||
|
|
||||||
.header-pic{
|
.header-pic{
|
||||||
text-align: end;
|
text-align: end;
|
||||||
/* id: right; */
|
/* id: right; */
|
||||||
|
|||||||
@ -32,6 +32,7 @@ select{
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
overflow-x: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll{
|
.scroll{
|
||||||
@ -50,7 +51,8 @@ select{
|
|||||||
.contact{
|
.contact{
|
||||||
background-color: rgb(46, 46, 46);
|
background-color: rgb(46, 46, 46);
|
||||||
align-items: left;
|
align-items: left;
|
||||||
height: 30.2rem;
|
height: 74vh;
|
||||||
|
width: 30%;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
/* width: 2rem; */
|
/* width: 2rem; */
|
||||||
/* height: 4rem; */
|
/* height: 4rem; */
|
||||||
@ -92,6 +94,8 @@ select{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navbar{
|
.navbar{
|
||||||
|
/* width: clamp(50%, 500px, 20%); */
|
||||||
|
/* height: min(50%, 100px); */
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
/* background-color: yellow; */
|
/* background-color: yellow; */
|
||||||
@ -130,6 +134,7 @@ select{
|
|||||||
background-color: rgb(26, 26, 26);
|
background-color: rgb(26, 26, 26);
|
||||||
/* height: calc(100% - 118px); */
|
/* height: calc(100% - 118px); */
|
||||||
width: 70%;
|
width: 70%;
|
||||||
|
/* height: 300px; */
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,11 +174,17 @@ input{
|
|||||||
|
|
||||||
.messageContent{
|
.messageContent{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: 80%;
|
max-width: 80%;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
.meMessage{
|
.meMessage{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
@ -193,6 +204,18 @@ input{
|
|||||||
margin: 1%;
|
margin: 1%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.darkSubmit{
|
||||||
|
display: inline-block;
|
||||||
|
color: white;
|
||||||
|
background-color: #282155;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight:lighter;
|
||||||
|
margin: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
.div_submit {
|
.div_submit {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -265,6 +288,12 @@ input{
|
|||||||
background-color: rgba(212, 175, 55, 0.7);
|
background-color: rgba(212, 175, 55, 0.7);
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
color: rgba(255, 255, 255, 1);
|
color: rgba(255, 255, 255, 1);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellowAlert::p {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
max-width: 1000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modalSetting{
|
.modalSetting{
|
||||||
@ -287,7 +316,7 @@ input{
|
|||||||
|
|
||||||
.settingSecondPart{
|
.settingSecondPart{
|
||||||
margin-top: 10%;
|
margin-top: 10%;
|
||||||
margin-left: 10%;
|
margin-left: 5%;
|
||||||
|
|
||||||
/* margin-left: 20%; */
|
/* margin-left: 20%; */
|
||||||
}
|
}
|
||||||
@ -305,3 +334,20 @@ input.in{
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.in_howLong{
|
||||||
|
margin-top: 14.5%;
|
||||||
|
margin-left: 0px;
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdp{
|
||||||
|
background-color : black;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: white;
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,75 @@
|
|||||||
|
/* Container style */
|
||||||
|
.file-upload-container {
|
||||||
|
|
||||||
|
margin-left: 2rem;
|
||||||
|
font-size: 1.7rem;
|
||||||
|
/* background: #5843e4; */
|
||||||
|
/* color:#f5f5f5; */
|
||||||
|
margin: 0 16px;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* File input style */
|
||||||
|
.file-input {
|
||||||
|
/* background: #5843e4; */
|
||||||
|
/* color:#f5f5f5; */
|
||||||
|
display: none; /* Hide the default file input */
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-label {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
color: #555;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-label:hover {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button style */
|
||||||
|
.upload-button {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background-color: #5843e4;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
overflow-y: scroll;
|
||||||
/* height: 50vh; */
|
/* height: 50vh; */
|
||||||
/* width: 50vh; */
|
/* width: 50vh; */
|
||||||
/* background-color: black; */
|
/* background-color: black; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile {
|
.profile {
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
@ -18,7 +82,7 @@
|
|||||||
border-color: red;
|
border-color: red;
|
||||||
/* border-image: linear-gradient(90deg, #5843e4, #5a0760); */
|
/* border-image: linear-gradient(90deg, #5843e4, #5a0760); */
|
||||||
|
|
||||||
margin-top: 20px;
|
/* margin-top: 20px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.home{
|
.home{
|
||||||
@ -45,7 +109,7 @@
|
|||||||
.div_history {
|
.div_history {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: -80px;
|
/* margin-top: -80px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit_name {
|
.edit_name {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
/* display: flex; */
|
/* display: flex; */
|
||||||
/* flex-direction: column; */
|
/* flex-direction: column; */
|
||||||
/* background-color: red; */
|
/* background-color: red; */
|
||||||
height: 70vh;
|
height: 60vh;
|
||||||
/* padding: 15px; */
|
/* padding: 15px; */
|
||||||
/* overflow: scroll; */
|
/* overflow: scroll; */
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,21 @@
|
|||||||
.playButton {
|
.playButton {
|
||||||
background-image: linear-gradient(90deg, #5843e4, #5a0760);;
|
background-image: linear-gradient(90deg, #5843e4, #5a0760);
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
overflow: hidden;
|
||||||
border-radius: 5vh;
|
border-radius: 5vh;
|
||||||
color: white;
|
color: white;
|
||||||
display: block;
|
/* display: block; */
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 30vh;
|
margin-top: 30vh;
|
||||||
padding: 2vh 5vw;
|
padding: 2vh 4vw;
|
||||||
height: 10vh;
|
height: 10vh;
|
||||||
width: 20vw;
|
width: 20vw;
|
||||||
font-size: 300%;
|
font-size: 250%;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
background-color: rgb(249, 249, 249);
|
background-color: rgb(249, 249, 249);
|
||||||
/* border-radius: 5vh; */
|
/* border-radius: 5vh; */
|
||||||
@ -40,6 +45,29 @@
|
|||||||
/* padding-top: 25; */
|
/* padding-top: 25; */
|
||||||
/* padding-top: 177.77% */
|
/* padding-top: 177.77% */
|
||||||
}
|
}
|
||||||
|
@media screen and (max-width: 900px){
|
||||||
|
.playButton{
|
||||||
|
font-size: 200%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 700px){
|
||||||
|
.playButton{
|
||||||
|
font-size: 150%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 530px){
|
||||||
|
.playButton{
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 350px){
|
||||||
|
.playButton{
|
||||||
|
font-size: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#myCanvas {
|
#myCanvas {
|
||||||
background-color: rgb(124, 47, 47);
|
background-color: rgb(124, 47, 47);
|
||||||
|
|||||||
@ -77,11 +77,6 @@ input{
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
label{
|
|
||||||
}
|
|
||||||
|
|
||||||
.login {
|
|
||||||
}
|
|
||||||
|
|
||||||
.loginForm {
|
.loginForm {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
111
containers/react/tsconfig.json
Normal file
111
containers/react/tsconfig.json
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||||
|
"jsx": "react",
|
||||||
|
"noEmit": true,
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
/* Projects */
|
||||||
|
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||||
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||||
|
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||||
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||||
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||||
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||||
|
|
||||||
|
/* Language and Environment */
|
||||||
|
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||||
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||||
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||||
|
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||||
|
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||||
|
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||||
|
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||||
|
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||||
|
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||||
|
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||||
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||||
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||||
|
|
||||||
|
/* Modules */
|
||||||
|
"module": "commonjs", /* Specify what module code is generated. */
|
||||||
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||||
|
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||||
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
|
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||||
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||||
|
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||||
|
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||||
|
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||||
|
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||||
|
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||||
|
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||||
|
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||||
|
|
||||||
|
/* JavaScript Support */
|
||||||
|
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||||
|
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||||
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||||
|
|
||||||
|
/* Emit */
|
||||||
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||||
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||||
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||||
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||||
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||||
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||||
|
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||||
|
// "removeComments": true, /* Disable emitting comments. */
|
||||||
|
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||||
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||||
|
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||||
|
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||||
|
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||||
|
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||||
|
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||||
|
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||||
|
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||||
|
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||||
|
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||||
|
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||||
|
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||||
|
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||||
|
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||||
|
|
||||||
|
/* Interop Constraints */
|
||||||
|
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||||
|
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||||
|
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||||
|
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||||
|
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||||
|
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||||
|
|
||||||
|
/* Type Checking */
|
||||||
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
|
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||||
|
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||||
|
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||||
|
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||||
|
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||||
|
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||||
|
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||||
|
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||||
|
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||||
|
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||||
|
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||||
|
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||||
|
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||||
|
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||||
|
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||||
|
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||||
|
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||||
|
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||||
|
|
||||||
|
/* Completeness */
|
||||||
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||||
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,2 +0,0 @@
|
|||||||
cc toi
|
|
||||||
cc 2
|
|
||||||
@ -11,7 +11,7 @@ services:
|
|||||||
|
|
||||||
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
|
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
|
||||||
ports:
|
ports:
|
||||||
- 80:80
|
- 8080:8080
|
||||||
volumes:
|
volumes:
|
||||||
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
# volumes:
|
# volumes:
|
||||||
@ -34,7 +34,7 @@ services:
|
|||||||
# depends_on:
|
# depends_on:
|
||||||
# - nginx
|
# - nginx
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8001:8001
|
||||||
volumes:
|
volumes:
|
||||||
- ./containers/react:/app
|
- ./containers/react:/app
|
||||||
# - ./containers/react:/app
|
# - ./containers/react:/app
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user