public PullRequestsViewModel(ISessionService sessionService) { _sessionService = sessionService; Title = "Pull Requests"; PullRequests = _pullRequests.CreateDerivedCollection(x => { var vm = new PullRequestItemViewModel(x); vm.GoToCommand.Subscribe(_ => { var prViewModel = this.CreateViewModel <PullRequestViewModel>(); prViewModel.Init(RepositoryOwner, RepositoryName, x.Number, x); NavigateTo(prViewModel); prViewModel.WhenAnyValue(y => y.Issue.State) .DistinctUntilChanged() .Skip(1) .Subscribe(y => LoadCommand.ExecuteIfCan()); }); return(vm); }, filter: x => x.Title.ContainsKeyword(SearchKeyword), signalReset: this.WhenAnyValue(x => x.SearchKeyword)); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { _pullRequests.Reset(await RetrievePullRequests()); }); this.WhenAnyValue(x => x.SelectedFilter).Skip(1).Subscribe(_ => { _pullRequests.Clear(); LoadCommand.ExecuteIfCan(); }); }
public static void Reset <T>(this IReactiveList <T> @this, IEnumerable <T> items) { using (@this.SuppressChangeNotifications()) { @this.Clear(); @this.AddRange(items); } }
void InitializeBubbles() { // Create a new matrix of bubbles. _bubblesInternal.Clear(); ((ReactiveList <BubbleViewModel>)_bubblesInternal).AddRange( from row in Enumerable.Range(0, RowCount) from col in Enumerable.Range(0, ColumnCount) select new BubbleViewModel(this, row, col)); }
private void RemoveDuplicates <T, TKey>(IReactiveList <T> list, Func <T, TKey> keySelector) { var distinct = list.Distinct(keySelector).ToList(); if (distinct.Count != list.Count) { list.Clear(); list.AddRange(distinct); } }
private async Task DoFetch() { var settings = await _settingManager.Read(); var response = await _feedStoreService.Load(_category.Channels); var viewModels = response.Select(_factory).ToList(); ShowRead = settings.Read; _source.Clear(); _source.AddRange(viewModels); }
public static void ClearAndAddRange <T>(this IReactiveList <T> lstSource, IEnumerable <T> lstAdditional) { if (lstAdditional == null) { return; } lstSource.Clear(); foreach (var item in lstAdditional) { lstSource.Add(item); } }
public FeedGroupViewModel( Func <Article, FeedItemViewModel> factory, INavigationService navigationService, IFeedStoreService feedStoreService, ISettingManager settingManager, Category category) { _source = new ReactiveList <FeedItemViewModel> { ChangeTrackingEnabled = true }; _navigationService = navigationService; _feedStoreService = feedStoreService; _settingManager = settingManager; _category = category; _factory = factory; Modify = ReactiveCommand.CreateFromTask(_navigationService.Navigate <ChannelViewModel>); Fetch = ReactiveCommand.CreateFromTask(() => _feedStoreService.Load(_category.Channels)); Items = _source.CreateDerivedCollection(x => x, x => !(!ShowRead && x.Read)); Fetch.Select(articles => articles.Select(_factory)) .ObserveOn(RxApp.MainThreadScheduler) .Do(articles => _source.Clear()) .Subscribe(_source.AddRange); Items.IsEmptyChanged .Subscribe(x => IsEmpty = x); Fetch.IsExecuting.Skip(1) .Subscribe(x => IsLoading = x); Fetch.IsExecuting .Where(executing => executing) .SelectMany(x => _settingManager.Read()) .Select(settings => settings.Read) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => ShowRead = x); Fetch.IsExecuting .Where(executing => executing) .Select(executing => false) .Subscribe(x => HasErrors = x); Fetch.ThrownExceptions .Select(exception => true) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => HasErrors = x); Activator = new ViewModelActivator(); this.WhenActivated((CompositeDisposable disposables) => Fetch.Execute().Subscribe()); }
/// <summary> /// Adapts the specified changeset /// </summary> /// <param name="changes">The changes.</param> public void Adapt(IChangeSet <TObject, TKey> changes) { Clone(changes); if (changes.Count - changes.Refreshes > _resetThreshold || !_loaded) { _loaded = true; using (_target.SuppressChangeNotifications()) { _target.Clear(); _target.AddRange(_data.Values); } } else { DoUpdate(changes); } }
/// <summary> /// Takes each list produced by this observable and mirrors its contents in the target list. /// The target list is modified, not replaced. /// The type of the target list property is IReadOnlyReactiveList because it doesn't make sense to have a mutible list /// if this binding keeps changing the contents of the list, but the type of the actual object should be ReactiveList /// so the list can be modified by this binding. /// </summary> /// <typeparam name="TObj">The type of viewmodel</typeparam> /// <typeparam name="TListItem">The type of object contained in the list</typeparam> /// <param name="data">The observable to take lists from.</param> /// <param name="target">The viewmodel that is used as a base for finding the target list property</param> /// <param name="property">The IReactiveList property that will be modified.</param> /// <returns>A disposable to break the binding</returns> public static IDisposable BindListContents <TObj, TListItem>(this IObservable <IList <TListItem> > data, TObj target, Expression <Func <TObj, IReadOnlyReactiveList <TListItem> > > property) where TObj : class { IObservable <IReadOnlyReactiveList <TListItem> > targetListObservable = target.WhenAnyValue(property); return(Observable.CombineLatest(targetListObservable, data, (a, b) => (TargetList: a, SourceList: b)) .Subscribe(t => { IReactiveList <TListItem> latestTargetList = t.TargetList as IReactiveList <TListItem>; IList <TListItem> latestData = t.SourceList; if (latestTargetList == null) { return; } if (latestData == null) { latestTargetList.Clear(); return; } var changes = LongestCommonSubsequence.GetChanges(latestTargetList, latestData).ToArray(); if (changes.Length == 0) { return; } using (changes.Length > 1 ? latestTargetList.SuppressChangeNotifications() : Disposable.Empty) { foreach (var(index, item, changeType) in changes) { if (changeType == LongestCommonSubsequence.ChangeType.Removed) { latestTargetList.RemoveAt(index); } else if (changeType == LongestCommonSubsequence.ChangeType.Added) { latestTargetList.Insert(index, item); } } } })); }
public FeedGroupViewModel( Func <Article, FeedItemViewModel> factory, INavigationService navigationService, IFeedStoreService feedStoreService, ISettingManager settingManager, Category category) { _source = new ReactiveList <FeedItemViewModel> { ChangeTrackingEnabled = true }; _navigationService = navigationService; _feedStoreService = feedStoreService; _settingManager = settingManager; _category = category; _factory = factory; Modify = ReactiveCommand.CreateFromTask(_navigationService.Navigate <ChannelViewModel>); Fetch = ReactiveCommand.CreateFromTask(() => _feedStoreService.Load(_category.Channels)); Items = _source.CreateDerivedCollection(x => x, x => !(!ShowRead && x.Read)); Fetch.Select(articles => articles.Select(_factory)) .ObserveOn(RxApp.MainThreadScheduler) .Do(articles => _source.Clear()) .Subscribe(_source.AddRange); Fetch.IsExecuting .Where(executing => executing) .SelectMany(x => _settingManager.Read()) .Select(settings => settings.Read) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => ShowRead = x); Items.IsEmptyChanged .Subscribe(x => IsEmpty = x); Fetch.IsExecuting .Skip(1) .Subscribe(x => IsLoading = x); Error = new Interaction <Exception, bool>(); Fetch.ThrownExceptions .ObserveOn(RxApp.MainThreadScheduler) .SelectMany(Error.Handle) .Where(retry => retry) .Select(x => Unit.Default) .InvokeCommand(Fetch); }
public static void Replace <T>(this IReactiveList <T> col, IEnumerable <T> replacement) { col.Clear(); col.AddRange(replacement); }