Skip to content
This repository was archived by the owner on Jul 2, 2022. It is now read-only.

Commit d7c5b50

Browse files
committed
Fix Issue & Pull Request Comment Limitations
- GitHubSharp was pinning comments to 100. Migrated Issue and PullRequest views to Octokit which will retrieve them all. This is not totally ideal (as we'd like to paginate) but it's better than it currently is. Fixes #445
1 parent 97060fb commit d7c5b50

File tree

4 files changed

+116
-61
lines changed

4 files changed

+116
-61
lines changed

CodeHub.Core/ViewModels/Issues/IssueViewModel.cs

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
using System.Reactive;
1111
using Splat;
1212
using System.Reactive.Threading.Tasks;
13+
using System.Collections.Generic;
14+
using System.Linq;
1315

1416
namespace CodeHub.Core.ViewModels.Issues
1517
{
@@ -81,6 +83,27 @@ public bool IsModifying
8183
set { this.RaiseAndSetIfChanged(ref _isModifying, value); }
8284
}
8385

86+
private int? _participants;
87+
public int? Participants
88+
{
89+
get { return _participants; }
90+
set { this.RaiseAndSetIfChanged(ref _participants, value); }
91+
}
92+
93+
private IReadOnlyList<Octokit.IssueComment> _comments;
94+
public IReadOnlyList<Octokit.IssueComment> Comments
95+
{
96+
get { return _comments ?? new List<Octokit.IssueComment>(); }
97+
private set { this.RaiseAndSetIfChanged(ref _comments, value); }
98+
}
99+
100+
private IReadOnlyList<Octokit.EventInfo> _events;
101+
public IReadOnlyList<Octokit.EventInfo> Events
102+
{
103+
get { return _events ?? new List<Octokit.EventInfo>(); }
104+
private set { this.RaiseAndSetIfChanged(ref _events, value); }
105+
}
106+
84107
public ReactiveUI.ReactiveCommand<Unit, bool> GoToOwner { get; }
85108

86109
public ICommand GoToAssigneeCommand
@@ -135,34 +158,34 @@ public ICommand ToggleStateCommand
135158
}
136159
}
137160

138-
private readonly CollectionViewModel<IssueCommentModel> _comments = new CollectionViewModel<IssueCommentModel>();
139-
public CollectionViewModel<IssueCommentModel> Comments
140-
{
141-
get { return _comments; }
142-
}
143-
144-
private readonly CollectionViewModel<IssueEventModel> _events = new CollectionViewModel<IssueEventModel>();
145-
public CollectionViewModel<IssueEventModel> Events
146-
{
147-
get { return _events; }
148-
}
149-
150161
protected override Task Load()
151162
{
152163
if (_featuresService.IsProEnabled)
153164
ShouldShowPro = false;
154165
else
155166
{
156-
var request = _applicationService.Client.Users[Username].Repositories[Repository].Get();
157-
_applicationService.Client.ExecuteAsync(request)
158-
.ToBackground(x => ShouldShowPro = x.Data.Private && !_featuresService.IsProEnabled);
167+
_applicationService
168+
.GitHubClient.Repository.Get(Username, Repository)
169+
.ToBackground(x => ShouldShowPro = x.Private && !_featuresService.IsProEnabled);
159170
}
160171

161-
var t1 = this.RequestModel(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].Get(), response => Issue = response.Data);
162-
Comments.SimpleCollectionLoad(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].GetComments()).ToBackground();
163-
Events.SimpleCollectionLoad(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].GetEvents()).ToBackground();
164-
this.RequestModel(this.GetApplication().Client.Users[Username].Repositories[Repository].IsCollaborator(this.GetApplication().Account.Username), response => IsCollaborator = response.Data).ToBackground();
165-
return t1;
172+
_applicationService
173+
.GitHubClient.Issue.Comment.GetAllForIssue(Username, Repository, (int)Id)
174+
.ToBackground(x => Comments = x);
175+
176+
_applicationService
177+
.GitHubClient.Issue.Events.GetAllForIssue(Username, Repository, (int)Id)
178+
.ToBackground(events =>
179+
{
180+
Events = events;
181+
Participants = events.Select(x => x.Actor.Login).Distinct().Count();
182+
});
183+
184+
_applicationService
185+
.GitHubClient.Repository.Collaborator.IsCollaborator(Username, Repository, _applicationService.Account.Username)
186+
.ToBackground(x => IsCollaborator = x);
187+
188+
return this.RequestModel(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].Get(), response => Issue = response.Data);
166189
}
167190

168191
public IssueViewModel(
@@ -208,8 +231,9 @@ public async Task<bool> AddComment(string text)
208231
{
209232
try
210233
{
211-
var comment = await this.GetApplication().Client.ExecuteAsync(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].CreateComment(text));
212-
Comments.Items.Add(comment.Data);
234+
var comment = await _applicationService.GitHubClient.Issue.Comment.Create(Username, Repository, (int)Id, text);
235+
var newCommentList = new List<Octokit.IssueComment>(Comments) { comment };
236+
Comments = newCommentList;
213237
return true;
214238
}
215239
catch (Exception e)

CodeHub.Core/ViewModels/PullRequests/PullRequestViewModel.cs

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
using CodeHub.Core.ViewModels.User;
1111
using System.Reactive;
1212
using System.Reactive.Threading.Tasks;
13+
using System.Collections.Generic;
1314

1415
namespace CodeHub.Core.ViewModels.PullRequests
1516
{
1617
public class PullRequestViewModel : LoadableViewModel
1718
{
19+
private readonly IApplicationService _applicationService;
1820
private readonly IMessageService _messageService;
1921
private IDisposable _issueEditSubscription;
2022
private IDisposable _pullRequestEditSubscription;
@@ -95,6 +97,20 @@ public bool? IsClosed
9597
private set { this.RaiseAndSetIfChanged(ref _isClosed, value); }
9698
}
9799

100+
private IReadOnlyList<Octokit.IssueComment> _comments;
101+
public IReadOnlyList<Octokit.IssueComment> Comments
102+
{
103+
get { return _comments ?? new List<Octokit.IssueComment>(); }
104+
private set { this.RaiseAndSetIfChanged(ref _comments, value); }
105+
}
106+
107+
private IReadOnlyList<Octokit.EventInfo> _events;
108+
public IReadOnlyList<Octokit.EventInfo> Events
109+
{
110+
get { return _events ?? new List<Octokit.EventInfo>(); }
111+
private set { this.RaiseAndSetIfChanged(ref _events, value); }
112+
}
113+
98114
private ICommand _goToAssigneeCommand;
99115

100116
public ICommand GoToAssigneeCommand
@@ -200,25 +216,13 @@ public ICommand GoToFilesCommand
200216
}
201217
}
202218

203-
private readonly CollectionViewModel<IssueCommentModel> _comments = new CollectionViewModel<IssueCommentModel>();
204-
205-
public CollectionViewModel<IssueCommentModel> Comments
206-
{
207-
get { return _comments; }
208-
}
209-
210-
private readonly CollectionViewModel<IssueEventModel> _events = new CollectionViewModel<IssueEventModel>();
211-
212-
public CollectionViewModel<IssueEventModel> Events
213-
{
214-
get { return _events; }
215-
}
216-
217219
public PullRequestViewModel(
220+
IApplicationService applicationService,
218221
IFeaturesService featuresService,
219222
IMessageService messageService,
220223
IMarkdownService markdownService)
221224
{
225+
_applicationService = applicationService;
222226
_featuresService = featuresService;
223227
_messageService = messageService;
224228
_markdownService = markdownService;
@@ -262,8 +266,9 @@ public async Task<bool> AddComment(string text)
262266
{
263267
try
264268
{
265-
var comment = await this.GetApplication().Client.ExecuteAsync(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].CreateComment(text));
266-
Comments.Items.Add(comment.Data);
269+
var comment = await _applicationService.GitHubClient.Issue.Comment.Create(Username, Repository, (int)Id, text);
270+
var newCommentList = new List<Octokit.IssueComment>(Comments) { comment };
271+
Comments = newCommentList;
267272
return true;
268273
}
269274
catch (Exception e)
@@ -302,17 +307,30 @@ protected override Task Load()
302307
{
303308
ShouldShowPro = false;
304309

310+
_applicationService
311+
.GitHubClient.Issue.Comment.GetAllForIssue(Username, Repository, (int)Id)
312+
.ToBackground(x => Comments = x);
313+
314+
_applicationService
315+
.GitHubClient.Issue.Events.GetAllForIssue(Username, Repository, (int)Id)
316+
.ToBackground(x => Events = x);
317+
305318
var pullRequest = this.GetApplication().Client.Users[Username].Repositories[Repository].PullRequests[Id].Get();
306319
var t1 = this.RequestModel(pullRequest, response => PullRequest = response.Data);
307-
Events.SimpleCollectionLoad(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].GetEvents()).ToBackground();
308-
Comments.SimpleCollectionLoad(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].GetComments()).ToBackground();
309320
this.RequestModel(this.GetApplication().Client.Users[Username].Repositories[Repository].Issues[Id].Get(), response => Issue = response.Data).ToBackground();
310-
this.RequestModel(this.GetApplication().Client.Users[Username].Repositories[Repository].Get(), response => {
311-
CanPush = response.Data.Permissions.Push;
312-
ShouldShowPro = response.Data.Private && !_featuresService.IsProEnabled;
313-
}).ToBackground();
314-
this.RequestModel(this.GetApplication().Client.Users[Username].Repositories[Repository].IsCollaborator(this.GetApplication().Account.Username),
315-
response => IsCollaborator = response.Data).ToBackground();
321+
322+
_applicationService
323+
.GitHubClient.Repository.Get(Username, Repository)
324+
.ToBackground(x =>
325+
{
326+
CanPush = x.Permissions.Push;
327+
ShouldShowPro = x.Private && !_featuresService.IsProEnabled;
328+
});
329+
330+
_applicationService
331+
.GitHubClient.Repository.Collaborator.IsCollaborator(Username, Repository, _applicationService.Account.Username)
332+
.ToBackground(x => IsCollaborator = x);
333+
316334
return t1;
317335
}
318336

CodeHub.iOS/Views/Issues/IssueView.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System.Threading.Tasks;
1616
using CodeHub.Core.Services;
1717
using Splat;
18+
using System.Reactive;
1819

1920
namespace CodeHub.iOS.Views.Issues
2021
{
@@ -112,11 +113,20 @@ public override void ViewDidLoad()
112113
Render();
113114
});
114115

115-
ViewModel.BindCollection(x => x.Comments).Subscribe(_ => RenderComments().ToBackground());
116-
ViewModel.BindCollection(x => x.Events).Subscribe(_ => RenderComments().ToBackground());
117-
ViewModel.Bind(x => x.ShouldShowPro).Subscribe(x => {
118-
if (x) this.ShowPrivateView();
119-
});
116+
ViewModel
117+
.Bind(x => x.Comments)
118+
.Select(_ => Unit.Default)
119+
.Merge(ViewModel.Bind(x => x.Events).Select(_ => Unit.Default))
120+
.Subscribe(_ => RenderComments().ToBackground());
121+
122+
ViewModel
123+
.Bind(x => x.Participants)
124+
.Subscribe(x => _splitButton2.Text = x.HasValue ? x.Value.ToString() : "-");
125+
126+
ViewModel
127+
.Bind(x => x.ShouldShowPro)
128+
.Where(x => x)
129+
.Subscribe(x => this.ShowPrivateView());
120130

121131
OnActivation(d =>
122132
{
@@ -161,14 +171,16 @@ private static string CreateEventBody(string eventType, string commitId)
161171
public async Task RenderComments()
162172
{
163173
var comments = new List<Comment>();
174+
164175
foreach (var x in ViewModel.Comments)
165176
{
166177
var body = await _markdownService.Convert(x.Body);
167178
comments.Add(new Comment(x.User.AvatarUrl, x.User.Login, body, x.CreatedAt));
168179
}
169180

170-
var events = ViewModel.Events
171-
.Select(x => new Comment(x.Actor.AvatarUrl, x.Actor.Login, CreateEventBody(x.Event, x.CommitId), x.CreatedAt));
181+
var events = ViewModel
182+
.Events
183+
.Select(x => new Comment(x.Actor.AvatarUrl, x.Actor.Login, CreateEventBody(x.Event.StringValue, x.CommitId), x.CreatedAt));
172184

173185
var items = comments
174186
.Concat(events)
@@ -192,10 +204,7 @@ protected virtual void Render()
192204
if (ViewModel.Issue == null)
193205
return;
194206

195-
var participants = ViewModel.Events.Select(x => x.Actor.Login).Distinct().Count();
196-
197207
_splitButton1.Text = ViewModel.Issue.Comments.ToString();
198-
_splitButton2.Text = participants.ToString();
199208

200209
ICollection<Section> sections = new LinkedList<Section>();
201210
sections.Add(new Section { _split });

CodeHub.iOS/Views/PullRequests/PullRequestView.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using ReactiveUI;
1616
using UIKit;
1717
using Splat;
18+
using System.Reactive;
1819

1920
namespace CodeHub.iOS.Views.PullRequests
2021
{
@@ -30,7 +31,6 @@ public class PullRequestView : PrettyDialogViewController
3031
private StringElement _labelsElement;
3132
private StringElement _addCommentElement;
3233

33-
3434
public new PullRequestViewModel ViewModel
3535
{
3636
get { return (PullRequestViewModel)base.ViewModel; }
@@ -124,8 +124,11 @@ public override void ViewDidLoad()
124124
_milestoneElement.Accessory = ViewModel.GoToMilestoneCommand.CanExecute(null) ? UITableViewCellAccessory.DisclosureIndicator : UITableViewCellAccessory.None;
125125
};
126126

127-
ViewModel.BindCollection(x => x.Comments).Subscribe(_ => RenderComments().ToBackground());
128-
ViewModel.BindCollection(x => x.Events).Subscribe(_ => RenderComments().ToBackground());
127+
ViewModel
128+
.Bind(x => x.Comments)
129+
.Select(_ => Unit.Default)
130+
.Merge(ViewModel.Bind(x => x.Events).Select(_ => Unit.Default))
131+
.Subscribe(_ => RenderComments().ToBackground());
129132

130133
OnActivation(d =>
131134
{
@@ -179,8 +182,9 @@ public async Task RenderComments()
179182
comments.Add(new Comment(x.User.AvatarUrl, x.User.Login, body, x.CreatedAt));
180183
}
181184

182-
var events = ViewModel.Events
183-
.Select(x => new Comment(x.Actor.AvatarUrl, x.Actor.Login, CreateEventBody(x.Event, x.CommitId), x.CreatedAt));
185+
var events = ViewModel
186+
.Events
187+
.Select(x => new Comment(x.Actor.AvatarUrl, x.Actor.Login, CreateEventBody(x.Event.StringValue, x.CommitId), x.CreatedAt));
184188

185189
var items = comments
186190
.Concat(events)

0 commit comments

Comments
 (0)