From 8d1c712be7f114e45d855632259a47e268182847 Mon Sep 17 00:00:00 2001 From: freetlab Date: Sun, 10 May 2026 00:26:26 +0200 Subject: [PATCH] =?UTF-8?q?avatares=20m=C3=A1s=20grandes=20y=20usuario=20p?= =?UTF-8?q?or=20defecto=20en=20partida=20individual?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pantallas/pantalla_ajustes.dart | 23 +++++-- lib/pantallas/pantalla_crear_partida.dart | 84 +++++++++++++++++++---- 2 files changed, 86 insertions(+), 21 deletions(-) diff --git a/lib/pantallas/pantalla_ajustes.dart b/lib/pantallas/pantalla_ajustes.dart index d61b982..58557ac 100644 --- a/lib/pantallas/pantalla_ajustes.dart +++ b/lib/pantallas/pantalla_ajustes.dart @@ -33,7 +33,7 @@ class _PantallaAjustesState extends State { leading: AvatarFarolero( texto: perfil.nombre.substring(0, 1).toUpperCase(), assetPath: perfil.avatarAsset, - size: 48, + size: 128, ), title: Text(perfil.nombre), subtitle: Text('@${perfil.nick}'), @@ -123,7 +123,7 @@ class _PantallaAjustesState extends State { builder: (ctx, setDialogState) => AlertDialog( title: const Text('Perfil del dispositivo'), content: SizedBox( - width: 420, + width: 520, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, @@ -131,6 +131,7 @@ class _PantallaAjustesState extends State { TextField( controller: nombreController, textCapitalization: TextCapitalization.words, + onChanged: (_) => setDialogState(() {}), decoration: const InputDecoration( labelText: 'Nombre', prefixIcon: Icon(Icons.person), @@ -144,15 +145,23 @@ class _PantallaAjustesState extends State { prefixIcon: Icon(Icons.alternate_email), ), ), - const SizedBox(height: 16), + const SizedBox(height: 18), + AvatarFarolero( + texto: nombreController.text.isEmpty + ? '?' + : nombreController.text.substring(0, 1).toUpperCase(), + assetPath: avatarSeleccionado, + size: 90, + ), + const SizedBox(height: 18), GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 5, - mainAxisSpacing: 8, - crossAxisSpacing: 8, + crossAxisCount: 4, + mainAxisSpacing: 12, + crossAxisSpacing: 12, ), itemCount: ServicioPerfilUsuario.avatares.length, itemBuilder: (context, index) { @@ -176,7 +185,7 @@ class _PantallaAjustesState extends State { child: AvatarFarolero( texto: '', assetPath: avatar, - size: 48, + size: 72, ), ), ); diff --git a/lib/pantallas/pantalla_crear_partida.dart b/lib/pantallas/pantalla_crear_partida.dart index 334fb12..64c7a58 100644 --- a/lib/pantallas/pantalla_crear_partida.dart +++ b/lib/pantallas/pantalla_crear_partida.dart @@ -37,6 +37,7 @@ class _PantallaCrearPartidaState extends State { int? _tiempoDebate; final List _jugadores = []; final _controladorNombre = TextEditingController(); + bool _agregandoPerfilPendiente = false; final _opcionesTiempo = [null, 60, 120, 180, 300]; @@ -44,6 +45,22 @@ class _PantallaCrearPartidaState extends State { void initState() { super.initState(); _modoMultimovil = widget.modoInicial; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) _agregarPerfilLocalSiNecesario(); + }); + } + + void _agregarPerfilLocalSiNecesario() { + if (_modoMultimovil) return; + final servicioPerfil = context.read(); + if (!servicioPerfil.cargado) return; + final perfil = servicioPerfil.perfil; + final nombre = + perfil.nombre.trim().isEmpty ? 'Jugador' : perfil.nombre.trim(); + if (_jugadores.contains(nombre)) return; + setState(() { + _jugadores.insert(0, nombre); + }); } int get _maxImpostores => @@ -83,6 +100,10 @@ class _PantallaCrearPartidaState extends State { } void _eliminarJugador(int index) { + final perfil = context.read().perfil; + final nombrePerfil = + perfil.nombre.trim().isEmpty ? 'Jugador' : perfil.nombre.trim(); + if (index == 0 && _jugadores[index] == nombrePerfil) return; setState(() { _jugadores.removeAt(index); if (_numImpostores > _maxImpostores && _maxImpostores > 0) { @@ -276,8 +297,22 @@ class _PantallaCrearPartidaState extends State { Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final estado = context.watch(); + final servicioPerfil = context.watch(); final categorias = ['todas', ...?estado.banco?.nombresCategorias]; final etiquetas = _etiquetasTiempo(l10n); + final nombrePerfilActual = servicioPerfil.perfil.nombre.trim().isEmpty + ? 'Jugador' + : servicioPerfil.perfil.nombre.trim(); + if (!_modoMultimovil && + servicioPerfil.cargado && + !_agregandoPerfilPendiente && + !_jugadores.contains(nombrePerfilActual)) { + _agregandoPerfilPendiente = true; + WidgetsBinding.instance.addPostFrameCallback((_) { + _agregandoPerfilPendiente = false; + if (mounted) _agregarPerfilLocalSiNecesario(); + }); + } return Scaffold( appBar: AppBar(title: Text(l10n.createGame)), @@ -347,6 +382,7 @@ class _PantallaCrearPartidaState extends State { _numImpostores = _maxImpostores; } }); + _agregarPerfilLocalSiNecesario(); }, ), ], @@ -457,22 +493,42 @@ class _PantallaCrearPartidaState extends State { ), const SizedBox(height: 8), ..._jugadores.asMap().entries.map((e) { + final perfil = servicioPerfil.perfil; + final nombrePerfil = perfil.nombre.trim().isEmpty + ? 'Jugador' + : perfil.nombre.trim(); + final inicialPerfil = nombrePerfil.isEmpty + ? '?' + : nombrePerfil.substring(0, 1).toUpperCase(); + final esPerfilLocal = + e.key == 0 && e.value == nombrePerfil; return ListTile( - leading: CircleAvatar( - backgroundColor: TemaApp.colorTarjeta, - child: Text( - '${e.key + 1}', - style: const TextStyle(color: TemaApp.colorTexto), - ), - ), + leading: esPerfilLocal + ? AvatarFarolero( + texto: inicialPerfil, + assetPath: perfil.avatarAsset, + size: 54, + ) + : CircleAvatar( + backgroundColor: TemaApp.colorTarjeta, + child: Text( + '${e.key + 1}', + style: const TextStyle(color: TemaApp.colorTexto), + ), + ), title: Text(e.value), - trailing: IconButton( - icon: const Icon( - Icons.close, - color: TemaApp.colorAcento, - ), - onPressed: () => _eliminarJugador(e.key), - ), + subtitle: esPerfilLocal + ? const Text('Usuario principal del dispositivo') + : null, + trailing: esPerfilLocal + ? const Icon(Icons.lock, color: TemaApp.colorDorado) + : IconButton( + icon: const Icon( + Icons.close, + color: TemaApp.colorAcento, + ), + onPressed: () => _eliminarJugador(e.key), + ), dense: true, ); }),