diff --git a/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs b/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs index 4ecefbec10..58178e0ca6 100644 --- a/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs +++ b/src/UniGetUI.Core.Settings/SettingsEngine_Lists.cs @@ -102,7 +102,7 @@ public static void SetList(string setting, List value) public static void AddToList(string setting, T value) { List? list = _getList(setting); - if (list == null) return; + list ??= []; list.Add(value); SetList(setting, list); diff --git a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs index a981de5470..e728c24929 100644 --- a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs +++ b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs @@ -1,5 +1,6 @@ using UniGetUI.Core.Classes; using UniGetUI.Core.Data; +using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; using UniGetUI.Interface.Enums; @@ -7,6 +8,7 @@ using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.Managers.WingetManager; +using UniGetUI.PackageEngine.PackageClasses; using UniGetUI.PackageEngine.PackageLoader; using UniGetUI.PackageOperations; @@ -47,9 +49,30 @@ public PackageOperation( Package.SetTag(PackageTag.OnQueue); }; - CancelRequested += (_, _) => Package.SetTag(PackageTag.Default); - OperationSucceeded += (_, _) => HandleSuccess(); - OperationFailed += (_, _) => HandleFailure(); + CancelRequested += (_, _) => + { + Settings.AddToList("AdvancedOperationHistory", new AdvancedOperationHistoryEntry( + Package, Role, OperationStatus.Canceled, + string.Join("\n", GetOutput().Select(item => item.Item1)) + )); + Package.SetTag(PackageTag.Default); + }; + OperationSucceeded += (_, _) => + { + Settings.AddToList("AdvancedOperationHistory", new AdvancedOperationHistoryEntry( + Package, Role, OperationStatus.Succeeded, + string.Join("\n", GetOutput().Select(item => item.Item1)) + )); + HandleSuccess(); + }; + OperationFailed += (_, _) => + { + Settings.AddToList("AdvancedOperationHistory", new AdvancedOperationHistoryEntry( + Package, Role, OperationStatus.Failed, + string.Join("\n", GetOutput().Select(item => item.Item1)) + )); + HandleFailure(); + }; } private bool RequiresAdminRights() diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs index 353012e3ea..af11bc079f 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs @@ -98,21 +98,26 @@ public Package( ignoredId = IgnoredUpdatesDatabase.GetIgnoredIdForPackage(this); - _iconId = Manager.Name switch + _iconId = GetPackageIconId(id, Manager.Name, Source.Name); + } + + public static string GetPackageIconId(string PackageId, string ManagerName, string SourceName) + { + return ManagerName switch { - "Winget" => Source.Name switch + "Winget" => SourceName switch { - "Steam" => id.ToLower().Split("\\")[^1].Replace("steam app ", "steam-").Trim(), - "Local PC" => id.ToLower().Split("\\")[^1], - "Microsoft Store" => id.IndexOf('_') < id.IndexOf('.') ? // If the first underscore is before the period, this ID has no publisher - string.Join('_', id.ToLower().Split("\\")[1].Split("_")[0..^4]) : // no publisher: remove `MSIX\`, then the standard ending _version_arch__{random id} - string.Join('_', string.Join('.', id.ToLower().Split(".")[1..]).Split("_")[0..^4]), // remove the publisher (before the first .), then the standard _version_arch__{random id} - _ => string.Join('.', id.ToLower().Split(".")[1..]), + "Steam" => PackageId.ToLower().Split("\\")[^1].Replace("steam app ", "steam-").Trim(), + "Local PC" => PackageId.ToLower().Split("\\")[^1], + "Microsoft Store" => PackageId.IndexOf('_') < PackageId.IndexOf('.') ? // If the first underscore is before the period, this ID has no publisher + string.Join('_', PackageId.ToLower().Split("\\")[1].Split("_")[0..^4]) : // no publisher: remove `MSIX\`, then the standard ending _version_arch__{random id} + string.Join('_', string.Join('.', PackageId.ToLower().Split(".")[1..]).Split("_")[0..^4]), // remove the publisher (before the first .), then the standard _version_arch__{random id} + _ => string.Join('.', PackageId.ToLower().Split(".")[1..]), }, - "Scoop" => id.ToLower().Replace(".app", ""), - "Chocolatey" => id.ToLower().Replace(".install", "").Replace(".portable", ""), - "vcpkg" => id.ToLower().Split(":")[0].Split("[")[0], - _ => id.ToLower() + "Scoop" => PackageId.ToLower().Replace(".app", ""), + "Chocolatey" => PackageId.ToLower().Replace(".install", "").Replace(".portable", ""), + "vcpkg" => PackageId.ToLower().Split(":")[0].Split("[")[0], + _ => PackageId.ToLower() }; } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/SimplePackage.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/SimplePackage.cs new file mode 100644 index 0000000000..b9c047ef42 --- /dev/null +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/SimplePackage.cs @@ -0,0 +1,92 @@ +using System.Text.Json.Serialization; +using UniGetUI.Interface.Enums; +using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageEngine.Interfaces; + +namespace UniGetUI.PackageEngine.PackageClasses +{ + public class SimplePackage + { + public SimplePackage(IPackage source) + { + Description = "Not loaded"; + Tags = []; + Name = source.Name; + Id = source.Id; + VersionString = source.VersionString; + NewVersionString = source.NewVersionString; + IconId = Package.GetPackageIconId(source.Id, source.Manager.Name, source.Source.Name); + ManagerName = source.Manager.Name; + ManagerDisplayName = source.Manager.DisplayName; + ManagerIconId = source.Manager.Properties.IconId; + SourceName = source.Source.Name; + SourceUrl = source.Source.Url; + SourceIconId = source.Source.IconId; + } + + [JsonConstructor] + public SimplePackage( + string description, string[] tags, string name, string id, + string versionString, string newVersionString, string iconId, + string managerName, string managerDisplayName, IconType managerIconId, + string sourceName, Uri sourceUrl, IconType sourceIconId) + { + Description = description; + Tags = tags; + Name = name; + Id = id; + VersionString = versionString; + NewVersionString = newVersionString; + IconId = iconId; + ManagerName = managerName; + ManagerDisplayName = managerDisplayName; + ManagerIconId = managerIconId; + SourceName = sourceName; + SourceUrl = sourceUrl; + SourceIconId = sourceIconId; + } + + public string Description { get; } + public string[] Tags { get; } + public string Name { get; } + public string Id { get; } + public string VersionString { get; } + public string NewVersionString { get; } + public string IconId { get; } + public string ManagerName { get; } + public string ManagerDisplayName { get; } + public IconType ManagerIconId { get; } + public string SourceName { get; } + public Uri SourceUrl { get; } + public IconType SourceIconId { get; } + } + + public class AdvancedOperationHistoryEntry : SimplePackage + { + public AdvancedOperationHistoryEntry(IPackage source, OperationType type, OperationStatus status, string logs) : base(source) + { + Type = type; + Status = status; + Logs = logs; + } + + [JsonConstructor] + public AdvancedOperationHistoryEntry( + OperationType type, OperationStatus status, string logs, + string description, string[] tags, string name, string id, + string versionString, string newVersionString, string iconId, + string managerName, string managerDisplayName, IconType managerIconId, + string sourceName, Uri sourceUrl, IconType sourceIconId) + : base(description, tags, name, id, versionString, newVersionString, iconId, + managerName, managerDisplayName, managerIconId, sourceName, sourceUrl, sourceIconId) + { + Type = type; + Status = status; + Logs = logs; + } + + public OperationType Type { get; } + public OperationStatus Status { get; } + public string Logs { get; } + }; +} \ No newline at end of file diff --git a/src/UniGetUI/Pages/AdvancedOperationHistoryPage.xaml b/src/UniGetUI/Pages/AdvancedOperationHistoryPage.xaml new file mode 100644 index 0000000000..2a6b5dd532 --- /dev/null +++ b/src/UniGetUI/Pages/AdvancedOperationHistoryPage.xaml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna + aliqua. Ut enim ad minim veniam, quis nostrud exercitation + ullamco laboris nisi ut aliquip ex ea commodo consequat. + Duis aute irure dolor in reprehenderit in voluptate velit + esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + occaecat cupidatat non proident, sunt in culpa qui officia + deserunt mollit anim id est laborum. + + + + + + + + + + diff --git a/src/UniGetUI/Pages/AdvancedOperationHistoryPage.xaml.cs b/src/UniGetUI/Pages/AdvancedOperationHistoryPage.xaml.cs new file mode 100644 index 0000000000..e9c0a67082 --- /dev/null +++ b/src/UniGetUI/Pages/AdvancedOperationHistoryPage.xaml.cs @@ -0,0 +1,43 @@ +using System.Collections.ObjectModel; +using Microsoft.UI.Xaml.Controls; +using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Logging; +using UniGetUI.Core.Tools; +using UniGetUI.Interface.Enums; +using UniGetUI.PackageEngine.Enums; +using UniGetUI.PackageEngine.PackageClasses; + +namespace UniGetUI.Interface.Pages +{ + + public partial class AdvancedOperationHistoryPage : IKeyboardShortcutListener, IEnterLeaveListener + { + private ObservableCollection Items = []; + + public AdvancedOperationHistoryPage() + { + InitializeComponent(); + + LoadOperationHistory(); + } + + private void LoadOperationHistory() + { + Items.Clear(); + + Items = [.. Settings.GetList("AdvancedOperationHistory") ?? []]; + AdvancedOperationHistoryList.ItemsSource = Items; + } + + public void ReloadTriggered() + => LoadOperationHistory(); + public void SelectAllTriggered() + { } + public void SearchTriggered() + { } + public void OnEnter() + => LoadOperationHistory(); + public void OnLeave() + { } + } +} diff --git a/src/UniGetUI/Pages/MainView.xaml b/src/UniGetUI/Pages/MainView.xaml index c4ffc27c91..b8b11ea598 100644 --- a/src/UniGetUI/Pages/MainView.xaml +++ b/src/UniGetUI/Pages/MainView.xaml @@ -23,7 +23,13 @@ - + + + + + + + diff --git a/src/UniGetUI/Pages/MainView.xaml.cs b/src/UniGetUI/Pages/MainView.xaml.cs index 9a7eec35f5..b7cc4254f9 100644 --- a/src/UniGetUI/Pages/MainView.xaml.cs +++ b/src/UniGetUI/Pages/MainView.xaml.cs @@ -31,6 +31,7 @@ public enum PageType OwnLog, ManagerLog, OperationHistory, + AdvancedOperationHistory, Help, Null // Used for initializers } @@ -45,6 +46,7 @@ public sealed partial class MainView : UserControl private UniGetUILogPage? UniGetUILogPage; private ManagerLogsPage? ManagerLogPage; private OperationHistoryPage? OperationHistoryPage; + private AdvancedOperationHistoryPage? AdvancedOperationHistoryPage; private HelpPage? HelpPage; private PageType OldPage_t = PageType.Null; @@ -137,6 +139,7 @@ public void LoadDefaultPage() "installed" => PageType.Installed, "bundles" => PageType.Bundles, "settings" => PageType.Settings, + "ophist" => PageType.AdvancedOperationHistory, _ => MainApp.Tooltip.AvailableUpdates > 0 ? PageType.Updates : PageType.Discover }; NavigateTo(type); @@ -172,6 +175,7 @@ private Page GetPageForType(PageType type) PageType.OwnLog => UniGetUILogPage ??= new UniGetUILogPage(), PageType.ManagerLog => ManagerLogPage ??= new ManagerLogsPage(), PageType.OperationHistory => OperationHistoryPage ??= new OperationHistoryPage(), + PageType.AdvancedOperationHistory => AdvancedOperationHistoryPage ??= new AdvancedOperationHistoryPage(), PageType.Help => HelpPage ??= new HelpPage(), PageType.Null => throw new InvalidCastException("Page type is Null"), _ => throw new InvalidDataException($"Unknown page type {type}") @@ -189,6 +193,7 @@ private static PageType GetNextPage(PageType type) // "Extra" pages PageType.OperationHistory => PageType.Discover, + PageType.AdvancedOperationHistory => PageType.Discover, PageType.OwnLog => PageType.Discover, PageType.ManagerLog => PageType.Discover, PageType.Help => PageType.Discover, @@ -208,6 +213,7 @@ private static PageType GetPreviousPage(PageType type) // "Extra" pages PageType.OperationHistory => PageType.Discover, + PageType.AdvancedOperationHistory => PageType.Discover, PageType.OwnLog => PageType.Discover, PageType.ManagerLog => PageType.Discover, PageType.Help => PageType.Discover, @@ -227,7 +233,7 @@ private void SelectNavButtonForPage(PageType page) SettingsNavButton.IsChecked = page is PageType.Settings; AboutNavButton.IsChecked = false; - MoreNavButton.IsChecked = page is PageType.Help or PageType.ManagerLog or PageType.OperationHistory or PageType.OwnLog; + MoreNavButton.IsChecked = page is PageType.Help or PageType.ManagerLog or PageType.OperationHistory or PageType.AdvancedOperationHistory or PageType.OwnLog; } private async void AboutNavButton_Click(object sender, EventArgs e) @@ -279,6 +285,9 @@ private void ReleaseNotesMenu_Click(object sender, RoutedEventArgs e) private void OperationHistoryMenu_Click(object sender, RoutedEventArgs e) => NavigateTo(PageType.OperationHistory); + private void AdvancedOperationHistoryMenu_Click(object sender, RoutedEventArgs e) + => NavigateTo(PageType.AdvancedOperationHistory); + private void ManagerLogsMenu_Click(object sender, RoutedEventArgs e) => OpenManagerLogs(); diff --git a/src/UniGetUI/Pages/SettingsPage.xaml.cs b/src/UniGetUI/Pages/SettingsPage.xaml.cs index 905a40ef9c..4980fb40aa 100644 --- a/src/UniGetUI/Pages/SettingsPage.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPage.xaml.cs @@ -103,6 +103,7 @@ public SettingsPage() StartupPageSelector.AddItem(CoreTools.AutoTranslated("Installed Packages"), "installed"); StartupPageSelector.AddItem(CoreTools.AutoTranslated("Package Bundles"), "bundles"); StartupPageSelector.AddItem(CoreTools.AutoTranslated("Settings"), "settings"); + StartupPageSelector.AddItem(CoreTools.AutoTranslated("Operation History"), "ophist"); StartupPageSelector.ShowAddedItems(); for (int i = 1; i <= 10; i++)