Refactor SettingsScreen and SearchAppBar: remove unused menu logic and enhance navigation features
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:notas/widgets/app_title_bar.dart';
|
import 'package:notas/widgets/app_title_bar.dart';
|
||||||
import 'package:notas/widgets/menu_drawer.dart';
|
|
||||||
import 'package:notas/widgets/search_app_bar.dart';
|
import 'package:notas/widgets/search_app_bar.dart';
|
||||||
|
|
||||||
class SettingsScreen extends StatefulWidget {
|
class SettingsScreen extends StatefulWidget {
|
||||||
@@ -17,38 +16,6 @@ class SettingsScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _SettingsScreenState extends State<SettingsScreen> {
|
class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
bool _isBusy = false;
|
bool _isBusy = false;
|
||||||
bool _isMenuOpen = false;
|
|
||||||
final GlobalKey _headerKey = GlobalKey();
|
|
||||||
double _menuTopInset = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
_updateMenuTopInset();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateMenuTopInset() {
|
|
||||||
final BuildContext? headerContext = _headerKey.currentContext;
|
|
||||||
if (headerContext == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final RenderObject? renderObject = headerContext.findRenderObject();
|
|
||||||
if (renderObject is! RenderBox) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final double newInset = renderObject.size.height;
|
|
||||||
if ((newInset - _menuTopInset).abs() < 0.5) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
_menuTopInset = newInset;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _confirmAndDeleteAll() async {
|
Future<void> _confirmAndDeleteAll() async {
|
||||||
final bool? confirmed = await showDialog<bool>(
|
final bool? confirmed = await showDialog<bool>(
|
||||||
@@ -92,22 +59,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleMenuItemTapped(String item) {
|
|
||||||
setState(() {
|
|
||||||
_isMenuOpen = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (item == 'all_notes') {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
_updateMenuTopInset();
|
|
||||||
});
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
@@ -122,80 +75,35 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: Stack(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Column(
|
const AppTitleBar(),
|
||||||
children: [
|
SearchAppBar(
|
||||||
Column(
|
onLeadingPressed: () => Navigator.of(context).pop(),
|
||||||
key: _headerKey,
|
leadingIcon: Icons.arrow_back,
|
||||||
mainAxisSize: MainAxisSize.min,
|
leadingTooltip: 'Atrás',
|
||||||
children: [
|
showSearch: false,
|
||||||
const AppTitleBar(),
|
titleText: 'Configuración',
|
||||||
SearchAppBar(
|
),
|
||||||
onMenuPressed: () {
|
Expanded(
|
||||||
setState(() {
|
child: Padding(
|
||||||
_isMenuOpen = !_isMenuOpen;
|
padding: const EdgeInsets.all(16.0),
|
||||||
});
|
child: Column(
|
||||||
},
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
showSearch: false,
|
children: [
|
||||||
titleText: 'Configuración',
|
ElevatedButton.icon(
|
||||||
),
|
style: ElevatedButton.styleFrom(backgroundColor: Colors.redAccent),
|
||||||
],
|
onPressed: _isBusy ? null : _confirmAndDeleteAll,
|
||||||
),
|
icon: _isBusy ? const SizedBox(width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2)) : const Icon(Icons.delete_forever),
|
||||||
Expanded(
|
label: const Text('Borrar todos los datos'),
|
||||||
child: Padding(
|
),
|
||||||
padding: const EdgeInsets.all(16.0),
|
const SizedBox(height: 16),
|
||||||
child: Column(
|
const Text('Esto cerrará el vault actual y eliminará la base de datos local junto con la clave de cifrado.'),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
],
|
||||||
children: [
|
|
||||||
ElevatedButton.icon(
|
|
||||||
style: ElevatedButton.styleFrom(backgroundColor: Colors.redAccent),
|
|
||||||
onPressed: _isBusy ? null : _confirmAndDeleteAll,
|
|
||||||
icon: _isBusy ? const SizedBox(width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2)) : const Icon(Icons.delete_forever),
|
|
||||||
label: const Text('Borrar todos los datos'),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
const Text('Esto cerrará el vault actual y eliminará la base de datos local junto con la clave de cifrado.'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Positioned.fill(
|
|
||||||
top: _menuTopInset,
|
|
||||||
child: IgnorePointer(
|
|
||||||
ignoring: !_isMenuOpen,
|
|
||||||
child: AnimatedOpacity(
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
opacity: _isMenuOpen ? 0.5 : 0.0,
|
|
||||||
curve: Curves.easeOutCubic,
|
|
||||||
child: GestureDetector(
|
|
||||||
behavior: HitTestBehavior.opaque,
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
_isMenuOpen = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Container(color: Colors.black),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
AnimatedPositioned(
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeOutCubic,
|
|
||||||
left: _isMenuOpen ? 0 : -280,
|
|
||||||
top: _menuTopInset,
|
|
||||||
bottom: 0,
|
|
||||||
width: 280,
|
|
||||||
child: Material(
|
|
||||||
color: const Color.fromRGBO(24, 25, 26, 1),
|
|
||||||
elevation: 8,
|
|
||||||
child: MenuDrawer(onMenuItemTapped: _handleMenuItemTapped),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ class SearchAppBar extends StatefulWidget {
|
|||||||
const SearchAppBar({
|
const SearchAppBar({
|
||||||
super.key,
|
super.key,
|
||||||
this.onMenuPressed,
|
this.onMenuPressed,
|
||||||
|
this.onLeadingPressed,
|
||||||
|
this.leadingIcon = Icons.menu,
|
||||||
|
this.leadingTooltip = 'Menú',
|
||||||
this.onSearchChanged,
|
this.onSearchChanged,
|
||||||
this.searchHint = 'Buscar notas...',
|
this.searchHint = 'Buscar notas...',
|
||||||
this.showSearch = true,
|
this.showSearch = true,
|
||||||
@@ -11,6 +14,9 @@ class SearchAppBar extends StatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final VoidCallback? onMenuPressed;
|
final VoidCallback? onMenuPressed;
|
||||||
|
final VoidCallback? onLeadingPressed;
|
||||||
|
final IconData leadingIcon;
|
||||||
|
final String leadingTooltip;
|
||||||
final ValueChanged<String>? onSearchChanged;
|
final ValueChanged<String>? onSearchChanged;
|
||||||
final String searchHint;
|
final String searchHint;
|
||||||
final bool showSearch;
|
final bool showSearch;
|
||||||
@@ -50,11 +56,10 @@ class _SearchAppBarState extends State<SearchAppBar> {
|
|||||||
padding: const EdgeInsets.only(left: 16, right: 16, top: 7, bottom: 7),
|
padding: const EdgeInsets.only(left: 16, right: 16, top: 7, bottom: 7),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
// Menu button (fixed on left)
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: widget.onMenuPressed,
|
onPressed: widget.onLeadingPressed ?? widget.onMenuPressed,
|
||||||
icon: const Icon(Icons.menu, color: Colors.white70, size: 20),
|
icon: Icon(widget.leadingIcon, color: Colors.white70, size: 20),
|
||||||
tooltip: 'Menú',
|
tooltip: widget.leadingTooltip,
|
||||||
splashRadius: 18,
|
splashRadius: 18,
|
||||||
constraints: const BoxConstraints(minWidth: 40, minHeight: 40),
|
constraints: const BoxConstraints(minWidth: 40, minHeight: 40),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user