diff --git a/lib/main.dart b/lib/main.dart index 75aaa20..71a3cf0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -701,6 +701,10 @@ class _SidebarState extends State<_Sidebar> static const double _channelRowH = 28; static const double _rowGap = 8; late final AnimationController _ctrl; + // True while the channel-switch menu is open — suppresses the + // hover-exit collapse so the rail stays expanded and the menu stays + // aligned to the pill (otherwise it floats at the pill's old x). + bool _menuOpen = false; @override void initState() { @@ -760,7 +764,9 @@ class _SidebarState extends State<_Sidebar> widget.activeChannel != null && widget.activeChannel!.isNotEmpty; return MouseRegion( onEnter: widget.forceExpanded ? null : (_) => _ctrl.forward(), - onExit: widget.forceExpanded ? null : (_) => _ctrl.reverse(), + onExit: (widget.forceExpanded || _menuOpen) + ? null + : (_) => _ctrl.reverse(), child: AnimatedBuilder( animation: _ctrl, builder: (context, _) { @@ -843,7 +849,18 @@ class _SidebarState extends State<_Sidebar> channel: widget.activeChannel!, ), ), - label: _ChannelPill(channel: widget.activeChannel!), + label: _ChannelPill( + channel: widget.activeChannel!, + onMenuOpen: () { + setState(() => _menuOpen = true); + _ctrl.forward(); + }, + onMenuClose: () { + if (!mounted) return; + setState(() => _menuOpen = false); + _ctrl.reverse(); + }, + ), t: t, labelsInteractive: labelsInteractive, ) @@ -1140,7 +1157,17 @@ class _ChannelMenuItem extends StatelessWidget { /// unmistakeable. class _ChannelPill extends StatelessWidget { final String channel; - const _ChannelPill({required this.channel}); + + /// Fired when the switch menu opens / closes so the parent sidebar can + /// stay expanded while it's up — otherwise the hover-exit collapses the + /// rail and the menu floats at the pill's old (expanded) position. + final VoidCallback? onMenuOpen; + final VoidCallback? onMenuClose; + const _ChannelPill({ + required this.channel, + this.onMenuOpen, + this.onMenuClose, + }); @override Widget build(BuildContext context) { @@ -1154,7 +1181,11 @@ class _ChannelPill extends StatelessWidget { borderRadius: BorderRadius.circular(ChainRadius.sm), child: InkWell( borderRadius: BorderRadius.circular(ChainRadius.sm), - onTap: () => _showChannelSwitchMenu(context, channel), + onTap: () async { + onMenuOpen?.call(); + await _showChannelSwitchMenu(context, channel); + onMenuClose?.call(); + }, child: Container( padding: const EdgeInsets.symmetric( horizontal: ChainSpace.sm,