feat: Implement menu open/close functionality in HomeScreen for improved user interaction

This commit is contained in:
2026-05-19 20:24:03 +02:00
parent 4912316845
commit 6035e3bc18
+91 -45
View File
@@ -50,6 +50,26 @@ class _HomeScreenState extends State<HomeScreen> {
bool _showDeletedNotes = false; bool _showDeletedNotes = false;
PointerDeviceKind _lastPointerKind = PointerDeviceKind.mouse; PointerDeviceKind _lastPointerKind = PointerDeviceKind.mouse;
void _openMenu() {
if (_isMenuOpen) {
return;
}
setState(() {
_isMenuOpen = true;
});
}
void _closeMenu() {
if (!_isMenuOpen) {
return;
}
setState(() {
_isMenuOpen = false;
});
}
bool _requiresLongPressToDrag(PointerDeviceKind kind) { bool _requiresLongPressToDrag(PointerDeviceKind kind) {
return kind == PointerDeviceKind.touch || return kind == PointerDeviceKind.touch ||
kind == PointerDeviceKind.stylus || kind == PointerDeviceKind.stylus ||
@@ -172,9 +192,7 @@ class _HomeScreenState extends State<HomeScreen> {
} }
Future<void> _handleMenuItemTapped(String item) async { Future<void> _handleMenuItemTapped(String item) async {
setState(() { _closeMenu();
_isMenuOpen = false;
});
if (item == 'settings') { if (item == 'settings') {
widget.onOpenSettings(); widget.onOpenSettings();
@@ -209,8 +227,8 @@ class _HomeScreenState extends State<HomeScreen> {
final Widget body = _isLoading final Widget body = _isLoading
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: _notes.isEmpty : _notes.isEmpty
? _EmptyState(showDeletedNotes: _showDeletedNotes) ? _EmptyState(showDeletedNotes: _showDeletedNotes)
: RefreshIndicator( : RefreshIndicator(
onRefresh: () async { onRefresh: () async {
await widget.onRequestSync(); await widget.onRequestSync();
}, },
@@ -546,53 +564,81 @@ class _HomeScreenState extends State<HomeScreen> {
}, },
), ),
Expanded( Expanded(
child: Stack( child: Listener(
children: [ onPointerDown: (PointerDownEvent event) {
Padding( if (_lastPointerKind == event.kind) {
padding: const EdgeInsets.symmetric( return;
horizontal: 12.0, }
vertical: 8.0,
setState(() {
_lastPointerKind = event.kind;
});
},
child: Stack(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12.0,
vertical: 8.0,
),
child: body,
), ),
child: body, Positioned(
), left: 0,
Positioned.fill( top: 0,
child: IgnorePointer( bottom: 0,
ignoring: !_isMenuOpen, width: 28,
child: AnimatedOpacity( child: IgnorePointer(
duration: const Duration(milliseconds: 300), ignoring:
opacity: _isMenuOpen ? 0.5 : 0.0, _isMenuOpen ||
curve: Curves.easeOutCubic, !_requiresLongPressToDrag(_lastPointerKind),
child: GestureDetector( child: GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.translucent,
onTap: () { onHorizontalDragUpdate:
setState(() { (DragUpdateDetails details) {
_isMenuOpen = false; if ((details.primaryDelta ?? 0) > 6) {
}); _openMenu();
}, }
child: Container(color: Colors.black), },
child: const SizedBox.expand(),
), ),
), ),
), ),
), Positioned.fill(
AnimatedPositioned( child: IgnorePointer(
duration: const Duration(milliseconds: 300), ignoring: !_isMenuOpen,
curve: Curves.easeOutCubic, child: AnimatedOpacity(
left: _isMenuOpen ? 0 : -280, duration: const Duration(milliseconds: 300),
top: 0, opacity: _isMenuOpen ? 0.5 : 0.0,
bottom: 0, curve: Curves.easeOutCubic,
width: 280, child: GestureDetector(
child: Material( behavior: HitTestBehavior.opaque,
color: const Color.fromRGBO(24, 25, 26, 1), onTap: _closeMenu,
elevation: 8, child: Container(color: Colors.black),
child: MenuDrawer( ),
onMenuItemTapped: _handleMenuItemTapped, ),
selectedItem: _showDeletedNotes
? 'deleted_notes'
: 'all_notes',
), ),
), ),
), AnimatedPositioned(
], duration: const Duration(milliseconds: 300),
curve: Curves.easeOutCubic,
left: _isMenuOpen ? 0 : -280,
top: 0,
bottom: 0,
width: 280,
child: Material(
color: const Color.fromRGBO(24, 25, 26, 1),
elevation: 8,
child: MenuDrawer(
onMenuItemTapped: _handleMenuItemTapped,
selectedItem: _showDeletedNotes
? 'deleted_notes'
: 'all_notes',
),
),
),
],
),
), ),
), ),
], ],