From 4d078d8e934390ea634e65a05b4f31327cf675a4 Mon Sep 17 00:00:00 2001 From: GamerVII-NET Date: Sun, 2 Jun 2024 05:43:06 +0300 Subject: [PATCH 01/63] Update host URL in ResourceKeysDictionary The host URL used in the ResourceKeysDictionary file has been updated from a local address to a production address. Additionally, a minor formatting change was made in the OverviewPageViewModel file. --- src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs | 4 ++-- src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index fd8f5a0..78d9295 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -17,7 +17,7 @@ public static class ResourceKeysDictionary public const string InvalidAuthData = "InvalidAuthData"; public const string Reconnecting = "Reconnecting"; public const string LostConnection = "LostConnection"; - public const string Host = "http://192.168.31.199:5000"; - // public const string Host = "https://gmlb.recloud.tech"; + // public const string Host = "http://192.168.31.199:5000"; + public const string Host = "https://gmlb.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; } diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index 065771c..dbcc1cd 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -188,6 +188,7 @@ private async Task GenerateProcess(CancellationToken cancellationToken, LocalizationService.GetString(ResourceKeysDictionary.Launching), LocalizationService.GetString(ResourceKeysDictionary.PreparingLaunch), true); + return process; } From 2dd54b8be62e186b3b9655377ed57375dd0a167e Mon Sep 17 00:00:00 2001 From: GamerVII-NET Date: Sun, 2 Jun 2024 05:43:17 +0300 Subject: [PATCH 02/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 5b38d80..caf9c80 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 5b38d80ab902c644a794a438752ba26cd7cc9a88 +Subproject commit caf9c80d67ac3d52d11f97e9c91da06f3d8aa8af From 74b5ff30ce0cd9941222241ba73d8c50d03b62b8 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 2 Jun 2024 22:21:42 +0300 Subject: [PATCH 03/63] Replace submodule update with git clone in scripts The git submodule update command in both the 'load-repositories.sh' and 'load-repositories.bat' scripts has been replaced with git clone. This allows for repositories 'GamerVII.Notification.Avalonia' and 'Gml.Client' to be cloned directly instead of being updated through submodules. --- load-repositories.bat | 6 +++++- load-repositories.sh | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/load-repositories.bat b/load-repositories.bat index 5b5110f..4b935f8 100644 --- a/load-repositories.bat +++ b/load-repositories.bat @@ -1 +1,5 @@ -git submodule update --init --recursive + +git clone --recursive https://github.com/GamerVII-NET/GamerVII.Notification.Avalonia.git ./src/GamerVII.Notification.Avalonia + + +git clone https://github.com/GamerVII-NET/Gml.Client.git ./src/Gml.Client diff --git a/load-repositories.sh b/load-repositories.sh index 5b5110f..4b935f8 100644 --- a/load-repositories.sh +++ b/load-repositories.sh @@ -1 +1,5 @@ -git submodule update --init --recursive + +git clone --recursive https://github.com/GamerVII-NET/GamerVII.Notification.Avalonia.git ./src/GamerVII.Notification.Avalonia + + +git clone https://github.com/GamerVII-NET/Gml.Client.git ./src/Gml.Client From f7f2a10ace712203790456cd71ef41ae0ac4a748 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 2 Jun 2024 22:21:52 +0300 Subject: [PATCH 04/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index caf9c80..7767b95 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit caf9c80d67ac3d52d11f97e9c91da06f3d8aa8af +Subproject commit 7767b95c309c546a281317c69b709ff020fb3500 From 7bcc2ff697dc2eed3dea2ae490d640f99088c0ae Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 2 Jun 2024 22:43:32 +0300 Subject: [PATCH 05/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 7767b95..ac72848 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 7767b95c309c546a281317c69b709ff020fb3500 +Subproject commit ac728482b0ad826dab45d79b4899982af851d78c From 883bce2adf2fc058a67d386b1f50076521ee552c Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 2 Jun 2024 22:45:13 +0300 Subject: [PATCH 06/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index ac72848..cbdb603 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit ac728482b0ad826dab45d79b4899982af851d78c +Subproject commit cbdb60349d2909cb18512f94e809904d44db5f96 From 8eb0dcc492ab9a97dfff3efc468947e0c3be5f60 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 03:11:05 +0300 Subject: [PATCH 07/63] Update system service, resources, and application UI The system service has been updated to asynchronously load system data. Additional resource keys and corresponding translations have been added to the localization service. Several changes have been made to the application user interface including a new splash screen, application icon, and version number. --- Gml.Launcher.sln | 12 +-- src/Gml.Launcher/App.axaml.cs | 20 +++- .../Assets/Images/avalonia-logo.ico | Bin 176111 -> 0 bytes src/Gml.Launcher/Assets/Images/document.svg | 2 +- src/Gml.Launcher/Assets/Images/logo.ico | Bin 0 -> 38078 bytes .../ResourceKeysDictionary.Template.cs | 3 + .../Resources/ResourceKeysDictionary.cs | 7 +- .../Assets/Resources/Resources.en.resx | 9 ++ .../Assets/Resources/Resources.resx | 9 ++ .../Assets/Resources/Resources.ru.resx | 9 ++ .../Core/Extensions/ServiceLocator.cs | 36 ++++--- .../Core/Services/ISystemService.cs | 1 + .../Core/Services/SystemService.cs | 16 ++- src/Gml.Launcher/Gml.Launcher.csproj | 4 +- .../ViewModels/Pages/OverviewPageViewModel.cs | 10 +- .../ViewModels/Pages/SettingsPageViewModel.cs | 7 +- .../ViewModels/SplashScreenViewModel.cs | 92 ++++++++++++++++++ src/Gml.Launcher/Views/MainWindow.axaml | 2 +- .../Views/SplashScreen/SplashScreen.axaml | 48 +++++++++ .../Views/SplashScreen/SplashScreen.axaml.cs | 22 +++++ 20 files changed, 268 insertions(+), 41 deletions(-) delete mode 100644 src/Gml.Launcher/Assets/Images/avalonia-logo.ico create mode 100644 src/Gml.Launcher/Assets/Images/logo.ico create mode 100644 src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs create mode 100644 src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml create mode 100644 src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs diff --git a/Gml.Launcher.sln b/Gml.Launcher.sln index 339b3cb..f469eff 100644 --- a/Gml.Launcher.sln +++ b/Gml.Launcher.sln @@ -29,7 +29,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gml.Web.Api.Dto", "src\Gml. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gml.Web.Api.Domains", "src\Gml.Client\src\Gml.Web.Api.Domains\Gml.Web.Api.Domains.csproj", "{88B821C7-B895-4CB0-832A-5B66138B6AF2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GmlCore.Interfaces", "src\Gml.Client\src\GmlCore.Interfaces\GmlCore.Interfaces.csproj", "{211E5785-E7FD-4E2B-925D-EAACED8F9D2C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gml.Core.Interfaces", "src\Gml.Client\src\Gml.Core.Interfaces\Gml.Core.Interfaces.csproj", "{AE697645-C3EB-4FC8-AAA6-932B9751D348}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -61,10 +61,10 @@ Global {88B821C7-B895-4CB0-832A-5B66138B6AF2}.Debug|Any CPU.Build.0 = Debug|Any CPU {88B821C7-B895-4CB0-832A-5B66138B6AF2}.Release|Any CPU.ActiveCfg = Release|Any CPU {88B821C7-B895-4CB0-832A-5B66138B6AF2}.Release|Any CPU.Build.0 = Release|Any CPU - {211E5785-E7FD-4E2B-925D-EAACED8F9D2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {211E5785-E7FD-4E2B-925D-EAACED8F9D2C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {211E5785-E7FD-4E2B-925D-EAACED8F9D2C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {211E5785-E7FD-4E2B-925D-EAACED8F9D2C}.Release|Any CPU.Build.0 = Release|Any CPU + {AE697645-C3EB-4FC8-AAA6-932B9751D348}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE697645-C3EB-4FC8-AAA6-932B9751D348}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE697645-C3EB-4FC8-AAA6-932B9751D348}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE697645-C3EB-4FC8-AAA6-932B9751D348}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -79,6 +79,6 @@ Global {B8E0451C-3C44-470B-9853-C7D0A3648C20} = {662268E9-BD01-43C7-924B-F4F285C8D391} {20707D1F-FF51-4E7B-BF99-2B87065AFDC7} = {662268E9-BD01-43C7-924B-F4F285C8D391} {88B821C7-B895-4CB0-832A-5B66138B6AF2} = {662268E9-BD01-43C7-924B-F4F285C8D391} - {211E5785-E7FD-4E2B-925D-EAACED8F9D2C} = {662268E9-BD01-43C7-924B-F4F285C8D391} + {AE697645-C3EB-4FC8-AAA6-932B9751D348} = {662268E9-BD01-43C7-924B-F4F285C8D391} EndGlobalSection EndGlobal diff --git a/src/Gml.Launcher/App.axaml.cs b/src/Gml.Launcher/App.axaml.cs index 1da5c4f..e85de60 100644 --- a/src/Gml.Launcher/App.axaml.cs +++ b/src/Gml.Launcher/App.axaml.cs @@ -1,9 +1,11 @@ using System.Globalization; +using System.Threading.Tasks; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Gml.Launcher.ViewModels; using Gml.Launcher.Views; +using Gml.Launcher.Views.SplashScreen; namespace Gml.Launcher; @@ -14,16 +16,32 @@ public override void Initialize() AvaloniaXamlLoader.Load(this); } - public override void OnFrameworkInitializationCompleted() + public override async void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { + +#if DEBUG desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel(), }; +#else + var splashViewModel = new SplashScreenViewModel(); + var splashScreen = new SplashScreen + { + DataContext = splashViewModel + }; + + desktop.MainWindow = splashScreen; + await splashViewModel.InitializeAsync(); + desktop.MainWindow = splashScreen.GetMainWindow(); + desktop.MainWindow.Show(); + splashScreen.Close(); +#endif } + base.OnFrameworkInitializationCompleted(); } } diff --git a/src/Gml.Launcher/Assets/Images/avalonia-logo.ico b/src/Gml.Launcher/Assets/Images/avalonia-logo.ico deleted file mode 100644 index da8d49ff9b94e52778f5324a1b87dd443a698b57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176111 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 zds⪻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

r@R8DskCg$QY%d=x6zD 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

!LxQh!NmF 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 diff --git a/src/Gml.Launcher/Assets/Images/logo.ico b/src/Gml.Launcher/Assets/Images/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..97c7f0d4cbbf593eea7e9c1ea40c8299ec7a7a7c GIT binary patch literal 38078 zcmeI5*>e;{9LJaPfd?O?$|_&w(Z|ID&ngg)@+c3y%JND)%Ck!1MM5|dj>sX901?6& zxetK=5(pq9+#p8)IaJUD|AF}EgXP!XcPH)44zs(no0;A2*@2o&Z|`jP%;$IXF?}Qw zgXDi@WkUWAO>AgRByLM25_iZUQHd@&7@zvrlt|oqvvpVzh5yC4VIxqJti!lun;hM! zP4>wdWpVIXYmz;wXRl3;A&bIE`u`=WlS3unR>_xnmj`RV&uPh|4pqq^{)zg#(!o7u z?nfTg$;P1MAo^Yz>w5vVPJ5_Mj`64A-d73t#@Npkz}{&iVhi4MGsmJXIYi3S?wI`m z*(*8JBs=r*N5Z``W*-oHB?GA=X4ZK78{r=N9Gh9N^^F|9NZ41!dLOvnyJc8mYr7rl z_xXJ>|IqpOus&~-w?eVs37xxb2hxUh@=xi0SUxXK*XHhI;jn@JejM-XoWF^~!7*~! zKw0&j>7zqE^g&VdSeJp(yar`Y!xZtXB&-pjz|N$I-o#oQgYbu!TMHZb8H6Xc-ZJvKZF ztRI^{cefli)BrP{(C_&MW;fwI&(x8?viJS_8aMAupI22$*&t=MuFqZS`>J~YSpLDl z^*s}R6~E>Spy82N4ocqR?*f`%1GdzM&tA!Zb)}X{fO)I?D93ZdC}8cE#pAB{tMkTM ztL;#3?Ad-=`d;upUUAL$%(7wH!_l{e+B<;-uS$Kgu5>z|NjCIJOWp-04v(H3SdX7O z8lb&rdVXEvH%$QMzas61yQ3k8>5l{JzS5t&TmIiq1R7ru8HnzfSU%9#ESC1C`?*Z} z%(8*yl~FPfooW5VeD+FL*oHQ#Tv+&Kbl58yuxvKL2I?Qur(UVp1#xEm$b>%CMHSK0 zeI>tEdH0~Z4Xm$@E`Qnp-$m#ugYi;l<~=HXiQ;*t#(mk7#rH>%x$~LWj?`8Er^-7& z=e7qLn|IpGlizhM2X@TxpMDhh?^~Fii(4LN ze*g}z6i&i4mrtY399RNScJ6dCeLlNG+#gP!y#M1H0G3}m^XI#+ zu(+S!4O~5u&fF~nex@8KqabDOOp9Z~bZvjJZ^U`8frQ(EUk(G;&*x^ZfOK3VZm`S8DVKz#gJ|J)USb-vEBp(|J!lmq{BqPN$4_!`AI*O}$Tg}uSZA?p0E z91>q6dYg-BzTeX){dNpEw`*W>h$?^TC(F)!x#oL)Z#O`{R%p2pMgC+ThR$b`&7}hC zs!`<6c2qW2VSLAOy<6&5`PxC$_+RQQK6@q4LfXwyG-E?z)`pNV+&E^&;A>w zkEJ+Y*pr_RiW2|x9i?SYd0!U)=ST0=HBsWvewtF~yfaVsZ78;W&dWd4xBp?&<_y%yo$>e~wep)%U3T z;{0{L?|V(se~yhXW!`p6g+CiGi9hEdDIGK6y!x};GBAZd-}`btn+e>V_qgaS;N<4a za?qVW$Hj5(ritv89JnqR*LLuFFRwHIJu>DbO6%5et+pep(``XV{>Nl&UGwYa`5L9~ z+0JaAaUS8p{;`NU@#k2vHJ=+e*H_wH*_eBNH_Va)>vYb(m{Nq<|F&+d{_QGHj)kyy z{ASYq0R3z!xHC`M;n$B9pg)dh2!l(p)BN@gYg|IHJ!8k@F zEIIIf7w6KLxK?YiWJfmb(%#`Xks#&3`2n+@j(v?^InH@b#`nvdqkP7FddZ9PZMdF~ z-+bfi(phm09?sG8Vw)|F<0`nGqV7CR**BB#T`$X6+HB1E9mjgIy=}&NF?~kuv&OZA zH;$LFv@&MFEeDP%@e$_k Play in + + Installing updates + + + Check for updates + + + Failed to determine the operating system + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.resx b/src/Gml.Launcher/Assets/Resources/Resources.resx index 95d2362..b3e1692 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.resx @@ -105,4 +105,13 @@ Play in + + Check for updates + + + Installing updates + + + Failed to determine the operating system + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx index 184c5ba..791bee6 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx @@ -98,4 +98,13 @@ Играет в + + Установка обновлений + + + Проверка обновлений + + + Не удалось определить операционную систему + \ No newline at end of file diff --git a/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs b/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs index 4184dda..a0987dd 100644 --- a/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs +++ b/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Threading; using Avalonia; using Gml.Client; using Gml.Launcher.Assets; @@ -21,11 +22,14 @@ public static AppBuilder RegisterServices(this AppBuilder builder) var configurationManager = ConfigurationManager.OpenMachineConfiguration(); - var installationDirectory = Path.Combine(systemService.GetApplicationFolder(), ResourceKeysDictionary.FolderName); + var installationDirectory = + Path.Combine(systemService.GetApplicationFolder(), ResourceKeysDictionary.FolderName); Locator.CurrentMutable.RegisterConstant(new ResourceLocalizationService(), typeof(ILocalizationService)); Locator.CurrentMutable.RegisterConstant(systemService, typeof(ISystemService)); - Locator.CurrentMutable.RegisterConstant(new GmlClientManager(installationDirectory, ResourceKeysDictionary.Host, ResourceKeysDictionary.FolderName, systemService.GetOsType()), typeof(IGmlClientManager)); + Locator.CurrentMutable.RegisterConstant( + new GmlClientManager(installationDirectory, ResourceKeysDictionary.Host, ResourceKeysDictionary.FolderName, + systemService.GetOsType()), typeof(IGmlClientManager)); var storageService = new LocalStorageService(); Locator.CurrentMutable.RegisterConstant(storageService, typeof(IStorageService)); @@ -34,14 +38,12 @@ public static AppBuilder RegisterServices(this AppBuilder builder) if (data != null && !string.IsNullOrEmpty(data.LanguageCode)) { - Assets.Resources.Resources.Culture = systemService + Thread.CurrentThread.CurrentCulture = systemService .GetAvailableLanguages() .FirstOrDefault(c => c.Culture.Name == data.LanguageCode)? - .Culture; + .Culture ?? new CultureInfo("ru-RU");; } - Assets.Resources.Resources.Culture ??= new CultureInfo("ru-RU"); - AppDomain.CurrentDomain.UnhandledException += (sender, args) => { SentrySdk.CaptureException((Exception)args.ExceptionObject); @@ -51,16 +53,19 @@ public static AppBuilder RegisterServices(this AppBuilder builder) try { - SentrySdk.Init(options => + if (!string.IsNullOrEmpty(sentryUrl)) { - options.Dsn = sentryUrl; - options.Debug = true; - options.TracesSampleRate = 1.0; - options.DiagnosticLevel = SentryLevel.Debug; - options.IsGlobalModeEnabled = true; - options.SendDefaultPii = true; - options.MaxAttachmentSize = 10 * 1024 * 1024; - }); + SentrySdk.Init(options => + { + options.Dsn = sentryUrl; + options.Debug = true; + options.TracesSampleRate = 1.0; + options.DiagnosticLevel = SentryLevel.Debug; + options.IsGlobalModeEnabled = true; + options.SendDefaultPii = true; + options.MaxAttachmentSize = 10 * 1024 * 1024; + }); + } } catch (Exception exception) { @@ -69,5 +74,4 @@ public static AppBuilder RegisterServices(this AppBuilder builder) return builder; } - } diff --git a/src/Gml.Launcher/Core/Services/ISystemService.cs b/src/Gml.Launcher/Core/Services/ISystemService.cs index 59f954f..22177d8 100644 --- a/src/Gml.Launcher/Core/Services/ISystemService.cs +++ b/src/Gml.Launcher/Core/Services/ISystemService.cs @@ -13,4 +13,5 @@ public interface ISystemService OsType GetOsType(); IEnumerable GetAvailableLanguages(); string GetHwid(); + Task LoadSystemData(); } diff --git a/src/Gml.Launcher/Core/Services/SystemService.cs b/src/Gml.Launcher/Core/Services/SystemService.cs index 1fe9daf..182f6ae 100644 --- a/src/Gml.Launcher/Core/Services/SystemService.cs +++ b/src/Gml.Launcher/Core/Services/SystemService.cs @@ -19,10 +19,6 @@ public class SystemService : ISystemService public SystemService() { _hardwareInfo = new HardwareInfo(); - - _hardwareInfo.RefreshDriveList(); - _hardwareInfo.RefreshMotherboardList(); - _hardwareInfo.RefreshCPUList(); } public ulong GetMaxRam() @@ -72,6 +68,16 @@ public string GetHwid() return $"{cpuIdentifier}-{motherboardIdentifier}-{diskIdentifiers}"; } + public async Task LoadSystemData() + { + await Task.Run(() => + { + _hardwareInfo.RefreshDriveList(); + _hardwareInfo.RefreshMotherboardList(); + _hardwareInfo.RefreshCPUList(); + }); + } + private static string GetFolderPath(Environment.SpecialFolder folder) { return Environment.GetFolderPath(folder); @@ -99,7 +105,7 @@ public OsType GetOsType() public IEnumerable GetAvailableLanguages() { - return new List + return new List { new() { IconPath = "/Assets/Images/lang-ru.svg", Name = "Русский", Culture = new CultureInfo("ru-RU") }, new() { IconPath = "/Assets/Images/lang-us.svg", Name = "English", Culture = new CultureInfo("en-US") }, diff --git a/src/Gml.Launcher/Gml.Launcher.csproj b/src/Gml.Launcher/Gml.Launcher.csproj index 5058fd5..579313d 100644 --- a/src/Gml.Launcher/Gml.Launcher.csproj +++ b/src/Gml.Launcher/Gml.Launcher.csproj @@ -6,7 +6,9 @@ true app.manifest true - Assets\Images\avalonia-logo.ico + Assets\Images\logo.ico + 2.1.0.0 + 2.1.0.0 diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index dbcc1cd..88b2519 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -95,13 +95,11 @@ internal OverviewPageViewModel(IScreen screen, HomeCommand = ReactiveCommand.Create(() => ListViewModel.SelectedProfile = null); - _gmlManager.ProgressChanged += (_, args) => + _gmlManager.ProgressChanged.Subscribe(percentage => { - if (LoadingPercentage != args.ProgressPercentage) - { - LoadingPercentage = args.ProgressPercentage; - } - }; + if (LoadingPercentage != percentage) + LoadingPercentage = percentage; + }); _closeEvent ??= onClosed.Subscribe(_ => _gameProcess?.Kill()); _profileNameChanged ??= ListViewModel.ProfileChanged.Subscribe(SaveSelectedServer); diff --git a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs index 4eb0be3..94096f1 100644 --- a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs @@ -1,8 +1,10 @@ using System; using System.Collections.ObjectModel; using System.Linq; +using System.Reactive; using System.Reactive.Concurrency; using System.Reactive.Linq; +using System.Threading; using Gml.Launcher.Core.Services; using Gml.Launcher.Models; using Gml.Launcher.ViewModels.Base; @@ -86,9 +88,10 @@ public SettingsPageViewModel( { if (language == null) return; - Assets.Resources.Resources.Culture = language.Culture; + Thread.CurrentThread.CurrentCulture = language.Culture; + Thread.CurrentThread.CurrentCulture.ClearCachedData(); - GoBackCommand.Execute(null); + GoBackCommand.Execute(Unit.Default); }); diff --git a/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs b/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs new file mode 100644 index 0000000..e3441e3 --- /dev/null +++ b/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs @@ -0,0 +1,92 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Threading.Tasks; +using Avalonia.Controls.Shapes; +using Gml.Client; +using Gml.Launcher.Assets; +using Gml.Launcher.Core.Exceptions; +using Gml.Launcher.Core.Services; +using Gml.Launcher.ViewModels.Base; +using Gml.Web.Api.Domains.System; +using GmlCore.Interfaces; +using GmlCore.Interfaces.Storage; +using ReactiveUI; +using ReactiveUI.Fody.Helpers; +using Splat; +using Path = Avalonia.Controls.Shapes.Path; + +namespace Gml.Launcher.ViewModels; + +public class SplashScreenViewModel : WindowViewModelBase +{ + private readonly ISystemService _systemService; + private readonly IGmlClientManager _manager; + private readonly ILocalizationService _localizationService; + + [Reactive] public string StatusText { get; set; } + [Reactive] public bool InfinityLoading { get; set; } = true; + [Reactive] public Int16 Progress { get; set; } + + public SplashScreenViewModel(ISystemService? systemService = null, IGmlClientManager? manager = null, ILocalizationService? localizationService = null) + { + _systemService = systemService ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(ISystemService)); + + _manager = manager ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); + + _localizationService = localizationService ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(ILocalizationService)); + + StatusText = _localizationService.GetString(ResourceKeysDictionary.PreparingLaunch); + } + + public async Task InitializeAsync() + { + var osType = _systemService.GetOsType(); + + await _systemService.LoadSystemData(); + ChangeState(_localizationService.GetString(ResourceKeysDictionary.CheckUpdates), true); + + var versionInfo = await CheckActualVersion(osType); + + if (!versionInfo.IsActuallVersion) + { + ChangeState(_localizationService.GetString(ResourceKeysDictionary.InstallingUpdates), false); + + string exePath = Process.GetCurrentProcess().MainModule?.FileName + ?? throw new Exception(ResourceKeysDictionary.FailedOs); + + var process = _manager.ProgressChanged.Subscribe( + percentage => Progress = Convert.ToInt16(percentage)); + + await _manager.UpdateCurrentLauncher(versionInfo, osType, System.IO.Path.GetFileName(exePath)); + + process.Dispose(); + } + } + + private async Task<(IVersionFile? ActualVersion, bool IsActuallVersion)> CheckActualVersion(OsType osType) + { + var actualVersion = await _manager.GetActualVersion(osType); + + if (actualVersion is null) + { + return (null, false); + } + + var version = Assembly.GetExecutingAssembly().GetName().Version ?? new Version(1, 0, 0, 0); + + return actualVersion.Version.Equals(version.ToString()) + ? (actualVersion, true) + : (actualVersion, false); + } + + private void ChangeState(string text, bool isInfinity) + { + StatusText = text; + InfinityLoading = isInfinity; + } +} diff --git a/src/Gml.Launcher/Views/MainWindow.axaml b/src/Gml.Launcher/Views/MainWindow.axaml index e75b29b..4bc71c8 100644 --- a/src/Gml.Launcher/Views/MainWindow.axaml +++ b/src/Gml.Launcher/Views/MainWindow.axaml @@ -21,7 +21,7 @@ WindowStartupLocation="CenterScreen" TransparencyLevelHint="AcrylicBlur" TransparencyBackgroundFallback="Transparent" - Icon="/Assets/Images/avalonia-logo.ico" + Icon="/Assets/Images/logo.ico" Title="Gml.Launcher"> diff --git a/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml new file mode 100644 index 0000000..617d3f0 --- /dev/null +++ b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + diff --git a/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs new file mode 100644 index 0000000..e1bf1ca --- /dev/null +++ b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs @@ -0,0 +1,22 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using Gml.Launcher.ViewModels; + +namespace Gml.Launcher.Views.SplashScreen; + +public partial class SplashScreen : Window +{ + public SplashScreen() + { + InitializeComponent(); + } + + public MainWindow GetMainWindow() + { + return new MainWindow + { + DataContext = new MainWindowViewModel(), + }; + } +} From 5400913136097ebbde335557e73ed4c9ca4874d5 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 03:11:17 +0300 Subject: [PATCH 08/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index cbdb603..35cb9aa 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit cbdb60349d2909cb18512f94e809904d44db5f96 +Subproject commit 35cb9aa0e949383cc0e0a5735bd69d674a556ed9 From f81fe07f64f33e051186e4df4dc13b31e8be9b72 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 03:17:47 +0300 Subject: [PATCH 09/63] Update submodule Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 35cb9aa..2bb22ae 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 35cb9aa0e949383cc0e0a5735bd69d674a556ed9 +Subproject commit 2bb22aefa210866daf09db4f5f300be3c1037b7e From 2242c13cad0696cf4629a6a10cf0ffc3fd5e6251 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 06:49:37 +0300 Subject: [PATCH 10/63] Add error tracking to AsyncStreamToImageLoader The update wraps the core logic of the OnSourceChanged method inside a try-catch block. In case of any exceptions during execution, they are captured and sent to Sentry for error tracking and troubleshooting. This ensures smoother runtime and easier debugging. --- .../Converters/AsyncStreamToImageLoader.cs | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs index a268000..1fef34f 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs @@ -5,6 +5,7 @@ using Avalonia; using Avalonia.Media.Imaging; using Gml.Launcher.Views.Components; +using Sentry; namespace Gml.Launcher.Core.Converters; @@ -24,31 +25,40 @@ static AsyncStreamToImageLoader() private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPropertyChangedEventArgs args) { - var url = args.GetNewValue(); - - if (string.IsNullOrEmpty(url)) + try { - sender.Source = null; - return; - } + var url = args.GetNewValue(); - if (string.IsNullOrEmpty(url) || !ValidateUrl(url)) - { - sender.Source = null; - return; - }; + if (string.IsNullOrEmpty(url)) + { + sender.Source = null; + return; + } + + if (string.IsNullOrEmpty(url) || !ValidateUrl(url)) + { + sender.Source = null; + return; + } - var fileName = Path.Combine(TempPath, Path.GetFileName(url)); + ; - if (!File.Exists(fileName)) + var fileName = Path.Combine(TempPath, Path.GetFileName(url)); + + if (!File.Exists(fileName)) + { + using var client = new HttpClient(); + var response = await client.GetByteArrayAsync(url); + using var stream = new MemoryStream(response); + await ConvertStreamToFile(stream, fileName); + } + + sender.Source = new Bitmap(File.OpenRead(fileName)); + } + catch (Exception exception) { - using var client = new HttpClient(); - var response = await client.GetByteArrayAsync(url); - using var stream = new MemoryStream(response); - await ConvertStreamToFile(stream, fileName); + SentrySdk.CaptureException(exception); } - - sender.Source = new Bitmap(File.OpenRead(fileName)); } private static async Task ConvertStreamToFile(Stream input, string filePath) From e5df19f3feaf851c0fc31c3254e5f6e24131c9d0 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 09:26:20 +0300 Subject: [PATCH 11/63] Update host URL and clean up code The host URL in the ResourceKeysDictionary file was changed from a local IP address to an external URL "https://gmlb.recloud.tech". --- src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs | 4 ++-- src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index 2996201..ace7a72 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -20,7 +20,7 @@ public static class ResourceKeysDictionary public const string CheckUpdates = "CheckUpdates"; public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; - public const string Host = "http://192.168.31.199:5000"; - // public const string Host = "https://gmlb.recloud.tech"; + // public const string Host = "http://192.168.31.199:5000"; + public const string Host = "https://gmlb.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; } diff --git a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs index 1fef34f..5657845 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs @@ -41,8 +41,6 @@ private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPr return; } - ; - var fileName = Path.Combine(TempPath, Path.GetFileName(url)); if (!File.Exists(fileName)) From 20a0333d1aff0eeecb53f928a24fbe0e97e92a88 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 09:26:36 +0300 Subject: [PATCH 12/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 2bb22ae..20badc0 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 2bb22aefa210866daf09db4f5f300be3c1037b7e +Subproject commit 20badc088bedc392a39b747b35abf7c4cac522e1 From 17f6ab7f7dfcdae1444c61e8bd1b00d14e14afe4 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 06:49:37 +0300 Subject: [PATCH 13/63] Add error tracking to AsyncStreamToImageLoader The update wraps the core logic of the OnSourceChanged method inside a try-catch block. In case of any exceptions during execution, they are captured and sent to Sentry for error tracking and troubleshooting. This ensures smoother runtime and easier debugging. --- .../Converters/AsyncStreamToImageLoader.cs | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs index a268000..1fef34f 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs @@ -5,6 +5,7 @@ using Avalonia; using Avalonia.Media.Imaging; using Gml.Launcher.Views.Components; +using Sentry; namespace Gml.Launcher.Core.Converters; @@ -24,31 +25,40 @@ static AsyncStreamToImageLoader() private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPropertyChangedEventArgs args) { - var url = args.GetNewValue(); - - if (string.IsNullOrEmpty(url)) + try { - sender.Source = null; - return; - } + var url = args.GetNewValue(); - if (string.IsNullOrEmpty(url) || !ValidateUrl(url)) - { - sender.Source = null; - return; - }; + if (string.IsNullOrEmpty(url)) + { + sender.Source = null; + return; + } + + if (string.IsNullOrEmpty(url) || !ValidateUrl(url)) + { + sender.Source = null; + return; + } - var fileName = Path.Combine(TempPath, Path.GetFileName(url)); + ; - if (!File.Exists(fileName)) + var fileName = Path.Combine(TempPath, Path.GetFileName(url)); + + if (!File.Exists(fileName)) + { + using var client = new HttpClient(); + var response = await client.GetByteArrayAsync(url); + using var stream = new MemoryStream(response); + await ConvertStreamToFile(stream, fileName); + } + + sender.Source = new Bitmap(File.OpenRead(fileName)); + } + catch (Exception exception) { - using var client = new HttpClient(); - var response = await client.GetByteArrayAsync(url); - using var stream = new MemoryStream(response); - await ConvertStreamToFile(stream, fileName); + SentrySdk.CaptureException(exception); } - - sender.Source = new Bitmap(File.OpenRead(fileName)); } private static async Task ConvertStreamToFile(Stream input, string filePath) From 7958c64e88ee75c3cde19f687ceb61bd5594caab Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 09:26:20 +0300 Subject: [PATCH 14/63] Update host URL and clean up code The host URL in the ResourceKeysDictionary file was changed from a local IP address to an external URL "https://gmlb.recloud.tech". --- src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs | 4 ++-- src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index 2996201..ace7a72 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -20,7 +20,7 @@ public static class ResourceKeysDictionary public const string CheckUpdates = "CheckUpdates"; public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; - public const string Host = "http://192.168.31.199:5000"; - // public const string Host = "https://gmlb.recloud.tech"; + // public const string Host = "http://192.168.31.199:5000"; + public const string Host = "https://gmlb.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; } diff --git a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs index 1fef34f..5657845 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs @@ -41,8 +41,6 @@ private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPr return; } - ; - var fileName = Path.Combine(TempPath, Path.GetFileName(url)); if (!File.Exists(fileName)) From 08c2c45372ac1579e0ab20a3398c3d000ea7953c Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 09:26:36 +0300 Subject: [PATCH 15/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 2bb22ae..20badc0 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 2bb22aefa210866daf09db4f5f300be3c1037b7e +Subproject commit 20badc088bedc392a39b747b35abf7c4cac522e1 From 00e8ee96ddcfb747f03927f0735e0db9c965a535 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Thu, 6 Jun 2024 09:34:19 +0300 Subject: [PATCH 16/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 20badc0..2bb22ae 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 20badc088bedc392a39b747b35abf7c4cac522e1 +Subproject commit 2bb22aefa210866daf09db4f5f300be3c1037b7e From 57be64834c9e99ba410761b2183501c83d000172 Mon Sep 17 00:00:00 2001 From: Sergey Bryzgalov <123618366+l1sonnn@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:34:38 +0300 Subject: [PATCH 17/63] Gif background functionality (#29) * Merge dev and master btanches (#28) * Update host URL in ResourceKeysDictionary The host URL used in the ResourceKeysDictionary file has been updated from a local address to a production address. Additionally, a minor formatting change was made in the OverviewPageViewModel file. * Replace submodule update with git clone in scripts The git submodule update command in both the 'load-repositories.sh' and 'load-repositories.bat' scripts has been replaced with git clone. This allows for repositories 'GamerVII.Notification.Avalonia' and 'Gml.Client' to be cloned directly instead of being updated through submodules. * Update system service, resources, and application UI The system service has been updated to asynchronously load system data. Additional resource keys and corresponding translations have been added to the localization service. Several changes have been made to the application user interface including a new splash screen, application icon, and version number. * Update submodule link Gml.Client * Add error tracking to AsyncStreamToImageLoader The update wraps the core logic of the OnSourceChanged method inside a try-catch block. In case of any exceptions during execution, they are captured and sent to Sentry for error tracking and troubleshooting. This ensures smoother runtime and easier debugging. * Update host URL and clean up code The host URL in the ResourceKeysDictionary file was changed from a local IP address to an external URL "https://gmlb.recloud.tech". * Add error tracking to AsyncStreamToImageLoader The update wraps the core logic of the OnSourceChanged method inside a try-catch block. In case of any exceptions during execution, they are captured and sent to Sentry for error tracking and troubleshooting. This ensures smoother runtime and easier debugging. * Update host URL and clean up code The host URL in the ResourceKeysDictionary file was changed from a local IP address to an external URL "https://gmlb.recloud.tech". --------- Co-authored-by: GamerVII-NET * Add GIF decoding functionality Introduced several new classes to handle the decoding of GIF files. This includes reading the data stream and processing headers, frames, color tables, and extensions. Functionality for rendering frames and handling exceptions has also been implemented. * Refactor code and optimize exceptions in gif decoder Code for gif decoding has been refactored for improved readability and efficiency. The exception handling has been optimized for specific errors, such as LzwDecompressionException, contributing to better error reporting and debugging. Unnecessary comments and code have also been removed. * Remove unnecessary whitespace in AsyncStreamToImageLoader This commit eliminates a redundant line in the AsyncStreamToImageLoader class file. The change helps to maintain the cleanliness and readability of the code. --------- Co-authored-by: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Co-authored-by: GamerVII-NET Co-authored-by: s.bryzglov Co-authored-by: Anton Terentev --- Gml.Launcher.sln | 7 + .../Converters/AsyncStreamToImageLoader.cs | 19 +- src/Gml.Launcher/Gml.Launcher.csproj | 1 + .../Components/BackgroundComponent.axaml | 13 +- .../Components/BackgroundComponent.axaml.cs | 14 +- src/L1.Avalonia.Gif/AvaloniaGif.csproj | 16 + src/L1.Avalonia.Gif/BgWorkerCommand.cs | 9 + src/L1.Avalonia.Gif/BgWorkerState.cs | 11 + src/L1.Avalonia.Gif/Decoding/BlockTypes.cs | 9 + src/L1.Avalonia.Gif/Decoding/ExtensionType.cs | 7 + src/L1.Avalonia.Gif/Decoding/FrameDisposal.cs | 9 + src/L1.Avalonia.Gif/Decoding/GifColor.cs | 31 + src/L1.Avalonia.Gif/Decoding/GifDecoder.cs | 668 ++++++++++++++++++ src/L1.Avalonia.Gif/Decoding/GifFrame.cs | 14 + src/L1.Avalonia.Gif/Decoding/GifHeader.cs | 15 + src/L1.Avalonia.Gif/Decoding/GifRect.cs | 45 ++ .../Decoding/GifRepeatBehavior.cs | 7 + .../Decoding/InvalidGifStreamException.cs | 23 + .../Decoding/LzwDecompressionException.cs | 23 + .../Extensions/StreamExtensions.cs | 81 +++ src/L1.Avalonia.Gif/GifImage.cs | 215 ++++++ src/L1.Avalonia.Gif/GifInstance.cs | 151 ++++ .../InvalidGifStreamException.cs | 23 + src/L1.Avalonia.Gif/L1.Avalonia.Gif.csproj | 19 + 24 files changed, 1422 insertions(+), 8 deletions(-) create mode 100644 src/L1.Avalonia.Gif/AvaloniaGif.csproj create mode 100644 src/L1.Avalonia.Gif/BgWorkerCommand.cs create mode 100644 src/L1.Avalonia.Gif/BgWorkerState.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/BlockTypes.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/ExtensionType.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/FrameDisposal.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/GifColor.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/GifDecoder.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/GifFrame.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/GifHeader.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/GifRect.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/GifRepeatBehavior.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs create mode 100644 src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs create mode 100644 src/L1.Avalonia.Gif/Extensions/StreamExtensions.cs create mode 100644 src/L1.Avalonia.Gif/GifImage.cs create mode 100644 src/L1.Avalonia.Gif/GifInstance.cs create mode 100644 src/L1.Avalonia.Gif/InvalidGifStreamException.cs create mode 100644 src/L1.Avalonia.Gif/L1.Avalonia.Gif.csproj diff --git a/Gml.Launcher.sln b/Gml.Launcher.sln index f469eff..84b1087 100644 --- a/Gml.Launcher.sln +++ b/Gml.Launcher.sln @@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gml.Web.Api.Domains", "src\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gml.Core.Interfaces", "src\Gml.Client\src\Gml.Core.Interfaces\Gml.Core.Interfaces.csproj", "{AE697645-C3EB-4FC8-AAA6-932B9751D348}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "L1.Avalonia.Gif", "src\L1.Avalonia.Gif\L1.Avalonia.Gif.csproj", "{19B15268-CF4D-4571-8DF3-6EBC586BB856}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -65,6 +67,10 @@ Global {AE697645-C3EB-4FC8-AAA6-932B9751D348}.Debug|Any CPU.Build.0 = Debug|Any CPU {AE697645-C3EB-4FC8-AAA6-932B9751D348}.Release|Any CPU.ActiveCfg = Release|Any CPU {AE697645-C3EB-4FC8-AAA6-932B9751D348}.Release|Any CPU.Build.0 = Release|Any CPU + {19B15268-CF4D-4571-8DF3-6EBC586BB856}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19B15268-CF4D-4571-8DF3-6EBC586BB856}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19B15268-CF4D-4571-8DF3-6EBC586BB856}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19B15268-CF4D-4571-8DF3-6EBC586BB856}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -80,5 +86,6 @@ Global {20707D1F-FF51-4E7B-BF99-2B87065AFDC7} = {662268E9-BD01-43C7-924B-F4F285C8D391} {88B821C7-B895-4CB0-832A-5B66138B6AF2} = {662268E9-BD01-43C7-924B-F4F285C8D391} {AE697645-C3EB-4FC8-AAA6-932B9751D348} = {662268E9-BD01-43C7-924B-F4F285C8D391} + {19B15268-CF4D-4571-8DF3-6EBC586BB856} = {662268E9-BD01-43C7-924B-F4F285C8D391} EndGlobalSection EndGlobal diff --git a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs index 5657845..d75cdcd 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs @@ -5,6 +5,7 @@ using Avalonia; using Avalonia.Media.Imaging; using Gml.Launcher.Views.Components; +using L1.Avalonia.Gif.Decoding; using Sentry; namespace Gml.Launcher.Core.Converters; @@ -51,7 +52,21 @@ private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPr await ConvertStreamToFile(stream, fileName); } - sender.Source = new Bitmap(File.OpenRead(fileName)); + + var fileStream = File.OpenRead(fileName); + + sender.Classes.Clear(); + if (GifDecoder.IsGifStream(fileStream)) + { + sender.Classes.Add("Gif"); + sender.SourceStream = fileStream; + } + else + { + sender.Classes.Add("Image"); + sender.Source = new Bitmap(fileStream); + } + } catch (Exception exception) { @@ -78,7 +93,7 @@ private static bool ValidateUrl(string url) { return Uri.TryCreate(url, UriKind.Absolute, out var uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps) - && Path.GetFileName(url) is {} fileName && Guid.TryParse(fileName, out _); + && Path.GetFileName(url) is { } fileName && Guid.TryParse(fileName, out _); } public static void SetSource(BackgroundComponent obj, string value) => obj.SetValue(SourceProperty, value); diff --git a/src/Gml.Launcher/Gml.Launcher.csproj b/src/Gml.Launcher/Gml.Launcher.csproj index 579313d..b162cbb 100644 --- a/src/Gml.Launcher/Gml.Launcher.csproj +++ b/src/Gml.Launcher/Gml.Launcher.csproj @@ -67,6 +67,7 @@ + diff --git a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml index 961758c..dcab09b 100644 --- a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml +++ b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml @@ -1,12 +1,13 @@  + xmlns:controls="using:Gml.Launcher.Views.Components" + xmlns:gif="clr-namespace:L1.Avalonia.Gif;assembly=L1.Avalonia.Gif"> - + diff --git a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs index 1504b5a..ea1db3b 100644 --- a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs @@ -1,8 +1,7 @@ -using Avalonia; -using Avalonia.Controls; +using System.IO; +using Avalonia; using Avalonia.Controls.Primitives; using Avalonia.Media; -using Avalonia.Media.Imaging; namespace Gml.Launcher.Views.Components; @@ -12,11 +11,18 @@ public class BackgroundComponent : TemplatedControl public static readonly StyledProperty SourceProperty = AvaloniaProperty.Register( nameof(Source)); + public static readonly StyledProperty SourceStreamProperty = AvaloniaProperty.Register( + nameof(SourceStream)); + public IImage? Source { get => GetValue(SourceProperty); set => SetValue(SourceProperty, value); } - + public Stream? SourceStream + { + get => GetValue(SourceStreamProperty); + set => SetValue(SourceStreamProperty, value); + } } diff --git a/src/L1.Avalonia.Gif/AvaloniaGif.csproj b/src/L1.Avalonia.Gif/AvaloniaGif.csproj new file mode 100644 index 0000000..12aec6a --- /dev/null +++ b/src/L1.Avalonia.Gif/AvaloniaGif.csproj @@ -0,0 +1,16 @@ + + + net7.0 + 11 + true + enable + + + + + + + + + + diff --git a/src/L1.Avalonia.Gif/BgWorkerCommand.cs b/src/L1.Avalonia.Gif/BgWorkerCommand.cs new file mode 100644 index 0000000..8714b78 --- /dev/null +++ b/src/L1.Avalonia.Gif/BgWorkerCommand.cs @@ -0,0 +1,9 @@ +namespace L1.Avalonia.Gif; + +internal enum BgWorkerCommand +{ + Null, + Play, + Pause, + Dispose +} diff --git a/src/L1.Avalonia.Gif/BgWorkerState.cs b/src/L1.Avalonia.Gif/BgWorkerState.cs new file mode 100644 index 0000000..0a26382 --- /dev/null +++ b/src/L1.Avalonia.Gif/BgWorkerState.cs @@ -0,0 +1,11 @@ +namespace L1.Avalonia.Gif; + +internal enum BgWorkerState +{ + Null, + Start, + Running, + Paused, + Complete, + Dispose +} diff --git a/src/L1.Avalonia.Gif/Decoding/BlockTypes.cs b/src/L1.Avalonia.Gif/Decoding/BlockTypes.cs new file mode 100644 index 0000000..f3c752d --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/BlockTypes.cs @@ -0,0 +1,9 @@ +namespace L1.Avalonia.Gif.Decoding; + +internal enum BlockTypes +{ + EMPTY = 0, + EXTENSION = 0x21, + IMAGE_DESCRIPTOR = 0x2C, + TRAILER = 0x3B +} diff --git a/src/L1.Avalonia.Gif/Decoding/ExtensionType.cs b/src/L1.Avalonia.Gif/Decoding/ExtensionType.cs new file mode 100644 index 0000000..b8379c7 --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/ExtensionType.cs @@ -0,0 +1,7 @@ +namespace L1.Avalonia.Gif.Decoding; + +internal enum ExtensionType +{ + GRAPHICS_CONTROL = 0xF9, + APPLICATION = 0xFF +} diff --git a/src/L1.Avalonia.Gif/Decoding/FrameDisposal.cs b/src/L1.Avalonia.Gif/Decoding/FrameDisposal.cs new file mode 100644 index 0000000..1efad2b --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/FrameDisposal.cs @@ -0,0 +1,9 @@ +namespace L1.Avalonia.Gif.Decoding; + +public enum FrameDisposal +{ + Unknown = 0, + Leave = 1, + Background = 2, + Restore = 3 +} diff --git a/src/L1.Avalonia.Gif/Decoding/GifColor.cs b/src/L1.Avalonia.Gif/Decoding/GifColor.cs new file mode 100644 index 0000000..e3863d1 --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/GifColor.cs @@ -0,0 +1,31 @@ +using System.Runtime.InteropServices; + +namespace L1.Avalonia.Gif.Decoding; + +[StructLayout(LayoutKind.Explicit)] +public readonly struct GifColor +{ + [FieldOffset(3)] public readonly byte A; + + [FieldOffset(2)] public readonly byte R; + + [FieldOffset(1)] public readonly byte G; + + [FieldOffset(0)] public readonly byte B; + + /// + /// A struct that represents a ARGB color and is aligned as + /// a BGRA bytefield in memory. + /// + /// Red + /// Green + /// Blue + /// Alpha + public GifColor(byte r, byte g, byte b, byte a = byte.MaxValue) + { + A = a; + R = r; + G = g; + B = b; + } +} diff --git a/src/L1.Avalonia.Gif/Decoding/GifDecoder.cs b/src/L1.Avalonia.Gif/Decoding/GifDecoder.cs new file mode 100644 index 0000000..9eb920e --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/GifDecoder.cs @@ -0,0 +1,668 @@ +using System.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using Avalonia; +using Avalonia.Media.Imaging; +using static L1.Avalonia.Gif.Extensions.StreamExtensions; + +namespace L1.Avalonia.Gif.Decoding; + +public sealed class GifDecoder : IDisposable +{ + private static readonly ReadOnlyMemory G87AMagic + = Encoding.ASCII.GetBytes("GIF87a").AsMemory(); + + private static readonly ReadOnlyMemory G89AMagic + = Encoding.ASCII.GetBytes("GIF89a").AsMemory(); + + private static readonly ReadOnlyMemory NetscapeMagic + = Encoding.ASCII.GetBytes("NETSCAPE2.0").AsMemory(); + + private static readonly TimeSpan FrameDelayThreshold = TimeSpan.FromMilliseconds(10); + private static readonly TimeSpan FrameDelayDefault = TimeSpan.FromMilliseconds(100); + private static readonly GifColor TransparentColor = new(0, 0, 0, 0); + private static readonly int MaxTempBuf = 768; + private static readonly int MaxStackSize = 4096; + private static readonly int MaxBits = 4097; + + private static readonly (int Start, int Step)[] Pass = + { + (0, 8), + (4, 8), + (2, 4), + (1, 2) + }; + + // private ulong _globalColorTable; + private readonly int _backBufferBytes; + private readonly CancellationToken _currentCtsToken; + + private readonly Stream _fileStream; + private readonly bool _hasFrameBackups; + + public readonly List Frames = new(); + private byte[] _backupFrameIndexBuf; + private GifColor[] _bitmapBackBuffer; + + private int _gctSize, _bgIndex, _prevFrame = -1, _backupFrame = -1; + private bool _gctUsed; + + private GifRect _gifDimensions; + private volatile bool _hasNewFrame; + private byte[] _indexBuf; + private byte[] _pixelStack; + + private short[] _prefixBuf; + private byte[] _suffixBuf; + + public GifDecoder(Stream fileStream, CancellationToken currentCtsToken) + { + _fileStream = fileStream; + _currentCtsToken = currentCtsToken; + + ProcessHeaderData(); + ProcessFrameData(); + + Header.IterationCount = Header.Iterations switch + { + -1 => new GifRepeatBehavior { Count = 1 }, + 0 => new GifRepeatBehavior { LoopForever = true }, + > 0 => new GifRepeatBehavior { Count = Header.Iterations }, + _ => Header.IterationCount + }; + + var pixelCount = _gifDimensions.TotalPixels; + + _hasFrameBackups = Frames + .Any(f => f.FrameDisposalMethod == FrameDisposal.Restore); + + _bitmapBackBuffer = new GifColor[pixelCount]; + _indexBuf = new byte[pixelCount]; + + if (_hasFrameBackups) + _backupFrameIndexBuf = new byte[pixelCount]; + + _prefixBuf = new short[MaxStackSize]; + _suffixBuf = new byte[MaxStackSize]; + _pixelStack = new byte[MaxStackSize + 1]; + + _backBufferBytes = pixelCount * Marshal.SizeOf(typeof(GifColor)); + } + + public GifHeader Header { get; private set; } + + public PixelSize Size => new(Header.Dimensions.Width, Header.Dimensions.Height); + + public void Dispose() + { + Frames.Clear(); + + _bitmapBackBuffer = null; + _prefixBuf = null; + _suffixBuf = null; + _pixelStack = null; + _indexBuf = null; + _backupFrameIndexBuf = null; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private int PixCoord(int x, int y) + { + return x + y * _gifDimensions.Width; + } + + private void ClearImage() + { + Array.Fill(_bitmapBackBuffer, TransparentColor); + //ClearArea(_gifDimensions); + + _prevFrame = -1; + _backupFrame = -1; + } + + public void RenderFrame(int fIndex, WriteableBitmap writeableBitmap, bool forceClear = false) + { + if (_currentCtsToken.IsCancellationRequested) + return; + + if ((fIndex < 0) | (fIndex >= Frames.Count)) + return; + + if (_prevFrame == fIndex) + return; + + if (fIndex == 0 || forceClear || fIndex < _prevFrame) + ClearImage(); + + DisposePreviousFrame(); + + _prevFrame++; + + // render intermediate frame + for (var idx = _prevFrame; idx < fIndex; ++idx) + { + var prevFrame = Frames[idx]; + + if (prevFrame.FrameDisposalMethod == FrameDisposal.Restore) + continue; + + if (prevFrame.FrameDisposalMethod == FrameDisposal.Background) + { + ClearArea(prevFrame.Dimensions); + continue; + } + + RenderFrameAt(idx, writeableBitmap); + } + + RenderFrameAt(fIndex, writeableBitmap); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void RenderFrameAt(int idx, WriteableBitmap writeableBitmap) + { + var tmpB = ArrayPool.Shared.Rent(MaxTempBuf); + + var curFrame = Frames[idx]; + DecompressFrameToIndexBuffer(curFrame, _indexBuf, tmpB); + + if (_hasFrameBackups & curFrame.ShouldBackup) + { + Buffer.BlockCopy(_indexBuf, 0, _backupFrameIndexBuf, 0, curFrame.Dimensions.TotalPixels); + _backupFrame = idx; + } + + DrawFrame(curFrame, _indexBuf); + + _prevFrame = idx; + _hasNewFrame = true; + + using var lockedBitmap = writeableBitmap.Lock(); + WriteBackBufToFb(lockedBitmap.Address); + + ArrayPool.Shared.Return(tmpB); + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void DrawFrame(GifFrame curFrame, Memory frameIndexSpan) + { + var activeColorTable = + curFrame.IsLocalColorTableUsed ? curFrame.LocalColorTable : Header.GlobarColorTable; + + var cX = curFrame.Dimensions.X; + var cY = curFrame.Dimensions.Y; + var cH = curFrame.Dimensions.Height; + var cW = curFrame.Dimensions.Width; + var tC = curFrame.TransparentColorIndex; + var hT = curFrame.HasTransparency; + + if (curFrame.IsInterlaced) + { + var curSrcRow = 0; + for (var i = 0; i < 4; i++) + { + var curPass = Pass[i]; + var y = curPass.Start; + while (y < cH) + { + DrawRow(curSrcRow++, y); + y += curPass.Step; + } + } + } + else + { + for (var i = 0; i < cH; i++) + DrawRow(i, i); + } + + //for (var row = 0; row < cH; row++) + void DrawRow(int srcRow, int destRow) + { + // Get the starting point of the current row on frame's index stream. + var indexOffset = srcRow * cW; + + // Get the target backbuffer offset from the frames coords. + var targetOffset = PixCoord(cX, destRow + cY); + var len = _bitmapBackBuffer.Length; + + for (var i = 0; i < cW; i++) + { + var indexColor = frameIndexSpan.Span[indexOffset + i]; + + if (activeColorTable == null || targetOffset >= len || + indexColor > activeColorTable.Length) return; + + if (!(hT & (indexColor == tC))) + _bitmapBackBuffer[targetOffset] = activeColorTable[indexColor]; + + targetOffset++; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void DisposePreviousFrame() + { + if (_prevFrame == -1) + return; + + var prevFrame = Frames[_prevFrame]; + + switch (prevFrame.FrameDisposalMethod) + { + case FrameDisposal.Background: + ClearArea(prevFrame.Dimensions); + break; + case FrameDisposal.Restore: + if (_hasFrameBackups && _backupFrame != -1) + DrawFrame(Frames[_backupFrame], _backupFrameIndexBuf); + else + ClearArea(prevFrame.Dimensions); + break; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ClearArea(GifRect area) + { + for (var y = 0; y < area.Height; y++) + { + var targetOffset = PixCoord(area.X, y + area.Y); + for (var x = 0; x < area.Width; x++) + _bitmapBackBuffer[targetOffset + x] = TransparentColor; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void DecompressFrameToIndexBuffer(GifFrame curFrame, Span indexSpan, byte[] tempBuf) + { + _fileStream.Position = curFrame.LZWStreamPosition; + var totalPixels = curFrame.Dimensions.TotalPixels; + + // Initialize GIF data stream decoder. + var dataSize = curFrame.LZWMinCodeSize; + var clear = 1 << dataSize; + var endOfInformation = clear + 1; + var available = clear + 2; + var oldCode = -1; + var codeSize = dataSize + 1; + var codeMask = (1 << codeSize) - 1; + + for (var code = 0; code < clear; code++) + { + _prefixBuf[code] = 0; + _suffixBuf[code] = (byte)code; + } + + // Decode GIF pixel stream. + int bits, first, top, pixelIndex; + var datum = bits = first = top = pixelIndex = 0; + + while (pixelIndex < totalPixels) + { + var blockSize = _fileStream.ReadBlock(tempBuf); + + if (blockSize == 0) + break; + + var blockPos = 0; + + while (blockPos < blockSize) + { + datum += tempBuf[blockPos] << bits; + blockPos++; + + bits += 8; + + while (bits >= codeSize) + { + // Get the next code. + var code = datum & codeMask; + datum >>= codeSize; + bits -= codeSize; + + // Interpret the code + if (code == clear) + { + // Reset decoder. + codeSize = dataSize + 1; + codeMask = (1 << codeSize) - 1; + available = clear + 2; + oldCode = -1; + continue; + } + + // Check for explicit end-of-stream + if (code == endOfInformation) + return; + + if (oldCode == -1) + { + indexSpan[pixelIndex++] = _suffixBuf[code]; + oldCode = code; + first = code; + continue; + } + + var inCode = code; + if (code >= available) + { + _pixelStack[top++] = (byte)first; + code = oldCode; + + if (top == MaxBits) + ThrowException(); + } + + while (code >= clear) + { + if (code >= MaxBits || code == _prefixBuf[code]) + ThrowException(); + + _pixelStack[top++] = _suffixBuf[code]; + code = _prefixBuf[code]; + + if (top == MaxBits) + ThrowException(); + } + + first = _suffixBuf[code]; + _pixelStack[top++] = (byte)first; + + // Add new code to the dictionary + if (available < MaxStackSize) + { + _prefixBuf[available] = (short)oldCode; + _suffixBuf[available] = (byte)first; + available++; + + if ((available & codeMask) == 0 && available < MaxStackSize) + { + codeSize++; + codeMask += available; + } + } + + oldCode = inCode; + + // Drain the pixel stack. + do + { + indexSpan[pixelIndex++] = _pixelStack[--top]; + } while (top > 0); + } + } + } + + while (pixelIndex < totalPixels) + indexSpan[pixelIndex++] = 0; // clear missing pixels + + void ThrowException() + { + throw new LzwDecompressionException(); + } + } + + /// + /// Directly copies the struct array to a bitmap IntPtr. + /// + private void WriteBackBufToFb(IntPtr targetPointer) + { + if (_currentCtsToken.IsCancellationRequested) + return; + + if (!(_hasNewFrame & (_bitmapBackBuffer != null))) return; + + unsafe + { + fixed (void* src = &_bitmapBackBuffer[0]) + { + Buffer.MemoryCopy(src, targetPointer.ToPointer(), (uint)_backBufferBytes, + (uint)_backBufferBytes); + } + + _hasNewFrame = false; + } + } + + public static bool IsGifStream(Stream stream) + { + var tmpB = ArrayPool.Shared.Rent(MaxTempBuf); + var tempBuf = tmpB.AsSpan(); + + var _ = stream.Read(tmpB, 0, 6); + stream.Position = 0; + + return tempBuf[..3].SequenceEqual(G87AMagic[..3].Span); + } + + /// + /// Processes GIF Header. + /// + private void ProcessHeaderData() + { + var str = _fileStream; + var tmpB = ArrayPool.Shared.Rent(MaxTempBuf); + var tempBuf = tmpB.AsSpan(); + + var _ = str.Read(tmpB, 0, 6); + + if (!tempBuf[..3].SequenceEqual(G87AMagic[..3].Span)) + throw new InvalidGifStreamException("Not a GIF stream"); + + if (!(tempBuf[..6].SequenceEqual(G87AMagic.Span) | + tempBuf[..6].SequenceEqual(G89AMagic.Span))) + throw new InvalidGifStreamException("Unsupported GIF Version: " + + Encoding.ASCII.GetString(tempBuf[..6].ToArray())); + + ProcessScreenDescriptor(tmpB); + + Header = new GifHeader + { + Dimensions = _gifDimensions, + HasGlobalColorTable = _gctUsed, + // GlobalColorTableCacheID = _globalColorTable, + GlobarColorTable = + _gctUsed ? ProcessColorTable(ref str, tmpB, _gctSize) : Array.Empty(), + GlobalColorTableSize = _gctSize, + BackgroundColorIndex = _bgIndex, + HeaderSize = _fileStream.Position + }; + + ArrayPool.Shared.Return(tmpB); + } + + /// + /// Parses colors from file stream to target color table. + /// + private static GifColor[] ProcessColorTable(ref Stream stream, byte[] rawBufSpan, int nColors) + { + var nBytes = 3 * nColors; + var target = new GifColor[nColors]; + + var n = stream.Read(rawBufSpan, 0, nBytes); + + if (n < nBytes) + throw new InvalidOperationException("Wrong color table bytes."); + + int i = 0, j = 0; + + while (i < nColors) + { + var r = rawBufSpan[j++]; + var g = rawBufSpan[j++]; + var b = rawBufSpan[j++]; + target[i++] = new GifColor(r, g, b); + } + + return target; + } + + /// + /// Parses screen and other GIF descriptors. + /// + private void ProcessScreenDescriptor(byte[] tempBuf) + { + var width = _fileStream.ReadUShortS(tempBuf); + var height = _fileStream.ReadUShortS(tempBuf); + + var packed = _fileStream.ReadByteS(tempBuf); + + _gctUsed = (packed & 0x80) != 0; + _gctSize = 2 << (packed & 7); + _bgIndex = _fileStream.ReadByteS(tempBuf); + + _gifDimensions = new GifRect(0, 0, width, height); + _fileStream.Skip(1); + } + + /// + /// Parses all frame data. + /// + private void ProcessFrameData() + { + _fileStream.Position = Header.HeaderSize; + + var tempBuf = ArrayPool.Shared.Rent(MaxTempBuf); + + var terminate = false; + var curFrame = 0; + + Frames.Add(new GifFrame()); + + do + { + var blockType = (BlockTypes)_fileStream.ReadByteS(tempBuf); + + switch (blockType) + { + case BlockTypes.EMPTY: + break; + + case BlockTypes.EXTENSION: + ProcessExtensions(ref curFrame, tempBuf); + break; + + case BlockTypes.IMAGE_DESCRIPTOR: + ProcessImageDescriptor(ref curFrame, tempBuf); + _fileStream.SkipBlocks(tempBuf); + break; + + case BlockTypes.TRAILER: + Frames.RemoveAt(Frames.Count - 1); + terminate = true; + break; + + default: + _fileStream.SkipBlocks(tempBuf); + break; + } + + // Break the loop when the stream is not valid anymore. + if ((_fileStream.Position >= _fileStream.Length) & (terminate == false)) + throw new InvalidProgramException("Reach the end of the filestream without trailer block."); + } while (!terminate); + + ArrayPool.Shared.Return(tempBuf); + } + + /// + /// Parses GIF Image Descriptor Block. + /// + private void ProcessImageDescriptor(ref int curFrame, byte[] tempBuf) + { + var str = _fileStream; + var currentFrame = Frames[curFrame]; + + // Parse frame dimensions. + var frameX = str.ReadUShortS(tempBuf); + var frameY = str.ReadUShortS(tempBuf); + var frameW = str.ReadUShortS(tempBuf); + var frameH = str.ReadUShortS(tempBuf); + + frameW = (ushort)Math.Min(frameW, _gifDimensions.Width - frameX); + frameH = (ushort)Math.Min(frameH, _gifDimensions.Height - frameY); + + currentFrame.Dimensions = new GifRect(frameX, frameY, frameW, frameH); + + // Unpack interlace and lct info. + var packed = str.ReadByteS(tempBuf); + currentFrame.IsInterlaced = (packed & 0x40) != 0; + currentFrame.IsLocalColorTableUsed = (packed & 0x80) != 0; + currentFrame.LocalColorTableSize = (int)Math.Pow(2, (packed & 0x07) + 1); + + if (currentFrame.IsLocalColorTableUsed) + currentFrame.LocalColorTable = + ProcessColorTable(ref str, tempBuf, currentFrame.LocalColorTableSize); + + currentFrame.LZWMinCodeSize = str.ReadByteS(tempBuf); + currentFrame.LZWStreamPosition = str.Position; + + curFrame += 1; + Frames.Add(new GifFrame()); + } + + /// + /// Parses GIF Extension Blocks. + /// + private void ProcessExtensions(ref int curFrame, byte[] tempBuf) + { + var extType = (ExtensionType)_fileStream.ReadByteS(tempBuf); + + switch (extType) + { + case ExtensionType.GRAPHICS_CONTROL: + + _fileStream.ReadBlock(tempBuf); + var currentFrame = Frames[curFrame]; + var packed = tempBuf[0]; + + currentFrame.FrameDisposalMethod = (FrameDisposal)((packed & 0x1c) >> 2); + + if (currentFrame.FrameDisposalMethod != FrameDisposal.Restore + && currentFrame.FrameDisposalMethod != FrameDisposal.Background) + currentFrame.ShouldBackup = true; + + currentFrame.HasTransparency = (packed & 1) != 0; + + currentFrame.FrameDelay = + TimeSpan.FromMilliseconds(SpanToShort(tempBuf.AsSpan(1)) * 10); + + if (currentFrame.FrameDelay <= FrameDelayThreshold) + currentFrame.FrameDelay = FrameDelayDefault; + + currentFrame.TransparentColorIndex = tempBuf[3]; + break; + + case ExtensionType.APPLICATION: + var blockLen = _fileStream.ReadBlock(tempBuf); + var _ = tempBuf.AsSpan(0, blockLen); + var blockHeader = tempBuf.AsSpan(0, NetscapeMagic.Length); + + if (blockHeader.SequenceEqual(NetscapeMagic.Span)) + { + var count = 1; + + while (count > 0) + count = _fileStream.ReadBlock(tempBuf); + + var iterationCount = SpanToShort(tempBuf.AsSpan(1)); + + Header.Iterations = iterationCount; + } + else + { + _fileStream.SkipBlocks(tempBuf); + } + + break; + + default: + _fileStream.SkipBlocks(tempBuf); + break; + } + } +} diff --git a/src/L1.Avalonia.Gif/Decoding/GifFrame.cs b/src/L1.Avalonia.Gif/Decoding/GifFrame.cs new file mode 100644 index 0000000..5b504dc --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/GifFrame.cs @@ -0,0 +1,14 @@ +namespace L1.Avalonia.Gif.Decoding; + +public class GifFrame +{ + public GifRect Dimensions; + public TimeSpan FrameDelay; + public FrameDisposal FrameDisposalMethod; + public bool HasTransparency, IsInterlaced, IsLocalColorTableUsed; + public GifColor[] LocalColorTable; + public int LZWMinCodeSize, LocalColorTableSize; + public long LZWStreamPosition; + public bool ShouldBackup; + public byte TransparentColorIndex; +} diff --git a/src/L1.Avalonia.Gif/Decoding/GifHeader.cs b/src/L1.Avalonia.Gif/Decoding/GifHeader.cs new file mode 100644 index 0000000..cc2c5fa --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/GifHeader.cs @@ -0,0 +1,15 @@ +namespace L1.Avalonia.Gif.Decoding; + +public class GifHeader +{ + private GifColor[] _globarColorTable; + public int BackgroundColorIndex; + public GifRect Dimensions; + public ulong GlobalColorTableCacheID; + public int GlobalColorTableSize; + public GifColor[] GlobarColorTable; + public bool HasGlobalColorTable; + public long HeaderSize; + public GifRepeatBehavior IterationCount; + internal int Iterations = -1; +} diff --git a/src/L1.Avalonia.Gif/Decoding/GifRect.cs b/src/L1.Avalonia.Gif/Decoding/GifRect.cs new file mode 100644 index 0000000..2a42737 --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/GifRect.cs @@ -0,0 +1,45 @@ +namespace L1.Avalonia.Gif.Decoding; + +public readonly struct GifRect +{ + public int X { get; } + public int Y { get; } + public int Width { get; } + public int Height { get; } + public int TotalPixels { get; } + + public GifRect(int x, int y, int width, int height) + { + X = x; + Y = y; + Width = width; + Height = height; + TotalPixels = width * height; + } + + public static bool operator ==(GifRect a, GifRect b) + { + return a.X == b.X && + a.Y == b.Y && + a.Width == b.Width && + a.Height == b.Height; + } + + public static bool operator !=(GifRect a, GifRect b) + { + return !(a == b); + } + + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + return false; + + return this == (GifRect)obj; + } + + public override int GetHashCode() + { + return (X.GetHashCode() ^ Y.GetHashCode()) | (Width.GetHashCode() ^ Height.GetHashCode()); + } +} diff --git a/src/L1.Avalonia.Gif/Decoding/GifRepeatBehavior.cs b/src/L1.Avalonia.Gif/Decoding/GifRepeatBehavior.cs new file mode 100644 index 0000000..08e8302 --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/GifRepeatBehavior.cs @@ -0,0 +1,7 @@ +namespace L1.Avalonia.Gif.Decoding; + +public class GifRepeatBehavior +{ + public bool LoopForever { get; set; } + public int? Count { get; set; } +} diff --git a/src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs b/src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs new file mode 100644 index 0000000..fddcdd2 --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/InvalidGifStreamException.cs @@ -0,0 +1,23 @@ +using System.Runtime.Serialization; + +namespace L1.Avalonia.Gif.Decoding; + +[Serializable] +public class InvalidGifStreamException : Exception +{ + public InvalidGifStreamException() + { + } + + public InvalidGifStreamException(string message) : base(message) + { + } + + public InvalidGifStreamException(string message, Exception innerException) : base(message, innerException) + { + } + + protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +} diff --git a/src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs b/src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs new file mode 100644 index 0000000..1453bda --- /dev/null +++ b/src/L1.Avalonia.Gif/Decoding/LzwDecompressionException.cs @@ -0,0 +1,23 @@ +using System.Runtime.Serialization; + +namespace L1.Avalonia.Gif.Decoding; + +[Serializable] +public class LzwDecompressionException : Exception +{ + public LzwDecompressionException() + { + } + + public LzwDecompressionException(string message) : base(message) + { + } + + public LzwDecompressionException(string message, Exception innerException) : base(message, innerException) + { + } + + protected LzwDecompressionException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +} diff --git a/src/L1.Avalonia.Gif/Extensions/StreamExtensions.cs b/src/L1.Avalonia.Gif/Extensions/StreamExtensions.cs new file mode 100644 index 0000000..9d3d3cc --- /dev/null +++ b/src/L1.Avalonia.Gif/Extensions/StreamExtensions.cs @@ -0,0 +1,81 @@ +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace L1.Avalonia.Gif.Extensions; + +[DebuggerStepThrough] +internal static class StreamExtensions +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort SpanToShort(Span b) + { + return (ushort)(b[0] | (b[1] << 8)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Skip(this Stream stream, long count) + { + stream.Position += count; + } + + /// + /// Read a Gif block from stream while advancing the position. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ReadBlock(this Stream stream, byte[] tempBuf) + { + stream.Read(tempBuf, 0, 1); + + var blockLength = (int)tempBuf[0]; + + if (blockLength > 0) + stream.Read(tempBuf, 0, blockLength); + + // Guard against infinite loop. + if (stream.Position >= stream.Length) + throw new InvalidGifStreamException("Reach the end of the filestream without trailer block."); + + return blockLength; + } + + /// + /// Skips GIF blocks until it encounters an empty block. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SkipBlocks(this Stream stream, byte[] tempBuf) + { + int blockLength; + do + { + stream.Read(tempBuf, 0, 1); + + blockLength = tempBuf[0]; + stream.Position += blockLength; + + // Guard against infinite loop. + if (stream.Position >= stream.Length) + throw new InvalidGifStreamException("Reach the end of the filestream without trailer block."); + } while (blockLength > 0); + } + + /// + /// Read a from stream by providing a temporary buffer. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort ReadUShortS(this Stream stream, byte[] tempBuf) + { + stream.Read(tempBuf, 0, 2); + return SpanToShort(tempBuf); + } + + /// + /// Read a from stream by providing a temporary buffer. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte ReadByteS(this Stream stream, byte[] tempBuf) + { + stream.Read(tempBuf, 0, 1); + var finalVal = tempBuf[0]; + return finalVal; + } +} diff --git a/src/L1.Avalonia.Gif/GifImage.cs b/src/L1.Avalonia.Gif/GifImage.cs new file mode 100644 index 0000000..bbc6a77 --- /dev/null +++ b/src/L1.Avalonia.Gif/GifImage.cs @@ -0,0 +1,215 @@ +using System.Diagnostics; +using Avalonia; +using Avalonia.Animation; +using Avalonia.Controls; +using Avalonia.Media; +using Avalonia.Media.Imaging; +using Avalonia.Threading; + +namespace L1.Avalonia.Gif; + +public class GifImage : Control +{ + public static readonly StyledProperty SourceUriRawProperty = + AvaloniaProperty.Register("SourceUriRaw"); + + public static readonly StyledProperty SourceUriProperty = + AvaloniaProperty.Register("SourceUri"); + + public static readonly StyledProperty SourceStreamProperty = + AvaloniaProperty.Register("SourceStream"); + + public static readonly StyledProperty IterationCountProperty = + AvaloniaProperty.Register("IterationCount", IterationCount.Infinite); + + public static readonly StyledProperty AutoStartProperty = + AvaloniaProperty.Register("AutoStart"); + + public static readonly StyledProperty StretchDirectionProperty = + AvaloniaProperty.Register("StretchDirection"); + + public static readonly StyledProperty StretchProperty = + AvaloniaProperty.Register("Stretch"); + + private bool _hasNewSource; + private object? _newSource; + private Stopwatch _stopwatch; + + private RenderTargetBitmap backingRTB; + + private GifInstance gifInstance; + + static GifImage() + { + SourceUriRawProperty.Changed.Subscribe(SourceChanged); + SourceUriProperty.Changed.Subscribe(SourceChanged); + SourceStreamProperty.Changed.Subscribe(SourceChanged); + IterationCountProperty.Changed.Subscribe(IterationCountChanged); + AutoStartProperty.Changed.Subscribe(AutoStartChanged); + AffectsRender(SourceStreamProperty, SourceUriProperty, SourceUriRawProperty, StretchProperty); + AffectsArrange(SourceStreamProperty, SourceUriProperty, SourceUriRawProperty, StretchProperty); + AffectsMeasure(SourceStreamProperty, SourceUriProperty, SourceUriRawProperty, StretchProperty); + } + + public string SourceUriRaw + { + get => GetValue(SourceUriRawProperty); + set => SetValue(SourceUriRawProperty, value); + } + + public Uri SourceUri + { + get => GetValue(SourceUriProperty); + set => SetValue(SourceUriProperty, value); + } + + public Stream SourceStream + { + get => GetValue(SourceStreamProperty); + set => SetValue(SourceStreamProperty, value); + } + + public IterationCount IterationCount + { + get => GetValue(IterationCountProperty); + set => SetValue(IterationCountProperty, value); + } + + public bool AutoStart + { + get => GetValue(AutoStartProperty); + set => SetValue(AutoStartProperty, value); + } + + public StretchDirection StretchDirection + { + get => GetValue(StretchDirectionProperty); + set => SetValue(StretchDirectionProperty, value); + } + + public Stretch Stretch + { + get => GetValue(StretchProperty); + set => SetValue(StretchProperty, value); + } + + private static void AutoStartChanged(AvaloniaPropertyChangedEventArgs e) + { + var image = e.Sender as GifImage; + if (image == null) + return; + } + + private static void IterationCountChanged(AvaloniaPropertyChangedEventArgs e) + { + var image = e.Sender as GifImage; + if (image is null || e.NewValue is not IterationCount iterationCount) + return; + + image.IterationCount = iterationCount; + } + + public override void Render(DrawingContext context) + { + Dispatcher.UIThread.Post(InvalidateMeasure, DispatcherPriority.Background); + Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background); + + if (_hasNewSource) + { + StopAndDispose(); + gifInstance = new GifInstance(_newSource); + gifInstance.IterationCount = IterationCount; + backingRTB = new RenderTargetBitmap(gifInstance.GifPixelSize, new Vector(96, 96)); + _hasNewSource = false; + + _stopwatch ??= new Stopwatch(); + _stopwatch.Reset(); + + + return; + } + + if (gifInstance is null || (gifInstance.CurrentCts?.IsCancellationRequested ?? true)) return; + + if (!_stopwatch.IsRunning) _stopwatch.Start(); + + var currentFrame = gifInstance.ProcessFrameTime(_stopwatch.Elapsed); + + if (currentFrame is { } source && backingRTB is not null) + { + using var ctx = backingRTB.CreateDrawingContext(); + var ts = new Rect(source.Size); + ctx.DrawImage(source, ts, ts); + // ctx.DrawImage(source.PlatformImpl, 1, ts, ts); + } + + if (backingRTB is not null && Bounds.Width > 0 && Bounds.Height > 0) + { + var viewPort = new Rect(Bounds.Size); + var sourceSize = backingRTB.Size; + + var scale = Stretch.CalculateScaling(Bounds.Size, sourceSize, StretchDirection); + var scaledSize = sourceSize * scale; + var destRect = viewPort + .CenterRect(new Rect(scaledSize)) + .Intersect(viewPort); + + var sourceRect = new Rect(sourceSize) + .CenterRect(new Rect(destRect.Size / scale)); + + var interpolationMode = RenderOptions.GetBitmapInterpolationMode(this); + + context.DrawImage(backingRTB, sourceRect, destRect); + } + } + + /// + /// Measures the control. + /// + /// The available size. + /// The desired size of the control. + protected override Size MeasureOverride(Size availableSize) + { + var source = backingRTB; + var result = new Size(); + + if (source != null) result = Stretch.CalculateSize(availableSize, source.Size, StretchDirection); + + return result; + } + + /// + protected override Size ArrangeOverride(Size finalSize) + { + var source = backingRTB; + + if (source != null) + { + var sourceSize = source.Size; + var result = Stretch.CalculateSize(finalSize, sourceSize); + return result; + } + + return new Size(); + } + + public void StopAndDispose() + { + gifInstance?.Dispose(); + backingRTB?.Dispose(); + } + + private static void SourceChanged(AvaloniaPropertyChangedEventArgs e) + { + var image = e.Sender as GifImage; + + if (image == null) + return; + + if (e.NewValue is null) return; + + image._hasNewSource = true; + image._newSource = e.NewValue; + Dispatcher.UIThread.Post(image.InvalidateVisual, DispatcherPriority.Background); + } +} diff --git a/src/L1.Avalonia.Gif/GifInstance.cs b/src/L1.Avalonia.Gif/GifInstance.cs new file mode 100644 index 0000000..9351759 --- /dev/null +++ b/src/L1.Avalonia.Gif/GifInstance.cs @@ -0,0 +1,151 @@ +using Avalonia; +using Avalonia.Animation; +using Avalonia.Media.Imaging; +using Avalonia.Platform; +using L1.Avalonia.Gif.Decoding; + +namespace L1.Avalonia.Gif +{ + public class GifInstance : IDisposable + { + private readonly List _colorTableIdList; + private readonly List _frameTimes; + private readonly GifDecoder _gifDecoder; + private readonly WriteableBitmap _targetBitmap; + private int _currentFrameIndex; + private uint _iterationCount; + private TimeSpan _totalTime; + + internal GifInstance(object newValue) : this(newValue switch + { + Stream s => s, + Uri u => GetStreamFromUri(u), + string str => GetStreamFromString(str), + _ => throw new InvalidDataException("Unsupported source object") + }) + { + } + + public GifInstance(string uri) : this(GetStreamFromString(uri)) + { + } + + public GifInstance(Uri uri) : this(GetStreamFromUri(uri)) + { + } + + public GifInstance(Stream currentStream) + { + if (!currentStream.CanSeek) + throw new InvalidDataException("The provided stream is not seekable."); + + if (!currentStream.CanRead) + throw new InvalidOperationException("Can't read the stream provided."); + + currentStream.Seek(0, SeekOrigin.Begin); + + CurrentCts = new CancellationTokenSource(); + + _gifDecoder = new GifDecoder(currentStream, CurrentCts.Token); + var pixSize = new PixelSize(_gifDecoder.Header.Dimensions.Width, _gifDecoder.Header.Dimensions.Height); + + _targetBitmap = new WriteableBitmap(pixSize, new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Opaque); + GifPixelSize = pixSize; + + _totalTime = TimeSpan.Zero; + + _frameTimes = _gifDecoder.Frames.Select(frame => + { + _totalTime = _totalTime.Add(frame.FrameDelay); + return _totalTime; + }).ToList(); + + _gifDecoder.RenderFrame(0, _targetBitmap); + + // Save the color table cache ID's to refresh them on cache while + // // the image is either stopped/paused. + // _colorTableIdList = _gifDecoder.Frames + // .Where(p => p.IsLocalColorTableUsed) + // .Select(p => p.LocalColorTableCacheID) + // .ToList(); + + // if (_gifDecoder.Header.HasGlobalColorTable) + // _colorTableIdList.Add(_gifDecoder.Header.GlobalColorTableCacheID); + } + + public IterationCount IterationCount { get; set; } + public bool AutoStart { get; private set; } = true; + + public CancellationTokenSource CurrentCts { get; } + + public int GifFrameCount => _frameTimes.Count; + + public PixelSize GifPixelSize { get; } + + public void Dispose() + { + CurrentCts.Cancel(); + _targetBitmap?.Dispose(); + } + + private static Stream GetStreamFromString(string str) + { + if (!Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out var res)) + throw new InvalidCastException("The string provided can't be converted to URI."); + + return GetStreamFromUri(res); + } + + private static Stream GetStreamFromUri(Uri uri) + { + var uriString = uri.OriginalString.Trim(); + + if (!uriString.StartsWith("resm") && !uriString.StartsWith("avares")) + throw new InvalidDataException( + "The URI provided is not currently supported."); + + var assetLocator = AssetLoader.Open(uri); + + // if (assetLocator is null) + // throw new InvalidDataException( + // "The resource URI was not found in the current assembly."); + + return assetLocator; + } + + [CanBeNull] + public WriteableBitmap ProcessFrameTime(TimeSpan stopwatchElapsed) + { + if (!IterationCount.IsInfinite && _iterationCount > IterationCount.Value) return null; + + if (CurrentCts.IsCancellationRequested) return null; + + var elapsedTicks = stopwatchElapsed.Ticks; + var timeModulus = TimeSpan.FromTicks(elapsedTicks % _totalTime.Ticks); + var targetFrame = _frameTimes.FirstOrDefault(x => timeModulus < x); + var currentFrame = _frameTimes.IndexOf(targetFrame); + if (currentFrame == -1) currentFrame = 0; + + if (_currentFrameIndex == currentFrame) + return _targetBitmap; + + _iterationCount = (uint)(elapsedTicks / _totalTime.Ticks); + + return ProcessFrameIndex(currentFrame); + } + + internal WriteableBitmap ProcessFrameIndex(int frameIndex) + { + _gifDecoder.RenderFrame(frameIndex, _targetBitmap); + _currentFrameIndex = frameIndex; + + return _targetBitmap; + } + } +} + +[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | + AttributeTargets.Delegate | AttributeTargets.Field)] +public sealed class CanBeNullAttribute : Attribute +{ +} diff --git a/src/L1.Avalonia.Gif/InvalidGifStreamException.cs b/src/L1.Avalonia.Gif/InvalidGifStreamException.cs new file mode 100644 index 0000000..0e1c9e4 --- /dev/null +++ b/src/L1.Avalonia.Gif/InvalidGifStreamException.cs @@ -0,0 +1,23 @@ +using System.Runtime.Serialization; + +namespace L1.Avalonia.Gif; + +[Serializable] +internal class InvalidGifStreamException : Exception +{ + public InvalidGifStreamException() + { + } + + public InvalidGifStreamException(string message) : base(message) + { + } + + public InvalidGifStreamException(string message, Exception innerException) : base(message, innerException) + { + } + + protected InvalidGifStreamException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +} diff --git a/src/L1.Avalonia.Gif/L1.Avalonia.Gif.csproj b/src/L1.Avalonia.Gif/L1.Avalonia.Gif.csproj new file mode 100644 index 0000000..d893a7c --- /dev/null +++ b/src/L1.Avalonia.Gif/L1.Avalonia.Gif.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + + + + From a81428d00ea03cc780be8715b32961700bc20fc2 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Fri, 7 Jun 2024 18:58:41 +0300 Subject: [PATCH 18/63] Refactor LoginPageViewModel and update AsyncStreamToImageLoader This commit refactors LoginPageViewModel to change the type of _screen from IScreen to MainWindowViewModel. This allows the app to subscribe to the 'OnClosed' event of the main window, and dispose of connections when the window is closed to prevent memory leaks. AsyncStreamToImageLoader has also been updated to clear avatar image classes upfront and enhance filename checking mechanism to prevent non-loaded images. --- .../Core/Converters/AsyncStreamToImageLoader.cs | 10 +++++----- .../ViewModels/Pages/LoginPageViewModel.cs | 13 +++++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs index d75cdcd..8df36f3 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs @@ -28,6 +28,7 @@ private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPr { try { + sender.Classes.Clear(); var url = args.GetNewValue(); if (string.IsNullOrEmpty(url)) @@ -42,20 +43,19 @@ private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPr return; } - var fileName = Path.Combine(TempPath, Path.GetFileName(url)); + var fileName = new FileInfo(Path.Combine(TempPath, Path.GetFileName(url))); - if (!File.Exists(fileName)) + if (!fileName.Exists || fileName.Length == 0) { using var client = new HttpClient(); var response = await client.GetByteArrayAsync(url); using var stream = new MemoryStream(response); - await ConvertStreamToFile(stream, fileName); + await ConvertStreamToFile(stream, fileName.FullName); } - var fileStream = File.OpenRead(fileName); + var fileStream = File.OpenRead(fileName.FullName); - sender.Classes.Clear(); if (GifDecoder.IsGifStream(fileStream)) { sender.Classes.Add("Gif"); diff --git a/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs index d9d7ce0..acd9def 100644 --- a/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs @@ -22,7 +22,7 @@ public class LoginPageViewModel : PageViewModelBase private string _login = string.Empty; private bool _isProcessing = false; private string _password = string.Empty; - private readonly IScreen _screen; + private readonly MainWindowViewModel _screen; private readonly IObservable _onClosed; private readonly IStorageService _storageService; private readonly IGmlClientManager _gmlClientManager; @@ -70,7 +70,7 @@ internal LoginPageViewModel(IScreen screen, ISystemService? systemService = null, ILocalizationService? localizationService = null) : base(screen, localizationService) { - _screen = screen; + _screen = (MainWindowViewModel)screen; _onClosed = onClosed; _storageService = storageService @@ -85,18 +85,27 @@ internal LoginPageViewModel(IScreen screen, ?? Locator.Current.GetService() ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); + _screen.OnClosed.Subscribe(DisposeConnections); LoginCommand = ReactiveCommand.CreateFromTask(OnAuth); RxApp.MainThreadScheduler.Schedule(CheckAuth); } + private void DisposeConnections(bool isClosed) + { + _gmlClientManager.Dispose(); + } + private async void CheckAuth() { var authUser = await _storageService.GetAsync(StorageConstants.User); if (authUser is { IsAuth: true }) + { _screen.Router.Navigate.Execute(new OverviewPageViewModel(_screen, authUser, _onClosed)); + await _gmlClientManager.OpenServerConnection(authUser); + } } private async Task OnAuth(CancellationToken arg) From 3501902fad113884f776fa83bd55dd783c48c7a1 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Fri, 7 Jun 2024 18:58:56 +0300 Subject: [PATCH 19/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 20badc0..4fde5eb 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 20badc088bedc392a39b747b35abf7c4cac522e1 +Subproject commit 4fde5eb58becd9cc9c527fc31d52c212edd6dfa4 From 6a777d7948df2d744ab8c14d6f35649a3fbe99f2 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 9 Jun 2024 06:49:44 +0300 Subject: [PATCH 20/63] Update background component in MainWindow Updated the background image's component in MainWindow.axaml file. Added a class attribute, which can be used for styling or Javascript manipulation in the future. --- src/Gml.Launcher/Views/MainWindow.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Launcher/Views/MainWindow.axaml b/src/Gml.Launcher/Views/MainWindow.axaml index 4bc71c8..23798a3 100644 --- a/src/Gml.Launcher/Views/MainWindow.axaml +++ b/src/Gml.Launcher/Views/MainWindow.axaml @@ -40,7 +40,7 @@ - + From a6b8668a81c81830378b0f2e2247159cb1615c33 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 9 Jun 2024 08:42:39 +0300 Subject: [PATCH 21/63] Remove invalid character from document.svg The first character of the document.svg file in the Gml.Launcher/Assets/Images directory was an invalid character and is now removed. This fix ensures that the SVG file is correctly formed and interprets as expected. --- src/Gml.Launcher/Assets/Images/document.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Launcher/Assets/Images/document.svg b/src/Gml.Launcher/Assets/Images/document.svg index bc3ecd7..e29421c 100644 --- a/src/Gml.Launcher/Assets/Images/document.svg +++ b/src/Gml.Launcher/Assets/Images/document.svg @@ -1,4 +1,4 @@ -ф + From b63bd9cac34ee2340341cd5ef472aae51d0d344d Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 9 Jun 2024 08:58:53 +0300 Subject: [PATCH 22/63] Add 'launcher' project and comment out language combo box Added a new 'launcher' project to the Gml.Launcher.sln file and made adjustments to project settings for consistency. Additionally, commented out the language selection combo box in the SettingsPageView.axaml as it is currently not in use. --- Gml.Launcher.sln | 4 ++- .../Views/Pages/SettingsPageView.axaml | 36 +++++++++---------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Gml.Launcher.sln b/Gml.Launcher.sln index 84b1087..d85bee9 100644 --- a/Gml.Launcher.sln +++ b/Gml.Launcher.sln @@ -33,6 +33,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gml.Core.Interfaces", "src\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "L1.Avalonia.Gif", "src\L1.Avalonia.Gif\L1.Avalonia.Gif.csproj", "{19B15268-CF4D-4571-8DF3-6EBC586BB856}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "launcher", "launcher", "{48DF3E50-4AB6-4569-9C79-E8FAC444434E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -79,7 +81,6 @@ Global SolutionGuid = {E0375879-A52D-4581-81EF-7A27063F494F} EndGlobalSection GlobalSection(NestedProjects) = preSolution - {F2771E71-C782-4713-862F-217694DDDFF5} = {662268E9-BD01-43C7-924B-F4F285C8D391} {49013DAA-207C-4542-8F85-671FB45797F4} = {662268E9-BD01-43C7-924B-F4F285C8D391} {34519B31-294B-4868-BFDB-817E550A54EC} = {53569526-A495-4E84-ADF3-83D2188318AB} {B8E0451C-3C44-470B-9853-C7D0A3648C20} = {662268E9-BD01-43C7-924B-F4F285C8D391} @@ -87,5 +88,6 @@ Global {88B821C7-B895-4CB0-832A-5B66138B6AF2} = {662268E9-BD01-43C7-924B-F4F285C8D391} {AE697645-C3EB-4FC8-AAA6-932B9751D348} = {662268E9-BD01-43C7-924B-F4F285C8D391} {19B15268-CF4D-4571-8DF3-6EBC586BB856} = {662268E9-BD01-43C7-924B-F4F285C8D391} + {F2771E71-C782-4713-862F-217694DDDFF5} = {48DF3E50-4AB6-4569-9C79-E8FAC444434E} EndGlobalSection EndGlobal diff --git a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml index 66f13a5..5c0a29e 100644 --- a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml +++ b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml @@ -133,24 +133,24 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + + + From 0a0127768f122b2cada9ea0396bb4543c4bf7b67 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 9 Jun 2024 08:59:03 +0300 Subject: [PATCH 23/63] Update submodule Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 4fde5eb..e24800a 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 4fde5eb58becd9cc9c527fc31d52c212edd6dfa4 +Subproject commit e24800a12be1624f9a036394de9266c41e3c8d13 From 0e3367d818813091b98699bf9c852327d0a5b5e7 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Sun, 9 Jun 2024 09:26:19 +0300 Subject: [PATCH 24/63] Update submodule Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 20badc0..6dd49d9 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 20badc088bedc392a39b747b35abf7c4cac522e1 +Subproject commit 6dd49d978a475634c0f26fe8b650562cebe5f06b From 583c7084270bb4c5432288cd74e774cf940d009b Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Mon, 10 Jun 2024 07:56:46 +0300 Subject: [PATCH 25/63] Switch host and update debugging settings Furthermore, the debugging settings in App.axaml.cs have been updated to not debug mode, and the return value in case of null 'actualVersion' has been set to true in SplashScreenViewModel.cs. --- src/Gml.Launcher/App.axaml.cs | 2 +- src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs | 4 ++-- src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Gml.Launcher/App.axaml.cs b/src/Gml.Launcher/App.axaml.cs index e85de60..f366d4c 100644 --- a/src/Gml.Launcher/App.axaml.cs +++ b/src/Gml.Launcher/App.axaml.cs @@ -21,7 +21,7 @@ public override async void OnFrameworkInitializationCompleted() if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { -#if DEBUG +#if !DEBUG desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel(), diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index ace7a72..2996201 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -20,7 +20,7 @@ public static class ResourceKeysDictionary public const string CheckUpdates = "CheckUpdates"; public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; - // public const string Host = "http://192.168.31.199:5000"; - public const string Host = "https://gmlb.recloud.tech"; + public const string Host = "http://192.168.31.199:5000"; + // public const string Host = "https://gmlb.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; } diff --git a/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs b/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs index e3441e3..91e3eaa 100644 --- a/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs +++ b/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs @@ -74,7 +74,7 @@ public async Task InitializeAsync() if (actualVersion is null) { - return (null, false); + return (null, true); } var version = Assembly.GetExecutingAssembly().GetName().Version ?? new Version(1, 0, 0, 0); From 93ac7382713c0c21de33755e024afb001577e0fe Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Mon, 10 Jun 2024 07:59:19 +0300 Subject: [PATCH 26/63] Optimize system data loading process The previous implementation executed the tasks for refreshing the drive, motherboard, and CPU lists sequentially. This was unnecessarily time-consuming. With the new implementation, these tasks are run concurrently using Task.WhenAll method for better performance and efficiency. --- src/Gml.Launcher/Core/Services/SystemService.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Gml.Launcher/Core/Services/SystemService.cs b/src/Gml.Launcher/Core/Services/SystemService.cs index 182f6ae..2211d92 100644 --- a/src/Gml.Launcher/Core/Services/SystemService.cs +++ b/src/Gml.Launcher/Core/Services/SystemService.cs @@ -70,12 +70,11 @@ public string GetHwid() public async Task LoadSystemData() { - await Task.Run(() => - { - _hardwareInfo.RefreshDriveList(); - _hardwareInfo.RefreshMotherboardList(); - _hardwareInfo.RefreshCPUList(); - }); + var refreshDriveListTask = Task.Run(() => _hardwareInfo.RefreshDriveList()); + var refreshMotherboardListTask = Task.Run(() => _hardwareInfo.RefreshMotherboardList()); + var refreshCpuListTask = Task.Run(() => _hardwareInfo.RefreshCPUList()); + + await Task.WhenAll(refreshDriveListTask, refreshMotherboardListTask, refreshCpuListTask); } private static string GetFolderPath(Environment.SpecialFolder folder) From 9838796a872576347c313719927346f2149272ac Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Mon, 10 Jun 2024 07:59:40 +0300 Subject: [PATCH 27/63] Change execution context for MainWindow in debug mode This update modifies the execution context for MainWindow in the Gml.Launcher App. Previously, it was running in non-debug mode. Now, it is set up to run in debug mode. --- src/Gml.Launcher/App.axaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Launcher/App.axaml.cs b/src/Gml.Launcher/App.axaml.cs index f366d4c..e85de60 100644 --- a/src/Gml.Launcher/App.axaml.cs +++ b/src/Gml.Launcher/App.axaml.cs @@ -21,7 +21,7 @@ public override async void OnFrameworkInitializationCompleted() if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { -#if !DEBUG +#if DEBUG desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel(), From 76d46a331dd2797f01461e1b89142c5a7b8cf1e1 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Tue, 11 Jun 2024 07:51:03 +0300 Subject: [PATCH 28/63] Disable window resizing and update pointer events handling A new property `CanResize=False` has been added to the MainWindow.axaml to prevent the window from being resized. The pointer events handling logic was moved from OverviewPageView to MainWindow. This was done to ensure better control over dragging behavior and to prevent inappropriate actions during specific interactions. --- src/Gml.Launcher/Views/MainWindow.axaml | 1 + src/Gml.Launcher/Views/MainWindow.axaml.cs | 10 ++++++++++ src/Gml.Launcher/Views/Pages/OverviewPageView.axaml.cs | 10 ---------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Gml.Launcher/Views/MainWindow.axaml b/src/Gml.Launcher/Views/MainWindow.axaml index 23798a3..44eb611 100644 --- a/src/Gml.Launcher/Views/MainWindow.axaml +++ b/src/Gml.Launcher/Views/MainWindow.axaml @@ -14,6 +14,7 @@ Width="1000" Height="600" MinHeight="600" + CanResize="False" x:Class="Gml.Launcher.Views.MainWindow" x:DataType="vm:MainWindowViewModel" Background="Transparent" diff --git a/src/Gml.Launcher/Views/MainWindow.axaml.cs b/src/Gml.Launcher/Views/MainWindow.axaml.cs index 46653ee..25bf211 100644 --- a/src/Gml.Launcher/Views/MainWindow.axaml.cs +++ b/src/Gml.Launcher/Views/MainWindow.axaml.cs @@ -45,4 +45,14 @@ protected override void OnClosed(EventArgs e) base.OnClosed(e); } + + protected override void OnPointerPressed(PointerPressedEventArgs e) + { + BeginMoveDrag(e); + + // if(this.GetVisualRoot() is Window window && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) + // { + // window.BeginMoveDrag(e); + // } + } } diff --git a/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml.cs b/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml.cs index 0af1ad4..7d7806e 100644 --- a/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml.cs +++ b/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml.cs @@ -15,15 +15,5 @@ public OverviewPageView() this.WhenActivated(disposables => { }); AvaloniaXamlLoader.Load(this); } - - protected override void OnPointerPressed(PointerPressedEventArgs e) - { - // BeginMoveDrag(e); - - if(this.GetVisualRoot() is Window window && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) - { - window.BeginMoveDrag(e); - } - } } From 5ff625d2be626042a8992a89c916144fbc9a28ea Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Tue, 11 Jun 2024 07:51:19 +0300 Subject: [PATCH 29/63] Update settings validation for window size Improved the validation and error-handling approach for setting window size parameters. Now, the windowWidth and windowHeight values are only updated when numeric values are provided. If non-numeric values are input, they will be reset to default. --- .../ViewModels/Pages/SettingsPageViewModel.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs index 94096f1..23aba3f 100644 --- a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs @@ -46,13 +46,35 @@ public double RamValue public string WindowWidth { get => _windowWidth.ToString(); - set => this.RaiseAndSetIfChanged(ref _windowWidth, int.Parse(string.Concat(value.Where(char.IsDigit)))); + set + { + var isNumeric = int.TryParse(string.Concat(value.Where(char.IsDigit)), out int numericValue); + if (isNumeric) + { + this.RaiseAndSetIfChanged(ref _windowWidth, numericValue); + } + else + { + this.RaiseAndSetIfChanged(ref _windowWidth, default); + } + } } public string WindowHeight { get => _windowHeight.ToString(); - set => this.RaiseAndSetIfChanged(ref _windowHeight, int.Parse(string.Concat(value.Where(char.IsDigit)))); + set + { + var isNumeric = int.TryParse(string.Concat(value.Where(char.IsDigit)), out int numericValue); + if (isNumeric) + { + this.RaiseAndSetIfChanged(ref _windowHeight, numericValue); + } + else + { + this.RaiseAndSetIfChanged(ref _windowWidth, default); + } + } } public ObservableCollection AvailableLanguages { get; } From 74eb8b8e63c8276fed0bc983c3345265e571dbc6 Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Tue, 11 Jun 2024 07:56:24 +0300 Subject: [PATCH 30/63] Remove commented out code in MainWindow.axaml.cs --- src/Gml.Launcher/Views/MainWindow.axaml.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Gml.Launcher/Views/MainWindow.axaml.cs b/src/Gml.Launcher/Views/MainWindow.axaml.cs index 25bf211..d7c6b89 100644 --- a/src/Gml.Launcher/Views/MainWindow.axaml.cs +++ b/src/Gml.Launcher/Views/MainWindow.axaml.cs @@ -49,10 +49,5 @@ protected override void OnClosed(EventArgs e) protected override void OnPointerPressed(PointerPressedEventArgs e) { BeginMoveDrag(e); - - // if(this.GetVisualRoot() is Window window && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) - // { - // window.BeginMoveDrag(e); - // } } } From f0b0b91665833fbf632627568fa9bfbd73e12d1f Mon Sep 17 00:00:00 2001 From: Anton Terentev Date: Tue, 11 Jun 2024 08:13:25 +0300 Subject: [PATCH 31/63] Added default font --- src/Gml.Launcher/Assets/Fonts/Manrope-Bold.ttf | Bin 0 -> 96800 bytes .../Assets/Fonts/Manrope-ExtraBold.ttf | Bin 0 -> 97524 bytes .../Assets/Fonts/Manrope-ExtraLight.ttf | Bin 0 -> 96700 bytes src/Gml.Launcher/Assets/Fonts/Manrope-Light.ttf | Bin 0 -> 96728 bytes .../Assets/Fonts/Manrope-Medium.ttf | Bin 0 -> 96904 bytes .../Assets/Fonts/Manrope-Regular.ttf | Bin 0 -> 96832 bytes .../Assets/Fonts/Manrope-SemiBold.ttf | Bin 0 -> 96936 bytes 7 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/Gml.Launcher/Assets/Fonts/Manrope-Bold.ttf create mode 100644 src/Gml.Launcher/Assets/Fonts/Manrope-ExtraBold.ttf create mode 100644 src/Gml.Launcher/Assets/Fonts/Manrope-ExtraLight.ttf create mode 100644 src/Gml.Launcher/Assets/Fonts/Manrope-Light.ttf create mode 100644 src/Gml.Launcher/Assets/Fonts/Manrope-Medium.ttf create mode 100644 src/Gml.Launcher/Assets/Fonts/Manrope-Regular.ttf create mode 100644 src/Gml.Launcher/Assets/Fonts/Manrope-SemiBold.ttf diff --git a/src/Gml.Launcher/Assets/Fonts/Manrope-Bold.ttf b/src/Gml.Launcher/Assets/Fonts/Manrope-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..98c1c3d5b6f7b5452964b591fc4a0411ac2b5722 GIT binary patch literal 96800 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 MwwU?%lX!H0184Be#{d8T literal 0 HcmV?d00001 diff --git a/src/Gml.Launcher/Assets/Fonts/Manrope-ExtraBold.ttf b/src/Gml.Launcher/Assets/Fonts/Manrope-ExtraBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..369d71902024c84076ceaf09c955f39014b3ae44 GIT binary patch literal 97524 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 PQ4w*`zjc2SOZWc)L>#?f literal 0 HcmV?d00001 diff --git a/src/Gml.Launcher/Assets/Fonts/Manrope-ExtraLight.ttf b/src/Gml.Launcher/Assets/Fonts/Manrope-ExtraLight.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8915d96075d5acbf90b5dd7fe4e12b2968c863fa GIT binary patch literal 96700 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%0D0&n{kD};N z6g`TfN8xrMTwV!4kD};N6g>*J3=!NiMDV|W5d6;{1UC&4iXMgAg$PBDqUce$TZmBf zD6Do9tVkQM=Vri;n*qFC2RTqDTB-zZN3FF1{z7UZ?bCqmfad_a0j~grl*Ic40QExu zsDmu2gDk1zEe&}BX$k+E024SGb-<2`0qYtBYnB8n8wBebgmnk>00aU;AT7t5j$o#Q zTi9CHvblgtsu8oPM$D!fF`H_{Y^o8nDcm~_co}dI@Cx8nz-xfl0dD{f0gk|i;7!0$z*_)* zCgE+salpHP_YmhK;C;X;e18Bq4fqi75rFsPGk{Ov{uJ-CctdiLe*n(G{Tbj|Ycs~; zW{kzn7>k=R7B^!oZpK*LjIp?xIsu#kE&x}68=xD&9pC}*1b6|w0X_gk_!?62{(ugs*8DnrW#^7d*!Od86X~y{5jPbV_<8L##>JsEm zAmmOUdkA#sgOSUCk;?$?F<|5}VB|7j)C&av3mk88C7gFmf3%av3mk88C7gFmiF} z*&uUq4rFl-IC&`Kz9U~gYNCf}h^8Lc>VT04N)5m+KL7u?`r>}YAy^$HRk0y{eQps> zsE6LTMX0RYXfRZd8&{c@R-KeoosdvDbm-!Uh{}NjEBp6f92Qoo*H;Jfj*MMEqTULe zImWn#E1LEO_yEIx%xxC_nOK5JUB;R;_1AMW%dW4Xiwy>@Nr-g1Jh*sGNn&rGXujp9 zq-L8kb23|EZ1d0>sr%I@9p}Vv1n1NuiJ{@)vC+Q%(NS@DX|*=F=8Y;IF>&UIQ8Olv zC~mpWF88pJMWaT{L}<~-Yv*lCQA_wb#fVnnZPKP3m3<9zt;*`bYm?Z1dDzW%|LtU( zGEJ-1TXjyLk&oa5k{BE9r|PJFeQNKpD%HM*rq!!f>FWQxTB@RbY$z&fIb+nwOi;8i zCo`wz&mGs&^wZUIZR*K+2>%nh2kwZv9e0SfrETB1IR5~Df2~#rSKsh(+g7!v^lRb4 z(`WYX;oKuOEM|0AcdzI;(|`^zIv5$&+iP&h_^~5=BYJ1|>FMHs)y)Pyx#e}=gS+}l zeK0X}FzX$v4d@*n7abMMz-WD={k0vo%Z0w<)02V+__?HePe|>T0e5(iTe^3~C)TZH zM>*Z_+rn?Vqi1R^UPD8Zi%j3Q-*QTSN`Z89=el-cd~`tXzB=osqNOLYP82-yh$+*K z9>&X;ckQ~i$EMnlmZFD(zZvZ)^N-r+ZrpWg&L7-O z+v3go)S5nUjJjax(+<$@0DC(IHe;Uy=DqoJJJ`3&wYmpEpYE8Ugjwj*A+sv2K)1GG z)SEjTm43J_hkjzyR7zdLfeF94x4#(^>X1=wc%oQtyU=zR^yW{FaH65Mta#vRTMe9++#5*xw>gAJJPER#CHgd6-uJ!|44kLf4$5sYA(`Wv5ejY1m1 z9)yn21N)gIvBPF(q)l_1JZDBw<-NndtKy;Eg7_HY&*xbWi~}ioTJ?f>T}5oxmrc>|C+}OrAg%lrwmY_Xq4&G z(I#yfTRvD-aq}YE-jbyX($pLKUw?q>Q6_XdW6NIt54o&-Mq2h3j$&H>YelBdS)IP#jnOmDR{WOPoA4m-iW3e&bVbM_} zKo=f{CS*FTH&n4O@DpK2&zdf5+(>(!y-8!@G9yga&c5=?a>kZld*v+EMP$aAP6i*L zQ_kbU?IWgZpZOmCYM1Hbx85?H*?sYl?`NiK&^AR`LTd~`n_(bQbzI^v7?K|Cv{a#2 zuIjL8bJ=`^<+46HAU;~xyOZKwFx(cL$nxwI16|6lU6-$|?+^vl-V`b*?aS{@K%ea! zFSOhkIHGl;kvqZXU`RsGps27xk;bSD)p_DYD`*he)^nGa@dbm@3w34>cF{#WraNU`63Py`gNVB!p(0SPynyyXhtoFPg zo4UcebSk4(+kH26-oBkW@9wVEqJ~%jQtv~F z+|`GWshE9H-upW&*B4vUE}fOlb{LH)LF;-MgSid<=)Xb5;RHbA*Ope!$j&K zP*OW425updsR7F936`X|TvXizb@=?$O1!SKk*Km1<^O97VhahQ%u21&ur+)hx5JWB znUN||SV_+*!L@KnN`MY#sZNb@jVmm`$B_FwOfJjP4 zVpLGwl(l#}9o{;(QL-K=bojUIvy}CBt6WX1K_y9d=ecritSyersn&F?Et*_0)0wq) zB~xhxbA&5b(X4T;lyMaryU78rlD4j7ERBq#WKF$8J>9yLX>uuT_4Jky`!XHt=n4Yn znn@aZr~0`y7Gq^B+SAWlYV2`wq?;?4pm#`osqDxP`QnwV7q zT>e2ZSF%HD&IjmQj#H!g-7KjUecURwO<%KXW;T+qCj4qiZ`Q%B%NIFt9o(@7ZdDih zRa*`GVN34qXx|F53Z;bZEhr^qtW~$BO)Z(0>=dorI=v}K?F3r+cc5`w;j1cZt8w4_ z#Zp4M+O|@p(za^I+@j=N+sQDr<=;UBOLjy})>=3y3Os@=;(Q@KiLZuAoO>ktD~nUBXOO zs=9`giHVkT<);!8V=tE`%h@+={3JrQ(Yb+p<=Nox5|0|Ej!71S;{-Cj{VwBs7Vy4NWw1dMm3zz+^pA zXyp{pbD`BE?)ut!BA&F$!DE?LQ>~~6$JZ*BG6acQCGgssYlYE==T(P6$0%wgmV2c7 z4@apP&>y_G<-*i9>pUFaoHm0?KVv&X3JM3UMBT+`0vwZt#vbhzPMb_$qb|yd4dNXz z1yO>!_~Q&Gnd)$zhL=CD?O@?$Yb7WBFz)jS-=^* z%ef!xfmjqocV#E4TSlr__06m3dj{6fVrcPXms_w6&-EWB(zx<<9BWxfEjchZS>Tzn ztn#uFY$p4BMNd>60WKO@7C-`UdS2fz`g=XJo+E;DG0rOeF~m>mk?f?oPa-xnJ`r29 zUmK3|eX!ZV|CNFxlEA$ls@)L{mpIs+x5pjY%@qahwJ6&bT^Wx&jt6p3@$r6YEQRg} zq2rgw+)WWkLys2F!Fet2GTuTWYJNg|H&H7ru0bFQ8XItAAsaKz)7dSj5&O7i`1L&X znH&AppWfjAm)1JWZ|jjxXcf`C5YaHIQpnLwi2tj`1)Ga**Kwv)iYsUXn~6leRpF(i zV2ynCW;9Ca%v5Tdnvb_=Ui0it$$-8t&)uBlJj@d}D->j|;P|?7d0|Ic8GBYHQ@7>1 zoR=MiEm)!crmdp>u%Jlf{iip0KUQ=ptmgHlpkg#tXBg8BK79hcZgYzZ_w&1Xh}Tn7 ze{I{0$!hHsl`1JGZbmQlsq0rbz07pty&tO-?W}&9DW@9Qo(#~Msp&uzSn42YGU-?) ze?X_{E>B8Apep|l$w^wA1&%8=_#I*PPdDGq_ z#@%$_TW`@pyOae(Fs9J)(gi2@2>sV)wa{_7Dm6G{o3ak%ux!CL=C#815m3tKyyVZ< zW6j!I$5p2%B?0zGCs>Gq)VvDTJ|3|Ag+`PvuK)yE?GA~3yiOW|ej;Hb_V!HqUBHPi z73@`($l6B>`-=&t)tYo!Td>B zp*x`fdlH=^ro-~NgoX0m1=*%xz%}y_F&k~u87$iljwL=@+D37Y><~LgN_`jDUm1_^ zKS+1OS{1i(fz1f?U<~A3G48C>s^=J8ePa7OFgA8fuc3aX><)3%&KkY=_Mm{lQJ&N@ zDEr#s&Y4<~FL}UDp`{Iee6Z-OZS8QZ?|dw^!7~!ZU0oPhm5~FKRGD!F-%}fWJEJFC zQ%mRG0!ewN(0zKVWHrl*_UYP%K4VAM;hpy&d%AY5JDIV45M0m;woaq$xwP$I(^>zr z!`<%|dz&pMUv6t4(S@$3@U~j+d8zib>Wo($o6*?Stm7U@Q`%9WZ7bM?uBr{TRkSfR zveI;w@rciR0G+jt>M8V5QxYB_9Sam8lDpVHWvMLIHsnz$q;rMtBieMiV;uOZNY_S1 z*a&Ox!l>wqm5l*}%;*~*PvheQbULcjbTU4rk38Y8TJQVv$hSRjR^zs%4p9mm{%LpB zN#D2QKlQvB6Lhk3F^k!_q{pc-8_y(sHvTz3Ga&gp6=)8rWq;CJU5s#PK06U}NpC*B zSBYKSVA$x0HI&{VUhs&EABolKaCtYGdHW6QS^W6asgD=;9O!3CqKCYObf3Ct`0zzj zyASa)C28ta8qXzvD=q!o5>K_d}X*%6C?tzHDgBXpE8niOeG+k3~Y6|uk zd|Se^GbV4oBPqkwM5~jB4XGY6=AOtwvC7zJ(PL6^1zl$?rM_-@B#D-`tnILgf@o=y zX;Vt)O(X3RE=Ik%y&852t!S;&g?NPkCE6abcW(4-Ij4#;T}-D#Z_aOzstu-?Yoi1+MX_@A%sR#!Sjjd?4JTGP9Ro9(JhX9!}g z3jJH14Ni`e_O;|SN|;>@W_|k%R&gskZs!)D6YH(q#LYiI6Rh&{b!Tk;Bi}t9XzXkH z+sfCA{~C#5+%?j30QKKtOZ zpM$-+89iJlJ+?6W;Tf8V^dBK<4J%UaOS*YRwKBD+|HE}7V#kG;T%EFCTK#S_-{tXz z^0^k$7&}Rk|rkiY!~1NlBD6 zVr9_X(&yy@Xr|Pc)lyPr?2ytzkMcG7a-5)Ftsq>#`VuGnf8u$f^*OGtk~O+z*BU0b z66VU#;4S5B)mSFEHc}fjA{U&qt}JByzHfd+JtHj=@SXFbBJ6l|vV3)PDde%C)t(kaMi0F zGz4dB)@qHIZ}$Nf%DPNklvw9-gn{OEqpNpppX}lOkv&Gbx7=e_y4EhzO}faT zc3Ac6lwWN)=2r*HM(rT1(2cJZ^^r7Ad6l+p#aA{Ud45IvF;PmrmOJ=?SR4MaZ9Z3a0!O7lUrD|l`6QAy6Lig?qUtc zG3_ySuQTOwsf)4u9x-+|;TGyNiI-6~>BJDuKr5$}9Gw?(Twk`&d?Ltla%hk}a_yWP zTHHRqVkF{gITF5~ll{P(atjjma*Q5Y=tbO&B$_h+mMgR97qn?s3*Uf0rwNzrWcm@J zl`SIVn26jPS6&`76->uzu8K_YFcoB))|)mWSlZj&k7A`RW96OQvW+j!X`E6!YLf0C`Ypcg75 zw@v11tvD38*J0KcV=&vS+t2~>%_djXEC@1_x5G@8qkZVG7N` z&B;4*Oku1*mCzE#&fh%NQpa0T#1}0I`xxGmDkT*QKr23ONhvj*0! zTWYgn>s+LUvdsrefE;hRl{il+`jwIuTO~~MtTK|D#U>-v2Ran5zlz)Y@LbIGq3_ie zT9ONmX}L|}Hq_wbl~O+a3T-*Zl3vz|_BhUg>q3DjzwJn4&TmJX;Y4rA-I3<=iA_;T z%W+#8JxX#o8ldS#&-7y3+7bMwE0#jr8rIpANJ#*rq7E!VM+^QeW5EiJ?ZoaBI zdh?JfDOfYu7<&E86wX&7uHY-hBFdbC&E?|ZSxY*Jv)ZQST*Y}oKF?y#fZii7^#xk; zkf&tkOcV^b#?CR|`j9yTHnO&5uO+Q8udOgA1@?y4X4NtEbgV@~dk}Ljeol2Hi`T_* zLvel|0LB5nI*plcfR>vQ#l^?P#Ns5YP8?>%MdB-WOqsf7LiX7MgMu}Getqq;Az5Kx z?%sSN%-wBbzX7e}rJBE%dpHe@eeJX{vUp6)oxzzKjdNF|d-~kwtMxtn+R_!>H`gsI z?pGPtl12Nmt-FlIr^<(}3JTSD_4IR#$sQLoKb_kf2~0KD;p$87Ks|X6<|E^+;>#wZ zQGU2ZoYj}8`?YU>2jU9eeBC>mjN$wXob6|ew_Jw^tBVbuzty_DZn@~-M)>cj6K;Cp zT%$cH*7D=!H8|T^{qEKoVpTJKt;fIri`wyPKd$-zz8d1>%`qWeeb6)bDkGP$e?;5S zQ?>q9b-dNqP+8Kqd zFJ!sz7U`n-$aYp{ePPS*l4FW&K9AA2zm>(DnB?3l+tZkr0F{ zB7&l#qN3uCJK`Ee#U%z4qeO`@ZetwAIF93(j4_Te#u&3qV*H#u$CsDM%P@|UF-Tv& z|EYT$8faSLd*AO%?56wny;Y}9ojP^)vP@JpnVxAZ2)leHrb{#`xb7Y7@#gW6G-F}s z{Kd0!qgZ+PY!f3GZNW27PQ!|`GCQO`J&WkVMyo?nLtrO8>+C!uLsdtlb29jX-rP}P zGYvdMqqi1}^x4K2q>ax?=3=`SZA3HBex#B^lYP#(MI1| z$gOhWnQ+iN3is#R&yE2h5g8G$K(T9Bo8EXm6T9T6Ny|0-!U5@nC|#}g{4)%IGzj7@ z&~?ljgju3{2BuQ-3jr5O_{3)b+q_3L>OIdam+7F_@BM{vlimY%@hrQO206HeBeH-; zfnHiLiD#0w*!wN)32wh|RQlsBOxDlD7Ko-u#?-HDq$!vRo{6>RAUAQ#FC9k^yui=0 z7-%hcNH?(-Tyg$sD(1!vbJGe{=BvNN9w0@w%#~DT{KAo0Pp!Q23=61XAEw%pJ;1jz z8b@o*!u?D%$@^I`fDihGW7eIvT3W02?z4>AOqr0$;CG!fC@??7|e;%WI^KoYE-A2w~w%4 zx%t416f1>!!|0`2y+nWqS-qrAoWcC3PptT4_MA^EUb#L!({S!W$?>u8U0nX|z=U3< zN9%g5|EOONXQopQ^!Oq+n`H=7kHyJz1BKcE7rz3_e zf>~5VxVrM}9am@0`uOFYAI>WL#I#Q~u##18Wo8^*yZZRJ%;TOFOnSYFvE45#%E3d5 z>19tO(VnS062W8FNXME4KVMa_8S-}aITe^Fc@7`j3aO(_Vurd zBx(Lvm3#j-Ag$l;mTx|j#ieT>EIl_Meb^n(a>m{|$?Uf6Smjf&0LZwb{4{r#Un$O9 zRC^G1KQBL!FA0;*gDyQ$6B~rtH8CuN`p>j3oEKTyUP|7 zX7%^!J(H({C_t6kTJM%S6pyggBgv4p=UeYj<(zOMVm&=)Z9S0*T$K3}EXCDTPYJ?~ zJYe4^g|j}~`SQoJW?tQ~=6L3~S4v>3SPH;878EMu!^^#2Cxn5N3k#)+kq<8W^lqa5M%`cx%@{ z=Eh_9f4!LVC3jv~{N+%m)nB~a{xsuBfq@Q7zp1!#{nI~OzWK?2Brw+mPrm-)p{jqZ z<9yPj%Ku#7A-(+@yGI}S>(RsiT%Y-`k3V@RN&mj_>ECr};cQAc{KZ(?`ZRqtV&<>d ziOhCg9x~g7)j`C1sd;H4217_ajT{$Trxh$6MIE05HZY|-Ez3_r+k`HaCUw2ReR@)s zbrZe^o==?IqS_|7IFH@;P4UuiUU~J-;%vjmzrS?*_N9&2Vn!r9G#!(QJhw2r({D4o z7t55NE_nRc&-MTLpY^Mk1Z~-?aamwP*IV!*ZxMH+aU#oI#!8QCz>Z$G(W}ahY<4Z^ zg8C+oo(2!m zs5K0!7N@7c!$xWt5*gNC+W<+OF_B+g>(>UD;xwC4B(x2iHlwFOn5jW%#XxlHsqk7e z2H6C@f#y`ZPmEn$1N7GIK2RQ>Hi9wQ2wF4p{N<^`Xlc)}H3*fDgGwt=6lNdzxOpwp zeyVaZZAZ1ekU1}ou>qR8tJ(rY^o*DV;@7{dXI4DeM$f8g<*7Y4ME1u$QizVj-4HX zJ)LtV_mo{mrN%jQ3+`a#F1;rCg*)|AKDGg|65{IW<2Ny~Z$@B`sVfr%(h7Tb{{gaQaE7xUisfQR_V0WPS&NkE!FfI7Un{-nj>l2%&vn+H}}CweacEFPQ>A^nYuH*N5=H% z=GieNd+w7=wI&Z{eX7pTW%h+_tw^T|?>los=)BxHUsN(@{#~7JKu*7P$1>PGo5HG)mkCy(PY|rF z#DF{t^f?xO=Y?$_iOwPbIvUtW4#e_2Ry@Im{!HE;unlVxK4j|{U43M z&>QiGzKG2k1}buaO6LY*L{Je(=UIlqH)_dCgW5h0LvOVR>j&ewGW|@rrGSN{`b_A$f)w9+-9vdW9yv_Q-wfjo7Eo8WgKnw ziTZLF9&r__l7q}IwN_)LEX#VYl9JkcbSM?qx5Nm)bY>7Su~+!-SO8Y8}aOEqq4CJKWtfUv@0pmp8F9L(t#?nTRtbLHUjNYjlEkuZ@5mu6`)b@0O=-rZc!Q1 zW3}lz-%@U>#F8%O_NM!$`*?p$QMbrc7th$L49PB;v(b;ryrHcoiHFVF)z%B-lZN%8 zzgU}q{wjfa+cjEoA9O9;$6ZC8iGSG%n;8qx6TI6Mj+&{I9gFDk42!D1M9teZIGyAs zz^Oe?!Q({&BBFn-3MAElyeV^6ssLGcUcd-H0BYRchfL%M`hZn#a#wN6i@^m4X^|tu zMe=qGb3wfc^}0)-;IZW6&~N7l7R9X_pRCV4TDb26UV99zHJHD;V)g#yiEqrFP&t+J z?>4dTkVdesty2FVYN$P zVteBJls=I`OSmIxMA%dz%4(ILTiHlxoaW-EY_-*%E$PWd_rR`FA$sow%X43h82VR) zE7ERh?Hi<42QIzRdywaV!OwM&2Y0g$z*oH#v*u>xZtChp8 z`7CYBdTaX90jsdJv!fa z_~zjCtAG0N#b0NA1Zys0b%VpO2&)+cP%CENHQ63SEiyp*Y*H!pB zn%kIL^fLow{-U+Mh{}Kd&UT09{)o<9g|EwsRkwMUEJ>AJc3JOLjhD0Cuj)bQtJx{L ziyUgT=N6XS7QLry<}+c$ozglC!g^~P46^RQ9@Q6n7uj!BI6&{#?6=L~fHh3HVFMAC zHruB|L3Cve8_lh@&7okEHEalj?YlOyK|z0Qf@FYZs|^w>P@9*)$Y!a|O>8hN;4&MM zt(a;5(mIsZ?6bB(HdB&npA8mzj|y=c?6WPPPS&v5nrZf{)5`n5K6)$(e) zJ2Q`=eOv9Vx#hLR2s^;&>Tj(-Rot)rsZBi!J-{252`h1DO{}fW`?qqC$uMisSW_FG zvkjWY;X`ydFB=k4Z;~vUR;jdbA2f$c`lLxc#p%{y(*0mrLh(sI+u*3HCj|SAT9uM; z)dU_br@wV-YzEVg)^{UIxRBKTw5>_w&4ekn3MIitytxT{HklB-Yb@*OC{sDLC3sIm zo3?gs;q7TO-VASHty8=uV4@hn)5zZpouGfJG6{=oOMipD?Rd1Z9@ytk$E%g)@rC7J z+KgqA2K})YC14y@HQunckEK&soOCh*kNWah%;+tGNws4LL=%4VrlUcl-uLouhe84G&xf=rWxJ%%dDA%}ip zlNymWxLi(5l`F66zB#7S)ileMC0YZ4ZaLI_U@9T&1wq-YHI_r`{butvHG^zxEpJ5g3xtgpR>2JI(GfuPu zIJaA_a54T4q>(naTs4D#x!I7_tPe{wL@OPMSkn7aHR!#Mh~)}Y-Fc$)YA_g;xv(SR zxUX|v{*)ERw zD&eVRylPwF{Hb~HYFi+-62tml+rV#**9OZ+TjBN6wEs5XRf}(HBVq}!T;R2X@N8Sy ziXkhs6};=(N(^WNd={(o+qPkkD)rshkv$vrf)ID9RZFB$

FSudghlD}GQXqgF6#;fA#cM)&WFZ#>MtkDRdqI0NY;oyZBWI-SYMRyh{Q!61s0 zazhKQaW>_Ll9LWq*obSKg^yK4ypvOWgq4p49?7X{Wv2=*C}W3mHuLg6$uj~1X2OY_ zpv=(r2LSO?fQa!8kP_HO!!R$rMYcT-D*tzr0kANCpr3M(1fbh2HbPA-jNc{BtM>1D zM8I`7vY4xfJ90APCutSxF$}O&z%Cw7QU0*C2S>vog=$+ko3?N0xof0MJi9dUPz5Rj zwWOGxUFzf{o?W^f2=$;@HN-Hz0CVa5MUVsw0Y73C12tSQ;s&cHoX&+J&Dqb_NQ#Zi z6@VqHD#P|n!x@a<-V|=^C$xchw6v0hz-z9z8fq?;_MviBn_{SM*sC+@KlAv&<2jYx zJ7nUuFG%uhg6b!`9nVoZ|NWZg#OLlvqvDl?sXsixsG*Xw~K@!>V%agfse z!gagp@9*@ldzRApmPw8_z?0zELYr=D1ToX>hZZe|===@wZv%_%Y#NB0z zK|q&qHj+jVz4vDKV}MQ+enigZP+v|4{lx`yE|}8!uAOUKtxR zv+AaK5wB^mPO5gpk#TmjuM&$RM~V5>l9H>!FGr6HKfhCaC1vN;1q-h3m^g6<{@s}Z zno|<=cpac8o%jlRfD$GxEB+51R}v>;?P8{ch%5?Y#w33Hx@*FW)H7$28jwk8RNG6x zlHu3MG-10ovr?I{{ezP@pJm*`Y+4n#g7)p0)-oPA1ODUh0c@o-r-2qoY$Mnv$a^eX-S#kuQ8P1uoN-8iUsPb9nWS^Rk6N8$c6Z5wW+A1JEa zIi@IUXo;`T1LZryIm||RAADr;RW08m^o%dbdSrBgvU-MAI_(*F95a()j%k2z)e zXTGQESA*yFvcvzDJoeaL+>f6ks|7kLQ0qwp$&Z>hsI1_7af+2iUTGUgqR0?(XaOodH#b|KcJ7K^Fqy!TsA9EoBol}3$?0FC+|dvt&+QBD7o<|v^N*T zve*z(8gl2bk|fNpCU}z?CA5Fe!(989g`@_vI#(o444nDjW>Lt#43BY3Q_ zf;K67_KEiJiZL~YHIH#Aw+b+oF)U$j)Y89I-~?%ItHV_vIFm(+SUyUV)`mbCbIwjuP z)WTH3$!A_xdE}EeVGZBY#I$EG<$Y4WXj9rhzFFT^DinbYS5LniUAumnU*b%OH?V34 z@W#80%P`Lps;t2GPk>j%Ome6^17oC+vKS;Q4sur>Q_6{6M%%8`aFq*bH-o|27R>&W zT>u(@E~Rb%If?ckX%H5DOUf^j@_z}7NW&k((u=|}@O0RMHQ0y!;O5(8GB8#DgowD&i&dy&DxnNv&cJA_$@e>b( zES_{{dC}QfG2`T669&(J%WloWl7va=@nIq6O+oSFM@Rc_O38@bSd_dbDB5D;+)*Wa zk^l$fct|v4epOhxL^F>ccvW@pnX7aVZr`Q9s?7M|DhK)nashjuWg!fBRPVZ_nP^q(Jjb{!lJgwFyf{jNU)vYiub3^C%rCq+z6Jr>gjvcyPcKJd_ z{_ecX7y2L0pn`OaK(9x~yEGDAAFp=a*(*8)yR?IL;lFqrfNllQ1FV=FGw(19se9-s zdlRz({d#act_f@8ea!or^oy@OYceQdWcv4{?+%DL%uhUfx<0UYxr;a|G6l5O3tBS+ z2LrRFfy*{L2M3yMJoBz_Axi*0Z2OMu4`irSmEn&xnxXKX344!e`Dhz%XrX;tT2#M5 zvSc)Qwe=lxUWgLqG49R*$&RaS2QO$@l^eKCEdoeH#ILOm-jVW%;T^Dlq&A=)CCt+| zSsRd3$bADCpcSb;+qO~I#JvDNl@~9zt%7$XUp}-k7T%G3$ohDy!z)cAG&~hwE!1`P zPHS=2gJLbWF-r9$VWg~5w$;ee$bn@Qn8}?{qjI(e;T6cEO2xaG>98o*9uS23dO{Ce zJOI9@dOw-bW>#XN zDo8n&WQGe2pv##AZJ%)Ls$GvBrp8G8G>0pT{@apQw+h7b4- zCcrwrhxx<}1$D;<^^`U73e!n3<0ki3@W_Ygv5f#I7DkQ$g+n{i5S+KjZZhi=uNf|r zmyg{FpuBE>HxNLLA0Iq0c))ky9M=zvX&N$&U}BG)AKxc}qi}7b*G!kRDiPR@LjY_T z^b3F;qIaSGhCXnre~DEXP)5m90H!lWrM0D0r(P;K=E@%UZVC%E}jrk5q zcZpZ@91`OjI|&DXtu1mT;Kz0dsC^qk6rGF>Kj5cAQWwT%3`2cv;h`17hJ~ViW-|95pb|{KY20_7#DMi$Ama z=z!CI2HsFE%U`+GOqfHq^xe2JbECt@?rkp|{$W|=4|XRG_@-qXSk<)ba9&2}?lW5j z;rKD3eJk{<0fakLbO9Ot4fKmsS5aZQ6wE-iKOC#1klCm!aV@+$Fbt9(EMuvD2ej}T zllmb0u?`M={~B6^k!$}-?ghQD!kNQ7*-oGefFNLnX&L(33OsMSre&4+^_G@v=4-C6 zIrI~3TR*aY&)&Ve_UyGQZP_fu!+6DS`*`+Nq5bFyLD-Y=o8l&UKNLTFZ7$`LQavk9Ab7y_>IWF z`_3xd&OX>VA#l(LvPj;;>iD*erv~)mV2ONINTv2r;-+U$uV}BaQ%rlHP1;`=%j*At z#@11_KvS;(x(tdNNNlM0WQkgv9aI~Ff(FNjFLcJT1?u$D>t$u<@7xJ_sf^`HOcj!Q z_3p{47SPS=OjFf|P$MWm|M*vlDJ(~#?T?vD0lvFX&+;C60DSdnhD0m#L8vE1AUIj} z1B6E5jomO(Za^(qRU(-E%;YB4qhh8C5D9g*;^EtqkG(snr-IzzU{#qhuEOIwjKSKD zb;V|)d-^0dd%+0Wf)y3GR%>6cXwhnBNayj!h}{KlqA)?%?j~{-5}F6--_a!U7Rv{> z!`h#yC!@O+;)RU0Fbtvy0y>K(BD25(n9x$^iL=#{7N7acy_a0k+qUB9w5rSVvh(<` z(lo!yueMICin*|7bY4(Z=7_BcpkKYJyw#ri7%exruX9oE^RV21h03OjI5?%``HxmL1H^J4}jM!kT_w z_DIYMv`H9vOR!lM{);REo8?>4W?81TS$^jhwyme8tRjx7>Ua3`JIY95F@Fm7mnle| zkwU14D^iX%NKNQ9@P?SPgJ&7Kp=HxGHee{9NGn>fPG=sGmX_DeJmv1@)5bx@!v{KH zGHavNV4@*VVFTI`Od|flsE)dXl%W)X$tv*g%nh>ky6~m&B}^^Qr+wQ#l->i49jMpH zBrCQ9wOL^FTGijN+75hwDC*llV$c%d`BM_LQ+U+3We{Nn-%<|fEKUJ3y~(@WT9VNs z^wHJPi^8r`hEv{gY`>9D0ccX~p9qefmH?r7E2gjpKtLA-zf!y&fEo5IJYqq{k&2wq z{7_c==kz5a`{I0mVH_#X%P-F_c#hTn0h21LY!$2i^KACD)ATwBVMw)C$<-vXM4RvG%NZ+0DK1m0> zMJ*Vf2fWde?(h}94*3Y%Ivjh=&1%=4b{oip@I4=3Ji}lf(ZJNiGofWEo(Z3rM>GPV zJjNqRK8KvlR>LmQrN@q`3Lfhc1^gPAMuhqc^ZYZK{K)Vf2Q+vRpC(ZAk;v@>*3txM ziRB)!NGrI&Y2 zO5OR7IWteM&KSt(HVWWd03BS72!y{C^#6qC1q$>6?w3uILF~`Si3|r~;+5$`yFR-J=6T@dxZF5Owr-tmUkV%R(T$T8{89(HF4 z+$oX02GPe~jXsy|>=dY4>z7V|2Ts(b^>^gFJj@2(h5z`&(i?zT#~WgHfLV7>AxCX7 z3A7@nuXnPfz|*WbFS^sl^RV4_7L|Xoch#HT%Jb)y-j}E6ufW4Ha%-Z(SHpH|3I}D- z9ZQP++Q2;VFR7G{%E&r7f5xdo)EObqG9Mxfwni`tDV?=NQCUQzLA~GIO^3#~p{I$> z;v*SVm*$?N<{|CALm7xprJF?hC3-yWzh3J&uA4iS!`t~hy%XWxjN z-J4sw(cbMaW5R2?vbBnJA5!n6+UzDw{r0b zFWE4D(6W2=JHDAWFlP0SyZ8LGy7`6eJ5Qh4vHKL=Yvr4;G&`VVLT?#8$;pj}xDE~( zHp~`hAI5P$h4BRKPK{xZLd3MgJ_fB{EW?cYzohDthYK#1c}xhEjfUfyrXo&fmh0h6_$owJZKjbF>&F9 z-1-%x(x=+;#yzcOo+yLy>!hu*@%xH@0CI_gtQb#qr0?p4ZQV;T%^n1ZQ2x&P)pF{;LyHh74AHhwG=LeZ#zhs;!J;`|=9`*I?uo^sF#$ z4Z`2djFfyjqN~-{&(cxtJYXF{<~iCkysr4I-{%(1ikg(X{$zU7f8zG|9=Ym87&XhI|NVId17^Lse8~&00S!gdw`B~ep1viyAgdt12;A+L zIdC~=PRN+$1qWyJG`5<4Vi901S=E3wXlj6UBvAO@Ko^kK^MMpfOQu_!sm}AypT8y) zivD!;$4U~fPAy|QBpx%xwPl^Uyq(nsPGPa~=BA_f7B0HIYsLwGGNfSbm@zelMXSR{ zuYn`~UI@$|QhjyqcA@?75m*h!k5s)#m*<`;o%>97_Oo;6oy=C#6+L9Iq9I+~ym+ae zpF~hOW+zyyCtw;MyD=|gd+B%=aFxB#I{0Jz+PvH)BS`;I<=OpHrn$ysIhoxr%eCUU zfN4wjO@4(KZ+dPIob;9ZZ1Kp7oDf2L_OdQHQ3}09N<9aZu~hq;v?L+8&?IjF`Z&aM z%xF%-FV%T3F7aKFM6L?A0}}IB|9W8e-hK5&Yaz;yU>K)M-*-+h{GL z&lzH>U3kBrDdz-sTshm7JZaVl%NzZM&pK6Ab*gxHKk_pjFEW4Byw#(qh3dt~t!qod z!%NnpzfX#H@N)93Mr+fKG?YU;WH7*VL!Xeg)&^q*la3|niuHL#t*vq^ z$g5H1seL8A?d>v%e{7M(ZkszS-ImT(y=|E^BrbC(;f}RUCBFG_?s4WcOtndw;$6Be zPA0|};QT7t9pD+T+r-tw96hKo^>CFCYk*20@lZ1>;9yY(_`$sRef{~&LkDV?mip$! zCPrJlZ4r|&KF@pZlG=s?+2?DDPB}U&Pup+$efwn+nt3Aa%I2JXQ}d4(Zr?urcwWZ7 z%pJ`WPh<;ky}j#x-K?srS-?k3MzZK1jBNx&|2RF8G7}-*>2`h0K-HM^kG+n%gooszsFTcTB$9P!kC1}9vUh09w_GAkybb?|Xg^IuWm>Xp~ zg9d$drM;nta{3jISDEa@d;vmPzZsXYe)~!N7V`wU&1+mJqPHq z62q-Ou2jf(kSW~}U(l-+zX*dQJTRadGgMAKUO#3U9K*mzgwIKuX7}_s>IaCt(;Zz- zMCkDf9gHCA7n4}VM;jZ#T9EPOux6W~RmCI)?oL5%4xQ?l5ClcU)y1kn6kE}i+rC<{ z;;U`q@1*L4gz6;r+YT<0`{HGxFZ_KczB-xq0&in{b&~4OO|Ph!OO;$)7*^{b4YOKw9S;5#ASYg1NjXh_HkowxC)&sZj&W6vRzwnNR5axS%oR z2}w(%$S2G1Zd&`#rT#?;f~__EhMcFqk&DCPm&A;(jH$i8Xvrt*^42dLDzNpaV_N`-H7-5GO)?0m{j7`Y?B5-uPg(e}Bd%}OuBRkM`R(8Lwv<5$E_UhMeN5U!^xH`Qry@PULi*B7t9XP16xMqqfR zUtCpuV%7L4uWA~0twgDYyfFjxY_@+$n>W;YhovTSPt7W7PC-Ul zQu{@9_4oDj-ih5kcuCaMwef>TzA|IY^@^G=*CbTMjju{bSP>UjWw-jf?c}}vzpR>+ zx+!2(>iR_CZ?ELcrJt;+xwYbI96VG74<*D`G426vn0p>*0o*g6up#-YC2dtStm+ zu{Ik89jpyF*S3Gp_2zcU6*R=iNOcdcl*8md3;Bf#8Y*1@e=mKXtA{J#Pi4;}wf{(u zvuD5pV^{E*+w2O^S-b*OmELAo!lf&>NlLqZDb40-$nTOB7k<Fq87+>L^W~7DMR+5atu};yML&tkg zSv@YkCT&#OxFNz{Ls#Pp1-osI0~QXfpG-Wkr4Ya<;GkKQelqm}MHUn^4q9iH<{zCt zHOA7@d^8C+6Gl@P;Q^Pnbj*YeR53r-B{+m+M8#zGGM+>Fd#$Ny^NnATG^vKk)qLp9 zZGeT@dE(ln4zQEIgc9O(NVxO+#XViPdpwn`n>9Jm=uZyfMS#hk6Y3 zAh)W$g$6el=eRYg6W1lP(WkT>MqlJXt{F^xva&5F@qTomW6lXK}siX z%_0MV2YvnX9Gn>s`j61?U{r2y6!IXBj4fRN{f1R2MO=j%Nr*5H$bALww69*RBDfAw zC@K%Q+JFU!+OeqnN$U_OSS+S)col+)vms%8EEh8BVCB*SVc{euE^)(@sI;`Gs7YyK zLt|q@Lt&OD(9p1ukg(8D zoX3FIJq-9;0U zYx-$nB3Cg?EYWYKmIj@thz2xYBoyOZx%>OZNt0Rwx&Z5#I_lOzn^DYx)*Zk~7dhlH zvs?$<$4q?wk~T^a3?&1yK=q(2mc-}`uzVe4IlxFk6v*<-ojZ464wMT5NrgNm@S3Fs zK_;#nI3~ehDDUm*-B&jM&fH%!IM*?rzX`1i%V90MZB$Dxa3^^;8VjpOEm+R6MnmaG zcn8{fl^@Q#(s3}i@cIxg9j-UP8vcsW9k?EQ-^d8w102|W&J+GpBe+N|$r=DFg@_mC zRo#cPr=X4!BF&I+wr$!=6b&O&ffj_za}+y|*7Lmr#tMa<@Pq8_G_4X9+JI zTMU@H-`a`g8Kc{k%~tf*fG33mT9A5c2b#{_e_wHUr~_W*+hL8ajHM|LW+h!;wzG zfev1=VM4|4zcb8)CEP8*Uc^j{?J*Aypn;x#pgA~e02NdoMNg~fQ?h`(BYGS#8#l?@ z&6Z*2Gs)IL8?&L_fLUaSxowZzx9M3mW>W%OBL+yAWgPVz>IImsiON1a8ZjFd8%k;r zGZ=gF8>yzPIQAgbK)DvB86hJQ6G!+bB#__Yf=7%WKO#5|o+d}gEbdiq1?I0xG7z6< z-a~pWZb@wHlDOza(b0>@tf-2(xQZz8H^K>}-*eV5#<(iE1-S)TyZI@CtQFR<{JGTE ze?Q{OUKe|PHR6Z*`c?G%+2NbhL<5P>J~Kg|C?j@0Z+s+(64ejo>X&?Z$l>- zO$DBS8Vj6@d_QP$MiH)*2DzG}dy+yV$=uwUt}APr%yE;O%J!9S9W!RzB4I-fNg)f) zpC=1QN=?~D;ihn<@vv}NxKRf*O%XQGJh815w?K3A0DnqBj+&b*tSJ3;-=b|}#%wL$ zCp9T-D64~QSR){^8B9DkmemNSgbnA<3mb$}$gBN@iJXnR4Kp5*v(5b7++6*Gg3tvL zD8|`9tyCzi(K&*FH(Fn@#Wc;#EX{OFMfC#5VSdBlpW^~y;+AqcbAaWNfnfudSX zu zsuwDU`FnZ!4^u9zM!@Fg09csV?CnUWiEYzq%3)WwmaBGITQ3<9HgJjM0M*X&En?5; zD*y|mWdu}XfV5Fd(w{WkyC+QS(RA_ek1ql~wSdnM=@}(+k16R8A^YAvNMD_N ztT#*H3XI&RFp|@ZLRlZK0QEn`k?aQbujr>fwB28*`*qw(L+ zr}DA%5n5YyB1&%0oX{duC%B`S^$3K)QNsf-@}y=b2H27WaudwsG-|h&xwpRoR_(0zwQYYgC`;+bFd7JDs`#CI zlYO75{w`}^-)D*6#WfqAAII$O20@@_jef(m7aXKe$(Bq5Y~h4Fu9=>dy$bRj(k>zt zuHxCMFa;D^pXu3NL&T;29rXvIz9qs4crUR;&G5`%{pLBwjb|;LB1@TVk1ajNuw`va z*lM*Q)A~%$7SFviU)I-qi11JKC+@NZv@HMKW2`He(eaT{z$l;lle-D|et=g2l;k2r z#(r}vgu^6rzVJP<7L3J@KM<>Y@+x^HU1$^zr)xd|X3L?K>*`h(xe*dXEZFbg=MyX8 zhxsJar3~8nzKmq%r;|*QkuJmt(dtjYN3i>6H@67$66rDIBT@$6ufwT;GQf(pME%g}F>zC0v#2&6(=huleNHK^#>90n*1AT`5AAtQShCNFCGNV7B#Z$Vl|DzN3 z;%tHUW+K)|1^GMB>mI-(0ZO1E0c`s7b;1{gWE;-&$# za^+Um{Dv4`VPlMsvaq3G&dd?By{9)6I{3s2n|xx)yg&=T8PR^TgGy(_6!};N*aeU^ z2^U}8oe||`pSkzd^YOysfD>eO@Wz#?BSIIZt*Q$Ic~jdS%paFeXId+sFsTHMIS{Y` zeG_#~3+XSxU9;M*OtxEAJXivJ1LDqYCnXti=FFK!_)#U&z;)*{7v$0P+Y2tO6N*TA z^xTNxSuw&Ak~JbDs5DbJbmfO1V{ff)1*x;1^O@(mosCDI#RnmD;9F z?>K#IUza|8RX8ELw&U)NVVBm2ykfTdkNVwz>@qul!K!H$M5J??ijRK?TR7G>T0%aW z9M+q1{%4sxYjj8P>zgM`*!+5N z$?IDtOxW_e>T>P(8|!|k{hprrzV>@nQ`Y`znfo)c_f4C&k9=JBeeFNsnG)@H;%dLI zrAa^3ecu)gFO+5N%gEZFk+DB3V}B+Msr|kVMlKe{aJ4js{vBh-G5IV5Vg5{ArieMS6 zQ`RLVuLVy;V$v#7(f?Z8JnpQJMvV#aDmXm9>`39Txo<75cyrE6!)8vIGQ(@wjLB1G z4m(Jf(y^^0h3^_0`A?4@2V)GgGWlP@H;c8)VdckK8KBldtqhT?fJ_QIIBN!(N{tCu zeN*`O2$3}suN!%P%!INN@CvIvvI2VG3b~tJMyW_ewT&1E`<_G#RTqbG#blq0z=MzEr*5ey4OZo=-sw5$=sxt^xv?Xdi`A%k5V9X)d0#}v9l4C51- zr^DzERi$8yze^##d!BRpv>3B~ee7%orTT_WwzVF>-IEWb@aJ5gFdw9(JZ$_h5LfDnc19tudz3Lus) z@I%b5nGN;smtLJZ_`{O#UQKyT_?*71ilr|@!5v4QlksL#*FRVAy71vuWnZ4s4~hGS z86Ob$4}i|TKx}vnW)Rl=AIjDzkaui13KHB&36hxY1;U6WnCgte>Ny0bQ1uP735&6} zjgA-)VJciEqkE5Ysn``2y{p`1TyNFO{OZ;}S_Jq*uDrJg0cbbW`Roz|_w!IH^&>QgOBPMBiaH z(^8=z&;bA5LOI#oE6k zYfVizn3c=3JnsU4kMoz!p%e`f5FpZ|6OGJ*h>{To7`&F`SdO#-u!j%3jUFl-B2zk* zDLVcI-5~r^^%i$SRZ7=`b}O@3{zln}pWTh+mw8#=q?u5#D5;N}S9yf0-r!a=Hj>K5 zMx4{2)yT~NCriv26e~`^dI9oGO%yX&P+^k5Vgj^~s;nr@%Bd$*1FATbc*997|8tsu zM|Be~H6%%w$OJVSs+Vc32)@+?NdaX7fjl%;^>V<>#J+N#zr~~r@XSz{o2(urc+{BL zCx+amWfKl}W&$?WKP+|Ti*pLqq`&8c4#^RC1WwTP- zHa63FSFXUwW9E1x^b$Q@;BP6=a5&H$GO37>$k;-tpyW3R%2OW`_m4C1SKBc$IUXnl zGDoq2wb56!YgidsP`cO#n@~mK!-+!1E#ghQZnIxP=EuUj!uzzcsYwM2L+cxSIDuag z(Eote_mCgqKg@S$SgG4&vJ9Gpe`c3Bhqf;`2SF|j_>*Lij6a0|v?uIXyWG_D5l!LZ zRgE;G?FAKD=!U&3!~`-acQ9K5cg4d%vR?lnY$WrV$XsC)F~JX|0_+;z$XcUI(PBaz znFR-S*;16e0EbNE=JIjaRxA}&Z7>4pLjnE=b3|xc1g;v{BB7PY$wVR-9xj3pvV}q$ z;TH<6!b7Holf&Gbd>-V`Gyn3%*pEl>DX{bo1q1yRFBJA-NF z%+8_z7M#ePmBIm%yPMp>Pe+BL$i3iq1zaY9HfD@8b3p-$w7yTTsk}riNW!z9e)_EN z#v0Y!rmk;9pwN}c5Pkk9?5E0$Uc!3?*A z@f39rnJ}N!HIWU%0@Zumo8*1W|OdzbVg$$TN4y*&^$XVhxMpaDBO9hY)& zox)x!*d+JJ4e3tR=-C;`F7}SH-bXElmBfxN%}R3eRGJ^L7+Mn7<<^|6WG6dEnF-#b zsu6L)p0S=&>yqI^_Ndg2slr6O6f;D;G&FW_YTYE@ubbo~e}D^TQ3VkVYp1U0?T=Vg zlH=j6w0Lu%%c6qt^4Zy*L!B+&9N<(=P7aS5o*p{ADSvqE@TuX`PZWqeyOfTuk zPI`{8&##Kj-=98d-^_7UdG;e5rdN-OS{M+pFe*6F!y}Py2~HY3I4L-4L15s5Q^haO zo&EBh%?-2GjLLhVyzG2&=<3r=R&a1uXh`<(!jclSmBt!5@|jS9 z9CN~9%>!%O8fw3HvJARvv-{Gxx6)L96urD5Az{PIMKfOBkeImPqv+-JiHYm+soI1sd5w8_M{;tGr$bV_XCN}V!>$dSb!Y_ zbn;Um5jfDcOsUgSvt_Xpp6Hnf8U;Co&GDej4gD0pQ;bg1?~6 zmDBU8C@zzzvaRTP)j}(JX#MLnIEx0oeqosEKiR7P47-5b(;sH`Tk^?hW#@1(+gNqU zTdxTZ$@+uj-It-J&XfZ}580Fl%)=#RlY@=UgKWcG;V&Vt<*tz(?iL!0rwk#ZfN8^Y z4vcF-*n(x5!Z3g)qHslSp~?HcSx!jRzjgcBn2^} z6~f)=u-e_8E_@E^(Ot>A zojA(+wazCFg}Brf3U|A}P@;r}n6~_#*15z{dgu$jjyefoN0G zGPQ?@3wWXM1xK3N(uf0F#o-Nlvu%a?y_dnOHrJ3>EuyKztH!YFctbCC5!%>6e6{@# z?yM{kW+v1~8;eDpiJJu+46$DLjJOg)T!qh8eDcZ7-t;s*t(u^kaE?4A4+I5Bl!kUM zd6mo<)*|p!fEPea-331YZ)J{V1Ssp^0>DK`nz+`A06%GSvU*pdwH+ta*w~0 zSNqwH@syvm=i1V!4I_f%Ph>@Br^csG&A3+FOpN!PCl1Yp3*Qw~b#Hx?5XZ%jOgm6C zYyYG`AOGdT?)Zd|!qIzgREJDCbgO#h$J-O^ZTC4lQJ)F9Q_{01PRc~-nGYTZYuN>( zkw(ebS2WYy#A5BNcVLX;+ROZEXu&x`|Dhjv0dpeUpn8!U!=lW_#N`+)dcwX~i-j2q zDy~Hb1#rXstcTl%kFJ{IH`8}&Q>bfz>4#=+$~4dDV1IvC2a5n(vX)YELDBPE%@(hD zBYd(v+{f5^1egnj_5l{w*2I2*`zE{SxUg+0$-6^s2ltIyp0@aHPs=|3Ax@LMyuFo! zENup)g$0gww)7q-Y_syUzVO$m0*B*U)_aZW)5rLop1sYS%}BY4ll7qZA>N7h-k#X^ zxx%;L@4-s8u!kyw)ftiYm_e^uimVwumSHl|WznGt$qf}QBTb0c@fP7*&YqK*FT1p0 z{-xz$1wV+ApMMaA?PUp{bKlB5!SV#(FGTS=Wz3>|hk2F2IjF3N)s5sFELO}q7VnBK z9#J>cdWw3KTwG!KiD`UcfX}4B5miMCkENA8KdtYSqVa3f%Ni%mzBrQinBX5$HGR>s zw1wxgr=P3n{fSA~WIyjD@A!3-=QpP1JSTiUc3YWpWRjahq@VZj!8Z2eOOo>{hs%-& zCWiVBckS;mt}MHBcOrF3Rtz2I=Mw}^jGH%g&gQY>HWs*zjB~aNcJ~|Z(jP8n0N@ENHo{A&ov0bf&li~n$O2asSoo9`TE)G6 zc9ffXRJePqvho&jJbIic@ssfR?wrlT{XNN0pP=o9!!vyX;`=rlJKOXRQ~IUY*;x&+ zv7Hz=&a1y&uVWUGoMGhVUeS)?CtYM4;|!hX=y&#)wR$sFy9SaLjAl3xsJ$yGY6i7HkN9)3CauP272<# zFODxwg*}t(+Q`;>J9($QRf?dH9C!Y z4xXHyFl&*Whr7cf>WNyTwidY+pGEx`ElU* zUTCjJs4LHLPMlOW)X9w7y_6UeVBstWzZz&Z;NAtSOHa0W|xKG@agT9~hg8l4l?{=d4e zFC>Z}jPK0u%?d%>WfuK86g^8QEu^|03T}5#D2jT>P_}xC=pN+Gr_wVbkP1q|dXV(V z2M+=xknSyl=%G?rD9q@Ndayu(f<%aj)3x6>v!-Wye`a9jyJ6?{+nMj1@6Ru2hjdCd zCGx|`)vM;emlmibiwtDg7a_!K^9c>MO!zhqW5i1AlHKTG7Hm8(Ia~zCIi@Nvtw+`e~;UYS?tvJ%RKgS zMaBs%*@aL+e+d7}H+ZUdWx{$~E88X_x^9-h+29UZ%U8+hShUra&Nn(42cKldwlm45 zM53wDvP8u0bdqVuNhh67`?l4n+HpNoBB>9U7o~lBS^Fk^B{&=4AJ#!^6UlNoHZ{9` zUNYnA9^nLsZxH=t%fP&W32Q+wq~{!~a9qxs0`B4pTY_B;pkM1wA2@b%&ta=;4Ww6$ z^An&;SG2U;A%lMb$$KgAIuLKz^EJ@SYM>ss+`G0nU3>0AeYC!6)1`gQWL17@*nCFu zrWU2F1=^JHQU4?(m1O>mC0^W0oY9b<|C65sdl*07;I)~!NY{q_xr+1R3HWIXX?(|d zWx0eVcOJ7jrjb967OSf@H1h7z4E+~-=%?=F{OMvgTV&O_5msHuW()pw&SNPS9vt-H lx9532>Y*VPW|xha{}}J1*#fIsrXG Date: Tue, 11 Jun 2024 08:14:06 +0300 Subject: [PATCH 32/63] Update font styles and host URL This commit updates the font styles across several components, improving text readability and consistency. It also switches the host URL in the ResourceKeysDictionary to a production-ready address. --- src/Gml.Launcher/App.axaml | 1 + src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs | 4 ++-- src/Gml.Launcher/Assets/Styles/Classes.axaml | 4 ++++ src/Gml.Launcher/Views/Components/BadgeComponent.axaml | 4 +++- src/Gml.Launcher/Views/Components/GmlButton.axaml | 2 +- src/Gml.Launcher/Views/Components/ServerInfo.axaml | 2 ++ 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Gml.Launcher/App.axaml b/src/Gml.Launcher/App.axaml index c68a03a..2bd69a7 100644 --- a/src/Gml.Launcher/App.axaml +++ b/src/Gml.Launcher/App.axaml @@ -8,6 +8,7 @@ + avares://Gml.Launcher/Assets/Fonts#Manrope diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index 2996201..ace7a72 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -20,7 +20,7 @@ public static class ResourceKeysDictionary public const string CheckUpdates = "CheckUpdates"; public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; - public const string Host = "http://192.168.31.199:5000"; - // public const string Host = "https://gmlb.recloud.tech"; + // public const string Host = "http://192.168.31.199:5000"; + public const string Host = "https://gmlb.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; } diff --git a/src/Gml.Launcher/Assets/Styles/Classes.axaml b/src/Gml.Launcher/Assets/Styles/Classes.axaml index f26c914..25e29a7 100644 --- a/src/Gml.Launcher/Assets/Styles/Classes.axaml +++ b/src/Gml.Launcher/Assets/Styles/Classes.axaml @@ -8,6 +8,10 @@ + + + diff --git a/src/Gml.Launcher/Views/Components/OnlineComponent.axaml.cs b/src/Gml.Launcher/Views/Components/OnlineComponent.axaml.cs new file mode 100644 index 0000000..662365f --- /dev/null +++ b/src/Gml.Launcher/Views/Components/OnlineComponent.axaml.cs @@ -0,0 +1,18 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; + +namespace Gml.Launcher.Views.Components; + +public class OnlineComponent : TemplatedControl +{ + public static readonly StyledProperty OnlineProperty = AvaloniaProperty.Register( + "Online", "0"); + + public string Online + { + get => GetValue(OnlineProperty); + set => SetValue(OnlineProperty, value); + } +} + diff --git a/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml b/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml index 7f5554e..ba9b84a 100644 --- a/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml +++ b/src/Gml.Launcher/Views/Pages/OverviewPageView.axaml @@ -31,6 +31,13 @@ + + Date: Sat, 13 Jul 2024 10:21:28 +0300 Subject: [PATCH 48/63] Switch ProfileUserControl to ItemsControl and add Spacing Updated ProfileUserControl from TemplatedControl to ItemsControl to support dynamic item presentations. Introduced a new Spacing property to allow custom spacing between items. Additionally, moved ProfileInfoComponent and GmlButton from the UserControl template to the ProfilePageView for better separation of concerns. --- .../Views/Components/ProfileUserControl.axaml | 9 +-------- .../Components/ProfileUserControl.axaml.cs | 19 ++++++++++++++----- .../Views/Pages/ProfilePageView.axaml | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml index fc3f4bb..686b388 100644 --- a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml +++ b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml @@ -54,14 +54,7 @@ FontWeight="ExtraBlack" /> - - - - + diff --git a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs index 19eea98..b48d35b 100644 --- a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs +++ b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs @@ -6,18 +6,22 @@ namespace Gml.Launcher.Views.Components; -public class ProfileUserControl : TemplatedControl +public class ProfileUserControl : ItemsControl { + public static readonly StyledProperty SpacingProperty = AvaloniaProperty.Register( + nameof(Spacing)); public static readonly StyledProperty> ProfileInfoItemsProperty = AvaloniaProperty.Register>( nameof(ProfileInfoItems)); - public static readonly StyledProperty SkinUrlProperty = AvaloniaProperty.Register( - nameof(SkinUrl), "https://www.clipartkey.com/mpngs/m/215-2156859_fond-transparent-steve-minecraft.png"); + public static readonly StyledProperty SkinUrlProperty = + AvaloniaProperty.Register( + nameof(SkinUrl), "https://www.clipartkey.com/mpngs/m/215-2156859_fond-transparent-steve-minecraft.png"); - public static readonly StyledProperty UserNameProperty = AvaloniaProperty.Register( - nameof(UserName), "GamerVII"); + public static readonly StyledProperty UserNameProperty = + AvaloniaProperty.Register( + nameof(UserName), "GamerVII"); public string UserName { @@ -37,4 +41,9 @@ public IEnumerable ProfileInfoItems set => SetValue(ProfileInfoItemsProperty, value); } + public int Spacing + { + get => GetValue(SpacingProperty); + set => SetValue(SpacingProperty, value); + } } diff --git a/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml b/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml index 15ee2f5..6fdce7f 100644 --- a/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml +++ b/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml @@ -33,7 +33,20 @@ Grid.Column="0" UserName="{Binding User.Name}" SkinUrl="{Binding User.TextureUrl, Converter={converters:NoiseStringAddConverter}}" - VerticalAlignment="Top" /> + VerticalAlignment="Top"> + + + + + + From 1977b19c103749b51963c0d219dd63edb2a38a34 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 13 Jul 2024 10:21:36 +0300 Subject: [PATCH 49/63] Add URL redirect attached property Introduce `UrlRedirectProperty` to handle URL redirections in controls. This property changes start a process to open the URL with the default system browser, enhancing the app's interactivity. --- .../Core/Converters/UrlRedirectProperty.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs diff --git a/src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs b/src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs new file mode 100644 index 0000000..54cdad5 --- /dev/null +++ b/src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs @@ -0,0 +1,30 @@ +using System.Diagnostics; +using Avalonia; +using Avalonia.Controls; + +namespace Gml.Launcher.Core.Converters; + +public class UrlRedirectProperty +{ + public static readonly AttachedProperty RedirectUrlProperty = + AvaloniaProperty.RegisterAttached("RedirectUrl"); + + public static void SetRedirectUrl(Control obj, string value) => obj.SetValue(RedirectUrlProperty, value); + public static string GetRedirectUrl(Control obj) => obj.GetValue(RedirectUrlProperty); + + public UrlRedirectProperty() + { + RedirectUrlProperty.Changed.AddClassHandler(OnSourceChanged); + } + + private void OnSourceChanged(Control control, AvaloniaPropertyChangedEventArgs args) + { + var url = args.GetNewValue(); + + Process.Start(new ProcessStartInfo + { + FileName = url, + UseShellExecute = true + }); + } +} From 23cbe6ac7f5259c97cc06c61b4e00de3b716ce95 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 13 Jul 2024 10:28:36 +0300 Subject: [PATCH 50/63] Add additional button and group ProfilePageView buttons Reorganized the buttons on the ProfilePageView into a horizontal stack panel, adding a new Icon Additional button alongside the existing TextIcon Primary button. Both buttons execute the OpenLinkCommand with the same URL but have distinct visual styles. --- .../Views/Pages/ProfilePageView.axaml | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml b/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml index 6fdce7f..f6c6762 100644 --- a/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml +++ b/src/Gml.Launcher/Views/Pages/ProfilePageView.axaml @@ -38,15 +38,29 @@ - - + + + + + + + From 5c6081ed4de36b710a177965fc7a2bc949c45b4f Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 13 Jul 2024 14:41:31 +0300 Subject: [PATCH 51/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 249830c..70ab8a3 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 249830cd4fa5d31b5aca63dc3ea8d15fb9916f32 +Subproject commit 70ab8a3bd71c0214416e05d596bb529989eeb567 From 9d518433b9de606966c264973182e9849e68f5f5 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 14 Jul 2024 22:52:16 +0300 Subject: [PATCH 52/63] Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 70ab8a3..99ed334 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 70ab8a3bd71c0214416e05d596bb529989eeb567 +Subproject commit 99ed3344ad5574709b2efed1eefcac577aaafd48 From 10fff68cf60ab61517bbe440c78d7344e5b94b45 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 14 Jul 2024 22:53:40 +0300 Subject: [PATCH 53/63] Update Update submodule link Gml.Client --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 99ed334..03c0179 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 99ed3344ad5574709b2efed1eefcac577aaafd48 +Subproject commit 03c0179a5492e8e00177d00ba908a2a6b396c731 From be07d591af34b5332a3ee1d49804c6682792e040 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:01:55 +0300 Subject: [PATCH 54/63] Update ProgressBar component descriptions Added a minimum width to the description TextBlock in ProgressBar.axaml to ensure better layout consistency. Changed the default value of the Description property to a more informative example in ProgressBar.axaml.cs. --- src/Gml.Launcher/Views/Components/ProgressBar.axaml | 1 + src/Gml.Launcher/Views/Components/ProgressBar.axaml.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Gml.Launcher/Views/Components/ProgressBar.axaml b/src/Gml.Launcher/Views/Components/ProgressBar.axaml index bb39bd6..b740ca6 100644 --- a/src/Gml.Launcher/Views/Components/ProgressBar.axaml +++ b/src/Gml.Launcher/Views/Components/ProgressBar.axaml @@ -60,6 +60,7 @@ FontWeight="SemiBold" Text="{TemplateBinding Headline}" /> diff --git a/src/Gml.Launcher/Views/Components/ProgressBar.axaml.cs b/src/Gml.Launcher/Views/Components/ProgressBar.axaml.cs index 4331bfc..f7bad12 100644 --- a/src/Gml.Launcher/Views/Components/ProgressBar.axaml.cs +++ b/src/Gml.Launcher/Views/Components/ProgressBar.axaml.cs @@ -11,7 +11,7 @@ public class ProgressBar : TemplatedControl nameof(Percentage), "50"); public static readonly StyledProperty DescriptionProperty = AvaloniaProperty.Register( - nameof(Description), "Hitech"); + nameof(Description), "Загружено: 1596 / 6599"); public static readonly StyledProperty HeadlineProperty = AvaloniaProperty.Register( nameof(Headline), "Обновление"); From a1c2ae4bdca1236f96ace8e6818f76fb51f7febd Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:02:07 +0300 Subject: [PATCH 55/63] Add "Stay" string constant to resources Added "Stay" string for localization in English and Russian resource files. Updated designer and resource dictionary templates to include the new constant. --- .../Assets/Resources/ResourceKeysDictionary.Template.cs | 1 + .../Assets/Resources/ResourceKeysDictionary.cs | 5 +++-- src/Gml.Launcher/Assets/Resources/Resources.Designer.cs | 8 ++++++++ src/Gml.Launcher/Assets/Resources/Resources.en.resx | 3 +++ src/Gml.Launcher/Assets/Resources/Resources.resx | 3 +++ src/Gml.Launcher/Assets/Resources/Resources.ru.resx | 3 +++ 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs index 6295512..486d158 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs @@ -7,6 +7,7 @@ public static class ResourceKeysDictionary public const string Error = "Error"; public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; + public const string Stay = "Stay"; public const string DefaultDRpcText = "DefaultDRpcText"; public const string PlayDRpcText = "PlayDRpcText"; public const string Launching = "Launching"; diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index 9b77891..4368a58 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -7,6 +7,7 @@ public static class ResourceKeysDictionary public const string Error = "Error"; public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; + public const string Stay = "Stay"; public const string DefaultDRpcText = "DefaultDRpcText"; public const string PlayDRpcText = "PlayDRpcText"; public const string Launching = "Launching"; @@ -21,8 +22,8 @@ public static class ResourceKeysDictionary public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; public const string JavaNotFound = "JavaNotFound"; - // public const string Host = "http://192.168.31.199:5000"; - public const string Host = "https://gmlb.recloud.tech"; + public const string Host = "http://192.168.31.199:5000"; + // public const string Host = "https://gmlb.recloud.tech"; // public const string Host = "https://gmlb-test.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; } diff --git a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs index ef35d1a..f5415ad 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs +++ b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs @@ -218,5 +218,13 @@ public static string PlayersShort { return ResourceManager.GetString("PlayersShort", resourceCulture); } } + ///

+ /// Ищет локализованную строку, похожую на ProfileNotConfigured. + /// + public static string Stay { + get { + return ResourceManager.GetString("Stay", resourceCulture); + } + } } } diff --git a/src/Gml.Launcher/Assets/Resources/Resources.en.resx b/src/Gml.Launcher/Assets/Resources/Resources.en.resx index e4546a5..4a3727d 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.en.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.en.resx @@ -116,4 +116,7 @@ Unable to detect a loaded Java for your operating system, please contact support or the project administrator. + + Stay + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.resx b/src/Gml.Launcher/Assets/Resources/Resources.resx index a69dbe2..d781a49 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.resx @@ -123,4 +123,7 @@ Unable to detect a loaded Java for your operating system, please contact support or the project administrator. + + Stay + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx index b051bee..1c483b4 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx @@ -116,4 +116,7 @@ Не удалось обнаружить загруженную Java для Вашей операционной системы, обратитесь в поддержку или к администратору проекта + + Осталось + \ No newline at end of file From 94c35cf173eb850f4e8b24570234b664eeb43b11 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:02:14 +0300 Subject: [PATCH 56/63] Refactor profile loading and update counts This commit refactors the profile loading logic into a separate `LoadProfiles` method and updates the `HomeCommand` and `ProfilesChanges` subscriptions to call this method. Additionally, it introduces reactive properties for `MaxCount` and `LoadedCount`, and a method to update the load process description based on these counts. --- .../ViewModels/Pages/OverviewPageViewModel.cs | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index 1c72c39..d30398d 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -38,6 +38,8 @@ public class OverviewPageViewModel : PageViewModelBase private readonly IObservable _onClosed; private readonly ISystemService _systemService; private readonly IDisposable? _closeEvent; + private readonly IDisposable? _maxCountLoaded; + private readonly IDisposable? _loadedLoaded; private readonly IDisposable _profileNameChanged; private Process? _gameProcess; private readonly MainWindowViewModel _mainViewModel; @@ -52,6 +54,8 @@ public class OverviewPageViewModel : PageViewModelBase public IUser User => _user; [Reactive] public int? LoadingPercentage { get; set; } + [Reactive] public int? MaxCount { get; set; } + [Reactive] public int? LoadedCount { get; set; } [Reactive] public string? Headline { get; set; } @@ -94,7 +98,7 @@ internal OverviewPageViewModel(IScreen screen, ListViewModel.SelectedProfile!)) ); - HomeCommand = ReactiveCommand.Create(() => ListViewModel.SelectedProfile = null); + HomeCommand = ReactiveCommand.Create(async () => await LoadProfiles()); _gmlManager.ProgressChanged.Subscribe(percentage => { @@ -102,8 +106,12 @@ internal OverviewPageViewModel(IScreen screen, LoadingPercentage = percentage; }); + _gmlManager.ProfilesChanges.Subscribe(async eventInfo => await LoadProfiles()); + _closeEvent ??= onClosed.Subscribe(_ => _gameProcess?.Kill()); _profileNameChanged ??= ListViewModel.ProfileChanged.Subscribe(SaveSelectedServer); + _maxCountLoaded ??= _gmlManager.MaxFileCount.Subscribe(count => MaxCount = count); + _loadedLoaded ??= _gmlManager.LoadedFilesCount.Subscribe(ChangeLoadProcessDescription); LogoutCommand = ReactiveCommand.CreateFromTask(OnLogout); @@ -112,6 +120,13 @@ internal OverviewPageViewModel(IScreen screen, RxApp.MainThreadScheduler.Schedule(LoadData); } + private void ChangeLoadProcessDescription(int count) + { + LoadedCount = count; + + Description = $"{LocalizationService.GetString(ResourceKeysDictionary.Stay)}: {MaxCount - LoadedCount}"; + } + private async void SaveSelectedServer(ProfileReadDto? profile) { if (profile != null) @@ -242,22 +257,7 @@ private async void LoadData() await _gmlManager.LoadDiscordRpc(); await _gmlManager.UpdateDiscordRpcState(LocalizationService.GetString(ResourceKeysDictionary.DefaultDRpcText)); - var profilesData = await _gmlManager.GetProfiles(); - - ListViewModel.Profiles = new ObservableCollection(profilesData.Data ?? []); - - var lastSelectedProfileName = await _storageService.GetAsync(StorageConstants.LastSelectedProfileName); - - if (!string.IsNullOrEmpty(lastSelectedProfileName) && ListViewModel.Profiles.Any()) - { - ListViewModel.SelectedProfile = - ListViewModel.Profiles.FirstOrDefault(c => c.Name == lastSelectedProfileName); - } - - if (string.IsNullOrEmpty(lastSelectedProfileName)) - { - ListViewModel.SelectedProfile = ListViewModel.Profiles.FirstOrDefault(); - } + await LoadProfiles(); } catch (TaskCanceledException exception) { @@ -276,6 +276,24 @@ private async void LoadData() } } + private async Task LoadProfiles() + { + var profilesData = await _gmlManager.GetProfiles(); + + ListViewModel.Profiles = new ObservableCollection(profilesData.Data ?? []); + + var lastSelectedProfileName = await _storageService.GetAsync(StorageConstants.LastSelectedProfileName); + + if (!string.IsNullOrEmpty(lastSelectedProfileName) && + ListViewModel.Profiles.FirstOrDefault(c => c.Name == lastSelectedProfileName) is { } profile) + { + ListViewModel.SelectedProfile = profile; + } + + ListViewModel.SelectedProfile ??= ListViewModel.Profiles.FirstOrDefault(); + + } + private async Task Reconnect() { _mainViewModel.Manager From b99e15e118907b0541fa25a7d7b5ceca76973691 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 27 Jul 2024 12:35:02 +0300 Subject: [PATCH 57/63] Update host URL to use test environment Replaced the hardcoded local host URL with the test environment URL for consistency and proper testing. Commented out the previous URLs to keep the history intact. --- src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index 4368a58..b851c52 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -22,8 +22,7 @@ public static class ResourceKeysDictionary public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; public const string JavaNotFound = "JavaNotFound"; - public const string Host = "http://192.168.31.199:5000"; // public const string Host = "https://gmlb.recloud.tech"; - // public const string Host = "https://gmlb-test.recloud.tech"; + public const string Host = "https://gmlb-test.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; } From 5c25427418f1da3a5d68aadaf54a12adf42a82aa Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 27 Jul 2024 12:35:07 +0300 Subject: [PATCH 58/63] Reorder method calls for proper Discord RPC initialization. Moved `LoadProfiles` call before `LoadDiscordRpc` to ensure profiles are loaded before attempting to initialize and update Discord RPC. This change prevents potential issues arising from uninitialized profiles during the RPC update process. --- src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index d30398d..5619cde 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -254,10 +254,11 @@ private async void LoadData() { try { + await LoadProfiles(); + await _gmlManager.LoadDiscordRpc(); await _gmlManager.UpdateDiscordRpcState(LocalizationService.GetString(ResourceKeysDictionary.DefaultDRpcText)); - await LoadProfiles(); } catch (TaskCanceledException exception) { From 9a4813a41588c6077dd6e72dae7d23d17bad7bb9 Mon Sep 17 00:00:00 2001 From: Anton Terentev <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 27 Jul 2024 14:28:09 +0300 Subject: [PATCH 59/63] Feature/change install folder (#41) * Add folder icon and directory selection feature Introduced a folder icon for the installation directory setting UI and implemented functionality to change the installation directory. Updated resource files to include new string entries for "InstallationDirectory" and "Edit" in multiple languages. * Add Click event to GmlButton component Implemented a new Click event for the GmlButton component, enhancing its functionality. Updated the axaml template to bind the button's click action and ensured command execution on click events. Also added handler in SettingsPageView to utilize the new Click event. * Remove OnPointerReleased override from GmlButton The OnPointerReleased method was overriding base functionality, which is now removed to restore default behavior. This change ensures that the button handles pointer events as per the standard implementation, preventing unexpected behavior. * Refactor settings initialization and folder change logic Separated responsibilities for initialization steps into distinct methods in `ServiceLocator`. Enhanced `SettingsPageViewModel` to save the installation directory upon changes. Modified `OpenFileDialog` to use new folder picker API and propagate the folder change correctly. * Add "Files" localization and update description format Added a new "Files" string to the resource files for localization support. Updated the OverviewPageViewModel to include the "Files" string in its description format, enhancing clarity for file-related messages. * Refactor (#40) * Refactor converters and optimize ProfileChanges handling Updated converters to ensure return values are non-nullable and handle exceptions gracefully. Optimized `ProfileChanges` handling by using a dedicated async method and made various minor improvements such as marking properties as private. * Refactor ServiceNotFoundException constructor. Simplify initialization of NotFoundedService property directly in the constructor. This reduces the code complexity and enhances readability. * Refactor `ServiceLocator` for readability and simplicity Simplified handler attachment with discards, removed redundant braces, and eliminated unnecessary return statement in `RegisterLocalizationService`. These changes improve code readability and maintainability without altering functionality. * Add detailed documentation comments and code refinements Enhance interface and class method documentation with detailed descriptions, parameters, and return type annotations. Refactor dependency initialization in LocalStorageService, improve encapsulation with "init" properties for immutable fields, and remove redundant constructor in SystemService. * Refactor ViewModels and streamline code Simplified several ViewModel, Model, and View implementations for better readability and maintainability. Removed unnecessary dependencies and streamlined property initializations. Also added event handling for window close functionality. * Refactor and clean up multiple classes for better readability Refactored various classes to improve code readability and maintainability. Changes include removing unnecessary usings, adjusting method placements, and cleaning up formatting inconsistencies. This enhances the overall structure and readability without altering core functionality. --- src/Gml.Launcher/App.axaml | 4 +- src/Gml.Launcher/App.axaml.cs | 8 +- src/Gml.Launcher/Assets/Images/app.svg | 8 +- src/Gml.Launcher/Assets/Images/back.svg | 8 +- src/Gml.Launcher/Assets/Images/document.svg | 8 +- src/Gml.Launcher/Assets/Images/download.svg | 22 +-- src/Gml.Launcher/Assets/Images/folder.svg | 11 ++ src/Gml.Launcher/Assets/Images/home.svg | 4 +- src/Gml.Launcher/Assets/Images/lang-ru.svg | 60 ++++--- src/Gml.Launcher/Assets/Images/lang-us.svg | 65 ++++--- src/Gml.Launcher/Assets/Images/login.svg | 8 +- src/Gml.Launcher/Assets/Images/logo.svg | 4 +- src/Gml.Launcher/Assets/Images/logout.svg | 4 +- src/Gml.Launcher/Assets/Images/profile.svg | 12 +- src/Gml.Launcher/Assets/Images/ram.svg | 20 ++- src/Gml.Launcher/Assets/Images/settings.svg | 16 +- src/Gml.Launcher/Assets/Images/users.svg | 24 ++- src/Gml.Launcher/Assets/Images/vk.svg | 4 +- src/Gml.Launcher/Assets/Images/window.svg | 6 +- .../ResourceKeysDictionary.Template.cs | 1 + .../Resources/ResourceKeysDictionary.cs | 3 + .../Assets/Resources/Resources.Designer.cs | 24 +++ .../Assets/Resources/Resources.en.resx | 17 +- .../Assets/Resources/Resources.resx | 20 ++- .../Assets/Resources/Resources.ru.resx | 19 +- src/Gml.Launcher/Assets/Styles/Classes.axaml | 87 +++++---- src/Gml.Launcher/Assets/Styles/Colors.axaml | 1 - .../Core/Converters/AsyncSkinRenderLoader.cs | 39 ++-- .../Converters/AsyncStreamToImageLoader.cs | 27 +-- .../Converters/Base64ToBitmapConverter.cs | 27 +-- .../Core/Converters/BoolReverseConverter.cs | 14 +- .../Core/Converters/FirstElementConverter.cs | 14 +- .../Core/Converters/HasElementsConverter.cs | 16 +- .../Converters/NoiseStringAddConverter.cs | 16 +- .../Converters/SumServersOnlineConverter.cs | 13 +- .../Core/Converters/UrlRedirectProperty.cs | 15 +- .../Exceptions/ServiceNotFoundException.cs | 9 +- .../Core/Extensions/ServiceLocator.cs | 84 ++++++--- .../Core/Helpers/AppViewLocator.cs | 17 +- .../Core/Services/ILocalizationService.cs | 8 + .../Core/Services/IStorageService.cs | 21 ++- .../Core/Services/ISystemService.cs | 38 ++++ .../Core/Services/LocalStorageService.cs | 42 +++-- .../Services/ResourceLocalizationService.cs | 5 +- src/Gml.Launcher/Core/Services/SkinService.cs | 2 +- .../Core/Services/StorageConstants.cs | 1 + .../Core/Services/SystemService.cs | 49 ++---- src/Gml.Launcher/Gml.Launcher.csproj | 166 +++++++++--------- src/Gml.Launcher/Models/Language.cs | 6 +- src/Gml.Launcher/Models/ProfileInfoItem.cs | 12 +- src/Gml.Launcher/Models/SettingsInfo.cs | 11 +- src/Gml.Launcher/Program.cs | 13 +- .../ViewModels/Base/PageViewModelBase.cs | 20 +-- .../ViewModels/Base/ViewModelBase.cs | 5 +- .../ViewModels/Base/WindowViewModelBase.cs | 1 - .../ViewModels/Components/ListViewModel.cs | 9 +- .../ViewModels/MainWindowViewModel.cs | 13 +- .../ViewModels/Pages/LoginPageViewModel.cs | 83 ++++----- .../ViewModels/Pages/OverviewPageViewModel.cs | 102 +++++------ .../ViewModels/Pages/ProfilePageViewModel.cs | 38 ++-- .../ViewModels/Pages/SettingsPageViewModel.cs | 140 ++++++++------- .../ViewModels/SplashScreenViewModel.cs | 30 ++-- .../Components/BackgroundComponent.axaml | 3 +- .../Components/BackgroundComponent.axaml.cs | 13 +- .../Views/Components/BadgeComponent.axaml | 13 +- .../Views/Components/BadgeComponent.axaml.cs | 3 - .../Views/Components/GmlButton.axaml | 5 +- .../Views/Components/GmlButton.axaml.cs | 31 +++- .../Views/Components/LoadingControl.axaml | 15 +- .../Views/Components/LoadingControl.axaml.cs | 4 - .../Views/Components/LogoComponent.axaml | 7 +- .../Views/Components/LogoComponent.axaml.cs | 4 - .../Views/Components/OnlineComponent.axaml.cs | 2 - .../Components/ProfileInfoComponent.axaml | 3 +- .../Components/ProfileInfoComponent.axaml.cs | 1 - .../Views/Components/ProfileUserControl.axaml | 7 +- .../Components/ProfileUserControl.axaml.cs | 1 - .../Views/Components/ProgressBar.axaml | 4 +- .../Views/Components/ProgressBar.axaml.cs | 4 - .../Views/Components/ServerInfo.axaml | 21 ++- .../Views/Components/ServerInfo.axaml.cs | 19 +- .../Components/ServerListComponent.axaml | 81 +++++---- .../Components/ServerListComponent.axaml.cs | 5 +- .../Components/SidebarComponent.axaml.cs | 23 +-- .../Views/Components/StackFrameBorder.axaml | 17 +- .../Components/StackFrameBorder.axaml.cs | 5 - src/Gml.Launcher/Views/MainWindow.axaml | 1 + src/Gml.Launcher/Views/MainWindow.axaml.cs | 20 ++- .../Views/Pages/LoginPageView.axaml | 3 +- .../Views/Pages/LoginPageView.axaml.cs | 1 - .../Views/Pages/OverviewPageView.axaml.cs | 6 +- .../Views/Pages/ProfilePageView.axaml.cs | 5 +- .../Views/Pages/SettingsPageView.axaml | 127 +++++++++----- .../Views/Pages/SettingsPageView.axaml.cs | 23 ++- .../Views/SplashScreen/SplashScreen.axaml | 2 +- .../Views/SplashScreen/SplashScreen.axaml.cs | 4 +- src/Gml.Launcher/app.manifest | 26 +-- 97 files changed, 1156 insertions(+), 927 deletions(-) create mode 100644 src/Gml.Launcher/Assets/Images/folder.svg diff --git a/src/Gml.Launcher/App.axaml b/src/Gml.Launcher/App.axaml index 863037e..b28e453 100644 --- a/src/Gml.Launcher/App.axaml +++ b/src/Gml.Launcher/App.axaml @@ -6,7 +6,7 @@ - + avares://Gml.Launcher/Assets/Fonts#Manrope @@ -32,7 +32,7 @@ - + diff --git a/src/Gml.Launcher/App.axaml.cs b/src/Gml.Launcher/App.axaml.cs index e85de60..fad59ec 100644 --- a/src/Gml.Launcher/App.axaml.cs +++ b/src/Gml.Launcher/App.axaml.cs @@ -1,15 +1,12 @@ -using System.Globalization; -using System.Threading.Tasks; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Gml.Launcher.ViewModels; using Gml.Launcher.Views; -using Gml.Launcher.Views.SplashScreen; namespace Gml.Launcher; -public partial class App : Application +public class App : Application { public override void Initialize() { @@ -20,11 +17,10 @@ public override async void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - #if DEBUG desktop.MainWindow = new MainWindow { - DataContext = new MainWindowViewModel(), + DataContext = new MainWindowViewModel() }; #else var splashViewModel = new SplashScreenViewModel(); diff --git a/src/Gml.Launcher/Assets/Images/app.svg b/src/Gml.Launcher/Assets/Images/app.svg index 11116f7..c49c6f7 100644 --- a/src/Gml.Launcher/Assets/Images/app.svg +++ b/src/Gml.Launcher/Assets/Images/app.svg @@ -1,4 +1,8 @@ - - + + diff --git a/src/Gml.Launcher/Assets/Images/back.svg b/src/Gml.Launcher/Assets/Images/back.svg index fd187f2..9d38e3b 100644 --- a/src/Gml.Launcher/Assets/Images/back.svg +++ b/src/Gml.Launcher/Assets/Images/back.svg @@ -1,4 +1,8 @@ - - + + diff --git a/src/Gml.Launcher/Assets/Images/document.svg b/src/Gml.Launcher/Assets/Images/document.svg index e29421c..80302f3 100644 --- a/src/Gml.Launcher/Assets/Images/document.svg +++ b/src/Gml.Launcher/Assets/Images/document.svg @@ -1,4 +1,8 @@ - - + + diff --git a/src/Gml.Launcher/Assets/Images/download.svg b/src/Gml.Launcher/Assets/Images/download.svg index 8721030..616335b 100644 --- a/src/Gml.Launcher/Assets/Images/download.svg +++ b/src/Gml.Launcher/Assets/Images/download.svg @@ -1,12 +1,14 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/Gml.Launcher/Assets/Images/folder.svg b/src/Gml.Launcher/Assets/Images/folder.svg new file mode 100644 index 0000000..3848212 --- /dev/null +++ b/src/Gml.Launcher/Assets/Images/folder.svg @@ -0,0 +1,11 @@ + + + + + diff --git a/src/Gml.Launcher/Assets/Images/home.svg b/src/Gml.Launcher/Assets/Images/home.svg index ba40e6d..38aa181 100644 --- a/src/Gml.Launcher/Assets/Images/home.svg +++ b/src/Gml.Launcher/Assets/Images/home.svg @@ -1,3 +1,5 @@ - + diff --git a/src/Gml.Launcher/Assets/Images/lang-ru.svg b/src/Gml.Launcher/Assets/Images/lang-ru.svg index d76f4a2..a5d77d7 100644 --- a/src/Gml.Launcher/Assets/Images/lang-ru.svg +++ b/src/Gml.Launcher/Assets/Images/lang-ru.svg @@ -1,30 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Gml.Launcher/Assets/Images/lang-us.svg b/src/Gml.Launcher/Assets/Images/lang-us.svg index 71f15b1..9f76438 100644 --- a/src/Gml.Launcher/Assets/Images/lang-us.svg +++ b/src/Gml.Launcher/Assets/Images/lang-us.svg @@ -1,31 +1,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Gml.Launcher/Assets/Images/login.svg b/src/Gml.Launcher/Assets/Images/login.svg index 152bd47..2a03f69 100644 --- a/src/Gml.Launcher/Assets/Images/login.svg +++ b/src/Gml.Launcher/Assets/Images/login.svg @@ -1,4 +1,8 @@ - - + + diff --git a/src/Gml.Launcher/Assets/Images/logo.svg b/src/Gml.Launcher/Assets/Images/logo.svg index 0cf4e23..abfb506 100644 --- a/src/Gml.Launcher/Assets/Images/logo.svg +++ b/src/Gml.Launcher/Assets/Images/logo.svg @@ -1,3 +1,5 @@ - + diff --git a/src/Gml.Launcher/Assets/Images/logout.svg b/src/Gml.Launcher/Assets/Images/logout.svg index f9d85d1..2cd4861 100644 --- a/src/Gml.Launcher/Assets/Images/logout.svg +++ b/src/Gml.Launcher/Assets/Images/logout.svg @@ -1,3 +1,5 @@ - + diff --git a/src/Gml.Launcher/Assets/Images/profile.svg b/src/Gml.Launcher/Assets/Images/profile.svg index 7a6dd68..53ef4a9 100644 --- a/src/Gml.Launcher/Assets/Images/profile.svg +++ b/src/Gml.Launcher/Assets/Images/profile.svg @@ -1,6 +1,10 @@ - - - - + + + + diff --git a/src/Gml.Launcher/Assets/Images/ram.svg b/src/Gml.Launcher/Assets/Images/ram.svg index 9a55e6b..3e23976 100644 --- a/src/Gml.Launcher/Assets/Images/ram.svg +++ b/src/Gml.Launcher/Assets/Images/ram.svg @@ -1,7 +1,17 @@ - - - - - + + + + + diff --git a/src/Gml.Launcher/Assets/Images/settings.svg b/src/Gml.Launcher/Assets/Images/settings.svg index f53fdc1..b88bf8c 100644 --- a/src/Gml.Launcher/Assets/Images/settings.svg +++ b/src/Gml.Launcher/Assets/Images/settings.svg @@ -1,8 +1,12 @@ - - - - - - + + + + + + diff --git a/src/Gml.Launcher/Assets/Images/users.svg b/src/Gml.Launcher/Assets/Images/users.svg index b8970a1..1590120 100644 --- a/src/Gml.Launcher/Assets/Images/users.svg +++ b/src/Gml.Launcher/Assets/Images/users.svg @@ -1,8 +1,20 @@ - - - - - - + + + + + + diff --git a/src/Gml.Launcher/Assets/Images/vk.svg b/src/Gml.Launcher/Assets/Images/vk.svg index a05a4d0..340e9ea 100644 --- a/src/Gml.Launcher/Assets/Images/vk.svg +++ b/src/Gml.Launcher/Assets/Images/vk.svg @@ -1,3 +1,5 @@ - + diff --git a/src/Gml.Launcher/Assets/Images/window.svg b/src/Gml.Launcher/Assets/Images/window.svg index a905304..598d1e1 100644 --- a/src/Gml.Launcher/Assets/Images/window.svg +++ b/src/Gml.Launcher/Assets/Images/window.svg @@ -1,4 +1,6 @@ - - + + diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs index 486d158..7c45c1e 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs @@ -8,6 +8,7 @@ public static class ResourceKeysDictionary public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; public const string Stay = "Stay"; + public const string Files = "Files"; public const string DefaultDRpcText = "DefaultDRpcText"; public const string PlayDRpcText = "PlayDRpcText"; public const string Launching = "Launching"; diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index b851c52..205a9fe 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -8,6 +8,7 @@ public static class ResourceKeysDictionary public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; public const string Stay = "Stay"; + public const string Files = "Files"; public const string DefaultDRpcText = "DefaultDRpcText"; public const string PlayDRpcText = "PlayDRpcText"; public const string Launching = "Launching"; @@ -21,7 +22,9 @@ public static class ResourceKeysDictionary public const string CheckUpdates = "CheckUpdates"; public const string InstallingUpdates = "InstallingUpdates"; public const string FailedOs = "FailedOs"; + public const string JavaNotFound = "JavaNotFound"; + // public const string Host = "https://gmlb.recloud.tech"; public const string Host = "https://gmlb-test.recloud.tech"; public const string FolderName = "GamerVIILacunerhV2"; diff --git a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs index f5415ad..e1d057c 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs +++ b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs @@ -221,10 +221,34 @@ public static string PlayersShort { /// /// Ищет локализованную строку, похожую на ProfileNotConfigured. /// + public static string InstallationDirectory { + get { + return ResourceManager.GetString("InstallationDirectory", resourceCulture); + } + } + /// + /// Ищет локализованную строку, похожую на ProfileNotConfigured. + /// + public static string Edit { + get { + return ResourceManager.GetString("Edit", resourceCulture); + } + } + /// + /// Ищет локализованную строку, похожую на ProfileNotConfigured. + /// public static string Stay { get { return ResourceManager.GetString("Stay", resourceCulture); } } + /// + /// Ищет локализованную строку, похожую на ProfileNotConfigured. + /// + public static string Files { + get { + return ResourceManager.GetString("Files", resourceCulture); + } + } } } diff --git a/src/Gml.Launcher/Assets/Resources/Resources.en.resx b/src/Gml.Launcher/Assets/Resources/Resources.en.resx index 4a3727d..56b35fa 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.en.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.en.resx @@ -6,10 +6,14 @@ 1.3 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + Sign in @@ -116,7 +120,16 @@ Unable to detect a loaded Java for your operating system, please contact support or the project administrator. + + Install folder + + + Change + Stay + + files + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.resx b/src/Gml.Launcher/Assets/Resources/Resources.resx index d781a49..a220396 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.resx @@ -1,7 +1,8 @@  - + @@ -13,10 +14,14 @@ 1.3 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + Sign in @@ -123,7 +128,16 @@ Unable to detect a loaded Java for your operating system, please contact support or the project administrator. + + Install folder + + + Change + Stay + + files + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx index 1c483b4..5d9b71d 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx @@ -6,10 +6,14 @@ 1.3 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, + PublicKeyToken=b77a5c561934e089 + АВТОРИЗОВАТЬСЯ @@ -116,7 +120,16 @@ Не удалось обнаружить загруженную Java для Вашей операционной системы, обратитесь в поддержку или к администратору проекта + + Папка установки + + + Изменить + Осталось - \ No newline at end of file + + файлов + + diff --git a/src/Gml.Launcher/Assets/Styles/Classes.axaml b/src/Gml.Launcher/Assets/Styles/Classes.axaml index 25e29a7..73385c9 100644 --- a/src/Gml.Launcher/Assets/Styles/Classes.axaml +++ b/src/Gml.Launcher/Assets/Styles/Classes.axaml @@ -4,105 +4,104 @@ - + - diff --git a/src/Gml.Launcher/Assets/Styles/Colors.axaml b/src/Gml.Launcher/Assets/Styles/Colors.axaml index 22aef54..e279c8c 100644 --- a/src/Gml.Launcher/Assets/Styles/Colors.axaml +++ b/src/Gml.Launcher/Assets/Styles/Colors.axaml @@ -48,4 +48,3 @@ - diff --git a/src/Gml.Launcher/Core/Converters/AsyncSkinRenderLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncSkinRenderLoader.cs index 24b03a3..107c8c9 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncSkinRenderLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncSkinRenderLoader.cs @@ -17,10 +17,10 @@ public class AsyncSkinRenderLoader public static readonly AttachedProperty SourceProperty = AvaloniaProperty.RegisterAttached("Source"); - public static readonly AttachedProperty IsLoadingProperty = + private static readonly AttachedProperty IsLoadingProperty = AvaloniaProperty.RegisterAttached("IsLoading"); - private static ConcurrentDictionary _pendingOperations = new(); + private static readonly ConcurrentDictionary PendingOperations = new(); static AsyncSkinRenderLoader() { @@ -32,10 +32,10 @@ private static async void OnSourceChanged(Image sender, AvaloniaPropertyChangedE try { SetIsLoading(sender, true); - CancellationTokenSource cts = _pendingOperations.AddOrUpdate( + var cts = PendingOperations.AddOrUpdate( sender, new CancellationTokenSource(), - (x, y) => + (_, y) => { y.Cancel(); return new CancellationTokenSource(); @@ -45,7 +45,7 @@ private static async void OnSourceChanged(Image sender, AvaloniaPropertyChangedE if (string.IsNullOrEmpty(url)) { - _pendingOperations.Remove(sender, out _); + PendingOperations.Remove(sender, out _); sender.Source = null; return; } @@ -61,10 +61,7 @@ private static async void OnSourceChanged(Image sender, AvaloniaPropertyChangedE var bitmap = new Bitmap(new MemoryStream(SkinViewer.GetFront(stream, 128))); - if (!cts.Token.IsCancellationRequested) - { - sender.Source = bitmap; - } + if (!cts.Token.IsCancellationRequested) sender.Source = bitmap; } catch (Exception e) { @@ -72,7 +69,7 @@ private static async void OnSourceChanged(Image sender, AvaloniaPropertyChangedE } finally { - _pendingOperations.Remove(sender, out _); + PendingOperations.Remove(sender, out _); SetIsLoading(sender, false); } } @@ -83,9 +80,23 @@ private static bool ValidateUrl(string url) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); } - public static void SetSource(Image obj, string value) => obj.SetValue(SourceProperty, value); - public static string GetSource(Image obj) => obj.GetValue(SourceProperty); + public static void SetSource(Image obj, string value) + { + obj.SetValue(SourceProperty, value); + } + + public static string GetSource(Image obj) + { + return obj.GetValue(SourceProperty); + } + + private static void SetIsLoading(Image obj, bool value) + { + obj.SetValue(IsLoadingProperty, value); + } - private static void SetIsLoading(Image obj, bool value) => obj.SetValue(IsLoadingProperty, value); - public static bool GetIsLoading(Image obj) => obj.GetValue(IsLoadingProperty); + public static bool GetIsLoading(Image obj) + { + return obj.GetValue(IsLoadingProperty); + } } diff --git a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs index bac3861..760ca6c 100644 --- a/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs +++ b/src/Gml.Launcher/Core/Converters/AsyncStreamToImageLoader.cs @@ -22,7 +22,7 @@ static AsyncStreamToImageLoader() TempPath = Path.GetTempPath(); } - public static string TempPath { get; set; } + private static string TempPath { get; } private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPropertyChangedEventArgs args) { @@ -66,7 +66,6 @@ private static async void OnSourceChanged(BackgroundComponent sender, AvaloniaPr sender.Classes.Add("Image"); sender.Source = new Bitmap(fileStream); } - } catch (Exception exception) { @@ -78,15 +77,10 @@ private static async Task ConvertStreamToFile(Stream input, string filePath) { var fileInfo = new FileInfo(filePath); - if (!fileInfo.Directory!.Exists) - { - fileInfo.Directory.Create(); - } + if (!fileInfo.Directory!.Exists) fileInfo.Directory.Create(); - using (var fileStream = File.Create(filePath)) - { - await input.CopyToAsync(fileStream); - } + await using var fileStream = File.Create(filePath); + await input.CopyToAsync(fileStream); } private static bool ValidateUrl(string url) @@ -96,6 +90,13 @@ private static bool ValidateUrl(string url) && Path.GetFileName(url) is { } fileName && Guid.TryParse(fileName, out _); } - public static void SetSource(BackgroundComponent obj, string value) => obj.SetValue(SourceProperty, value); - public static string GetSource(BackgroundComponent obj) => obj.GetValue(SourceProperty); -} \ No newline at end of file + public static void SetSource(BackgroundComponent obj, string value) + { + obj.SetValue(SourceProperty, value); + } + + public static string GetSource(BackgroundComponent obj) + { + return obj.GetValue(SourceProperty); + } +} diff --git a/src/Gml.Launcher/Core/Converters/Base64ToBitmapConverter.cs b/src/Gml.Launcher/Core/Converters/Base64ToBitmapConverter.cs index 164f551..9de0a23 100644 --- a/src/Gml.Launcher/Core/Converters/Base64ToBitmapConverter.cs +++ b/src/Gml.Launcher/Core/Converters/Base64ToBitmapConverter.cs @@ -12,18 +12,18 @@ public class Base64ToBitmapConverter : MarkupExtension, IValueConverter { public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (value is string base64) + if (value is not string base64) + return AvaloniaProperty.UnsetValue; + + try + { + var bytes = System.Convert.FromBase64String(base64); + using var ms = new MemoryStream(bytes); + return new Bitmap(ms); + } + catch { - try - { - var bytes = System.Convert.FromBase64String(base64); - using var ms = new MemoryStream(bytes); - return new Bitmap(ms); - } - catch - { - // ignored - } + // ignored } return AvaloniaProperty.UnsetValue; @@ -34,5 +34,8 @@ public object ConvertBack(object? value, Type targetType, object? parameter, Cul throw new NotImplementedException(); } - public override object ProvideValue(IServiceProvider serviceProvider) => this; + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } } diff --git a/src/Gml.Launcher/Core/Converters/BoolReverseConverter.cs b/src/Gml.Launcher/Core/Converters/BoolReverseConverter.cs index f2e6c42..11c1e9d 100644 --- a/src/Gml.Launcher/Core/Converters/BoolReverseConverter.cs +++ b/src/Gml.Launcher/Core/Converters/BoolReverseConverter.cs @@ -7,20 +7,20 @@ namespace Gml.Launcher.Core.Converters; public class BoolReverseConverter : MarkupExtension, IValueConverter { - public override object ProvideValue(IServiceProvider serviceProvider) => this; - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (bool.TryParse(value?.ToString(), out bool boolValue)) - { - return !boolValue; - } + if (bool.TryParse(value?.ToString(), out var boolValue)) return !boolValue; return null; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { - throw new NotImplementedException(); + return null; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; } } diff --git a/src/Gml.Launcher/Core/Converters/FirstElementConverter.cs b/src/Gml.Launcher/Core/Converters/FirstElementConverter.cs index 7f43c0b..117233f 100644 --- a/src/Gml.Launcher/Core/Converters/FirstElementConverter.cs +++ b/src/Gml.Launcher/Core/Converters/FirstElementConverter.cs @@ -9,20 +9,20 @@ namespace Gml.Launcher.Core.Converters; public class FirstElementConverter : MarkupExtension, IValueConverter { - public override object ProvideValue(IServiceProvider serviceProvider) => this; - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (value is IEnumerable enumerable) - { - return enumerable.FirstOrDefault(); - } + if (value is IEnumerable enumerable) return enumerable.FirstOrDefault(); return null; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { - throw new NotImplementedException(); + return null; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; } } diff --git a/src/Gml.Launcher/Core/Converters/HasElementsConverter.cs b/src/Gml.Launcher/Core/Converters/HasElementsConverter.cs index 61ca604..f7a8f89 100644 --- a/src/Gml.Launcher/Core/Converters/HasElementsConverter.cs +++ b/src/Gml.Launcher/Core/Converters/HasElementsConverter.cs @@ -9,20 +9,20 @@ namespace Gml.Launcher.Core.Converters; public class HasElementsConverter : MarkupExtension, IValueConverter { - public override object ProvideValue(IServiceProvider serviceProvider) => this; - - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (value is IEnumerable enumerable) - { - return enumerable.Any(); - } + if (value is IEnumerable enumerable) return enumerable.Any(); return false; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { - throw new NotImplementedException(); + return null; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; } } diff --git a/src/Gml.Launcher/Core/Converters/NoiseStringAddConverter.cs b/src/Gml.Launcher/Core/Converters/NoiseStringAddConverter.cs index a278a23..0ca83ce 100644 --- a/src/Gml.Launcher/Core/Converters/NoiseStringAddConverter.cs +++ b/src/Gml.Launcher/Core/Converters/NoiseStringAddConverter.cs @@ -7,20 +7,20 @@ namespace Gml.Launcher.Core.Converters; public class NoiseStringAddConverter : MarkupExtension, IValueConverter { - public override object ProvideValue(IServiceProvider serviceProvider) => this; - - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { - if (value is not null && value.ToString()!.Contains('?')) - { - return value; - } + if (value is not null && value.ToString()!.Contains('?')) return value; return $"{value}?{DateTime.Now:mm-ss-fff}"; } public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { - throw new NotImplementedException(); + return null; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; } } diff --git a/src/Gml.Launcher/Core/Converters/SumServersOnlineConverter.cs b/src/Gml.Launcher/Core/Converters/SumServersOnlineConverter.cs index d32a61e..2c84c78 100644 --- a/src/Gml.Launcher/Core/Converters/SumServersOnlineConverter.cs +++ b/src/Gml.Launcher/Core/Converters/SumServersOnlineConverter.cs @@ -10,23 +10,24 @@ namespace Gml.Launcher.Core.Converters; public class SumServersOnlineConverter : MarkupExtension, IValueConverter { - public override object ProvideValue(IServiceProvider serviceProvider) => this; - - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is List server) - { return server .Where(c => c.IsOnline) .Sum(c => c.Online)? .ToString() ?? "0"; - } return "0"; } - public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { return "0"; } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } } diff --git a/src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs b/src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs index 54cdad5..a93a88c 100644 --- a/src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs +++ b/src/Gml.Launcher/Core/Converters/UrlRedirectProperty.cs @@ -6,17 +6,24 @@ namespace Gml.Launcher.Core.Converters; public class UrlRedirectProperty { - public static readonly AttachedProperty RedirectUrlProperty = + private static readonly AttachedProperty RedirectUrlProperty = AvaloniaProperty.RegisterAttached("RedirectUrl"); - public static void SetRedirectUrl(Control obj, string value) => obj.SetValue(RedirectUrlProperty, value); - public static string GetRedirectUrl(Control obj) => obj.GetValue(RedirectUrlProperty); - public UrlRedirectProperty() { RedirectUrlProperty.Changed.AddClassHandler(OnSourceChanged); } + public static void SetRedirectUrl(Control obj, string value) + { + obj.SetValue(RedirectUrlProperty, value); + } + + public static string GetRedirectUrl(Control obj) + { + return obj.GetValue(RedirectUrlProperty); + } + private void OnSourceChanged(Control control, AvaloniaPropertyChangedEventArgs args) { var url = args.GetNewValue(); diff --git a/src/Gml.Launcher/Core/Exceptions/ServiceNotFoundException.cs b/src/Gml.Launcher/Core/Exceptions/ServiceNotFoundException.cs index 211e181..6ff1ba2 100644 --- a/src/Gml.Launcher/Core/Exceptions/ServiceNotFoundException.cs +++ b/src/Gml.Launcher/Core/Exceptions/ServiceNotFoundException.cs @@ -2,12 +2,7 @@ namespace Gml.Launcher.Core.Exceptions; -public class ServiceNotFoundException : Exception +public class ServiceNotFoundException(Type eType) : Exception { - public Type NotFoundedService { get;} - - public ServiceNotFoundException(Type eType) - { - NotFoundedService = eType; - } + public Type NotFoundedService { get; } = eType; } diff --git a/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs b/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs index a0987dd..ed9b035 100644 --- a/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs +++ b/src/Gml.Launcher/Core/Extensions/ServiceLocator.cs @@ -1,5 +1,4 @@ using System; -using System.Configuration; using System.Globalization; using System.IO; using System.Linq; @@ -20,41 +19,33 @@ public static AppBuilder RegisterServices(this AppBuilder builder) { var systemService = new SystemService(); - var configurationManager = ConfigurationManager.OpenMachineConfiguration(); - var installationDirectory = Path.Combine(systemService.GetApplicationFolder(), ResourceKeysDictionary.FolderName); - Locator.CurrentMutable.RegisterConstant(new ResourceLocalizationService(), typeof(ILocalizationService)); - Locator.CurrentMutable.RegisterConstant(systemService, typeof(ISystemService)); - Locator.CurrentMutable.RegisterConstant( - new GmlClientManager(installationDirectory, ResourceKeysDictionary.Host, ResourceKeysDictionary.FolderName, - systemService.GetOsType()), typeof(IGmlClientManager)); - - var storageService = new LocalStorageService(); - Locator.CurrentMutable.RegisterConstant(storageService, typeof(IStorageService)); - - var data = storageService.GetAsync(StorageConstants.Settings).Result; + RegisterLocalizationService(); + RegisterSystemService(systemService); + var manager = RegisterGmlManager(systemService, installationDirectory); + var storageService = RegisterStorage(); - if (data != null && !string.IsNullOrEmpty(data.LanguageCode)) - { - Thread.CurrentThread.CurrentCulture = systemService - .GetAvailableLanguages() - .FirstOrDefault(c => c.Culture.Name == data.LanguageCode)? - .Culture ?? new CultureInfo("ru-RU");; - } + CheckAndChangeInstallationFolder(storageService, manager); + CheckAndChangeLanguage(storageService, systemService); + InitializeSentry(); - AppDomain.CurrentDomain.UnhandledException += (sender, args) => + AppDomain.CurrentDomain.UnhandledException += (_, args) => { SentrySdk.CaptureException((Exception)args.ExceptionObject); }; + return builder; + } + + private static void InitializeSentry() + { var sentryUrl = GmlClientManager.GetSentryLink(ResourceKeysDictionary.Host).Result; try { if (!string.IsNullOrEmpty(sentryUrl)) - { SentrySdk.Init(options => { options.Dsn = sentryUrl; @@ -65,13 +56,58 @@ public static AppBuilder RegisterServices(this AppBuilder builder) options.SendDefaultPii = true; options.MaxAttachmentSize = 10 * 1024 * 1024; }); - } } catch (Exception exception) { Console.WriteLine(exception); } + } - return builder; + private static void CheckAndChangeLanguage(LocalStorageService storageService, SystemService systemService) + { + var data = storageService.GetAsync(StorageConstants.Settings).Result; + + if (data != null && !string.IsNullOrEmpty(data.LanguageCode)) + Thread.CurrentThread.CurrentCulture = systemService + .GetAvailableLanguages() + .FirstOrDefault(c => c.Culture.Name == data.LanguageCode)? + .Culture ?? new CultureInfo("ru-RU"); + } + + private static LocalStorageService RegisterStorage() + { + var storageService = new LocalStorageService(); + Locator.CurrentMutable.RegisterConstant(storageService, typeof(IStorageService)); + + return storageService; + } + + private static void CheckAndChangeInstallationFolder(LocalStorageService storageService, GmlClientManager manager) + { + var installationDirectory = storageService.GetAsync(StorageConstants.InstallationDirectory).Result; + + if (!string.IsNullOrEmpty(installationDirectory)) manager.ChangeInstallationFolder(installationDirectory); + } + + private static GmlClientManager RegisterGmlManager(SystemService systemService, string installationDirectory) + { + var manager = new GmlClientManager(installationDirectory, ResourceKeysDictionary.Host, + ResourceKeysDictionary.FolderName, + systemService.GetOsType()); + + Locator.CurrentMutable.RegisterConstant(manager, typeof(IGmlClientManager)); + + return manager; + } + + private static void RegisterSystemService(SystemService systemService) + { + Locator.CurrentMutable.RegisterConstant(systemService, typeof(ISystemService)); + } + + private static void RegisterLocalizationService() + { + var service = new ResourceLocalizationService(); + Locator.CurrentMutable.RegisterConstant(service, typeof(ILocalizationService)); } } diff --git a/src/Gml.Launcher/Core/Helpers/AppViewLocator.cs b/src/Gml.Launcher/Core/Helpers/AppViewLocator.cs index 59661a6..e50f6cb 100644 --- a/src/Gml.Launcher/Core/Helpers/AppViewLocator.cs +++ b/src/Gml.Launcher/Core/Helpers/AppViewLocator.cs @@ -7,13 +7,16 @@ namespace Gml.Launcher.Core.Helpers; public class AppViewLocator : IViewLocator { - public IViewFor ResolveView(T? viewModel, string? contract = null) => viewModel switch + public IViewFor ResolveView(T? viewModel, string? contract = null) { - OverviewPageViewModel context => new OverviewPageView { DataContext = context }, - ProfilePageViewModel context => new ProfilePageView { DataContext = context }, - SettingsPageViewModel context => new SettingsPageView { DataContext = context }, - LoginPageViewModel context => new LoginPageView { DataContext = context }, + return viewModel switch + { + OverviewPageViewModel context => new OverviewPageView { DataContext = context }, + ProfilePageViewModel context => new ProfilePageView { DataContext = context }, + SettingsPageViewModel context => new SettingsPageView { DataContext = context }, + LoginPageViewModel context => new LoginPageView { DataContext = context }, - _ => throw new ArgumentOutOfRangeException(nameof(viewModel)) - }; + _ => throw new ArgumentOutOfRangeException(nameof(viewModel)) + }; + } } diff --git a/src/Gml.Launcher/Core/Services/ILocalizationService.cs b/src/Gml.Launcher/Core/Services/ILocalizationService.cs index 7f83090..6c621e3 100644 --- a/src/Gml.Launcher/Core/Services/ILocalizationService.cs +++ b/src/Gml.Launcher/Core/Services/ILocalizationService.cs @@ -1,6 +1,14 @@ namespace Gml.Launcher.Core.Services; +/// +/// Represents the interface for localization services. +/// public interface ILocalizationService { + /// + /// Retrieves a localized string for the specified key. + /// + /// The key of the localized string. + /// The localized string. string GetString(string key); } diff --git a/src/Gml.Launcher/Core/Services/IStorageService.cs b/src/Gml.Launcher/Core/Services/IStorageService.cs index 1ae41a5..0fcb976 100644 --- a/src/Gml.Launcher/Core/Services/IStorageService.cs +++ b/src/Gml.Launcher/Core/Services/IStorageService.cs @@ -1,17 +1,15 @@ -using System.Collections.Generic; -using System.Threading; +using System.Threading; using System.Threading.Tasks; -using Gml.Launcher.Models; namespace Gml.Launcher.Core.Services; /// -/// Represents a storage service interface used for saving and retrieving data. +/// Represents a storage service interface used for saving and retrieving data. /// public interface IStorageService { /// - /// Stores the provided value with the specified key asynchronously. + /// Stores the provided value with the specified key asynchronously. /// /// The type of the value to store. /// The key for the value. @@ -21,23 +19,28 @@ public interface IStorageService Task SetAsync(string key, T value, CancellationToken? token = default); /// - /// Retrieves the value associated with the specified key asynchronously. + /// Retrieves the value associated with the specified key asynchronously. /// /// The type of the value. /// The key of the value to retrieve. /// - /// A task representing the asynchronous operation. The task result contains the retrieved value, - /// or null if the key does not exist in the storage. + /// A task representing the asynchronous operation. The task result contains the retrieved value, + /// or null if the key does not exist in the storage. /// Task GetAsync(string key); /// - /// Saves a record of type T to the storage service. + /// Saves a record of type T to the storage service. /// /// The type of the record to save. /// The record to save. /// A task representing the asynchronous save operation. Task SaveRecord(T value); + /// + /// Retrieves the logs from the storage service asynchronously. + /// + /// The maximum number of logs to retrieve. Default value is 100. + /// A task representing the asynchronous operation. The task result contains the logs as a concatenated string. Task GetLogsAsync(int rowCount); } diff --git a/src/Gml.Launcher/Core/Services/ISystemService.cs b/src/Gml.Launcher/Core/Services/ISystemService.cs index 22177d8..3f15683 100644 --- a/src/Gml.Launcher/Core/Services/ISystemService.cs +++ b/src/Gml.Launcher/Core/Services/ISystemService.cs @@ -5,13 +5,51 @@ namespace Gml.Launcher.Core.Services; +/// +/// Represents a system service that provides various system-related information and functionalities. +/// public interface ISystemService { + /// + /// Retrieves the application folder path based on the current operating system. + /// + /// The path to the application folder. string GetApplicationFolder(); + + /// Retrieves the game folder path. + /// @param additionalPath The additional path within the game folder. Can be null or empty. + /// @param needCreate Specify whether the folder should be created if it does not exist. + /// @return The full path to the game folder, including the additional path if provided. + /// / string GetGameFolder(string additionalPath, bool needCreate); + + /// + /// Gets the maximum amount of RAM available in the system in megabytes. + /// + /// The maximum amount of RAM available in the system in megabytes. ulong GetMaxRam(); + + /// + /// Gets the operating system type. + /// + /// The operating system type. Possible values are: Undefined, Linux, OsX, Windows. OsType GetOsType(); + + /// + /// Gets the available languages. + /// + /// An enumerable of Language objects representing the available languages. IEnumerable GetAvailableLanguages(); + + /// + /// Gets the hardware identification (HWID) of the system. + /// + /// The HWID of the system. string GetHwid(); + + /// + /// Asynchronously loads system data such as drive list, motherboard list, and CPU list. + /// + /// A task representing the asynchronous operation. Task LoadSystemData(); } diff --git a/src/Gml.Launcher/Core/Services/LocalStorageService.cs b/src/Gml.Launcher/Core/Services/LocalStorageService.cs index 40d088d..a1dbda9 100644 --- a/src/Gml.Launcher/Core/Services/LocalStorageService.cs +++ b/src/Gml.Launcher/Core/Services/LocalStorageService.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.IO; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -13,31 +14,25 @@ public class LocalStorageService : IStorageService { private const string DatabaseFileName = "data.db"; private readonly SQLiteAsyncConnection _database; - private readonly IGmlClientManager _gmlClient; - private readonly ISystemService _systemService; public LocalStorageService(ISystemService? systemService = null, IGmlClientManager? gmlClient = null) { - _gmlClient = gmlClient - ?? Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); + var gmlClientManager = gmlClient + ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); - _systemService ??= Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(ISystemService)); + var systemServiceDependency = systemService + ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(ISystemService)); - var databasePath = System.IO.Path.Combine(_systemService.GetGameFolder(_gmlClient.ProjectName ,true), DatabaseFileName); + var databasePath = Path.Combine(systemServiceDependency.GetGameFolder(gmlClientManager.ProjectName, true), + DatabaseFileName); _database = new SQLiteAsyncConnection(databasePath); InitializeTables(); } - private void InitializeTables() - { - _database.CreateTableAsync().Wait(); - _database.CreateTableAsync().Wait(); - } - public async Task SetAsync(string key, T value, CancellationToken? token = default) { var serializedValue = JsonSerializer.Serialize(value); @@ -57,10 +52,7 @@ public async Task SetAsync(string key, T value, CancellationToken? token = de .Where(si => si.Key == key) .FirstOrDefaultAsync(); - if (storageItem != null) - { - return JsonSerializer.Deserialize(storageItem.Value); - } + if (storageItem != null) return JsonSerializer.Deserialize(storageItem.Value); return default; } @@ -77,19 +69,25 @@ public async Task GetLogsAsync(int rowCount = 100) return string.Join("\n", logs.Select(c => c.Message)); } + private void InitializeTables() + { + _database.CreateTableAsync().Wait(); + _database.CreateTableAsync().Wait(); + } + [Table("StorageItems")] private class StorageItem { - [PrimaryKey] public string Key { get; set; } = null!; + [PrimaryKey] public string Key { get; init; } = null!; public string? TypeName { get; set; } - public string Value { get; set; } = null!; + public string Value { get; init; } = null!; } [Table("Logs")] private class LogsItem { [PrimaryKey] public string Date { get; set; } = null!; - public string? Message { get; set; } + public string? Message { get; } public string StackTrace { get; set; } = null!; } } diff --git a/src/Gml.Launcher/Core/Services/ResourceLocalizationService.cs b/src/Gml.Launcher/Core/Services/ResourceLocalizationService.cs index 803990f..3bb2590 100644 --- a/src/Gml.Launcher/Core/Services/ResourceLocalizationService.cs +++ b/src/Gml.Launcher/Core/Services/ResourceLocalizationService.cs @@ -8,10 +8,7 @@ public class ResourceLocalizationService : ILocalizationService { public string GetString(string key) { - if (Application.Current == null) - { - throw new ArgumentException($"Key '{key}' not found in resources"); - } + if (Application.Current == null) throw new ArgumentException($"Key '{key}' not found in resources"); return TryGetLocalizedString(key) ?? throw new Exception($"Resource \"{key}\" not found"); } diff --git a/src/Gml.Launcher/Core/Services/SkinService.cs b/src/Gml.Launcher/Core/Services/SkinService.cs index 8d227a4..2982797 100644 --- a/src/Gml.Launcher/Core/Services/SkinService.cs +++ b/src/Gml.Launcher/Core/Services/SkinService.cs @@ -44,7 +44,7 @@ public static byte[] GetCloak(string cloakPath, int size) public static byte[] GetFront(Stream skinStream, int size) { - using Image inputImage = Image.Load(skinStream); + using var inputImage = Image.Load(skinStream); var scaleFactor = inputImage.Width / 64; diff --git a/src/Gml.Launcher/Core/Services/StorageConstants.cs b/src/Gml.Launcher/Core/Services/StorageConstants.cs index fe5d8e7..c7ac41a 100644 --- a/src/Gml.Launcher/Core/Services/StorageConstants.cs +++ b/src/Gml.Launcher/Core/Services/StorageConstants.cs @@ -5,4 +5,5 @@ public static class StorageConstants public const string User = "UserInfo"; public const string Settings = "Settings"; public const string LastSelectedProfileName = "LastSelectedProfile"; + public const string InstallationDirectory = "InstallationDirectory"; } diff --git a/src/Gml.Launcher/Core/Services/SystemService.cs b/src/Gml.Launcher/Core/Services/SystemService.cs index 2211d92..00e96d9 100644 --- a/src/Gml.Launcher/Core/Services/SystemService.cs +++ b/src/Gml.Launcher/Core/Services/SystemService.cs @@ -13,20 +13,12 @@ namespace Gml.Launcher.Core.Services; public class SystemService : ISystemService { - private readonly HardwareInfo _hardwareInfo; private const string NotSupportedMessage = "The operating system is not supported."; - - public SystemService() - { - _hardwareInfo = new HardwareInfo(); - } + private readonly HardwareInfo _hardwareInfo = new(); public ulong GetMaxRam() { - if (!(IsWindows() || IsLinux() || IsMacOS())) - { - throw new NotSupportedException(NotSupportedMessage); - } + if (!(IsWindows() || IsLinux() || IsMacOS())) throw new NotSupportedException(NotSupportedMessage); _hardwareInfo.RefreshMemoryStatus(); @@ -35,15 +27,9 @@ public ulong GetMaxRam() public string GetApplicationFolder() { - if (IsWindows()) - { - return GetFolderPath(Environment.SpecialFolder.ApplicationData); - } + if (IsWindows()) return GetFolderPath(Environment.SpecialFolder.ApplicationData); - if (IsLinux() || IsMacOS()) - { - return GetFolderPath(Environment.SpecialFolder.UserProfile); - } + if (IsLinux() || IsMacOS()) return GetFolderPath(Environment.SpecialFolder.UserProfile); throw new NotSupportedException(NotSupportedMessage); } @@ -77,27 +63,13 @@ public async Task LoadSystemData() await Task.WhenAll(refreshDriveListTask, refreshMotherboardListTask, refreshCpuListTask); } - private static string GetFolderPath(Environment.SpecialFolder folder) - { - return Environment.GetFolderPath(folder); - } - public OsType GetOsType() { - if (IsWindows()) - { - return OsType.Windows; - } + if (IsWindows()) return OsType.Windows; - if (IsLinux()) - { - return OsType.Linux; - } + if (IsLinux()) return OsType.Linux; - if (IsMacOS()) - { - return OsType.OsX; - } + if (IsMacOS()) return OsType.OsX; return OsType.Undefined; } @@ -107,7 +79,12 @@ public IEnumerable GetAvailableLanguages() return new List { new() { IconPath = "/Assets/Images/lang-ru.svg", Name = "Русский", Culture = new CultureInfo("ru-RU") }, - new() { IconPath = "/Assets/Images/lang-us.svg", Name = "English", Culture = new CultureInfo("en-US") }, + new() { IconPath = "/Assets/Images/lang-us.svg", Name = "English", Culture = new CultureInfo("en-US") } }; } + + private static string GetFolderPath(Environment.SpecialFolder folder) + { + return Environment.GetFolderPath(folder); + } } diff --git a/src/Gml.Launcher/Gml.Launcher.csproj b/src/Gml.Launcher/Gml.Launcher.csproj index b162cbb..dbb153e 100644 --- a/src/Gml.Launcher/Gml.Launcher.csproj +++ b/src/Gml.Launcher/Gml.Launcher.csproj @@ -1,95 +1,95 @@  - - WinExe - net8.0 - enable - true - app.manifest - true - Assets\Images\logo.ico - 2.1.0.0 - 2.1.0.0 - + + WinExe + net8.0 + enable + true + app.manifest + true + Assets\Images\logo.ico + 2.1.0.0 + 2.1.0.0 + - - - + + + - - - - PublicResXFileCodeGenerator - Resources.Designer.cs - - + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - ILocalizationService.cs - - - ISystemService.cs - - - True - True - Resources.resx - - - IStorageService.cs - - - + + + ILocalizationService.cs + + + ISystemService.cs + + + True + True + Resources.resx + + + IStorageService.cs + + + - - - - - - + + + + + + - - - True - True - Resource.resx - - - PublicResXFileCodeGenerator - Resource.Designer.cs - - - PublicResXFileCodeGenerator - - - PublicResXFileCodeGenerator - Resources.Designer.cs - - - PublicResXFileCodeGenerator - - + + + True + True + Resource.resx + + + PublicResXFileCodeGenerator + Resource.Designer.cs + + + PublicResXFileCodeGenerator + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + PublicResXFileCodeGenerator + + diff --git a/src/Gml.Launcher/Models/Language.cs b/src/Gml.Launcher/Models/Language.cs index fce1644..1cd0906 100644 --- a/src/Gml.Launcher/Models/Language.cs +++ b/src/Gml.Launcher/Models/Language.cs @@ -4,7 +4,7 @@ namespace Gml.Launcher.Models; public class Language { - public required string IconPath { get; set; } - public required string Name { get; set; } - public required CultureInfo Culture { get; set; } + public required string IconPath { get; init; } + public required string Name { get; init; } + public required CultureInfo Culture { get; init; } } diff --git a/src/Gml.Launcher/Models/ProfileInfoItem.cs b/src/Gml.Launcher/Models/ProfileInfoItem.cs index 62b3c29..37d70ea 100644 --- a/src/Gml.Launcher/Models/ProfileInfoItem.cs +++ b/src/Gml.Launcher/Models/ProfileInfoItem.cs @@ -1,13 +1,7 @@ namespace Gml.Launcher.Models; -public class ProfileInfoItem +public class ProfileInfoItem(string key, string value) { - public ProfileInfoItem(string key, string value) - { - Value = value; - Key = key; - } - - public string Key { get; set; } = null!; - public string Value { get; set; } = null!; + public string Key { get; set; } = key; + public string Value { get; set; } = value; } diff --git a/src/Gml.Launcher/Models/SettingsInfo.cs b/src/Gml.Launcher/Models/SettingsInfo.cs index 2c40f16..9ac09a3 100644 --- a/src/Gml.Launcher/Models/SettingsInfo.cs +++ b/src/Gml.Launcher/Models/SettingsInfo.cs @@ -1,7 +1,12 @@ namespace Gml.Launcher.Models; -public record SettingsInfo(int GameWidth, int GameHeight, bool FullScreen, bool IsDynamicRam, double RamValue, string? LanguageCode) +public record SettingsInfo( + int GameWidth, + int GameHeight, + bool FullScreen, + bool IsDynamicRam, + double RamValue, + string? LanguageCode) { - public static SettingsInfo Default - => new SettingsInfo(900, 600, false, true, 0, "ru-RU"); + public static SettingsInfo Default => new(900, 600, false, true, 0, "ru-RU"); } diff --git a/src/Gml.Launcher/Program.cs b/src/Gml.Launcher/Program.cs index c66ef67..ff89e66 100644 --- a/src/Gml.Launcher/Program.cs +++ b/src/Gml.Launcher/Program.cs @@ -1,14 +1,14 @@ -using Avalonia; -using Avalonia.ReactiveUI; -using System; +using System; using System.Reactive; +using Avalonia; +using Avalonia.ReactiveUI; using Gml.Launcher.Core.Extensions; using ReactiveUI; using Sentry; namespace Gml.Launcher; -class Program +internal class Program { [STAThread] public static void Main(string[] args) @@ -18,7 +18,6 @@ public static void Main(string[] args) RxApp.DefaultExceptionHandler = Observer.Create(GlobalExceptionHandler); BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); - } catch (Exception e) { @@ -32,10 +31,12 @@ private static void GlobalExceptionHandler(Exception exception) } public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() + { + return AppBuilder.Configure() .UsePlatformDetect() .WithInterFont() .RegisterServices() .LogToTrace() .UseReactiveUI(); + } } diff --git a/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs b/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs index 9a012a0..cf4ac7b 100644 --- a/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs +++ b/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs @@ -3,10 +3,6 @@ using System.Threading; using System.Threading.Tasks; using System.Windows.Input; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Layout; -using Avalonia.Media; using Avalonia.Threading; using GamerVII.Notification.Avalonia; using Gml.Launcher.Assets; @@ -19,15 +15,8 @@ namespace Gml.Launcher.ViewModels.Base; public class PageViewModelBase : ViewModelBase, IRoutableViewModel { - public IScreen HostScreen { get; } - public string? UrlPathSegment { get; } = Guid.NewGuid().ToString().Substring(0, 5); protected readonly ILocalizationService LocalizationService; - public string Title => LocalizationService.GetString(ResourceKeysDictionary.DefaultPageTitle); - - public ICommand OpenLinkCommand { get; } - public ICommand GoBackCommand { get; set; } - protected PageViewModelBase(IScreen screen, ILocalizationService? localizationService = null) { LocalizationService = localizationService @@ -40,6 +29,13 @@ protected PageViewModelBase(IScreen screen, ILocalizationService? localizationSe HostScreen = screen; } + public string Title => LocalizationService.GetString(ResourceKeysDictionary.DefaultPageTitle); + + public ICommand OpenLinkCommand { get; } + public ICommand GoBackCommand { get; set; } + public IScreen HostScreen { get; } + public string? UrlPathSegment { get; } = Guid.NewGuid().ToString().Substring(0, 5); + private void OpenLink(string url) { Process.Start(new ProcessStartInfo @@ -52,7 +48,6 @@ private void OpenLink(string url) protected void ShowError(string title, string content) { if (HostScreen is MainWindowViewModel mainViewModel) - { Dispatcher.UIThread.Invoke(() => { mainViewModel.Manager @@ -63,7 +58,6 @@ protected void ShowError(string title, string content) .WithDelay(TimeSpan.FromSeconds(3)) .Queue(); }); - } } protected Task ExecuteFromNewThread(Func func) diff --git a/src/Gml.Launcher/ViewModels/Base/ViewModelBase.cs b/src/Gml.Launcher/ViewModels/Base/ViewModelBase.cs index d60f8d9..e256bca 100644 --- a/src/Gml.Launcher/ViewModels/Base/ViewModelBase.cs +++ b/src/Gml.Launcher/ViewModels/Base/ViewModelBase.cs @@ -1,10 +1,9 @@ -using System; -using System.Reactive.Subjects; +using System.Reactive.Subjects; using ReactiveUI; namespace Gml.Launcher.ViewModels.Base; public class ViewModelBase : ReactiveObject { - protected internal Subject OnClosed = new(); + protected internal readonly Subject OnClosed = new(); } diff --git a/src/Gml.Launcher/ViewModels/Base/WindowViewModelBase.cs b/src/Gml.Launcher/ViewModels/Base/WindowViewModelBase.cs index 72d054f..d99f19e 100644 --- a/src/Gml.Launcher/ViewModels/Base/WindowViewModelBase.cs +++ b/src/Gml.Launcher/ViewModels/Base/WindowViewModelBase.cs @@ -2,5 +2,4 @@ public class WindowViewModelBase : ViewModelBase { - } diff --git a/src/Gml.Launcher/ViewModels/Components/ListViewModel.cs b/src/Gml.Launcher/ViewModels/Components/ListViewModel.cs index 8efc3b9..038acd4 100644 --- a/src/Gml.Launcher/ViewModels/Components/ListViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Components/ListViewModel.cs @@ -11,6 +11,10 @@ public class ListViewModel : ViewModelBase { internal readonly Subject ProfileChanged = new(); + + private ObservableCollection? _profiles; + private ProfileReadDto? _selectedProfile; + public ObservableCollection? Profiles { get => _profiles; @@ -38,9 +42,4 @@ public ProfileReadDto? SelectedProfile public bool IsNotLoaded => _profiles == null; public bool HasItems => _profiles != null && _profiles.Any(); public bool HasSelectedItem => _selectedProfile != null; - - - private ObservableCollection? _profiles; - private ProfileReadDto? _selectedProfile; - } diff --git a/src/Gml.Launcher/ViewModels/MainWindowViewModel.cs b/src/Gml.Launcher/ViewModels/MainWindowViewModel.cs index 6efdc49..f244667 100644 --- a/src/Gml.Launcher/ViewModels/MainWindowViewModel.cs +++ b/src/Gml.Launcher/ViewModels/MainWindowViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Reactive; using System.Reactive.Subjects; using GamerVII.Notification.Avalonia; using Gml.Launcher.ViewModels.Base; @@ -10,16 +9,14 @@ namespace Gml.Launcher.ViewModels; public class MainWindowViewModel : WindowViewModelBase, IScreen { - public RoutingState Router { get; } = new(); - - public ReactiveCommand GoBackCommand => Router.NavigateBack!; - - public INotificationMessageManager Manager { get; } = new NotificationMessageManager(); - protected internal Subject gameLaunched = new(); - protected internal IObservable GameLaunched => gameLaunched; + protected internal readonly Subject _gameLaunched = new(); public MainWindowViewModel() { Router.Navigate.Execute(new LoginPageViewModel(this, OnClosed)); } + + public INotificationMessageManager Manager { get; } = new NotificationMessageManager(); + protected internal IObservable GameLaunched => _gameLaunched; + public RoutingState Router { get; } = new(); } diff --git a/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs index acd9def..740f2d1 100644 --- a/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/LoginPageViewModel.cs @@ -19,14 +19,45 @@ namespace Gml.Launcher.ViewModels.Pages; public class LoginPageViewModel : PageViewModelBase { - private string _login = string.Empty; - private bool _isProcessing = false; - private string _password = string.Empty; - private readonly MainWindowViewModel _screen; + private readonly IGmlClientManager _gmlClientManager; private readonly IObservable _onClosed; + private readonly MainWindowViewModel _screen; private readonly IStorageService _storageService; - private readonly IGmlClientManager _gmlClientManager; private readonly ISystemService _systemService; + private ObservableCollection _errorList = new(); + private bool _isProcessing; + private string _login = string.Empty; + private string _password = string.Empty; + + + internal LoginPageViewModel(IScreen screen, + IObservable onClosed, + IGmlClientManager? gmlClientManager = null, + IStorageService? storageService = null, + ISystemService? systemService = null, + ILocalizationService? localizationService = null) : base(screen, localizationService) + { + _screen = (MainWindowViewModel)screen; + _onClosed = onClosed; + + _storageService = storageService + ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(IStorageService)); + + _systemService = systemService + ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(IStorageService)); + + _gmlClientManager = gmlClientManager + ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); + + _screen.OnClosed.Subscribe(DisposeConnections); + + LoginCommand = ReactiveCommand.CreateFromTask(OnAuth); + + RxApp.MainThreadScheduler.Schedule(CheckAuth); + } public string Login { @@ -53,45 +84,14 @@ public bool IsProcessing public ObservableCollection Errors { - get => _errors; - set => this.RaiseAndSetIfChanged(ref _errors, value); + get => _errorList; + set => this.RaiseAndSetIfChanged(ref _errorList, value); } public bool IsNotProcessing => !_isProcessing; - public ObservableCollection _errors = new(); public ICommand LoginCommand { get; set; } - - internal LoginPageViewModel(IScreen screen, - IObservable onClosed, - IGmlClientManager? gmlClientManager = null, - IStorageService? storageService = null, - ISystemService? systemService = null, - ILocalizationService? localizationService = null) : base(screen, localizationService) - { - _screen = (MainWindowViewModel)screen; - _onClosed = onClosed; - - _storageService = storageService - ?? Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(IStorageService)); - - _systemService = systemService - ?? Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(IStorageService)); - - _gmlClientManager = gmlClientManager - ?? Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); - - _screen.OnClosed.Subscribe(DisposeConnections); - - LoginCommand = ReactiveCommand.CreateFromTask(OnAuth); - - RxApp.MainThreadScheduler.Schedule(CheckAuth); - } - private void DisposeConnections(bool isClosed) { _gmlClientManager.Dispose(); @@ -134,16 +134,12 @@ private async Task OnAuth(CancellationToken arg) } if (authInfo.Item1.Has2Fa) - { //ToDo: Next versions - return; - } - if (_screen is MainWindowViewModel mainView) + if (_screen is { } mainView) { if (!authInfo.Details.Any()) - { mainView.Manager .CreateMessage(true, "#D03E3E", LocalizationService.GetString(ResourceKeysDictionary.InvalidAuthData), @@ -151,7 +147,6 @@ private async Task OnAuth(CancellationToken arg) .Dismiss() .WithDelay(TimeSpan.FromSeconds(3)) .Queue(); - } Errors = new ObservableCollection(authInfo.Details); } diff --git a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs index 5619cde..007ea90 100644 --- a/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/OverviewPageViewModel.cs @@ -32,36 +32,16 @@ namespace Gml.Launcher.ViewModels.Pages; public class OverviewPageViewModel : PageViewModelBase { - private readonly IStorageService _storageService; - private readonly IGmlClientManager _gmlManager; - private readonly IUser _user; - private readonly IObservable _onClosed; - private readonly ISystemService _systemService; private readonly IDisposable? _closeEvent; - private readonly IDisposable? _maxCountLoaded; + private readonly IGmlClientManager _gmlManager; private readonly IDisposable? _loadedLoaded; + private readonly MainWindowViewModel _mainViewModel; + private readonly IDisposable? _maxCountLoaded; + private readonly IObservable _onClosed; private readonly IDisposable _profileNameChanged; + private readonly IStorageService _storageService; + private readonly ISystemService _systemService; private Process? _gameProcess; - private readonly MainWindowViewModel _mainViewModel; - public new string Title => LocalizationService.GetString(ResourceKeysDictionary.MainPageTitle); - - public ICommand GoProfileCommand { get; set; } - public ICommand LogoutCommand { get; set; } - public ICommand PlayCommand { get; set; } - public ICommand GoSettingsCommand { get; set; } - public ICommand HomeCommand { get; set; } - public ListViewModel ListViewModel { get; } = new(); - public IUser User => _user; - - [Reactive] public int? LoadingPercentage { get; set; } - [Reactive] public int? MaxCount { get; set; } - [Reactive] public int? LoadedCount { get; set; } - - [Reactive] public string? Headline { get; set; } - - [Reactive] public string? Description { get; set; } - - [Reactive] public bool IsProcessing { get; set; } internal OverviewPageViewModel(IScreen screen, IUser user, @@ -71,7 +51,7 @@ internal OverviewPageViewModel(IScreen screen, IStorageService? storageService = null) : base(screen) { _mainViewModel = screen as MainWindowViewModel ?? throw new Exception("Not valid screen"); - _user = user; + User = user; _onClosed = onClosed; _systemService = systemService ?? Locator.Current.GetService() @@ -82,11 +62,11 @@ internal OverviewPageViewModel(IScreen screen, ?? throw new ServiceNotFoundException(typeof(IStorageService)); _gmlManager = gmlManager - ?? Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); + ?? Locator.Current.GetService() + ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); GoProfileCommand = ReactiveCommand.CreateFromObservable( - () => screen.Router.Navigate.Execute(new ProfilePageViewModel(screen, _user, gmlManager)) + () => screen.Router.Navigate.Execute(new ProfilePageViewModel(screen, User)) ); GoSettingsCommand = ReactiveCommand.CreateFromObservable( @@ -95,6 +75,7 @@ internal OverviewPageViewModel(IScreen screen, LocalizationService, _storageService, _systemService, + _gmlManager, ListViewModel.SelectedProfile!)) ); @@ -106,7 +87,7 @@ internal OverviewPageViewModel(IScreen screen, LoadingPercentage = percentage; }); - _gmlManager.ProfilesChanges.Subscribe(async eventInfo => await LoadProfiles()); + _gmlManager.ProfilesChanges.Subscribe(LoadProfilesAsync); _closeEvent ??= onClosed.Subscribe(_ => _gameProcess?.Kill()); _profileNameChanged ??= ListViewModel.ProfileChanged.Subscribe(SaveSelectedServer); @@ -120,11 +101,39 @@ internal OverviewPageViewModel(IScreen screen, RxApp.MainThreadScheduler.Schedule(LoadData); } + public new string Title => LocalizationService.GetString(ResourceKeysDictionary.MainPageTitle); + + public ICommand GoProfileCommand { get; set; } + public ICommand LogoutCommand { get; set; } + public ICommand PlayCommand { get; set; } + public ICommand GoSettingsCommand { get; set; } + public ICommand HomeCommand { get; set; } + public ListViewModel ListViewModel { get; } = new(); + public IUser User { get; } + + [Reactive] public int? LoadingPercentage { get; set; } + [Reactive] public int? MaxCount { get; set; } + [Reactive] public int? LoadedCount { get; set; } + + [Reactive] public string? Headline { get; set; } + + [Reactive] public string? Description { get; set; } + + [Reactive] public bool IsProcessing { get; set; } + + private async void LoadProfilesAsync(bool eventInfo) + { + await LoadProfiles(); + } + private void ChangeLoadProcessDescription(int count) { LoadedCount = count; - Description = $"{LocalizationService.GetString(ResourceKeysDictionary.Stay)}: {MaxCount - LoadedCount}"; + Description = + $"{LocalizationService.GetString(ResourceKeysDictionary.Stay)}: " + + $"{MaxCount - LoadedCount} " + + $"{LocalizationService.GetString(ResourceKeysDictionary.Files)}"; } private async void SaveSelectedServer(ProfileReadDto? profile) @@ -141,7 +150,6 @@ private async Task OnLogout(CancellationToken arg) private async Task StartGame(CancellationToken cancellationToken) { - await ExecuteFromNewThread(async () => { try @@ -154,7 +162,7 @@ await ExecuteFromNewThread(async () => _gameProcess = await GenerateProcess(cancellationToken, profileInfo); _gameProcess.Start(); await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); - Dispatcher.UIThread.Invoke(() => _mainViewModel.gameLaunched.OnNext(true)); + Dispatcher.UIThread.Invoke(() => _mainViewModel._gameLaunched.OnNext(true)); UpdateProgress(string.Empty, string.Empty, false); await _gameProcess.WaitForExitAsync(cancellationToken); } @@ -165,7 +173,8 @@ await ExecuteFromNewThread(async () => } catch (FileNotFoundException exception) { - ShowError(ResourceKeysDictionary.Error, LocalizationService.GetString(ResourceKeysDictionary.JavaNotFound)); + ShowError(ResourceKeysDictionary.Error, + LocalizationService.GetString(ResourceKeysDictionary.JavaNotFound)); Console.WriteLine(exception); } @@ -177,17 +186,16 @@ await ExecuteFromNewThread(async () => } finally { - Dispatcher.UIThread.Invoke(() => _mainViewModel.gameLaunched.OnNext(false)); + Dispatcher.UIThread.Invoke(() => _mainViewModel._gameLaunched.OnNext(false)); UpdateProgress(string.Empty, string.Empty, false); - await _gmlManager.UpdateDiscordRpcState(LocalizationService.GetString(ResourceKeysDictionary.DefaultDRpcText)); + await _gmlManager.UpdateDiscordRpcState( + LocalizationService.GetString(ResourceKeysDictionary.DefaultDRpcText)); } }); - - - } - private async Task GenerateProcess(CancellationToken cancellationToken, ResponseMessage profileInfo) + private async Task GenerateProcess(CancellationToken cancellationToken, + ResponseMessage profileInfo) { UpdateProgress( LocalizationService.GetString(ResourceKeysDictionary.Updating), @@ -195,9 +203,7 @@ private async Task GenerateProcess(CancellationToken cancellationToken, true); if (profileInfo.Data is null) - { throw new Exception(LocalizationService.GetString(ResourceKeysDictionary.ProfileNotConfigured)); - } await _gmlManager.DownloadNotInstalledFiles(profileInfo.Data, cancellationToken); @@ -220,7 +226,8 @@ private async Task GenerateProcess(CancellationToken cancellationToken, LocalizationService.GetString(ResourceKeysDictionary.UpdatingDescription), true); - await _gmlManager.UpdateDiscordRpcState($"{LocalizationService.GetString(ResourceKeysDictionary.PlayDRpcText)} \"{ListViewModel.SelectedProfile!.Name}\""); + await _gmlManager.UpdateDiscordRpcState( + $"{LocalizationService.GetString(ResourceKeysDictionary.PlayDRpcText)} \"{ListViewModel.SelectedProfile!.Name}\""); var settings = await _storageService.GetAsync(StorageConstants.Settings) ?? SettingsInfo.Default; @@ -257,8 +264,8 @@ private async void LoadData() await LoadProfiles(); await _gmlManager.LoadDiscordRpc(); - await _gmlManager.UpdateDiscordRpcState(LocalizationService.GetString(ResourceKeysDictionary.DefaultDRpcText)); - + await _gmlManager.UpdateDiscordRpcState( + LocalizationService.GetString(ResourceKeysDictionary.DefaultDRpcText)); } catch (TaskCanceledException exception) { @@ -287,12 +294,9 @@ private async Task LoadProfiles() if (!string.IsNullOrEmpty(lastSelectedProfileName) && ListViewModel.Profiles.FirstOrDefault(c => c.Name == lastSelectedProfileName) is { } profile) - { ListViewModel.SelectedProfile = profile; - } ListViewModel.SelectedProfile ??= ListViewModel.Profiles.FirstOrDefault(); - } private async Task Reconnect() diff --git a/src/Gml.Launcher/ViewModels/Pages/ProfilePageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/ProfilePageViewModel.cs index b9802ff..47483e7 100644 --- a/src/Gml.Launcher/ViewModels/Pages/ProfilePageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/ProfilePageViewModel.cs @@ -1,52 +1,36 @@ -using System.Reactive.Concurrency; -using Gml.Client; +using System; +using System.Reactive.Concurrency; using Gml.Client.Models; using Gml.Launcher.Assets; -using Gml.Launcher.Core.Exceptions; using Gml.Launcher.Core.Services; using Gml.Launcher.ViewModels.Base; using ReactiveUI; -using Sentry; -using Splat; namespace Gml.Launcher.ViewModels.Pages; public class ProfilePageViewModel : PageViewModelBase { private IUser _user; - private readonly IGmlClientManager _clientManager; - private readonly IStorageService _storageService; - public new string Title => LocalizationService.GetString(ResourceKeysDictionary.MainPageTitle); - - public IUser User - { - get => _user; - private init => this.RaiseAndSetIfChanged(ref _user, value); - } - - internal ProfilePageViewModel(IScreen screen, IUser user, - IGmlClientManager? clientManager = null, - IStorageService? storageService = null, ILocalizationService? localizationService = null) : base(screen, localizationService) { - User = user; - _clientManager = clientManager - ?? Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(IGmlClientManager)); - - _storageService = storageService - ?? Locator.Current.GetService() - ?? throw new ServiceNotFoundException(typeof(IStorageService)); + _user = user ?? throw new ArgumentNullException(nameof(user)); RxApp.MainThreadScheduler.Schedule(LoadData); + } + + public new string Title => LocalizationService.GetString(ResourceKeysDictionary.MainPageTitle); + public IUser User + { + get => _user; + set => this.RaiseAndSetIfChanged(ref _user, value); } - private async void LoadData() + private void LoadData() { // string logs = await _storageService.GetLogsAsync(1500); // diff --git a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs index 23aba3f..b6425fc 100644 --- a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs @@ -5,6 +5,8 @@ using System.Reactive.Concurrency; using System.Reactive.Linq; using System.Threading; +using System.Windows.Input; +using Gml.Client; using Gml.Launcher.Core.Services; using Gml.Launcher.Models; using Gml.Launcher.ViewModels.Base; @@ -16,19 +18,70 @@ namespace Gml.Launcher.ViewModels.Pages; public class SettingsPageViewModel : PageViewModelBase { + private readonly IGmlClientManager _gmlManager; private readonly IStorageService _storageService; + private double _ramValue; + private int _windowHeight; - [Reactive] - public bool DynamicRamValue { get; set; } + private int _windowWidth; - [Reactive] - public bool FullScreen { get; set; } + public SettingsPageViewModel( + IScreen screen, + ILocalizationService? localizationService, + IStorageService storageService, + ISystemService systemService, + IGmlClientManager gmlManager, + ProfileReadDto selectedProfile) : base(screen, localizationService) + { + _storageService = storageService; + _gmlManager = gmlManager; - [Reactive] - public ulong MaxRamValue { get; set; } + this.WhenAnyValue( + x => x.RamValue, + x => x.WindowWidth, + x => x.WindowHeight, + x => x.FullScreen, + x => x.DynamicRamValue, + x => x.SelectedLanguage + ) + .Throttle(TimeSpan.FromMilliseconds(400)) + .ObserveOn(RxApp.MainThreadScheduler) + .Subscribe(SaveSettings); - [Reactive] - public Language? SelectedLanguage { get; set; } + this.WhenAnyValue(x => x.SelectedLanguage) + .Skip(2) + .Subscribe(language => + { + if (language == null) return; + + Thread.CurrentThread.CurrentCulture = language.Culture; + Thread.CurrentThread.CurrentCulture.ClearCachedData(); + + GoBackCommand.Execute(Unit.Default); + }); + + ChangeInstallationDirectory = ReactiveCommand.Create(ChangeFolder); + + AvailableLanguages = new ObservableCollection(systemService.GetAvailableLanguages()); + + MaxRamValue = systemService.GetMaxRam(); + + InstallationFolder = _gmlManager.InstallationDirectory; + + RxApp.MainThreadScheduler.Schedule(LoadSettings); + } + + [Reactive] public bool DynamicRamValue { get; set; } + + [Reactive] public bool FullScreen { get; set; } + + [Reactive] public ulong MaxRamValue { get; set; } + + [Reactive] public Language? SelectedLanguage { get; set; } + + [Reactive] public string? InstallationFolder { get; set; } + + public ICommand ChangeInstallationDirectory { get; } public double RamValue @@ -48,15 +101,11 @@ public string WindowWidth get => _windowWidth.ToString(); set { - var isNumeric = int.TryParse(string.Concat(value.Where(char.IsDigit)), out int numericValue); + var isNumeric = int.TryParse(string.Concat(value.Where(char.IsDigit)), out var numericValue); if (isNumeric) - { this.RaiseAndSetIfChanged(ref _windowWidth, numericValue); - } else - { this.RaiseAndSetIfChanged(ref _windowWidth, default); - } } } @@ -65,63 +114,22 @@ public string WindowHeight get => _windowHeight.ToString(); set { - var isNumeric = int.TryParse(string.Concat(value.Where(char.IsDigit)), out int numericValue); + var isNumeric = int.TryParse(string.Concat(value.Where(char.IsDigit)), out var numericValue); if (isNumeric) - { this.RaiseAndSetIfChanged(ref _windowHeight, numericValue); - } else - { this.RaiseAndSetIfChanged(ref _windowWidth, default); - } } } public ObservableCollection AvailableLanguages { get; } - private int _windowWidth; - private int _windowHeight; - private double _ramValue; - - public SettingsPageViewModel( - IScreen screen, - ILocalizationService? localizationService, - IStorageService storageService, - ISystemService systemService, - ProfileReadDto selectedProfile) : base(screen, localizationService) + internal void ChangeFolder() { - _storageService = storageService; - - this.WhenAnyValue( - x => x.RamValue, - x => x.WindowWidth, - x => x.WindowHeight, - x => x.FullScreen, - x => x.DynamicRamValue, - x => x.SelectedLanguage - ) - .Throttle(TimeSpan.FromMilliseconds(400)) - .ObserveOn(RxApp.MainThreadScheduler) - .Subscribe(SaveSettings); - - this.WhenAnyValue(x => x.SelectedLanguage) - .Skip(2) - .Subscribe(language => - { - if (language == null) return; - - Thread.CurrentThread.CurrentCulture = language.Culture; - Thread.CurrentThread.CurrentCulture.ClearCachedData(); - - GoBackCommand.Execute(Unit.Default); - }); - - - AvailableLanguages = new ObservableCollection(systemService.GetAvailableLanguages()); - - MaxRamValue = systemService.GetMaxRam(); + if (InstallationFolder != null) + _gmlManager.ChangeInstallationFolder(InstallationFolder); - RxApp.MainThreadScheduler.Schedule(LoadSettings); + _storageService.SetAsync(StorageConstants.InstallationDirectory, InstallationFolder); } private double RoundToNearest(double value, double step) @@ -138,14 +146,9 @@ private async void LoadSettings() if (data == null) return; - if (!string.IsNullOrEmpty(data.LanguageCode)) - { - SelectedLanguage = AvailableLanguages.FirstOrDefault(c => c.Culture.Name == data.LanguageCode); - } - else - { - SelectedLanguage = AvailableLanguages.FirstOrDefault(); - } + SelectedLanguage = !string.IsNullOrEmpty(data.LanguageCode) + ? AvailableLanguages.FirstOrDefault(c => c.Culture.Name == data.LanguageCode) + : AvailableLanguages.FirstOrDefault(); WindowWidth = data.GameWidth == 0 ? "900" : data.GameWidth.ToString(); WindowHeight = data.GameHeight == 0 ? "600" : data.GameHeight.ToString(); @@ -155,7 +158,8 @@ private async void LoadSettings() } private void SaveSettings( - (double ramValue, string width, string height, bool isFullScreen, bool isDynamicRam, Language? selectedLanguage) update) + (double ramValue, string width, string height, bool isFullScreen, bool isDynamicRam, Language? selectedLanguage) + update) { _storageService.SetAsync( StorageConstants.Settings, diff --git a/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs b/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs index 7a80094..ad7c28d 100644 --- a/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs +++ b/src/Gml.Launcher/ViewModels/SplashScreenViewModel.cs @@ -4,33 +4,26 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; -using Avalonia.Controls.Shapes; using Gml.Client; using Gml.Launcher.Assets; using Gml.Launcher.Core.Exceptions; using Gml.Launcher.Core.Services; using Gml.Launcher.ViewModels.Base; using Gml.Web.Api.Domains.System; -using GmlCore.Interfaces; using GmlCore.Interfaces.Storage; -using ReactiveUI; using ReactiveUI.Fody.Helpers; using Splat; -using Path = Avalonia.Controls.Shapes.Path; namespace Gml.Launcher.ViewModels; public class SplashScreenViewModel : WindowViewModelBase { - private readonly ISystemService _systemService; - private readonly IGmlClientManager _manager; private readonly ILocalizationService _localizationService; + private readonly IGmlClientManager _manager; + private readonly ISystemService _systemService; - [Reactive] public string StatusText { get; set; } - [Reactive] public bool InfinityLoading { get; set; } = true; - [Reactive] public Int16 Progress { get; set; } - - public SplashScreenViewModel(ISystemService? systemService = null, IGmlClientManager? manager = null, ILocalizationService? localizationService = null) + public SplashScreenViewModel(ISystemService? systemService = null, IGmlClientManager? manager = null, + ILocalizationService? localizationService = null) { _systemService = systemService ?? Locator.Current.GetService() ?? throw new ServiceNotFoundException(typeof(ISystemService)); @@ -44,6 +37,10 @@ public SplashScreenViewModel(ISystemService? systemService = null, IGmlClientMan StatusText = _localizationService.GetString(ResourceKeysDictionary.PreparingLaunch); } + [Reactive] public string StatusText { get; set; } + [Reactive] public bool InfinityLoading { get; set; } = true; + [Reactive] public short Progress { get; set; } + public async Task InitializeAsync() { var osType = _systemService.GetOsType(); @@ -58,13 +55,13 @@ public async Task InitializeAsync() { ChangeState(_localizationService.GetString(ResourceKeysDictionary.InstallingUpdates), false); - string exePath = Process.GetCurrentProcess().MainModule?.FileName - ?? throw new Exception(ResourceKeysDictionary.FailedOs); + var exePath = Process.GetCurrentProcess().MainModule?.FileName + ?? throw new Exception(ResourceKeysDictionary.FailedOs); var process = _manager.ProgressChanged.Subscribe( percentage => Progress = Convert.ToInt16(percentage)); - await _manager.UpdateCurrentLauncher(versionInfo, osType, System.IO.Path.GetFileName(exePath)); + await _manager.UpdateCurrentLauncher(versionInfo, osType, Path.GetFileName(exePath)); process.Dispose(); } @@ -75,10 +72,7 @@ public async Task InitializeAsync() { var actualVersion = await _manager.GetActualVersion(osType, osArch); - if (actualVersion is null) - { - return (null, true); - } + if (actualVersion is null) return (null, true); var version = Assembly.GetExecutingAssembly().GetName().Version ?? new Version(1, 0, 0, 0); diff --git a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml index dcab09b..f26726d 100644 --- a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml +++ b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml @@ -19,9 +19,8 @@ + SourceStream="{TemplateBinding SourceStream}" /> - diff --git a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs index ea1db3b..27bf622 100644 --- a/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/BackgroundComponent.axaml.cs @@ -7,22 +7,23 @@ namespace Gml.Launcher.Views.Components; public class BackgroundComponent : TemplatedControl { + public static readonly StyledProperty SourceProperty = + AvaloniaProperty.Register( + nameof(Source)); - public static readonly StyledProperty SourceProperty = AvaloniaProperty.Register( - nameof(Source)); - - public static readonly StyledProperty SourceStreamProperty = AvaloniaProperty.Register( - nameof(SourceStream)); + public static readonly StyledProperty SourceStreamProperty = + AvaloniaProperty.Register( + nameof(SourceStream)); public IImage? Source { get => GetValue(SourceProperty); set => SetValue(SourceProperty, value); } + public Stream? SourceStream { get => GetValue(SourceStreamProperty); set => SetValue(SourceStreamProperty, value); } } - diff --git a/src/Gml.Launcher/Views/Components/BadgeComponent.axaml b/src/Gml.Launcher/Views/Components/BadgeComponent.axaml index 8a88213..d79bee1 100644 --- a/src/Gml.Launcher/Views/Components/BadgeComponent.axaml +++ b/src/Gml.Launcher/Views/Components/BadgeComponent.axaml @@ -9,11 +9,11 @@ - diff --git a/src/Gml.Launcher/Views/Components/BadgeComponent.axaml.cs b/src/Gml.Launcher/Views/Components/BadgeComponent.axaml.cs index 0fcc0a8..b8df275 100644 --- a/src/Gml.Launcher/Views/Components/BadgeComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/BadgeComponent.axaml.cs @@ -1,12 +1,10 @@ using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.Primitives; namespace Gml.Launcher.Views.Components; public class BadgeComponent : TemplatedControl { - public static readonly StyledProperty TextProperty = AvaloniaProperty.Register( nameof(Text), "Badge"); @@ -16,4 +14,3 @@ public string Text set => SetValue(TextProperty, value); } } - diff --git a/src/Gml.Launcher/Views/Components/GmlButton.axaml b/src/Gml.Launcher/Views/Components/GmlButton.axaml index cb2becc..bcec941 100644 --- a/src/Gml.Launcher/Views/Components/GmlButton.axaml +++ b/src/Gml.Launcher/Views/Components/GmlButton.axaml @@ -62,7 +62,8 @@ - diff --git a/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs b/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs index 0afc7e4..a7d267a 100644 --- a/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs +++ b/src/Gml.Launcher/Views/Components/GmlButton.axaml.cs @@ -1,12 +1,18 @@ -using System.Windows.Input; +using System; +using System.Linq; +using System.Windows.Input; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; +using Avalonia.Interactivity; namespace Gml.Launcher.Views.Components; public class GmlButton : TemplatedControl { + public static readonly RoutedEvent ClickEvent = + RoutedEvent.Register(nameof(Click), RoutingStrategies.Bubble); public static readonly StyledProperty IconPathProperty = AvaloniaProperty.Register( nameof(IconPath), "/Assets/Images/profile.svg"); @@ -26,8 +32,9 @@ public class GmlButton : TemplatedControl public static readonly StyledProperty IsDefaultProperty = AvaloniaProperty.Register( nameof(IsDefault)); - public static readonly StyledProperty CommandParameterProperty = AvaloniaProperty.Register( - nameof(CommandParameter)); + public static readonly StyledProperty CommandParameterProperty = + AvaloniaProperty.Register( + nameof(CommandParameter)); public object? CommandParameter { @@ -71,5 +78,21 @@ public string IconPath set => SetValue(IconPathProperty, value); } -} + public event EventHandler? Click + { + add => AddHandler(ClickEvent, value); + remove => RemoveHandler(ClickEvent, value); + } + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + + if (this.GetTemplateChildren().First() is Button button) + button.Click += (sender, args) => + { + RaiseEvent(new RoutedEventArgs(ClickEvent)); + Command?.Execute(CommandParameter); + }; + } +} diff --git a/src/Gml.Launcher/Views/Components/LoadingControl.axaml b/src/Gml.Launcher/Views/Components/LoadingControl.axaml index e1d6e8b..c89413c 100644 --- a/src/Gml.Launcher/Views/Components/LoadingControl.axaml +++ b/src/Gml.Launcher/Views/Components/LoadingControl.axaml @@ -9,18 +9,18 @@ - + - + - diff --git a/src/Gml.Launcher/Views/Components/LoadingControl.axaml.cs b/src/Gml.Launcher/Views/Components/LoadingControl.axaml.cs index 868743b..1b1e183 100644 --- a/src/Gml.Launcher/Views/Components/LoadingControl.axaml.cs +++ b/src/Gml.Launcher/Views/Components/LoadingControl.axaml.cs @@ -1,12 +1,10 @@ using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.Primitives; namespace Gml.Launcher.Views.Components; public class LoadingControl : TemplatedControl { - public static readonly StyledProperty SizeProperty = AvaloniaProperty.Register( nameof(Size), 16); @@ -15,6 +13,4 @@ public double Size get => GetValue(SizeProperty); set => SetValue(SizeProperty, value); } - } - diff --git a/src/Gml.Launcher/Views/Components/LogoComponent.axaml b/src/Gml.Launcher/Views/Components/LogoComponent.axaml index 2fca82d..a7e8ba0 100644 --- a/src/Gml.Launcher/Views/Components/LogoComponent.axaml +++ b/src/Gml.Launcher/Views/Components/LogoComponent.axaml @@ -17,7 +17,7 @@ + Height="{TemplateBinding Size}" /> @@ -30,15 +30,14 @@ Spacing="15"> + Height="{TemplateBinding Size}" /> + Foreground="{StaticResource HeadlineColor}" /> - diff --git a/src/Gml.Launcher/Views/Components/LogoComponent.axaml.cs b/src/Gml.Launcher/Views/Components/LogoComponent.axaml.cs index f09950b..262f87e 100644 --- a/src/Gml.Launcher/Views/Components/LogoComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/LogoComponent.axaml.cs @@ -1,12 +1,10 @@ using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.Primitives; namespace Gml.Launcher.Views.Components; public class LogoComponent : TemplatedControl { - public static readonly StyledProperty SizeProperty = AvaloniaProperty.Register( nameof(Size), 32); @@ -15,6 +13,4 @@ public double Size get => GetValue(SizeProperty); set => SetValue(SizeProperty, value); } - } - diff --git a/src/Gml.Launcher/Views/Components/OnlineComponent.axaml.cs b/src/Gml.Launcher/Views/Components/OnlineComponent.axaml.cs index 662365f..abd3efd 100644 --- a/src/Gml.Launcher/Views/Components/OnlineComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/OnlineComponent.axaml.cs @@ -1,5 +1,4 @@ using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.Primitives; namespace Gml.Launcher.Views.Components; @@ -15,4 +14,3 @@ public string Online set => SetValue(OnlineProperty, value); } } - diff --git a/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml b/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml index 2747625..27acb90 100644 --- a/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml +++ b/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml @@ -32,7 +32,7 @@ StrokeJoin="Round" StrokeLineCap="Round" StrokeThickness="1" - Stroke="{DynamicResource FormBorderColor}"/> + Stroke="{DynamicResource FormBorderColor}" /> @@ -42,4 +42,3 @@ - diff --git a/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml.cs b/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml.cs index 51b30af..4bd8b34 100644 --- a/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/ProfileInfoComponent.axaml.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.Primitives; using Gml.Launcher.Models; diff --git a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml index 686b388..727a05c 100644 --- a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml +++ b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml @@ -1,9 +1,6 @@  + Size="45" /> - + diff --git a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs index b48d35b..b5bafe7 100644 --- a/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs +++ b/src/Gml.Launcher/Views/Components/ProfileUserControl.axaml.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; using Gml.Launcher.Models; namespace Gml.Launcher.Views.Components; diff --git a/src/Gml.Launcher/Views/Components/ProgressBar.axaml b/src/Gml.Launcher/Views/Components/ProgressBar.axaml index b740ca6..6a53083 100644 --- a/src/Gml.Launcher/Views/Components/ProgressBar.axaml +++ b/src/Gml.Launcher/Views/Components/ProgressBar.axaml @@ -43,14 +43,14 @@ Background="Transparent" Foreground="{DynamicResource PrimaryColor}" Margin="8" - Size="28"/> + Size="28" /> + Foreground="{DynamicResource PrimaryColor}" /> PercentageProperty = AvaloniaProperty.Register( nameof(Percentage), "50"); @@ -33,6 +31,4 @@ public string Percentage get => GetValue(PercentageProperty); set => SetValue(PercentageProperty, value); } - } - diff --git a/src/Gml.Launcher/Views/Components/ServerInfo.axaml b/src/Gml.Launcher/Views/Components/ServerInfo.axaml index dcea920..0f14354 100644 --- a/src/Gml.Launcher/Views/Components/ServerInfo.axaml +++ b/src/Gml.Launcher/Views/Components/ServerInfo.axaml @@ -10,11 +10,11 @@ - diff --git a/src/Gml.Launcher/Views/Components/ServerInfo.axaml.cs b/src/Gml.Launcher/Views/Components/ServerInfo.axaml.cs index 04e777f..67ddf0a 100644 --- a/src/Gml.Launcher/Views/Components/ServerInfo.axaml.cs +++ b/src/Gml.Launcher/Views/Components/ServerInfo.axaml.cs @@ -1,13 +1,11 @@ using System.Windows.Input; using Avalonia; -using Avalonia.Controls; using Avalonia.Controls.Primitives; namespace Gml.Launcher.Views.Components; public class ServerInfo : TemplatedControl { - public static readonly StyledProperty ProfileNameProperty = AvaloniaProperty.Register( nameof(ProfileName), "Techno Magic"); @@ -17,14 +15,17 @@ public class ServerInfo : TemplatedControl public static readonly StyledProperty SpacingProperty = AvaloniaProperty.Register( nameof(Spacing)); - public static readonly StyledProperty PlayCommandProperty = AvaloniaProperty.Register( - nameof(PlayCommand)); + public static readonly StyledProperty PlayCommandProperty = + AvaloniaProperty.Register( + nameof(PlayCommand)); - public static readonly StyledProperty SettingsCommandProperty = AvaloniaProperty.Register( - nameof(SettingsCommand)); + public static readonly StyledProperty SettingsCommandProperty = + AvaloniaProperty.Register( + nameof(SettingsCommand)); - public static readonly StyledProperty ProfileDescriptionProperty = AvaloniaProperty.Register( - nameof(ProfileDescription)); + public static readonly StyledProperty ProfileDescriptionProperty = + AvaloniaProperty.Register( + nameof(ProfileDescription)); public string ProfileDescription { @@ -61,6 +62,4 @@ public string ProfileName get => GetValue(ProfileNameProperty); set => SetValue(ProfileNameProperty, value); } - } - diff --git a/src/Gml.Launcher/Views/Components/ServerListComponent.axaml b/src/Gml.Launcher/Views/Components/ServerListComponent.axaml index c8c0f80..bacca1b 100644 --- a/src/Gml.Launcher/Views/Components/ServerListComponent.axaml +++ b/src/Gml.Launcher/Views/Components/ServerListComponent.axaml @@ -10,49 +10,48 @@ mc:Ignorable="d" d:DesignWidth="80" d:DesignHeight="350" x:Class="Gml.Launcher.Views.Components.ServerListComponent"> + HorizontalAlignment="Center" + ClipToBounds="True" + MaxHeight="350" + Padding="5" + CornerRadius="50"> - - + + - + - - - - - + + + + + - - - - - - - - + + + + + + + + - diff --git a/src/Gml.Launcher/Views/Components/ServerListComponent.axaml.cs b/src/Gml.Launcher/Views/Components/ServerListComponent.axaml.cs index 9207fa8..257848d 100644 --- a/src/Gml.Launcher/Views/Components/ServerListComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/ServerListComponent.axaml.cs @@ -1,6 +1,4 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; +using Avalonia.Controls; namespace Gml.Launcher.Views.Components; @@ -11,4 +9,3 @@ public ServerListComponent() InitializeComponent(); } } - diff --git a/src/Gml.Launcher/Views/Components/SidebarComponent.axaml.cs b/src/Gml.Launcher/Views/Components/SidebarComponent.axaml.cs index 4a6578c..500860d 100644 --- a/src/Gml.Launcher/Views/Components/SidebarComponent.axaml.cs +++ b/src/Gml.Launcher/Views/Components/SidebarComponent.axaml.cs @@ -7,18 +7,21 @@ namespace Gml.Launcher.Views.Components; public class SidebarComponent : TemplatedControl { + public static readonly StyledProperty ProfileCommandProperty = + AvaloniaProperty.Register( + nameof(ProfileCommand)); - public static readonly StyledProperty ProfileCommandProperty = AvaloniaProperty.Register( - nameof(ProfileCommand)); + public static readonly StyledProperty LogoutCommandProperty = + AvaloniaProperty.Register( + nameof(LogoutCommand)); - public static readonly StyledProperty LogoutCommandProperty = AvaloniaProperty.Register( - nameof(LogoutCommand)); + public static readonly StyledProperty ListViewModelProperty = + AvaloniaProperty.Register( + nameof(ListViewModel)); - public static readonly StyledProperty ListViewModelProperty = AvaloniaProperty.Register( - nameof(ListViewModel)); - - public static readonly StyledProperty HomeCommandProperty = AvaloniaProperty.Register( - nameof(HomeCommand)); + public static readonly StyledProperty HomeCommandProperty = + AvaloniaProperty.Register( + nameof(HomeCommand)); public ICommand HomeCommand { @@ -43,6 +46,4 @@ public ICommand ProfileCommand get => GetValue(ProfileCommandProperty); set => SetValue(ProfileCommandProperty, value); } - } - diff --git a/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml b/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml index 440ea7f..1d62890 100644 --- a/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml +++ b/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml @@ -9,16 +9,16 @@ - diff --git a/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml.cs b/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml.cs index 43b8151..008070e 100644 --- a/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml.cs +++ b/src/Gml.Launcher/Views/Components/StackFrameBorder.axaml.cs @@ -1,13 +1,10 @@ using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Metadata; namespace Gml.Launcher.Views.Components; public class StackFrameBorder : ItemsControl { - public static readonly StyledProperty SpacingProperty = AvaloniaProperty.Register( nameof(Spacing)); @@ -16,6 +13,4 @@ public int Spacing get => GetValue(SpacingProperty); set => SetValue(SpacingProperty, value); } - } - diff --git a/src/Gml.Launcher/Views/MainWindow.axaml b/src/Gml.Launcher/Views/MainWindow.axaml index 44eb611..c391654 100644 --- a/src/Gml.Launcher/Views/MainWindow.axaml +++ b/src/Gml.Launcher/Views/MainWindow.axaml @@ -15,6 +15,7 @@ Height="600" MinHeight="600" CanResize="False" + Closed="WindowClosed" x:Class="Gml.Launcher.Views.MainWindow" x:DataType="vm:MainWindowViewModel" Background="Transparent" diff --git a/src/Gml.Launcher/Views/MainWindow.axaml.cs b/src/Gml.Launcher/Views/MainWindow.axaml.cs index d7c6b89..5c50066 100644 --- a/src/Gml.Launcher/Views/MainWindow.axaml.cs +++ b/src/Gml.Launcher/Views/MainWindow.axaml.cs @@ -1,7 +1,5 @@ using System; -using System.Reactive.Subjects; using Avalonia; -using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xaml; using Avalonia.ReactiveUI; @@ -14,14 +12,12 @@ public partial class MainWindow : ReactiveWindow { public MainWindow() { - this.WhenActivated(disposables => { }); + this.WhenActivated(_ => { }); AvaloniaXamlLoader.Load(this); #if DEBUG this.AttachDevTools(); #endif - - } protected override void OnDataContextChanged(EventArgs e) @@ -40,14 +36,24 @@ protected override void OnDataContextChanged(EventArgs e) protected override void OnClosed(EventArgs e) { - if(DataContext is MainWindowViewModel viewModel) - viewModel.OnClosed.OnNext(false); + SendCloseEvent(); base.OnClosed(e); } + private void SendCloseEvent() + { + if (DataContext is MainWindowViewModel viewModel) + viewModel.OnClosed.OnNext(false); + } + protected override void OnPointerPressed(PointerPressedEventArgs e) { BeginMoveDrag(e); } + + private void WindowClosed(object? sender, EventArgs e) + { + SendCloseEvent(); + } } diff --git a/src/Gml.Launcher/Views/Pages/LoginPageView.axaml b/src/Gml.Launcher/Views/Pages/LoginPageView.axaml index 02dddc6..843dbd6 100644 --- a/src/Gml.Launcher/Views/Pages/LoginPageView.axaml +++ b/src/Gml.Launcher/Views/Pages/LoginPageView.axaml @@ -5,7 +5,6 @@ xmlns:vm="clr-namespace:Gml.Launcher.ViewModels.Pages" xmlns:lang="clr-namespace:Gml.Launcher.Assets.Resources" xmlns:components="clr-namespace:Gml.Launcher.Views.Components" - xmlns:system="clr-namespace:System;assembly=System.Runtime" xmlns:converters="clr-namespace:Gml.Launcher.Core.Converters" mc:Ignorable="d" d:DesignWidth="800" @@ -49,7 +48,7 @@ + Margin="0, 0, 0, 20" /> + - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - + + - + diff --git a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs index 33a4d74..6631e18 100644 --- a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs +++ b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs @@ -1,9 +1,11 @@ using System.Linq; using Avalonia; using Avalonia.Controls; -using Avalonia.Input; +using Avalonia.Interactivity; using Avalonia.Markup.Xaml; +using Avalonia.Platform.Storage; using Avalonia.ReactiveUI; +using Avalonia.VisualTree; using Gml.Launcher.ViewModels.Pages; using ReactiveUI; @@ -24,10 +26,23 @@ private void OnTextInput(object sender, AvaloniaPropertyChangedEventArgs e) private void OnTextInput(object? sender, TextChangedEventArgs e) { - if (sender is TextBox textBox) + if (sender is TextBox textBox) textBox.Text = string.Concat(textBox.Text?.Where(char.IsDigit) ?? string.Empty); + } + + private async void OpenFileDialog(object? sender, RoutedEventArgs e) + { + if (this.GetVisualRoot() is MainWindow mainWindow) { - textBox.Text = string.Concat(textBox.Text?.Where(char.IsDigit) ?? string.Empty); - } + var folders = await mainWindow.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions + { + AllowMultiple = false, + Title = "Select a folder" + }); + + if (folders.Count != 1) return; + ViewModel!.InstallationFolder = folders[0].Path.AbsolutePath; + ViewModel!.ChangeFolder(); + } } } diff --git a/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml index 617d3f0..3432c23 100644 --- a/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml +++ b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml @@ -39,7 +39,7 @@ + Foreground="{DynamicResource ContentColor}" /> diff --git a/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs index e1bf1ca..2692191 100644 --- a/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs +++ b/src/Gml.Launcher/Views/SplashScreen/SplashScreen.axaml.cs @@ -1,6 +1,4 @@ -using Avalonia; using Avalonia.Controls; -using Avalonia.Markup.Xaml; using Gml.Launcher.ViewModels; namespace Gml.Launcher.Views.SplashScreen; @@ -16,7 +14,7 @@ public MainWindow GetMainWindow() { return new MainWindow { - DataContext = new MainWindowViewModel(), + DataContext = new MainWindowViewModel() }; } } diff --git a/src/Gml.Launcher/app.manifest b/src/Gml.Launcher/app.manifest index ed05310..132e5ed 100644 --- a/src/Gml.Launcher/app.manifest +++ b/src/Gml.Launcher/app.manifest @@ -1,18 +1,18 @@  - - + + - - - + + + - - - - + + + + From 31a86cda1c2e575aa82904ca86287c28f761b820 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 27 Jul 2024 14:47:20 +0300 Subject: [PATCH 60/63] Add new error message for folder change failures This commit adds an error message for unsuccessful attempts to change the installation folder. It updates resource files with the new error message and modifies relevant ViewModel and View files to handle and display the error appropriately. --- .../Resources/ResourceKeysDictionary.cs | 1 + .../Assets/Resources/Resources.Designer.cs | 8 +++++ .../Assets/Resources/Resources.en.resx | 3 ++ .../Assets/Resources/Resources.resx | 3 ++ .../Assets/Resources/Resources.ru.resx | 3 ++ .../ViewModels/Base/PageViewModelBase.cs | 2 +- .../ViewModels/Pages/SettingsPageViewModel.cs | 3 ++ .../Views/Pages/SettingsPageView.axaml | 6 ++-- .../Views/Pages/SettingsPageView.axaml.cs | 35 ++++++++++++++----- 9 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs index 205a9fe..e10bcee 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.cs @@ -5,6 +5,7 @@ public static class ResourceKeysDictionary public const string MainPageTitle = "DefaultPageTitle"; public const string DefaultPageTitle = "DefaultPageTitle"; public const string Error = "Error"; + public const string InvalidFolder = "InvalidFolder"; public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; public const string Stay = "Stay"; diff --git a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs index e1d057c..649e671 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs +++ b/src/Gml.Launcher/Assets/Resources/Resources.Designer.cs @@ -250,5 +250,13 @@ public static string Files { return ResourceManager.GetString("Files", resourceCulture); } } + /// + /// Ищет локализованную строку, похожую на ProfileNotConfigured. + /// + public static string InvalidFolder { + get { + return ResourceManager.GetString("InvalidFolder", resourceCulture); + } + } } } diff --git a/src/Gml.Launcher/Assets/Resources/Resources.en.resx b/src/Gml.Launcher/Assets/Resources/Resources.en.resx index 56b35fa..3441c25 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.en.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.en.resx @@ -132,4 +132,7 @@ files + + Failed to change the installation folder or an error occurred while changing the folder. + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.resx b/src/Gml.Launcher/Assets/Resources/Resources.resx index a220396..32ad5b3 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.resx @@ -140,4 +140,7 @@ files + + Failed to change the installation folder or an error occurred while changing the folder. + diff --git a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx index 5d9b71d..b1a4814 100644 --- a/src/Gml.Launcher/Assets/Resources/Resources.ru.resx +++ b/src/Gml.Launcher/Assets/Resources/Resources.ru.resx @@ -132,4 +132,7 @@ файлов + + Не получилось сменить папку установки или произошла ошибка при смене папки + diff --git a/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs b/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs index cf4ac7b..11d19be 100644 --- a/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs +++ b/src/Gml.Launcher/ViewModels/Base/PageViewModelBase.cs @@ -15,7 +15,7 @@ namespace Gml.Launcher.ViewModels.Base; public class PageViewModelBase : ViewModelBase, IRoutableViewModel { - protected readonly ILocalizationService LocalizationService; + internal readonly ILocalizationService LocalizationService; protected PageViewModelBase(IScreen screen, ILocalizationService? localizationService = null) { diff --git a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs index b6425fc..b7ce5e9 100644 --- a/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs +++ b/src/Gml.Launcher/ViewModels/Pages/SettingsPageViewModel.cs @@ -18,6 +18,7 @@ namespace Gml.Launcher.ViewModels.Pages; public class SettingsPageViewModel : PageViewModelBase { + private readonly MainWindowViewModel _mainViewModel; private readonly IGmlClientManager _gmlManager; private readonly IStorageService _storageService; private double _ramValue; @@ -33,6 +34,7 @@ public SettingsPageViewModel( IGmlClientManager gmlManager, ProfileReadDto selectedProfile) : base(screen, localizationService) { + _mainViewModel = (MainWindowViewModel)screen; _storageService = storageService; _gmlManager = gmlManager; @@ -123,6 +125,7 @@ public string WindowHeight } public ObservableCollection AvailableLanguages { get; } + public MainWindowViewModel MainViewModel => _mainViewModel; internal void ChangeFolder() { diff --git a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml index 8f5f1af..c5b583f 100644 --- a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml +++ b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml @@ -150,12 +150,10 @@ Classes="HeadlineText" /> - + + ColumnDefinitions="*, 15, Auto"> diff --git a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs index 6631e18..327fdf0 100644 --- a/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs +++ b/src/Gml.Launcher/Views/Pages/SettingsPageView.axaml.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using Avalonia; using Avalonia.Controls; using Avalonia.Interactivity; @@ -6,6 +7,8 @@ using Avalonia.Platform.Storage; using Avalonia.ReactiveUI; using Avalonia.VisualTree; +using GamerVII.Notification.Avalonia; +using Gml.Launcher.Assets; using Gml.Launcher.ViewModels.Pages; using ReactiveUI; @@ -31,18 +34,32 @@ private void OnTextInput(object? sender, TextChangedEventArgs e) private async void OpenFileDialog(object? sender, RoutedEventArgs e) { - if (this.GetVisualRoot() is MainWindow mainWindow) + try { - var folders = await mainWindow.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions + if (this.GetVisualRoot() is MainWindow mainWindow) { - AllowMultiple = false, - Title = "Select a folder" - }); + var folders = await mainWindow.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions + { + AllowMultiple = false, + Title = "Select a folder" + }); - if (folders.Count != 1) return; + if (folders.Count != 1) return; - ViewModel!.InstallationFolder = folders[0].Path.AbsolutePath; - ViewModel!.ChangeFolder(); + ViewModel!.InstallationFolder = folders[0].Path.AbsolutePath; + ViewModel!.ChangeFolder(); + } + } + catch (Exception exception) + { + //ToDo: Sentry send + ViewModel?.MainViewModel.Manager + .CreateMessage(true, "#D03E3E", + ViewModel.LocalizationService.GetString(ResourceKeysDictionary.Error), + ViewModel.LocalizationService.GetString(ResourceKeysDictionary.InvalidFolder)) + .Dismiss() + .WithDelay(TimeSpan.FromSeconds(3)) + .Queue(); } } } From c850bd0ba1d6dc74bdd2720a419f7fcbd7f3fb9c Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 27 Jul 2024 22:11:41 +0300 Subject: [PATCH 61/63] Update submodule link Gml.Core --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 03c0179..3f2f87e 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 03c0179a5492e8e00177d00ba908a2a6b396c731 +Subproject commit 3f2f87ef88e281cf0dfd7b5a9d0c32de76d9ed32 From 28374783ee3f53f79e5ce347c0bf9a0d8af47d9f Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sat, 27 Jul 2024 22:20:40 +0300 Subject: [PATCH 62/63] Add InvalidFolder constant to ResourceKeysDictionary This update introduces a new constant, `InvalidFolder`, to the `ResourceKeysDictionary.Template.cs` file. This additional entry aims to standardize and centralize the error message related to invalid folders across the application. --- .../Assets/Resources/ResourceKeysDictionary.Template.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs index 7c45c1e..35085dc 100644 --- a/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs +++ b/src/Gml.Launcher/Assets/Resources/ResourceKeysDictionary.Template.cs @@ -5,6 +5,7 @@ public static class ResourceKeysDictionary public const string MainPageTitle = "DefaultPageTitle"; public const string DefaultPageTitle = "DefaultPageTitle"; public const string Error = "Error"; + public const string InvalidFolder = "InvalidFolder"; public const string NotSetting = "NotSetting"; public const string Updating = "Updating"; public const string Stay = "Stay"; From cd74654dcbd44ddb7286a2b6674e55a154b22b42 Mon Sep 17 00:00:00 2001 From: GamerVII-NET <111225722+GamerVII-NET@users.noreply.github.com> Date: Sun, 28 Jul 2024 15:45:56 +0300 Subject: [PATCH 63/63] Update submodule link Gml.Core --- src/Gml.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gml.Client b/src/Gml.Client index 3f2f87e..0d334ab 160000 --- a/src/Gml.Client +++ b/src/Gml.Client @@ -1 +1 @@ -Subproject commit 3f2f87ef88e281cf0dfd7b5a9d0c32de76d9ed32 +Subproject commit 0d334abe23f13b2fe361a7444d5df6e9924eb6e8

xJh26P%wL~g!42Pbx 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%0DkHd$(vxWe)RHz8zmVZQ;91{>U6Aq|Q{XeDm_R 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 F`wdleUETly literal 0 HcmV?d00001 diff --git a/src/Gml.Launcher/Assets/Fonts/Manrope-Medium.ttf b/src/Gml.Launcher/Assets/Fonts/Manrope-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5eda9ec96e91ba8e4a418e53af4483766e245d6d GIT binary patch literal 96904 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 z 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 PYKF&ZM0WQ-@!I|YI=d1? literal 0 HcmV?d00001 diff --git a/src/Gml.Launcher/Assets/Fonts/Manrope-SemiBold.ttf b/src/Gml.Launcher/Assets/Fonts/Manrope-SemiBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b6e9c209002016a67600b6772e386525c60417f5 GIT binary patch literal 96936 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