diff --git a/DownKyi.Core/BiliApi/BilibiliImages.xaml b/DownKyi.Core/BiliApi/BilibiliImages.xaml new file mode 100644 index 0000000..a2aed4a --- /dev/null +++ b/DownKyi.Core/BiliApi/BilibiliImages.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DownKyi.Core/BiliApi/Zone/ZoneImage.xaml b/DownKyi.Core/BiliApi/Zone/ZoneImages.xaml similarity index 100% rename from DownKyi.Core/BiliApi/Zone/ZoneImage.xaml rename to DownKyi.Core/BiliApi/Zone/ZoneImages.xaml diff --git a/DownKyi.Core/DownKyi.Core.csproj b/DownKyi.Core/DownKyi.Core.csproj index 4fda17f..fc516b6 100644 --- a/DownKyi.Core/DownKyi.Core.csproj +++ b/DownKyi.Core/DownKyi.Core.csproj @@ -315,7 +315,11 @@ - + + MSBuild:Compile + Designer + + MSBuild:Compile Designer diff --git a/DownKyi.Core/Storage/StorageCover.cs b/DownKyi.Core/Storage/StorageCover.cs index 28b7dfb..ce45c31 100644 --- a/DownKyi.Core/Storage/StorageCover.cs +++ b/DownKyi.Core/Storage/StorageCover.cs @@ -42,6 +42,8 @@ namespace DownKyi.Core.Storage /// public BitmapImage GetCoverThumbnail(string cover, int width, int height) { + if (cover == null) { return null; } + Bitmap bitmap = new Bitmap(cover); Image thumbnail = bitmap.GetThumbnailImage(width, height, null, IntPtr.Zero); diff --git a/DownKyi.sln b/DownKyi.sln index 9afa28f..5bc5e70 100644 --- a/DownKyi.sln +++ b/DownKyi.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31019.35 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32126.317 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DownKyi", "DownKyi\DownKyi.csproj", "{97075FCD-6E8F-4FF9-B73A-994197F3765A}" ProjectSection(ProjectDependencies) = postProject diff --git a/DownKyi/App.xaml b/DownKyi/App.xaml index 7835032..e13350d 100644 --- a/DownKyi/App.xaml +++ b/DownKyi/App.xaml @@ -9,7 +9,8 @@ - + + diff --git a/DownKyi/App.xaml.cs b/DownKyi/App.xaml.cs index 41e07d7..59124ef 100644 --- a/DownKyi/App.xaml.cs +++ b/DownKyi/App.xaml.cs @@ -6,11 +6,13 @@ using DownKyi.ViewModels.Dialogs; using DownKyi.ViewModels.DownloadManager; using DownKyi.ViewModels.Settings; using DownKyi.ViewModels.Toolbox; +using DownKyi.ViewModels.UserSpace; using DownKyi.Views; using DownKyi.Views.Dialogs; using DownKyi.Views.DownloadManager; using DownKyi.Views.Settings; using DownKyi.Views.Toolbox; +using DownKyi.Views.UserSpace; using Prism.Ioc; using System; using System.Collections.Generic; @@ -179,6 +181,10 @@ namespace DownKyi containerRegistry.RegisterForNavigation(ViewDelogoViewModel.Tag); containerRegistry.RegisterForNavigation(ViewExtractMediaViewModel.Tag); + // UserSpace + containerRegistry.RegisterForNavigation(ViewArchiveViewModel.Tag); + containerRegistry.RegisterForNavigation(ViewChannelViewModel.Tag); + // dialogs containerRegistry.RegisterDialog(ViewDownloadSetterViewModel.Tag); containerRegistry.RegisterDialog(ViewParsingSelectorViewModel.Tag); diff --git a/DownKyi/DownKyi.csproj b/DownKyi/DownKyi.csproj index 405275c..1727b3b 100644 --- a/DownKyi/DownKyi.csproj +++ b/DownKyi/DownKyi.csproj @@ -132,6 +132,12 @@ + + + + + + @@ -184,6 +190,12 @@ ViewExtractMedia.xaml + + ViewArchive.xaml + + + ViewChannel.xaml + ViewDownloadManager.xaml @@ -343,6 +355,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -475,6 +495,8 @@ + + PreserveNewest diff --git a/DownKyi/Images/NormalIcon.cs b/DownKyi/Images/NormalIcon.cs index d1388b3..bd21580 100644 --- a/DownKyi/Images/NormalIcon.cs +++ b/DownKyi/Images/NormalIcon.cs @@ -239,6 +239,33 @@ l-85 0 l0 341 l341 0 l0 -85 l-256 0 l0 -256 Z", Fill = "#FF000000" }; + + VideoUp = new VectorImage + { + Height = 24, + Width = 24, + Data = @"M711,212.3l47-47c41.7-47.6-25-112.2-72-71l-107,106c-3.3,3.3-6,7-8,11H454c-1.3-2.7-3.3-5-6-7l-112-111 + c-21.3-17.3-51-17-71,3s-20.3,49.7-3,71l45,44H198c-56.7,0-105,48.3-105,105v417c0,56.7,48.3,105,105,105h57 + c-17.9,49.6,19.9,105,73.5,105c55.4,0,90.4-55.3,74.5-105h218c-15.9,49.7,19.1,105,74.5,105c53.6,0,91.4-55.4,73.5-105h57 + c56.7,0,105-48.3,105-105v-417c0-57.6-48.3-104-105-104H711L711,212.3z", + Fill = "#FF000000" + }; + + Channel = new VectorImage + { + Height = 24, + Width = 24, + Data = @"M921.6 211.41 q1.1 -6.61 7.15 -10.47 q6.05 -3.85 12.66 -0.54 q38.54 19.82 60.56 56.16 + q22.02 36.33 22.02 80.38 l0 329.22 q-1.1 64.96 -44.6 108.46 q-43.5 43.5 -108.45 44.6 + l-483.37 0 q-44.04 0 -80.38 -22.02 q-36.34 -22.02 -56.15 -61.66 q-3.31 -5.51 0.54 -11.57 + q3.85 -6.05 10.47 -7.15 l557.14 0 q44.04 -1.1 72.67 -29.73 q28.63 -28.63 29.73 -72.67 + l0 -402.99 ZM102.4 0 l666.15 0 q41.84 0 71.57 29.73 q29.73 29.73 30.83 72.67 l0 461.35 + q-1.1 41.84 -30.83 71.57 q-29.73 29.73 -71.57 30.83 l-666.15 0 q-42.94 -1.1 -72.67 -30.83 + q-29.73 -29.73 -29.73 -71.57 l0 -461.35 q0 -42.94 29.73 -72.67 q29.73 -29.73 72.67 -29.73 + ZM559.35 353.45 q9.91 -7.71 9.91 -20.93 q0 -13.21 -9.91 -20.92 l-186.09 -129.92 q-13.21 -8.81 -26.42 -1.66 + q-13.21 7.16 -14.32 22.57 l0 259.85 q1.11 15.42 14.32 22.57 q13.21 7.16 26.42 -1.65 l186.09 -129.92 Z", + Fill = "#FF000000" + }; } public VectorImage Play { get; private set; } @@ -260,5 +287,8 @@ public VectorImage Subscription { get; private set; } public VectorImage ToView { get; private set; } public VectorImage History { get; private set; } + + public VectorImage VideoUp { get; private set; } + public VectorImage Channel { get; private set; } } } diff --git a/DownKyi/Languages/Default.xaml b/DownKyi/Languages/Default.xaml index 2362811..60c0bdb 100644 --- a/DownKyi/Languages/Default.xaml +++ b/DownKyi/Languages/Default.xaml @@ -51,6 +51,19 @@ 正常 封停 + + 个人空间 + 已关注 + 未关注 + 关注数 + 粉丝数 + 获赞数 + 播放数 + 阅读数 + 全部 + 投稿视频 + 频道 + 复制封面图片 复制封面URL diff --git a/DownKyi/Resources/channel.png b/DownKyi/Resources/channel.png new file mode 100644 index 0000000..9f532cb Binary files /dev/null and b/DownKyi/Resources/channel.png differ diff --git a/DownKyi/Resources/video-placeholder.png b/DownKyi/Resources/video-placeholder.png new file mode 100644 index 0000000..157a110 Binary files /dev/null and b/DownKyi/Resources/video-placeholder.png differ diff --git a/DownKyi/Themes/ColorBrush.xaml b/DownKyi/Themes/ColorBrush.xaml index 3d1c458..71ec9be 100644 --- a/DownKyi/Themes/ColorBrush.xaml +++ b/DownKyi/Themes/ColorBrush.xaml @@ -43,19 +43,21 @@ - - - + + + + + \ No newline at end of file diff --git a/DownKyi/Themes/Colors/ColorDefault.xaml b/DownKyi/Themes/Colors/ColorDefault.xaml index 1c38497..b02719f 100644 --- a/DownKyi/Themes/Colors/ColorDefault.xaml +++ b/DownKyi/Themes/Colors/ColorDefault.xaml @@ -43,19 +43,21 @@ #FF999999 #7F999999 - - #FFE4E4E4 - #FFF3CB85 + #99000000 #7FD0D0D0 #7FFFFFFF #7FD0D0D0 + #FFE4E4E4 + #FFF3CB85 + white black #FF999999 #FF757575 #FFFFAE00 + #FF02B5DA \ No newline at end of file diff --git a/DownKyi/ViewModels/UserSpace/Channel.cs b/DownKyi/ViewModels/UserSpace/Channel.cs new file mode 100644 index 0000000..af7c2f4 --- /dev/null +++ b/DownKyi/ViewModels/UserSpace/Channel.cs @@ -0,0 +1,39 @@ +using Prism.Mvvm; +using System.Windows.Media; + +namespace DownKyi.ViewModels.UserSpace +{ + public class Channel : BindableBase + { + public long Cid { get; set; } + + private ImageSource cover; + public ImageSource Cover + { + get => cover; + set => SetProperty(ref cover, value); + } + + private string name; + public string Name + { + get => name; + set => SetProperty(ref name, value); + } + + private int count; + public int Count + { + get => count; + set => SetProperty(ref count, value); + } + + private string ctime; + public string Ctime + { + get => ctime; + set => SetProperty(ref ctime, value); + } + + } +} diff --git a/DownKyi/ViewModels/UserSpace/PublicationZone.cs b/DownKyi/ViewModels/UserSpace/PublicationZone.cs new file mode 100644 index 0000000..fef0c79 --- /dev/null +++ b/DownKyi/ViewModels/UserSpace/PublicationZone.cs @@ -0,0 +1,31 @@ +using Prism.Mvvm; +using System.Windows.Media; + +namespace DownKyi.ViewModels.UserSpace +{ + public class PublicationZone : BindableBase + { + public int Tid { get; set; } + + private DrawingImage icon; + public DrawingImage Icon + { + get => icon; + set => SetProperty(ref icon, value); + } + + private string name; + public string Name + { + get => name; + set => SetProperty(ref name, value); + } + + private int count; + public int Count + { + get => count; + set => SetProperty(ref count, value); + } + } +} diff --git a/DownKyi/ViewModels/UserSpace/TabLeftBanner.cs b/DownKyi/ViewModels/UserSpace/TabLeftBanner.cs new file mode 100644 index 0000000..0754727 --- /dev/null +++ b/DownKyi/ViewModels/UserSpace/TabLeftBanner.cs @@ -0,0 +1,41 @@ +using DownKyi.Images; +using Prism.Mvvm; + +namespace DownKyi.ViewModels.UserSpace +{ + public class TabLeftBanner : BindableBase + { + public object Object { get; set; } + + public int Id { get; set; } + + private bool isSelected; + public bool IsSelected + { + get => isSelected; + set => SetProperty(ref isSelected, value); + } + + private VectorImage icon; + public VectorImage Icon + { + get => icon; + set => SetProperty(ref icon, value); + } + + private string iconColor; + public string IconColor + { + get => iconColor; + set => SetProperty(ref iconColor, value); + } + + private string title; + public string Title + { + get => title; + set => SetProperty(ref title, value); + } + + } +} diff --git a/DownKyi/ViewModels/UserSpace/TabRightBanner.cs b/DownKyi/ViewModels/UserSpace/TabRightBanner.cs new file mode 100644 index 0000000..f36a678 --- /dev/null +++ b/DownKyi/ViewModels/UserSpace/TabRightBanner.cs @@ -0,0 +1,43 @@ +using Prism.Mvvm; + +namespace DownKyi.ViewModels.UserSpace +{ + public class TabRightBanner : BindableBase + { + private bool isEnabled; + public bool IsEnabled + { + get => isEnabled; + set => SetProperty(ref isEnabled, value); + } + + private string labelColor; + public string LabelColor + { + get => labelColor; + set => SetProperty(ref labelColor, value); + } + + private string countColor; + public string CountColor + { + get => countColor; + set => SetProperty(ref countColor, value); + } + + private string label; + public string Label + { + get => label; + set => SetProperty(ref label, value); + } + + private string count; + public string Count + { + get => count; + set => SetProperty(ref count, value); + } + + } +} diff --git a/DownKyi/ViewModels/UserSpace/ViewArchiveViewModel.cs b/DownKyi/ViewModels/UserSpace/ViewArchiveViewModel.cs new file mode 100644 index 0000000..8f2cea5 --- /dev/null +++ b/DownKyi/ViewModels/UserSpace/ViewArchiveViewModel.cs @@ -0,0 +1,89 @@ +using DownKyi.Core.BiliApi.Users.Models; +using DownKyi.Core.BiliApi.Zone; +using DownKyi.Utils; +using Prism.Events; +using Prism.Regions; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Media; + +namespace DownKyi.ViewModels.UserSpace +{ + public class ViewArchiveViewModel : BaseViewModel + { + public const string Tag = "ArchiveView"; + + #region 页面属性申明 + + private ObservableCollection publicationZones; + public ObservableCollection PublicationZones + { + get => publicationZones; + set => SetProperty(ref publicationZones, value); + } + + #endregion + + public ViewArchiveViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + #region 属性初始化 + + PublicationZones = new ObservableCollection(); + + #endregion + } + + #region 命令申明 + #endregion + + public override void OnNavigatedFrom(NavigationContext navigationContext) + { + base.OnNavigatedFrom(navigationContext); + + PublicationZones.Clear(); + } + + /// + /// 接收mid参数 + /// + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + PublicationZones.Clear(); + + // 根据传入参数不同执行不同任务 + var parameter = navigationContext.Parameters.GetValue>("object"); + if (parameter == null) + { + return; + } + + int VideoCount = 0; + foreach (var zone in parameter) + { + VideoCount += zone.Count; + string iconKey = VideoZoneIcon.Instance().GetZoneImageKey(zone.Tid); + publicationZones.Add(new PublicationZone + { + Tid = zone.Tid, + Icon = (DrawingImage)Application.Current.Resources[iconKey], + Name = zone.Name, + Count = zone.Count + }); + } + + // 全部 + publicationZones.Insert(0, new PublicationZone + { + Tid = 0, + Icon = (DrawingImage)Application.Current.Resources["videoUpDrawingImage"], + Name = DictionaryResource.GetString("AllPublicationZones"), + Count = VideoCount + }); + + } + } +} diff --git a/DownKyi/ViewModels/UserSpace/ViewChannelViewModel.cs b/DownKyi/ViewModels/UserSpace/ViewChannelViewModel.cs new file mode 100644 index 0000000..88f2da9 --- /dev/null +++ b/DownKyi/ViewModels/UserSpace/ViewChannelViewModel.cs @@ -0,0 +1,101 @@ +using DownKyi.Core.BiliApi.Users.Models; +using DownKyi.Core.Storage; +using Prism.Events; +using Prism.Regions; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace DownKyi.ViewModels.UserSpace +{ + public class ViewChannelViewModel : BaseViewModel + { + public const string Tag = "Channel"; + + #region 页面属性申明 + + private ObservableCollection channels; + public ObservableCollection Channels + { + get => channels; + set => SetProperty(ref channels, value); + } + + #endregion + + public ViewChannelViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + { + #region 属性初始化 + + Channels = new ObservableCollection(); + + #endregion + } + + #region 命令申明 + #endregion + + public override void OnNavigatedFrom(NavigationContext navigationContext) + { + base.OnNavigatedFrom(navigationContext); + + Channels.Clear(); + } + + /// + /// 接收mid参数 + /// + /// + public async override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + Channels.Clear(); + + // 根据传入参数不同执行不同任务 + var parameter = navigationContext.Parameters.GetValue>("object"); + if (parameter == null) + { + return; + } + + foreach (var channel in parameter) + { + if (channel.Count <= 0) { continue; } + + BitmapImage image = null; + if (channel.Cover == null || channel.Cover == "") + { + image = new BitmapImage(new Uri($"pack://application:,,,/Resources/video-placeholder.png")); + } + else + { + StorageCover storageCover = new StorageCover(); + string cover = null; + await Task.Run(() => + { + cover = storageCover.GetCover(channel.Cover); + }); + image = storageCover.GetCoverThumbnail(cover, 190, 190); + } + + // 当地时区 + DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); + DateTime dateCTime = startTime.AddSeconds(channel.Mtime); + string mtime = dateCTime.ToString("yyyy-MM-dd"); + + Channels.Add(new Channel + { + Cid = channel.Cid, + Cover = image, + Name = channel.Name, + Count = channel.Count, + Ctime = mtime + }); + } + + } + } +} diff --git a/DownKyi/ViewModels/ViewMySpaceViewModel.cs b/DownKyi/ViewModels/ViewMySpaceViewModel.cs index 59c5022..82d2639 100644 --- a/DownKyi/ViewModels/ViewMySpaceViewModel.cs +++ b/DownKyi/ViewModels/ViewMySpaceViewModel.cs @@ -423,9 +423,8 @@ namespace DownKyi.ViewModels await Task.Run(() => { - // 背景图片 - SpaceSettings spaceSettings = UserSpace.GetSpaceSettings(mid); + SpaceSettings spaceSettings = Core.BiliApi.Users.UserSpace.GetSpaceSettings(mid); if (spaceSettings != null) { StorageCover storageCover = new StorageCover(); @@ -506,9 +505,9 @@ namespace DownKyi.ViewModels // 没有数据 isNoData = true; } - }); + // 是否获取到数据 if (isNoData) { TopNavigationBg = "#00FFFFFF"; // 透明 diff --git a/DownKyi/ViewModels/ViewUserSpaceViewModel.cs b/DownKyi/ViewModels/ViewUserSpaceViewModel.cs index 627d0f2..ba5b274 100644 --- a/DownKyi/ViewModels/ViewUserSpaceViewModel.cs +++ b/DownKyi/ViewModels/ViewUserSpaceViewModel.cs @@ -1,10 +1,21 @@ -using Prism.Commands; +using DownKyi.Core.BiliApi.Users; +using DownKyi.Core.BiliApi.Users.Models; +using DownKyi.Core.Storage; +using DownKyi.Core.Utils; +using DownKyi.CustomControl; +using DownKyi.Events; +using DownKyi.Images; +using DownKyi.Utils; +using DownKyi.ViewModels.UserSpace; +using Prism.Commands; using Prism.Events; -using Prism.Mvvm; using Prism.Regions; using System; using System.Collections.Generic; -using System.Linq; +using System.Collections.ObjectModel; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media.Imaging; namespace DownKyi.ViewModels { @@ -12,11 +23,460 @@ namespace DownKyi.ViewModels { public const string Tag = "PageUserSpace"; + private readonly IRegionManager regionManager; + // mid - private long mid; + private long mid = -1; + + #region 页面属性申明 + + private VectorImage arrowBack; + public VectorImage ArrowBack + { + get => arrowBack; + set => SetProperty(ref arrowBack, value); + } + + private GifImage loading; + public GifImage Loading + { + get => loading; + set => SetProperty(ref loading, value); + } + + private Visibility noDataVisibility; + public Visibility NoDataVisibility + { + get => noDataVisibility; + set => SetProperty(ref noDataVisibility, value); + } + + private Visibility loadingVisibility; + public Visibility LoadingVisibility + { + get => loadingVisibility; + set => SetProperty(ref loadingVisibility, value); + } + + private Visibility viewVisibility; + public Visibility ViewVisibility + { + get => viewVisibility; + set => SetProperty(ref viewVisibility, value); + } + + private Visibility contentVisibility; + public Visibility ContentVisibility + { + get => contentVisibility; + set => SetProperty(ref contentVisibility, value); + } + + private string topNavigationBg; + public string TopNavigationBg + { + get => topNavigationBg; + set => SetProperty(ref topNavigationBg, value); + } + + private BitmapImage background; + public BitmapImage Background + { + get => background; + set => SetProperty(ref background, value); + } + + private BitmapImage header; + public BitmapImage Header + { + get => header; + set => SetProperty(ref header, value); + } + + private string userName; + public string UserName + { + get => userName; + set => SetProperty(ref userName, value); + } + + private BitmapImage sex; + public BitmapImage Sex + { + get => sex; + set => SetProperty(ref sex, value); + } + + private BitmapImage level; + public BitmapImage Level + { + get => level; + set => SetProperty(ref level, value); + } + + private Visibility vipTypeVisibility; + public Visibility VipTypeVisibility + { + get => vipTypeVisibility; + set => SetProperty(ref vipTypeVisibility, value); + } + + private string vipType; + public string VipType + { + get => vipType; + set => SetProperty(ref vipType, value); + } + + private string sign; + public string Sign + { + get => sign; + set => SetProperty(ref sign, value); + } + + private string isFollowed; + public string IsFollowed + { + get => isFollowed; + set => SetProperty(ref isFollowed, value); + } + + private ObservableCollection tabLeftBanners; + public ObservableCollection TabLeftBanners + { + get => tabLeftBanners; + set => SetProperty(ref tabLeftBanners, value); + } + + private ObservableCollection tabRightBanners; + public ObservableCollection TabRightBanners + { + get => tabRightBanners; + set => SetProperty(ref tabRightBanners, value); + } + + #endregion + + public ViewUserSpaceViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) : base(eventAggregator) + { + this.regionManager = regionManager; + + #region 属性初始化 + + // 返回按钮 + ArrowBack = NavigationIcon.Instance().ArrowBack; + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + + // 初始化loading gif + Loading = new GifImage(Properties.Resources.loading); + Loading.StartAnimate(); + + TopNavigationBg = "#00FFFFFF"; // 透明 + + TabLeftBanners = new ObservableCollection(); + TabRightBanners = new ObservableCollection(); + + #endregion + } + + #region 命令申明 - public ViewUserSpaceViewModel(IEventAggregator eventAggregator) : base(eventAggregator) + // 返回事件 + private DelegateCommand backSpaceCommand; + public DelegateCommand BackSpaceCommand => backSpaceCommand ?? (backSpaceCommand = new DelegateCommand(ExecuteBackSpace)); + + /// + /// 返回事件 + /// + private void ExecuteBackSpace() + { + NavigationParam parameter = new NavigationParam + { + ViewName = ParentView, + ParentViewName = null, + Parameter = null + }; + eventAggregator.GetEvent().Publish(parameter); + } + + + // 左侧tab点击事件 + private DelegateCommand tabLeftBannersCommand; + public DelegateCommand TabLeftBannersCommand => tabLeftBannersCommand ?? (tabLeftBannersCommand = new DelegateCommand(ExecuteTabLeftBannersCommand)); + + /// + /// 左侧tab点击事件 + /// + /// + private void ExecuteTabLeftBannersCommand(object parameter) + { + if (!(parameter is TabLeftBanner banner)) { return; } + + NavigationParameters param = new NavigationParameters() + { + { "object", banner.Object }, + }; + + switch (banner.Id) + { + case 0: + regionManager.RequestNavigate("UserSpaceContentRegion", ViewArchiveViewModel.Tag, param); + break; + case 1: + regionManager.RequestNavigate("UserSpaceContentRegion", ViewChannelViewModel.Tag, param); + break; + } + } + + #endregion + + /// + /// 初始化页面 + /// + private void InitView() { + TopNavigationBg = "#00FFFFFF"; // 透明 + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + Background = null; + + Header = null; + UserName = ""; + Sex = null; + Level = null; + VipTypeVisibility = Visibility.Collapsed; + VipType = ""; + Sign = ""; + + TabLeftBanners.Clear(); + TabRightBanners.Clear(); + + // 将内容置空,使其不指向任何页面 + regionManager.RequestNavigate("UserSpaceContentRegion", ""); + + ContentVisibility = Visibility.Collapsed; + ViewVisibility = Visibility.Collapsed; + LoadingVisibility = Visibility.Visible; + NoDataVisibility = Visibility.Collapsed; + } + + /// + /// 更新用户信息 + /// + private async void UpdateSpaceInfo() + { + bool isNoData = true; + Uri toutuUri = null; + string headerUri = null; + Uri sexUri = null; + Uri levelUri = null; + + await Task.Run(() => + { + // 背景图片 + SpaceSettings spaceSettings = Core.BiliApi.Users.UserSpace.GetSpaceSettings(mid); + if (spaceSettings != null) + { + StorageCover storageCover = new StorageCover(); + string toutu = storageCover.GetCover($"https://i0.hdslb.com/{spaceSettings.Toutu.Limg}"); + toutuUri = new Uri(toutu); + } + else + { + toutuUri = new Uri("pack://application:,,,/Resources/backgound/9-绿荫秘境.png"); + } + + // 用户信息 + UserInfoForSpace userInfo = UserInfo.GetUserInfoForSpace(mid); + if (userInfo != null) + { + isNoData = false; + + // 头像 + StorageHeader storageHeader = new StorageHeader(); + headerUri = storageHeader.GetHeader(mid, userInfo.Name, userInfo.Face); + // 用户名 + UserName = userInfo.Name; + // 性别 + if (userInfo.Sex == "男") + { + sexUri = new Uri($"pack://application:,,,/Resources/sex/male.png"); + } + else if (userInfo.Sex == "女") + { + sexUri = new Uri($"pack://application:,,,/Resources/sex/female.png"); + } + // 显示vip信息 + if (userInfo.Vip.Label.Text == null || userInfo.Vip.Label.Text == "") + { + VipTypeVisibility = Visibility.Collapsed; + } + else + { + VipTypeVisibility = Visibility.Visible; + VipType = userInfo.Vip.Label.Text; + } + // 等级 + levelUri = new Uri($"pack://application:,,,/Resources/level/lv{userInfo.Level}.png"); + // 签名 + Sign = userInfo.Sign; + + // 是否关注此UP + IsFollowed = userInfo.IsFollowed ? + DictionaryResource.GetString("Followed") : DictionaryResource.GetString("NotFollowed"); + } + else + { + // 没有数据 + isNoData = true; + } + }); + + // 是否获取到数据 + if (isNoData) + { + TopNavigationBg = "#00FFFFFF"; // 透明 + ArrowBack.Fill = DictionaryResource.GetColor("ColorTextDark"); + Background = null; + + ViewVisibility = Visibility.Collapsed; + LoadingVisibility = Visibility.Collapsed; + NoDataVisibility = Visibility.Visible; + return; + } + else + { + // 头像 + StorageHeader storageHeader = new StorageHeader(); + Header = storageHeader.GetHeaderThumbnail(headerUri, 64, 64); + // 性别 + Sex = sexUri == null ? null : new BitmapImage(sexUri); + // 等级 + Level = new BitmapImage(levelUri); + + ArrowBack.Fill = DictionaryResource.GetColor("ColorText"); + TopNavigationBg = DictionaryResource.GetColor("ColorMask100"); + Background = new BitmapImage(toutuUri); + + ViewVisibility = Visibility.Visible; + LoadingVisibility = Visibility.Collapsed; + NoDataVisibility = Visibility.Collapsed; + } + + ContentVisibility = Visibility.Visible; + + // 投稿视频 + List publicationTypes = null; + await Task.Run(() => + { + publicationTypes = Core.BiliApi.Users.UserSpace.GetPublicationType(mid); + }); + if (publicationTypes != null && publicationTypes.Count > 0) + { + TabLeftBanners.Add(new TabLeftBanner + { + Object = publicationTypes, + Id = 0, + Icon = NormalIcon.Instance().VideoUp, + IconColor = "#FF02B5DA", + Title = DictionaryResource.GetString("Publication"), + IsSelected = true + }); + } + + // 频道 + List channelList = null; + await Task.Run(() => + { + channelList = Core.BiliApi.Users.UserSpace.GetChannelList(mid); + }); + if (channelList != null && channelList.Count > 0) + { + TabLeftBanners.Add(new TabLeftBanner + { + Object = channelList, + Id = 1, + Icon = NormalIcon.Instance().Channel, + IconColor = "#FF23C9ED", + Title = DictionaryResource.GetString("Channel") + }); + } + + // 收藏夹 + // 订阅 + + // 关系状态数 + UserRelationStat relationStat = null; + await Task.Run(() => + { + relationStat = UserStatus.GetUserRelationStat(mid); + }); + if (relationStat != null) + { + TabRightBanners.Add(new TabRightBanner + { + IsEnabled = true, + LabelColor = DictionaryResource.GetColor("ColorPrimary"), + CountColor = DictionaryResource.GetColor("ColorPrimary"), + Label = DictionaryResource.GetString("FollowingCount"), + Count = Format.FormatNumber(relationStat.Following) + }); + TabRightBanners.Add(new TabRightBanner + { + IsEnabled = true, + LabelColor = DictionaryResource.GetColor("ColorPrimary"), + CountColor = DictionaryResource.GetColor("ColorPrimary"), + Label = DictionaryResource.GetString("FollowerCount"), + Count = Format.FormatNumber(relationStat.Follower) + }); + } + + // UP主状态数,需要任意用户登录,否则不会返回任何数据 + UpStat upStat = null; + await Task.Run(() => + { + upStat = UserStatus.GetUpStat(mid); + }); + if (upStat != null && upStat.Archive != null && upStat.Article != null) + { + TabRightBanners.Add(new TabRightBanner + { + IsEnabled = false, + LabelColor = DictionaryResource.GetColor("ColorTextGrey"), + CountColor = DictionaryResource.GetColor("ColorTextDark"), + Label = DictionaryResource.GetString("LikesCount"), + Count = Format.FormatNumber(upStat.Likes) + }); + + long archiveView = 0; + if (upStat.Archive != null) + { + archiveView = upStat.Archive.View; + } + TabRightBanners.Add(new TabRightBanner + { + IsEnabled = false, + LabelColor = DictionaryResource.GetColor("ColorTextGrey"), + CountColor = DictionaryResource.GetColor("ColorTextDark"), + Label = DictionaryResource.GetString("ArchiveViewCount"), + Count = Format.FormatNumber(archiveView) + }); + + long articleView = 0; + if (upStat.Article != null) + { + articleView = upStat.Article.View; + } + TabRightBanners.Add(new TabRightBanner + { + IsEnabled = false, + LabelColor = DictionaryResource.GetColor("ColorTextGrey"), + CountColor = DictionaryResource.GetColor("ColorTextDark"), + Label = DictionaryResource.GetString("ArticleViewCount"), + Count = Format.FormatNumber(articleView) + }); + } + } /// @@ -34,6 +494,9 @@ namespace DownKyi.ViewModels return; } mid = parameter; + + InitView(); + UpdateSpaceInfo(); } } diff --git a/DownKyi/Views/UserSpace/ViewArchive.xaml b/DownKyi/Views/UserSpace/ViewArchive.xaml new file mode 100644 index 0000000..9faa88b --- /dev/null +++ b/DownKyi/Views/UserSpace/ViewArchive.xaml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/UserSpace/ViewArchive.xaml.cs b/DownKyi/Views/UserSpace/ViewArchive.xaml.cs new file mode 100644 index 0000000..530bf57 --- /dev/null +++ b/DownKyi/Views/UserSpace/ViewArchive.xaml.cs @@ -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.UserSpace +{ + /// + /// ViewArchive.xaml 的交互逻辑 + /// + public partial class ViewArchive : UserControl + { + public ViewArchive() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/UserSpace/ViewChannel.xaml b/DownKyi/Views/UserSpace/ViewChannel.xaml new file mode 100644 index 0000000..71fac21 --- /dev/null +++ b/DownKyi/Views/UserSpace/ViewChannel.xaml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/Views/UserSpace/ViewChannel.xaml.cs b/DownKyi/Views/UserSpace/ViewChannel.xaml.cs new file mode 100644 index 0000000..4077907 --- /dev/null +++ b/DownKyi/Views/UserSpace/ViewChannel.xaml.cs @@ -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.UserSpace +{ + /// + /// ViewChannel.xaml 的交互逻辑 + /// + public partial class ViewChannel : UserControl + { + public ViewChannel() + { + InitializeComponent(); + } + } +} diff --git a/DownKyi/Views/ViewUserSpace.xaml b/DownKyi/Views/ViewUserSpace.xaml index 7b6477c..9bdb814 100644 --- a/DownKyi/Views/ViewUserSpace.xaml +++ b/DownKyi/Views/ViewUserSpace.xaml @@ -2,9 +2,362 @@ x:Class="DownKyi.Views.ViewUserSpace" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"> + + + + + + + + + - 用户空间 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DownKyi/ffmpeg.exe b/DownKyi/ffmpeg.exe index 473a761..3284f06 100644 Binary files a/DownKyi/ffmpeg.exe and b/DownKyi/ffmpeg.exe differ