Skip to content
Open
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
13 changes: 12 additions & 1 deletion ui/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,18 @@
<ui:NavigationViewItem x:Name="RestartSteamItem"
Content="{res:Loc Nav_RestartSteam}"
Icon="{ui:SymbolIcon ArrowSync24}"
Click="RestartSteamItem_Click" />
Click="SteamNav_Click"
Tag="restart" />
<ui:NavigationViewItem x:Name="CloseSteamItem"
Content="{res:Loc Nav_CloseSteam}"
Icon="{ui:SymbolIcon Dismiss24}"
Click="SteamNav_Click"
Tag="close" />
<ui:NavigationViewItem x:Name="StartSteamItem"
Content="{res:Loc Nav_StartSteam}"
Icon="{ui:SymbolIcon Play24}"
Click="SteamNav_Click"
Tag="start" />
<ui:NavigationViewItem Content="{res:Loc Nav_Settings}"
Icon="{ui:SymbolIcon Settings24}"
TargetPageType="{x:Type pages:SettingsPage}" />
Expand Down
54 changes: 43 additions & 11 deletions ui/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
using TextBlock = System.Windows.Controls.TextBlock;
Expand All @@ -14,6 +15,7 @@ public partial class MainWindow : FluentWindow
{
private Services.AppUpdater.CheckResult? _pendingUpdate;
public bool AppUpdateAvailable { get; private set; }
private readonly DispatcherTimer _steamStateTimer = new() { Interval = TimeSpan.FromSeconds(5) };

public MainWindow()
{
Expand All @@ -40,6 +42,10 @@ public MainWindow()
RootNavigation.Navigate(typeof(Pages.DashboardPage));
}
catch { }

UpdateSteamNavItem();
_steamStateTimer.Tick += (_, _) => UpdateSteamNavItem();
_steamStateTimer.Start();
};
}

Expand Down Expand Up @@ -179,18 +185,42 @@ private void UpdateSkip_Click(object sender, RoutedEventArgs e)

public void ShowRestartSteam()
{
// Button is always visible now; kept for callers.
UpdateSteamNavItem();
}

private void UpdateSteamNavItem()
{
var running = Services.SteamDetector.IsSteamRunning();
RestartSteamItem.Visibility = running ? Visibility.Visible : Visibility.Collapsed;
CloseSteamItem.Visibility = running ? Visibility.Visible : Visibility.Collapsed;
StartSteamItem.Visibility = running ? Visibility.Collapsed : Visibility.Visible;
}

private async void RestartSteamItem_Click(object sender, RoutedEventArgs e)
private async void SteamNav_Click(object sender, RoutedEventArgs e)
{
var tag = (sender as FrameworkElement)?.Tag as string;

var steamPath = Services.SteamDetector.FindSteamPath();
if (steamPath == null) return;

var steamExe = Path.Combine(steamPath, "steam.exe");
if (!File.Exists(steamExe)) return;

// Graceful shutdown first
if (tag == "start")
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = steamExe,
UseShellExecute = true
})?.Dispose();
}
catch { }
return;
}

// restart or close — shut down Steam first
var procs = Process.GetProcessesByName("steam");
bool wasRunning = procs.Length > 0;
foreach (var p in procs) p.Dispose();
Expand All @@ -204,7 +234,6 @@ private async void RestartSteamItem_Click(object sender, RoutedEventArgs e)
UseShellExecute = true
})?.Dispose();

// Wait up to 15s for Steam to close
for (int i = 0; i < 30; i++)
{
await Task.Delay(500);
Expand All @@ -215,16 +244,19 @@ private async void RestartSteamItem_Click(object sender, RoutedEventArgs e)
}
}

try
if (tag == "restart")
{
Process.Start(new ProcessStartInfo
try
{
FileName = steamExe,
UseShellExecute = true
})?.Dispose();
Process.Start(new ProcessStartInfo
{
FileName = steamExe,
UseShellExecute = true
})?.Dispose();
}
catch { }
}
catch { }

RestartSteamItem.Visibility = Visibility.Collapsed;
UpdateSteamNavItem();
}
}
13 changes: 12 additions & 1 deletion ui/Pages/DashboardPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,21 @@
Icon="{ui:SymbolIcon Document24}"
Margin="0,0,8,8"
Click="OpenLog_Click" />
<ui:Button Content="{res:Loc Dashboard_RestartSteam}"
<ui:Button x:Name="RestartSteamBtn"
Content="{res:Loc Dashboard_RestartSteam}"
Icon="{ui:SymbolIcon ArrowSync24}"
Margin="0,0,8,8"
Click="RestartSteam_Click" />
<ui:Button x:Name="CloseSteamBtn"
Content="{res:Loc Dashboard_CloseSteam}"
Icon="{ui:SymbolIcon Dismiss24}"
Margin="0,0,8,8"
Click="CloseSteam_Click" />
<ui:Button x:Name="StartSteamBtn"
Content="{res:Loc Dashboard_StartSteam}"
Icon="{ui:SymbolIcon Play24}"
Margin="0,0,8,8"
Click="StartSteam_Click" />
</WrapPanel>
</StackPanel>
</ScrollViewer>
Expand Down
96 changes: 96 additions & 0 deletions ui/Pages/DashboardPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using CloudRedirect.Resources;

namespace CloudRedirect.Pages;

public partial class DashboardPage : Page
{
private string? _steamPath;
private readonly DispatcherTimer _steamStateTimer = new() { Interval = TimeSpan.FromSeconds(5) };

public void HideDllUpdateBanner()
{
Expand All @@ -25,6 +27,10 @@ public DashboardPage()
try { await LoadStatusAsync(); }
catch { }

UpdateSteamButtons();
_steamStateTimer.Tick += (_, _) => UpdateSteamButtons();
_steamStateTimer.Start();

// Give the app-level update check time to finish, then hide the
// DLL banner if a full app update is available (avoids two banners).
await Task.Delay(3000);
Expand Down Expand Up @@ -268,6 +274,96 @@ await Task.Run(() =>
}
}

private void UpdateSteamButtons()
{
var running = Services.SteamDetector.IsSteamRunning();
RestartSteamBtn.Visibility = running ? Visibility.Visible : Visibility.Collapsed;
CloseSteamBtn.Visibility = running ? Visibility.Visible : Visibility.Collapsed;
StartSteamBtn.Visibility = running ? Visibility.Collapsed : Visibility.Visible;
}

private async void CloseSteam_Click(object sender, RoutedEventArgs e)
{
var steamPath = Services.SteamDetector.FindSteamPath();
if (steamPath == null) return;

var steamExe = Path.Combine(steamPath, "steam.exe");
if (!File.Exists(steamExe)) return;

var button = (Wpf.Ui.Controls.Button)sender;
button.IsEnabled = false;
var originalContent = button.Content;
button.Content = S.Get("Dashboard_ShuttingDownSteam");

try
{
Process.Start(new ProcessStartInfo
{
FileName = steamExe,
Arguments = "-shutdown",
UseShellExecute = true
})?.Dispose();

bool exited = await Task.Run(async () =>
{
for (int i = 0; i < 30; i++)
{
await Task.Delay(500);
var procs = Process.GetProcessesByName("steam");
bool any = procs.Length > 0;
foreach (var p in procs) p.Dispose();
if (!any) return true;
}
return false;
});

if (!exited)
{
button.Content = S.Get("Dashboard_ForceKilling");
await Task.Run(() =>
{
foreach (var proc in Process.GetProcessesByName("steam"))
{
try { proc.Kill(); }
catch { }
finally { proc.Dispose(); }
}
});
await Task.Delay(1000);
}
}
catch { }

button.Content = originalContent;
button.IsEnabled = true;
UpdateSteamButtons();
}

private async void StartSteam_Click(object sender, RoutedEventArgs e)
{
var steamPath = Services.SteamDetector.FindSteamPath();
if (steamPath == null) return;

var steamExe = Path.Combine(steamPath, "steam.exe");
if (!File.Exists(steamExe)) return;

var button = (Wpf.Ui.Controls.Button)sender;
button.IsEnabled = false;

try
{
Process.Start(new ProcessStartInfo
{
FileName = steamExe,
UseShellExecute = true
})?.Dispose();
}
catch { }

button.IsEnabled = true;
UpdateSteamButtons();
}

private async void UpdateDll_Click(object sender, RoutedEventArgs e)
{
if (_steamPath == null) return;
Expand Down
12 changes: 12 additions & 0 deletions ui/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@
<data name="Nav_RestartSteam" xml:space="preserve">
<value>Restart Steam</value>
</data>
<data name="Nav_CloseSteam" xml:space="preserve">
<value>Close Steam</value>
</data>
<data name="Nav_StartSteam" xml:space="preserve">
<value>Start Steam</value>
</data>
<data name="Nav_ChoiceMode" xml:space="preserve">
<value>Mode</value>
</data>
Expand Down Expand Up @@ -518,6 +524,12 @@ If you skip this, saves will be stored locally in your Steam folder.</value>
<data name="Dashboard_RestartSteam" xml:space="preserve">
<value>Restart Steam</value>
</data>
<data name="Dashboard_CloseSteam" xml:space="preserve">
<value>Close Steam</value>
</data>
<data name="Dashboard_StartSteam" xml:space="preserve">
<value>Start Steam</value>
</data>

<!-- DashboardPage code-behind -->
<data name="Dashboard_NotFound" xml:space="preserve">
Expand Down