// TODO: 視聴開始(会場後のみ、チャンネル会員限定やチケット必要な場合あり)
        // TODO: タイムシフト予約(tsがある場合のみ、会場前のみ、プレミアムの場合は会場後でも可)
        // TODO: 後からタイムシフト予約(プレミアムの場合のみ)
        // TODO: 配信説明
        // TODO: タグ
        // TODO: 配信者(チャンネルやコミュニティ)の概要説明
        // TODO: 配信者(チャンネルやコミュニティ)のフォロー
        // TODO: オススメ生放送(放送中、放送予定を明示)
        // TODO: ニコニコ市場
        // TODO: SNS共有


        // gateとwatchをどちらも扱った上でその差を意識させないように表現する

        // LiveInfo.Video.CurrentStatusは開演前、放送中は時間の経過によって変化する可能性がある

        public LiveInfomationPageViewModel(
            PageManager pageManager,
            Models.NiconicoSession niconicoSession,
            NicoLiveProvider nicoLiveProvider,
            DialogService dialogService,
            Services.HohoemaPlaylist hohoemaPlaylist,
            ExternalAccessService externalAccessService
            )
            : base(pageManager)
        {
            NiconicoSession       = niconicoSession;
            NicoLiveProvider      = nicoLiveProvider;
            HohoemaDialogService  = dialogService;
            HohoemaPlaylist       = hohoemaPlaylist;
            ExternalAccessService = externalAccessService;
            IsLoadFailed          = new ReactiveProperty <bool>(false)
                                    .AddTo(_CompositeDisposable);
            LoadFailedMessage = new ReactiveProperty <string>()
                                .AddTo(_CompositeDisposable);



            IsLiveIdAvairable = this.ObserveProperty(x => x.LiveId)
                                .Select(x => x != null ? NiconicoRegex.IsLiveId(x) : false)
                                .ToReadOnlyReactiveProperty()
                                .AddTo(_CompositeDisposable);



            IsLoggedIn = NiconicoSession.ObserveProperty(x => x.IsLoggedIn)
                         .ToReadOnlyReactiveProperty()
                         .AddTo(_CompositeDisposable);

            IsPremiumAccount = NiconicoSession.ObserveProperty(x => x.IsPremiumAccount)
                               .ToReadOnlyReactiveProperty()
                               .AddTo(_CompositeDisposable);



            _IsTsPreserved = new ReactiveProperty <bool>(false)
                             .AddTo(_CompositeDisposable);

            LiveTags = new ReadOnlyObservableCollection <LiveTagViewModel>(_LiveTags);

            IchibaItems = new ReadOnlyObservableCollection <IchibaItem>(_IchibaItems);

            ReccomendItems = _ReccomendItems.ToReadOnlyReactiveCollection(x =>
            {
                var liveId     = "lv" + x.ProgramId;
                var liveInfoVM = new LiveInfoListItemViewModel(liveId);
                liveInfoVM.Setup(x);

                var reserve = _Reservations?.ReservedProgram.FirstOrDefault(reservation => liveId == reservation.Id);
                if (reserve != null)
                {
                    liveInfoVM.SetReservation(reserve);
                }

                return(liveInfoVM);
            })
                             .AddTo(_CompositeDisposable);

            IsShowOpenLiveContentButton = this.ObserveProperty(x => LiveInfo)
                                          .Select(x =>
            {
                if (LiveInfo == null)
                {
                    return(false);
                }

                if (NiconicoSession.IsPremiumAccount)
                {
                    if (LiveInfo.Video.OpenTime > DateTime.Now)
                    {
                        return(false);
                    }

                    return(LiveInfo.Video.TimeshiftEnabled);
                }
                else
                {
                    // 一般アカウントは放送中のみ
                    if (LiveInfo.Video.OpenTime > DateTime.Now)
                    {
                        return(false);
                    }

                    if (_IsTsPreserved.Value)
                    {
                        return(true);
                    }

                    if (LiveInfo.Video.EndTime < DateTime.Now)
                    {
                        return(false);
                    }

                    return(true);
                }
            })
                                          .ToReadOnlyReactiveProperty()
                                          .AddTo(_CompositeDisposable);

            IsShowAddTimeshiftButton = this.ObserveProperty(x => LiveInfo)
                                       .Select(x =>
            {
                if (LiveInfo == null)
                {
                    return(false);
                }
                if (!LiveInfo.Video.TimeshiftEnabled)
                {
                    return(false);
                }
                if (!NiconicoSession.IsLoggedIn)
                {
                    return(false);
                }

                if (!niconicoSession.IsPremiumAccount)
                {
                    // 一般アカウントは放送開始の30分前からタイムシフトの登録はできなくなる
                    if ((LiveInfo.Video.StartTime - TimeSpan.FromMinutes(30)) < DateTime.Now)
                    {
                        return(false);
                    }
                }

                if (LiveInfo.Video.TsArchiveEndTime != null &&
                    LiveInfo.Video.TsArchiveEndTime > DateTime.Now)
                {
                    return(false);
                }

                if (_IsTsPreserved.Value)
                {
                    return(false);
                }

                return(true);
            })
                                       .ToReadOnlyReactiveProperty()
                                       .AddTo(_CompositeDisposable);

            IsShowDeleteTimeshiftButton = _IsTsPreserved;
        }
Exemple #2
0
        public SearchSummaryPageViewModel(
            SearchProvider searchProvider,
            Services.PageManager pageManager
            )
            : base(pageManager)
        {
            RelatedVideoTags = new ObservableCollection <string>();

            KeywordSearchResultItems = this.ObserveProperty(x => x.Keyword)
                                       .Where(x => !string.IsNullOrWhiteSpace(x))
                                       .SelectMany(async(x, i, cancelToken) =>
            {
                RelatedVideoTags.Clear();
                var res = await SearchProvider.GetKeywordSearch(x, 0, 10);

                if (res.IsOK)
                {
                    KeywordSearchItemsTotalCount = (int)res.GetTotalCount();

                    if (res.Tags != null)
                    {
                        foreach (var tag in res.Tags.TagItems)
                        {
                            RelatedVideoTags.Add(tag.Name);
                        }
                    }

                    return(res.VideoInfoItems?.AsEnumerable() ?? Enumerable.Empty <Mntone.Nico2.Searches.Video.VideoInfo>());
                }
                else
                {
                    return(Enumerable.Empty <Mntone.Nico2.Searches.Video.VideoInfo>());
                }
            })
                                       .SelectMany(x => x)
                                       .Select(x =>
            {
                var vm = new VideoInfoControlViewModel(x.Video.Id);
                vm.SetTitle(x.Video.Title);
                vm.SetThumbnailImage(x.Video.ThumbnailUrl.OriginalString);
                return(vm);
            })
                                       .ToReadOnlyReactiveCollection(onReset: this.ObserveProperty(x => x.Keyword).ToUnit())
                                       .AddTo(_CompositeDisposable);
            HasKeywordSearchResultItems = KeywordSearchResultItems
                                          .ObserveProperty(x => x.Count)
                                          .Select(x => x > 0)
                                          .ToReadOnlyReactiveProperty()
                                          .AddTo(_CompositeDisposable);

            RelatedLiveTags       = new ObservableCollection <string>();
            LiveSearchResultItems = this.ObserveProperty(x => x.Keyword)
                                    .Where(x => !string.IsNullOrWhiteSpace(x))
                                    .SelectMany(async(x, i, cancelToken) =>
            {
                RelatedLiveTags.Clear();
                var res = await SearchProvider.LiveSearchAsync(x, false, length: 10);
                if (res.IsStatusOK)
                {
                    if (res.Tags != null)
                    {
                        foreach (var tag in res.Tags.Tag)
                        {
                            RelatedLiveTags.Add(tag.Name);
                        }
                    }

                    LiveSearchItemsTotalCount = res.TotalCount.FilteredCount;
                    return(res.VideoInfo?.AsEnumerable() ?? Enumerable.Empty <Mntone.Nico2.Searches.Live.VideoInfo>());
                }
                else
                {
                    return(Enumerable.Empty <Mntone.Nico2.Searches.Live.VideoInfo>());
                }
            })
                                    .SelectMany(x => x)
                                    .Select(x =>
            {
                var liveInfoVM = new LiveInfoListItemViewModel(x.Video.Id);
                liveInfoVM.Setup(x);
                return(liveInfoVM);
            })
                                    .ToReadOnlyReactiveCollection(onReset: this.ObserveProperty(x => x.Keyword).ToUnit());
            HasLiveSearchResultItems = LiveSearchResultItems
                                       .ObserveProperty(x => x.Count)
                                       .Select(x => x > 0)
                                       .ToReadOnlyReactiveProperty()
                                       .AddTo(_CompositeDisposable);
            SearchProvider = searchProvider;
        }