From 8e888dde581a2ffa00942970c679827763198f8f Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Wed, 31 Dec 2025 11:34:33 -0500 Subject: [PATCH] chore: collapse navigation rail on navigate (#5013) --- .../spaces/space_navigation_column.dart | 53 +++++++++++++++---- lib/widgets/navigation_rail.dart | 16 +++++- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/lib/pangea/spaces/space_navigation_column.dart b/lib/pangea/spaces/space_navigation_column.dart index a8dbed70e..0b52100e2 100644 --- a/lib/pangea/spaces/space_navigation_column.dart +++ b/lib/pangea/spaces/space_navigation_column.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; @@ -27,7 +29,39 @@ class SpaceNavigationColumn extends StatefulWidget { } class SpaceNavigationColumnState extends State { - bool _expand = false; + bool _expanded = false; + Timer? _debounceTimer; + + @override + void dispose() { + _debounceTimer?.cancel(); + _debounceTimer = null; + super.dispose(); + } + + void _expand() { + if (_debounceTimer?.isActive == true) return; + if (!_expanded) { + setState(() => _expanded = true); + } + } + + void _collapse() { + if (_expanded) { + setState(() { + _expanded = false; + _debounce(); + }); + } + } + + void _debounce() { + _debounceTimer?.cancel(); + _debounceTimer = Timer(const Duration(milliseconds: 300), () { + _debounceTimer?.cancel(); + _debounceTimer = null; + }); + } @override Widget build(BuildContext context) { @@ -63,7 +97,7 @@ class SpaceNavigationColumnState extends State { return AnimatedContainer( duration: FluffyThemes.animationDuration, - width: _expand ? expandedWidth : baseWidth, + width: _expanded ? expandedWidth : baseWidth, child: Stack( children: [ if (isColumnMode) @@ -91,13 +125,9 @@ class SpaceNavigationColumnState extends State { if (showNavRail) HoverBuilder( builder: (context, hovered) { - if (_expand != hovered) { - WidgetsBinding.instance.addPostFrameCallback((_) { - setState(() { - _expand = hovered; - }); - }); - } + WidgetsBinding.instance.addPostFrameCallback((_) { + hovered ? _expand() : _collapse(); + }); return Row( mainAxisSize: MainAxisSize.min, @@ -105,10 +135,11 @@ class SpaceNavigationColumnState extends State { SpacesNavigationRail( activeSpaceId: widget.state.pathParameters['spaceid'], path: widget.state.fullPath, - railWidth: _expand + railWidth: _expanded ? navRailWidth + navRailExtraWidth : navRailWidth, - expanded: _expand, + expanded: _expanded, + collapse: _collapse, ), Container( width: 1, diff --git a/lib/widgets/navigation_rail.dart b/lib/widgets/navigation_rail.dart index 7c6b887eb..148daa1f1 100644 --- a/lib/widgets/navigation_rail.dart +++ b/lib/widgets/navigation_rail.dart @@ -24,6 +24,7 @@ class SpacesNavigationRail extends StatelessWidget { final String? path; final double railWidth; final bool expanded; + final VoidCallback collapse; // Pangea# const SpacesNavigationRail({ @@ -33,6 +34,7 @@ class SpacesNavigationRail extends StatelessWidget { // required this.onGoToSpaceId, required this.path, required this.railWidth, + required this.collapse, this.expanded = false, // Pangea# super.key, @@ -99,6 +101,7 @@ class SpacesNavigationRail extends StatelessWidget { return NaviRailItem( isSelected: isAnalytics, onTap: () { + collapse(); AnalyticsNavigationUtil.navigateToAnalytics( context: context, ); @@ -152,7 +155,10 @@ class SpacesNavigationRail extends StatelessWidget { // unreadBadgeFilter: (room) => true, icon: const Icon(Icons.forum_outlined), selectedIcon: const Icon(Icons.forum), - onTap: () => context.go("/rooms"), + onTap: () { + collapse(); + context.go("/rooms"); + }, toolTip: L10n.of(context).directMessages, unreadBadgeFilter: (room) => room.firstSpaceParent == null, @@ -175,6 +181,7 @@ class SpacesNavigationRail extends StatelessWidget { borderRadius: BorderRadius.circular(0), isSelected: isCourse, onTap: () { + collapse(); context.go('/rooms/course'); }, icon: ClipPath( @@ -212,6 +219,7 @@ class SpacesNavigationRail extends StatelessWidget { borderRadius: BorderRadius.circular(0), // onTap: () => onGoToSpaceId(rootSpaces[i].id), onTap: () { + collapse(); final room = client.getRoomById(rootSpaces[i].id); if (room != null) { chatListHandleSpaceTap( @@ -279,8 +287,8 @@ class SpacesNavigationRail extends StatelessWidget { ), NaviRailItem( isSelected: isSettings, - onTap: () => context.go('/rooms/settings'), // #Pangea + // onTap: () => context.go('/rooms/settings'), // icon: const Padding( // padding: EdgeInsets.all(10.0), // child: Icon(Icons.settings_outlined), @@ -289,6 +297,10 @@ class SpacesNavigationRail extends StatelessWidget { // padding: EdgeInsets.all(10.0), // child: Icon(Icons.settings), // ), + onTap: () { + collapse(); + context.go('/rooms/settings'); + }, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings), expanded: expanded,