fix(ui): the gear and socials drawers retract on an outside click

Reported 2026-11-05: those two tabs stayed open when clicking elsewhere, unlike Stream Settings, YPP
and TEST. All five drawers share one host (TextPullOutHost), but the window's click-outside guard only
listed the other three, so the gear and socials panels had no way to dismiss except their own tab.

The guard now closes them too, and a test pins both directions: an outside click retracts the drawer,
and a click inside it does not.
This commit is contained in:
2026-11-05 17:14:40 -08:00
parent a1d861608f
commit 3261293d57
3 changed files with 82 additions and 2 deletions
+4
View File
@@ -201,6 +201,10 @@ public partial class MainWindow : Window
if (form.IsDrawerOpen) form.CloseDrawerCommand.Execute(null);
if (ypp.IsDrawerOpen) ypp.CloseDrawerCommand.Execute(null);
if (test.IsDrawerOpen) test.CloseDrawerCommand.Execute(null);
// The Settings (gear) and Socials drawers live in the same host but were left out of this
// guard, so clicking anywhere else left them open (reported 2026-11-05).
_viewModel.CloseSettingsDrawerIfOpen();
_viewModel.CloseSocialsDrawer();
}
if (_previewPane.IsClickInsidePreview(original)) return;
if (_leftPanel.IsClickInside(original)) return;
+3 -2
View File
@@ -34,8 +34,9 @@ public partial class MainViewModel
SettingsDrawerOpen = true;
}
/// <summary>Called by the other drawers when they open, so settings yields to them.</summary>
private void CloseSettingsDrawerIfOpen()
/// <summary>Called by the other drawers when they open, so settings yields to them — and by the
/// window's click-outside guard, so the gear tab retracts like every other drawer (2026-11-05).</summary>
internal void CloseSettingsDrawerIfOpen()
{
if (_settingsDrawerOpen) SettingsDrawerOpen = false;
}
+75
View File
@@ -0,0 +1,75 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Input;
using Microsoft.Data.Sqlite;
using Xunit;
using ytLive.ViewModels;
namespace ytLive.Tests;
/// <summary>
/// 2026-11-05 report: "the gear-icon tab and the socials tab do not retract when I click off the div,
/// like the other tabs." Both drawers live in the same host as Stream Settings / YPP / TEST, but the
/// window's click-outside guard only knew about the other three.
/// </summary>
[Collection("RealApp")]
public sealed class DrawerOutsideClickTests
{
private readonly RealAppHost _app;
public DrawerOutsideClickTests(RealAppHost app) => _app = app;
[Fact]
public void ClickingOutside_RetractsTheSettingsAndSocialsDrawers()
{
_app.Run(() =>
{
var tempDb = Path.Combine(Path.GetTempPath(), $"ytLlive-drawers-{Guid.NewGuid():N}.db");
MainViewModel.LayoutPathOverride = tempDb;
var window = new MainWindow();
var vm = (MainViewModel)window.DataContext;
try
{
window.Show();
window.UpdateLayout();
// Open the gear drawer, then click somewhere that is not the drawer host.
vm.ToggleSettingsDrawer();
Assert.True(vm.SettingsDrawerOpen);
RaiseOutsideClick(window);
Assert.False(vm.SettingsDrawerOpen);
// …and clicking INSIDE the drawer must not close it, or the panel would be unusable.
vm.ToggleSettingsDrawer();
Assert.True(vm.SettingsDrawerOpen);
var pane = (System.Windows.Controls.UserControl)window.FindName("PreviewPane")!;
var host = (FrameworkElement)pane.FindName("TextPullOutHost")!;
RaiseClickOn(host);
Assert.True(vm.SettingsDrawerOpen);
}
finally
{
window.Close();
MainViewModel.LayoutPathOverride = null;
SqliteConnection.ClearAllPools();
try { File.Delete(tempDb); } catch { /* best-effort cleanup */ }
}
});
}
/// <summary>A left-button-down that originates on the window itself — outside the preview, the left
/// panel and the drawer host, which is exactly the case the guard handles.</summary>
private static void RaiseOutsideClick(Window window) => RaiseClickOn(window);
private static void RaiseClickOn(UIElement target)
{
var args = new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, MouseButton.Left)
{
RoutedEvent = UIElement.PreviewMouseLeftButtonDownEvent,
Source = target,
};
target.RaiseEvent(args);
}
}