Exemple #1
0
 /// <summary>
 /// Fired when the stories come in for a type
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void Collector_OnCollectionUpdated(UpdateTypes type, OnCollectionUpdatedArgs <Post> e)
 {
     if (e.ChangedItems.Count > 0)
     {
         // If we successfully got the post now get the images
         GetImagesFromPosts(e.ChangedItems, type);
     }
 }
Exemple #2
0
        private void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Post> e)
        {
            List <string> newTrendingSubs = new List <string>();

            if (e.ChangedItems.Count > 0)
            {
                // We got it!
                Post   todaysPost = e.ChangedItems[0];
                string selfText   = e.ChangedItems[0].Selftext;

                // Parse out the subreddits. This isn't going to be pretty.
                // There inst any api to get these right now (that I can find)
                // so this is the best we have.
                try
                {
                    // This is so bad. The only way to really find them is to look for the ## and then **
                    // I hope they never change this or this will explode so quickly
                    int nextHash = selfText.IndexOf("##");
                    while (nextHash != -1)
                    {
                        // Find the bold indicator
                        int nextBold = selfText.IndexOf("**", nextHash);
                        if (nextBold == -1)
                        {
                            break;
                        }
                        nextBold += 2;

                        // Find the last bold indicator
                        int endBold = selfText.IndexOf("**", nextBold);
                        if (endBold == -1)
                        {
                            break;
                        }

                        // Get the subreddit
                        string subreddit = selfText.Substring(nextBold, endBold - nextBold);
                        newTrendingSubs.Add(subreddit);

                        // Update the index
                        nextHash = selfText.IndexOf("##", endBold + 2);
                    }
                }
                catch (Exception ex)
                {
                    m_baconMan.MessageMan.DebugDia("failed to parse trending subs post", ex);
                }
            }

            // If we get this far we are going to say this is good enough and set the
            // time and list. If our parser breaks we don't want to make a ton of requests
            // constantly.
            LastTrendingSubs = newTrendingSubs;
            LastUpdate       = DateTime.Now;

            // Fire the event if we are good or not. If the list is empty that's fine
            FireReadyEvent(newTrendingSubs);
        }
Exemple #3
0
        private async void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Message> e)
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Setup the insert
                int insertIndex = e.StartingPosition;

                // Lock the list
                lock (m_messageList)
                {
                    // Set up the objects for the UI
                    foreach (Message message in e.ChangedItems)
                    {
                        // Check if we are adding or inserting.
                        bool isReplace = insertIndex < m_messageList.Count;

                        if (isReplace)
                        {
                            if (m_messageList[insertIndex].Id.Equals(message.Id))
                            {
                                // If the message is the same just update the UI vars
                                m_messageList[insertIndex].Body  = message.Body;
                                m_messageList[insertIndex].IsNew = message.IsNew;
                            }
                            else
                            {
                                // Replace the current item
                                m_messageList[insertIndex] = message;
                            }
                        }
                        else
                        {
                            // Add it to the end
                            m_messageList.Add(message);
                        }
                        insertIndex++;
                    }

                    // If it was a fresh update, remove anything past the last story sent.
                    while (e.IsFreshUpdate && m_messageList.Count > e.ChangedItems.Count)
                    {
                        m_messageList.RemoveAt(m_messageList.Count - 1);
                    }
                }
            });
        }
        /// <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 (m_attemptedToLoadComments)
            {
                return(false);
            }
            m_attemptedToLoadComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Get the comment collector, if we don't want to show a subset don't give it the target comment
                m_commentCollector = CommentCollector.GetCollector(m_post, App.BaconMan, m_showThreadSubset ? m_targetComment : null);

                // Sub to collection callbacks for the comments.
                m_commentCollector.OnCollectionUpdated    += CommentCollector_OnCollectionUpdated;
                m_commentCollector.OnCollectorStateChange += CommentCollector_OnCollectorStateChange;

                // Request a few comments so we will fill the screen.
                // If the user scrolls we will get more later.
                // To fix a bug where reddit doesn't give us the same
                // comments the first time as the next, we will
                // #bug #todo because of the "can't ask for more" bug we will
                // just ask for all of the comments here.
                if (!m_commentCollector.Update(false, 150))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs <Comment> args = new OnCollectionUpdatedArgs <Comment>()
                    {
                        ChangedItems     = m_commentCollector.GetCurrentPosts(),
                        IsFreshUpdate    = true,
                        IsInsert         = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });

            return(true);
        }
        /// <summary>
        /// Fired when comments are updated
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void CommentCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Comment> e)
        {
            // Jump to the UI thread
            await global::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 (m_commentList.Count != 0)
                    {
                        m_commentList.RemoveAt(m_commentList.Count - 1);
                    }
                }

                // Add the new posts to the end of the list
                foreach (Comment comment in e.ChangedItems)
                {
                    m_commentList.Add(comment);
                }
            });
        }
        /// <summary>
        /// Fired when the comment sort is changed.
        /// </summary>
        public void ChangeCommentSort()
        {
            // Show loading
            m_post.FlipViewShowLoadingMoreComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Kill the current collector
                if (m_commentCollector != null)
                {
                    m_commentCollector.OnCollectionUpdated    -= CommentCollector_OnCollectionUpdated;
                    m_commentCollector.OnCollectorStateChange -= CommentCollector_OnCollectorStateChange;
                }
                m_commentCollector = null;

                // Get a new collector with the new sort
                m_commentCollector = new DeferredCollector <Comment>(CommentCollector.GetCollector(m_post, App.BaconMan));

                // Sub to collection callbacks for the comments.
                m_commentCollector.OnCollectionUpdated    += CommentCollector_OnCollectionUpdated;
                m_commentCollector.OnCollectorStateChange += CommentCollector_OnCollectorStateChange;

                // Force our collector to update.
                if (!m_commentCollector.LoadAllItems(true, m_post.CurrentCommentShowingCount))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs <Comment> args = new OnCollectionUpdatedArgs <Comment>()
                    {
                        ChangedItems     = m_commentCollector.GetCurrentItems(true),
                        IsFreshUpdate    = true,
                        IsInsert         = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });
        }
Exemple #7
0
        /// <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 (m_attemptedToLoadComments)
            {
                return(false);
            }
            m_attemptedToLoadComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Get the comment collector, if we don't want to show a subset don't give it the target comment
                m_commentCollector = CommentCollector.GetCollector(m_post, App.BaconMan, m_showThreadSubset ? m_targetComment : null);

                // Sub to collection callbacks for the comments.
                m_commentCollector.OnCollectionUpdated    += CommentCollector_OnCollectionUpdated;
                m_commentCollector.OnCollectorStateChange += CommentCollector_OnCollectorStateChange;

                // We have to ask for all the comments here bc we can't extend.
                if (!m_commentCollector.Update(false, m_post.CurrentCommentShowingCount))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs <Comment> args = new OnCollectionUpdatedArgs <Comment>()
                    {
                        ChangedItems     = m_commentCollector.GetCurrentPosts(),
                        IsFreshUpdate    = true,
                        IsInsert         = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });

            return(true);
        }
 /// <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, OnCollectionUpdatedArgs <Post> e)
 {
     Collector_OnCollectionUpdated(UpdateTypes.LockScreen, e);
 }
        /// <summary>
        /// Fired when the comment sort is changed.
        /// </summary>
        public void ChangeCommentSort()
        {
            // Show loading
            m_post.FlipViewShowLoadingMoreComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Delete the collector
                DeleteCollector();

                // Make a new one.
                DeferredCollector<Comment> collector = EnsureCollector();

                // Force our collector to update.
                if (!collector.LoadAllItems(true, m_post.CurrentCommentShowingCount))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs<Comment> args = new OnCollectionUpdatedArgs<Comment>()
                    {
                        ChangedItems = collector.GetCurrentItems(true),
                        IsFreshUpdate = true,
                        IsInsert = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });
        }
        /// <summary>
        /// Fired when we have subreddit results
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void CurrentSubCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Subreddit> e)
        {
            await global::Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Subreddits are always at the top of the list
                int insertIndex = 1;
                bool showAll    = m_currentSearchType.HasValue && m_currentSearchType.Value == SearchResultTypes.Subreddit;

                // Lock the list
                lock (m_searchResultsList)
                {
                    // Insert the header
                    SearchResult header = new SearchResult()
                    {
                        ResultType = SearchResultTypes.Header,
                        HeaderText = "Subreddit Results"
                    };
                    m_searchResultsList.Insert(0, header);

                    int count = 0;
                    foreach (Subreddit 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
                        SearchResult subredditResult = new SearchResult()
                        {
                            ResultType      = SearchResultTypes.Subreddit,
                            MajorText       = subreddit.Title,
                            MarkdownText    = subreddit.PublicDescription,
                            MinorAccentText = $"/r/{subreddit.DisplayName}",
                            DataContext     = subreddit
                        };

                        // Add it to the list
                        m_searchResultsList.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
                        SearchResult noResults = new SearchResult()
                        {
                            ResultType = SearchResultTypes.NoResults
                        };
                        m_searchResultsList.Insert(insertIndex, noResults);
                        insertIndex++;
                    }

                    // Insert show more if we didn't show all
                    if (e.ChangedItems.Count != 0 && !showAll)
                    {
                        // Insert the header
                        SearchResult showMore = new SearchResult()
                        {
                            ResultType  = SearchResultTypes.ShowMore,
                            DataContext = c_subredditShowMoreHeader
                        };
                        m_searchResultsList.Insert(insertIndex, showMore);
                    }
                }
            });
        }
Exemple #11
0
        /// <summary>
        /// Fired when we have subreddit results
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void CurrentSubCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Subreddit> e)
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Subreddits are always at the top of the list
                int insertIndex = 1;
                bool showAll = m_currentSearchType.HasValue && m_currentSearchType.Value == SearchResultTypes.Subreddit;

                // Lock the list
                lock(m_searchResultsList)
                {
                    // Insert the header
                    SearchResult header = new SearchResult()
                    {
                        ResultType = SearchResultTypes.Header,
                        HeaderText = "Subreddit Results"
                    };
                    m_searchResultsList.Insert(0, header);

                    int count = 0;
                    foreach(Subreddit 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
                        SearchResult subredditResult = new SearchResult()
                        {
                            ResultType = SearchResultTypes.Subreddit,
                            MajorText = subreddit.Title,
                            MinorText = subreddit.PublicDescription,
                            MinorAccentText = $"/r/{subreddit.DisplayName}",
                            DataContext = subreddit
                        };

                        // Hide the minor text if there isn't any
                        if(String.IsNullOrWhiteSpace(subreddit.PublicDescription))
                        {
                            subredditResult.ShowMinorText = Visibility.Collapsed;
                        }

                        // Add it to the list
                        m_searchResultsList.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
                        SearchResult noResults = new SearchResult()
                        {
                            ResultType = SearchResultTypes.NoResults
                        };
                        m_searchResultsList.Insert(insertIndex, noResults);
                        insertIndex++;
                    }

                    // Insert show more if we didn't show all
                    if(e.ChangedItems.Count != 0 && !showAll)
                    {
                        // Insert the header
                        SearchResult showMore = new SearchResult()
                        {
                            ResultType = SearchResultTypes.ShowMore,
                            DataContext = c_subredditShowMoreHeader
                        };
                        m_searchResultsList.Insert(insertIndex, showMore);
                    }
                }
            });
        }
Exemple #12
0
        private async void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Message> e)
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Setup the insert
                int insertIndex = e.StartingPosition;

                // Lock the list
                lock (m_messageList)
                {
                    // Set up the objects for the UI
                    foreach (Message message in e.ChangedItems)
                    {
                        // Check if we are adding or inserting.
                        bool isReplace = insertIndex < m_messageList.Count;

                        if (isReplace)
                        {
                            if (m_messageList[insertIndex].Id.Equals(message.Id))
                            {
                                // If the message is the same just update the UI vars
                                m_messageList[insertIndex].Body = message.Body;
                            }
                            else
                            {
                                // Replace the current item
                                m_messageList[insertIndex] = message;
                            }
                        }
                        else
                        {
                            // Add it to the end
                            m_messageList.Add(message);
                        }
                        insertIndex++;
                    }

                    // If it was a fresh update, remove anything past the last story sent.
                    while (e.IsFreshUpdate && m_messageList.Count > e.ChangedItems.Count)
                    {
                        m_messageList.RemoveAt(m_messageList.Count - 1);
                    }
                }
            });
        }
 /// <summary>
 /// Fired when the stories come in for a type
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void Collector_OnCollectionUpdated(UpdateTypes type, OnCollectionUpdatedArgs<Post> e)
 {
     if(e.ChangedItems.Count > 0)
     {
         // If we successfully got the post now get the images
         GetImagesFromPosts(e.ChangedItems, type);
     }
 }
 /// <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, OnCollectionUpdatedArgs<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, OnCollectionUpdatedArgs<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, OnCollectionUpdatedArgs<Post> e)
 {
     Collector_OnCollectionUpdated(UpdateTypes.LockScreen, e);
 }
        private void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Post> e)
        {
            List<string> newTrendingSubs = new List<string>();
            if (e.ChangedItems.Count > 0)
            {
                // We got it!
                Post todaysPost = e.ChangedItems[0];
                string selfText = e.ChangedItems[0].Selftext;

                // Parse out the subreddits. This isn't going to be pretty.
                // There inst any api to get these right now (that I can find)
                // so this is the best we have.
                try
                {
                    // This is so bad. The only way to really find them is to look for the ## and then **
                    // I hope they never change this or this will explode so quickly
                    int nextHash = selfText.IndexOf("##");
                    while (nextHash != -1)
                    {
                        // Find the bold indicator
                        int nextBold = selfText.IndexOf("**", nextHash);
                        if(nextBold == -1)
                        {
                            break;
                        }
                        nextBold += 2;

                        // Find the last bold indicator
                        int endBold = selfText.IndexOf("**", nextBold);
                        if (endBold == -1)
                        {
                            break;
                        }

                        // Get the subreddit
                        string subreddit = selfText.Substring(nextBold, endBold - nextBold);
                        newTrendingSubs.Add(subreddit);

                        // Update the index
                        nextHash = selfText.IndexOf("##", endBold + 2);
                    }
                }
                catch(Exception ex)
                {
                    m_baconMan.TelemetryMan.ReportUnExpectedEvent(this, "failedtoParseTrendingPost", ex);
                    m_baconMan.MessageMan.DebugDia("failed to parse trending subs post", ex);
                }
            }

            // If we get this far we are going to say this is good enough and set the
            // time and list. If our parser breaks we don't want to make a ton of requests
            // constantly.
            LastTrendingSubs = newTrendingSubs;
            LastUpdate = DateTime.Now;

            // Fire the event if we are good or not. If the list is empty that's fine
            FireReadyEvent(newTrendingSubs);
        }
        /// <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(m_attemptedToLoadComments)
            {
                return false;
            }
            m_attemptedToLoadComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Get the comment collector, if we don't want to show a subset don't give it the target comment
                m_commentCollector = CommentCollector.GetCollector(m_post, App.BaconMan, m_showThreadSubset ? m_targetComment : null);

                // Sub to collection callbacks for the comments.
                m_commentCollector.OnCollectionUpdated += CommentCollector_OnCollectionUpdated;
                m_commentCollector.OnCollectorStateChange += CommentCollector_OnCollectorStateChange;

                // We have to ask for all the comments here bc we can't extend.
                if (!m_commentCollector.Update(false, m_post.CurrentCommentShowingCount))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs<Comment> args = new OnCollectionUpdatedArgs<Comment>()
                    {
                        ChangedItems = m_commentCollector.GetCurrentPosts(),
                        IsFreshUpdate = true,
                        IsInsert = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });

            return true;
        }
 /// <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, OnCollectionUpdatedArgs <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_OnCollectionUpdatedBand(object sender, OnCollectionUpdatedArgs <Post> e)
 {
     Collector_OnCollectionUpdated(UpdateTypes.Band, e);
 }
 /// <summary>
 /// Used by the get subreddit stories to return posts.
 /// We can't use a lambda because the weak events don't support it.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Post> e)
 {
     m_currentSubredditPosts = e.ChangedItems;
     m_autoReset.Set();
 }
 /// <summary>
 /// Fired when the collection list has been updated.
 /// </summary>
 /// <param name="startingPos"></param>
 /// <param name="changedPosts"></param>
 private void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Post> args)
 {
     // Update the post or posts
     SetPosts(args.StartingPosition, args.ChangedItems, args.IsFreshUpdate);
 }
 /// <summary>
 /// Used by the get subreddit stories to return posts.
 /// We can't use a lambda because the weak events don't support it.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Post> e)
 {
     m_currentSubredditPosts = e.ChangedItems;
     m_autoReset.Set();
 }
Exemple #24
0
        /// <summary>
        /// Fired when we have post results
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void CurrentPostCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Post> e)
        {
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Posts insert at the bottom of the list.
                bool showAll = m_currentSearchType.HasValue && m_currentSearchType.Value == SearchResultTypes.Post;

                // Lock the list
                lock (m_searchResultsList)
                {
                    // Insert the header
                    SearchResult header = new SearchResult()
                    {
                        ResultType = SearchResultTypes.Header,
                        HeaderText = "Post Results"
                    };
                    m_searchResultsList.Add(header);

                    // Insert the items
                    int count = 0;
                    foreach (Post post in e.ChangedItems)
                    {
                        // Make the result
                        SearchResult 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
                        m_searchResultsList.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
                        SearchResult noResults = new SearchResult()
                        {
                            ResultType = SearchResultTypes.NoResults
                        };
                        m_searchResultsList.Add(noResults);
                    }

                    // Insert show more if we didn't show all
                    if (e.ChangedItems.Count != 0 && !showAll)
                    {
                        // Insert the header
                        SearchResult showMore = new SearchResult()
                        {
                            ResultType = SearchResultTypes.ShowMore,
                            DataContext = c_postShowMoreHeader
                        };
                        m_searchResultsList.Add(showMore);
                    }
                }
            });
        }
        /// <summary>
        /// Fired when comments are updated
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void CommentCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<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 (m_commentList.Count != 0)
                    {
                        m_commentList.RemoveAt(m_commentList.Count - 1);
                    }
                }

                // Add the new posts to the end of the list
                foreach (Comment comment in e.ChangedItems)
                {
                    m_commentList.Add(comment);
                }
            });
        }
        private async void CommentCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Comment> e)
        {
            // Dispatch to the UI thread
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Setup the insert
                int insertIndex = e.StartingPosition;

                // Lock the list
                lock (m_post.Comments)
                {
                    lock (m_fullCommentList)
                    {
                        if (e.IsFreshUpdate)
                        {
                            // Reset the full list
                            m_fullCommentList.Clear();


                            // For fresh updates we can just replace everything and expand anything that isn't.
                            for (int i = 0; i < e.ChangedItems.Count; i++)
                            {
                                Comment newComment     = e.ChangedItems[i];
                                Comment currentComment = i >= m_post.Comments.Count ? null : m_post.Comments[i];

                                if (currentComment == null)
                                {
                                    m_post.Comments.Add(newComment);
                                }
                                else
                                {
                                    if (newComment.Id.Equals(currentComment.Id))
                                    {
                                        // Update the comment
                                        m_post.Comments[i].Author                = newComment.Author;
                                        m_post.Comments[i].Score                 = newComment.Score;
                                        m_post.Comments[i].TimeString            = newComment.TimeString;
                                        m_post.Comments[i].CollapsedCommentCount = newComment.CollapsedCommentCount;
                                        m_post.Comments[i].Body            = newComment.Body;
                                        m_post.Comments[i].Likes           = newComment.Likes;
                                        m_post.Comments[i].ShowFullComment = true;
                                    }
                                    else
                                    {
                                        // Replace it
                                        m_post.Comments[i] = newComment;
                                    }
                                }

                                // Always add to the full list
                                m_fullCommentList.Add(newComment);
                            }

                            // Trim off anything that shouldn't be here anymore
                            while (m_post.Comments.Count > e.ChangedItems.Count)
                            {
                                m_post.Comments.RemoveAt(m_post.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.
                            List <KeyValuePair <string, Comment> > 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.
                            List <KeyValuePair <string, Comment> > replaceList = new List <KeyValuePair <string, Comment> >();

                            // First update the main list
                            foreach (Comment comment in e.ChangedItems)
                            {
                                if (m_targetComment != null && comment.Id.Equals(m_targetComment))
                                {
                                    comment.IsHighlighted = true;
                                }

                                // Check if this is a add or replace if not an insert
                                bool isReplace = insertIndex < m_fullCommentList.Count;

                                // If we are inserting just insert it where it should be.
                                if (e.IsInsert)
                                {
                                    m_fullCommentList.Insert(insertIndex, comment);

                                    // Make sure we have a parent, if not use empty string
                                    string parentComment = insertIndex > 0 ? m_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>(m_fullCommentList[insertIndex].Id, comment));

                                    // Replace the current item
                                    m_fullCommentList[insertIndex] = comment;
                                }
                                else
                                {
                                    // Add it to the end of the main list
                                    m_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.
                                    m_post.Comments.Add(comment);
                                }
                                insertIndex++;
                            }

                            // Now deal with the insert list.
                            foreach (KeyValuePair <string, Comment> insertPair in insertList)
                            {
                                // If the key is empty string we are inserting into the head
                                if (String.IsNullOrWhiteSpace(insertPair.Key))
                                {
                                    m_post.Comments.Insert(0, insertPair.Value);
                                }
                                else
                                {
                                    // Try to find the parent comment.
                                    for (int i = 0; i < m_post.Comments.Count; i++)
                                    {
                                        Comment comment = m_post.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)
                                            {
                                                m_post.Comments.Insert(i + 1, insertPair.Value);
                                            }

                                            // We are done, break out of this parent search.
                                            break;
                                        }
                                    }
                                }
                            }

                            // Now deal with the replace list.
                            for (int replaceCount = 0; replaceCount < replaceList.Count; replaceCount++)
                            {
                                KeyValuePair <string, Comment> 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 (int i = replaceCount; i < m_post.Comments.Count; i++)
                                {
                                    Comment comment = m_post.Comments[i];
                                    if (comment.Id.Equals(replacePair.Key))
                                    {
                                        // 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))
                                        {
                                            m_post.Comments[i].Author                = replacePair.Value.Author;
                                            m_post.Comments[i].Score                 = replacePair.Value.Score;
                                            m_post.Comments[i].TimeString            = replacePair.Value.TimeString;
                                            m_post.Comments[i].CollapsedCommentCount = replacePair.Value.CollapsedCommentCount;
                                            m_post.Comments[i].Body  = replacePair.Value.Body;
                                            m_post.Comments[i].Likes = replacePair.Value.Likes;
                                        }
                                        else
                                        {
                                            // Replace the comment with this one
                                            m_post.Comments[i] = replacePair.Value;
                                        }

                                        // We are done, break out of the search for the match.
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
Exemple #27
0
 /// <summary>
 /// Fired when the collection list has been updated.
 /// </summary>
 /// <param name="startingPos"></param>
 /// <param name="changedPosts"></param>
 private void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Post> args)
 {
     // Update the posts
     UpdatePosts(args.StartingPosition, args.ChangedItems);
 }
        /// <summary>
        /// Fired when we have post results
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void CurrentPostCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs <Post> e)
        {
            await global::Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Posts insert at the bottom of the list.
                bool showAll = m_currentSearchType.HasValue && m_currentSearchType.Value == SearchResultTypes.Post;

                // Lock the list
                lock (m_searchResultsList)
                {
                    // Insert the header
                    SearchResult header = new SearchResult()
                    {
                        ResultType = SearchResultTypes.Header,
                        HeaderText = "Post Results"
                    };
                    m_searchResultsList.Add(header);

                    // Insert the items
                    int count = 0;
                    foreach (Post post in e.ChangedItems)
                    {
                        // Make the result
                        SearchResult 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
                        m_searchResultsList.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
                        SearchResult noResults = new SearchResult()
                        {
                            ResultType = SearchResultTypes.NoResults
                        };
                        m_searchResultsList.Add(noResults);
                    }

                    // Insert show more if we didn't show all
                    if (e.ChangedItems.Count != 0 && !showAll)
                    {
                        // Insert the header
                        SearchResult showMore = new SearchResult()
                        {
                            ResultType  = SearchResultTypes.ShowMore,
                            DataContext = c_postShowMoreHeader
                        };
                        m_searchResultsList.Add(showMore);
                    }
                }
            });
        }
        /// <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(m_attemptedToLoadComments)
            {
                return false;
            }
            m_attemptedToLoadComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Get the comment collector, if we don't want to show a subset don't give it the target comment
                m_commentCollector = CommentCollector.GetCollector(m_post, App.BaconMan, m_showThreadSubset ? m_targetComment : null);

                // Sub to collection callbacks for the comments.
                m_commentCollector.OnCollectionUpdated += CommentCollector_OnCollectionUpdated;
                m_commentCollector.OnCollectorStateChange += CommentCollector_OnCollectorStateChange;

                // Request a few comments so we will fill the screen.
                // If the user scrolls we will get more later.
                // To fix a bug where reddit doesn't give us the same
                // comments the first time as the next, we will
                // #bug #todo because of the "can't ask for more" bug we will
                // just ask for all of the comments here.
                if (!m_commentCollector.Update(false, 150))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs<Comment> args = new OnCollectionUpdatedArgs<Comment>()
                    {
                        ChangedItems = m_commentCollector.GetCurrentPosts(),
                        IsFreshUpdate = true,
                        IsInsert = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });

            return true;
        }
 /// <summary>
 /// Fired when the collection list has been updated.
 /// </summary>
 /// <param name="startingPos"></param>
 /// <param name="changedPosts"></param>
 private void Collector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Post> args)
 {
     // Update the post or posts
     SetPosts(args.StartingPosition, args.ChangedItems, args.IsFreshUpdate);
 }
        private async void CommentCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Comment> e)
        {
            // Dispatch to the UI thread
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Setup the insert
                int insertIndex = e.StartingPosition;

                // Lock the list
                lock (Comments)
                {
                    lock(m_fullCommentList)
                    {
                        if (e.IsFreshUpdate)
                        {
                            // Reset the full list
                            m_fullCommentList.Clear();


                            // For fresh updates we can just replace everything and expand anything that isn't.
                            for (int i = 0; i < e.ChangedItems.Count; i++)
                            {
                                Comment newComment = e.ChangedItems[i];
                                Comment currentComment = i >= Comments.Count ? null : Comments[i];

                                // Check for highlight
                                if (!String.IsNullOrWhiteSpace(m_targetComment) && newComment.Id.Equals(m_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
                                m_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.
                            List<KeyValuePair<string, Comment>> 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.
                            List<KeyValuePair<string, Comment>> replaceList = new List<KeyValuePair<string, Comment>>();

                            // First update the main list
                            foreach (Comment comment in e.ChangedItems)
                            {
                                if (!String.IsNullOrWhiteSpace(m_targetComment) && comment.Id.Equals(m_targetComment))
                                {
                                    comment.IsHighlighted = true;
                                }

                                // Check if this is a add or replace if not an insert
                                bool isReplace = insertIndex < m_fullCommentList.Count;

                                // If we are inserting just insert it where it should be.
                                if (e.IsInsert)
                                {
                                    m_fullCommentList.Insert(insertIndex, comment);

                                    // Make sure we have a parent, if not use empty string
                                    string parentComment = insertIndex > 0 ? m_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>(m_fullCommentList[insertIndex].Id, comment));

                                    // Replace the current item
                                    m_fullCommentList[insertIndex] = comment;
                                }
                                else
                                {
                                    // Add it to the end of the main list
                                    m_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 (KeyValuePair<string, Comment> 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 (int i = 0; i < Comments.Count; i++)
                                    {
                                        Comment 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 (int replaceCount = 0; replaceCount < replaceList.Count; replaceCount++)
                            {
                                KeyValuePair<string, Comment> 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 (int i = replaceCount; i < Comments.Count; i++)
                                {
                                    Comment comment = Comments[i];
                                    if (comment.Id.Equals(replacePair.Key))
                                    {
                                        // 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;

                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
        private async void CommentCollector_OnCollectionUpdated(object sender, OnCollectionUpdatedArgs<Comment> e)
        {
            // Dispatch to the UI thread
            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                // Setup the insert
                int insertIndex = e.StartingPosition;

                // Lock the list
                lock (m_post.Comments)
                {
                    lock(m_fullCommentList)
                    {
                        // 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.
                        List<KeyValuePair<string, Comment>> 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.
                        List<KeyValuePair<string, Comment>> replaceList = new List<KeyValuePair<string, Comment>>();

                        // First update the main list
                        foreach (Comment comment in e.ChangedItems)
                        {
                            if(m_targetComment != null && comment.Id.Equals(m_targetComment))
                            {
                                comment.IsHighlighted = true;
                            }

                            // Check if this is a add or replace if not an insert
                            bool isReplace = insertIndex < m_fullCommentList.Count;

                            // If we are inserting just insert it where it should be.
                            if (e.IsInsert)
                            {
                                m_fullCommentList.Insert(insertIndex, comment);

                                // Make sure we have a parent, if not use empty string
                                string parentComment = insertIndex > 0 ? m_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>(m_fullCommentList[insertIndex].Id, comment));

                                // Replace the current item
                                m_fullCommentList[insertIndex] = comment;
                            }
                            else
                            {
                                // Add it to the end of the main list
                                m_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.
                                m_post.Comments.Add(comment);
                            }
                            insertIndex++;
                        }

                        // Now deal with the insert list.
                        foreach(KeyValuePair<string, Comment> insertPair in insertList)
                        {
                            // If the key is empty string we are inserting into the head
                            if(String.IsNullOrWhiteSpace(insertPair.Key))
                            {
                                m_post.Comments.Insert(0, insertPair.Value);
                            }
                            else
                            {
                                // Try to find the parent comment.
                                for(int i = 0; i < m_post.Comments.Count; i++)
                                {
                                    Comment comment = m_post.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)
                                        {
                                            m_post.Comments.Insert(i + 1, insertPair.Value);
                                        }

                                        // We are done, break out of this parent search.
                                        break;

                                    }
                                }
                            }
                        }

                        // Now deal with the replace list.
                        foreach (KeyValuePair<string, Comment> replacePair in replaceList)
                        {
                            // Try to find the comment we will replace
                            for (int i = 0; i < m_post.Comments.Count; i++)
                            {
                                Comment comment = m_post.Comments[i];
                                if (comment.Id.Equals(replacePair.Key))
                                {
                                    // 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))
                                    {
                                        m_post.Comments[i].Author = comment.Author;
                                        m_post.Comments[i].Score = comment.Score;
                                        m_post.Comments[i].TimeString = comment.TimeString;
                                        m_post.Comments[i].CollapsedCommentCount = comment.CollapsedCommentCount;
                                        m_post.Comments[i].Body = comment.Body;
                                        m_post.Comments[i].Likes = comment.Likes;
                                    }
                                    else
                                    {
                                        // Replace the comment with this one
                                        m_post.Comments[i] = replacePair.Value;
                                    }

                                    // We are done, break out of the search for the match.
                                    break;

                                }
                            }

                        }
                    }
                }
            });
        }
        /// <summary>
        /// Fired when the comment sort is changed.
        /// </summary>
        public void ChangeCommentSort()
        {
            // Show loading
            m_post.FlipViewShowLoadingMoreComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Kill the current collector
                if (m_commentCollector != null)
                {
                    m_commentCollector.OnCollectionUpdated -= CommentCollector_OnCollectionUpdated;
                    m_commentCollector.OnCollectorStateChange -= CommentCollector_OnCollectorStateChange;
                }
                m_commentCollector = null;

                // Get a new collector with the new sort
                m_commentCollector = new DeferredCollector<Comment>(CommentCollector.GetCollector(m_post, App.BaconMan));

                // Sub to collection callbacks for the comments.
                m_commentCollector.OnCollectionUpdated += CommentCollector_OnCollectionUpdated;
                m_commentCollector.OnCollectorStateChange += CommentCollector_OnCollectorStateChange;

                // Force our collector to update.
                if (!m_commentCollector.LoadAllItems(true, m_post.CurrentCommentShowingCount))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs<Comment> args = new OnCollectionUpdatedArgs<Comment>()
                    {
                        ChangedItems = m_commentCollector.GetCurrentItems(true),
                        IsFreshUpdate = true,
                        IsInsert = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });
        }
 /// <summary>
 /// Fired when the collection list has been updated.
 /// </summary>
 /// <param name="startingPos"></param>
 /// <param name="changedPosts"></param>
 private void Collector_OnCollectionUpdated(object sender , OnCollectionUpdatedArgs<Post> args)
 {
     // Update the posts
     UpdatePosts(args.StartingPosition, args.ChangedItems);
 }
        /// <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(m_attemptedToLoadComments)
            {
                return false;
            }
            m_attemptedToLoadComments = true;

            // Do this in a background thread
            Task.Run(() =>
            {
                // Ensure we have a collector
                EnsureCollector();

                // We have to ask for all the comments here bc we can't extend.
                if (!m_commentCollector.PreLoadItems(false, m_post.CurrentCommentShowingCount))
                {
                    // If update returns false it isn't going to update because it has a cache. So just show the
                    // cache.
                    OnCollectionUpdatedArgs<Comment> args = new OnCollectionUpdatedArgs<Comment>()
                    {
                        ChangedItems = m_commentCollector.GetCurrentItems(false),
                        IsFreshUpdate = true,
                        IsInsert = false,
                        StartingPosition = 0
                    };
                    CommentCollector_OnCollectionUpdated(null, args);
                }
            });

            return true;
        }