Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 7799ed5

Browse files
committed
Use GraphQL to read PR reviews/comments.
This is integrated a bit hackily into `ModelService`; `ModelService` doesn't really mesh well with GraphQL but without a lot of refactoring this was the best way to get things up and running.
1 parent d51f5f5 commit 7799ed5

28 files changed

+501
-61
lines changed

src/GitHub.App/Factories/ModelServiceFactory.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.ComponentModel.Composition;
44
using System.Threading;
55
using System.Threading.Tasks;
6+
using GitHub.Api;
67
using GitHub.Caches;
78
using GitHub.Models;
89
using GitHub.Services;
@@ -15,6 +16,7 @@ namespace GitHub.Factories
1516
public sealed class ModelServiceFactory : IModelServiceFactory, IDisposable
1617
{
1718
readonly IApiClientFactory apiClientFactory;
19+
readonly IGraphQLClientFactory graphQLClientFactory;
1820
readonly IHostCacheFactory hostCacheFactory;
1921
readonly IAvatarProvider avatarProvider;
2022
readonly Dictionary<IConnection, ModelService> cache = new Dictionary<IConnection, ModelService>();
@@ -23,10 +25,12 @@ public sealed class ModelServiceFactory : IModelServiceFactory, IDisposable
2325
[ImportingConstructor]
2426
public ModelServiceFactory(
2527
IApiClientFactory apiClientFactory,
28+
IGraphQLClientFactory graphQLClientFactory,
2629
IHostCacheFactory hostCacheFactory,
2730
IAvatarProvider avatarProvider)
2831
{
2932
this.apiClientFactory = apiClientFactory;
33+
this.graphQLClientFactory = graphQLClientFactory;
3034
this.hostCacheFactory = hostCacheFactory;
3135
this.avatarProvider = avatarProvider;
3236
}
@@ -43,6 +47,7 @@ public async Task<IModelService> CreateAsync(IConnection connection)
4347
{
4448
result = new ModelService(
4549
await apiClientFactory.Create(connection.HostAddress),
50+
await graphQLClientFactory.CreateConnection(connection.HostAddress),
4651
await hostCacheFactory.Create(connection.HostAddress),
4752
avatarProvider);
4853
result.InsertUser(AccountCacheItem.Create(connection.User));

src/GitHub.App/GitHub.App.csproj

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,17 @@
8989
<SpecificVersion>False</SpecificVersion>
9090
<HintPath>..\..\packages\Microsoft.VisualStudio.Threading.14.1.131\lib\net45\Microsoft.VisualStudio.Threading.dll</HintPath>
9191
</Reference>
92-
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
93-
<SpecificVersion>False</SpecificVersion>
94-
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
95-
<Private>False</Private>
92+
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
93+
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
94+
<Private>True</Private>
95+
</Reference>
96+
<Reference Include="Octokit.GraphQL, Version=0.0.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
97+
<HintPath>..\..\packages\Octokit.GraphQL.0.0.1\lib\netstandard1.1\Octokit.GraphQL.dll</HintPath>
98+
<Private>True</Private>
99+
</Reference>
100+
<Reference Include="Octokit.GraphQL.Core, Version=0.0.1.0, Culture=neutral, PublicKeyToken=0be8860aee462442, processorArchitecture=MSIL">
101+
<HintPath>..\..\packages\Octokit.GraphQL.0.0.1\lib\netstandard1.1\Octokit.GraphQL.Core.dll</HintPath>
102+
<Private>True</Private>
96103
</Reference>
97104
<Reference Include="PresentationCore" />
98105
<Reference Include="PresentationFramework" />
@@ -152,6 +159,7 @@
152159
<Compile Include="Models\IssueCommentModel.cs" />
153160
<Compile Include="Models\PullRequestReviewCommentModel.cs" />
154161
<Compile Include="Models\PullRequestDetailArgument.cs" />
162+
<Compile Include="Models\PullRequestReviewModel.cs" />
155163
<Compile Include="Services\EnterpriseCapabilitiesService.cs" />
156164
<Compile Include="Services\GlobalConnection.cs" />
157165
<Compile Include="Services\PullRequestEditorService.cs" />

src/GitHub.App/Models/Account.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public Account(
2323
bool isEnterprise,
2424
int ownedPrivateRepositoryCount,
2525
long privateRepositoryInPlanCount,
26+
string avatarUrl,
2627
IObservable<BitmapSource> bitmapSource)
2728
{
2829
Guard.ArgumentNotEmptyString(login, nameof(login));
@@ -34,6 +35,7 @@ public Account(
3435
PrivateReposInPlan = privateRepositoryInPlanCount;
3536
IsOnFreePlan = privateRepositoryInPlanCount == 0;
3637
HasMaximumPrivateRepositories = OwnedPrivateRepos >= PrivateReposInPlan;
38+
AvatarUrl = avatarUrl;
3739
this.bitmapSource = bitmapSource;
3840

3941
bitmapSourceSubscription = bitmapSource
@@ -54,6 +56,7 @@ public Account(Octokit.Account account)
5456
OwnedPrivateRepos = account.OwnedPrivateRepos;
5557
IsOnFreePlan = PrivateReposInPlan == 0;
5658
HasMaximumPrivateRepositories = OwnedPrivateRepos >= PrivateReposInPlan;
59+
AvatarUrl = account.AvatarUrl;
5760
}
5861

5962
public Account(Octokit.Account account, IObservable<BitmapSource> bitmapSource)
@@ -77,13 +80,15 @@ public Account(Octokit.Account account, IObservable<BitmapSource> bitmapSource)
7780

7881
public long PrivateReposInPlan { get; private set; }
7982

83+
public string AvatarUrl { get; private set; }
84+
8085
public BitmapSource Avatar
8186
{
8287
get { return avatar; }
8388
set { avatar = value; this.RaisePropertyChanged(); }
8489
}
8590

86-
#region Equality things
91+
#region Equality things
8792
public void CopyFrom(IAccount other)
8893
{
8994
if (!Equals(other))
@@ -115,7 +120,7 @@ public override bool Equals(object obj)
115120

116121
public override int GetHashCode()
117122
{
118-
return (Login?.GetHashCode() ?? 0) ^ IsUser .GetHashCode() ^ IsEnterprise.GetHashCode();
123+
return (Login?.GetHashCode() ?? 0) ^ IsUser.GetHashCode() ^ IsEnterprise.GetHashCode();
119124
}
120125

121126
bool IEquatable<IAccount>.Equals(IAccount other)

src/GitHub.App/Models/IssueCommentModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ namespace GitHub.Models
44
{
55
public class IssueCommentModel : ICommentModel
66
{
7-
public string Body { get; set; }
87
public int Id { get; set; }
8+
public string NodeId { get; set; }
9+
public string Body { get; set; }
910
public DateTimeOffset CreatedAt { get; set; }
1011
public IAccount User { get; set; }
1112
}

src/GitHub.App/Models/PullRequestModel.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,23 @@ public string Body
162162
public DateTimeOffset CreatedAt { get; set; }
163163
public DateTimeOffset UpdatedAt { get; set; }
164164
public IAccount Author { get; set; }
165-
public IReadOnlyCollection<IPullRequestFileModel> ChangedFiles { get; set; } = new IPullRequestFileModel[0];
166-
public IReadOnlyCollection<ICommentModel> Comments { get; set; } = new ICommentModel[0];
165+
public IReadOnlyList<IPullRequestFileModel> ChangedFiles { get; set; } = new IPullRequestFileModel[0];
166+
public IReadOnlyList<ICommentModel> Comments { get; set; } = new ICommentModel[0];
167167

168-
IReadOnlyCollection<IPullRequestReviewCommentModel> reviewComments = new IPullRequestReviewCommentModel[0];
169-
public IReadOnlyCollection<IPullRequestReviewCommentModel> ReviewComments
168+
IReadOnlyList<IPullRequestReviewModel> reviews = new IPullRequestReviewModel[0];
169+
public IReadOnlyList<IPullRequestReviewModel> Reviews
170+
{
171+
get { return reviews; }
172+
set
173+
{
174+
Guard.ArgumentNotNull(value, nameof(value));
175+
reviews = value;
176+
this.RaisePropertyChange();
177+
}
178+
}
179+
180+
IReadOnlyList<IPullRequestReviewCommentModel> reviewComments = new IPullRequestReviewCommentModel[0];
181+
public IReadOnlyList<IPullRequestReviewCommentModel> ReviewComments
170182
{
171183
get { return reviewComments; }
172184
set

src/GitHub.App/Models/PullRequestReviewCommentModel.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace GitHub.Models
55
public class PullRequestReviewCommentModel : IPullRequestReviewCommentModel
66
{
77
public int Id { get; set; }
8+
public string NodeId { get; set; }
9+
public int PullRequestReviewId { get; set; }
810
public string Path { get; set; }
911
public int? Position { get; set; }
1012
public int? OriginalPosition { get; set; }
@@ -14,5 +16,6 @@ public class PullRequestReviewCommentModel : IPullRequestReviewCommentModel
1416
public IAccount User { get; set; }
1517
public string Body { get; set; }
1618
public DateTimeOffset CreatedAt { get; set; }
19+
public bool IsPending { get; set; }
1720
}
1821
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
3+
namespace GitHub.Models
4+
{
5+
public class PullRequestReviewModel : IPullRequestReviewModel
6+
{
7+
public long Id { get; set; }
8+
public string NodeId { get; set; }
9+
public IAccount User { get; set; }
10+
public string Body { get; set; }
11+
public PullRequestReviewState State { get; set; }
12+
public string CommitId { get; set; }
13+
}
14+
}

src/GitHub.App/SampleData/AccountDesigner.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public BitmapSource Avatar
3232
public string Login { get; set; }
3333
public int OwnedPrivateRepos { get; set; }
3434
public long PrivateReposInPlan { get; set; }
35+
public string AvatarUrl { get; set; }
3536

3637
public override string ToString()
3738
{

src/GitHub.App/Services/AvatarProvider.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,21 @@ public IObservable<BitmapSource> GetAvatar(IAvatarContainer apiAccount)
7070
.Catch<BitmapSource, Exception>(_ => Observable.Return(DefaultAvatar(apiAccount)));
7171
}
7272

73+
public IObservable<BitmapSource> GetAvatar(string url)
74+
{
75+
if (url == null)
76+
{
77+
return Observable.Return(DefaultUserBitmapImage);
78+
}
79+
80+
Uri avatarUrl;
81+
Uri.TryCreate(url, UriKind.Absolute, out avatarUrl);
82+
Log.Assert(avatarUrl != null, "Cannot have a null avatar url");
83+
84+
return imageCache.GetImage(avatarUrl)
85+
.Catch<BitmapSource, Exception>(_ => Observable.Return(DefaultUserBitmapImage));
86+
}
87+
7388
public IObservable<Unit> InvalidateAvatar(IAvatarContainer apiAccount)
7489
{
7590
return String.IsNullOrWhiteSpace(apiAccount?.Login)

0 commit comments

Comments
 (0)