avatares más grandes y usuario por defecto en partida individual

This commit is contained in:
2026-05-10 00:26:26 +02:00
parent e6ee6adddc
commit 8d1c712be7
2 changed files with 86 additions and 21 deletions

View File

@@ -33,7 +33,7 @@ class _PantallaAjustesState extends State<PantallaAjustes> {
leading: AvatarFarolero( leading: AvatarFarolero(
texto: perfil.nombre.substring(0, 1).toUpperCase(), texto: perfil.nombre.substring(0, 1).toUpperCase(),
assetPath: perfil.avatarAsset, assetPath: perfil.avatarAsset,
size: 48, size: 128,
), ),
title: Text(perfil.nombre), title: Text(perfil.nombre),
subtitle: Text('@${perfil.nick}'), subtitle: Text('@${perfil.nick}'),
@@ -123,7 +123,7 @@ class _PantallaAjustesState extends State<PantallaAjustes> {
builder: (ctx, setDialogState) => AlertDialog( builder: (ctx, setDialogState) => AlertDialog(
title: const Text('Perfil del dispositivo'), title: const Text('Perfil del dispositivo'),
content: SizedBox( content: SizedBox(
width: 420, width: 520,
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -131,6 +131,7 @@ class _PantallaAjustesState extends State<PantallaAjustes> {
TextField( TextField(
controller: nombreController, controller: nombreController,
textCapitalization: TextCapitalization.words, textCapitalization: TextCapitalization.words,
onChanged: (_) => setDialogState(() {}),
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'Nombre', labelText: 'Nombre',
prefixIcon: Icon(Icons.person), prefixIcon: Icon(Icons.person),
@@ -144,15 +145,23 @@ class _PantallaAjustesState extends State<PantallaAjustes> {
prefixIcon: Icon(Icons.alternate_email), 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( GridView.builder(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
gridDelegate: gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount( const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5, crossAxisCount: 4,
mainAxisSpacing: 8, mainAxisSpacing: 12,
crossAxisSpacing: 8, crossAxisSpacing: 12,
), ),
itemCount: ServicioPerfilUsuario.avatares.length, itemCount: ServicioPerfilUsuario.avatares.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
@@ -176,7 +185,7 @@ class _PantallaAjustesState extends State<PantallaAjustes> {
child: AvatarFarolero( child: AvatarFarolero(
texto: '', texto: '',
assetPath: avatar, assetPath: avatar,
size: 48, size: 72,
), ),
), ),
); );

View File

@@ -37,6 +37,7 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
int? _tiempoDebate; int? _tiempoDebate;
final List<String> _jugadores = []; final List<String> _jugadores = [];
final _controladorNombre = TextEditingController(); final _controladorNombre = TextEditingController();
bool _agregandoPerfilPendiente = false;
final _opcionesTiempo = <int?>[null, 60, 120, 180, 300]; final _opcionesTiempo = <int?>[null, 60, 120, 180, 300];
@@ -44,6 +45,22 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
void initState() { void initState() {
super.initState(); super.initState();
_modoMultimovil = widget.modoInicial; _modoMultimovil = widget.modoInicial;
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) _agregarPerfilLocalSiNecesario();
});
}
void _agregarPerfilLocalSiNecesario() {
if (_modoMultimovil) return;
final servicioPerfil = context.read<ServicioPerfilUsuario>();
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 => int get _maxImpostores =>
@@ -83,6 +100,10 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
} }
void _eliminarJugador(int index) { void _eliminarJugador(int index) {
final perfil = context.read<ServicioPerfilUsuario>().perfil;
final nombrePerfil =
perfil.nombre.trim().isEmpty ? 'Jugador' : perfil.nombre.trim();
if (index == 0 && _jugadores[index] == nombrePerfil) return;
setState(() { setState(() {
_jugadores.removeAt(index); _jugadores.removeAt(index);
if (_numImpostores > _maxImpostores && _maxImpostores > 0) { if (_numImpostores > _maxImpostores && _maxImpostores > 0) {
@@ -276,8 +297,22 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!; final l10n = AppLocalizations.of(context)!;
final estado = context.watch<EstadoJuego>(); final estado = context.watch<EstadoJuego>();
final servicioPerfil = context.watch<ServicioPerfilUsuario>();
final categorias = ['todas', ...?estado.banco?.nombresCategorias]; final categorias = ['todas', ...?estado.banco?.nombresCategorias];
final etiquetas = _etiquetasTiempo(l10n); 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( return Scaffold(
appBar: AppBar(title: Text(l10n.createGame)), appBar: AppBar(title: Text(l10n.createGame)),
@@ -347,6 +382,7 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
_numImpostores = _maxImpostores; _numImpostores = _maxImpostores;
} }
}); });
_agregarPerfilLocalSiNecesario();
}, },
), ),
], ],
@@ -457,8 +493,23 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
..._jugadores.asMap().entries.map((e) { ..._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( return ListTile(
leading: CircleAvatar( leading: esPerfilLocal
? AvatarFarolero(
texto: inicialPerfil,
assetPath: perfil.avatarAsset,
size: 54,
)
: CircleAvatar(
backgroundColor: TemaApp.colorTarjeta, backgroundColor: TemaApp.colorTarjeta,
child: Text( child: Text(
'${e.key + 1}', '${e.key + 1}',
@@ -466,7 +517,12 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
), ),
), ),
title: Text(e.value), title: Text(e.value),
trailing: IconButton( subtitle: esPerfilLocal
? const Text('Usuario principal del dispositivo')
: null,
trailing: esPerfilLocal
? const Icon(Icons.lock, color: TemaApp.colorDorado)
: IconButton(
icon: const Icon( icon: const Icon(
Icons.close, Icons.close,
color: TemaApp.colorAcento, color: TemaApp.colorAcento,