Renames AssemblyName to LlamaCasty before the first Steam depot — Steamworks is explicit that renaming a live exe is painful, so this had to land first, not later. Four assembly-qualified pack URIs carried the old name, not three: MainWindow (window icon), OverlayHost (logo), RenameRecordingDialog and KeepBroadcastDialog. Pack URIs resolve by assembly name at runtime, so a stale one compiles, passes every test and then silently renders nothing the first time that view opens. AssemblyIdentityTests guards both halves — the assembly name, and no source XAML still naming the legacy assembly. Packaging/Package.appxmanifest and package-msix.sh carry the exe name too. scripts/publish.sh replaces the by-hand publish: single-file win-x64, ReadyToRun, ffmpeg beside the exe, and it refuses to finish if ffmpeg, LICENSE, PRIVACY.md or THIRD-PARTY-NOTICES.txt are missing, or if a test assembly leaked in. That last guard exists because the first publish was wrong in a way no test could see: PublishSingleFile + IncludeNativeLibrariesForSelfExtract bundled the libav*.dll family into the exe — a 9-file output with no ffmpeg folder and a 182 MB binary, so the locator would have found nothing at runtime. ExcludeFromSingleFile="true" on the content keeps the folder a folder. Diffing against a control publish without the single-file flags found it; guessing at item globs wasted two attempts first (recorded in MyMistakes.md). Measured: 127 MB exe + 129 MB ffmpeg = 257 MB depot. Tests: AssemblyIdentity, StorePackaging, BuildStamp, BundledFonts all pass; app builds with 0 warnings.
236 lines
19 KiB
XML
236 lines
19 KiB
XML
<UserControl x:Class="ytLive.Controls.OverlayHost"
|
|
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:Models="clr-namespace:ytLive.Models"
|
|
xmlns:services="clr-namespace:ytLive.Services">
|
|
<Grid Grid.RowSpan="3"
|
|
Visibility="{Binding IsAnyOverlayOpen, Converter={StaticResource BoolToVis}}">
|
|
<Button Background="{StaticResource Brush.ScrimDarkStrong}" BorderThickness="0" Cursor="Hand"
|
|
Command="{Binding CloseOverlayCommand}">
|
|
<Button.Template>
|
|
<ControlTemplate TargetType="Button">
|
|
<Border Background="{TemplateBinding Background}"/>
|
|
</ControlTemplate>
|
|
</Button.Template>
|
|
</Button>
|
|
|
|
<Border Background="{StaticResource Brush.Background}" CornerRadius="8" Width="650" MaxHeight="700"
|
|
VerticalAlignment="Center" HorizontalAlignment="Center"
|
|
Padding="28" BorderBrush="#333" BorderThickness="1">
|
|
<Grid>
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto"/>
|
|
<RowDefinition Height="Auto"/>
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Header -->
|
|
<Grid Grid.Row="0">
|
|
<TextBlock Text="{Binding OverlayTitle}" FontSize="18" FontWeight="Bold"
|
|
Foreground="{StaticResource Brush.OnSurface}" VerticalAlignment="Center"/>
|
|
<Button HorizontalAlignment="Right" ToolTip="Close" Style="{StaticResource IconButton}"
|
|
Command="{Binding CloseOverlayCommand}">
|
|
<Path Data="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"
|
|
Fill="{StaticResource Brush.OnSurface}" Width="14" Height="14" Stretch="Uniform"/>
|
|
</Button>
|
|
</Grid>
|
|
|
|
<!-- App Settings: broadcast fields live in the preview's
|
|
Text pull-out now — this panel keeps app-level prefs only.
|
|
(Currently empty; the overlay shell stays for future use.) -->
|
|
<StackPanel Grid.Row="1" Margin="0,8,0,0"
|
|
Visibility="{Binding IsSettingsOpen, Converter={StaticResource BoolToVis}}">
|
|
|
|
<TextBlock Text="Recordings" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,2"/>
|
|
<TextBlock Text="Default location" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" Margin="10,0,0,2"/>
|
|
<DockPanel Margin="10,0,0,8">
|
|
<Button DockPanel.Dock="Right" Content="Browse…" Command="{Binding ChooseRecordFolderCommand}"
|
|
Style="{StaticResource YtButtonSecondary}" Padding="8,2" FontSize="11" Margin="6,0,0,0"/>
|
|
<Button DockPanel.Dock="Right" Content="Use Downloads" Command="{Binding ResetRecordFolderCommand}"
|
|
Style="{StaticResource YtButtonSecondary}" Padding="8,2" FontSize="11" Margin="6,0,0,0"/>
|
|
<TextBox Style="{StaticResource YtTextBoxCompact}" Text="{Binding RecordFolderDisplay, Mode=OneWay}"
|
|
IsReadOnly="True" Foreground="{StaticResource Brush.OnSurfaceVariant}" VerticalAlignment="Center"/>
|
|
</DockPanel>
|
|
|
|
<TextBlock Text="Brand logo" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,2"/>
|
|
<TextBlock Text="Image file (shown on every scene)" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" Margin="10,0,0,2"/>
|
|
<DockPanel Margin="10,0,0,8">
|
|
<Button DockPanel.Dock="Right" Content="Browse…" Command="{Binding BrowseBrandLogoCommand}"
|
|
Style="{StaticResource YtButtonSecondary}" Padding="8,2" FontSize="11" Margin="6,0,0,0"/>
|
|
<!-- A file NAME says nothing about the picture. The thumbnail shows what
|
|
is set; hovering enlarges it, a click collapses it again. -->
|
|
<Border x:Name="BrandLogoThumbFrame" DockPanel.Dock="Left" Width="28" Height="28"
|
|
Margin="0,0,6,0" CornerRadius="4" ClipToBounds="True"
|
|
Background="{StaticResource Brush.SurfaceContainerLowest}"
|
|
BorderBrush="{StaticResource Brush.Outline}" BorderThickness="1"
|
|
Cursor="Hand" ToolTip="Hover to enlarge — click to close"
|
|
Visibility="{Binding BrandLogoPreviewImage, Converter={StaticResource NotNullToVis}}">
|
|
<Image x:Name="BrandLogoThumbImage" Source="{Binding BrandLogoPreviewImage}"
|
|
Stretch="Uniform" MouseEnter="BrandLogoThumb_MouseEnter"
|
|
MouseLeave="BrandLogoThumb_MouseLeave"
|
|
MouseLeftButtonUp="BrandLogoThumb_Click"/>
|
|
</Border>
|
|
<TextBox Style="{StaticResource YtTextBoxCompact}" Text="{Binding BrandLogoFileDisplay, Mode=OneWay}"
|
|
IsReadOnly="True" Foreground="{StaticResource Brush.OnSurfaceVariant}" VerticalAlignment="Center"/>
|
|
</DockPanel>
|
|
<Popup x:Name="BrandLogoPreviewPopup" PlacementTarget="{Binding ElementName=BrandLogoThumbFrame}"
|
|
Placement="Right" HorizontalOffset="6" StaysOpen="True" AllowsTransparency="True"
|
|
IsHitTestVisible="True" MouseLeave="BrandLogoPreviewPopup_MouseLeave">
|
|
<Border Padding="6" CornerRadius="6"
|
|
Background="{StaticResource Brush.SurfaceContainerHighest}"
|
|
BorderBrush="{StaticResource Brush.Outline}" BorderThickness="1">
|
|
<StackPanel>
|
|
<Image Source="{Binding BrandLogoPreviewImage}" MaxWidth="420" MaxHeight="320"
|
|
Stretch="Uniform" RenderOptions.BitmapScalingMode="HighQuality"/>
|
|
<TextBlock Text="{Binding BrandLogoFileDisplay}" FontSize="11" Margin="0,6,0,0"
|
|
Foreground="{StaticResource Brush.OnSurfaceVariant}"/>
|
|
</StackPanel>
|
|
</Border>
|
|
</Popup>
|
|
|
|
<TextBlock Text="Preview" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,2"/>
|
|
<TextBlock Text="Zoom view shape" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" Margin="10,0,0,2"/>
|
|
<ComboBox Style="{StaticResource YtComboBox}" Margin="10,0,0,8" SelectedValue="{Binding ZoomShape}" SelectedValuePath="Tag">
|
|
<ComboBoxItem Content="Circle" Tag="{x:Static Models:ZoomShape.Circle}"/>
|
|
<ComboBoxItem Content="Phone (Vertical Rectangle)" Tag="{x:Static Models:ZoomShape.VerticalRectangle}"/>
|
|
<ComboBoxItem Content="Tablet (Horizontal Rectangle)" Tag="{x:Static Models:ZoomShape.HorizontalRectangle}"/>
|
|
</ComboBox>
|
|
|
|
<TextBlock Text="Scene transition" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" FontWeight="SemiBold" Margin="0,8,0,2"/>
|
|
<TextBlock Text="Type" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" Margin="10,0,0,2"/>
|
|
<ComboBox Style="{StaticResource YtComboBox}" Margin="10,0,0,8" SelectedValue="{Binding SelectedTransitionType}" SelectedValuePath="Tag">
|
|
<ComboBoxItem Content="Cut" Tag="{x:Static services:TransitionType.Cut}"/>
|
|
<ComboBoxItem Content="Fade" Tag="{x:Static services:TransitionType.Fade}"/>
|
|
<ComboBoxItem Content="Move" Tag="{x:Static services:TransitionType.Move}"/>
|
|
<ComboBoxItem Content="Wipe" Tag="{x:Static services:TransitionType.Wipe}"/>
|
|
</ComboBox>
|
|
<DockPanel Margin="10,0,0,6">
|
|
<TextBlock DockPanel.Dock="Right" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="11" VerticalAlignment="Center" Margin="8,0,0,0" Width="56">
|
|
<Run Text="{Binding TransitionDurationMs, StringFormat={}{0:0}}"/><Run Text=" ms"/>
|
|
</TextBlock>
|
|
<Slider Minimum="100" Maximum="2000" TickFrequency="50" IsSnapToTickEnabled="True"
|
|
Value="{Binding TransitionDurationMs, Mode=TwoWay}" VerticalAlignment="Center"/>
|
|
</DockPanel>
|
|
</StackPanel>
|
|
|
|
<!-- Report Bug -->
|
|
<StackPanel Grid.Row="1" Margin="0,16,0,0"
|
|
Visibility="{Binding IsBugOpen, Converter={StaticResource BoolToVis}}">
|
|
<TextBlock Text="What went wrong?" Style="{StaticResource YtLabel}" Margin="0,0,0,4"/>
|
|
<TextBox Style="{StaticResource YtTextBox}" Height="110" AcceptsReturn="True" TextWrapping="Wrap"
|
|
Margin="0,0,0,12"
|
|
Text="{Binding BugReportText, UpdateSourceTrigger=PropertyChanged}"
|
|
VerticalScrollBarVisibility="Auto"/>
|
|
|
|
<TextBlock Text="Email (optional)" Style="{StaticResource YtLabel}" Margin="0,0,0,4"/>
|
|
<TextBox Style="{StaticResource YtTextBox}" Margin="0,0,0,12"
|
|
Text="{Binding BugReportEmail, UpdateSourceTrigger=PropertyChanged}"/>
|
|
|
|
<TextBlock Text="Opens a pre-filled email to the LlamaCasty team." Style="{StaticResource YtLabel}"/>
|
|
<Button Content="Send Report" Command="{Binding SubmitBugCommand}"
|
|
Style="{StaticResource YtButton}" HorizontalAlignment="Right" Margin="0,16,0,0"/>
|
|
</StackPanel>
|
|
|
|
<!-- Feature Request -->
|
|
<StackPanel Grid.Row="1" Margin="0,16,0,0"
|
|
Visibility="{Binding IsFeatureOpen, Converter={StaticResource BoolToVis}}">
|
|
<TextBlock Text="What would you like to see?" Style="{StaticResource YtLabel}" Margin="0,0,0,4"/>
|
|
<TextBox Style="{StaticResource YtTextBox}" Height="110" AcceptsReturn="True" TextWrapping="Wrap"
|
|
Margin="0,0,0,12"
|
|
Text="{Binding FeatureRequestText, UpdateSourceTrigger=PropertyChanged}"
|
|
VerticalScrollBarVisibility="Auto"/>
|
|
|
|
<TextBlock Text="Email (optional)" Style="{StaticResource YtLabel}" Margin="0,0,0,4"/>
|
|
<TextBox Style="{StaticResource YtTextBox}" Margin="0,0,0,12"
|
|
Text="{Binding FeatureRequestEmail, UpdateSourceTrigger=PropertyChanged}"/>
|
|
|
|
<TextBlock Text="Opens a pre-filled email to the LlamaCasty team." Style="{StaticResource YtLabel}"/>
|
|
<Button Content="Send Request" Command="{Binding SubmitFeatureCommand}"
|
|
Style="{StaticResource YtButton}" HorizontalAlignment="Right" Margin="0,16,0,0"/>
|
|
</StackPanel>
|
|
|
|
<!-- About -->
|
|
<Grid Grid.Row="1" Margin="0,16,0,0"
|
|
Background="{StaticResource Brush.SurfaceContainerLow}"
|
|
Visibility="{Binding IsAboutOpen, Converter={StaticResource BoolToVis}}">
|
|
|
|
<!-- Hub view -->
|
|
<StackPanel Visibility="{Binding IsHubVisible, Converter={StaticResource BoolToVis}}">
|
|
<Image Source="/LlamaCasty;component/Assets/llamacasty-logo.jpg" Height="125" Stretch="Uniform"
|
|
HorizontalAlignment="Center" Margin="0,0,0,12"/>
|
|
<TextBlock Text="{Binding AppVersionLabel}" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="12"
|
|
HorizontalAlignment="Center" Margin="0,4,0,0"/>
|
|
<TextBlock Text="Live streaming for YouTube — simple enough that even the most right-brained person can intuit it."
|
|
Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="13" TextWrapping="Wrap" MaxWidth="380"
|
|
TextAlignment="Center" Margin="0,16,0,0"/>
|
|
<TextBlock Text="Free forever — live streams carry a brief "made with LlamaCasty!" flash. A subscription removes it and adds alerts."
|
|
Foreground="#888" FontSize="12" TextWrapping="Wrap" MaxWidth="380"
|
|
TextAlignment="Center" Margin="0,12,0,0"/>
|
|
<TextBlock Text="Made by gramps · llama chile shop" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="12"
|
|
HorizontalAlignment="Center" Margin="0,16,0,8"/>
|
|
|
|
<!-- Creator hub links -->
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,8">
|
|
<Button Content="llama chile shop on YouTube" Command="{Binding OpenChannelCommand}"
|
|
Style="{StaticResource YtButtonSecondary}" Margin="0,0,8,0"/>
|
|
<Button Content="Mastodon" Command="{Binding OpenMastodonCommand}"
|
|
Style="{StaticResource YtButtonSecondary}"/>
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
|
<Button Content="Buy me a coffee" Command="{Binding OpenCoffeeCommand}"
|
|
Style="{StaticResource YtButtonSecondary}" Margin="0,0,8,0"/>
|
|
<Button Content="Unlock Premium" Command="{Binding OpenPremiumCommand}"
|
|
Style="{StaticResource YtButtonSecondary}"
|
|
IsEnabled="{Binding IsPremiumAvailable}"
|
|
ToolTip="Open the LlamaCasty subscription page"/>
|
|
<Button Content="Enter License Key" Command="{Binding OpenLicenseEntryCommand}"
|
|
Style="{StaticResource YtButtonSecondary}"
|
|
ToolTip="Activate a license key to remove the watermark"/>
|
|
</StackPanel>
|
|
|
|
<Button Content="Licenses & legal" Command="{Binding OpenLicensesCommand}"
|
|
Style="{StaticResource YtButtonSecondary}" HorizontalAlignment="Center"
|
|
Margin="0,16,0,0"/>
|
|
</StackPanel>
|
|
|
|
<!-- Licensing/legal panel -->
|
|
<StackPanel Visibility="{Binding IsLicensesOpen, Converter={StaticResource BoolToVis}}">
|
|
<TextBlock Text="Third-party notices & license texts" FontSize="15" FontWeight="Bold"
|
|
Foreground="{StaticResource Brush.OnSurface}" Margin="0,0,0,8"/>
|
|
<Border Background="{StaticResource Brush.SurfaceContainerLowest}" CornerRadius="4" Padding="10" MaxHeight="360"
|
|
BorderBrush="#333" BorderThickness="1">
|
|
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
|
<TextBlock Text="{Binding LicensesText}" Foreground="{StaticResource Brush.OnSurface}" FontSize="11"
|
|
FontFamily="Consolas" TextWrapping="Wrap"/>
|
|
</ScrollViewer>
|
|
</Border>
|
|
<Button Content="← Back to About" Style="{StaticResource YtButtonSecondary}"
|
|
HorizontalAlignment="Left" Margin="0,12,0,0"
|
|
Click="BackToAbout_Click"/>
|
|
</StackPanel>
|
|
|
|
<!-- License key entry panel -->
|
|
<StackPanel Visibility="{Binding IsLicenseEntryOpen, Converter={StaticResource BoolToVis}}">
|
|
<TextBlock Text="Activate LlamaCasty Premium" FontSize="15" FontWeight="Bold"
|
|
Foreground="{StaticResource Brush.OnSurface}" Margin="0,0,0,8"/>
|
|
<TextBlock Text="Enter your license key to remove the branding watermark."
|
|
Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="12" TextWrapping="Wrap" Margin="0,0,0,12"/>
|
|
<TextBlock Text="License Key" Style="{StaticResource YtLabel}" Margin="0,0,0,4"/>
|
|
<TextBox Style="{StaticResource YtTextBox}" Margin="0,0,0,12"
|
|
Text="{Binding LicenseKey, UpdateSourceTrigger=PropertyChanged}"
|
|
MaxLength="100"/>
|
|
<Button Content="Activate" Command="{Binding ActivateLicenseCommand}"
|
|
Style="{StaticResource YtButton}" HorizontalAlignment="Right"
|
|
Margin="0,0,0,8"/>
|
|
<TextBlock Text="{Binding LicenseMessage}" Foreground="{StaticResource Brush.OnSurfaceVariant}" FontSize="12"
|
|
TextWrapping="Wrap" Margin="0,0,0,8"/>
|
|
<Button Content="← Back to About" Style="{StaticResource YtButtonSecondary}"
|
|
HorizontalAlignment="Left" Margin="0,8,0,0"
|
|
Click="BackToAbout_Click"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Grid>
|
|
</Border>
|
|
</Grid>
|
|
</UserControl>
|