зеркало из https://github.com/github/VisualStudio.git
wip: new Start Page, async loading, P5 support
This commit is contained in:
Родитель
6d642a4ba1
Коммит
b40d85c707
|
@ -239,4 +239,3 @@ WiX.Toolset.DummyFile.txt
|
|||
nunit-UnitTests.xml
|
||||
nunit-TrackingCollectionTests.xml
|
||||
GitHubVS.sln.DotSettings
|
||||
**/generated/*.cs
|
||||
|
|
44
GitHubVS.sln
44
GitHubVS.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.25807.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.VisualStudio", "src\GitHub.VisualStudio\GitHub.VisualStudio.csproj", "{11569514-5AE5-4B5B-92A2-F10B0967DE5F}"
|
||||
EndProject
|
||||
|
@ -107,6 +107,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.TeamFoundation.15",
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.VisualStudio.UI", "src\GitHub.VisualStudio.UI\GitHub.VisualStudio.UI.csproj", "{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Subpackages", "Subpackages", "{7F25BDD5-474F-4EC1-A624-ED946B91F34E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.StartPage.Preview5", "submodules\externalpackages\StartPage\preview5\GitHub.StartPage.Preview5.csproj", "{1BC94B6A-B021-4207-A70E-936EE272AD3E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.StartPage.Preview4", "submodules\externalpackages\StartPage\preview4\GitHub.StartPage.Preview4.csproj", "{1BC94B6A-B021-4207-A70E-936EE272AD3D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -542,6 +548,38 @@ Global
|
|||
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|x86.ActiveCfg = Release|Any CPU
|
||||
{D1DFBB0C-B570-4302-8F1E-2E3A19C41961}.XamlDesign|x86.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Publish|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Publish|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Publish|x86.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Publish|x86.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.XamlDesign|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.XamlDesign|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.XamlDesign|x86.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E}.XamlDesign|x86.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Publish|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Publish|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Publish|x86.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Publish|x86.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.XamlDesign|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.XamlDesign|Any CPU.Build.0 = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.XamlDesign|x86.ActiveCfg = Release|Any CPU
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D}.XamlDesign|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -566,5 +604,7 @@ Global
|
|||
{0EC8DBA1-D745-4EE5-993A-6026440EC3BF} = {1E7F7253-A6AF-43C4-A955-37BEDDA01AF9}
|
||||
{DD99FD0F-82F6-4C30-930E-4A1D0DF01D65} = {1E7F7253-A6AF-43C4-A955-37BEDDA01AB9}
|
||||
{7B835A7D-CF94-45E8-B191-96F5A4FE26A8} = {8A7DA2E7-262B-4581-807A-1C45CE79CDFD}
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3E} = {7F25BDD5-474F-4EC1-A624-ED946B91F34E}
|
||||
{1BC94B6A-B021-4207-A70E-936EE272AD3D} = {7F25BDD5-474F-4EC1-A624-ED946B91F34E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace DesignTimeStyleHelper
|
|||
|
||||
void ShowDialog(UIControllerFlow flow)
|
||||
{
|
||||
var ui = App.ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
var ui = App.ServiceProvider.GetService<IUIProvider>();
|
||||
|
||||
var factory = ui.GetService<IExportFactoryProvider>();
|
||||
var d = factory.UIControllerFactory.CreateExport();
|
||||
|
|
|
@ -53,7 +53,46 @@ namespace GitHub.ViewModels
|
|||
IUsageTracker usageTracker)
|
||||
: this(connectionRepositoryHostMap.CurrentRepositoryHost, repositoryCloneService, operatingSystem, notificationService, usageTracker)
|
||||
{ }
|
||||
|
||||
|
||||
public RepositoryCloneViewModel(
|
||||
IRepositoryHost repositoryHost,
|
||||
IRepositoryModel repositoryToClone,
|
||||
IRepositoryCloneService cloneService,
|
||||
IOperatingSystem operatingSystem,
|
||||
INotificationService notificationService,
|
||||
IUsageTracker usageTracker)
|
||||
{
|
||||
this.repositoryHost = repositoryHost;
|
||||
this.cloneService = cloneService;
|
||||
this.operatingSystem = operatingSystem;
|
||||
this.notificationService = notificationService;
|
||||
this.usageTracker = usageTracker;
|
||||
this.SelectedRepository = repositoryToClone;
|
||||
|
||||
Title = string.Format(CultureInfo.CurrentCulture, Resources.CloneTitle, repositoryHost.Title);
|
||||
|
||||
var baseRepositoryPath = this.WhenAnyValue(x => x.BaseRepositoryPath);
|
||||
|
||||
BaseRepositoryPathValidator = ReactivePropertyValidator.ForObservable(baseRepositoryPath)
|
||||
.IfNullOrEmpty(Resources.RepositoryCreationClonePathEmpty)
|
||||
.IfTrue(x => x.Length > 200, Resources.RepositoryCreationClonePathTooLong)
|
||||
.IfContainsInvalidPathChars(Resources.RepositoryCreationClonePathInvalidCharacters)
|
||||
.IfPathNotRooted(Resources.RepositoryCreationClonePathInvalid)
|
||||
.IfTrue(IsAlreadyRepoAtPath, Resources.RepositoryNameValidatorAlreadyExists);
|
||||
|
||||
var canCloneObservable = this.WhenAny(
|
||||
x => x.SelectedRepository,
|
||||
x => x.BaseRepositoryPathValidator.ValidationResult.IsValid,
|
||||
(x, y) => x.Value != null && y.Value);
|
||||
canClone = canCloneObservable.ToProperty(this, x => x.CanClone);
|
||||
CloneCommand = ReactiveCommand.CreateAsyncObservable(canCloneObservable, OnCloneRepository);
|
||||
|
||||
browseForDirectoryCommand.Subscribe(_ => ShowBrowseForDirectoryDialog());
|
||||
this.WhenAny(x => x.BaseRepositoryPathValidator.ValidationResult, x => x.Value)
|
||||
.Subscribe();
|
||||
BaseRepositoryPath = cloneService.DefaultClonePath;
|
||||
}
|
||||
|
||||
public RepositoryCloneViewModel(
|
||||
IRepositoryHost repositoryHost,
|
||||
IRepositoryCloneService cloneService,
|
||||
|
|
|
@ -9,8 +9,6 @@ namespace GitHub.Extensions
|
|||
{
|
||||
public static class IServiceProviderExtensions
|
||||
{
|
||||
static IUIProvider cachedUIProvider = null;
|
||||
|
||||
/// <summary>
|
||||
/// Safe variant of GetService that doesn't throw exceptions if the service is
|
||||
/// not found.
|
||||
|
@ -18,13 +16,21 @@ namespace GitHub.Extensions
|
|||
/// <returns>The service, or null if not found</returns>
|
||||
public static object TryGetService(this IServiceProvider serviceProvider, Type type)
|
||||
{
|
||||
if (cachedUIProvider != null && type == typeof(IUIProvider))
|
||||
return cachedUIProvider;
|
||||
|
||||
var ui = serviceProvider as IUIProvider;
|
||||
return ui != null
|
||||
? ui.TryGetService(type)
|
||||
: GetServiceAndCache(serviceProvider, type, ref cachedUIProvider);
|
||||
if (ui != null)
|
||||
return ui.TryGetService(type);
|
||||
|
||||
object ret = null;
|
||||
try
|
||||
{
|
||||
ret = serviceProvider.GetService(type);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Print(ex.ToString());
|
||||
VisualStudio.VsOutputLogger.WriteLine("GetServiceAndCache: Could not obtain instance of '{0}'", type);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -42,13 +48,10 @@ namespace GitHub.Extensions
|
|||
}
|
||||
public static T GetExportedValue<T>(this IServiceProvider serviceProvider) where T : class
|
||||
{
|
||||
if (cachedUIProvider != null && typeof(T) == typeof(IUIProvider))
|
||||
return (T)cachedUIProvider;
|
||||
|
||||
var ui = serviceProvider as IUIProvider;
|
||||
return ui != null
|
||||
? ui.TryGetService(typeof(T)) as T
|
||||
: GetExportedValueAndCache<T, IUIProvider>(ref cachedUIProvider);
|
||||
: VisualStudio.Services.ComponentModel.DefaultExportProvider.GetExportedValueOrDefault<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -71,31 +74,6 @@ namespace GitHub.Extensions
|
|||
return serviceProvider.TryGetService(typeof(T)) as T;
|
||||
}
|
||||
|
||||
static object GetServiceAndCache<CacheType>(IServiceProvider provider, Type type, ref CacheType cache)
|
||||
{
|
||||
object ret = null;
|
||||
try
|
||||
{
|
||||
ret = provider.GetService(type);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Print(ex.ToString());
|
||||
VisualStudio.VsOutputLogger.WriteLine("GetServiceAndCache: Could not obtain instance of '{0}'", type);
|
||||
}
|
||||
if (ret != null && type == typeof(CacheType))
|
||||
cache = (CacheType)ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static T GetExportedValueAndCache<T, CacheType>(ref CacheType cache) where T : class
|
||||
{
|
||||
object ret = VisualStudio.Services.ComponentModel.DefaultExportProvider.GetExportedValueOrDefault<T>();
|
||||
if (ret != null && typeof(T) == typeof(CacheType))
|
||||
cache = (CacheType)ret;
|
||||
return ret as T;
|
||||
}
|
||||
|
||||
public static void AddCommandHandler(this IServiceProvider provider,
|
||||
Guid guid,
|
||||
int cmdId,
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace GitHub.VisualStudio
|
|||
/// Container for static and dynamic visibility menus (context, toolbar, top, etc)
|
||||
/// Get a reference to this via MEF and register the menus
|
||||
/// </summary>
|
||||
[Guid(Guids.MenuProviderId)]
|
||||
[Guid("76904E1A-9D58-41AB-8957-C23B9F50727B")]
|
||||
public interface IMenuProvider
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// This is an automatically generated file, based on settings.json and PackageSettingsGen.tt
|
||||
/* settings.json content:
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"name": "CollectMetrics",
|
||||
"type": "bool",
|
||||
"default": 'true'
|
||||
},
|
||||
{
|
||||
"name": "UIState",
|
||||
"type": "object",
|
||||
"typename": "UIState",
|
||||
"default": 'null'
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace GitHub.Settings
|
||||
{
|
||||
public interface IPackageSettings : INotifyPropertyChanged
|
||||
{
|
||||
void Save();
|
||||
bool CollectMetrics { get; set; }
|
||||
UIState UIState { get; set; }
|
||||
}
|
||||
}
|
|
@ -20,6 +20,21 @@ namespace GitHub.Extensions
|
|||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
[return: AllowNull]
|
||||
public static async Task Catch(this Task source, Action<Exception> handler = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await source;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (handler != null)
|
||||
handler(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Forget(this Task task)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace GitHub.VisualStudio.TeamExplorer.Sync
|
|||
|
||||
void StartFlow(UIControllerFlow controllerFlow)
|
||||
{
|
||||
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
var uiProvider = ServiceProvider.GetService<IUIProvider>();
|
||||
var ret = uiProvider.SetupUI(controllerFlow, null);
|
||||
ret.Subscribe(c => { }, () => CheckLogin().Forget());
|
||||
uiProvider.RunUI();
|
||||
|
|
|
@ -342,7 +342,7 @@ namespace GitHub.VisualStudio.TeamExplorer.Connect
|
|||
var teServices = ServiceProvider.GetExportedValue<ITeamExplorerServices>();
|
||||
notifications.AddListener(teServices);
|
||||
|
||||
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
var uiProvider = ServiceProvider.GetService<IUIProvider>();
|
||||
uiProvider.GitServiceProvider = ServiceProvider;
|
||||
uiProvider.SetupUI(controllerFlow, SectionConnection);
|
||||
uiProvider.ListenToCompletionState()
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace GitHub.VisualStudio.TeamExplorer.Connect
|
|||
|
||||
void StartFlow(UIControllerFlow controllerFlow)
|
||||
{
|
||||
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
var uiProvider = ServiceProvider.GetService<IUIProvider>();
|
||||
uiProvider.RunUI(controllerFlow, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace GitHub.VisualStudio.TeamExplorer.Sync
|
|||
|
||||
void StartFlow(UIControllerFlow controllerFlow)
|
||||
{
|
||||
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
var uiProvider = ServiceProvider.GetService<IUIProvider>();
|
||||
var ret = uiProvider.SetupUI(controllerFlow, null);
|
||||
ret.Subscribe((c) => { }, async () =>
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ namespace GitHub.VisualStudio.TeamExplorer.Sync
|
|||
public void ShowPublish()
|
||||
{
|
||||
IsBusy = true;
|
||||
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
var uiProvider = ServiceProvider.GetService<IUIProvider>();
|
||||
var factory = uiProvider.GetService<IExportFactoryProvider>();
|
||||
var uiflow = factory.UIControllerFactory.CreateExport();
|
||||
disposable = uiflow;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<BuildType Condition="Exists('..\..\script\src\ApiClientConfiguration.cs')">Internal</BuildType>
|
||||
<ApplicationVersion>2.0.15.2</ApplicationVersion>
|
||||
<OutputPath>..\..\build\$(Configuration)\</OutputPath>
|
||||
<GenerateVsixV3>true</GenerateVsixV3>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
|
@ -276,7 +277,7 @@
|
|||
<Compile Include="..\common\SolutionInfo.cs">
|
||||
<Link>Properties\SolutionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Base\MenuBase.cs" />
|
||||
<Compile Include="Menus\MenuBase.cs" />
|
||||
<Compile Include="Menus\CreateGist.cs" />
|
||||
<Compile Include="Helpers\SharedDictionaryManager.cs" />
|
||||
<Compile Include="Helpers\ActiveDocumentSnapshot.cs" />
|
||||
|
@ -659,18 +660,33 @@
|
|||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$(Buildtype) == 'Internal'">
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\build\GitHub.StartPage.pkgdef">
|
||||
<Link>GitHub.StartPage.pkgdef</Link>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\preview4\build\GitHub.StartPage.Preview4.pkgdef">
|
||||
<Link>GitHub.StartPage.Preview4.pkgdef</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\build\GitHub.StartPage.dll">
|
||||
<Link>GitHub.StartPage.dll</Link>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\preview4\build\GitHub.StartPage.Preview4.dll">
|
||||
<Link>GitHub.StartPage.Preview4.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\build\GitHub.StartPage.pdb">
|
||||
<Link>GitHub.StartPage.pdb</Link>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\preview4\build\GitHub.StartPage.Preview4.pdb">
|
||||
<Link>GitHub.StartPage.Preview4.pdb</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\preview5\build\GitHub.StartPage.Preview5.pkgdef">
|
||||
<Link>GitHub.StartPage.Preview5.pkgdef</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\preview5\build\GitHub.StartPage.Preview5.dll">
|
||||
<Link>GitHub.StartPage.Preview5.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
<Content Include="..\..\submodules\externalpackages\StartPage\preview5\build\GitHub.StartPage.Preview5.pdb">
|
||||
<Link>GitHub.StartPage.Preview5.pdb</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
|
|
|
@ -215,6 +215,10 @@
|
|||
</CommandPlacement>
|
||||
|
||||
</CommandPlacements>
|
||||
|
||||
<VisibilityConstraints>
|
||||
<VisibilityItem guid="guidContextMenuSet" id="idGitHubContextMenuGroup" context="guidMenuLoadingContext"/>
|
||||
</VisibilityConstraints>
|
||||
|
||||
<Symbols>
|
||||
<!-- This is the package guid. -->
|
||||
|
@ -262,6 +266,8 @@
|
|||
<IDSymbol name="idCreateGistCommand" value="0x0400" />
|
||||
</GuidSymbol>
|
||||
|
||||
<GuidSymbol name="guidMenuLoadingContext" value="{F2CC8C27-AF24-4BA6-80BC-4819A0E8844F}" />
|
||||
|
||||
<GuidSymbol name="GUID_XAML_EDITOR" value="{4C87B692-1202-46AA-B64C-EF01FAEC53DA}">
|
||||
<IDSymbol name="ID_XAML_CTXT" value="259"/>
|
||||
</GuidSymbol>
|
||||
|
|
|
@ -10,15 +10,17 @@ using Microsoft.VisualStudio.Shell;
|
|||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Octokit;
|
||||
using GitHub.Helpers;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using tasks = System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
using Microsoft.VisualStudio.ComponentModelHost;
|
||||
using GitHub.VisualStudio.Menus;
|
||||
|
||||
namespace GitHub.VisualStudio
|
||||
{
|
||||
[PackageRegistration(UseManagedResourcesOnly = true)]
|
||||
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
|
||||
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
|
||||
[Guid(GuidList.guidGitHubPkgString)]
|
||||
[ProvideMenuResource("Menus.ctmenu", 1)]
|
||||
|
@ -29,6 +31,7 @@ namespace GitHub.VisualStudio
|
|||
public class GitHubPackage : AsyncPackage
|
||||
{
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
readonly IServiceProvider serviceProvider;
|
||||
|
||||
static GitHubPackage()
|
||||
|
@ -46,10 +49,12 @@ namespace GitHub.VisualStudio
|
|||
this.serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
protected override async tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
|
||||
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
|
||||
{
|
||||
var usageTracker = await GetServiceAsync(typeof(IUsageTracker)) as IUsageTracker;
|
||||
await tasks.Task.Run(() => usageTracker.IncrementLaunchCount());
|
||||
await base.InitializeAsync(cancellationToken, progress);
|
||||
|
||||
//var usageTracker = await GetServiceAsync(typeof(IUsageTracker)) as IUsageTracker;
|
||||
//usageTracker.IncrementLaunchCount();
|
||||
var menus = await GetServiceAsync(typeof(IMenuProvider)) as IMenuProvider;
|
||||
|
||||
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
||||
|
@ -59,8 +64,6 @@ namespace GitHub.VisualStudio
|
|||
|
||||
foreach (var menu in menus.DynamicMenus)
|
||||
serviceProvider.AddCommandHandler(menu.Guid, menu.CmdId, menu.CanShow, () => menu.Activate());
|
||||
|
||||
await base.InitializeAsync(cancellationToken, progress);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,10 +78,32 @@ namespace GitHub.VisualStudio
|
|||
}
|
||||
}
|
||||
|
||||
//[NullGuard.NullGuard(NullGuard.ValidationFlags.None)]
|
||||
//[PackageRegistration(UseManagedResourcesOnly = true)]
|
||||
//[ProvideAutoLoad(MenuLoadingContextId)]
|
||||
//[ProvideUIContextRule(MenuLoadingContextId,
|
||||
// name: "GitHub context menus",
|
||||
// expression: "FileOpen",
|
||||
// termNames: new[] { "FileOpen" },
|
||||
// termValues: new[] { "ActiveEditorContentType:CSharp" }
|
||||
//)]
|
||||
//[Guid(MenuRegistrationPackageId)]
|
||||
//public sealed class MenuRegistrationPackage : Package
|
||||
//{
|
||||
// const string MenuRegistrationPackageId = "E37D3B17-2255-4144-9802-349530796693";
|
||||
// const string MenuLoadingContextId = "F2CC8C27-AF24-4BA6-80BC-4819A0E8844F";
|
||||
|
||||
// protected override void Initialize()
|
||||
// {
|
||||
// base.Initialize();
|
||||
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
[NullGuard.NullGuard(NullGuard.ValidationFlags.None)]
|
||||
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
|
||||
[ProvideService(typeof(IUIProvider), IsAsyncQueryable = true)]
|
||||
[ProvideService(typeof(IMenuProvider), IsAsyncQueryable = true)]
|
||||
[ProvideService(typeof(IUsageTracker), IsAsyncQueryable = true)]
|
||||
[ProvideAutoLoad(UIContextGuids.NoSolution)]
|
||||
[ProvideAutoLoad(UIContextGuids.SolutionExists)]
|
||||
|
@ -87,6 +112,7 @@ namespace GitHub.VisualStudio
|
|||
{
|
||||
const string ServiceProviderPackageId = "D5CE1488-DEDE-426D-9E5B-BFCCFBE33E53";
|
||||
const string StartPagePreview4PackageId = "3b764d23-faf7-486f-94c7-b3accc44a70d";
|
||||
const string StartPagePreview5PackageId = "3b764d23-faf7-486f-94c7-b3accc44a70e";
|
||||
|
||||
Version vsversion;
|
||||
Version VSVersion
|
||||
|
@ -113,33 +139,57 @@ namespace GitHub.VisualStudio
|
|||
}
|
||||
}
|
||||
|
||||
protected override async tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
|
||||
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
|
||||
{
|
||||
AddService(typeof(IUIProvider), CreateService, true);
|
||||
AddService(typeof(IMenuProvider), CreateService, true);
|
||||
AddService(typeof(IUsageTracker), CreateService, true);
|
||||
AddService(typeof(IMenuProvider), CreateService, true);
|
||||
|
||||
// Load the start page package only for Dev15 Preview 4
|
||||
if (VSVersion.Major == 15 && VSVersion.Build == 25618)
|
||||
if (VSVersion.Major == 15)
|
||||
{
|
||||
var shell = await GetServiceAsync(typeof(SVsShell)) as IVsShell;
|
||||
IVsPackage startPagePackage;
|
||||
if (ErrorHandler.Failed(shell?.LoadPackage(new Guid(StartPagePreview4PackageId), out startPagePackage) ?? -1))
|
||||
// Load the start page package only for Dev15 Preview 4
|
||||
if (VSVersion.Build == 25618)
|
||||
{
|
||||
// ¯\_(ツ)_/¯
|
||||
var shell = await GetServiceAsync(typeof(SVsShell)) as IVsShell;
|
||||
IVsPackage startPagePackage;
|
||||
if (ErrorHandler.Failed(shell?.LoadPackage(new Guid(StartPagePreview4PackageId), out startPagePackage) ?? -1))
|
||||
{
|
||||
// ¯\_(ツ)_/¯
|
||||
}
|
||||
}
|
||||
// Load the start page package only for Dev15 Preview 5
|
||||
else if (VSVersion.Build == 25807)
|
||||
{
|
||||
var shell = await GetServiceAsync(typeof(SVsShell)) as IVsShell;
|
||||
IVsPackage startPagePackage;
|
||||
if (ErrorHandler.Failed(shell?.LoadPackage(new Guid(StartPagePreview5PackageId), out startPagePackage) ?? -1))
|
||||
{
|
||||
// ¯\_(ツ)_/¯
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async tasks.Task<object> CreateService(IAsyncServiceContainer container, CancellationToken cancellationToken, Type serviceType)
|
||||
async Task<object> CreateService(IAsyncServiceContainer container, CancellationToken cancellationToken, Type serviceType)
|
||||
{
|
||||
if (serviceType == null)
|
||||
return null;
|
||||
string contract = AttributedModelServices.GetContractName(serviceType);
|
||||
var cm = await GetServiceAsync(typeof(SComponentModel)) as IComponentModel;
|
||||
if (cm == null)
|
||||
return null;
|
||||
return await tasks.Task.Run(() => cm.DefaultExportProvider.GetExportedValueOrDefault<object>(contract));
|
||||
|
||||
if (serviceType == typeof(IUIProvider))
|
||||
{
|
||||
return new UIProvider(this);
|
||||
}
|
||||
else if (serviceType == typeof(IMenuProvider))
|
||||
{
|
||||
var sp = await GetServiceAsync(typeof(IUIProvider)) as IUIProvider;
|
||||
return new MenuProvider(sp);
|
||||
}
|
||||
// go the mef route
|
||||
else
|
||||
{
|
||||
var sp = await GetServiceAsync(typeof(IUIProvider)) as IUIProvider;
|
||||
return sp.TryGetService(serviceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
using Microsoft.VisualStudio.Shell;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using GitHub.Services;
|
||||
using GitHub.Services;
|
||||
using GitHub.UI;
|
||||
using GitHub.Extensions;
|
||||
using NullGuard;
|
||||
using GitHub.Api;
|
||||
using System;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
[Export(typeof(IMenuHandler))]
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class AddConnection: MenuBase, IMenuHandler
|
||||
{
|
||||
[ImportingConstructor]
|
||||
public AddConnection([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider, ISimpleApiClientFactory apiFactory)
|
||||
: base(serviceProvider, apiFactory)
|
||||
public AddConnection(IUIProvider serviceProvider)
|
||||
: base(serviceProvider)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,17 @@
|
|||
using Microsoft.VisualStudio.Shell;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Windows;
|
||||
using GitHub.Extensions;
|
||||
using GitHub.Services;
|
||||
using GitHub.Services;
|
||||
using GitHub.VisualStudio.UI;
|
||||
using NullGuard;
|
||||
using GitHub.Api;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
[Export(typeof(IDynamicMenuHandler))]
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class CopyLink : LinkMenuBase, IDynamicMenuHandler
|
||||
{
|
||||
readonly IUsageTracker usageTracker;
|
||||
|
||||
[ImportingConstructor]
|
||||
public CopyLink([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
|
||||
IUsageTracker usageTracker, ISimpleApiClientFactory apiFactory)
|
||||
: base(serviceProvider, apiFactory)
|
||||
public CopyLink(IUIProvider serviceProvider)
|
||||
: base(serviceProvider)
|
||||
{
|
||||
this.usageTracker = usageTracker;
|
||||
}
|
||||
|
||||
public Guid Guid => GuidList.guidContextMenuSet;
|
||||
|
@ -39,13 +29,13 @@ namespace GitHub.VisualStudio.Menus
|
|||
try
|
||||
{
|
||||
Clipboard.SetText(link);
|
||||
var ns = ServiceProvider.GetExportedValue<IStatusBarNotificationService>();
|
||||
var ns = ServiceProvider.TryGetService<IStatusBarNotificationService>();
|
||||
ns?.ShowMessage(Resources.LinkCopiedToClipboardMessage);
|
||||
this.usageTracker.IncrementLinkToGitHubCount();
|
||||
UsageTracker.IncrementLinkToGitHubCount();
|
||||
}
|
||||
catch
|
||||
{
|
||||
var ns = ServiceProvider.GetExportedValue<IStatusBarNotificationService>();
|
||||
var ns = ServiceProvider.TryGetService<IStatusBarNotificationService>();
|
||||
ns?.ShowMessage(Resources.Error_FailedToCopyToClipboard);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,20 @@
|
|||
using Microsoft.VisualStudio.Shell;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using GitHub.Services;
|
||||
using GitHub.Services;
|
||||
using GitHub.UI;
|
||||
using GitHub.Extensions;
|
||||
using System.Diagnostics;
|
||||
using NullGuard;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
[Export(typeof(IDynamicMenuHandler))]
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class CreateGist : MenuBase, IDynamicMenuHandler
|
||||
{
|
||||
readonly Lazy<ISelectedTextProvider> selectedTextProvider;
|
||||
ISelectedTextProvider SelectedTextProvider => selectedTextProvider.Value;
|
||||
|
||||
[ImportingConstructor]
|
||||
public CreateGist([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
|
||||
Lazy<ISelectedTextProvider> selectedTextProvider)
|
||||
public CreateGist(IUIProvider serviceProvider)
|
||||
: base(serviceProvider)
|
||||
{
|
||||
this.selectedTextProvider = selectedTextProvider;
|
||||
selectedTextProvider = new Lazy<ISelectedTextProvider>(() => ServiceProvider.TryGetService<ISelectedTextProvider>());
|
||||
}
|
||||
|
||||
public Guid Guid { get { return GuidList.guidContextMenuSet; } }
|
||||
|
@ -28,9 +22,8 @@ namespace GitHub.VisualStudio.Menus
|
|||
|
||||
public bool CanShow()
|
||||
{
|
||||
var stp = selectedTextProvider.Value;
|
||||
Debug.Assert(stp != null, "Could not get an instance of ISelectedTextProvider");
|
||||
return !String.IsNullOrWhiteSpace(stp?.GetSelectedText());
|
||||
Debug.Assert(SelectedTextProvider != null, "Could not get an instance of ISelectedTextProvider");
|
||||
return !String.IsNullOrWhiteSpace(SelectedTextProvider?.GetSelectedText());
|
||||
}
|
||||
|
||||
public void Activate([AllowNull] object data)
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
using GitHub.Api;
|
||||
using GitHub.Extensions;
|
||||
using GitHub.Primitives;
|
||||
using GitHub.Primitives;
|
||||
using GitHub.Services;
|
||||
using System;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
public class LinkMenuBase: MenuBase
|
||||
{
|
||||
public LinkMenuBase(IServiceProvider serviceProvider, ISimpleApiClientFactory apiFactory)
|
||||
: base(serviceProvider, apiFactory)
|
||||
readonly Lazy<IUsageTracker> usageTracker;
|
||||
|
||||
protected IUsageTracker UsageTracker => usageTracker.Value;
|
||||
|
||||
public LinkMenuBase(IUIProvider serviceProvider)
|
||||
: base(serviceProvider)
|
||||
{
|
||||
usageTracker = new Lazy<IUsageTracker>(() => ServiceProvider.TryGetService<IUsageTracker>());
|
||||
}
|
||||
|
||||
protected UriString GenerateLink()
|
||||
{
|
||||
var repo = ActiveRepo;
|
||||
var activeDocument = ServiceProvider.GetExportedValue<IActiveDocumentSnapshot>();
|
||||
var activeDocument = ServiceProvider.TryGetService<IActiveDocumentSnapshot>();
|
||||
if (activeDocument == null)
|
||||
return null;
|
||||
return repo.GenerateUrl(activeDocument.Name, activeDocument.StartLine, activeDocument.EndLine);
|
||||
|
|
|
@ -1,24 +1,22 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using GitHub.Extensions;
|
||||
using GitHub.Api;
|
||||
using GitHub.Models;
|
||||
using GitHub.Primitives;
|
||||
using GitHub.Services;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Api;
|
||||
using NullGuard;
|
||||
using GitHub.UI;
|
||||
using NullGuard;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GitHub.VisualStudio
|
||||
{
|
||||
public abstract class MenuBase
|
||||
{
|
||||
readonly IServiceProvider serviceProvider;
|
||||
readonly ISimpleApiClientFactory apiFactory;
|
||||
readonly IUIProvider serviceProvider;
|
||||
readonly Lazy<ISimpleApiClientFactory> apiFactory;
|
||||
|
||||
protected IServiceProvider ServiceProvider { get { return serviceProvider; } }
|
||||
protected IUIProvider ServiceProvider { get { return serviceProvider; } }
|
||||
|
||||
protected ISimpleRepositoryModel ActiveRepo { get; private set; }
|
||||
|
||||
|
@ -32,35 +30,29 @@ namespace GitHub.VisualStudio
|
|||
set
|
||||
{
|
||||
if (simpleApiClient != value && value == null)
|
||||
apiFactory.ClearFromCache(simpleApiClient);
|
||||
ApiFactory.ClearFromCache(simpleApiClient);
|
||||
simpleApiClient = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected ISimpleApiClientFactory ApiFactory => apiFactory;
|
||||
protected ISimpleApiClientFactory ApiFactory => apiFactory.Value;
|
||||
|
||||
protected MenuBase()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
protected MenuBase(IServiceProvider serviceProvider, ISimpleApiClientFactory apiFactory)
|
||||
{
|
||||
this.serviceProvider = serviceProvider;
|
||||
this.apiFactory = apiFactory;
|
||||
}
|
||||
|
||||
protected MenuBase(IServiceProvider serviceProvider)
|
||||
protected MenuBase(IUIProvider serviceProvider)
|
||||
{
|
||||
this.serviceProvider = serviceProvider;
|
||||
apiFactory = new Lazy<ISimpleApiClientFactory>(() => ServiceProvider.TryGetService<ISimpleApiClientFactory>());
|
||||
}
|
||||
|
||||
protected ISimpleRepositoryModel GetActiveRepo()
|
||||
{
|
||||
var activeRepo = ServiceProvider.GetExportedValue<ITeamExplorerServiceHolder>()?.ActiveRepo;
|
||||
var activeRepo = ServiceProvider.TryGetService<ITeamExplorerServiceHolder>()?.ActiveRepo;
|
||||
// activeRepo can be null at this point because it is set elsewhere as the result of async operation that may not have completed yet.
|
||||
if (activeRepo == null)
|
||||
{
|
||||
var path = ServiceProvider.GetExportedValue<IVSGitServices>()?.GetActiveRepoPath() ?? String.Empty;
|
||||
var path = ServiceProvider.TryGetService<IVSGitServices>()?.GetActiveRepoPath() ?? String.Empty;
|
||||
try
|
||||
{
|
||||
activeRepo = !string.IsNullOrEmpty(path) ? new SimpleRepositoryModel(path) : null;
|
||||
|
@ -75,28 +67,23 @@ namespace GitHub.VisualStudio
|
|||
|
||||
protected void StartFlow(UIControllerFlow controllerFlow)
|
||||
{
|
||||
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
Debug.Assert(uiProvider != null, "MenuBase:StartFlow:No UIProvider available.");
|
||||
if (uiProvider == null)
|
||||
return;
|
||||
|
||||
IConnection connection = null;
|
||||
if (controllerFlow != UIControllerFlow.Authentication)
|
||||
{
|
||||
var activeRepo = GetActiveRepo();
|
||||
connection = ServiceProvider.GetExportedValue<IConnectionManager>()?.Connections
|
||||
connection = ServiceProvider.TryGetService<IConnectionManager>()?.Connections
|
||||
.FirstOrDefault(c => activeRepo?.CloneUrl?.RepositoryName != null && c.HostAddress.Equals(HostAddress.Create(activeRepo.CloneUrl)));
|
||||
}
|
||||
uiProvider.RunUI(controllerFlow, connection);
|
||||
ServiceProvider.RunUI(controllerFlow, connection);
|
||||
}
|
||||
|
||||
void RefreshRepo()
|
||||
{
|
||||
ActiveRepo = ServiceProvider.GetExportedValue<ITeamExplorerServiceHolder>().ActiveRepo;
|
||||
ActiveRepo = ServiceProvider.TryGetService<ITeamExplorerServiceHolder>().ActiveRepo;
|
||||
|
||||
if (ActiveRepo == null)
|
||||
{
|
||||
var vsGitServices = ServiceProvider.GetExportedValue<IVSGitServices>();
|
||||
var vsGitServices = ServiceProvider.TryGetService<IVSGitServices>();
|
||||
string path = vsGitServices?.GetActiveRepoPath() ?? String.Empty;
|
||||
try
|
||||
{
|
||||
|
@ -117,8 +104,7 @@ namespace GitHub.VisualStudio
|
|||
if (uri == null)
|
||||
return false;
|
||||
|
||||
Debug.Assert(apiFactory != null, "apiFactory cannot be null. Did you call the right constructor?");
|
||||
SimpleApiClient = apiFactory.Create(uri);
|
||||
SimpleApiClient = ApiFactory.Create(uri);
|
||||
|
||||
var isdotcom = HostAddress.IsGitHubDotComUri(uri.ToRepositoryUrl());
|
||||
if (!isdotcom)
|
|
@ -1,23 +1,32 @@
|
|||
using System.Collections.Generic;
|
||||
using GitHub.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
[Export(typeof(IMenuProvider))]
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class MenuProvider : IMenuProvider
|
||||
{
|
||||
public IReadOnlyCollection<IMenuHandler> Menus { get; }
|
||||
|
||||
public IReadOnlyCollection<IDynamicMenuHandler> DynamicMenus { get; }
|
||||
|
||||
[ImportingConstructor]
|
||||
public MenuProvider([ImportMany] IEnumerable<IMenuHandler> menus, [ImportMany] IEnumerable<IDynamicMenuHandler> dynamicMenus)
|
||||
public MenuProvider(IUIProvider serviceProvider)
|
||||
{
|
||||
Menus = new ReadOnlyCollection<IMenuHandler>(menus.ToList());
|
||||
DynamicMenus = new ReadOnlyCollection<IDynamicMenuHandler>(dynamicMenus.ToList());
|
||||
Menus = new List<IMenuHandler>
|
||||
{
|
||||
new AddConnection(serviceProvider),
|
||||
new OpenPullRequests(),
|
||||
new ShowGitHubPane()
|
||||
};
|
||||
|
||||
DynamicMenus = new List<IDynamicMenuHandler>
|
||||
{
|
||||
new CopyLink(serviceProvider),
|
||||
new CreateGist(serviceProvider),
|
||||
new OpenLink(serviceProvider)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,14 @@
|
|||
using GitHub.Extensions;
|
||||
using GitHub.Services;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using GitHub.Services;
|
||||
using NullGuard;
|
||||
using GitHub.Api;
|
||||
using System;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
[Export(typeof(IDynamicMenuHandler))]
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class OpenLink: LinkMenuBase, IDynamicMenuHandler
|
||||
{
|
||||
readonly IUsageTracker usageTracker;
|
||||
|
||||
[ImportingConstructor]
|
||||
public OpenLink([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
|
||||
IUsageTracker usageTracker, ISimpleApiClientFactory apiFactory)
|
||||
: base(serviceProvider, apiFactory)
|
||||
public OpenLink(IUIProvider serviceProvider)
|
||||
: base(serviceProvider)
|
||||
{
|
||||
this.usageTracker = usageTracker;
|
||||
}
|
||||
|
||||
public Guid Guid => GuidList.guidContextMenuSet;
|
||||
|
@ -34,10 +23,10 @@ namespace GitHub.VisualStudio.Menus
|
|||
var link = GenerateLink();
|
||||
if (link == null)
|
||||
return;
|
||||
var browser = ServiceProvider.GetExportedValue<IVisualStudioBrowser>();
|
||||
var browser = ServiceProvider.TryGetService<IVisualStudioBrowser>();
|
||||
browser?.OpenUrl(link.ToUri());
|
||||
|
||||
usageTracker.IncrementOpenInGitHubCount();
|
||||
UsageTracker.IncrementOpenInGitHubCount();
|
||||
}
|
||||
|
||||
public bool CanShow()
|
||||
|
|
|
@ -3,13 +3,10 @@ using GitHub.UI;
|
|||
using GitHub.VisualStudio.UI;
|
||||
using NullGuard;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
[ExportMenu(MenuType = MenuType.OpenPullRequests)]
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class OpenPullRequests: MenuBase, IMenuHandler
|
||||
public class OpenPullRequests : MenuBase, IMenuHandler
|
||||
{
|
||||
public Guid Guid => GuidList.guidGitHubCmdSet;
|
||||
public int CmdId => PkgCmdIDList.openPullRequestsCommand;
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
using GitHub.Exports;
|
||||
using GitHub.UI;
|
||||
using GitHub.VisualStudio.UI;
|
||||
using GitHub.VisualStudio.UI;
|
||||
using NullGuard;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
|
||||
namespace GitHub.VisualStudio.Menus
|
||||
{
|
||||
[ExportMenu(MenuType = MenuType.GitHubPane)]
|
||||
[PartCreationPolicy(CreationPolicy.Shared)]
|
||||
public class ShowGitHubPane: MenuBase, IMenuHandler
|
||||
{
|
||||
public Guid Guid => GuidList.guidGitHubCmdSet;
|
||||
|
|
|
@ -9,7 +9,6 @@ using System.Globalization;
|
|||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows.Controls;
|
||||
using GitHub.Infrastructure;
|
||||
using GitHub.Models;
|
||||
using GitHub.Services;
|
||||
|
@ -18,6 +17,10 @@ using Microsoft.VisualStudio.ComponentModelHost;
|
|||
using Microsoft.VisualStudio.Shell;
|
||||
using NLog;
|
||||
using NullGuard;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
|
||||
namespace GitHub.VisualStudio
|
||||
{
|
||||
|
@ -39,30 +42,7 @@ namespace GitHub.VisualStudio
|
|||
readonly Version currentVersion;
|
||||
bool initializingLogging = false;
|
||||
|
||||
ExportProvider exportProvider = null;
|
||||
[AllowNull]
|
||||
public ExportProvider ExportProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
if (exportProvider == null)
|
||||
{
|
||||
var componentModel = serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;
|
||||
Debug.Assert(componentModel != null, "Service of type SComponentModel not found");
|
||||
if (componentModel == null)
|
||||
{
|
||||
log.Error("Service of type SComponentModel not found");
|
||||
}
|
||||
exportProvider = componentModel.DefaultExportProvider;
|
||||
|
||||
if (ExportProvider == null)
|
||||
{
|
||||
log.Error("DefaultExportProvider could not be obtained.");
|
||||
}
|
||||
}
|
||||
return exportProvider;
|
||||
}
|
||||
}
|
||||
public ExportProvider ExportProvider { get; }
|
||||
|
||||
CompositionContainer tempContainer;
|
||||
CompositionContainer TempContainer
|
||||
|
@ -83,7 +63,7 @@ namespace GitHub.VisualStudio
|
|||
[AllowNull]
|
||||
public IServiceProvider GitServiceProvider { get; set; }
|
||||
|
||||
bool Initialized { get { return exportProvider != null; } }
|
||||
public bool Initialized { get { return ExportProvider != null; } }
|
||||
|
||||
[ImportingConstructor]
|
||||
public UIProvider([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider)
|
||||
|
@ -92,13 +72,39 @@ namespace GitHub.VisualStudio
|
|||
this.serviceProvider = serviceProvider;
|
||||
|
||||
tempParts = new Dictionary<string, OwnedComposablePart>();
|
||||
|
||||
var asyncProvider = serviceProvider as IAsyncServiceProvider;
|
||||
IComponentModel componentModel = null;
|
||||
if (asyncProvider != null)
|
||||
{
|
||||
componentModel = asyncProvider.GetServiceAsync(typeof(SComponentModel)) as IComponentModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
componentModel = serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;
|
||||
}
|
||||
|
||||
Debug.Assert(componentModel != null, "Service of type SComponentModel not found");
|
||||
if (componentModel == null)
|
||||
{
|
||||
log.Error("Service of type SComponentModel not found");
|
||||
}
|
||||
|
||||
ExportProvider = componentModel.DefaultExportProvider;
|
||||
if (ExportProvider == null)
|
||||
{
|
||||
log.Error("DefaultExportProvider could not be obtained.");
|
||||
}
|
||||
}
|
||||
|
||||
[return: AllowNull]
|
||||
public object TryGetService(Type serviceType)
|
||||
{
|
||||
if (!Initialized)
|
||||
{
|
||||
log.Error("ExportProvider is not initialized, cannot add service.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!initializingLogging && log.Factory.Configuration == null)
|
||||
{
|
||||
|
@ -118,7 +124,19 @@ namespace GitHub.VisualStudio
|
|||
if (instance != null)
|
||||
return instance;
|
||||
|
||||
instance = AddToDisposables(ExportProvider.GetExportedValues<object>(contract).FirstOrDefault(x => contract.StartsWith("github.", StringComparison.OrdinalIgnoreCase) ? x.GetType().Assembly.GetName().Version == currentVersion : true));
|
||||
instance = TryGetServiceOnMainThread(serviceType, contract);
|
||||
if (instance == null)
|
||||
{
|
||||
// we need to log these things
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
async Task<object> TryGetServiceOnMainThread(Type serviceType, string contract)
|
||||
{
|
||||
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
||||
|
||||
var instance = AddToDisposables(ExportProvider.GetExportedValues<object>(contract).FirstOrDefault(x => contract.StartsWith("github.", StringComparison.OrdinalIgnoreCase) ? x.GetType().Assembly.GetName().Version == currentVersion : true));
|
||||
|
||||
if (instance != null)
|
||||
return instance;
|
||||
|
@ -127,12 +145,9 @@ namespace GitHub.VisualStudio
|
|||
if (instance != null)
|
||||
return instance;
|
||||
|
||||
if (GitServiceProvider != null)
|
||||
{
|
||||
instance = GitServiceProvider.GetService(serviceType);
|
||||
if (instance != null)
|
||||
return instance;
|
||||
}
|
||||
instance = GitServiceProvider?.GetService(serviceType);
|
||||
if (instance != null)
|
||||
return instance;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -182,7 +182,17 @@ namespace GitHub.Services
|
|||
timer.Start();
|
||||
}
|
||||
|
||||
async void TimerTick(object sender, EventArgs e)
|
||||
void TimerTick(object sender, EventArgs e)
|
||||
{
|
||||
TimerTick()
|
||||
.Catch(ex =>
|
||||
{
|
||||
//log.Warn("Failed submitting usage data", ex);
|
||||
})
|
||||
.Forget();
|
||||
}
|
||||
|
||||
async Task TimerTick()
|
||||
{
|
||||
Debug.Assert(client != null, "TimerTick should not be triggered when there is no IMetricsService");
|
||||
|
||||
|
@ -204,30 +214,23 @@ namespace GitHub.Services
|
|||
if (!userSettings.CollectMetrics)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// Every time we increment the launch count we increment both daily and weekly
|
||||
// launch count but we only submit (and clear) the weekly launch count when we've
|
||||
// transitioned into a new week. We've defined a week by the ISO8601 definition,
|
||||
// i.e. week starting on Monday and ending on Sunday.
|
||||
var usage = LoadUsage();
|
||||
var lastDate = usage.LastUpdated;
|
||||
var currentDate = DateTimeOffset.Now;
|
||||
var includeWeekly = GetIso8601WeekOfYear(lastDate) != GetIso8601WeekOfYear(currentDate);
|
||||
var includeMonthly = lastDate.Month != currentDate.Month;
|
||||
// Every time we increment the launch count we increment both daily and weekly
|
||||
// launch count but we only submit (and clear) the weekly launch count when we've
|
||||
// transitioned into a new week. We've defined a week by the ISO8601 definition,
|
||||
// i.e. week starting on Monday and ending on Sunday.
|
||||
var usage = LoadUsage();
|
||||
var lastDate = usage.LastUpdated;
|
||||
var currentDate = DateTimeOffset.Now;
|
||||
var includeWeekly = GetIso8601WeekOfYear(lastDate) != GetIso8601WeekOfYear(currentDate);
|
||||
var includeMonthly = lastDate.Month != currentDate.Month;
|
||||
|
||||
// Only send stats once a day.
|
||||
if (lastDate.Date != currentDate.Date)
|
||||
{
|
||||
await SendUsage(usage.Model, includeWeekly, includeMonthly);
|
||||
ClearCounters(usage.Model, includeWeekly, includeMonthly);
|
||||
usage.LastUpdated = DateTimeOffset.Now.UtcDateTime;
|
||||
SaveUsage(usage);
|
||||
}
|
||||
}
|
||||
catch //(Exception ex)
|
||||
// Only send stats once a day.
|
||||
if (lastDate.Date != currentDate.Date)
|
||||
{
|
||||
//log.Warn("Failed submitting usage data", ex);
|
||||
await SendUsage(usage.Model, includeWeekly, includeMonthly);
|
||||
ClearCounters(usage.Model, includeWeekly, includeMonthly);
|
||||
usage.LastUpdated = DateTimeOffset.Now.UtcDateTime;
|
||||
SaveUsage(usage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
// This is an automatically generated file, based on settings.json and PackageSettingsGen.tt
|
||||
/* settings.json content:
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"name": "CollectMetrics",
|
||||
"type": "bool",
|
||||
"default": 'true'
|
||||
},
|
||||
{
|
||||
"name": "UIState",
|
||||
"type": "object",
|
||||
"typename": "UIState",
|
||||
"default": 'null'
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
using GitHub.Settings;
|
||||
using GitHub.Primitives;
|
||||
using GitHub.VisualStudio.Helpers;
|
||||
|
||||
namespace GitHub.VisualStudio.Settings {
|
||||
|
||||
public partial class PackageSettings : NotificationAwareObject, IPackageSettings
|
||||
{
|
||||
|
||||
bool collectMetrics;
|
||||
public bool CollectMetrics
|
||||
{
|
||||
get { return collectMetrics; }
|
||||
set { collectMetrics = value; this.RaisePropertyChange(); }
|
||||
}
|
||||
|
||||
UIState uIState;
|
||||
public UIState UIState
|
||||
{
|
||||
get { return uIState; }
|
||||
set { uIState = value; this.RaisePropertyChange(); }
|
||||
}
|
||||
|
||||
|
||||
void LoadSettings()
|
||||
{
|
||||
CollectMetrics = (bool)settingsStore.Read("CollectMetrics", true);
|
||||
UIState = SimpleJson.DeserializeObject<UIState>((string)settingsStore.Read("UIState", "{}"));
|
||||
}
|
||||
|
||||
void SaveSettings()
|
||||
{
|
||||
settingsStore.Write("CollectMetrics", CollectMetrics);
|
||||
settingsStore.Write("UIState", SimpleJson.SerializeObject(UIState));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -225,7 +225,7 @@ namespace GitHub.VisualStudio.UI.Views
|
|||
break;
|
||||
}
|
||||
|
||||
var uiProvider = ServiceProvider.GetExportedValue<IUIProvider>();
|
||||
var uiProvider = ServiceProvider.GetService<IUIProvider>();
|
||||
var factory = uiProvider.GetService<IExportFactoryProvider>();
|
||||
var uiflow = factory.UIControllerFactory.CreateExport();
|
||||
disposables.Add(uiflow);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 01158551686845eaf3cd3298aabc48a2a6fde90d
|
||||
Subproject commit c41c900b6f90245187a4b6d8335f85ae70a57462
|
Загрузка…
Ссылка в новой задаче