feat: Refactor note editor dialog and delete confirmation for improved readability and reusability

This commit is contained in:
2026-05-21 16:26:31 +02:00
parent 49fc33edc0
commit 28f4ede4aa
3 changed files with 518 additions and 458 deletions
+87 -154
View File
@@ -28,39 +28,44 @@ class NoteEditorScreen extends StatefulWidget {
@override
State<NoteEditorScreen> createState() => _NoteEditorScreenState();
static Future<dynamic> _showGeneralEditorDialog(
BuildContext context, {
Note? note,
String? categoryId,
}) {
return showGeneralDialog<dynamic>(
context: context,
barrierDismissible: false,
barrierColor: Colors.transparent,
transitionDuration: const Duration(milliseconds: 200),
pageBuilder: (context, animation, secondaryAnimation) {
return NoteEditorScreen(note: note, categoryId: categoryId);
},
transitionBuilder: (context, animation, secondaryAnimation, child) {
return ScaleTransition(scale: animation, child: child);
},
);
}
static Future<dynamic> showDialog(
BuildContext context, {
Note? note,
String? categoryId,
}) {
if (isAndroid || isIOS) {
return showGeneralDialog<dynamic>(
context: context,
barrierDismissible: false,
barrierColor: Colors.transparent,
transitionDuration: const Duration(milliseconds: 200),
pageBuilder: (context, animation, secondaryAnimation) {
return NoteEditorScreen(note: note, categoryId: categoryId);
},
transitionBuilder: (context, animation, secondaryAnimation, child) {
return ScaleTransition(scale: animation, child: child);
},
return _showGeneralEditorDialog(
context,
note: note,
categoryId: categoryId,
);
}
final OverlayState? overlayState = Overlay.of(context, rootOverlay: true);
if (overlayState == null) {
return showGeneralDialog<dynamic>(
context: context,
barrierDismissible: false,
barrierColor: Colors.transparent,
transitionDuration: const Duration(milliseconds: 200),
pageBuilder: (context, animation, secondaryAnimation) {
return NoteEditorScreen(note: note, categoryId: categoryId);
},
transitionBuilder: (context, animation, secondaryAnimation, child) {
return ScaleTransition(scale: animation, child: child);
},
return _showGeneralEditorDialog(
context,
note: note,
categoryId: categoryId,
);
}
@@ -161,43 +166,52 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
_complete(updatedNote);
}
Future<bool> _showDeleteConfirmation() async {
Widget _buildDeleteConfirmationDialog({
required ValueChanged<bool> onConfirmed,
}) {
final bool isDeletedNote = _currentNote.isDeleted;
return AlertDialog(
backgroundColor: const Color(0xFF303134),
title: Text(
isDeletedNote ? 'Eliminar permanentemente' : 'Eliminar nota',
style: const TextStyle(color: Colors.white),
),
content: Text(
isDeletedNote
? 'Esta nota ya está borrada. Si la eliminas ahora, se borrará permanentemente.'
: '¿Estás seguro de que deseas eliminar esta nota?',
style: const TextStyle(color: Colors.white70),
),
actions: [
TextButton(
onPressed: () => onConfirmed(false),
child: const Text(
'Cancelar',
style: TextStyle(color: Colors.white70),
),
),
TextButton(
onPressed: () => onConfirmed(true),
child: Text(
isDeletedNote ? 'Eliminar permanentemente' : 'Eliminar',
style: const TextStyle(color: Colors.red),
),
),
],
);
}
Future<bool> _showDeleteConfirmation() async {
if (_isMobileLayout) {
final bool? confirmed = await showDialog<bool>(
context: context,
barrierDismissible: false,
barrierColor: Colors.transparent,
builder: (BuildContext dialogContext) {
return AlertDialog(
backgroundColor: const Color(0xFF303134),
title: Text(
isDeletedNote ? 'Eliminar permanentemente' : 'Eliminar nota',
style: const TextStyle(color: Colors.white),
),
content: Text(
isDeletedNote
? 'Esta nota ya está borrada. Si la eliminas ahora, se borrará permanentemente.'
: '¿Estás seguro de que deseas eliminar esta nota?',
style: const TextStyle(color: Colors.white70),
),
actions: [
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(false),
child: const Text(
'Cancelar',
style: TextStyle(color: Colors.white70),
),
),
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(true),
child: Text(
isDeletedNote ? 'Eliminar permanentemente' : 'Eliminar',
style: const TextStyle(color: Colors.red),
),
),
],
return _buildDeleteConfirmationDialog(
onConfirmed: (bool confirmed) =>
Navigator.of(dialogContext).pop(confirmed),
);
},
);
@@ -212,34 +226,9 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
barrierDismissible: false,
barrierColor: Colors.transparent,
builder: (BuildContext dialogContext) {
return AlertDialog(
backgroundColor: const Color(0xFF303134),
title: Text(
isDeletedNote ? 'Eliminar permanentemente' : 'Eliminar nota',
style: const TextStyle(color: Colors.white),
),
content: Text(
isDeletedNote
? 'Esta nota ya está borrada. Si la eliminas ahora, se borrará permanentemente.'
: '¿Estás seguro de que deseas eliminar esta nota?',
style: const TextStyle(color: Colors.white70),
),
actions: [
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(false),
child: const Text(
'Cancelar',
style: TextStyle(color: Colors.white70),
),
),
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(true),
child: Text(
isDeletedNote ? 'Eliminar permanentemente' : 'Eliminar',
style: const TextStyle(color: Colors.red),
),
),
],
return _buildDeleteConfirmationDialog(
onConfirmed: (bool confirmed) =>
Navigator.of(dialogContext).pop(confirmed),
);
},
);
@@ -251,18 +240,18 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
late final OverlayEntry entry;
bool didRemove = false;
void close(bool confirmed) {
if (!completer.isCompleted) {
completer.complete(confirmed);
}
if (!didRemove && entry.mounted) {
didRemove = true;
entry.remove();
}
}
entry = OverlayEntry(
builder: (BuildContext overlayContext) {
final ValueChanged<bool> close = (bool confirmed) {
if (!completer.isCompleted) {
completer.complete(confirmed);
}
if (!didRemove && entry.mounted) {
didRemove = true;
entry.remove();
}
};
return Material(
color: Colors.transparent,
child: Stack(
@@ -276,39 +265,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 420),
child: AlertDialog(
backgroundColor: const Color(0xFF303134),
title: Text(
isDeletedNote
? 'Eliminar permanentemente'
: 'Eliminar nota',
style: const TextStyle(color: Colors.white),
),
content: Text(
isDeletedNote
? 'Esta nota ya está borrada. Si la eliminas ahora, se borrará permanentemente.'
: '¿Estás seguro de que deseas eliminar esta nota?',
style: const TextStyle(color: Colors.white70),
),
actions: [
TextButton(
onPressed: () => close(false),
child: const Text(
'Cancelar',
style: TextStyle(color: Colors.white70),
),
),
TextButton(
onPressed: () => close(true),
child: Text(
isDeletedNote
? 'Eliminar permanentemente'
: 'Eliminar',
style: const TextStyle(color: Colors.red),
),
),
],
),
child: _buildDeleteConfirmationDialog(onConfirmed: close),
),
),
],
@@ -351,26 +308,15 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
return Column(
children: [
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.white12,
width: 1,
),
),
border: Border(bottom: BorderSide(color: Colors.white12, width: 1)),
),
child: Row(
children: [
IconButton(
onPressed: _closeWithoutSaving,
icon: const Icon(
Icons.close,
color: Colors.white70,
),
icon: const Icon(Icons.close, color: Colors.white70),
tooltip: 'Cerrar sin guardar',
),
const SizedBox(width: 8),
@@ -434,9 +380,7 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
),
decoration: const InputDecoration(
hintText: 'Escribe tu nota...',
hintStyle: TextStyle(
color: Colors.white30,
),
hintStyle: TextStyle(color: Colors.white30),
border: InputBorder.none,
contentPadding: EdgeInsets.zero,
),
@@ -447,14 +391,9 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.white12, width: 1),
),
border: Border(top: BorderSide(color: Colors.white12, width: 1)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -462,18 +401,12 @@ class _NoteEditorScreenState extends State<NoteEditorScreen> {
if (!_isNewNote)
IconButton(
onPressed: _deleteNote,
icon: const Icon(
Icons.delete_outline,
color: Colors.red,
),
icon: const Icon(Icons.delete_outline, color: Colors.red),
tooltip: 'Eliminar nota',
)
else
const SizedBox(width: 48),
FilledButton(
onPressed: _saveNote,
child: const Text('Guardar'),
),
FilledButton(onPressed: _saveNote, child: const Text('Guardar')),
],
),
),