@@ -75,12 +75,14 @@ public bool IsGridView
7575 public string LayoutToggleLabel => _isGridView ? L . Tr ( "packages.button.listView" ) : L . Tr ( "packages.button.gridView" ) ;
7676
7777 public RelayCommand < CatalogPackageVersion > InstallCommand { get ; }
78+ public RelayCommand < CatalogPackageVersion > RemoveCommand { get ; }
7879 public RelayCommand < InstalledPackageRow > UninstallCommand { get ; }
7980 public RelayCommand RefreshCommand { get ; }
8081 public RelayCommand AddFromGitHubCommand { get ; }
8182 public RelayCommand CreateBundleCommand { get ; }
8283 public RelayCommand < CatalogPackageVersion > ChooseVersionCommand { get ; }
8384 public RelayCommand ToggleLayoutCommand { get ; }
85+ public RelayCommand < string > OpenLinkCommand { get ; }
8486
8587 public PackagesViewModel ( UserSettingsService settingsService , CatalogService catalogService , UnityProjectService projectService , MainWindowViewModel shell )
8688 {
@@ -91,12 +93,14 @@ public PackagesViewModel(UserSettingsService settingsService, CatalogService cat
9193 _shell = shell ;
9294
9395 InstallCommand = new RelayCommand < CatalogPackageVersion > ( InstallCuratedAsync ) ;
96+ RemoveCommand = new RelayCommand < CatalogPackageVersion > ( RemoveAvailableAsync ) ;
9497 UninstallCommand = new RelayCommand < InstalledPackageRow > ( UninstallAsync ) ;
9598 RefreshCommand = new RelayCommand ( RefreshAsync ) ;
9699 AddFromGitHubCommand = new RelayCommand ( AddFromGitHubAsync ) ;
97100 CreateBundleCommand = new RelayCommand ( CreateBundleAsync ) ;
98101 ChooseVersionCommand = new RelayCommand < CatalogPackageVersion > ( ChooseVersionAsync ) ;
99102 ToggleLayoutCommand = new RelayCommand ( ( ) => IsGridView = ! IsGridView ) ;
103+ OpenLinkCommand = new RelayCommand < string > ( url => { if ( ! string . IsNullOrWhiteSpace ( url ) ) ExternalLink . Open ( url ! ) ; } ) ;
100104 }
101105
102106 /// <summary>Applies the persisted layout choice at startup without re-saving it.</summary>
@@ -372,11 +376,24 @@ private async Task ChooseVersionAsync(CatalogPackageVersion? entry)
372376
373377 private async Task UninstallAsync ( InstalledPackageRow ? row )
374378 {
375- if ( row is null || _install is null ) return ;
376- if ( _install . Manifest . Dependencies . Remove ( row . Name ) )
379+ if ( row is null ) return ;
380+ await RemoveByNameAsync ( row . Name , row . DisplayName ) ;
381+ }
382+
383+ /// <summary>Removes an already-installed package straight from the "Available" list.</summary>
384+ private async Task RemoveAvailableAsync ( CatalogPackageVersion ? entry )
385+ {
386+ if ( entry is null ) return ;
387+ await RemoveByNameAsync ( entry . Name , entry . DisplayName ) ;
388+ }
389+
390+ private async Task RemoveByNameAsync ( string name , string displayName )
391+ {
392+ if ( _install is null ) return ;
393+ if ( _install . Manifest . Dependencies . Remove ( name ) )
377394 {
378395 await _projectService . SaveManifestAsync ( _install . UnityProjectPath , _install . Manifest ) ;
379- _shell . SetStatus ( L . Tr ( "packages.status.removed" , row . DisplayName ) , StatusKind . Success ) ;
396+ _shell . SetStatus ( L . Tr ( "packages.status.removed" , displayName ) , StatusKind . Success ) ;
380397 RefreshInstalled ( ) ;
381398 }
382399 }
@@ -624,6 +641,8 @@ public sealed record PackageRow(CatalogPackageVersion Entry, string? InstalledVe
624641 public string Owner => PackagesViewModel . OwnerOf ( Entry . Name ) ;
625642 public string Initial => string . IsNullOrWhiteSpace ( DisplayName ) ? "?" : DisplayName . TrimStart ( ) [ ..1 ] . ToUpperInvariant ( ) ;
626643 public bool HasGit => ! string . IsNullOrWhiteSpace ( Entry . Url ) ;
644+ public string ? Link => Entry . Link ;
645+ public bool HasLink => ! string . IsNullOrWhiteSpace ( Entry . Link ) ;
627646}
628647
629648public sealed record InstalledPackageRow ( string Name , string DisplayName , string Version , bool IsFromGit ) ;
0 commit comments