part of '../space_admin_dialog.dart'; class _SectionLabel extends StatelessWidget { final String text; final PyramidTheme pt; const _SectionLabel(this.text, this.pt); @override Widget build(BuildContext context) { return Text(text, style: TextStyle( color: pt.fgDim, fontSize: 11, fontWeight: FontWeight.w700, letterSpacing: 0.8)); } } class _Field extends StatelessWidget { final TextEditingController controller; final String hint; final int maxLines; final PyramidTheme pt; const _Field({ required this.controller, required this.hint, this.maxLines = 1, required this.pt, }); @override Widget build(BuildContext context) { return TextField( controller: controller, maxLines: maxLines, style: TextStyle(color: pt.fg, fontSize: 13), decoration: InputDecoration( hintText: hint, hintStyle: TextStyle(color: pt.fgDim), filled: true, fillColor: pt.bg0, contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), border: OutlineInputBorder( borderRadius: BorderRadius.circular(pt.rSm), borderSide: BorderSide(color: pt.border), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(pt.rSm), borderSide: BorderSide(color: pt.border), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(pt.rSm), borderSide: BorderSide(color: pt.accent), ), ), ); } } class _SearchField extends StatelessWidget { final TextEditingController controller; final String hint; final PyramidTheme pt; final ValueChanged onChanged; const _SearchField({ required this.controller, required this.hint, required this.pt, required this.onChanged, }); @override Widget build(BuildContext context) { return TextField( controller: controller, onChanged: onChanged, style: TextStyle(color: pt.fg, fontSize: 13), decoration: InputDecoration( hintText: hint, hintStyle: TextStyle(color: pt.fgDim), prefixIcon: Icon(Icons.search, color: pt.fgDim, size: 18), filled: true, fillColor: pt.bg0, contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), isDense: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(pt.rSm), borderSide: BorderSide(color: pt.border), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(pt.rSm), borderSide: BorderSide(color: pt.border), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(pt.rSm), borderSide: BorderSide(color: pt.accent), ), ), ); } } class _AvatarEditor extends StatelessWidget { final Room space; final Uint8List? pendingAvatar; final bool canEdit; final VoidCallback onPick; final VoidCallback onRemove; final PyramidTheme pt; final dynamic client; const _AvatarEditor({ required this.space, required this.pendingAvatar, required this.canEdit, required this.onPick, required this.onRemove, required this.pt, required this.client, }); @override Widget build(BuildContext context) { final letter = space.getLocalizedDisplayname().isNotEmpty ? space.getLocalizedDisplayname()[0].toUpperCase() : '?'; final avatarUri = space.avatar; final hasAvatar = pendingAvatar != null || avatarUri != null; Widget avatarWidget; if (pendingAvatar != null) { avatarWidget = Image.memory(pendingAvatar!, fit: BoxFit.cover, width: 64, height: 64); } else if (avatarUri != null && client != null) { avatarWidget = MxcAvatar( mxcUri: avatarUri, client: client, size: 64, borderRadius: BorderRadius.circular(32), placeholder: (_) => _InitialAvatar(letter: letter, pt: pt, size: 64), ); } else { avatarWidget = _InitialAvatar(letter: letter, pt: pt, size: 64); } return Row( children: [ GestureDetector( onTap: canEdit ? onPick : null, child: Stack( clipBehavior: Clip.none, children: [ Container( width: 64, height: 64, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all(color: pt.border), ), clipBehavior: Clip.hardEdge, child: avatarWidget, ), if (canEdit) Positioned( right: -2, bottom: -2, child: Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: pt.accent, shape: BoxShape.circle, border: Border.all(color: pt.bg1, width: 2), ), child: const Icon(Icons.edit, size: 10, color: Colors.white), ), ), ], ), ), const SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( canEdit ? 'Klicken zum Ändern' : 'Serverbild', style: TextStyle(color: pt.fg, fontSize: 13, fontWeight: FontWeight.w500), ), if (canEdit && hasAvatar) GestureDetector( onTap: onRemove, child: Text('Entfernen', style: TextStyle( color: const Color(0xFFED4245), fontSize: 12)), ), ], ), ], ); } } class _InitialAvatar extends StatelessWidget { final String letter; final PyramidTheme pt; final double size; const _InitialAvatar( {required this.letter, required this.pt, required this.size}); @override Widget build(BuildContext context) { return Container( width: size, height: size, decoration: BoxDecoration( color: pt.bg3, borderRadius: BorderRadius.circular(size / 2), ), child: Center( child: Text(letter, style: TextStyle( color: pt.fg, fontSize: size * 0.4, fontWeight: FontWeight.w700)), ), ); } }