wip: new Start Page, async loading, P5 support

This commit is contained in:
Andreia Gaita 2016-10-26 20:47:48 +02:00
Родитель 6d642a4ba1
Коммит b40d85c707
29 изменённых файлов: 459 добавлений и 255 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -239,4 +239,3 @@ WiX.Toolset.DummyFile.txt
nunit-UnitTests.xml
nunit-TrackingCollectionTests.xml
GitHubVS.sln.DotSettings
**/generated/*.cs

Просмотреть файл

@ -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