diff --git a/src/GitHub.App/GitHub.App.csproj b/src/GitHub.App/GitHub.App.csproj index a9d7ebdbf0..369cf401bf 100644 --- a/src/GitHub.App/GitHub.App.csproj +++ b/src/GitHub.App/GitHub.App.csproj @@ -198,6 +198,8 @@ + + diff --git a/src/GitHub.App/ViewModels/NotAGitHubRepositoryViewModel.cs b/src/GitHub.App/ViewModels/NotAGitHubRepositoryViewModel.cs new file mode 100644 index 0000000000..4f373d5ac7 --- /dev/null +++ b/src/GitHub.App/ViewModels/NotAGitHubRepositoryViewModel.cs @@ -0,0 +1,44 @@ +using System; +using System.ComponentModel.Composition; +using GitHub.Exports; +using GitHub.Models; +using GitHub.Services; +using GitHub.UI; +using ReactiveUI; + +namespace GitHub.ViewModels +{ + /// + /// The view model for the "Not a GitHub repository" view in the GitHub pane. + /// + [ExportViewModel(ViewType = UIViewType.NotAGitHubRepository)] + [PartCreationPolicy(CreationPolicy.NonShared)] + public class NotAGitHubRepositoryViewModel : BaseViewModel, INotAGitHubRepositoryViewModel + { + ITeamExplorerServices teamExplorerServices; + + /// + /// Initializes a new instance of the class. + /// + [ImportingConstructor] + public NotAGitHubRepositoryViewModel(ITeamExplorerServices teamExplorerServices) + { + this.teamExplorerServices = teamExplorerServices; + Publish = ReactiveCommand.Create(); + Publish.Subscribe(_ => OnPublish()); + } + + /// + /// Gets the command executed when the user clicks the "Publish to GitHub" link. + /// + public IReactiveCommand Publish { get; } + + /// + /// Called when the command is executed. + /// + private void OnPublish() + { + teamExplorerServices.ShowPublishSection(); + } + } +} \ No newline at end of file diff --git a/src/GitHub.App/ViewModels/NotAGitRepositoryViewModel.cs b/src/GitHub.App/ViewModels/NotAGitRepositoryViewModel.cs new file mode 100644 index 0000000000..cc63ceb8ba --- /dev/null +++ b/src/GitHub.App/ViewModels/NotAGitRepositoryViewModel.cs @@ -0,0 +1,19 @@ +using System; +using System.ComponentModel.Composition; +using GitHub.Exports; +using GitHub.Models; +using GitHub.Services; +using GitHub.UI; +using ReactiveUI; + +namespace GitHub.ViewModels +{ + /// + /// The view model for the "Not a Git repository" view in the GitHub pane. + /// + [ExportViewModel(ViewType = UIViewType.NotAGitRepository)] + [PartCreationPolicy(CreationPolicy.NonShared)] + public class NotAGitRepositoryViewModel : BaseViewModel, INotAGitRepositoryViewModel + { + } +} \ No newline at end of file diff --git a/src/GitHub.Exports.Reactive/GitHub.Exports.Reactive.csproj b/src/GitHub.Exports.Reactive/GitHub.Exports.Reactive.csproj index 8fd06bd998..3f7d374e3b 100644 --- a/src/GitHub.Exports.Reactive/GitHub.Exports.Reactive.csproj +++ b/src/GitHub.Exports.Reactive/GitHub.Exports.Reactive.csproj @@ -97,6 +97,8 @@ + + diff --git a/src/GitHub.Exports.Reactive/ViewModels/INotAGitHubRepositoryViewModel.cs b/src/GitHub.Exports.Reactive/ViewModels/INotAGitHubRepositoryViewModel.cs new file mode 100644 index 0000000000..2fb562e65f --- /dev/null +++ b/src/GitHub.Exports.Reactive/ViewModels/INotAGitHubRepositoryViewModel.cs @@ -0,0 +1,15 @@ +using ReactiveUI; + +namespace GitHub.ViewModels +{ + /// + /// Defines the view model for the "Sign in to GitHub" view in the GitHub pane. + /// + public interface INotAGitHubRepositoryViewModel : IViewModel + { + /// + /// Gets the command executed when the user clicks the "Publish to GitHub" link. + /// + IReactiveCommand Publish { get; } + } +} \ No newline at end of file diff --git a/src/GitHub.Exports.Reactive/ViewModels/INotAGitRepositoryViewModel.cs b/src/GitHub.Exports.Reactive/ViewModels/INotAGitRepositoryViewModel.cs new file mode 100644 index 0000000000..6ee8569e75 --- /dev/null +++ b/src/GitHub.Exports.Reactive/ViewModels/INotAGitRepositoryViewModel.cs @@ -0,0 +1,10 @@ +namespace GitHub.ViewModels +{ + /// + /// Defines the view model for the "Not a git repository" view in the GitHub pane. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")] + public interface INotAGitRepositoryViewModel : IViewModel + { + } +} \ No newline at end of file diff --git a/src/GitHub.Exports/Exports/ExportMetadata.cs b/src/GitHub.Exports/Exports/ExportMetadata.cs index ac173af9db..b9f6a6026d 100644 --- a/src/GitHub.Exports/Exports/ExportMetadata.cs +++ b/src/GitHub.Exports/Exports/ExportMetadata.cs @@ -25,7 +25,9 @@ public enum UIViewType PRCreation, LogoutRequired, GitHubPane, - LoggedOut + LoggedOut, + NotAGitRepository, + NotAGitHubRepository, } public enum MenuType diff --git a/src/GitHub.Exports/Services/ITeamExplorerServices.cs b/src/GitHub.Exports/Services/ITeamExplorerServices.cs index 7b4b10fc2a..8b5657d309 100644 --- a/src/GitHub.Exports/Services/ITeamExplorerServices.cs +++ b/src/GitHub.Exports/Services/ITeamExplorerServices.cs @@ -4,6 +4,7 @@ namespace GitHub.Services { public interface ITeamExplorerServices : INotificationService { + void ShowPublishSection(); void ClearNotifications(); } } \ No newline at end of file diff --git a/src/GitHub.TeamFoundation.14/Services/TeamExplorerServices.cs b/src/GitHub.TeamFoundation.14/Services/TeamExplorerServices.cs index 04f7cd35a9..51739d75ef 100644 --- a/src/GitHub.TeamFoundation.14/Services/TeamExplorerServices.cs +++ b/src/GitHub.TeamFoundation.14/Services/TeamExplorerServices.cs @@ -1,9 +1,10 @@ using System; using System.ComponentModel.Composition; using System.Windows.Input; +using GitHub.Extensions; +using GitHub.VisualStudio.TeamExplorer.Sync; using Microsoft.TeamFoundation.Controls; using Microsoft.VisualStudio.Shell; -using GitHub.Extensions; namespace GitHub.Services { @@ -27,6 +28,14 @@ public TeamExplorerServices([Import(typeof(SVsServiceProvider))] IServiceProvide this.serviceProvider = serviceProvider; } + public void ShowPublishSection() + { + var te = serviceProvider.TryGetService(); + var foo = te.NavigateToPage(new Guid(TeamExplorerPageIds.GitCommits), null); + var publish = foo?.GetSection(new Guid(GitHubPublishSection.GitHubPublishSectionId)) as GitHubPublishSection; + publish?.ShowPublish(); + } + public void ShowMessage(string message) { manager = serviceProvider.TryGetService() as ITeamExplorerNotificationManager; diff --git a/src/GitHub.TeamFoundation.14/Sync/GitHubPublishSection.cs b/src/GitHub.TeamFoundation.14/Sync/GitHubPublishSection.cs index bc5d7bf0cc..b01b7301dc 100644 --- a/src/GitHub.TeamFoundation.14/Sync/GitHubPublishSection.cs +++ b/src/GitHub.TeamFoundation.14/Sync/GitHubPublishSection.cs @@ -111,7 +111,7 @@ void StartFlow(UIControllerFlow controllerFlow) uiProvider.RunUI(); } - void ShowPublish() + public void ShowPublish() { IsBusy = true; var uiProvider = ServiceProvider.GetExportedValue(); diff --git a/src/GitHub.VisualStudio.UI/Base/TeamExplorerItemBase.cs b/src/GitHub.VisualStudio.UI/Base/TeamExplorerItemBase.cs index a714183c3b..40420fc160 100644 --- a/src/GitHub.VisualStudio.UI/Base/TeamExplorerItemBase.cs +++ b/src/GitHub.VisualStudio.UI/Base/TeamExplorerItemBase.cs @@ -8,6 +8,7 @@ using GitHub.VisualStudio.Helpers; using NullGuard; using GitHub.ViewModels; +using GitHub.VisualStudio.UI; namespace GitHub.VisualStudio.Base { @@ -98,22 +99,41 @@ protected virtual void RepoChanged(bool changed) } } - protected async Task IsAGitHubRepo() + protected async Task GetRepositoryOrigin() { + if (ActiveRepo == null) + return RepositoryOrigin.NonGitRepository; + var uri = ActiveRepoUri; if (uri == null) - return false; + return RepositoryOrigin.Other; Debug.Assert(apiFactory != null, "apiFactory cannot be null. Did you call the right constructor?"); SimpleApiClient = apiFactory.Create(uri); var isdotcom = HostAddress.IsGitHubDotComUri(uri.ToRepositoryUrl()); - if (!isdotcom) + + if (isdotcom) + { + return RepositoryOrigin.DotCom; + } + else { var repo = await SimpleApiClient.GetRepository(); - return (repo.FullName == ActiveRepoName || repo.Id == 0) && SimpleApiClient.IsEnterprise(); + + if ((repo.FullName == ActiveRepoName || repo.Id == 0) && SimpleApiClient.IsEnterprise()) + { + return RepositoryOrigin.Enterprise; + } } - return isdotcom; + + return RepositoryOrigin.Other; + } + + protected async Task IsAGitHubRepo() + { + var origin = await GetRepositoryOrigin(); + return origin == RepositoryOrigin.DotCom || origin == RepositoryOrigin.Enterprise; } bool disposed; diff --git a/src/GitHub.VisualStudio.UI/GitHub.VisualStudio.UI.csproj b/src/GitHub.VisualStudio.UI/GitHub.VisualStudio.UI.csproj index 55c66e86b9..04ec2d04eb 100644 --- a/src/GitHub.VisualStudio.UI/GitHub.VisualStudio.UI.csproj +++ b/src/GitHub.VisualStudio.UI/GitHub.VisualStudio.UI.csproj @@ -79,6 +79,7 @@ + Resources.resx True diff --git a/src/GitHub.VisualStudio.UI/RepositoryOrigin.cs b/src/GitHub.VisualStudio.UI/RepositoryOrigin.cs new file mode 100644 index 0000000000..0cec4559a9 --- /dev/null +++ b/src/GitHub.VisualStudio.UI/RepositoryOrigin.cs @@ -0,0 +1,11 @@ +namespace GitHub.VisualStudio.UI +{ + public enum RepositoryOrigin + { + Unknown, + DotCom, + Enterprise, + Other, + NonGitRepository, + } +} diff --git a/src/GitHub.VisualStudio.UI/Resources.Designer.cs b/src/GitHub.VisualStudio.UI/Resources.Designer.cs index 5babff65d7..8533c6bc63 100644 --- a/src/GitHub.VisualStudio.UI/Resources.Designer.cs +++ b/src/GitHub.VisualStudio.UI/Resources.Designer.cs @@ -438,6 +438,42 @@ public static string noRepositoriesMessageText { } } + /// + /// Looks up a localized string similar to This repository is not on GitHub. + /// + public static string NotAGitHubRepository { + get { + return ResourceManager.GetString("NotAGitHubRepository", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Publish this repository to GitHub and get powerful collaboration, code review, and code management for open source and private projects.. + /// + public static string NotAGitHubRepositoryMessage { + get { + return ResourceManager.GetString("NotAGitHubRepositoryMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No repository. + /// + public static string NotAGitRepository { + get { + return ResourceManager.GetString("NotAGitRepository", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to We couldn't find a git repository here. Open a git project or click "File -> Add to Source Control" in a project to get started.. + /// + public static string NotAGitRepositoryMessage { + get { + return ResourceManager.GetString("NotAGitRepositoryMessage", resourceCulture); + } + } + /// /// Looks up a localized string similar to You are not logged in to {0}, so certain git operations may fail. [Login now]({1}). /// diff --git a/src/GitHub.VisualStudio.UI/Resources.resx b/src/GitHub.VisualStudio.UI/Resources.resx index 7345b76214..ab68d55312 100644 --- a/src/GitHub.VisualStudio.UI/Resources.resx +++ b/src/GitHub.VisualStudio.UI/Resources.resx @@ -315,4 +315,16 @@ Open in Browser + + Publish this repository to GitHub and get powerful collaboration, code review, and code management for open source and private projects. + + + This repository is not on GitHub + + + No repository + + + We couldn't find a git repository here. Open a git project or click "File -> Add to Source Control" in a project to get started. + \ No newline at end of file diff --git a/src/GitHub.VisualStudio/GitHub.VisualStudio.csproj b/src/GitHub.VisualStudio/GitHub.VisualStudio.csproj index 76dd288836..6e04327db6 100644 --- a/src/GitHub.VisualStudio/GitHub.VisualStudio.csproj +++ b/src/GitHub.VisualStudio/GitHub.VisualStudio.csproj @@ -274,6 +274,12 @@ GitHubPaneView.xaml + + NotAGitRepositoryView.xaml + + + NotAGitHubRepositoryView.xaml + LoggedOutView.xaml @@ -469,6 +475,14 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/src/GitHub.VisualStudio/UI/Views/GitHubPaneViewModel.cs b/src/GitHub.VisualStudio/UI/Views/GitHubPaneViewModel.cs index 8707d8cfb7..d09cb43439 100644 --- a/src/GitHub.VisualStudio/UI/Views/GitHubPaneViewModel.cs +++ b/src/GitHub.VisualStudio/UI/Views/GitHubPaneViewModel.cs @@ -19,6 +19,7 @@ using ReactiveUI; using System.Collections.Generic; using System.Threading.Tasks; +using GitHub.VisualStudio.UI; namespace GitHub.VisualStudio.UI.Views { @@ -109,7 +110,7 @@ protected override void RepoChanged(bool changed) return; Stop(); - IsGitHubRepo = null; + RepositoryOrigin = RepositoryOrigin.Unknown; Reload().Forget(); } @@ -129,13 +130,13 @@ async Task Reload([AllowNull] ViewWithData data = null, bool navigating = false) navigatingViaArrows = navigating; - if (!IsGitHubRepo.HasValue) + if (RepositoryOrigin == RepositoryOrigin.Unknown) { - var isGitHubRepo = await IsAGitHubRepo(); + var origin = await GetRepositoryOrigin(); if (reloadCallId != latestReloadCallId) return; - IsGitHubRepo = isGitHubRepo; + RepositoryOrigin = origin; } var connection = await connectionManager.LookupConnection(ActiveRepo); @@ -153,16 +154,18 @@ async Task Reload([AllowNull] ViewWithData data = null, bool navigating = false) IsLoggedIn = isLoggedIn; } - if (!IsGitHubRepo.Value) + if (RepositoryOrigin == UI.RepositoryOrigin.NonGitRepository) { - //LoadView(UIViewType.NotAGitHubRepo); + LoadView(UIViewType.NotAGitRepository); + } + else if (RepositoryOrigin == UI.RepositoryOrigin.Other) + { + LoadView(UIViewType.NotAGitHubRepository); } - else if (!IsLoggedIn) { LoadView(UIViewType.LoggedOut); } - else { LoadView(data?.ActiveFlow ?? DefaultControllerFlow, connection, data); @@ -337,13 +340,23 @@ public bool IsLoggedIn set { isLoggedIn = value; this.RaisePropertyChange(); } } - bool? isGitHubRepo; - public bool? IsGitHubRepo + RepositoryOrigin repositoryOrigin; + public RepositoryOrigin RepositoryOrigin { - get { return isGitHubRepo; } - set { isGitHubRepo = value; this.RaisePropertyChange(); } + get { return repositoryOrigin; } + private set { repositoryOrigin = value; } } + public bool? IsGitHubRepo + { + get + { + return repositoryOrigin == RepositoryOrigin.Unknown ? + (bool?)null : + repositoryOrigin == UI.RepositoryOrigin.DotCom || + repositoryOrigin == UI.RepositoryOrigin.Enterprise; + } + } public ReactiveCommand CancelCommand { get; private set; } public ICommand Cancel => CancelCommand; diff --git a/src/GitHub.VisualStudio/UI/Views/NotAGitHubRepositoryView.xaml b/src/GitHub.VisualStudio/UI/Views/NotAGitHubRepositoryView.xaml new file mode 100644 index 0000000000..75adf90bc9 --- /dev/null +++ b/src/GitHub.VisualStudio/UI/Views/NotAGitHubRepositoryView.xaml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/GitHub.VisualStudio/UI/Views/NotAGitHubRepositoryView.xaml.cs b/src/GitHub.VisualStudio/UI/Views/NotAGitHubRepositoryView.xaml.cs new file mode 100644 index 0000000000..546aa29cd0 --- /dev/null +++ b/src/GitHub.VisualStudio/UI/Views/NotAGitHubRepositoryView.xaml.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.Composition; +using GitHub.Exports; +using GitHub.UI; +using GitHub.ViewModels; + +namespace GitHub.VisualStudio.UI.Views +{ + public class GenericNotAGitHubRepositoryView : SimpleViewUserControl + { + } + + [ExportView(ViewType = UIViewType.NotAGitHubRepository)] + [PartCreationPolicy(CreationPolicy.NonShared)] + + public partial class NotAGitHubRepositoryView : GenericNotAGitHubRepositoryView + { + public NotAGitHubRepositoryView() + { + this.InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/src/GitHub.VisualStudio/UI/Views/NotAGitRepositoryView.xaml b/src/GitHub.VisualStudio/UI/Views/NotAGitRepositoryView.xaml new file mode 100644 index 0000000000..ade340132c --- /dev/null +++ b/src/GitHub.VisualStudio/UI/Views/NotAGitRepositoryView.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/GitHub.VisualStudio/UI/Views/NotAGitRepositoryView.xaml.cs b/src/GitHub.VisualStudio/UI/Views/NotAGitRepositoryView.xaml.cs new file mode 100644 index 0000000000..0d6ffb2a6a --- /dev/null +++ b/src/GitHub.VisualStudio/UI/Views/NotAGitRepositoryView.xaml.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.Composition; +using GitHub.Exports; +using GitHub.UI; +using GitHub.ViewModels; + +namespace GitHub.VisualStudio.UI.Views +{ + public class GenericNotAGitRepositoryView : SimpleViewUserControl + { + } + + [ExportView(ViewType = UIViewType.NotAGitRepository)] + [PartCreationPolicy(CreationPolicy.NonShared)] + + public partial class NotAGitRepositoryView : GenericNotAGitRepositoryView + { + public NotAGitRepositoryView() + { + this.InitializeComponent(); + } + } +} \ No newline at end of file