public FilterDynamicDataViewModel() { this.WhenActivated((CompositeDisposable disposables) => { _searchResultSource = new SourceList <RssEntry>().DisposeWith(disposables); _searchResultSource .Connect() .ObserveOn(RxApp.MainThreadScheduler) .Bind(out var searchResultsBinding) .Subscribe() .DisposeWith(disposables); this.SearchResults = searchResultsBinding; Search = ReactiveCommand .CreateFromTask( async(ct) => { var worldNews = await RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct).ConfigureAwait(false); _searchResultSource .Edit( innerList => { innerList.Clear(); innerList.AddRange(worldNews); }); }) .DisposeWith(disposables); }); }
public SortDynamicDataViewModel() { this.WhenActivated((CompositeDisposable disposables) => { _searchResultSource = new SourceList <RssEntry>().DisposeWith(disposables); var sorter = this.WhenAnyValue(x => x.SelectedSortType) .Select( SelectedSortType => { switch (SelectedSortType) { case SortType.DateTimeAscending: return(SortExpressionComparer <RssEntry> .Ascending(x => x.Updated)); case SortType.DateTimeDescending: return(SortExpressionComparer <RssEntry> .Descending(x => x.Updated)); case SortType.TitleAscending: return(SortExpressionComparer <RssEntry> .Ascending(x => x.Title)); case SortType.TitleDescending: default: return(SortExpressionComparer <RssEntry> .Descending(x => x.Title)); } }); _searchResultSource .Connect() .SubscribeOn(RxApp.TaskpoolScheduler) .Sort(sorter) .ObserveOn(RxApp.MainThreadScheduler) .Bind(out var searchResultsBinding) .Subscribe() .DisposeWith(disposables); this.SearchResults = searchResultsBinding; Search = ReactiveCommand .CreateFromTask( async(ct) => { var worldNews = await RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct).ConfigureAwait(false); _searchResultSource .Edit( innerList => { innerList.Clear(); innerList.AddRange(worldNews); }); }) .DisposeWith(disposables); }); }
public SourceCacheDynamicDataViewModel() { this.WhenActivated((CompositeDisposable disposables) => { _searchResultSource = new SourceCache <RssEntry, string>(x => x.Id).DisposeWith(disposables); _searchResultSource .Connect() .SubscribeOn(RxApp.TaskpoolScheduler) .OnItemAdded(x => x.New = true) .OnItemUpdated((current, previous) => current.New = false) .Sort( SortExpressionComparer <RssEntry> .Descending(x => x.New) .ThenByDescending(x => x.Updated)) .ObserveOn(RxApp.MainThreadScheduler) .Bind(out var searchResultsBinding) .Subscribe() .DisposeWith(disposables); this.SearchResults = searchResultsBinding; Search = ReactiveCommand .CreateFromTask( async(ct) => { var rss = await RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct).ConfigureAwait(false); _searchResultSource.AddOrUpdate(rss); }) .DisposeWith(disposables); Observable .Interval(TimeSpan.FromSeconds(5)) .SelectUnit() .InvokeCommand(this, x => x.Search) .DisposeWith(disposables); }); }
Task <IEnumerable <RssEntry> > DownloadMultipleRss(CancellationToken ct) { return(Task.Run <IEnumerable <RssEntry> >(async() => { System.Diagnostics.Debug.WriteLine($"Starting download at {DateTimeOffset.Now}"); var askReddit = RssDownloader.DownloadRss("https://www.reddit.com/r/AskReddit/new/.rss", ct); var todayILearned = RssDownloader.DownloadRss("https://www.reddit.com/r/todayilearned/new/.rss", ct); var news = RssDownloader.DownloadRss("https://www.reddit.com/r/news/new/.rss", ct); var worldNews = RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct); var tcs = new TaskCompletionSource <object>(); ct.Register(() => tcs.TrySetCanceled(), false); await Task.WhenAny(Task.WhenAll(askReddit, todayILearned, news, worldNews), tcs.Task).ConfigureAwait(false); var masterList = new List <RssEntry>(); if (!ct.IsCancellationRequested && !tcs.Task.IsCanceled) { masterList.AddRange(await askReddit.ConfigureAwait(false)); masterList.AddRange(await todayILearned.ConfigureAwait(false)); masterList.AddRange(await news.ConfigureAwait(false)); masterList.AddRange(await worldNews.ConfigureAwait(false)); } var filteredList = masterList.GroupBy(x => x.Id).Select(x => x.First()).ToList(); if (ct.IsCancellationRequested) { System.Diagnostics.Debug.WriteLine($"Cancelled download at {DateTimeOffset.Now}"); return Enumerable.Empty <RssEntry>(); } return filteredList; })); }
public SimpleDynamicDataViewModel() { this.WhenActivated((CompositeDisposable disposables) => { _searchResultSource = new SourceList <RssEntry>().DisposeWith(disposables); var filter = this.WhenAnyValue(x => x.SearchQuery) .SubscribeOn(RxApp.MainThreadScheduler) .Select( search => { var searchIsEmpty = string.IsNullOrEmpty(search); return(new Func <RssEntry, bool>( value => { if (searchIsEmpty) { return true; } return FuzzySharp.Fuzz.PartialRatio(value.Title, search) > 75; })); }); var filteredData = _searchResultSource .Connect() .SubscribeOn(RxApp.MainThreadScheduler) .Filter(filter) .Publish() .RefCount(); filteredData .ObserveOn(RxApp.MainThreadScheduler) .Bind(out var searchResultsBinding) .Subscribe() .DisposeWith(disposables); this.SearchResults = searchResultsBinding; filteredData .Count() .BindTo(this, x => x.ResultCount) .DisposeWith(disposables); Search = ReactiveCommand .CreateFromTask( async(ct) => { var worldNews = await RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct).ConfigureAwait(false); _searchResultSource .Edit( innerList => { innerList.Clear(); innerList.AddRange(worldNews); }); }) .DisposeWith(disposables); }); }
public FilterDynamicDataViewModel() { this.WhenActivated((CompositeDisposable disposables) => { _searchResultSource = new SourceList <RssEntry>().DisposeWith(disposables); var filter = this.WhenAnyValue(x => x.SearchQuery) .SubscribeOn(RxApp.TaskpoolScheduler) .Select( search => { var searchIsEmpty = string.IsNullOrEmpty(search); return(new Func <RssEntry, bool>( value => { if (searchIsEmpty) { return true; } return FuzzySharp.Fuzz.PartialRatio(value.Title, search) > 75; })); }); var filteredData = _searchResultSource .Connect() .SubscribeOn(RxApp.MainThreadScheduler) .Filter(filter) .Publish() .RefCount(); filteredData .ObserveOn(RxApp.MainThreadScheduler) .Bind(out var searchResultsBinding) .Subscribe() .DisposeWith(disposables); this.SearchResults = searchResultsBinding; filteredData .Count() .BindTo(this, x => x.ResultCount) .DisposeWith(disposables); CancelSearch = ReactiveCommand .Create(() => {}) .DisposeWith(disposables); Search = ReactiveCommand .CreateFromObservable( () => { return(Observable .StartAsync( async(ct) => { var worldNews = await RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct).ConfigureAwait(false); if (ct.IsCancellationRequested) { return; } _searchResultSource .Edit( innerList => { innerList.Clear(); innerList.AddRange(worldNews); }); }) .TakeUntil(this.CancelSearch) .SelectUnit()); }) .DisposeWith(disposables); Observable .Merge( this.ThrownExceptions, Search.ThrownExceptions) .Do(ex => System.Diagnostics.Debug.WriteLine($"ERROR!!: {ex}")); }); }