예제 #1
0
 public static ContentPanelSource CreateFromUrl(string url)
 {
     ContentPanelSource source = new ContentPanelSource();
     source.Id = c_genericIdBase + DateTime.Now.Ticks;
     source.Url = url;
     return source;
 }
예제 #2
0
        public static ContentPanelSource CreateFromUrl(string url)
        {
            ContentPanelSource source = new ContentPanelSource();

            source.Id  = c_genericIdBase + DateTime.Now.Ticks;
            source.Url = url;
            return(source);
        }
예제 #3
0
        public static ContentPanelSource CreateFromUrl(string url)
        {
            var source = new ContentPanelSource {
                Id = CGenericIdBase + DateTime.Now.Ticks, Url = url
            };

            return(source);
        }
예제 #4
0
 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;
 }
예제 #5
0
        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);
        }
예제 #6
0
        /// <summary>
        /// This is called by every piece of content when it is done loading or errors out.
        /// </summary>
        /// <param name="sourceId"></param>
        public async void OnContentLoadComplete(string sourceId)
        {
            // Delay a little bit since this might kick off a background load
            // and it isn't super important.
            await Task.Delay(100);

            bool isSourceVisible          = false;
            ContentPanelSource nextSource = null;

            lock (m_currentPanelList)
            {
                // Check if we are waiting on us
                if (m_currentLoadingContent != null && m_currentLoadingContent.Equals(sourceId))
                {
                    if (m_delayLoadQueue.Count == 0)
                    {
                        // If the queue is empty set current to null and
                        // return.
                        m_currentLoadingContent = null;
                        return;
                    }
                    else
                    {
                        // Otherwise, grab the next element
                        nextSource = m_delayLoadQueue.First();
                        m_delayLoadQueue.RemoveAt(0);

                        // Get if the source is visible.
                        if (m_currentPanelList.ContainsKey(nextSource.Id))
                        {
                            isSourceVisible = m_currentPanelList[nextSource.Id].IsVisible;
                        }

                        // Set it loading
                        m_currentLoadingContent = nextSource.Id;
                    }
                }
                else
                {
                    // Not waiting on us. Get out of here.
                    return;
                }
            }

            // And out of lock start loading.
            if (nextSource != null)
            {
                BeginLoadContent(nextSource, isSourceVisible);
            }
        }
예제 #7
0
        public static ContentPanelSource CreateFromPost(Post post)
        {
            var source = new ContentPanelSource
            {
                Id             = post.Id,
                Url            = post.Url,
                SelfText       = post.Selftext,
                Subreddit      = post.Subreddit,
                IsNsfw         = post.IsOver18,
                IsSelf         = post.IsSelf,
                IsVideo        = post.IsVideo,
                IsRedditVideo  = post.SecureMedia?.RedditVideo?.Url != null,
                IsImageGallery = post.GalleryData?.Items?.Count() > 0
            };

            if (source.IsRedditVideo)
            {
                source.VideoUrl = new Uri(post.SecureMedia.RedditVideo.Url);
            }

            return(source);
        }
        /// <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(State != GlobalContentStates.Idle)
                {
                    return;
                }
                State = GlobalContentStates.Opening;
            }

            // Create the content control
            m_contentControl = new ContentPanelHost();

            // Disable full screen
            m_contentControl.CanGoFullscreen = false;

            // This isn't great, but for now mock a post
            m_source = ContentPanelSource.CreateFromUrl(link);

            // Approve the content to be shown
            Task.Run(() =>
            {                
                ContentPanelMaster.Current.AddAllowedContent(m_source);
            });     

            // Add the control to the UI
            ui_contentRoot.Children.Add(m_contentControl);

            // Set the post to begin loading
            m_contentControl.SourceId = m_source.Id;
            m_contentControl.IsVisible = true;

            // Show the panel
            ToggleShown(true);
        }
예제 #9
0
        /// <summary>
        /// Adds the content to the list of content that is allowed. If someone requested or request this
        /// content they will get a control.
        /// </summary>
        /// <param name="source"></param>
        public void AddAllowedContent(ContentPanelSource source, string groupId = "default", bool delayLoad = false)
        {
            bool isSourceVisible = false;

            // First add an entry that we are making the control.
            lock (m_currentPanelList)
            {
                ContentListElement element;
                // Check to see if it already exists.
                if (m_currentPanelList.ContainsKey(source.Id))
                {
                    element = m_currentPanelList[source.Id];
                    if (element.State != ContentState.NotAllowed)
                    {
                        // We already have this element and it is already loading.
                        // just leave.
                        return;
                    }
                    element.State = ContentState.PendingCreation;
                    element.Source = source;
                    element.Group = groupId;

                    // If we have a host tell them we are starting to load their
                    // content (even though it might be delay loaded). This is safe
                    // to call under lock because it will async to the UI thread.
                    if(element.Host != null)
                    {
                        FireOnContentPreloading(element.Host);
                    }
                }
                else
                {
                    // No one is listening, just make the object.
                    element = new ContentListElement()
                    {
                        State = ContentState.PendingCreation,
                        Group = groupId,
                        Source = source
                    };
                    m_currentPanelList.Add(source.Id, element);
                }

                // Set if we are visible or not
                isSourceVisible = element.IsVisible;

                // Check if we are delay load.
                if (delayLoad)
                {
                    // If so, check if there is content loading.
                    if(String.IsNullOrWhiteSpace(m_currentLoadingContent))
                    {
                        // If not then load us now.
                        m_currentLoadingContent = source.Id;
                    }
                    else
                    {
                        // Otherwise add use to the list and return
                        // #todo add a timeout to the waiting.
                        m_delayLoadQueue.Add(source);
                        return;
                    }
                }
                else
                {
                    // If we are not delay loading set us to be the current content
                    // we are waiting on. Even if there is someone else, people should
                    // wait on this content.
                    m_currentLoadingContent = source.Id;
                }
            }

            // If we got here we need to load some content!
            BeginLoadContent(source, isSourceVisible);
        }
예제 #10
0
        /// <summary>
        /// When fired the source given should fall back to a web
        /// browser instead of a complex control.
        /// </summary>
        public async void FallbackToWebrowser(ContentPanelSource source)
        {
            IContentPanelHost hostToReport = null;
            IContentPanelBase panelToKill = null;

            // Fire on load complete so if someone else was waiting on us they will 
            // move on.
            OnContentLoadComplete(source.Id);

            // Lock
            lock (m_currentPanelList)
            {
                // Make sure we have it.
                if (m_currentPanelList.ContainsKey(source.Id))
                {
                    // Grab the panel to kill and the host to tell.
                    ContentListElement element = m_currentPanelList[source.Id];
                    hostToReport = element.Host;
                    panelToKill = element.PanelBase;

                    // Null the post and update our state
                    element.PanelBase = null;
                    element.State = ContentState.Unloaded;
                }
                else
                {
                    return;
                }
            }

            // Remove the panel
            if (hostToReport != null && panelToKill != null)
            {
                await FireOnRemovePanel(hostToReport, panelToKill);
            }

            // Kill the panel
            if (panelToKill != null)
            {
                await FireOnDestroyContent(panelToKill);
                panelToKill = null;
            }

            ContentPanelSource sourceToCreate = null;
            bool isVisible = false;

            // Now lock again
            lock (m_currentPanelList)
            {
                // Make sure we still have it.
                if (m_currentPanelList.ContainsKey(source.Id))
                {
                    ContentListElement element = m_currentPanelList[source.Id];
                    if (element.State == ContentState.Unloaded)
                    {
                        // Grab the element again and set the new state.
                        isVisible = element.IsVisible;
                        element.Source.ForceWeb = true;
                        sourceToCreate = element.Source;
                        element.State = ContentState.PendingCreation;
                    }
                    else
                    {
                        // if we are not in the same state get out of here.
                        return;
                    }     
                }
                else
                {
                    return;
                }
            }

            if(sourceToCreate != null)
            {
                BeginLoadContent(sourceToCreate, isVisible);
            }
        }
예제 #11
0
        /// <summary>
        /// This will actually do the loading of content. This starts the load but
        /// the load isn't actually done until the app fires the loading function above.
        /// </summary>
        /// <param name="source"></param>
        private void BeginLoadContent(ContentPanelSource source, bool isVisible)
        {
            // Next make the control, spin this off to keep the UI thread going.
            Task.Run(async () =>
            {
                // Create a new base and panel.
                ContentPanelBase panelBase = new ContentPanelBase();
                bool panelLoaded = await panelBase.CreateContentPanel(source, CanLoadLaregePanel(isVisible));

                bool destoryPanel = true;
                IContentPanelHost hostToGivePanel = null;
                IContentPanelHost hostToInformUnlaoded = null;

                // Update the list with the control
                lock (m_currentPanelList)
                {
                    // Make sure it is still there.
                    if (m_currentPanelList.ContainsKey(source.Id))
                    {
                        ContentListElement element = m_currentPanelList[source.Id];

                        // Make sure we still have a good state.
                        if (element.State == ContentState.PendingCreation)
                        {
                            // Make sure the panel loaded
                            if (panelLoaded)
                            {
                                // Set the panel and state, if we have a host grab it.
                                destoryPanel = false;
                                element.PanelBase = panelBase;
                                element.State = ContentState.Created;
                                hostToGivePanel = element.Host;                               
                            }
                            else
                            {
                                // If we didn't load it was probably due to low memory.
                                // Set our state to unloaded and tell the host.
                                element.State = ContentState.Unloaded;
                                hostToInformUnlaoded = element.Host;
                                destoryPanel = true;
                            }
                        }                                        
                    }
                }

                // If the entry is now gone or whatever, destroy the post.
                if (destoryPanel)
                {
                    await FireOnDestroyContent(panelBase);
                }
                else
                {
                    // If we have a host inform them the panel is now ready.
                    if (hostToGivePanel != null)
                    {
                        FireOnPanelAvailable(hostToGivePanel, panelBase);
                    }
                }

                // If we have a host to tell that we unloaded the panel tell them.
                if(hostToInformUnlaoded != null)
                {
                    FireOnPanelUnloaded(hostToInformUnlaoded);
                }
            });
        }
예제 #12
0
        /// <summary>
        /// Adds the content to the list of content that is allowed. If someone requested or request this
        /// content they will get a control.
        /// </summary>
        /// <param name="source"></param>
        public void AddAllowedContent(ContentPanelSource source, string groupId = "default", bool delayLoad = false)
        {
            var isSourceVisible = false;

            // First add an entry that we are making the control.
            lock (_mCurrentPanelList)
            {
                ContentListElement element;
                // Check to see if it already exists.
                if (_mCurrentPanelList.ContainsKey(source.Id))
                {
                    element = _mCurrentPanelList[source.Id];
                    if (element.State != ContentState.NotAllowed)
                    {
                        // We already have this element and it is already loading.
                        // just leave.
                        return;
                    }
                    element.State  = ContentState.PendingCreation;
                    element.Source = source;
                    element.Group  = groupId;

                    // If we have a host tell them we are starting to load their
                    // content (even though it might be delay loaded). This is safe
                    // to call under lock because it will async to the UI thread.
                    if (element.Host != null)
                    {
                        FireOnContentPreloading(element.Host);
                    }
                }
                else
                {
                    // No one is listening, just make the object.
                    element = new ContentListElement
                    {
                        State  = ContentState.PendingCreation,
                        Group  = groupId,
                        Source = source
                    };
                    _mCurrentPanelList.Add(source.Id, element);
                }

                // Set if we are visible or not
                isSourceVisible = element.IsVisible;

                // Check if we are delay load.
                if (delayLoad)
                {
                    // If so, check if there is content loading.
                    if (string.IsNullOrWhiteSpace(_mCurrentLoadingContent))
                    {
                        // If not then load us now.
                        _mCurrentLoadingContent = source.Id;
                    }
                    else
                    {
                        // Otherwise add use to the list and return
                        // #todo add a timeout to the waiting.
                        _mDelayLoadQueue.Add(source);
                        return;
                    }
                }
                else
                {
                    // If we are not delay loading set us to be the current content
                    // we are waiting on. Even if there is someone else, people should
                    // wait on this content.
                    _mCurrentLoadingContent = source.Id;
                }
            }

            // If we got here we need to load some content!
            BeginLoadContent(source, isSourceVisible);
        }
예제 #13
0
        /// <summary>
        /// When fired the source given should fall back to a web
        /// browser instead of a complex control.
        /// </summary>
        public async void FallbackToWebrowser(ContentPanelSource source)
        {
            IContentPanelHost hostToReport = null;
            IContentPanelBase panelToKill  = null;

            // Fire on load complete so if someone else was waiting on us they will
            // move on.
            OnContentLoadComplete(source.Id);

            // Lock
            lock (_mCurrentPanelList)
            {
                // Make sure we have it.
                if (_mCurrentPanelList.ContainsKey(source.Id))
                {
                    // Grab the panel to kill and the host to tell.
                    var element = _mCurrentPanelList[source.Id];
                    hostToReport = element.Host;
                    panelToKill  = element.PanelBase;

                    // Null the post and update our state
                    element.PanelBase = null;
                    element.State     = ContentState.Unloaded;
                }
                else
                {
                    return;
                }
            }

            // Remove the panel
            if (hostToReport != null && panelToKill != null)
            {
                await FireOnRemovePanel(hostToReport, panelToKill);
            }

            // Kill the panel
            if (panelToKill != null)
            {
                await FireOnDestroyContent(panelToKill);

                panelToKill = null;
            }

            ContentPanelSource sourceToCreate = null;
            var isVisible = false;

            // Now lock again
            lock (_mCurrentPanelList)
            {
                // Make sure we still have it.
                if (_mCurrentPanelList.ContainsKey(source.Id))
                {
                    var element = _mCurrentPanelList[source.Id];
                    if (element.State == ContentState.Unloaded)
                    {
                        // Grab the element again and set the new state.
                        isVisible = element.IsVisible;
                        element.Source.ForceWeb = true;
                        sourceToCreate          = element.Source;
                        element.State           = ContentState.PendingCreation;
                    }
                    else
                    {
                        // if we are not in the same state get out of here.
                        return;
                    }
                }
                else
                {
                    return;
                }
            }

            if (sourceToCreate != null)
            {
                BeginLoadContent(sourceToCreate, isVisible);
            }
        }
예제 #14
0
        /// <summary>
        /// This will actually do the loading of content. This starts the load but
        /// the load isn't actually done until the app fires the loading function above.
        /// </summary>
        /// <param name="source"></param>
        private void BeginLoadContent(ContentPanelSource source, bool isVisible)
        {
            // Next make the control, spin this off to keep the UI thread going.
            Task.Run(async() =>
            {
                // Create a new base and panel.
                var panelBase   = new ContentPanelBase();
                var panelLoaded = await panelBase.CreateContentPanel(source, CanLoadLaregePanel(isVisible));

                var destoryPanel = true;
                IContentPanelHost hostToGivePanel      = null;
                IContentPanelHost hostToInformUnlaoded = null;

                // Update the list with the control
                lock (_mCurrentPanelList)
                {
                    // Make sure it is still there.
                    if (_mCurrentPanelList.ContainsKey(source.Id))
                    {
                        var element = _mCurrentPanelList[source.Id];

                        // Make sure we still have a good state.
                        if (element.State == ContentState.PendingCreation)
                        {
                            // Make sure the panel loaded
                            if (panelLoaded)
                            {
                                // Set the panel and state, if we have a host grab it.
                                destoryPanel      = false;
                                element.PanelBase = panelBase;
                                element.State     = ContentState.Created;
                                hostToGivePanel   = element.Host;
                            }
                            else
                            {
                                // If we didn't load it was probably due to low memory.
                                // Set our state to unloaded and tell the host.
                                element.State        = ContentState.Unloaded;
                                hostToInformUnlaoded = element.Host;
                                destoryPanel         = true;
                            }
                        }
                    }
                }

                // If the entry is now gone or whatever, destroy the post.
                if (destoryPanel)
                {
                    await FireOnDestroyContent(panelBase);
                }
                else
                {
                    // If we have a host inform them the panel is now ready.
                    if (hostToGivePanel != null)
                    {
                        FireOnPanelAvailable(hostToGivePanel, panelBase);
                    }
                }

                // If we have a host to tell that we unloaded the panel tell them.
                if (hostToInformUnlaoded != null)
                {
                    FireOnPanelUnloaded(hostToInformUnlaoded);
                }
            });
        }
예제 #15
0
        /// <summary>
        /// Called when a panel changes visibility.
        /// </summary>
        /// <param name="sourcdId"></param>
        public void OnPanelVisibliltyChanged(string sourceId, bool isVisible)
        {
            ContentPanelSource loadNowSource = null;

            lock (_mCurrentPanelList)
            {
                // See if the panel exists.
                if (_mCurrentPanelList.ContainsKey(sourceId))
                {
                    // Get the element
                    var element = _mCurrentPanelList[sourceId];

                    // Set the new visibility
                    element.IsVisible = isVisible;

                    // If we aren't visible get out of here now.
                    if (!isVisible)
                    {
                        return;
                    }

                    // If we are unloaded start loading right now.
                    if (element.State == ContentState.Unloaded)
                    {
                        // Grab the source
                        loadNowSource = element.Source;

                        // Set our state to pending.
                        element.State = ContentState.PendingCreation;

                        // Make the delay loading id this so everyone will wait on us.
                        _mCurrentLoadingContent = loadNowSource.Id;
                    }
                    // If we are pending make sure we aren't being delayed.
                    else if (element.State == ContentState.PendingCreation)
                    {
                        // See if this post is in the delay load post list.
                        foreach (var source in _mDelayLoadQueue)
                        {
                            if (source.Id.Equals(sourceId))
                            {
                                loadNowSource = source;
                                break;
                            }
                        }

                        // If we found the element clean it out of the queue
                        if (loadNowSource != null)
                        {
                            // Remove us from it and start loading now!
                            _mDelayLoadQueue.Remove(loadNowSource);

                            // We want to load this now. No matter if we were currently waiting on someone or not
                            // all delay loaded post should wait on this one.
                            _mCurrentLoadingContent = loadNowSource.Id;
                        }
                    }
                }
            }

            // Now that we are out of lock load the source if we have
            // one to load.
            if (loadNowSource != null)
            {
                BeginLoadContent(loadNowSource, true);
            }
        }