Replace three-button cluster with a single context-aware primary button
Button follows the user journey: 'Connect to YouTube' (not signed in) -> 'Go Live' (connected, idle) -> 'Stop Stream' (live).
This commit is contained in:
+3
-31
@@ -119,38 +119,10 @@
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Stream Controls -->
|
||||
<!-- Primary action: single button, adapts to state -->
|
||||
<StackPanel Grid.Column="3" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
|
||||
<!-- YouTube connection status light + button -->
|
||||
<Border Background="#0f3460" CornerRadius="4" Padding="8,6" Margin="0,0,12,0"
|
||||
VerticalAlignment="Center" ToolTip="YouTube connection status">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Ellipse Width="10" Height="10" Margin="0,0,8,0" VerticalAlignment="Center">
|
||||
<Ellipse.Style>
|
||||
<Style TargetType="Ellipse">
|
||||
<Setter Property="Fill" Value="#555"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsYouTubeConnected}" Value="True">
|
||||
<Setter Property="Fill" Value="#00ff00"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Ellipse.Style>
|
||||
</Ellipse>
|
||||
<Button Content="YouTube" Style="{StaticResource YtButtonSecondary}"
|
||||
Background="Transparent" Padding="0"
|
||||
Command="{Binding ConnectYouTubeCommand}"
|
||||
ToolTip="Sign in to YouTube (optional)"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Button Content="Go Live" Style="{StaticResource YtButton}"
|
||||
Command="{Binding StartStreamCommand}"
|
||||
Visibility="{Binding IsOffline, Converter={StaticResource BoolToVis}}"/>
|
||||
<Button Content="Stop Stream" Style="{StaticResource YtButton}"
|
||||
Background="#333" Command="{Binding StopStreamCommand}"
|
||||
Visibility="{Binding IsLive, Converter={StaticResource BoolToVis}}"/>
|
||||
<Button Content="{Binding PrimaryButtonText}" Style="{StaticResource YtButton}"
|
||||
Command="{Binding PrimaryCommand}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
+28
-10
@@ -38,6 +38,7 @@ public class MainViewModel : ViewModelBase
|
||||
OnPropertyChanged(nameof(IsOffline));
|
||||
OnPropertyChanged(nameof(IsLive));
|
||||
OnPropertyChanged(nameof(StatusDisplay));
|
||||
OnPropertyChanged(nameof(PrimaryButtonText));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,7 +67,11 @@ public class MainViewModel : ViewModelBase
|
||||
public bool IsYouTubeConnected
|
||||
{
|
||||
get => _isYouTubeConnected;
|
||||
set => SetProperty(ref _isYouTubeConnected, value);
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _isYouTubeConnected, value))
|
||||
OnPropertyChanged(nameof(PrimaryButtonText));
|
||||
}
|
||||
}
|
||||
|
||||
public string StatusDisplay => StreamStatus switch
|
||||
@@ -78,12 +83,20 @@ public class MainViewModel : ViewModelBase
|
||||
_ => "UNKNOWN"
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Single, context-aware primary button. Follows the user's journey:
|
||||
/// not connected → connect, connected+idle → go live, live → stop.
|
||||
/// </summary>
|
||||
public string PrimaryButtonText => !IsYouTubeConnected
|
||||
? "Connect to YouTube"
|
||||
: IsLive
|
||||
? "Stop Stream"
|
||||
: "Go Live";
|
||||
|
||||
// Commands
|
||||
public ICommand AddSceneCommand { get; }
|
||||
public ICommand RemoveSceneCommand { get; }
|
||||
public ICommand StartStreamCommand { get; }
|
||||
public ICommand StopStreamCommand { get; }
|
||||
public ICommand ConnectYouTubeCommand { get; }
|
||||
public ICommand PrimaryCommand { get; }
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
@@ -95,9 +108,7 @@ public class MainViewModel : ViewModelBase
|
||||
|
||||
AddSceneCommand = new RelayCommand(_ => AddScene());
|
||||
RemoveSceneCommand = new RelayCommand(scene => RemoveScene(scene as Scene));
|
||||
StartStreamCommand = new RelayCommand(_ => StartStream(), _ => StreamStatus == StreamStatus.Offline);
|
||||
StopStreamCommand = new RelayCommand(_ => StopStream(), _ => StreamStatus == StreamStatus.Streaming);
|
||||
ConnectYouTubeCommand = new RelayCommand(_ => ConnectYouTube());
|
||||
PrimaryCommand = new RelayCommand(_ => PrimaryAction());
|
||||
|
||||
// Start with a default scene
|
||||
AddScene("Scene 1");
|
||||
@@ -131,19 +142,16 @@ public class MainViewModel : ViewModelBase
|
||||
private async void StartStream()
|
||||
{
|
||||
StreamStatus = StreamStatus.Connecting;
|
||||
OnPropertyChanged(nameof(StatusDisplay));
|
||||
|
||||
// TODO: Initialize capture pipeline, encode, and push to RTMP
|
||||
// For now, simulate connection
|
||||
await Task.Delay(500);
|
||||
StreamStatus = StreamStatus.Streaming;
|
||||
OnPropertyChanged(nameof(StatusDisplay));
|
||||
}
|
||||
|
||||
private void StopStream()
|
||||
{
|
||||
StreamStatus = StreamStatus.Offline;
|
||||
OnPropertyChanged(nameof(StatusDisplay));
|
||||
}
|
||||
|
||||
private void ConnectYouTube()
|
||||
@@ -152,4 +160,14 @@ public class MainViewModel : ViewModelBase
|
||||
// For now, this is a stub
|
||||
IsYouTubeConnected = false;
|
||||
}
|
||||
|
||||
private void PrimaryAction()
|
||||
{
|
||||
if (!IsYouTubeConnected)
|
||||
ConnectYouTube();
|
||||
else if (IsLive)
|
||||
StopStream();
|
||||
else
|
||||
StartStream();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user