完成“我的订阅”页面;修复一些问题

croire 3 years ago
parent 7b8b6b9009
commit 62a0528112

@ -159,15 +159,17 @@ namespace DownKyi
containerRegistry.RegisterForNavigation<ViewLogin>(ViewLoginViewModel.Tag); containerRegistry.RegisterForNavigation<ViewLogin>(ViewLoginViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewVideoDetail>(ViewVideoDetailViewModel.Tag); containerRegistry.RegisterForNavigation<ViewVideoDetail>(ViewVideoDetailViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewSettings>(ViewSettingsViewModel.Tag); containerRegistry.RegisterForNavigation<ViewSettings>(ViewSettingsViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewDownloadManager>(ViewDownloadManagerViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewToolbox>(ViewToolboxViewModel.Tag); containerRegistry.RegisterForNavigation<ViewToolbox>(ViewToolboxViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewUserSpace>(ViewUserSpaceViewModel.Tag); containerRegistry.RegisterForNavigation<ViewDownloadManager>(ViewDownloadManagerViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewMySpace>(ViewMySpaceViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewPublicFavorites>(ViewPublicFavoritesViewModel.Tag); containerRegistry.RegisterForNavigation<ViewPublicFavorites>(ViewPublicFavoritesViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewUserSpace>(ViewUserSpaceViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewPublication>(ViewPublicationViewModel.Tag); containerRegistry.RegisterForNavigation<ViewPublication>(ViewPublicationViewModel.Tag);
containerRegistry.RegisterForNavigation<Views.ViewChannel>(ViewModels.ViewChannelViewModel.Tag); containerRegistry.RegisterForNavigation<Views.ViewChannel>(ViewModels.ViewChannelViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewMySpace>(ViewMySpaceViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewMyFavorites>(ViewMyFavoritesViewModel.Tag); containerRegistry.RegisterForNavigation<ViewMyFavorites>(ViewMyFavoritesViewModel.Tag);
containerRegistry.RegisterForNavigation<ViewMyBangumiFollow>(ViewMyBangumiFollowViewModel.Tag);
// downloadManager pages // downloadManager pages
containerRegistry.RegisterForNavigation<ViewDownloading>(ViewDownloadingViewModel.Tag); containerRegistry.RegisterForNavigation<ViewDownloading>(ViewDownloadingViewModel.Tag);

@ -74,6 +74,8 @@ namespace DownKyi.CustomControl
OnCountChanged(count); OnCountChanged(count);
SetView();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Count")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Count"));
} }
} }
@ -100,6 +102,8 @@ namespace DownKyi.CustomControl
{ {
current = value; current = value;
SetView();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Current")); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Current"));
} }
} }

@ -100,6 +100,7 @@
<Compile Include="Services\Download\AddToDownloadService.cs" /> <Compile Include="Services\Download\AddToDownloadService.cs" />
<Compile Include="Services\Download\DownloadStorageService.cs" /> <Compile Include="Services\Download\DownloadStorageService.cs" />
<Compile Include="Services\SearchService.cs" /> <Compile Include="Services\SearchService.cs" />
<Compile Include="ViewModels\PageViewModels\BangumiFollowMedia.cs" />
<Compile Include="ViewModels\PageViewModels\Favorites.cs" /> <Compile Include="ViewModels\PageViewModels\Favorites.cs" />
<Compile Include="ViewModels\PageViewModels\FavoritesMedia.cs" /> <Compile Include="ViewModels\PageViewModels\FavoritesMedia.cs" />
<Compile Include="ViewModels\PageViewModels\ChannelMedia.cs" /> <Compile Include="ViewModels\PageViewModels\ChannelMedia.cs" />
@ -152,6 +153,7 @@
<Compile Include="ViewModels\ViewLoginViewModel.cs" /> <Compile Include="ViewModels\ViewLoginViewModel.cs" />
<Compile Include="ViewModels\Settings\ViewNetworkViewModel.cs" /> <Compile Include="ViewModels\Settings\ViewNetworkViewModel.cs" />
<Compile Include="ViewModels\Dialogs\ViewParsingSelectorViewModel.cs" /> <Compile Include="ViewModels\Dialogs\ViewParsingSelectorViewModel.cs" />
<Compile Include="ViewModels\ViewMyBangumiFollowViewModel.cs" />
<Compile Include="ViewModels\ViewMyFavoritesViewModel.cs" /> <Compile Include="ViewModels\ViewMyFavoritesViewModel.cs" />
<Compile Include="ViewModels\ViewMySpaceViewModel.cs" /> <Compile Include="ViewModels\ViewMySpaceViewModel.cs" />
<Compile Include="ViewModels\ViewPublicationViewModel.cs" /> <Compile Include="ViewModels\ViewPublicationViewModel.cs" />
@ -218,6 +220,9 @@
<Compile Include="Views\ViewLogin.xaml.cs"> <Compile Include="Views\ViewLogin.xaml.cs">
<DependentUpon>ViewLogin.xaml</DependentUpon> <DependentUpon>ViewLogin.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\ViewMyBangumiFollow.xaml.cs">
<DependentUpon>ViewMyBangumiFollow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ViewMyFavorites.xaml.cs"> <Compile Include="Views\ViewMyFavorites.xaml.cs">
<DependentUpon>ViewMyFavorites.xaml</DependentUpon> <DependentUpon>ViewMyFavorites.xaml</DependentUpon>
</Compile> </Compile>
@ -402,6 +407,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Views\ViewMyBangumiFollow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ViewMyFavorites.xaml"> <Page Include="Views\ViewMyFavorites.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

@ -76,6 +76,9 @@
<system:String x:Key="FavoritesCreateTime">投稿:</system:String> <system:String x:Key="FavoritesCreateTime">投稿:</system:String>
<system:String x:Key="FavoritesFavTime">收藏于:</system:String> <system:String x:Key="FavoritesFavTime">收藏于:</system:String>
<!-- MyBangumiFollow -->
<system:String x:Key="MyBangumiFollow">我的订阅</system:String>
<!-- Publication --> <!-- Publication -->
<system:String x:Key="DownloadSelectedPublication">下载选中项</system:String> <system:String x:Key="DownloadSelectedPublication">下载选中项</system:String>
<system:String x:Key="DownloadAllPublication">下载全部</system:String> <system:String x:Key="DownloadAllPublication">下载全部</system:String>

@ -0,0 +1,121 @@
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Utils;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System.Windows.Media.Imaging;
namespace DownKyi.ViewModels.PageViewModels
{
public class BangumiFollowMedia : BindableBase
{
protected readonly IEventAggregator eventAggregator;
public BangumiFollowMedia(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}
// media id
public long MediaId { get; set; }
// season id
public long SeasonId { get; set; }
#region 页面属性申明
// 是否选中
private bool isSelected;
public bool IsSelected
{
get => isSelected;
set => SetProperty(ref isSelected, value);
}
// 封面
private BitmapImage cover;
public BitmapImage Cover
{
get => cover;
set => SetProperty(ref cover, value);
}
// 视频标题
private string title;
public string Title
{
get => title;
set => SetProperty(ref title, value);
}
// 视频类型名称
private string seasonTypeName;
public string SeasonTypeName
{
get => seasonTypeName;
set => SetProperty(ref seasonTypeName, value);
}
// 地区
private string area;
public string Area
{
get => area;
set => SetProperty(ref area, value);
}
// 标记是否会员
private string badge;
public string Badge
{
get => badge;
set => SetProperty(ref badge, value);
}
// 简介
private string evaluate;
public string Evaluate
{
get => evaluate;
set => SetProperty(ref evaluate, value);
}
// 视频更新进度
private string indexShow;
public string IndexShow
{
get => indexShow;
set => SetProperty(ref indexShow, value);
}
// 观看进度
private string progress;
public string Progress
{
get => progress;
set => SetProperty(ref progress, value);
}
#endregion
#region 命令申明
// 视频标题点击事件
private DelegateCommand<object> titleCommand;
public DelegateCommand<object> TitleCommand => titleCommand ?? (titleCommand = new DelegateCommand<object>(ExecuteTitleCommand));
/// <summary>
/// 视频标题点击事件
/// </summary>
/// <param name="parameter"></param>
private void ExecuteTitleCommand(object parameter)
{
if (!(parameter is string tag)) { return; }
NavigateToView.NavigationView(eventAggregator, ViewVideoDetailViewModel.Tag, tag, $"{ParseEntrance.BangumiMediaUrl}md{MediaId}");
}
#endregion
}
}

@ -19,6 +19,8 @@ namespace DownKyi.ViewModels.PageViewModels
public long Avid { get; set; } public long Avid { get; set; }
public string Bvid { get; set; } public string Bvid { get; set; }
#region 页面属性申明
private bool isSelected; private bool isSelected;
public bool IsSelected public bool IsSelected
{ {
@ -61,6 +63,10 @@ namespace DownKyi.ViewModels.PageViewModels
set => SetProperty(ref createTime, value); set => SetProperty(ref createTime, value);
} }
#endregion
#region 命令申明
// 视频标题点击事件 // 视频标题点击事件
private DelegateCommand<object> titleCommand; private DelegateCommand<object> titleCommand;
public DelegateCommand<object> TitleCommand => titleCommand ?? (titleCommand = new DelegateCommand<object>(ExecuteTitleCommand)); public DelegateCommand<object> TitleCommand => titleCommand ?? (titleCommand = new DelegateCommand<object>(ExecuteTitleCommand));
@ -78,5 +84,7 @@ namespace DownKyi.ViewModels.PageViewModels
//System.Diagnostics.Process.Start(url); //System.Diagnostics.Process.Start(url);
} }
#endregion
} }
} }

@ -19,6 +19,8 @@ namespace DownKyi.ViewModels.PageViewModels
public long Avid { get; set; } public long Avid { get; set; }
public string Bvid { get; set; } public string Bvid { get; set; }
#region 页面属性申明
private bool isSelected; private bool isSelected;
public bool IsSelected public bool IsSelected
{ {
@ -61,6 +63,10 @@ namespace DownKyi.ViewModels.PageViewModels
set => SetProperty(ref createTime, value); set => SetProperty(ref createTime, value);
} }
#endregion
#region 命令申明
// 视频标题点击事件 // 视频标题点击事件
private DelegateCommand<object> titleCommand; private DelegateCommand<object> titleCommand;
public DelegateCommand<object> TitleCommand => titleCommand ?? (titleCommand = new DelegateCommand<object>(ExecuteTitleCommand)); public DelegateCommand<object> TitleCommand => titleCommand ?? (titleCommand = new DelegateCommand<object>(ExecuteTitleCommand));
@ -78,5 +84,7 @@ namespace DownKyi.ViewModels.PageViewModels
//System.Diagnostics.Process.Start(url); //System.Diagnostics.Process.Start(url);
} }
#endregion
} }
} }

@ -16,6 +16,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
@ -246,8 +247,12 @@ namespace DownKyi.ViewModels
int i = 0; int i = 0;
await Task.Run(() => await Task.Run(() =>
{ {
// 为了避免执行其他操作时,
// Medias变化导致的异常
var list = Medias.ToList();
// 添加到下载 // 添加到下载
foreach (var media in Medias) foreach (var media in list)
{ {
// 只下载选中项,跳过未选中项 // 只下载选中项,跳过未选中项
if (isOnlySelected && !media.IsSelected) { continue; } if (isOnlySelected && !media.IsSelected) { continue; }

@ -0,0 +1,504 @@
using DownKyi.Core.BiliApi.BiliUtils;
using DownKyi.Core.BiliApi.VideoStream;
using DownKyi.Core.Storage;
using DownKyi.CustomControl;
using DownKyi.Events;
using DownKyi.Images;
using DownKyi.Services;
using DownKyi.Services.Download;
using DownKyi.Utils;
using DownKyi.ViewModels.PageViewModels;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
namespace DownKyi.ViewModels
{
public class ViewMyBangumiFollowViewModel : BaseViewModel
{
public const string Tag = "PageMyBangumiFollow";
private readonly IDialogService dialogService;
private CancellationTokenSource tokenSource;
private long mid = -1;
// 每页视频数量,暂时在此写死,以后在设置中增加选项
private readonly int VideoNumberInPage = 15;
#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 ObservableCollection<TabHeader> tabHeaders;
public ObservableCollection<TabHeader> TabHeaders
{
get => tabHeaders;
set => SetProperty(ref tabHeaders, value);
}
private int selectTabId;
public int SelectTabId
{
get => selectTabId;
set => SetProperty(ref selectTabId, value);
}
private bool isEnabled = true;
public bool IsEnabled
{
get => isEnabled;
set => SetProperty(ref isEnabled, value);
}
private Visibility contentVisibility;
public Visibility ContentVisibility
{
get => contentVisibility;
set => SetProperty(ref contentVisibility, value);
}
private CustomPagerViewModel pager;
public CustomPagerViewModel Pager
{
get => pager;
set => SetProperty(ref pager, value);
}
private ObservableCollection<BangumiFollowMedia> medias;
public ObservableCollection<BangumiFollowMedia> Medias
{
get => medias;
set => SetProperty(ref medias, value);
}
private bool isSelectAll;
public bool IsSelectAll
{
get => isSelectAll;
set => SetProperty(ref isSelectAll, value);
}
private GifImage loading;
public GifImage Loading
{
get => loading;
set => SetProperty(ref loading, value);
}
private Visibility loadingVisibility;
public Visibility LoadingVisibility
{
get => loadingVisibility;
set => SetProperty(ref loadingVisibility, value);
}
private Visibility noDataVisibility;
public Visibility NoDataVisibility
{
get => noDataVisibility;
set => SetProperty(ref noDataVisibility, value);
}
#endregion
public ViewMyBangumiFollowViewModel(IEventAggregator eventAggregator, IDialogService dialogService) : base(eventAggregator)
{
this.dialogService = dialogService;
#region 属性初始化
// 初始化loading gif
Loading = new GifImage(Properties.Resources.loading);
Loading.StartAnimate();
LoadingVisibility = Visibility.Collapsed;
NoDataVisibility = Visibility.Collapsed;
ArrowBack = NavigationIcon.Instance().ArrowBack;
ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark");
TabHeaders = new ObservableCollection<TabHeader>
{
new TabHeader { Id = (int)Core.BiliApi.Users.Models.BangumiType.ANIME, Title = "追番" },
new TabHeader { Id = (int)Core.BiliApi.Users.Models.BangumiType.EPISODE, Title = "追剧" }
};
Medias = new ObservableCollection<BangumiFollowMedia>();
#endregion
}
#region 命令申明
// 返回事件
private DelegateCommand backSpaceCommand;
public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace));
/// <summary>
/// 返回事件
/// </summary>
private void ExecuteBackSpace()
{
InitView();
ArrowBack.Fill = DictionaryResource.GetColor("ColorText");
// 结束任务
tokenSource?.Cancel();
NavigationParam parameter = new NavigationParam
{
ViewName = ParentView,
ParentViewName = null,
Parameter = null
};
eventAggregator.GetEvent<NavigationEvent>().Publish(parameter);
}
// 顶部tab点击事件
private DelegateCommand<object> tabHeadersCommand;
public DelegateCommand<object> TabHeadersCommand => tabHeadersCommand ?? (tabHeadersCommand = new DelegateCommand<object>(ExecuteTabHeadersCommand, CanExecuteTabHeadersCommand));
/// <summary>
/// 左侧tab点击事件
/// </summary>
/// <param name="parameter"></param>
private void ExecuteTabHeadersCommand(object parameter)
{
if (!(parameter is TabHeader tabHeader)) { return; }
// 页面选择
Pager = new CustomPagerViewModel(1, 1);
Pager.CurrentChanged += OnCurrentChanged_Pager;
Pager.CountChanged += OnCountChanged_Pager;
Pager.Current = 1;
}
/// <summary>
/// 顶部tab点击事件是否允许执行
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
private bool CanExecuteTabHeadersCommand(object parameter)
{
return IsEnabled;
}
// 全选按钮点击事件
private DelegateCommand<object> selectAllCommand;
public DelegateCommand<object> SelectAllCommand => selectAllCommand ?? (selectAllCommand = new DelegateCommand<object>(ExecuteSelectAllCommand));
/// <summary>
/// 全选按钮点击事件
/// </summary>
/// <param name="parameter"></param>
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<object> mediasCommand;
public DelegateCommand<object> MediasCommand => mediasCommand ?? (mediasCommand = new DelegateCommand<object>(ExecuteMediasCommand));
/// <summary>
/// 列表选择事件
/// </summary>
/// <param name="parameter"></param>
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));
/// <summary>
/// 添加选中项到下载列表事件
/// </summary>
private void ExecuteAddToDownloadCommand()
{
AddToDownload(true);
}
// 添加所有视频到下载列表事件
private DelegateCommand addAllToDownloadCommand;
public DelegateCommand AddAllToDownloadCommand => addAllToDownloadCommand ?? (addAllToDownloadCommand = new DelegateCommand(ExecuteAddAllToDownloadCommand));
/// <summary>
/// 添加所有视频到下载列表事件
/// </summary>
private void ExecuteAddAllToDownloadCommand()
{
AddToDownload(false);
}
#endregion
/// <summary>
/// 添加到下载
/// </summary>
/// <param name="isOnlySelected"></param>
private async void AddToDownload(bool isOnlySelected)
{
// 订阅里只有BANGUMI类型
AddToDownloadService addToDownloadService = new AddToDownloadService(PlayStreamType.BANGUMI);
// 选择文件夹
string directory = addToDownloadService.SetDirectory(dialogService);
// 视频计数
int i = 0;
await Task.Run(() =>
{
// 为了避免执行其他操作时,
// Medias变化导致的异常
var list = Medias.ToList();
// 添加到下载
foreach (var media in list)
{
// 只下载选中项,跳过未选中项
if (isOnlySelected && !media.IsSelected) { continue; }
/// 有分P的就下载全部
// 开启服务
BangumiInfoService service = new BangumiInfoService($"{ParseEntrance.BangumiMediaUrl}md{media.MediaId}");
addToDownloadService.SetVideoInfoService(service);
addToDownloadService.GetVideo();
addToDownloadService.ParseVideo(service);
// 下载
i += addToDownloadService.AddToDownload(eventAggregator, directory);
}
});
if (directory == null)
{
return;
}
// 通知用户添加到下载列表的结果
if (i == 0)
{
eventAggregator.GetEvent<MessageEvent>().Publish(DictionaryResource.GetString("TipAddDownloadingZero"));
}
else
{
eventAggregator.GetEvent<MessageEvent>().Publish($"{DictionaryResource.GetString("TipAddDownloadingFinished1")}{i}{DictionaryResource.GetString("TipAddDownloadingFinished2")}");
}
}
private void OnCountChanged_Pager(int count) { }
private bool OnCurrentChanged_Pager(int old, int current)
{
if (!IsEnabled)
{
//Pager.Current = old;
return false;
}
UpdateBangumiMediaList(current);
return true;
}
private async void UpdateBangumiMediaList(int current)
{
Medias.Clear();
LoadingVisibility = Visibility.Visible;
NoDataVisibility = Visibility.Collapsed;
// 是否正在获取数据
// 在所有的退出分支中都需要设为true
IsEnabled = false;
var tab = TabHeaders[SelectTabId];
Core.BiliApi.Users.Models.BangumiType type = (Core.BiliApi.Users.Models.BangumiType)tab.Id;
await Task.Run(() =>
{
CancellationToken cancellationToken = tokenSource.Token;
var bangumiFollows = Core.BiliApi.Users.UserSpace.GetBangumiFollow(mid, type, current, VideoNumberInPage);
if (bangumiFollows == null || bangumiFollows.List == null || bangumiFollows.List.Count == 0)
{
LoadingVisibility = Visibility.Collapsed;
NoDataVisibility = Visibility.Visible;
return;
}
// 更新总页码
Pager.Count = (int)Math.Ceiling((double)bangumiFollows.Total / VideoNumberInPage);
// 更新内容
ContentVisibility = Visibility.Visible;
foreach (var bangumiFollow in bangumiFollows.List)
{
// 查询、保存封面
string coverUrl = bangumiFollow.Cover;
BitmapImage cover;
if (coverUrl == null || coverUrl == "")
{
cover = null;
}
else
{
if (!coverUrl.ToLower().StartsWith("http"))
{
coverUrl = $"https:{bangumiFollow.Cover}";
}
StorageCover storageCover = new StorageCover();
cover = storageCover.GetCoverThumbnail(bangumiFollow.MediaId, bangumiFollow.SeasonId.ToString(), -1, coverUrl, 110, 140);
}
// 地区
string area = string.Empty;
if (bangumiFollow.Areas != null && bangumiFollow.Areas.Count > 0)
{
area = bangumiFollow.Areas[0].Name;
}
// 视频更新进度
string indexShow = string.Empty;
if (bangumiFollow.NewEp != null)
{
indexShow = bangumiFollow.NewEp.IndexShow;
}
// 观看进度
string progress;
if (bangumiFollow.Progress == null || bangumiFollow.Progress == "")
{
progress = "尚未观看";
}
else
{
progress = bangumiFollow.Progress;
}
App.PropertyChangeAsync(() =>
{
BangumiFollowMedia media = new BangumiFollowMedia(eventAggregator)
{
MediaId = bangumiFollow.MediaId,
SeasonId = bangumiFollow.SeasonId,
Title = bangumiFollow.Title,
SeasonTypeName = bangumiFollow.SeasonTypeName,
Area = area,
Badge = bangumiFollow.Badge,
Cover = cover ?? new BitmapImage(new Uri($"pack://application:,,,/Resources/video-placeholder.png")),
Evaluate = bangumiFollow.Evaluate,
IndexShow = indexShow,
Progress = progress
};
Medias.Add(media);
LoadingVisibility = Visibility.Collapsed;
NoDataVisibility = Visibility.Collapsed;
});
// 判断是否该结束线程若为true跳出循环
if (cancellationToken.IsCancellationRequested)
{
break;
}
}
}, (tokenSource = new CancellationTokenSource()).Token);
IsEnabled = true;
}
/// <summary>
/// 初始化页面数据
/// </summary>
private void InitView()
{
ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark");
ContentVisibility = Visibility.Collapsed;
LoadingVisibility = Visibility.Visible;
NoDataVisibility = Visibility.Collapsed;
Medias.Clear();
}
/// <summary>
/// 导航到VideoDetail页面时执行
/// </summary>
/// <param name="navigationContext"></param>
public override void OnNavigatedTo(NavigationContext navigationContext)
{
base.OnNavigatedTo(navigationContext);
// 根据传入参数不同执行不同任务
mid = navigationContext.Parameters.GetValue<long>("Parameter");
if (mid == 0)
{
return;
}
InitView();
// 初始选中项
SelectTabId = 0;
// 页面选择
Pager = new CustomPagerViewModel(1, 1);
Pager.CurrentChanged += OnCurrentChanged_Pager;
Pager.CountChanged += OnCountChanged_Pager;
Pager.Current = 1;
}
}
}

@ -15,6 +15,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
@ -317,8 +318,12 @@ namespace DownKyi.ViewModels
int i = 0; int i = 0;
await Task.Run(() => await Task.Run(() =>
{ {
// 为了避免执行其他操作时,
// Medias变化导致的异常
var list = Medias.ToList();
// 添加到下载 // 添加到下载
foreach (var media in Medias) foreach (var media in list)
{ {
// 只下载选中项,跳过未选中项 // 只下载选中项,跳过未选中项
if (isOnlySelected && !media.IsSelected) { continue; } if (isOnlySelected && !media.IsSelected) { continue; }

@ -343,7 +343,7 @@ namespace DownKyi.ViewModels
NavigateToView.NavigationView(eventAggregator, ViewMyFavoritesViewModel.Tag, Tag, mid); NavigateToView.NavigationView(eventAggregator, ViewMyFavoritesViewModel.Tag, Tag, mid);
break; break;
case 1: case 1:
Console.WriteLine(SelectedPackage); NavigateToView.NavigationView(eventAggregator, ViewMyBangumiFollowViewModel.Tag, Tag, mid);
break; break;
case 2: case 2:
Console.WriteLine(SelectedPackage); Console.WriteLine(SelectedPackage);

@ -15,6 +15,7 @@ using Prism.Services.Dialogs;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
@ -249,8 +250,12 @@ namespace DownKyi.ViewModels
int i = 0; int i = 0;
await Task.Run(() => await Task.Run(() =>
{ {
// 为了避免执行其他操作时,
// Medias变化导致的异常
var list = FavoritesMedias.ToList();
// 添加到下载 // 添加到下载
foreach (FavoritesMedia media in FavoritesMedias) foreach (var media in list)
{ {
// 只下载选中项,跳过未选中项 // 只下载选中项,跳过未选中项
if (isOnlySelected && !media.IsSelected) { continue; } if (isOnlySelected && !media.IsSelected) { continue; }

@ -284,8 +284,12 @@ namespace DownKyi.ViewModels
int i = 0; int i = 0;
await Task.Run(() => await Task.Run(() =>
{ {
// 为了避免执行其他操作时,
// Medias变化导致的异常
var list = Medias.ToList();
// 添加到下载 // 添加到下载
foreach (var media in Medias) foreach (var media in list)
{ {
// 只下载选中项,跳过未选中项 // 只下载选中项,跳过未选中项
if (isOnlySelected && !media.IsSelected) { continue; } if (isOnlySelected && !media.IsSelected) { continue; }

@ -0,0 +1,358 @@
<UserControl
x:Class="DownKyi.Views.ViewMyBangumiFollow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:DownKyi.CustomControl"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True">
<UserControl.Resources>
<Style x:Key="MediaListStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid
Name="nameMediaPanel"
Width="308"
Height="140"
Margin="25,15,10,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border
Name="nameCover"
Grid.Column="0"
Width="110"
Height="140"
HorizontalAlignment="Center"
CornerRadius="5">
<Border.Background>
<!-- 长宽比1.6 -->
<ImageBrush ImageSource="{Binding Cover}" />
</Border.Background>
</Border>
<Image
Name="nameChecked"
Grid.Column="0"
Width="24"
Height="24"
Margin="10"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Source="/DownKyi;component/Resources/checked.png" />
<StackPanel Grid.Column="1" Margin="10,0,0,0">
<TextBlock
Name="nameTitle"
Cursor="Hand"
FontSize="16"
Foreground="{DynamicResource BrushTextDark}"
Text="{Binding Title}"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding Title}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding TitleCommand}" CommandParameter="{Binding DataContext.PageName, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<TextBlock
Height="40"
Margin="0,10,0,0"
Foreground="{DynamicResource BrushTextDark}"
Text="{Binding Evaluate}"
TextTrimming="CharacterEllipsis"
TextWrapping="WrapWithOverflow"
ToolTip="{Binding Evaluate}" />
<StackPanel Margin="0,5,0,0" Orientation="Horizontal">
<TextBlock Foreground="{DynamicResource BrushTextGrey}" Text="{Binding SeasonTypeName}" />
<TextBlock
Margin="5,0"
Foreground="{DynamicResource BrushTextGrey}"
Text="|" />
<TextBlock Foreground="{DynamicResource BrushTextGrey}" Text="{Binding Area}" />
</StackPanel>
<StackPanel Margin="0,5,0,0" Orientation="Horizontal">
<TextBlock Foreground="{DynamicResource BrushTextGrey}" Text="{Binding Progress}" />
<TextBlock
Margin="5,0"
Foreground="{DynamicResource BrushTextGrey}"
Text="|" />
<TextBlock Foreground="{DynamicResource BrushTextGrey}" Text="{Binding IndexShow}" />
</StackPanel>
</StackPanel>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="nameChecked" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="nameChecked" Property="Visibility" Value="Hidden" />
</Trigger>
<Trigger SourceName="nameTitle" Property="IsMouseOver" Value="True">
<Setter TargetName="nameTitle" Property="Foreground" Value="{DynamicResource BrushPrimary}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="1" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Button
Grid.Column="0"
Margin="10,5,0,5"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding BackSpaceCommand}"
Style="{StaticResource ImageBtnStyle}">
<StackPanel Orientation="Horizontal">
<ContentControl Width="24" Height="24">
<Path
Width="{Binding ArrowBack.Width}"
Height="{Binding ArrowBack.Height}"
Data="{Binding ArrowBack.Data}"
Fill="{Binding ArrowBack.Fill}"
Stretch="None" />
</ContentControl>
<TextBlock
VerticalAlignment="Center"
FontSize="16"
Foreground="{DynamicResource BrushTextDark}"
Text="{DynamicResource MyBangumiFollow}" />
</StackPanel>
</Button>
<!-- 顶部Tab -->
<ListBox
Name="nameTabHeaders"
Grid.Column="1"
BorderThickness="0"
IsEnabled="{Binding IsEnabled}"
ItemsSource="{Binding TabHeaders}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
SelectedIndex="{Binding SelectTabId, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding TabHeadersCommand}" CommandParameter="{Binding ElementName=nameTabHeaders, Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<StackPanel
x:Name="panel"
Margin="10,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Cursor="Hand">
<TextBlock
Name="nameText"
Padding="0,0,0,3"
Text="{Binding Title}" />
<TextBlock Name="nameIndicator" Height="1.5" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="False">
<Setter TargetName="nameText" Property="Foreground" Value="{DynamicResource BrushTextDark}" />
<Setter TargetName="nameIndicator" Property="Visibility" Value="Hidden" />
<Setter TargetName="nameIndicator" Property="Background" Value="{DynamicResource BrushTextDark}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="nameText" Property="Foreground" Value="{DynamicResource BrushPrimary}" />
</Trigger>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter TargetName="nameText" Property="Foreground" Value="{DynamicResource BrushPrimary}" />
<Setter TargetName="nameIndicator" Property="Visibility" Value="Visible" />
<Setter TargetName="nameIndicator" Property="Background" Value="{DynamicResource BrushPrimary}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border
x:Name="Bd"
Padding="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
</Grid>
<TextBlock Grid.Row="1" Background="{DynamicResource BrushBorder}" />
<Grid Grid.Row="2" Visibility="{Binding ContentVisibility}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="1" />
<RowDefinition Height="49" />
</Grid.RowDefinitions>
<ListBox
x:Name="nameMedias"
Grid.Row="0"
BorderThickness="0"
ItemContainerStyle="{StaticResource MediaListStyle}"
ItemsSource="{Binding Medias}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionMode="Extended">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding MediasCommand}" CommandParameter="{Binding ElementName=nameMedias, Path=SelectedItems}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border
x:Name="Bd"
Padding="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
<TextBlock Grid.Row="1" Background="{DynamicResource BrushBorder}" />
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
Margin="10,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding SelectAllCommand}"
CommandParameter="{Binding ElementName=nameMedias, Path=SelectedItem}"
Content="{DynamicResource SelectAll}"
Foreground="{DynamicResource BrushTextDark}"
IsChecked="{Binding IsSelectAll, Mode=TwoWay}"
Style="{StaticResource CheckBoxStyle}" />
<custom:CustomPager
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
DataContext="{Binding Pager}" />
<Button
Grid.Column="2"
Margin="0,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding AddToDownloadCommand}"
Content="{DynamicResource DownloadSelectedPublication}"
FontSize="12"
Foreground="{DynamicResource BrushText}"
Style="{StaticResource BtnStyle}" />
<Button
Grid.Column="3"
Margin="0,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding AddAllToDownloadCommand}"
Content="{DynamicResource DownloadAllPublication}"
FontSize="12"
Foreground="{DynamicResource BrushText}"
Style="{StaticResource BtnStyle}" />
</Grid>
</Grid>
<!-- 加载gif -->
<StackPanel
Grid.Row="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical"
Visibility="{Binding LoadingVisibility}">
<ContentControl
Width="40"
Height="40"
Content="{Binding Loading}" />
<TextBlock
Margin="0,10,0,0"
FontSize="14"
Foreground="{DynamicResource BrushTextDark}"
Text="{DynamicResource PublicationWait}" />
</StackPanel>
<!-- 没有数据提示 -->
<Image
Grid.Row="2"
Width="256"
Height="256"
Source="/DownKyi;component/Resources/no-data.png"
Visibility="{Binding NoDataVisibility}" />
</Grid>
</UserControl>

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DownKyi.Views
{
/// <summary>
/// ViewMyBangumiFollow.xaml 的交互逻辑
/// </summary>
public partial class ViewMyBangumiFollow : UserControl
{
public ViewMyBangumiFollow()
{
InitializeComponent();
}
}
}

@ -105,7 +105,6 @@
Margin="0,5" Margin="0,5"
Cursor="Hand" Cursor="Hand"
Foreground="{DynamicResource BrushTextDark}" Foreground="{DynamicResource BrushTextDark}"
Tag="{Binding Bvid}"
Text="{Binding Title}" Text="{Binding Title}"
TextTrimming="CharacterEllipsis" TextTrimming="CharacterEllipsis"
TextWrapping="WrapWithOverflow" TextWrapping="WrapWithOverflow"

Loading…
Cancel
Save