Skip to content

feat(chat): improve group chat typing indicator with a full member dictionary #43

Description

@nicgen

[ISSUE / FEATURE] Group Chat Improvement: Full member dictionary for typing indicator resolution

Contexte et Problématique

Dans le cadre des fonctionnalités de chat temps réel (Phase 010+), l'événement WebSocket chat.typing est diffusé aux participants d'une même conversation sous la forme :

{
  "type": "chat.typing",
  "data": {
    "conversation_id": "conv-xxx",
    "account_id": "acc-sender-xxx"
  }
}
  • Comportement actuel :

    • Le client est capable de résoudre le pseudo de l'interlocuteur principal (peer_name) ou de l'association (group_name) car ces données sont directement rattachées à l'objet Conversation retourné par GET /api/v1/conversations.
    • Cependant, pour les conversations de groupe (ex. une conversation d'association comptant jusqu'à 20 membres), si un autre participant (qui n'est ni le correspondant principal peer_id, ni l'association elle-même) se met à écrire, le client ne dispose pas de son pseudo dans ses états locaux et dégrade l'affichage sous la forme "Utilisateur XXXX écrit...".
  • Objectif :
    Permettre l'affichage du vrai pseudo pour absolument tous les membres d'une conversation de groupe en cours de saisie, sans provoquer de requêtes HTTP supplémentaires répétées.


Solutions techniques proposées

Option A : Enrichir le payload WebSocket temps réel (Recommandée)

C'est la solution la plus directe et légère, évitant de stocker des états superflus côté client.

  1. Backend (backend/internal/adapters/ws/hub.go & client.go) :
    • Lors du traitement de la trame chat.typing montante, récupérer le pseudo/nom d'affichage de l'émetteur depuis la base de données ou le contexte de connexion.
    • Diffuser la trame descendante enrichie avec le champ display_name (ou nickname) :
      {
        "type": "chat.typing",
        "data": {
          "conversation_id": "conv-xxx",
          "account_id": "acc-sender-xxx",
          "display_name": "Alice Cooper"
        }
      }
  2. Frontend (frontend/components/chat/TypingIndicator.tsx & useWebSocket.ts) :
    • Mettre à jour le store de présence pour conserver le couple (account_id, display_name).
    • Adapter TypingIndicator pour utiliser directement display_name s'il est fourni dans l'événement de saisie.

Option B : Ajouter un dictionnaire des membres à l'API Conversation

Permet d'avoir un référentiel statique complet des participants de la conversation.

  1. Backend Go :
    • Mettre à jour le contrat de réponse de l'endpoint GET /api/v1/conversations (et sa variante unitaire) pour inclure un dictionnaire complet des membres de la conversation :
      {
        "id": "conv-xxx",
        "kind": "association",
        "participants_registry": {
          "acc-alice-id": "Alice Cooper",
          "acc-bob-id": "Bob Marley"
        }
      }
  2. Frontend React :
    • Stocker ce registre dans le store Zustand useChatStore.
    • Dans TypingIndicator, résoudre le nom en faisant simplement conversation.participants_registry[id].

Tâches à réaliser

1. Backend (Go)

  • Modifier la structure de diffusion TypingFrame ou enrichir la réponse GET /api/v1/conversations.
  • Mettre à jour les tests unitaires et d'intégration correspondants (backend/internal/adapters/ws/integration_test.go).

2. Frontend (React/TS)

  • Mettre à jour les types TypeScript dans frontend/lib/types.ts.
  • Adapter le gestionnaire d'événement WebSocket dans useWebSocket.ts.
  • Mettre à jour TypingIndicator.tsx pour exploiter la nouvelle structure de données.
  • Compléter les tests unitaires dans TypingIndicator.test.tsx pour valider les nouveaux scénarios.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions