Skip to content

Commit ba61e91

Browse files
authored
Allow updating a package from the installed packages list (#5366)
1 parent 093a1d0 commit ba61e91

3 files changed

Lines changed: 48 additions & 51 deletions

File tree

src/Languages/lang_en.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,6 @@
10101010
"Manage the list": "Manage the list",
10111011
"Automatically update selected packages": "Automatically update selected packages",
10121012
"Manage automatic updates": "Manage automatic updates",
1013-
"Update this package automatically": "Update this package automatically",
10141013
"{0} package(s) marked for automatic updates": "{0} package(s) marked for automatic updates",
10151014
"Turn on \"Install available updates\" in the scheduled maintenance settings for this to take effect.": "Turn on \"Install available updates\" in the scheduled maintenance settings for this to take effect.",
10161015
"Every upgradable package is already installed automatically, so this changes nothing until the scheduled task is limited to marked packages.": "Every upgradable package is already installed automatically, so this changes nothing until the scheduled task is limited to marked packages.",

src/UniGetUI.Avalonia/Views/SoftwarePages/InstalledPackagesPage.cs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class InstalledPackagesPage : AbstractPackagesPage
3434
private MenuItem? _menuOpenInstallLocation;
3535
private MenuItem? _menuDownloadInstaller;
3636
private MenuItem? _menuManual;
37+
private MenuItem? _menuUpdate;
38+
private MenuItem? _menuUpdateAsAdmin;
3739

3840
private static bool _hasBackedUp;
3941

@@ -183,6 +185,21 @@ protected override void GenerateToolBar(PackagesPageViewModel vm)
183185
};
184186
_menuRemoveData.Click += (_, _) => _ = LaunchUninstall([SelectedItem!], remove_data: true);
185187

188+
_menuUpdate = new MenuItem
189+
{
190+
Header = CoreTools.Translate("Update"),
191+
Icon = LoadMenuIcon("update"),
192+
};
193+
_menuUpdate.Click += (_, _) => _ = LaunchUpdate(SelectedItem);
194+
195+
_menuUpdateAsAdmin = new MenuItem
196+
{
197+
Header = CoreTools.Translate("Update as administrator"),
198+
Icon = LoadMenuIcon("uac"),
199+
IsVisible = OperatingSystem.IsWindows(),
200+
};
201+
_menuUpdateAsAdmin.Click += (_, _) => _ = LaunchUpdate(SelectedItem, elevated: true);
202+
186203
_menuDownloadInstaller = new MenuItem
187204
{
188205
Header = CoreTools.Translate("Download installer"),
@@ -230,6 +247,9 @@ protected override void GenerateToolBar(PackagesPageViewModel vm)
230247
menu.Items.Add(_menuInteractive);
231248
menu.Items.Add(_menuRemoveData);
232249
menu.Items.Add(new Separator());
250+
menu.Items.Add(_menuUpdate);
251+
menu.Items.Add(_menuUpdateAsAdmin);
252+
menu.Items.Add(new Separator());
233253
menu.Items.Add(_menuDownloadInstaller);
234254
menu.Items.Add(new Separator());
235255
menu.Items.Add(_menuReinstall);
@@ -244,7 +264,8 @@ protected override void GenerateToolBar(PackagesPageViewModel vm)
244264

245265
protected override void WhenShowingContextMenu(IPackage package)
246266
{
247-
if (_menuAsAdmin is null || _menuInteractive is null || _menuRemoveData is null
267+
if (_menuUpdate is null || _menuUpdateAsAdmin is null
268+
|| _menuAsAdmin is null || _menuInteractive is null || _menuRemoveData is null
248269
|| _menuInstallationOptions is null || _menuReinstall is null
249270
|| _menuUninstallThenReinstall is null || _menuIgnoreUpdates is null
250271
|| _menuDetails is null
@@ -262,6 +283,17 @@ protected override void WhenShowingContextMenu(IPackage package)
262283
_menuAsAdmin.IsEnabled = caps.CanRunAsAdmin;
263284
_menuInteractive.IsEnabled = caps.CanRunInteractively;
264285
_menuRemoveData.IsEnabled = caps.CanRemoveDataOnUninstall;
286+
287+
// The installed entry knows no target version; its upgradable counterpart does,
288+
// and is null whenever no update is pending for the package.
289+
var upgradable = package.GetUpgradablePackage();
290+
bool canUpdate = upgradable is not null;
291+
_menuUpdate.IsEnabled = canUpdate;
292+
_menuUpdate.Header = upgradable is null
293+
? CoreTools.Translate("Update")
294+
: CoreTools.Translate("Update to version {0}", upgradable.NewVersionString);
295+
_menuUpdateAsAdmin.IsEnabled = canUpdate && caps.CanRunAsAdmin;
296+
265297
_menuDownloadInstaller.IsEnabled = !isLocal && caps.CanDownloadInstaller;
266298
_menuInstallationOptions.IsEnabled = !isLocal;
267299
_menuReinstall.IsEnabled = !isLocal;
@@ -373,6 +405,20 @@ private static async Task LaunchUninstall(
373405
}
374406
}
375407

408+
private static async Task LaunchUpdate(IPackage? package, bool? elevated = null)
409+
{
410+
// Updates must run on the upgradable instance: the installed one reports
411+
// NewVersionString == VersionString, which managers read as "nothing to do".
412+
if (package?.GetUpgradablePackage() is not { } upgradable) return;
413+
var opts = await InstallOptionsFactory.LoadApplicableAsync(upgradable, elevated: elevated);
414+
if (PackageOperation.HasPendingOperation(upgradable, OperationType.Update)) return;
415+
var op = new UpdatePackageOperation(upgradable, opts);
416+
op.OperationSucceeded += (_, _) => TelemetryHandler.UpdatePackage(upgradable, TEL_OP_RESULT.SUCCESS);
417+
op.OperationFailed += (_, _) => TelemetryHandler.UpdatePackage(upgradable, TEL_OP_RESULT.FAILED);
418+
AvaloniaOperationRegistry.Add(op);
419+
_ = op.MainThread();
420+
}
421+
376422
private static async Task LaunchReinstall(IPackage? package)
377423
{
378424
if (package is null || package.Source.IsVirtualManager) return;

src/UniGetUI.Avalonia/Views/SoftwarePages/SoftwareUpdatesPage.cs

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public class SoftwareUpdatesPage : AbstractPackagesPage
2828
private MenuItem? _menuSkipHash;
2929
private MenuItem? _menuDownloadInstaller;
3030
private MenuItem? _menuOpenInstallLocation;
31-
private MenuItem? _menuAutoUpdate;
3231

3332
public SoftwareUpdatesPage() : base(new PackagesPageData
3433
{
@@ -198,23 +197,6 @@ protected override void GenerateToolBar(PackagesPageViewModel vm)
198197
UpgradablePackagesLoader.Instance.IgnoredPackages[pkg.Id] = pkg;
199198
};
200199

201-
_menuAutoUpdate = new MenuItem
202-
{
203-
Header = CoreTools.Translate("Update this package automatically"),
204-
Icon = LoadMenuIcon("sandclock"),
205-
ToggleType = MenuItemToggleType.CheckBox,
206-
};
207-
_menuAutoUpdate.Click += (_, _) =>
208-
{
209-
var pkg = SelectedItem;
210-
if (pkg is null) return;
211-
string id = AutoUpdatesDatabase.GetIdForPackage(pkg);
212-
if (AutoUpdatesDatabase.IsAutoUpdated(id))
213-
AutoUpdatesDatabase.Remove(id);
214-
else
215-
MarkForAutoUpdates([pkg]);
216-
};
217-
218200
var menuSkipVersion = new MenuItem
219201
{
220202
Header = CoreTools.Translate("Skip this version"),
@@ -282,8 +264,6 @@ protected override void GenerateToolBar(PackagesPageViewModel vm)
282264
menu.Items.Add(menuUninstallThenUpdate);
283265
menu.Items.Add(menuUninstall);
284266
menu.Items.Add(new Separator());
285-
menu.Items.Add(_menuAutoUpdate);
286-
menu.Items.Add(new Separator());
287267
menu.Items.Add(menuIgnore);
288268
menu.Items.Add(menuSkipVersion);
289269
menu.Items.Add(menuPause);
@@ -296,8 +276,7 @@ protected override void GenerateToolBar(PackagesPageViewModel vm)
296276
protected override void WhenShowingContextMenu(IPackage package)
297277
{
298278
if (_menuAsAdmin is null || _menuInteractive is null || _menuSkipHash is null
299-
|| _menuDownloadInstaller is null || _menuOpenInstallLocation is null
300-
|| _menuAutoUpdate is null)
279+
|| _menuDownloadInstaller is null || _menuOpenInstallLocation is null)
301280
{
302281
Logger.Warn("Context menu items are null on SoftwareUpdatesPage");
303282
return;
@@ -310,7 +289,6 @@ protected override void WhenShowingContextMenu(IPackage package)
310289
_menuDownloadInstaller.IsEnabled = caps.CanDownloadInstaller;
311290
_menuOpenInstallLocation.IsEnabled =
312291
package.Manager.DetailsHelper.GetInstallLocation(package) is not null;
313-
_menuAutoUpdate.IsChecked = AutoUpdatesDatabase.IsAutoUpdated(package);
314292
}
315293

316294
// ─── Abstract action overrides ────────────────────────────────────────────
@@ -461,32 +439,6 @@ private static async Task WhenPackagesLoaded()
461439
}
462440
}
463441

464-
private static void MarkForAutoUpdates(IEnumerable<IPackage> packages)
465-
{
466-
int marked = 0;
467-
foreach (var pkg in packages)
468-
{
469-
string id = AutoUpdatesDatabase.GetIdForPackage(pkg);
470-
if (AutoUpdatesDatabase.IsAutoUpdated(id)) continue;
471-
AutoUpdatesDatabase.Add(id);
472-
marked++;
473-
}
474-
475-
if (marked is 0) return;
476-
477-
var schedule = MaintenanceScheduleStore.Get(MaintenanceTaskKind.InstallUpdates);
478-
string message = !schedule.Enabled
479-
? CoreTools.Translate("Turn on \"Install available updates\" in the scheduled maintenance settings for this to take effect.")
480-
: schedule.InstallTargets is ScheduleInstallTargets.AllPackages
481-
? CoreTools.Translate("Every upgradable package is already installed automatically, so this changes nothing until the scheduled task is limited to marked packages.")
482-
: CoreTools.Translate("They will be updated when the scheduled maintenance task runs.");
483-
484-
GetMainWindow()?.ShowBanner(
485-
CoreTools.Translate("{0} package(s) marked for automatic updates", marked),
486-
message,
487-
MainWindow.RuntimeNotificationLevel.Success);
488-
}
489-
490442
private static async Task LaunchScheduledUpdate(IReadOnlyList<IPackage> upgradable)
491443
{
492444
bool markedOnly = MaintenanceScheduleStore.GetInstallTargets()

0 commit comments

Comments
 (0)