5. Page de Rejoindre (JoinPageComponent)

Vue d'ensemble

La page de rejoindre permet aux utilisateurs de découvrir et rejoindre des parties en cours ou en attente créées par d'autres joueurs. Elle offre une vue publique des parties disponibles avec toutes leurs informations, ainsi qu'un système de saisie de code pour rejoindre des parties privées ou verrouillées.

Localisation

Fichier: client/src/app/pages/join-page/join-page.component.ts

Route: /join

Fonctionnalités Principales

Liste des Parties Disponibles

Affiche en temps réel toutes les parties publiques ou accessibles par l'utilisateur.

Informations affichées par partie:

Filtrage des Parties

Critères de visibilité:

Parties affichées:

Parties masquées:

Rejoindre une Partie depuis la Liste

Conditions pour rejoindre:

Processus de join:

  1. Utilisateur clique sur une partie dans la liste
  2. Partie sélectionnée est mise en surbrillance
  3. Utilisateur clique sur "Rejoindre"
  4. Validation du code d'accès automatique
  5. Vérification des conditions (frais, accessibilité)
  6. Si partie en attente : redirection vers création de personnage
  7. Si partie en cours (drop-in) : rejoindre directement la partie

Rejoindre via Code d'Accès

Alternative pour rejoindre des parties non publiques ou verrouillées.

Processus:

  1. Utilisateur clique sur "Entrer un code"
  2. Popup de saisie de code s'affiche
  3. Saisie d'un code à 4 chiffres
  4. Validation du code côté serveur
  5. Vérification si l'utilisateur était déjà dans cette partie (returning player)
  6. Si valid et nouvelle partie : redirection vers création de personnage
  7. Si returning player : rejoint directement la partie en cours

Validation du code:

Rafraîchissement Automatique

Mécanisme:

Événements Socket.IO écoutés:

Drop-In (Rejoindre Partie en Cours)

Fonctionnalité permettant de rejoindre une partie déjà commencée.

Conditions:

Processus spécifique drop-in:

  1. Validation du code/sélection de la partie
  2. Serveur vérifie les conditions de drop-in
  3. Serveur envoie les données complètes de la partie via DropInGame
  4. Client reçoit l'état complet du jeu
  5. Joueur est placé à une position libre sur la carte
  6. Redirection directe vers la vue de jeu (pas de création de personnage)
  7. Le joueur rejoint avec un personnage par défaut généré

Événement Socket.IO:

this.socketService.listen<OnGoingGame>('DropInGame').subscribe((game) => {
  this.waitingRoomService.setCurrentGame(game);
  this.router.navigate(['/game-view']);
});

Services Utilisés

SocketService

Méthodes:

JoinCharacterCreationService

Méthodes:

Validation:

WaitingRoomService

Méthodes utilisées pour drop-in:

UserService

Méthodes:

Interfaces

AvailableGameInfo

Structure des informations d'une partie disponible:

interface AvailableGameInfo {
  code: string;              // Code à 4 chiffres
  name: string;              // Nom de la partie/jeu
  adminName: string;         // Nom du créateur
  players: number;           // Nombre de joueurs actuels
  maxPlayers: number;        // Maximum de joueurs
  mapSize: number;           // Taille de la carte
  previewImage: string;      // URL de l'aperçu (base64 ou URL)
  status: 'waiting' | 'in-progress';  // Statut
  isLocked: boolean;         // Partie verrouillée
  isFull: boolean;           // Partie pleine
  accessibility: string;     // 'open', 'locked', 'full', 'friends-only'
  entryFee: number;          // Frais d'entrée (0 si gratuit)
  visibility: 'public' | 'friends';  // Visibilité
  dropInOut: boolean;        // Drop-in/drop-out activé
}

État du Composant

Variables principales:

availableGames: AvailableGameInfo[]  // Liste des parties
selectedGame: AvailableGameInfo | null  // Partie sélectionnée
isJoinCodePopupActive: boolean       // Popup de code active
isCodeValid: boolean                 // Validation du code
codeErrorMsg: string                 // Message d'erreur code
codeInputs: number[]                 // Array pour inputs (0-3)
accessCode: string[]                 // Code saisi (4 chiffres)
subscriptions: Subscription[]        // Souscriptions Socket.IO

Méthodes Principales

ngOnInit()

Initialise la page et configure les listeners Socket.IO.

Actions:

  1. Souscription aux événements Socket.IO
  2. Chargement initial de la liste des parties
  3. Configuration du rafraîchissement automatique (10s)
  4. Initialisation du code d'accès

ngOnDestroy()

Nettoie les souscriptions pour éviter les fuites mémoire.

loadAvailableGames()

Demande la liste actualisée des parties disponibles.

Flux:

this.socketService.emit(SocketIOEvents.GetAvailableGames);
// Serveur répond via SocketIOEvents.AvailableGamesUpdated

canJoinGame(game: AvailableGameInfo): boolean

Détermine si l'utilisateur peut rejoindre une partie.

Logique:

if (game.status === 'waiting') {
  return !game.isLocked && !game.isFull && 
         (game.visibility === 'public' || game.dropInOut);
} else {
  return !game.isFull && 
         (game.visibility === 'public' || game.dropInOut);
}

joinGame(game: AvailableGameInfo)

Rejoint une partie sélectionnée depuis la liste.

Flux:

  1. Vérification via canJoinGame()
  2. Définition du code d'accès dans JoinCharacterCreationService
  3. Validation du code via isCodeValid()
  4. Si returning player : gestion automatique
  5. Sinon : navigation vers création de personnage avec query params
    this.router.navigate(['/character-creation'], {
      queryParams: { mode: 'join', gameCode: game.code }
    });
    

showJoinCodePopup()

Affiche la popup de saisie de code manuel.

closeJoinCodePopup()

Ferme la popup et réinitialise le code.

onInputChange(event: Event, index: number)

Gère la saisie d'un chiffre dans un champ du code.

Comportement:

onBackspace(event: KeyboardEvent, index: number)

Gère la suppression avec la touche Backspace.

Comportement:

redirectToCharacterCreation()

Valide le code saisi et redirige vers la création de personnage.

Flux:

  1. Validation du code via JoinCharacterCreationService
  2. Si invalide : affichage du message d'erreur
  3. Si returning player : fermeture popup et rejoindre directement
  4. Si valide : navigation vers création de personnage

selectGame(game: AvailableGameInfo)

Sélectionne une partie dans la liste (met en surbrillance).

joinSelectedGame()

Rejoint la partie actuellement sélectionnée.

goBack()

Retour à la page d'accueil.

Traductions

Utilise le pipe TranslatePipe pour les libellés.

Clés de traduction:

Interface Utilisateur

Structure de la Page

Disposition:

+--------------------------------------+
|  [← Retour]         [Actualiser]     |
|                                      |
|  Parties Disponibles                 |
|                                      |
|  [Entrer un Code]                    |
|                                      |
|  +--------------------------------+  |
|  | [Aperçu]  Nom: ...             |  |
|  |           Admin: ...           |  |
|  |           Joueurs: 2/4         |  |
|  |           Carte: 10x10         |  |
|  |           Statut: En attente   |  |
|  |           Frais: 50 coins      |  |
|  |           [Rejoindre]          |  |
|  +--------------------------------+  |
|                                      |
|  +--------------------------------+  |
|  | ...                            |  |
|  +--------------------------------+  |
|                                      |
+--------------------------------------+

Carte de Partie

Chaque partie est affichée dans une carte contenant:

En-tête:

Corps:

Pied:

États visuels:

Structure:

+----------------------------+
|  Entrer le Code d'Accès    |
|                            |
|  [_] [_] [_] [_]          |
|                            |
|  [Message d'erreur]        |
|                            |
|  [Annuler]  [Valider]      |
+----------------------------+

Caractéristiques:

Style et Thème

Couleurs par statut:

Badges:

Animations:

Entrée sur la Page

Depuis:

Sortie de la Page

Vers:

Cas d'Usage Typiques

Cas 1: Rejoindre une Partie Publique en Attente

  1. Utilisateur accède à /join
  2. Liste des parties affichée automatiquement
  3. Utilisateur clique sur une partie "En attente"
  4. Carte mise en surbrillance
  5. Utilisateur clique sur "Rejoindre"
  6. Validation réussie
  7. Redirection vers /character-creation?mode=join&gameCode=1234

Cas 2: Drop-In dans une Partie en Cours

  1. Utilisateur voit une partie "En cours" avec badge "Drop-in/out"
  2. Clique sur la partie
  3. Clique sur "Rejoindre"
  4. Validation drop-in réussie
  5. Événement DropInGame reçu avec état complet
  6. Personnage par défaut créé automatiquement
  7. Redirection directe vers /game-view

Cas 3: Rejoindre via Code d'Accès

  1. Utilisateur clique sur "Entrer un Code"
  2. Popup affichée
  3. Saisit le code à 4 chiffres: "1234"
  4. Clique sur "Valider"
  5. Code validé côté serveur
  6. Redirection vers création de personnage

Cas 4: Code Invalide

  1. Utilisateur entre un code dans la popup
  2. Clique sur "Valider"
  3. Serveur retourne { valid: false, message: "Partie introuvable" }
  4. Message d'erreur affiché en rouge
  5. Code reste dans les champs pour correction

Cas 5: Returning Player

  1. Utilisateur avait quitté une partie (drop-out)
  2. Entre le code de cette partie
  3. Serveur détecte isReturningPlayer: true
  4. Événement DropInGame envoyé avec joueur existant
  5. Redirection directe vers /game-view
  6. Joueur reprend son personnage et sa position

Cas 6: Partie Pleine

  1. Utilisateur voit une partie avec "4/4 joueurs"
  2. Badge rouge "Pleine" affiché
  3. Bouton "Rejoindre" désactivé et grisé
  4. Impossible de sélectionner la partie

Cas 7: Frais d'Entrée Insuffisants

  1. Partie avec frais de 100 coins
  2. Utilisateur a seulement 50 coins
  3. Tentative de rejoindre
  4. Serveur rejette avec erreur "Monnaie virtuelle insuffisante"
  5. Message d'erreur affiché
  6. Retour à la liste

Écoutés

AvailableGamesUpdated

GameUpdated

GameLockUpdated

GameListUpdated

DropInGame

Émis

GetAvailableGames

Validation et Sécurité

Validation Côté Client

Validation Côté Serveur

Gestion des Erreurs

Erreurs possibles:

Performance

Optimisations

Gestion Mémoire

Points d'Attention

Drop-In/Drop-Out

Returning Players

Frais d'Entrée

Améliorations Futures