Right rail, top bar, bottom bar and chat border: Socials slide-out drawer, tab icons and colors, EDIT toggle, stream readouts moved to the top-left cell, webcam border restored, chat border controls, 30fps vertical tier

- Socials: the dialog is a right-rail drawer (same pattern as Stream Info/YPP/TEST); the live-screen button is removed
- Right rail: Stream Info (was Stream Settings) and YPP show the YouTube logo; Socials and TEST get icons; tab colors and label colors per spec
- Top bar: EDIT toggle beside REC (orange when on, blue when off); going live on YouTube turns it off
- Stream readouts (bitrate, FPS, dropped n (x.y%), Live hh:mm:ss, health) and the resolution dropdown moved to the top-left cell; bottom bar emptied at the same height
- Webcam border drawing restored (it was removed with the CRT bezel change)
- YouTube chat layer: border color, thickness, and opacity controls
- Vertical 1080p30 tier added

Not related to the fps gate yet; no gating is enforced.
This commit is contained in:
2026-10-26 18:24:09 -07:00
parent a8814b42d0
commit 7ae30d4cfc
13 changed files with 341 additions and 102 deletions
+150 -23
View File
@@ -1,7 +1,8 @@
<UserControl x:Class="ytLive.Controls.PreviewPane"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Helpers="clr-namespace:ytLive.Helpers">
xmlns:Helpers="clr-namespace:ytLive.Helpers"
xmlns:local="clr-namespace:ytLive">
<Border Background="#0a0a1a" CornerRadius="6" Margin="8,0"
BorderBrush="{Binding PreviewGlowBrush}" BorderThickness="{Binding PreviewGlowThickness}">
<Grid>
@@ -181,6 +182,50 @@
</Viewbox>
<!-- OBS-style border: stroked rect (Traditional) / centered circle (Round).
Animations are driven by code-behind in WebcamMenu_SetBorderAnimation
because DataTrigger storyboards in DataTemplates cannot be stopped
(no ExitActions namescope support). -->
<Rectangle IsHitTestVisible="False"
Stroke="{Binding BorderBrush}"
StrokeThickness="{Binding BorderWidth}">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding HasBorder}" Value="True"/>
<Condition Binding="{Binding ClipShape}" Value="Traditional"/>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<Ellipse IsHitTestVisible="False"
Stroke="{Binding BorderBrush}"
StrokeThickness="{Binding BorderWidth}"
Width="{Binding RoundBorderSize}"
Height="{Binding RoundBorderSize}"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding HasBorder}" Value="True"/>
<Condition Binding="{Binding ClipShape}" Value="Round"/>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<Grid.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Change Webcam…" Click="WebcamMenu_ChangeWebcam"
@@ -267,8 +312,8 @@
<Grid x:Name="SelectionOverlay" IsHitTestVisible="False"
Canvas.Left="{Binding SelectedElement.X}" Canvas.Top="{Binding SelectedElement.Y}"
Width="{Binding SelectedElement.Width}" Height="{Binding SelectedElement.Height}">
<Rectangle Stroke="#e94560" StrokeDashArray="4 3" StrokeThickness="3"/>
<Ellipse Width="26" Height="26" Fill="#e94560" Stroke="White" StrokeThickness="2"
<Rectangle Stroke="#ff8c3a" StrokeDashArray="4 3" StrokeThickness="5"/>
<Ellipse Width="26" Height="26" Fill="#ff8c3a" Stroke="White" StrokeThickness="2"
HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-13,-13"/>
</Grid>
@@ -516,6 +561,63 @@
</StackPanel>
</Grid>
</Border>
<!-- The Socials drawer (same pattern as the other pull-outs) -->
<Border Background="#16213e" ClipToBounds="True">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Width" Value="0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SocialsDrawerOpen}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
To="320" Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
To="0" Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Width="320" Margin="14,10,14,12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="0,0,0,8">
<TextBlock Text="SOCIALS" Style="{StaticResource SectionHeader}" HorizontalAlignment="Left"/>
<Button HorizontalAlignment="Right" VerticalAlignment="Top"
Background="Transparent" BorderThickness="0" Cursor="Hand"
Command="{Binding OpenSocialDialogCommand}"
ToolTip="Close">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Button.Template>
<TextBlock Text="✕" Foreground="#a0a0b0" FontSize="14" FontWeight="Bold"/>
</Button>
</Grid>
<local:SocialsDialog Grid.Row="1" DataContext="{Binding SocialsDrawer}"/>
</Grid>
</Border>
<!-- The YPP-progress drawer (below Stream Settings on the rail) -->
<Border Background="#16213e" ClipToBounds="True">
<Border.Style>
@@ -750,47 +852,86 @@
</Border>
<!-- The stacked white tabs -->
<StackPanel Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<Border Width="30" VerticalAlignment="Center" Background="#ffffff"
<Border Width="30" VerticalAlignment="Center" Background="#ff5451"
CornerRadius="4,0,0,4" Padding="0,10" Cursor="Hand" Margin="0,4,0,0"
ToolTip="Broadcast text fields">
<Border.InputBindings>
<MouseBinding Gesture="LeftClick"
Command="{Binding BroadcastForm.ToggleDrawerCommand}"/>
</Border.InputBindings>
<TextBlock Text="Stream Settings" Foreground="#e94560" FontWeight="Bold" FontSize="15"
<StackPanel HorizontalAlignment="Center">
<Border Width="18" Height="13" CornerRadius="3" Background="White" HorizontalAlignment="Center" Margin="0,0,0,6">
<Border.LayoutTransform><RotateTransform Angle="90"/></Border.LayoutTransform>
<Path Data="M0,0 L6,3.5 L0,7 Z" Fill="#ff0000" Width="6" Height="7"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<TextBlock Text="Stream Info" Foreground="White" FontWeight="Bold" FontSize="15"
HorizontalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</StackPanel>
</Border>
<Border Width="30" VerticalAlignment="Center" Background="#ffffff"
<Border Width="30" VerticalAlignment="Center" Background="#ff5451"
CornerRadius="4,0,0,4" Padding="0,10" Cursor="Hand" Margin="0,4,0,0"
ToolTip="YouTube Partner Program progress">
<Border.InputBindings>
<MouseBinding Gesture="LeftClick"
Command="{Binding Ypp.ToggleDrawerCommand}"/>
</Border.InputBindings>
<TextBlock Text="YPP" Foreground="#e94560" FontWeight="Bold" FontSize="15"
<StackPanel HorizontalAlignment="Center">
<Border Width="18" Height="13" CornerRadius="3" Background="White" HorizontalAlignment="Center" Margin="0,0,0,6">
<Border.LayoutTransform><RotateTransform Angle="90"/></Border.LayoutTransform>
<Path Data="M0,0 L6,3.5 L0,7 Z" Fill="#ff0000" Width="6" Height="7"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<TextBlock Text="YPP" Foreground="White" FontWeight="Bold" FontSize="15"
HorizontalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</StackPanel>
</Border>
<Border Width="30" VerticalAlignment="Center" Background="#ffffff"
<Border Width="30" VerticalAlignment="Center" Background="#3b82f6"
CornerRadius="4,0,0,4" Padding="0,10" Cursor="Hand" Margin="0,4,0,0"
ToolTip="Add or manage your social handles">
<Border.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding OpenSocialDialogCommand}"/>
</Border.InputBindings>
<StackPanel HorizontalAlignment="Center">
<Path Data="M4,4 m-2,0 a2,2 0 1 0 4,0 a2,2 0 1 0 -4,0 M16,8 m-2,0 a2,2 0 1 0 4,0 a2,2 0 1 0 -4,0 M4,14 m-2,0 a2,2 0 1 0 4,0 a2,2 0 1 0 -4,0 M5.8,5.2 L14.2,7.2 M5.8,12.8 L14.2,8.8"
Stroke="#0b1326" StrokeThickness="1.5" Width="18" Height="18" Stretch="Uniform"
HorizontalAlignment="Center" Margin="0,0,0,6">
<Path.LayoutTransform><RotateTransform Angle="90"/></Path.LayoutTransform></Path>
<TextBlock Text="Socials" Foreground="#0b1326" FontWeight="Bold" FontSize="15"
HorizontalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</StackPanel>
</Border>
<Border Width="30" VerticalAlignment="Center" Background="#ff8c3a"
CornerRadius="4,0,0,4" Padding="0,10" Cursor="Hand" Margin="0,4,0,0"
ToolTip="Test stream — mock chat input and simulated events">
<Border.InputBindings>
<MouseBinding Gesture="LeftClick"
Command="{Binding TestSession.ToggleDrawerCommand}"/>
</Border.InputBindings>
<TextBlock Text="TEST" Foreground="#9c6f1c" FontWeight="Bold" FontSize="15"
<StackPanel HorizontalAlignment="Center">
<Path Data="M8,2 H16 M9,2 V8 L4,18 H20 L15,8 V2 M7,14 H17"
Stroke="#0b1326" StrokeThickness="1.5" Width="18" Height="18" Stretch="Uniform"
HorizontalAlignment="Center" Margin="0,0,0,6">
<Path.LayoutTransform><RotateTransform Angle="90"/></Path.LayoutTransform></Path>
<TextBlock Text="TEST" Foreground="#0b1326" FontWeight="Bold" FontSize="15"
HorizontalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
@@ -803,20 +944,6 @@
VerticalAlignment="Center" Margin="0,4">
<!-- Line 1: Socials + TRAX -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,4">
<!-- Socials button: hover glows the social bar in the preview -->
<Button x:Name="SocialsButton"
Command="{Binding OpenSocialDialogCommand}"
Style="{StaticResource YtButtonSecondary}" Padding="12,4"
FontSize="11" VerticalAlignment="Center" Margin="0,0,12,0"
ToolTip="Add or manage your social handles"
MouseEnter="SocialsButton_MouseEnter"
MouseLeave="SocialsButton_MouseLeave">
<StackPanel Orientation="Horizontal">
<Ellipse Width="8" Height="8" Fill="{Binding SocialBarDotBrush}"
Margin="0,0,6,0" VerticalAlignment="Center"/>
<TextBlock Text="Socials"/>
</StackPanel>
</Button>
<!-- TRAX meter -->
<Border Background="#D9000000" CornerRadius="6" Padding="12,8">
<StackPanel Orientation="Horizontal">