Files
Wino-Mail/Wino.Services/UpdateManager.cs
T

127 lines
4.0 KiB
C#
Raw Normal View History

2026-03-02 00:44:29 +01:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Wino.Core.Domain;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Updates;
2026-03-05 10:12:03 +01:00
using Wino.Services.Migrations;
2026-03-02 00:44:29 +01:00
namespace Wino.Services;
public class UpdateManager : IUpdateManager
{
private const string UpdateNotesResourcePath = "ms-appx:///Assets/UpdateNotes/vnext.json";
2026-03-05 10:12:03 +01:00
private const string FeaturesResourcePath = "ms-appx:///Assets/UpdateNotes/features.json";
2026-03-02 00:44:29 +01:00
private const string UpdateNotesSeenKeyFormat = "UpdateNotes_{0}_Shown";
private const string MigrationCompletedKeyFormat = "Migration_{0}_Completed";
private readonly IFileService _fileService;
private readonly IConfigurationService _configurationService;
private readonly INativeAppService _nativeAppService;
private readonly List<IAppMigration> _migrations = [];
private string _versionSeenKey = string.Empty;
2026-03-05 10:12:03 +01:00
private UpdateNotes _latestUpdateNotes = new();
2026-03-02 00:44:29 +01:00
public UpdateManager(IFileService fileService,
IConfigurationService configurationService,
INativeAppService nativeAppService)
{
_fileService = fileService;
_configurationService = configurationService;
_nativeAppService = nativeAppService;
2026-03-05 10:12:03 +01:00
_migrations.Add(new VNextDelayMigration());
2026-03-02 00:44:29 +01:00
}
private string GetVersionSeenKey()
{
if (string.IsNullOrEmpty(_versionSeenKey))
{
var version = _nativeAppService.GetFullAppVersion();
var sanitized = version.Replace(".", "_");
_versionSeenKey = string.Format(UpdateNotesSeenKeyFormat, sanitized);
}
return _versionSeenKey;
}
public async Task<UpdateNotes> GetLatestUpdateNotesAsync()
{
try
{
var json = await _fileService.GetFileContentByApplicationUriAsync(UpdateNotesResourcePath);
if (string.IsNullOrEmpty(json))
2026-03-05 10:12:03 +01:00
{
_latestUpdateNotes = new UpdateNotes();
return _latestUpdateNotes;
}
2026-03-02 00:44:29 +01:00
2026-03-05 10:12:03 +01:00
_latestUpdateNotes = JsonSerializer.Deserialize(json, BasicTypesJsonContext.Default.UpdateNotes) ?? new UpdateNotes();
return _latestUpdateNotes;
2026-03-02 00:44:29 +01:00
}
catch (Exception)
{
2026-03-05 10:12:03 +01:00
_latestUpdateNotes = new UpdateNotes();
return _latestUpdateNotes;
2026-03-02 00:44:29 +01:00
}
}
2026-03-05 10:12:03 +01:00
// T
2026-03-02 00:44:29 +01:00
public bool ShouldShowUpdateNotes()
=> !_configurationService.Get(GetVersionSeenKey(), false);
2026-03-05 10:12:03 +01:00
public async Task<List<UpdateNoteSection>> GetFeaturesAsync()
{
try
{
var json = await _fileService.GetFileContentByApplicationUriAsync(FeaturesResourcePath);
if (string.IsNullOrEmpty(json))
return [];
return JsonSerializer.Deserialize(json, BasicTypesJsonContext.Default.ListUpdateNoteSection) ?? [];
}
catch (Exception)
{
return [];
}
}
2026-03-02 00:44:29 +01:00
public void MarkUpdateNotesAsSeen()
=> _configurationService.Set(GetVersionSeenKey(), true);
public bool HasPendingMigrations()
2026-03-05 10:12:03 +01:00
{
if (!_latestUpdateNotes.HasPendingMigrations)
return false;
return _migrations.Any(m => !_configurationService.Get(string.Format(MigrationCompletedKeyFormat, m.MigrationId), false));
}
2026-03-02 00:44:29 +01:00
public async Task RunPendingMigrationsAsync()
{
2026-03-05 10:12:03 +01:00
if (!_latestUpdateNotes.HasPendingMigrations)
_latestUpdateNotes = await GetLatestUpdateNotesAsync();
if (!_latestUpdateNotes.HasPendingMigrations)
return;
2026-03-02 00:44:29 +01:00
foreach (var migration in _migrations)
{
var key = string.Format(MigrationCompletedKeyFormat, migration.MigrationId);
if (!_configurationService.Get(key, false))
{
await migration.ExecuteAsync();
_configurationService.Set(key, true);
}
}
}
public void RegisterMigrations(IEnumerable<IAppMigration> migrations)
=> _migrations.AddRange(migrations);
}