From d1a0da37d6597cf204d21fce28d42c5165895cad Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Fri, 5 Jan 2018 09:38:59 +0000 Subject: [PATCH 1/4] Use IVSGitExt for PullRequestSessionManager events We need to be notified when a branch changes. ITeamExplorerServiceHolder only fires when moving to a new repo. IVSGitExt.ActiveRepositoriesChanged also fires when a branch changes. --- .../Services/PullRequestSessionManager.cs | 14 ++- .../GitHub.InlineReviews.UnitTests.csproj | 1 - .../PullRequestSessionManagerTests.cs | 115 +++++++++++------- .../FakeTeamExplorerServiceHolder.cs | 54 -------- 4 files changed, 85 insertions(+), 99 deletions(-) delete mode 100644 test/GitHub.InlineReviews.UnitTests/TestDoubles/FakeTeamExplorerServiceHolder.cs diff --git a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs index 106c67d6cf..055afd6e1d 100644 --- a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs +++ b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs @@ -53,19 +53,21 @@ public PullRequestSessionManager( IPullRequestSessionService sessionService, IConnectionManager connectionManager, IModelServiceFactory modelServiceFactory, - ITeamExplorerServiceHolder teamExplorerService) + IVSGitExt vsGitExt) { Guard.ArgumentNotNull(service, nameof(service)); Guard.ArgumentNotNull(sessionService, nameof(sessionService)); Guard.ArgumentNotNull(connectionManager, nameof(connectionManager)); Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory)); - Guard.ArgumentNotNull(teamExplorerService, nameof(teamExplorerService)); + Guard.ArgumentNotNull(vsGitExt, nameof(vsGitExt)); this.service = service; this.sessionService = sessionService; this.connectionManager = connectionManager; this.modelServiceFactory = modelServiceFactory; - teamExplorerService.Subscribe(this, x => RepoChanged(x).Forget()); + + RepoChanged(vsGitExt); + vsGitExt.ActiveRepositoriesChanged += () => RepoChanged(vsGitExt); } /// @@ -178,6 +180,12 @@ public PullRequestTextBufferInfo GetTextBufferInfo(ITextBuffer buffer) return null; } + void RepoChanged(IVSGitExt vsGitExt) + { + var repo = vsGitExt.ActiveRepositories.FirstOrDefault(); + RepoChanged(repo).Forget(); + } + async Task RepoChanged(ILocalRepositoryModel localRepositoryModel) { try diff --git a/test/GitHub.InlineReviews.UnitTests/GitHub.InlineReviews.UnitTests.csproj b/test/GitHub.InlineReviews.UnitTests/GitHub.InlineReviews.UnitTests.csproj index 1cc2c42efb..471f99879e 100644 --- a/test/GitHub.InlineReviews.UnitTests/GitHub.InlineReviews.UnitTests.csproj +++ b/test/GitHub.InlineReviews.UnitTests/GitHub.InlineReviews.UnitTests.csproj @@ -143,7 +143,6 @@ - diff --git a/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs b/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs index 2a38ff7806..d6419f7406 100644 --- a/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs +++ b/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs @@ -5,7 +5,6 @@ using System.Reactive.Subjects; using System.Text; using System.Threading.Tasks; -using GitHub.Extensions; using GitHub.Factories; using GitHub.InlineReviews.Models; using GitHub.InlineReviews.Services; @@ -50,11 +49,30 @@ public void ReadsPullRequestFromCorrectFork() Substitute.For(), connectionManager, modelFactory, - new FakeTeamExplorerServiceHolder(repositoryModel)); + CreateVSGitExt(repositoryModel)); var modelService = modelFactory.CreateBlocking(connectionManager.Connections[0]); modelService.Received(1).GetPullRequest("fork", "repo", 15); } + + [Fact] + public void LocalRepositoryModelNull() + { + var repositoryModel = null as LocalRepositoryModel; + var service = CreatePullRequestService(); + var connectionManager = CreateConnectionManager(); + var modelFactory = CreateModelServiceFactory(); + var vsGitExt = CreateVSGitExt(repositoryModel); + + var target = new PullRequestSessionManager( + service, + Substitute.For(), + connectionManager, + modelFactory, + vsGitExt); + + Assert.Null(target.CurrentSession); + } } public class TheCurrentSessionProperty : PullRequestSessionManagerTests @@ -67,7 +85,7 @@ public void CreatesSessionForCurrentBranch() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); Assert.NotNull(target.CurrentSession); Assert.True(target.CurrentSession.IsCheckedOut); @@ -84,7 +102,7 @@ public void CurrentSessionIsNullIfNoPullRequestForCurrentBranch() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); Assert.Null(target.CurrentSession); } @@ -93,18 +111,18 @@ public void CurrentSessionIsNullIfNoPullRequestForCurrentBranch() public void CurrentSessionChangesWhenBranchChanges() { var service = CreatePullRequestService(); - var teService = new FakeTeamExplorerServiceHolder(CreateRepositoryModel()); + var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); var target = new PullRequestSessionManager( service, Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - teService); + vsGitExt); var session = target.CurrentSession; service.GetPullRequestForCurrentBranch(null).ReturnsForAnyArgs(Observable.Return(Tuple.Create("foo", 22))); - teService.NotifyActiveRepoChanged(); + vsGitExt.ActiveRepositoriesChanged += Raise.Event(); Assert.NotSame(session, target.CurrentSession); } @@ -112,17 +130,17 @@ public void CurrentSessionChangesWhenBranchChanges() [Fact] public void CurrentSessionChangesWhenRepoChanged() { - var teService = new FakeTeamExplorerServiceHolder(CreateRepositoryModel()); + var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - teService); + vsGitExt); var session = target.CurrentSession; - teService.ActiveRepo = CreateRepositoryModel("https://github.com/owner/other"); + SetActiveRepository(vsGitExt, CreateRepositoryModel("https://github.com/owner/other")); Assert.NotSame(session, target.CurrentSession); } @@ -130,17 +148,17 @@ public void CurrentSessionChangesWhenRepoChanged() [Fact] public void RepoChangedDoesntCreateNewSessionIfNotNecessary() { - var teService = new FakeTeamExplorerServiceHolder(CreateRepositoryModel()); + var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - teService); + vsGitExt); var session = target.CurrentSession; - teService.NotifyActiveRepoChanged(); + vsGitExt.ActiveRepositoriesChanged += Raise.Event(); Assert.Same(session, target.CurrentSession); } @@ -148,15 +166,15 @@ public void RepoChangedDoesntCreateNewSessionIfNotNecessary() [Fact] public void RepoChangedHandlesNullRepository() { - var teService = new FakeTeamExplorerServiceHolder(CreateRepositoryModel()); + var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - teService); + vsGitExt); - teService.ActiveRepo = null; + SetActiveRepository(vsGitExt, null); Assert.Null(target.CurrentSession); } @@ -169,7 +187,7 @@ public void CreatesSessionWithCorrectRepositoryOwner() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); Assert.Equal("this-owner", target.CurrentSession.RepositoryOwner); } @@ -189,7 +207,7 @@ public async Task BaseShaIsSet() CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same("BASESHA", file.BaseSha); @@ -205,7 +223,7 @@ public async Task CommitShaIsSet() CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same("TIPSHA", file.CommitSha); @@ -221,7 +239,7 @@ public async Task CommitShaIsNullIfModified() CreateSessionService(true), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Null(file.CommitSha); @@ -249,7 +267,7 @@ public async Task DiffIsSet() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same(diff, file.Diff); @@ -267,7 +285,7 @@ public async Task InlineCommentThreadsIsSet() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -296,7 +314,7 @@ public async Task CreatesTrackingPointsForThreads() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -315,14 +333,14 @@ public async Task MovingToNoRepositoryShouldNullOutProperties() var textView = CreateTextView(); var sessionService = CreateSessionService(); var threads = new List(); - var teHolder = new FakeTeamExplorerServiceHolder(CreateRepositoryModel()); + var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - teHolder); + vsGitExt); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -338,7 +356,7 @@ public async Task MovingToNoRepositoryShouldNullOutProperties() Assert.NotNull(file.InlineCommentThreads); Assert.NotNull(file.TrackingPoints); - teHolder.ActiveRepo = null; + SetActiveRepository(vsGitExt, null); Assert.Null(file.BaseSha); Assert.Null(file.CommitSha); @@ -366,7 +384,7 @@ public async Task ModifyingBufferMarksThreadsAsStaleAndSignalsRebuild() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -409,7 +427,7 @@ public async Task RebuildSignalUpdatesCommitSha() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same("TIPSHA", file.CommitSha); @@ -430,7 +448,7 @@ public async Task ClosingTextViewDisposesFile() CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); var compositeDisposable = file.ToDispose as CompositeDisposable; @@ -474,7 +492,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal(1, file.InlineCommentThreads.Count); @@ -520,7 +538,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal(1, file.InlineCommentThreads.Count); @@ -580,7 +598,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal("Original Comment", file.InlineCommentThreads[0].Comments[0].Body); @@ -635,7 +653,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal(1, file.InlineCommentThreads[0].Comments.Count); @@ -666,7 +684,7 @@ public async Task CommitShaIsUpdatedOnTextChange() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal("TIPSHA", file.CommitSha); @@ -695,7 +713,7 @@ public async Task UpdatingCurrentSessionPullRequestTriggersLinesChanged() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); var raised = false; var pullRequest = target.CurrentSession.PullRequest; @@ -807,7 +825,7 @@ public async Task GetSessionReturnsAndUpdatesCurrentSessionIfNumbersMatch() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var newModel = CreatePullRequestModel(CurrentBranchPullRequestNumber); var result = await target.GetSession(newModel); @@ -824,7 +842,7 @@ public async Task GetSessionReturnsNewSessionForPullRequestWithDifferentNumber() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var newModel = CreatePullRequestModel(NotCurrentBranchPullRequestNumber); var result = await target.GetSession(newModel); @@ -842,7 +860,7 @@ public async Task GetSessionReturnsNewSessionForPullRequestWithDifferentBaseOwne Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var newModel = CreatePullRequestModel(CurrentBranchPullRequestNumber, "https://github.com/fork/repo"); var result = await target.GetSession(newModel); @@ -860,7 +878,7 @@ public async Task GetSessionReturnsSameSessionEachTime() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); var newModel = CreatePullRequestModel(NotCurrentBranchPullRequestNumber); var result1 = await target.GetSession(newModel); @@ -879,7 +897,7 @@ public async Task SessionCanBeCollected() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); Func run = async () => { @@ -912,7 +930,7 @@ public async Task GetSessionUpdatesCurrentSessionIfCurrentBranchIsPullRequestBut Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - new FakeTeamExplorerServiceHolder(CreateRepositoryModel())); + CreateVSGitExt(CreateRepositoryModel())); Assert.Null(target.CurrentSession); @@ -927,6 +945,13 @@ public async Task GetSessionUpdatesCurrentSessionIfCurrentBranchIsPullRequestBut } } + static void SetActiveRepository(IVSGitExt vsGitExt, ILocalRepositoryModel localRepositoryModel) + { + var repos = localRepositoryModel != null ? new[] { localRepositoryModel } : new ILocalRepositoryModel[0]; + vsGitExt.ActiveRepositories.Returns(repos); + vsGitExt.ActiveRepositoriesChanged += Raise.Event(); + } + IPullRequestModel CreatePullRequestModel( int number, string cloneUrl = OwnerCloneUrl, @@ -983,5 +1008,13 @@ ILocalRepositoryModel CreateRepositoryModel(string cloneUrl = OwnerCloneUrl) result.Owner.Returns(uriString.Owner); return result; } + + static IVSGitExt CreateVSGitExt(ILocalRepositoryModel repo) + { + var vsGitExt = Substitute.For(); + var repos = repo != null ? new[] { repo } : new ILocalRepositoryModel[0]; + vsGitExt.ActiveRepositories.Returns(repos); + return vsGitExt; + } } } diff --git a/test/GitHub.InlineReviews.UnitTests/TestDoubles/FakeTeamExplorerServiceHolder.cs b/test/GitHub.InlineReviews.UnitTests/TestDoubles/FakeTeamExplorerServiceHolder.cs deleted file mode 100644 index e6f5d1b2a9..0000000000 --- a/test/GitHub.InlineReviews.UnitTests/TestDoubles/FakeTeamExplorerServiceHolder.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using GitHub.Models; -using GitHub.Services; - -namespace GitHub.InlineReviews.UnitTests.TestDoubles -{ - class FakeTeamExplorerServiceHolder : ITeamExplorerServiceHolder - { - ILocalRepositoryModel activeRepo; - Action listener; - - public FakeTeamExplorerServiceHolder() - { - } - - public FakeTeamExplorerServiceHolder(ILocalRepositoryModel repo) - { - ActiveRepo = repo; - } - - public ILocalRepositoryModel ActiveRepo - { - get { return activeRepo; } - set { activeRepo = value; NotifyActiveRepoChanged(); } - } - - public IGitAwareItem HomeSection { get; set; } - - public IServiceProvider ServiceProvider { get; set; } - - public void ClearServiceProvider(IServiceProvider provider) - { - } - - public void NotifyActiveRepoChanged() - { - listener?.Invoke(activeRepo); - } - - public void Refresh() - { - } - - public void Subscribe(object who, Action handler) - { - listener = handler; - handler(ActiveRepo); - } - - public void Unsubscribe(object who) - { - } - } -} From c4b80e55856b8e8db583791a87606c4f20d2572d Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Fri, 5 Jan 2018 12:20:36 +0000 Subject: [PATCH 2/4] Change from using IVSGitExt to ITeamExplorerContext TeamExplorerContext uses IVSGitExt and ITeamExplorerServiceHolder to expose all status change events. --- src/GitHub.App/GitHub.App.csproj | 1 + .../Services/TeamExplorerContext.cs | 42 +++++++ src/GitHub.Exports/GitHub.Exports.csproj | 1 + .../Services/ITeamExplorerContext.cs | 11 ++ .../Services/PullRequestSessionManager.cs | 17 ++- .../PullRequestSessionManagerTests.cs | 106 +++++++++--------- 6 files changed, 114 insertions(+), 64 deletions(-) create mode 100644 src/GitHub.App/Services/TeamExplorerContext.cs create mode 100644 src/GitHub.Exports/Services/ITeamExplorerContext.cs diff --git a/src/GitHub.App/GitHub.App.csproj b/src/GitHub.App/GitHub.App.csproj index f726e09103..e359cd6022 100644 --- a/src/GitHub.App/GitHub.App.csproj +++ b/src/GitHub.App/GitHub.App.csproj @@ -138,6 +138,7 @@ + diff --git a/src/GitHub.App/Services/TeamExplorerContext.cs b/src/GitHub.App/Services/TeamExplorerContext.cs new file mode 100644 index 0000000000..55d6aeb1c8 --- /dev/null +++ b/src/GitHub.App/Services/TeamExplorerContext.cs @@ -0,0 +1,42 @@ +using System; +using System.Linq; +using System.ComponentModel; +using System.ComponentModel.Composition; +using GitHub.Models; + +namespace GitHub.Services +{ + [Export(typeof(ITeamExplorerContext))] + [PartCreationPolicy(CreationPolicy.Shared)] + public class TeamExplorerContext : ITeamExplorerContext + { + readonly IVSGitExt vsGitExt; + readonly ITeamExplorerServiceHolder teamExplorerServiceHolder; + + [ImportingConstructor] + public TeamExplorerContext(IVSGitExt vsGitExt, ITeamExplorerServiceHolder teamExplorerServiceHolder) + { + this.vsGitExt = vsGitExt; + this.teamExplorerServiceHolder = teamExplorerServiceHolder; + + vsGitExt.ActiveRepositoriesChanged += () => + { + StatusChanged?.Invoke(this, EventArgs.Empty); + }; + } + + public ILocalRepositoryModel GetActiveRepository() + { + var activeRepository = vsGitExt.ActiveRepositories.FirstOrDefault(); + if (activeRepository == null) + { + // HACK: TeamExplorerServiceHolder does some magic to ensure that ActiveRepositories is aviablable. + activeRepository = teamExplorerServiceHolder.ActiveRepo; + } + + return activeRepository; + } + + public event EventHandler StatusChanged; + } +} diff --git a/src/GitHub.Exports/GitHub.Exports.csproj b/src/GitHub.Exports/GitHub.Exports.csproj index dc0c9d224c..4bf3018444 100644 --- a/src/GitHub.Exports/GitHub.Exports.csproj +++ b/src/GitHub.Exports/GitHub.Exports.csproj @@ -154,6 +154,7 @@ + diff --git a/src/GitHub.Exports/Services/ITeamExplorerContext.cs b/src/GitHub.Exports/Services/ITeamExplorerContext.cs new file mode 100644 index 0000000000..68abd63081 --- /dev/null +++ b/src/GitHub.Exports/Services/ITeamExplorerContext.cs @@ -0,0 +1,11 @@ +using System; +using GitHub.Models; + +namespace GitHub.Services +{ + public interface ITeamExplorerContext + { + ILocalRepositoryModel GetActiveRepository(); + event EventHandler StatusChanged; + } +} diff --git a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs index 055afd6e1d..0c8e4486e1 100644 --- a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs +++ b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs @@ -53,21 +53,24 @@ public PullRequestSessionManager( IPullRequestSessionService sessionService, IConnectionManager connectionManager, IModelServiceFactory modelServiceFactory, - IVSGitExt vsGitExt) + ITeamExplorerContext teamExplorerContext) { Guard.ArgumentNotNull(service, nameof(service)); Guard.ArgumentNotNull(sessionService, nameof(sessionService)); Guard.ArgumentNotNull(connectionManager, nameof(connectionManager)); Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory)); - Guard.ArgumentNotNull(vsGitExt, nameof(vsGitExt)); + Guard.ArgumentNotNull(teamExplorerContext, nameof(teamExplorerContext)); this.service = service; this.sessionService = sessionService; this.connectionManager = connectionManager; this.modelServiceFactory = modelServiceFactory; - RepoChanged(vsGitExt); - vsGitExt.ActiveRepositoriesChanged += () => RepoChanged(vsGitExt); + RepoChanged(teamExplorerContext.GetActiveRepository()).Forget(); + teamExplorerContext.StatusChanged += (s, e) => + { + RepoChanged(teamExplorerContext.GetActiveRepository()).Forget(); + }; } /// @@ -180,12 +183,6 @@ public PullRequestTextBufferInfo GetTextBufferInfo(ITextBuffer buffer) return null; } - void RepoChanged(IVSGitExt vsGitExt) - { - var repo = vsGitExt.ActiveRepositories.FirstOrDefault(); - RepoChanged(repo).Forget(); - } - async Task RepoChanged(ILocalRepositoryModel localRepositoryModel) { try diff --git a/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs b/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs index d6419f7406..40431a0ce6 100644 --- a/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs +++ b/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs @@ -49,7 +49,7 @@ public void ReadsPullRequestFromCorrectFork() Substitute.For(), connectionManager, modelFactory, - CreateVSGitExt(repositoryModel)); + CreateTeamExplorerContext(repositoryModel)); var modelService = modelFactory.CreateBlocking(connectionManager.Connections[0]); modelService.Received(1).GetPullRequest("fork", "repo", 15); @@ -62,14 +62,14 @@ public void LocalRepositoryModelNull() var service = CreatePullRequestService(); var connectionManager = CreateConnectionManager(); var modelFactory = CreateModelServiceFactory(); - var vsGitExt = CreateVSGitExt(repositoryModel); + var teamExplorerContext = CreateTeamExplorerContext(repositoryModel); var target = new PullRequestSessionManager( service, Substitute.For(), connectionManager, modelFactory, - vsGitExt); + teamExplorerContext); Assert.Null(target.CurrentSession); } @@ -85,7 +85,7 @@ public void CreatesSessionForCurrentBranch() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); Assert.NotNull(target.CurrentSession); Assert.True(target.CurrentSession.IsCheckedOut); @@ -102,7 +102,7 @@ public void CurrentSessionIsNullIfNoPullRequestForCurrentBranch() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); Assert.Null(target.CurrentSession); } @@ -111,18 +111,18 @@ public void CurrentSessionIsNullIfNoPullRequestForCurrentBranch() public void CurrentSessionChangesWhenBranchChanges() { var service = CreatePullRequestService(); - var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); + var teamExplorerContext = CreateTeamExplorerContext(CreateRepositoryModel()); var target = new PullRequestSessionManager( service, Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - vsGitExt); + teamExplorerContext); var session = target.CurrentSession; service.GetPullRequestForCurrentBranch(null).ReturnsForAnyArgs(Observable.Return(Tuple.Create("foo", 22))); - vsGitExt.ActiveRepositoriesChanged += Raise.Event(); + teamExplorerContext.StatusChanged += Raise.Event(); Assert.NotSame(session, target.CurrentSession); } @@ -130,17 +130,17 @@ public void CurrentSessionChangesWhenBranchChanges() [Fact] public void CurrentSessionChangesWhenRepoChanged() { - var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); + var teamExplorerContext = CreateTeamExplorerContext(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - vsGitExt); + teamExplorerContext); var session = target.CurrentSession; - SetActiveRepository(vsGitExt, CreateRepositoryModel("https://github.com/owner/other")); + SetActiveRepository(teamExplorerContext, CreateRepositoryModel("https://github.com/owner/other")); Assert.NotSame(session, target.CurrentSession); } @@ -148,17 +148,17 @@ public void CurrentSessionChangesWhenRepoChanged() [Fact] public void RepoChangedDoesntCreateNewSessionIfNotNecessary() { - var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); + var teamExplorerContext = CreateTeamExplorerContext(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - vsGitExt); + teamExplorerContext); var session = target.CurrentSession; - vsGitExt.ActiveRepositoriesChanged += Raise.Event(); + teamExplorerContext.StatusChanged += Raise.Event(); Assert.Same(session, target.CurrentSession); } @@ -166,15 +166,15 @@ public void RepoChangedDoesntCreateNewSessionIfNotNecessary() [Fact] public void RepoChangedHandlesNullRepository() { - var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); + var teamExplorerContext = CreateTeamExplorerContext(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - vsGitExt); + teamExplorerContext); - SetActiveRepository(vsGitExt, null); + SetActiveRepository(teamExplorerContext, null); Assert.Null(target.CurrentSession); } @@ -187,7 +187,7 @@ public void CreatesSessionWithCorrectRepositoryOwner() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); Assert.Equal("this-owner", target.CurrentSession.RepositoryOwner); } @@ -207,7 +207,7 @@ public async Task BaseShaIsSet() CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same("BASESHA", file.BaseSha); @@ -223,7 +223,7 @@ public async Task CommitShaIsSet() CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same("TIPSHA", file.CommitSha); @@ -239,7 +239,7 @@ public async Task CommitShaIsNullIfModified() CreateSessionService(true), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Null(file.CommitSha); @@ -267,7 +267,7 @@ public async Task DiffIsSet() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same(diff, file.Diff); @@ -285,7 +285,7 @@ public async Task InlineCommentThreadsIsSet() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -314,7 +314,7 @@ public async Task CreatesTrackingPointsForThreads() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -333,14 +333,14 @@ public async Task MovingToNoRepositoryShouldNullOutProperties() var textView = CreateTextView(); var sessionService = CreateSessionService(); var threads = new List(); - var vsGitExt = CreateVSGitExt(CreateRepositoryModel()); + var teamExplorerContext = CreateTeamExplorerContext(CreateRepositoryModel()); var target = new PullRequestSessionManager( CreatePullRequestService(), CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - vsGitExt); + teamExplorerContext); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -356,7 +356,7 @@ public async Task MovingToNoRepositoryShouldNullOutProperties() Assert.NotNull(file.InlineCommentThreads); Assert.NotNull(file.TrackingPoints); - SetActiveRepository(vsGitExt, null); + SetActiveRepository(teamExplorerContext, null); Assert.Null(file.BaseSha); Assert.Null(file.CommitSha); @@ -384,7 +384,7 @@ public async Task ModifyingBufferMarksThreadsAsStaleAndSignalsRebuild() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); sessionService.BuildCommentThreads( target.CurrentSession.PullRequest, @@ -427,7 +427,7 @@ public async Task RebuildSignalUpdatesCommitSha() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Same("TIPSHA", file.CommitSha); @@ -448,7 +448,7 @@ public async Task ClosingTextViewDisposesFile() CreateSessionService(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); var compositeDisposable = file.ToDispose as CompositeDisposable; @@ -492,7 +492,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal(1, file.InlineCommentThreads.Count); @@ -538,7 +538,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal(1, file.InlineCommentThreads.Count); @@ -598,7 +598,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal("Original Comment", file.InlineCommentThreads[0].Comments[0].Body); @@ -653,7 +653,7 @@ Line 2 CreateRealSessionService(diff: diffService), CreateConnectionManager(), CreateModelServiceFactory(pullRequest), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = (PullRequestSessionLiveFile)await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal(1, file.InlineCommentThreads[0].Comments.Count); @@ -684,7 +684,7 @@ public async Task CommitShaIsUpdatedOnTextChange() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); Assert.Equal("TIPSHA", file.CommitSha); @@ -713,7 +713,7 @@ public async Task UpdatingCurrentSessionPullRequestTriggersLinesChanged() sessionService, CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var file = await target.GetLiveFile(FilePath, textView, textView.TextBuffer); var raised = false; var pullRequest = target.CurrentSession.PullRequest; @@ -825,7 +825,7 @@ public async Task GetSessionReturnsAndUpdatesCurrentSessionIfNumbersMatch() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var newModel = CreatePullRequestModel(CurrentBranchPullRequestNumber); var result = await target.GetSession(newModel); @@ -842,7 +842,7 @@ public async Task GetSessionReturnsNewSessionForPullRequestWithDifferentNumber() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var newModel = CreatePullRequestModel(NotCurrentBranchPullRequestNumber); var result = await target.GetSession(newModel); @@ -860,7 +860,7 @@ public async Task GetSessionReturnsNewSessionForPullRequestWithDifferentBaseOwne Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var newModel = CreatePullRequestModel(CurrentBranchPullRequestNumber, "https://github.com/fork/repo"); var result = await target.GetSession(newModel); @@ -878,7 +878,7 @@ public async Task GetSessionReturnsSameSessionEachTime() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); var newModel = CreatePullRequestModel(NotCurrentBranchPullRequestNumber); var result1 = await target.GetSession(newModel); @@ -897,7 +897,7 @@ public async Task SessionCanBeCollected() Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); Func run = async () => { @@ -930,7 +930,7 @@ public async Task GetSessionUpdatesCurrentSessionIfCurrentBranchIsPullRequestBut Substitute.For(), CreateConnectionManager(), CreateModelServiceFactory(), - CreateVSGitExt(CreateRepositoryModel())); + CreateTeamExplorerContext(CreateRepositoryModel())); Assert.Null(target.CurrentSession); @@ -945,13 +945,6 @@ public async Task GetSessionUpdatesCurrentSessionIfCurrentBranchIsPullRequestBut } } - static void SetActiveRepository(IVSGitExt vsGitExt, ILocalRepositoryModel localRepositoryModel) - { - var repos = localRepositoryModel != null ? new[] { localRepositoryModel } : new ILocalRepositoryModel[0]; - vsGitExt.ActiveRepositories.Returns(repos); - vsGitExt.ActiveRepositoriesChanged += Raise.Event(); - } - IPullRequestModel CreatePullRequestModel( int number, string cloneUrl = OwnerCloneUrl, @@ -1009,12 +1002,17 @@ ILocalRepositoryModel CreateRepositoryModel(string cloneUrl = OwnerCloneUrl) return result; } - static IVSGitExt CreateVSGitExt(ILocalRepositoryModel repo) + static ITeamExplorerContext CreateTeamExplorerContext(ILocalRepositoryModel repo) + { + var teamExplorerContext = Substitute.For(); + teamExplorerContext.GetActiveRepository().Returns(repo); + return teamExplorerContext; + } + + static void SetActiveRepository(ITeamExplorerContext teamExplorerContext, ILocalRepositoryModel localRepositoryModel) { - var vsGitExt = Substitute.For(); - var repos = repo != null ? new[] { repo } : new ILocalRepositoryModel[0]; - vsGitExt.ActiveRepositories.Returns(repos); - return vsGitExt; + teamExplorerContext.GetActiveRepository().Returns(localRepositoryModel); + teamExplorerContext.StatusChanged += Raise.Event(); } } } From 71b80458a7662c16f2817e6ad65f52d820889211 Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Fri, 5 Jan 2018 15:17:52 +0000 Subject: [PATCH 3/4] Fire PropertyChanged event when ActiveRepository changes Delegate `ActiveRepository` property to `ITeamExplorerServiceHolder.ActiveRepo`. --- .../Services/TeamExplorerContext.cs | 24 +++++++++---------- .../Services/ITeamExplorerContext.cs | 5 ++-- .../Services/PullRequestSessionManager.cs | 4 ++-- .../PullRequestSessionManagerTests.cs | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/GitHub.App/Services/TeamExplorerContext.cs b/src/GitHub.App/Services/TeamExplorerContext.cs index 55d6aeb1c8..3ef0780330 100644 --- a/src/GitHub.App/Services/TeamExplorerContext.cs +++ b/src/GitHub.App/Services/TeamExplorerContext.cs @@ -10,33 +10,33 @@ namespace GitHub.Services [PartCreationPolicy(CreationPolicy.Shared)] public class TeamExplorerContext : ITeamExplorerContext { - readonly IVSGitExt vsGitExt; readonly ITeamExplorerServiceHolder teamExplorerServiceHolder; + ILocalRepositoryModel activeRepository; + [ImportingConstructor] public TeamExplorerContext(IVSGitExt vsGitExt, ITeamExplorerServiceHolder teamExplorerServiceHolder) { - this.vsGitExt = vsGitExt; this.teamExplorerServiceHolder = teamExplorerServiceHolder; vsGitExt.ActiveRepositoriesChanged += () => { StatusChanged?.Invoke(this, EventArgs.Empty); }; - } - public ILocalRepositoryModel GetActiveRepository() - { - var activeRepository = vsGitExt.ActiveRepositories.FirstOrDefault(); - if (activeRepository == null) + teamExplorerServiceHolder.Subscribe(this, repo => { - // HACK: TeamExplorerServiceHolder does some magic to ensure that ActiveRepositories is aviablable. - activeRepository = teamExplorerServiceHolder.ActiveRepo; - } - - return activeRepository; + if (!Equals(repo, activeRepository)) + { + activeRepository = repo; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ActiveRepository))); + } + }); } + public ILocalRepositoryModel ActiveRepository => teamExplorerServiceHolder.ActiveRepo; + public event EventHandler StatusChanged; + public event PropertyChangedEventHandler PropertyChanged; } } diff --git a/src/GitHub.Exports/Services/ITeamExplorerContext.cs b/src/GitHub.Exports/Services/ITeamExplorerContext.cs index 68abd63081..7429997e81 100644 --- a/src/GitHub.Exports/Services/ITeamExplorerContext.cs +++ b/src/GitHub.Exports/Services/ITeamExplorerContext.cs @@ -1,11 +1,12 @@ using System; +using System.ComponentModel; using GitHub.Models; namespace GitHub.Services { - public interface ITeamExplorerContext + public interface ITeamExplorerContext : INotifyPropertyChanged { - ILocalRepositoryModel GetActiveRepository(); + ILocalRepositoryModel ActiveRepository { get; } event EventHandler StatusChanged; } } diff --git a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs index 0c8e4486e1..04ae698577 100644 --- a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs +++ b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs @@ -66,10 +66,10 @@ public PullRequestSessionManager( this.connectionManager = connectionManager; this.modelServiceFactory = modelServiceFactory; - RepoChanged(teamExplorerContext.GetActiveRepository()).Forget(); + RepoChanged(teamExplorerContext.ActiveRepository).Forget(); teamExplorerContext.StatusChanged += (s, e) => { - RepoChanged(teamExplorerContext.GetActiveRepository()).Forget(); + RepoChanged(teamExplorerContext.ActiveRepository).Forget(); }; } diff --git a/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs b/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs index 40431a0ce6..e31e4acae5 100644 --- a/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs +++ b/test/GitHub.InlineReviews.UnitTests/Services/PullRequestSessionManagerTests.cs @@ -1005,13 +1005,13 @@ ILocalRepositoryModel CreateRepositoryModel(string cloneUrl = OwnerCloneUrl) static ITeamExplorerContext CreateTeamExplorerContext(ILocalRepositoryModel repo) { var teamExplorerContext = Substitute.For(); - teamExplorerContext.GetActiveRepository().Returns(repo); + teamExplorerContext.ActiveRepository.Returns(repo); return teamExplorerContext; } static void SetActiveRepository(ITeamExplorerContext teamExplorerContext, ILocalRepositoryModel localRepositoryModel) { - teamExplorerContext.GetActiveRepository().Returns(localRepositoryModel); + teamExplorerContext.ActiveRepository.Returns(localRepositoryModel); teamExplorerContext.StatusChanged += Raise.Event(); } } From d1fac986eeac97f19bcbb5d3754c70fa399d7348 Mon Sep 17 00:00:00 2001 From: Jamie Cansdale Date: Mon, 8 Jan 2018 11:13:14 +0000 Subject: [PATCH 4/4] Add StatusChanged event to TeamExplorerServiceHolder TeamExplorerContext is now a simple wrapper on top TeamExplorerServiceHolder that exposes events. --- .../Services/TeamExplorerContext.cs | 21 +++++++------------ .../Services/ITeamExplorerServiceHolder.cs | 5 +++++ .../Base/TeamExplorerServiceHolder.cs | 7 +++++++ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/GitHub.App/Services/TeamExplorerContext.cs b/src/GitHub.App/Services/TeamExplorerContext.cs index 3ef0780330..c8aab93df0 100644 --- a/src/GitHub.App/Services/TeamExplorerContext.cs +++ b/src/GitHub.App/Services/TeamExplorerContext.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.ComponentModel; using System.ComponentModel.Composition; using GitHub.Models; @@ -12,26 +11,20 @@ public class TeamExplorerContext : ITeamExplorerContext { readonly ITeamExplorerServiceHolder teamExplorerServiceHolder; - ILocalRepositoryModel activeRepository; - [ImportingConstructor] - public TeamExplorerContext(IVSGitExt vsGitExt, ITeamExplorerServiceHolder teamExplorerServiceHolder) + public TeamExplorerContext(ITeamExplorerServiceHolder teamExplorerServiceHolder) { this.teamExplorerServiceHolder = teamExplorerServiceHolder; - vsGitExt.ActiveRepositoriesChanged += () => - { - StatusChanged?.Invoke(this, EventArgs.Empty); - }; - teamExplorerServiceHolder.Subscribe(this, repo => { - if (!Equals(repo, activeRepository)) - { - activeRepository = repo; - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ActiveRepository))); - } + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ActiveRepository))); }); + + teamExplorerServiceHolder.StatusChanged += (s, e) => + { + StatusChanged?.Invoke(this, e); + }; } public ILocalRepositoryModel ActiveRepository => teamExplorerServiceHolder.ActiveRepo; diff --git a/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs b/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs index ae60d6c8de..515d8af252 100644 --- a/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs +++ b/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs @@ -47,6 +47,11 @@ public interface ITeamExplorerServiceHolder /// Refresh the information on the active repo (in case of remote url changes or other such things) /// void Refresh(); + + /// + /// Fired when the repo or its status changes. + /// + event EventHandler StatusChanged; } public interface IGitAwareItem diff --git a/src/GitHub.TeamFoundation.14/Base/TeamExplorerServiceHolder.cs b/src/GitHub.TeamFoundation.14/Base/TeamExplorerServiceHolder.cs index eb0912372c..1e9976f69f 100644 --- a/src/GitHub.TeamFoundation.14/Base/TeamExplorerServiceHolder.cs +++ b/src/GitHub.TeamFoundation.14/Base/TeamExplorerServiceHolder.cs @@ -197,9 +197,14 @@ async void UIContextChanged(bool active, bool refresh) void UpdateActiveRepo() { var repo = gitService.ActiveRepositories.FirstOrDefault(); + if (!Equals(repo, ActiveRepo)) + { // so annoying that this is on the wrong thread syncContext.Post(r => ActiveRepo = r as ILocalRepositoryModel, repo); + } + + StatusChanged?.Invoke(this, EventArgs.Empty); } void ActiveRepoPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) @@ -269,6 +274,8 @@ IVSUIContextFactory UIContextFactory return uiContextFactory; } } + + public event EventHandler StatusChanged; } [Export(typeof(IVSUIContextFactory))]