Пример #1
0
        private ReactiveTableViewSource <TeamItemViewModel> CreateSource(IReadOnlyReactiveList <TeamItemViewModel> items)
        {
            var source = new ReactiveTableViewSource <TeamItemViewModel>(TableView, items, TeamCellView.Key, (float)UITableView.AutomaticDimension);

            source.ElementSelected.OfType <TeamItemViewModel>().Subscribe(x => x.GoToCommand.ExecuteIfCan());
            return(source);
        }
Пример #2
0
        public LanguagesViewModel()
        {
            Title = "Languages";

            var languages = new ReactiveList<Language>();
            Languages = languages.CreateDerivedCollection(
                x => new LanguageItemViewModel(x.Name, x.Slug), 
                filter: x => x.Name.StartsWith(SearchKeyword ?? string.Empty, StringComparison.OrdinalIgnoreCase), 
                signalReset: this.WhenAnyValue(x => x.SearchKeyword));

            Languages
                .Changed.Select(_ => Unit.Default)
                .Merge(this.WhenAnyValue(x => x.SelectedLanguage).Select(_ => Unit.Default))
                .Select(_ => SelectedLanguage)
                .Where(x => x != null)
                .Subscribe(x =>
                {
                    foreach (var l in Languages)
                        l.Selected = l.Slug == x.Slug;
                });

            this.WhenAnyValue(x => x.SelectedLanguage)
                .IsNotNull()
                .Subscribe(_ => Dismiss());

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var languageRepository = new LanguageRepository();
                var langs = await languageRepository.GetLanguages();
                langs.Insert(0, LanguageRepository.DefaultLanguage);
                languages.Reset(langs);
            });
        }
Пример #3
0
        public LanguagesViewModel(IJsonSerializationService jsonSerializationService, INetworkActivityService networkActivity)
        {
            var languages = new ReactiveList<LanguageModel>();

            Languages = languages.CreateDerivedCollection(
                x => new LanguageItemViewModel(x.Name, x.Slug), 
                x => x.Name.StartsWith(SearchKeyword ?? string.Empty, StringComparison.OrdinalIgnoreCase), 
                signalReset: this.WhenAnyValue(x => x.SearchKeyword));

            Languages
                .Changed.Select(_ => Unit.Default)
                .Merge(this.WhenAnyValue(x => x.SelectedLanguage).Select(_ => Unit.Default))
                .Select(_ => SelectedLanguage)
                .Where(x => x != null)
                .Subscribe(x =>
                {
                    foreach (var l in Languages)
                        l.Selected = l.Slug == x.Slug;
                });

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var trendingData = await BlobCache.LocalMachine.DownloadUrl(LanguagesUrl, absoluteExpiration: DateTimeOffset.Now.AddDays(1));
                var langs = jsonSerializationService.Deserialize<List<LanguageModel>>(System.Text.Encoding.UTF8.GetString(trendingData));
                langs.Insert(0, DefaultLanguage);
                languages.Reset(langs);
            });

            LoadCommand.TriggerNetworkActivity(networkActivity);
            LoadCommand.ExecuteIfCan();
        }
Пример #4
0
        public LanguagesViewModel(IJsonSerializationService jsonSerializationService, INetworkActivityService networkActivity)
        {
            var languages = new ReactiveList <LanguageModel>();

            Languages = languages.CreateDerivedCollection(
                x => new LanguageItemViewModel(x.Name, x.Slug),
                x => x.Name.StartsWith(SearchKeyword ?? string.Empty, StringComparison.OrdinalIgnoreCase),
                signalReset: this.WhenAnyValue(x => x.SearchKeyword));

            Languages
            .Changed.Select(_ => Unit.Default)
            .Merge(this.WhenAnyValue(x => x.SelectedLanguage).Select(_ => Unit.Default))
            .Select(_ => SelectedLanguage)
            .Where(x => x != null)
            .Subscribe(x =>
            {
                foreach (var l in Languages)
                {
                    l.Selected = l.Slug == x.Slug;
                }
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var trendingData = await BlobCache.LocalMachine.DownloadUrl(LanguagesUrl, absoluteExpiration: DateTimeOffset.Now.AddDays(1));
                var langs        = jsonSerializationService.Deserialize <List <LanguageModel> >(System.Text.Encoding.UTF8.GetString(trendingData));
                langs.Insert(0, DefaultLanguage);
                languages.Reset(langs);
            });
        }
        public ValueListNodeInputViewModel()
        {
            MaxConnections      = Int32.MaxValue;
            ConnectionValidator = pending => new ConnectionValidationResult(pending.Output is ValueNodeOutputViewModel <T>, null);

            Values = Connections.ObserveLatestToList(c => ((ValueNodeOutputViewModel <T>)c.Output).WhenAnyObservable(vm => vm.Value), c => true).List;
        }
Пример #6
0
 public static IObservable <IReadOnlyReactiveList <T> > ChangedObservable <T>(this IReadOnlyReactiveList <T> @this)
 {
     return(@this.Changed
            .Select(_ => Unit.Default)
            .StartWith(Unit.Default)
            .Select(_ => @this));
 }
Пример #7
0
        public LanguagesViewModel(LanguageRepository languageRepository)
        {
            Title = "Languages";

            var languages = new ReactiveList <Language>();

            Languages = languages.CreateDerivedCollection(
                x => new LanguageItemViewModel(x.Name, x.Slug),
                filter: x => x.Name.StartsWith(SearchKeyword ?? string.Empty, StringComparison.OrdinalIgnoreCase),
                signalReset: this.WhenAnyValue(x => x.SearchKeyword));

            Languages
            .Changed.Select(_ => Unit.Default)
            .Merge(this.WhenAnyValue(x => x.SelectedLanguage).Select(_ => Unit.Default))
            .Select(_ => SelectedLanguage)
            .Where(x => x != null)
            .Subscribe(x =>
            {
                foreach (var l in Languages)
                {
                    l.Selected = l.Slug == x.Slug;
                }
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var langs = await languageRepository.GetLanguages();
                langs.Insert(0, LanguageRepository.DefaultLanguage);
                languages.Reset(langs);
            });
        }
Пример #8
0
 public NotificationGroupViewModel(string name, IReadOnlyReactiveList <NotificationModel> notifications, Action <NotificationGroupViewModel> readAll)
     : this(name, notifications)
 {
     if (readAll != null)
     {
         ReadAllCommand = ReactiveCommand.Create().WithSubscription(_ => readAll(this));
     }
 }
Пример #9
0
 public ItemsSection(string title, IReadOnlyReactiveList <ItemViewModel> items)
 {
     this.Collection           = items;
     this.CellKeySelector      = _ => cellKey;
     this.Header               = new TableSectionHeader(title);
     this.SizeHint             = 30;
     this.InitializeCellAction = x => x.Accessory = UITableViewCellAccessory.None;
 }
Пример #10
0
 public MovieListAdapter(IReadOnlyReactiveList <IMovieModel> list, IScheduleProvider scheduleProvider)
 {
     _list  = list;
     _inner = _list.Changed
              .Throttle(TimeSpan.FromMilliseconds(100))
              .ObserveOn(scheduleProvider.UiScheduler)
              .Subscribe(_ => NotifyDataSetChanged());
     HasStableIds = true;
 }
 public SectionViewModel(string title, IReadOnlyReactiveList <ItemViewModel> items)
 {
     this.title     = title;
     this.items     = items;
     this.isVisible = this.items
                      .CountChanged
                      .Select(x => x > 0)
                      .ToProperty(this, x => x.IsVisible, initialValue: false, scheduler: RxApp.MainThreadScheduler);
 }
Пример #12
0
        public NotificationGroupViewModel(string name, IReadOnlyReactiveList<NotificationItemViewModel> notifications)
        {
            Notifications = notifications;
            Name = name;

            _visible = notifications.CountChanged
                .StartWith(notifications.Count)
                .Select(x => x > 0)
                .ToProperty(this, x => x.IsVisible);
        }
Пример #13
0
        public ReactivePagerAdapter(IReadOnlyReactiveList <TViewModel> backingList,
                                    Func <TViewModel, ViewGroup, View> viewCreator,
                                    Action <TViewModel, View> viewInitializer = null)
        {
            this.list            = backingList;
            this.viewCreator     = viewCreator;
            this.viewInitializer = viewInitializer;

            inner = this.list.Changed.Subscribe(_ => NotifyDataSetChanged());
        }
Пример #14
0
        public NotificationGroupViewModel(string name, IReadOnlyReactiveList <NotificationItemViewModel> notifications)
        {
            Notifications = notifications;
            Name          = name;

            _visible = notifications.CountChanged
                       .StartWith(notifications.Count)
                       .Select(x => x > 0)
                       .ToProperty(this, x => x.IsVisible);
        }
Пример #15
0
        public CommitedFilesTableViewSource(UITableView tableView, IReadOnlyReactiveList <CommitedFileItemViewModel> collection)
            : base(tableView, 44f)
        {
            tableView.RegisterClassForCellReuse(typeof(CommitedFileTableViewCell), CommitedFileTableViewCell.Key);

            collection.Changed
            .Select(_ => Unit.Default)
            .StartWith(Unit.Default)
            .Select(_ => collection)
            .Subscribe(SetData);
        }
Пример #16
0
 public NotificationTableViewSource(UITableView tableView, IReadOnlyReactiveList <NotificationGroupViewModel> collections, Func <bool> canEdit)
     : base(tableView, UITableView.AutomaticDimension, 64f)
 {
     _canEdit = canEdit;
     tableView.RegisterNibForCellReuse(NotificationTableViewCell.Nib, NotificationTableViewCell.Key);
     Data = collections.CreateDerivedCollection(x =>
                                                new TableSectionInformation <NotificationItemViewModel, NotificationTableViewCell>(x.Notifications, NotificationTableViewCell.Key, (float)UITableView.AutomaticDimension)
     {
         Header = new TableSectionHeader(x.Name)
     },
                                                filter: x => x.IsVisible,
                                                signalReset: collections.Changed);
 }
Пример #17
0
        public AccountsViewModel(
            IApplicationService applicationService = null,
            IAccountsService accountsService       = null)
        {
            accountsService    = accountsService ?? Locator.Current.GetService <IAccountsService>();
            applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>();

            Title = "Accounts";

            var activeAccount   = applicationService.Account;
            var currentUsername = activeAccount?.Username;

            var accounts = new ReactiveList <Account>();

            Items = accounts.CreateDerivedCollection(x =>
            {
                var vm = new AccountItemViewModel(x);

                if (activeAccount?.Id == x.Id)
                {
                    vm.GoToCommand.BindCommand(DismissCommand);
                    vm.IsSelected = true;
                }
                else
                {
                    vm.GoToCommand
                    .Do(_ => applicationService.SetDefaultAccount(x))
                    .Subscribe(_ => MessageBus.Current.SendMessage(new LogoutMessage()));
                }

                vm.DeleteCommand.Subscribe(_ =>
                {
                    accountsService.Remove(x);
                    accounts.Remove(x);
                });

                return(vm);
            });

            DismissCommand = ReactiveCommand.Create(
                () => { },
                accounts.Changed.Select(x => accounts.Any(y => y.Username == currentUsername)));

            LoadCommand = ReactiveCommand.CreateFromTask(async _ =>
            {
                var allAccounts = await accountsService.GetAccounts();
                return(allAccounts.ToList());
            });
            LoadCommand.Subscribe(x => accounts.Reset(x));
        }
Пример #18
0
        protected UsersViewModel()
        {
            var users = new ReactiveList <UserItemViewModel>(resetChangeThreshold: 1);

            Items = users.CreateDerivedCollection(
                x => x,
                x => x.Username.ContainsKeyword(SearchText) || x.DisplayName.ContainsKeyword(SearchText),
                signalReset: this.WhenAnyValue(x => x.SearchText));

            LoadCommand = ReactiveCommand.CreateFromTask(async _ =>
            {
                users.Clear();
                await Load(users);
            });

            _isEmpty = LoadCommand
                       .IsExecuting
                       .Skip(1)
                       .Select(x => !x && users.Count == 0)
                       .ToProperty(this, x => x.IsEmpty);
        }
Пример #19
0
        public IssueAssigneeViewModel(
            Func <Task <IReadOnlyList <User> > > loadAssignees,
            Func <Task <Issue> > loadIssue,
            Func <IssueUpdate, Task <Issue> > updateIssue
            )
        {
            var derivedFunc = new Func <User, IssueAssigneeItemViewModel>(x =>
            {
                var vm = new IssueAssigneeItemViewModel(x);
                if (_selectedUser != null)
                {
                    vm.IsSelected = x.Id == _selectedUser.Id;
                }

                vm.GoToCommand.Subscribe(_ =>
                {
                    var assigneeName = vm.IsSelected ? vm.Name : null;
                    updateIssue(new IssueUpdate {
                        Assignee = assigneeName
                    }).ToBackground();
                });
                return(vm);
            });

            var assignees = new ReactiveList <User>();

            Assignees = assignees.CreateDerivedCollection(
                derivedFunc,
                filter: x => x.Name.ContainsKeyword(SearchKeyword),
                signalReset: this.WhenAnyValue(x => x.SearchKeyword));

            LoadCommand = ReactiveCommand.CreateAsyncTask(async _ =>
            {
                _selectedUser = (await loadIssue()).Assignee;
                assignees.Reset(await loadAssignees());
            });
        }
        public PartyViewsDragPanel(IReadOnlyReactiveList <CommunicationDiagramPartyView> partyViews)
        {
            PartyViews = partyViews;

            // Automatically enter label editing mode when adding a party
            PartyViews.OnAdd.Subscribe(elem =>
            {
                if (IsVisible && (IsFocused || HasChildInFocus()))
                {
                    elem.Element.LabelView.IsInEditMode = true;
                    elem.Element.LabelView.Focus();
                }
            });

            // Two-way binding between the viewmodel and view position.
            partyViews.ObserveEach(partyView => partyView.ViewModel.PositionChanged)
            .Subscribe(e => e.Element.Position = e.Value);
            partyViews.ObserveEach(partyView => partyView.PositionChanged)
            .Subscribe(e => e.Element.ViewModel.Position = e.Value);

            // Automatically add and remove party views to Children.
            PartyViews.OnAdd.Subscribe(e => Children.Add(e.Element));
            PartyViews.OnDelete.Subscribe(e => Children.Remove(e.Element));
        }
Пример #21
0
     this IReadOnlyReactiveList <TInput> sourceList,
     Func <TInput, TResult> selectorFunc,
     Func <TInput, bool> filterFunc = null
     )
 {
     return(CreateDerivedListBinding(Observable.Return(sourceList), selectorFunc, filterFunc));
        protected ReactiveRecyclerViewAdapter(IReadOnlyReactiveList <TViewModel> backingList)
        {
            this.list = backingList;

            _inner = this.list.Changed.Subscribe(_ => NotifyDataSetChanged());
        }
Пример #23
0
 public IssueGroupViewModel(string name, IEnumerable<IssueItemViewModel> issues)
 {
     Issues = new ReactiveList<IssueItemViewModel>(issues);
     Name = name;
 }
Пример #24
0
 public CardAdapter(IReadOnlyReactiveList <CardViewModel> collection) : base(collection)
 {
     ItemSelected = new Subject <int>();
 }
Пример #25
0
 public Parent(int id)
 {
     Id               = id;
     Children         = new ReactiveList <Person>();
     ChildrenReadonly = Children;
 }
Пример #26
0
 public Parent(int id, IEnumerable <Person> children)
 {
     Id               = id;
     Children         = new ReactiveList <Person>(children);
     ChildrenReadonly = Children;
 }
Пример #27
0
 public NotificationGroupViewModel(string name, IReadOnlyReactiveList <NotificationModel> notifications)
 {
     Notifications = notifications;
     Name          = name;
 }
 public NotificationGroupViewModel(string name, IReadOnlyReactiveList<NotificationModel> notifications, Action<NotificationGroupViewModel> readAll)
     : this(name, notifications)
 {
     if (readAll != null)
         ReadAllCommand = ReactiveCommand.Create().WithSubscription(_ => readAll(this));
 }
 public Parent()
 {
     Children         = new ReactiveList <Person>();
     ChildrenReadonly = Children;
 }
Пример #30
0
        /// <summary>
        /// Clones the ReactiveList from all changes
        /// </summary>
        /// <typeparam name="TObject">The type of the object.</typeparam>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <param name="source">The source.</param>
        /// <param name="keySelector">The key selector.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">source
        /// or
        /// keySelector</exception>
        public static IObservable <IChangeSet <TObject, TKey> > ToObservableChangeSet <TObject, TKey>(this IReadOnlyReactiveList <TObject> source, Func <TObject, TKey> keySelector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (keySelector == null)
            {
                throw new ArgumentNullException(nameof(keySelector));
            }

            return(source.ToObservableChangeSet <IReadOnlyReactiveList <TObject>, TObject>().AddKey(keySelector));
        }
Пример #31
0
 /// <summary>
 /// Converts the Reactive List into an observable change set
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="source">The source.</param>
 /// <returns></returns>
 /// <exception cref="System.ArgumentNullException">source</exception>
 public static IObservable <IChangeSet <T> > ToObservableChangeSet <T>(this IReadOnlyReactiveList <T> source)
 {
     return(source.ToObservableChangeSet <IReadOnlyReactiveList <T>, T>());
 }
        public ExerciseProgramViewModel(
            ILoggerService loggerService,
            IScheduler scheduler,
            IScreen hostScreen,
            ExerciseProgram model)
        {
            Ensure.ArgumentNotNull(loggerService, nameof(loggerService));
            Ensure.ArgumentNotNull(scheduler, nameof(scheduler));
            Ensure.ArgumentNotNull(hostScreen, nameof(hostScreen));
            Ensure.ArgumentNotNull(model, nameof(model));

            this.logger      = loggerService.GetLogger(this.GetType());
            this.scheduler   = scheduler;
            this.model       = model;
            this.hostScreen  = hostScreen;
            this.disposables = new CompositeDisposable();
            this.exercises   = this.model.Exercises.CreateDerivedCollection(x => new ExerciseViewModel(scheduler, x, this.WhenAnyValue(y => y.ExecutionContext)));

            this
            .WhenAnyValue(
                x => x.ExecutionContext,
                x => x.ExecutionContext.IsCancelled,
                (ec, isCancelled) => ec != null && !isCancelled)
            .ObserveOn(scheduler)
            .Subscribe(x => this.IsStarted = x)
            .AddTo(this.disposables);

            this
            .WhenAnyValue(x => x.ExecutionContext)
            .Select(x => x == null ? Observable.Return(false) : x.WhenAnyValue(y => y.IsPaused))
            .Switch()
            .ObserveOn(scheduler)
            .Subscribe(x => this.IsPaused = x)
            .AddTo(this.disposables);

            this
            .WhenAnyValue(x => x.ExecutionContext)
            .Select(x => x == null ? Observable.Return(TimeSpan.Zero) : x.WhenAnyValue(y => y.Progress))
            .Switch()
            .ObserveOn(scheduler)
            .Subscribe(x => this.ProgressTimeSpan = x)
            .AddTo(this.disposables);

            this
            .WhenAnyValue(x => x.ProgressTimeSpan)
            .Select(x => x.TotalMilliseconds / this.model.Duration.TotalMilliseconds)
            .Subscribe(x => this.Progress = x)
            .AddTo(this.disposables);

            this
            .WhenAnyValue(
                x => x.ExecutionContext,
                x => x.ExecutionContext.CurrentExercise,
                (ec, currentExercise) => ec == null ? null : currentExercise)
            .Select(x => this.Exercises.SingleOrDefault(y => y.Model == x))
            .ObserveOn(scheduler)
            .Subscribe(x => this.CurrentExercise = x)
            .AddTo(this.disposables);

            var canStart = this
                           .WhenAnyValue(x => x.IsStarted)
                           .Select(x => !x);

            this.startCommand = ReactiveCommand
                                .CreateFromObservable <TimeSpan?, Unit>(this.OnStart, canStart, scheduler)
                                .AddTo(this.disposables);

            var canPause = this
                           .WhenAnyValue(x => x.IsStarted)
                           .CombineLatest(this.WhenAnyValue(x => x.ExecutionContext.IsPaused), (isStarted, isPaused) => isStarted && !isPaused)
                           .ObserveOn(scheduler);

            this.pauseCommand = ReactiveCommand
                                .CreateFromObservable(this.OnPause, canPause, scheduler)
                                .AddTo(this.disposables);

            var canResume = this
                            .WhenAnyValue(x => x.IsStarted)
                            .CombineLatest(this.WhenAnyValue(x => x.ExecutionContext.IsPaused), (isStarted, isPaused) => isStarted && isPaused)
                            .ObserveOn(scheduler);

            this.resumeCommand = ReactiveCommand
                                 .CreateFromObservable(this.OnResume, canResume, scheduler)
                                 .AddTo(this.disposables);

            var canSkipBackwards = this
                                   .WhenAnyValue(
                x => x.ExecutionContext,
                x => x.ProgressTimeSpan,
                (ec, progress) => new { ExecutionContext = ec, Progress = progress })
                                   .Select(x => x.ExecutionContext != null && x.Progress >= skipBackwardsThreshold)
                                   .ObserveOn(scheduler);

            this.skipBackwardsCommand = ReactiveCommand
                                        .CreateFromObservable(this.OnSkipBackwards, canSkipBackwards, scheduler)
                                        .AddTo(this.disposables);

            var canSkipForwards = this
                                  .WhenAnyValue(
                x => x.ExecutionContext,
                x => x.CurrentExercise,
                (ec, currentExercise) => new { ExecutionContext = ec, CurrentExercise = currentExercise })
                                  .Select(x => x.ExecutionContext != null && x.CurrentExercise != null && x.CurrentExercise != this.exercises.LastOrDefault())
                                  .ObserveOn(scheduler);

            this.skipForwardsCommand = ReactiveCommand
                                       .CreateFromObservable(this.OnSkipForwards, canSkipForwards, scheduler)
                                       .AddTo(this.disposables);

            this.startCommand
            .CanExecute
            .Subscribe(x => this.IsStartVisible = x)
            .AddTo(this.disposables);

            this.pauseCommand
            .CanExecute
            .Subscribe(x => this.IsPauseVisible = x)
            .AddTo(this.disposables);

            this.resumeCommand
            .CanExecute
            .Subscribe(x => this.IsResumeVisible = x)
            .AddTo(this.disposables);

            this.startCommand
            .ThrownExceptions
            .Subscribe(ex => this.OnThrownException("start", ex))
            .AddTo(this.disposables);

            this.pauseCommand
            .ThrownExceptions
            .Subscribe(ex => this.OnThrownException("pause", ex))
            .AddTo(this.disposables);

            this.resumeCommand
            .ThrownExceptions
            .Subscribe(ex => this.OnThrownException("resume", ex))
            .AddTo(this.disposables);

            this.skipBackwardsCommand
            .ThrownExceptions
            .Subscribe(ex => this.OnThrownException("skip backwards", ex))
            .AddTo(this.disposables);

            this.skipForwardsCommand
            .ThrownExceptions
            .Subscribe(ex => this.OnThrownException("skip forwards", ex))
            .AddTo(this.disposables);

            // we don't use a reactive command here because switching in different commands causes it to get confused and
            // command binding leaves the target button disabled. We could also have not used command binding to get around
            // this problem
            this.playbackCommand = new PlaybackCommandImpl(this);

            // cancel the exercise program if the user navigates away
            this
            .hostScreen
            .Router
            .NavigationStack
            .ItemsRemoved
            .OfType <ExerciseProgramViewModel>()
            .SelectMany(x => x.Stop())
            .Subscribe()
            .AddTo(this.disposables);
        }
 public GroupedCollection(string name, IReadOnlyReactiveList <TViewModel> items)
 {
     Name  = name;
     Items = items;
 }
Пример #34
0
 public RxSpyObservablesGridViewModel(IReadOnlyReactiveList <RxSpyObservableModel> model)
 {
     Observables = model.CreateDerivedCollection(x => new RxSpyObservableGridItemViewModel(x));
 }
Пример #35
0
 public RxSpyObservablesGridViewModel(IReadOnlyReactiveList<RxSpyObservableModel> model)
 {
     Observables = model.CreateDerivedCollection(x => new RxSpyObservableGridItemViewModel(x));
 }
 public NotificationGroupViewModel(string name, IReadOnlyReactiveList<NotificationModel> notifications)
 {
     Notifications = notifications;
     Name = name;
 }
Пример #37
0
 public IssueGroupViewModel(string name, IEnumerable <IssueItemViewModel> issues)
 {
     Issues = new ReactiveList <IssueItemViewModel>(issues);
     Name   = name;
 }
        public ExerciseProgramViewModel(
            ILoggerService loggerService,
            IScheduler scheduler,
            IScreen hostScreen,
            ExerciseProgram model)
        {
            Ensure.ArgumentNotNull(loggerService, nameof(loggerService));
            Ensure.ArgumentNotNull(scheduler, nameof(scheduler));
            Ensure.ArgumentNotNull(hostScreen, nameof(hostScreen));
            Ensure.ArgumentNotNull(model, nameof(model));

            this.logger = loggerService.GetLogger(this.GetType());
            this.scheduler = scheduler;
            this.model = model;
            this.hostScreen = hostScreen;
            this.disposables = new CompositeDisposable();
            this.exercises = this.model.Exercises.CreateDerivedCollection(x => new ExerciseViewModel(scheduler, x, this.WhenAnyValue(y => y.ExecutionContext)));

            this
                .WhenAnyValue(
                    x => x.ExecutionContext,
                    x => x.ExecutionContext.IsCancelled,
                    (ec, isCancelled) => ec != null && !isCancelled)
                .ObserveOn(scheduler)
                .Subscribe(x => this.IsStarted = x)
                .AddTo(this.disposables);

            this
                .WhenAnyValue(x => x.ExecutionContext)
                .Select(x => x == null ? Observable.Return(false) : x.WhenAnyValue(y => y.IsPaused))
                .Switch()
                .ObserveOn(scheduler)
                .Subscribe(x => this.IsPaused = x)
                .AddTo(this.disposables);

            this
                .WhenAnyValue(x => x.ExecutionContext)
                .Select(x => x == null ? Observable.Return(TimeSpan.Zero) : x.WhenAnyValue(y => y.Progress))
                .Switch()
                .ObserveOn(scheduler)
                .Subscribe(x => this.ProgressTimeSpan = x)
                .AddTo(this.disposables);

            this
                .WhenAnyValue(x => x.ProgressTimeSpan)
                .Select(x => x.TotalMilliseconds / this.model.Duration.TotalMilliseconds)
                .Subscribe(x => this.Progress = x)
                .AddTo(this.disposables);

            this
                .WhenAnyValue(
                    x => x.ExecutionContext,
                    x => x.ExecutionContext.CurrentExercise,
                    (ec, currentExercise) => ec == null ? null : currentExercise)
                .Select(x => this.Exercises.SingleOrDefault(y => y.Model == x))
                .ObserveOn(scheduler)
                .Subscribe(x => this.CurrentExercise = x)
                .AddTo(this.disposables);

            var canStart = this
                .WhenAnyValue(x => x.IsStarted)
                .Select(x => !x);

            this.startCommand = ReactiveCommand
                .CreateFromObservable<TimeSpan?, Unit>(this.OnStart, canStart, scheduler)
                .AddTo(this.disposables);

            var canPause = this
                .WhenAnyValue(x => x.IsStarted)
                .CombineLatest(this.WhenAnyValue(x => x.ExecutionContext.IsPaused), (isStarted, isPaused) => isStarted && !isPaused)
                .ObserveOn(scheduler);

            this.pauseCommand = ReactiveCommand
                .CreateFromObservable(this.OnPause, canPause, scheduler)
                .AddTo(this.disposables);

            var canResume = this
                .WhenAnyValue(x => x.IsStarted)
                .CombineLatest(this.WhenAnyValue(x => x.ExecutionContext.IsPaused), (isStarted, isPaused) => isStarted && isPaused)
                .ObserveOn(scheduler);

            this.resumeCommand = ReactiveCommand
                .CreateFromObservable(this.OnResume, canResume, scheduler)
                .AddTo(this.disposables);

            var canSkipBackwards = this
                .WhenAnyValue(
                    x => x.ExecutionContext,
                    x => x.ProgressTimeSpan,
                    (ec, progress) => new { ExecutionContext = ec, Progress = progress })
                .Select(x => x.ExecutionContext != null && x.Progress >= skipBackwardsThreshold)
                .ObserveOn(scheduler);

            this.skipBackwardsCommand = ReactiveCommand
                .CreateFromObservable(this.OnSkipBackwards, canSkipBackwards, scheduler)
                .AddTo(this.disposables);

            var canSkipForwards = this
                .WhenAnyValue(
                    x => x.ExecutionContext,
                    x => x.CurrentExercise,
                    (ec, currentExercise) => new { ExecutionContext = ec, CurrentExercise = currentExercise })
                .Select(x => x.ExecutionContext != null && x.CurrentExercise != null && x.CurrentExercise != this.exercises.LastOrDefault())
                .ObserveOn(scheduler);

            this.skipForwardsCommand = ReactiveCommand
                .CreateFromObservable(this.OnSkipForwards, canSkipForwards, scheduler)
                .AddTo(this.disposables);

            this.startCommand
                .CanExecute
                .Subscribe(x => this.IsStartVisible = x)
                .AddTo(this.disposables);

            this.pauseCommand
                .CanExecute
                .Subscribe(x => this.IsPauseVisible = x)
                .AddTo(this.disposables);

            this.resumeCommand
                .CanExecute
                .Subscribe(x => this.IsResumeVisible = x)
                .AddTo(this.disposables);

            this.startCommand
                .ThrownExceptions
                .Subscribe(ex => this.OnThrownException("start", ex))
                .AddTo(this.disposables);

            this.pauseCommand
                .ThrownExceptions
                .Subscribe(ex => this.OnThrownException("pause", ex))
                .AddTo(this.disposables);

            this.resumeCommand
                .ThrownExceptions
                .Subscribe(ex => this.OnThrownException("resume", ex))
                .AddTo(this.disposables);

            this.skipBackwardsCommand
                .ThrownExceptions
                .Subscribe(ex => this.OnThrownException("skip backwards", ex))
                .AddTo(this.disposables);

            this.skipForwardsCommand
                .ThrownExceptions
                .Subscribe(ex => this.OnThrownException("skip forwards", ex))
                .AddTo(this.disposables);

            // we don't use a reactive command here because switching in different commands causes it to get confused and
            // command binding leaves the target button disabled. We could also have not used command binding to get around
            // this problem
            this.playbackCommand = new PlaybackCommandImpl(this);

            // cancel the exercise program if the user navigates away
            this
                .hostScreen
                .Router
                .NavigationStack
                .ItemsRemoved
                .OfType<ExerciseProgramViewModel>()
                .SelectMany(x => x.Stop())
                .Subscribe()
                .AddTo(this.disposables);
        }