Skip to content

Commit d71d4bd

Browse files
Tom BrewerTom Brewer
authored andcommitted
fix: updates shouldn't block
fix: handle update errors better fix: uniontentional app context style
1 parent 9166c7a commit d71d4bd

File tree

8 files changed

+54
-30
lines changed

8 files changed

+54
-30
lines changed

Mythetech.Framework.Desktop/Mythetech.Framework.Desktop.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<PackageId>Mythetech.Framework.Desktop</PackageId>
8-
<Version>0.7.0</Version>
8+
<Version>0.7.1</Version>
99
<Authors>Mythetech</Authors>
1010
<Description>Desktop-specific components for cross platform blazor applications</Description>
1111
<PackageTags>blazor;desktop;photino;components;ui;framework;cross-platform</PackageTags>

Mythetech.Framework.Desktop/Updates/Events/UpdateEvents.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,16 @@ public record UpdateDownloadCompleted(UpdateInfo Update);
4141
/// </summary>
4242
/// <param name="Update">The update ready to install.</param>
4343
public record UpdateReadyToInstall(UpdateInfo Update);
44+
45+
/// <summary>
46+
/// Published when an update check fails due to network or server errors.
47+
/// </summary>
48+
/// <param name="Error">The exception that occurred.</param>
49+
public record UpdateCheckFailed(Exception Error);
50+
51+
/// <summary>
52+
/// Published when an update download fails.
53+
/// </summary>
54+
/// <param name="Update">The update that was being downloaded.</param>
55+
/// <param name="Error">The exception that occurred.</param>
56+
public record UpdateDownloadFailed(UpdateInfo Update, Exception Error);

Mythetech.Framework.Desktop/Updates/IUpdateService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,16 @@ public interface IUpdateService
2424
/// <summary>
2525
/// Checks for available updates.
2626
/// Publishes UpdateCheckStarted, UpdateCheckCompleted, and UpdateAvailable events.
27+
/// On failure, publishes UpdateCheckFailed.
2728
/// </summary>
2829
Task CheckForUpdatesAsync(CancellationToken cancellationToken = default);
2930

31+
/// <summary>
32+
/// Checks for updates if the app is installed and AutoCheckOnStartup is enabled.
33+
/// Call from your layout's OnAfterRenderAsync for non-blocking startup checks.
34+
/// </summary>
35+
Task CheckForUpdatesOnStartupAsync(CancellationToken cancellationToken = default);
36+
3037
/// <summary>
3138
/// Downloads the available update.
3239
/// Publishes UpdateDownloadStarted, UpdateDownloadProgress, and UpdateDownloadCompleted events.

Mythetech.Framework.Desktop/Updates/UpdateRegistrationExtensions.cs

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,14 @@ public static IServiceCollection AddUpdateService(this IServiceCollection servic
3434
}
3535

3636
/// <summary>
37-
/// Activates the update system by checking for updates on startup if enabled.
38-
/// Call after UseMessageBus() and UseSettingsFramework().
37+
/// Activates the update system. Call after UseMessageBus() and UseSettingsFramework().
38+
/// To check for updates on startup, call <see cref="IUpdateService.CheckForUpdatesAsync"/>
39+
/// from your layout's OnAfterRenderAsync method.
3940
/// </summary>
40-
public static async Task<IServiceProvider> UseUpdateServiceAsync(this IServiceProvider serviceProvider)
41+
public static IServiceProvider UseUpdateService(this IServiceProvider serviceProvider)
4142
{
42-
var settingsProvider = serviceProvider.GetService<ISettingsProvider>();
43-
var settings = settingsProvider?.GetSettings<UpdateSettings>();
44-
45-
if (settings?.AutoCheckOnStartup == true)
46-
{
47-
var updateService = serviceProvider.GetRequiredService<IUpdateService>();
48-
if (updateService.IsInstalled)
49-
{
50-
try
51-
{
52-
await updateService.CheckForUpdatesAsync();
53-
}
54-
catch
55-
{
56-
// Silently ignore startup check failures
57-
}
58-
}
59-
}
60-
43+
// Currently a no-op, but provides a consistent activation pattern
44+
// and a place to add future initialization logic
6145
return serviceProvider;
6246
}
6347
}

Mythetech.Framework.Desktop/Updates/VelopackUpdateService.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Microsoft.Extensions.Options;
33
using Mythetech.Framework.Desktop.Updates.Events;
44
using Mythetech.Framework.Infrastructure.MessageBus;
5+
using Mythetech.Framework.Infrastructure.Settings;
56
using Velopack;
67

78
namespace Mythetech.Framework.Desktop.Updates;
@@ -14,17 +15,20 @@ public class VelopackUpdateService : IUpdateService
1415
{
1516
private readonly UpdateServiceOptions _options;
1617
private readonly IMessageBus _messageBus;
18+
private readonly ISettingsProvider? _settingsProvider;
1719
private readonly ILogger<VelopackUpdateService> _logger;
1820
private UpdateManager? _updateManager;
1921

2022
public VelopackUpdateService(
2123
IOptions<UpdateServiceOptions> options,
2224
IMessageBus messageBus,
23-
ILogger<VelopackUpdateService> logger)
25+
ILogger<VelopackUpdateService> logger,
26+
ISettingsProvider? settingsProvider = null)
2427
{
2528
_options = options.Value;
2629
_messageBus = messageBus;
2730
_logger = logger;
31+
_settingsProvider = settingsProvider;
2832
}
2933

3034
/// <inheritdoc />
@@ -118,11 +122,30 @@ public async Task CheckForUpdatesAsync(CancellationToken cancellationToken = def
118122
catch (Exception ex)
119123
{
120124
_logger.LogError(ex, "Failed to check for updates");
125+
await _messageBus.PublishAsync(new UpdateCheckFailed(ex));
121126
await _messageBus.PublishAsync(new UpdateCheckCompleted(null));
122-
throw;
123127
}
124128
}
125129

130+
/// <inheritdoc />
131+
public async Task CheckForUpdatesOnStartupAsync(CancellationToken cancellationToken = default)
132+
{
133+
if (!IsInstalled)
134+
{
135+
_logger.LogDebug("Startup update check skipped - app is not installed via Velopack");
136+
return;
137+
}
138+
139+
var settings = _settingsProvider?.GetSettings<UpdateSettings>();
140+
if (settings?.AutoCheckOnStartup != true)
141+
{
142+
_logger.LogDebug("Startup update check skipped - disabled in settings");
143+
return;
144+
}
145+
146+
await CheckForUpdatesAsync(cancellationToken);
147+
}
148+
126149
/// <inheritdoc />
127150
public async Task DownloadUpdateAsync(CancellationToken cancellationToken = default)
128151
{
@@ -153,7 +176,7 @@ await manager.DownloadUpdatesAsync(veloUpdate, progress =>
153176
catch (Exception ex)
154177
{
155178
_logger.LogError(ex, "Failed to download update");
156-
throw;
179+
await _messageBus.PublishAsync(new UpdateDownloadFailed(AvailableUpdate, ex));
157180
}
158181
}
159182

Mythetech.Framework/Components/AppContextDrawer/AppContextDrawer.razor.css

Lines changed: 0 additions & 2 deletions
This file was deleted.

Mythetech.Framework/Components/AppContextDrawer/ContextPanelItem.razor.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
.context-item-active {
77
background-color: var(--mud-palette-secondary);
8-
border-radius: 20%;
98
}
109

1110
.context-panel-badge {

Mythetech.Framework/Mythetech.Framework.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<Company>Mythetech</Company>
88
<GenerateDocumentationFile>True</GenerateDocumentationFile>
99
<PackageId>Mythetech.Framework</PackageId>
10-
<Version>0.7.0</Version>
10+
<Version>0.7.1</Version>
1111
<Authors>Mythetech</Authors>
1212
<Description>Base component library for Mythetech applications</Description>
1313
<PackageTags>blazor;components;ui;framework;cross-platform;desktop;webassembly;photino</PackageTags>

0 commit comments

Comments
 (0)