예제 #1
0
        private static ReactiveCommand FireCommandEx(
            IGeneralBus bus,
            Func <Object, Command> commandFunc,
            IObservable <bool> canExecute = null,
            IScheduler scheduler          = null,
            string userErrorMsg           = null,
            TimeSpan?responseTimeout      = null,
            TimeSpan?ackTimeout           = null)
        {
            if (scheduler == null)
            {
                scheduler = RxApp.MainThreadScheduler;
            }
            Func <object, Task> task = async _ => await Task.Run(() =>
            {
                var c = commandFunc(_);
                if (c != null)
                {
                    bus.Fire(c, userErrorMsg, responseTimeout, ackTimeout);
                }
            });

            var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler);

            cmd.ThrownExceptions
            .SelectMany(ex => UserError.Throw(userErrorMsg ?? ex.Message, ex))
            .ObserveOn(MainThreadScheduler).Subscribe(result =>
            {
                //This will return the recovery option returned from the registered user error handler
                //right now this is a simple message box in the view code behind
                /* n.b. this forces evaluation/execution of the select many  */
            });
            return(cmd);
        }
예제 #2
0
        public ConnectViewModel()
        {
            ConnectText = new ReactiveProperty <string>("Connect");

            Host = new ReactiveProperty <string>("127.0.0.1:3306").SetValidateNotifyError(x =>
                                                                                          ConnectViewModelValidation.Host.Validate(x).ErrorMessages.FirstOrDefault());

            Username = new ReactiveProperty <string>("root").SetValidateNotifyError(x =>
                                                                                    ConnectViewModelValidation.Username.Validate(x).ErrorMessages.FirstOrDefault());

            Password = new ReactiveProperty <string>("").SetValidateNotifyError(x =>
                                                                                ConnectViewModelValidation.Password.Validate(x).ErrorMessages.FirstOrDefault());

            Database = new ReactiveProperty <string>("").SetValidateNotifyError(x =>
                                                                                ConnectViewModelValidation.Database.Validate(x).ErrorMessages.FirstOrDefault());

            ResourcePath = new ReactiveProperty <string>("")
                           .SetValidateNotifyError(x =>
                                                   ConnectViewModelValidation.ResourcePath.Validate(x).ErrorMessages.FirstOrDefault());

            var canConnect = this.WhenAnyValue(x => x.Host.Value, x => x.Username.Value, x => x.Password.Value,
                                               x => x.Database.Value, x => x.ResourcePath.Value)
                             .Select(_ => ConnectViewModelValidation.MySql.Validate(this).Succeeded);

            Connect            = ReactiveCommand.CreateFromTask(ConnectImpl, canConnect);
            Exit               = ReactiveCommand.Create(ExitImpl);
            SelectResourceFile = ReactiveCommand.CreateFromTask(SelectResourceFileImpl);
        }
예제 #3
0
        private static ReactiveCommand PublishEvents(
            IBus bus,
            IEnumerable <Func <Event> > events,
            IObservable <bool> canExecute = null,
            IScheduler scheduler          = null,
            string userErrorMsg           = null)
        {
            if (scheduler == null)
            {
                scheduler = RxApp.MainThreadScheduler;
            }
            Func <object, Task> task = async _ => await Task.Run(() =>
            {
                foreach (var func in events)
                {
                    bus.Publish(func());
                }
            });

            var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler);

            cmd.ThrownExceptions
            .SelectMany(ex => UserError.Throw(userErrorMsg ?? ex.Message, ex))
            .ObserveOn(MainThreadScheduler).Subscribe(result =>
            {
                //This will return the recovery option returned from the registered user error handler
                //right now this is a simple message box in the view code behind
                /* n.b. this forces evaluation/execution of the select many  */
            });
            return(cmd);
        }
예제 #4
0
        private ReactiveCommand GetSelectSourceFileCommand()
        {
            var command = ReactiveCommand.Create(SelectSourceFile, null, DispatcherScheduler.Current);

            _disposables.Add(command);
            return(command);
        }
예제 #5
0
        private static ReactiveCommand FireCommands(
            ICommandPublisher bus,
            IEnumerable <Func <Command> > commands,
            IObservable <bool> canExecute = null,
            IScheduler scheduler          = null,
            string userErrorMsg           = null,
            TimeSpan?responseTimeout      = null,
            TimeSpan?ackTimeout           = null)
        {
            if (scheduler == null)
            {
                scheduler = RxApp.MainThreadScheduler;
            }
            Func <object, Task> task = async _ => await Task.Run(() =>
            {
                foreach (var func in commands)
                {
                    bus.Send(func(), userErrorMsg, responseTimeout, ackTimeout);
                }
            });

            var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler);

            cmd.ThrownExceptions
#pragma warning disable CS0618 // Type or member is obsolete
            .SelectMany(ex => UserError.Throw(userErrorMsg, ex))
#pragma warning restore CS0618 // Type or member is obsolete
            .ObserveOn(MainThreadScheduler).Subscribe(result =>
            {
                //This will return the recovery option returned from the registered user error handler
                //right now this is a simple message box in the view code behind
                /* n.b. this forces evaluation/execution of the select many  */
            });
            return(cmd);
        }
        public SelectItemViewModel()
        {
            Search       = new ReactiveProperty <string>();
            Items        = new ReactiveList <Item>();
            SelectedItem = new ReactiveProperty <Item>();
            Search.WhenAnyValue(x => x.Value)
            .Throttle(TimeSpan.FromSeconds(1))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(search =>
            {
                Items.Clear();

                // It's not possible to add an item more than once so remove existing shop items from the search
                var items = ResourceService.Instance.Items.Where(item =>
                                                                 ShopService.Instance.Items.All(x => x.ItemNumber != item.ItemNumber));

                if (!string.IsNullOrWhiteSpace(search))
                {
                    var split = search.Split(' ');
                    items     = items.Where(item =>
                                            split.All(word => item.Name.Contains(word, StringComparison.OrdinalIgnoreCase)));
                }

                Items.AddRange(items);
            });

            var canSelect = SelectedItem.WhenAnyValue(x => x.Value).Select(x => x != null);

            Select = ReactiveCommand.Create(SelectImpl, canSelect);
            Cancel = ReactiveCommand.Create(CancelImpl);
        }
예제 #7
0
        public YoutubeSongViewModel(YoutubeSong wrapped, Func <string> downloadPathFunc)
            : base(wrapped)
        {
            this.hasThumbnail = this.WhenAnyValue(x => x.Thumbnail)
                                .Select(x => x != null)
                                .ToProperty(this, x => x.HasThumbnail);

            // Wait for the opening of the context menu to download the YouTube information
            this.WhenAnyValue(x => x.IsContextMenuOpen)
            .FirstAsync(x => x)
            .SelectMany(_ => this.LoadContextMenu().ToObservable())
            .Subscribe();

            // We have to set a dummy here, so that we can connect the commands
            this.isDownloading = Observable.Never <bool>().ToProperty(this, x => x.IsDownloading);

            this.DownloadVideoCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.IsDownloading).Select(x => !x),
                                                                        x => this.DownloadVideo((VideoInfo)x, downloadPathFunc()));

            this.DownloadAudioCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.IsDownloading).Select(x => !x),
                                                                        x => this.DownloadAudio((VideoInfo)x, downloadPathFunc()));

            this.isDownloading = this.DownloadVideoCommand.IsExecuting
                                 .CombineLatest(this.DownloadAudioCommand.IsExecuting, (x1, x2) => x1 || x2)
                                 .ToProperty(this, x => x.IsDownloading);
        }
예제 #8
0
        private static ReactiveCommand FromAction(
            Action <object> action,
            IObservable <bool> canExecute = null,
            IScheduler scheduler          = null,
            string userErrorMsg           = null)
        {
            if (scheduler == null)
            {
                scheduler = RxApp.MainThreadScheduler;
            }
            Func <object, Task> task = async _ => await Task.Run(() => action(_));

            var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler);

            cmd.ThrownExceptions
#pragma warning disable CS0618 // Type or member is obsolete
            .ObserveOn(MainThreadScheduler).SelectMany(ex => UserError.Throw(userErrorMsg ?? ex.Message, ex))
#pragma warning restore CS0618 // Type or member is obsolete
            .Subscribe(result =>
            {
                //This will return the recovery option returned from the registered user error handler
                //right now this is a simple message box in the view code behind
                /* n.b. this forces evaluation/execution of the select many  */
            });
            return(cmd);
        }
예제 #9
0
        private static ReactiveCommand <object, Unit> PublishEventsEx(
            IPublisher bus,
            IEnumerable <Func <object, Event> > eventFuncs,
            IObservable <bool> canExecute = null,
            IScheduler scheduler          = null,
            string userErrorMsg           = null)
        {
            if (scheduler == null)
            {
                scheduler = RxApp.MainThreadScheduler;
            }
            Func <object, Task> task = async x => await Task.Run(() =>
            {
                foreach (var func in eventFuncs)
                {
                    bus.Publish(func(x));
                }
            });

            var cmd =
                canExecute == null?
                ReactiveCommand.CreateFromTask(task, outputScheduler : scheduler) :
                    ReactiveCommand.CreateFromTask(task, canExecute, scheduler);

            cmd.ThrownExceptions
            .SelectMany(ex => Interactions.Errors.Handle(new UserError(userErrorMsg ?? ex.Message, ex)))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(result =>
            {
                // This will return the recovery option returned from the registered user error handler,
                // e.g. a simple message box in the view code behind
                /* n.b. this forces evaluation/execution of the select many  */
            });
            return(cmd);
        }
예제 #10
0
        public SettingsViewModel(IUserInterface userInterface,
                                 IUserDialogs userDialogs,
                                 IDotaClientDistanceLoader distanceLoader,
                                 ISettingsManager <Settings> settingsManager)
        {
            _userDialogs = userDialogs;
            Settings     = settingsManager.LoadAsync().ToObservable().ToReactiveProperty();

            SaveSettingsCommand = ReactiveCommand.CreateFromTask <Settings>(settingsManager.SaveAsync);

            ToggleDarkModeCommand = ReactiveCommand.Create <bool>(userInterface.DarkMode);

            LoadDistanceCommand = ReactiveCommand.CreateFromTask <Settings>(distanceLoader.LoadAsync);

            BrowseDota2FolderCommand = ReactiveCommand.CreateFromTask(OpenFolderDialog);

            BrowseDota2FolderCommand.Where(value => !string.IsNullOrWhiteSpace(value))
            .SubscribeOnUIDispatcher()
            .Subscribe(value => Settings.Value.Dota2FolderPath = value);

            this.WhenAnyValue(vm => vm.Settings.Value.DarkMode)
            .InvokeCommand(ToggleDarkModeCommand);

            this.WhenAnyValue(vm => vm.Settings.Value.Dota2FolderPath)
            .Where(value => !string.IsNullOrWhiteSpace(value))
            .Select(_ => Settings.Value)
            .ObserveOnUIDispatcher()
            .InvokeCommand(LoadDistanceCommand);
        }
예제 #11
0
        public MainWindowViewModel()
        {
            TorrentSelected = new ReactiveCommand();
            DownloadAll = new ReactiveAsyncCommand();
            DeleteSelected = new ReactiveAsyncCommand();

            DeleteSelected.Subscribe(new AnonymousObserver<object>(x =>
            {
                App.streamza.RemoveTorrent(_selectedTorrent.id);
            }));

            DownloadAll.Subscribe(new AnonymousObserver<object>(x =>
            {
                var sel = _selectedTorrent;
                var s = new VistaFolderBrowserDialog();
                var res = s.ShowDialog();
                if (!res.HasValue || res.Value != true) return;

                var files = App.streamza.GetTorrentFiles(sel);
                foreach (var file in files)
                {
                    var uri = App.streamza.GetDownloadLink(file);
                    var cl = new WebClient();
                    var path = Path.Combine(s.SelectedPath, file.path);
                    if (!Directory.Exists(Path.GetDirectoryName(path)))
                        Directory.CreateDirectory(Path.GetDirectoryName(path));
                    cl.DownloadFile(new Uri(uri), path);
                }

                // This probably works best when there are lots of small files; doesn't
                // offer any improvement when there are only a couple of large files.
                // TODO: Check file count and set parallelism appropriately
                //Parallel.ForEach(files,
                //    new ParallelOptions { MaxDegreeOfParallelism = 4 },
                //    (file) =>
                //    {
                //        var uri = App.streamza.GetDownloadLink(file);
                //        var cl = new WebClient();
                //        var path = Path.Combine(s.SelectedPath, file.path);
                //        if (!Directory.Exists(Path.GetDirectoryName(path)))
                //            Directory.CreateDirectory(Path.GetDirectoryName(path));
                //        cl.DownloadFile(new Uri(uri), path);
                //    });
            }));

            _torrents = App.streamza.Torrents;

            Observable
                .Start(() =>
                {
                    Observable
                         .Interval(TimeSpan.FromSeconds(10))
                         .Subscribe(i =>
                         {
                             if (FetchingFiles) return;
                             _torrents = App.streamza.Torrents;
                             raisePropertyChanged("Torrents");
                         });
                });
        }
        public SelectEffectViewModel()
        {
            Search         = new ReactiveProperty <string>();
            Effects        = new ReactiveList <Effect>();
            SelectedEffect = new ReactiveProperty <Effect>();
            Search.WhenAnyValue(x => x.Value)
            .Throttle(TimeSpan.FromSeconds(1))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(search =>
            {
                Effects.Clear();
                if (string.IsNullOrWhiteSpace(search))
                {
                    Effects.AddRange(ResourceService.Instance.Effects);
                    return;
                }

                var split   = search.Split(' ');
                var effects = ResourceService.Instance.Effects
                              .Where(effect => split.All(word => effect.Name.Contains(word, StringComparison.OrdinalIgnoreCase)))
                              .ToArray();
                Effects.AddRange(effects);
            });

            var canSelect = SelectedEffect.WhenAnyValue(x => x.Value).Select(x => x != null);

            Select = ReactiveCommand.Create(SelectImpl, canSelect);
            Cancel = ReactiveCommand.Create(CancelImpl);
        }
예제 #13
0
        private ReactiveCommand GetStartCalculationCommand()
        {
            var canExecuteObservable = CanStartCalculationExecuteObservable();
            var command = ReactiveCommand.Create(StartCalculation, canExecuteObservable, DispatcherScheduler.Current);

            _disposables.Add(command);
            return(command);
        }
예제 #14
0
        protected JobViewModelBase(T job, IScheduler scheduler)
        {
            Job            = job;
            _scheduler     = scheduler;
            _preChangeName = job.Name;

            Save = ReactiveCommand.Create(ExecuteSave, this.WhenAny(x => x.ValidationError, x => string.IsNullOrEmpty(x.Value)));
        }
예제 #15
0
        public DownloadItemViewModel(Job job)
        {
            Job = job;
            Job.WhenAnyValue(j => j.Status).StartWith(job.Status).Subscribe(OnStatusUpdated);

            // update progress every 300ms
            Job.WhenAnyValue(j => j.TransferPercent)
            .Sample(TimeSpan.FromMilliseconds(300))
            .Where(x => !job.IsFinished)
            .Subscribe(progress => {
                // on main thread
                System.Windows.Application.Current.Dispatcher.Invoke(() => {
                    DownloadPercent          = progress;
                    DownloadPercentFormatted = $"{Math.Round(DownloadPercent)}%";
                });
            });

            // update download speed every 1.5 seconds
            var  lastUpdatedProgress = DateTime.Now;
            long bytesReceived       = 0;

            Job.WhenAnyValue(j => j.TransferPercent)
            .Sample(TimeSpan.FromMilliseconds(1500))
            .Where(x => !job.IsFinished)
            .Subscribe(progress => {
                // on main thread
                System.Windows.Application.Current.Dispatcher.Invoke(() => {
                    var timespan = DateTime.Now - lastUpdatedProgress;
                    var bytespan = Job.TransferredBytes - bytesReceived;

                    if (timespan.TotalMilliseconds > 0)
                    {
                        var downloadSpeed      = 1000 * bytespan / timespan.TotalMilliseconds;
                        DownloadSpeedFormatted = $"{downloadSpeed.Bytes().ToString("#.0")}/s";
                    }

                    bytesReceived       = Job.TransferredBytes;
                    lastUpdatedProgress = DateTime.Now;
                });
            });

            // update initial size only once
            Job.WhenAnyValue(j => j.TransferSize).Select(size => size.Bytes().ToString("#.0")).ToProperty(this, vm => vm.DownloadSizeFormatted, out _downloadSizeFormatted);

            // abort job on command
            CancelJob = ReactiveCommand.Create(() => { Job.Cancel(); });

            // retry job
            RetryJob = ReactiveCommand.Create(() => { JobManager.RetryJob(Job); });

            // delete job
            DeleteJob = ReactiveCommand.Create(() => { JobManager.DeleteJob(Job); });

            // setup icon
            SetupFileIcon();
        }
        public override void Init()
        {
            RefreshCommand = ReactiveUI.ReactiveCommand.CreateFromTask(RefreshDevicesList)
                             .AddDisposableTo(Disposables);

            this.WhenAnyValue(model => model.SelectedDevice)
            .Subscribe(deviceService.SelectDevice)
            .AddDisposableTo(Disposables)
            ;
        }
예제 #17
0
        public EqualizerViewModel(Equalizer equalizer)
        {
            this.Equalizer = equalizer;

            this.SetToDefaultCommand = ReactiveCommand.Create(
                () => this.Equalizer.SetToDefault(),
                this.WhenAnyValue(x => x.Equalizer.IsEnabled));

            this.CloseEqualizerCommand = ReactiveCommand.Create(
                () => this.Equalizer.SaveEqualizerSettings());
        }
 public EffectGroupViewModel(ShopEffectGroup effectGroup)
 {
     EffectGroup = effectGroup;
     AddEffect   = ReactiveCommand.CreateFromTask(AddEffectImpl);
     Delete      = ReactiveCommand.CreateFromTask(DeleteImpl);
     EffectGroup.WhenAnyValue(x => x.Name.Value)
     .Where(x => IsInitialized.Value)
     .Throttle(TimeSpan.FromSeconds(2))
     .ObserveOn(RxApp.MainThreadScheduler)
     .Subscribe(_ => UpdateImpl());
 }
예제 #19
0
 public PriceViewModel(ShopPrice price)
 {
     Price  = price;
     Delete = ReactiveCommand.CreateFromTask(DeleteImpl);
     Price.WhenAnyValue(_ => _.PeriodType.Value, _ => _.Period.Value, _ => _.Price.Value,
                        _ => _.IsRefundable.Value, _ => _.Durability.Value, _ => _.IsEnabled.Value)
     .Where(x => IsInitialized.Value)
     .Throttle(TimeSpan.FromSeconds(2))
     .ObserveOn(RxApp.MainThreadScheduler)
     .Subscribe(_ => UpdateImpl());
 }
예제 #20
0
 public EffectViewModel(ShopEffect effect)
 {
     Effect = effect;
     Change = ReactiveCommand.CreateFromTask(ChangeImpl);
     Delete = ReactiveCommand.CreateFromTask(DeleteImpl);
     Effect.WhenAnyValue(x => x.Effect.Value)
     .Where(x => IsInitialized.Value)
     .Throttle(TimeSpan.FromSeconds(2))
     .ObserveOn(RxApp.MainThreadScheduler)
     .Subscribe(_ => UpdateImpl());
 }
 public AddCustomResolverViewModel()
 {
     Name = new ReactiveProperty <string>("").SetValidateNotifyError(s =>
     {
         if (string.IsNullOrWhiteSpace(s))
         {
             return("Name must not be empty");
         }
         return(ExistingNames.Contains(s) ? $"Name {s} is already present in the server list" : null);
     });
     OkCommand     = ReactiveCommand.CreateFromTask(() => TryCloseAsync(true), Name.ObserveHasErrors.CombineLatest(Stamp.ObserveHasErrors, (a, b) => !a && !b));
     CancelCommand = ReactiveCommand.CreateFromTask(() => TryCloseAsync(false));
 }
예제 #22
0
        public LoginViewModel()
        {
            var canLogin = this.WhenAnyValue(
                x => x.Email,
                x => x.Password,
                (em, pa) =>
                !string.IsNullOrWhiteSpace(em) && !string.IsNullOrWhiteSpace(pa) && EmailIsValid(em));

            LoginCommand = ReactiveCommand.CreateFromTask(async() =>
            {
                await LoginAsync();
            }, canLogin);
            LoginCommand.IsExecuting.ToProperty(this, x => x.IsLoading, out _isLoading);
        }
예제 #23
0
 public ItemInfoViewModel(ShopItemInfo itemInfo)
 {
     ItemInfo = itemInfo;
     Delete   = ReactiveCommand.CreateFromTask(DeleteImpl);
     ItemInfo.WhenAnyValue(
         x => x.PriceGroup.Value,
         x => x.EffectGroup.Value,
         x => x.DiscountPercentage.Value,
         x => x.IsEnabled.Value)
     .Where(x => IsInitialized.Value)
     .Throttle(TimeSpan.FromSeconds(2))
     .ObserveOn(RxApp.MainThreadScheduler)
     .Subscribe(_ => UpdateImpl());
 }
예제 #24
0
        public UserViewModel(IScreen screen, User user, IUserRepository userRepository)
        {
            _userRepository = userRepository;
            HostScreen      = screen;
            // Commands
            var canSubmit = this.WhenAny(e => e.Code, code => code.Value.IsValid());

            Submit = ReactiveCommand.CreateFromTask(_ => userRepository.Submit(Model), canSubmit);
            Submit.Subscribe(result => MessageBox.Show(result ? "Success" : "Failure"));
            // Observe on UI thread
            Submit.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler)
            .Select(ex => new UserError("It will fail again, try anyway?", ex.Message))
            .SelectMany(UserError.Throw)
            .Subscribe(resolution =>
            {
                if (resolution == RecoveryOptionResult.RetryOperation)
                {
                    Submit.Execute();
                }
            });
            // Model subscription
            this.WhenAnyValue(e => e.Model).Where(e => e != null).Subscribe(model =>
            {
                Code  = model.Code;
                Group = model.Group;
            });
            Model = user;
            // Properties subscriptions
            this.WhenAnyValue(e => e.Group).Subscribe(group => Model.Group = group);
            this.WhenAnyValue(e => e.Code).Subscribe(code => Model.Code    = code);
            // Subscribe to error handle
            UserError.RegisterHandler(async error =>
            {
                // This shouldn't be a messagebox because is blocking the application, you must provide context and offer a resolution to the user not just showing "error"
                await Task.Delay(1);
                var message             = new StringBuilder();
                bool hasRecoveryOptions = error.ErrorCauseOrResolution.IsValid();
                if (hasRecoveryOptions)
                {
                    message.AppendLine(error.ErrorCauseOrResolution);
                }
                message.AppendLine(error.ErrorMessage);
                var result = MessageBox.Show(message.ToString(), "Alert!",
                                             hasRecoveryOptions ? MessageBoxButton.YesNo : MessageBoxButton.OK);

                return(hasRecoveryOptions && result == MessageBoxResult.Yes ?  RecoveryOptionResult.RetryOperation : RecoveryOptionResult.CancelOperation);
            });
        }
예제 #25
0
        public ItemsViewModel()
        {
            AddItem     = ReactiveCommand.CreateFromTask(AddItemImpl);
            Items       = new ReactiveList <ShopItem>();
            CurrentPage = new ReactiveProperty <int>(1);
            PageCount   = new ReactiveProperty <int>(ShopService.Instance.Items.Count);
            Search      = new ReactiveProperty <string>("");

            ShopService.Instance.Items.Changed.Subscribe(_ =>
            {
                PageCount.Value = GetFilteredItems().Count() / ItemsPerPage;
                UpdateItems();
            });

            _pageString = this.WhenAnyValue(x => x.CurrentPage.Value, x => x.PageCount.Value)
                          .Select(x => $"{x.Item1} / {x.Item2}")
                          .ToProperty(this, x => x.PageString);

            this.WhenAnyValue(x => x.PageCount.Value)
            .Subscribe(x =>
            {
                if (CurrentPage.Value > x)
                {
                    CurrentPage.Value = x;
                }

                UpdateItems();
            });

            this.WhenAnyValue(x => x.Search.Value)
            .Throttle(TimeSpan.FromSeconds(2))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(_ =>
            {
                PageCount.Value = GetFilteredItems().Count() / ItemsPerPage;
                UpdateItems();
            });

            var canNextPage = this.WhenAnyValue(x => x.CurrentPage.Value, x => x.PageCount.Value)
                              .Select(x => x.Item1 < x.Item2);

            var canPrevPage = this.WhenAnyValue(x => x.CurrentPage.Value)
                              .Select(x => x > 1);

            NextPage = ReactiveCommand.CreateFromTask(NextPageImpl, canNextPage);
            PrevPage = ReactiveCommand.CreateFromTask(PrevPageImpl, canPrevPage);
        }
예제 #26
0
        public IssuesViewModel(INetworkConnectivityService networkConnectivityService, IWeeklyXamarinService weeklyXamarinService)
        {
            Ensure.ArgumentNotNull(networkConnectivityService, nameof(networkConnectivityService));
            Ensure.ArgumentNotNull(weeklyXamarinService, nameof(weeklyXamarinService));

            _networkConnectivityService = networkConnectivityService;
            _weeklyXamarinService       = weeklyXamarinService;

            SearchResults = new ReactiveList <IssuesResult>();

            // Here we're describing here, in a *declarative way*, the conditions in
            // which the Search command is enabled.  Now our Command IsEnabled is
            // perfectly efficient, because we're only updating the UI in the scenario
            // when it should change.
            var canSearch = this.WhenAnyValue(vm => vm.SearchQuery, value => !string.IsNullOrWhiteSpace(value));

            // ReactiveCommand has built-in support for background operations and
            // guarantees that this block will only run exactly once at a time, and
            // that the CanExecute will auto-disable and that property IsExecuting will
            // be set according whilst it is running.
            Search = ReactiveCommand.CreateAsyncObservable(canSearch, x => _weeklyXamarinService.Search(SearchQuery));

            // ReactiveCommands are themselves IObservables, whose value are the results
            // from the async method, guaranteed to arrive on the UI thread. We're going
            // to take the list of search results that the background operation loaded,
            // and them into our SearchResults.
            Search.Subscribe(results =>
            {
                SearchResults.Clear();
                SearchResults.AddRange(results);
            });

            // ThrownExceptions is any exception thrown from the CreateAsyncTask piped
            // to this Observable. Subscribing to this allows you to handle errors on
            // the UI thread.
            Search.ThrownExceptions
            .Subscribe(ex => {
                UserError.Throw("Potential Network Connectivity Error", ex);
            });

            // Whenever the Search query changes, we're going to wait for one second
            // of "dead airtime", then automatically invoke the subscribe command.
            this.WhenAnyValue(x => x.SearchQuery)
            .Throttle(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler)
            .InvokeCommand(this, x => x.Search);
        }
예제 #27
0
        public override void Init()
        {
            deviceService.SelectedDevice
            .Do(device => Device = device)
            .ObserveOnDispatcher()
            .Subscribe()
            .AddDisposableTo(Disposables);

            SaveCommand = ReactiveUI.ReactiveCommand.CreateFromTask(SaveDeviceSettings)
                          .AddDisposableTo(Disposables);

            SavePermanentCommand = ReactiveUI.ReactiveCommand.CreateFromTask(SavePermanentDeviceSettings)
                                   .AddDisposableTo(Disposables);

            ResetCommand = ReactiveUI.ReactiveCommand.CreateFromTask(ResetDevice)
                           .AddDisposableTo(Disposables);

            LocateDeviceCommand = ReactiveUI.ReactiveCommand.CreateFromTask(LocateDevice)
                                  .AddDisposableTo(Disposables);
            LocateButtonText = "Start Blinking";
            IsDeviceSelected = false;
        }
예제 #28
0
        private static ReactiveCommand <object, Unit> SendCommandEx(
            IDispatcher bus,
            Func <object, Command> commandFunc,
            IObservable <bool> canExecute = null,
            IScheduler scheduler          = null,
            string userErrorMsg           = null,
            TimeSpan?responseTimeout      = null,
            TimeSpan?ackTimeout           = null)
        {
            if (scheduler == null)
            {
                scheduler = RxApp.MainThreadScheduler;
            }
            Func <object, Task> task = async x => await Task.Run(() =>
            {
                var c = commandFunc(x);
                if (c != null)
                {
                    bus.Send(c, userErrorMsg, responseTimeout, ackTimeout);
                }
            });

            var cmd =
                canExecute == null?
                ReactiveCommand.CreateFromTask(task, outputScheduler : scheduler) :
                    ReactiveCommand.CreateFromTask(task, canExecute, scheduler);

            cmd.ThrownExceptions
            .SelectMany(ex => Interactions.Errors.Handle(new UserError(userErrorMsg ?? ex.Message, ex)))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(result =>
            {
                // This will return the recovery option returned from the registered user error handler,
                // e.g. a simple message box in the view code behind
                /* n.b. this forces evaluation/execution of the select many  */
            });
            return(cmd);
        }
예제 #29
0
        public ViewModel2(
            SynchronizationContext context,
            IObservable <string> name,
            IObservable <string> password,
            IObservable <int> progress)
        {
            name.ToProperty(this, x => x.UserName, out _userName);
            password.ToProperty(this, x => x.Password, out _password);
            progress.ToProperty(this, x => x.Progress, out _progress);

            CanUserLogin = this.WhenAnyValue(
                x => x.UserName, x => x.Password,
                (user, pass) =>
                !string.IsNullOrWhiteSpace(user) &&
                !string.IsNullOrWhiteSpace(pass) &&
                user.Length >= 2 && pass.Length >= 3)
                           .DistinctUntilChanged();

            CmdLogin = ReactiveCommand.Create(() => CanUserLogin, CanUserLogin);
            //.InvokeCommand(CmdProcessLoginAsync);

            CmdProcessLoginAsync = ReactiveCommand.CreateFromTask(() =>
            {
                return(Task.Run(() =>
                {
                    Progress = 0;
                    while (Progress <= 100)
                    {
                        Progress += 10;
                        Thread.Sleep(100);
                    }
                }));
            }, CanUserLogin);

            //CmdCancel = ReactiveCommand.CreateCombined();
        }
예제 #30
0
        public MainViewViewModel(IUserDialogs userDialogs,
                                 IDotaClientDistancePatcher distancePatcher,
                                 SettingsViewModel settingsViewModel,
                                 IScreen hostScreen)
        {
            SettingsViewModel = settingsViewModel;
            HostScreen        = hostScreen;

            var pathCanExecute = this.WhenAnyValue(
                model => model.SettingsViewModel.Settings.Value.X32Client.Distance.Value,
                model => model.SettingsViewModel.Settings.Value.X64Client.Distance.Value,
                (x32, x64) => new[] { x32, x64 })
                                 .Select(items => items.All(value => value >= 1000 && value <= 9999));

            PatchCommand = ReactiveCommand.CreateFromTask <Settings>(distancePatcher.PatchAsync, pathCanExecute);

            PatchCommand
            .SubscribeOnUIDispatcher()
            .Subscribe(_ => { userDialogs.Alert("Done!"); });

            PatchCommand.ThrownExceptions
            .SubscribeOnUIDispatcher()
            .Subscribe(exception => userDialogs.Alert("Error occurred!"));
        }
예제 #31
0
        public PullRequestDetailViewModel(
            IPullRequestService pullRequestsService,
            IPullRequestSessionManager sessionManager,
            IModelServiceFactory modelServiceFactory,
            IUsageTracker usageTracker,
            ITeamExplorerContext teamExplorerContext,
            IPullRequestFilesViewModel files,
            ISyncSubmodulesCommand syncSubmodulesCommand,
            IViewViewModelFactory viewViewModelFactory,
            IGitService gitService,
            IOpenIssueishDocumentCommand openDocumentCommand,
            [Import(AllowDefault = true)] JoinableTaskContext joinableTaskContext)
        {
            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));
            Guard.ArgumentNotNull(gitService, nameof(gitService));
            Guard.ArgumentNotNull(openDocumentCommand, nameof(openDocumentCommand));

            this.pullRequestsService   = pullRequestsService;
            this.sessionManager        = sessionManager;
            this.modelServiceFactory   = modelServiceFactory;
            this.usageTracker          = usageTracker;
            this.teamExplorerContext   = teamExplorerContext;
            this.syncSubmodulesCommand = syncSubmodulesCommand;
            this.viewViewModelFactory  = viewViewModelFactory;
            this.gitService            = gitService;
            this.openDocumentCommand   = openDocumentCommand;
            JoinableTaskContext        = joinableTaskContext ?? ThreadHelper.JoinableTaskContext;

            Files = files;

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

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

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

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

            OpenConversation = ReactiveCommand.Create(DoOpenConversation);

            OpenOnGitHub = ReactiveCommand.Create(DoOpenDetailsUrl);

            ShowReview = ReactiveCommand.Create <IPullRequestReviewSummaryViewModel>(DoShowReview);

            ShowAnnotations = ReactiveCommand.Create <IPullRequestCheckViewModel>(DoShowAnnotations);
        }