/// <summary>
        /// Setup the links to run.
        /// </summary>
        public ExpandingSlideThumbViewModel(PDFFile downloader, TimePeriod talkTime)
        {
            // Showing the slides should generate it here, and nullify it everywhere else.
            ShowSlides = ReactiveCommand.Create();

            // FIre the reset command, with the current downloader as an argument
            ShowSlides
            .Select(_ => downloader)
            .InvokeCommand(_resetSlideShow);

            // When the reset shows up, only pay attention if a different file is being shown
            // and we have something to show!
            var noThumbs = _resetSlideShow
                           .Where(dl => downloader != dl && downloader.NumberOfPages != 0)
                           .Select(_ => (FileSlideListViewModel)null);

            // When we want to show the slides just create the new view model.
            var newThumbs = ShowSlides
                            .Select(_ => new FileSlideListViewModel(downloader, talkTime));

            // Now, allow the property we manage to flip back and forth here.
            Observable.Merge(newThumbs, noThumbs)
            .WriteLine(x => string.Format("--> writing out a {0} to the actual display property.", x == null ? "null" : "non-null"))
            .ToProperty(this, x => x.TalkAsThumbs, out _talkAsThumbs, null, RxApp.MainThreadScheduler);

            // The logic for canShowThumbs is tricky:
            // 1. True if the downloader has downloaded and opened the file and parsed it successfully (# pages != 0).
            // 2. False if we have fired off a new thumbs guy, but that can be only active if can show thumbs is true (right??).
            // 3. True if we've shown thumbs and we stop showing them.

            var downloaded = downloader.WhenAny(x => x.NumberOfPages, x => x.Value != 0);
            var areShowing = Observable.Merge(newThumbs, noThumbs)
                             .Select(x => x == null ? true : false);

            Observable.Merge(downloaded, areShowing)
            .WriteLine(x => string.Format("  -> and writing out {0} for can show thumbs", x))
            .ToProperty(this, x => x.CanShowThumbs, out _canShowThumbs, false, RxApp.MainThreadScheduler);

            // Track the # of pages. Used to display some info below the button in most implementations.
            downloader.WhenAny(x => x.NumberOfPages, x => x.Value)
            .ToProperty(this, x => x.NumberOfSlides, out _numberOfSlides, 0, RxApp.MainThreadScheduler);
        }
Пример #2
0
        /// <summary>
        /// Get everything setup to show the PDF document
        /// </summary>
        /// <param name="docSequence"></param>
        /// <param name="initialPage">The page that should be shown when we start up. Zero indexed</param>
        /// <param name="screen">The screen that hosts everything (routing!)</param>
        public FullTalkAsStripViewModel(IScreen screen, PDFFile file)
        {
            Debug.Assert(file != null);
            Debug.Assert(screen != null);

            HostScreen = screen;

            // We basically re-set each time a new file comes down from the top.

            Pages = new ReactiveList <PDFPageViewModel>();

            var pageSizeChanged = file.WhenAny(x => x.NumberOfPages, x => x.Value)
                                  .DistinctUntilChanged()
                                  .ObserveOn(RxApp.MainThreadScheduler);

            var b = from newPageLength in pageSizeChanged
                    let np = Pages.Count
                             from allpages in CreateNPages(newPageLength - np, np, file)
                             select new {
                numPages   = newPageLength,
                freshPages = allpages
            };

            b
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(info => SetNPages(info.numPages, info.freshPages));

            // Page navigation. Make sure things are clean and we don't over-burden the UI before
            // we pass the info back to the UI!
            _moveToPage = new ReplaySubject <int>(1);
            _loaded     = new ReplaySubject <Unit>(1);
            MoveToPage  = _moveToPage
                          .CombineLatest(_loaded, (p, _) => p)
                          .Select(scrubPageIndex)
                          .DistinctUntilChanged();

            PageForward = ReactiveCommand.Create();
            PageForward
            .Cast <int>()
            .Select(pn => pn + 1)
            .Subscribe(_moveToPage);

            PageBack = ReactiveCommand.Create();
            PageBack
            .Cast <int>()
            .Select(pn => pn - 1)
            .Subscribe(_moveToPage);

            PageMove = ReactiveCommand.Create();
            PageMove
            .Cast <int>()
            .Subscribe(_moveToPage);
        }
        /// <summary>
        /// Setup the VM for the file.
        /// </summary>
        /// <param name="downloader">The download controller. This assumes this is for a PDF file, and it is Valid.</param>
        /// <param name="talkTime">The time that this guy is relevant</param>
        public FileSlideListViewModel(PDFFile pdfFile, TimePeriod talkTime)
        {
            // Get the object consistent.
            SlideThumbnails = new ReactiveList <SlideThumbViewModel>();

            // We will want to refresh the view of this file depending on how close we are to the actual
            // meeting time.

            var innerBuffer = new TimePeriod(talkTime);

            innerBuffer.StartTime -= TimeSpan.FromMinutes(30);
            innerBuffer.EndTime   += TimeSpan.FromHours(2);

            var updateTalkFile = Observable.Empty <Unit>();

            if (innerBuffer.Contains(DateTime.Now))
            {
                // Fire every 15 minutes, but only while in the proper time.
                // We only check when requested, so we will start right off the bat.
                updateTalkFile = Observable.Return(default(Unit))
                                 .Concat(Observable.Interval(TimeSpan.FromMinutes(15))
                                         .Where(_ => innerBuffer.Contains(DateTime.Now))
                                         .Select(_ => default(Unit))
                                         )
                                 .Where(_ => Settings.AutoDownloadNewMeeting);
            }

            // A view model to show the whole thing as a strip view.
            var fullVM = new Lazy <FullTalkAsStripViewModel>(() => new FullTalkAsStripViewModel(Locator.Current.GetService <IScreen>(), pdfFile));

            // All we do is sit and watch for the # of pages to change, and when it does, we fix up the list of SlideThumbViewModel.
            var newSlideInfo = from nPages in pdfFile.WhenAny(x => x.NumberOfPages, x => x.Value).DistinctUntilChanged()
                               from newSlides in CreateNewThumbs(nPages, pdfFile, fullVM)
                               select new
            {
                n      = nPages,
                slides = newSlides
            };

            newSlideInfo
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(info => SetNumberOfThumbNails(info.n, info.slides));
        }