10000 Add command to show the current PR · github/VisualStudio@2fd7153 · GitHub
[go: up one dir, main page]

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

Commit 2fd7153

Browse files
committed
Add command to show the current PR
1 parent 7e0195f commit 2fd7153

File tree

12 files changed

+275
-26
lines changed

12 files changed

+275
-26
lines changed

src/GitHub.App/Models/PullRequestDetailArgument.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using GitHub.ViewModels;
3+
using GitHub.Primitives;
34

45
namespace GitHub.Models
56
{
@@ -9,9 +10,9 @@ namespace GitHub.Models
910
public class PullRequestDetailArgument
1011
{
1112
/// <summary>
12-
/// Gets or sets the repository containing the pull request.
13+
/// Gets or sets the owner of the repository containing the pull request.
1314
/// </summary>
14-
public IRemoteRepositoryModel Repository { get; set; }
15+
public string RepositoryOwner { get; set; }
1516

1617
/// <summary>
1718
/// Gets or sets the number of the pull request.

src/GitHub.App/SampleData/PullRequestDetailViewModelDesigner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public PullRequestDetailViewModelDesigner()
3636
{
3737
var repoPath = @"C:\Repo";
3838

39-
Model = new PullRequestModel(419,
39+
Model = new PullRequestModel(419,
4040
"Error handling/bubbling from viewmodels to views to viewhosts",
4141
new AccountDesigner { Login = "shana", IsUser = true },
4242
DateTime.Now.Subtract(TimeSpan.FromDays(3)))
@@ -75,7 +75,7 @@ public PullRequestDetailViewModelDesigner()
7575
public IPullRequestModel Model { get; }
7676
public IPullRequestSession Session { get; }
7777
public ILocalRepositoryModel LocalRepository { get; }
78-
public IRemoteRepositoryModel RemoteRepository { get; }
78+
public string RemoteRepositoryOwner { get; }
7979
public string SourceBranchDisplayName { get; set; }
8080
public string TargetBranchDisplayName { get; set; }
8181
public int CommentCount { get; set; }

src/GitHub.App/ViewModels/PullRequestDetailViewModel.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public PullRequestDetailViewModel(
9393
Checkout = ReactiveCommand.CreateAsyncObservable(
9494
this.WhenAnyValue(x => x.CheckoutState)
9595
.Cast<CheckoutCommandState>()
96-
.Select(x => x != null && x.IsEnabled),
96+
.Select(x => x != null && x.IsEnabled),
9797
DoCheckout);
9898
Checkout.IsExecuting.Subscribe(x => isInCheckout = x);
9999
SubscribeOperationError(Checkout);
@@ -145,13 +145,13 @@ private set
145145
public ILocalRepositoryModel LocalRepository { get; }
146146

147147
/// <summary>
148-
/// Gets the remote repository that contains the pull request.
148+
/// Gets the owner of the remote repository that contains the pull request.
149149
/// </summary>
150150
/// <remarks>
151151
/// The remote repository may be different from the local repository if the local
152152
/// repository is a fork and the user is viewing pull requests from the parent repository.
153153
/// </remarks>
154-
public IRemoteRepositoryModel RemoteRepository { get; private set; }
154+
public string RemoteRepositoryOwner { get; private set; }
155155

156156
/// <summary>
157157
/// Gets the session for the pull request.
@@ -323,13 +323,13 @@ public IReadOnlyList<IPullRequestChangeNode> ChangedFilesTree
323323
public override void Initialize(ViewWithData data)
324324
{
325325
int number;
326-
var repo = RemoteRepository;
326+
var repoOwner = RemoteRepositoryOwner;
327327

328328
if (data != null)
329329
{
330330
var arg = (PullRequestDetailArgument)data.Data;
331331
number = arg.Number;
332-
repo = arg.Repository;
332+
repoOwner = arg.RepositoryOwner;
333333
}
334334
else
335335
{
@@ -346,7 +346,7 @@ public override void Initialize(ViewWithData data)
346346
}
347347

348348
ErrorMessage = OperationError = null;
349-
modelService.GetPullRequest(repo, number)
349+
modelService.GetPullRequest(repoOwner, LocalRepository.Name, number)
350350
.TakeLast(1)
351351
.ObserveOn(RxApp.MainThreadScheduler)
352352
.Catch<IPullRequestModel, Exception>(ex =>
@@ -355,23 +355,23 @@ public override void Initialize(ViewWithData data)
355355
IsLoading = IsBusy = false;
356356
return Observable.Empty<IPullRequestModel>();
357357
})
358-
.Subscribe(x => Load(repo, x).Forget());
358+
.Subscribe(x => Load(repoOwner, x).Forget());
359359
}
360360

361361
/// <summary>
362362
/// Loads the view model from octokit models.
363363
/// </summary>
364-
/// <param name="remoteRepository">The remote repository.</param>
364+
/// <param name="remoteRepositoryOwner">The owner of the remote repository.</param>
365365
/// <param name="pullRequest">The pull request model.</param>
366-
public async Task Load(IRemoteRepositoryModel remoteRepository, IPullRequestModel pullRequest)
366+
public async Task Load(string remoteRepositoryOwner, IPullRequestModel pullRequest)
367367
{
368-
Guard.ArgumentNotNull(remoteRepository, nameof(remoteRepository));
368+
Guard.ArgumentNotNull(remoteRepositoryOwner, nameof(remoteRepositoryOwner));
369369

370370
try
371371
{
372372
var firstLoad = (Model == null);
373373
Model = pullRequest;
374-
RemoteRepository = remoteRepository;
374+
RemoteRepositoryOwner = remoteRepositoryOwner;
375375
Session = await sessionManager.GetSession(pullRequest);
376376
Title = Resources.PullRequestNavigationItemText + " #" + pullRequest.Number;
377377

src/GitHub.App/ViewModels/PullRequestListViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ void DoOpenPullRequest(object pullRequest)
321321
{
322322
Data = new PullRequestDetailArgument
323323
{
324-
Repository = SelectedRepository,
324+
RepositoryOwner = SelectedRepository.Owner,
325325
Number = (int)pullRequest,
326326
}
327327
};

src/GitHub.Exports.Reactive/ViewModels/IPullRequestDetailViewModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ public interface IPullRequestDetailViewModel : IViewModel, IHasLoading, IHasBusy
8383
ILocalRepositoryModel LocalRepository { get; }
8484

8585
/// <summary>
86-
/// Gets the remote repository that contains the pull request.
86+
/// Gets the owner of the remote repository that contains the pull request.
8787
/// </summary>
8888
/// <remarks>
8989
/// The remote repository may be different from the local repository if the local
9090
/// repository is a fork and the user is viewing pull requests from the parent repository.
9191
/// </remarks>
92-
IRemoteRepositoryModel RemoteRepository { get; }
92+
string RemoteRepositoryOwner { get; }
9393

9494
/// <summary>
9595
/// Gets a string describing how to display the pull request's source branch.

src/GitHub.Exports/Settings/PkgCmdID.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public static class PkgCmdIDList
99
public const int idGitHubToolbar = 0x1120;
1010
public const int showGitHubPaneCommand = 0x200;
1111
public const int openPullRequestsCommand = 0x201;
12+
public const int showCurrentPullRequestCommand = 0x202;
1213
public const int backCommand = 0x300;
1314
public const int forwardCommand = 0x301;
1415
public const int refreshCommand = 0x302;
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
using System;
2+
using System.Windows;
3+
using System.Windows.Media;
4+
using System.Windows.Input;
5+
using System.Windows.Controls;
6+
using System.Windows.Controls.Primitives;
7+
using System.ComponentModel;
8+
using System.ComponentModel.Composition;
9+
using GitHub.InlineReviews.Views;
10+
using GitHub.InlineReviews.ViewModels;
11+
using GitHub.Services;
12+
using Microsoft.VisualStudio.Shell;
13+
using GitHub.VisualStudio;
14+
15+
namespace GitHub.InlineReviews.Services
16+
{
17+
[Export(typeof(IPullRequestStatusManager))]
18+
public class PullRequestStatusManager : IPullRequestStatusManager
19+
{
20+
const string SccStatusBarName = "SccStatusBar";
21+
const string GitHubStatusName = "GitHubStatusView";
22+
23+
readonly Window mainWindow;
24+
readonly IPullRequestSessionManager pullRequestSessionManager;
25+
readonly PullRequestStatusViewModel pullRequestStatusViewModel;
26+
27+
[ImportingConstructor]
28+
public PullRequestStatusManager(SVsServiceProvider serviceProvider, IPullRequestSessionManager pullRequestSessionManager)
29+
: this(CreatePullRequestStatusViewModel(serviceProvider))
30+
{
31+
this.pullRequestSessionManager = pullRequestSessionManager;
32+
33+
RefreshCurrentSession();
34+
pullRequestSessionManager.PropertyChanged += PullRequestSessionManager_PropertyChanged;
35+
}
36+
37+
public PullRequestStatusManager(PullRequestStatusViewModel pullRequestStatusViewModel)
38+
{
39+
this.pullRequestStatusViewModel = pullRequestStatusViewModel;
40+
mainWindow = Application.Current.MainWindow;
41+
}
42+
43+
static PullRequestStatusViewModel CreatePullRequestStatusViewModel(IServiceProvider serviceProvider)
44+
{
45+
var command = new ShowGitHubPaneCommand(serviceProvider);
46+
return new PullRequestStatusViewModel(command);
47+
}
48+
49+
class ShowGitHubPaneCommand : ICommand
50+
{
51+
readonly IServiceProvider serviceProvider;
52+
53+
internal ShowGitHubPaneCommand(IServiceProvider serviceProvider)
54+
{
55+
this.serviceProvider = serviceProvider;
56+
}
57+
58+
public bool CanExecute(object parameter) => true;
59+
60+
public void Execute(object parameter)
61+
{
62+
try
63+
{
64+
var dte = serviceProvider.GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
65+
object customIn = null;
66+
object customOut = null;
67+
dte.Commands.Raise(Guids.guidGitHubCmdSetString, PkgCmdIDList.showCurrentPullRequestCommand, ref customIn, ref customOut);
68+
}
69+
catch (Exception e)
70+
{
71+
VsOutputLogger.WriteLine("Couldn't raise {0}: {1}", nameof(PkgCmdIDList.openPullRequestsCommand), e);
72+
System.Diagnostics.Trace.WriteLine(e);
73+
}
74+
}
75+
76+
public event EventHandler CanExecuteChanged;
77+
}
78+
79+
void PullRequestSessionManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
80+
{
81+
if (e.PropertyName == nameof(PullRequestSessionManager.CurrentSession))
82+
{
83+
RefreshCurrentSession();
84+
}
85+
}
86+
87+
void RefreshCurrentSession()
88+
{
89+
var pullRequest = pullRequestSessionManager.CurrentSession?.PullRequest;
90+
pullRequestStatusViewModel.Number = pullRequest?.Number;
91+
pullRequestStatusViewModel.Title = pullRequest?.Title;
92+
}
93+
94+
public void ShowStatus()
95+
{
96+
var statusBar = FindSccStatusBar();
97+
if (statusBar != null)
98+
{
99+
var githubStatusBar = FindPullRequestStatusView(statusBar);
100+
if (githubStatusBar == null)
101+
{
102+
var view = new PullRequestStatusView { Name = GitHubStatusName, DataContext = pullRequestStatusViewModel };
103+
statusBar.Items.Insert(0, view);
104+
}
105+
}
106+
}
107+
108+
public void HideStatus()
109+
{
110+
var statusBar = FindSccStatusBar();
111+
if (statusBar != null)
112+
{
113+
var githubStatusBar = FindPullRequestStatusView(statusBar);
114+
if (githubStatusBar != null)
115+
{
116+
statusBar.Items.Remove(githubStatusBar);
117+
}
118+
}
119+
}
120+
121+
static UserControl FindPullRequestStatusView(StatusBar statusBar)
122+
{
123+
return FindChild<UserControl>(statusBar, GitHubStatusName);
124+
}
125+
126+
StatusBar FindSccStatusBar()
127+
{
128+
return FindChild<StatusBar>(mainWindow, SccStatusBarName);
129+
}
130+
131+
// https://stackoverflow.com/questions/636383/how-can-i-find-wpf-controls-by-name-or-type
132+
static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
133+
{
134+
// Confirm parent and childName are valid.
135+
if (parent == null) return null;
136+
137+
T foundChild = null;
138+
139+
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
140+
for (int i = 0; i < childrenCount; i++)
141+
{
142+
var child = VisualTreeHelper.GetChild(parent, i);
143+
// If the child is not of the request child type child
144+
T childType = child as T;
145+
if (childType == null)
146+
{
147+
// recursively drill down the tree
148+
foundChild = FindChild<T>(child, childName);
149+
150+
// If the child is found, break so we do not overwrite the found child.
151+
if (foundChild != null) break;
152+
}
153+
else if (!string.IsNullOrEmpty(childName))
154+
{
155+
var frameworkElement = child as FrameworkElement;
156+
// If the child's name is set for search
157+
if (frameworkElement != null && frameworkElement.Name == childName)
158+
{
159+
// if the child's name is of the request name
160+
foundChild = (T)child;
161+
break;
162+
}
163+
}
164+
else
165+
{
166+
// child element found.
167+
foundChild = (T)child;
168+
break;
169+
}
170+
}
171+
172+
return foundChild;
173+
}
174+
175+
class PullRequestStatusManagerInstaller
176+
{
177+
[STAThread]
178+
void Install()
179+
{
180+
var viewModel = new PullRequestStatusViewModel(null) { Number = 666, Title = "A beast of a PR" };
181+
var provider = new PullRequestStatusManager(viewModel);
182+
provider.HideStatus();
183+
provider.ShowStatus();
184+
}
185+
}
186+
}
187+
}

src/GitHub.VisualStudio/GitHub.VisualStudio.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
<Compile Include="Helpers\ActiveDocumentSnapshot.cs" />
295295
<Compile Include="Menus\OpenLink.cs" />
296296
<Compile Include="Menus\LinkMenuBase.cs" />
297+
<Compile Include="Menus\ShowCurrentPullRequest.cs" />
297298
<Compile Include="Menus\OpenPullRequests.cs" />
298299
<Compile Include="Menus\ShowGitHubPane.cs" />
299300
<Compile Include="Menus\AddConnection.cs" />

0 commit comments

Comments
 (0)
0