Iceshrimp.NET/Iceshrimp.Frontend/Core/Services/UpdateService.cs
2024-11-23 02:11:22 +01:00

106 lines
No EOL
3.1 KiB
C#

using Iceshrimp.Frontend.Components;
using Iceshrimp.Shared.Helpers;
using Iceshrimp.Shared.Schemas.Web;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace Iceshrimp.Frontend.Core.Services;
internal class UpdateService
{
private readonly ApiService _api;
private readonly ILogger<UpdateService> _logger;
private readonly GlobalComponentSvc _globalComponentSvc;
private readonly Lazy<Task<IJSObjectReference>> _moduleTask;
private readonly NavigationManager _nav;
private VersionInfo FrontendVersion { get; } = VersionHelpers.VersionInfo.Value;
public VersionResponse? BackendVersion { get; private set; }
// ReSharper disable once UnusedAutoPropertyAccessor.Local
private Timer Timer { get; set; }
public UpdateService(
ApiService api, ILogger<UpdateService> logger, GlobalComponentSvc globalComponentSvc, IJSRuntime js,
NavigationManager nav
)
{
_api = api;
_logger = logger;
_globalComponentSvc = globalComponentSvc;
_nav = nav;
_moduleTask = new Lazy<Task<IJSObjectReference>>(() => js.InvokeAsync<IJSObjectReference>(
"import",
"./Core/Services/UpdateService.cs.js")
.AsTask());
Timer = new Timer(Callback, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
_ = RegisterUpdateCallbackAsync();
}
private async Task RegisterUpdateCallbackAsync()
{
var module = await _moduleTask.Value;
var objRef = DotNetObjectReference.Create(this);
await module.InvokeAsync<string>("RegisterUpdateCallback", objRef);
}
[JSInvokable]
public void OnUpdateFound()
{
var banner = new BannerContainer.Banner
{
Text = "New version available", OnTap = () => { _nav.NavigateTo("/settings/about"); }
};
_globalComponentSvc.BannerComponent?.AddBanner(banner);
}
public async Task<bool> ServiceWorkerCheckWaitingAsync()
{
var module = await _moduleTask.Value;
return await module.InvokeAsync<bool>("ServiceWorkerCheckWaiting");
}
public async Task ServiceWorkerUpdateAsync()
{
var module = await _moduleTask.Value;
await module.InvokeVoidAsync("ServiceWorkerUpdate");
}
public async Task<bool> ServiceWorkerSkipWaitingAsync()
{
var module = await _moduleTask.Value;
return await module.InvokeAsync<bool>("ServiceWorkerSkipWaiting");
}
private void Callback(object? caller)
{
_ = CheckVersionAsync();
}
private async Task<VersionResponse?> GetVersionAsync()
{
try
{
var backendVersion = await _api.Version.GetVersionAsync();
_logger.LogInformation("Successfully fetched backend version.");
return backendVersion;
}
catch (Exception e)
{
_logger.LogError(e, "Failed to fetch backend version.");
return null;
}
}
private async Task CheckVersionAsync()
{
var version = await GetVersionAsync();
if (version is null) return;
BackendVersion = version;
if (version.Version != FrontendVersion.Version)
{
await ServiceWorkerUpdateAsync();
}
}
}