public AddPlayViewModel(IRepository repository, INotificationService notificationService, IMapper mapper)
        {
            _repository          = repository;
            _notificationService = notificationService;

            AddValidationRules();

            _repository.Games
            .Sort(SortExpressionComparer <GameModel> .Ascending(p => p.Name))
            .Transform(p => new AvailableGameViewModel(p.Id, p.Name))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Bind(out _availableGames).Subscribe();

            var selectedGameFilter = this.WhenAnyValue(x => x.SelectedGame)
                                     .Throttle(TimeSpan.FromMilliseconds(200))
                                     .DistinctUntilChanged()
                                     .Select(p => p?.Id)
                                     .Select(CreateRecentPlayFilter);

            this.WhenAnyValue(x => x.SelectedGame)
            .Subscribe(p => NumberOfRecentPlays = DefaultNumberOfRecentPlays);

            var whenTopChanges = this.WhenAnyValue(x => x.NumberOfRecentPlays)
                                 .Select(p => new TopRequest(NumberOfRecentPlays));

            _repository.Plays
            .Filter(selectedGameFilter)
            .Sort(SortExpressionComparer <PlayModel> .Descending(p => p.Date))
            .Virtualise(whenTopChanges)
            .Transform(p => new RecentPlayViewModel(_repository, p))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Bind(out _recentPlays).Subscribe();

            var canSave = WhenDataErrorsChanged.Select(p => !p);

            Save = ReactiveCommand.CreateFromTask(SavePlay, canSave);

            var canLoadMore = _recentPlays.ToObservableChangeSet(p => p.Id).Select(p => _recentPlays.Count == NumberOfRecentPlays)
                              .ObserveOn(RxApp.MainThreadScheduler);

            LoadMore = ReactiveCommand.Create(() => NumberOfRecentPlays += 15, canLoadMore);

            _recentPlays.ToObservableChangeSet(p => p.Id)
            .StartWithEmpty()
            .Select(p => string.Format($"{_recentPlays.Count} most recent plays"))
            .ToPropertyEx(this, x => x.RecentPlaysHeader);

            SelectedDate = DateTime.Today;
            PlayerCount  = 1;
        }
        public AddGameViewModel(IRepository repository, IBggService bggService, INotificationService notificationService)
        {
            _repository          = repository;
            _bggService          = bggService;
            _notificationService = notificationService;

            _availableSoloModes =
                new ReadOnlyCollection <SoloModeViewModel>(
                    ((SoloMode[])Enum.GetValues(typeof(SoloMode))).Select(p => new SoloModeViewModel(p)).ToList());

            _repository.Games
            .Sort(SortExpressionComparer <GameModel> .Ascending(p => p.Name))
            .Transform(p => new AvailableGameViewModel(p.Id, p.Name))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Bind(out _availableGames).Subscribe();

            SetInitialValues();
            AddValidationRules();

            this.WhenAnyValue(x => x.BggGameName)
            .Throttle(TimeSpan.FromMilliseconds(400))
            .Select(term => term?.Trim())
            .DistinctUntilChanged()
            .Where(term => !string.IsNullOrWhiteSpace(term))
            .Select(SearchBggGames)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(async p => await AssignAvailableBggGames(p));

            this.WhenAnyValue(x => x.SelectedBggGame)
            .Throttle(TimeSpan.FromMilliseconds(400))
            .Select(LoadBggGameDetail)
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(async p => await AssignSelectedBggGameDetail(p));

            var canSave = WhenDataErrorsChanged.Select(p => !p);

            Save = ReactiveCommand.CreateFromTask(SaveGame, canSave);
        }