Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions Trdo/Pages/SettingsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,52 @@
</Grid>
</StackPanel>

<!-- Enable Auto-Resume setting -->
<!-- Play on startup setting -->
<StackPanel Spacing="8">
<TextBlock FontSize="16" Text="Enable Auto-Resume" />
<TextBlock FontSize="16" Text="Play on startup" />
<TextBlock
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="Automatically start playing the last selected station when the app opens"
TextWrapping="Wrap" />
<InfoBar
x:Name="AutoPlayWarningInfoBar"
IsClosable="True"
IsOpen="False"
Message="This means audio will begin playing when Trdo is launched. It could be disruptive. Are you sure you want to enable this?"
Severity="Warning">
<InfoBar.ActionButton>
<Button
x:Name="ConfirmAutoPlayButton"
Click="ConfirmAutoPlayButton_Click"
Content="Enable anyway" />
</InfoBar.ActionButton>
</InfoBar>
<Grid ColumnDefinitions="Auto,*" ColumnSpacing="12">
<ToggleSwitch
x:Name="AutoPlayOnStartupToggle"
Toggled="AutoPlayOnStartupToggle_Toggled"
Grid.Column="0"
MinWidth="0"
IsOn="{x:Bind ViewModel.IsAutoPlayOnStartupEnabled, Mode=OneWay}"
OffContent=""
OnContent="" />
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Text="{x:Bind ViewModel.AutoPlayOnStartupToggleText, Mode=OneWay}" />
</Grid>
</StackPanel>

<!-- Auto-recover setting -->
<StackPanel Spacing="8">
<TextBlock FontSize="16" Text="Auto-recover" />
<TextBlock
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="If the stream is unstable or stops unexpectedly, Trdo will try to recover playback automatically"
TextWrapping="Wrap" />
<Grid ColumnDefinitions="Auto,*" ColumnSpacing="12">
<ToggleSwitch
x:Name="WatchdogToggle"
Expand Down
46 changes: 46 additions & 0 deletions Trdo/Pages/SettingsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public sealed partial class SettingsPage : Page
private static extern nint GetActiveWindow();

private float _displayLevel;
private bool _isUpdatingAutoPlayToggle;

public SettingsViewModel ViewModel { get; }

Expand Down Expand Up @@ -133,4 +134,49 @@ private async void ExportButton_Click(object sender, RoutedEventArgs e)
ImportExportInfoBar.IsOpen = true;
}
}

private void AutoPlayOnStartupToggle_Toggled(object sender, RoutedEventArgs e)
{
if (_isUpdatingAutoPlayToggle)
{
return;
}

bool isEnabled = ViewModel.IsAutoPlayOnStartupEnabled;
bool requestedState = AutoPlayOnStartupToggle.IsOn;

if (requestedState == isEnabled)
{
if (!requestedState)
{
AutoPlayWarningInfoBar.IsOpen = false;
}

return;
}

if (!requestedState)
{
ViewModel.IsAutoPlayOnStartupEnabled = false;
AutoPlayWarningInfoBar.IsOpen = false;
return;
}

SetAutoPlayToggle(false);
AutoPlayWarningInfoBar.IsOpen = true;
}

private void ConfirmAutoPlayButton_Click(object sender, RoutedEventArgs e)
{
ViewModel.IsAutoPlayOnStartupEnabled = true;
SetAutoPlayToggle(true);
AutoPlayWarningInfoBar.IsOpen = false;
}

private void SetAutoPlayToggle(bool value)
{
_isUpdatingAutoPlayToggle = true;
AutoPlayOnStartupToggle.IsOn = value;
_isUpdatingAutoPlayToggle = false;
}
}
40 changes: 40 additions & 0 deletions Trdo/Services/SettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,46 @@ public static class SettingsService
{
private const string IsFirstRunKey = "IsFirstRun";
private const string IsVolumeSliderVisibleKey = "IsVolumeSliderVisible";
private const string AutoPlayOnStartupKey = "AutoPlayOnStartup";

/// <summary>
/// Gets or sets whether the app should automatically start playing the last selected station on startup.
/// Defaults to false when no saved value exists.
/// </summary>
public static bool AutoPlayOnStartup
{
get
{
try
{
if (ApplicationData.Current.LocalSettings.Values.TryGetValue(AutoPlayOnStartupKey, out object? value))
{
return value switch
{
bool b => b,
string s when bool.TryParse(s, out bool b2) => b2,
_ => false
};
}
return false;
}
catch
{
return false;
}
}
set
{
try
{
ApplicationData.Current.LocalSettings.Values[AutoPlayOnStartupKey] = value;
}
catch
{
// Silently fail if unable to save
}
}
}

/// <summary>
/// Gets or sets whether the volume slider is visible on the playing page.
Expand Down
7 changes: 5 additions & 2 deletions Trdo/Services/WindowPlacementService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ public static void PositionWindowNearAnchor(Window window, int width, int height
int x = placeLeft ? anchor.X - width - WindowMargin : anchor.X + WindowMargin;
int y = placeAbove ? anchor.Y - height - WindowMargin : anchor.Y + WindowMargin;

x = System.Math.Clamp(x, workArea.X, workArea.X + workArea.Width - width);
y = System.Math.Clamp(y, workArea.Y, workArea.Y + workArea.Height - height);
int maxX = System.Math.Max(workArea.X, workArea.X + workArea.Width - width);
int maxY = System.Math.Max(workArea.Y, workArea.Y + workArea.Height - height);

x = System.Math.Clamp(x, workArea.X, maxX);
y = System.Math.Clamp(y, workArea.Y, maxY);

window.MoveAndResize(x, y, width, height);
}
Expand Down
7 changes: 7 additions & 0 deletions Trdo/ViewModels/PlayerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@
{
Debug.WriteLine($"[PlayerViewModel] Initializing stream with URL: {_selectedStation.StreamUrl}");
InitializeStream(_selectedStation.StreamUrl);

// Auto-play on startup if the setting is enabled
if (SettingsService.AutoPlayOnStartup)
{
Debug.WriteLine("[PlayerViewModel] AutoPlayOnStartup is enabled, starting playback...");
_player.Play();
}
}
else
{
Expand Down Expand Up @@ -550,7 +557,7 @@
return uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps;
}

protected void OnPropertyChanged([CallerMemberName] string? name = null)

Check warning on line 560 in Trdo/ViewModels/PlayerViewModel.cs

View workflow job for this annotation

GitHub Actions / build

'PlayerViewModel.OnPropertyChanged(string?)': new protected member declared in sealed type
{
Debug.WriteLine($"[PlayerViewModel] PropertyChanged: {name}");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
Expand Down
30 changes: 29 additions & 1 deletion Trdo/ViewModels/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ public partial class SettingsViewModel : INotifyPropertyChanged
private string _startupToggleText = "Off";
private string _watchdogToggleText = "Off";
private string _autoBufferToggleText = "Off";
private string _autoPlayOnStartupToggleText = "Off";
private StartupTask? _startupTask;
private bool _initDone;

public event PropertyChangedEventHandler? PropertyChanged;

public SettingsViewModel()
{
_playerViewModel = new PlayerViewModel();
_playerViewModel = PlayerViewModel.Shared;

// Subscribe to PlayerViewModel property changes
_playerViewModel.PropertyChanged += (_, args) =>
Expand Down Expand Up @@ -57,6 +58,7 @@ public SettingsViewModel()
// Initialize toggle text
WatchdogToggleText = GetToggleText(_playerViewModel.WatchdogEnabled);
AutoBufferToggleText = GetToggleText(_playerViewModel.AutoBufferIncreaseEnabled);
AutoPlayOnStartupToggleText = GetToggleText(SettingsService.AutoPlayOnStartup);

// Initialize startup task
_ = InitializeStartupTaskAsync();
Expand Down Expand Up @@ -101,6 +103,32 @@ public string StartupToggleText
}
}

/// <summary>
/// Gets or sets whether the app should automatically start playing the last selected station on startup.
/// </summary>
public bool IsAutoPlayOnStartupEnabled
{
get => SettingsService.AutoPlayOnStartup;
set
{
if (value == SettingsService.AutoPlayOnStartup) return;
SettingsService.AutoPlayOnStartup = value;
OnPropertyChanged();
AutoPlayOnStartupToggleText = GetToggleText(value);
}
}

public string AutoPlayOnStartupToggleText
{
get => _autoPlayOnStartupToggleText;
set
{
if (value == _autoPlayOnStartupToggleText) return;
_autoPlayOnStartupToggleText = value;
OnPropertyChanged();
}
}

public bool IsWatchdogEnabled
{
get => _playerViewModel.WatchdogEnabled;
Expand Down
Loading