feat: Implement permanent deletion and restoration of notes with updated UI
This commit is contained in:
@@ -47,6 +47,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
bool _isLoading = true;
|
||||
bool _isDragging = false;
|
||||
bool _isMenuOpen = false;
|
||||
bool _showDeletedNotes = false;
|
||||
PointerDeviceKind _lastPointerKind = PointerDeviceKind.mouse;
|
||||
|
||||
bool _requiresLongPressToDrag(PointerDeviceKind kind) {
|
||||
@@ -71,7 +72,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
Future<void> _loadNotes() async {
|
||||
try {
|
||||
final List<Note> storedNotes = await widget.repository.loadNotes();
|
||||
final List<Note> storedNotes = _showDeletedNotes
|
||||
? await widget.repository.loadDeletedNotes()
|
||||
: await widget.repository.loadNotes();
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
@@ -95,19 +98,8 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
}
|
||||
|
||||
if (result is Note) {
|
||||
final Note createdNote = await widget.repository.createNote(result);
|
||||
final List<Note> updatedNotes = _normalizeNotes(<Note>[
|
||||
createdNote,
|
||||
..._notes,
|
||||
]);
|
||||
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_notes = updatedNotes;
|
||||
});
|
||||
await widget.repository.createNote(result);
|
||||
await _loadNotes();
|
||||
|
||||
// Trigger sync after creating a note.
|
||||
try {
|
||||
@@ -118,18 +110,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
Future<void> _deleteNote(Note note) async {
|
||||
await widget.repository.deleteNote(note);
|
||||
|
||||
final List<Note> updatedNotes = _normalizeNotes(
|
||||
_notes.where((Note item) => item.id != note.id).toList(),
|
||||
);
|
||||
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_notes = updatedNotes;
|
||||
});
|
||||
await _loadNotes();
|
||||
|
||||
// Trigger sync after deleting a note.
|
||||
try {
|
||||
@@ -142,19 +123,10 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<Note> updatedNotes = [..._notes];
|
||||
final Note movedNote = updatedNotes.removeAt(oldIndex);
|
||||
updatedNotes.insert(newIndex, movedNote);
|
||||
final Note movedNote = _notes[oldIndex];
|
||||
|
||||
await widget.repository.moveNote(movedNote, newIndex);
|
||||
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_notes = _normalizeNotes(updatedNotes);
|
||||
});
|
||||
await _loadNotes();
|
||||
}
|
||||
|
||||
Future<void> _openNoteEditor(Note note) async {
|
||||
@@ -173,19 +145,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
}
|
||||
|
||||
if (result is Note) {
|
||||
final int noteIndex = _notes.indexWhere((Note item) => item == note);
|
||||
if (noteIndex != -1) {
|
||||
final Note savedNote = await widget.repository.updateNote(result);
|
||||
final List<Note> updatedNotes = [..._notes];
|
||||
updatedNotes[noteIndex] = savedNote;
|
||||
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_notes = _normalizeNotes(updatedNotes);
|
||||
});
|
||||
if (_notes.any((Note item) => item == note)) {
|
||||
await widget.repository.updateNote(result);
|
||||
await _loadNotes();
|
||||
// Trigger sync after editing a note.
|
||||
try {
|
||||
await widget.onRequestSync();
|
||||
@@ -194,12 +156,6 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
List<Note> _normalizeNotes(List<Note> notes) {
|
||||
return notes.asMap().entries.map((MapEntry<int, Note> entry) {
|
||||
return entry.value.copyWith(index: entry.key);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
List<Note> _getFilteredNotes() {
|
||||
if (_searchQuery.isEmpty) {
|
||||
return _notes;
|
||||
@@ -215,6 +171,36 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<void> _handleMenuItemTapped(String item) async {
|
||||
setState(() {
|
||||
_isMenuOpen = false;
|
||||
});
|
||||
|
||||
if (item == 'settings') {
|
||||
widget.onOpenSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == 'deleted_notes') {
|
||||
setState(() {
|
||||
_showDeletedNotes = true;
|
||||
_searchQuery = '';
|
||||
_isLoading = true;
|
||||
});
|
||||
await _loadNotes();
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == 'all_notes') {
|
||||
setState(() {
|
||||
_showDeletedNotes = false;
|
||||
_searchQuery = '';
|
||||
_isLoading = true;
|
||||
});
|
||||
await _loadNotes();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double width = MediaQuery.of(context).size.width;
|
||||
@@ -223,8 +209,8 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
final Widget body = _isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: _notes.isEmpty
|
||||
? const _EmptyState()
|
||||
: RefreshIndicator(
|
||||
? _EmptyState(showDeletedNotes: _showDeletedNotes)
|
||||
: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
await widget.onRequestSync();
|
||||
},
|
||||
@@ -599,15 +585,10 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
color: const Color.fromRGBO(24, 25, 26, 1),
|
||||
elevation: 8,
|
||||
child: MenuDrawer(
|
||||
onMenuItemTapped: (String item) {
|
||||
setState(() {
|
||||
_isMenuOpen = false;
|
||||
});
|
||||
|
||||
if (item == 'settings') {
|
||||
widget.onOpenSettings();
|
||||
}
|
||||
},
|
||||
onMenuItemTapped: _handleMenuItemTapped,
|
||||
selectedItem: _showDeletedNotes
|
||||
? 'deleted_notes'
|
||||
: 'all_notes',
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -618,41 +599,47 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _openNoteComposer,
|
||||
child: const MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
floatingActionButton: _showDeletedNotes
|
||||
? null
|
||||
: FloatingActionButton(
|
||||
onPressed: _openNoteComposer,
|
||||
child: const MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _EmptyState extends StatelessWidget {
|
||||
const _EmptyState();
|
||||
const _EmptyState({required this.showDeletedNotes});
|
||||
|
||||
final bool showDeletedNotes;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const [
|
||||
Icon(Icons.note_add_outlined, color: Colors.white54, size: 48),
|
||||
SizedBox(height: 12),
|
||||
children: [
|
||||
const Icon(Icons.note_add_outlined, color: Colors.white54, size: 48),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
'Aún no hay notas',
|
||||
style: TextStyle(
|
||||
showDeletedNotes ? 'No hay notas borradas' : 'Aún no hay notas',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Pulsa el botón + para crear la primera.',
|
||||
showDeletedNotes
|
||||
? 'Las notas borradas aparecerán aquí para poder restaurarlas.'
|
||||
: 'Pulsa el botón + para crear la primera.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.white70),
|
||||
style: const TextStyle(color: Colors.white70),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user