Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,17 @@ function Sala({
* blanco sin que nada diga que algo está pasando.
*/
const [cargandoFrame, setCargandoFrame] = useState(false);

/**
* Ya llegó el estado de la sala (el `joined`).
*
* Sin esto, entre que el socket conecta y el server responde, el chat vacío se
* ve IGUAL que una sala donde nadie ha hablado. Con internet lento eso son
* varios segundos, y en las sesiones con estudiantes fue lo más reportado:
* recargaban, veían todo en blanco y creían que habían perdido su trabajo.
* Nadie perdió nada, faltaba decirles que estaban esperando.
*/
const [unido, setUnido] = useState(false);
const [draft, setDraft] = useState("");
/**
* El nombre de la sala, o null si nadie la ha nombrado (ahí se ve el id).
Expand Down Expand Up @@ -459,6 +470,10 @@ function Sala({
const socket = connectSocket();
socketRef.current = socket;

// Se cayó la conexión. Socket.io reconecta solo, así que esto no arregla
// nada: solo evita que la sala se vea normal mientras ya no llega nada.
socket.on("disconnect", () => setUnido(false));

socket.on("connect", () => {
socket.emit("join", { roomId, name });
// La key ya configurada viaja sola: no se pide de nuevo en cada sala.
Expand All @@ -467,6 +482,7 @@ function Sala({
});

socket.on("joined", (p: JoinedPayload) => {
setUnido(true);
setMembers(p.members);
setNombre(p.nombre ?? null);
recordarNombre(roomId, p.nombre ?? null);
Expand Down Expand Up @@ -905,6 +921,12 @@ function Sala({
<div className={`sala ver-${tab} ${chatColapsado ? "chat-colapsado" : ""}`}>
{/* Chat izquierda */}
<aside className="chat">
{/* Con mensajes ya en pantalla, el chat se ve normal aunque no llegue
nada. Esta barra es lo único que distingue "nadie ha escrito" de
"se cayó el wifi". */}
{roomId && !unido && messages.length > 0 && (
<div className="chat-desconectado">{t.reconectando}</div>
)}
<div className="sala-cab">
<MenuSalas actual={roomId ?? undefined} />
<div className="sala-titulo">
Expand Down Expand Up @@ -997,6 +1019,15 @@ function Sala({
)}

<div className="chat-scroll">
{/* Solo mientras no sabemos qué hay: en cuanto llega el `joined`, un
chat vacío SÍ significa que nadie ha hablado. Y si ya hay mensajes
pintados (una reconexión), taparlos sería peor que el vacío. */}
{roomId && !unido && messages.length === 0 && (
<div className="chat-cargando">
<div className="preview-barra" aria-hidden="true" />
<p>{t.cargandoSala}</p>
</div>
)}
{mensajesVisibles.map((m, i) => (
// Mensajes seguidos del mismo autor se agrupan sin repetir avatar
// ni nombre (patrón Discord): el chat respira y se lee como
Expand Down Expand Up @@ -1362,6 +1393,13 @@ function Sala({
<p>{t.ningunaSala}</p>
<p className="preview-loading-sub">{t.eligeOCrea}</p>
</>
) : !unido ? (
// Hay sala, pero su estado todavía no llega. Decir aquí que está
// vacía sería inventar: no se sabe.
<>
<div className="preview-spinner" aria-hidden="true" />
<p>{t.cargandoSala}</p>
</>
) : (
<>
<p>{t.salaVacia}</p>
Expand Down
4 changes: 4 additions & 0 deletions web/src/i18n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const TEXTOS = {
ningunaSala: "ninguna sala abierta",
eligeOCrea: "abre una de tus salas o crea una nueva con el +",
salaVacia: "La sala está vacía.",
cargandoSala: "Cargando la sala…",
reconectando: "Sin conexión. Reconectando…",
pideAlgo: "@agente crea un Next con Tailwind",
hablaConLaSala: "habla con la sala — o escribe @agente para pedir algo",
adjuntarImagen: "Adjuntar un archivo",
Expand Down Expand Up @@ -249,6 +251,8 @@ const TEXTOS = {
ningunaSala: "no room open",
eligeOCrea: "open one of your rooms or create a new one with the +",
salaVacia: "The room is empty.",
cargandoSala: "Loading the room…",
reconectando: "No connection. Reconnecting…",
pideAlgo: "@agente build a Next app with Tailwind",
hablaConLaSala: "talk to the room — or type @agente to ask for something",
adjuntarImagen: "Attach a file",
Expand Down
24 changes: 24 additions & 0 deletions web/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -2494,3 +2494,27 @@ img.av {
.adjunto-doc-link:hover {
border-color: var(--lavanda);
}

/* Mientras el `joined` no llega, el chat dice que está cargando en vez de
verse igual que una sala donde nadie ha hablado. Reusa `preview-barra`, que
ya resuelve esto mismo en el iframe; el `relative` es para que la barra
tenga de dónde colgarse. */
.chat-cargando {
position: relative;
margin: auto;
padding: 24px 12px;
color: var(--dim);
font-size: 13px;
text-align: center;
}

/* Se cayó la conexión con mensajes ya en pantalla. Va arriba del chat y no en
medio: lo de abajo sigue siendo válido, solo dejó de actualizarse. */
.chat-desconectado {
padding: 6px 12px;
background: var(--fondo2);
border-bottom: 1px solid var(--linea);
color: var(--dim);
font-size: 11.5px;
text-align: center;
}
Loading