Feat: Macht die Kontoliste und Versionsanzeige funktional

This commit is contained in:
2025-12-25 23:15:54 +01:00
parent 7916161e4f
commit a45169bf12
11 changed files with 488 additions and 326 deletions

View File

@@ -10,5 +10,5 @@ class DialogAction {
final bool isPrimary;
/// Was bei einem Knopfdruck passieren soll
final void Function(Map<String, String> inputValues)? onPressed;
final void Function(Map<String, dynamic> inputValues)? onPressed;
}

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import '../../Entities/dialog_type_enum.dart';
import '../../Services/navigation_service.dart';
import '../../Services/theme_service.dart';
import 'dialog_action.dart';
import 'dialog_input_field.dart';
@@ -18,6 +19,7 @@ class DynamicDialog {
this.borderRadius = 16,
this.barrierDismissible = true,
this.dialogType = DialogTypeEnum.info,
this.hiddenValues
}) : inputFields = inputFields ?? const [],
actions = actions ?? [DialogAction(label: 'Schließen')];
@@ -48,6 +50,9 @@ class DynamicDialog {
/// Der Typ des Dialogs
final DialogTypeEnum dialogType;
/// Versteckte Werte, die beim Abschicken mit zurückgegeben werden
final Map<String, dynamic>? hiddenValues;
Map<String, TextEditingController>? _controllers;
Map<String, FocusNode>? _focusNodes;
@@ -79,119 +84,133 @@ class DynamicDialog {
}
/// Zeigt den vorher zusammengebauten Dialog an
Future<void> show(final BuildContext context) async {
final ThemeData theme = Theme.of(context);
Future<void> show() async {
final BuildContext? context = NavigationService.getCurrentBuildContext();
_prepareControllers();
_prepareFocusNodes();
if (context != null) {
final ThemeData theme = Theme.of(context);
await showDialog(
context: context,
barrierDismissible: barrierDismissible,
builder: (final BuildContext ctx) {
_dialogContext = ctx;
WidgetsBinding.instance.addPostFrameCallback((_) {
final DialogInputField? autoFocusField = inputFields
.where((final DialogInputField f) => f.autoFocus)
.cast<DialogInputField?>()
.firstWhere(
(final DialogInputField? f) => f != null,
orElse: () => null,
);
_prepareControllers();
_prepareFocusNodes();
if (autoFocusField != null) {
_focusNodes![autoFocusField.id]!.requestFocus();
}
});
await showDialog(
context: context,
barrierDismissible: barrierDismissible,
builder: (final BuildContext ctx) {
_dialogContext = ctx;
WidgetsBinding.instance.addPostFrameCallback((_) {
final DialogInputField? autoFocusField = inputFields
.where((final DialogInputField f) => f.autoFocus)
.cast<DialogInputField?>()
.firstWhere(
(final DialogInputField? f) => f != null,
orElse: () => null,
);
final DialogAction primaryAction = actions.firstWhere(
(final a) => a.isPrimary,
orElse: () => actions.first,
);
if (autoFocusField != null) {
_focusNodes![autoFocusField.id]!.requestFocus();
}
});
Color backgroundColor =
this.backgroundColor ?? theme.colorScheme.surface;
if (dialogType == DialogTypeEnum.error) {
backgroundColor = theme.colorScheme.errorContainer;
} else if (dialogType == DialogTypeEnum.success) {
backgroundColor = ThemeService.getSuccessColor(
brightness: theme.brightness,
final DialogAction primaryAction = actions.firstWhere(
(final a) => a.isPrimary,
orElse: () => actions.first,
);
}
return AlertDialog(
backgroundColor: backgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(borderRadius),
),
title: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null)
Icon(icon, size: 48, color: theme.colorScheme.primary),
if (title != null)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
title!,
style: theme.textTheme.titleLarge,
textAlign: TextAlign.center,
),
),
],
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (content != null) content!,
...inputFields.map(
(final DialogInputField field) => Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: TextField(
controller: _controllers![field.id],
focusNode: _focusNodes![field.id],
keyboardType: field.keyboardType,
obscureText: field.obscureText,
onChanged: field.onChanged,
decoration: InputDecoration(
labelText: field.label,
border: const OutlineInputBorder(),
isDense: true,
Color backgroundColor =
this.backgroundColor ?? theme.colorScheme.surface;
if (dialogType == DialogTypeEnum.error) {
backgroundColor = theme.colorScheme.errorContainer;
} else if (dialogType == DialogTypeEnum.success) {
backgroundColor = ThemeService.getSuccessColor(
brightness: theme.brightness,
);
}
return AlertDialog(
backgroundColor: backgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(borderRadius),
),
title: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null)
Icon(icon, size: 48, color: theme.colorScheme.primary),
if (title != null)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
title!,
style: theme.textTheme.titleLarge,
textAlign: TextAlign.center,
),
onSubmitted: (_) {
final Map<String, String> values = {
),
],
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (content != null) content!,
...inputFields.map(
(final DialogInputField field) =>
Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: TextField(
controller: _controllers![field.id],
focusNode: _focusNodes![field.id],
keyboardType: field.keyboardType,
obscureText: field.obscureText,
onChanged: field.onChanged,
decoration: InputDecoration(
labelText: field.label,
border: const OutlineInputBorder(),
isDense: true,
),
onSubmitted: (_) {
final Map<String, dynamic> values = {
for (final entry in _controllers!.entries)
entry.key: entry.value.text,
};
hiddenValues?.forEach((final key, final value) {
values[key] = value;
});
close();
primaryAction.onPressed?.call(values);
},
),
),
),
],
),
actions: actions
.map(
(final action) =>
TextButton(
onPressed: () {
final Map<String, dynamic> values = {
for (final entry in _controllers!.entries)
entry.key: entry.value.text,
};
close();
primaryAction.onPressed?.call(values);
},
),
),
),
],
),
actions: actions
.map(
(final action) => TextButton(
onPressed: () {
final Map<String, String> values = {
for (final entry in _controllers!.entries)
entry.key: entry.value.text,
};
hiddenValues?.forEach((final key, final value) {
values[key] = value;
});
close();
action.onPressed?.call(values);
},
child: Text(action.label),
),
)
.toList(),
);
},
);
close();
action.onPressed?.call(values);
},
child: Text(action.label),
),
)
.toList(),
);
},
);
}
}
/// Schließt den dynamischen Dialog