← ☕︎ mmaria·Chats · color de usuariopropuesta · octubre 2026
Documento interno · Equipo de desarrollo
Propuesta · Chats
El color, en manos de quien lo lleva
Hoy el color de cada participante depende de la posición que ocupa en la lista de la sala, y cualquier cambio de orden lo altera sin aviso. Propongo guardarlo en el usuario y que cada persona pueda elegirlo. Este documento incluye una simulación para probarlo y las notas para implementarlo.
María · UX · 3 de octubre de 2026
01
Cómo se asigna el color hoy
El color no pertenece al usuario: pertenece a su posición en el array de participantes de la sala.
Visto en el códigoEn el componente que pinta el chip del participante, el color se calcula a partir del índice del participante en currentChatRoom.participants. El usuario actual se salta la paleta y se pinta en blanco con borde naranja.
// Reproducido del bundle (nombres minificados)
const qt = [Pt.A[100], St.A[100], Tt.A[100], Dt.A[100],
It.A[100], Rt.A[100], Nt.A[100], Mt.A[100]];
const l = ft.h.currentChatRoom.participants;
const u = s.id !== r ? qt[l.indexOf(s) % qt.length] : "white"; // backgroundColor
const m = s.id !== r ? qt[l.indexOf(s) % qt.length] : "orange"; // borde
// style: { backgroundColor: u,
// border: s.id == r ? "2px solid ".concat(m) : "none" }
La paleta son ocho colores que se repiten en secuencia: el participante en la posición 9 lleva el color de la posición 1. Está en el chunk 893.34ffb5ef.chunk.js; el hash del nombre cambia en cada despliegue.
Prueba qué pasa si cambia el orden del array. Los nombres son de ejemplo, y el chip en blanco con borde naranja es el del usuario actual (Mmaria), como se ve hoy.
Cada celda muestra la posición, el color que le toca y su hex. Con otro orden, las mismas personas cambian de color. En Mmaria el color que le corresponde queda oculto bajo el blanco.
02
Qué cambia
Cada persona se ve con su color real, igual que la ven los demás, y puede cambiarlo desde su propio avatar.
PropuestaTres cambios visibles:
1. Se elimina el blanco con borde naranja del usuario actual, tanto en sus comentarios como en su chip de la lista. Para distinguir los mensajes propios ya basta con que van alineados a la derecha y los ajenos a la izquierda.
2. El menú del avatar propio pasa de tener «Ver perfil público» más dos opciones desactivadas («Enviar mensaje» y «Crear nuevo chat», que no tienen sentido sobre uno mismo) a tener «Ver perfil público» y «Cambiar mi color».
3. El menú del avatar de otra persona no cambia: no hay selector de color para colores ajenos.
HoyPropuesta
Tu avatar · hoy
Ver perfil público
✉Enviar mensaje
+Crear nuevo chat
Tu avatar · propuesta
Ver perfil público
Cambiar mi color
Avatar de otra persona · sin cambios
Ver perfil público
+Añadir a amigos
✉Enviar mensaje
+Crear nuevo chat
Visto en la interfazLas opciones de «Hoy» y de «Avatar de otra persona» están tomadas del chat real.
03
Pruébalo
La simulación funciona como lo haría el producto: tú eres Mmaria.
Pulsa tu avatar (el de la burbuja de la derecha o tu chip de la lista) para abrir el menú y elegir «Cambiar mi color». Pulsa el avatar de cualquier otra persona para ver que ahí no aparece el selector. Prueba con un color muy oscuro y con uno casi blanco.
Simulación interactiva
El lado del mal
Creado por ChemaAlonso
ArchivosParticipantesSilenciarSalirse
Tu color
Los demás lo verán la próxima vez que abran o recarguen el chat.
👆
04
Legibilidad con cualquier color
Si el color es libre, el texto tiene que adaptarse solo.
PropuestaCalcular la luminancia del color elegido y escribir en negro o en blanco, el que dé más contraste. Con este criterio el contraste mínimo posible es de aproximadamente 4,6:1 (en el color más desfavorable, el gris medio), por encima del 4,5:1 que pide WCAG AA para texto normal.
function textColorFor(hex) {
const [r, g, b] = [1, 3, 5]
.map(i => parseInt(hex.slice(i, i + 2), 16) / 255)
.map(c => c > 0.03928 ? ((c + 0.055) / 1.055) ** 2.4 : c / 12.92);
const L = 0.2126 * r + 0.7152 * g + 0.0722 * b;
return L > 0.179 ? "#000" : "#fff";
}
El umbral 0,179 es el punto en que negro y blanco dan el mismo contraste.
Texto de ejemplo en la burbuja
Estrategia
Libertad de color
Contraste
Valoración
Limitar el picker a colores claros
Baja
Garantizado, pero hay que acotar también los casi blancos
Recorta justo lo que se quiere dar
Forzar texto blanco en fondos oscuros
Alta
Solo cubre un lado: en fondos medios puede fallar
Incompleta
Texto automático (negro o blanco según luminancia)
Total
Mínimo aproximado 4,6:1 en cualquier color
Recomendada
Corregir la luminosidad al guardar
Aparente
Garantizado
Cambia lo que la persona eligió sin avisar
PropuestaEl texto automático debe aplicarse a todo lo que va dentro del color: nombre, mensaje, hora, iconos y enlaces. Los enlaces hoy salen en azul, que sobre un fondo oscuro no se lee; con el color heredado y subrayado se resuelve.
PropuestaCon un color casi blanco la burbuja se confundiría con el fondo de la página. No hace falta prohibirlo: un borde fino y sutil en todas las burbujas basta (en las simulaciones de arriba ya está aplicado).
05
Indicadores de conexión y audio
Los dos iconos del chip viven sobre el color de fondo, así que necesitan una base propia.
Visto en la interfazEn el chip de la lista de participantes hay dos indicadores: conectado/desconectado y audio activado/desactivado, en rojo #e53935 (apagado) o verde #43a047 (encendido).
PropuestaUn círculo blanco detrás de cada icono, de modo que se lean sobre cualquier color. Además, los dos se distinguen por forma, no solo por el tono, lo cual ayuda a quien no distingue rojo y verde.
06
Notas para implementarlo
Lo que he comprobado, lo que propongo y lo que queda por revisar.
Lo que he comprobado
CódigoEl color del chip sale de qt[indexOf % qt.length] y el usuario actual se pinta en blanco con borde naranja.
CódigoLa paleta son ocho entradas de tipo A[100], que por sus valores parecen ser el tono 100 de Material UI.
InterfazEl menú del avatar propio ofrece «Ver perfil público» y dos opciones desactivadas; el de otra persona ofrece cuatro opciones.
InterfazLos mensajes propios van a la derecha y los ajenos a la izquierda.
Por comprobar
RevisarDónde se pinta el fondo de las burbujas de mensaje; no se ha inspeccionado.
RevisarSi la paleta se usa en otros sitios (otros chunks, correos, apps móviles).
RevisarNombre del campo de fecha de entrada y orden en que llega hoy el array desde el backend.
DecidirSi el cambio de color se emite en directo o solo se ve al recargar. Esta propuesta asume lo segundo, que es lo más simple.
Propuesta técnica
Un campo en el usuario, con respaldo estable
Si la persona ha elegido color, se usa. Si no, se deriva del id del usuario y no de su posición, de modo que no depende del orden ni de la sala.
// El nombre del campo es orientativo
function hash(id) {
let h = 0;
for (const ch of String(id)) h = (h * 31 + ch.charCodeAt(0)) >>> 0;
return h;
}
const color = participant.chatColor ?? qt[hash(participant.id) % qt.length];
const ink = textColorFor(color);
Mismo color en todas las salas
Al guardarse en el usuario y no en la sala, la persona se ve igual en todos sus chats. Hoy eso solo ocurre por casualidad.
Validar en el servidor
El valor acaba dentro de estilos en varios clientes, así que se acepta únicamente un hexadecimal de seis dígitos.
const HEX = /^#[0-9a-f]{6}$/i;
if (!HEX.test(value)) throw new Error("color inválido");
Guardar al aplicar, no al arrastrar
El selector continuo dispara muchos eventos; se guarda cuando la persona pulsa «Aplicar». Conviene guardar el hexadecimal y no la posición en la paleta, para que reordenar la paleta no vuelva a descolocar nada.
Marcador del usuario en la lista
Al quitar el blanco con borde, el chip propio deja de destacar en la lista de participantes, que no tiene la alineación a la derecha como guía. Es opcional, pero podría añadirse un «(tú)» discreto o el nombre en negrita.
Para quien usa el chat, el color es la forma más rápida de reconocer quién habla. Hoy la asignación de colores depende de un orden que puede verse alterado en cualquier momento, sin querer o por otras decisiones que alteran los colores como daño colateral.
Si el color se guarda en el usuario, deja de ser un efecto secundario: se mantiene entre salas, entre despliegues y entre reordenaciones, y lo puede cambiar quien lo lleva. Para el equipo, el coste es un campo, un endpoint y un selector.