static void data_SectionStoriesDownloadCompleted(object sender, DownloadStringCompletedEventArgs downloadCompletedEvent, ObservableCollection<Story> storyCollection, Section section, InsertStoriesAt insertStoriesAt) { if (downloadCompletedEvent.Error != null) { DownloadFailed(sender, downloadCompletedEvent); return; } SunApiAdapter.handleJsonWithSanitization( (json) => { var stories = SunApiAdapter.StoriesOfApiResponse(json); var existingNids = storyCollection.Select(s => s.Nid); int countStoriesAdded = insertStoriesAt == InsertStoriesAt.Beginning ? 0 : storyCollection.Count; foreach (Story story in stories.Where(article => !existingNids.Contains(article.Nid))) { story.Vid = section.Vid; // cached stories will already be present // so we want to add the new stuff to the beginning // Do we need to sort anyway, or will this always work? storyCollection.Insert(countStoriesAdded++, story); } }, () => { Debug.Assert(false, "Why couldn't the JSON be parsed?"); DownloadFailed(sender, downloadCompletedEvent); }, downloadCompletedEvent.Result ); }
internal static bool ShouldAcceptSection(Section section) { // Just ignore subsections. Maybe later this app will handle them in some // interesting way, but for now let's simplify. return !section.HasParent && // In practice, this may be redundant with the previous check. SunApiAdapter.SECTIONS_WHITELIST.Contains(section.Vid); }
internal static ObservableCollection<Story> GetStories(Section section, InsertStoriesAt insertStoriesAt) { if (!_downloadedSectionStories.Contains(section) && !_currentlyDownloadingSectionStories.Contains(section)) { _currentlyDownloadingSectionStories.Add(section); downloadData(SunApiAdapter.StoriesUrlOfSection(section), (sender, e) => { _downloadedSectionStories.Add(section); _currentlyDownloadingSectionStories.Remove(section); data_SectionStoriesDownloadCompleted(sender, e, getSectionStories()[section], section, insertStoriesAt); section.LoadedPage++; }); } return getSectionStories()[section]; }
internal static ObservableCollection<Story> GetStories(Section section) { return GetStories(section, InsertStoriesAt.Beginning); }
// Find the first page of story data that contains stories we don't already have, // then load that page. This basically sucks, because we will request the last page twice // (once to determine that we haven't loaded it yet, and once again to actually fetch the stories // and update the models). It's shitty but I don't think it's worth fixing now. // // This could possibly be done much more simply on the server side // Just have a service that returns the page number we need // However, I'd rather minimize the serverside dependency, since it can break without notice. internal static void GetMoreStories(Section section) { if (sectionsCurrentlyLoadingMoreStories.Contains(section)) { return; } sectionsCurrentlyLoadingMoreStories.Add(section); // TODO: this seems to fire off two queries for the first page it checks // TODO: could the stories/nid view be used to save time when loading the 0th page? // Perhaps it's not necessary to make that big call at all, if we're already fully cached. string queryUrl = SunApiAdapter.StoriesUrlOfSection(section); downloadData(queryUrl, (sender, e) => { sectionsCurrentlyLoadingMoreStories.Remove(section); if (e.Error != null) { Debug.WriteLine("Error getting story nids page: " + queryUrl); return; } var stories = SunApiAdapter.StoriesOfApiResponse(e.Result); var nids = stories.Select(story => story.Nid); // if all the nids on this page are already in memory IEnumerable<int> existingNids = _sectionStories[section].Select(story => story.Nid); if (nids.Intersect(existingNids).Count() == nids.Count()) { // try the next page // Note: if we aren't constructing the url such that each successive attempt actually // is giving us subsequent pages, this recursion will go on indefinitely. section.LoadedPage++; GetMoreStories(section); return; } // We want more data for `section`, // so remove it from the collection of sections // we've already fully loaded. _downloadedSectionStories.Remove(section); GetStories(section, InsertStoriesAt.End); }); }
public SectionViewModel(Section section) { Section = section; SunData.GetFavorites().CollectionChanged += new NotifyCollectionChangedEventHandler(SectionViewModel_CollectionChanged); }