diff --git a/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj b/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj index f8a55d4e7..65a1bf569 100644 --- a/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj +++ b/src/UniGetUI.Core.Classes.Tests/UniGetUI.Core.Classes.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj b/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj index 7587542f7..0da9bfb3d 100644 --- a/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj +++ b/src/UniGetUI.Core.Classes/UniGetUI.Core.Classes.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj b/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj index 617604af8..60a7b3c41 100644 --- a/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj +++ b/src/UniGetUI.Core.Data.Tests/UniGetUI.Core.Data.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj b/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj index fd29a2c5c..6dc38ed1c 100644 --- a/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj +++ b/src/UniGetUI.Core.Data/UniGetUI.Core.Data.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj b/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj index f9234050b..c47592682 100644 --- a/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj +++ b/src/UniGetUI.Core.IconEngine.Tests/UniGetUI.Core.IconEngine.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -29,6 +29,7 @@ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> <PackageReference Include="xunit" Version="2.9.2" /> <PackageReference Include="xunit.analyzers" Version="1.17.0"> <PrivateAssets>all</PrivateAssets> diff --git a/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj b/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj index d7e69f793..2de7625c5 100644 --- a/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj +++ b/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -30,7 +30,7 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="PhotoSauce.MagicScaler" Version="0.14.2" /> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> <PackageReference Include="System.Drawing.Common" Version="9.0.0" /> </ItemGroup> </Project> diff --git a/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj b/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj index c8d1e7a9e..5158e612d 100644 --- a/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj +++ b/src/UniGetUI.Core.Language.Tests/UniGetUI.Core.LanguageEngine.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.LanguageEngine/LanguageData.cs b/src/UniGetUI.Core.LanguageEngine/LanguageData.cs index 18d856c84..0ad91b58c 100644 --- a/src/UniGetUI.Core.LanguageEngine/LanguageData.cs +++ b/src/UniGetUI.Core.LanguageEngine/LanguageData.cs @@ -116,7 +116,6 @@ private static Person[] LoadLanguageTranslatorList() result.Add(person); } } - return result.ToArray(); } } diff --git a/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj b/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj index a53395763..7dc6e7fb5 100644 --- a/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj +++ b/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj b/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj index a586277e3..60a30f5c7 100644 --- a/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj +++ b/src/UniGetUI.Core.Logger/UniGetUI.Core.Logging.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj b/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj index 520feb29a..87976ef73 100644 --- a/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj +++ b/src/UniGetUI.Core.Logging.Tests/UniGetUI.Core.Logging.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj b/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj index 28325a8bb..facdaeb5d 100644 --- a/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj +++ b/src/UniGetUI.Core.Settings.Tests/UniGetUI.Core.Settings.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj b/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj index a56448c8f..44a20f7be 100644 --- a/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj +++ b/src/UniGetUI.Core.Settings/UniGetUI.Core.Settings.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj b/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj index 4e56f7250..4c116f5b1 100644 --- a/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj +++ b/src/UniGetUI.Core.Tools.Tests/UniGetUI.Core.Tools.Tests.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj b/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj index 19d550ee4..12b86baca 100644 --- a/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj +++ b/src/UniGetUI.Core.Tools/UniGetUI.Core.Tools.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj b/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj index e4980d0e1..42fe1af13 100644 --- a/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj +++ b/src/UniGetUI.Interface.BackgroundApi/UniGetUI.Interface.BackgroundApi.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -22,6 +22,11 @@ <PackageReference Include="Nancy.Hosting.Self" Version="2.0.0"> <NoWarn>NU1701</NoWarn> </PackageReference> + <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + <PackageReference Include="System.Net.Http" Version="4.3.4" /> + <PackageReference Include="System.Private.Uri" Version="4.3.2" /> + <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" /> </ItemGroup> <ItemGroup> diff --git a/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj b/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj index f92ab867a..87bc731d7 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj +++ b/src/UniGetUI.PAckageEngine.Interfaces/UniGetUI.PackageEngine.Interfaces.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -22,6 +22,10 @@ <Configurations>Debug;Release</Configurations> </PropertyGroup> + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> + <ItemGroup> <ProjectReference Include="..\UniGetUI.Core.Classes\UniGetUI.Core.Classes.csproj" /> <ProjectReference Include="..\UniGetUI.Core.Data\UniGetUI.Core.Data.csproj" /> diff --git a/src/UniGetUI.PackageEngine.Enums/Enums.cs b/src/UniGetUI.PackageEngine.Enums/Enums.cs index 15001d09f..6b8d6305f 100644 --- a/src/UniGetUI.PackageEngine.Enums/Enums.cs +++ b/src/UniGetUI.PackageEngine.Enums/Enums.cs @@ -29,15 +29,16 @@ public enum BundleFormatType public enum OperationVeredict { - Succeeded, - Failed, + Success, + Failure, Canceled, - RestartRequired, + // RestartRequired, AutoRetry, } + public enum OperationStatus { - Pending, + InQueue, Running, Succeeded, Failed, diff --git a/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj b/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj index a586277e3..60a30f5c7 100644 --- a/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj +++ b/src/UniGetUI.PackageEngine.Enums/UniGetUI.PackageEngine.Structs.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs b/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs index 49200e3f6..aaa813c08 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/Cargo.cs @@ -146,10 +146,10 @@ private IEnumerable<Package> GetPackages(LoggableTaskType taskType) List<Package> Packages = []; foreach(var match in TaskRecycler<List<Match>>.RunOrAttach(GetInstalledCommandOutput, 15)) { - var id = match.Groups[1].Value.Trim(); + var id = match.Groups[1]?.Value?.Trim() ?? ""; var name = CoreTools.FormatAsName(id); - var oldVersion = match.Groups[2].Value; - var newVersion = match.Groups[3].Value; + var oldVersion = match.Groups[2]?.Value?.Trim() ?? ""; + var newVersion = match.Groups[3]?.Value?.Trim() ?? ""; if(taskType is LoggableTaskType.ListUpdates && oldVersion != newVersion) Packages.Add(new Package(name, id, oldVersion, newVersion, DefaultSource, this)); else if(taskType is LoggableTaskType.ListInstalledPackages) diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs index ca31f9836..dbb402f2c 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/Helpers/CargoPkgOperationHelper.cs @@ -22,6 +22,6 @@ protected override IEnumerable<string> _getOperationParameters(IPackage package, protected override OperationVeredict _getOperationResult(IPackage package, OperationType operation, IEnumerable<string> processOutput, int returnCode) { - return returnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj b/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj index f23d6a820..50deb4f3a 100644 --- a/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Cargo/UniGetUI.PackageEngine.Managers.Cargo.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -35,4 +35,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs index 0b37b7f34..113c83b71 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateyPkgOperationHelper.cs @@ -55,12 +55,13 @@ protected override OperationVeredict _getOperationResult( { if(returnCode is 3010) { - return OperationVeredict.RestartRequired; + return OperationVeredict.Success; + // return OperationVeredict.RestartRequired; } if (returnCode is 1641 or 1614 or 1605 or 0) { - return OperationVeredict.Succeeded; + return OperationVeredict.Success; } string output_string = string.Join("\n", processOutput); @@ -76,6 +77,6 @@ protected override OperationVeredict _getOperationResult( return OperationVeredict.AutoRetry; } - return OperationVeredict.Failed; + return OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs index 28b1db7ec..77395c8c3 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Helpers/ChocolateySourceHelper.cs @@ -23,12 +23,12 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override IEnumerable<IManagerSource> GetSources_UnSafe() diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj b/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj index 1c4254519..b0c73f7ab 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/UniGetUI.PackageEngine.Managers.Chocolatey.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -42,4 +42,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs index ac489b80c..acf789f43 100644 --- a/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Dotnet/Helpers/DotNetPkgOperationHelper.cs @@ -52,6 +52,6 @@ protected override OperationVeredict _getOperationResult( IEnumerable<string> processOutput, int returnCode) { - return returnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj b/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj index 48c154195..174cde52b 100644 --- a/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Dotnet/UniGetUI.PackageEngine.Managers.Dotnet.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -36,4 +36,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj index c9da46d1a..c03532463 100644 --- a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -26,4 +26,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs index d0b2d767c..5195e7a6c 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgOperationHelper.cs @@ -36,6 +36,6 @@ protected override OperationVeredict _getOperationResult( IEnumerable<string> processOutput, int returnCode) { - return returnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj b/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj index 66878f953..96ab48183 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Npm/UniGetUI.PackageEngine.Managers.Npm.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -35,4 +35,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs index 9c07687f4..675181438 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgOperationHelper.cs @@ -54,7 +54,7 @@ protected override OperationVeredict _getOperationResult( { if (returnCode == 0) { - return OperationVeredict.Succeeded; + return OperationVeredict.Success; } string output_string = string.Join("\n", processOutput); @@ -64,7 +64,7 @@ protected override OperationVeredict _getOperationResult( package.OverridenOptions.Scope = PackageScope.User; return OperationVeredict.AutoRetry; } - return OperationVeredict.Failed; + return OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj b/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj index 66878f953..96ab48183 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Pip/UniGetUI.PackageEngine.Managers.Pip.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -35,4 +35,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs index 30f81f0a5..88efdfd60 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellPkgOperationHelper.cs @@ -67,6 +67,6 @@ protected override OperationVeredict _getOperationResult( return OperationVeredict.AutoRetry; } - return returnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs index 96c381a19..44a23f134 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/Helpers/PowerShellSourceHelper.cs @@ -30,12 +30,12 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override IEnumerable<IManagerSource> GetSources_UnSafe() diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj b/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj index 48c154195..174cde52b 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/UniGetUI.PackageEngine.Managers.PowerShell.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -36,4 +36,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs index e89c59fbe..6e391d296 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7PkgOperationHelper.cs @@ -58,6 +58,6 @@ protected override OperationVeredict _getOperationResult( return OperationVeredict.AutoRetry; } - return returnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs index b4ec51f0f..088bc3b1a 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/Helpers/PowerShell7SourceHelper.cs @@ -30,12 +30,12 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override IEnumerable<IManagerSource> GetSources_UnSafe() diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj b/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj index c9b40a3cb..7765f14b2 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/UniGetUI.PackageEngine.Managers.PowerShell7.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -35,4 +35,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs index d510de5a7..fe2105c88 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgOperationHelper.cs @@ -81,16 +81,16 @@ protected override OperationVeredict _getOperationResult( if (operation is OperationType.Uninstall) { if (output_string.Contains("was uninstalled")) - return OperationVeredict.Succeeded; + return OperationVeredict.Success; - return OperationVeredict.Failed; + return OperationVeredict.Failure; } else { if (output_string.Contains("ERROR")) - return OperationVeredict.Failed; + return OperationVeredict.Failure; - return OperationVeredict.Succeeded; + return OperationVeredict.Success; } } } diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs index bdc9a8453..9e58c2311 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopSourceHelper.cs @@ -15,7 +15,7 @@ public ScoopSourceHelper(Scoop manager) : base(manager) { } protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } public override string[] GetAddSourceParameters(IManagerSource source) @@ -25,7 +25,7 @@ public override string[] GetAddSourceParameters(IManagerSource source) protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } public override string[] GetRemoveSourceParameters(IManagerSource source) diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj b/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj index 66878f953..96ab48183 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/UniGetUI.PackageEngine.Managers.Scoop.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -35,4 +35,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs index a611eea54..2240f4e42 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgOperationHelper.cs @@ -26,6 +26,6 @@ protected override OperationVeredict _getOperationResult( IEnumerable<string> processOutput, int returnCode) { - return returnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return returnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } } diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj b/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj index d42527872..3cf2fcfbb 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/UniGetUI.PackageEngine.Managers.Vcpkg.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs index b6f98e320..18755ab23 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs @@ -339,7 +339,7 @@ protected override ManagerStatus LoadManager() public override void RefreshPackageIndexes() { - var (found, path) = GetVcpkgPath(); + var (found, _) = GetVcpkgPath(); var (vcpkgRootFound, vcpkgRoot) = GetVcpkgRoot(); var (gitFound, gitPath) = CoreTools.Which("git"); diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs index 38830c5d0..def508835 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetPkgOperationHelper.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; using Microsoft.Management.Deployment; +using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; using UniGetUI.PackageEngine.Classes.Manager.BaseProviders; @@ -86,26 +87,35 @@ protected override IEnumerable<string> _getOperationParameters(IPackage package, }); } - var installOptions = NativePackageHandler.GetInstallationOptions(package, operation); - if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationRequired - or ElevationRequirement.ElevatesSelf) + try { - package.OverridenOptions.RunAsAdministrator = true; + var installOptions = NativePackageHandler.GetInstallationOptions(package, operation); + if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationRequired + or ElevationRequirement.ElevatesSelf) + { + package.OverridenOptions.RunAsAdministrator = true; + } + else if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationProhibited) + { + if (CoreTools.IsAdministrator()) + throw new UnauthorizedAccessException( + CoreTools.Translate("This package cannot be installed from an elevated context.") + + CoreTools.Translate("Please run UniGetUI as a regular user and try again.")); + + if (options.RunAsAdministrator) + throw new UnauthorizedAccessException( + CoreTools.Translate("This package cannot be installed from an elevated context.") + + CoreTools.Translate("Please check the installation options for this package and try again")); + package.OverridenOptions.RunAsAdministrator = false; + } } - else if (installOptions?.ElevationRequirement is ElevationRequirement.ElevationProhibited) + catch (Exception ex) { - if (CoreTools.IsAdministrator()) - throw new UnauthorizedAccessException( - CoreTools.Translate("This package cannot be installed from an elevated context.") - + CoreTools.Translate("Please run UniGetUI as a regular user and try again.")); - - if (options.RunAsAdministrator) - throw new UnauthorizedAccessException( - CoreTools.Translate("This package cannot be installed from an elevated context.") - + CoreTools.Translate("Please check the installation options for this package and try again")); - package.OverridenOptions.RunAsAdministrator = false; + Logger.Error("Recovered from fatal WinGet exception:"); + Logger.Error(ex); } + return parameters; } @@ -122,7 +132,8 @@ protected override OperationVeredict _getOperationResult( { // If the user is required to restart the system to complete the installation if(operation is OperationType.Update) MarkUpgradeAsDone(package); - return OperationVeredict.RestartRequired; + //return OperationVeredict.RestartRequired; + return OperationVeredict.Success; } if (uintCode == 0x8A150077 || uintCode == 0x8A15010C || uintCode == 0x8A150005) @@ -133,26 +144,26 @@ protected override OperationVeredict _getOperationResult( if (uintCode == 0x8A150011) { // TODO: Needs skip checksum - return OperationVeredict.Failed; + return OperationVeredict.Failure; } if (uintCode == 0x8A15002B) { - return OperationVeredict.Failed; + return OperationVeredict.Failure; } if (uintCode == 0x8A15010D || uintCode == 0x8A15004F || uintCode == 0x8A15010E) { // Application is already installed if(operation is OperationType.Update) MarkUpgradeAsDone(package); - return OperationVeredict.Succeeded; + return OperationVeredict.Success; } if (returnCode == 0) { // Operation succeeded if(operation is OperationType.Update) MarkUpgradeAsDone(package); - return OperationVeredict.Succeeded; + return OperationVeredict.Success; } if(uintCode == 0x8A150056 && package.OverridenOptions.RunAsAdministrator != false && !CoreTools.IsAdministrator()) @@ -169,7 +180,7 @@ protected override OperationVeredict _getOperationResult( return OperationVeredict.AutoRetry; } - return OperationVeredict.Failed; + return OperationVeredict.Failure; } private static void MarkUpgradeAsDone(IPackage package) diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs index e0d3e099e..098356bae 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/Helpers/WinGetSourceHelper.cs @@ -26,12 +26,12 @@ public override string[] GetRemoveSourceParameters(IManagerSource source) protected override OperationVeredict _getAddSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override OperationVeredict _getRemoveSourceOperationVeredict(IManagerSource source, int ReturnCode, string[] Output) { - return ReturnCode == 0 ? OperationVeredict.Succeeded : OperationVeredict.Failed; + return ReturnCode == 0 ? OperationVeredict.Success : OperationVeredict.Failure; } protected override IEnumerable<IManagerSource> GetSources_UnSafe() diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj b/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj index 623e8d6b8..27758f023 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/UniGetUI.PackageEngine.Managers.WinGet.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -87,4 +87,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs b/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs new file mode 100644 index 000000000..15f17a7e6 --- /dev/null +++ b/src/UniGetUI.PackageEngine.Operations/AbstractOperation.cs @@ -0,0 +1,356 @@ +using UniGetUI.Core.Logging; +using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Tools; +using UniGetUI.PackageEngine.Enums; + +namespace UniGetUI.PackageOperations; + +public abstract class AbstractOperation : IDisposable +{ + public static class RetryMode + { + public const string NoRetry = ""; + public const string Retry = "Retry"; + public const string Retry_AsAdmin = "RetryAsAdmin"; + public const string Retry_Interactive = "RetryInteractive"; + public const string Retry_SkipIntegrity = "RetryNoHashCheck"; + } + + public class OperationMetadata + { + /// <summary> + /// Installation of X + /// </summary> + public string Title = ""; + + /// <summary> + /// X is being installed/upated/removed + /// </summary> + public string Status = ""; + + /// <summary> + /// X was installed + /// </summary> + public string SuccessTitle = ""; + + /// <summary> + /// X has been installed successfully + /// </summary> + public string SuccessMessage = ""; + + /// <summary> + /// X could not be installed. + /// </summary> + public string FailureTitle = ""; + + /// <summary> + /// X Could not be installed + /// </summary> + public string FailureMessage = ""; + + /// <summary> + /// Starting operation X with options Y + /// </summary> + public string OperationInformation = ""; + + public readonly string Identifier; + + public OperationMetadata() + { + Identifier = new Random().NextInt64(1000000, 9999999).ToString(); + } + } + + public readonly OperationMetadata Metadata = new(); + public static readonly List<AbstractOperation> OperationQueue = new(); + + public event EventHandler<OperationStatus>? StatusChanged; + public event EventHandler<EventArgs>? CancelRequested; + public event EventHandler<(string, LineType)>? LogLineAdded; + public event EventHandler<EventArgs>? OperationStarting; + public event EventHandler<EventArgs>? OperationFinished; + public event EventHandler<EventArgs>? Enqueued; + public event EventHandler<EventArgs>? OperationSucceeded; + public event EventHandler<EventArgs>? OperationFailed; + + public static int MAX_OPERATIONS; + + public event EventHandler<BadgeCollection>? BadgesChanged; + + public class BadgeCollection + { + public readonly bool AsAdministrator; + public readonly bool Interactive; + public readonly bool SkipHashCheck; + public readonly PackageScope? Scope; + + public BadgeCollection(bool admin, bool interactive, bool skiphash, PackageScope? scope) + { + AsAdministrator = admin; + Interactive = interactive; + SkipHashCheck = skiphash; + Scope = scope; + } + } + public void ApplyCapabilities(bool admin, bool interactive, bool skiphash, PackageScope? scope) + { + BadgesChanged?.Invoke(this, new BadgeCollection(admin, interactive, skiphash, scope)); + } + + public enum LineType + { + OperationInfo, + Progress, + StdOUT, + StdERR + } + + private List<(string, LineType)> LogList = new(); + private OperationStatus _status = OperationStatus.InQueue; + public OperationStatus Status + { + get => _status; + set { _status = value; StatusChanged?.Invoke(this, value); } + } + + public bool Started { get; private set; } + protected bool QUEUE_ENABLED; + protected bool FORCE_HOLD_QUEUE; + + public AbstractOperation(bool queue_enabled) + { + QUEUE_ENABLED = queue_enabled; + Status = OperationStatus.InQueue; + Line("Please wait...", LineType.Progress); + + if(int.TryParse(Settings.GetValue("ParallelOperationCount"), out int _maxPps)) + { + Logger.Debug("Parallel operation limit not set, defaulting to 1"); + MAX_OPERATIONS = _maxPps; + } + else + { + MAX_OPERATIONS = 1; + Logger.Debug($"Parallel operation limit set to {MAX_OPERATIONS}"); + } + } + + public void Cancel() + { + switch (_status) + { + case OperationStatus.Canceled: + break; + case OperationStatus.Failed: + break; + case OperationStatus.Running: + Status = OperationStatus.Canceled; + while(OperationQueue.Remove(this)); + CancelRequested?.Invoke(this, EventArgs.Empty); + Status = OperationStatus.Canceled; + break; + case OperationStatus.InQueue: + Status = OperationStatus.Canceled; + while(OperationQueue.Remove(this)); + Status = OperationStatus.Canceled; + break; + case OperationStatus.Succeeded: + break; + } + } + + protected void Line(string line, LineType type) + { + if(type != LineType.Progress) LogList.Add((line, type)); + LogLineAdded?.Invoke(this, (line, type)); + } + + public IReadOnlyList<(string, LineType)> GetOutput() + { + return LogList; + } + + public async Task MainThread() + { + try + { + if (Metadata.Status == "") throw new InvalidDataException("Metadata.Status was not set!"); + if (Metadata.Title == "") throw new InvalidDataException("Metadata.Title was not set!"); + if (Metadata.OperationInformation == "") + throw new InvalidDataException("Metadata.OperationInformation was not set!"); + if (Metadata.SuccessTitle == "") throw new InvalidDataException("Metadata.SuccessTitle was not set!"); + if (Metadata.SuccessMessage == "") throw new InvalidDataException("Metadata.SuccessMessage was not set!"); + if (Metadata.FailureTitle == "") throw new InvalidDataException("Metadata.FailureTitle was not set!"); + if (Metadata.FailureMessage == "") throw new InvalidDataException("Metadata.FailureMessage was not set!"); + + Started = true; + + if (OperationQueue.Contains(this)) + throw new InvalidOperationException("This operation was already on the queue"); + + Status = OperationStatus.InQueue; + Line(Metadata.OperationInformation, LineType.OperationInfo); + Line(Metadata.Status, LineType.Progress); + + // BEGIN QUEUE HANDLER + if (QUEUE_ENABLED) + { + SKIP_QUEUE = false; + OperationQueue.Add(this); + Enqueued?.Invoke(this, EventArgs.Empty); + int lastPos = -2; + + while (FORCE_HOLD_QUEUE || (OperationQueue.IndexOf(this) >= MAX_OPERATIONS && !SKIP_QUEUE)) + { + int pos = OperationQueue.IndexOf(this) - MAX_OPERATIONS + 1; + + if (pos == -1) return; + // In this case, operation was canceled; + + if (pos != lastPos) + { + lastPos = pos; + Line(CoreTools.Translate("Operation on queue (position {0})...", pos), LineType.Progress); + } + + await Task.Delay(100); + } + } + // END QUEUE HANDLER + + // BEGIN ACTUAL OPERATION + OperationVeredict result; + Line(CoreTools.Translate("Starting operation..."), LineType.Progress); + if(Status is OperationStatus.InQueue) Status = OperationStatus.Running; + OperationStarting?.Invoke(this, EventArgs.Empty); + + do + { + try + { + // Check if the operation was canceled + if (Status is OperationStatus.Canceled) + { + result = OperationVeredict.Canceled; + break; + } + + Task<OperationVeredict> op = PerformOperation(); + while (Status != OperationStatus.Canceled && !op.IsCompleted) await Task.Delay(100); + + if (Status is OperationStatus.Canceled) result = OperationVeredict.Canceled; + else result = op.GetAwaiter().GetResult(); + } + catch (Exception e) + { + result = OperationVeredict.Failure; + Logger.Error(e); + foreach (string l in e.ToString().Split("\n")) Line(l, LineType.StdERR); + } + } while (result == OperationVeredict.AutoRetry); + + OperationFinished?.Invoke(this, EventArgs.Empty); + + while (OperationQueue.Remove(this)); + // END OPERATION + + if (result == OperationVeredict.Success) + { + Status = OperationStatus.Succeeded; + OperationSucceeded?.Invoke(this, EventArgs.Empty); + Line(Metadata.SuccessMessage, LineType.StdOUT); + } + else if (result == OperationVeredict.Failure) + { + Status = OperationStatus.Failed; + OperationFailed?.Invoke(this, EventArgs.Empty); + Line(Metadata.FailureMessage, LineType.StdERR); + Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"), + LineType.Progress); + } + else if (result == OperationVeredict.Canceled) + { + Status = OperationStatus.Canceled; + Line(CoreTools.Translate("Operation canceled by user"), LineType.StdERR); + } + } + catch (Exception ex) + { + Line("An internal error occurred:", LineType.StdERR); + foreach (var line in ex.ToString().Split("\n")) + Line(line, LineType.StdERR); + + while (OperationQueue.Remove(this)) ; + + Status = OperationStatus.Failed; + try + { + OperationFinished?.Invoke(this, EventArgs.Empty); + OperationFailed?.Invoke(this, EventArgs.Empty); + } + catch (Exception e2) + { + Line("An internal error occurred while handling an internal error:", LineType.StdERR); + foreach (var line in e2.ToString().Split("\n")) + Line(line, LineType.StdERR); + } + + Line(Metadata.FailureMessage, LineType.StdERR); + Line(Metadata.FailureMessage + " - " + CoreTools.Translate("Click here for more details"), + LineType.Progress); + } + } + + private bool SKIP_QUEUE; + + public void SkipQueue() + { + if (Status != OperationStatus.InQueue) return; + while(OperationQueue.Remove(this)); + SKIP_QUEUE = true; + } + + public void RunNext() + { + if (Status != OperationStatus.InQueue) return; + if (!OperationQueue.Contains(this)) return; + + FORCE_HOLD_QUEUE = true; + while(OperationQueue.Remove(this)); + OperationQueue.Insert(Math.Min(MAX_OPERATIONS, OperationQueue.Count), this); + FORCE_HOLD_QUEUE = false; + } + + public void BackOfTheQueue() + { + if (Status != OperationStatus.InQueue) return; + if (!OperationQueue.Contains(this)) return; + + FORCE_HOLD_QUEUE = true; + while(OperationQueue.Remove(this)); + OperationQueue.Add(this); + FORCE_HOLD_QUEUE = false; + } + + public void Retry(string retryMode) + { + if (retryMode is RetryMode.NoRetry) + throw new InvalidOperationException("We weren't supposed to reach this, weren't we?"); + + ApplyRetryAction(retryMode); + Line($"", LineType.OperationInfo); + Line($"-----------------------", LineType.OperationInfo); + Line($"Retrying operation with RetryMode={retryMode}", LineType.OperationInfo); + Line($"", LineType.OperationInfo); + if (Status is OperationStatus.Running or OperationStatus.InQueue) return; + _ = MainThread(); + } + + protected abstract void ApplyRetryAction(string retryMode); + protected abstract Task<OperationVeredict> PerformOperation(); + public abstract Task<Uri> GetOperationIcon(); + public void Dispose() + { + while(OperationQueue.Remove(this)); + } +} diff --git a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs new file mode 100644 index 000000000..c0f8efab2 --- /dev/null +++ b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs @@ -0,0 +1,289 @@ +using System.Diagnostics; +using UniGetUI.Core.Classes; +using UniGetUI.Core.Data; +using UniGetUI.Core.Logging; +using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Tools; +using UniGetUI.Interface; +using UniGetUI.Interface.Enums; +using UniGetUI.PackageEngine.Classes.Packages.Classes; +using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageEngine.Interfaces; +using UniGetUI.PackageEngine.PackageClasses; +using UniGetUI.PackageEngine.PackageLoader; +using UniGetUI.PackageOperations; + +namespace UniGetUI.PackageEngine.Operations +{ + public abstract class PackageOperation : AbstractProcessOperation + { + protected List<string> DesktopShortcutsBeforeStart = []; + + public readonly IPackage Package; + public readonly IInstallationOptions Options; + public readonly OperationType Role; + + protected abstract Task HandleSuccess(); + protected abstract Task HandleFailure(); + protected abstract void Initialize(); + + public PackageOperation( + IPackage package, + IInstallationOptions options, + OperationType role, + bool IgnoreParallelInstalls = false) + : base(!IgnoreParallelInstalls) + { + Package = package; + Options = options; + Role = role; + + Initialize(); + + Enqueued += (_, _) => + { + ApplyCapabilities(RequiresAdminRights(), + Options.InteractiveInstallation, + (Options.SkipHashCheck && Role is not OperationType.Uninstall), + Package.OverridenOptions.Scope ?? Options.InstallationScope); + + Package.SetTag(PackageTag.OnQueue); + }; + CancelRequested += (_, _) => Package.SetTag(PackageTag.Default); + OperationSucceeded += (_, _) => HandleSuccess(); + OperationFailed += (_, _) => HandleFailure(); + } + + public PackageOperation( + IPackage package, + OperationType role, + bool IgnoreParallelInstalls = false) + : this(package, InstallationOptions.FromPackage(package), role, IgnoreParallelInstalls) { } + + private bool RequiresAdminRights() + { + return Package.OverridenOptions.RunAsAdministrator is true + || Options.RunAsAdministrator + || (Settings.Get("AlwaysElevate" + Package.Manager.Name) && !Package.OverridenOptions.RunAsAdministrator is false); + } + + protected override void ApplyRetryAction(string retryMode) + { + switch (retryMode) + { + case RetryMode.Retry_AsAdmin: + Options.RunAsAdministrator = true; + break; + case RetryMode.Retry_Interactive: + Options.InteractiveInstallation = true; + break; + case RetryMode.Retry_SkipIntegrity: + Options.SkipHashCheck = true; + break; + case RetryMode.Retry: + break; + default: + throw new InvalidOperationException($"Retry mode {retryMode} is not supported in this context"); + } + Metadata.OperationInformation = "Retried package operation for Package=" + Package.Id + " with Manager=" + + Package.Manager.Name + "\nUpdated installation options: " + Options.ToString(); + + } + + protected sealed override void PrepareProcessStartInfo() + { + bool admin = false; + Package.SetTag(PackageTag.OnQueue); + string operation_args = string.Join(" ", Package.Manager.OperationHelper.GetParameters(Package, Options, Role)); + + if (RequiresAdminRights()) + { + admin = true; + if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) + { + CoreTools.CacheUACForCurrentProcess().GetAwaiter().GetResult(); + } + + process.StartInfo.FileName = CoreData.GSudoPath; + process.StartInfo.Arguments = + $"\"{Package.Manager.Status.ExecutablePath}\" {Package.Manager.Properties.ExecutableCallArgs} {operation_args}"; + } + else + { + process.StartInfo.FileName = Package.Manager.Status.ExecutablePath; + process.StartInfo.Arguments = $"{Package.Manager.Properties.ExecutableCallArgs} {operation_args}"; + } + ApplyCapabilities(admin, + Options.InteractiveInstallation, + (Options.SkipHashCheck && Role is not OperationType.Uninstall), + Package.OverridenOptions.Scope ?? Options.InstallationScope); + } + + protected sealed override Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output) + { + return Task.FromResult(Package.Manager.OperationHelper.GetResult(Package, Role, Output, ReturnCode)); + } + + public override Task<Uri> GetOperationIcon() + { + return TaskRecycler<Uri>.RunOrAttachAsync(Package.GetIconUrl); + } + } + + public class InstallPackageOperation : PackageOperation + { + + public InstallPackageOperation( + IPackage package, + IInstallationOptions options, + bool IgnoreParallelInstalls = false) + : base(package, options, OperationType.Install, IgnoreParallelInstalls) + { } + + public InstallPackageOperation( + IPackage package, + bool IgnoreParallelInstalls = false) + : base(package, OperationType.Install, IgnoreParallelInstalls) + { } + + protected override Task HandleFailure() + { + Package.SetTag(PackageTag.Failed); + return Task.CompletedTask; + } + + protected override Task HandleSuccess() + { + Package.SetTag(PackageTag.AlreadyInstalled); + InstalledPackagesLoader.Instance.AddForeign(Package); + + if (Settings.Get("AskToDeleteNewDesktopShortcuts")) + { + DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart); + } + return Task.CompletedTask; + } + + protected override void Initialize() + { + Metadata.OperationInformation = "Package install operation for Package=" + Package.Id + " with Manager=" + + Package.Manager.Name + "\nInstallation options: " + Options.ToString(); + + Metadata.Title = CoreTools.Translate("{package} Installation", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.Status = CoreTools.Translate("{0} is being installed", Package.Name); + Metadata.SuccessTitle = CoreTools.Translate("Installation succeeded"); + Metadata.SuccessMessage = CoreTools.Translate("{package} was installed successfully", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.FailureTitle = CoreTools.Translate("Installation failed", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.FailureMessage = CoreTools.Translate("{package} could not be installed", new Dictionary<string, object?> { { "package", Package.Name } }); + + if (Settings.Get("AskToDeleteNewDesktopShortcuts")) + { + DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts(); + } + } + } + + public class UpdatePackageOperation : PackageOperation + { + + public UpdatePackageOperation( + IPackage package, + IInstallationOptions options, + bool IgnoreParallelInstalls = false) + : base(package, options, OperationType.Update, IgnoreParallelInstalls) + { } + + public UpdatePackageOperation( + IPackage package, + bool IgnoreParallelInstalls = false) + : base(package, OperationType.Update, IgnoreParallelInstalls) + { } + + protected override Task HandleFailure() + { + Package.SetTag(PackageTag.Failed); + return Task.CompletedTask; + } + + protected override async Task HandleSuccess() + { + Package.SetTag(PackageTag.Default); + Package.GetInstalledPackage()?.SetTag(PackageTag.Default); + Package.GetAvailablePackage()?.SetTag(PackageTag.AlreadyInstalled); + + UpgradablePackagesLoader.Instance.Remove(Package); + + if (await Package.HasUpdatesIgnoredAsync() && await Package.GetIgnoredUpdatesVersionAsync() != "*") + await Package.RemoveFromIgnoredUpdatesAsync(); + + if (Settings.Get("AskToDeleteNewDesktopShortcuts")) + { + DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart); + } + } + + protected override void Initialize() + { + Metadata.OperationInformation = "Package update operation for Package=" + Package.Id + " with Manager=" + + Package.Manager.Name + "\nInstallation options: " + Options.ToString(); + + Metadata.Title = CoreTools.Translate("{package} Update", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.Status = CoreTools.Translate("{0} is being updated to version {1}", Package.Name, Package.NewVersion); + Metadata.SuccessTitle = CoreTools.Translate("Update succeeded"); + Metadata.SuccessMessage = CoreTools.Translate("{package} was updated successfully", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.FailureTitle = CoreTools.Translate("Update failed", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.FailureMessage = CoreTools.Translate("{package} could not be updated", new Dictionary<string, object?> { { "package", Package.Name } }); + + if (Settings.Get("AskToDeleteNewDesktopShortcuts")) + { + DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts(); + } + } + } + + public class UninstallPackageOperation : PackageOperation + { + + public UninstallPackageOperation( + IPackage package, + IInstallationOptions options, + bool IgnoreParallelInstalls = false) + : base(package, options, OperationType.Uninstall, IgnoreParallelInstalls) + { } + + public UninstallPackageOperation( + IPackage package, + bool IgnoreParallelInstalls = false) + : base(package, OperationType.Uninstall, IgnoreParallelInstalls) + { } + + protected override Task HandleFailure() + { + Package.SetTag(PackageTag.Failed); + return Task.CompletedTask; + } + + protected override Task HandleSuccess() + { + Package.SetTag(PackageTag.Default); + Package.GetAvailablePackage()?.SetTag(PackageTag.Default); + UpgradablePackagesLoader.Instance.Remove(Package); + InstalledPackagesLoader.Instance.Remove(Package); + + return Task.CompletedTask; + } + + protected override void Initialize() + { + Metadata.OperationInformation = "Package uninstall operation for Package=" + Package.Id + " with Manager=" + + Package.Manager.Name + "\nInstallation options: " + Options.ToString(); + + Metadata.Title = CoreTools.Translate("{package} Uninstall", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.Status = CoreTools.Translate("{0} is being uninstalled", Package.Name); + Metadata.SuccessTitle = CoreTools.Translate("Uninstall succeeded"); + Metadata.SuccessMessage = CoreTools.Translate("{package} was uninstalled successfully", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.FailureTitle = CoreTools.Translate("Uninstall failed", new Dictionary<string, object?> { { "package", Package.Name } }); + Metadata.FailureMessage = CoreTools.Translate("{package} could not be uninstalled", new Dictionary<string, object?> { { "package", Package.Name } }); + } + } +} diff --git a/src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs b/src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs new file mode 100644 index 000000000..1782d60f7 --- /dev/null +++ b/src/UniGetUI.PackageEngine.Operations/ProcessOperation.cs @@ -0,0 +1,100 @@ +using System.Diagnostics; +using UniGetUI.PackageEngine.Enums; + +namespace UniGetUI.PackageOperations; + +public abstract class AbstractProcessOperation : AbstractOperation +{ + protected Process process { get; private set; } + private bool ProcessKilled; + protected AbstractProcessOperation(bool queue_enabled) : base(queue_enabled) + { + process = new(); + CancelRequested += (_, _) => + { + try + { + process.Kill(); + ProcessKilled = true; + } + catch (InvalidOperationException e) + { + Line("Attempted to cancel a process that hasn't ben created yet: " + e.Message, LineType.StdERR); + } + }; + OperationStarting += (_, _) => + { + ProcessKilled = false; + process = new(); + process.StartInfo.UseShellExecute = false; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardInput = true; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.FileName = "lol"; + process.StartInfo.Arguments = "lol"; + process.OutputDataReceived += (_, e) => + { + if (e.Data is null) return; + string line = e.Data.ToString().Trim(); + if (line.Contains("For the question below") || + line.Contains("Would remove:")) + { // Mitigate chocolatey timeouts + process.StandardInput.WriteLine(""); + } + + var lineType = LineType.StdOUT; + if (line.Length < 6 || line.EndsWith("install/uninstall to complete...")) + { + lineType = LineType.Progress; + } + + Line(line, lineType); + }; + process.ErrorDataReceived += (_, e) => + { + if (e.Data is null) return; + string line = e.Data.ToString().Trim(); + var lineType = LineType.StdERR; + if (line.Length < 6 || line.Contains("Waiting for another install...")) + { + lineType = LineType.Progress; + } + + Line(line, lineType); + }; + PrepareProcessStartInfo(); + }; + } + + protected override async Task<OperationVeredict> PerformOperation() + { + if(process.StartInfo.UseShellExecute) throw new InvalidOperationException("UseShellExecute must be set to false"); + if(!process.StartInfo.RedirectStandardOutput) throw new InvalidOperationException("RedirectStandardOutput must be set to true"); + if(!process.StartInfo.RedirectStandardInput) throw new InvalidOperationException("RedirectStandardInput must be set to true"); + if(!process.StartInfo.RedirectStandardError) throw new InvalidOperationException("RedirectStandardError must be set to true"); + if (process.StartInfo.FileName == "lol") throw new InvalidOperationException("StartInfo.FileName has not been set"); + if (process.StartInfo.Arguments == "lol") throw new InvalidOperationException("StartInfo.Arguments has not been set"); + + Line($"Executing process with StartInfo:", LineType.OperationInfo); + Line($" - FileName: \"{process.StartInfo.FileName.Trim()}\"", LineType.OperationInfo); + Line($" - Arguments: \"{process.StartInfo.Arguments.Trim()}\"", LineType.OperationInfo); + Line($"Start Time: \"{DateTime.Now}\"", LineType.OperationInfo); + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + await process.WaitForExitAsync(); + + Line($"End Time: \"{DateTime.Now}\"", LineType.OperationInfo); + Line($"Process return value: \"{process.ExitCode}\" (0x{process.ExitCode:X})", LineType.OperationInfo); + + if (ProcessKilled) + return OperationVeredict.Canceled; + + return await GetProcessVeredict(process.ExitCode, []); + } + + protected abstract Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output); + protected abstract void PrepareProcessStartInfo(); +} diff --git a/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs b/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs new file mode 100644 index 000000000..6ce64ba1f --- /dev/null +++ b/src/UniGetUI.PackageEngine.Operations/SourceOperations.cs @@ -0,0 +1,141 @@ +using System.Diagnostics; +using Windows.Media.Capture; +using UniGetUI.Core.Data; +using UniGetUI.Core.Logging; +using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Tools; +using UniGetUI.Interface; +using UniGetUI.Interface.Enums; +using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageEngine.Interfaces; +using UniGetUI.PackageOperations; + +namespace UniGetUI.PackageEngine.Operations +{ + + public abstract class SourceOperation : AbstractProcessOperation + { + protected abstract void Initialize(); + + protected IManagerSource Source; + public bool ForceAsAdministrator { get; private set; } + + public SourceOperation(IManagerSource source) : base(false) + { + Source = source; + Initialize(); + } + + public override Task<Uri> GetOperationIcon() + { + return Task.FromResult(new Uri($"ms-appx:///Assets/Images/{Source.Manager.Properties.ColorIconId}.png")); + } + + protected override void ApplyRetryAction(string retryMode) + { + switch (retryMode) + { + case RetryMode.Retry: + break; + case RetryMode.Retry_AsAdmin: + ForceAsAdministrator = true; + break; + default: + throw new InvalidOperationException($"Retry mode {retryMode} is not supported in this context"); + } + } + } + + public class AddSourceOperation : SourceOperation + { + public AddSourceOperation(IManagerSource source) : base(source) + { } + + protected override void PrepareProcessStartInfo() + { + bool admin = false; + if (ForceAsAdministrator || Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin) + { + if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) + { + CoreTools.CacheUACForCurrentProcess().GetAwaiter().GetResult(); + } + + admin = true; + process.StartInfo.FileName = CoreData.GSudoPath; + process.StartInfo.Arguments = $"\"{Source.Manager.Status.ExecutablePath}\" " + Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); + } + else + { + process.StartInfo.FileName = Source.Manager.Status.ExecutablePath; + process.StartInfo.Arguments = Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); + } + + ApplyCapabilities(admin, false, false, null); + } + + protected override Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output) + { + return Task.Run(() => Source.Manager.SourcesHelper.GetAddOperationVeredict(Source, ReturnCode, Output)); + } + + protected override void Initialize() + { + Metadata.OperationInformation = "Starting adding source operation for source=" + Source.Name + + "with Manager=" + Source.Manager.Name; + + Metadata.Title = CoreTools.Translate("Adding source {source}", new Dictionary<string, object?> { { "source", Source.Name } }); + Metadata.Status = CoreTools.Translate("Adding source {source} to {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } });; + Metadata.SuccessTitle = CoreTools.Translate("Source added successfully"); + Metadata.SuccessMessage = CoreTools.Translate("The source {source} was added to {manager} successfully", + new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + Metadata.FailureTitle = CoreTools.Translate("Could not add source"); + Metadata.FailureMessage = CoreTools.Translate("Could not add source {source} to {manager}", + new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + } + } + + public class RemoveSourceOperation : SourceOperation + { + public RemoveSourceOperation(IManagerSource source) : base(source) + { } + + protected override void PrepareProcessStartInfo() + { + if (ForceAsAdministrator || Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin) + { + if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) + { + CoreTools.CacheUACForCurrentProcess().GetAwaiter().GetResult(); + } + process.StartInfo.FileName = CoreData.GSudoPath; + process.StartInfo.Arguments = $"\"{Source.Manager.Status.ExecutablePath}\" " + Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source)); + + } + else + { + process.StartInfo.FileName = Source.Manager.Status.ExecutablePath; + process.StartInfo.Arguments = Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source)); + } + } + + protected override Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output) + { + return Task.Run(() => Source.Manager.SourcesHelper.GetRemoveOperationVeredict(Source, ReturnCode, Output)); + } + + protected override void Initialize() + { + Metadata.OperationInformation = "Starting remove source operation for source=" + Source.Name + "with Manager=" + Source.Manager.Name; + + Metadata.Title = CoreTools.Translate("Removing source {source}", new Dictionary<string, object?> { { "source", Source.Name } }); + Metadata.Status = CoreTools.Translate("Removing source {source} from {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } });; + Metadata.SuccessTitle = CoreTools.Translate("Source removed successfully"); + Metadata.SuccessMessage = CoreTools.Translate("The source {source} was removed from {manager} successfully", + new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + Metadata.FailureTitle = CoreTools.Translate("Could not remove source"); + Metadata.FailureMessage = CoreTools.Translate("Could not remove source {source} from {manager}", + new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); + } + } +} diff --git a/src/UniGetUI.PackageEngine.Operations/UniGetUI.PackageEngine.Operations.csproj b/src/UniGetUI.PackageEngine.Operations/UniGetUI.PackageEngine.Operations.csproj new file mode 100644 index 000000000..bb637b524 --- /dev/null +++ b/src/UniGetUI.PackageEngine.Operations/UniGetUI.PackageEngine.Operations.csproj @@ -0,0 +1,42 @@ +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> + <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> + <Platforms>x64</Platforms> + <TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion> + <WindowsSdkPackageVersion>10.0.26100.53</WindowsSdkPackageVersion> + <SdkVersion>8.0.401</SdkVersion> + <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained> + <PublishSelfContained>true</PublishSelfContained> + <Authors>Martí Climent and the contributors</Authors> + <PublisherName>Martí Climent</PublisherName> + <Nullable>enable</Nullable> + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> + </PropertyGroup> + + <ItemGroup> + <ProjectReference Include="..\UniGetUI.Core.Classes\UniGetUI.Core.Classes.csproj" /> + <ProjectReference Include="..\UniGetUI.Core.Data\UniGetUI.Core.Data.csproj" /> + <ProjectReference Include="..\UniGetUI.Core.Logger\UniGetUI.Core.Logging.csproj" /> + <ProjectReference Include="..\UniGetUI.Core.Settings\UniGetUI.Core.Settings.csproj" /> + <ProjectReference Include="..\UniGetUI.Core.Tools\UniGetUI.Core.Tools.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Enums\UniGetUI.PackageEngine.Structs.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Cargo\UniGetUI.PackageEngine.Managers.Cargo.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Chocolatey\UniGetUI.PackageEngine.Managers.Chocolatey.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Dotnet\UniGetUI.PackageEngine.Managers.Dotnet.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Generic.NuGet\UniGetUI.PackageEngine.Managers.Generic.NuGet.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Npm\UniGetUI.PackageEngine.Managers.Npm.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Pip\UniGetUI.PackageEngine.Managers.Pip.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.PowerShell\UniGetUI.PackageEngine.Managers.PowerShell.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Scoop\UniGetUI.PackageEngine.Managers.Scoop.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.WinGet\UniGetUI.PackageEngine.Managers.WinGet.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.PackageLoader\UniGetUI.PackageEngine.PackageLoaders.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.PackageManagerClasses\UniGetUI.PackageEngine.Classes.csproj" /> + </ItemGroup> + + <ItemGroup> + <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> + </ItemGroup> +</Project> diff --git a/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs b/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs index 34b8fc04a..6ae940213 100644 --- a/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs +++ b/src/UniGetUI.PackageEngine.PackageEngine/PEInterface.cs @@ -11,6 +11,8 @@ using UniGetUI.PackageEngine.Managers.WingetManager; using UniGetUI.PackageEngine.Managers.VcpkgManager; using UniGetUI.PackageEngine.PackageLoader; +using System.Collections.ObjectModel; +using UniGetUI.PackageOperations; namespace UniGetUI.PackageEngine { @@ -30,7 +32,7 @@ public static class PEInterface public static readonly PowerShell PowerShell = new(); public static readonly PowerShell7 PowerShell7 = new(); public static readonly Cargo Cargo = new(); - public static readonly Vcpkg Vcpkg = new(); + public static readonly Vcpkg Vcpkg = new(); public static readonly IPackageManager[] Managers = [WinGet, Scoop, Chocolatey, Npm, Pip, Cargo, Vcpkg, DotNet, PowerShell, PowerShell7]; @@ -45,7 +47,7 @@ public static void Initialize() foreach (IPackageManager manager in Managers) { - initializeTasks.Add(Task.Run(() => manager.Initialize())); + initializeTasks.Add(Task.Run(manager.Initialize)); } Task ManagersMetaTask = Task.WhenAll(initializeTasks); diff --git a/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj b/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj index 84eab2b0d..0ae20166a 100644 --- a/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj +++ b/src/UniGetUI.PackageEngine.PackageEngine/UniGetUI.PackageEngine.PEInterface.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -37,6 +37,7 @@ <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Scoop\UniGetUI.PackageEngine.Managers.Scoop.csproj" /> <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.WinGet\UniGetUI.PackageEngine.Managers.WinGet.csproj" /> <ProjectReference Include="..\UniGetUI.PackageEngine.Managers.Vcpkg\UniGetUI.PackageEngine.Managers.Vcpkg.csproj" /> + <ProjectReference Include="..\UniGetUI.PackageEngine.Operations\UniGetUI.PackageEngine.Operations.csproj" /> <ProjectReference Include="..\UniGetUI.PackageEngine.PackageLoader\UniGetUI.PackageEngine.PackageLoaders.csproj" /> <ProjectReference Include="..\UniGetUI.PackageEngine.PackageManagerClasses\UniGetUI.PackageEngine.Classes.csproj" /> </ItemGroup> @@ -44,4 +45,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs index c81890cfd..0a8a40151 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/DiscoverablePackagesLoader.cs @@ -6,11 +6,15 @@ namespace UniGetUI.PackageEngine.PackageLoader { public class DiscoverablePackagesLoader : AbstractPackageLoader { + public static DiscoverablePackagesLoader Instance = null!; + private string QUERY_TEXT = string.Empty; public DiscoverablePackagesLoader(IEnumerable<IPackageManager> managers) - : base(managers, "DISCOVERABLE_PACKAGES", AllowMultiplePackageVersions: false, CheckedBydefault: false) - { } + : base(managers, "DISCOVERABLE_PACKAGES", AllowMultiplePackageVersions: false, CheckedBydefault: false) + { + Instance = this; + } public async Task ReloadPackages(string query) { diff --git a/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs index e0a2279dd..372c87bc8 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/InstalledPackagesLoader.cs @@ -6,9 +6,12 @@ namespace UniGetUI.PackageEngine.PackageLoader { public class InstalledPackagesLoader : AbstractPackageLoader { + public static InstalledPackagesLoader Instance = null!; + public InstalledPackagesLoader(IEnumerable<IPackageManager> managers) : base(managers, "INSTALLED_PACKAGES", AllowMultiplePackageVersions: true, CheckedBydefault: false) { + Instance = this; } protected override Task<bool> IsPackageValid(IPackage package) diff --git a/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs index 6c2033a15..e0b64ccb7 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/PackageBundlesLoader.cs @@ -7,9 +7,12 @@ namespace UniGetUI.PackageEngine.PackageLoader { public class PackageBundlesLoader : AbstractPackageLoader { + public static PackageBundlesLoader Instance = null!; + public PackageBundlesLoader(IEnumerable<IPackageManager> managers) : base(managers, "PACKAGE_BUNDLES", AllowMultiplePackageVersions: true, DisableReload: true, CheckedBydefault: false) { + Instance = this; } protected override Task<bool> IsPackageValid(IPackage package) diff --git a/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj b/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj index 5ef1a1d72..43b16adf3 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj +++ b/src/UniGetUI.PackageEngine.PackageLoader/UniGetUI.PackageEngine.PackageLoaders.csproj @@ -1,6 +1,6 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -38,4 +38,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs b/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs index 5f57e67e8..f3f86878f 100644 --- a/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs +++ b/src/UniGetUI.PackageEngine.PackageLoader/UpgradablePackagesLoader.cs @@ -9,6 +9,7 @@ namespace UniGetUI.PackageEngine.PackageLoader public class UpgradablePackagesLoader : AbstractPackageLoader { private System.Timers.Timer? UpdatesTimer; + public static UpgradablePackagesLoader Instance = null!; /// <summary> /// The collection of packages with updates ignored @@ -18,6 +19,7 @@ public class UpgradablePackagesLoader : AbstractPackageLoader public UpgradablePackagesLoader(IEnumerable<IPackageManager> managers) : base(managers, "DISCOVERABLE_PACKAGES", AllowMultiplePackageVersions: false, CheckedBydefault: !Settings.Get("DisableSelectingUpdatesByDefault")) { + Instance = this; FinishedLoading += (_, _) => StartAutoCheckTimeout(); } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs index ea9d428d1..ea10569a8 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Manager/Helpers/PackagePkgOperationHelper.cs @@ -30,21 +30,12 @@ public IEnumerable<string> GetParameters( IInstallationOptions options, OperationType operation) { - try - { - var parameters = _getOperationParameters(package, options, operation); - Logger.Info( - $"Loaded operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}: " + - string.Join(' ', parameters)); - return parameters; - } - catch (Exception ex) - { - Logger.Error( - $"A fatal error ocurred while loading operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}"); - Logger.Error(ex); - return []; - } + var parameters = _getOperationParameters(package, options, operation); + Logger.Info( + $"Loaded operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}: " + + string.Join(' ', parameters)); + return parameters; + } public OperationVeredict GetResult( @@ -53,22 +44,13 @@ public OperationVeredict GetResult( IEnumerable<string> processOutput, int returnCode) { - try - { - if (returnCode is 999 && processOutput.Last() == "Error: The operation was canceled by the user.") - { - Logger.Warn("Elevator [or GSudo] UAC prompt was canceled, not showing error message..."); - return OperationVeredict.Canceled; - } - return _getOperationResult(package, operation, processOutput, returnCode); - } - catch (Exception ex) + if (returnCode is 999 && (!processOutput.Any() || processOutput.Last() == "Error: The operation was canceled by the user.")) { - Logger.Error( - $"A fatal error ocurred while loading operation parameters for package id={package.Id} on manager {Manager.Name} and operation {operation}"); - Logger.Error(ex); - return OperationVeredict.Failed; + Logger.Warn("Elevator [or GSudo] UAC prompt was canceled, not showing error message..."); + return OperationVeredict.Canceled; } + + return _getOperationResult(package, operation, processOutput, returnCode); } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj index 15ecac6fb..985eb24ea 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> @@ -34,4 +34,8 @@ <ItemGroup> <Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" /> </ItemGroup> + + <ItemGroup> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> + </ItemGroup> </Project> diff --git a/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj b/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj index a586277e3..60a30f5c7 100644 --- a/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj +++ b/src/UniGetUI.PackageEngine.Serializable/UniGetUI.PackageEngine.Serializable.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> diff --git a/src/UniGetUI.sln b/src/UniGetUI.sln index 279e0f714..313b3cffd 100644 --- a/src/UniGetUI.sln +++ b/src/UniGetUI.sln @@ -96,6 +96,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniGetUI.PackageEngine.Mana EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniGetUI.PackageEngine.Managers.Vcpkg", "UniGetUI.PackageEngine.Managers.Vcpkg\UniGetUI.PackageEngine.Managers.Vcpkg.csproj", "{E337A71E-3C30-4315-B8F1-57CBC5CF50A6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniGetUI.PackageEngine.Operations", "UniGetUI.PackageEngine.Operations\UniGetUI.PackageEngine.Operations.csproj", "{727866B8-BBD5-43B9-933A-78199F65429C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -250,6 +252,10 @@ Global {E337A71E-3C30-4315-B8F1-57CBC5CF50A6}.Debug|x64.Build.0 = Debug|x64 {E337A71E-3C30-4315-B8F1-57CBC5CF50A6}.Release|x64.ActiveCfg = Release|x64 {E337A71E-3C30-4315-B8F1-57CBC5CF50A6}.Release|x64.Build.0 = Release|x64 + {727866B8-BBD5-43B9-933A-78199F65429C}.Debug|x64.ActiveCfg = Debug|x64 + {727866B8-BBD5-43B9-933A-78199F65429C}.Debug|x64.Build.0 = Debug|x64 + {727866B8-BBD5-43B9-933A-78199F65429C}.Release|x64.ActiveCfg = Release|x64 + {727866B8-BBD5-43B9-933A-78199F65429C}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -294,6 +300,7 @@ Global {C396E5F6-C6D9-465D-9903-7E33D0841E6A} = {7940E867-EEBA-4AFD-9904-1536F003239C} {54DA0549-366F-4E70-B5D1-0B8891D0A2A5} = {95168D0B-1B2C-4295-B6D4-D5BAF781B9FA} {E337A71E-3C30-4315-B8F1-57CBC5CF50A6} = {95168D0B-1B2C-4295-B6D4-D5BAF781B9FA} + {727866B8-BBD5-43B9-933A-78199F65429C} = {7940E867-EEBA-4AFD-9904-1536F003239C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D044BB14-0B37-47E5-A579-8B30FCBA1F9F} diff --git a/src/UniGetUI/App.xaml.cs b/src/UniGetUI/App.xaml.cs index 3d315deff..abf930372 100644 --- a/src/UniGetUI/App.xaml.cs +++ b/src/UniGetUI/App.xaml.cs @@ -1,7 +1,9 @@ +using System.Collections.ObjectModel; using System.Diagnostics; using System.Text.RegularExpressions; using Windows.ApplicationModel.Activation; using CommunityToolkit.WinUI.Helpers; +using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using UniGetUI.Core.Data; @@ -15,26 +17,64 @@ using UniGetUI.PackageEngine.Operations; using Microsoft.Windows.AppLifecycle; using Microsoft.Windows.AppNotifications; +using UniGetUI.Controls.OperationWidgets; using UniGetUI.PackageEngine.Interfaces; +using AbstractOperation = UniGetUI.PackageOperations.AbstractOperation; using LaunchActivatedEventArgs = Microsoft.UI.Xaml.LaunchActivatedEventArgs; namespace UniGetUI { public partial class MainApp { - public class __tooltip_options + public static DispatcherQueue Dispatcher = null!; + + public static class Tooltip { - private int _errors_occurred; - public int ErrorsOccurred { get { return _errors_occurred; } set { _errors_occurred = value; Instance.MainWindow.UpdateSystemTrayStatus(); } } - private bool _restart_required; - public bool RestartRequired { get { return _restart_required; } set { _restart_required = value; Instance.MainWindow.UpdateSystemTrayStatus(); } } - private int _operations_in_progress; - public int OperationsInProgress { get { return _operations_in_progress; } set { _operations_in_progress = value; Instance.MainWindow.UpdateSystemTrayStatus(); } } - private int _available_updates; - public int AvailableUpdates { get { return _available_updates; } set { _available_updates = value; Instance.MainWindow.UpdateSystemTrayStatus(); } } + private static int _errors_occurred; + public static int ErrorsOccurred + { + get => _errors_occurred; + set { _errors_occurred = value; Instance?.MainWindow?.UpdateSystemTrayStatus(); } + } + + private static bool _restart_required; + public static bool RestartRequired + { + get => _restart_required; + set { _restart_required = value; Instance?.MainWindow?.UpdateSystemTrayStatus(); } + } + + private static int _operations_in_progress; + public static int OperationsInProgress + { + get => _operations_in_progress; + set { _operations_in_progress = value; Instance?.MainWindow?.UpdateSystemTrayStatus(); } + } + + private static int _available_updates; + public static int AvailableUpdates + { + get => _available_updates; + set { _available_updates = value; Instance?.MainWindow?.UpdateSystemTrayStatus(); } + } } - public List<AbstractOperation> OperationQueue = []; + public static class Operations + { + public static ObservableCollection<OperationControl> _operationList = new(); + + public static void Add(AbstractOperation op) + => _operationList.Add(new(op)); + + public static void Remove(OperationControl control) + => _operationList.Remove(control); + + public static void Remove(AbstractOperation op) + { + foreach(var control in _operationList.Where(x => x.Operation == op).ToArray()) + _operationList.Remove(control); + } + } public bool RaiseExceptionAsFatal = true; @@ -44,13 +84,13 @@ public class __tooltip_options private readonly BackgroundApiRunner BackgroundApi = new(); public static MainApp Instance = null!; - public __tooltip_options TooltipStatus = new(); public MainApp() { try { Instance = this; + Dispatcher = DispatcherQueue.GetForCurrentThread(); InitializeComponent(); @@ -212,11 +252,6 @@ private void RegisterNotificationService() } } - public void AddOperationToList(AbstractOperation operation) - { - MainWindow.NavigationPage.OperationStackPanel.Children.Add(operation); - } - /// <summary> /// Background component loader /// </summary> diff --git a/src/UniGetUI/Controls/OperationWidgets/OperationBadge.cs b/src/UniGetUI/Controls/OperationWidgets/OperationBadge.cs new file mode 100644 index 000000000..e753fe008 --- /dev/null +++ b/src/UniGetUI/Controls/OperationWidgets/OperationBadge.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UniGetUI.Interface.Enums; + +namespace UniGetUI.Controls.OperationWidgets; +public class OperationBadge +{ + public string Tooltip; + public string PrimaryBanner; + public string SecondaryBanner; + public bool SecondaryBannerVisible; + public IconType Icon; + + public OperationBadge(string tooltip, IconType icon, string primaryBanner, string? secondaryBanner = null) + { + Tooltip = tooltip; + Icon = icon; + PrimaryBanner = primaryBanner; + if(secondaryBanner is null || secondaryBanner == String.Empty) + { + SecondaryBannerVisible = false; + SecondaryBanner = ""; + } + else + { + SecondaryBanner = secondaryBanner; + SecondaryBannerVisible = true; + } + } +} diff --git a/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs b/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs new file mode 100644 index 000000000..faf7304ad --- /dev/null +++ b/src/UniGetUI/Controls/OperationWidgets/OperationControl.cs @@ -0,0 +1,579 @@ +using System.ComponentModel; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices.JavaScript; +using Windows.Devices.Sensors; +using Windows.UI; +using Microsoft.UI.Dispatching; +using Microsoft.UI.Input; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Media; +using Microsoft.Windows.AppNotifications; +using Microsoft.Windows.AppNotifications.Builder; +using UniGetUI.Core.Logging; +using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Tools; +using UniGetUI.Interface.Enums; +using UniGetUI.PackageEngine.Classes.Packages.Classes; +using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageOperations; +using UniGetUI.Pages.DialogPages; +using CommunityToolkit.WinUI; +using Microsoft.UI.Xaml.Controls; +using UniGetUI.Interface.Widgets; +using UniGetUI.PackageEngine.Operations; +using System.Collections.ObjectModel; + +namespace UniGetUI.Controls.OperationWidgets; + +public class OperationControl: INotifyPropertyChanged +{ + public AbstractOperation Operation; + private bool ErrorTooltipShown; + public BetterMenu OpMenu; + public OperationStatus? MenuStateOnLoaded; + public ObservableCollection<OperationBadge> Badges = new(); + + public OperationControl(AbstractOperation operation) + { + OpMenu = new BetterMenu(); + Operation = operation; + Operation.LogLineAdded += (_, values) => LiveLine = values.Item1; + Operation.StatusChanged += OnOperationStatusChanged; + Operation.OperationStarting += OnOperationStarting; + Operation.OperationFinished += OnOperationFinished; + Operation.OperationFailed += OnOperationFailed; + Operation.OperationSucceeded += OnOperationSucceeded; + + Operation.BadgesChanged += (_, badges) => + { + Badges.Clear(); + if (badges.AsAdministrator) Badges.Add(new( + CoreTools.Translate("Administrator privileges"), + IconType.UAC, + CoreTools.Translate("This operation is running with administrator privileges."), + "" + )); + + if (badges.Interactive) Badges.Add(new( + CoreTools.Translate("Interactive operation"), + IconType.Interactive, + CoreTools.Translate("This operation is running interactively."), + CoreTools.Translate("You will likely need to interact with the installer.") + )); + + if (badges.SkipHashCheck) Badges.Add(new( + CoreTools.Translate("Integrity checks skipped"), + IconType.Checksum, + CoreTools.Translate("Integrity checks will not be performed during this operation"), + CoreTools.Translate("This is not recommended.") + " " + CoreTools.Translate("Proceed at your own risk.") + )); + + /*if (badges.Scope is not null) + { + if (badges.Scope is PackageScope.Local) + Badges.Add(new( + CoreTools.Translate ("Local operation"), + IconType.Home, + CoreTools.Translate ("The changes performed by this operation will affect only the current user."), + "" + )); + else + Badges.Add(new( + CoreTools.Translate ("Global operation"), + IconType.LocalPc, + CoreTools.Translate ("The changes performed by this operation may affect other users on this machine."), + "" + )); + }*/ + }; + + _title = Operation.Metadata.Title; + _liveLine = operation.GetOutput().Any()? operation.GetOutput().Last().Item1 : CoreTools.Translate("Please wait..."); + _buttonText = ""; + OnOperationStatusChanged(this, operation.Status); + LoadIcon(); + if (!operation.Started) + _ = operation.MainThread(); + } + + private void OnOperationStarting(object? sender, EventArgs e) + { + ShowProgressToast(); + MainApp.Tooltip.OperationsInProgress++; + MainApp.Instance.MainWindow.NavigationPage.OperationList.SmoothScrollIntoViewWithItemAsync(this); + } + + private async void OnOperationSucceeded(object? sender, EventArgs e) + { + // Success notification + ShowSuccessToast(); + + // Handle UAC for batches + if (Settings.Get("DoCacheAdminRightsForBatches")) + { + bool isOpRunning = false; + foreach (var op in MainApp.Operations._operationList) + { + if (op.Operation.Status is OperationStatus.Running or OperationStatus.InQueue) + { + isOpRunning = true; + break; + } + } + if(!isOpRunning) await CoreTools.ResetUACForCurrentProcess(); + } + + // Clean succesful operation from list + if(!Settings.Get("MaintainSuccessfulInstalls")) + await TimeoutAndClose(); + } + + private void OnOperationFailed(object? sender, EventArgs e) + { + ShowErrorToast(); + } + + private void OnOperationFinished(object? sender, EventArgs e) + { + // Remove progress notification (if any) + AppNotificationManager.Default.RemoveByTagAsync(Operation.Metadata.Identifier + "progress"); + MainApp.Tooltip.OperationsInProgress--; + + // Generate process output + List<string> rawOutput = new(); + rawOutput.Add(" "); + rawOutput.Add("▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"); + foreach (var line in Operation.GetOutput()) + { + rawOutput.Add(line.Item1); + } + + string[] oldHistory = Settings.GetValue("OperationHistory").Split("\n"); + if (oldHistory.Length > 300) oldHistory = oldHistory.Take(300).ToArray(); + + List<string> newHistory = [.. rawOutput, .. oldHistory]; + Settings.SetValue("OperationHistory", string.Join('\n', newHistory)); + rawOutput.Add(""); + rawOutput.Add(""); + rawOutput.Add(""); + } + + private async void LoadIcon() + { + Icon = await Operation.GetOperationIcon(); + } + + private void OnOperationStatusChanged(object? sender, OperationStatus newStatus) + { + switch (newStatus) + { + case OperationStatus.InQueue: + ProgressIndeterminate = false; + ProgressValue = 0; + ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBrush"]; + Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; + ButtonText = CoreTools.Translate("Cancel"); + break; + case OperationStatus.Running: + ProgressIndeterminate = true; + ButtonText = CoreTools.Translate("Cancel"); + ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorAttentionBrush"]; + Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorAttentionBackgroundBrush"]; + break; + case OperationStatus.Succeeded: + ProgressIndeterminate = false; + ProgressValue = 100; + ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorSuccessBrush"]; + Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; + ButtonText = CoreTools.Translate("Close"); + break; + case OperationStatus.Failed: + ProgressIndeterminate = false; + ProgressValue = 100; + ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]; + Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; + ButtonText = CoreTools.Translate("Close"); + break; + case OperationStatus.Canceled: + ProgressIndeterminate = false; + ProgressValue = 100; + ProgressForeground = (SolidColorBrush)Application.Current.Resources["SystemFillColorCautionBrush"]; + Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; + ButtonText = CoreTools.Translate("Close"); + break; + default: + throw new ArgumentOutOfRangeException(nameof(newStatus), newStatus, null); + } + + // Handle error tooltip counter + if (!ErrorTooltipShown && newStatus is OperationStatus.Failed) + { + MainApp.Tooltip.ErrorsOccurred++; + ErrorTooltipShown = true; + } + else if (ErrorTooltipShown && newStatus is not OperationStatus.Failed) + { + MainApp.Tooltip.ErrorsOccurred--; + ErrorTooltipShown = false; + } + } + + public async Task LiveLineClick() + { + if (Operation.Status is OperationStatus.Failed or OperationStatus.Canceled) + { + await DialogHelper.ShowOperationFailedDialog(Operation, this); + } + else + { + await DialogHelper.ShowLiveLogDialog(Operation); + } + } + + public void ButtonClick() + { + if (Operation.Status is OperationStatus.Running or OperationStatus.InQueue) + { + Operation.Cancel(); + } + else + { + Close(); + } + } + + public void LoadMenu() + { + if (MenuStateOnLoaded == Operation.Status) return; + MenuStateOnLoaded = Operation.Status; + + // Reset menu + OpMenu.Items.Clear(); + + // Load operation-specific entries + var normalOptions = GetOperationOptions(); + if (normalOptions.Any()) + { + foreach(var item in normalOptions) + OpMenu.Items.Add(item); + + OpMenu.Items.Add(new MenuFlyoutSeparator()); + } + + if (Operation.Status is OperationStatus.InQueue) + { + var skipQueue = new BetterMenuItem() { Text = CoreTools.Translate("Run now"), Icon = new FontIcon(){Glyph = "\uE768"} }; + skipQueue.Click += (_, _) => Operation.SkipQueue(); + OpMenu.Items.Add(skipQueue); + + var putNext = new BetterMenuItem() { Text = CoreTools.Translate("Run next"), Icon = new FontIcon(){Glyph = "\uEB9D"} }; + putNext.Click += (_, _) => Operation.RunNext(); + OpMenu.Items.Add(putNext); + + var putLast = new BetterMenuItem() { Text = CoreTools.Translate("Run last"), Icon = new FontIcon(){Glyph = "\uEB9E"} }; + putLast.Click += (_, _) => Operation.BackOfTheQueue(); + OpMenu.Items.Add(putLast); + + OpMenu.Items.Add(new MenuFlyoutSeparator()); + } + + // Create Cancel/Retry buttons + if (Operation.Status is OperationStatus.InQueue or OperationStatus.Running) + { + var cancel = new BetterMenuItem() { Text = CoreTools.Translate("Cancel"), IconName = IconType.Cross, }; + cancel.Click += (_, _) => Operation.Cancel(); + OpMenu.Items.Add(cancel); + } + else + { + var retry = new BetterMenuItem() { Text = CoreTools.Translate("Retry"), IconName = IconType.Reload, }; + retry.Click += (_, _) => Operation.Retry(AbstractOperation.RetryMode.Retry); + OpMenu.Items.Add(retry); + + // Add extra retry options, if applicable + var extraRetry = GetRetryOptions(() => { }); + if (extraRetry.Any()) + { + OpMenu.Items.Add(new MenuFlyoutSeparator()); + + foreach(var item in extraRetry) + OpMenu.Items.Add(item); + } + } + } + + private async Task TimeoutAndClose() + { + var oldStatus = Operation.Status; + await Task.Delay(5000); + + if (Operation.Status == oldStatus) + Close(); + } + + public void Close() + { + if (ErrorTooltipShown && Operation.Status is OperationStatus.Failed) + { + MainApp.Tooltip.ErrorsOccurred--; + ErrorTooltipShown = false; + } + + MainApp.Operations._operationList.Remove(this); + while(AbstractOperation.OperationQueue.Remove(Operation)); + + if (MainApp.Operations._operationList.Count == 0 + && DesktopShortcutsDatabase.GetUnknownShortcuts().Any() + && Settings.Get("AskToDeleteNewDesktopShortcuts")) + { + _ = DialogHelper.HandleNewDesktopShortcuts(); + } + } + + private string _buttonText; + public string ButtonText + { + get => _buttonText; + set { _buttonText = value; OnPropertyChanged(); } + } + + private string _liveLine; + public string LiveLine + { + get => _liveLine; + set { _liveLine = value; OnPropertyChanged(); } + } + + private string _title; + public string Title + { + get => _title; + set { _title = value; OnPropertyChanged(); } + } + + private bool _progressIndeterminate; + public bool ProgressIndeterminate + { + get => _progressIndeterminate; + set { _progressIndeterminate = value; OnPropertyChanged(); } + } + + private int _progressValue; + public int ProgressValue + { + get => _progressValue; + set { _progressValue = value; OnPropertyChanged(); } + } + + private Uri _icon = new("ms-appx:///Assets/images/package_color.png"); + public Uri Icon + { + get => _icon; + set { _icon = value; OnPropertyChanged(); } + } + + private SolidColorBrush _background = new(Color.FromArgb(0, 0, 0, 0)); + public SolidColorBrush Background + { + get => _background; + set { _background = value; OnPropertyChanged(); } + } + + private SolidColorBrush _progressForeground = new(Color.FromArgb(0, 0, 0, 0)); + public SolidColorBrush ProgressForeground + { + get => _progressForeground; + set { _progressForeground = value; OnPropertyChanged(); } + } + + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + MainApp.Dispatcher.TryEnqueue(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName))); + } + + + private void ShowProgressToast() + { + if (Settings.AreProgressNotificationsDisabled()) + return; + + try + { + AppNotificationManager.Default.RemoveByTagAsync(Operation.Metadata.Identifier + "progress"); + AppNotificationBuilder builder = new AppNotificationBuilder() + .SetScenario(AppNotificationScenario.Default) + .SetTag(Operation.Metadata.Identifier + "progress") + .AddProgressBar(new AppNotificationProgressBar() + .SetStatus(CoreTools.Translate("Please wait...")) + .SetValueStringOverride("\u2003") + .SetTitle(Operation.Metadata.Status) + .SetValue(1.0)) + .AddArgument("action", NotificationArguments.Show); + AppNotification notification = builder.BuildNotification(); + notification.ExpiresOnReboot = true; + notification.SuppressDisplay = true; + AppNotificationManager.Default.Show(notification); + } + catch (Exception ex) + { + Logger.Error("Failed to show toast notification"); + Logger.Error(ex); + } + } + + private void ShowSuccessToast() + { + if (Settings.AreSuccessNotificationsDisabled()) + return; + + try + { + AppNotificationManager.Default.RemoveByTagAsync(Operation.Metadata.Identifier); + AppNotificationBuilder builder = new AppNotificationBuilder() + .SetScenario(AppNotificationScenario.Default) + .SetTag(Operation.Metadata.Identifier) + .AddText(Operation.Metadata.SuccessTitle) + .AddText(Operation.Metadata.SuccessMessage) + .AddArgument("action", NotificationArguments.Show); + AppNotification notification = builder.BuildNotification(); + notification.ExpiresOnReboot = true; + AppNotificationManager.Default.Show(notification); + } + catch (Exception ex) + { + Logger.Error("Failed to show toast notification"); + Logger.Error(ex); + } + } + + private void ShowErrorToast() + { + if (Settings.AreErrorNotificationsDisabled()) + return; + + try + { + AppNotificationManager.Default.RemoveByTagAsync(Operation.Metadata.Identifier); + AppNotificationBuilder builder = new AppNotificationBuilder() + .SetScenario(AppNotificationScenario.Urgent) + .SetTag(Operation.Metadata.Identifier) + .AddText(Operation.Metadata.FailureTitle) + .AddText(Operation.Metadata.FailureMessage) + .AddArgument("action", NotificationArguments.Show); + AppNotification notification = builder.BuildNotification(); + notification.ExpiresOnReboot = true; + AppNotificationManager.Default.Show(notification); + } + catch (Exception ex) + { + Logger.Error("Failed to show toast notification"); + Logger.Error(ex); + } + } + + public List<BetterMenuItem> GetRetryOptions(Action callback) + { + var retryOptionsMenu = new List<BetterMenuItem>(); + + if (Operation is SourceOperation sourceOp && !sourceOp.ForceAsAdministrator) + { + var adminButton = new BetterMenuItem() { Text = CoreTools.Translate("Retry as administrator") }; + adminButton.IconName = IconType.UAC; + adminButton.Click += (_, _) => + { + callback(); + Operation.Retry(AbstractOperation.RetryMode.Retry_AsAdmin); + }; + retryOptionsMenu.Add(adminButton); + } + else if (Operation is PackageOperation packageOp) + { + if (!packageOp.Options.RunAsAdministrator && packageOp.Package.Manager.Capabilities.CanRunAsAdmin) + { + var adminButton = new BetterMenuItem() { Text = CoreTools.Translate("Retry as administrator") }; + adminButton.IconName = IconType.UAC; + adminButton.Click += (_, _) => + { + callback(); + Operation.Retry(AbstractOperation.RetryMode.Retry_AsAdmin); + }; + retryOptionsMenu.Add(adminButton); + } + + if (!packageOp.Options.InteractiveInstallation && + packageOp.Package.Manager.Capabilities.CanRunInteractively) + { + var interactiveButton = new BetterMenuItem() { Text = CoreTools.Translate("Retry interactively") }; + interactiveButton.IconName = IconType.Interactive; + interactiveButton.Click += (_, _) => + { + callback(); + Operation.Retry(AbstractOperation.RetryMode.Retry_Interactive); + }; + retryOptionsMenu.Add(interactiveButton); + } + + if (!packageOp.Options.SkipHashCheck && packageOp.Package.Manager.Capabilities.CanSkipIntegrityChecks) + { + var skiphashButton = + new BetterMenuItem() { Text = CoreTools.Translate("Retry skipping integrity checks") }; + skiphashButton.IconName = IconType.Checksum; + skiphashButton.Click += (_, _) => + { + callback(); + Operation.Retry(AbstractOperation.RetryMode.Retry_SkipIntegrity); + }; + retryOptionsMenu.Add(skiphashButton); + } + } + + return retryOptionsMenu; + } + + public List<BetterMenuItem> GetOperationOptions() + { + var optionsMenu = new List<BetterMenuItem>(); + if (Operation is PackageOperation packageOp) + { + var details = new BetterMenuItem() { Text = CoreTools.Translate("Package details") }; + details.IconName = IconType.Info_Round; + details.Click += (_, _) => + { + DialogHelper.ShowPackageDetails(packageOp.Package, OperationType.None); + }; + optionsMenu.Add(details); + + + var installationSettings = new BetterMenuItem() { Text = CoreTools.Translate("Installation options") }; + installationSettings.IconName = IconType.Options; + installationSettings.Click += (_, _) => + { + _ = DialogHelper.ShowInstallatOptions_Continue(packageOp.Package, OperationType.None); + }; + optionsMenu.Add(installationSettings); + + string? location = packageOp.Package.Manager.DetailsHelper.GetInstallLocation(packageOp.Package); + if (location is not null && Directory.Exists(location)) + { + var openLocation = new BetterMenuItem() { Text = CoreTools.Translate("Open install location") }; + openLocation.IconName = IconType.OpenFolder; + openLocation.Click += (_, _) => + { + System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo() { + FileName = location, + UseShellExecute = true, + Verb = "open" + }); + + }; + optionsMenu.Add(openLocation); + } + + } + + return optionsMenu; + } +} diff --git a/src/UniGetUI/Controls/OperationWidgets/OperationControl.xaml b/src/UniGetUI/Controls/OperationWidgets/OperationControl.xaml deleted file mode 100644 index 538504697..000000000 --- a/src/UniGetUI/Controls/OperationWidgets/OperationControl.xaml +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<UserControl - x:Class="UniGetUI.PackageEngine.Operations.AbstractOperation" - xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - mc:Ignorable="d" SizeChanged="ResizeEvent" Margin="0,8,0,0"> - - <Grid ColumnSpacing="6" RowSpacing="6" Padding="8" x:Name="MainGrid"> - <Grid.Style> - <Style TargetType="Grid"> - <Setter Property="Background" Value="{ThemeResource SystemFillColorNeutralBackgroundBrush}"/> - <Setter Property="BorderBrush" Value="{StaticResource ExpanderContentBorderBrush}"/> - <Setter Property="BorderThickness" Value="1"/> - <Setter Property="CornerRadius" Value="8"/> - <Setter Property="Margin" Value="0"/> - <Setter Property="Padding" Value="0"/> - </Style> - </Grid.Style> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="40" /> - <ColumnDefinition Width="Auto"/> - <ColumnDefinition Width="*" /> - <ColumnDefinition Width="150" /> - </Grid.ColumnDefinitions> - <Grid.RowDefinitions> - <RowDefinition Height="Auto"/> - </Grid.RowDefinitions> - <Grid.Resources> - <ResourceDictionary> - <Style TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}"> - <Setter Property="Height" Value="32"/> - <Setter Property="CornerRadius" Value="2"/> - <Setter Property="BorderThickness" Value="0"/> - </Style> - </ResourceDictionary> - </Grid.Resources> - <Image Grid.Column="0" VerticalAlignment="Center" Name="PackageIcon" Width="32" Height="24" Margin="0"/> - <TextBlock Name="InfoTextBlock" Grid.Column="1" VerticalAlignment="Center"/> - <Button Grid.Column="2" VerticalAlignment="Center" Name="OutputViewewBlock" HorizontalAlignment="Stretch" - FontFamily="Consolas" HorizontalContentAlignment="Left" CornerRadius="5"/> - <Border Grid.Column="2" Margin="0,0,0,0" Height="12" VerticalAlignment="Bottom" CornerRadius="0,0,6,6"> - <ProgressBar Name="ProgressIndicator" IsIndeterminate="True" VerticalAlignment="Bottom" Margin="0,0,0,-2" CornerRadius="0,0,6,6" Height="6" Maximum="100" Value="100"/> - </Border> - <Button Grid.Column="3" VerticalAlignment="Center" Name="ActionButton" HorizontalAlignment="Stretch" CornerRadius="5"/> - - </Grid> -</UserControl> diff --git a/src/UniGetUI/Controls/OperationWidgets/OperationControl.xaml.cs b/src/UniGetUI/Controls/OperationWidgets/OperationControl.xaml.cs deleted file mode 100644 index 6fe344a13..000000000 --- a/src/UniGetUI/Controls/OperationWidgets/OperationControl.xaml.cs +++ /dev/null @@ -1,626 +0,0 @@ -using System.Collections.ObjectModel; -using System.Diagnostics; -using ExternalLibraries.Clipboard; -using Microsoft.UI; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Documents; -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Media.Imaging; -using UniGetUI.Core.Logging; -using UniGetUI.Core.SettingsEngine; -using UniGetUI.Core.Tools; -using UniGetUI.PackageEngine.Classes.Packages.Classes; -using UniGetUI.PackageEngine.Enums; -using UniGetUI.Pages.DialogPages; - -// To learn more about WinUI, the WinUI project structure, -// and more about our project templates, see: http://aka.ms/winui-project-info. - -namespace UniGetUI.PackageEngine.Operations -{ - public abstract partial class AbstractOperation : UserControl - { - protected enum AfterFinshAction - { - TimeoutClose, - ManualClose, - Retry, - } - - private enum WidgetLayout - { - Default, - Compact, - } - - public struct OutputLine - { - public enum LineType - { - Header, - STDOUT, - STDERR - } - - readonly public LineType Type; - readonly public string Contents; - - public OutputLine(string contents, LineType type) - { - Contents = contents; - Type = type; - } - } - - private OperationStatus __status = OperationStatus.Pending; - private bool IsDialogOpen; - - private WidgetLayout __layout_mode; - private WidgetLayout LayoutMode - { - set - { - if (value == WidgetLayout.Compact) - { - Grid.SetColumn(OutputViewewBlock, 0); - Grid.SetColumnSpan(OutputViewewBlock, 4); - Grid.SetRow(OutputViewewBlock, 1); - Grid.SetColumn(ProgressIndicator, 0); - Grid.SetColumnSpan(ProgressIndicator, 4); - Grid.SetRow(ProgressIndicator, 1); - if (MainGrid.RowDefinitions.Count < 2) - { - MainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); - } - } - else - { - Grid.SetColumn(OutputViewewBlock, 2); - Grid.SetColumnSpan(OutputViewewBlock, 1); - Grid.SetRow(OutputViewewBlock, 0); - Grid.SetColumn(ProgressIndicator, 2); - Grid.SetColumnSpan(ProgressIndicator, 1); - Grid.SetRow(ProgressIndicator, 0); - if (MainGrid.RowDefinitions.Count >= 2) - { - MainGrid.RowDefinitions.RemoveAt(1); - } - } - __layout_mode = value; - } - get { return __layout_mode; } - } - - protected string ButtonText - { - set => ActionButton.Content = value; - } - protected string LineInfoText - { - set => OutputViewewBlock.Content = value; - } - protected Uri IconSource - { - set => PackageIcon.Source = new BitmapImage(value); - } - protected string OperationTitle - { - set => InfoTextBlock.Text = value; - } - -#pragma warning disable CS0067 - protected event EventHandler<OperationCanceledEventArgs>? CancelRequested; - protected event EventHandler<OperationCanceledEventArgs>? CloseRequested; -#pragma warning restore CS0067 - protected Process Process = new(); - - protected ObservableCollection<OutputLine> ProcessOutput = []; - - protected string[] RawProcessOutput - { - get - { - List<string> tempOutput = new(); - foreach (var line in ProcessOutput) - { - if(line.Type is not OutputLine.LineType.Header) - tempOutput.Add(line.Contents); - } - - return tempOutput.ToArray(); - } - } - - protected readonly ContentDialog OutputDialog = new(); - private readonly ScrollViewer LiveOutputScrollBar = new(); - private readonly RichTextBlock LiveOutputTextBlock = new(); - - public OperationStatus Status - { - get => __status; - set - { - MainGrid.RequestedTheme = MainApp.Instance.MainWindow.ContentRoot.RequestedTheme; - __status = value; - switch (__status) - { - case OperationStatus.Pending: - ProgressIndicator.IsIndeterminate = false; - ProgressIndicator.Foreground = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBrush"]; - MainGrid.Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; - ButtonText = CoreTools.Translate("Cancel"); - break; - - case OperationStatus.Running: - ProgressIndicator.IsIndeterminate = true; - ProgressIndicator.Foreground = (SolidColorBrush)Application.Current.Resources["SystemFillColorAttentionBrush"]; - MainGrid.Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorAttentionBackgroundBrush"]; - ButtonText = CoreTools.Translate("Cancel"); - break; - - case OperationStatus.Succeeded: - ProgressIndicator.Foreground = (SolidColorBrush)Application.Current.Resources["SystemFillColorSuccessBrush"]; - MainGrid.Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; - ProgressIndicator.IsIndeterminate = false; - ButtonText = CoreTools.Translate("Close"); - break; - - case OperationStatus.Failed: - ProgressIndicator.IsIndeterminate = false; - ProgressIndicator.Foreground = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]; - MainGrid.Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBackgroundBrush"]; - ButtonText = CoreTools.Translate("Close"); - break; - - case OperationStatus.Canceled: - ProgressIndicator.IsIndeterminate = false; - ProgressIndicator.Foreground = (SolidColorBrush)Application.Current.Resources["SystemFillColorCautionBrush"]; - MainGrid.Background = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBackgroundBrush"]; - ButtonText = CoreTools.Translate("Close"); - LineInfoText = CoreTools.Translate("Operation canceled by user"); - break; - } - } - } - protected bool IGNORE_PARALLEL_OPERATION_SETTINGS; - public AbstractOperation(bool IgnoreParallelInstalls = false) - { - IGNORE_PARALLEL_OPERATION_SETTINGS = IgnoreParallelInstalls; - - InitializeComponent(); - - OutputDialog = new ContentDialog - { - Style = (Style)Application.Current.Resources["DefaultContentDialogStyle"], - XamlRoot = XamlRoot - }; - OutputDialog.Resources["ContentDialogMaxWidth"] = 1200; - OutputDialog.Resources["ContentDialogMaxHeight"] = 1000; - - LiveOutputTextBlock = new RichTextBlock - { - Margin = new Thickness(8), - FontFamily = new FontFamily("Consolas") - }; - - LiveOutputScrollBar = new ScrollViewer - { - CornerRadius = new CornerRadius(6), - Background = (Brush)Application.Current.Resources["ApplicationPageBackgroundThemeBrush"], - Height = 400, - Width = 600, - Content = LiveOutputTextBlock - }; - - OutputDialog.Title = CoreTools.Translate("Live output"); - OutputDialog.CloseButtonText = CoreTools.Translate("Close"); - - OutputDialog.SizeChanged += (_, _) => - { - if (!IsDialogOpen) - { - return; - } - - LiveOutputScrollBar.MinWidth = MainApp.Instance.MainWindow.NavigationPage.ActualWidth - 400; - LiveOutputScrollBar.MinHeight = MainApp.Instance.MainWindow.NavigationPage.ActualHeight - 200; - }; - - OutputDialog.Content = LiveOutputScrollBar; - - ProcessOutput.CollectionChanged += async (_, _) => - { - if (!IsDialogOpen) - { - return; - } - - LiveOutputTextBlock.Blocks.Clear(); - Paragraph p = new(); - foreach (OutputLine line in ProcessOutput) - { - if (line.Type is OutputLine.LineType.STDOUT) - p.Inlines.Add(new Run { Text = line.Contents + "\x0a" }); - else if (line.Type is OutputLine.LineType.Header) - // TODO: Theme-aware colorss - p.Inlines.Add(new Run { Text = line.Contents + "\x0a", Foreground = new SolidColorBrush(Colors.Azure)}); - else - p.Inlines.Add(new Run { Text = line.Contents + "\x0a", Foreground = new SolidColorBrush(Colors.Red)}); - } - LiveOutputTextBlock.Blocks.Add(p); - await Task.Delay(100); - LiveOutputScrollBar.ScrollToVerticalOffset(LiveOutputScrollBar.ScrollableHeight); - }; - - Status = OperationStatus.Pending; - - ActionButton.Click += ActionButtonClicked; - OutputViewewBlock.Click += (_, _) => - { - OpenLiveViewDialog(); - }; - } - - public async void OpenLiveViewDialog() - { - OutputDialog.XamlRoot = XamlRoot; - LiveOutputTextBlock.Blocks.Clear(); - Paragraph p = new() - { - LineHeight = 4.8 - }; - foreach (OutputLine line in ProcessOutput) - { - if (line.Type is OutputLine.LineType.STDOUT) - p.Inlines.Add(new Run { Text = line.Contents + "\x0a" }); - else if (line.Type is OutputLine.LineType.Header) - // TODO: Theme-aware colorss - p.Inlines.Add(new Run { Text = line.Contents + "\x0a", Foreground = new SolidColorBrush(Colors.Azure)}); - else - p.Inlines.Add(new Run { Text = line.Contents + "\x0a", Foreground = new SolidColorBrush(Colors.Red)}); - } - LiveOutputTextBlock.Blocks.Add(p); - IsDialogOpen = true; - - if (await MainApp.Instance.MainWindow.ShowDialogAsync(OutputDialog) == ContentDialogResult.Secondary) - { - LiveOutputScrollBar.ScrollToVerticalOffset(LiveOutputScrollBar.ScrollableHeight); - WindowsClipboard.SetText(string.Join('\n', ProcessOutput.ToArray())); - } - IsDialogOpen = false; - } - - public void ActionButtonClicked(object sender, RoutedEventArgs args) - { - if (Status is OperationStatus.Pending or OperationStatus.Running) - { - CancelButtonClicked(); - } - else - { - CloseButtonClicked(); - } - } - - protected void RemoveFromQueue() - { - while (MainApp.Instance.OperationQueue.IndexOf(this) != -1) - { - MainApp.Instance.OperationQueue.Remove(this); - } - } - protected void AddToQueue() - { - if (!MainApp.Instance.OperationQueue.Contains(this)) - { - MainApp.Instance.OperationQueue.Add(this); - } - } - - public async void CancelButtonClicked() - { - RemoveFromQueue(); - - if (Status is OperationStatus.Running) - { - Process.Kill(); - } - - await HandleCancelation(); - PostProcessEndAction(); - Status = OperationStatus.Canceled; - } - - public void CloseButtonClicked() - { - _ = Close(); - } - - protected void AddToQueue_Priority() - { - MainApp.Instance.OperationQueue.Insert(0, this); - } - - protected virtual async Task WaitForAvailability() - { - AddToQueue(); - int currentIndex = -2; - int oldIndex = -1; - while (currentIndex != 0) - { - if (Status is OperationStatus.Canceled) - { - RemoveFromQueue(); - return; - } - - currentIndex = MainApp.Instance.OperationQueue.IndexOf(this); - if (currentIndex != oldIndex) - { - LineInfoText = CoreTools.Translate("Operation on queue (position {0})...", currentIndex); - oldIndex = currentIndex; - } - await Task.Delay(100); - } - } - protected async Task PreMainThread() - { - Status = OperationStatus.Pending; - await WaitForAvailability(); - await MainThread(); - } - protected async Task MainThread() - { - try - { - - if (Status is OperationStatus.Canceled) - { - return; // If the operation was canceled, do nothing. - } - - MainApp.Instance.TooltipStatus.OperationsInProgress += 1; - - LineInfoText = CoreTools.Translate("Launching subprocess..."); - ProcessStartInfo startInfo = new() - { - RedirectStandardInput = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - CreateNoWindow = true, - StandardOutputEncoding = System.Text.Encoding.UTF8, - StandardInputEncoding = System.Text.Encoding.UTF8, - StandardErrorEncoding = System.Text.Encoding.UTF8, - WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) - }; - - Process = new Process(); - - Process.StartInfo = await BuildProcessInstance(startInfo); - // Process.StartInfo = CoreTools.UpdateEnvironmentVariables(Process.StartInfo); - - foreach (string infoLine in GenerateProcessLogHeader()) - { - ProcessOutput.Add(new(infoLine, OutputLine.LineType.Header)); - } - - ProcessOutput.Add(new("Process Executable : " + Process.StartInfo.FileName, OutputLine.LineType.Header)); - ProcessOutput.Add(new("Process Call Arguments : " + Process.StartInfo.Arguments, OutputLine.LineType.Header)); - ProcessOutput.Add(new("Working Directory : " + Process.StartInfo.WorkingDirectory, OutputLine.LineType.Header)); - ProcessOutput.Add(new("Process Start Time : " + DateTime.Now, OutputLine.LineType.Header)); - - Process.OutputDataReceived += (_, e) => DispatcherQueue.TryEnqueue(async () => - { - if (e.Data?.Trim() is string line && line != String.Empty) - { - if (line.Contains("For the question below") || - line.Contains("Would remove:")) // Mitigate chocolatey timeouts - { - await Process.StandardInput.WriteLineAsync(""); - } - - if (Status is not OperationStatus.Canceled) - { - LineInfoText = line; - if(line.Length > 3) ProcessOutput.Add(new(line, OutputLine.LineType.STDOUT)); - } - } - }); - - Process.ErrorDataReceived += (_, e) => DispatcherQueue.TryEnqueue(async () => - { - if (e.Data?.Trim() is string line && line != String.Empty) - { - if (Status is not OperationStatus.Canceled) - { - LineInfoText = line; - if(line.Length > 3) ProcessOutput.Add(new(line, OutputLine.LineType.STDERR)); - } - } - }); - - - Process.Start(); - PostProcessStartAction(); - - Process.BeginOutputReadLine(); - Process.BeginErrorReadLine(); - - Status = OperationStatus.Running; - - await Process.WaitForExitAsync(); - PostProcessEndAction(); - - ProcessOutput.Add(new("Process Exit Code : " + Process.ExitCode, OutputLine.LineType.Header)); - ProcessOutput.Add(new("Process End Time : " + DateTime.Now, OutputLine.LineType.Header)); - - AfterFinshAction postAction = AfterFinshAction.ManualClose; - - OperationVeredict OperationVeredict = await GetProcessVeredict(Process.ExitCode, RawProcessOutput); - - - if (Status is not OperationStatus.Canceled) - { - switch (OperationVeredict) - { - case OperationVeredict.Succeeded or OperationVeredict.RestartRequired: - Status = OperationStatus.Succeeded; - postAction = await HandleSuccess(); - RemoveFromQueue(); - break; - - case OperationVeredict.Canceled: - Status = OperationStatus.Canceled; - RemoveFromQueue(); - postAction = AfterFinshAction.ManualClose; - await HandleCancelation(); - break; - - case OperationVeredict.AutoRetry: - Status = OperationStatus.Pending; - postAction = AfterFinshAction.Retry; - break; - - case OperationVeredict.Failed: - Status = OperationStatus.Failed; - RemoveFromQueue(); - MainApp.Instance.TooltipStatus.ErrorsOccurred += 1; - postAction = await HandleFailure(); - MainApp.Instance.TooltipStatus.ErrorsOccurred -= 1; - break; - - default: - throw new ArgumentException($"Unexpected OperationVeredict {OperationVeredict}"); - } - } - - - switch (postAction) - { - case AfterFinshAction.TimeoutClose: - if (MainApp.Instance.OperationQueue.Count == 0) - { - if (Settings.Get("DoCacheAdminRightsForBatches")) - { - await CoreTools.ResetUACForCurrentProcess(); - } - } - - await Task.Delay(5000); - if (!Settings.Get("MaintainSuccessfulInstalls")) - { - _ = Close(); - } - - break; - - case AfterFinshAction.ManualClose: - if (MainApp.Instance.OperationQueue.Count == 0) - { - if (Settings.Get("DoCacheAdminRightsForBatches")) - { - await CoreTools.ResetUACForCurrentProcess(); - } - } - - break; - - case AfterFinshAction.Retry: - Retry(); - break; - } - - if (MainApp.Instance.OperationQueue.Count == 0 && DesktopShortcutsDatabase.GetUnknownShortcuts().Any() && Settings.Get("AskToDeleteNewDesktopShortcuts")) - { - await DialogHelper.HandleNewDesktopShortcuts(); - } - - List<string> rawOutput = RawProcessOutput.ToList(); - - rawOutput.Insert(0, " "); - rawOutput.Insert(0, "▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄"); - rawOutput.Add(""); - rawOutput.Add(""); - rawOutput.Add(""); - - string[] oldHistory = Settings.GetValue("OperationHistory").Split("\n"); - - if (oldHistory.Length > 1000) - { - oldHistory = oldHistory.Take(1000).ToArray(); - } - - List<string> newHistory = [.. rawOutput, .. oldHistory]; - - Settings.SetValue("OperationHistory", string.Join('\n', newHistory).Replace(" | ", " ║ ")); - } - catch (Exception e) - { - Logger.Error("Operation crashed: "); - Logger.Error(e); - LineInfoText = CoreTools.Translate("An unexpected error occurred:") + " " + e.Message; - RemoveFromQueue(); - try { Status = OperationStatus.Failed; } catch { } - } - MainApp.Instance.TooltipStatus.OperationsInProgress -= 1; - } - protected async Task Close() - { - while (IsDialogOpen) - { - await Task.Delay(1000); - } - - RemoveFromQueue(); - if (MainApp.Instance.MainWindow.NavigationPage.OperationStackPanel.Children.Contains(this)) - { - MainApp.Instance.MainWindow.NavigationPage.OperationStackPanel.Children.Remove(this); - } - } - - protected abstract Task Initialize(); - protected abstract void PostProcessStartAction(); - protected abstract void PostProcessEndAction(); - protected abstract Task<ProcessStartInfo> BuildProcessInstance(ProcessStartInfo startInfo); - protected abstract Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output); - protected abstract Task<AfterFinshAction> HandleFailure(); - protected abstract Task<AfterFinshAction> HandleSuccess(); - protected abstract Task HandleCancelation(); - protected abstract string[] GenerateProcessLogHeader(); - - protected void Retry() - { - AddToQueue_Priority(); - LineInfoText = CoreTools.Translate("Retrying, please wait..."); - ProcessOutput.Clear(); - Status = OperationStatus.Pending; - _ = MainThread(); - } - - protected void MainProcedure() - { - Initialize(); - _ = PreMainThread(); - } - private void ResizeEvent(object sender, SizeChangedEventArgs e) - { - if (e.NewSize.Width < 500) - { - if (LayoutMode != WidgetLayout.Compact) - { - LayoutMode = WidgetLayout.Compact; - } - } - else - { - if (LayoutMode != WidgetLayout.Default) - { - LayoutMode = WidgetLayout.Default; - } - } - - } - } -} diff --git a/src/UniGetUI/Controls/OperationWidgets/PackageOperations.cs b/src/UniGetUI/Controls/OperationWidgets/PackageOperations.cs deleted file mode 100644 index da82de403..000000000 --- a/src/UniGetUI/Controls/OperationWidgets/PackageOperations.cs +++ /dev/null @@ -1,463 +0,0 @@ -using System.Diagnostics; -using Microsoft.UI.Xaml.Controls; -using Microsoft.Windows.AppNotifications; -using Microsoft.Windows.AppNotifications.Builder; -using UniGetUI.Core.Data; -using UniGetUI.Core.Logging; -using UniGetUI.Core.SettingsEngine; -using UniGetUI.Core.Tools; -using UniGetUI.Interface.Enums; -using UniGetUI.PackageEngine.Classes.Packages.Classes; -using UniGetUI.PackageEngine.Enums; -using UniGetUI.PackageEngine.Interfaces; -using UniGetUI.PackageEngine.PackageClasses; -using UniGetUI.Pages.DialogPages; - -namespace UniGetUI.PackageEngine.Operations -{ - - public class OperationCanceledEventArgs : EventArgs - { - public OperationStatus OldStatus; - public OperationCanceledEventArgs(OperationStatus OldStatus) - { - this.OldStatus = OldStatus; - } - } - - public abstract class PackageOperation : AbstractOperation - { - protected List<string> DesktopShortcutsBeforeStart = []; - - protected readonly IPackage Package; - protected readonly IInstallationOptions Options; - protected readonly OperationType Role; - protected string ONGOING_PROGRESS_STRING = null!; - - public PackageOperation( - IPackage package, - IInstallationOptions options, - OperationType role, - bool IgnoreParallelInstalls = false) - : base(IgnoreParallelInstalls) - { - Package = package; - Options = options; - Role = role; - MainProcedure(); - if (ONGOING_PROGRESS_STRING is null) - { - throw new NullReferenceException("ONGOING_PROGRESS_STRING must be set to a non-null value in the Initialize method"); - } - - OutputDialog.SecondaryButtonText = CoreTools.Translate("Package details"); - OutputDialog.SecondaryButtonClick += (_, _) => - { - DialogHelper.ShowPackageDetails(Package, Role); - }; - } - - public PackageOperation( - IPackage package, - OperationType role, - bool IgnoreParallelInstalls = false) - : this(package, InstallationOptions.FromPackage(package), role, IgnoreParallelInstalls) - { - } - - protected sealed override async Task<ProcessStartInfo> BuildProcessInstance(ProcessStartInfo startInfo) - { - string operation_args = string.Join(" ", Package.Manager.OperationHelper.GetParameters(Package, Options, Role)); - - if (Package.OverridenOptions.RunAsAdministrator == true - || Options.RunAsAdministrator - || (Settings.Get("AlwaysElevate" + Package.Manager.Name) - && !Package.OverridenOptions.RunAsAdministrator is false) - ) - { - if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) - { - await CoreTools.CacheUACForCurrentProcess(); - } - - startInfo.FileName = CoreData.GSudoPath; - startInfo.Arguments = - $"\"{Package.Manager.Status.ExecutablePath}\" {Package.Manager.Properties.ExecutableCallArgs} {operation_args}"; - } - else - { - startInfo.FileName = Package.Manager.Status.ExecutablePath; - startInfo.Arguments = $"{Package.Manager.Properties.ExecutableCallArgs} {operation_args}"; - } - - return startInfo; - } - - protected override Task HandleCancelation() - { - Package.SetTag(PackageTag.Default); - return Task.CompletedTask; - } - - protected sealed override Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output) - { - return Task.FromResult(Package.Manager.OperationHelper.GetResult(Package, Role, Output, ReturnCode)); - } - - protected override async Task WaitForAvailability() - { - if (!IGNORE_PARALLEL_OPERATION_SETTINGS && - (Settings.Get("AllowParallelInstalls") - || Settings.Get($"AllowParallelInstallsForManager{Package.Manager.Name}"))) - { - Logger.Debug("Parallel installs are allowed. Skipping queue check"); - Package.SetTag(PackageTag.BeingProcessed); - return; - } - - Package.SetTag(PackageTag.OnQueue); - - AddToQueue(); - int currentIndex = -2; - int oldIndex = -1; - while (currentIndex != 0) - { - if (Status == OperationStatus.Canceled) - { - Package.Tag = PackageTag.Default; - return; // If the operation has been cancelled - } - - currentIndex = MainApp.Instance.OperationQueue.IndexOf(this); - if (currentIndex != oldIndex) - { - LineInfoText = CoreTools.Translate("Operation on queue (position {0})...", currentIndex); - oldIndex = currentIndex; - } - - await Task.Delay(100); - } - - Package.SetTag(PackageTag.BeingProcessed); - - } - - protected void ShowErrorNotification(string title, string body) - { - if (Settings.AreErrorNotificationsDisabled()) - return; - - try - { - AppNotificationManager.Default.RemoveByTagAsync(Package.Id); - AppNotificationBuilder builder = new AppNotificationBuilder() - .SetScenario(AppNotificationScenario.Urgent) - .SetTag(Package.Id) - .AddText(title) - .AddText(body) - .AddArgument("action", NotificationArguments.Show); - AppNotification notification = builder.BuildNotification(); - notification.ExpiresOnReboot = true; - AppNotificationManager.Default.Show(notification); - } - catch (Exception ex) - { - Logger.Error("Failed to show toast notification"); - Logger.Error(ex); - } - } - - protected void ShowSuccessNotification(string title, string body) - { - if (Settings.AreSuccessNotificationsDisabled()) - return; - - try - { - AppNotificationManager.Default.RemoveByTagAsync(Package.Id); - AppNotificationBuilder builder = new AppNotificationBuilder() - .SetScenario(AppNotificationScenario.Default) - .SetTag(Package.Id) - .AddText(title) - .AddText(body) - .AddArgument("action", NotificationArguments.Show); - AppNotification notification = builder.BuildNotification(); - notification.ExpiresOnReboot = true; - AppNotificationManager.Default.Show(notification); - } - catch (Exception ex) - { - Logger.Error("Failed to show toast notification"); - Logger.Error(ex); - } - } - - protected override void PostProcessStartAction() - { - if (Settings.AreProgressNotificationsDisabled()) - return; - - try - { - AppNotificationManager.Default.RemoveByTagAsync(Package.Id + "progress"); - AppNotificationBuilder builder = new AppNotificationBuilder() - .SetScenario(AppNotificationScenario.Default) - .SetTag(Package.Id + "progress") - .AddProgressBar(new AppNotificationProgressBar() - .SetStatus(CoreTools.Translate("Please wait...")) - .SetValueStringOverride("\u2003") - .SetTitle(ONGOING_PROGRESS_STRING) - .SetValue(1.0)) - .AddArgument("action", NotificationArguments.Show); - AppNotification notification = builder.BuildNotification(); - notification.ExpiresOnReboot = true; - notification.SuppressDisplay = true; - AppNotificationManager.Default.Show(notification); - } - catch (Exception ex) - { - Logger.Error("Failed to show toast notification"); - Logger.Error(ex); - } - } - - protected override void PostProcessEndAction() - { - AppNotificationManager.Default.RemoveByTagAsync(Package.Id + "progress"); - } - } - - public class InstallPackageOperation : PackageOperation - { - - public InstallPackageOperation( - IPackage package, - IInstallationOptions options, - bool IgnoreParallelInstalls = false) - : base(package, options, OperationType.Install, IgnoreParallelInstalls) - { } - - public InstallPackageOperation( - IPackage package, - bool IgnoreParallelInstalls = false) - : base(package, OperationType.Install, IgnoreParallelInstalls) - { } - - protected override string[] GenerateProcessLogHeader() - { - return - [ - "Starting package install operation for package id=" + Package.Id + " with Manager name=" + Package.Manager.Name, - "Given installation options are " + Options.ToString(), - ]; - } - - protected override async Task<AfterFinshAction> HandleFailure() - { - LineInfoText = CoreTools.Translate("{package} installation failed", new Dictionary<string, object?> { { "package", Package.Name } }); - Package.SetTag(PackageTag.Failed); - - ShowErrorNotification( - CoreTools.Translate("Installation failed"), - CoreTools.Translate("{package} could not be installed", - new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - ContentDialogResult result = await DialogHelper.ShowOperationFailed( - ProcessOutput, - CoreTools.Translate("{package} installation failed", new Dictionary<string, object?> { { "package", Package.Name } }), - CoreTools.Translate("{package} could not be installed", new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - return result == ContentDialogResult.Primary? AfterFinshAction.Retry: AfterFinshAction.ManualClose; - - } - - protected override Task<AfterFinshAction> HandleSuccess() - { - LineInfoText = CoreTools.Translate("{package} was installed successfully", new Dictionary<string, object?> { { "package", Package.Name } }); - Package.SetTag(PackageTag.AlreadyInstalled); - PEInterface.InstalledPackagesLoader.AddForeign(Package); - - ShowSuccessNotification( - CoreTools.Translate("Installation succeeded"), - CoreTools.Translate("{package} was installed successfully", - new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - if (Settings.Get("AskToDeleteNewDesktopShortcuts")) - { - DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart); - } - - return Task.FromResult(AfterFinshAction.TimeoutClose); - } - - protected override async Task Initialize() - { - ONGOING_PROGRESS_STRING = CoreTools.Translate("{0} is being installed", Package.Name); - OperationTitle = CoreTools.Translate("{package} Installation", new Dictionary<string, object?> { { "package", Package.Name } }); - IconSource = await Task.Run(Package.GetIconUrl); - - if (Settings.Get("AskToDeleteNewDesktopShortcuts")) - { - DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts(); - } - } - } - - public class UpdatePackageOperation : PackageOperation - { - - public UpdatePackageOperation( - IPackage package, - IInstallationOptions options, - bool IgnoreParallelInstalls = false) - : base(package, options, OperationType.Update, IgnoreParallelInstalls) - { } - - public UpdatePackageOperation( - IPackage package, - bool IgnoreParallelInstalls = false) - : base(package, OperationType.Update, IgnoreParallelInstalls) - { } - - protected override string[] GenerateProcessLogHeader() - { - return - [ - "Starting package update operation for package id=" + Package.Id + " with Manager name=" + Package.Manager.Name, - "Given installation options are " + Options.ToString(), - ]; - } - - protected override async Task<AfterFinshAction> HandleFailure() - { - LineInfoText = CoreTools.Translate("{package} update failed. Click here for more details.", new Dictionary<string, object?> { { "package", Package.Name } }); - Package.SetTag(PackageTag.Failed); - - ShowErrorNotification( - CoreTools.Translate("Update failed"), - CoreTools.Translate("{package} could not be updated", - new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - ContentDialogResult result = await DialogHelper.ShowOperationFailed( - ProcessOutput, - CoreTools.Translate("{package} update failed", new Dictionary<string, object?> { { "package", Package.Name } }), - CoreTools.Translate("{package} could not be updated", new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - return result == ContentDialogResult.Primary ? AfterFinshAction.Retry : AfterFinshAction.ManualClose; - } - - protected override async Task<AfterFinshAction> HandleSuccess() - { - LineInfoText = CoreTools.Translate("{package} was updated successfully", new Dictionary<string, object?> { { "package", Package.Name } }); - Package.SetTag(PackageTag.Default); - Package.GetInstalledPackage()?.SetTag(PackageTag.Default); - Package.GetAvailablePackage()?.SetTag(PackageTag.AlreadyInstalled); - - if (await Package.HasUpdatesIgnoredAsync() && await Package.GetIgnoredUpdatesVersionAsync() != "*") - { - await Package.RemoveFromIgnoredUpdatesAsync(); - } - PEInterface.UpgradablePackagesLoader.Remove(Package); - - ShowSuccessNotification( - CoreTools.Translate("Update succeeded"), - CoreTools.Translate("{package} was updated successfully", - new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - if (Settings.Get("AskToDeleteNewDesktopShortcuts")) - { - DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart); - } - - return AfterFinshAction.TimeoutClose; - } - - protected override async Task Initialize() - { - ONGOING_PROGRESS_STRING = CoreTools.Translate("{0} is being updated to version {1}", Package.Name, Package.NewVersion); - OperationTitle = CoreTools.Translate("{package} Update", new Dictionary<string, object?> { { "package", Package.Name } }); - IconSource = await Task.Run(Package.GetIconUrl); - - if (Settings.Get("AskToDeleteNewDesktopShortcuts")) - { - DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts(); - } - } - } - - public class UninstallPackageOperation : PackageOperation - { - - public UninstallPackageOperation( - IPackage package, - IInstallationOptions options, - bool IgnoreParallelInstalls = false) - : base(package, options, OperationType.Uninstall, IgnoreParallelInstalls) - { } - - public UninstallPackageOperation( - IPackage package, - bool IgnoreParallelInstalls = false) - : base(package, OperationType.Uninstall, IgnoreParallelInstalls) - { } - - protected override string[] GenerateProcessLogHeader() - { - return - [ - "Starting package uninstall operation for package id=" + Package.Id + " with Manager name=" + Package.Manager.Name, - "Given installation options are " + Options.ToString(), - ]; - } - - protected override async Task<AfterFinshAction> HandleFailure() - { - LineInfoText = CoreTools.Translate("{package} uninstall failed", new Dictionary<string, object?> { { "package", Package.Name } }); - Package.SetTag(PackageTag.Failed); - - ShowErrorNotification( - CoreTools.Translate("Uninstall failed"), - CoreTools.Translate("{package} could not be uninstalled", - new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - ContentDialogResult result = await DialogHelper.ShowOperationFailed( - ProcessOutput, - CoreTools.Translate("{package} uninstall failed", new Dictionary<string, object?> { { "package", Package.Name } }), - CoreTools.Translate("{package} could not be uninstalled", new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - return result == ContentDialogResult.Primary ? AfterFinshAction.Retry : AfterFinshAction.ManualClose; - } - - protected override async Task<AfterFinshAction> HandleSuccess() - { - LineInfoText = CoreTools.Translate("{package} was uninstalled successfully", new Dictionary<string, object?> { { "package", Package.Name } }); - Package.SetTag(PackageTag.Default); - Package.GetAvailablePackage()?.SetTag(PackageTag.Default); - PEInterface.UpgradablePackagesLoader.Remove(Package); - PEInterface.InstalledPackagesLoader.Remove(Package); - - ShowSuccessNotification( - CoreTools.Translate("Uninstall succeeded"), - CoreTools.Translate("{package} was uninstalled successfully", - new Dictionary<string, object?> { { "package", Package.Name } }) - ); - - return AfterFinshAction.TimeoutClose; - } - - protected override async Task Initialize() - { - ONGOING_PROGRESS_STRING = CoreTools.Translate("{0} is being uninstalled", Package.Name); - OperationTitle = CoreTools.Translate("{package} Uninstall", new Dictionary<string, object?> { { "package", Package.Name } }); - IconSource = await Task.Run(Package.GetIconUrl); - } - } -} diff --git a/src/UniGetUI/Controls/OperationWidgets/SourceOperations.cs b/src/UniGetUI/Controls/OperationWidgets/SourceOperations.cs deleted file mode 100644 index 5aea58d79..000000000 --- a/src/UniGetUI/Controls/OperationWidgets/SourceOperations.cs +++ /dev/null @@ -1,282 +0,0 @@ -using System.Diagnostics; -using Microsoft.UI.Xaml.Controls; -using Microsoft.Windows.AppNotifications; -using Microsoft.Windows.AppNotifications.Builder; -using UniGetUI.Core.Data; -using UniGetUI.Core.Logging; -using UniGetUI.Core.SettingsEngine; -using UniGetUI.Core.Tools; -using UniGetUI.Interface.Enums; -using UniGetUI.PackageEngine.Enums; -using UniGetUI.PackageEngine.Interfaces; -using UniGetUI.Pages.DialogPages; - -namespace UniGetUI.PackageEngine.Operations -{ - - public abstract class SourceOperation : AbstractOperation - { - protected IManagerSource Source; - protected string OPERATION_ONGOING_STRING = null!; - - public SourceOperation(IManagerSource source) - { - Source = source; - MainProcedure(); - if (OPERATION_ONGOING_STRING is null) - { - throw new NullReferenceException("OPERATION_ONGOING_STRING must be set to a non-null value in the Initialize method"); - } - } - - protected override Task HandleCancelation() => Task.CompletedTask; - - protected void ShowErrorNotification(string title, string body) - { - if (Settings.AreErrorNotificationsDisabled()) - return; - - try - { - AppNotificationManager.Default.RemoveByTagAsync(Source.Name); - AppNotificationBuilder builder = new AppNotificationBuilder() - .SetScenario(AppNotificationScenario.Urgent) - .SetTag(Source.Name) - .AddText(title) - .AddText(body) - .AddArgument("action", NotificationArguments.Show); - AppNotification notification = builder.BuildNotification(); - notification.ExpiresOnReboot = true; - AppNotificationManager.Default.Show(notification); - } - catch (Exception ex) - { - Logger.Error("Failed to show toast notification"); - Logger.Error(ex); - } - } - - protected void ShowSuccessNotification(string title, string body) - { - if (Settings.AreSuccessNotificationsDisabled()) - return; - - try - { - AppNotificationManager.Default.RemoveByTagAsync(Source.Name); - AppNotificationBuilder builder = new AppNotificationBuilder() - .SetScenario(AppNotificationScenario.Default) - .SetTag(Source.Name) - .AddText(title) - .AddText(body) - .AddArgument("action", NotificationArguments.Show); - AppNotification notification = builder.BuildNotification(); - notification.ExpiresOnReboot = true; - AppNotificationManager.Default.Show(notification); - } - catch (Exception ex) - { - Logger.Error("Failed to show toast notification"); - Logger.Error(ex); - } - } - - protected override void PostProcessStartAction() - { - if (Settings.AreProgressNotificationsDisabled()) - return; - - try - { - AppNotificationManager.Default.RemoveByTagAsync(Source.Name + "progress"); - AppNotificationBuilder builder = new AppNotificationBuilder() - .SetScenario(AppNotificationScenario.Default) - .SetTag(Source.Name + "progress") - .AddProgressBar(new AppNotificationProgressBar() - .SetStatus(CoreTools.Translate("Please wait...")) - .SetValueStringOverride("\uE002") - .SetTitle(OPERATION_ONGOING_STRING) - .SetValue(1.0)) - .AddArgument("action", NotificationArguments.Show); - AppNotification notification = builder.BuildNotification(); - notification.ExpiresOnReboot = true; - notification.SuppressDisplay = true; - AppNotificationManager.Default.Show(notification); - } - catch (Exception ex) - { - Logger.Error("Failed to show toast notification"); - Logger.Error(ex); - } - } - - protected override void PostProcessEndAction() - { - AppNotificationManager.Default.RemoveByTagAsync(Source.Name + "progress"); - } - } - - public class AddSourceOperation : SourceOperation - { - - public event EventHandler<EventArgs>? OperationSucceeded; - - public AddSourceOperation(IManagerSource source) : base(source) - { } - - protected override async Task<ProcessStartInfo> BuildProcessInstance(ProcessStartInfo startInfo) - { - if (Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin) - { - if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) - { - await CoreTools.CacheUACForCurrentProcess(); - } - startInfo.FileName = CoreData.GSudoPath; - startInfo.Arguments = $"\"{Source.Manager.Status.ExecutablePath}\" " + Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); - } - else - { - startInfo.FileName = Source.Manager.Status.ExecutablePath; - startInfo.Arguments = Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetAddSourceParameters(Source)); - } - - return startInfo; - } - - protected override string[] GenerateProcessLogHeader() - { - return - [ - "Starting adding source operation for source name=" + Source.Name + "with Manager name=" + Source.Manager.Name, - ]; - } - - protected override Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output) - { - return Task.Run(() => Source.Manager.SourcesHelper.GetAddOperationVeredict(Source, ReturnCode, Output)); - } - - protected override async Task<AfterFinshAction> HandleFailure() - { - LineInfoText = CoreTools.Translate("Could not add source {source} to {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); - - ShowErrorNotification( - CoreTools.Translate("Installation failed"), - CoreTools.Translate("Could not add source {source} to {manager}", - new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }) - ); - - ContentDialogResult result = await DialogHelper.ShowOperationFailed( - ProcessOutput, - CoreTools.Translate("Source addition failed"), - CoreTools.Translate("Could not add source {source} to {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }) - ); - - return result == ContentDialogResult.Primary ? AfterFinshAction.Retry : AfterFinshAction.ManualClose; - } - - protected override async Task<AfterFinshAction> HandleSuccess() - { - OperationSucceeded?.Invoke(this, EventArgs.Empty); - LineInfoText = CoreTools.Translate("The source {source} was added to {manager} successfully", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); - - ShowSuccessNotification( - CoreTools.Translate("Addition succeeded"), - CoreTools.Translate("The source {source} was added to {manager} successfully", - new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }) - ); - - return AfterFinshAction.TimeoutClose; - } - - protected override async Task Initialize() - { - OperationTitle = OPERATION_ONGOING_STRING = CoreTools.Translate("Adding source {source} to {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); - IconSource = new Uri("ms-appx:///Assets/Images/" + Source.Manager.Properties.ColorIconId + ".png"); - } - } - - public class RemoveSourceOperation : SourceOperation - { - - public event EventHandler<EventArgs>? OperationSucceeded; - - public RemoveSourceOperation(IManagerSource source) : base(source) - { } - - protected override async Task<ProcessStartInfo> BuildProcessInstance(ProcessStartInfo startInfo) - { - if (Source.Manager.Capabilities.Sources.MustBeInstalledAsAdmin) - { - if (Settings.Get("DoCacheAdminRights") || Settings.Get("DoCacheAdminRightsForBatches")) - { - await CoreTools.CacheUACForCurrentProcess(); - } - startInfo.FileName = CoreData.GSudoPath; - startInfo.Arguments = $"\"{Source.Manager.Status.ExecutablePath}\" " + Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source)); - - } - else - { - startInfo.FileName = Source.Manager.Status.ExecutablePath; - startInfo.Arguments = Source.Manager.Properties.ExecutableCallArgs + " " + string.Join(" ", Source.Manager.SourcesHelper.GetRemoveSourceParameters(Source)); - } - - return startInfo; - } - - protected override string[] GenerateProcessLogHeader() - { - return - [ - "Starting remove source operation for source name=" + Source.Name + "with Manager name=" + Source.Manager.Name, - ]; - } - - protected override Task<OperationVeredict> GetProcessVeredict(int ReturnCode, string[] Output) - { - return Task.Run(() => Source.Manager.SourcesHelper.GetRemoveOperationVeredict(Source, ReturnCode, Output)); - } - - protected override async Task<AfterFinshAction> HandleFailure() - { - LineInfoText = CoreTools.Translate("Could not remove source {source} from {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); - - ShowErrorNotification( - CoreTools.Translate("Removal failed"), - CoreTools.Translate("Could not remove source {source} from {manager}", - new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }) - ); - - ContentDialogResult result = await DialogHelper.ShowOperationFailed( - ProcessOutput, - CoreTools.Translate("Source removal failed"), - CoreTools.Translate("Could not remove source {source} from {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }) - ); - - return result == ContentDialogResult.Primary ? AfterFinshAction.Retry : AfterFinshAction.ManualClose; - } - - protected override async Task<AfterFinshAction> HandleSuccess() - { - OperationSucceeded?.Invoke(this, EventArgs.Empty); - LineInfoText = CoreTools.Translate("The source {source} was removed from {manager} successfully", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); - - ShowSuccessNotification( - CoreTools.Translate("Removal succeeded"), - CoreTools.Translate("The source {source} was removed from {manager} successfully", - new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }) - ); - - await Task.Delay(0); - return AfterFinshAction.TimeoutClose; - } - - protected override async Task Initialize() - { - OperationTitle = OPERATION_ONGOING_STRING = CoreTools.Translate("Removing source {source} from {manager}", new Dictionary<string, object?> { { "source", Source.Name }, { "manager", Source.Manager.Name } }); - IconSource = new Uri("ms-appx:///Assets/Images/" + Source.Manager.Properties.ColorIconId + ".png"); - } - } -} diff --git a/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs index 9886db087..2416cb780 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs @@ -9,7 +9,7 @@ namespace UniGetUI.Interface.Widgets { - public sealed class CheckboxCard : SettingsCard + public sealed partial class CheckboxCard : SettingsCard { public CheckBox _checkbox; private bool IS_INVERTED; diff --git a/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs index c018f9667..49d79c050 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/ComboboxCard.cs @@ -84,5 +84,6 @@ public void ShowAddedItems() }; } + public string SelectedValue() => _combobox.SelectedValue.ToString() ?? throw new InvalidCastException(); } } diff --git a/src/UniGetUI/Controls/SourceManager.xaml.cs b/src/UniGetUI/Controls/SourceManager.xaml.cs index 72d097d4d..2964f603a 100644 --- a/src/UniGetUI/Controls/SourceManager.xaml.cs +++ b/src/UniGetUI/Controls/SourceManager.xaml.cs @@ -1,6 +1,7 @@ using System.Collections.ObjectModel; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using UniGetUI.Controls.OperationWidgets; using UniGetUI.Core.Logging; using UniGetUI.Core.Tools; using UniGetUI.PackageEngine.Classes.Manager; @@ -25,9 +26,9 @@ public SourceItem(SourceManager Parent, IManagerSource Source) public void Remove(object sender, RoutedEventArgs e) { - RemoveSourceOperation op = new(Source); - MainApp.Instance.AddOperationToList(op); - op.OperationSucceeded += (_, _) => { Parent.RemoveSourceItem(this); }; + var op = new OperationControl(new RemoveSourceOperation(Source)); + MainApp.Operations._operationList.Add(op); + op.Operation.OperationSucceeded += (_, _) => { Parent.RemoveSourceItem(this); }; } } @@ -124,19 +125,14 @@ public SourceManager(IPackageManager Manager) if (await MainApp.Instance.MainWindow.ShowDialogAsync(d) == ContentDialogResult.Primary) { - AddSourceOperation op; + PackageOperations.AbstractOperation op; if (CoreTools.Translate("Other") != SourcesCombo.SelectedValue.ToString()) - { op = new AddSourceOperation(NameSourceRef[SourcesCombo.SelectedValue.ToString() ?? ""]); - } else - { op = new AddSourceOperation(new ManagerSource(this.Manager, SourceNameTextBox.Text, new Uri(SourceUrlTextBox.Text))); - } - - MainApp.Instance.AddOperationToList(op); - op.OperationSucceeded += (_, _) => { LoadSources(); }; + MainApp.Operations.Add(op); + op.OperationSucceeded += (_, _) => LoadSources(); } } catch (Exception ex) diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index 7023dbb64..36762bc0a 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -45,7 +45,6 @@ public XamlRoot XamlRoot public int LoadingDialogCount; public List<ContentDialog> DialogQueue = []; - public List<NavButton> NavButtonList = []; public static readonly ObservableQueue<string> ParametersToProcess = new(); @@ -210,7 +209,7 @@ public async void HandleClosingEvent(AppWindow sender, AppWindowClosingEventArgs } else { - if (MainApp.Instance.OperationQueue.Count > 0) + if (MainApp.Operations._operationList.Count > 0) { args.Cancel = true; ContentDialog d = new() @@ -461,80 +460,95 @@ private void LoadTrayMenu() UpdateSystemTrayStatus(); } + private string LastTrayIcon = ""; public void UpdateSystemTrayStatus() { - string modifier = "_empty"; - string tooltip = CoreTools.Translate("Everything is up to date") + " - " + Title; - - if (MainApp.Instance.TooltipStatus.OperationsInProgress > 0) - { - modifier = "_blue"; - tooltip = CoreTools.Translate("Operation in progress") + " - " + Title; - } - else if (MainApp.Instance.TooltipStatus.ErrorsOccurred > 0) - { - modifier = "_orange"; - tooltip = CoreTools.Translate("Attention required") + " - " + Title; - } - else if (MainApp.Instance.TooltipStatus.RestartRequired) - { - modifier = "_turquoise"; - tooltip = CoreTools.Translate("Restart required") + " - " + Title; - } - else if (MainApp.Instance.TooltipStatus.AvailableUpdates > 0) + try { - modifier = "_green"; - if (MainApp.Instance.TooltipStatus.AvailableUpdates == 1) + string modifier = "_empty"; + string tooltip = CoreTools.Translate("Everything is up to date") + " - " + Title; + + if (MainApp.Tooltip.OperationsInProgress > 0) { - tooltip = CoreTools.Translate("1 update is available") + " - " + Title; + modifier = "_blue"; + tooltip = CoreTools.Translate("Operation in progress") + " - " + Title; } - else + else if (MainApp.Tooltip.ErrorsOccurred > 0) { - tooltip = CoreTools.Translate("{0} updates are available", - MainApp.Instance.TooltipStatus.AvailableUpdates) + " - " + Title; + modifier = "_orange"; + tooltip = CoreTools.Translate("Attention required") + " - " + Title; + } + else if (MainApp.Tooltip.RestartRequired) + { + modifier = "_turquoise"; + tooltip = CoreTools.Translate("Restart required") + " - " + Title; + } + else if (MainApp.Tooltip.AvailableUpdates > 0) + { + modifier = "_green"; + if (MainApp.Tooltip.AvailableUpdates == 1) + { + tooltip = CoreTools.Translate("1 update is available") + " - " + Title; + } + else + { + tooltip = CoreTools.Translate("{0} updates are available", + MainApp.Tooltip.AvailableUpdates) + " - " + Title; + } } - } - if (TrayIcon is null) - { - Logger.Warn("Attempting to update a null taskbar icon tray, aborting!"); - return; - } + if (TrayIcon is null) + { + Logger.Warn("Attempting to update a null taskbar icon tray, aborting!"); + return; + } - TrayIcon.ToolTipText = tooltip; + TrayIcon.ToolTipText = tooltip; - ApplicationTheme theme = ApplicationTheme.Light; - string RegistryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; - string RegistryValueName = "SystemUsesLightTheme"; - RegistryKey? key = Registry.CurrentUser.OpenSubKey(RegistryKeyPath); - object? registryValueObject = key?.GetValue(RegistryValueName) ?? null; - if (registryValueObject is not null) - { - int registryValue = (int)registryValueObject; - theme = registryValue > 0 ? ApplicationTheme.Light : ApplicationTheme.Dark; - } + ApplicationTheme theme = ApplicationTheme.Light; + string RegistryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; + string RegistryValueName = "SystemUsesLightTheme"; + RegistryKey? key = Registry.CurrentUser.OpenSubKey(RegistryKeyPath); + object? registryValueObject = key?.GetValue(RegistryValueName) ?? null; + if (registryValueObject is not null) + { + int registryValue = (int)registryValueObject; + theme = registryValue > 0 ? ApplicationTheme.Light : ApplicationTheme.Dark; + } - if (theme == ApplicationTheme.Light) - { - modifier += "_black"; - } - else - { - modifier += "_white"; - } + if (theme == ApplicationTheme.Light) + { + modifier += "_black"; + } + else + { + modifier += "_white"; + } - string FullIconPath = Path.Join(CoreData.UniGetUIExecutableDirectory, - "\\Assets\\Images\\tray" + modifier + ".ico"); + string FullIconPath = Path.Join(CoreData.UniGetUIExecutableDirectory, "\\Assets\\Images\\tray" + modifier + ".ico"); + if (LastTrayIcon != FullIconPath) + { + LastTrayIcon = FullIconPath; + if (File.Exists(FullIconPath)) + { + TrayIcon.SetValue(TaskbarIcon.IconSourceProperty, new BitmapImage { UriSource = new Uri(FullIconPath) }); + } + } - TrayIcon.SetValue(TaskbarIcon.IconSourceProperty, new BitmapImage { UriSource = new Uri(FullIconPath) }); + if (Settings.Get("DisableSystemTray")) + { + TrayIcon.Visibility = Visibility.Collapsed; + } + else + { + TrayIcon.Visibility = Visibility.Visible; + } - if (Settings.Get("DisableSystemTray")) - { - TrayIcon.Visibility = Visibility.Collapsed; } - else + catch (Exception ex) { - TrayIcon.Visibility = Visibility.Visible; + Logger.Error("An error occurred while updating the System Tray icon:"); + Logger.Error(ex); } } diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Operations.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Operations.cs new file mode 100644 index 000000000..3be21e1fd --- /dev/null +++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Operations.cs @@ -0,0 +1,285 @@ +using Windows.UI; +using ExternalLibraries.Clipboard; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Documents; +using Microsoft.UI.Xaml.Media; +using UniGetUI.Controls.OperationWidgets; +using UniGetUI.Core.Tools; +using UniGetUI.Interface.Enums; +using UniGetUI.Interface.Widgets; +using UniGetUI.PackageOperations; + +namespace UniGetUI.Pages.DialogPages; + +public static partial class DialogHelper +{ + public static async Task ShowOperationFailedDialog(AbstractOperation operation, OperationControl opControl) + { + ContentDialog dialog = new() + { + Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, XamlRoot = Window.XamlRoot + }; + dialog.Resources["ContentDialogMaxWidth"] = 850; + dialog.Resources["ContentDialogMaxHeight"] = 800; + dialog.Title = operation.Metadata.FailureTitle; + + Grid grid = new() + { + RowSpacing = 16, + HorizontalAlignment = HorizontalAlignment.Stretch, + VerticalAlignment = VerticalAlignment.Stretch, + }; + + grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); + grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + + TextBlock headerContent = new() + { + TextWrapping = TextWrapping.WrapWholeWords, + Text = $"{operation.Metadata.FailureMessage}.\n" + + CoreTools.Translate("Please see the Command-line Output or refer to the Operation History for further information about the issue.") + }; + + StackPanel HeaderPanel = new() { Orientation = Orientation.Horizontal, Spacing = 8 }; + + HeaderPanel.Children.Add(new LocalIcon(IconType.Console) + { + VerticalAlignment = VerticalAlignment.Center, + Height = 24, + Width = 24, + HorizontalAlignment = HorizontalAlignment.Left + }); + + HeaderPanel.Children.Add(new TextBlock + { + Text = CoreTools.Translate("Command-line Output"), + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center + }); + + RichTextBlock CommandLineOutput = new() + { + Padding = new Thickness(6), + FontFamily = new FontFamily("Consolas"), + TextWrapping = TextWrapping.Wrap, + }; + + ScrollViewer ScrollView = new() + { + MaxHeight = MainApp.Instance.MainWindow.NavigationPage.ActualHeight > 800? 500: 300, + MaxWidth = 800, + CornerRadius = new CornerRadius(6), + Background = (Brush)Application.Current.Resources["ApplicationPageBackgroundThemeBrush"], + Content = CommandLineOutput, + VerticalScrollMode = ScrollMode.Enabled, + HorizontalScrollMode = ScrollMode.Disabled, + }; + + Paragraph par = new(); + + SolidColorBrush errorColor = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]; + SolidColorBrush debugColor = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBrush"]; + + foreach (var line in operation.GetOutput()) + { + if (line.Item2 is AbstractOperation.LineType.StdOUT) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); + } + else if (line.Item2 is AbstractOperation.LineType.OperationInfo) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = debugColor }); + } + else + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = errorColor }); + } + } + + CommandLineOutput.Blocks.Add(par); + + grid.Children.Add(headerContent); + grid.Children.Add(ScrollView); + Grid.SetRow(headerContent, 0); + Grid.SetRow(ScrollView, 1); + + var CloseButton = new Button() + { + Content = CoreTools.Translate("Close"), HorizontalAlignment = HorizontalAlignment.Stretch, Height = 30, + }; + CloseButton.Click += (_, _) => + { + dialog.Hide(); + }; + Control _retryButton; + + var retryOptions = opControl.GetRetryOptions(() => dialog.Hide()); + if (retryOptions.Any()) + { + SplitButton RetryButton = new SplitButton() + { + Content = CoreTools.Translate("Retry"), + HorizontalAlignment = HorizontalAlignment.Stretch, + Height = 30, + }; + RetryButton.Click += (_, _) => + { + operation.Retry(AbstractOperation.RetryMode.Retry); + dialog.Hide(); + }; + BetterMenu menu = new(); + RetryButton.Flyout = menu; + foreach (var opt in retryOptions) + { + menu.Items.Add(opt); + } + + _retryButton = RetryButton; + } + else + { + var RetryButton = new Button() + { + Content = CoreTools.Translate("Retry"), + HorizontalAlignment = HorizontalAlignment.Stretch, + Height = 30, + }; + RetryButton.Click += (_, _) => + { + operation.Retry(AbstractOperation.RetryMode.Retry); + dialog.Hide(); + }; + _retryButton = RetryButton; + } + + Grid sp = new() + { + Margin = new Thickness(-25, 0, -25, -25), + ColumnSpacing = 8, + Padding = new Thickness(30), + HorizontalAlignment = HorizontalAlignment.Stretch, + Background = (Brush)Application.Current.Resources["ApplicationPageBackgroundThemeBrush"] + }; + sp.ColumnDefinitions.Add(new ColumnDefinition(){Width = new(1, GridUnitType.Star)}); + sp.ColumnDefinitions.Add(new ColumnDefinition(){Width = new(1, GridUnitType.Star)}); + sp.Children.Add(_retryButton); + Grid.SetColumn(CloseButton, 1); + sp.Children.Add(CloseButton); + Grid.SetRow(sp, 3); + Grid.SetColumn(sp, 0); + grid.Children.Add(sp); + dialog.Content = grid; + + await Window.ShowDialogAsync(dialog); + } + + public static async Task ShowLiveLogDialog(AbstractOperation operation) + { + bool LastLineWasProgress = false; + + ContentDialog OutputDialog = new ContentDialog + { + Style = (Style)Application.Current.Resources["DefaultContentDialogStyle"], + XamlRoot = Window.XamlRoot + }; + OutputDialog.Resources["ContentDialogMaxWidth"] = 1200; + OutputDialog.Resources["ContentDialogMaxHeight"] = 1000; + + var LiveOutputTextBlock = new RichTextBlock + { + Margin = new Thickness(8), + FontFamily = new FontFamily("Consolas") + }; + + var LiveOutputScrollBar = new ScrollViewer + { + CornerRadius = new CornerRadius(6), + Background = (Brush)Application.Current.Resources["ApplicationPageBackgroundThemeBrush"], + Height = 400, + Width = 600, + Content = LiveOutputTextBlock + }; + + OutputDialog.Title = CoreTools.Translate("Live output"); + OutputDialog.CloseButtonText = CoreTools.Translate("Close"); + + OutputDialog.SizeChanged += (_, _) => + { + LiveOutputScrollBar.MinWidth = MainApp.Instance.MainWindow.NavigationPage.ActualWidth - 400; + LiveOutputScrollBar.MinHeight = MainApp.Instance.MainWindow.NavigationPage.ActualHeight - 200; + }; + + OutputDialog.Content = LiveOutputScrollBar; + LiveOutputTextBlock.Blocks.Clear(); + Paragraph par = new() + { + LineHeight = 4.8 + }; + SolidColorBrush errorColor = (SolidColorBrush)Application.Current.Resources["SystemFillColorCriticalBrush"]; + SolidColorBrush debugColor = (SolidColorBrush)Application.Current.Resources["SystemFillColorNeutralBrush"]; + + foreach (var line in operation.GetOutput()) + { + if (line.Item2 is AbstractOperation.LineType.StdOUT) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); + } + else if (line.Item2 is AbstractOperation.LineType.OperationInfo) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = debugColor }); + } + else + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = errorColor }); + } + } + + EventHandler<(string, AbstractOperation.LineType)> AddLineLambda = (_, line) => MainApp.Dispatcher.TryEnqueue(() => + { + if(LastLineWasProgress) par.Inlines.RemoveAt(par.Inlines.Count-1); + + LastLineWasProgress = false; + if (line.Item2 is AbstractOperation.LineType.StdOUT) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); + } + else if (line.Item2 is AbstractOperation.LineType.OperationInfo) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = debugColor }); + } + else if (line.Item2 is AbstractOperation.LineType.StdERR) + { + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a", Foreground = errorColor }); + } + else + { + LastLineWasProgress = true; + par.Inlines.Add(new Run { Text = line.Item1 + "\x0a" }); + } + + LiveOutputTextBlock.Blocks.Clear(); + LiveOutputTextBlock.Blocks.Add(par); + LiveOutputScrollBar.ScrollToVerticalOffset(LiveOutputScrollBar.ScrollableHeight); + }); + + LiveOutputTextBlock.Blocks.Add(par); + + operation.LogLineAdded += AddLineLambda; + if (await MainApp.Instance.MainWindow.ShowDialogAsync(OutputDialog) == ContentDialogResult.Secondary) + { + LiveOutputScrollBar.ScrollToVerticalOffset(LiveOutputScrollBar.ScrollableHeight); + string text = ""; + foreach (var line in par.Inlines) + { + if (line is Run run) + text += run + "\n"; + } + WindowsClipboard.SetText(text); + } + operation.LogLineAdded -= AddLineLambda; + } +} + diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs index a8d23070e..fdeaae6ea 100644 --- a/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs +++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Packages.cs @@ -4,6 +4,7 @@ using Microsoft.UI.Xaml.Documents; using Microsoft.UI.Xaml.Media; using UniGetUI.Core.Tools; +using UniGetUI.Interface; using UniGetUI.Interface.Dialogs; using UniGetUI.Interface.Enums; using UniGetUI.Interface.Widgets; @@ -12,14 +13,13 @@ using UniGetUI.PackageEngine.Operations; using UniGetUI.PackageEngine.PackageClasses; using UniGetUI.PackageEngine.Serializable; +using AbstractOperation = UniGetUI.PackageOperations.AbstractOperation; namespace UniGetUI.Pages.DialogPages; public static partial class DialogHelper { - - /// <summary> /// Will update the Installation Options for the given Package, and will return whether the user choose to continue /// </summary> @@ -178,118 +178,4 @@ public static async Task<bool> ConfirmUninstallation(IEnumerable<IPackage> packa return await Window.ShowDialogAsync(dialog) is ContentDialogResult.Primary; } - - public static async Task<ContentDialogResult> ShowOperationFailed( - IEnumerable<AbstractOperation.OutputLine> processOutput, - string dialogTitle, - string shortDescription) - { - ContentDialog dialog = new() - { - Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, XamlRoot = Window.XamlRoot - }; - dialog.Resources["ContentDialogMaxWidth"] = 850; - dialog.Resources["ContentDialogMaxHeight"] = 800; - dialog.Title = dialogTitle; - - Grid grid = new() - { - RowSpacing = 16, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch, - }; - - grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); - grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); - - TextBlock headerContent = new() - { - TextWrapping = TextWrapping.WrapWholeWords, - Text = $"{shortDescription}. " - + CoreTools.Translate( - "Please see the Command-line Output or refer to the Operation History for further information about the issue.") - }; - - StackPanel HeaderPanel = new() { Orientation = Orientation.Horizontal, Spacing = 8 }; - - HeaderPanel.Children.Add(new LocalIcon(IconType.Console) - { - VerticalAlignment = VerticalAlignment.Center, - Height = 24, - Width = 24, - HorizontalAlignment = HorizontalAlignment.Left - }); - - HeaderPanel.Children.Add(new TextBlock - { - Text = CoreTools.Translate("Command-line Output"), - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center - }); - - RichTextBlock CommandLineOutput = new() - { - FontFamily = new FontFamily("Consolas"), - TextWrapping = TextWrapping.Wrap, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch, - }; - - ScrollViewer ScrollView = new() - { - BorderBrush = new SolidColorBrush(), - Content = CommandLineOutput, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch, - }; - - Grid OutputGrid = new(); - OutputGrid.Children.Add(ScrollView); - OutputGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); - OutputGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); - Grid.SetColumn(ScrollView, 0); - Grid.SetRow(ScrollView, 0); - - Expander expander = new() - { - Header = HeaderPanel, - Content = OutputGrid, - CornerRadius = new CornerRadius(8), - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Stretch, - }; - - Paragraph par = new(); - foreach (var line in processOutput) - { - if (line.Type is AbstractOperation.OutputLine.LineType.STDOUT) - par.Inlines.Add(new Run { Text = line.Contents + "\x0a" }); - else if (line.Type is AbstractOperation.OutputLine.LineType.Header) - // TODO: Theme-aware colorss - par.Inlines.Add(new Run - { - Text = line.Contents + "\x0a", Foreground = new SolidColorBrush(Colors.Azure) - }); - else - par.Inlines.Add(new Run - { - Text = line.Contents + "\x0a", Foreground = new SolidColorBrush(Colors.Red) - }); - } - - CommandLineOutput.Blocks.Add(par); - - grid.Children.Add(headerContent); - grid.Children.Add(expander); - Grid.SetRow(headerContent, 0); - Grid.SetRow(expander, 1); - - dialog.Content = grid; - dialog.PrimaryButtonText = CoreTools.Translate("Retry"); - dialog.CloseButtonText = CoreTools.Translate("Close"); - dialog.DefaultButton = ContentDialogButton.Primary; - - return await Window.ShowDialogAsync(dialog); - } - } diff --git a/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs b/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs index 29d90e4dd..a27e08430 100644 --- a/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/IgnoredUpdates.xaml.cs @@ -27,7 +27,6 @@ public IgnoredUpdatesManager() UpdateData(); InitializeComponent(); IgnoredUpdatesList.ItemsSource = ignoredPackages; - // IgnoredUpdatesList.DoubleTapped += IgnoredUpdatesList_DoubleTapped; } private void UpdateData() diff --git a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs index a35ccbf59..340997cb2 100644 --- a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs @@ -657,18 +657,18 @@ public async void DoAction( if (action is OperationType.Install) { - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, newOptions)); + MainApp.Operations.Add((new InstallPackageOperation(package, newOptions))); } else if (action is OperationType.Uninstall) { if (await DialogHelper.ConfirmUninstallation(package)) { - MainApp.Instance.AddOperationToList(new UninstallPackageOperation(package, newOptions)); + MainApp.Operations.Add((new UninstallPackageOperation(package, newOptions))); } } else if (action is OperationType.Update) { - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package, newOptions)); + MainApp.Operations.Add((new UpdatePackageOperation(package, newOptions))); } else { diff --git a/src/UniGetUI/Pages/MainView.xaml b/src/UniGetUI/Pages/MainView.xaml index b4a75369e..3579ada1e 100644 --- a/src/UniGetUI/Pages/MainView.xaml +++ b/src/UniGetUI/Pages/MainView.xaml @@ -8,24 +8,150 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:interface="using:UniGetUI.Interface" xmlns:widgets="using:UniGetUI.Interface.Widgets" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:operations="using:UniGetUI.PackageOperations" + xmlns:operationWidgets="using:UniGetUI.Controls.OperationWidgets" mc:Ignorable="d" MinHeight="200" - MinWidth="200" - > + MinWidth="200"> <UserControl.Resources> - <widgets:BetterMenu x:Name="MoreNavButtonMenu" Placement="Right"> - <widgets:BetterMenuItem Text="Help" IconName="help" Name="HelpMenu" Click="HelpMenu_Click" /> - <MenuFlyoutSeparator Height="5"/> - <widgets:BetterMenuItem Text="WingetUI Log" IconName="buggy" Name="WingetUILogs" Click="UniGetUILogs_Click" /> - <widgets:BetterMenuItem Text="Package Manager logs" IconName="console" Name="ManagerLogsMenu" Click="ManagerLogsMenu_Click" /> - <widgets:BetterMenuItem Text="Operation history" IconName="history" Name="OperationHistoryMenu" Click="OperationHistoryMenu_Click" /> - <MenuFlyoutSeparator Height="5"/> - <widgets:BetterMenuItem x:Name="VersionMenuItem" IconName="info_round" IsEnabled="False" /> - <widgets:BetterMenuItem Text="Release notes" IconName="megaphone" Name="ReleaseNotesMenu" Click="ReleaseNotesMenu_Click" /> - <MenuFlyoutSeparator Height="5"/> - <widgets:BetterMenuItem Text="Quit WingetUI" IconName="close_round" Name="QuitWingetUI" Click="QuitUniGetUI_Click" /> - </widgets:BetterMenu> + + <ResourceDictionary> + <widgets:BetterMenu x:Name="MoreNavButtonMenu" Placement="Right"> + <widgets:BetterMenuItem Text="Help" IconName="help" Name="HelpMenu" Click="HelpMenu_Click" /> + <MenuFlyoutSeparator Height="5"/> + <widgets:BetterMenuItem Text="WingetUI Log" IconName="buggy" Name="WingetUILogs" Click="UniGetUILogs_Click" /> + <widgets:BetterMenuItem Text="Package Manager logs" IconName="console" Name="ManagerLogsMenu" Click="ManagerLogsMenu_Click" /> + <widgets:BetterMenuItem Text="Operation history" IconName="history" Name="OperationHistoryMenu" Click="OperationHistoryMenu_Click" /> + <MenuFlyoutSeparator Height="5"/> + <widgets:BetterMenuItem x:Name="VersionMenuItem" IconName="info_round" IsEnabled="False" /> + <widgets:BetterMenuItem Text="Release notes" IconName="megaphone" Name="ReleaseNotesMenu" Click="ReleaseNotesMenu_Click" /> + <MenuFlyoutSeparator Height="5"/> + <widgets:BetterMenuItem Text="Quit WingetUI" IconName="close_round" Name="QuitWingetUI" Click="QuitUniGetUI_Click" /> + </widgets:BetterMenu> + + <widgets:BetterMenu x:Name="OperationListMenu" Placement="Bottom"> + <widgets:BetterMenuItem Text="Retry failed operations" IconName="Reload" Name="RetryFailedOps" Click="RetryFailedOps_Click"/> + <widgets:BetterMenuItem Text="Clean successful operations" IconName="ClipboardList" Name="PausePendingOps" Click="ClearSuccessfulOps_Click"/> + <widgets:BetterMenuItem Text="Cancel all operations" IconName="Cross" Name="CancellAllOps" Click="CancellAllOps_Click"/> + </widgets:BetterMenu> + + <DataTemplate x:Key="OperationBadgeTemplate" x:DataType="operationWidgets:OperationBadge"> + <Button + Margin="6,0,0,0" Padding="0" + Width="32" Height="32" + ToolTipService.ToolTip="{x:Bind Tooltip}" + CornerRadius="6"> + <widgets:LocalIcon Icon="{x:Bind Icon}"/> + <Button.Flyout> + <Flyout> + <StackPanel Orientation="Horizontal" Spacing="12"> + <widgets:LocalIcon Icon="{x:Bind Icon}"/> + <StackPanel Orientation="Vertical" Spacing="6"> + <TextBlock Text="{x:Bind PrimaryBanner}" TextWrapping="WrapWholeWords" MaxWidth="200"/> + <TextBlock Opacity="0.6" Text="{x:Bind SecondaryBanner}" + Visibility="{x:Bind SecondaryBannerVisible}" TextWrapping="WrapWholeWords" MaxWidth="200"/> + </StackPanel> + </StackPanel> + </Flyout> + </Button.Flyout> + </Button> + </DataTemplate> + + <DataTemplate x:Key="OperationTemplate" x:DataType="operationWidgets:OperationControl"> + <ItemContainer AutomationProperties.Name="{x:Bind Title}"> + <Grid Background="{x:Bind Background, Mode=OneWay}" ColumnSpacing="0" RowSpacing="6" Padding="8"> + <Grid.Style> + <Style TargetType="Grid"> + <Setter Property="Background" Value="{ThemeResource SystemFillColorNeutralBackgroundBrush}"/> + <Setter Property="BorderBrush" Value="{StaticResource ExpanderContentBorderBrush}"/> + <Setter Property="BorderThickness" Value="1"/> + <Setter Property="CornerRadius" Value="8"/> + <Setter Property="Margin" Value="0"/> + <Setter Property="Padding" Value="0"/> + </Style> + </Grid.Style> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="40" /> + <ColumnDefinition Width="Auto"/> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="110" /> + <ColumnDefinition Width="36" /> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="Auto"/> + </Grid.RowDefinitions> + <Grid.Resources> + <ResourceDictionary> + <Style TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}"> + <Setter Property="Height" Value="32"/> + <Setter Property="CornerRadius" Value="2"/> + <Setter Property="BorderThickness" Value="0"/> + </Style> + </ResourceDictionary> + </Grid.Resources> + <Image + Grid.Column="0" VerticalAlignment="Center" + Width="32" Height="24" Margin="0"> + <Image.Source> + <BitmapImage UriSource="{x:Bind Icon, Mode=OneWay}"/> + </Image.Source> + </Image> + <TextBlock + Grid.Column="1" VerticalAlignment="Center" + Text="{x:Bind Title}" Margin="6,0,0,0" + /> + <Button + Grid.Column="2" VerticalAlignment="Center" + Name="OutputViewewBlock" HorizontalAlignment="Stretch" + FontFamily="Consolas" HorizontalContentAlignment="Left" + Content="{x:Bind LiveLine, Mode=OneWay}" CornerRadius="5" + Click="{x:Bind LiveLineClick}" Margin="12,0,0,0"/> + <Border + Grid.Column="2" Margin="12,0,0,0" + Height="12" VerticalAlignment="Bottom" + CornerRadius="6"> + <ProgressBar + IsIndeterminate="{x:Bind ProgressIndeterminate, Mode=OneWay}" + VerticalAlignment="Bottom" Margin="0,0,0,-2" + CornerRadius="0,0,6,6" Height="6" + Maximum="100" Value="{x:Bind ProgressValue, Mode=OneWay}" + Foreground="{x:Bind ProgressForeground, Mode=OneWay}" + /> + </Border> + <Border Grid.Column="3" Margin="0,0,0,0" CornerRadius="6"> + <ItemsRepeater + ItemTemplate="{StaticResource OperationBadgeTemplate}" + ItemsSource="{x:Bind Badges}"> + <ItemsRepeater.Layout> + <StackLayout Orientation="Horizontal" Spacing="0"/> + </ItemsRepeater.Layout> + </ItemsRepeater> + </Border> + <Button + Grid.Column="4" VerticalAlignment="Center" + HorizontalAlignment="Stretch" Margin="6,0,1,0" + CornerRadius="6,0,0,6" Content="{x:Bind ButtonText, Mode=OneWay}" + Click="{x:Bind ButtonClick}"/> + <Button + Grid.Column="5" VerticalAlignment="Center" + HorizontalAlignment="Stretch" Height="32" + BorderThickness="0" Padding="0" + CornerRadius="0,6,6,0" Margin="0,0,0,0" + PointerEntered="{x:Bind LoadMenu}" + GotFocus="{x:Bind LoadMenu}" + Flyout="{x:Bind OpMenu}"> + <SymbolIcon Symbol="More"/> + </Button> + </Grid> + </ItemContainer> + </DataTemplate> + + + </ResourceDictionary> + </UserControl.Resources> <Grid RowSpacing="4" ColumnSpacing="0"> @@ -49,11 +175,59 @@ </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> - <RowDefinition Height="Auto"/> + <RowDefinition Height="16"/> + <RowDefinition Height="Auto" MaxHeight="200" MinHeight="0"/> </Grid.RowDefinitions> - <ScrollView Grid.Column="0" Grid.ColumnSpan="7" Grid.Row="1" Margin="0" Padding="0,0,0,0" MaxHeight="200"> - <StackPanel Orientation="Vertical" Spacing="0" Margin="0,0,0,0" Padding="0,0,0,0" Name="OperationStackPanel" x:FieldModifier="public"/> - </ScrollView> + + <controls:GridSplitter + Grid.Column="0" Grid.ColumnSpan="7" Grid.Row="1" + Name="OperationSplitter" + Orientation="Horizontal" + CornerRadius="4" Height="12" Padding="0,0,0,0" + Margin="1,0,1,0"/> + <Grid + Grid.Column="0" Grid.ColumnSpan="7" Grid.Row="1"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="Auto"/> + <ColumnDefinition Width="Auto"/> + <ColumnDefinition Width="15"/> + </Grid.ColumnDefinitions> + <HyperlinkButton + Grid.Column="1" Height="12" + Name="ExpandCollapseOpList" + Click="ExpandCollapseOpList_Click" + Padding="12,0,12,0" CornerRadius="4" + Foreground="{ThemeResource ScrollBarButtonPointerOverBackgroundThemeBrush}" > + <FontIcon Glyph="" FontSize="14"/> + </HyperlinkButton> + <HyperlinkButton + Grid.Column="2" Height="12" + Name="OperationSplitterMenuButton" + Click="OperationSplitterMenuButton_Click" + Padding="12,0,12,0" CornerRadius="4" + Foreground="{ThemeResource ScrollBarButtonPointerOverBackgroundThemeBrush}" > + <FontIcon Glyph="" FontSize="24"/> + </HyperlinkButton> + </Grid> + <ListView + SizeChanged="OperationScrollView_SizeChanged" + Grid.Column="0" Grid.ColumnSpan="7" Grid.Row="2" + Padding="0,0,0,0" + + ItemTemplate="{StaticResource OperationTemplate}" + Margin="0,0,0,0" SelectionMode="None" + Name="OperationList" x:FieldModifier="public"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Vertical" Spacing="8"/> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ListView.Resources> + <SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent" /> + <SolidColorBrush x:Key="ItemContainerPressedBackground" Color="Transparent" /> + </ListView.Resources> + </ListView> </Grid> <ScrollViewer HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Hidden" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" Margin="4,0,4,4" Padding="0,0,0,0"> diff --git a/src/UniGetUI/Pages/MainView.xaml.cs b/src/UniGetUI/Pages/MainView.xaml.cs index 34202c51c..a4c5039b9 100644 --- a/src/UniGetUI/Pages/MainView.xaml.cs +++ b/src/UniGetUI/Pages/MainView.xaml.cs @@ -13,6 +13,11 @@ using Windows.UI.Core; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.Pages.DialogPages; +using UniGetUI.PackageEngine.Operations; +using CommunityToolkit.WinUI.Controls; +using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageEngine; +using UniGetUI.PackageOperations; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -52,6 +57,7 @@ public sealed partial class MainView : UserControl public MainView() { InitializeComponent(); + OperationList.ItemsSource = MainApp.Operations._operationList; DiscoverPage = new DiscoverSoftwarePage(); UpdatesPage = new SoftwareUpdatesPage { @@ -108,6 +114,9 @@ public MainView() Settings.Set("AlreadyWarnedAboutAdmin", true); DialogHelper.WarnAboutAdminRights(); } + + UpdateOperationsLayout(); + MainApp.Operations._operationList.CollectionChanged += (_, _) => UpdateOperationsLayout(); } public void LoadDefaultPage() @@ -119,7 +128,7 @@ public void LoadDefaultPage() "installed" => PageType.Installed, "bundles" => PageType.Bundles, "settings" => PageType.Settings, - _ => MainApp.Instance.TooltipStatus.AvailableUpdates > 0 ? PageType.Updates : PageType.Discover + _ => MainApp.Tooltip.AvailableUpdates > 0 ? PageType.Updates : PageType.Discover }; NavigateTo(type); } @@ -280,5 +289,126 @@ public void ShowHelp() private void QuitUniGetUI_Click(object sender, RoutedEventArgs e) => MainApp.Instance.DisposeAndQuit(); + + + private bool ResizingOPLayout; + private int OpListChanges; + + + bool isCollapsed; + + private void UpdateOperationsLayout() + { + OpListChanges++; + + ResizingOPLayout = true; + int OpCount = MainApp.Operations._operationList.Count; + int maxHeight = Math.Max((OpCount * 58) - 7, 0); + + MainContentPresenterGrid.RowDefinitions[2].MaxHeight = maxHeight; + + if (OpCount > 0) + { + if(isCollapsed) + { + MainContentPresenterGrid.RowDefinitions[2].Height = new GridLength(0); + MainContentPresenterGrid.RowDefinitions[1].Height = new GridLength(16); + OperationSplitter.Visibility = Visibility.Visible; + OperationSplitterMenuButton.Visibility = Visibility.Visible; + // OperationScrollView.Visibility = Visibility.Collapsed; + OperationSplitter.IsEnabled = false; + } + else + { + //if (int.TryParse(Settings.GetValue("OperationHistoryPreferredHeight"), out int setHeight) && setHeight < maxHeight) + // MainContentPresenterGrid.RowDefinitions[2].Height = new GridLength(setHeight); + //else + MainContentPresenterGrid.RowDefinitions[2].Height = new GridLength(Math.Min(maxHeight, 200)); + MainContentPresenterGrid.RowDefinitions[1].Height = new GridLength(16); + OperationSplitter.Visibility = Visibility.Visible; + OperationSplitterMenuButton.Visibility = Visibility.Visible; + // OperationScrollView.Visibility = Visibility.Visible; + OperationSplitter.IsEnabled = true; + } + } + else + { + MainContentPresenterGrid.RowDefinitions[1].Height = new GridLength(0); + MainContentPresenterGrid.RowDefinitions[2].Height = new GridLength(0); + OperationSplitter.Visibility = Visibility.Collapsed; + OperationSplitterMenuButton.Visibility = Visibility.Collapsed; + // OperationScrollView.Visibility = Visibility.Collapsed; + } + ResizingOPLayout = false; + } + + // int lastSaved = -1; + private async void OperationScrollView_SizeChanged(object sender, SizeChangedEventArgs e) + { + if (ResizingOPLayout) + return; + + if(OpListChanges > 0) + { + OpListChanges--; + return; + } + + //lastSaved = (int)e.NewSize.Height; + //await Task.Delay(100); + //if ((int)e.NewSize.Height == lastSaved) + // Settings.SetValue("OperationHistoryPreferredHeight", lastSaved.ToString()); + } + + private void OperationSplitterMenuButton_Click(object sender, RoutedEventArgs e) + { + OperationListMenu.ShowAt(OperationSplitterMenuButton, new FlyoutShowOptions { ShowMode = FlyoutShowMode.Standard }); + } + + private void ExpandCollapseOpList_Click(object sender, RoutedEventArgs e) + { + if (isCollapsed) + { + isCollapsed = false; + ExpandCollapseOpList.Content = new FontIcon() { Glyph = "\uE96E", FontSize = 14 }; + UpdateOperationsLayout(); + } + else + { + isCollapsed = true; + ExpandCollapseOpList.Content = new FontIcon() { Glyph = "\uE96D", FontSize = 14 }; + UpdateOperationsLayout(); + } + } + + private void CancellAllOps_Click(object sender, RoutedEventArgs e) + { + foreach (var widget in MainApp.Operations._operationList) + { + var operation = widget.Operation; + if (operation.Status is OperationStatus.InQueue or OperationStatus.Running) + operation.Cancel(); + } + } + + private void RetryFailedOps_Click(object sender, RoutedEventArgs e) + { + foreach (var widget in MainApp.Operations._operationList) + { + var operation = widget.Operation; + if (operation.Status is OperationStatus.Failed) + operation.Retry(AbstractOperation.RetryMode.Retry); + } + } + + private void ClearSuccessfulOps_Click(object sender, RoutedEventArgs e) + { + foreach (var widget in MainApp.Operations._operationList.ToArray()) + { + var operation = widget.Operation; + if (operation.Status is OperationStatus.Succeeded) + widget.Close(); + } + } } } diff --git a/src/UniGetUI/Pages/SettingsPage.xaml b/src/UniGetUI/Pages/SettingsPage.xaml index 344697dc6..0e7116976 100644 --- a/src/UniGetUI/Pages/SettingsPage.xaml +++ b/src/UniGetUI/Pages/SettingsPage.xaml @@ -204,9 +204,9 @@ <!-- Updates Settings --> <widgets:SettingsEntry - Text="Updates preferences" + Text="Install and update preferences" x:Name="UpdatesOptionsExpander" - UnderText="Change how UniGetUI checks and installs available updates for your packages" + UnderText="Change how UniGetUI installs packages, and checks and installs available updates" Icon="update"> <Toolkit:SettingsExpander.Items> <widgets:CheckboxCard @@ -229,7 +229,13 @@ SettingName="AskToDeleteNewDesktopShortcuts" ButtonText="Manage shortcuts" Click="CheckboxButtonCard_OnClick" - /> <!-- UniGetUI will only delete desktop shortcuts that were newly added after an update operation and that were explicitly approved --> + /> + <widgets:ComboboxCard + x:Name="ParallelOperationCount" + Text="Choose how many operations shouls be performed in parallel" + SettingName="ParallelOperationCount" + ValueChanged="ParallelOperationCount_OnValueChanged" + /> </Toolkit:SettingsExpander.Items> </widgets:SettingsEntry> @@ -339,10 +345,6 @@ SettingName="UseUserGSudo" StateChanged="UseUserGSudoToggle_StateChanged" /> - <widgets:CheckboxCard - Text="Allow package operations to be performed in parallel" - SettingName="AllowParallelInstalls" - /> <widgets:CheckboxCard Text="Disable the 1-minute timeout for package-related operations" ForceInversion="True" diff --git a/src/UniGetUI/Pages/SettingsPage.xaml.cs b/src/UniGetUI/Pages/SettingsPage.xaml.cs index 894194609..8c526ea16 100644 --- a/src/UniGetUI/Pages/SettingsPage.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPage.xaml.cs @@ -17,6 +17,7 @@ using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.Managers.VcpkgManager; using UniGetUI.PackageEngine.PackageClasses; +using UniGetUI.PackageOperations; using UniGetUI.Pages.DialogPages; // To learn more about WinUI, the WinUI project structure, @@ -98,6 +99,19 @@ public SettingsPage() StartupPageSelector.AddItem(CoreTools.AutoTranslated("Settings"), "settings"); StartupPageSelector.ShowAddedItems(); + for (int i = 1; i <= 10; i++) + { + ParallelOperationCount.AddItem(i.ToString(), i.ToString(), false); + + } + ParallelOperationCount.AddItem("15", "15", false); + ParallelOperationCount.AddItem("20", "20", false); + ParallelOperationCount.AddItem("30", "30", false); + ParallelOperationCount.AddItem("50", "50", false); + ParallelOperationCount.AddItem("75", "75", false); + ParallelOperationCount.AddItem("100", "100", false); + ParallelOperationCount.ShowAddedItems(); + // Backup Section BackupDirectoryLabel = (TextBlock)((StackPanel)ChangeBackupDirectory.Description).Children.ElementAt(0); ResetBackupDirectory = (HyperlinkButton)((StackPanel)ChangeBackupDirectory.Description).Children.ElementAt(1); @@ -428,13 +442,13 @@ void EnableOrDisableEntries() AdminCard._checkbox.Content = (AdminCard._checkbox.Content.ToString() ?? "").Replace("{pm}", Manager.DisplayName); ExtraSettingsCards[Manager].Insert(index++, AdminCard); - CheckboxCard ParallelCard = new() + /*CheckboxCard ParallelCard = new() { Text = CoreTools.AutoTranslated("Allow {pm} operations to be performed in parallel"), SettingName = "AllowParallelInstallsForManager" + Manager.Name, }; ParallelCard._checkbox.Content = (ParallelCard._checkbox.Content.ToString() ?? "").Replace("{pm}", Manager.DisplayName); - ExtraSettingsCards[Manager].Insert(index++, ParallelCard); + ExtraSettingsCards[Manager].Insert(index++, ParallelCard);*/ if (Manager.Capabilities.SupportsCustomSources && Manager is not Vcpkg) { @@ -742,5 +756,13 @@ private void CheckboxButtonCard_OnClick(object? sender, RoutedEventArgs e) { _ = DialogHelper.ManageDesktopShortcuts(); } + + private void ParallelOperationCount_OnValueChanged(object? sender, EventArgs e) + { + if (int.TryParse(ParallelOperationCount.SelectedValue(), out int value)) + { + AbstractOperation.MAX_OPERATIONS = value; + } + } } } diff --git a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs index 2c6af7573..dd139a66b 100644 --- a/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs +++ b/src/UniGetUI/Pages/SoftwarePages/AbstractPackagesPage.xaml.cs @@ -863,15 +863,15 @@ protected void PerformMainPackageAction(IPackage? package) if (PAGE_ROLE == OperationType.Install) { - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package)); + MainApp.Operations.Add((new InstallPackageOperation(package))); } else if (PAGE_ROLE == OperationType.Update) { - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package)); + MainApp.Operations.Add((new UpdatePackageOperation(package))); } else // if (PageRole == OperationType.Uninstall) { - MainApp.Instance.AddOperationToList(new UninstallPackageOperation(package)); + MainApp.Operations.Add((new UninstallPackageOperation(package))); } } diff --git a/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs b/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs index 8bb16099c..21c3eafb5 100644 --- a/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/DiscoverSoftwarePage.cs @@ -208,7 +208,7 @@ public override void GenerateToolBar() { foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package)); + MainApp.Operations.Add((new InstallPackageOperation(package))); } }; @@ -217,7 +217,7 @@ public override void GenerateToolBar() foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { InstallationOptions options = await InstallationOptions.FromPackageAsync(package, elevated: true); - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, options)); + MainApp.Operations.Add((new InstallPackageOperation(package, options))); } }; @@ -226,7 +226,7 @@ public override void GenerateToolBar() foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { InstallationOptions options = await InstallationOptions.FromPackageAsync(package, no_integrity: true); - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, options)); + MainApp.Operations.Add((new InstallPackageOperation(package, options))); } }; @@ -235,7 +235,7 @@ public override void GenerateToolBar() foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { InstallationOptions options = await InstallationOptions.FromPackageAsync(package, interactive: true); - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, options)); + MainApp.Operations.Add((new InstallPackageOperation(package, options))); } }; @@ -312,7 +312,7 @@ private void MenuInstall_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package)); + MainApp.Operations.Add((new InstallPackageOperation(package))); } private async void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) @@ -323,8 +323,8 @@ private async void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, - await InstallationOptions.FromPackageAsync(package, no_integrity: true))); + MainApp.Operations.Add((new InstallPackageOperation(package, + await InstallationOptions.FromPackageAsync(package, no_integrity: true)))); } private async void MenuInteractive_Invoked(object sender, RoutedEventArgs e) @@ -335,8 +335,8 @@ private async void MenuInteractive_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, - await InstallationOptions.FromPackageAsync(package, interactive: true))); + MainApp.Operations.Add((new InstallPackageOperation(package, + await InstallationOptions.FromPackageAsync(package, interactive: true)))); } private async void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) @@ -347,8 +347,8 @@ private async void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, - await InstallationOptions.FromPackageAsync(package, elevated: true))); + MainApp.Operations.Add((new InstallPackageOperation(package, + await InstallationOptions.FromPackageAsync(package, elevated: true)))); } private void MenuInstallSettings_Invoked(object sender, RoutedEventArgs e) diff --git a/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs b/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs index 0dc3b182a..b213a1f64 100644 --- a/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/InstalledPackagesPage.cs @@ -350,7 +350,7 @@ public async void ConfirmAndUninstall(IPackage package, IInstallationOptions opt { if (await DialogHelper.ConfirmUninstallation(package)) { - MainApp.Instance.AddOperationToList(new UninstallPackageOperation(package, options)); + MainApp.Operations.Add((new UninstallPackageOperation(package, options))); } } @@ -360,8 +360,8 @@ public async void ConfirmAndUninstall(IEnumerable<IPackage> packages, bool? elev { foreach (IPackage package in packages) { - MainApp.Instance.AddOperationToList(new UninstallPackageOperation(package, - await InstallationOptions.FromPackageAsync(package, elevated, interactive, remove_data: remove_data))); + MainApp.Operations.Add((new UninstallPackageOperation(package, + await InstallationOptions.FromPackageAsync(package, elevated, interactive, remove_data: remove_data)))); } } } @@ -468,7 +468,7 @@ private void MenuReinstall_Invoked(object sender, RoutedEventArgs args) return; } - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package)); + MainApp.Operations.Add((new InstallPackageOperation(package))); } private void MenuUninstallThenReinstall_Invoked(object sender, RoutedEventArgs args) @@ -479,8 +479,8 @@ private void MenuUninstallThenReinstall_Invoked(object sender, RoutedEventArgs a return; } - MainApp.Instance.AddOperationToList(new UninstallPackageOperation(package, IgnoreParallelInstalls: true)); - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, IgnoreParallelInstalls: true)); + MainApp.Operations.Add((new UninstallPackageOperation(package, IgnoreParallelInstalls: true))); + MainApp.Operations.Add((new InstallPackageOperation(package, IgnoreParallelInstalls: true))); } private async void MenuIgnorePackage_Invoked(object sender, RoutedEventArgs args) diff --git a/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs b/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs index db08e821d..c675a5075 100644 --- a/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/PackageBundlesPage.cs @@ -21,7 +21,7 @@ namespace UniGetUI.Interface.SoftwarePages { - public class PackageBundlesPage : AbstractPackagesPage + public partial class PackageBundlesPage : AbstractPackagesPage { private BetterMenuItem? MenuInstallOptions; private BetterMenuItem? MenuInstall; @@ -329,8 +329,8 @@ public async Task ImportAndInstallPackage(IEnumerable<IPackage> packages, bool? foreach (Package package in packages_to_install) { - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, - await InstallationOptions.FromPackageAsync(package, elevated, interactive, skiphash))); + MainApp.Operations.Add((new InstallPackageOperation(package, + await InstallationOptions.FromPackageAsync(package, elevated, interactive, skiphash)))); } } diff --git a/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs b/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs index b263de141..f9154d9f6 100644 --- a/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs +++ b/src/UniGetUI/Pages/SoftwarePages/SoftwareUpdatesPage.cs @@ -277,7 +277,7 @@ public override void GenerateToolBar() { foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package)); + MainApp.Operations.Add((new UpdatePackageOperation(package))); } }; @@ -286,7 +286,7 @@ public override void GenerateToolBar() foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { InstallationOptions options = await InstallationOptions.FromPackageAsync(package, elevated: true); - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package, options)); + MainApp.Operations.Add((new UpdatePackageOperation(package, options))); } }; @@ -295,7 +295,7 @@ public override void GenerateToolBar() foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { InstallationOptions options = await InstallationOptions.FromPackageAsync(package, no_integrity: true); - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package, options)); + MainApp.Operations.Add((new UpdatePackageOperation(package, options))); } }; @@ -304,7 +304,7 @@ public override void GenerateToolBar() foreach (IPackage package in FilteredPackages.GetCheckedPackages()) { InstallationOptions options = await InstallationOptions.FromPackageAsync(package, interactive: true); - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package, options)); + MainApp.Operations.Add((new UpdatePackageOperation(package, options))); } }; @@ -313,11 +313,7 @@ public override void GenerateToolBar() protected override void WhenPackageCountUpdated() { - try - { - MainApp.Instance.TooltipStatus.AvailableUpdates = Loader.Count(); - } - catch { } + MainApp.Tooltip.AvailableUpdates = Loader.Count(); } public void UpdateAll() @@ -326,7 +322,7 @@ public void UpdateAll() { if (package.Tag is not PackageTag.BeingProcessed and not PackageTag.OnQueue) { - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package)); + MainApp.Operations.Add((new UpdatePackageOperation(package))); } } } @@ -458,7 +454,7 @@ private void MenuInstall_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package)); + MainApp.Operations.Add((new UpdatePackageOperation(package))); } private async void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) @@ -469,8 +465,8 @@ private async void MenuSkipHash_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package, - await InstallationOptions.FromPackageAsync(package, no_integrity: true))); + MainApp.Operations.Add((new UpdatePackageOperation(package, + await InstallationOptions.FromPackageAsync(package, no_integrity: true)))); } private async void MenuInteractive_Invoked(object sender, RoutedEventArgs e) @@ -481,8 +477,8 @@ private async void MenuInteractive_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package, - await InstallationOptions.FromPackageAsync(package, interactive: true))); + MainApp.Operations.Add((new UpdatePackageOperation(package, + await InstallationOptions.FromPackageAsync(package, interactive: true)))); } private async void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) @@ -493,8 +489,8 @@ private async void MenuAsAdmin_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package, - await InstallationOptions.FromPackageAsync(package, elevated: true))); + MainApp.Operations.Add((new UpdatePackageOperation(package, + await InstallationOptions.FromPackageAsync(package, elevated: true)))); } private void MenuUpdateAfterUninstall_Invoked(object sender, RoutedEventArgs e) @@ -505,8 +501,8 @@ private void MenuUpdateAfterUninstall_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new UninstallPackageOperation(package, IgnoreParallelInstalls: true)); - MainApp.Instance.AddOperationToList(new InstallPackageOperation(package, IgnoreParallelInstalls: true)); + MainApp.Operations.Add((new UninstallPackageOperation(package, IgnoreParallelInstalls: true))); + MainApp.Operations.Add((new InstallPackageOperation(package, IgnoreParallelInstalls: true))); } private void MenuUninstall_Invoked(object sender, RoutedEventArgs e) @@ -517,7 +513,7 @@ private void MenuUninstall_Invoked(object sender, RoutedEventArgs e) return; } - MainApp.Instance.AddOperationToList(new UninstallPackageOperation(package)); + MainApp.Operations.Add((new UninstallPackageOperation(package))); } private void MenuIgnorePackage_Invoked(object sender, RoutedEventArgs e) @@ -552,7 +548,7 @@ public void UpdatePackageForId(string id) { if (package.Id == id) { - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package)); + MainApp.Operations.Add((new UpdatePackageOperation(package))); Logger.Info($"[WIDGETS] Updating package with id {id}"); break; } @@ -568,7 +564,7 @@ public void UpdateAllPackagesForManager(string manager) { if (package.Manager.Name == manager || package.Manager.DisplayName == manager) { - MainApp.Instance.AddOperationToList(new UpdatePackageOperation(package)); + MainApp.Operations.Add((new UpdatePackageOperation(package))); } } } diff --git a/src/UniGetUI/UniGetUI.csproj b/src/UniGetUI/UniGetUI.csproj index 9bdf68a39..b1ac7ce2a 100644 --- a/src/UniGetUI/UniGetUI.csproj +++ b/src/UniGetUI/UniGetUI.csproj @@ -5,7 +5,7 @@ <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier> <Platforms>ARM64;x64</Platforms> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion> <Authors>Martí Climent and the contributors</Authors> <PublisherName>Martí Climent</PublisherName> @@ -77,13 +77,16 @@ <PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.1.240916" /> <PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.1.240916" /> <PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.1.240916" /> - <PackageReference Include="H.NotifyIcon.WinUI" Version="2.1.4" /> + <PackageReference Include="H.NotifyIcon.WinUI" Version="2.2.0" /> <PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.2.0" /> <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.241114003" /> <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1742" /> + <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> + <PackageReference Include="PhotoSauce.MagicScaler" Version="0.15.0" /> <PackageReference Include="System.Net.Http" Version="4.3.4" /> + <PackageReference Include="System.Private.Uri" Version="4.3.2" /> <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" /> - <PackageReference Include="YamlDotNet" Version="16.2.0" /> + <PackageReference Include="YamlDotNet" Version="16.2.1" /> <Manifest Include="$(ApplicationManifest)" /> </ItemGroup> diff --git a/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj b/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj index bed078e66..b848b92e9 100644 --- a/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj +++ b/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj @@ -1,10 +1,10 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>net8.0-windows10.0.22621.0</TargetFramework> + <TargetFramework>net8.0-windows10.0.26100.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion> - <!--WindowsSdkPackageVersion>10.0.26100.56</WindowsSdkPackageVersion--> + <WindowsSdkPackageVersion>10.0.26100.56</WindowsSdkPackageVersion> <Platforms>x64</Platforms> <SelfContained>true</SelfContained> <RootNamespace>WindowsPackageManager.Interop</RootNamespace>