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); }
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); }
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; }); })); }); }
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); }); }
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(); }
/// <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(); }
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 }); }
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); }
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); }
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); }
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); }
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); }
/// <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(); }
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); }
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 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()); }
public void ExecuteDoesNotThrowOnAsyncError() { var command = ReactiveCommand.CreateAsyncObservable(_ => ThrowAsync(new Exception("Aieeeee!"))); command.ThrownExceptions.Subscribe(); command.Execute(null); }
public async Task ExecuteAsyncThrowsExceptionOnError() { var exception = new Exception("Aieeeee!"); var command = ReactiveCommand.CreateAsyncObservable(_ => ThrowSync(exception)); await AssertThrowsOnExecuteAsync(command, exception); }
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(); }
public LogoutRequiredViewModel(IRepositoryHosts repositoryHosts, INotificationService notificationService) { this.repositoryHosts = repositoryHosts; this.notificationService = notificationService; Title = Resources.LogoutRequiredTitle; Logout = ReactiveCommand.CreateAsyncObservable(OnLogout); Icon = Octicon.mark_github; }
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)); }); }
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); }
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); }); }
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)); }); }