コード例 #1
0
        public LoginToGitHubForEnterpriseViewModel(
            IConnectionManager connectionManager,
            IEnterpriseCapabilitiesService enterpriseCapabilities,
            IVisualStudioBrowser browser,
            IScheduler scheduler)
            : base(connectionManager, browser)
        {
            Guard.ArgumentNotNull(connectionManager, nameof(connectionManager));
            Guard.ArgumentNotNull(enterpriseCapabilities, nameof(enterpriseCapabilities));
            Guard.ArgumentNotNull(browser, nameof(browser));

            this.enterpriseCapabilities = enterpriseCapabilities;

            EnterpriseUrlValidator = ReactivePropertyValidator.For(this, x => x.EnterpriseUrl)
                                     .IfNullOrEmpty(Resources.EnterpriseUrlValidatorEmpty)
                                     .IfNotUri(Resources.EnterpriseUrlValidatorInvalid)
                                     .IfGitHubDotComHost(Resources.EnterpriseUrlValidatorNotAGitHubHost);

            canLogin = this.WhenAnyValue(
                x => x.UsernameOrEmailValidator.ValidationResult.IsValid,
                x => x.PasswordValidator.ValidationResult.IsValid,
                x => x.SupportedLoginMethods,
                (x, y, z) => (x || (z & EnterpriseLoginMethods.Token) != 0) && y)
                       .ToProperty(this, x => x.CanLogin);

            canSsoLogin = this.WhenAnyValue(
                x => x.EnterpriseUrlValidator.ValidationResult.IsValid)
                          .ToProperty(this, x => x.CanLogin);

            this.WhenAnyValue(x => x.EnterpriseUrl, x => x.EnterpriseUrlValidator.ValidationResult)
            .Throttle(TimeSpan.FromMilliseconds(500), scheduler)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => UpdatingProbeStatus = EnterpriseUrlChanged(x.Item1, x.Item2?.IsValid ?? false));

            NavigateLearnMore = ReactiveCommand.CreateFromObservable(() =>
            {
                browser.OpenUrl(GitHubUrls.LearnMore);
                return(Observable.Return(Unit.Default));
            });
        }
コード例 #2
0
        public RepositoryCloneViewModelDesigner()
        {
            Repositories = new ObservableCollection <IRemoteRepositoryModel>
            {
                RepositoryModelDesigner.Create("encourage", "haacked"),
                RepositoryModelDesigner.Create("haacked.com", "haacked"),
                RepositoryModelDesigner.Create("octokit.net", "octokit"),
                RepositoryModelDesigner.Create("octokit.rb", "octokit"),
                RepositoryModelDesigner.Create("octokit.objc", "octokit"),
                RepositoryModelDesigner.Create("windows", "github"),
                RepositoryModelDesigner.Create("mac", "github"),
                RepositoryModelDesigner.Create("github", "github")
            };

            BrowseForDirectory = ReactiveCommand.Create();

            BaseRepositoryPathValidator = ReactivePropertyValidator.ForObservable(this.WhenAny(x => x.BaseRepositoryPath, x => x.Value))
                                          .IfNullOrEmpty("Please enter a repository path")
                                          .IfTrue(x => x.Length > 200, "Path too long")
                                          .IfContainsInvalidPathChars("Path contains invalid characters")
                                          .IfPathNotRooted("Please enter a valid path");
        }
コード例 #3
0
        public StartPageCloneViewModel(
            IRepositoryHost repositoryHost,
            IRepositoryCloneService cloneService,
            IOperatingSystem operatingSystem,
            INotificationService notificationService,
            IUsageTracker usageTracker)
        {
            this.cloneService        = cloneService;
            this.operatingSystem     = operatingSystem;
            this.notificationService = notificationService;
            this.usageTracker        = usageTracker;

            Title = string.Format(CultureInfo.CurrentCulture, Resources.CloneTitle, repositoryHost.Title);

            var baseRepositoryPath = this.WhenAny(
                x => x.BaseRepositoryPath,
                x => x.SelectedRepository,
                (x, y) => x.Value);

            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;
        }
コード例 #4
0
        public StartPageCloneViewModel(
            IConnection connection,
            IRepositoryCloneService cloneService,
            IOperatingSystem operatingSystem)
        {
            Guard.ArgumentNotNull(connection, nameof(connection));
            Guard.ArgumentNotNull(cloneService, nameof(cloneService));
            Guard.ArgumentNotNull(operatingSystem, nameof(operatingSystem));

            this.operatingSystem = operatingSystem;

            Title = string.Format(CultureInfo.CurrentCulture, Resources.CloneTitle, connection.HostAddress.Title);

            var baseRepositoryPath = this.WhenAny(
                x => x.BaseRepositoryPath,
                x => x.SelectedRepository,
                (x, y) => x.Value);

            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.Create(canCloneObservable);

            browseForDirectoryCommand.Subscribe(_ => ShowBrowseForDirectoryDialog());
            this.WhenAny(x => x.BaseRepositoryPathValidator.ValidationResult, x => x.Value)
            .Subscribe();
            BaseRepositoryPath = cloneService.DefaultClonePath;
        }
コード例 #5
0
        public LoginToGitHubForEnterpriseViewModel(IRepositoryHosts hosts, IVisualStudioBrowser browser) : base(hosts, browser)
        {
            Guard.ArgumentNotNull(hosts, nameof(hosts));
            Guard.ArgumentNotNull(browser, nameof(browser));

            EnterpriseUrlValidator = ReactivePropertyValidator.For(this, x => x.EnterpriseUrl)
                                     .IfNullOrEmpty(Resources.EnterpriseUrlValidatorEmpty)
                                     .IfNotUri(Resources.EnterpriseUrlValidatorInvalid)
                                     .IfGitHubDotComHost(Resources.EnterpriseUrlValidatorNotAGitHubHost);

            canLogin = this.WhenAny(
                x => x.UsernameOrEmailValidator.ValidationResult.IsValid,
                x => x.PasswordValidator.ValidationResult.IsValid,
                x => x.EnterpriseUrlValidator.ValidationResult.IsValid,
                (x, y, z) => x.Value && y.Value && z.Value)
                       .ToProperty(this, x => x.CanLogin);

            NavigateLearnMore = ReactiveCommand.CreateAsyncObservable(_ =>
            {
                browser.OpenUrl(GitHubUrls.LearnMore);
                return(Observable.Return(Unit.Default));
            });
        }
コード例 #6
0
        public RepositoryCreationViewModel(
            IConnection connection,
            IModelServiceFactory modelServiceFactory,
            IOperatingSystem operatingSystem,
            IRepositoryCreationService repositoryCreationService,
            IUsageTracker usageTracker)
        {
            Guard.ArgumentNotNull(connection, nameof(connection));
            Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
            Guard.ArgumentNotNull(operatingSystem, nameof(operatingSystem));
            Guard.ArgumentNotNull(repositoryCreationService, nameof(repositoryCreationService));
            Guard.ArgumentNotNull(usageTracker, nameof(usageTracker));

            this.operatingSystem           = operatingSystem;
            this.repositoryCreationService = repositoryCreationService;
            this.usageTracker = usageTracker;

            Title = string.Format(CultureInfo.CurrentCulture, Resources.CreateTitle, connection.HostAddress.Title);
            SelectedGitIgnoreTemplate = GitIgnoreItem.None;
            SelectedLicense           = LicenseItem.None;

            modelService = modelServiceFactory.CreateBlocking(connection);

            accounts = modelService.GetAccounts()
                       .ObserveOn(RxApp.MainThreadScheduler)
                       .ToProperty(this, vm => vm.Accounts, initialValue: new ReadOnlyCollection <IAccount>(new IAccount[] {}));

            this.WhenAny(x => x.Accounts, x => x.Value)
            .Select(accts => accts?.FirstOrDefault())
            .WhereNotNull()
            .Subscribe(a => SelectedAccount = a);

            browseForDirectoryCommand.Subscribe(_ => ShowBrowseForDirectoryDialog());

            BaseRepositoryPathValidator = ReactivePropertyValidator.ForObservable(this.WhenAny(x => x.BaseRepositoryPath, x => x.Value))
                                          .IfNullOrEmpty(Resources.RepositoryCreationClonePathEmpty)
                                          .IfTrue(x => x.Length > 200, Resources.RepositoryCreationClonePathTooLong)
                                          .IfContainsInvalidPathChars(Resources.RepositoryCreationClonePathInvalidCharacters)
                                          .IfPathNotRooted(Resources.RepositoryCreationClonePathInvalid);

            var nonNullRepositoryName = this.WhenAny(
                x => x.RepositoryName,
                x => x.BaseRepositoryPath,
                (x, y) => x.Value)
                                        .WhereNotNull();

            RepositoryNameValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName)
                                      .IfNullOrEmpty(Resources.RepositoryNameValidatorEmpty)
                                      .IfTrue(x => x.Length > 100, Resources.RepositoryNameValidatorTooLong)
                                      .IfTrue(IsAlreadyRepoAtPath, Resources.RepositoryNameValidatorAlreadyExists);

            SafeRepositoryNameWarningValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName)
                                                 .Add(repoName =>
            {
                var parsedReference = GetSafeRepositoryName(repoName);
                return(parsedReference != repoName ? String.Format(CultureInfo.CurrentCulture, Resources.SafeRepositoryNameWarning, parsedReference) : null);
            });

            this.WhenAny(x => x.BaseRepositoryPathValidator.ValidationResult, x => x.Value)
            .Subscribe();

            CreateRepository = InitializeCreateRepositoryCommand();

            canKeepPrivate = CanKeepPrivateObservable.CombineLatest(CreateRepository.IsExecuting,
                                                                    (canKeep, publishing) => canKeep && !publishing)
                             .ToProperty(this, x => x.CanKeepPrivate);

            isCreating = CreateRepository.IsExecuting
                         .ToProperty(this, x => x.IsCreating);

            GitIgnoreTemplates = TrackingCollection.CreateListenerCollectionAndRun(
                modelService.GetGitIgnoreTemplates(),
                new[] { GitIgnoreItem.None },
                OrderedComparer <GitIgnoreItem> .OrderByDescending(item => GitIgnoreItem.IsRecommended(item.Name)).Compare,
                x =>
            {
                if (x.Name.Equals("VisualStudio", StringComparison.OrdinalIgnoreCase))
                {
                    SelectedGitIgnoreTemplate = x;
                }
            });

            Licenses = TrackingCollection.CreateListenerCollectionAndRun(
                modelService.GetLicenses(),
                new[] { LicenseItem.None },
                OrderedComparer <LicenseItem> .OrderByDescending(item => LicenseItem.IsRecommended(item.Name)).Compare);

            BaseRepositoryPath = repositoryCreationService.DefaultClonePath;
        }
コード例 #7
0
        public RepositoryCreationViewModel(
            IRepositoryHost repositoryHost,
            IOperatingSystem operatingSystem,
            IRepositoryCreationService repositoryCreationService,
            IAvatarProvider avatarProvider)
        {
            this.repositoryHost            = repositoryHost;
            this.operatingSystem           = operatingSystem;
            this.repositoryCreationService = repositoryCreationService;

            Title = string.Format(CultureInfo.CurrentCulture, Resources.CreateTitle, repositoryHost.Title);
            SelectedGitIgnoreTemplate = GitIgnoreItem.None;
            SelectedLicense           = LicenseItem.None;

            accounts = repositoryHost.ModelService.GetAccounts()
                       .ObserveOn(RxApp.MainThreadScheduler)
                       .ToProperty(this, vm => vm.Accounts, initialValue: new ReadOnlyCollection <IAccount>(new IAccount[] {}));

            this.WhenAny(x => x.Accounts, x => x.Value)
            .WhereNotNull()
            .Where(accts => accts.Any())
            .Subscribe(accts => {
                var selectedAccount = accts.FirstOrDefault();
                if (selectedAccount != null)
                {
                    SelectedAccount = accts.FirstOrDefault();
                }
            });

            browseForDirectoryCommand.Subscribe(_ => ShowBrowseForDirectoryDialog());

            BaseRepositoryPathValidator = this.CreateBaseRepositoryPathValidator();

            var nonNullRepositoryName = this.WhenAny(
                x => x.RepositoryName,
                x => x.BaseRepositoryPath,
                (x, y) => x.Value)
                                        .WhereNotNull();

            RepositoryNameValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName)
                                      .IfNullOrEmpty(Resources.RepositoryNameValidatorEmpty)
                                      .IfTrue(x => x.Length > 100, Resources.RepositoryNameValidatorTooLong)
                                      .IfTrue(IsAlreadyRepoAtPath, Resources.RepositoryNameValidatorAlreadyExists);

            SafeRepositoryNameWarningValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName)
                                                 .Add(repoName =>
            {
                var parsedReference = GetSafeRepositoryName(repoName);
                return(parsedReference != repoName ? String.Format(CultureInfo.CurrentCulture, Resources.SafeRepositoryNameWarning, parsedReference) : null);
            });

            this.WhenAny(x => x.BaseRepositoryPathValidator.ValidationResult, x => x.Value)
            .Subscribe();

            CreateRepository = InitializeCreateRepositoryCommand();

            canKeepPrivate = CanKeepPrivateObservable.CombineLatest(CreateRepository.IsExecuting,
                                                                    (canKeep, publishing) => canKeep && !publishing)
                             .ToProperty(this, x => x.CanKeepPrivate);

            isCreating = CreateRepository.IsExecuting
                         .ToProperty(this, x => x.IsCreating);

            gitIgnoreTemplates = repositoryHost.ModelService.GetGitIgnoreTemplates()
                                 .ObserveOn(RxApp.MainThreadScheduler)
                                 .ToProperty(this, x => x.GitIgnoreTemplates, initialValue: new GitIgnoreItem[] { });

            this.WhenAny(x => x.GitIgnoreTemplates, x => x.Value)
            .WhereNotNull()
            .Where(ignores => ignores.Any())
            .Subscribe(ignores =>
            {
                SelectedGitIgnoreTemplate = ignores.FirstOrDefault(
                    template => template.Name.Equals("VisualStudio", StringComparison.OrdinalIgnoreCase));
            });

            licenses = repositoryHost.ModelService.GetLicenses()
                       .ObserveOn(RxApp.MainThreadScheduler)
                       .ToProperty(this, x => x.Licenses, initialValue: new LicenseItem[] { });

            BaseRepositoryPath = repositoryCreationService.DefaultClonePath;
        }
コード例 #8
0
        public RepositoryCloneViewModel(
            IConnection connection,
            IModelServiceFactory modelServiceFactory,
            IRepositoryCloneService cloneService,
            IOperatingSystem operatingSystem)
        {
            Guard.ArgumentNotNull(connection, nameof(connection));
            Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
            Guard.ArgumentNotNull(cloneService, nameof(cloneService));
            Guard.ArgumentNotNull(operatingSystem, nameof(operatingSystem));

            this.connection          = connection;
            this.modelServiceFactory = modelServiceFactory;
            this.operatingSystem     = operatingSystem;

            Title = string.Format(CultureInfo.CurrentCulture, Resources.CloneTitle, connection.HostAddress.Title);

            Repositories = new TrackingCollection <IRemoteRepositoryModel>();
            repositories.ProcessingDelay = TimeSpan.Zero;
            repositories.Comparer        = OrderedComparer <IRemoteRepositoryModel> .OrderBy(x => x.Owner).ThenBy(x => x.Name).Compare;

            repositories.Filter        = FilterRepository;
            repositories.NewerComparer = OrderedComparer <IRemoteRepositoryModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            filterTextIsEnabled = this.WhenAny(x => x.IsBusy,
                                               loading => loading.Value || repositories.UnfilteredCount > 0 && !LoadingFailed)
                                  .ToProperty(this, x => x.FilterTextIsEnabled);

            this.WhenAny(
                x => x.repositories.UnfilteredCount,
                x => x.IsBusy,
                x => x.LoadingFailed,
                (unfilteredCount, loading, failed) =>
            {
                if (loading.Value)
                {
                    return(false);
                }

                if (failed.Value)
                {
                    return(false);
                }

                return(unfilteredCount.Value == 0);
            })
            .Subscribe(x =>
            {
                NoRepositoriesFound = x;
            });

            this.WhenAny(x => x.FilterText, x => x.Value)
            .DistinctUntilChanged(StringComparer.OrdinalIgnoreCase)
            .Throttle(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler)
            .Subscribe(_ => repositories.Filter = FilterRepository);

            var baseRepositoryPath = this.WhenAny(
                x => x.BaseRepositoryPath,
                x => x.SelectedRepository,
                (x, y) => x.Value);

            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.Create(canCloneObservable);

            browseForDirectoryCommand.Subscribe(_ => ShowBrowseForDirectoryDialog());
            this.WhenAny(x => x.BaseRepositoryPathValidator.ValidationResult, x => x.Value)
            .Subscribe();
            BaseRepositoryPath  = cloneService.DefaultClonePath;
            NoRepositoriesFound = true;
        }
コード例 #9
0
        public RepositoryCloneViewModel(
            IRepositoryHost repositoryHost,
            IRepositoryCloneService cloneService,
            IOperatingSystem operatingSystem,
            INotificationService notificationService,
            IUsageTracker usageTracker)
        {
            this.repositoryHost      = repositoryHost;
            this.cloneService        = cloneService;
            this.operatingSystem     = operatingSystem;
            this.notificationService = notificationService;
            this.usageTracker        = usageTracker;

            Title = string.Format(CultureInfo.CurrentCulture, Resources.CloneTitle, repositoryHost.Title);

            Repositories = new TrackingCollection <IRepositoryModel>();
            repositories.ProcessingDelay = TimeSpan.Zero;
            repositories.Comparer        = OrderedComparer <IRepositoryModel> .OrderBy(x => x.Owner).ThenBy(x => x.Name).Compare;

            repositories.Filter        = FilterRepository;
            repositories.NewerComparer = OrderedComparer <IRepositoryModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            filterTextIsEnabled = this.WhenAny(x => x.IsLoading, x => x.Value)
                                  .Select(x => !x && repositories.UnfilteredCount > 0)
                                  .ToProperty(this, x => x.FilterTextIsEnabled);

            this.WhenAny(x => x.FilterTextIsEnabled, x => x.IsLoading, x => x.LoadingFailed
                         , (any, loading, failed) => !any.Value && !loading.Value && !failed.Value)
            .Subscribe(x => NoRepositoriesFound = x);

            this.WhenAny(x => x.FilterText, x => x.Value)
            .DistinctUntilChanged(StringComparer.OrdinalIgnoreCase)
            .Throttle(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler)
            .Subscribe(_ => repositories.Filter = FilterRepository);

            var baseRepositoryPath = this.WhenAny(
                x => x.BaseRepositoryPath,
                x => x.SelectedRepository,
                (x, y) => x.Value);

            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;
            NoRepositoriesFound = true;
        }