TASK 4 ship step 5.5: social bar bug fixes + bar on the live output — direction-snap drag (SocialBarSnap.Decide + ClearValue, local Canvas.Top was overriding the binding), fediverse nodeinfo subdomain probing + load-time heal (settable FediverseSoftware), SocialBarRenderer strip blitted above the flash via a re-read FramePump socialBar seam — 155 tests passing, 0 warnings

This commit is contained in:
2026-08-13 09:29:58 -07:00
parent e72ba71165
commit ac60a26d82
16 changed files with 666 additions and 52 deletions
+26 -7
View File
@@ -254,18 +254,20 @@ public partial class MainWindow : Window
private void OpacitySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
=> OpacityValueText.Text = $"{Math.Round(e.NewValue * 100)}%";
// ─── Social bar drag: vertical only, snaps to top/bottom on release ───
// ─── Social bar drag: vertical only, direction-snaps to the top/bottom edge ───
private const double SocialBarBottomTop = 1040;
private bool _isDraggingSocialBar;
private double _socialBarGrabOffsetY;
private double _socialBarDragStartY;
private SocialBarPosition? _socialBarDragDirection;
private void SocialBar_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var bar = (FrameworkElement)sender;
_isDraggingSocialBar = true;
_socialBarDragDirection = null;
var toCanvas = CanvasGrid.TransformToVisual(bar).Inverse;
var p = toCanvas.Transform(e.GetPosition(bar));
_socialBarGrabOffsetY = p.Y - Canvas.GetTop(bar);
_socialBarDragStartY = p.Y;
bar.CaptureMouse();
e.Handled = true;
}
@@ -276,7 +278,17 @@ public partial class MainWindow : Window
var bar = (FrameworkElement)sender;
var toCanvas = CanvasGrid.TransformToVisual(bar).Inverse;
var p = toCanvas.Transform(e.GetPosition(bar));
Canvas.SetTop(bar, Math.Clamp(p.Y - _socialBarGrabOffsetY, 0, SocialBarBottomTop));
// Derive the drag direction once it commits (past the deadzone) and keep it
// for the rest of the drag — the bar snaps to the edge it's being dragged
// toward and is never left mid-screen.
var direction = _socialBarDragDirection
?? SocialBarSnap.Decide(p.Y - _socialBarDragStartY);
if (direction != null)
{
_socialBarDragDirection = direction;
Canvas.SetTop(bar, direction == SocialBarPosition.Top ? 0 : SocialBarBottomTop);
}
e.Handled = true;
}
@@ -284,11 +296,18 @@ public partial class MainWindow : Window
{
if (!_isDraggingSocialBar) return;
var bar = (FrameworkElement)sender;
var top = Canvas.GetTop(bar);
bar.ReleaseMouseCapture();
_isDraggingSocialBar = false;
var position = top <= SocialBarBottomTop / 2.0 ? SocialBarPosition.Top : SocialBarPosition.Bottom;
_viewModel.SetSocialBarPosition(position);
var direction = _socialBarDragDirection
?? (Canvas.GetTop(bar) <= SocialBarBottomTop / 2.0
? SocialBarPosition.Top : SocialBarPosition.Bottom);
// ClearValue removes the local value Canvas.SetTop applied during the drag —
// a local value permanently overrides the {Binding SocialBarTop}, which is
// why the release snap never used to show. Clearing re-engages the binding.
bar.ClearValue(Canvas.TopProperty);
_viewModel.SetSocialBarPosition(direction);
e.Handled = true;
}