public FlipViewPostCommentManager(ref Post post, string targetComment, bool showThreadSubset) { m_post = post; m_targetComment = targetComment; m_showThreadSubset = showThreadSubset; // If we have a target comment and we want to show only a subset. if (showThreadSubset && !String.IsNullOrWhiteSpace(targetComment)) { post.FlipViewShowEntireThreadMessage = Visibility.Visible; } else { post.FlipViewShowEntireThreadMessage = Visibility.Collapsed; } // This post might have comments if opened already in flip view. Clear them out if it does. m_post.Comments.Clear(); if (!m_post.HaveCommentDefaultsBeenSet) { // Set the default count and sort for comments post.CurrentCommentShowingCount = App.BaconMan.UiSettingsMan.Comments_DefaultCount; post.CommentSortType = App.BaconMan.UiSettingsMan.Comments_DefaultSortType; m_post.HaveCommentDefaultsBeenSet = true; } }
/// <summary> /// Called by the host when we should show content. /// </summary> /// <param name="post"></param> public void OnPrepareContent(Post post) { // So the loading UI m_host.ShowLoading(); m_post = post; // Since this can be costly kick it off to a background thread so we don't do work // as we are animating. Task.Run(async () => { // Get the video Uri YouTubeUri youTubeUri = await GetYouTubeVideoUrl(post); // Back to the UI thread with pri await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { if (youTubeUri == null) { // If we failed fallback to the browser. m_host.FallbackToWebBrowser(m_post); App.BaconMan.TelemetryMan.ReportUnExpectedEvent(this, "FailedToGetYoutubeVideoAfterSuccess"); return; } // Setup the video m_youTubeVideo = new MediaElement(); m_youTubeVideo.AutoPlay = false; m_youTubeVideo.AreTransportControlsEnabled = true; m_youTubeVideo.CurrentStateChanged += MediaElement_CurrentStateChanged; m_youTubeVideo.Source = youTubeUri.Uri; ui_contentRoot.Children.Add(m_youTubeVideo); }); }); }
public FlipViewPostContext(IPanelHost host, PostCollector collector, Post post, string targetComment) { Post = post; Collector = collector; Host = host; TargetComment = targetComment; }
/// <summary> /// Called when we should show the content /// </summary> /// <param name="post"></param> public void OnPrepareContent(Post post) { string headerText = ""; string minorText = ""; if (post.IsSelf) { headerText = "There's no content here!"; minorText = "Scroll down to view the discussion."; } else { m_content = MiscellaneousHelper.TryToFindRedditContentInLink(post.Url); switch(m_content.Type) { case RedditContentType.Subreddit: headerText = "This post links to a subreddit"; minorText = $"Tap anywhere to view /r/{m_content.Subreddit}"; break; case RedditContentType.Comment: headerText = "This post links to a comment thread"; minorText = "Tap anywhere to view it"; break; case RedditContentType.Post: headerText = "This post links to a reddit post"; minorText = $"Tap anywhere to view it"; break; } } ui_headerText.Text = headerText; ui_minorText.Text = minorText; }
/// <summary> /// Called by the host when we should show content. /// </summary> /// <param name="post"></param> public async void OnPrepareContent(Post post) { // So the loading UI m_host.ShowLoading(); m_loadingHidden = false; // Since some of this can be costly, delay the work load until we aren't animating. await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { lock(this) { if(m_isDestroyed) { return; } // Make the webview m_webView = new WebView(WebViewExecutionMode.SeparateThread); // Setup the listeners, we need all of these because some web pages don't trigger // some of them. m_webView.FrameNavigationCompleted += NavigationCompleted; m_webView.NavigationFailed += NavigationFailed; m_webView.DOMContentLoaded += DOMContentLoaded; m_webView.ContentLoading += ContentLoading; // Navigate m_webView.Navigate(new Uri(post.Url, UriKind.Absolute)); ui_contentRoot.Children.Add(m_webView); } }); }
/// <summary> /// Called when we should show the content /// </summary> /// <param name="post"></param> public void OnPrepareContent(Post post) { m_markdownBox = new MarkdownTextBox(); m_markdownBox.OnMarkdownReady += MarkdownBox_OnMarkdownReady; m_markdownBox.Markdown = post.Selftext; ui_contentRoot.Children.Add(m_markdownBox); }
/// <summary> /// Called when we should show something /// </summary> /// <param name="link"></param> public void ShowContent(string link) { // Make sure we are in the correct state lock(this) { if(m_state != State.Idle) { return; } m_state = State.Opening; } // Create the content control m_contentControl = new FlipViewContentControl(); // This isn't great, but for now mock a post Post post = new Post() { Url = link, Id = "quinn" }; // Add the control to the UI ui_contentRoot.Children.Add(m_contentControl); // Set the post to begin loading m_contentControl.FlipPost = post; m_contentControl.IsVisible = true; // Show the panel ToggleShown(true); }
/// <summary> /// Called when we should show the content /// </summary> /// <param name="post"></param> public void OnPrepareContent(Post post) { m_markdownBlock = new MarkdownTextBlock(); m_markdownBlock.OnMarkdownLinkTapped += MarkdownBlock_OnMarkdownLinkTapped; m_markdownBlock.OnMarkdownReady += MarkdownBox_OnMarkdownReady; m_markdownBlock.Markdown = post.Selftext; ui_contentRoot.Children.Add(m_markdownBlock); }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { // Note! We can't do the full Uri get because it relays on an Internet request and // we can't lose the time for this quick check. If we can get the youtube id assume we are good. // See if we can get a link return !String.IsNullOrWhiteSpace(TryToGetYouTubeId(post)); }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { string urlLower = post.Url.ToLower(); if(urlLower.Contains("microsoft.com") && (urlLower.Contains("/store/apps/") || urlLower.Contains("/store/games/"))) { return true; } return false; }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { // See if we can get an image from the url if(String.IsNullOrWhiteSpace(ImageManager.GetImageUrl(post.Url))) { return false; } return true; }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { // Check if we have the spoiler tag. if (!String.IsNullOrWhiteSpace(post.Url) && post.Url.TrimStart().ToLower().StartsWith("/s")) { return true; } return false; }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { // See if we can find a imgur or gfycat gif if (String.IsNullOrWhiteSpace(GetImgurUrl(post.Url)) && String.IsNullOrWhiteSpace(GetGfyCatApiUrl(post.Url))) { return false; } return true; }
public static ContentPanelSource CreateFromPost(Post post) { ContentPanelSource source = new ContentPanelSource(); source.Id = post.Id; source.Url = post.Url; source.SelfText = post.Selftext; source.Subreddit = post.Subreddit; source.IsNSFW = post.IsOver18; source.IsSelf = post.IsSelf; return source; }
/// <summary> /// Called when we should show the content /// </summary> /// <param name="post"></param> public async void OnPrepareContent(Post post) { // Since some of this can be costly, delay the work load until we aren't animating. await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { m_markdownBlock = new MarkdownTextBlock(); m_markdownBlock.OnMarkdownLinkTapped += MarkdownBlock_OnMarkdownLinkTapped; m_markdownBlock.OnMarkdownReady += MarkdownBox_OnMarkdownReady; m_markdownBlock.Markdown = post.Selftext; ui_contentRoot.Children.Add(m_markdownBlock); }); }
/// <summary> /// Called when the flip view consent should shown. /// </summary> /// <param name="url"></param> public void OnPrepareContent(Post post) { m_shouldBePlaying = false; m_loadingHidden = false; // Show loading m_host.ShowLoading(); // Run the rest on a background thread. Task.Run(async () => { // Try to get the imgur url string gifUrl = GetImgurUrl(post.Url); // If that failed try to get a url from GfyCat if (gifUrl.Equals(String.Empty)) { // We have to get it from gyfcat gifUrl = await GetGfyCatGifUrl(GetGfyCatApiUrl(post.Url)); } // Since some of this can be costly, delay the work load until we aren't animating. await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { // Make sure we aren't destroyed. if (m_isDestoryed) { return; } // If we didn't get anything something went wrong. if (String.IsNullOrWhiteSpace(gifUrl)) { m_host.FallbackToWebBrowser(post); App.BaconMan.TelemetryMan.ReportUnExpectedEvent(this, "FailedToShowGifAfterConfirm"); return; } // Create the media element m_gifVideo = new MediaElement(); m_gifVideo.HorizontalAlignment = HorizontalAlignment.Stretch; m_gifVideo.Tapped += OnVideoTapped; m_gifVideo.CurrentStateChanged += OnVideoCurrentStateChanged; m_gifVideo.Source = new Uri(gifUrl, UriKind.Absolute); m_gifVideo.Play(); m_gifVideo.IsLooping = true; ui_contentRoot.Children.Add(m_gifVideo); }); }); }
/// <summary> /// Called by the host when we should show content. /// </summary> /// <param name="post"></param> public async void OnPrepareContent(Post post) { // So the loading UI m_host.ShowLoading(); m_loadingHidden = false; // Since some of this can be costly, delay the work load until we aren't animating. await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { lock (this) { if (m_isDestroyed) { return; } // Get the post url m_postUrl = post.Url; // Make the webview m_webView = new WebView(WebViewExecutionMode.SeparateThread); // Setup the listeners, we need all of these because some web pages don't trigger // some of them. m_webView.FrameNavigationCompleted += NavigationCompleted; m_webView.NavigationFailed += NavigationFailed; m_webView.DOMContentLoaded += DOMContentLoaded; m_webView.ContentLoading += ContentLoading; m_webView.ContainsFullScreenElementChanged += WebView_ContainsFullScreenElementChanged; // Navigate try { m_webView.Navigate(new Uri(post.Url, UriKind.Absolute)); } catch (Exception e) { App.BaconMan.TelemetryMan.ReportUnExpectedEvent(this, "FailedToMakeUriInWebControl", e); m_host.ShowError(); } // Now add an event for navigating. m_webView.NavigationStarting += NavigationStarting; // Insert this before the full screen button. ui_contentRoot.Children.Insert(0, m_webView); } }); }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { // If this is a self post with no text we will handle this. if(post.IsSelf && String.IsNullOrWhiteSpace(post.Selftext)) { return true; } // Check if this is a reddit content post, if so this is us if (!String.IsNullOrWhiteSpace(post.Url)) { return MiscellaneousHelper.TryToFindRedditContentInLink(post.Url) != null; } return false; }
/// <summary> /// Called when we should show the content /// </summary> /// <param name="post"></param> public void OnPrepareContent(Post post) { string spoilerText = post.Url; // Parse out the spoiler int firstQuote = spoilerText.IndexOf('"'); int lastQuote = spoilerText.LastIndexOf('"'); if (firstQuote != -1 && lastQuote != -1 && firstQuote != lastQuote) { firstQuote++; spoilerText = spoilerText.Substring(firstQuote, lastQuote - firstQuote); } // Set the text ui_textBlock.Text = spoilerText; }
/// <summary> /// Called when we should show content /// </summary> /// <param name="post"></param> public void OnPrepareContent(Post post) { // Set our flag m_isDestoryed = false; // First show loading m_host.ShowLoading(); // Hide the content root ui_contentRoot.Opacity = 0; // Grab the post URL m_postUrl = post.Url; // Do the rest of the work on a background thread. Task.Run(async () => { // Get the image Url string imageUrl = ImageManager.GetImageUrl(post.Url); if (String.IsNullOrWhiteSpace(imageUrl)) { // This is bad, we should be able to get the url. App.BaconMan.TelemetryMan.ReportUnExpectedEvent(this, "BasicImageControlNoImageUrl"); // Jump back to the UI thread await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { m_host.ShowError(); }); return; } // Fire off a request for the image. ImageManager.ImageManagerRequest request = new ImageManager.ImageManagerRequest() { ImageId = post.Id, Url = imageUrl }; request.OnRequestComplete += OnRequestComplete; App.BaconMan.ImageMan.QueueImageRequest(request); }); }
public FlipViewPostCommentManager(ref Post post, string targetComment, bool showThreadSubset) { m_post = post; m_targetComment = targetComment; m_showThreadSubset = showThreadSubset; // If we have a target comment and we want to show only a subset. if (showThreadSubset && !String.IsNullOrWhiteSpace(targetComment)) { post.FlipViewShowEntireThreadMessage = Visibility.Visible; } else { post.FlipViewShowEntireThreadMessage = Visibility.Collapsed; } // This post might have comments if opened already in flip view. Clear them out if it does. m_post.Comments.Clear(); }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { // If this is a self post with no text we will handle this. if(post.IsSelf && String.IsNullOrWhiteSpace(post.Selftext)) { return true; } // Check if this is a reddit content post, if so this is us if (!String.IsNullOrWhiteSpace(post.Url)) { // Check the content RedditContentContainer container = MiscellaneousHelper.TryToFindRedditContentInLink(post.Url); // If we got a container and it isn't a web site return it. if(container != null && container.Type != RedditContentType.Website) { return true; } } return false; }
/// <summary> /// Called when we should show the content /// </summary> /// <param name="post"></param> public void OnPrepareContent(Post post) { string headerText = ""; string minorText = ""; if (post.IsSelf) { headerText = "There's no content here!"; minorText = "Scroll down to view the discussion."; } else { m_content = MiscellaneousHelper.TryToFindRedditContentInLink(post.Url); switch(m_content.Type) { case RedditContentType.Subreddit: headerText = "This post links to a subreddit"; minorText = $"Tap anywhere to view /r/{m_content.Subreddit}"; break; case RedditContentType.Comment: headerText = "This post links to a comment thread"; minorText = "Tap anywhere to view it"; break; case RedditContentType.Post: headerText = "This post links to a reddit post"; minorText = $"Tap anywhere to view it"; break; case RedditContentType.Website: // This shouldn't happen App.BaconMan.MessageMan.DebugDia("Got website back when prepare on reddit content control"); App.BaconMan.TelemetryMan.ReportUnExpectedEvent(this, "GotWebsiteOnPrepareRedditContent"); break; } } ui_headerText.Text = headerText; ui_minorText.Text = minorText; }
private void NavigateToFlipView(Post post) { // Send the subreddit and post to flipview Dictionary<string, object> args = new Dictionary<string, object>(); args.Add(PanelManager.NAV_ARGS_SUBREDDIT_NAME, m_subreddit.DisplayName); args.Add(PanelManager.NAV_ARGS_SUBREDDIT_SORT, m_currentSortType); args.Add(PanelManager.NAV_ARGS_SUBREDDIT_SORT_TIME, m_currentSortTimeType); args.Add(PanelManager.NAV_ARGS_POST_ID, post.Id); m_host.Navigate(typeof(FlipViewPanel), m_subreddit.DisplayName + m_currentSortType + m_currentSortTimeType, args); }
public void ShowNsfwIfNeeded(Post post) { // If the post is over 18, and it hasn't been lowered, and we don't have block off, and we won't have per subreddit on and the subreddit has been lowered if(post.IsOver18 && !s_previousLoweredNsfwBlocks.ContainsKey(post.Id) && (App.BaconMan.UiSettingsMan.FlipView_NsfwBlockingType == NsfwBlockType.Always || (App.BaconMan.UiSettingsMan.FlipView_NsfwBlockingType == NsfwBlockType.PerSubreddit && !s_previousLoweredNsfwSubreddits.ContainsKey(post.Subreddit)))) { VisualStateManager.GoToState(this, "ShowNsfwBlock", false); } else { VisualStateManager.GoToState(this, "HideNsfwBlock", false); } }
/// <summary> /// Creates new post content /// </summary> /// <param name="flipPost"></param> private void CreateNewControl(Post flipPost) { // First figure out who can handle this post. // Important, the order we ask matter since there maybe overlap // in handlers. if (GifImageFliplControl.CanHandlePost(flipPost)) { m_control = new GifImageFliplControl(this); } else if (YoutubeFlipControl.CanHandlePost(flipPost)) { m_control = new YoutubeFlipControl(this); } else if (BasicImageFlipControl.CanHandlePost(flipPost)) { m_control = new BasicImageFlipControl(this); } else if (RedditMarkdownFlipControl.CanHandlePost(flipPost)) { m_control = new RedditMarkdownFlipControl(this); } else if (RedditContentFlipControl.CanHandlePost(flipPost)) { m_control = new RedditContentFlipControl(this); } else if (WindowsAppFlipControl.CanHandlePost(flipPost)) { m_control = new WindowsAppFlipControl(this); } else { m_control = new WebPageFlipControl(this); } // Setup the control m_control.OnPrepareContent(flipPost); // Add the control to the UI ui_contentRoot.Children.Add((UserControl)m_control); }
/// <summary> /// Deletes the current post's content. /// </summary> private void DeleteCurrentControl() { // Clear out the panel ui_contentRoot.Children.Clear(); // Clear the current post m_currentPost = null; if (m_control != null) { // Destroy it m_control.OnDestroyContent(); // Kill it. m_control = null; } }
/// <summary> /// Fired when the backing post changed /// </summary> /// <param name="flipPost">New post</param> public void OnPostChanged(Post flipPost) { if(m_currentPost != null && flipPost != null && m_currentPost.Id.Equals(flipPost.Id)) { // We already have this loaded, jump out of here return; } // Delete the current control DeleteCurrentControl(); if (flipPost != null) { m_currentPost = flipPost; ShowNsfwIfNeeded(flipPost); CreateNewControl(flipPost); } }
/// <summary> /// Called by the host when it queries if we can handle a post. /// </summary> /// <param name="post"></param> /// <returns></returns> static public bool CanHandlePost(Post post) { // Web view is the fall back, we should be handle just about anything. return true; }
/// <summary> /// Returns the current space that's available for the flipview scroller /// </summary> /// <returns></returns> private int GetCurrentScrollArea(Post post = null) { // If the post is null get the current post if(post == null && ui_flipView.SelectedIndex != -1) { post = m_postsLists[ui_flipView.SelectedIndex]; } // Get the control size int screenSize = (int)ui_contentRoot.ActualHeight; // If the comment box is open remove the height of it. if (ui_commmentBox.IsOpen) { screenSize -= (int)ui_commmentBox.ActualHeight; } // If post is null back out here. if(post == null) { return screenSize; } // If we are showing the show all comments header add the height of that so it won't be on the screen by default if(post.FlipViewShowEntireThreadMessage == Visibility.Visible) { screenSize += c_hiddenShowAllCommentsHeight; } // If we are not hiding the large header also add the height of the comment bar so it will be off screen by default // or if we are full screen from the flip control. if(post.FlipviewHeaderVisibility == Visibility.Visible || m_isFullScreen) { screenSize += c_hiddenCommentHeaderHeight; } return screenSize; }