Beispiel #1
0
        protected override async Task <int> ResetSourceImpl()
        {
            await VideoCacheManager.Initialize();


            _CacheRequestMap.Clear();

            var list = new List <NicoVideoCacheRequest>();

            // キャッシュ待ちアイテム
            // キャッシュ中アイテム
            // キャッシュ済みアイテム
            foreach (var item in await VideoCacheManager.EnumerateCacheRequestedVideosAsync())
            {
                if (!_CacheRequestMap.ContainsKey(item.RawVideoId))
                {
                    list.Add(item);

                    _CacheRequestMap.Add(item.RawVideoId, new List <NicoVideoCacheRequest>());
                }

                _CacheRequestMap[item.RawVideoId].Add(item);
            }



            _CacheRequestedItems = list.OrderBy(x => x.RequestAt.Ticks).Reverse().Select(x => x.RawVideoId).ToList();

            return(_CacheRequestedItems.Count);
        }
        protected override async void Execute(IEnumerable <IVideoContent> items)
        {
            var anyCached = items.Any(x => VideoCacheManager.CheckCachedAsyncUnsafe(x.Id));

            if (anyCached)
            {
                var confirmed = await DialogService.ShowMessageDialog(
                    "ConfirmCacheRemoveContent_Multiple".Translate(),
                    $"ConfirmCacheRemoveTitle_Multiple".Translate(items.Count()),
                    acceptButtonText : "Delete".Translate(),
                    "Cancel".Translate()
                    );

                if (confirmed)
                {
                    foreach (var item in items)
                    {
                        await VideoCacheManager.CancelCacheRequest(item.Id);
                    }
                }
            }
            else
            {
                foreach (var item in items)
                {
                    await VideoCacheManager.CancelCacheRequest(item.Id);
                }
            }
        }
        protected override async void Execute(object parameter)
        {
            if (parameter is Interfaces.IVideoContent content)
            {
                var video         = Database.NicoVideoDb.Get(content.Id);
                var cacheRequests = await VideoCacheManager.GetCacheRequest(content.Id);

                if (cacheRequests.Any())
                {
                    var choiceItems = await DialogService.ShowMultiChoiceDialogAsync(
                        $"削除するキャッシュ動画を選択する\n「{video.Title}」",
                        cacheRequests,
                        Enumerable.Empty <Models.Cache.NicoVideoCacheRequest>(),
                        nameof(Models.Cache.NicoVideoCacheRequest.Quality)
                        );

                    if (choiceItems?.Any() ?? false)
                    {
                        foreach (var deleteItem in choiceItems)
                        {
                            await VideoCacheManager.CancelCacheRequest(content.Id, deleteItem.Quality);
                        }
                    }
                }
            }
        }
 private void initDisplayer(VideoCacheManager cache, ITimeProcess playProcess)
 {
     _displayer                       = new VideoDisplayManager(cache, playProcess);
     _displayer.OnCaching            += onCaching;
     _displayer.OnHaveData           += onHaveData;
     _displayer.VideoFrameImageEvent += onVideoFrameImage;
 }
Beispiel #5
0
 protected override void Execute(object parameter)
 {
     if (parameter is Interfaces.IVideoContent content)
     {
         VideoCacheManager.RequestCache(content.Id);
     }
 }
Beispiel #6
0
 public CacheDeleteRequestCommand(
     VideoCacheManager videoCacheManager,
     DialogService dialogService
     )
 {
     _videoCacheManager = videoCacheManager;
     _dialogService     = dialogService;
 }
 static VideoItemViewModel()
 {
     _messenger     = Microsoft.Toolkit.Mvvm.DependencyInjection.Ioc.Default.GetService <IMessenger>();
     _queuePlaylist = Microsoft.Toolkit.Mvvm.DependencyInjection.Ioc.Default.GetService <QueuePlaylist>();
     _cacheManager  = Microsoft.Toolkit.Mvvm.DependencyInjection.Ioc.Default.GetService <VideoCacheManager>();
     _scheduler     = Microsoft.Toolkit.Mvvm.DependencyInjection.Ioc.Default.GetService <IScheduler>();
     _videoPlayedHistoryRepository = Microsoft.Toolkit.Mvvm.DependencyInjection.Ioc.Default.GetService <VideoPlayedHistoryRepository>();
     _addWatchAfterCommand         = Microsoft.Toolkit.Mvvm.DependencyInjection.Ioc.Default.GetService <QueueAddItemCommand>();
     _removeWatchAfterCommand      = Microsoft.Toolkit.Mvvm.DependencyInjection.Ioc.Default.GetService <QueueRemoveItemCommand>();
 }
Beispiel #8
0
        public NotificationCacheRequestRejectedService(
            NotificationService notificationService,
            VideoCacheManager videoCacheManager
            )
        {
            NotificationService = notificationService;
            VideoCacheManager   = videoCacheManager;

            VideoCacheManager.Rejected += VideoCacheManager_Rejected;
        }
Beispiel #9
0
 protected override Task <IAsyncEnumerable <CacheVideoViewModel> > GetPagedItemsImpl(int head, int count)
 {
     return(Task.FromResult(VideoCacheManager.GetCacheRequests(head, count)
                            .Select(x =>
     {
         var vm = new CacheVideoViewModel(x.VideoId);
         vm.CacheRequestTime = x.RequestAt;
         return vm;
     })
                            .ToAsyncEnumerable()));
 }
Beispiel #10
0
        public async void Receive(VideoDeletedMessage message)
        {
            var videoInfo = message.Value;

            if (await VideoCacheManager.DeleteFromNiconicoServer(videoInfo.VideoId))
            {
                NotificationService.ShowToast("ToastNotification_VideoDeletedWithId".Translate(videoInfo.VideoId)
                                              , "ToastNotification_ExplainVideoForceDeletion".Translate(videoInfo?.Title ?? videoInfo.VideoId)
                                              , Microsoft.Toolkit.Uwp.Notifications.ToastDuration.Long
                                              );
            }
        }
 public VideoStreamingOriginOrchestrator(
     NiconicoSession niconicoSession,
     VideoCacheManager videoCacheManager,
     NicoVideoSessionProvider nicoVideoSessionProvider,
     NicoVideoProvider nicoVideoProvider
     )
 {
     _niconicoSession          = niconicoSession;
     _videoCacheManager        = videoCacheManager;
     _nicoVideoSessionProvider = nicoVideoSessionProvider;
     _nicoVideoProvider        = nicoVideoProvider;
 }
 public VideoCacheDatabaseMigration_V_0_29_0(
     Domain.Application.AppFlagsRepository appFlagsRepository,
     Domain.Player.Video.Cache.CacheRequestRepository cacheRequestRepositoryLegacy,
     Domain.VideoCache.VideoCacheManager videoCacheManager,
     Presentation.Services.DialogService dialogService
     )
 {
     _appFlagsRepository           = appFlagsRepository;
     _cacheRequestRepositoryLegacy = cacheRequestRepositoryLegacy;
     _videoCacheManager            = videoCacheManager;
     _dialogService = dialogService;
 }
Beispiel #13
0
        /// <summary>
        /// Models.Provider.NicoVideoProvider内で検出した動画削除のイベントを受けて
        /// キャッシュされた動画を削除します
        /// </summary>
        /// <param name="videoCacheManager"></param>
        /// <param name="notificationService"></param>
        public NotificationCacheVideoDeletedService(
            IMessenger messenger,
            VideoCacheManager videoCacheManager,
            NotificationService notificationService

            )
        {
            _messenger          = messenger;
            VideoCacheManager   = videoCacheManager;
            NotificationService = notificationService;

            _messenger.Register <VideoDeletedMessage>(this);
        }
Beispiel #14
0
 public VideoStreamingOriginOrchestrator(
     NiconicoSession niconicoSession,
     VideoCacheManager videoCacheManager,
     NicoVideoSessionProvider nicoVideoSessionProvider,
     DialogService dialogService,
     CommentRepository commentRepository
     )
 {
     _niconicoSession          = niconicoSession;
     _videoCacheManager        = videoCacheManager;
     _nicoVideoSessionProvider = nicoVideoSessionProvider;
     _dialogService            = dialogService;
     _commentRepository        = commentRepository;
 }
Beispiel #15
0
 public NavigationTriggerFromExternal(
     MylistResolver mylistResolver,
     NicoVideoProvider nicoVideoProvider,
     VideoCacheManager videoCacheManager,
     PageManager pageManager,
     IMessenger messenger
     )
 {
     _mylistResolver    = mylistResolver;
     _nicoVideoProvider = nicoVideoProvider;
     _videoCacheManager = videoCacheManager;
     _pageManager       = pageManager;
     _messenger         = messenger;
 }
Beispiel #16
0
        // Windows10のメディアコントロールとHohoemaのプレイリスト機能を統合してサポート

        // 外部からの次送り、前送り
        // プレイリストリセットなどに対応する
        //
        // 外部からの操作はイベントに切り出す

        // 画面の遷移自体はPageManagerに任せることにする
        // PageManagerに動画情報を渡すまでをやる

        // TODO: 「あとで見る」プレイリストをローミングフォルダへ書き出す

        public HohoemaPlaylist(
            IScheduler scheduler,
            NiconicoSession niconicoSession,
            VideoCacheManager videoCacheManager,
            PlaylistSettings playlistSettings,
            PlayerViewManager viewMan
            )
        {
            Scheduler         = scheduler;
            NiconicoSession   = niconicoSession;
            VideoCacheManager = videoCacheManager;
            PlaylistSettings  = playlistSettings;
            PlayerViewManager = viewMan;

            Player = new PlaylistPlayer(this, playlistSettings);

            MakeDefaultPlaylist();

            Player.PlayRequested += Player_PlayRequested;


            // 一般会員は再生とキャッシュDLを1ラインしか許容していないため
            // 再生終了時にキャッシュダウンロードの再開を行う必要がある
            // PlayerViewManager.NowPlaying はSecondaryViewでの再生時にFalseを示してしまうため
            // IsPlayerShowWithSecondaryViewを使ってセカンダリビューでの再生中を検出している
            _resumingObserver = new[]
            {
                // PlayerViewManager.ObserveProperty(x => x.NowPlaying).Select(x => !x),
                PlayerViewManager.ObserveProperty(x => x.IsPlayerShowWithPrimaryView).Select(x => !x),
                PlayerViewManager.ObserveProperty(x => x.IsPlayerShowWithSecondaryView).Select(x => !x),
                NiconicoSession.ObserveProperty(x => x.IsPremiumAccount).Select(x => !x)
            }
            .CombineLatestValuesAreAllTrue()
            .Throttle(TimeSpan.FromSeconds(1))
            .Subscribe(nowResumingCacheDL =>
            {
                Scheduler.Schedule(() =>
                {
                    if (nowResumingCacheDL)
                    {
                        _ = VideoCacheManager.ResumeCacheDownload();

                        // TODO: キャッシュDL再開した場合の通知
                    }
                });
            });
        }
Beispiel #17
0
        public VideoCacheFolderManager(
            ILoggerFactory loggerFactory,
            VideoCacheManager vIdeoCacheManager,
            NicoVideoProvider nicoVideoProvider
            )
        {
            _logger            = loggerFactory.CreateLogger <VideoCacheFolderManager>();
            _videoCacheManager = vIdeoCacheManager;
            _nicoVideoProvider = nicoVideoProvider;

            _messenger = WeakReferenceMessenger.Default;

            // キャッシュファイル名の解決方法を設定
            VideoCacheManager.ResolveVideoTitle = (id) =>
            {
                return(_nicoVideoProvider.ResolveVideoTitleAsync(id));
            };
        }
 public VideoDisplayManager(VideoCacheManager cache, ITimeProcess playProcess)
 {
     _replayProcess                 = playProcess;
     _replayProcess.JumpEvent      += onJump;
     _replayProcess.FastTimesEvent += onFastTimes;
     _replayProcess.AddCache(_guid);
     _render = new D3DImageSource();
     _render.ImageSourceChanged += render_ImageSourceChanged;
     _decoder = new VideoStreamDecoder();
     _decoder.VideoFrameEvent += onVideoFrame;
     _cache = cache;
     _cache.PropertyChanged += _cache_PropertyChanged;
     _disposeEvent.Reset();
     new Thread(run)
     {
         IsBackground = true
     }.Start();
     onJump();
     onFastTimes();
 }
 public VideoInfomationPageViewModel(
     ApplicationLayoutManager applicationLayoutManager,
     AppearanceSettings appearanceSettings,
     NGSettings ngSettings,
     Models.NiconicoSession niconicoSession,
     UserMylistManager userMylistManager,
     HohoemaPlaylist hohoemaPlaylist,
     NicoVideoProvider nicoVideoProvider,
     LoginUserMylistProvider loginUserMylistProvider,
     VideoCacheManager videoCacheManager,
     SubscriptionManager subscriptionManager,
     Models.NicoVideoSessionProvider nicoVideo,
     Services.PageManager pageManager,
     Services.NotificationService notificationService,
     Services.DialogService dialogService,
     Services.ExternalAccessService externalAccessService,
     AddMylistCommand addMylistCommand,
     Commands.Subscriptions.CreateSubscriptionGroupCommand createSubscriptionGroupCommand
     )
 {
     ApplicationLayoutManager = applicationLayoutManager;
     _appearanceSettings      = appearanceSettings;
     NgSettings              = ngSettings;
     NiconicoSession         = niconicoSession;
     UserMylistManager       = userMylistManager;
     HohoemaPlaylist         = hohoemaPlaylist;
     NicoVideoProvider       = nicoVideoProvider;
     LoginUserMylistProvider = loginUserMylistProvider;
     VideoCacheManager       = videoCacheManager;
     SubscriptionManager     = subscriptionManager;
     NicoVideo                      = nicoVideo;
     PageManager                    = pageManager;
     NotificationService            = notificationService;
     DialogService                  = dialogService;
     ExternalAccessService          = externalAccessService;
     AddMylistCommand               = addMylistCommand;
     CreateSubscriptionGroupCommand = createSubscriptionGroupCommand;
     NowLoading                     = new ReactiveProperty <bool>(false);
     IsLoadFailed                   = new ReactiveProperty <bool>(false);
 }
        public VideoCacheResumingObserver(
            IScheduler scheduler,
            NiconicoSession niconicoSession,
            ScondaryViewPlayerManager playerViewManager,
            VideoCacheManager videoCacheManager
            )
        {
            _scheduler         = scheduler;
            _niconicoSession   = niconicoSession;
            _playerViewManager = playerViewManager;
            _videoCacheManager = videoCacheManager;

            // 一般会員は再生とキャッシュDLを1ラインしか許容していないため
            // 再生終了時にキャッシュダウンロードの再開を行う必要がある
            // PlayerViewManager.NowPlaying はSecondaryViewでの再生時にFalseを示してしまうため
            // IsPlayerShowWithSecondaryViewを使ってセカンダリビューでの再生中を検出している
            //new[]
            //{
            //    // PlayerViewManager.ObserveProperty(x => x.NowPlaying).Select(x => !x),
            //    _playerViewManager.ObserveProperty(x => x.IsPlayerShowWithPrimaryView).Select(x => !x),
            //    _playerViewManager.ObserveProperty(x => x.IsPlayerShowWithSecondaryView).Select(x => !x),
            //    _niconicoSession.ObserveProperty(x => x.IsPremiumAccount).Select(x => !x)
            //}
            //.CombineLatestValuesAreAllTrue()
            //.Throttle(TimeSpan.FromSeconds(1))
            //.Subscribe(nowResumingCacheDL =>
            //{
            //    _scheduler.Schedule(() =>
            //    {
            //        if (nowResumingCacheDL)
            //        {
            //            _ = _videoCacheManager.ResumeCacheDownload();

            //            // TODO: キャッシュDL再開した場合の通知
            //        }
            //    });
            //})
            //.AddTo(_disposables);
        }
Beispiel #21
0
 public VideoInfomationPageViewModel(
     NGSettings ngSettings,
     Models.NiconicoSession niconicoSession,
     UserMylistManager userMylistManager,
     Services.HohoemaPlaylist hohoemaPlaylist,
     NicoVideoProvider nicoVideoProvider,
     LoginUserMylistProvider loginUserMylistProvider,
     VideoCacheManager videoCacheManager,
     Models.NicoVideoStreamingSessionProvider nicoVideo,
     Services.Helpers.MylistHelper mylistHelper,
     Services.PageManager pageManager,
     Services.NotificationService notificationService,
     Services.DialogService dialogService,
     Services.ExternalAccessService externalAccessService,
     Commands.AddMylistCommand addMylistCommand,
     Commands.Subscriptions.CreateSubscriptionGroupCommand createSubscriptionGroupCommand
     )
     : base(pageManager)
 {
     NgSettings              = ngSettings;
     NiconicoSession         = niconicoSession;
     UserMylistManager       = userMylistManager;
     HohoemaPlaylist         = hohoemaPlaylist;
     NicoVideoProvider       = nicoVideoProvider;
     LoginUserMylistProvider = loginUserMylistProvider;
     VideoCacheManager       = videoCacheManager;
     NicoVideo                      = nicoVideo;
     MylistHelper                   = mylistHelper;
     NotificationService            = notificationService;
     DialogService                  = dialogService;
     ExternalAccessService          = externalAccessService;
     AddMylistCommand               = addMylistCommand;
     CreateSubscriptionGroupCommand = createSubscriptionGroupCommand;
     NowLoading                     = new ReactiveProperty <bool>(false);
     IsLoadFailed                   = new ReactiveProperty <bool>(false);
 }
        protected override async void Execute(IVideoContent content)
        {
            var video         = Database.NicoVideoDb.Get(content.Id);
            var cacheRequests = await VideoCacheManager.GetCachedAsync(content.Id);

            if (cacheRequests.Any())
            {
                var confirmed = await DialogService.ShowMessageDialog(
                    "ConfirmCacheRemoveContent".Translate(content.Label),
                    $"ConfirmCacheRemoveTitle".Translate(),
                    acceptButtonText : "Delete".Translate(),
                    "Cancel".Translate()
                    );

                if (confirmed)
                {
                    await VideoCacheManager.CancelCacheRequest(content.Id);
                }
            }
            else
            {
                await VideoCacheManager.CancelCacheRequest(content.Id);
            }
        }
        public CachedQualityNicoVideoListItemViewModel(NicoVideoCacheRequest req, VideoCacheManager cacheManager)
        {
            _Request = req;
            Quality  = _Request.Quality;

            var firstCacheState = _Request.ToCacheState();

            if (firstCacheState != NicoVideoCacheState.Cached)
            {
                CacheState = Observable.FromEventPattern <VideoCacheStateChangedEventArgs>(
                    (x) => cacheManager.VideoCacheStateChanged += x,
                    (x) => cacheManager.VideoCacheStateChanged -= x
                    )
                             .Where(x => x.EventArgs.Request.RawVideoId == _Request.RawVideoId && x.EventArgs.Request.Quality == _Request.Quality)
                             .Select(x => x.EventArgs.CacheState)
                             .ObserveOnUIDispatcher()
                             .ToReadOnlyReactiveProperty(firstCacheState)
                             .AddTo(_CompositeDisposable);

                CacheState.Subscribe(x =>
                {
                    if (x == NicoVideoCacheState.Downloading)
                    {
                        var _cacheManager = App.Current.Container.Resolve <VideoCacheManager>();

                        float firstProgressParcent = 0.0f;
                        if (_Request is NicoVideoCacheProgress)
                        {
                            var prog = (_Request as NicoVideoCacheProgress).DownloadOperation.Progress;
                            if (prog.TotalBytesToReceive > 0)
                            {
                                firstProgressParcent = (float)Math.Round((prog.BytesReceived / (float)prog.TotalBytesToReceive) * 100, 1);
                            }
                        }
                        ProgressPercent = Observable.FromEventPattern <NicoVideoCacheProgress>(
                            (handler) => _cacheManager.DownloadProgress += handler,
                            (handler) => _cacheManager.DownloadProgress -= handler
                            )
                                          .ObserveOnUIDispatcher()
                                          .Where(y => y.EventArgs.RawVideoId == _Request.RawVideoId && y.EventArgs.Quality == _Request.Quality)
                                          .Select(y =>
                        {
                            var prog = y.EventArgs.DownloadOperation.Progress;
                            if (prog.TotalBytesToReceive > 0)
                            {
                                return((float)Math.Round((prog.BytesReceived / (float)prog.TotalBytesToReceive) * 100, 1));
                            }
                            else
                            {
                                return(0.0f);
                            }
                        })
                                          .ToReactiveProperty(firstProgressParcent);
                        RaisePropertyChanged(nameof(ProgressPercent));
                    }
                    else
                    {
                        ProgressPercent?.Dispose();
                        ProgressPercent = null;
                        RaisePropertyChanged(nameof(ProgressPercent));
                    }
                })
                .AddTo(_CompositeDisposable);

                IsCacheDownloading = CacheState.Select(x => x == NicoVideoCacheState.Downloading)
                                     .ToReadOnlyReactiveProperty()
                                     .AddTo(_CompositeDisposable);
            }
            else
            {
                CacheState         = new ReactiveProperty <NicoVideoCacheState>(NicoVideoCacheState.Cached);
                IsCacheDownloading = new ReactiveProperty <bool>(false);
                ProgressPercent    = new ReactiveProperty <float>(0.0f);
            }

            IsCached = CacheState.Select(x => x == NicoVideoCacheState.Cached)
                       .ToReadOnlyReactivePropertySlim()
                       .AddTo(_CompositeDisposable);
        }
 public VideoDisplayViewModel(LocalDownloadInfoPacket param, DateTime begin, DateTime end, ITimeProcess palyProcess)
 {
     StreamManager = new VideoCacheManager(param, begin, end);
     initDisplayer(StreamManager, palyProcess);
 }
 public VideoDisplayViewModel(DownloadInfoParam param, ITimeProcess playProcess)
 {
     StreamManager = new VideoCacheManager(param);
     initDisplayer(StreamManager, playProcess);
 }
Beispiel #26
0
        public CacheManagementPageViewModel(
            IScheduler scheduler,
            NiconicoSession niconicoSession,
            ApplicationLayoutManager applicationLayoutManager,
            VideoCacheSettings cacheSettings,
            VideoCacheManager videoCacheManager,
            VideoCacheFolderManager videoCacheFolderManager,
            VideoCacheDownloadOperationManager videoCacheDownloadOperationManager,
            NicoVideoProvider nicoVideoProvider,
            PageManager pageManager,
            DialogService dialogService,
            NotificationService notificationService,
            SelectionModeToggleCommand selectionModeToggleCommand,
            VideoPlayWithQueueCommand videoPlayWithQueueCommand
            )
        {
            _scheduler                          = scheduler;
            _niconicoSession                    = niconicoSession;
            ApplicationLayoutManager            = applicationLayoutManager;
            VideoCacheSettings                  = cacheSettings;
            VideoCacheManager                   = videoCacheManager;
            _videoCacheFolderManager            = videoCacheFolderManager;
            _videoCacheDownloadOperationManager = videoCacheDownloadOperationManager;
            NicoVideoProvider                   = nicoVideoProvider;
            HohoemaDialogService                = dialogService;
            NotificationService                 = notificationService;
            SelectionModeToggleCommand          = selectionModeToggleCommand;
            VideoPlayWithQueueCommand           = videoPlayWithQueueCommand;
            Groups = new (new[]
            {
                VideoCacheStatus.Failed,
                VideoCacheStatus.Downloading,
                VideoCacheStatus.DownloadPaused,
                VideoCacheStatus.Pending,
                VideoCacheStatus.Completed,
            }
                          .Select(x => new CacheItemsGroup(x, new ObservableCollection <CacheVideoViewModel>()))
                          );

            IsLoggedInWithPremiumMember = _niconicoSession.ObserveProperty(x => x.IsPremiumAccount).ToReadOnlyReactivePropertySlim(_niconicoSession.IsPremiumAccount)
                                          .AddTo(_CompositeDisposable);

            CurrentlyCachedStorageSize = VideoCacheSettings.ObserveProperty(x => x.CachedStorageSize).ToReadOnlyReactivePropertySlim(VideoCacheSettings.CachedStorageSize)
                                         .AddTo(_CompositeDisposable);

            MaxCacheStorageSize = VideoCacheSettings.ObserveProperty(x => x.MaxVideoCacheStorageSize).ToReadOnlyReactivePropertySlim(VideoCacheSettings.MaxVideoCacheStorageSize)
                                  .AddTo(_CompositeDisposable);

            IsAllowDownload = new ReactivePropertySlim <bool>(_videoCacheDownloadOperationManager.IsAllowDownload, mode: ReactivePropertyMode.DistinctUntilChanged);
            IsAllowDownload.Subscribe(isAllowDownload =>
            {
                if (isAllowDownload)
                {
                    _videoCacheDownloadOperationManager.ResumeDownload();
                }
                else
                {
                    _videoCacheDownloadOperationManager.SuspendDownload();
                }
            })
            .AddTo(_CompositeDisposable);

            AvairableStorageSizeNormalized = new[]
            {
                CurrentlyCachedStorageSize,
                MaxCacheStorageSize.Select(x => x ?? 0),
            }
            .CombineLatest()
            .Select(xy => xy[1] == 0 ? 0.0 : ((double)xy[0] / xy[1]))
            .ToReadOnlyReactivePropertySlim()
            .AddTo(_CompositeDisposable);
        }
        public MenuNavigatePageBaseViewModel(
            IUnityContainer container,
            IScheduler scheduler,
            INavigationService navigationService,
            AppearanceSettings appearanceSettings,
            PinSettings pinSettings,
            NiconicoSession niconicoSession,
            LocalMylistManager localMylistManager,
            UserMylistManager userMylistManager,
            VideoCacheManager videoCacheManager,
            PageManager pageManager,
            PlayerViewManager playerViewManager,
            Services.NiconicoLoginService niconicoLoginService,
            Commands.LogoutFromNiconicoCommand logoutFromNiconicoCommand
            )
        {
            PageManager               = pageManager;
            PlayerViewManager         = playerViewManager;
            NiconicoLoginService      = niconicoLoginService;
            LogoutFromNiconicoCommand = logoutFromNiconicoCommand;
            Container          = container;
            Scheduler          = scheduler;
            NavigationService  = navigationService;
            AppearanceSettings = appearanceSettings;
            PinSettings        = pinSettings;
            NiconicoSession    = niconicoSession;
            LocalMylistManager = localMylistManager;
            UserMylistManager  = userMylistManager;
            VideoCacheManager  = videoCacheManager;

            NiconicoSession.LogIn  += (sender, e) => ResetMenuItems();
            NiconicoSession.LogOut += (sender, e) => ResetMenuItems();

            CurrentMenuType = new ReactiveProperty <MenuItemBase>();
            VideoMenu       = App.Current.Container.Resolve <VideoMenuSubPageContent>();
            LiveMenu        = App.Current.Container.Resolve <LiveMenuSubPageContent>();

            // TV Mode
            if (Services.Helpers.DeviceTypeHelper.IsXbox)
            {
                IsTVModeEnable = new ReactiveProperty <bool>(true);
            }
            else
            {
                IsTVModeEnable = AppearanceSettings.ObserveProperty(x => x.IsForceTVModeEnable)
                                 .ToReactiveProperty();
            }


            ServiceLevel = NiconicoSession.ObserveProperty(x => x.ServiceStatus)
                           .ToReadOnlyReactiveProperty(eventScheduler: Scheduler);

            IsNeedFullScreenToggleHelp
                = ApplicationView.PreferredLaunchWindowingMode == ApplicationViewWindowingMode.FullScreen;

            IsOpenPane = new ReactiveProperty <bool>(false);

            MainSelectedItem = new ReactiveProperty <HohoemaListingPageItemBase>(null, ReactivePropertyMode.DistinctUntilChanged);


            PinItems = new ObservableCollection <PinItemViewModel>(
                PinSettings.Pins.Select(x => Container.Resolve <PinItemViewModel>(new ParameterOverride("pin", x)))
                );


            bool isPinItemsChanging = false;

            PinSettings.Pins.CollectionChangedAsObservable()
            .Subscribe(args =>
            {
                if (isPinItemsChanging)
                {
                    return;
                }

                if (args.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    foreach (var item in args.NewItems)
                    {
                        PinItems.Add(Container.Resolve <PinItemViewModel>(new ParameterOverride("pin", item as HohoemaPin)));
                    }
                    RaisePropertyChanged(nameof(PinItems));
                }
                else if (args.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                {
                    foreach (var item in args.OldItems)
                    {
                        var removedPin = item as HohoemaPin;
                        var pinVM      = PinItems.FirstOrDefault(x => x.Pin == removedPin);
                        if (pinVM != null)
                        {
                            PinItems.Remove(pinVM);
                        }
                    }
                    RaisePropertyChanged(nameof(PinItems));
                }
            });

            ResetMenuItems();

            // TODO; PinSettings側で自動保存するようにしたい
            PinItems.CollectionChangedAsObservable()
            .Subscribe(async _ =>
            {
                await Task.Delay(50);

                try
                {
                    isPinItemsChanging = true;
                    PinSettings.Pins.Clear();
                    foreach (var pin in PinItems)
                    {
                        PinSettings.Pins.Add(pin.Pin);
                    }
                }
                finally
                {
                    isPinItemsChanging = false;
                }
            });

            /*
             * Observable.Merge(
             *  MainSelectedItem,
             *  SubSelectedItem
             *  )
             *  .Where(x => x != null)
             *  .Subscribe(x => x.SelectedAction(x.Source));
             */
            /*
             * PageManager.ObserveProperty(x => x.CurrentPageType)
             *  .Subscribe(pageType =>
             *  {
             *      //                    IsOpenPane.Value = false;
             *
             *      bool isMenuItemOpened = false;
             *      foreach (var item in MenuItems)
             *      {
             *          if ((item as MenuItemViewModel)?.PageType == pageType)
             *          {
             *              MainSelectedItem.Value = item;
             *              isMenuItemOpened = true;
             *              break;
             *          }
             *      }
             *
             *
             *      if (!isMenuItemOpened)
             *      {
             *          MainSelectedItem.Value = null;
             *      }
             *
             *      if (Services.Helpers.DeviceTypeHelper.IsXbox || AppearanceSettings.IsForceTVModeEnable
             || Services.Helpers.DeviceTypeHelper.IsMobile
             ||     )
             ||     {
             ||         IsOpenPane.Value = false;
             ||     }
             || });
             */


            PageManager.ObserveProperty(x => x.PageTitle)
            .Subscribe(x =>
            {
                TitleText = x;
            });

            CanGoBackNavigation = new ReactiveProperty <bool>();

            (NavigationService as IPlatformNavigationService).CanGoBackChanged += (_, e) =>
            {
                CanGoBackNavigation.Value = NavigationService.CanGoBack();
            };

            /*
             * IsVisibleMenu = PageManager.ObserveProperty(x => x.CurrentPageType)
             *  .Select(x =>
             *  {
             *      return !PageManager.IsHiddenMenuPage(x);
             *  })
             *  .ToReactiveProperty(false);
             */

            NowNavigating = PageManager.ObserveProperty(x => x.PageNavigating)
                            .ToReactiveProperty();


            PageManager.StartWork    += PageManager_StartWork;
            PageManager.ProgressWork += PageManager_ProgressWork;
            PageManager.CompleteWork += PageManager_CompleteWork;
            PageManager.CancelWork   += PageManager_CancelWork;

            UserName = NiconicoSession.ObserveProperty(x => x.UserName)
                       .ToReadOnlyReactiveProperty(eventScheduler: Scheduler);

            UserIconUrl = NiconicoSession.ObserveProperty(x => x.UserIconUrl)
                          .ToReadOnlyReactiveProperty(eventScheduler: Scheduler);


            // 検索
            SearchKeyword = new ReactiveProperty <string>("");

            SearchCommand = new ReactiveCommand();
            SearchCommand
            .Subscribe(async _ =>
            {
                await Task.Delay(50);
                var keyword = SearchKeyword.Value;

                if (string.IsNullOrWhiteSpace(keyword))
                {
                    return;
                }

                SearchTarget?searchType = CurrentMenuType.Value is LiveMenuSubPageContent ? SearchTarget.Niconama : SearchTarget.Keyword;
                var searched            = Database.SearchHistoryDb.LastSearchedTarget(keyword);
                if (searched != null)
                {
                    searchType = searched;
                }

                PageManager.Search(searchType.Value, keyword);

                ResetSearchHistoryItems();
            });

            SearchSuggestionWords = new ObservableCollection <string>();



            // InAppNotification
            IsShowInAppNotification = new ReactiveProperty <bool>(true);


            // 検索履歴アイテムを初期化
            ResetSearchHistoryItems();
        }
        private void VideoItemFlyout_Opening(object sender, object e)
        {
            object dataContext = Target.DataContext ?? (Target as SelectorItem)?.Content;
            var    content     = (dataContext as Interfaces.IVideoContent);

            if (content == null || (VideoItems?.Any() ?? false))
            {
                content     = VideoItems?.First();
                dataContext = VideoItems;
            }

            bool isMultipleSelection = VideoItems?.Count >= 2;

            var playlist = Playlist;


            // 視聴履歴
            RemoveWatchHisotryItem.Visibility = (content is IWatchHistory).ToVisibility();

            // ローカルプレイリスト
            if (playlist is LocalPlaylist localPlaylist)
            {
                RemoveLocalPlaylistItem.CommandParameter = dataContext;
                RemoveLocalPlaylistItem.Command          = localPlaylist.ItemsRemoveCommand;
                RemoveLocalPlaylistItem.Visibility       = Visibility.Visible;
            }
            else
            {
                RemoveLocalPlaylistItem.Visibility = Visibility.Collapsed;
            }

            // マイリスト
            if (playlist is LoginUserMylistPlaylist mylistPlaylist)
            {
                RemoveMylistItem.CommandParameter = dataContext;
                RemoveMylistItem.Command          = mylistPlaylist.ItemsRemoveCommand;
                RemoveMylistItem.Visibility       = Visibility.Visible;
            }
            else
            {
                RemoveMylistItem.Visibility = Visibility.Collapsed;
            }

            // キュー
            AddQueue.CommandParameter    = dataContext;
            RemoveQueue.CommandParameter = dataContext;
            if (isMultipleSelection)
            {
                AddQueue.Visibility    = VideoItems.All(x => HohoemaPlaylist.QueuePlaylist.Contains(x)).ToInvisibility();
                RemoveQueue.Visibility = VideoItems.Any(x => HohoemaPlaylist.QueuePlaylist.Contains(x)).ToVisibility();
            }
            else if (HohoemaPlaylist.QueuePlaylist.Contains(content))
            {
                AddQueue.Visibility    = Visibility.Collapsed;
                RemoveQueue.Visibility = Visibility.Visible;
            }
            else
            {
                AddQueue.Visibility    = Visibility.Visible;
                RemoveQueue.Visibility = Visibility.Collapsed;
            }

            // あとで見る
            AddWatchAfter.CommandParameter    = dataContext;
            RemoveWatchAfter.CommandParameter = dataContext;
            if (isMultipleSelection)
            {
                AddWatchAfter.Visibility    = VideoItems.All(x => HohoemaPlaylist.WatchAfterPlaylist.Contains(x)).ToInvisibility();
                RemoveWatchAfter.Visibility = VideoItems.Any(x => HohoemaPlaylist.WatchAfterPlaylist.Contains(x)).ToVisibility();
            }
            else if (HohoemaPlaylist.WatchAfterPlaylist.Contains(content))
            {
                AddWatchAfter.Visibility    = Visibility.Collapsed;
                RemoveWatchAfter.Visibility = Visibility.Visible;
            }
            else
            {
                AddWatchAfter.Visibility    = Visibility.Visible;
                RemoveWatchAfter.Visibility = Visibility.Collapsed;
            }


            // マイリスト
            AddToMylistSubItem.Items.Clear();
            AddToMylistSubItem.Visibility = UserMylistManager.IsLoginUserMylistReady ? Visibility.Visible : Visibility.Collapsed;
            if (UserMylistManager.IsLoginUserMylistReady)
            {
                AddToMylistSubItem.Items.Add(new MenuFlyoutItem()
                {
                    Text             = _localizedText_CreateNew,
                    Command          = CreateMylistCommand,
                    CommandParameter = dataContext
                });

                foreach (var mylist in UserMylistManager.Mylists)
                {
                    AddToMylistSubItem.Items.Add(new MenuFlyoutItem()
                    {
                        Text             = mylist.Label,
                        Command          = mylist.ItemsAddCommand,
                        CommandParameter = dataContext
                    });
                }
            }

            var visibleSingleSelectionItem = isMultipleSelection.ToInvisibility();

            OpenVideoInfoPage.Visibility      = visibleSingleSelectionItem;
            OpenOwnerVideosPage.Visibility    = visibleSingleSelectionItem;
            AddNgUser.Visibility              = visibleSingleSelectionItem;
            VideoInfoItemSeparator.Visibility = visibleSingleSelectionItem;


            //OpenOwnerSeriesPage.Visibility = (content?.ProviderType == Database.NicoVideoUserType.User && content?.ProviderId != null).ToVisibility();
            //OpenOwnerSeriesPage.CommandParameter = content?.ProviderId;

            Share.Visibility       = visibleSingleSelectionItem;
            CopySubItem.Visibility = visibleSingleSelectionItem;

            SusbcriptionSubItem.Visibility = visibleSingleSelectionItem;


            // プレイリスト
            LocalMylistSubItem.Items.Clear();
            LocalMylistSubItem.Items.Add(new MenuFlyoutItem()
            {
                Text             = _localizedText_CreateNew,
                Command          = CreateLocalMylistCommand,
                CommandParameter = dataContext
            });

            foreach (var localMylist in LocalMylistManager.LocalPlaylists)
            {
                LocalMylistSubItem.Items.Add(new MenuFlyoutItem()
                {
                    Text             = localMylist.Label,
                    Command          = localMylist.ItemsAddCommand,
                    CommandParameter = dataContext
                });
            }

            // 購読
            var susbcSourceConverter = new Subscriptions.SubscriptionSourceConverter();
            var subscSource          = susbcSourceConverter.Convert(content, typeof(SubscriptionSource), null, null);

            SusbcriptionSubItem.Items.Clear();
            SusbcriptionSubItem.Items.Add(new MenuFlyoutItem()
            {
                Text             = _localizedText_CreateNew,
                Command          = CreateSubscriptionGroupCommand,
                CommandParameter = subscSource
            });

            foreach (var subsc in SubscriptionManager.Subscriptions)
            {
                SusbcriptionSubItem.Items.Add(new MenuFlyoutItem()
                {
                    Text             = subsc.Label,
                    Command          = subsc.AddSource,
                    CommandParameter = subscSource
                });
            }

            // NG投稿者
            AddNgUser.Visibility    = AddNgUser.Command.CanExecute(content).ToVisibility();
            RemoveNgUser.Visibility = RemoveNgUser.Command.CanExecute(content).ToVisibility();


            // キャッシュ
            var isCacheEnabled          = VideoCacheManager.CacheSettings.IsEnableCache && VideoCacheManager.CacheSettings.IsUserAcceptedCache;
            var cacheEnableToVisibility = isCacheEnabled.ToVisibility();

            if (isMultipleSelection && isCacheEnabled)
            {
                // 一つでもキャッシュ済みがあれば削除ボタンを表示
                // 一つでも未キャッシュがあれば取得ボタンを表示
                var anyItemsCached    = VideoItems.Any(x => VideoCacheManager.IsCacheRequested(x.Id));
                var anyItemsNotCached = VideoItems.Any(x => !VideoCacheManager.CheckCachedAsyncUnsafe(x.Id));

                var notCachedToVisible = (anyItemsNotCached).ToVisibility();
                CacheRequest.Visibility             = notCachedToVisible;
                CacheRequest.CommandParameter       = dataContext;
                CacheRequestWithQuality.Visibility  = notCachedToVisible;
                DeleteCacheRequest.CommandParameter = dataContext;

                CacheSeparator.Visibility = Visibility.Visible;

                var cachedToVisible = (anyItemsCached).ToVisibility();
                DeleteCacheRequest.Visibility = cachedToVisible;
            }
            else if (isCacheEnabled)
            {
                var itemCached    = VideoCacheManager.IsCacheRequested(content.Id);
                var itemNotCached = !VideoCacheManager.CheckCachedAsyncUnsafe(content.Id);

                var notCachedToVisible = (itemNotCached).ToVisibility();
                CacheRequest.Visibility             = notCachedToVisible;
                CacheRequest.CommandParameter       = dataContext;
                CacheRequestWithQuality.Visibility  = notCachedToVisible;
                DeleteCacheRequest.CommandParameter = dataContext;

                CacheSeparator.Visibility = Visibility.Visible;

                var cachedToVisible = (itemCached).ToVisibility();
                DeleteCacheRequest.Visibility = cachedToVisible;
            }
            else
            {
                CacheRequest.Visibility            = Visibility.Collapsed;
                CacheRequestWithQuality.Visibility = Visibility.Collapsed;
                CacheSeparator.Visibility          = Visibility.Collapsed;
                DeleteCacheRequest.Visibility      = Visibility.Collapsed;
            }


            if (CacheRequestWithQuality.Items.Count == 0)
            {
                foreach (var quality in Enum.GetValues(typeof(NicoVideoQuality)).Cast <NicoVideoQuality>().Where(x => x.IsDmc() && x != NicoVideoQuality.Unknown))
                {
                    var command = App.Current.Container.Resolve <CacheAddRequestCommand>();
                    command.VideoQuality = quality;
                    var cacheRequestMenuItem = new MenuFlyoutItem()
                    {
                        Text    = quality.Translate(),
                        Command = command,
                    };
                    CacheRequestWithQuality.Items.Add(cacheRequestMenuItem);
                }
            }

            foreach (var qualityCacheRequest in CacheRequestWithQuality.Items)
            {
                (qualityCacheRequest as MenuFlyoutItem).CommandParameter = dataContext;
            }


            // 選択
            if (!VideoItemsSelectionContext.IsSelectionEnabled)
            {
                SelectionStart.Visibility = Visibility.Visible;
                SelectionEnd.Visibility   = Visibility.Collapsed;
                SelectionAll.Visibility   = Visibility.Collapsed;
            }
            else
            {
                SelectionStart.Visibility = Visibility.Collapsed;
                SelectionEnd.Visibility   = Visibility.Visible;
                SelectionAll.Visibility   = Visibility.Visible;
            }
        }
        public CacheManagementPageViewModel(
            HohoemaApp app,
            PageManager pageManager,
            HohoemaDialogService dialogService
            )
            : base(app, pageManager)
        {
            _MediaManager         = app.CacheManager;
            _HohoemaDialogService = dialogService;

            IsRequireUpdateCacheSaveFolder = new ReactiveProperty <bool>(false);

            IsCacheUserAccepted = HohoemaApp.UserSettings.CacheSettings.ObserveProperty(x => x.IsUserAcceptedCache)
                                  .ToReadOnlyReactiveProperty();

            RequireEnablingCacheCommand = new DelegateCommand(async() =>
            {
                var result = await _HohoemaDialogService.ShowAcceptCacheUsaseDialogAsync();
                if (result)
                {
                    HohoemaApp.UserSettings.CacheSettings.IsEnableCache       = true;
                    HohoemaApp.UserSettings.CacheSettings.IsUserAcceptedCache = true;
                    (App.Current).Resources["IsCacheEnabled"] = true;

                    await RefreshCacheSaveFolderStatus();

                    (App.Current as App).PublishInAppNotification(
                        InAppNotificationPayload.CreateReadOnlyNotification("キャッシュの保存先フォルダを選択してください。\n保存先が選択されると利用準備が完了します。",
                                                                            showDuration: TimeSpan.FromSeconds(30)
                                                                            ));

                    if (await HohoemaApp.ChangeUserDataFolder())
                    {
                        await RefreshCacheSaveFolderStatus();
                        await ResetList();

                        (App.Current as App).PublishInAppNotification(
                            InAppNotificationPayload.CreateReadOnlyNotification("キャッシュの利用準備が出来ました")
                            );
                    }
                }
            });

            ReadCacheAcceptTextCommand = new DelegateCommand(async() =>
            {
                var result = await _HohoemaDialogService.ShowAcceptCacheUsaseDialogAsync(showWithoutConfirmButton: true);
            });



            CacheFolderStateDescription = new ReactiveProperty <string>("");
            CacheSaveFolderPath         = new ReactiveProperty <string>("");

            OpenCurrentCacheFolderCommand = new DelegateCommand(async() =>
            {
                await RefreshCacheSaveFolderStatus();

                var folder = await HohoemaApp.GetVideoCacheFolder();
                if (folder != null)
                {
                    await Launcher.LaunchFolderAsync(folder);
                }
            });


            ChangeCacheFolderCommand = new DelegateCommand(async() =>
            {
                var prevPath = CacheSaveFolderPath.Value;

                if (await HohoemaApp.ChangeUserDataFolder())
                {
                    (App.Current as App).PublishInAppNotification(
                        InAppNotificationPayload.CreateReadOnlyNotification($"キャッシュの保存先を {CacheSaveFolderPath.Value} に変更しました")
                        );

                    await RefreshCacheSaveFolderStatus();
                    await ResetList();
                }
            });
        }
Beispiel #30
0
        public async void Play(PlaylistItem item)
        {
            // プレイリストアイテムが不正
            var playlist = item.Owner;

            if (item.Type == PlaylistItemType.Video)
            {
                if (playlist != null && !playlist.Contains(item.ContentId))
                {
                    throw new Exception();
                }
            }


            if (!NiconicoSession.IsPremiumAccount && !VideoCacheManager.CanAddDownloadLine)
            {
                // 一般ユーザーまたは未登録ユーザーの場合
                // 視聴セッションを1つに制限するため、キャッシュダウンロードを止める必要がある
                // キャッシュ済みのアイテムを再生中の場合はダウンロード可能なので確認をスキップする
                bool playingVideoIsCached = false;
                var  currentItem          = item;
                if (currentItem != null && currentItem.Type == PlaylistItemType.Video)
                {
                    var cachedItems = await VideoCacheManager.GetCacheRequest(currentItem.ContentId);

                    if (cachedItems.FirstOrDefault(x => x.ToCacheState() == NicoVideoCacheState.Cached) != null)
                    {
                        playingVideoIsCached = true;
                    }
                }

                if (!playingVideoIsCached)
                {
                    var currentDownloadingItems = await VideoCacheManager.GetDownloadProgressVideosAsync();

                    var downloadingItem          = currentDownloadingItems.FirstOrDefault();
                    var downloadingItemVideoInfo = Database.NicoVideoDb.Get(downloadingItem.RawVideoId);

                    var dialogService = App.Current.Container.Resolve <Services.DialogService>();
                    var totalSize     = downloadingItem.DownloadOperation.Progress.TotalBytesToReceive;
                    var receivedSize  = downloadingItem.DownloadOperation.Progress.BytesReceived;
                    var megaBytes     = (totalSize - receivedSize) / 1000_000.0;
                    var downloadProgressDescription = $"ダウンロード中\n{downloadingItemVideoInfo.Title}\n残り {megaBytes:0.0} MB ( {receivedSize / 1000_000.0:0.0} MB / {totalSize / 1000_000.0:0.0} MB)";
                    var isCancelCacheAndPlay        = await dialogService.ShowMessageDialog("ニコニコのプレミアム会員以外は 視聴とダウンロードは一つしか同時に行えません。\n視聴を開始する場合、キャッシュは中止されます。またキャッシュを再開する場合はダウンロードは最初からやり直しになります。\n\n" + downloadProgressDescription, "キャッシュを中止して視聴を開始しますか?", "キャッシュを中止して視聴する", "何もしない");

                    if (isCancelCacheAndPlay)
                    {
                        await VideoCacheManager.SuspendCacheDownload();
                    }
                    else
                    {
                        return;
                    }
                }
            }
            else if (!NiconicoSession.IsPremiumAccount)
            {
                // キャッシュ済みの場合はサスペンドを掛けない
                if (item.Type == PlaylistItemType.Video && false == await VideoCacheManager.CheckCachedAsync(item.ContentId))
                {
                    await VideoCacheManager.SuspendCacheDownload();
                }
            }

            Player.PlayStarted(item);

            _ = PlayerViewManager.PlayWithCurrentPlayerView(item);
        }