mirror of
https://github.com/BlossomiShymae/Needlework.Net.git
synced 2025-12-06 10:10:48 +01:00
feat: add settings page
This commit is contained in:
@@ -3,5 +3,7 @@
|
|||||||
public static class BlobCacheKeys
|
public static class BlobCacheKeys
|
||||||
{
|
{
|
||||||
public static readonly string GithubLatestRelease = nameof(GithubLatestRelease);
|
public static readonly string GithubLatestRelease = nameof(GithubLatestRelease);
|
||||||
|
|
||||||
|
public static readonly string AppSettings = nameof(AppSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
Needlework.Net/DataModels/AppSettings.cs
Normal file
13
Needlework.Net/DataModels/AppSettings.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace Needlework.Net.DataModels
|
||||||
|
{
|
||||||
|
public partial class AppSettings : ObservableObject
|
||||||
|
{
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _isCheckForUpdates = true;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _isCheckForSchema = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.8" />
|
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.8" />
|
||||||
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.3.0" />
|
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.3.0" />
|
||||||
<PackageReference Include="BlossomiShymae.Briar" Version="0.2.0" />
|
<PackageReference Include="BlossomiShymae.Briar" Version="0.2.0" />
|
||||||
|
<PackageReference Include="bodong.Avalonia.PropertyGrid" Version="11.2.4" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
<PackageReference Include="DebounceThrottle" Version="3.0.1" />
|
<PackageReference Include="DebounceThrottle" Version="3.0.1" />
|
||||||
<PackageReference Include="FastCache.Cached" Version="1.8.2" />
|
<PackageReference Include="FastCache.Cached" Version="1.8.2" />
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using Needlework.Net.ViewModels.Pages.Console;
|
|||||||
using Needlework.Net.ViewModels.Pages.Endpoints;
|
using Needlework.Net.ViewModels.Pages.Endpoints;
|
||||||
using Needlework.Net.ViewModels.Pages.Home;
|
using Needlework.Net.ViewModels.Pages.Home;
|
||||||
using Needlework.Net.ViewModels.Pages.Schemas;
|
using Needlework.Net.ViewModels.Pages.Schemas;
|
||||||
|
using Needlework.Net.ViewModels.Pages.Settings;
|
||||||
using Needlework.Net.ViewModels.Pages.WebSocket;
|
using Needlework.Net.ViewModels.Pages.WebSocket;
|
||||||
using Needlework.Net.Views.MainWindow;
|
using Needlework.Net.Views.MainWindow;
|
||||||
using Needlework.Net.Views.Pages.About;
|
using Needlework.Net.Views.Pages.About;
|
||||||
@@ -21,6 +22,7 @@ using Needlework.Net.Views.Pages.Console;
|
|||||||
using Needlework.Net.Views.Pages.Endpoints;
|
using Needlework.Net.Views.Pages.Endpoints;
|
||||||
using Needlework.Net.Views.Pages.Home;
|
using Needlework.Net.Views.Pages.Home;
|
||||||
using Needlework.Net.Views.Pages.Schemas;
|
using Needlework.Net.Views.Pages.Schemas;
|
||||||
|
using Needlework.Net.Views.Pages.Settings;
|
||||||
using Needlework.Net.Views.Pages.WebSocket;
|
using Needlework.Net.Views.Pages.WebSocket;
|
||||||
using Projektanker.Icons.Avalonia;
|
using Projektanker.Icons.Avalonia;
|
||||||
using Projektanker.Icons.Avalonia.FontAwesome;
|
using Projektanker.Icons.Avalonia.FontAwesome;
|
||||||
@@ -97,6 +99,8 @@ class Program
|
|||||||
// WEBSOCKET
|
// WEBSOCKET
|
||||||
locator.Register<WebSocketViewModel>(() => new WebSocketView());
|
locator.Register<WebSocketViewModel>(() => new WebSocketView());
|
||||||
locator.Register<EventViewModel>(() => new EventView());
|
locator.Register<EventViewModel>(() => new EventView());
|
||||||
|
// SETTINGS
|
||||||
|
locator.Register<SettingsViewModel>(() => new SettingsView());
|
||||||
|
|
||||||
builder.AddSingleton<IDataTemplate>(locator);
|
builder.AddSingleton<IDataTemplate>(locator);
|
||||||
}
|
}
|
||||||
@@ -132,6 +136,7 @@ class Program
|
|||||||
builder.AddSingleton<PageBase, WebSocketViewModel>();
|
builder.AddSingleton<PageBase, WebSocketViewModel>();
|
||||||
builder.AddSingleton<PageBase, SchemasViewModel>();
|
builder.AddSingleton<PageBase, SchemasViewModel>();
|
||||||
builder.AddSingleton<PageBase, AboutViewModel>();
|
builder.AddSingleton<PageBase, AboutViewModel>();
|
||||||
|
builder.AddSingleton<PageBase, SettingsViewModel>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
private static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using BlossomiShymae.Briar;
|
|
||||||
using BlossomiShymae.Briar.Utils;
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
@@ -11,7 +9,6 @@ using Needlework.Net.Constants;
|
|||||||
using Needlework.Net.Extensions;
|
using Needlework.Net.Extensions;
|
||||||
using Needlework.Net.Helpers;
|
using Needlework.Net.Helpers;
|
||||||
using Needlework.Net.Messages;
|
using Needlework.Net.Messages;
|
||||||
using Needlework.Net.Models;
|
|
||||||
using Needlework.Net.Services;
|
using Needlework.Net.Services;
|
||||||
using Needlework.Net.ViewModels.Pages;
|
using Needlework.Net.ViewModels.Pages;
|
||||||
using Needlework.Net.Views.MainWindow;
|
using Needlework.Net.Views.MainWindow;
|
||||||
@@ -20,8 +17,6 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http.Json;
|
|
||||||
using System.Reactive;
|
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -33,25 +28,18 @@ public partial class MainWindowViewModel
|
|||||||
{
|
{
|
||||||
private readonly DocumentService _documentService;
|
private readonly DocumentService _documentService;
|
||||||
|
|
||||||
private readonly GithubService _githubService;
|
|
||||||
|
|
||||||
private readonly NotificationService _notificationService;
|
private readonly NotificationService _notificationService;
|
||||||
|
|
||||||
private readonly DialogService _dialogService;
|
private readonly DialogService _dialogService;
|
||||||
|
|
||||||
private readonly SchemaPaneService _schemaPaneService;
|
private readonly SchemaPaneService _schemaPaneService;
|
||||||
|
|
||||||
private readonly IDisposable _checkForUpdatesDisposable;
|
public MainWindowViewModel(IEnumerable<PageBase> pages, DialogService dialogService, DocumentService documentService, NotificationService notificationService, SchemaPaneService schemaPaneService)
|
||||||
|
|
||||||
private readonly IDisposable _checkForSchemaVersionDisposable;
|
|
||||||
|
|
||||||
public MainWindowViewModel(IEnumerable<PageBase> pages, DialogService dialogService, DocumentService documentService, NotificationService notificationService, GithubService githubService, SchemaPaneService schemaPaneService)
|
|
||||||
{
|
{
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
_documentService = documentService;
|
_documentService = documentService;
|
||||||
_notificationService = notificationService;
|
_notificationService = notificationService;
|
||||||
_schemaPaneService = schemaPaneService;
|
_schemaPaneService = schemaPaneService;
|
||||||
_githubService = githubService;
|
|
||||||
|
|
||||||
NavigationViewItems = pages
|
NavigationViewItems = pages
|
||||||
.OrderBy(p => p.Index)
|
.OrderBy(p => p.Index)
|
||||||
@@ -89,42 +77,6 @@ public partial class MainWindowViewModel
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_checkForUpdatesDisposable = Observable.Timer(TimeSpan.Zero, Intervals.CheckForUpdates)
|
|
||||||
.Select(time => Unit.Default)
|
|
||||||
.Subscribe(async _ =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await CheckForUpdatesAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var message = "Failed to check for updates. Please check your internet connection or try again later.";
|
|
||||||
this.Log()
|
|
||||||
.Error(ex, message);
|
|
||||||
_notificationService.Notify(AppInfo.Name, message, InfoBarSeverity.Error);
|
|
||||||
_checkForUpdatesDisposable?.Dispose();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_checkForSchemaVersionDisposable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromMinutes(5))
|
|
||||||
.Select(time => Unit.Default)
|
|
||||||
.Subscribe(async _ =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await CheckForSchemaVersionAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var message = "Failed to check for schema version. Please check your internet connection or try again later.";
|
|
||||||
this.Log()
|
|
||||||
.Error(ex, message);
|
|
||||||
_notificationService.Notify(AppInfo.Name, message, InfoBarSeverity.Error);
|
|
||||||
_checkForSchemaVersionDisposable?.Dispose();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
WeakReferenceMessenger.Default.RegisterAll(this);
|
WeakReferenceMessenger.Default.RegisterAll(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,8 +103,6 @@ public partial class MainWindowViewModel
|
|||||||
|
|
||||||
public List<NavigationViewItem> NavigationViewItems { get; private set; } = [];
|
public List<NavigationViewItem> NavigationViewItems { get; private set; } = [];
|
||||||
|
|
||||||
public bool IsSchemaVersionChecked { get; private set; }
|
|
||||||
|
|
||||||
public string AppName => AppInfo.Name;
|
public string AppName => AppInfo.Name;
|
||||||
|
|
||||||
public string Title => $"{AppInfo.Name} {AppInfo.Version}";
|
public string Title => $"{AppInfo.Name} {AppInfo.Version}";
|
||||||
@@ -224,48 +174,6 @@ public partial class MainWindowViewModel
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private async Task CheckForUpdatesAsync()
|
|
||||||
{
|
|
||||||
var release = await _githubService.GetLatestReleaseAsync();
|
|
||||||
if (release.IsLatest(AppInfo.Version))
|
|
||||||
{
|
|
||||||
this.Log()
|
|
||||||
.Information("New version available: {TagName}", release.TagName);
|
|
||||||
_notificationService.Notify(AppInfo.Name, $"New version available: {release.TagName}", InfoBarSeverity.Informational, null, "https://github.com/BlossomiShymae/Needlework.Net/releases/latest");
|
|
||||||
_checkForUpdatesDisposable?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async Task CheckForSchemaVersionAsync()
|
|
||||||
{
|
|
||||||
if (!ProcessFinder.IsPortOpen()) return;
|
|
||||||
|
|
||||||
var lcuSchemaDocument = await _documentService.GetLcuSchemaDocumentAsync();
|
|
||||||
var client = Connector.GetLcuHttpClientInstance();
|
|
||||||
var currentSemVer = lcuSchemaDocument.Info.Version.Split('.');
|
|
||||||
var systemBuild = await client.GetFromJsonAsync<SystemBuild>("/system/v1/builds") ?? throw new NullReferenceException();
|
|
||||||
var latestSemVer = systemBuild.Version.Split('.');
|
|
||||||
|
|
||||||
if (!IsSchemaVersionChecked)
|
|
||||||
{
|
|
||||||
this.Log()
|
|
||||||
.Information("LCU Schema (current): {Version}", lcuSchemaDocument.Info.Version);
|
|
||||||
this.Log()
|
|
||||||
.Information("LCU Schema (latest): {Version}", systemBuild.Version);
|
|
||||||
IsSchemaVersionChecked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isVersionMatching = currentSemVer[0] == latestSemVer[0] && currentSemVer[1] == latestSemVer[1]; // Compare major and minor versions
|
|
||||||
if (!isVersionMatching)
|
|
||||||
{
|
|
||||||
this.Log()
|
|
||||||
.Warning("LCU Schema version mismatch: Current {CurrentVersion}, Latest {LatestVersion}", lcuSchemaDocument.Info.Version, systemBuild.Version);
|
|
||||||
_notificationService.Notify(AppInfo.Name, $"LCU Schema is possibly outdated compared to latest system build. Consider submitting a pull request on dysolix/hasagi-types.\nCurrent: {string.Join(".", currentSemVer)}\nLatest: {string.Join(".", latestSemVer)}", InfoBarSeverity.Warning, null, "https://github.com/dysolix/hasagi-types#updating-the-types");
|
|
||||||
_checkForSchemaVersionDisposable?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<object>> PopulateAsync(string? searchText, CancellationToken cancellationToken)
|
public async Task<IEnumerable<object>> PopulateAsync(string? searchText, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (searchText == null) return [];
|
if (searchText == null) return [];
|
||||||
|
|||||||
197
Needlework.Net/ViewModels/Pages/Settings/SettingsViewModel.cs
Normal file
197
Needlework.Net/ViewModels/Pages/Settings/SettingsViewModel.cs
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
using Akavache;
|
||||||
|
using Avalonia.Threading;
|
||||||
|
using BlossomiShymae.Briar;
|
||||||
|
using BlossomiShymae.Briar.Utils;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
|
using Needlework.Net.Constants;
|
||||||
|
using Needlework.Net.DataModels;
|
||||||
|
using Needlework.Net.Extensions;
|
||||||
|
using Needlework.Net.Models;
|
||||||
|
using Needlework.Net.Services;
|
||||||
|
using System;
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using System.Reactive;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Needlework.Net.ViewModels.Pages.Settings
|
||||||
|
{
|
||||||
|
public partial class SettingsViewModel : PageBase, IEnableLogger
|
||||||
|
{
|
||||||
|
private readonly IBlobCache _blobCache;
|
||||||
|
|
||||||
|
private readonly IDisposable _checkForUpdatesDisposable;
|
||||||
|
|
||||||
|
private readonly IDisposable _checkForSchemaVersionDisposable;
|
||||||
|
|
||||||
|
private readonly GithubService _githubService;
|
||||||
|
|
||||||
|
private readonly DocumentService _documentService;
|
||||||
|
|
||||||
|
private readonly NotificationService _notificationService;
|
||||||
|
|
||||||
|
private readonly TaskCompletionSource<bool> _initializeTaskCompletionSource = new();
|
||||||
|
|
||||||
|
public SettingsViewModel(IBlobCache blobCache, GithubService githubService, DocumentService documentService, NotificationService notificationService) : base("Settings", "fa-solid fa-gear")
|
||||||
|
{
|
||||||
|
_blobCache = blobCache;
|
||||||
|
_githubService = githubService;
|
||||||
|
_documentService = documentService;
|
||||||
|
_notificationService = notificationService;
|
||||||
|
|
||||||
|
_checkForUpdatesDisposable = Observable.Timer(TimeSpan.Zero, Intervals.CheckForUpdates)
|
||||||
|
.Select(time => Unit.Default)
|
||||||
|
.Subscribe(async _ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _initializeTaskCompletionSource.Task;
|
||||||
|
if (AppSettings!.IsCheckForUpdates)
|
||||||
|
{
|
||||||
|
await CheckForUpdatesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var message = "Failed to check for updates. Please check your internet connection or try again later.";
|
||||||
|
this.Log()
|
||||||
|
.Error(ex, message);
|
||||||
|
_notificationService.Notify(AppInfo.Name, message, InfoBarSeverity.Error);
|
||||||
|
_checkForUpdatesDisposable?.Dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_checkForSchemaVersionDisposable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromMinutes(5))
|
||||||
|
.Select(time => Unit.Default)
|
||||||
|
.Subscribe(async _ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _initializeTaskCompletionSource.Task;
|
||||||
|
if (AppSettings!.IsCheckForSchema)
|
||||||
|
{
|
||||||
|
await CheckForSchemaVersionAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var message = "Failed to check for schema version. Please check your internet connection or try again later.";
|
||||||
|
this.Log()
|
||||||
|
.Error(ex, message);
|
||||||
|
_notificationService.Notify(AppInfo.Name, message, InfoBarSeverity.Error);
|
||||||
|
_checkForSchemaVersionDisposable?.Dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _isBusy = true;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private AppSettings? _appSettings;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
[NotifyPropertyChangedFor(nameof(UpdateCheckTitle), nameof(UpdateCheckIconValue), nameof(UpdateCheckLastChecked))]
|
||||||
|
private Guid _upToDateGuid = Guid.Empty;
|
||||||
|
|
||||||
|
public bool IsUpToDate { get; private set; }
|
||||||
|
|
||||||
|
public bool IsSchemaVersionChecked { get; private set; }
|
||||||
|
|
||||||
|
public string UpdateCheckTitle => IsUpToDate switch
|
||||||
|
{
|
||||||
|
true => "You're up to date",
|
||||||
|
false => "You're out of date"
|
||||||
|
};
|
||||||
|
|
||||||
|
public string UpdateCheckIconValue => IsUpToDate switch
|
||||||
|
{
|
||||||
|
true => "fa-heart-circle-check",
|
||||||
|
false => "fa-heart-circle-exclamation"
|
||||||
|
};
|
||||||
|
|
||||||
|
public string UpdateCheckLastChecked => $"Last checked: {DateTime.Now:dddd}, {DateTime.Now:T}";
|
||||||
|
|
||||||
|
partial void OnAppSettingsChanged(AppSettings? value)
|
||||||
|
{
|
||||||
|
if (AppSettings is AppSettings appSettings)
|
||||||
|
{
|
||||||
|
_blobCache.InsertObject(BlobCacheKeys.AppSettings, appSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task InitializeAsync()
|
||||||
|
{
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AppSettings = await _blobCache.GetObject<AppSettings>(BlobCacheKeys.AppSettings);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.Log()
|
||||||
|
.Warning(ex, "Failed to get application settings.");
|
||||||
|
AppSettings = new();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
AppSettings!.PropertyChanged += (s, e) => OnAppSettingsChanged((AppSettings?)s);
|
||||||
|
IsBusy = false;
|
||||||
|
_initializeTaskCompletionSource.SetResult(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task CheckForUpdatesAsync()
|
||||||
|
{
|
||||||
|
var release = await _githubService.GetLatestReleaseAsync();
|
||||||
|
if (release.IsLatest(AppInfo.Version))
|
||||||
|
{
|
||||||
|
this.Log()
|
||||||
|
.Information("New version available: {TagName}", release.TagName);
|
||||||
|
_notificationService.Notify(AppInfo.Name, $"New version available: {release.TagName}", InfoBarSeverity.Informational, null, "https://github.com/BlossomiShymae/Needlework.Net/releases/latest");
|
||||||
|
_checkForUpdatesDisposable?.Dispose();
|
||||||
|
IsUpToDate = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IsUpToDate = true;
|
||||||
|
}
|
||||||
|
UpToDateGuid = Guid.NewGuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task CheckForSchemaVersionAsync()
|
||||||
|
{
|
||||||
|
if (!ProcessFinder.IsPortOpen()) return;
|
||||||
|
|
||||||
|
var lcuSchemaDocument = await _documentService.GetLcuSchemaDocumentAsync();
|
||||||
|
var client = Connector.GetLcuHttpClientInstance();
|
||||||
|
var currentSemVer = lcuSchemaDocument.Info.Version.Split('.');
|
||||||
|
var systemBuild = await client.GetFromJsonAsync<SystemBuild>("/system/v1/builds") ?? throw new NullReferenceException();
|
||||||
|
var latestSemVer = systemBuild.Version.Split('.');
|
||||||
|
|
||||||
|
if (!IsSchemaVersionChecked)
|
||||||
|
{
|
||||||
|
this.Log()
|
||||||
|
.Information("LCU Schema (current): {Version}", lcuSchemaDocument.Info.Version);
|
||||||
|
this.Log()
|
||||||
|
.Information("LCU Schema (latest): {Version}", systemBuild.Version);
|
||||||
|
IsSchemaVersionChecked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isVersionMatching = currentSemVer[0] == latestSemVer[0] && currentSemVer[1] == latestSemVer[1]; // Compare major and minor versions
|
||||||
|
if (!isVersionMatching)
|
||||||
|
{
|
||||||
|
this.Log()
|
||||||
|
.Warning("LCU Schema outdated: Current {CurrentVersion}, Latest {LatestVersion}", lcuSchemaDocument.Info.Version, systemBuild.Version);
|
||||||
|
_notificationService.Notify(AppInfo.Name, $"LCU Schema is outdated compared to latest system build. Consider submitting a pull request on dysolix/hasagi-types.\nCurrent: {string.Join(".", currentSemVer)}\nLatest: {string.Join(".", latestSemVer)}", InfoBarSeverity.Warning, null, "https://github.com/dysolix/hasagi-types#updating-the-types");
|
||||||
|
_checkForSchemaVersionDisposable?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
Needlework.Net/Views/Pages/Settings/SettingsView.axaml
Normal file
75
Needlework.Net/Views/Pages/Settings/SettingsView.axaml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:vm="using:Needlework.Net.ViewModels.Pages.Settings"
|
||||||
|
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||||
|
xmlns:uip="using:FluentAvalonia.UI.Controls.Primitives"
|
||||||
|
xmlns:i="https://github.com/projektanker/icons.avalonia"
|
||||||
|
xmlns:controls="using:Needlework.Net.Controls"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="Needlework.Net.Views.Pages.Settings.SettingsView"
|
||||||
|
x:DataType="vm:SettingsViewModel">
|
||||||
|
<controls:BusyArea IsBusy="{Binding IsBusy}"
|
||||||
|
BusyText="Loading...">
|
||||||
|
<ScrollViewer Margin="16">
|
||||||
|
<StackPanel>
|
||||||
|
<StackPanel.Styles>
|
||||||
|
<Style Selector="ui|SettingsExpander">
|
||||||
|
<Setter Property="Margin" Value="0,0,0,4"/>
|
||||||
|
</Style>
|
||||||
|
</StackPanel.Styles>
|
||||||
|
<Grid ColumnDefinitions="auto,*"
|
||||||
|
Margin="16">
|
||||||
|
<i:Icon Value="{Binding UpdateCheckIconValue}"
|
||||||
|
FontSize="64"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="0,0,16,0"/>
|
||||||
|
<StackPanel Grid.Column="1"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<TextBlock Theme="{StaticResource SubtitleTextBlockStyle}"
|
||||||
|
Text="{Binding UpdateCheckTitle}"/>
|
||||||
|
<TextBlock Foreground="{DynamicResource TextFillColorTertiaryBrush}"
|
||||||
|
Text="{Binding UpdateCheckLastChecked}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<ui:SettingsExpander Header="Updates">
|
||||||
|
<ui:SettingsExpander.IconSource>
|
||||||
|
<ui:ImageIconSource>
|
||||||
|
<ui:ImageIconSource.Source>
|
||||||
|
<i:IconImage Value="fa-rotate" Brush="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||||
|
</ui:ImageIconSource.Source>
|
||||||
|
</ui:ImageIconSource>
|
||||||
|
</ui:SettingsExpander.IconSource>
|
||||||
|
<ui:SettingsExpander.Footer>
|
||||||
|
<Button Command="{Binding CheckForUpdatesCommand}">Check for updates</Button>
|
||||||
|
</ui:SettingsExpander.Footer>
|
||||||
|
</ui:SettingsExpander>
|
||||||
|
<ui:SettingsExpander Header="Get notified of the latest update as soon as it's available">
|
||||||
|
<ui:SettingsExpander.IconSource>
|
||||||
|
<ui:ImageIconSource>
|
||||||
|
<ui:ImageIconSource.Source>
|
||||||
|
<i:IconImage Value="fa-bullhorn" Brush="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||||
|
</ui:ImageIconSource.Source>
|
||||||
|
</ui:ImageIconSource>
|
||||||
|
</ui:SettingsExpander.IconSource>
|
||||||
|
<ui:SettingsExpander.Footer>
|
||||||
|
<ToggleSwitch IsChecked="{Binding AppSettings.IsCheckForUpdates}"/>
|
||||||
|
</ui:SettingsExpander.Footer>
|
||||||
|
</ui:SettingsExpander>
|
||||||
|
<ui:SettingsExpander Header="Get notified when LCU Schema is outdated with /system/v1/builds">
|
||||||
|
<ui:SettingsExpander.IconSource>
|
||||||
|
<ui:ImageIconSource>
|
||||||
|
<ui:ImageIconSource.Source>
|
||||||
|
<i:IconImage Value="fa-file-circle-question" Brush="{DynamicResource TextFillColorPrimaryBrush}"/>
|
||||||
|
</ui:ImageIconSource.Source>
|
||||||
|
</ui:ImageIconSource>
|
||||||
|
</ui:SettingsExpander.IconSource>
|
||||||
|
<ui:SettingsExpander.Footer>
|
||||||
|
<ToggleSwitch IsChecked="{Binding AppSettings.IsCheckForSchema}"/>
|
||||||
|
</ui:SettingsExpander.Footer>
|
||||||
|
</ui:SettingsExpander>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</controls:BusyArea>
|
||||||
|
</UserControl>
|
||||||
11
Needlework.Net/Views/Pages/Settings/SettingsView.axaml.cs
Normal file
11
Needlework.Net/Views/Pages/Settings/SettingsView.axaml.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Needlework.Net.Views.Pages.Settings;
|
||||||
|
|
||||||
|
public partial class SettingsView : UserControl
|
||||||
|
{
|
||||||
|
public SettingsView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user