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

Commit 54ef0b8

Browse files
authored
Merge pull request #1426 from github/fixes/githubpane-initialization
Ensure that the GitHubPaneViewModel is initalized.
2 parents 21f82b4 + a39d0bb commit 54ef0b8

File tree

8 files changed

+101
-45
lines changed

8 files changed

+101
-45
lines changed

src/GitHub.App/ViewModels/GitHubPane/GitHubPaneViewModel.cs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public sealed class GitHubPaneViewModel : ViewModelBase, IGitHubPaneViewModel, I
4646
readonly ReactiveCommand<Unit> refresh;
4747
readonly ReactiveCommand<Unit> showPullRequests;
4848
readonly ReactiveCommand<object> openInBrowser;
49+
readonly SemaphoreSlim initializing = new SemaphoreSlim(1);
50+
bool initialized;
4951
IViewModel content;
5052
ILocalRepositoryModel localRepository;
5153
string searchQuery;
@@ -198,26 +200,37 @@ public void Dispose()
198200
/// <inheritdoc/>
199201
public async Task InitializeAsync(IServiceProvider paneServiceProvider)
200202
{
201-
await UpdateContent(teamExplorerContext.ActiveRepository);
202-
teamExplorerContext.WhenAnyValue(x => x.ActiveRepository)
203-
.Skip(1)
204-
.ObserveOn(RxApp.MainThreadScheduler)
205-
.Subscribe(x => UpdateContent(x).Forget());
206-
207-
connectionManager.Connections.CollectionChanged += (_, __) => UpdateContent(LocalRepository).Forget();
208-
209-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.pullRequestCommand, showPullRequests);
210-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.backCommand, navigator.NavigateBack);
211-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.forwardCommand, navigator.NavigateForward);
212-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.refreshCommand, refresh);
213-
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.githubCommand, openInBrowser);
214-
215-
paneServiceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.helpCommand,
216-
(_, __) =>
217-
{
218-
browser.OpenUrl(new Uri(GitHubUrls.Documentation));
219-
usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget();
220-
});
203+
await initializing.WaitAsync();
204+
if (initialized) return;
205+
206+
try
207+
{
208+
await UpdateContent(teamExplorerContext.ActiveRepository);
209+
teamExplorerContext.WhenAnyValue(x => x.ActiveRepository)
210+
.Skip(1)
211+
.ObserveOn(RxApp.MainThreadScheduler)
212+
.Subscribe(x => UpdateContent(x).Forget());
213+
214+
connectionManager.Connections.CollectionChanged += (_, __) => UpdateContent(LocalRepository).Forget();
215+
216+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.pullRequestCommand, showPullRequests);
217+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.backCommand, navigator.NavigateBack);
218+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.forwardCommand, navigator.NavigateForward);
219+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.refreshCommand, refresh);
220+
BindNavigatorCommand(paneServiceProvider, PkgCmdIDList.githubCommand, openInBrowser);
221+
222+
paneServiceProvider.AddCommandHandler(Guids.guidGitHubToolbarCmdSet, PkgCmdIDList.helpCommand,
223+
(_, __) =>
224+
{
225+
browser.OpenUrl(new Uri(GitHubUrls.Documentation));
226+
usageTracker.IncrementCounter(x => x.NumberOfGitHubPaneHelpClicks).Forget();
227+
});
228+
}
229+
finally
230+
{
231+
initialized = true;
232+
initializing.Release();
233+
}
221234
}
222235

223236
/// <inheritdoc/>

src/GitHub.Exports.Reactive/Services/IPullRequestSessionManager.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ public interface IPullRequestSessionManager : INotifyPropertyChanged
3131
/// </returns>
3232
IPullRequestSession CurrentSession { get; }
3333

34+
/// <summary>
35+
/// Ensures that the service is initialized.
36+
/// </summary>
37+
/// <returns>A task that when completed indicates that the service is initialized.</returns>
38+
/// <remarks>
39+
/// If you are simply monitoring changes to the <see cref="CurrentSession"/> then you
40+
/// don't need to call this method: <see cref="CurrentSession"/> will be updated on
41+
/// initialization. If however, you want to be sure that <see cref="CurrentSession"/> is
42+
/// initialized, you can await the task returned from this method.
43+
/// </remarks>
44+
Task EnsureInitialized();
45+
3446
/// <summary>
3547
/// Gets an <see cref="IPullRequestSessionFile"/> that tracks the live state of a document.
3648
/// </summary>

src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class PullRequestSessionManager : ReactiveObject, IPullRequestSessionMana
3636
readonly IModelServiceFactory modelServiceFactory;
3737
readonly Dictionary<Tuple<string, int>, WeakReference<PullRequestSession>> sessions =
3838
new Dictionary<Tuple<string, int>, WeakReference<PullRequestSession>>();
39+
TaskCompletionSource<object> initialized;
3940
IPullRequestSession currentSession;
4041
ILocalRepositoryModel repository;
4142

@@ -65,6 +66,7 @@ public PullRequestSessionManager(
6566
this.sessionService = sessionService;
6667
this.connectionManager = connectionManager;
6768
this.modelServiceFactory = modelServiceFactory;
69+
initialized = new TaskCompletionSource<object>(null);
6870

6971
Observable.FromEventPattern(teamExplorerContext, nameof(teamExplorerContext.StatusChanged))
7072
.ObserveOn(RxApp.MainThreadScheduler)
@@ -82,6 +84,10 @@ public IPullRequestSession CurrentSession
8284
private set { this.RaiseAndSetIfChanged(ref currentSession, value); }
8385
}
8486

87+
/// <inheritdoc/>
88+
public Task EnsureInitialized() => initialized.Task;
89+
90+
/// <inheritdoc/>
8591
public async Task<IPullRequestSessionFile> GetLiveFile(
8692
string relativePath,
8793
ITextView textView,
@@ -230,6 +236,7 @@ async Task StatusChanged()
230236
}
231237

232238
CurrentSession = session;
239+
initialized.SetResult(null);
233240
}
234241
catch (Exception e)
235242
{

src/GitHub.VisualStudio/GitHubPackage.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ protected override Task InitializeAsync(CancellationToken cancellationToken, IPr
158158
return Task.CompletedTask;
159159
}
160160

161-
public IGitHubPaneViewModel ShowHomePane()
161+
public async Task<IGitHubPaneViewModel> ShowGitHubPane()
162162
{
163163
var pane = ShowToolWindow(new Guid(GitHubPane.GitHubPaneGuid));
164164
if (pane == null)
@@ -168,7 +168,10 @@ public IGitHubPaneViewModel ShowHomePane()
168168
{
169169
ErrorHandler.Failed(frame.Show());
170170
}
171-
return (IGitHubPaneViewModel)((FrameworkElement)pane.Content).DataContext;
171+
172+
var viewModel = (IGitHubPaneViewModel)((FrameworkElement)pane.Content).DataContext;
173+
await viewModel.InitializeAsync(pane);
174+
return viewModel;
172175
}
173176

174177
static ToolWindowPane ShowToolWindow(Guid windowGuid)

src/GitHub.VisualStudio/IServiceProviderPackage.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Runtime.InteropServices;
3+
using System.Threading.Tasks;
34
using GitHub.ViewModels.GitHubPane;
45

56
namespace GitHub.VisualStudio
@@ -12,6 +13,6 @@ public interface IServiceProviderPackage : IServiceProvider, Microsoft.VisualStu
1213
[ComVisible(true)]
1314
public interface IGitHubToolWindowManager
1415
{
15-
IGitHubPaneViewModel ShowHomePane();
16+
Task<IGitHubPaneViewModel> ShowGitHubPane();
1617
}
1718
}
Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
using GitHub.Exports;
2-
using GitHub.UI;
3-
using GitHub.VisualStudio.UI;
4-
using System;
5-
using GitHub.Services;
1+
using System;
2+
using GitHub.Exports;
63
using GitHub.Extensions;
4+
using GitHub.Logging;
5+
using GitHub.Services;
6+
using Serilog;
77

88
namespace GitHub.VisualStudio.Menus
99
{
1010
[ExportMenu(MenuType = MenuType.OpenPullRequests)]
1111
public class OpenPullRequests : MenuBase, IMenuHandler
1212
{
13+
static readonly ILogger log = LogManager.ForContext<ShowCurrentPullRequest>();
14+
1315
public OpenPullRequests(IGitHubServiceProvider serviceProvider)
1416
: base(serviceProvider)
1517
{
@@ -19,10 +21,17 @@ public OpenPullRequests(IGitHubServiceProvider serviceProvider)
1921
public Guid Guid => Guids.guidGitHubCmdSet;
2022
public int CmdId => PkgCmdIDList.openPullRequestsCommand;
2123

22-
public void Activate(object data = null)
24+
public async void Activate(object data = null)
2325
{
24-
var host = ServiceProvider.TryGetService<IGitHubToolWindowManager>().ShowHomePane();
25-
host.ShowPullRequests().Forget();
26+
try
27+
{
28+
var host = await ServiceProvider.TryGetService<IGitHubToolWindowManager>().ShowGitHubPane();
29+
await host.ShowPullRequests();
30+
}
31+
catch (Exception ex)
32+
{
33+
log.Error(ex, "Error showing opening pull requests");
34+
}
2635
}
2736
}
2837
}
Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
using System;
22
using GitHub.Exports;
3-
using GitHub.UI;
4-
using GitHub.Services;
53
using GitHub.Extensions;
6-
using GitHub.Models;
4+
using GitHub.Logging;
5+
using GitHub.Services;
6+
using Serilog;
77

88
namespace GitHub.VisualStudio.Menus
99
{
1010
[ExportMenu(MenuType = MenuType.OpenPullRequests)]
1111
public class ShowCurrentPullRequest : MenuBase, IMenuHandler
1212
{
13+
static readonly ILogger log = LogManager.ForContext<ShowCurrentPullRequest>();
14+
1315
public ShowCurrentPullRequest(IGitHubServiceProvider serviceProvider)
1416
: base(serviceProvider)
1517
{
@@ -19,19 +21,28 @@ public ShowCurrentPullRequest(IGitHubServiceProvider serviceProvider)
1921
public Guid Guid => Guids.guidGitHubCmdSet;
2022
public int CmdId => PkgCmdIDList.showCurrentPullRequestCommand;
2123

22-
public void Activate(object data = null)
24+
public async void Activate(object data = null)
2325
{
24-
var pullRequestSessionManager = ServiceProvider.ExportProvider.GetExportedValueOrDefault<IPullRequestSessionManager>();
25-
var session = pullRequestSessionManager?.CurrentSession;
26-
if (session == null)
26+
try
2727
{
28-
return; // No active PR session.
29-
}
28+
var pullRequestSessionManager = ServiceProvider.ExportProvider.GetExportedValueOrDefault<IPullRequestSessionManager>();
29+
await pullRequestSessionManager.EnsureInitialized();
3030

31-
var pullRequest = session.PullRequest;
32-
var manager = ServiceProvider.TryGetService<IGitHubToolWindowManager>();
33-
var host = manager.ShowHomePane();
34-
host.ShowPullRequest(session.RepositoryOwner, host.LocalRepository.Name, pullRequest.Number);
31+
var session = pullRequestSessionManager?.CurrentSession;
32+
if (session == null)
33+
{
34+
return; // No active PR session.
35+
}
36+
37+
var pullRequest = session.PullRequest;
38+
var manager = ServiceProvider.TryGetService<IGitHubToolWindowManager>();
39+
var host = await manager.ShowGitHubPane();
40+
await host.ShowPullRequest(session.RepositoryOwner, host.LocalRepository.Name, pullRequest.Number);
41+
}
42+
catch (Exception ex)
43+
{
44+
log.Error(ex, "Error showing current pull request");
45+
}
3546
}
3647
}
3748
}

src/GitHub.VisualStudio/Menus/ShowGitHubPane.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public ShowGitHubPane(IGitHubServiceProvider serviceProvider)
1717

1818
public void Activate(object data = null)
1919
{
20-
ServiceProvider.TryGetService<IGitHubToolWindowManager>()?.ShowHomePane();
20+
ServiceProvider.TryGetService<IGitHubToolWindowManager>()?.ShowGitHubPane();
2121
}
2222
}
2323
}

0 commit comments

Comments
 (0)