void InitializeValidation() { var nonNullRepositoryName = this.WhenAny( x => x.RepositoryName, x => x.Value) .WhereNotNull(); RepositoryNameValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName) .IfNullOrEmpty("Please enter a repository name") .IfTrue(x => x.Length > 100, "Repository name must be fewer than 100 characters"); SafeRepositoryNameWarningValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName) .Add(repoName => { var parsedReference = GetSafeRepositoryName(repoName); return(parsedReference != repoName ? "Will be created as " + parsedReference : null); }); this.WhenAny(x => x.SafeRepositoryNameWarningValidator.ValidationResult, x => x.Value) .WhereNotNull() // When this is instantiated, it sends a null result. .Select(result => result?.Message) .Subscribe(message => { if (!string.IsNullOrEmpty(message)) { vsServices.ShowWarning(message); } else { vsServices.ClearNotifications(); } }); }
public StartPageCloneViewModel( IRepositoryHost repositoryHost, IRepositoryCloneService cloneService, IOperatingSystem operatingSystem) { this.operatingSystem = operatingSystem; 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.Create(canCloneObservable); browseForDirectoryCommand.Subscribe(_ => ShowBrowseForDirectoryDialog()); this.WhenAny(x => x.BaseRepositoryPathValidator.ValidationResult, x => x.Value) .Subscribe(); BaseRepositoryPath = cloneService.DefaultClonePath; }
public RepositoryRecloneViewModel( IRepositoryCloneService cloneService, IOperatingSystem operatingSystem) { Guard.ArgumentNotNull(cloneService, nameof(cloneService)); Guard.ArgumentNotNull(operatingSystem, nameof(operatingSystem)); this.operatingSystem = operatingSystem; 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; }
void InitializeValidation() { var nonNullRepositoryName = this.WhenAny( x => x.RepositoryName, x => x.Value) .WhereNotNull(); RepositoryNameValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName) .IfNullOrEmpty(Resources.RepositoryNameValidatorEmpty) .IfTrue(x => x.Length > 100, Resources.RepositoryNameValidatorTooLong); 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.SafeRepositoryNameWarningValidator.ValidationResult, x => x.Value) .WhereNotNull() // When this is instantiated, it sends a null result. .Select(result => result?.Message) .Subscribe(message => { if (!string.IsNullOrEmpty(message)) { vsServices.ShowWarning(message); } else { vsServices.ClearNotifications(); } }); }
public RepositoryCloneViewModelDesigner() { var repositories = new ReactiveList <IRepositoryModel> { new RepositoryModelDesigner("encourage", "haacked"), new RepositoryModelDesigner("haacked.com", "haacked"), new RepositoryModelDesigner("octokit.net", "octokit"), new RepositoryModelDesigner("octokit.rb", "octokit"), new RepositoryModelDesigner("octokit.objc", "octokit"), new RepositoryModelDesigner("windows", "github"), new RepositoryModelDesigner("mac", "github"), new RepositoryModelDesigner("github", "github") }; BrowseForDirectory = ReactiveCommand.Create(); FilteredRepositories = repositories.CreateDerivedCollection( x => x ); 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"); }
public RepositoryCreationViewModel( IModelServiceFactory modelServiceFactory, IOperatingSystem operatingSystem, IRepositoryCreationService repositoryCreationService, IUsageTracker usageTracker) { Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory)); Guard.ArgumentNotNull(operatingSystem, nameof(operatingSystem)); Guard.ArgumentNotNull(repositoryCreationService, nameof(repositoryCreationService)); Guard.ArgumentNotNull(usageTracker, nameof(usageTracker)); this.modelServiceFactory = modelServiceFactory; this.operatingSystem = operatingSystem; this.repositoryCreationService = repositoryCreationService; this.usageTracker = usageTracker; SelectedGitIgnoreTemplate = GitIgnoreItem.None; SelectedLicense = LicenseItem.None; 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); BaseRepositoryPath = repositoryCreationService.DefaultClonePath; }
public RepositoryCloneViewModel( IRepositoryHost repositoryHost, IRepositoryCloneService cloneService, IOperatingSystem operatingSystem, INotificationService notificationService) { this.repositoryHost = repositoryHost; this.cloneService = cloneService; this.operatingSystem = operatingSystem; this.notificationService = notificationService; Title = string.Format(CultureInfo.CurrentCulture, Resources.CloneTitle, repositoryHost.Title); Repositories = new ReactiveList <IRepositoryModel>(); loadRepositoriesCommand = ReactiveCommand.CreateAsyncObservable(OnLoadRepositories); isLoading = this.WhenAny(x => x.LoadingFailed, x => x.Value) .CombineLatest(loadRepositoriesCommand.IsExecuting, (failed, loading) => !failed && loading) .ToProperty(this, x => x.IsLoading); loadRepositoriesCommand.Subscribe(Repositories.AddRange); filterTextIsEnabled = this.WhenAny(x => x.Repositories.Count, x => x.Value > 0) .ToProperty(this, x => x.FilterTextIsEnabled); noRepositoriesFound = this.WhenAny(x => x.FilterTextIsEnabled, x => x.IsLoading, x => x.LoadingFailed , (any, loading, failed) => !any.Value && !loading.Value && !failed.Value) .ToProperty(this, x => x.NoRepositoriesFound); var filterResetSignal = this.WhenAny(x => x.FilterText, x => x.Value) .DistinctUntilChanged(StringComparer.OrdinalIgnoreCase) .Throttle(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler); FilteredRepositories = Repositories.CreateDerivedCollection( x => x, filter: FilterRepository, signalReset: filterResetSignal ); var baseRepositoryPath = this.WhenAny( x => x.BaseRepositoryPath, x => x.SelectedRepository, (x, y) => x.Value); BaseRepositoryPathValidator = ReactivePropertyValidator.ForObservable(baseRepositoryPath) .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") .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 static ReactivePropertyValidator <string> CreateBaseRepositoryPathValidator( this IRepositoryCreationTarget target) { return(ReactivePropertyValidator.ForObservable(target.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")); }
void SetupValidators() { var titleObs = this.WhenAnyValue(x => x.PRTitle); TitleValidator = ReactivePropertyValidator.ForObservable(titleObs) .IfNullOrEmpty(Resources.PullRequestCreationTitleValidatorEmpty); var branchObs = this.WhenAnyValue( x => x.Initialized, x => x.TargetBranch, x => x.SourceBranch, (init, target, source) => new { Initialized = init, Source = source, Target = target }) .Where(x => x.Initialized); BranchValidator = ReactivePropertyValidator.ForObservable(branchObs) .IfTrue(x => x.Source == null, Resources.PullRequestSourceBranchDoesNotExist) .IfTrue(x => x.Source.Equals(x.Target), Resources.PullRequestSourceAndTargetBranchTheSame); }
void InitializeValidation() { var nonNullRepositoryName = this.WhenAny( x => x.RepositoryName, x => x.Value) .WhereNotNull(); RepositoryNameValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName) .IfNullOrEmpty(Resources.RepositoryNameValidatorEmpty) .IfTrue(x => x.Length > 100, Resources.RepositoryNameValidatorTooLong); SafeRepositoryNameWarningValidator = ReactivePropertyValidator.ForObservable(nonNullRepositoryName) .Add(repoName => { var parsedReference = GetSafeRepositoryName(repoName); return(parsedReference != repoName ? String.Format(CultureInfo.CurrentCulture, Resources.SafeRepositoryNameWarning, parsedReference) : null); }); }
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; }
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; }
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; }
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; }