diff --git a/src/Api.Service/Api.Service.csproj b/src/Api.Service/Api.Service.csproj index c98317ca0..21a087bfb 100644 --- a/src/Api.Service/Api.Service.csproj +++ b/src/Api.Service/Api.Service.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Api.Service/ApiStartupServices.cs b/src/Api.Service/ApiStartupServices.cs index 0c1426dc1..c090207f4 100644 --- a/src/Api.Service/ApiStartupServices.cs +++ b/src/Api.Service/ApiStartupServices.cs @@ -55,7 +55,8 @@ public static void ConfigureP2GApiServices(this IServiceCollection services) services.AddSingleton(); services.AddSingleton(); - // SYSTEM INFO + // SYSTEM INFO + services.AddSingleton(); services.AddSingleton(); // USERS diff --git a/src/Api.Service/SystemInfoService.cs b/src/Api.Service/SystemInfoService.cs index b8af4483f..605f81bad 100644 --- a/src/Api.Service/SystemInfoService.cs +++ b/src/Api.Service/SystemInfoService.cs @@ -1,9 +1,9 @@ using Api.Contract; +using Api.Service; using Common; using Common.Dto; using Common.Observe; using Common.Service; -using Core.GitHub; using Philosowaffle.Capability.ReleaseChecks.Model; namespace Api.Services; @@ -16,12 +16,12 @@ public interface ISystemInfoService public class SystemInfoService : ISystemInfoService { - private readonly IGitHubReleaseCheckService _gitHubService; + private readonly IVersionInformationService _versionInformationService; private readonly ISettingsService _settingsService; - public SystemInfoService(IGitHubReleaseCheckService gitHubService, ISettingsService settingsService) + public SystemInfoService(ISettingsService settingsService, IVersionInformationService versionInformationService) { - _gitHubService = gitHubService; + _versionInformationService = versionInformationService; _settingsService = settingsService; } @@ -30,7 +30,9 @@ public async Task GetAsync(SystemInfoGetRequest request, LatestReleaseInformation? versionInformation = null; if (request.CheckForUpdate) - versionInformation = await _gitHubService.GetLatestReleaseInformationAsync("philosowaffle", "peloton-to-garmin", Constants.AppVersion); + versionInformation = await _versionInformationService.GetLatestReleaseInformationAsync(); + + var documentationVersion = versionInformation?.IsInstalledVersionReleaseCandidate ?? true ? "master" : $"v{Constants.AppVersion}"; var settings = await _settingsService.GetSettingsAsync(); @@ -52,7 +54,7 @@ public async Task GetAsync(SystemInfoGetRequest request, } : null, GitHub = "https://github.com/philosowaffle/peloton-to-garmin", - Documentation = "https://philosowaffle.github.io/peloton-to-garmin/", + Documentation = $"https://philosowaffle.github.io/peloton-to-garmin/{documentationVersion}", Forums = "https://github.com/philosowaffle/peloton-to-garmin/discussions", Donate = "https://www.buymeacoffee.com/philosowaffle", Issues = "https://github.com/philosowaffle/peloton-to-garmin/issues", diff --git a/src/Api.Service/VersionInformationService.cs b/src/Api.Service/VersionInformationService.cs new file mode 100644 index 000000000..55467ed30 --- /dev/null +++ b/src/Api.Service/VersionInformationService.cs @@ -0,0 +1,52 @@ +using Common; +using Common.Observe; +using Core.GitHub; +using Microsoft.Extensions.Caching.Memory; +using Philosowaffle.Capability.ReleaseChecks.Model; +using Serilog; + +namespace Api.Service; + +public interface IVersionInformationService +{ + Task GetLatestReleaseInformationAsync(); +} + +public class VersionInformationService : IVersionInformationService +{ + private static readonly ILogger _logger = LogContext.ForClass(); + private static readonly object _lock = new object(); + + private readonly IGitHubReleaseCheckService _gitHubService; + private readonly IMemoryCache _cache; + + public VersionInformationService(IGitHubReleaseCheckService gitHubService, IMemoryCache cache) + { + _gitHubService = gitHubService; + _cache = cache; + } + + public Task GetLatestReleaseInformationAsync() + { + using var tracing = Tracing.Trace($"{nameof(VersionInformationService)}.{nameof(GetLatestReleaseInformationAsync)}"); + + try + { + lock (_lock) + { + var key = $"LatestReleaseInformation"; + return _cache.GetOrCreateAsync(key, (cacheEntry) => + { + cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); + + return _gitHubService.GetLatestReleaseInformationAsync("philosowaffle", "peloton-to-garmin", Constants.AppVersion); + }); + } + } + catch (Exception e) + { + _logger.Error("Failed to fetch Latest P2G Release information.", e); + return Task.FromResult(new LatestReleaseInformation()); + } + } +} diff --git a/src/SharedUI/Pages/Settings.razor b/src/SharedUI/Pages/Settings.razor index 2a258c342..f934f5f8d 100644 --- a/src/SharedUI/Pages/Settings.razor +++ b/src/SharedUI/Pages/Settings.razor @@ -56,8 +56,10 @@ private async Task LoadDataAsync() { using var tracing = Tracing.ClientTrace($"{nameof(Settings)}.{nameof(LoadDataAsync)}", kind: ActivityKind.Client); - var systemInfo = await _apiClient.SystemInfoGetAsync(new SystemInfoGetRequest() { CheckForUpdate = false }); - configDocumentation = systemInfo.Documentation + "/configuration/json.html"; + var settings = await _apiClient.SettingsGetAsync(); + var systemInfo = await _apiClient.SystemInfoGetAsync(new SystemInfoGetRequest() { CheckForUpdate = settings.App.CheckForUpdates }); + + configDocumentation = systemInfo.Documentation + "/configuration/json"; } } \ No newline at end of file diff --git a/src/UnitTests/Api.Service/SystemInfoServiceTests.cs b/src/UnitTests/Api.Service/SystemInfoServiceTests.cs index 401127c8d..e079945ac 100644 --- a/src/UnitTests/Api.Service/SystemInfoServiceTests.cs +++ b/src/UnitTests/Api.Service/SystemInfoServiceTests.cs @@ -1,4 +1,5 @@ using Api.Contract; +using Api.Service; using Api.Services; using Common; using Core.GitHub; @@ -42,9 +43,9 @@ public async Task GetAsync_WhenRequest_Enriches_LatestVersionInfo() // SETUP var autoMocker = new AutoMocker(); var controller = autoMocker.CreateInstance(); - var ghService = autoMocker.GetMock(); + var ghService = autoMocker.GetMock(); - ghService.Setup(x => x.GetLatestReleaseInformationAsync("philosowaffle", "peloton-to-garmin", Constants.AppVersion)) + ghService.Setup(x => x.GetLatestReleaseInformationAsync()) .ReturnsAsync(new LatestReleaseInformation() { IsReleaseNewerThanInstalledVersion = true, @@ -64,6 +65,6 @@ public async Task GetAsync_WhenRequest_Enriches_LatestVersionInfo() response.NewerVersionAvailable.Should().NotBeNull(); response.LatestVersionInformation.Should().NotBeNull(); - ghService.Verify(x => x.GetLatestReleaseInformationAsync("philosowaffle", "peloton-to-garmin", Constants.AppVersion), Times.Once()); + ghService.Verify(x => x.GetLatestReleaseInformationAsync(), Times.Once()); } } diff --git a/vNextReleaseNotes.md b/vNextReleaseNotes.md index f0d680be6..6336e58be 100644 --- a/vNextReleaseNotes.md +++ b/vNextReleaseNotes.md @@ -6,6 +6,10 @@ - [#564] Set a custom title prefix on Workouts - [#559] Ability to exclude Outdoor Cycling workouts from sycning +## Fixes + +- [#581] Fix broken Documentation link in UI + ## Docker Tags - Console