// The original source allows for un-registered view models to be new()'d
    // this extension provides that same ability, but again with a strongly typed return value
    public static IReactiveCommand <T> StrongNewNavigateCommandFor <T>(this RoutingState This, IReactiveCommand <object> navigationCommand = null, IDependencyResolver dependencyResolver = null, string contract = null)
        where T : IRoutableViewModel, new()
    {
        navigationCommand = navigationCommand ?? This.Navigate;
        var ret = new ReactiveCommand <T>(navigationCommand.CanExecuteObservable.Skip(1), _ => Observable.Return((T)((IRoutableViewModel)(dependencyResolver ?? Locator.Current).GetService <T>(contract) ?? new T())));

        ret.InvokeCommand(navigationCommand);
        return(ret);
    }
    // My attempt to optimize the return value to be strongly typed
    // I'm not sure if this has any implications
    public static IReactiveCommand <T> NavigateCommandFor3 <T>(this RoutingState This, IReactiveCommand <object> navigationCommand = null, IDependencyResolver dependencyResolver = null, string contract = null)
        where T : IRoutableViewModel
    {
        navigationCommand = navigationCommand ?? This.Navigate;
        var ret = new ReactiveCommand <T>(navigationCommand.CanExecuteObservable, _ => Observable.Return((dependencyResolver ?? Locator.Current).GetService <T>(contract)));

        ret.InvokeCommand(navigationCommand);

        return(ret.SubscribeToCommand());
    }
Ejemplo n.º 3
0
        public SearchViewModel(IScreen hostScreen, ILoginMethods loginMethods, [Named("UserAccount")] IBlobCache userCache)
        {
            HostScreen    = hostScreen;
            SearchResults = new ReactiveCollection <ISongTileViewModel>();
            var playApi = loginMethods.CurrentAuthenticatedClient;

            if (playApi == null)
            {
                hostScreen.Router.Navigate.Execute(RxApp.GetService <IWelcomeViewModel>());
                return;
            }

            var canSearch = this.WhenAny(x => x.SearchQuery, x => !String.IsNullOrWhiteSpace(x.Value));

            PerformSearch = new ReactiveAsyncCommand(canSearch);

            this.ObservableForProperty(x => x.SearchQuery)
            .Throttle(TimeSpan.FromMilliseconds(700), RxApp.DeferredScheduler)
            .InvokeCommand(PerformSearch);

            var searchResults = PerformSearch.RegisterAsyncObservable(_ =>
                                                                      userCache.GetOrFetchObject(
                                                                          "search__" + SearchQuery,
                                                                          () => playApi.Search(SearchQuery),
                                                                          RxApp.TaskpoolScheduler.Now + TimeSpan.FromMinutes(1.0)));

            SearchResults = searchResults
                            .Do(_ => SearchResults.Clear())
                            .SelectMany(list => list.ToObservable())
                            .LoggedCatch(this, Observable.Empty <Song>())
                            .CreateCollection(x => (ISongTileViewModel) new SongTileViewModel(x, playApi));

            PerformSearch.ItemsInflight.StartWith(0)
            .Select(x => x > 0 ? Visibility.Visible : Visibility.Hidden)
            .ToProperty(this, x => x.SearchBusySpinner);

            PerformSearch.ThrownExceptions.Subscribe(_ => { });

            GoBack = new ReactiveCommand();
            GoBack.InvokeCommand(hostScreen.Router.NavigateBack);
        }
Ejemplo n.º 4
0
        public SearchViewModel(IScreen hostScreen, ILoginMethods loginMethods)
        {
            HostScreen = hostScreen;
            SearchResults = new ReactiveCollection<ISongTileViewModel>();
            var playApi = loginMethods.CurrentAuthenticatedClient;

            if (playApi == null) {
                hostScreen.Router.Navigate.Execute(RxApp.GetService<IWelcomeViewModel>());
                return;
            }

            var canSearch = this.WhenAny(x => x.SearchQuery, x => !String.IsNullOrWhiteSpace(x.Value));
            PerformSearch = new ReactiveAsyncCommand(canSearch);

            this.ObservableForProperty(x => x.SearchQuery)
                .Throttle(TimeSpan.FromMilliseconds(700), RxApp.DeferredScheduler)
                .InvokeCommand(PerformSearch);

            var searchResults = PerformSearch.RegisterAsyncObservable(_ => playApi.Search(SearchQuery));

            SearchResults = searchResults
                .Do(_ => SearchResults.Clear())
                .SelectMany(list => list.ToObservable())
                .LoggedCatch(this, Observable.Empty<Song>())
                .CreateCollection(x => (ISongTileViewModel) new SongTileViewModel(x, playApi));

            PerformSearch.ItemsInflight.StartWith(0)
                .Select(x => x > 0 ? Visibility.Visible : Visibility.Collapsed)
                .ToProperty(this, x => x.SearchBusySpinner);

            PerformSearch.ThrownExceptions.Subscribe(_ => { });

            GoBack = new ReactiveCommand();
            GoBack.InvokeCommand(hostScreen.Router.NavigateBack);
        }
Ejemplo n.º 5
0
        public ProviderViewModel(
            CreateFolderViewModelFactory createFolder,
            RenameFileViewModelFactory createRename,
            FileViewModelFactory createFile,
            IAuthViewModel authViewModel,
            IFileManager fileManager,
            IProvider provider,
            IScheduler current,
            IScheduler main)
        {
            _provider = provider;
            Folder    = createFolder(this);
            Rename    = createRename(this);

            var canInteract = this
                              .WhenAnyValue(
                x => x.Folder.IsVisible,
                x => x.Rename.IsVisible,
                (folder, rename) => !folder && !rename);

            _canInteract = canInteract
                           .DistinctUntilChanged()
                           .ToProperty(this, x => x.CanInteract, scheduler: current);

            _refresh = ReactiveCommand.CreateFromTask(
                () => provider.Get(CurrentPath),
                canInteract, main);

            _files = _refresh
                     .Select(files => files
                             .Select(file => createFile(file, this))
                             .OrderByDescending(file => file.IsFolder)
                             .ThenBy(file => file.Name)
                             .ToList())
                     .StartWithEmpty()
                     .Where(files => Files == null ||
                            files.Count != Files.Count() ||
                            !files.All(x => Files.Any(y => x.Path == y.Path &&
                                                      x.Modified == y.Modified)))
                     .ToProperty(this, x => x.Files, scheduler: current);

            _isLoading = _refresh
                         .IsExecuting
                         .ToProperty(this, x => x.IsLoading, scheduler: current);

            _isReady = _refresh
                       .IsExecuting
                       .Select(executing => !executing)
                       .Skip(1)
                       .ToProperty(this, x => x.IsReady, scheduler: current);

            var canOpenCurrentPath = this
                                     .WhenAnyValue(x => x.SelectedFile)
                                     .Select(file => file != null && file.IsFolder)
                                     .CombineLatest(_refresh.IsExecuting, (folder, busy) => folder && !busy)
                                     .CombineLatest(canInteract, (open, interact) => open && interact);

            _open = ReactiveCommand.Create(
                () => Path.Combine(CurrentPath, SelectedFile.Name),
                canOpenCurrentPath, main);

            var canCurrentPathGoBack = this
                                       .WhenAnyValue(x => x.CurrentPath)
                                       .Select(path => path.Length > provider.InitialPath.Length)
                                       .CombineLatest(_refresh.IsExecuting, (valid, busy) => valid && !busy)
                                       .CombineLatest(canInteract, (back, interact) => back && interact);

            _back = ReactiveCommand.Create(
                () => Path.GetDirectoryName(CurrentPath),
                canCurrentPathGoBack, main);

            _currentPath = _open
                           .Merge(_back)
                           .DistinctUntilChanged()
                           .Log(this, $"Current path changed in {provider.Name}")
                           .ToProperty(this, x => x.CurrentPath, provider.InitialPath, scheduler: current);

            this.WhenAnyValue(x => x.CurrentPath)
            .Skip(1)
            .Select(path => Unit.Default)
            .InvokeCommand(_refresh);

            this.WhenAnyValue(x => x.CurrentPath)
            .Subscribe(path => SelectedFile = null);

            _isCurrentPathEmpty = this
                                  .WhenAnyValue(x => x.Files)
                                  .Skip(1)
                                  .Where(files => files != null)
                                  .Select(files => !files.Any())
                                  .ToProperty(this, x => x.IsCurrentPathEmpty, scheduler: current);

            _hasErrors = _refresh
                         .ThrownExceptions
                         .Select(exception => true)
                         .Merge(_refresh.Select(x => false))
                         .ToProperty(this, x => x.HasErrors, scheduler: current);

            var canUploadToCurrentPath = this
                                         .WhenAnyValue(x => x.CurrentPath)
                                         .Select(path => path != null)
                                         .CombineLatest(_refresh.IsExecuting, (up, loading) => up && !loading)
                                         .CombineLatest(canInteract, (upload, interact) => upload && interact);

            _uploadToCurrentPath = ReactiveCommand.CreateFromObservable(
                () => Observable
                .FromAsync(fileManager.OpenRead)
                .Where(response => response.Name != null && response.Stream != null)
                .Select(x => _provider.UploadFile(CurrentPath, x.Stream, x.Name))
                .SelectMany(task => task.ToObservable()),
                canUploadToCurrentPath,
                main);

            _uploadToCurrentPath.InvokeCommand(_refresh);

            var canDownloadSelectedFile = this
                                          .WhenAnyValue(x => x.SelectedFile)
                                          .Select(file => file != null && !file.IsFolder)
                                          .CombineLatest(_refresh.IsExecuting, (down, loading) => down && !loading)
                                          .CombineLatest(canInteract, (download, interact) => download && interact);

            _downloadSelectedFile = ReactiveCommand.CreateFromObservable(
                () => Observable
                .FromAsync(() => fileManager.OpenWrite(SelectedFile.Name))
                .Where(stream => stream != null)
                .Select(stream => _provider.DownloadFile(SelectedFile.Path, stream))
                .SelectMany(task => task.ToObservable()),
                canDownloadSelectedFile,
                main);

            var isAuthEnabled = provider.SupportsDirectAuth || provider.SupportsOAuth;
            var canLogout     = provider
                                .IsAuthorized
                                .Select(loggedIn => loggedIn && isAuthEnabled)
                                .DistinctUntilChanged()
                                .CombineLatest(canInteract, (logout, interact) => logout && interact)
                                .ObserveOn(main);

            _logout    = ReactiveCommand.CreateFromTask(provider.Logout, canLogout);
            _canLogout = canLogout
                         .ToProperty(this, x => x.CanLogout, scheduler: current);

            var canDeleteSelection = this
                                     .WhenAnyValue(x => x.SelectedFile)
                                     .Select(file => file != null && !file.IsFolder)
                                     .CombineLatest(_refresh.IsExecuting, (del, loading) => del && !loading)
                                     .CombineLatest(canInteract, (delete, interact) => delete && interact);

            _deleteSelectedFile = ReactiveCommand.CreateFromTask(
                () => provider.Delete(SelectedFile.Path, SelectedFile.IsFolder),
                canDeleteSelection);

            _deleteSelectedFile.InvokeCommand(Refresh);

            var canUnselectFile = this
                                  .WhenAnyValue(x => x.SelectedFile)
                                  .Select(selection => selection != null)
                                  .CombineLatest(_refresh.IsExecuting, (sel, loading) => sel && !loading)
                                  .CombineLatest(canInteract, (unselect, interact) => unselect && interact);

            _unselectFile = ReactiveCommand.Create(
                () => { SelectedFile = null; },
                canUnselectFile);

            _uploadToCurrentPath
            .ThrownExceptions
            .Merge(_deleteSelectedFile.ThrownExceptions)
            .Merge(_downloadSelectedFile.ThrownExceptions)
            .Merge(_refresh.ThrownExceptions)
            .Log(this, $"Exception occured in provider {provider.Name}")
            .Subscribe();

            Auth      = authViewModel;
            Activator = new ViewModelActivator();
            this.WhenActivated(disposable =>
            {
                this.WhenAnyValue(x => x.Auth.IsAuthenticated)
                .Where(authenticated => authenticated)
                .Select(ignore => Unit.Default)
                .InvokeCommand(_refresh)
                .DisposeWith(disposable);

                var interval = TimeSpan.FromSeconds(1);
                Observable.Timer(interval, interval)
                .Select(unit => RefreshingIn - 1)
                .Where(value => value >= 0)
                .ObserveOn(main)
                .Subscribe(x => RefreshingIn = x)
                .DisposeWith(disposable);

                this.WhenAnyValue(x => x.RefreshingIn)
                .Skip(1)
                .Where(refreshing => refreshing == 0)
                .Log(this, $"Refreshing provider {provider.Name} path {CurrentPath}")
                .Select(value => Unit.Default)
                .InvokeCommand(_refresh)
                .DisposeWith(disposable);

                const int refreshPeriod = 30;
                _refresh.Select(results => refreshPeriod)
                .StartWith(refreshPeriod)
                .Subscribe(x => RefreshingIn = x)
                .DisposeWith(disposable);

                this.WhenAnyValue(x => x.CanInteract)
                .Skip(1)
                .Where(interact => interact)
                .Select(x => Unit.Default)
                .InvokeCommand(_refresh);
            });
        }
Ejemplo n.º 6
0
        public CpTabViewModel(SimulationOptions options) : base("Порівняння")
        {
            var logger = Logger.New(typeof(CpTabViewModel));

            using (logger.LogPerf("Init"))
            {
                InitComponents(options);

                m_Player = new Player(() =>
                {
                    Simulate(0.05d);
                }, () =>
                {
                    for (int i = 0; i < 50; i++)
                    {
                        Simulate();
                    }
                }, () =>
                {
                    UpdateVisualization.Execute().Subscribe();
                }, TimeSpan.FromMilliseconds(10), DispatcherPriority.ContextIdle);

                UpdateVisualization = ReactiveCommand.Create(() =>
                {
                    using (logger.LogPerf("Visualization"))
                    {
                        PrVisualization   = m_Visualizer.GenerateTableVisualization(m_PrSimulator.GetData());
                        StVisualization   = m_Visualizer.GenerateEdgeTableVisualization(m_StSimulator.GetData());
                        DiffVisualization = m_Visualizer.GenerateEdgeTableVisualization(m_DiffGenerator.GetData());

                        PrSimulationInfo = m_PrSimulator.SimulationInfo;
                        StSimulationInfo = m_StSimulator.SimulationInfo;
                    }
                });

                var notRunningOrPlaying = m_Player.WhenAny(x => x.RunningOrPlaying, r => !r.Value);

                var notSingleStepRunning = m_Player.WhenAny(x => x.SingleStepRunning, r => !r.Value);

                SimulateStep = ReactiveCommand.Create(() =>
                {
                    m_Player.StepOnce();
                }, notRunningOrPlaying);

                PlayPause = new ReactivePlayPauseCommand("Програти", "Пауза", notSingleStepRunning);

                PlayPause.Subscribe(p =>
                {
                    if (p)
                    {
                        m_Player.Start();
                    }
                    else
                    {
                        m_Player.Stop();
                    }
                });

                Restart = ReactiveCommand.Create(() =>
                {
                    m_PrSimulator.Reset();
                    m_StSimulator.Reset();
                }, notRunningOrPlaying);

                Restart.InvokeCommand(UpdateVisualization);

                OpenSimualationOptions = ReactiveCommand.Create(() =>
                {
                    SimulationOptionsDialog dialog = new SimulationOptionsDialog(SimulationOptions.FromSimulator(m_PrSimulator));
                    dialog.ShowDialog();

                    if (dialog.DialogResult.GetValueOrDefault(false))
                    {
                        SimulationOptions result = dialog.SimulationOptions;
                        InitComponents(result);
                    }
                }, notRunningOrPlaying);

                OpenSimualationOptions.InvokeCommand(UpdateVisualization);

                Settings.SettingsChange
                .InvokeCommand(UpdateVisualization);

                UpdateVisualization.Execute().Subscribe();
            }
        }
Ejemplo n.º 7
0
        public RenameFileViewModel(
            IProviderViewModel providerViewModel,
            IProvider provider,
            IScheduler current,
            IScheduler main)
        {
            _oldName = providerViewModel
                       .WhenAnyValue(x => x.SelectedFile)
                       .Select(file => file?.Name)
                       .ToProperty(this, x => x.OldName, scheduler: current);

            var canInteract = providerViewModel
                              .WhenAnyValue(x => x.CanInteract);

            var oldNameValid = this
                               .WhenAnyValue(x => x.OldName)
                               .Select(old => !string.IsNullOrWhiteSpace(old));

            var canOpen = this
                          .WhenAnyValue(x => x.IsVisible)
                          .Select(visible => !visible)
                          .CombineLatest(oldNameValid, (visible, old) => visible && old)
                          .CombineLatest(canInteract, (open, interact) => open && interact);

            _open = ReactiveCommand.Create(
                () => { IsVisible = true; },
                canOpen, main);

            var canClose = this
                           .WhenAnyValue(x => x.IsVisible)
                           .Select(visible => visible);

            _close = ReactiveCommand.Create(
                () => { IsVisible = false; },
                canClose, main);

            var canRename = this
                            .WhenAnyValue(x => x.NewName)
                            .Select(name => !string.IsNullOrWhiteSpace(name))
                            .CombineLatest(oldNameValid, (old, name) => old && name);

            _rename = ReactiveCommand.CreateFromTask(
                () => provider.RenameFile(providerViewModel.SelectedFile.Path, NewName),
                canRename, main);

            _isLoading = _rename
                         .IsExecuting
                         .ToProperty(this, x => x.IsLoading, scheduler: current);

            _hasErrors = _rename
                         .ThrownExceptions
                         .Select(exception => true)
                         .Merge(_close.Select(x => false))
                         .ToProperty(this, x => x.HasErrors, scheduler: current);

            _errorMessage = _rename
                            .ThrownExceptions
                            .Select(exception => exception.Message)
                            .Log(this, $"Rename file error occured in {provider.Name} for {OldName}")
                            .Merge(_close.Select(x => string.Empty))
                            .ToProperty(this, x => x.ErrorMessage, scheduler: current);

            _rename.InvokeCommand(_close);
            _close.Subscribe(x => NewName = string.Empty);
        }
Ejemplo n.º 8
0
        public ProviderViewModel(
            IAuthViewModel authViewModel,
            IFileManager fileManager,
            IScheduler currentThread,
            IScheduler mainThread,
            IProvider provider)
        {
            _provider = provider;
            _refresh  = ReactiveCommand.CreateFromTask(
                () => provider.Get(CurrentPath),
                outputScheduler: mainThread);

            _files = _refresh
                     .Select(files => files
                             .OrderByDescending(file => file.IsFolder)
                             .ThenBy(file => file.Name)
                             .ToList())
                     .StartWithEmpty()
                     .ToProperty(this, x => x.Files, scheduler: currentThread);

            _isLoading = _refresh
                         .IsExecuting
                         .ToProperty(this, x => x.IsLoading, scheduler: currentThread);

            _isReady = _refresh
                       .IsExecuting
                       .Select(executing => !executing)
                       .Skip(1)
                       .ToProperty(this, x => x.IsReady, scheduler: currentThread);

            var canOpenCurrentPath = this
                                     .WhenAnyValue(x => x.SelectedFile)
                                     .Select(file => file != null && file.IsFolder)
                                     .CombineLatest(_refresh.IsExecuting, (folder, busy) => folder && !busy);

            _open = ReactiveCommand.Create(
                () => Path.Combine(CurrentPath, SelectedFile.Name),
                canOpenCurrentPath, mainThread);

            var canCurrentPathGoBack = this
                                       .WhenAnyValue(x => x.CurrentPath)
                                       .Select(path => path.Length > provider.InitialPath.Length)
                                       .CombineLatest(_refresh.IsExecuting, (valid, busy) => valid && !busy);

            _back = ReactiveCommand.Create(
                () => Path.GetDirectoryName(CurrentPath),
                canCurrentPathGoBack, mainThread);

            _currentPath = _open
                           .Merge(_back)
                           .DistinctUntilChanged()
                           .ToProperty(this, x => x.CurrentPath, provider.InitialPath, scheduler: currentThread);

            this.WhenAnyValue(x => x.CurrentPath)
            .Skip(1)
            .Select(path => Unit.Default)
            .InvokeCommand(_refresh);

            this.WhenAnyValue(x => x.CurrentPath)
            .Subscribe(path => SelectedFile = null);

            _isCurrentPathEmpty = this
                                  .WhenAnyValue(x => x.Files)
                                  .Skip(2)
                                  .Where(files => files != null)
                                  .Select(files => !files.Any())
                                  .ToProperty(this, x => x.IsCurrentPathEmpty, scheduler: currentThread);

            _hasErrors = _refresh
                         .ThrownExceptions
                         .Select(exception => true)
                         .Merge(_refresh.Select(x => false))
                         .ToProperty(this, x => x.HasErrors, scheduler: currentThread);

            var canUploadToCurrentPath = this
                                         .WhenAnyValue(x => x.CurrentPath)
                                         .Select(path => path != null)
                                         .DistinctUntilChanged();

            _uploadToCurrentPath = ReactiveCommand.CreateFromObservable(
                () => Observable
                .FromAsync(fileManager.OpenRead)
                .Where(response => response.Name != null && response.Stream != null)
                .Select(x => _provider.UploadFile(CurrentPath, x.Stream, x.Name))
                .SelectMany(task => task.ToObservable()),
                canUploadToCurrentPath,
                mainThread);

            _uploadToCurrentPath.InvokeCommand(_refresh);

            var canDownloadSelectedFile = this
                                          .WhenAnyValue(x => x.SelectedFile)
                                          .Select(file => file != null && !file.IsFolder)
                                          .DistinctUntilChanged();

            _downloadSelectedFile = ReactiveCommand.CreateFromObservable(
                () => Observable
                .FromAsync(() => fileManager.OpenWrite(SelectedFile.Name))
                .Where(stream => stream != null)
                .Select(stream => _provider.DownloadFile(SelectedFile.Path, stream))
                .SelectMany(task => task.ToObservable()),
                canDownloadSelectedFile,
                mainThread);

            _uploadToCurrentPath
            .ThrownExceptions
            .Merge(_downloadSelectedFile.ThrownExceptions)
            .Subscribe(Console.WriteLine);

            this.WhenAnyValue(x => x.SelectedFile)
            .Where(file => file != null && file.IsFolder)
            .Buffer(2, 1)
            .Select(files => (files.First().Path, files.Last().Path))
            .DistinctUntilChanged()
            .Where(x => x.Item1 == x.Item2)
            .Select(ignore => Unit.Default)
            .InvokeCommand(_open);

            var isAuthEnabled = provider.SupportsDirectAuth || provider.SupportsOAuth;
            var canLogout     = provider
                                .IsAuthorized
                                .Select(loggedIn => loggedIn && isAuthEnabled)
                                .DistinctUntilChanged()
                                .ObserveOn(mainThread);

            _logout    = ReactiveCommand.CreateFromTask(provider.Logout, canLogout);
            _canLogout = canLogout
                         .ToProperty(this, x => x.CanLogout, scheduler: currentThread);

            var canDeleteSelection = this
                                     .WhenAnyValue(x => x.SelectedFile)
                                     .Select(file => file != null && !file.IsFolder);

            _deleteSelectedFile = ReactiveCommand.CreateFromTask(
                () => provider.Delete(SelectedFile),
                canDeleteSelection);

            _deleteSelectedFile.InvokeCommand(Refresh);

            Auth      = authViewModel;
            Activator = new ViewModelActivator();
            this.WhenActivated(disposable =>
            {
                this.WhenAnyValue(x => x.Auth.IsAuthenticated)
                .Where(authenticated => authenticated)
                .Select(ignore => Unit.Default)
                .InvokeCommand(_refresh)
                .DisposeWith(disposable);
            });
        }
Ejemplo n.º 9
0
        public CreateFolderViewModel(
            IProviderViewModel providerViewModel,
            IProvider provider,
            IScheduler current,
            IScheduler main)
        {
            _path = providerViewModel
                    .WhenAnyValue(x => x.CurrentPath)
                    .ToProperty(this, x => x.Path, scheduler: current);

            var canInteract = providerViewModel
                              .WhenAnyValue(x => x.CanInteract);

            var pathValid = this
                            .WhenAnyValue(x => x.Path)
                            .Select(path => !string.IsNullOrWhiteSpace(path));

            var canCreateFolder = this
                                  .WhenAnyValue(x => x.Name)
                                  .Select(name => !string.IsNullOrWhiteSpace(name))
                                  .CombineLatest(pathValid, (name, path) => name && path);

            _create = ReactiveCommand.CreateFromTask(
                () => provider.CreateFolder(Path, Name),
                canCreateFolder, main);

            var canCreate = Observable.Return(provider.CanCreateFolder);
            var canOpen   = this
                            .WhenAnyValue(x => x.IsVisible)
                            .Select(visible => !visible)
                            .CombineLatest(canCreate, pathValid, (visible, can, path) => visible && path && can)
                            .CombineLatest(canInteract, (open, interact) => open && interact);

            _open = ReactiveCommand.Create(
                () => { IsVisible = true; },
                canOpen, main);

            var canClose = this
                           .WhenAnyValue(x => x.IsVisible)
                           .Select(visible => visible);

            _close = ReactiveCommand.Create(
                () => { IsVisible = false; },
                canClose, main);

            _create.InvokeCommand(_close);
            _close.Subscribe(x => Name = string.Empty);

            _hasErrors = _create
                         .ThrownExceptions
                         .Select(exception => true)
                         .Merge(_close.Select(unit => false))
                         .ToProperty(this, x => x.HasErrors, scheduler: current);

            _errorMessage = _create
                            .ThrownExceptions
                            .Select(exception => exception.Message)
                            .Log(this, $"Create folder error occured in {provider.Name}")
                            .Merge(_close.Select(unit => string.Empty))
                            .ToProperty(this, x => x.ErrorMessage, scheduler: current);

            _isLoading = _create
                         .IsExecuting
                         .ToProperty(this, x => x.IsLoading, scheduler: current);
        }