Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow paths in the installations page to be clickable #228

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
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
8 changes: 7 additions & 1 deletion UnitystationLauncher/Views/InstallationView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:UnitystationLauncher.ViewModels"
xmlns:drawing="clr-namespace:System.Drawing;assembly=System.Drawing.Primitives"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="120" FontSize="16"
x:Class="UnitystationLauncher.Views.InstallationView"
x:DataType="viewModels:InstallationViewModel">
Expand All @@ -18,7 +19,12 @@
<StackPanel VerticalAlignment="Center" Margin="10 0 0 0" Grid.Column="1">
<TextBlock FontSize="16" Text="{Binding Installation.ForkName, StringFormat='Fork: {0}'}" />
<TextBlock FontSize="16" Text="{Binding Installation.BuildVersion, StringFormat='Build: {0}'}" />
<TextBlock FontSize="16" Text="{Binding Installation.InstallationPath, StringFormat='Path: {0}'}" />
<TextBlock FontSize="16">
<Run Text="Path: " />
<TextBlock Text="{Binding Installation.InstallationPath}"
TextDecorations="Underline"
PointerPressed="HandlePathClick"/>
</TextBlock>
<TextBlock FontSize="16" Text="{Binding Installation.LastPlayedDate, StringFormat='Last Played: {0}'}" />
</StackPanel>

Expand Down
39 changes: 39 additions & 0 deletions UnitystationLauncher/Views/InstallationView.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
using System.Diagnostics;
using System.IO;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;

namespace UnitystationLauncher.Views;
Expand All @@ -14,4 +18,39 @@ private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void HandlePathClick(object sender, PointerPressedEventArgs e)
{
TextBlock? block = sender as TextBlock;
if (block?.Text == null)
{
return;
}
string path = Path.GetFullPath(block.Text);
string protcol = GetManagerProtocl();
Process.Start(protcol, new Uri(RemoveLastPart(path)).ToString());
}

private string GetManagerProtocl()
{
string protocol = "Explorer.exe";
if (OperatingSystem.IsWindows())
Copy link
Contributor

@CorruptComputer CorruptComputer Mar 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have the EnvironmentService to do platform detection already, if you move this from the View to the ViewModel using a Command instead of a PointerClicked event it should be as easy as dependency injecting it in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I don't think you need to detect the platform at all, you can just do it the same way we open log directory after a scan fail, it should open in whatever the user has specified as their default handler for opening directories.

https://github.com/unitystation/stationhub/blob/develop/UnitystationLauncher/Services/InstallationService.cs#L550

ProcessStartInfo psi = new()
{
    FileName = path,
    UseShellExecute = true,
    Verb = "open"
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work.

Unhandled exception. System.ComponentModel.Win32Exception (5): An error occurred trying to start process 'C:\Users\Maximus\AppData\Roaming\StationHub\Installations\UnityStationDevelop' with working directory 'F:\projects\stationhub\UnitystationLauncher\bin\Debug\net8.0'. Access is denied.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have the EnvironmentService to do platform detection already, if you move this from the View to the ViewModel using a Command instead of a PointerClicked event it should be as easy as dependency injecting it in.

what difference does this make?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work.

Unhandled exception. System.ComponentModel.Win32Exception (5): An error occurred trying to start process 'C:\Users\Maximus\AppData\Roaming\StationHub\Installations\UnityStationDevelop' with working directory 'F:\projects\stationhub\UnitystationLauncher\bin\Debug\net8.0'. Access is denied.

Hmm, thats odd, I checked it out locally and that worked fine for me. Does it work when opening the log folder for a failed scan? I tested that in a Windows VM when I was working on that before and I remember it working fine, but maybe something regarding that changed with the upgrade to .NET 8.

We have the EnvironmentService to do platform detection already, if you move this from the View to the ViewModel using a Command instead of a PointerClicked event it should be as easy as dependency injecting it in.

what difference does this make?

Having standard ways of doing things makes the code a lot more maintainable, and code in the ViewModel can be effectively unit tested, while the code in the View cannot be in most cases. https://docs.avaloniaui.net/docs/concepts/the-mvvm-pattern

{
protocol = "Explorer.exe";
}
else if (OperatingSystem.IsMacOS())
{
protocol = "open";
}
else if (OperatingSystem.IsLinux())
{
protocol = "xdg-open";
}
return protocol;
}

private string RemoveLastPart(string path)
{
int lastBackslashIndex = path.LastIndexOf('\\');
return lastBackslashIndex >= 0 ? path.Substring(0, lastBackslashIndex) : path;
}
}
Loading