Page de Rejoindre
La page de Rejoindre (JoinPage) affiche la liste des parties publiques disponibles et permet aux utilisateurs de rejoindre une partie existante via un code ou depuis la liste.
JoinPage
Type : ConsumerStatefulWidget
State : _JoinPageState extends ConsumerState(JoinPage)
Propriétés
| Propriété | Type | Description |
|---|---|---|
isJoinCodePopupActive |
bool |
Contrôle l'affichage du popup de saisie de code |
focusNodes |
List(FocusNode) | Liste des focus nodes pour les 4 champs de code |
textControllers |
List(TextEditingController) | Contrôleurs pour les 4 champs de code |
_refreshTimer |
Timer? |
Timer pour le rafraîchissement automatique des parties (toutes les 10s) |
_imageCache |
Map(String, Uint8List) | Cache pour les images de grille |
Méthodes
initState()
Description : Initialise la page, configure les écouteurs et lance le rafraîchissement automatique.
Actions :
- Crée 4 FocusNodes et TextEditingControllers pour le code
- Configure les écouteurs Socket.IO (drop-in, game list)
- Charge la liste des parties disponibles
- Lance le timer de rafraîchissement (10 secondes)
- Charge la liste des amis
Retour : void
dispose()
Description : Libère les ressources (timer, focus nodes, controllers).
Retour : void
_loadFriends()
Description : Charge la liste des amis de l'utilisateur.
Retour : Future
bool _isFriendWithHost(String adminName)
Description : Vérifie si l'utilisateur est ami avec l'hôte de la partie.
Paramètres :
adminName: Nom de l'hôte
Retour : bool
bool _canJoinGame(AvailableGameModel game, List friendsList)
Description : Vérifie si l'utilisateur peut rejoindre une partie.
Validation :
- Si visibilité "friends", vérifie l'amitié avec l'hôte
- Vérifie si la partie est pleine
- Vérifie si la partie est verrouillée
Retour : bool
void _setupGameListListener()
Description : Configure l'écouteur pour les mises à jour de la liste de parties.
Comportement : Met à jour le jeu sélectionné si des changements sont détectés
Retour : void
void _setupDropInListener()
Description : Configure l'écouteur pour le drop-in (rejoindre une partie en cours).
Event : onDropInGameData
Action : Navigue directement vers GameViewPage avec les données de la partie
Retour : void
void _onCodeInputChange(String value, int index)
Description : Gère la saisie d'un chiffre du code.
Comportement : Déplace le focus au champ suivant après saisie
Retour : void
void _onCodeBackspace(int index)
Description : Gère le backspace sur un champ vide.
Comportement : Retourne au champ précédent
Retour : void
void _showJoinCodePopup()
Description : Affiche le popup de saisie de code.
Retour : void
void _closeJoinCodePopup()
Description : Ferme le popup et réinitialise les champs.
Retour : void
_onJoinWithCode()
Description : Rejoint une partie via le code saisi.
Flux :
- Valide que le code a 4 chiffres
- Appelle
joinGameNotifier.joinGameByCode(code) - Si succès, navigue vers
CharacterCreationPage - Si échec, affiche message d'erreur
Retour : Future
_onJoinGame(AvailableGameModel game)
Description : Rejoint une partie depuis la liste.
Flux :
- Sélectionne la partie
- Appelle
joinGameNotifier.joinGame(gameCode) - Si succès, navigue vers
CharacterCreationPage - Si échec, affiche message d'erreur
Retour : Future
void _showErrorPopup(String message)
Description : Affiche un popup d'erreur.
Retour : void
void _goBack()
Description : Retourne à la page d'accueil.
Retour : void
Widget _buildGameCard(AvailableGameModel game)
Description : Construit une carte de partie disponible.
Contenu :
- Aperçu de la grille
- Nom du jeu
- Hôte (admin)
- Joueurs actifs / max
- Statut (en attente, en cours)
- Visibilité (public, amis)
- Drop-in/out activé
- Droit d'entrée
- Bouton "REJOINDRE"
Retour : Widget
Widget _buildCodePopup()
Description : Construit le popup de saisie de code à 4 chiffres.
Retour : Widget
Éléments visuels
En-tête
- Bouton Retour : "←" vers HomePage
- Titre : "REJOINDRE UNE PARTIE" centré
- Bouton "Code" : Ouvre le popup de saisie de code (coin supérieur droit)
Liste des parties
- Grille scrollable : 2 colonnes de cartes de parties
- Filtrage automatique : Affiche seulement les parties rejoignables
Carte de partie
- Badge statut : "EN ATTENTE" ou "EN COURS"
- Aperçu de la grille : Miniature de la grille du jeu
- Nom du jeu : En grand
- Informations :
- Hôte :
username - Joueurs :
X / Max - Visibilité : Icône (public/amis)
- Drop-in/out : Icône si activé
- Droit d'entrée : Montant en coins (si > 0)
- Hôte :
- Bouton REJOINDRE :
- Actif si partie rejoignable
- Désactivé si pleine, verrouillée ou amis uniquement (sans être ami)
- Indicateur verrouillé : Cadenas si partie verrouillée
Popup de code
- Titre : "ENTREZ LE CODE À 4 CHIFFRES"
- 4 champs de saisie : 1 chiffre chacun
- Validation : Accepte uniquement les chiffres
- Navigation automatique : Passe au champ suivant après saisie
- Boutons :
- ANNULER : Ferme le popup
- REJOINDRE : Valide et rejoint la partie
Overlays
- UserProfileWidget : Profil utilisateur
- ChatboxWidget : Chat
- HelpButtonWidget : Aide
- HelpPopupWidget : Aide contextuelle
Cas particuliers
- Aucune partie : Message "Aucune partie disponible"
- Chargement : Indicateur de chargement
Composants utilisés
CodeInputFormatter
TextInputFormatter personnalisé pour gérer le backspace sur champ vide.
Propriétés
| Propriété | Type | Description |
|---|---|---|
index |
int |
Index du champ |
onBackspaceOnEmpty |
Function(int) |
Callback appelé quand backspace sur champ vide |
OneButtonPopup
Popup avec un seul bouton (erreurs).
UserProfileWidget
Widget de profil utilisateur.
ChatboxWidget
Widget de chat.
HelpButtonWidget
Bouton d'aide.
HelpPopupWidget
Popup d'aide.
Providers utilisés
joinGameNotifierProvider
Type : StateNotifierProvider(JoinGameNotifier, JoinGameState)
Provider gérant la logique de rejoindre une partie.
JoinGameState
| Propriété | Type | Description |
|---|---|---|
availableGames |
List(AvailableGameModel) | Liste des parties disponibles |
selectedGame |
AvailableGameModel? |
Partie sélectionnée |
isLoading |
bool |
Si le chargement est en cours |
errorMessage |
String? |
Message d'erreur |
JoinGameNotifier - Méthodes
loadAvailableGames()
Description : Charge la liste des parties disponibles.
Retour : Future
Future joinGame(String gameCode)
Description : Rejoint une partie par son code.
Retour : Future(Map(String, dynamic)?) (contient gameCode, status, etc.)
Future joinGameByCode(String code)
Description : Rejoint une partie via un code à 4 chiffres.
Retour : Future(Map(String, dynamic)?)
void selectGame(AvailableGameModel? game)
Description : Sélectionne une partie.
Retour : void
waitingRoomNotifierProvider
Type : StateNotifierProvider(WaitingRoomNotifier, WaitingRoomState)
Provider gérant la salle d'attente (utilisé pour le drop-in).
WaitingRoomNotifier - Méthodes
void setCurrentGame(OnGoingGameModel game)
Description : Définit la partie actuelle.
Retour : void
void setCurrentPlayer(PlayerModel player)
Description : Définit le joueur actuel.
Retour : void
waitingRoomSocketDataSourceProvider
Type : Provider(WaitingRoomSocketDataSource)
Provider fournissant la source de données Socket.IO de la salle d'attente.
WaitingRoomSocketDataSource - Méthodes
onDropInGameData()
Description : Stream émettant les données de partie pour le drop-in.
Retour : Stream(OnGoingGameModel)
friendsNotifierProvider
Type : StateNotifierProvider(FriendsNotifier, FriendsState)
Provider gérant la liste des amis.
FriendsState
| Propriété | Type | Description |
|---|---|---|
friends |
List(FriendUserEntity) | Liste des amis |
userProfileProvider
Type : Provider(UserProfileEntity?)
Provider du profil utilisateur.
translationProvider
Type : Provider(TranslationWrapper)
Provider de traduction.
themeNotifierProvider
Type : StateNotifierProvider(ThemeNotifier, ThemeState)
Provider de thème.
helpPopupProvider
Type : StateNotifierProvider(HelpPopupNotifier, HelpPopupState)
Provider d'aide.
Écouteurs Socket.IO
Events écoutés
dropInGameData
Description : Reçu quand un joueur rejoint une partie en cours (drop-in).
Payload : OnGoingGameModel
Action : Navigation directe vers GameViewPage avec les données de la partie
gameListUpdated (implicite)
Description : Déclenché quand la liste des parties change.
Action : Recharge automatiquement la liste
Navigation
- Retour :
AppRoutes.home.path→HomePage - Rejoindre réussie :
AppRoutes.characterCreation.path→CharacterCreationPage- Paramètres :
mode: "join"gameCode: Code de la partiegameStatus: Statut ("waiting" ou "started")dropInOut: Si drop-in/drop-out activéisLocked: Si partie verrouillée
- Paramètres :
- Drop-in :
AppRoutes.gameView.path→GameViewPage- Paramètres :
gameCode: Code de la partieplayerName: Nom du joueurgameData: Données complètes de la partiesessionId: ID de session généré
- Paramètres :
Rafraîchissement automatique
Timer : 10 secondes
Action : Recharge la liste des parties disponibles
Comportement : Continue même si l'utilisateur est dans la page
Filtrage des parties
Critères pour afficher une partie
-
Visibilité :
- Public : Toujours affiché
- Amis : Affiché seulement si ami avec l'hôte
-
État :
- En attente : Toujours rejoignable (si pas pleine/verrouillée)
- En cours : Rejoignable seulement si drop-in/drop-out activé
-
Capacité :
- Pas pleine : Rejoignable
- Pleine : Non rejoignable
-
Verrouillage :
- Non verrouillée : Rejoignable
- Verrouillée : Non rejoignable
Modèle de données
AvailableGameModel
| Propriété | Type | Description |
|---|---|---|
code |
String |
Code de la partie (4 chiffres) |
gameName |
String |
Nom du jeu |
adminName |
String |
Nom de l'hôte |
visibility |
String |
"public" ou "friends" |
dropInOut |
bool |
Si drop-in/drop-out activé |
entryFee |
int |
Droit d'entrée |
activePlayers |
int |
Nombre de joueurs actifs |
maxPlayers |
int |
Nombre maximum de joueurs |
status |
String |
"waiting" ou "started" |
isLocked |
bool |
Si la partie est verrouillée |
isFull |
bool |
Si la partie est pleine |
gridImage |
String? |
Image de la grille en base64 |
Gestion du cache d'images
Le cache _imageCache stocke les images de grille décodées pour éviter de décoder la même image plusieurs fois, améliorant ainsi les performances lors du scroll de la liste.