From c2db7041555b969cd05181a98e87dee36af72afb Mon Sep 17 00:00:00 2001 From: Marck64 Date: Thu, 2 Jul 2026 10:52:33 +0200 Subject: [PATCH] refactor: Improve code readability by formatting and simplifying widget structures --- lib/screens/home_screen.dart | 61 ++++++----- lib/screens/note_editor_screen.dart | 34 +++--- lib/widgets/note_card.dart | 158 ++++++++++++++-------------- 3 files changed, 127 insertions(+), 126 deletions(-) diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 5cfe747..50d7b9e 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -86,7 +86,8 @@ class _HomeScreenState extends State { try { final List notes = await widget.repository.loadNotes(); - final List categories = await widget.repository.loadCategories(); + final List categories = await widget.repository + .loadCategories(); final DateTime? lastSyncAt = await widget.repository.getLastSyncAt(); if (!mounted) { @@ -138,7 +139,9 @@ class _HomeScreenState extends State { Iterable notes = _notes; if (_selectedCategoryId != null) { - notes = notes.where((Note note) => note.categoryId == _selectedCategoryId); + notes = notes.where( + (Note note) => note.categoryId == _selectedCategoryId, + ); } if (_searchQuery.isEmpty) { @@ -181,8 +184,8 @@ class _HomeScreenState extends State { RelativeRect _menuRectFromContext(BuildContext anchorContext) { final RenderBox button = anchorContext.findRenderObject()! as RenderBox; - final RenderBox overlay = Overlay.of(anchorContext).context.findRenderObject()! - as RenderBox; + final RenderBox overlay = + Overlay.of(anchorContext).context.findRenderObject()! as RenderBox; final Offset topLeft = button.localToGlobal(Offset.zero, ancestor: overlay); final Offset bottomRight = button.localToGlobal( button.size.bottomRight(Offset.zero), @@ -190,12 +193,7 @@ class _HomeScreenState extends State { ); return RelativeRect.fromRect( - Rect.fromLTRB( - topLeft.dx, - topLeft.dy, - bottomRight.dx, - bottomRight.dy, - ), + Rect.fromLTRB(topLeft.dx, topLeft.dy, bottomRight.dx, bottomRight.dy), Offset.zero & overlay.size, ); } @@ -246,7 +244,10 @@ class _HomeScreenState extends State { }); } - Future _changeNoteCategory(BuildContext anchorContext, Note note) async { + Future _changeNoteCategory( + BuildContext anchorContext, + Note note, + ) async { final Category? selected = await _showAnchoredCategoryMenu( anchorContext: anchorContext, items: >[ @@ -256,10 +257,7 @@ class _HomeScreenState extends State { ), const PopupMenuDivider(), for (final Category category in _categories) - PopupMenuItem( - value: category, - child: Text(category.name), - ), + PopupMenuItem(value: category, child: Text(category.name)), ], ); @@ -409,9 +407,9 @@ class _HomeScreenState extends State { return; } - await Navigator.of(context).push( - MaterialPageRoute(builder: (_) => editor), - ); + await Navigator.of( + context, + ).push(MaterialPageRoute(builder: (_) => editor)); } Future _handleNoteTap(Note note, bool isDesktop) async { @@ -430,7 +428,8 @@ class _HomeScreenState extends State { } final Note movedNote = visibleNotes[oldIndex]; - final List remainingVisible = [...visibleNotes]..removeAt(oldIndex); + final List remainingVisible = [...visibleNotes] + ..removeAt(oldIndex); final int clampedNewIndex = newIndex.clamp(0, remainingVisible.length); int targetFullIndex; @@ -442,7 +441,9 @@ class _HomeScreenState extends State { targetFullIndex = _notes.length - 1; } else { final Note afterNote = remainingVisible[clampedNewIndex]; - targetFullIndex = _notes.indexWhere((Note note) => note.id == afterNote.id); + targetFullIndex = _notes.indexWhere( + (Note note) => note.id == afterNote.id, + ); if (targetFullIndex < 0) { targetFullIndex = 0; } @@ -501,7 +502,10 @@ class _HomeScreenState extends State { decoration: InputDecoration( hintText: 'Buscar notas...', hintStyle: TextStyle(color: palette.textSecondary), - prefixIcon: Icon(Icons.search, color: palette.textSecondary), + prefixIcon: Icon( + Icons.search, + color: palette.textSecondary, + ), suffixIcon: _searchQuery.isEmpty ? null : IconButton( @@ -582,10 +586,7 @@ class _HomeScreenState extends State { padding: const EdgeInsets.only(top: 8, bottom: 88), child: Text( _formatLastSyncAt(), - style: TextStyle( - color: palette.textSecondary, - fontSize: 12, - ), + style: TextStyle(color: palette.textSecondary, fontSize: 12), ), ), itemBuilder: (BuildContext context, int index) { @@ -598,6 +599,7 @@ class _HomeScreenState extends State { child: NoteCard( note: note, isSelected: note.id == _selectedNoteId, + showSelectionBorder: isDesktop, onTap: () => _handleNoteTap(note, isDesktop), onDelete: () => _deleteNote(note), onChangeCategory: (BuildContext buttonContext) => @@ -637,7 +639,8 @@ class _HomeScreenState extends State { final AppPalette palette = _paletteOf(context); final double leftWidth = (constraints.maxWidth * 0.34).clamp(320, 440); final Note? selectedNote = _selectedNote(); - final bool selectedIsVisible = selectedNote != null && + final bool selectedIsVisible = + selectedNote != null && _visibleNotes().any((Note note) => note.id == selectedNote.id); return Row( @@ -674,11 +677,11 @@ class _HomeScreenState extends State { padding: const EdgeInsets.all(16), child: AnimatedSwitcher( duration: const Duration(milliseconds: 220), - child: selectedIsVisible + child: selectedIsVisible ? NoteEditorScreen( - key: ValueKey(selectedNote.id), + key: ValueKey(selectedNote.id), repository: widget.repository, - note: selectedNote, + note: selectedNote, categories: _categories, embedded: true, onSaved: (Note saved) { diff --git a/lib/screens/note_editor_screen.dart b/lib/screens/note_editor_screen.dart index 2189259..9bca818 100644 --- a/lib/screens/note_editor_screen.dart +++ b/lib/screens/note_editor_screen.dart @@ -116,8 +116,8 @@ class _NoteEditorScreenState extends State { RelativeRect _menuRectFromContext(BuildContext anchorContext) { final RenderBox button = anchorContext.findRenderObject()! as RenderBox; - final RenderBox overlay = Overlay.of(anchorContext).context.findRenderObject()! - as RenderBox; + final RenderBox overlay = + Overlay.of(anchorContext).context.findRenderObject()! as RenderBox; final Offset topLeft = button.localToGlobal(Offset.zero, ancestor: overlay); final Offset bottomRight = button.localToGlobal( button.size.bottomRight(Offset.zero), @@ -125,12 +125,7 @@ class _NoteEditorScreenState extends State { ); return RelativeRect.fromRect( - Rect.fromLTRB( - topLeft.dx, - topLeft.dy, - bottomRight.dx, - bottomRight.dy, - ), + Rect.fromLTRB(topLeft.dx, topLeft.dy, bottomRight.dx, bottomRight.dy), Offset.zero & overlay.size, ); } @@ -157,7 +152,8 @@ class _NoteEditorScreenState extends State { isDirty: true, ); - final bool hasChanges = draft.title != _baselineNote.title || + final bool hasChanges = + draft.title != _baselineNote.title || draft.body != _baselineNote.body || draft.categoryId != _baselineNote.categoryId; @@ -206,10 +202,7 @@ class _NoteEditorScreenState extends State { ), const PopupMenuDivider(), for (final Category category in widget.categories) - PopupMenuItem( - value: category, - child: Text(category.name), - ), + PopupMenuItem(value: category, child: Text(category.name)), ], ); @@ -273,8 +266,11 @@ class _NoteEditorScreenState extends State { ); } - Widget _buildEditorBody() { + Widget _buildEditorBody({required bool embedded}) { final AppPalette palette = _paletteOf(context); + final BoxBorder? bodyBorder = embedded + ? null + : Border.all(color: palette.border); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -309,7 +305,7 @@ class _NoteEditorScreenState extends State { decoration: BoxDecoration( color: palette.transparent, borderRadius: BorderRadius.circular(16), - border: Border.all(color: palette.border), + border: bodyBorder, ), padding: const EdgeInsets.all(14), child: QuillEditor.basic( @@ -372,18 +368,16 @@ class _NoteEditorScreenState extends State { final Widget editor = Padding( padding: const EdgeInsets.all(20), - child: _buildEditorBody(), + child: _buildEditorBody(embedded: widget.embedded), ); if (widget.embedded) { - return Container(color: palette.cardBackground, child: editor); + return editor; } return Scaffold( backgroundColor: palette.cardBackground, - appBar: AppBar( - title: const Text('Editar nota'), - ), + appBar: AppBar(title: const Text('Editar nota')), body: SafeArea(child: editor), ); } diff --git a/lib/widgets/note_card.dart b/lib/widgets/note_card.dart index cd4b6ac..85b0be2 100644 --- a/lib/widgets/note_card.dart +++ b/lib/widgets/note_card.dart @@ -13,6 +13,7 @@ class NoteCard extends StatelessWidget { this.onTap, this.onDelete, this.onChangeCategory, + this.showSelectionBorder = true, }); final Note note; @@ -21,93 +22,96 @@ class NoteCard extends StatelessWidget { final VoidCallback? onTap; final VoidCallback? onDelete; final ValueChanged? onChangeCategory; + final bool showSelectionBorder; @override Widget build(BuildContext context) { final AppPalette palette = Theme.of(context).extension()!; final String bodyText = noteBodyToPlainText(note.body).trim(); -return Material( - color: Colors.transparent, // 1. Fondo completamente transparente - shape: BorderDirectional( - start: BorderSide( - color: isSelected ? palette.accent : Colors.transparent, - width: isSelected ? 1.6 : 1.0, - ), - ), - child: InkWell( - borderRadius: BorderRadius.circular(14), - onTap: onTap, - hoverColor: Colors.transparent, // 2. Desactiva el efecto hover (pasar el ratón) - splashColor: Colors.transparent, // 3. Desactiva el efecto de onda al hacer clic - highlightColor: Colors.transparent, // Desactiva el brillo al mantener pulsado - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - note.title.isEmpty ? 'Sin título' : note.title, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: palette.textPrimary, - fontSize: 15, - fontWeight: FontWeight.w700, - ), + return Material( + color: Colors.transparent, // 1. Fondo completamente transparente + shape: BorderDirectional( + start: BorderSide( + color: (isSelected && showSelectionBorder) + ? palette.accent + : Colors.transparent, + width: isSelected ? 1.6 : 1.0, + ), + ), + child: InkWell( + borderRadius: BorderRadius.circular(14), + onTap: onTap, + hoverColor: + Colors.transparent, // 2. Desactiva el efecto hover (pasar el ratón) + splashColor: + Colors.transparent, // 3. Desactiva el efecto de onda al hacer clic + highlightColor: + Colors.transparent, // Desactiva el brillo al mantener pulsado + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + note.title.isEmpty ? 'Sin título' : note.title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: palette.textPrimary, + fontSize: 15, + fontWeight: FontWeight.w700, + ), + ), + const SizedBox(height: 6), + Text( + bodyText.isEmpty ? ' ' : bodyText, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: palette.textSecondary, + fontSize: 13, + height: 1.2, + ), + ), + ], ), - const SizedBox(height: 6), - Text( - bodyText.isEmpty ? ' ' : bodyText, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: palette.textSecondary, - fontSize: 13, - height: 1.2, - ), - ), - ], - ), - ), - const SizedBox(width: 8), - PopupMenuButton( - tooltip: 'Más opciones', - icon: Icon( - Icons.more_vert, - color: palette.textSecondary, - ), - onOpened: () {}, - onSelected: (String value) { - switch (value) { - case 'delete': - onDelete?.call(); - return; - case 'category': - onChangeCategory?.call(context); - return; - } - }, - itemBuilder: (BuildContext context) => >[ - const PopupMenuItem( - value: 'delete', - child: Text('Eliminar nota'), ), - const PopupMenuItem( - value: 'category', - child: Text('Cambiar categoría'), + const SizedBox(width: 8), + PopupMenuButton( + tooltip: 'Más opciones', + icon: Icon(Icons.more_vert, color: palette.textSecondary), + onOpened: () {}, + onSelected: (String value) { + switch (value) { + case 'delete': + onDelete?.call(); + return; + case 'category': + onChangeCategory?.call(context); + return; + } + }, + itemBuilder: (BuildContext context) => >[ + const PopupMenuItem( + value: 'delete', + child: Text('Eliminar nota'), + ), + const PopupMenuItem( + value: 'category', + child: Text('Cambiar categoría'), + ), + ], ), ], ), - ], + ), ), - ), - ), -); -} + ); + } }