/// <summary> /// Attempts to prefetch comments. Returns true if it is going, or false it not. /// </summary> /// <returns></returns> public bool PreFetchComments() { // Only attempt to do this once. if (_attemptedToLoadComments) { return(false); } _attemptedToLoadComments = true; // Do this in a background thread Task.Run(() => { // Ensure we have a collector var collector = EnsureCollector(); // We have to ask for all the comments here bc we can't extend. if (collector.PreLoadItems(false, _post.CurrentCommentShowingCount)) { return; } // If update returns false it isn't going to update because it has a cache. So just show the // cache. var args = new CollectionUpdatedArgs <Comment> { ChangedItems = collector.GetCurrentItems(false), IsFreshUpdate = true, IsInsert = false, StartingPosition = 0 }; CommentCollector_OnCollectionUpdated(null, args); }); return(true); }
/// <summary> /// Fired when the comment sort is changed. /// </summary> public void ChangeCommentSort() { // Show loading _post.FlipViewShowLoadingMoreComments = true; // Do this in a background thread Task.Run(() => { // Delete the collector DeleteCollector(); // Make a new one. var collector = EnsureCollector(); // Force our collector to update. if (collector.LoadAllItems(true, _post.CurrentCommentShowingCount)) { return; } // If update returns false it isn't going to update because it has a cache. So just show the // cache. var args = new CollectionUpdatedArgs <Comment> { ChangedItems = collector.GetCurrentItems(true), IsFreshUpdate = true, IsInsert = false, StartingPosition = 0 }; CommentCollector_OnCollectionUpdated(null, args); }); }
/// <summary> /// Fired when the stories come in for a type /// </summary> /// <param name="type"></param> /// <param name="e"></param> private void Collector_OnCollectionUpdated(UpdateTypes type, CollectionUpdatedArgs <Post> e) { if (e.ChangedItems.Count > 0) { // If we successfully got the post now get the images GetImagesFromPosts(e.ChangedItems, type); } }
private async void Collector_OnCollectionUpdated(object sender, CollectionUpdatedArgs <Message> e) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Setup the insert var insertIndex = e.StartingPosition; // Lock the list lock (_mMessageList) { // Set up the objects for the UI foreach (var message in e.ChangedItems) { // Check if we are adding or inserting. var isReplace = insertIndex < _mMessageList.Count; if (isReplace) { if (_mMessageList[insertIndex].Id.Equals(message.Id)) { // If the message is the same just update the UI vars _mMessageList[insertIndex].Body = message.Body; _mMessageList[insertIndex].IsNew = message.IsNew; } else { // Replace the current item _mMessageList[insertIndex] = message; } } else { // Add it to the end _mMessageList.Add(message); } insertIndex++; } // If it was a fresh update, remove anything past the last story sent. while (e.IsFreshUpdate && _mMessageList.Count > e.ChangedItems.Count) { _mMessageList.RemoveAt(_mMessageList.Count - 1); } } }); }
/// <summary> /// Fired when comments are updated /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void CommentCollector_OnCollectionUpdated(object sender, CollectionUpdatedArgs <Comment> e) { // Jump to the UI thread await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { // If this is fresh clear if (e.IsFreshUpdate) { // Remove each individually so we get nice animations while (_mCommentList.Count != 0) { _mCommentList.RemoveAt(_mCommentList.Count - 1); } } // Add the new posts to the end of the list foreach (var comment in e.ChangedItems) { _mCommentList.Add(comment); } }); }
/// <summary> /// Fired when the collection list has been updated. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void Collector_OnCollectionUpdated(object sender, CollectionUpdatedArgs <Post> args) { // Update the posts UpdatePosts(args.StartingPosition, args.ChangedItems); }
private async void CommentCollector_OnCollectionUpdated(object sender, CollectionUpdatedArgs <Comment> e) { // Dispatch to the UI thread await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Setup the insert var insertIndex = e.StartingPosition; // Lock the list lock (Comments) { lock (_fullCommentList) { if (e.IsFreshUpdate) { // Reset the full list _fullCommentList.Clear(); // For fresh updates we can just replace everything and expand anything that isn't. for (var i = 0; i < e.ChangedItems.Count; i++) { var newComment = e.ChangedItems[i]; var currentComment = i >= Comments.Count ? null : Comments[i]; // Check for highlight if (!string.IsNullOrWhiteSpace(_targetComment) && newComment.Id.Equals(_targetComment)) { newComment.IsHighlighted = true; } if (currentComment == null) { Comments.Add(newComment); } else { if (newComment.Id.Equals(currentComment.Id)) { // Update the comment Comments[i].Author = newComment.Author; Comments[i].Score = newComment.Score; Comments[i].TimeString = newComment.TimeString; Comments[i].CollapsedCommentCount = newComment.CollapsedCommentCount; Comments[i].Body = newComment.Body; Comments[i].Likes = newComment.Likes; Comments[i].ShowFullComment = true; } else { // Replace it Comments[i] = newComment; } } // Always add to the full list _fullCommentList.Add(newComment); } // Trim off anything that shouldn't be here anymore while (Comments.Count > e.ChangedItems.Count) { Comments.RemoveAt(Comments.Count - 1); } } else { // This is tricky because the comment list in the post is a subset of the main list due to collapse. // Thus items are missing or moved in that list. // How we will do it is the following. We will make all of actions to the main list. If the operation is // "add at the end" we will do it to both lists because it is safe no matter what the state of the comment list. // If we have an insert or replace we will build two lists. Once the main list is updated we will then address updating // the comment list properly. // This list tracks any inserts we need to do. The key is the parent comment id, the value is the comment to // be inserted. var insertList = new List <KeyValuePair <string, Comment> >(); // This list tracks any replaces we need to do. The key is the parent comment id, the value is the comment to // be inserted. var replaceList = new List <KeyValuePair <string, Comment> >(); // First update the main list foreach (var comment in e.ChangedItems) { if (!string.IsNullOrWhiteSpace(_targetComment) && comment.Id.Equals(_targetComment)) { comment.IsHighlighted = true; } // Check if this is a add or replace if not an insert var isReplace = insertIndex < _fullCommentList.Count; // If we are inserting just insert it where it should be. if (e.IsInsert) { _fullCommentList.Insert(insertIndex, comment); // Make sure we have a parent, if not use empty string var parentComment = insertIndex > 0 ? _fullCommentList[insertIndex - 1].Id : string.Empty; insertList.Add(new KeyValuePair <string, Comment>(parentComment, comment)); } else if (isReplace) { // Grab the id that we are replacing and the comment to replace it. replaceList.Add(new KeyValuePair <string, Comment>(_fullCommentList[insertIndex].Id, comment)); // Replace the current item _fullCommentList[insertIndex] = comment; } else { // Add it to the end of the main list _fullCommentList.Add(comment); // If we are adding it to the end of the main list it is safe to add it to the end of the UI list. Comments.Add(comment); } insertIndex++; } // Now deal with the insert list. foreach (var insertPair in insertList) { // If the key is empty string we are inserting into the head if (string.IsNullOrWhiteSpace(insertPair.Key)) { Comments.Insert(0, insertPair.Value); } else { // Try to find the parent comment. for (var i = 0; i < Comments.Count; i++) { var comment = Comments[i]; if (comment.Id.Equals(insertPair.Key)) { // We found the parent, it is not collapsed we should insert this comment after it. if (comment.ShowFullComment) { Comments.Insert(i + 1, insertPair.Value); } // We are done, break out of this parent search. break; } } } } // Now deal with the replace list. for (var replaceCount = 0; replaceCount < replaceList.Count; replaceCount++) { var replacePair = replaceList[replaceCount]; // Try to find the comment we will replace; Note if is very important that we start at the current replace point // because this comment might have been added before this count already due to a perviouse replace. In that case // we don't want to accidentally find that one instead of this one. for (var i = replaceCount; i < Comments.Count; i++) { var comment = Comments[i]; if (!comment.Id.Equals(replacePair.Key)) { continue; } // If the id is the same we are updating. If we replace the comment the UI will freak out, // so just update the UI values if (comment.Id.Equals(replacePair.Value.Id)) { Comments[i].Author = replacePair.Value.Author; Comments[i].Score = replacePair.Value.Score; Comments[i].TimeString = replacePair.Value.TimeString; Comments[i].CollapsedCommentCount = replacePair.Value.CollapsedCommentCount; Comments[i].Body = replacePair.Value.Body; Comments[i].Likes = replacePair.Value.Likes; } else { // Replace the comment with this one Comments[i] = replacePair.Value; } // We are done, break out of the search for the match. break; } } } } } }); }
/// <summary> /// Fired when we have post results /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void CurrentPostCollector_OnCollectionUpdated(object sender, CollectionUpdatedArgs <Post> e) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Posts insert at the bottom of the list. var showAll = _mCurrentSearchType.HasValue && _mCurrentSearchType.Value == SearchResultTypes.Post; // Lock the list lock (_mSearchResultsList) { // Insert the header var header = new SearchResult { ResultType = SearchResultTypes.Header, HeaderText = "Post Results" }; _mSearchResultsList.Add(header); // Insert the items var count = 0; foreach (var post in e.ChangedItems) { // Make the result var postResult = new SearchResult { ResultType = SearchResultTypes.Post, MajorText = post.Title, MinorText = $"{post.SubTextLine1} to {post.Subreddit}", MinorAccentText = $"({post.Score}) score; {post.NumComments} comments", DataContext = post }; // Add it to the list _mSearchResultsList.Add(postResult); // Itter count++; // If we are showing everything only show the top 3 results. // Otherwise show everything. if (!showAll && count > 2) { break; } } // Insert no results if so if (e.ChangedItems.Count == 0) { // Insert the header var noResults = new SearchResult { ResultType = SearchResultTypes.NoResults }; _mSearchResultsList.Add(noResults); } // Insert show more if we didn't show all if (e.ChangedItems.Count != 0 && !showAll) { // Insert the header var showMore = new SearchResult { ResultType = SearchResultTypes.ShowMore, DataContext = CPostShowMoreHeader }; _mSearchResultsList.Add(showMore); } } }); }
/// <summary> /// Fired when we have subreddit results /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void CurrentSubCollector_OnCollectionUpdated(object sender, CollectionUpdatedArgs <Subreddit> e) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Subreddits are always at the top of the list var insertIndex = 1; var showAll = _mCurrentSearchType.HasValue && _mCurrentSearchType.Value == SearchResultTypes.Subreddit; // Lock the list lock (_mSearchResultsList) { // Insert the header var header = new SearchResult { ResultType = SearchResultTypes.Header, HeaderText = "Subreddit Results" }; _mSearchResultsList.Insert(0, header); var count = 0; foreach (var subreddit in e.ChangedItems) { // Make sure it isn't private. Since we can't show these we will skip them for now // #todo fix this if (subreddit.SubredditType != null && subreddit.SubredditType.Equals("private")) { continue; } // Make the result var subredditResult = new SearchResult { ResultType = SearchResultTypes.Subreddit, MajorText = subreddit.Title, MarkdownText = subreddit.PublicDescription, MinorAccentText = $"/r/{subreddit.DisplayName}", DataContext = subreddit }; // Add it to the list _mSearchResultsList.Insert(insertIndex, subredditResult); // Itter count++; insertIndex++; // If we are showing everything only show the top 3 results. // Otherwise show everything. if (!showAll && count > 2) { break; } } // Insert no results if so if (e.ChangedItems.Count == 0) { // Insert the header var noResults = new SearchResult { ResultType = SearchResultTypes.NoResults }; _mSearchResultsList.Insert(insertIndex, noResults); insertIndex++; } // Insert show more if we didn't show all if (e.ChangedItems.Count != 0 && !showAll) { // Insert the header var showMore = new SearchResult { ResultType = SearchResultTypes.ShowMore, DataContext = CSubredditShowMoreHeader }; _mSearchResultsList.Insert(insertIndex, showMore); } } }); }
/// <summary> /// Fired when the collection list has been updated. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void Collector_OnCollectionUpdated(object sender, CollectionUpdatedArgs <Post> args) { // Update the post or posts SetPosts(args.StartingPosition, args.ChangedItems, args.IsFreshUpdate); }
/// <summary> /// Fired when the stories come in for a type /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Collector_OnCollectionUpdatedBand(object sender, CollectionUpdatedArgs <Post> e) { Collector_OnCollectionUpdated(UpdateTypes.Band, e); }
/// <summary> /// Fired when the stories come in for a type /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Collector_OnCollectionUpdatedDesktop(object sender, CollectionUpdatedArgs <Post> e) { Collector_OnCollectionUpdated(UpdateTypes.Desktop, e); }
/// <summary> /// Fired when the stories come in for a type /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Collector_OnCollectionUpdatedLockScreen(object sender, CollectionUpdatedArgs <Post> e) { Collector_OnCollectionUpdated(UpdateTypes.LockScreen, e); }