From 4d31f659e702eeb85878d244f3bc85498e7b0f81 Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Fri, 21 Dec 2018 09:23:13 +0000 Subject: [PATCH 1/4] Show max 100 recently pushed repos for each org Limit the number of repositories displayed for each org to the 100 most recently pushed ones. This should stop organizations with 1000s of repositories from having a disproportional impact on the load time. --- src/GitHub.App/Services/RepositoryCloneService.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/GitHub.App/Services/RepositoryCloneService.cs b/src/GitHub.App/Services/RepositoryCloneService.cs index f8a6048bec..ab3a0ce605 100644 --- a/src/GitHub.App/Services/RepositoryCloneService.cs +++ b/src/GitHub.App/Services/RepositoryCloneService.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Reactive.Linq; +using System.Threading; using System.Threading.Tasks; using GitHub.Api; using GitHub.Extensions; @@ -69,8 +70,8 @@ public async Task ReadViewerRepositories(HostAddress ad { var order = new RepositoryOrder { - Field = RepositoryOrderField.Name, - Direction = OrderDirection.Asc + Field = RepositoryOrderField.PushedAt, + Direction = OrderDirection.Desc }; var affiliation = new RepositoryAffiliation?[] @@ -100,8 +101,8 @@ public async Task ReadViewerRepositories(HostAddress ad Organizations = viewer.Organizations(null, null, null, null).AllPages().Select(org => new { org.Login, - Repositories = org.Repositories(null, null, null, null, null, null, null, order, null, null) - .AllPages() + Repositories = org.Repositories(100, null, null, null, null, null, null, order, null, null) + .Nodes .Select(repositorySelection).ToList() }).ToDictionary(x => x.Login, x => (IReadOnlyList)x.Repositories), }).Compile(); From e161f115fd267dc06e23fd1a6b271d49f29c668c Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Fri, 21 Dec 2018 12:02:33 +0000 Subject: [PATCH 2/4] Warn when showing max number of repos in org --- .../Dialog/Clone/RepositorySelectViewModel.cs | 14 +++++++++++++- src/GitHub.Resources/Resources.Designer.cs | 9 +++++++++ src/GitHub.Resources/Resources.resx | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs b/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs index 487cbbfa70..54f3be0a2f 100644 --- a/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs +++ b/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Composition; +using System.Globalization; using System.Linq; using System.Reactive.Linq; using System.Threading.Tasks; @@ -120,7 +121,7 @@ public async Task Activate() .Select(x => new RepositoryItemViewModel(x, "Collaborator repositories")); var orgRepositories = results.Organizations .OrderBy(x => x.Key) - .SelectMany(x => x.Value.Select(y => new RepositoryItemViewModel(y, x.Key))); + .SelectMany(x => x.Value.Select(y => new RepositoryItemViewModel(y, GroupName(x, 100)))); Items = yourRepositories.Concat(collaboratorRepositories).Concat(orgRepositories).ToList(); log.Information("Read {Total} viewer repositories", Items.Count); ItemsView = CollectionViewSource.GetDefaultView(Items); @@ -144,6 +145,17 @@ public async Task Activate() } } + static string GroupName(KeyValuePair> group, int max) + { + var name = group.Key; + if (group.Value.Count == max) + { + name += $" ({string.Format(CultureInfo.InvariantCulture, Resources.MostRecentlyPushed, max)})"; + } + + return name; + } + bool FilterItem(object obj) { if (obj is IRepositoryItemViewModel item && !string.IsNullOrWhiteSpace(Filter)) diff --git a/src/GitHub.Resources/Resources.Designer.cs b/src/GitHub.Resources/Resources.Designer.cs index 5d54d56f10..4b75172d7b 100644 --- a/src/GitHub.Resources/Resources.Designer.cs +++ b/src/GitHub.Resources/Resources.Designer.cs @@ -1026,6 +1026,15 @@ public static string months { } } + /// + /// Looks up a localized string similar to {0} most recently pushed. + /// + public static string MostRecentlyPushed { + get { + return ResourceManager.GetString("MostRecentlyPushed", resourceCulture); + } + } + /// /// Looks up a localized string similar to You must pull before you can push. /// diff --git a/src/GitHub.Resources/Resources.resx b/src/GitHub.Resources/Resources.resx index 42d50a315d..003b8be2e6 100644 --- a/src/GitHub.Resources/Resources.resx +++ b/src/GitHub.Resources/Resources.resx @@ -845,4 +845,7 @@ https://git-scm.com/download/win Couldn't find file corresponding to '{0}' in the repository. Please do a 'git fetch' or checkout the target pull request. + + {0} most recently pushed + \ No newline at end of file From a2eb5c262e0e133df99a4401dd095d20901a1ea8 Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Fri, 21 Dec 2018 12:44:33 +0000 Subject: [PATCH 3/4] Include repositories contributed to in list --- src/GitHub.App/Services/RepositoryCloneService.cs | 3 +++ .../ViewModels/Dialog/Clone/RepositorySelectViewModel.cs | 8 +++++++- src/GitHub.Exports/Models/ViewerRepositoriesModel.cs | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/GitHub.App/Services/RepositoryCloneService.cs b/src/GitHub.App/Services/RepositoryCloneService.cs index ab3a0ce605..af053c1dbc 100644 --- a/src/GitHub.App/Services/RepositoryCloneService.cs +++ b/src/GitHub.App/Services/RepositoryCloneService.cs @@ -98,6 +98,9 @@ public async Task ReadViewerRepositories(HostAddress ad Repositories = viewer.Repositories(null, null, null, null, null, null, null, order, affiliation, null) .AllPages() .Select(repositorySelection).ToList(), + ContributedToRepositories = viewer.RepositoriesContributedTo(100, null, null, null, null, null, null, order, null) + .Nodes + .Select(repositorySelection).ToList(), Organizations = viewer.Organizations(null, null, null, null).AllPages().Select(org => new { org.Login, diff --git a/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs b/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs index 54f3be0a2f..6a9034bc8a 100644 --- a/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs +++ b/src/GitHub.App/ViewModels/Dialog/Clone/RepositorySelectViewModel.cs @@ -119,10 +119,16 @@ public async Task Activate() .Where(r => r.Owner != results.Owner) .OrderBy(r => r.Owner) .Select(x => new RepositoryItemViewModel(x, "Collaborator repositories")); + var repositoriesContributedTo = results.ContributedToRepositories + .Select(x => new RepositoryItemViewModel(x, "Contributed to repositories")); var orgRepositories = results.Organizations .OrderBy(x => x.Key) .SelectMany(x => x.Value.Select(y => new RepositoryItemViewModel(y, GroupName(x, 100)))); - Items = yourRepositories.Concat(collaboratorRepositories).Concat(orgRepositories).ToList(); + Items = yourRepositories + .Concat(collaboratorRepositories) + .Concat(repositoriesContributedTo) + .Concat(orgRepositories) + .ToList(); log.Information("Read {Total} viewer repositories", Items.Count); ItemsView = CollectionViewSource.GetDefaultView(Items); ItemsView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(RepositoryItemViewModel.Group))); diff --git a/src/GitHub.Exports/Models/ViewerRepositoriesModel.cs b/src/GitHub.Exports/Models/ViewerRepositoriesModel.cs index b5a9d9659c..7987af54d1 100644 --- a/src/GitHub.Exports/Models/ViewerRepositoriesModel.cs +++ b/src/GitHub.Exports/Models/ViewerRepositoriesModel.cs @@ -7,6 +7,7 @@ public class ViewerRepositoriesModel { public string Owner { get; set; } public IReadOnlyList Repositories { get; set; } + public IReadOnlyList ContributedToRepositories { get; set; } public IDictionary> Organizations { get; set; } } } From dd34b3b9d2bdd57f7161614c50c0305ae5821347 Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Fri, 21 Dec 2018 12:57:32 +0000 Subject: [PATCH 4/4] Set both affiliations and ownerAffiliations Explanation by @nicksnyder: Before this change, the affiliations field was overloaded to mean both the affiliations that the viewer had with the specified repositories, as well as the affiliations between the user that the connection was operating on. This caused a host of issues in various places, and we opted to separate them out to allow for more flexibility. In order to fix the above, the proper behavior would be to pass the full list of arguments to both connections (affiliations and ownerAffiliations), which should provide you all of the possible repositories. https://platform.github.community/t/unable-to-fetch-users-repositories-by-organization-membership/7557/6 --- src/GitHub.App/Services/RepositoryCloneService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitHub.App/Services/RepositoryCloneService.cs b/src/GitHub.App/Services/RepositoryCloneService.cs index af053c1dbc..d4bccf029f 100644 --- a/src/GitHub.App/Services/RepositoryCloneService.cs +++ b/src/GitHub.App/Services/RepositoryCloneService.cs @@ -95,7 +95,7 @@ public async Task ReadViewerRepositories(HostAddress ad .Select(viewer => new ViewerRepositoriesModel { Owner = viewer.Login, - Repositories = viewer.Repositories(null, null, null, null, null, null, null, order, affiliation, null) + Repositories = viewer.Repositories(null, null, null, null, affiliation, null, null, order, affiliation, null) .AllPages() .Select(repositorySelection).ToList(), ContributedToRepositories = viewer.RepositoriesContributedTo(100, null, null, null, null, null, null, order, null)