private RepoTreeItem FilterByTagPrefix(ILoadedRepository repo, string prefix, Func <string, string> convertor)
        {
            // var nodes = new ObservableCollection<PackageCategoryTreeItem>();

            var map = new Dictionary <string, List <PackageMenuItem> >();

            foreach (var package in repo.Packages.Packages)
            {
                if (package.Value == null)
                {
                    continue;
                }

                IDescriptor descriptor = package.Value !;

                var pkgKey  = PackageKey.Create(repo.Index.Url, descriptor.Id);
                var release = repo.Release(pkgKey);
                var payload = release?.WindowsExecutable();

                if (release == null || payload == null)
                {
                    continue;
                }

                var tags = Iter.ToArray(descriptor.Tags.Where(x => x.StartsWith(prefix)));

                if (tags.IsNullOrEmpty())
                {
                    tags = new[] { prefix };
                }

                foreach (var tag in tags)
                {
                    if (!map.ContainsKey(tag))
                    {
                        map[tag] = new List <PackageMenuItem>();
                    }

                    map[tag].Add(new PackageMenuItem(_store,
                                                     pkgKey, payload, descriptor.NativeName() ?? "<>", release.Version));
                }
            }

            var categoriesSet = new SortedSet <PackageCategoryTreeItem>(map.OrderBy(x => x.Key).Map(x => {
                x.Value.Sort();
                var items = new ObservableCollection <PackageMenuItem>(x.Value);
                return(new PackageCategoryTreeItem(_store, convertor(x.Key), items));
            }));

            var categories = new ObservableCollection <PackageCategoryTreeItem>(categoriesSet);

            return(new RepoTreeItem(repo.Index.NativeName(), categories));
        }
 public static IWindowsExecutable?Payload(this ILoadedRepository repo, PackageKey packageKey)
 {
     return(repo.Release(packageKey)?.WindowsExecutable());
 }
            private async Task <bool> Transaction(JArray args)
            {
                var actions = new List <PackageAction>();

                foreach (var arg in args)
                {
                    if (arg.Type != JTokenType.Object)
                    {
                        continue;
                    }

                    JObject obj       = (JObject)arg;
                    var     rawKey    = obj.Value <string>("key");
                    var     rawAction = obj.Value <string>("action");
                    // var target = obj.Value<string>("target");

                    try {
                        var key    = PackageKey.From(rawKey);
                        var action = InstallAction.Uninstall;
                        if (rawAction == "install")
                        {
                            action = InstallAction.Install;
                        }

                        actions.Add(new PackageAction(key, action));
                    }
                    catch {
                    }
                }

                var primaryButton = string.Format(Strings.InstallUninstallNPackages, actions.Count);

                // Resolve the names for the package keys
                var strings = actions.Map(x => {
                    var package = Repo.Packages.Packages[x.PackageKey.Id];
                    var release = Repo.Release(x.PackageKey);
                    if (release == null || package == null)
                    {
                        return(null);
                    }

                    return($"{x.Action.NativeName()}: {package.NativeName()} {release.Version}");
                });

                return(await await PahkatApp.Current.Dispatcher.InvokeAsync(async() => {
                    var dialog = new ConfirmationDialog(
                        "Confirm Selection",
                        "Do you wish to do the following actions:",
                        string.Join("\n", strings),
                        primaryButton);

                    try {
                        WebView.Visibility = Visibility.Hidden;
                        var result = await dialog.ShowAsync();
                        WebView.Visibility = Visibility.Visible;

                        if (result == ContentDialogResult.Primary)
                        {
                            var app = (PahkatApp)Application.Current;
                            await app.StartTransaction(actions.ToArray());
                            return true;
                        }
                    }
                    catch (Exception e) {
                        Log.Debug(e, "wat");
                    }

                    return false;
                }));
            }