refactor: Gott-Datei space_admin_dialog.dart in 6 Dateien aufgeteilt
Gleiche Technik wie bei den vorigen drei Umbauten: reine Verschiebung per Dart part/part-of, keine Logikänderung. space_admin_dialog.dart schrumpft von 2278 auf 19 Zeilen (nur noch Bibliothekskopf). Verifiziert per automatisiertem Blockvergleich gegen das Original und flutter analyze. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
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<String> 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)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user