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

Commit 44ebe6a

Browse files
authored
Merge pull request #1593 from github/enhancement/1591-status-bar-open-PRs
Show `Pull requests` button on status bar when there's no active PR branch
2 parents bad4e2d + e0679a1 commit 44ebe6a

File tree

5 files changed

+129
-39
lines changed

5 files changed

+129
-39
lines changed

src/GitHub.Exports/Models/UsageModel.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public class MeasuresModel
6868
public int NumberOfPRReviewDiffViewInlineCommentStartReview { get; set; }
6969
public int NumberOfPRReviewPosts { get; set; }
7070
public int NumberOfShowCurrentPullRequest { get; set; }
71+
public int NumberOfStatusBarOpenPullRequestList { get; set; }
7172
public int NumberOfTeamExplorerHomeOpenPullRequestList { get; set; }
7273
}
7374
}

src/GitHub.InlineReviews/Services/PullRequestStatusBarManager.cs

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
using System;
22
using System.Windows;
3+
using System.Windows.Input;
34
using System.Windows.Controls;
45
using System.Windows.Controls.Primitives;
56
using System.ComponentModel.Composition;
7+
using System.Reactive.Linq;
8+
using System.Linq.Expressions;
69
using GitHub.Commands;
710
using GitHub.InlineReviews.Views;
811
using GitHub.InlineReviews.ViewModels;
912
using GitHub.Services;
1013
using GitHub.Models;
1114
using GitHub.Logging;
15+
using GitHub.Extensions;
1216
using Serilog;
1317
using ReactiveUI;
1418

@@ -23,19 +27,31 @@ public class PullRequestStatusBarManager
2327
static readonly ILogger log = LogManager.ForContext<PullRequestStatusBarManager>();
2428
const string StatusBarPartName = "PART_SccStatusBarHost";
2529

26-
readonly IShowCurrentPullRequestCommand showCurrentPullRequestCommand;
30+
readonly ICommand openPullRequestsCommand;
31+
readonly ICommand showCurrentPullRequestCommand;
2732

28-
// At the moment this must be constructed on the main thread.
33+
// At the moment these must be constructed on the main thread.
2934
// TeamExplorerContext needs to retrieve DTE using GetService.
3035
readonly Lazy<IPullRequestSessionManager> pullRequestSessionManager;
36+
readonly Lazy<ITeamExplorerContext> teamExplorerContext;
37+
38+
IDisposable currentSessionSubscription;
3139

3240
[ImportingConstructor]
3341
public PullRequestStatusBarManager(
42+
IUsageTracker usageTracker,
43+
IOpenPullRequestsCommand openPullRequestsCommand,
3444
IShowCurrentPullRequestCommand showCurrentPullRequestCommand,
35-
Lazy<IPullRequestSessionManager> pullRequestSessionManager)
45+
Lazy<IPullRequestSessionManager> pullRequestSessionManager,
46+
Lazy<ITeamExplorerContext> teamExplorerContext)
3647
{
37-
this.showCurrentPullRequestCommand = showCurrentPullRequestCommand;
48+
this.openPullRequestsCommand = new UsageTrackingCommand(openPullRequestsCommand,
49+
usageTracker, x => x.NumberOfStatusBarOpenPullRequestList);
50+
this.showCurrentPullRequestCommand = new UsageTrackingCommand(showCurrentPullRequestCommand,
51+
usageTracker, x => x.NumberOfShowCurrentPullRequest);
52+
3853
this.pullRequestSessionManager = pullRequestSessionManager;
54+
this.teamExplorerContext = teamExplorerContext;
3955
}
4056

4157
/// <summary>
@@ -48,27 +64,44 @@ public void StartShowingStatus()
4864
{
4965
try
5066
{
51-
pullRequestSessionManager.Value.WhenAnyValue(x => x.CurrentSession)
52-
.Subscribe(x => RefreshCurrentSession());
67+
teamExplorerContext.Value.WhenAnyValue(x => x.ActiveRepository)
68+
.ObserveOn(RxApp.MainThreadScheduler)
69+
.Subscribe(x => RefreshActiveRepository(x));
5370
}
5471
catch (Exception e)
5572
{
5673
log.Error(e, "Error initializing");
5774
}
5875
}
5976

60-
void RefreshCurrentSession()
77+
void RefreshActiveRepository(ILocalRepositoryModel repository)
78+
{
79+
currentSessionSubscription?.Dispose();
80+
currentSessionSubscription = pullRequestSessionManager.Value.WhenAnyValue(x => x.CurrentSession)
81+
.Subscribe(x => RefreshCurrentSession(repository, x));
82+
}
83+
84+
void RefreshCurrentSession(ILocalRepositoryModel repository, IPullRequestSession session)
6185
{
62-
var pullRequest = pullRequestSessionManager.Value.CurrentSession?.PullRequest;
63-
var viewModel = pullRequest != null ? CreatePullRequestStatusViewModel(pullRequest) : null;
64-
ShowStatus(viewModel);
86+
var cloneUrl = repository?.CloneUrl;
87+
if (cloneUrl != null)
88+
{
89+
// Only show PR status bar if repo has remote
90+
var viewModel = CreatePullRequestStatusViewModel(session);
91+
ShowStatus(viewModel);
92+
}
93+
else
94+
{
95+
ShowStatus(null);
96+
}
6597
}
6698

67-
PullRequestStatusViewModel CreatePullRequestStatusViewModel(IPullRequestModel pullRequest)
99+
PullRequestStatusViewModel CreatePullRequestStatusViewModel(IPullRequestSession session)
68100
{
69-
var pullRequestStatusViewModel = new PullRequestStatusViewModel(showCurrentPullRequestCommand);
70-
pullRequestStatusViewModel.Number = pullRequest.Number;
71-
pullRequestStatusViewModel.Title = pullRequest.Title;
101+
var pullRequestStatusViewModel = new PullRequestStatusViewModel(openPullRequestsCommand, showCurrentPullRequestCommand);
102+
var pullRequest = session?.PullRequest;
103+
pullRequestStatusViewModel.Number = pullRequest?.Number;
104+
pullRequestStatusViewModel.Title = pullRequest?.Title;
72105
return pullRequestStatusViewModel;
73106
}
74107

@@ -110,5 +143,37 @@ StatusBar FindSccStatusBar(Window mainWindow)
110143
var contentControl = mainWindow?.Template?.FindName(StatusBarPartName, mainWindow) as ContentControl;
111144
return contentControl?.Content as StatusBar;
112145
}
146+
147+
class UsageTrackingCommand : ICommand
148+
{
149+
readonly ICommand command;
150+
readonly IUsageTracker usageTracker;
151+
readonly Expression<Func<UsageModel.MeasuresModel, int>> counter;
152+
153+
internal UsageTrackingCommand(ICommand command, IUsageTracker usageTracker,
154+
Expression<Func<UsageModel.MeasuresModel, int>> counter)
155+
{
156+
this.command = command;
157+
this.usageTracker = usageTracker;
158+
this.counter = counter;
159+
}
160+
161+
public event EventHandler CanExecuteChanged
162+
{
163+
add { command.CanExecuteChanged += value; }
164+
remove { command.CanExecuteChanged -= value; }
165+
}
166+
167+
public bool CanExecute(object parameter)
168+
{
169+
return command.CanExecute(parameter);
170+
}
171+
172+
public void Execute(object parameter)
173+
{
174+
command.Execute(parameter);
175+
usageTracker.IncrementCounter(counter).Forget();
176+
}
177+
}
113178
}
114179
}

src/GitHub.InlineReviews/ViewModels/PullRequestStatusViewModel.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ public class PullRequestStatusViewModel : INotifyPropertyChanged
99
int? number;
1010
string title;
1111

12-
public PullRequestStatusViewModel(ICommand showCurrentPullRequestCommand)
12+
public PullRequestStatusViewModel(ICommand openPullRequestsCommand, ICommand showCurrentPullRequestCommand)
1313
{
14+
OpenPullRequestsCommand = openPullRequestsCommand;
1415
ShowCurrentPullRequestCommand = showCurrentPullRequestCommand;
1516
}
1617

@@ -40,6 +41,7 @@ public string Title
4041
}
4142
}
4243

44+
public ICommand OpenPullRequestsCommand { get; }
4345
public ICommand ShowCurrentPullRequestCommand { get; }
4446

4547
public event PropertyChangedEventHandler PropertyChanged;

src/GitHub.InlineReviews/Views/PullRequestStatusView.xaml

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,55 @@
3535
</Style>
3636
</UserControl.Resources>
3737

38-
<Grid Visibility="{Binding Number, TargetNullValue=Collapsed}">
39-
<Button
38+
<StackPanel Orientation="Horizontal">
39+
<Grid Visibility="{Binding Number, Converter={ui:EqualsToVisibilityConverter {x:Null}}}">
40+
<Button
4041
Foreground="{DynamicResource VsBrush.StatusBarText}"
4142
BorderThickness="0"
4243
Padding="4 0"
43-
Command="{Binding ShowCurrentPullRequestCommand}">
44+
Command="{Binding OpenPullRequestsCommand}">
4445

45-
<StackPanel Orientation="Horizontal">
46-
<ui:OcticonPath
47-
Fill="White"
48-
VerticalAlignment="Bottom"
49-
Margin="0 0 4 0 "
50-
Icon="git_pull_request" />
51-
<TextBlock
52-
VerticalAlignment="Center">
53-
#<Run Text="{Binding Number}" />
46+
<StackPanel Orientation="Horizontal">
47+
<ui:OcticonPath
48+
Fill="White"
49+
VerticalAlignment="Bottom"
50+
Margin="0 0 4 0 "
51+
Icon="git_pull_request" />
52+
<TextBlock VerticalAlignment="Center">
53+
Pull requests
54+
</TextBlock>
55+
</StackPanel>
56+
</Button>
57+
<Grid.ToolTip>
58+
<TextBlock VerticalAlignment="Center">
59+
Open or Create a Pull request
5460
</TextBlock>
55-
</StackPanel>
56-
</Button>
57-
<Grid.ToolTip>
58-
<TextBlock VerticalAlignment="Center">
61+
</Grid.ToolTip>
62+
</Grid>
63+
64+
<Grid Visibility="{Binding Number, Converter={ui:NotEqualsToVisibilityConverter {x:Null}}}">
65+
<Button
66+
Foreground="{DynamicResource VsBrush.StatusBarText}"
67+
BorderThickness="0"
68+
Padding="4 0"
69+
Command="{Binding ShowCurrentPullRequestCommand}">
70+
71+
<StackPanel Orientation="Horizontal">
72+
<ui:OcticonPath
73+
Fill="White"
74+
VerticalAlignment="Bottom"
75+
Margin="0 0 4 0 "
76+
Icon="git_pull_request" />
77+
<TextBlock VerticalAlignment="Center">
78+
#<Run Text="{Binding Number}" />
79+
</TextBlock>
80+
</StackPanel>
81+
</Button>
82+
<Grid.ToolTip>
83+
<TextBlock VerticalAlignment="Center">
5984
#<Run Text="{Binding Number}" /> - <Run Text="{Binding Title}" />
60-
</TextBlock>
61-
</Grid.ToolTip>
62-
</Grid>
85+
</TextBlock>
86+
</Grid.ToolTip>
87+
</Grid>
88+
</StackPanel>
6389
</UserControl>

src/GitHub.VisualStudio/Commands/ShowCurrentPullRequestCommand.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,12 @@ public class ShowCurrentPullRequestCommand : VsCommand, IShowCurrentPullRequestC
2121
{
2222
static readonly ILogger log = LogManager.ForContext<ShowCurrentPullRequestCommand>();
2323
readonly IGitHubServiceProvider serviceProvider;
24-
readonly Lazy<IUsageTracker> usageTracker;
2524

2625
[ImportingConstructor]
27-
protected ShowCurrentPullRequestCommand(IGitHubServiceProvider serviceProvider, Lazy<IUsageTracker> usageTracker)
26+
protected ShowCurrentPullRequestCommand(IGitHubServiceProvider serviceProvider)
2827
: base(CommandSet, CommandId)
2928
{
3029
this.serviceProvider = serviceProvider;
31-
this.usageTracker = usageTracker;
3230
}
3331

3432
/// <summary>
@@ -61,8 +59,6 @@ public override async Task Execute()
6159
var manager = serviceProvider.TryGetService<IGitHubToolWindowManager>();
6260
var host = await manager.ShowGitHubPane();
6361
await host.ShowPullRequest(session.RepositoryOwner, host.LocalRepository.Name, pullRequest.Number);
64-
65-
usageTracker.Value.IncrementCounter(x => x.NumberOfShowCurrentPullRequest).Forget();
6662
}
6763
catch (Exception ex)
6864
{

0 commit comments

Comments
 (0)