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

Open PR link to the selected (not active) repo on GitHub #1214

Merged
merged 12 commits into from
Sep 5, 2017
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public PullRequestListViewModelDesigner()
Assignee = new AccountDesigner { Login = "haacked", IsUser = true },
});
prs.Add(new PullRequestModel(409, "Fix publish button style and a really, really long name for this thing... OMG look how long this name is yusssss",
new AccountDesigner { Login = "shana", IsUser = true },
new AccountDesigner { Login = "shana", IsUser = true },
DateTimeOffset.Now - TimeSpan.FromHours(5))
{
CommentCount = 27,
Expand Down Expand Up @@ -76,5 +76,6 @@ public PullRequestListViewModelDesigner()

public ReactiveCommand<object> OpenPullRequest { get; }
public ReactiveCommand<object> CreatePullRequest { get; }
public ReactiveCommand<object> OpenPullRequestOnGitHub { get; }
}
}
24 changes: 20 additions & 4 deletions src/GitHub.App/ViewModels/PullRequestListViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
Expand Down Expand Up @@ -32,6 +31,7 @@ public class PullRequestListViewModel : PanePageViewModelBase, IPullRequestListV
readonly TrackingCollection<IAccount> trackingAuthors;
readonly TrackingCollection<IAccount> trackingAssignees;
readonly IPackageSettings settings;
readonly IVisualStudioBrowser visualStudioBrowser;
readonly PullRequestListUIState listSettings;
readonly bool constructing;
IRemoteRepositoryModel remoteRepository;
Expand All @@ -40,8 +40,9 @@ public class PullRequestListViewModel : PanePageViewModelBase, IPullRequestListV
PullRequestListViewModel(
IConnectionRepositoryHostMap connectionRepositoryHostMap,
ITeamExplorerServiceHolder teservice,
IPackageSettings settings)
: this(connectionRepositoryHostMap.CurrentRepositoryHost, teservice.ActiveRepo, settings)
IPackageSettings settings,
IVisualStudioBrowser visualStudioBrowser)
: this(connectionRepositoryHostMap.CurrentRepositoryHost, teservice.ActiveRepo, settings, visualStudioBrowser)
{
Guard.ArgumentNotNull(connectionRepositoryHostMap, nameof(connectionRepositoryHostMap));
Guard.ArgumentNotNull(teservice, nameof(teservice));
Expand All @@ -51,16 +52,19 @@ public class PullRequestListViewModel : PanePageViewModelBase, IPullRequestListV
public PullRequestListViewModel(
IRepositoryHost repositoryHost,
ILocalRepositoryModel repository,
IPackageSettings settings)
IPackageSettings settings,
IVisualStudioBrowser visualStudioBrowser)
{
Guard.ArgumentNotNull(repositoryHost, nameof(repositoryHost));
Guard.ArgumentNotNull(repository, nameof(repository));
Guard.ArgumentNotNull(settings, nameof(settings));
Guard.ArgumentNotNull(visualStudioBrowser, nameof(visualStudioBrowser));

constructing = true;
this.repositoryHost = repositoryHost;
this.localRepository = repository;
this.settings = settings;
this.visualStudioBrowser = visualStudioBrowser;

Title = Resources.PullRequestsNavigationItemText;

Expand Down Expand Up @@ -108,6 +112,9 @@ public PullRequestListViewModel(
CreatePullRequest = ReactiveCommand.Create();
CreatePullRequest.Subscribe(_ => DoCreatePullRequest());

OpenPullRequestOnGitHub = ReactiveCommand.Create();
OpenPullRequestOnGitHub.Subscribe(x => DoOpenPullRequestOnGitHub((int)x));

constructing = false;
}

Expand Down Expand Up @@ -269,6 +276,8 @@ public IAccount EmptyUser
public ReactiveCommand<object> OpenPullRequest { get; }
public ReactiveCommand<object> CreatePullRequest { get; }

public ReactiveCommand<object> OpenPullRequestOnGitHub { get; }

bool disposed;
protected void Dispose(bool disposing)
{
Expand Down Expand Up @@ -334,5 +343,12 @@ void DoCreatePullRequest()
var d = new ViewWithData(UIControllerFlow.PullRequestCreation);
navigate.OnNext(d);
}

void DoOpenPullRequestOnGitHub(int pullRequest)
{
var repoUrl = SelectedRepository.CloneUrl.ToRepositoryUrl();
var url = repoUrl.Append("pull/" + pullRequest);
visualStudioBrowser.OpenUrl(url);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ public interface IPullRequestListViewModel : IViewModel, ICanNavigate, IHasBusy
IAccount SelectedAssignee { get; set; }
ReactiveCommand<object> OpenPullRequest { get; }
ReactiveCommand<object> CreatePullRequest { get; }
ReactiveCommand<object> OpenPullRequestOnGitHub { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
</Grid.ColumnDefinitions>
<Button x:Name="prHashtagLink"
Grid.Column="0"
Command="{Binding OpenPROnGitHub, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PullRequestListView}}}"
Command="{Binding ViewModel.OpenPullRequestOnGitHub, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PullRequestListView}}}"
CommandParameter="{Binding Number}"
Content="{Binding Number}"
ToolTip="{x:Static prop:Resources.OpenPROnGitHubToolTip}"
Expand Down
23 changes: 1 addition & 22 deletions src/GitHub.VisualStudio/UI/Views/PullRequestListView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,16 @@ public partial class PullRequestListView : GenericPullRequestListView, IDisposab
readonly Subject<int> open = new Subject<int>();
readonly Subject<object> create = new Subject<object>();

public PullRequestListView()
{
InitializeComponent();
}

[ImportingConstructor]
public PullRequestListView(IGitHubServiceProvider serviceProvider)
public PullRequestListView()
{
InitializeComponent();

OpenPROnGitHub = new RelayCommand(x =>
{
var repo = serviceProvider.TryGetService<ITeamExplorerServiceHolder>()?.ActiveRepo;
var browser = serviceProvider.TryGetService<IVisualStudioBrowser>();
Debug.Assert(repo != null, "No active repo, cannot open PR on GitHub");
Debug.Assert(browser != null, "No browser service, cannot open PR on GitHub");
if (repo == null || browser == null)
{
return;
}
var url = repo.CloneUrl.ToRepositoryUrl().Append("pull/" + x);
browser.OpenUrl(url);
});

this.WhenActivated(d =>
{
});
}

public ICommand OpenPROnGitHub { get; set; }

bool disposed;
protected override void Dispose(bool disposing)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using GitHub.Services;
using GitHub.Settings;
using GitHub.ViewModels;
using GitHub.Primitives;
using NSubstitute;
using Xunit;

Expand All @@ -20,7 +21,8 @@ public void SelectingAssigneeShouldTriggerFilter()
var repositoryHost = CreateRepositoryHost();
var repository = Substitute.For<ILocalRepositoryModel>();
var settings = CreateSettings();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings);
var browser = Substitute.For<IVisualStudioBrowser>();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings, browser);

prViewModel.Initialize(null);
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
Expand All @@ -35,7 +37,8 @@ public void ResettingAssigneeToNoneShouldNotTriggerFilter()
var repositoryHost = CreateRepositoryHost();
var repository = Substitute.For<ILocalRepositoryModel>();
var settings = CreateSettings();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings);
var browser = Substitute.For<IVisualStudioBrowser>();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings, browser);

prViewModel.Initialize(null);
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
Expand All @@ -56,7 +59,8 @@ public void SelectingAuthorShouldTriggerFilter()
var repositoryHost = CreateRepositoryHost();
var repository = Substitute.For<ILocalRepositoryModel>();
var settings = CreateSettings();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings);
var browser = Substitute.For<IVisualStudioBrowser>();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings, browser);

prViewModel.Initialize(null);
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
Expand All @@ -71,7 +75,8 @@ public void ResettingAuthorToNoneShouldNotTriggerFilter()
var repositoryHost = CreateRepositoryHost();
var repository = Substitute.For<ILocalRepositoryModel>();
var settings = CreateSettings();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings);
var browser = Substitute.For<IVisualStudioBrowser>();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings, browser);

prViewModel.Initialize(null);
prViewModel.PullRequests.Received(1).Filter = AnyFilter;
Expand All @@ -86,6 +91,23 @@ public void ResettingAuthorToNoneShouldNotTriggerFilter()
prViewModel.PullRequests.Received(2).Filter = AnyFilter;
}

[Theory]
[InlineData("https://github.com/owner/repo", 666, "https://github.com/owner/repo/pull/666")]
public void OpenPullRequestOnGitHubShouldOpenBrowser(string cloneUrl, int pullNumber, string expectUrl)
{
var repositoryHost = CreateRepositoryHost();
var repository = Substitute.For<ILocalRepositoryModel>();
var settings = CreateSettings();
var browser = Substitute.For<IVisualStudioBrowser>();
var prViewModel = new PullRequestListViewModel(repositoryHost, repository, settings, browser);
prViewModel.SelectedRepository = Substitute.For<IRemoteRepositoryModel>();
prViewModel.SelectedRepository.CloneUrl.Returns(new UriString(cloneUrl));

prViewModel.OpenPullRequestOnGitHub.Execute(pullNumber);

browser.ReceivedWithAnyArgs(1).OpenUrl(new Uri(expectUrl));
}

Func<IPullRequestModel, int, IList<IPullRequestModel>, bool> AnyFilter =>
Arg.Any<Func<IPullRequestModel, int, IList<IPullRequestModel>, bool>>();

Expand Down