using System; using System.Collections; using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Threading.Tasks; using Avalonia.Media.Imaging; using DownKyi.Core.BiliApi.History; using DownKyi.Core.BiliApi.VideoStream; using DownKyi.Core.Storage; using DownKyi.Events; using DownKyi.Images; using DownKyi.PrismExtension.Dialog; using DownKyi.Services; using DownKyi.Services.Download; using DownKyi.Utils; using DownKyi.ViewModels.PageViewModels; using Prism.Commands; using Prism.Events; using Prism.Regions; namespace DownKyi.ViewModels; public class ViewMyToViewVideoViewModel : ViewModelBase { public const string Tag = "PageMyToView"; private CancellationTokenSource tokenSource; #region 页面属性申明 private string pageName = Tag; public string PageName { get => pageName; set => SetProperty(ref pageName, value); } private VectorImage arrowBack; public VectorImage ArrowBack { get => arrowBack; set => SetProperty(ref arrowBack, value); } private VectorImage downloadManage; public VectorImage DownloadManage { get => downloadManage; set => SetProperty(ref downloadManage, value); } private bool contentVisibility; public bool ContentVisibility { get => contentVisibility; set => SetProperty(ref contentVisibility, value); } private ObservableCollection medias; public ObservableCollection Medias { get => medias; set => SetProperty(ref medias, value); } private bool isSelectAll; public bool IsSelectAll { get => isSelectAll; set => SetProperty(ref isSelectAll, value); } private bool loading; public bool Loading { get => loading; set => SetProperty(ref loading, value); } private bool loadingVisibility; public bool LoadingVisibility { get => loadingVisibility; set => SetProperty(ref loadingVisibility, value); } private bool noDataVisibility; public bool NoDataVisibility { get => noDataVisibility; set => SetProperty(ref noDataVisibility, value); } #endregion public ViewMyToViewVideoViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base( eventAggregator) { this.DialogService = dialogService; #region 属性初始化 // 初始化loading Loading = true; LoadingVisibility = false; NoDataVisibility = false; ArrowBack = NavigationIcon.Instance().ArrowBack; ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); // 下载管理按钮 DownloadManage = ButtonIcon.Instance().DownloadManage; DownloadManage.Height = 24; DownloadManage.Width = 24; DownloadManage.Fill = DictionaryResource.GetColor("ColorPrimary"); Medias = new ObservableCollection(); #endregion } #region 命令申明 // 返回事件 private DelegateCommand backSpaceCommand; public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace)); /// /// 返回事件 /// private void ExecuteBackSpace() { InitView(); ArrowBack.Fill = DictionaryResource.GetColor("ColorText"); // 结束任务 tokenSource?.Cancel(); NavigationParam parameter = new NavigationParam { ViewName = ParentView, ParentViewName = null, Parameter = null }; EventAggregator.GetEvent().Publish(parameter); } // 前往下载管理页面 private DelegateCommand downloadManagerCommand; public DelegateCommand DownloadManagerCommand => downloadManagerCommand ?? (downloadManagerCommand = new DelegateCommand(ExecuteDownloadManagerCommand)); /// /// 前往下载管理页面 /// private void ExecuteDownloadManagerCommand() { NavigationParam parameter = new NavigationParam { ViewName = ViewDownloadManagerViewModel.Tag, ParentViewName = Tag, Parameter = null }; EventAggregator.GetEvent().Publish(parameter); } // 全选按钮点击事件 private DelegateCommand selectAllCommand; public DelegateCommand SelectAllCommand => selectAllCommand ?? (selectAllCommand = new DelegateCommand(ExecuteSelectAllCommand)); /// /// 全选按钮点击事件 /// /// private void ExecuteSelectAllCommand(object parameter) { if (IsSelectAll) { foreach (var item in Medias) { item.IsSelected = true; } } else { foreach (var item in Medias) { item.IsSelected = false; } } } // 列表选择事件 private DelegateCommand mediasCommand; public DelegateCommand MediasCommand => mediasCommand ?? (mediasCommand = new DelegateCommand(ExecuteMediasCommand)); /// /// 列表选择事件 /// /// private void ExecuteMediasCommand(object parameter) { if (!(parameter is IList selectedMedia)) { return; } if (selectedMedia.Count == Medias.Count) { IsSelectAll = true; } else { IsSelectAll = false; } } // 添加选中项到下载列表事件 private DelegateCommand addToDownloadCommand; public DelegateCommand AddToDownloadCommand => addToDownloadCommand ?? (addToDownloadCommand = new DelegateCommand(ExecuteAddToDownloadCommand)); /// /// 添加选中项到下载列表事件 /// private void ExecuteAddToDownloadCommand() { AddToDownload(true); } // 添加所有视频到下载列表事件 private DelegateCommand addAllToDownloadCommand; public DelegateCommand AddAllToDownloadCommand => addAllToDownloadCommand ?? (addAllToDownloadCommand = new DelegateCommand(ExecuteAddAllToDownloadCommand)); /// /// 添加所有视频到下载列表事件 /// private void ExecuteAddAllToDownloadCommand() { AddToDownload(false); } #endregion /// /// 添加到下载 /// /// private async void AddToDownload(bool isOnlySelected) { // 稍后再看里只有视频 AddToDownloadService addToDownloadService = new AddToDownloadService(PlayStreamType.VIDEO); // 选择文件夹 string directory = await addToDownloadService.SetDirectory(DialogService); // 视频计数 int i = 0; await Task.Run(async () => { // 为了避免执行其他操作时, // Medias变化导致的异常 var list = Medias.ToList(); // 添加到下载 foreach (var media in list) { // 只下载选中项,跳过未选中项 if (isOnlySelected && !media.IsSelected) { continue; } /// 有分P的就下载全部 // 开启服务 VideoInfoService videoInfoService = new VideoInfoService(media.Bvid); addToDownloadService.SetVideoInfoService(videoInfoService); addToDownloadService.GetVideo(); addToDownloadService.ParseVideo(videoInfoService); // 下载 i += await addToDownloadService.AddToDownload(EventAggregator, DialogService, directory); } }); if (directory == null) { return; } // 通知用户添加到下载列表的结果 if (i <= 0) { EventAggregator.GetEvent().Publish(DictionaryResource.GetString("TipAddDownloadingZero")); } else { EventAggregator.GetEvent() .Publish( $"{DictionaryResource.GetString("TipAddDownloadingFinished1")}{i}{DictionaryResource.GetString("TipAddDownloadingFinished2")}"); } } private async void UpdateToViewMediaList() { LoadingVisibility = true; NoDataVisibility = false; Medias.Clear(); await Task.Run(() => { CancellationToken cancellationToken = tokenSource.Token; var toViewList = ToView.GetToView(); if (toViewList == null || toViewList.Count == 0) { LoadingVisibility = false; NoDataVisibility = true; return; } foreach (var toView in toViewList) { // 查询、保存封面 string coverUrl = toView.Pic; Bitmap cover; if (coverUrl == null || coverUrl == "") { cover = null; } else { if (!coverUrl.ToLower().StartsWith("http")) { coverUrl = $"https:{toView.Pic}"; } StorageCover storageCover = new StorageCover(); cover = storageCover.GetCoverThumbnail(toView.Aid, toView.Bvid, toView.Cid, coverUrl, 160, 100); } // 获取用户头像 long upMid = -1; string upName; Bitmap upHeader; if (toView.Owner != null && toView.Owner.Face != null) { upMid = toView.Owner.Mid; upName = toView.Owner.Name; StorageHeader storageHeader = new StorageHeader(); upHeader = storageHeader.GetHeaderThumbnail(toView.Owner.Mid, upName, toView.Owner.Face, 24, 24); } else { upName = ""; upHeader = null; } App.PropertyChangeAsync(() => { ToViewMedia media = new ToViewMedia(EventAggregator) { Aid = toView.Aid, Bvid = toView.Bvid, UpMid = upMid, Cover = cover ?? ImageHelper.LoadFromResource( new Uri($"avares://DownKyi/Resources/video-placeholder.png")), Title = toView.Title, UpName = upName, UpHeader = upHeader }; Medias.Add(media); ContentVisibility = true; LoadingVisibility = false; NoDataVisibility = false; }); // 判断是否该结束线程,若为true,跳出循环 if (cancellationToken.IsCancellationRequested) { break; } } }, (tokenSource = new CancellationTokenSource()).Token); } /// /// 初始化页面数据 /// private void InitView() { ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); ContentVisibility = false; LoadingVisibility = false; NoDataVisibility = false; Medias.Clear(); IsSelectAll = false; } /// /// 导航到页面时执行 /// /// public override void OnNavigatedTo(NavigationContext navigationContext) { base.OnNavigatedTo(navigationContext); ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); DownloadManage = ButtonIcon.Instance().DownloadManage; DownloadManage.Height = 24; DownloadManage.Width = 24; DownloadManage.Fill = DictionaryResource.GetColor("ColorPrimary"); // 根据传入参数不同执行不同任务 long mid = navigationContext.Parameters.GetValue("Parameter"); if (mid == 0) { IsSelectAll = false; foreach (var media in Medias) { media.IsSelected = false; } return; } InitView(); UpdateToViewMediaList(); } }