private ReactiveCommand <GitCommandResponse> GenerateGitCommand(IObservable <bool> canExecuteObservable, Func <CancellationToken, Task <GitCommandResponse> > func)
        {
            Func <Task <GitCommandResponse> > executeFunc = () =>
            {
                Dispatcher.CurrentDispatcher.Invoke(() => this.IsBusy = true);
                try
                {
                    this.tokenSource?.Cancel();
                }
                catch (ObjectDisposedException)
                {
                }

                this.tokenSource = new CancellationTokenSource();

                return(func(this.tokenSource.Token));
            };

            ReactiveCommand <GitCommandResponse> command = ReactiveCommand.CreateAsyncObservable(canExecuteObservable, _ => Observable.FromAsync(() => executeFunc()));

            command.Subscribe(x =>
            {
                this.GitCommandResponse = x;
                this.IsBusy             = false;
            });

            command.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler).Subscribe(ex => this.GitCommandResponse = new GitCommandResponse(false, ex.Message, null, 0));

            return(command);
        }
Esempio n. 2
0
        public GistCreationViewModel(
            IModelServiceFactory modelServiceFactory,
            ISelectedTextProvider selectedTextProvider,
            IGistPublishService gistPublishService,
            INotificationService notificationService,
            IUsageTracker usageTracker)
        {
            Guard.ArgumentNotNull(selectedTextProvider, nameof(selectedTextProvider));
            Guard.ArgumentNotNull(gistPublishService, nameof(gistPublishService));
            Guard.ArgumentNotNull(usageTracker, nameof(usageTracker));

            this.modelServiceFactory = modelServiceFactory;
            this.gistPublishService  = gistPublishService;
            this.notificationService = notificationService;
            this.usageTracker        = usageTracker;

            FileName     = VisualStudio.Services.GetFileNameFromActiveDocument() ?? Resources.DefaultGistFileName;
            SelectedText = selectedTextProvider.GetSelectedText();

            var canCreateGist = this.WhenAny(
                x => x.FileName,
                fileName => !String.IsNullOrEmpty(fileName.Value));

            CreateGist = ReactiveCommand.CreateAsyncObservable(canCreateGist, OnCreateGist);
        }
Esempio n. 3
0
        public void RegisterAsyncFunctionSmokeTest()
        {
            (new TestScheduler()).With(sched => {
                var fixture = ReactiveCommand.CreateAsyncObservable(Observable.Return(true),
                                                                    _ => Observable.Return(5).Delay(TimeSpan.FromSeconds(5), sched));

                IReactiveDerivedList <int> results;

                results = fixture.CreateCollection();

                var inflightResults = fixture.IsExecuting.CreateCollection();
                sched.AdvanceToMs(10);
                Assert.True(fixture.CanExecute(null));

                fixture.Execute(null);
                sched.AdvanceToMs(1005);
                Assert.False(fixture.CanExecute(null));

                sched.AdvanceToMs(5100);
                Assert.True(fixture.CanExecute(null));

                new[] { false, true, false }.AssertAreEqual(inflightResults);
                new[] { 5 }.AssertAreEqual(results);
            });
        }
        public TwitterTestViewModel(ITwitterService service = null)
        {
            _service = service ?? Resolver.Resolve <ITwitterService>();

            this.WhenActivated(registerDisposable =>
            {
                var canLogoutOrGetProfile = _service.CurrentAccount.AsObservable().Select(account => null != account);
                var canAuthorize          = _service
                                            .ServiceReadySub
                                            .AsObservable()
                                            .Select(authenticator => null != authenticator)
                                            .CombineLatest(canLogoutOrGetProfile, (arg1, arg2) => arg1 && !arg2);

                LogInCommand      = ReactiveCommand.CreateAsyncObservable(canAuthorize, args => Observable.Start(() => _service.Authorize()));
                LogOutCommand     = ReactiveCommand.CreateAsyncObservable(canLogoutOrGetProfile, args => Observable.Start(async() => await _service.Logout()));
                GetProfileCommand = ReactiveCommand.CreateAsyncObservable(canLogoutOrGetProfile, args => Observable.Start(() =>
                {
                    IsLoaderShowing = true;
                    _service
                    .GetUserData()
                    .ObserveOnUI()
                    .Catch(ex =>
                    {
                        IsLoaderShowing = false;
                        Error           = ex.Message;
                    }).SubscribeOnce(data =>
                    {
                        UserData        = data;
                        IsLoaderShowing = false;
                    });
                }));
            });
        }
Esempio n. 5
0
        public ArtistsViewModel(ISongFetcher <T> songFetcher, string serializationKey)
        {
            if (songFetcher == null)
            {
                throw new ArgumentNullException("songFetcher");
            }

            this.Activator = new ViewModelActivator();

            this.WhenActivated(() =>
            {
                var disposable = new CompositeDisposable();

                this.LoadCommand = ReactiveCommand.CreateAsyncObservable(_ => songFetcher.GetSongsAsync()
                                                                         .Timeout(LoadCommandTimeout, RxApp.TaskpoolScheduler)
                                                                         .TakeUntil(disposable));

                this.artists = this.LoadCommand
                               .Do(x => this.songs = x)
                               .Select(GetArtists)
                               .ToProperty(this, x => x.Artists, new List <string>());

                this.WhenAnyValue(x => x.SelectedArtist).Where(x => x != null)
                .Select(FilterSongsByArtist)
                .Select(x => BlobCache.LocalMachine.InsertObject(serializationKey, x))
                .Concat()
                .Subscribe();

                return(disposable);
            });
        }
Esempio n. 6
0
        public BlogViewModel(string title, Uri feedAddress, IFeedService feedService = null, IBlobCache cache = null)
        {
            Title       = title;
            FeedAddress = feedAddress;
            FeedService = feedService ?? Locator.Current.GetService <IFeedService>();
            Cache       = cache ?? Locator.Current.GetService <IBlobCache>();

            Articles = new ReactiveList <ArticleViewModel>();

            Refresh = ReactiveCommand.CreateAsyncObservable(x => GetAndFetchLatestArticles());
            Refresh.Subscribe(articles =>
            {
                // this could be done cleaner, send a PR.
                // Refresh.ToPropertyEx(this, x => x.Articles);

                Articles.Clear();
                Articles.AddRange(articles);
            });


            Refresh.ThrownExceptions.Subscribe(thrownException => { this.Log().Error(thrownException); });
            _isLoading = Refresh.IsExecuting.ToProperty(this, x => x.IsLoading);

            // post-condition checks
            Condition.Ensures(FeedAddress).IsNotNull();
            Condition.Ensures(FeedService).IsNotNull();
            Condition.Ensures(Cache).IsNotNull();
        }
Esempio n. 7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PullRequestDetailViewModel"/> class.
        /// </summary>
        /// <param name="repositoryHost">The repository host.</param>
        /// <param name="teservice">The team explorer service.</param>
        /// <param name="pullRequestsService">The pull requests service.</param>
        /// <param name="avatarProvider">The avatar provider.</param>
        public PullRequestDetailViewModel(
            ILocalRepositoryModel repository,
            IModelService modelService,
            IPullRequestService pullRequestsService,
            IPackageSettings settings)
        {
            this.repository          = repository;
            this.modelService        = modelService;
            this.pullRequestsService = pullRequestsService;

            Checkout = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.CheckoutState)
                .Cast <CheckoutCommandState>()
                .Select(x => x != null && x.DisabledMessage == null),
                DoCheckout);
            Checkout.ThrownExceptions.Subscribe(x => OperationError = x.Message);

            Pull = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.PullDisabledMessage == null),
                DoPull);
            Pull.ThrownExceptions.Subscribe(x => OperationError = x.Message);

            Push = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.PushDisabledMessage == null),
                DoPush);
            Push.ThrownExceptions.Subscribe(x => OperationError = x.Message);

            OpenOnGitHub = ReactiveCommand.Create();

            ChangedFilesViewType = (settings.UIState?.PullRequestDetailState?.ShowTree ?? true) ?
                                   ChangedFilesViewType.TreeView : ChangedFilesViewType.ListView;

            ToggleChangedFilesView = ReactiveCommand.Create();
            ToggleChangedFilesView.Subscribe(_ =>
            {
                ChangedFilesViewType = ChangedFilesViewType == ChangedFilesViewType.TreeView ?
                                       ChangedFilesViewType.ListView : ChangedFilesViewType.TreeView;
                settings.UIState.PullRequestDetailState.ShowTree = ChangedFilesViewType == ChangedFilesViewType.TreeView;
                settings.Save();
            });

            OpenChangedFileAction = (settings.UIState?.PullRequestDetailState?.DiffOnOpen ?? true) ?
                                    OpenChangedFileAction.Diff : OpenChangedFileAction.Open;

            ToggleOpenChangedFileAction = ReactiveCommand.Create();
            ToggleOpenChangedFileAction.Subscribe(_ =>
            {
                OpenChangedFileAction = OpenChangedFileAction == OpenChangedFileAction.Diff ?
                                        OpenChangedFileAction.Open : OpenChangedFileAction.Diff;
                settings.UIState.PullRequestDetailState.DiffOnOpen = OpenChangedFileAction == OpenChangedFileAction.Diff;
                settings.Save();
            });

            OpenFile = ReactiveCommand.Create();
            DiffFile = ReactiveCommand.Create();
        }
Esempio n. 8
0
        public void MultipleSubscribersShouldntDecrementRefcountBelowZero()
        {
            (new TestScheduler()).With(sched => {
                var fixture = ReactiveCommand.CreateAsyncObservable(Observable.Return(true),
                                                                    _ => Observable.Return(5).Delay(TimeSpan.FromMilliseconds(5000), sched));

                var results        = new List <int>();
                bool[] subscribers = new[] { false, false, false, false, false };

                fixture.Subscribe(x => results.Add(x));

                Enumerable.Range(0, 5).Run(x => fixture.Subscribe(_ => subscribers[x] = true));

                Assert.True(fixture.CanExecute(null));

                fixture.Execute(null);
                sched.AdvanceToMs(2000);
                Assert.False(fixture.CanExecute(null));

                sched.AdvanceToMs(6000);
                Assert.True(fixture.CanExecute(null));

                Assert.True(results.Count == 1);
                Assert.True(results[0] == 5);
                Assert.True(subscribers.All(x => x));
            });
        }
        public MainFlowViewModel(IScreen hostScreen, IAuthService authService)
        {
            HostScreen = hostScreen;

            if (authService.IsAuthenticated)
            {
                HostScreen.Router.Navigate.Execute(new ShellViewModel(HostScreen));
            }

            RegistryCommand = ReactiveCommand.Create();
            Observable.ObserveOn(RegistryCommand, RxApp.MainThreadScheduler).Subscribe(_ =>
            {
                HostScreen.Router.Navigate.Execute(new RegistryViewModel(HostScreen));
            });

            var canAdd = this.WhenAny(x => x.UserLogin, x => x.Password,
                                      (user, password) => !string.IsNullOrWhiteSpace(user.Value) && !string.IsNullOrWhiteSpace(password.Value));

            LoginCommand = ReactiveCommand.CreateAsyncObservable <bool>(canAdd,
                                                                        _ => Observable.FromAsync <bool>(async() => await authService.LoginAsync(UserLogin, Password)));
            Observable.ObserveOn(LoginCommand, RxApp.MainThreadScheduler).Subscribe(isAuthenticated =>
            {
                if (isAuthenticated)
                {
                    HostScreen.Router.Navigate.Execute(new ShellViewModel(HostScreen));
                }
                // else show login error
            });
        }
Esempio n. 10
0
        public MainViewModel()
        {
            Activator = new ViewModelActivator();


            var m1 = new SubViewModel();
            var m2 = new SubViewTwoModel();

            PanelViewModel = new DummyViewModel();

            this.WhenActivated(d =>
            {
                // length of time for the button to be disabled, simulating work
                var timeSpan = TimeSpan.FromSeconds(3);
                d(MyCommand  = ReactiveCommand.CreateAsyncObservable(_ => Observable.Return(true).Delay(timeSpan)));

                // menu should only be enabled when 2nd subview is active
                var enableWhen = this
                                 .WhenAnyValue(x => x.SubViewModel)
                                 .Select(subViewModel => subViewModel == m2);
                d(MyMenuCommand = ReactiveCommand.Create(enableWhen));

                d(MyCommand.Subscribe(_ => SubViewModel = (SubViewModel == m2) ? (ReactiveObject)m1 : m2));

                d(ShowPanelCommand = ReactiveCommand.Create());

                MyCommand.Execute(null);
            });

            SubViewModel = m1;
        }
        public FlickrSearchViewModel(IImageService imageService)
        {
            Images = new ReactiveList <SearchResultViewModel>();

            var canExecute = this.WhenAnyValue(x => x.SearchText)
                             .Select(x => !String.IsNullOrWhiteSpace(x));

            Search = ReactiveCommand.CreateAsyncObservable(canExecute,
                                                           _ =>
            {
                Images.Clear();
                ShowError = false;
                return(imageService.GetImages(SearchText));
            });

            Search.Subscribe(images => Images.Add(images));

            Search.ThrownExceptions.Subscribe(_ => ShowError = true);

            isLoading = Search.IsExecuting.ToProperty(this, vm => vm.IsLoading);

            canEnterSearchText = this.WhenAnyValue(x => x.IsLoading)
                                 .Select(x => !x)
                                 .ToProperty(this, vm => vm.CanEnterSearchText);
        }
Esempio n. 12
0
        public void DisallowConcurrentExecutionTest()
        {
            (new TestScheduler()).With(sched => {
                var fixture = ReactiveCommand.CreateAsyncObservable(Observable.Return(true),
                                                                    _ => Observable.Return(4).Delay(TimeSpan.FromSeconds(5), sched),
                                                                    sched);

                Assert.True(fixture.CanExecute(null));

                var result = fixture.CreateCollection();
                Assert.Equal(0, result.Count);

                sched.AdvanceToMs(25);
                Assert.Equal(0, result.Count);

                fixture.Execute(null);
                Assert.False(fixture.CanExecute(null));
                Assert.Equal(0, result.Count);

                sched.AdvanceToMs(2500);
                Assert.False(fixture.CanExecute(null));
                Assert.Equal(0, result.Count);

                sched.AdvanceToMs(5500);
                Assert.True(fixture.CanExecute(null));
                Assert.Equal(1, result.Count);
            });
        }
        public async Task AllowsLoginFromEnterpriseAfterGitHubLoginHasFailed()
        {
            var connectionManager = Substitute.For <IConnectionManager>();
            var connection        = Substitute.For <IConnection>();

            var gitHubLogin        = Substitute.For <ILoginToGitHubViewModel>();
            var gitHubLoginCommand = ReactiveCommand.CreateAsyncObservable(_ =>
                                                                           Observable.Return <IConnection>(null));

            gitHubLogin.Login.Returns(gitHubLoginCommand);

            var enterpriseLogin        = Substitute.For <ILoginToGitHubForEnterpriseViewModel>();
            var enterpriseLoginCommand = ReactiveCommand.CreateAsyncObservable(_ =>
                                                                               Observable.Return(connection));

            enterpriseLogin.Login.Returns(enterpriseLoginCommand);

            var loginViewModel = new LoginCredentialsViewModel(connectionManager, gitHubLogin, enterpriseLogin);
            var success        = false;

            loginViewModel.Done
            .OfType <IConnection>()
            .Where(x => x != null)
            .Subscribe(_ => success = true);

            await gitHubLoginCommand.ExecuteAsync();

            await enterpriseLoginCommand.ExecuteAsync();

            Assert.True(success);
        }
Esempio n. 14
0
        public UiController()
        {
            this.Uninstallables         = new ReactiveList <Uninstallable>(this.Refresh());
            this.SelectedUninstallables = new ReactiveList <Uninstallable>();

            this.TurnOffHyperVCommand  = ReactiveCommand.CreateAsyncObservable(x => OperatingSystemTasks.TurnOffHyperV());
            this.CleanSetupLogsCommand = ReactiveCommand.CreateAsyncObservable(x => OperatingSystemTasks.CleanSetupLogs());
            this.UninstallCommand      = ReactiveCommand.CreateAsyncObservable(this.SelectedUninstallables.CountChanged.Select(count => count != 0), x => DoUninstall());
            this.UninstallCommand.ObserveOn(RxApp.MainThreadScheduler).Subscribe(x => {
                this.Uninstallables.Clear();
                this.Uninstallables.AddRange(this.Refresh());
            });
            this.AboutCommand            = ReactiveCommand.CreateAsyncObservable(x => Observable.Return(!this.ShowAbout));
            this.showAbout               = this.AboutCommand.ToProperty(this, x => x.ShowAbout, false);
            this.ShowPackageCacheCommand = ReactiveCommand.CreateAsyncObservable(x => Observable.Return(!this.ShowPackageCache));
            this.showPackageCache        = this.ShowPackageCacheCommand.ToProperty(this, x => x.ShowPackageCache, false);
            this.MovePackageCacheCommand = ReactiveCommand.CreateAsyncObservable(x => OperatingSystemTasks.MovePackageCache(this.PackageCacheDestination));

            this.isBusy = this.WhenAnyObservable(
                x => x.TurnOffHyperVCommand.IsExecuting,
                x => x.CleanSetupLogsCommand.IsExecuting,
                x => x.UninstallCommand.IsExecuting,
                x => x.MovePackageCacheCommand.IsExecuting)
                          .ToProperty(this, x => x.IsBusy);
        }
Esempio n. 15
0
        public PullRequestDetailViewModel(
            IPullRequestService pullRequestsService,
            IPullRequestSessionManager sessionManager,
            IModelServiceFactory modelServiceFactory,
            IUsageTracker usageTracker,
            ITeamExplorerContext teamExplorerContext,
            IPullRequestFilesViewModel files,
            ISyncSubmodulesCommand syncSubmodulesCommand,
            IViewViewModelFactory viewViewModelFactory)
        {
            Guard.ArgumentNotNull(pullRequestsService, nameof(pullRequestsService));
            Guard.ArgumentNotNull(sessionManager, nameof(sessionManager));
            Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
            Guard.ArgumentNotNull(usageTracker, nameof(usageTracker));
            Guard.ArgumentNotNull(teamExplorerContext, nameof(teamExplorerContext));
            Guard.ArgumentNotNull(syncSubmodulesCommand, nameof(syncSubmodulesCommand));
            Guard.ArgumentNotNull(viewViewModelFactory, nameof(viewViewModelFactory));

            this.pullRequestsService   = pullRequestsService;
            this.sessionManager        = sessionManager;
            this.modelServiceFactory   = modelServiceFactory;
            this.usageTracker          = usageTracker;
            this.teamExplorerContext   = teamExplorerContext;
            this.syncSubmodulesCommand = syncSubmodulesCommand;
            this.viewViewModelFactory  = viewViewModelFactory;
            Files = files;

            Checkout = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.CheckoutState)
                .Cast <CheckoutCommandState>()
                .Select(x => x != null && x.IsEnabled),
                DoCheckout);
            Checkout.IsExecuting.Subscribe(x => isInCheckout = x);
            SubscribeOperationError(Checkout);

            Pull = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.PullEnabled),
                DoPull);
            SubscribeOperationError(Pull);

            Push = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.PushEnabled),
                DoPush);
            SubscribeOperationError(Push);

            SyncSubmodules = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.SyncSubmodulesEnabled),
                DoSyncSubmodules);
            SyncSubmodules.Subscribe(_ => Refresh().ToObservable());
            SubscribeOperationError(SyncSubmodules);

            OpenOnGitHub = ReactiveCommand.Create();
            ShowReview   = ReactiveCommand.Create().OnExecuteCompleted(DoShowReview);
        }
Esempio n. 16
0
        public GistCreationViewModel(
            IRepositoryHost repositoryHost,
            ISelectedTextProvider selectedTextProvider,
            IGistPublishService gistPublishService)
        {
            Title     = Resources.CreateGistTitle;
            apiClient = repositoryHost.ApiClient;
            this.gistPublishService = gistPublishService;

            FileName     = VisualStudio.Services.GetFileNameFromActiveDocument() ?? Resources.DefaultGistFileName;
            SelectedText = selectedTextProvider.GetSelectedText();

            // This class is only instantiated after we are logged into to a github account, so we should be safe to grab the first one here as the defaut.
            account = repositoryHost.ModelService.GetAccounts()
                      .FirstAsync()
                      .Select(a => a.First())
                      .ObserveOn(RxApp.MainThreadScheduler)
                      .ToProperty(this, vm => vm.Account);

            var canCreateGist = this.WhenAny(
                x => x.FileName,
                fileName => !String.IsNullOrEmpty(fileName.Value));

            CreateGist = ReactiveCommand.CreateAsyncObservable(canCreateGist, OnCreateGist);
        }
Esempio n. 17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PullRequestDetailViewModel"/> class.
        /// </summary>
        /// <param name="repositoryHost">The repository host.</param>
        /// <param name="teservice">The team explorer service.</param>
        /// <param name="pullRequestsService">The pull requests service.</param>
        /// <param name="avatarProvider">The avatar provider.</param>
        public PullRequestDetailViewModel(
            ILocalRepositoryModel repository,
            IModelService modelService,
            IPullRequestService pullRequestsService)
        {
            this.repository          = repository;
            this.modelService        = modelService;
            this.pullRequestsService = pullRequestsService;

            var canCheckout = this.WhenAnyValue(
                x => x.CheckoutMode,
                x => x.CheckoutDisabledMessage,
                (mode, disabled) => mode != CheckoutMode.UpToDate && mode != CheckoutMode.Push && disabled == null);

            Checkout = ReactiveCommand.CreateAsyncObservable(canCheckout, DoCheckout);

            OpenOnGitHub = ReactiveCommand.Create();

            ToggleChangedFilesView = ReactiveCommand.Create();
            ToggleChangedFilesView.Subscribe(_ =>
            {
                ChangedFilesViewType = ChangedFilesViewType == ChangedFilesViewType.TreeView ?
                                       ChangedFilesViewType.ListView : ChangedFilesViewType.TreeView;
            });

            ToggleOpenChangedFileAction = ReactiveCommand.Create();
            ToggleOpenChangedFileAction.Subscribe(_ =>
            {
                OpenChangedFileAction = OpenChangedFileAction == OpenChangedFileAction.Diff ?
                                        OpenChangedFileAction.Open : OpenChangedFileAction.Diff;
            });

            OpenFile = ReactiveCommand.Create();
            DiffFile = ReactiveCommand.Create();
        }
Esempio n. 18
0
        public async Task AllowsLoginFromEnterpriseAfterGitHubLoginHasFailed()
        {
            var connectionManager = Substitute.For <IConnectionManager>();

            var gitHubLogin        = Substitute.For <ILoginToGitHubViewModel>();
            var gitHubLoginCommand = ReactiveCommand.CreateAsyncObservable(_ =>
                                                                           Observable.Return(AuthenticationResult.CredentialFailure));

            gitHubLogin.Login.Returns(gitHubLoginCommand);

            var enterpriseLogin        = Substitute.For <ILoginToGitHubForEnterpriseViewModel>();
            var enterpriseLoginCommand = ReactiveCommand.CreateAsyncObservable(_ =>
                                                                               Observable.Return(AuthenticationResult.Success));

            enterpriseLogin.Login.Returns(enterpriseLoginCommand);

            var loginViewModel = new LoginControlViewModel(connectionManager, gitHubLogin, enterpriseLogin);
            var success        = false;

            loginViewModel.AuthenticationResults
            .Where(x => x == AuthenticationResult.Success)
            .Subscribe(_ => success = true);

            await gitHubLoginCommand.ExecuteAsync();

            await enterpriseLoginCommand.ExecuteAsync();

            Assert.True(success);
        }
Esempio n. 19
0
        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;
        }
Esempio n. 20
0
        public async Task ExecuteAsyncForwardsAsyncExceptionsToThrownExceptions()
        {
            var exception = new Exception("Aieeeee!");

            var command = ReactiveCommand.CreateAsyncObservable(_ => throwAsync(exception));

            await assertExceptionForwardedToThrownExceptions(command, exception);
        }
    // this was my first attempt without actually analyzing the current NavigateCommandFor source
    public static IReactiveCommand <object> NavigateCommandFor1 <T>(this RoutingState This, IReactiveCommand <object> navigationCommand = null, IDependencyResolver dependencyResolver = null, string contract = null)
        where T : IRoutableViewModel
    {
        navigationCommand = navigationCommand ?? This.Navigate;
        var ret = ReactiveCommand.CreateAsyncObservable(navigationCommand.CanExecuteObservable, _ => navigationCommand.ExecuteAsync((dependencyResolver ?? Locator.Current).GetService <T>(contract)));

        return(ret.SubscribeToCommand());
    }
Esempio n. 22
0
        public void ExecuteDoesNotThrowOnAsyncError()
        {
            var command = ReactiveCommand.CreateAsyncObservable(_ => ThrowAsync(new Exception("Aieeeee!")));

            command.ThrownExceptions.Subscribe();

            command.Execute(null);
        }
Esempio n. 23
0
        public async Task ExecuteAsyncThrowsExceptionOnError()
        {
            var exception = new Exception("Aieeeee!");

            var command = ReactiveCommand.CreateAsyncObservable(_ => ThrowSync(exception));

            await AssertThrowsOnExecuteAsync(command, exception);
        }
Esempio n. 24
0
        public void CanExecuteShouldChangeOnInflightOp()
        {
            (new TestScheduler()).With(sched => {
                var canExecute = sched.CreateHotObservable(
                    sched.OnNextAt(0, true),
                    sched.OnNextAt(250, false),
                    sched.OnNextAt(500, true),
                    sched.OnNextAt(750, false),
                    sched.OnNextAt(1000, true),
                    sched.OnNextAt(1100, false)
                    );

                var fixture = ReactiveCommand.CreateAsyncObservable(canExecute,
                                                                    x => Observable.Return((int)x * 5).Delay(TimeSpan.FromMilliseconds(900), RxApp.MainThreadScheduler));

                int calculatedResult  = -1;
                bool latestCanExecute = false;

                fixture.Subscribe(x => calculatedResult = x);

                fixture.CanExecuteObservable.Subscribe(x => latestCanExecute = x);

                // CanExecute should be true, both input observable is true
                // and we don't have anything inflight
                sched.AdvanceToMs(10);
                Assert.True(fixture.CanExecute(1));
                Assert.True(latestCanExecute);

                // Invoke a command 10ms in
                fixture.Execute(1);

                // At 300ms, input is false
                sched.AdvanceToMs(300);
                Assert.False(fixture.CanExecute(1));
                Assert.False(latestCanExecute);

                // At 600ms, input is true, but the command is still running
                sched.AdvanceToMs(600);
                Assert.False(fixture.CanExecute(1));
                Assert.False(latestCanExecute);

                // After we've completed, we should still be false, since from
                // 750ms-1000ms the input observable is false
                sched.AdvanceToMs(900);
                Assert.False(fixture.CanExecute(1));
                Assert.False(latestCanExecute);
                Assert.Equal(-1, calculatedResult);

                sched.AdvanceToMs(1010);
                Assert.True(fixture.CanExecute(1));
                Assert.True(latestCanExecute);
                Assert.Equal(calculatedResult, 5);

                sched.AdvanceToMs(1200);
                Assert.False(fixture.CanExecute(1));
                Assert.False(latestCanExecute);
            });
        }
        public PullRequestDetailViewModel(
            IPullRequestService pullRequestsService,
            IPullRequestSessionManager sessionManager,
            IModelServiceFactory modelServiceFactory,
            IUsageTracker usageTracker,
            ITeamExplorerContext teamExplorerContext,
            IStatusBarNotificationService statusBarNotificationService)
        {
            Guard.ArgumentNotNull(pullRequestsService, nameof(pullRequestsService));
            Guard.ArgumentNotNull(sessionManager, nameof(sessionManager));
            Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
            Guard.ArgumentNotNull(usageTracker, nameof(usageTracker));
            Guard.ArgumentNotNull(teamExplorerContext, nameof(teamExplorerContext));
            Guard.ArgumentNotNull(statusBarNotificationService, nameof(statusBarNotificationService));

            this.pullRequestsService          = pullRequestsService;
            this.sessionManager               = sessionManager;
            this.modelServiceFactory          = modelServiceFactory;
            this.usageTracker                 = usageTracker;
            this.teamExplorerContext          = teamExplorerContext;
            this.statusBarNotificationService = statusBarNotificationService;

            Checkout = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.CheckoutState)
                .Cast <CheckoutCommandState>()
                .Select(x => x != null && x.IsEnabled),
                DoCheckout);
            Checkout.IsExecuting.Subscribe(x => isInCheckout = x);
            SubscribeOperationError(Checkout);

            Pull = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.PullEnabled),
                DoPull);
            SubscribeOperationError(Pull);

            Push = ReactiveCommand.CreateAsyncObservable(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.PushEnabled),
                DoPush);
            SubscribeOperationError(Push);

            SyncSubmodules = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.UpdateState)
                .Cast <UpdateCommandState>()
                .Select(x => x != null && x.SyncSubmodulesEnabled),
                DoSyncSubmodules);
            SyncSubmodules.Subscribe(_ => Refresh().ToObservable());
            SubscribeOperationError(SyncSubmodules);

            OpenOnGitHub = ReactiveCommand.Create();
            DiffFile     = ReactiveCommand.Create();
            DiffFileWithWorkingDirectory = ReactiveCommand.Create(this.WhenAnyValue(x => x.IsCheckedOut));
            OpenFileInWorkingDirectory   = ReactiveCommand.Create(this.WhenAnyValue(x => x.IsCheckedOut));
            ViewFile = ReactiveCommand.Create();
        }
Esempio n. 26
0
        public LogoutRequiredViewModel(IRepositoryHosts repositoryHosts, INotificationService notificationService)
        {
            this.repositoryHosts     = repositoryHosts;
            this.notificationService = notificationService;

            Title  = Resources.LogoutRequiredTitle;
            Logout = ReactiveCommand.CreateAsyncObservable(OnLogout);
            Icon   = Octicon.mark_github;
        }
Esempio n. 27
0
        protected LoginTabViewModel(IRepositoryHosts repositoryHosts, IVisualStudioBrowser browser)
        {
            Guard.ArgumentNotNull(repositoryHosts, nameof(repositoryHosts));
            Guard.ArgumentNotNull(browser, nameof(browser));

            RepositoryHosts = repositoryHosts;

            UsernameOrEmailValidator = ReactivePropertyValidator.For(this, x => x.UsernameOrEmail)
                                       .IfNullOrEmpty(Resources.UsernameOrEmailValidatorEmpty)
                                       .IfMatch(@"\s", Resources.UsernameOrEmailValidatorSpaces);

            PasswordValidator = ReactivePropertyValidator.For(this, x => x.Password)
                                .IfNullOrEmpty(Resources.PasswordValidatorEmpty);

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

            Login = ReactiveCommand.CreateAsyncObservable(this.WhenAny(x => x.CanLogin, x => x.Value), LogIn);

            Login.ThrownExceptions.Subscribe(ex =>
            {
                if (ex.IsCriticalException())
                {
                    return;
                }

                log.Info(string.Format(CultureInfo.InvariantCulture, "Error logging into '{0}' as '{1}'", BaseUri, UsernameOrEmail), ex);

                if (ex is Octokit.ForbiddenException)
                {
                    Error = new UserError(Resources.LoginFailedForbiddenMessage, ex.Message);
                }
                else
                {
                    Error = new UserError(ex.Message);
                }
            });

            isLoggingIn = Login.IsExecuting.ToProperty(this, x => x.IsLoggingIn);

            Reset = ReactiveCommand.CreateAsyncTask(_ => Clear());

            NavigateForgotPassword = new RecoveryCommand(Resources.ForgotPasswordLink, _ =>
            {
                browser.OpenUrl(new Uri(BaseUri, GitHubUrls.ForgotPasswordPath));
                return(RecoveryOptionResult.RetryOperation);
            });

            SignUp = ReactiveCommand.CreateAsyncObservable(_ =>
            {
                browser.OpenUrl(GitHubUrls.Plans);
                return(Observable.Return(Unit.Default));
            });
        }
Esempio n. 28
0
        public void MakeSureReactiveCommandWorks2()
        {
            var rc    = ReactiveCommand.CreateAsyncObservable(_ => Observable.Return(false).Select(dummy => false));
            var value = true;

            rc.Subscribe(v => value = v);
            Assert.IsTrue(value);
            rc.Execute(null);
            Assert.IsFalse(value);
        }
Esempio n. 29
0
        public AuthViewModel()
        {
            Activator = new ViewModelActivator();
            var canSignIn = this.WhenAnyValue(x => x.Username, x => x.Password,
                                              (u, p) => !u.Empty() && !p.Empty());

            this.WhenActivated(d => {
                d(Avatar        = ReactiveCommand.CreateAsyncObservable(_ => GetAvatar()));
                d(SignIn        = ReactiveCommand.CreateAsyncObservable(canSignIn, _ => Authenticate()));
                d(Registration  = ReactiveCommand.Create());
                d(ResetPassword = ReactiveCommand.Create());

                // External links
                d(Registration.Subscribe(_ => Process.Start("http://hummingbird.me/users/sign_up")));
                d(ResetPassword.Subscribe(_ => Process.Start("http://hummingbird.me/users/password/new")));

                // Handle when signing in was successful
                d(SignIn.Subscribe(token => {
                    // Save the correct user data to the secure cache
                    var account      = Service.Get <Account>();
                    account.Username = Username;
                    account.Token    = token;
                    account.Save();

                    // Sign in was successful, Tell the MainView to change the content view
                    MessageBus.Current.SendMessage(new MediaViewModel() as ReactiveObject, "Content");
                }));

                // Handle when an exception is thrown during the sign in process
                d(SignIn.ThrownExceptions
                  .Select(x => {
                    if (x is ApiException)
                    {
                        var ex = x as ApiException;
                        if (ex.StatusCode == HttpStatusCode.Unauthorized)
                        {
                            return(new UserError("Check your credentials, and try again."));
                        }
                    }
                    return(new UserError("There was an issue authenticating with Hummingbird."));
                })
                  .SelectMany(UserError.Throw)
                  .Subscribe(_ => {
                    // Error was thrown to the handler, empty out the credentials
                    Username = "";
                    Password = "";

                    // will set the avatar back to blank hummingbird
                    Avatar.Execute(null);
                }));

                // Execute the Avatar command so that the default image is set on the view
                Avatar.Execute(null);
            });
        }
Esempio n. 30
0
        protected LoginTabViewModel(IRepositoryHosts repositoryHosts, IVisualStudioBrowser browser)
        {
            RepositoryHosts = repositoryHosts;

            UsernameOrEmailValidator = ReactivePropertyValidator.For(this, x => x.UsernameOrEmail)
                                       .IfNullOrEmpty("Please enter your username or email address")
                                       .IfMatch(@"\s", "Username or email address must not have spaces");

            PasswordValidator = ReactivePropertyValidator.For(this, x => x.Password)
                                .IfNullOrEmpty("Please enter your password");

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

            Login = ReactiveCommand.CreateAsyncObservable(this.WhenAny(x => x.CanLogin, x => x.Value), LogIn);

            Login.ThrownExceptions.Subscribe(ex =>
            {
                if (ex.IsCriticalException())
                {
                    return;
                }

                log.Info(string.Format(CultureInfo.InvariantCulture, "Error logging into '{0}' as '{1}'", BaseUri,
                                       UsernameOrEmail), ex);
                if (ex is Octokit.ForbiddenException)
                {
                    ShowLogInFailedError = true;
                    LoginFailedMessage   = "Make sure to use your password and not a Personal Access token to log in.";
                }
                else
                {
                    ShowConnectingToHostFailed = true;
                }
            });

            isLoggingIn = Login.IsExecuting.ToProperty(this, x => x.IsLoggingIn);

            Reset = ReactiveCommand.CreateAsyncTask(_ => Clear());

            NavigateForgotPassword = ReactiveCommand.CreateAsyncObservable(_ =>
            {
                browser.OpenUrl(new Uri(BaseUri, GitHubUrls.ForgotPasswordPath));
                return(Observable.Return(Unit.Default));
            });

            SignUp = ReactiveCommand.CreateAsyncObservable(_ =>
            {
                browser.OpenUrl(GitHubUrls.Plans);
                return(Observable.Return(Unit.Default));
            });
        }