diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f9fefc26..87d17dd2 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -116,6 +116,14 @@ jobs:
run: cp C:\Package\安装教程.pdf ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_x64_Test\安装教程.pdf
if: github.event.inputs.enableX64 == 'true'
+ - name: Remove x64 useless files
+ run: |
+ cd ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_x64_Test
+ rm -r -fo *.appxsym
+ cd Dependencies
+ rm -r -fo arm,arm64,x86
+ if: github.event.inputs.enableX64 == 'true'
+
- name: Create x64 archive
run: Compress-Archive -Path ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_x64_Test -DestinationPath C:\Package\${{env.AppName}}_${{github.event.inputs.version}}_x64.zip
if: github.event.inputs.enableX64 == 'true'
@@ -143,6 +151,14 @@ jobs:
run: cp C:\Package\安装教程.pdf ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_x86_Test\安装教程.pdf
if: github.event.inputs.enableX86 == 'true'
+ - name: Remove x86 useless files
+ run: |
+ cd ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_x86_Test
+ rm -r -fo *.appxsym
+ cd Dependencies
+ rm -r -fo arm,arm64,x64
+ if: github.event.inputs.enableX86 == 'true'
+
- name: Create x86 archive
run: Compress-Archive -Path ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_x86_Test -DestinationPath C:\Package\${{env.AppName}}_${{github.event.inputs.version}}_x86.zip
if: github.event.inputs.enableX86 == 'true'
@@ -170,6 +186,14 @@ jobs:
run: cp C:\Package\安装教程.pdf ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_ARM64_Test\安装教程.pdf
if: github.event.inputs.enableArm64 == 'true'
+ - name: Remove arm64 useless files
+ run: |
+ cd ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_ARM64_Test
+ rm -r -fo *.appxsym
+ cd Dependencies
+ rm -r -fo arm,x64,x86
+ if: github.event.inputs.enableArm64 == 'true'
+
- name: Create ARM64 archive
run: Compress-Archive -Path ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_ARM64_Test -DestinationPath C:\Package\${{env.AppName}}_${{github.event.inputs.version}}_ARM64.zip
if: github.event.inputs.enableArm64 == 'true'
@@ -197,6 +221,14 @@ jobs:
run: cp C:\Package\安装教程.pdf ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_ARM_Test\安装教程.pdf
if: github.event.inputs.enableArm32 == 'true'
+ - name: Remove arm32 useless files
+ run: |
+ cd ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_ARM_Test
+ rm -r -fo *.appxsym
+ cd Dependencies
+ rm -r -fo arm64,x64,x86
+ if: github.event.inputs.enableArm32 == 'true'
+
- name: Create ARM32 archive
run: Compress-Archive -Path ${{env.UWP_Project_Directory}}\AppPackages\${{env.AppName}}_${{github.event.inputs.version}}_ARM_Test -DestinationPath C:\Package\${{env.AppName}}_${{github.event.inputs.version}}_ARM.zip
if: github.event.inputs.enableArm32 == 'true'
diff --git a/src/BiliLite.Packages/Package.appxmanifest b/src/BiliLite.Packages/Package.appxmanifest
index 53e3f790..3b9a830e 100644
--- a/src/BiliLite.Packages/Package.appxmanifest
+++ b/src/BiliLite.Packages/Package.appxmanifest
@@ -48,7 +48,7 @@
-
+
diff --git a/src/BiliLite.UWP/App.xaml.cs b/src/BiliLite.UWP/App.xaml.cs
index b389d704..3f674121 100644
--- a/src/BiliLite.UWP/App.xaml.cs
+++ b/src/BiliLite.UWP/App.xaml.cs
@@ -61,8 +61,16 @@ private void SynchronizationContext_UnhandledException(object sender, AysncUnhan
e.Handled = true;
try
{
- logger.Log("程序运行出现错误", LogType.Error, e.Exception);
- Notify.ShowMessageToast("程序出现一个错误,已记录");
+ if (e.Exception is NotImplementedException)
+ {
+ logger.Log("功能未实现", LogType.Error, e.Exception);
+ Notify.ShowMessageToast("功能未实现");
+ }
+ else
+ {
+ logger.Log("程序运行出现错误", LogType.Error, e.Exception);
+ Notify.ShowMessageToast("程序出现一个错误,已记录");
+ }
}
catch (Exception)
{
@@ -73,8 +81,16 @@ private void App_UnhandledException(object sender, Windows.UI.Xaml.UnhandledExce
e.Handled = true;
try
{
- logger.Log("程序运行出现错误", LogType.Error, e.Exception);
- Notify.ShowMessageToast("程序出现一个错误,已记录");
+ if (e.Exception is NotImplementedException)
+ {
+ logger.Log("功能未实现", LogType.Error, e.Exception);
+ Notify.ShowMessageToast("功能未实现");
+ }
+ else
+ {
+ logger.Log("程序运行出现错误", LogType.Error, e.Exception);
+ Notify.ShowMessageToast("程序出现一个错误,已记录");
+ }
}
catch (Exception)
{
diff --git a/src/BiliLite.UWP/BiliLite.UWP.csproj b/src/BiliLite.UWP/BiliLite.UWP.csproj
index fed18a0c..0e940315 100644
--- a/src/BiliLite.UWP/BiliLite.UWP.csproj
+++ b/src/BiliLite.UWP/BiliLite.UWP.csproj
@@ -139,13 +139,29 @@
AttentionButton.xaml
+
+
+ DynamicItemV2Control.xaml
+
UserFollowingTagsFlyout.xaml
+
+ SendDynamicV2Dialog.xaml
+
+
+
+
+
+
+
+
+
+
@@ -194,6 +210,12 @@
+
+ DynamicSpacePage.xaml
+
+
+
+
@@ -602,7 +624,7 @@
-
+
@@ -634,7 +656,7 @@
-
+
@@ -646,8 +668,8 @@
-
-
+
+
@@ -928,10 +950,26 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
Designer
MSBuild:Compile
+
+ MSBuild:Compile
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -1311,6 +1349,7 @@
+
diff --git a/src/BiliLite.UWP/Controls/CommentControl.xaml b/src/BiliLite.UWP/Controls/CommentControl.xaml
index a2e29bce..abd64332 100644
--- a/src/BiliLite.UWP/Controls/CommentControl.xaml
+++ b/src/BiliLite.UWP/Controls/CommentControl.xaml
@@ -11,6 +11,7 @@
xmlns:convert="using:BiliLite.Converters" xmlns:modules="using:BiliLite.Modules"
xmlns:comment="using:BiliLite.ViewModels.Comment"
xmlns:common="using:BiliLite.Models.Common"
+ xmlns:viewModels="using:BiliLite.ViewModels"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="CommentControlContent"
@@ -30,13 +31,20 @@
+
+
-
+
@@ -185,11 +193,18 @@
-
+
-
+
@@ -204,6 +219,7 @@
+
@@ -268,8 +284,6 @@
UP主觉得很赞
-
-
@@ -388,6 +402,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Controls/CommentControl.xaml.cs b/src/BiliLite.UWP/Controls/CommentControl.xaml.cs
index 881e5fae..317aeaa6 100644
--- a/src/BiliLite.UWP/Controls/CommentControl.xaml.cs
+++ b/src/BiliLite.UWP/Controls/CommentControl.xaml.cs
@@ -16,6 +16,7 @@
using BiliLite.Models.Exceptions;
using BiliLite.Models.Requests.Api;
using BiliLite.Services;
+using BiliLite.ViewModels;
using BiliLite.ViewModels.Comment;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Toolkit.Uwp.UI.Controls;
@@ -30,7 +31,7 @@ public sealed partial class CommentControl : UserControl
#region Fields
private readonly CommentApi m_commentApi;
- EmoteVM emoteVM;
+ EmoteViewModel emoteVM;
private bool m_disableShowPicture = false;
private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
private CommentCursor m_nextCursor;
@@ -50,10 +51,10 @@ public CommentControl()
{
m_mapper = App.ServiceProvider.GetService();
m_viewModel = App.ServiceProvider.GetService();
+ emoteVM = App.ServiceProvider.GetService();
DataContext = m_viewModel;
this.InitializeComponent();
m_commentApi = new CommentApi();
- emoteVM = new EmoteVM();
Unloaded += CommentControl_Unloaded;
}
@@ -104,6 +105,7 @@ private async Task GetComment()
result = await m_commentApi.CommentV2(m_loadCommentInfo.Oid, m_loadCommentInfo.CommentSort, m_page,
m_loadCommentInfo.CommentMode, offsetStr: m_nextCursor?.PaginationReply?.NextOffset).Request();
}
+
if (!result.status)
{
throw new CustomizedErrorException("加载评论失败");
diff --git a/src/BiliLite.UWP/Controls/DataTemplateSelectors/UserDynamicItemV2DataTemplateSelector.cs b/src/BiliLite.UWP/Controls/DataTemplateSelectors/UserDynamicItemV2DataTemplateSelector.cs
new file mode 100644
index 00000000..54f8981a
--- /dev/null
+++ b/src/BiliLite.UWP/Controls/DataTemplateSelectors/UserDynamicItemV2DataTemplateSelector.cs
@@ -0,0 +1,75 @@
+using BiliLite.Models.Common;
+using BiliLite.ViewModels.UserDynamic;
+using System;
+using System.Collections.Generic;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace BiliLite.Controls.DataTemplateSelectors
+{
+ public class UserDynamicItemV2DataTemplateSelector : DataTemplateSelector
+ {
+ private static readonly Dictionary> _dynamicTypeTemplateSelectFuncs;
+
+ static UserDynamicItemV2DataTemplateSelector()
+ {
+ DataTemplate SelectRowTemplate(UserDynamicItemDataTemplateSelector selector,
+ UserDynamicItemDisplayViewModel _) => selector.OneRowTemplate;
+
+ _dynamicTypeTemplateSelectFuncs =
+ new Dictionary>()
+ {
+ {
+ Constants.DynamicTypes.DRAW, (selector, model) =>
+ {
+ if (model.Dynamic.DynDraw.Items.Count == 1)
+ {
+ return selector.Draw1x1Template;
+ }
+ return model.Dynamic.DynDraw.Items.Count == 4 ? selector.Draw2x2Template : selector.Draw3x3Template;
+ }
+ },
+ { Constants.DynamicTypes.ARTICLE, (selector, model) => selector.ArticleTemplate },
+ { Constants.DynamicTypes.FORWARD, (selector, model) => selector.ForwardTemplate },
+ { Constants.DynamicTypes.AV, (selector, model) => selector.AvTemplate },
+ { Constants.DynamicTypes.PGC, (selector, model) => selector.PgcTemplate },
+ { Constants.DynamicTypes.WORD, (selector, model) => selector.WordTemplate },
+ { Constants.DynamicTypes.MUSIC, (selector, model) => selector.MusicTemplate },
+ { Constants.DynamicTypes.COMMON_SQUARE, (selector, model) => selector.CommonSquareTemplate },
+ { Constants.DynamicTypes.LIVE_RCMD, (selector, model) => selector.LiveRcmdTemplate },
+ };
+ }
+
+ public DataTemplate AvTemplate { get; set; }
+
+ public DataTemplate PgcTemplate { get; set; }
+
+ public DataTemplate ArticleTemplate { get; set; }
+
+ public DataTemplate WordTemplate { get; set; }
+
+ public DataTemplate MusicTemplate { get; set; }
+
+ public DataTemplate ForwardTemplate { get; set; }
+
+ public DataTemplate Draw1x1Template { get; set; }
+
+ public DataTemplate Draw2x2Template { get; set; }
+
+ public DataTemplate Draw3x3Template { get; set; }
+
+ public DataTemplate CommonSquareTemplate { get; set; }
+
+ public DataTemplate LiveRcmdTemplate { get; set; }
+
+ public DataTemplate OtherTemplate { get; set; }
+
+ protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
+ {
+ var model = item as DynamicV2ItemViewModel;
+ var success = _dynamicTypeTemplateSelectFuncs.TryGetValue(model.CardType, out var selectFunc);
+ return success ? selectFunc(this, model) : OtherTemplate;
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml b/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml
new file mode 100644
index 00000000..b638f5ad
--- /dev/null
+++ b/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml.cs b/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml.cs
new file mode 100644
index 00000000..abc86117
--- /dev/null
+++ b/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml.cs
@@ -0,0 +1,34 @@
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using BiliLite.ViewModels.UserDynamic;
+
+// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
+
+namespace BiliLite.Controls.Dynamic
+{
+ public sealed partial class DynamicItemV2Control : UserControl
+ {
+ public DynamicItemV2Control()
+ {
+ this.InitializeComponent();
+ }
+
+ public FrameworkElement CardContent
+ {
+ get => (FrameworkElement)GetValue(CardContentProperty);
+ set => SetValue(CardContentProperty, value);
+ }
+
+ public static readonly DependencyProperty CardContentProperty =
+ DependencyProperty.Register(nameof(CardContent), typeof(FrameworkElement), typeof(DynamicItemV2Control), new PropertyMetadata(null));
+
+ public DynamicV2ItemViewModel ViewModel
+ {
+ get => (DynamicV2ItemViewModel)GetValue(ViewModelProperty);
+ set => SetValue(ViewModelProperty, value);
+ }
+
+ public static readonly DependencyProperty ViewModelProperty =
+ DependencyProperty.Register(nameof(ViewModel), typeof(DynamicV2ItemViewModel), typeof(DynamicItemV2Control), new PropertyMetadata(null));
+ }
+}
diff --git a/src/BiliLite.UWP/Controls/Dynamic/DynamicV2Template.xaml b/src/BiliLite.UWP/Controls/Dynamic/DynamicV2Template.xaml
new file mode 100644
index 00000000..f94488e4
--- /dev/null
+++ b/src/BiliLite.UWP/Controls/Dynamic/DynamicV2Template.xaml
@@ -0,0 +1,349 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 长图
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 无法显示此动态,请点击以下按钮复制内容给开发者适配
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Converters/CountOrTextConvert.cs b/src/BiliLite.UWP/Converters/CountOrTextConvert.cs
index 5f56268a..10a05b80 100644
--- a/src/BiliLite.UWP/Converters/CountOrTextConvert.cs
+++ b/src/BiliLite.UWP/Converters/CountOrTextConvert.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace BiliLite.Converters
@@ -15,6 +11,11 @@ public object Convert(object value, Type targetType, object parameter, string la
{
return "";
}
+
+ if (value is string valueStr)
+ {
+ value = long.Parse(valueStr);
+ }
if (value is int || value is long)
{
var number = System.Convert.ToDouble(value);
diff --git a/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml b/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml
index 013f6060..b6777381 100644
--- a/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml
+++ b/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml
@@ -8,6 +8,7 @@
mc:Ignorable="d"
Title="发表评论"
xmlns:modules="using:BiliLite.Modules"
+ xmlns:viewModels="using:BiliLite.ViewModels"
PrimaryButtonText="发送"
SecondaryButtonText="取消"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
@@ -17,7 +18,7 @@
-
+
diff --git a/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml.cs b/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml.cs
index 6a2ff243..de6bc867 100644
--- a/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml.cs
+++ b/src/BiliLite.UWP/Dialogs/SendCommentDialog.xaml.cs
@@ -1,10 +1,11 @@
using BiliLite.Models.Requests.Api;
-using BiliLite.Modules;
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using BiliLite.Extensions;
+using BiliLite.ViewModels;
using static BiliLite.Models.Requests.Api.CommentApi;
+using Microsoft.Extensions.DependencyInjection;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“内容对话框”项模板
@@ -13,14 +14,14 @@ namespace BiliLite.Dialogs
public sealed partial class SendCommentDialog : ContentDialog
{
readonly CommentApi commentApi;
- readonly EmoteVM emoteVM;
+ readonly EmoteViewModel emoteVM;
readonly string oid;
readonly CommentType commentType;
public SendCommentDialog(string oid, CommentType commentType)
{
+ emoteVM = App.ServiceProvider.GetService();
this.InitializeComponent();
commentApi = new CommentApi();
- emoteVM = new EmoteVM();
this.oid = oid;
this.commentType = commentType;
}
diff --git a/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml b/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml
index c968ab61..afb35b13 100644
--- a/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml
+++ b/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml
@@ -6,13 +6,14 @@
xmlns:modules="using:BiliLite.Modules"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:viewModels="using:BiliLite.ViewModels"
mc:Ignorable="d">
-
+
@@ -30,7 +31,7 @@
-
+
@@ -99,13 +100,25 @@
- 转发动态
- 发表动态
+ 转发动态
+ 发表动态
-
- @
-
+
+
+ @
+
+
+
@@ -121,7 +134,7 @@
-->
-
-
+
图片上传中...
-
- /9张图片
-
+
+ /9张图片
+
-
+
diff --git a/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml.cs b/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml.cs
index ac621a3e..a00855f6 100644
--- a/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml.cs
+++ b/src/BiliLite.UWP/Dialogs/SendDynamicDialog.xaml.cs
@@ -1,12 +1,12 @@
using BiliLite.Extensions;
using BiliLite.Models.Requests.Api;
-using BiliLite.Modules;
-using BiliLite.Modules.User;
-using BiliLite.Modules.User.SendDynamic;
using System;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
+using BiliLite.Models.Common.User.SendDynamic;
+using BiliLite.ViewModels;
+using BiliLite.ViewModels.User.SendDynamic;
using BiliLite.ViewModels.UserDynamic;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“内容对话框”项模板
@@ -15,25 +15,22 @@ namespace BiliLite.Dialogs
{
public sealed partial class SendDynamicDialog : ContentDialog
{
- readonly EmoteVM emoteVM;
- readonly AtVM atVM;
- readonly SendDynamicVM sendDynamicVM;
- readonly TopicVM topicVM;
- public SendDynamicDialog()
+ readonly EmoteViewModel emoteVM;
+ readonly AtViewModel atVM;
+ readonly SendDynamicViewModel m_viewModel;
+ readonly TopicViewModel topicVM;
+ public SendDynamicDialog(SendDynamicViewModel sendDynamicViewModel, EmoteViewModel emoteViewModel, AtViewModel atViewModel, TopicViewModel topicVm)
{
+ m_viewModel = sendDynamicViewModel;
+ emoteVM = emoteViewModel;
+ atVM = atViewModel;
+ topicVM = topicVm;
this.InitializeComponent();
- emoteVM = new EmoteVM();
- atVM = new AtVM();
- sendDynamicVM = new SendDynamicVM();
- topicVM = new TopicVM();
}
- public SendDynamicDialog(UserDynamicItemDisplayViewModel userDynamicItem)
+
+ public void SetRepost(UserDynamicItemDisplayViewModel userDynamicItem)
{
- this.InitializeComponent();
- emoteVM = new EmoteVM();
- atVM = new AtVM();
- topicVM = new TopicVM();
- sendDynamicVM = new SendDynamicVM(userDynamicItem);
+ m_viewModel.SetRepost(userDynamicItem);
}
private void btn_Close_Click(object sender, RoutedEventArgs e)
@@ -72,12 +69,12 @@ private void listAt_ItemClick(object sender, ItemClickEventArgs e)
var at = "[@" + data.UserName + "]";
txtContent.Text += at;
- sendDynamicVM.AtDisplaylist.Add(new AtDisplayModel()
+ m_viewModel.AddAtItem(new AtDisplayModel()
{
- data = data.ID,
- text = at,
- location = location,
- length = at.Length
+ Data = data.ID,
+ Text = at,
+ Location = location,
+ Length = at.Length
});
}
@@ -113,13 +110,13 @@ private void TextTopic_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuery
private void btn_RemovePic_Click(object sender, RoutedEventArgs e)
{
- sendDynamicVM.Images.Remove((sender as Button).DataContext as UploadImagesModel);
- sendDynamicVM.ShowImage = gv_Pics.Items.Count > 0;
+ m_viewModel.Images.Remove((sender as Button).DataContext as UploadImagesModel);
+ m_viewModel.ShowImage = gv_Pics.Items.Count > 0;
}
private async void btnImage_Click(object sender, RoutedEventArgs e)
{
- if (sendDynamicVM.Images.Count == 9)
+ if (m_viewModel.Images.Count == 9)
{
Notify.ShowMessageToast("只能上传9张图片哦");
return;
@@ -135,22 +132,22 @@ private async void btnImage_Click(object sender, RoutedEventArgs e)
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
- sendDynamicVM.UploadImage(file);
+ m_viewModel.UploadImage(file);
}
}
private async void btnSend_Click(object sender, RoutedEventArgs e)
{
- sendDynamicVM.Content = txtContent.Text;
+ m_viewModel.Content = txtContent.Text;
bool result = false;
btnSend.IsEnabled = false;
- if (sendDynamicVM.IsRepost)
+ if (m_viewModel.IsRepost)
{
- result = await sendDynamicVM.SendRepost();
+ result = await m_viewModel.SendRepost();
}
else
{
- result = await sendDynamicVM.SendDynamic();
+ result = await m_viewModel.SendDynamic();
}
if (result)
{
diff --git a/src/BiliLite.UWP/Dialogs/SendDynamicV2Dialog.xaml b/src/BiliLite.UWP/Dialogs/SendDynamicV2Dialog.xaml
new file mode 100644
index 00000000..ab138b78
--- /dev/null
+++ b/src/BiliLite.UWP/Dialogs/SendDynamicV2Dialog.xaml
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载更多
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 转发动态
+ 发表动态
+
+
+
+
+ @
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 233
+ 取消
+ 发表
+
+
+
+
+ 图片上传中...
+
+
+
+ /9张图片
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Dialogs/SendDynamicV2Dialog.xaml.cs b/src/BiliLite.UWP/Dialogs/SendDynamicV2Dialog.xaml.cs
new file mode 100644
index 00000000..0073e874
--- /dev/null
+++ b/src/BiliLite.UWP/Dialogs/SendDynamicV2Dialog.xaml.cs
@@ -0,0 +1,164 @@
+using BiliLite.Extensions;
+using BiliLite.Models.Requests.Api;
+using System;
+using Windows.Storage.Pickers;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using BiliLite.Models.Common.User.SendDynamic;
+using BiliLite.ViewModels;
+using BiliLite.ViewModels.User.SendDynamic;
+using BiliLite.ViewModels.UserDynamic;
+
+// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“内容对话框”项模板
+
+namespace BiliLite.Dialogs
+{
+ public sealed partial class SendDynamicV2Dialog : ContentDialog
+ {
+ readonly EmoteViewModel emoteVM;
+ readonly AtViewModel atVM;
+ readonly SendDynamicV2ViewModel m_viewModel;
+ readonly TopicViewModel topicVM;
+
+ public SendDynamicV2Dialog(SendDynamicV2ViewModel sendDynamicV2ViewModel, EmoteViewModel emoteViewModel, AtViewModel atViewModel, TopicViewModel topicVm)
+ {
+ m_viewModel = sendDynamicV2ViewModel;
+ emoteVM = emoteViewModel;
+ atVM = atViewModel;
+ topicVM = topicVm;
+ this.InitializeComponent();
+ }
+
+ public void SetRepost(DynamicV2ItemViewModel userDynamicItem)
+ {
+ m_viewModel.SetRepost(userDynamicItem);
+ }
+
+ private void btn_Close_Click(object sender, RoutedEventArgs e)
+ {
+ this.Hide();
+ }
+
+ private async void btnEmoji_Click(object sender, RoutedEventArgs e)
+ {
+ FaceFlyout.ShowAt(sender as Button);
+ if (emoteVM.Packages == null || emoteVM.Packages.Count == 0)
+ {
+ await emoteVM.GetEmote(EmoteBusiness.dynamic);
+ }
+ }
+
+ private void gvEmoji_ItemClick(object sender, ItemClickEventArgs e)
+ {
+ txtContent.Text += (e.ClickedItem as EmotePackageItemModel).text.ToString();
+ }
+
+ private void txtContent_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ txtLength.Text = (233 - txtContent.Text.Length).ToString();
+ }
+
+ private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
+ {
+ atVM.Search(sender.Text);
+ }
+
+ private void listAt_ItemClick(object sender, ItemClickEventArgs e)
+ {
+ var data = e.ClickedItem as AtUserModel;
+ var location = txtContent.Text.Length;
+ var at = "[@" + data.UserName + "]";
+ txtContent.Text += at;
+
+ m_viewModel.AddAtItem(new AtDisplayModel()
+ {
+ Data = data.ID,
+ Text = at,
+ Location = location,
+ Length = at.Length
+ });
+ }
+
+ private async void btnAt_Click(object sender, RoutedEventArgs e)
+ {
+ AtFlyout.ShowAt(sender as Button);
+ if (atVM.Users.Count == 0 && string.IsNullOrEmpty(atVM.Keyword))
+ {
+ await atVM.GetUser();
+ }
+ }
+
+ private async void btnTopic_Click(object sender, RoutedEventArgs e)
+ {
+ TopicFlyout.ShowAt(sender as Button);
+ if (topicVM.Items == null || topicVM.Items.Count == 0)
+ {
+ await topicVM.GetTopic();
+ }
+ }
+
+ private void listTopic_ItemClick(object sender, ItemClickEventArgs e)
+ {
+ txtContent.Text += (e.ClickedItem as RcmdTopicModel).display;
+ TopicFlyout.Hide();
+ }
+
+ private void TextTopic_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
+ {
+ txtContent.Text += args.QueryText;
+ TopicFlyout.Hide();
+ }
+
+ private void btn_RemovePic_Click(object sender, RoutedEventArgs e)
+ {
+ m_viewModel.Images.Remove((sender as Button).DataContext as UploadImagesModel);
+ m_viewModel.ShowImage = gv_Pics.Items.Count > 0;
+ }
+
+ private async void btnImage_Click(object sender, RoutedEventArgs e)
+ {
+ if (m_viewModel.Images.Count == 9)
+ {
+ Notify.ShowMessageToast("只能上传9张图片哦");
+ return;
+ }
+ var picker = new FileOpenPicker();
+ picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
+ picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
+ picker.FileTypeFilter.Add(".jpg");
+ picker.FileTypeFilter.Add(".jpeg");
+ picker.FileTypeFilter.Add(".png");
+ picker.FileTypeFilter.Add(".bmp");
+ picker.FileTypeFilter.Add(".webp");
+ Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
+ if (file != null)
+ {
+ m_viewModel.UploadImage(file);
+ }
+ }
+
+ private async void btnSend_Click(object sender, RoutedEventArgs e)
+ {
+ m_viewModel.Content = txtContent.Text;
+ bool result = false;
+ btnSend.IsEnabled = false;
+ if (m_viewModel.IsRepost)
+ {
+ result = await m_viewModel.SendRepost();
+ }
+ else
+ {
+ result = await m_viewModel.SendDynamic();
+ }
+ if (result)
+ {
+ this.Hide();
+ }
+ else
+ {
+ btnSend.IsEnabled = true;
+ }
+
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Extensions/ControlsExtensions.cs b/src/BiliLite.UWP/Extensions/ControlsExtensions.cs
new file mode 100644
index 00000000..955ccf7a
--- /dev/null
+++ b/src/BiliLite.UWP/Extensions/ControlsExtensions.cs
@@ -0,0 +1,15 @@
+using BiliLite.Dialogs;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace BiliLite.Extensions
+{
+ public static class ControlsExtensions
+ {
+ public static IServiceCollection AddControls(this IServiceCollection services)
+ {
+ services.AddTransient();
+ services.AddTransient();
+ return services;
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Extensions/DynamicParseExtensions.cs b/src/BiliLite.UWP/Extensions/DynamicParseExtensions.cs
index 3a29d00b..cbeb5e4a 100644
--- a/src/BiliLite.UWP/Extensions/DynamicParseExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/DynamicParseExtensions.cs
@@ -5,13 +5,14 @@
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Markup;
-using BiliLite.Controls.Dynamic;
+using Bilibili.App.Dynamic.V2;
using BiliLite.Models.Common;
using BiliLite.Models.Common.UserDynamic;
using BiliLite.Models.Dynamic;
using BiliLite.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using Paragraph = Windows.UI.Xaml.Documents.Paragraph;
namespace BiliLite.Extensions
{
@@ -48,6 +49,7 @@ public static UserDynamicItemDisplayShortVideoInfo ParseShortVideoInfo(JObject o
return null;
}
}
+
/**
* Command
* UserCommand=>打开用户页面
@@ -65,7 +67,14 @@ public static UserDynamicItemDisplayShortVideoInfo ParseShortVideoInfo(JObject o
///
///
///
- public static RichTextBlock UserDynamicStringToRichText(this string txt, string id, List emote, JObject extend_json)
+ public static RichTextBlock UserDynamicStringToRichText(
+ this string txt,
+ string id,
+ List emote = null,
+ JObject extend_json = null,
+ List wordNodes = null,
+ string title = null,
+ string bindingCommands= "UserDynamicItemDisplayCommands")
{
if (string.IsNullOrEmpty(txt)) return new RichTextBlock();
var input = txt;
@@ -84,25 +93,31 @@ public static RichTextBlock UserDynamicStringToRichText(this string txt, string
input = Regex.Replace(input, @"[\p{Cc}\p{Cf}]", string.Empty);
//处理@
- input = HandelAtAndVote(input, txt, extend_json);
+ input = HandelAtAndVote(input, txt, extend_json, bindingCommands);
//处理网页🔗
- input = HandelUrl(input);
+ input = HandelUrl(input, bindingCommands);
//处理表情
input = HandelEmoji(input, emote);
+ input = HandelWordNodes(input, wordNodes, bindingCommands);
//处理话题
- input = HandelTag(input);
+ input = HandelTag(input, bindingCommands);
+
+ //标题
+ var titlePara = string.IsNullOrEmpty(title) ? "" : $" {title}";
//互动抽奖🎁
- input = HandelLottery(input, id, extend_json);
- input = HandelVideoID(input);
+ input = HandelLottery(input, id, extend_json, bindingCommands);
+ input = HandelVideoID(input, bindingCommands);
input = input.Replace("^x$%^", "@");
//生成xaml
- var xaml = string.Format(@"
- {0}
- ", input);
+ {1}
+{0}
+ ", input, titlePara);
var p = (RichTextBlock)XamlReader.Load(xaml);
return p;
@@ -141,12 +156,64 @@ private static string HandelEmoji(string input, List
+ /// 处理Word节点
+ ///
+ private static string HandelWordNodes(string input, List nodes, string bindingCommands)
+ {
+ if (nodes == null || nodes.Count <= 0) return input;
+
+ //替换表情
+ var emotes = nodes.Where(x => x.NodeType == TextNode.Types.TextNodeType.Emote);
+ if (emotes.Count() != 0)
+ {
+ var matchCollection = Regex.Matches(input, @"\[.*?\]");
+ foreach (Match item in matchCollection)
+ {
+ var name = item.Groups[0].Value;
+ var emoji = emotes.FirstOrDefault(x =>
+ x.NodeType == TextNode.Types.TextNodeType.Emote && x.RawText.Equals(name));
+ if (emoji != null)
+ {
+ input = input.Replace(item.Groups[0].Value, string.Format(
+ @"",
+ emoji.Emote.EmoteUrl, 24));
+ }
+ }
+ }
+
+ //替换AT
+ var ats = nodes.Where(x => x.NodeType == TextNode.Types.TextNodeType.At);
+ if (ats.Count() != 0)
+ {
+ foreach (var atItem in ats)
+ {
+ try
+ {
+ var run = @""
+ + $@"{0}"
+ +""
+ , atItem.RawText.Replace("@", "^x$%^"), atItem.Link.Link);
+
+ input = input.Replace(atItem.RawText, run);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error("处理At及投票信息失败", ex);
+ }
+ }
+ }
+
+ return input;
+ }
+
///
/// 处理标签
///
///
///
- private static string HandelTag(string input)
+ private static string HandelTag(string input,string bindingCommands)
{
//处理话题
var avMatchCollection = Regex.Matches(input, @"\#(.*?)\#");
@@ -154,7 +221,7 @@ private static string HandelTag(string input)
foreach (Match item in avMatchCollection)
{
if (handel.Contains(item.Groups[0].Value)) continue;
- var data = @"{0}",
+ var data = $@"{0}",
item.Groups[0].Value, item.Groups[1].Value);
handel.Add(item.Groups[0].Value);
input = input.Replace(item.Groups[0].Value, data);
@@ -169,7 +236,7 @@ private static string HandelTag(string input)
///
///
///
- private static string HandelUrl(string input)
+ private static string HandelUrl(string input, string bindingCommands)
{
var keyword = new List();
var urlMatchCollection = Regex.Matches(input, @"(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]");
@@ -180,7 +247,7 @@ private static string HandelUrl(string input)
continue;
}
keyword.Add(item.Groups[0].Value);
- var data = @"🔗网页链接", item.Groups[0].Value);
input = input.Replace(item.Groups[0].Value, data);
}
@@ -194,8 +261,9 @@ private static string HandelUrl(string input)
///
///
///
- private static string HandelAtAndVote(string input, string origin_content, JObject extendJson)
+ private static string HandelAtAndVote(string input, string origin_content, JObject extendJson, string bindingCommands)
{
+ if (extendJson == null) return input;
var content = origin_content;
var ctrls = new List();
if (extendJson.TryGetValue("ctrl", out var ctrl))
@@ -218,7 +286,7 @@ private static string HandelAtAndVote(string input, string origin_content, JObje
var d = content.Substring(item.Location, item.Length);
var index = input.IndexOf(d);
input = input.Remove(index, item.Length);
- var run = @"{0}", d.Replace("@", "^x$%^"), item.Data);
+ var run = $@"{0}", d.Replace("@", "^x$%^"), item.Data);
input = input.Insert(index, run);
}
catch (Exception ex)
@@ -232,7 +300,7 @@ private static string HandelAtAndVote(string input, string origin_content, JObje
var d = content.Substring(item.Location, content.Length - item.Location);
var index = input.IndexOf(d);
input = input.Remove(index, content.Length - item.Location);
- var run = @"{0}",
+ var run = $@"{0}",
"📊" + d, extendJson["vote"]?["vote_id"]?.ToInt32() ?? 0);
input = input.Insert(index, run);
}
@@ -246,15 +314,16 @@ private static string HandelAtAndVote(string input, string origin_content, JObje
///
///
///
- private static string HandelLottery(string input, string id, JObject extendJson)
+ private static string HandelLottery(string input, string id, JObject extendJson, string bindingCommands)
{
+ if (extendJson == null) return input;
if (!extendJson.ContainsKey("lott")) return input;
if (input.IndexOf("互动抽奖") == 1)
{
input = input.Remove(1, 4);
}
- input = input.Insert(0, $@"🎁互动抽奖");
+ input = input.Insert(0, $@"🎁互动抽奖");
return input;
}
@@ -263,7 +332,7 @@ private static string HandelLottery(string input, string id, JObject extendJson)
///
///
///
- private static string HandelVideoID(string input)
+ private static string HandelVideoID(string input, string bindingCommands)
{
var keyword = new List();
//如果是链接就不处理了
@@ -280,7 +349,7 @@ private static string HandelVideoID(string input)
keyword.Add(item.Groups[0].Value);
var urlPrefix = "bilibili://video/";
var data =
- $"{item.Groups[0].Value}";
input = input.Replace(item.Groups[0].Value, data);
}
@@ -296,7 +365,7 @@ private static string HandelVideoID(string input)
keyword.Add(item.Groups[0].Value);
var urlPrefix = "bilibili://video/";
var data =
- $"{item.Groups[0].Value}";
input = input.Replace(item.Groups[0].Value, data);
}
@@ -312,7 +381,7 @@ private static string HandelVideoID(string input)
keyword.Add(item.Groups[0].Value);
var urlPrefix = "bilibili://article/";
var data =
- $"{item.Groups[0].Value}";
input = input.Replace(item.Groups[0].Value, data);
}
diff --git a/src/BiliLite.UWP/Extensions/MapperExtensions.cs b/src/BiliLite.UWP/Extensions/MapperExtensions.cs
index 81f52854..83488543 100644
--- a/src/BiliLite.UWP/Extensions/MapperExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/MapperExtensions.cs
@@ -43,7 +43,12 @@ public static IServiceCollection AddMapper(this IServiceCollection services)
{
expression.CreateMap();
expression.CreateMap();
- expression.CreateMap();
+ expression.CreateMap()
+ .ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.Member.Uname))
+ .ForMember(dest => dest.Message, opt => opt.MapFrom(src => src.Content.Message))
+ .ForMember(dest => dest.Emote, opt => opt.MapFrom(src => src.Content.Emote));
+ expression.CreateMap()
+ .ForMember(dest => dest.HotReplies, opt => opt.MapFrom(src => src.Replies));
expression.CreateMap();
expression.CreateMap();
expression.CreateMap();
@@ -120,6 +125,23 @@ public static IServiceCollection AddMapper(this IServiceCollection services)
SubTitle = src.SubTitle,
Title = src.Title,
}));
+
+ expression.CreateMap()
+ .ForMember(dest => dest.Author,
+ opt => opt.MapFrom(src =>
+ src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleAuthor).ModuleAuthor))
+ .ForMember(dest => dest.AuthorForward,
+ opt => opt.MapFrom(src =>
+ src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleAuthorForward).ModuleAuthorForward))
+ .ForMember(dest => dest.Dynamic,
+ opt => opt.MapFrom(src =>
+ src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleDynamic).ModuleDynamic))
+ .ForMember(dest => dest.Desc,
+ opt => opt.MapFrom(src =>
+ src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleDesc).ModuleDesc))
+ .ForMember(dest => dest.Stat,
+ opt => opt.MapFrom(src =>
+ src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleStat).ModuleStat));
}));
services.AddSingleton(mapper);
diff --git a/src/BiliLite.UWP/Extensions/StringExtensions.cs b/src/BiliLite.UWP/Extensions/StringExtensions.cs
index 5bff2a1a..18052046 100644
--- a/src/BiliLite.UWP/Extensions/StringExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/StringExtensions.cs
@@ -80,7 +80,7 @@ public static string TraditionalToSimplified(this string input)
///
///
///
- public static RichTextBlock ToRichTextBlock(this string txt, JObject emote, bool isLive = false, string fontColor = null, string fontWeight = "Normal")
+ public static RichTextBlock ToRichTextBlock(this string txt, JObject emote, bool isLive = false, string fontColor = null, string fontWeight = "Normal",string lowProfilePrefix="")
{
var input = txt;
try
@@ -105,15 +105,21 @@ public static RichTextBlock ToRichTextBlock(this string txt, JObject emote, bool
//处理av号/bv号
if (!isLive) { input = HandelVideoID(input); }
+ if (!string.IsNullOrEmpty(lowProfilePrefix))
+ {
+ lowProfilePrefix = $"";
+ }
+
//生成xaml
var xaml = string.Format(@"
- {0}
+ {4}{0}
", input,
isLive ? 22 : 20,
fontColor == null ? "" : $"Foreground=\"{fontColor}\"",
- $"FontWeight=\"{fontWeight}\"");
+ $"FontWeight=\"{fontWeight}\"",
+ lowProfilePrefix);
var p = (RichTextBlock)XamlReader.Load(xaml);
return p;
}
@@ -157,6 +163,7 @@ public static string SubstringCommentText(this string input,int length)
matches.Add(index, value);
}
var newInput = regex.Replace(input, "");
+ if (newInput.Length < length) return input;
var output = newInput.Substring(0, length);
foreach (var pair in matches)
{
diff --git a/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs b/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs
index a188a8a1..1b309f2d 100644
--- a/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs
@@ -1,8 +1,11 @@
-using BiliLite.ViewModels.Comment;
+using BiliLite.ViewModels;
+using BiliLite.ViewModels.Comment;
using BiliLite.ViewModels.Download;
using BiliLite.ViewModels.Home;
using BiliLite.ViewModels.Live;
using BiliLite.ViewModels.User;
+using BiliLite.ViewModels.User.SendDynamic;
+using BiliLite.ViewModels.UserDynamic;
using Microsoft.Extensions.DependencyInjection;
namespace BiliLite.Extensions
@@ -25,6 +28,12 @@ public static IServiceCollection AddViewModels(this IServiceCollection services)
services.AddTransient();
services.AddTransient();
services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
return services;
}
}
diff --git a/src/BiliLite.UWP/MainPage.xaml.cs b/src/BiliLite.UWP/MainPage.xaml.cs
index 4050c59a..6a47ea94 100644
--- a/src/BiliLite.UWP/MainPage.xaml.cs
+++ b/src/BiliLite.UWP/MainPage.xaml.cs
@@ -269,7 +269,7 @@ private void tabView_TabItemsChanged(TabView sender, IVectorChangedEventArgs arg
private void TabView_OnPreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
- if(e.Key == VirtualKey.Space)
+ if(e.Key == VirtualKey.Space && e.OriginalSource.GetType()!= typeof(TextBox))
e.Handled = true;
}
}
diff --git a/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs b/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs
index 6ce593f4..821b3282 100644
--- a/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs
+++ b/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs
@@ -191,7 +191,10 @@ public DynamicItemDisplayModelBuilder SetContent(JObject card, JObject extendJso
if (!string.IsNullOrEmpty(content))
{
m_displayViewModel.ContentStr = content;
- m_displayViewModel.Content = content.UserDynamicStringToRichText(m_cardModel.desc.dynamic_id, m_cardModel.display?.emoji_info?.emoji_details, extendJson);
+ m_displayViewModel.Content = content.UserDynamicStringToRichText(
+ m_cardModel.desc.dynamic_id,
+ emote: m_cardModel.display?.emoji_info?.emoji_details,
+ extend_json: extendJson);
}
else
{
diff --git a/src/BiliLite.UWP/Models/Common/Comment/HotReply.cs b/src/BiliLite.UWP/Models/Common/Comment/HotReply.cs
new file mode 100644
index 00000000..8195e1e1
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/Comment/HotReply.cs
@@ -0,0 +1,43 @@
+using System;
+using Windows.UI.Xaml.Controls;
+using BiliLite.Extensions;
+using BiliLite.Services;
+using Newtonsoft.Json.Linq;
+
+namespace BiliLite.Models.Common.Comment
+{
+ public class HotReply
+ {
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+
+ public string UserName { get; set; }
+
+ public string Message { get; set; }
+
+ public JObject Emote { get; set; }
+
+ public RichTextBlock Content
+ {
+ get
+ {
+ try
+ {
+ if (Message.Length <= 50)
+ {
+ return $"{Message}"
+ .ToRichTextBlock(Emote, lowProfilePrefix: $"{UserName}: ");
+ }
+
+ var substringMsg = $"{Message.SubstringCommentText(50)}...";
+
+ return substringMsg.ToRichTextBlock(Emote, lowProfilePrefix: $"{UserName}: ");
+ }
+ catch (Exception ex)
+ {
+ _logger.Error("热门回复加载失败", ex);
+ return new RichTextBlock();
+ }
+ }
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/Constants.cs b/src/BiliLite.UWP/Models/Common/Constants.cs
index 0d05e216..6fce164c 100644
--- a/src/BiliLite.UWP/Models/Common/Constants.cs
+++ b/src/BiliLite.UWP/Models/Common/Constants.cs
@@ -81,5 +81,26 @@ public static class Images
///
public const string MY_ICON_IMAGE = "ms-appx:///Assets/Icon/我的.png";
}
+
+ public static class DynamicTypes
+ {
+ public const string AV = "Av";
+
+ public const string PGC = "Pgc";
+
+ public const string WORD = "Word";
+
+ public const string DRAW = "Draw";
+
+ public const string MUSIC = "Music";
+
+ public const string ARTICLE = "Article";
+
+ public const string FORWARD = "Forward";
+
+ public const string COMMON_SQUARE = "CommonSquare";
+
+ public const string LIVE_RCMD = "LiveRcmd";
+ }
}
}
diff --git a/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs b/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs
index 60e26296..829c070c 100644
--- a/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs
+++ b/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs
@@ -119,6 +119,30 @@ public static List GetDefaultHideHomeNavItems()
Title = "新标签页",
NeedLogin = false,
Show = true
+ },
+ new HomeNavItem()
+ {
+ Icon = FontAwesome5.EFontAwesomeIcon.Regular_PlayCircle,
+ Page = typeof(Pages.User.WatchlaterPage),
+ Title = "稍后再看",
+ NeedLogin = true,
+ Show = false
+ },
+ new HomeNavItem()
+ {
+ Icon = FontAwesome5.EFontAwesomeIcon.Solid_History,
+ Page = typeof(Pages.User.HistoryPage),
+ Title = "历史记录",
+ NeedLogin = true,
+ Show = false
+ },
+ new HomeNavItem()
+ {
+ Icon = FontAwesome5.EFontAwesomeIcon.Regular_Star,
+ Page = typeof(Pages.User.FavoritePage),
+ Title = "我的收藏",
+ NeedLogin = true,
+ Show = false
}
};
}
diff --git a/src/BiliLite.UWP/Models/Common/SettingConstants.cs b/src/BiliLite.UWP/Models/Common/SettingConstants.cs
index 64812d2e..84ac4dec 100644
--- a/src/BiliLite.UWP/Models/Common/SettingConstants.cs
+++ b/src/BiliLite.UWP/Models/Common/SettingConstants.cs
@@ -107,6 +107,16 @@ public class UI
/// 默认折叠评论长度
///
public const int COMMENT_SHRINK_DEFAULT_LENGTH = 75;
+
+ ///
+ /// 显示评论热门回复
+ ///
+ public const string SHOW_HOT_REPLIES = "ShowHotReplies";
+
+ ///
+ /// 显示评论热门回复默认选项
+ ///
+ public const bool DEFAULT_SHOW_HOT_REPLIES = true;
}
public class Account
diff --git a/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtDisplayModel.cs b/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtDisplayModel.cs
new file mode 100644
index 00000000..52280f66
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtDisplayModel.cs
@@ -0,0 +1,13 @@
+namespace BiliLite.Models.Common.User.SendDynamic
+{
+ public class AtDisplayModel
+ {
+ public long Data { get; set; }
+
+ public string Text { get; set; }
+
+ public int Location { get; set; }
+
+ public int Length { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtModel.cs b/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtModel.cs
new file mode 100644
index 00000000..41fa02ea
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtModel.cs
@@ -0,0 +1,13 @@
+namespace BiliLite.Models.Common.User.SendDynamic
+{
+ public class AtModel
+ {
+ public string Data { get; set; }
+
+ public int Location { get; set; }
+
+ public int Length { get; set; }
+
+ public int Type { get; set; } = 1;
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtUserModel.cs b/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtUserModel.cs
new file mode 100644
index 00000000..84460808
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/User/SendDynamic/AtUserModel.cs
@@ -0,0 +1,10 @@
+namespace BiliLite.Models.Common.User.SendDynamic
+{
+ public class AtUserModel
+ {
+ public long ID { get; set; }
+ public string UserName { get; set; }
+ public string Face { get; set; }
+ public string Display { get { return "@" + UserName; } }
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/User/SendDynamic/RcmdTopicModel.cs b/src/BiliLite.UWP/Models/Common/User/SendDynamic/RcmdTopicModel.cs
new file mode 100644
index 00000000..b9fde95f
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/User/SendDynamic/RcmdTopicModel.cs
@@ -0,0 +1,13 @@
+namespace BiliLite.Models.Common.User.SendDynamic
+{
+ public class RcmdTopicModel
+ {
+ public int topic_id { get; set; }
+ public string topic_name { get; set; }
+ public int is_activity { get; set; }
+ public string display
+ {
+ get { return "#" + topic_name + "#"; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/User/SendDynamic/SendImagesModel.cs b/src/BiliLite.UWP/Models/Common/User/SendDynamic/SendImagesModel.cs
new file mode 100644
index 00000000..f89142a2
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/User/SendDynamic/SendImagesModel.cs
@@ -0,0 +1,18 @@
+using Newtonsoft.Json;
+
+namespace BiliLite.Models.Common.User.SendDynamic
+{
+ public class SendImagesModel
+ {
+ [JsonProperty("img_height")]
+ public int ImgHeight { get; set; }
+ [JsonProperty("img_src")]
+ public string ImgSrc { get; set; }
+
+ [JsonProperty("img_size")]
+ public double ImgSize { get; set; }
+
+ [JsonProperty("img_width")]
+ public int ImgWidth { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/User/SendDynamic/UploadImagesModel.cs b/src/BiliLite.UWP/Models/Common/User/SendDynamic/UploadImagesModel.cs
new file mode 100644
index 00000000..b5ee47d4
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/User/SendDynamic/UploadImagesModel.cs
@@ -0,0 +1,21 @@
+using Newtonsoft.Json;
+
+namespace BiliLite.Models.Common.User.SendDynamic
+{
+ public class UploadImagesModel
+ {
+ [JsonProperty("image_height")]
+ public int ImageHeight { get; set; }
+
+ [JsonProperty("image_url")]
+ public string ImageUrl { get; set; }
+
+ [JsonProperty("image_size")]
+ public double ImageSize { get; set; }
+
+ public string Image => ImageUrl + "@120w_120h_1e_1c.jpg";
+
+ [JsonProperty("image_width")]
+ public int ImageWidth { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/UserDynamic/DynLiveInfo.cs b/src/BiliLite.UWP/Models/Common/UserDynamic/DynLiveInfo.cs
new file mode 100644
index 00000000..42028a00
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/UserDynamic/DynLiveInfo.cs
@@ -0,0 +1,39 @@
+using Newtonsoft.Json;
+
+namespace BiliLite.Models.Common.UserDynamic
+{
+ public class DynLiveInfo
+ {
+ [JsonProperty("live_play_info")]
+ public DynLivePlayInfo PlayInfo { get; set; }
+ }
+
+ public class DynLivePlayInfo
+ {
+ [JsonProperty("room_id")]
+ public long RoomId { get; set; }
+
+ [JsonProperty("uid")]
+ public long UserId { get; set; }
+
+ [JsonProperty("live_status")]
+ public int LiveStatus { get; set; }
+
+ public string Title { get; set; }
+
+ public string Cover { get; set; }
+
+ [JsonProperty("area_name")]
+ public string AreaName { get; set; }
+
+ [JsonProperty("watched_show")]
+ public DynLiveWatchedShow WatchedShow { get; set; }
+ }
+
+ public class DynLiveWatchedShow
+ {
+
+ [JsonProperty("text_large")]
+ public string TextLarge { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/UserDynamic/UserDynamicItemDisplayImageInfo.cs b/src/BiliLite.UWP/Models/Common/UserDynamic/UserDynamicItemDisplayImageInfo.cs
index 5e329cae..bf703b1d 100644
--- a/src/BiliLite.UWP/Models/Common/UserDynamic/UserDynamicItemDisplayImageInfo.cs
+++ b/src/BiliLite.UWP/Models/Common/UserDynamic/UserDynamicItemDisplayImageInfo.cs
@@ -11,9 +11,9 @@ public class UserDynamicItemDisplayImageInfo
public string ImageUrl { get; set; }
- public int Width { get; set; }
+ public long Width { get; set; }
- public int Height { get; set; }
+ public long Height { get; set; }
public List AllImages { get; set; }
diff --git a/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs b/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs
index 7ea075ec..f5da85fa 100644
--- a/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs
+++ b/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs
@@ -63,7 +63,9 @@ public ApiModel DynamicDetail(string id)
//使用Web的API
if (SettingService.Account.Logined)
{
- api.parameter += $"&access_key={SettingService.Account.AccessKey}";
+ api.parameter += "&";
+ api.parameter += ApiHelper.MustParameter(AppKey, true);
+ api.parameter += ApiHelper.GetSign(api.parameter, AppKey);
}
return api;
@@ -135,6 +137,24 @@ public ApiModel SpaceHistory(string mid, string dynamic_id = "")
return api;
}
+
+ public ApiModel SpaceHistoryV2(string mid, string offset = "")
+ {
+ var api = new ApiModel()
+ {
+ method = RestSharp.Method.Get,
+ baseUrl = $"https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space",
+ parameter = $"offset={offset}&host_mid={mid}",
+ need_cookie = true,
+ };
+ //if (SettingService.Account.Logined)
+ //{
+ // api.parameter += ApiHelper.MustParameter(AppKey, true);
+ // api.parameter += ApiHelper.GetSign(api.parameter, AppKey);
+ //}
+
+ return api;
+ }
///
/// 推荐话题
///
diff --git a/src/BiliLite.UWP/Modules/User/SendDynamic/SendDynamicVM.cs b/src/BiliLite.UWP/Modules/User/SendDynamic/SendDynamicVM.cs
deleted file mode 100644
index 85a280f8..00000000
--- a/src/BiliLite.UWP/Modules/User/SendDynamic/SendDynamicVM.cs
+++ /dev/null
@@ -1,331 +0,0 @@
-using BiliLite.Models;
-using BiliLite.Models.Requests.Api.User;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using RestSharp;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Runtime.InteropServices.WindowsRuntime;
-using System.Threading.Tasks;
-using Windows.Storage;
-using Windows.Storage.Streams;
-using BiliLite.Extensions;
-using BiliLite.Models.Responses;
-using BiliLite.Models.Common;
-using BiliLite.Services;
-using BiliLite.ViewModels.UserDynamic;
-
-namespace BiliLite.Modules.User
-{
- public class SendDynamicVM : IModules
- {
- private static readonly ILogger logger = GlobalLogger.FromCurrentType();
-
- readonly DynamicAPI dynamicAPI;
- public SendDynamicVM()
- {
- dynamicAPI = new DynamicAPI();
- Images = new ObservableCollection();
- }
- public SendDynamicVM(UserDynamicItemDisplayViewModel repostInfo)
- {
- dynamicAPI = new DynamicAPI();
- RepostInfo = repostInfo;
- IsRepost = true;
- }
- private bool _IsRepost = false;
- public bool IsRepost
- {
- get { return _IsRepost; }
- set { _IsRepost = value; DoPropertyChanged("IsRepost"); }
- }
-
- public UserDynamicItemDisplayViewModel RepostInfo { get; set; }
-
- private string _Content = "";
- public string Content
- {
- get { return _Content; }
- set { _Content = value; DoPropertyChanged("Content"); DoPropertyChanged("Count"); }
- }
-
- private ObservableCollection _images;
-
- public ObservableCollection Images
- {
- get { return _images; }
- set { _images = value; DoPropertyChanged("Images"); }
- }
- private bool _uploading;
-
- public bool Uploading
- {
- get { return _uploading; }
- set { _uploading = value; DoPropertyChanged("Uploading"); }
- }
-
- private bool _showImage = false;
-
- public bool ShowImage
- {
- get { return _showImage; }
- set { _showImage = value; DoPropertyChanged("ShowImage"); }
- }
- public List AtDisplaylist = new List();
- public List Atlist = new List();
- public async void UploadImage(StorageFile file)
- {
- try
- {
-
- Uploading = true;
- var api = dynamicAPI.UploadImage();
-
-
- IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);
- var bytes = new byte[fileStream.Size];
- await fileStream.ReadAsync(bytes.AsBuffer(), (uint)fileStream.Size, Windows.Storage.Streams.InputStreamOptions.None);
- var client = new RestClient(api.url);
- var request = new RestRequest();
- request.Method = Method.Post;
- request.AddParameter("biz", "draw");
- request.AddParameter("category", "daily");
- request.AddFile("file_up", bytes, file.Name);
- RestResponse response = await client.ExecuteAsync(request);
- var content = response.Content;
-
- ApiDataModel result = JsonConvert.DeserializeObject>(content);
- if (result.code == 0)
- {
- result.data.image_size = (await file.GetBasicPropertiesAsync()).Size / 1024;
- Images.Add(result.data);
- }
- else
- {
- Notify.ShowMessageToast(result.message);
- }
- }
- catch (Exception ex)
- {
- logger.Log("图片上传失败", LogType.Fatal, ex);
- Notify.ShowMessageToast("图片上传失败");
- }
- finally
- {
- Uploading = false;
- ShowImage = Images.Count > 0;
-
- }
- }
-
- ///
- /// 转发
- ///
- public async Task SendRepost()
- {
- var ctrl = "[]";
- var at_uids = "";
- Atlist.Clear();
-
- if (AtDisplaylist.Count != 0)
- {
-
- foreach (var item in AtDisplaylist)
- {
- if (Content.Contains(item.text))
- {
- Atlist.Add(new AtModel()
- {
- data = item.data.ToString(),
- length = item.length - 2,
- location = Content.IndexOf(item.text),
- type = 1
- });
- var d = item.text.Replace("[", "").Replace("]", "");
- Content = Content.Replace(item.text, d);
- at_uids += item.data.ToString() + ",";
- }
- }
- ctrl = JsonConvert.SerializeObject(Atlist);
- at_uids = at_uids.Remove(at_uids.Length - 1, 1);
- AtDisplaylist.Clear();
- }
- if (Content == "")
- {
- Content = "转发动态";
- }
- try
- {
-
- HttpResults httpResults = await dynamicAPI.RepostDynamic(RepostInfo.DynamicID, Content, at_uids, ctrl).Request();
- if (httpResults.status)
- {
- var data = await httpResults.GetData();
- if (data.code == 0)
- {
-
- Notify.ShowMessageToast("转发成功");
- AtDisplaylist.Clear();
- return true;
- }
- else
- {
-
- Notify.ShowMessageToast("发表动态失败:" + data.message);
- return false;
- }
- }
- else
- {
-
- Notify.ShowMessageToast(httpResults.message);
- return false;
- }
-
- }
- catch (Exception ex)
- {
- Notify.ShowMessageToast("转发动态失败" + ex.Message);
- logger.Log("转发动态失败", LogType.Error, ex);
- return false;
- }
-
- }
- public async Task SendDynamic()
- {
- if (Content.Trim().Length == 0)
- {
- Notify.ShowMessageToast("不能发送空白动态");
- return false;
- }
-
- var ctrl = "[]";
- var at_uids = "";
- Atlist.Clear();
- var txt = Content;
- if (AtDisplaylist.Count != 0)
- {
- foreach (var item in AtDisplaylist)
- {
- if (txt.Contains(item.text))
- {
- Atlist.Add(new AtModel()
- {
- data = item.data.ToString(),
- length = item.length - 2,
- location = txt.IndexOf(item.text),
- type = 1
- });
- var d = item.text.Replace("[", "").Replace("]", "");
- txt = txt.Replace(item.text, d);
- at_uids += item.data.ToString() + ",";
- }
- }
- ctrl = JsonConvert.SerializeObject(Atlist);
- at_uids = at_uids.Remove(at_uids.Length - 1, 1);
-
- }
-
- List send_pics = new List();
- foreach (var item in Images)
- {
- send_pics.Add(new SendImagesModel()
- {
- img_height = item.image_height,
- img_size = item.image_size,
- img_src = item.image_url,
- img_width = item.image_width
- });
- }
- var imgStr = JsonConvert.SerializeObject(send_pics);
- try
- {
- HttpResults httpResults;
- if (send_pics.Count == 0)
- {
- httpResults = await dynamicAPI.CreateDynamicText(txt, at_uids, ctrl).Request();
- }
- else
- {
- httpResults = await dynamicAPI.CreateDynamicPhoto(imgStr, txt, at_uids, ctrl).Request();
- }
- if (httpResults.status)
- {
- var data = await httpResults.GetData();
- if (data.code == 0)
- {
-
- Notify.ShowMessageToast("发表动态成功");
- AtDisplaylist.Clear();
- return true;
- }
- else
- {
-
- Notify.ShowMessageToast("发表动态失败:" + data.message);
- return false;
- }
- }
- else
- {
- Notify.ShowMessageToast(httpResults.message);
- return false;
- }
-
- }
- catch (Exception ex)
- {
-
- Notify.ShowMessageToast("发表动态发生错误");
- logger.Log("发表动态失败", LogType.Error, ex);
- return false;
- }
-
- }
- }
-
- public class UploadImagesModel
- {
- public int image_height { get; set; }
- public string image_url { get; set; }
-
- public double image_size { get; set; }
-
- public string image
- {
- get
- {
- return image_url + "@120w_120h_1e_1c.jpg";
- }
- }
- public int image_width { get; set; }
-
- }
- public class SendImagesModel
- {
-
-
- public int img_height { get; set; }
- public string img_src { get; set; }
-
- public double img_size { get; set; }
- public int img_width { get; set; }
-
- }
- public class AtModel
- {
- public string data { get; set; }
- public int location { get; set; }
- public int length { get; set; }
- public int type { get; set; } = 1;
- }
- public class AtDisplayModel
- {
- public long data { get; set; }
- public string text { get; set; }
- public int location { get; set; }
- public int length { get; set; }
- }
-
-}
diff --git a/src/BiliLite.UWP/Modules/User/WatchLaterVM.cs b/src/BiliLite.UWP/Modules/User/WatchLaterVM.cs
index fe9b66ba..f1b97ab4 100644
--- a/src/BiliLite.UWP/Modules/User/WatchLaterVM.cs
+++ b/src/BiliLite.UWP/Modules/User/WatchLaterVM.cs
@@ -5,12 +5,9 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using BiliLite.Extensions;
-using BiliLite.Models.Common;
using BiliLite.Services;
namespace BiliLite.Modules.User
@@ -39,6 +36,7 @@ public WatchLaterVM()
{
watchLaterAPI = new WatchLaterAPI();
AddCommand = new RelayCommand(AddToWatchlater);
+ AddCommandWithAvId = new RelayCommand(AddToWatchlater);
RefreshCommand = new RelayCommand(Refresh);
CleanCommand = new RelayCommand(Clear);
DeleteCommand = new RelayCommand(Del);
@@ -46,10 +44,20 @@ public WatchLaterVM()
}
public ICommand AddCommand { get; private set; }
+
+ public ICommand AddCommandWithAvId { get; private set; }
+
public ICommand CleanCommand { get; private set; }
public ICommand CleanViewedCommand { get; private set; }
public ICommand DeleteCommand { get; private set; }
public ICommand RefreshCommand { get; private set; }
+
+
+ public async void AddToWatchlater(long aid)
+ {
+ AddToWatchlater(aid.ToString());
+ }
+
public async void AddToWatchlater(string aid)
{
try
diff --git a/src/BiliLite.UWP/Pages/HomePage.xaml.cs b/src/BiliLite.UWP/Pages/HomePage.xaml.cs
index 7347317b..ee619c6f 100644
--- a/src/BiliLite.UWP/Pages/HomePage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/HomePage.xaml.cs
@@ -317,6 +317,8 @@ private async void SearchBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTe
{
if (args.Reason != AutoSuggestionBoxTextChangeReason.UserInput) return;
var text = sender.Text;
+ text = text.TrimEnd();
+ if (string.IsNullOrWhiteSpace(text)) return;
var suggestSearchContents = await new SearchService().GetSearchSuggestContents(text);
if (m_viewModel.SuggestSearchContents == null)
{
diff --git a/src/BiliLite.UWP/Pages/SearchPage.xaml.cs b/src/BiliLite.UWP/Pages/SearchPage.xaml.cs
index 5b9c6360..3bc486c9 100644
--- a/src/BiliLite.UWP/Pages/SearchPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/SearchPage.xaml.cs
@@ -259,6 +259,8 @@ private async void txtKeyword_TextChanged(AutoSuggestBox sender, AutoSuggestBoxT
{
if (args.Reason != AutoSuggestionBoxTextChangeReason.UserInput) return;
var text = sender.Text;
+ text = text.TrimEnd();
+ if (string.IsNullOrWhiteSpace(text)) return;
var suggestSearchContents = await new SearchService().GetSearchSuggestContents(text);
if (searchVM.SuggestSearchContents == null)
{
diff --git a/src/BiliLite.UWP/Pages/SettingPage.xaml b/src/BiliLite.UWP/Pages/SettingPage.xaml
index bcb54965..505e8a8e 100644
--- a/src/BiliLite.UWP/Pages/SettingPage.xaml
+++ b/src/BiliLite.UWP/Pages/SettingPage.xaml
@@ -182,6 +182,11 @@
+
+ 展示评论热门回复
+
+
+
新窗口打开图片预览
diff --git a/src/BiliLite.UWP/Pages/SettingPage.xaml.cs b/src/BiliLite.UWP/Pages/SettingPage.xaml.cs
index 554decdc..d3d8c23a 100644
--- a/src/BiliLite.UWP/Pages/SettingPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/SettingPage.xaml.cs
@@ -232,6 +232,16 @@ private void LoadUI()
};
};
+ // 展示评论热门回复
+ swShowHotReplies.IsOn = SettingService.GetValue(SettingConstants.UI.SHOW_HOT_REPLIES, SettingConstants.UI.DEFAULT_SHOW_HOT_REPLIES);
+ swShowHotReplies.Loaded += (sender, e) =>
+ {
+ swShowHotReplies.Toggled += (obj, args) =>
+ {
+ SettingService.SetValue(SettingConstants.UI.SHOW_HOT_REPLIES, swShowHotReplies.IsOn);
+ };
+ };
+
//动态显示
cbDynamicDisplayMode.SelectedIndex = SettingService.GetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0);
cbDynamicDisplayMode.Loaded += new RoutedEventHandler((sender, e) =>
diff --git a/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml
new file mode 100644
index 00000000..8ba235e1
--- /dev/null
+++ b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Visible
+
+
+
+
+ Collapsed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Collapsed
+
+
+
+
+ Visible
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml.cs b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml.cs
new file mode 100644
index 00000000..4a21e0bb
--- /dev/null
+++ b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml.cs
@@ -0,0 +1,160 @@
+using System.Linq;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media.Animation;
+using Windows.UI.Xaml.Navigation;
+using BiliLite.Models.Common;
+using BiliLite.Models.Common.Comment;
+using BiliLite.Services;
+using BiliLite.ViewModels.UserDynamic;
+using Microsoft.Extensions.DependencyInjection;
+using BiliLite.Models.Requests.Api;
+
+// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace BiliLite.Pages.User
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class DynamicSpacePage : Page
+ {
+ private readonly UserDynamicSpaceViewModel m_viewModel;
+ private bool m_isStaggered = false;
+
+ public DynamicSpacePage()
+ {
+ m_viewModel = App.ServiceProvider.GetRequiredService();
+ m_viewModel.OpenCommentEvent += UserDynamicViewModelOpenCommentEvent;
+ this.InitializeComponent();
+ }
+
+ private void SetStaggered()
+ {
+ var staggered = SettingService.GetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0) == 1;
+ if (staggered != m_isStaggered)
+ {
+ m_isStaggered = staggered;
+ if (staggered)
+ {
+ SetGridCore();
+ }
+ else
+ {
+ SetListCore();
+ }
+ }
+ }
+
+ private void SetGridCore()
+ {
+ m_isStaggered = true;
+ BtnGrid.Visibility = Visibility.Collapsed;
+ BtnList.Visibility = Visibility.Visible;
+ //XAML
+ ListDyn.ItemsPanel = (ItemsPanelTemplate)this.Resources["GridPanel"];
+ }
+
+ private void SetListCore()
+ {
+ m_isStaggered = false;
+ //右下角按钮
+ BtnGrid.Visibility = Visibility.Visible;
+ BtnList.Visibility = Visibility.Collapsed;
+ //XAML
+ ListDyn.ItemsPanel = (ItemsPanelTemplate)this.Resources["ListPanel"];
+ }
+
+ protected override async void OnNavigatedTo(NavigationEventArgs e)
+ {
+ SetStaggered();
+ m_viewModel.UserId = e.Parameter as string;
+ await m_viewModel.GetDynamicItems();
+ }
+
+ private async void BtnRefreshDynamic_OnClick(object sender, RoutedEventArgs e)
+ {
+ await m_viewModel.GetDynamicItems();
+ }
+
+ private void BtnTop_OnClick(object sender, RoutedEventArgs e)
+ {
+ ListDyn.ScrollIntoView(ListDyn.Items.FirstOrDefault());
+ }
+
+ private void BtnList_OnClick(object sender, RoutedEventArgs e)
+ {
+ SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0);
+ SetListCore();
+ }
+
+ private void BtnGrid_OnClick(object sender, RoutedEventArgs e)
+ {
+ SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 1);
+ SetGridCore();
+ }
+
+ private void CloseCommentCore()
+ {
+ var storyboard = (Storyboard)this.Resources["HideComment"];
+ storyboard.Begin();
+ }
+
+
+ private void UserDynamicViewModelOpenCommentEvent(object sender, DynamicV2ItemViewModel e)
+ {
+ CommentApi.CommentType commentType = CommentApi.CommentType.Dynamic;
+ var id = e.Extend.BusinessId;
+ switch (e.CardType)
+ {
+ case Constants.DynamicTypes.DRAW:
+ commentType = CommentApi.CommentType.Photo;
+ break;
+ case Constants.DynamicTypes.AV:
+ commentType = CommentApi.CommentType.Video;
+ break;
+ case Constants.DynamicTypes.PGC:
+ id = e.Dynamic.DynPgc.Aid.ToString();
+ commentType = CommentApi.CommentType.Video;
+ break;
+ //case UserDynamicDisplayType.ShortVideo:
+ // commentType = CommentApi.CommentType.MiniVideo;
+ // break;
+ case Constants.DynamicTypes.MUSIC:
+ commentType = CommentApi.CommentType.Song;
+ break;
+ case Constants.DynamicTypes.ARTICLE:
+ commentType = CommentApi.CommentType.Article;
+ break;
+ //case UserDynamicDisplayType.MediaList:
+ // if (e.OneRowInfo.Tag != "收藏夹")
+ // commentType = CommentApi.CommentType.Video;
+ // break;
+ default:
+ id = e.Extend.DynIdStr;
+ break;
+ }
+
+ OpenCommentCore(id, (int)commentType, CommentApi.CommentSort.Hot);
+ }
+
+ private void OpenCommentCore(string oid, int commentMode, CommentApi.CommentSort commentSort)
+ {
+ Comment.LoadComment(new LoadCommentInfo()
+ {
+ CommentMode = commentMode,
+ CommentSort = commentSort,
+ Oid = oid,
+ IsDialog = true
+ });
+ var storyboard = (Storyboard)this.Resources["ShowComment"];
+ storyboard.Begin();
+ }
+
+ private void CommentPanel_OnTapped(object sender, TappedRoutedEventArgs e)
+ {
+ CloseCommentCore();
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Pages/UserInfoPage.xaml b/src/BiliLite.UWP/Pages/UserInfoPage.xaml
index 3aeb89e7..a8f7c298 100644
--- a/src/BiliLite.UWP/Pages/UserInfoPage.xaml
+++ b/src/BiliLite.UWP/Pages/UserInfoPage.xaml
@@ -288,49 +288,14 @@
-
+
动态
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs b/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs
index 3c2bf9b3..b0df033f 100644
--- a/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs
@@ -118,7 +118,7 @@ private void UserDynamicViewModelOpenCommentEvent(object sender, UserDynamicItem
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
- SetStaggered();
+ //SetStaggered();
if (e.NavigationMode == NavigationMode.New)
{
var mid = "";
@@ -237,49 +237,49 @@ private void pivotRight_SelectionChanged(object sender, SelectionChangedEventArg
}
}
- void SetStaggered()
- {
- var staggered = SettingService.GetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0) == 1;
- if (staggered != IsStaggered)
- {
- IsStaggered = staggered;
- if (staggered)
- {
- btnGrid_Click(this, null);
- }
- else
- {
- btnList_Click(this, null);
- }
- }
- }
+ //void SetStaggered()
+ //{
+ // var staggered = SettingService.GetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0) == 1;
+ // if (staggered != IsStaggered)
+ // {
+ // IsStaggered = staggered;
+ // if (staggered)
+ // {
+ // btnGrid_Click(this, null);
+ // }
+ // else
+ // {
+ // btnList_Click(this, null);
+ // }
+ // }
+ //}
- private void btnGrid_Click(object sender, RoutedEventArgs e)
- {
- SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 1);
- IsStaggered = true;
- btnGrid.Visibility = Visibility.Collapsed;
- btnList.Visibility = Visibility.Visible;
- //XAML
- list.ItemsPanel = (ItemsPanelTemplate)this.Resources["GridPanel"];
- }
+ //private void btnGrid_Click(object sender, RoutedEventArgs e)
+ //{
+ // SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 1);
+ // IsStaggered = true;
+ // btnGrid.Visibility = Visibility.Collapsed;
+ // btnList.Visibility = Visibility.Visible;
+ // //XAML
+ // list.ItemsPanel = (ItemsPanelTemplate)this.Resources["GridPanel"];
+ //}
- private void btnList_Click(object sender, RoutedEventArgs e)
- {
- IsStaggered = false;
- //右下角按钮
- btnGrid.Visibility = Visibility.Visible;
- btnList.Visibility = Visibility.Collapsed;
- //设置
- SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0);
- //XAML
- list.ItemsPanel = (ItemsPanelTemplate)this.Resources["ListPanel"];
- }
+ //private void btnList_Click(object sender, RoutedEventArgs e)
+ //{
+ // IsStaggered = false;
+ // //右下角按钮
+ // btnGrid.Visibility = Visibility.Visible;
+ // btnList.Visibility = Visibility.Collapsed;
+ // //设置
+ // SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0);
+ // //XAML
+ // list.ItemsPanel = (ItemsPanelTemplate)this.Resources["ListPanel"];
+ //}
- private void btnTop_Click(object sender, RoutedEventArgs e)
- {
- list.ScrollIntoView(list.Items[0]);
- }
+ //private void btnTop_Click(object sender, RoutedEventArgs e)
+ //{
+ // list.ScrollIntoView(list.Items[0]);
+ //}
private async void pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
@@ -287,9 +287,10 @@ private async void pivot_SelectionChanged(object sender, SelectionChangedEventAr
{
await m_userSubmitVideoViewModel.GetSubmitVideo();
}
- if (pivot.SelectedIndex == 1 && m_userDynamicViewModel.Items == null)
+ if (pivot.SelectedIndex == 1 && DynamicSpaceFrame.Content==null)
{
- await m_userDynamicViewModel.GetDynamicItems();
+ DynamicSpaceFrame.Navigate(typeof(DynamicSpacePage), m_viewModel.Mid);
+ //await m_userDynamicViewModel.GetDynamicItems();
}
if (pivot.SelectedIndex == 2 && userSubmitArticleVM.SubmitArticleItems == null)
{
diff --git a/src/BiliLite.UWP/Pages/WebPage.xaml.cs b/src/BiliLite.UWP/Pages/WebPage.xaml.cs
index ec3538fb..a05666ed 100644
--- a/src/BiliLite.UWP/Pages/WebPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/WebPage.xaml.cs
@@ -35,7 +35,7 @@ public WebPage()
private async void CoreWebView2_NewWindowRequested(CoreWebView2 sender, CoreWebView2NewWindowRequestedEventArgs args)
{
args.Handled = true;
- var handelUrlResult = await MessageCenter.HandelUrl(sender.Source);
+ var handelUrlResult = await MessageCenter.HandelUrl(args.Uri);
if (handelUrlResult) return;
var md = new MessageDialog("是否使用外部浏览器打开此链接?");
md.Commands.Add(new UICommand("确定", new UICommandInvokedHandler(async (e) => { await Windows.System.Launcher.LaunchUriAsync(new Uri(args.Uri)); })));
diff --git a/src/BiliLite.UWP/Services/GrpcService.cs b/src/BiliLite.UWP/Services/GrpcService.cs
index 68080131..5dcd9ccb 100644
--- a/src/BiliLite.UWP/Services/GrpcService.cs
+++ b/src/BiliLite.UWP/Services/GrpcService.cs
@@ -63,6 +63,35 @@ public async Task GetDynAll(int page = 1)
}
}
+ public async Task GetDynSpace(long mid,string from = "space", int page = 1,string offset = null)
+ {
+ var message = new DynSpaceReq()
+ {
+ Page = page,
+ From = from,
+ HostUid = mid
+ };
+ if (offset != null)
+ {
+ message.HistoryOffset = offset;
+ }
+ var requestUserInfo = new GrpcBiliUserInfo(
+ SettingService.Account.AccessKey,
+ SettingService.Account.UserID,
+ SettingService.Account.GetLoginAppKeySecret().Appkey);
+
+ var result = await GrpcRequest.Instance.SendMessage("https://grpc.biliapi.net:443/bilibili.app.dynamic.v2.Dynamic/DynSpace", message, requestUserInfo);
+ if (result.status)
+ {
+ var reply = DynSpaceRsp.Parser.ParseFrom(result.results);
+ return reply;
+ }
+ else
+ {
+ throw new Exception(result.message);
+ }
+ }
+
public async Task GetDynVideo(int page, string historyOffset, string updateBaseline)
{
var message = new DynVideoReq()
diff --git a/src/BiliLite.UWP/Services/MessageCenter.cs b/src/BiliLite.UWP/Services/MessageCenter.cs
index ba2fb431..0d916fd1 100644
--- a/src/BiliLite.UWP/Services/MessageCenter.cs
+++ b/src/BiliLite.UWP/Services/MessageCenter.cs
@@ -104,6 +104,31 @@ public static async Task HandelUrl(string url, bool dontGoTo = false)
{
url = await BiliExtensions.GetShortLinkLocation(url);
}
+
+
+
+ /*
+ * 直播
+ * http://live.bilibili.com/live/5619438.html
+ * http://live.bilibili.com/h5/5619438
+ * http://live.bilibili.com/5619438
+ * bilibili://live/5619438
+ */
+
+ var live = StringExtensions.RegexMatch(url.Replace("h5", "live").Replace("live.bilibili.com", "live").Replace("/", ""), @"live(\d+)");
+ if (live != "")
+ {
+ NavigateToPage(null, new NavigationInfo()
+ {
+ icon = Symbol.Video,
+ page = typeof(LiveDetailPage),
+ title = "直播间加载中...",
+ parameters = live,
+ dontGoTo = dontGoTo,
+ });
+ return true;
+ }
+
/*
* 视频
* https://www.bilibili.com/video/av3905642
@@ -265,28 +290,6 @@ await BiliExtensions.BangumiEpidToSid(bangumi),
- /*
- * 直播
- * http://live.bilibili.com/live/5619438.html
- * http://live.bilibili.com/h5/5619438
- * http://live.bilibili.com/5619438
- * bilibili://live/5619438
- */
-
- var live = StringExtensions.RegexMatch(url.Replace("h5", "live").Replace("live.bilibili.com", "live").Replace("/", ""), @"live(\d+)");
- if (live != "")
- {
- NavigateToPage(null, new NavigationInfo()
- {
- icon = Symbol.Video,
- page = typeof(LiveDetailPage),
- title = "直播间加载中...",
- parameters = live,
- dontGoTo = dontGoTo,
- });
- return true;
- }
-
///*
// * 小视频
// * http://vc.bilibili.com/mobile/detail?vc=1399466&bilifrom=1
diff --git a/src/BiliLite.UWP/Startup.cs b/src/BiliLite.UWP/Startup.cs
index c24fbe15..811ce56d 100644
--- a/src/BiliLite.UWP/Startup.cs
+++ b/src/BiliLite.UWP/Startup.cs
@@ -11,6 +11,7 @@ public void ConfigureServices(HostBuilderContext context, IServiceCollection ser
{
services.AddMapper();
services.AddViewModels();
+ services.AddControls();
services.AddDanmakuController();
services.AddSingleton();
diff --git a/src/BiliLite.UWP/Themes/Dark.xaml b/src/BiliLite.UWP/Themes/Dark.xaml
index 3438a4ed..9e085fc8 100644
--- a/src/BiliLite.UWP/Themes/Dark.xaml
+++ b/src/BiliLite.UWP/Themes/Dark.xaml
@@ -14,6 +14,8 @@
#CC000000
#ec407a
#008ac5
+ Gray
+ #805C5C5C
#FF282828
diff --git a/src/BiliLite.UWP/Themes/Light.xaml b/src/BiliLite.UWP/Themes/Light.xaml
index 6d373c7e..1e655668 100644
--- a/src/BiliLite.UWP/Themes/Light.xaml
+++ b/src/BiliLite.UWP/Themes/Light.xaml
@@ -14,6 +14,8 @@
#CC000000
#ec407a
#008ac5
+ Gray
+ #805C5C5C
#FFF9F9F9
diff --git a/src/BiliLite.UWP/ViewModels/Comment/CommentControlViewModel.cs b/src/BiliLite.UWP/ViewModels/Comment/CommentControlViewModel.cs
index a5a50aa5..c05db6f4 100644
--- a/src/BiliLite.UWP/ViewModels/Comment/CommentControlViewModel.cs
+++ b/src/BiliLite.UWP/ViewModels/Comment/CommentControlViewModel.cs
@@ -32,9 +32,9 @@ public class CommentControlViewModel : BaseViewModel
public double Width { get; set; } = 320;
- [DependsOn(nameof(Width))] public bool IsNarrowMode => Width < 300;
+ [DependsOn(nameof(Width))] public bool IsNarrowMode => Width < 360;
- [DependsOn(nameof(Width))] public bool IsWideMode => Width >= 300;
+ [DependsOn(nameof(Width))] public bool IsWideMode => Width >= 360;
[DependsOn(nameof(Width))] public bool IsNarrow2Mode => Width < 200;
diff --git a/src/BiliLite.UWP/ViewModels/Comment/CommentViewModel.cs b/src/BiliLite.UWP/ViewModels/Comment/CommentViewModel.cs
index 8cbafb2e..1a8e5a6e 100644
--- a/src/BiliLite.UWP/ViewModels/Comment/CommentViewModel.cs
+++ b/src/BiliLite.UWP/ViewModels/Comment/CommentViewModel.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using Windows.UI;
using Windows.UI.Xaml;
@@ -151,6 +152,18 @@ public string Time
public ObservableCollection Replies { get; set; }
+ public List HotReplies { get; set; }
+
+ [DependsOn(nameof(ShowReplies))]
+ public bool ShowHotReplies
+ {
+ get
+ {
+ if (!SettingService.GetValue(SettingConstants.UI.SHOW_HOT_REPLIES, SettingConstants.UI.DEFAULT_SHOW_HOT_REPLIES)) return false;
+ return !ShowReplies;
+ }
+ }
+
//public ObservableCollection replies { get; set; }
public bool ShowReplies { get; set; } = false;
diff --git a/src/BiliLite.UWP/Modules/EmoteVM.cs b/src/BiliLite.UWP/ViewModels/EmoteViewModel.cs
similarity index 71%
rename from src/BiliLite.UWP/Modules/EmoteVM.cs
rename to src/BiliLite.UWP/ViewModels/EmoteViewModel.cs
index 01a71c98..0d4beef7 100644
--- a/src/BiliLite.UWP/Modules/EmoteVM.cs
+++ b/src/BiliLite.UWP/ViewModels/EmoteViewModel.cs
@@ -1,43 +1,34 @@
-using BiliLite.Models;
-using BiliLite.Models.Requests.Api;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using System;
+using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using BiliLite.Extensions;
+using BiliLite.Models;
+using BiliLite.Models.Requests.Api;
+using BiliLite.ViewModels.Common;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
-namespace BiliLite.Modules
+namespace BiliLite.ViewModels
{
- public class EmoteVM : IModules
+ public class EmoteViewModel : BaseViewModel
{
- readonly EmoteApi emoteApi;
- public EmoteVM()
- {
- emoteApi = new EmoteApi();
- }
-
- private List _packages;
+ private readonly EmoteApi m_emoteApi;
- public List Packages
+ public EmoteViewModel()
{
- get { return _packages; }
- set { _packages = value; DoPropertyChanged("Packages"); }
+ m_emoteApi = new EmoteApi();
}
- private bool _loading = true;
- public bool Loading
- {
- get { return _loading; }
- set { _loading = value; DoPropertyChanged("Loading"); }
- }
+ public List Packages { get; set; }
+
+ public bool Loading { get; set; } = true;
public async Task GetEmote(EmoteBusiness business)
{
try
{
Loading = true;
- var api = emoteApi.UserEmote(business);
+ var api = m_emoteApi.UserEmote(business);
var results = await api.Request();
if (results.status)
@@ -60,7 +51,7 @@ public async Task GetEmote(EmoteBusiness business)
}
catch (Exception ex)
{
- var handel = HandelError(ex);
+ var handel = HandelError(ex);
Notify.ShowMessageToast(handel.message);
}
finally
@@ -70,7 +61,6 @@ public async Task GetEmote(EmoteBusiness business)
}
}
-
public class EmotePackageModel
{
public int id { get; set; }
@@ -81,6 +71,7 @@ public class EmotePackageModel
public int attr { get; set; }
public List emote { get; set; }
}
+
public class EmotePackageItemModel
{
public int id { get; set; }
diff --git a/src/BiliLite.UWP/Modules/User/SendDynamic/AtVM.cs b/src/BiliLite.UWP/ViewModels/User/SendDynamic/AtViewModel.cs
similarity index 78%
rename from src/BiliLite.UWP/Modules/User/SendDynamic/AtVM.cs
rename to src/BiliLite.UWP/ViewModels/User/SendDynamic/AtViewModel.cs
index 5ed9ac29..d88f3015 100644
--- a/src/BiliLite.UWP/Modules/User/SendDynamic/AtVM.cs
+++ b/src/BiliLite.UWP/ViewModels/User/SendDynamic/AtViewModel.cs
@@ -6,48 +6,50 @@
using System.Threading.Tasks;
using System.Windows.Input;
using BiliLite.Extensions;
+using BiliLite.Models.Common.User.SendDynamic;
+using BiliLite.Modules;
+using BiliLite.ViewModels.Common;
+using PropertyChanged;
-namespace BiliLite.Modules.User
+namespace BiliLite.ViewModels.User.SendDynamic
{
- public class AtVM : IModules
+ public class AtViewModel : BaseViewModel
{
- readonly AtApi atApi;
- public AtVM()
+ readonly AtApi m_atApi;
+
+ public AtViewModel()
{
- atApi = new AtApi();
+ m_atApi = new AtApi();
SearchCommand = new RelayCommand(Search);
LoadMoreCommand = new RelayCommand(LoadMore);
Users = new ObservableCollection();
}
+
+ [DoNotNotify]
public ICommand LoadMoreCommand { get; private set; }
- public ICommand SearchCommand { get; private set; }
+ [DoNotNotify]
+ public ICommand SearchCommand { get; private set; }
- private ObservableCollection _user;
+ public ObservableCollection Users { get; set; }
- public ObservableCollection Users
- {
- get { return _user; }
- set { _user = value; DoPropertyChanged("Users"); }
- }
+ public bool Loading { get; set; } = true;
- private bool _loading = true;
- public bool Loading
- {
- get { return _loading; }
- set { _loading = value; DoPropertyChanged("Loading"); }
- }
+ [DoNotNotify]
public int Page { get; set; } = 1;
+
+ [DoNotNotify]
public string Keyword { get; set; }
+
public async Task GetUser()
{
try
{
Loading = true;
- var api = atApi.RecommendAt(Page);
+ var api = m_atApi.RecommendAt(Page);
if (!string.IsNullOrEmpty(Keyword))
{
- api = atApi.SearchUser(Keyword, Page);
+ api = m_atApi.SearchUser(Keyword, Page);
}
if (Page == 1)
{
@@ -102,7 +104,7 @@ public async Task GetUser()
}
catch (Exception ex)
{
- var handel = HandelError(ex);
+ var handel = HandelError(ex);
Notify.ShowMessageToast(handel.message);
}
finally
@@ -132,11 +134,4 @@ public async void Search(string keyword)
await GetUser();
}
}
-}
-public class AtUserModel
-{
- public long ID { get; set; }
- public string UserName { get; set; }
- public string Face { get; set; }
- public string Display { get { return "@" + UserName; } }
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/ViewModels/User/SendDynamic/SendDynamicV2ViewModel.cs b/src/BiliLite.UWP/ViewModels/User/SendDynamic/SendDynamicV2ViewModel.cs
new file mode 100644
index 00000000..61c59fd6
--- /dev/null
+++ b/src/BiliLite.UWP/ViewModels/User/SendDynamic/SendDynamicV2ViewModel.cs
@@ -0,0 +1,256 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using System.Threading.Tasks;
+using Windows.Storage;
+using BiliLite.Extensions;
+using BiliLite.Models;
+using BiliLite.Models.Common;
+using BiliLite.Models.Common.User.SendDynamic;
+using BiliLite.Models.Exceptions;
+using BiliLite.Models.Requests.Api.User;
+using BiliLite.Models.Responses;
+using BiliLite.Services;
+using BiliLite.ViewModels.Common;
+using BiliLite.ViewModels.UserDynamic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PropertyChanged;
+using RestSharp;
+
+namespace BiliLite.ViewModels.User.SendDynamic
+{
+ public class SendDynamicV2ViewModel : BaseViewModel
+ {
+ #region Fields
+
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+ readonly DynamicAPI m_dynamicApi;
+ private List m_atDisplaylist = new List();
+ private List m_atlist = new List();
+
+ #endregion
+
+ #region Constructors
+
+ public SendDynamicV2ViewModel()
+ {
+ m_dynamicApi = new DynamicAPI();
+ Images = new ObservableCollection();
+ }
+
+ #endregion
+
+ #region Properties
+
+ public bool IsRepost { get; set; }
+
+ public DynamicV2ItemViewModel RepostInfo { get; set; }
+
+ public ObservableCollection Images { get; set; }
+
+ public bool Uploading { get; set; }
+
+ public bool ShowImage { get; set; }
+
+ public string Content { get; set; } = "";
+
+ [DependsOn(nameof(Content))]
+ public int Count => Content.Length;
+
+ #endregion
+
+ #region Public Methods
+
+ public void SetRepost(DynamicV2ItemViewModel repostInfo)
+ {
+ RepostInfo = repostInfo;
+ IsRepost = true;
+ }
+
+ public void AddAtItem(AtDisplayModel atDisplayModel)
+ {
+ m_atDisplaylist.Add(atDisplayModel);
+ }
+
+ public async void UploadImage(StorageFile file)
+ {
+ try
+ {
+ Uploading = true;
+ var api = m_dynamicApi.UploadImage();
+
+ var fileStream = await file.OpenAsync(FileAccessMode.Read);
+ var bytes = new byte[fileStream.Size];
+ await fileStream.ReadAsync(bytes.AsBuffer(), (uint)fileStream.Size, Windows.Storage.Streams.InputStreamOptions.None);
+ var client = new RestClient(api.url);
+ var request = new RestRequest();
+ request.Method = Method.Post;
+ request.AddParameter("biz", "draw");
+ request.AddParameter("category", "daily");
+ request.AddFile("file_up", bytes, file.Name);
+ var response = await client.ExecuteAsync(request);
+ var content = response.Content;
+
+ var result = JsonConvert.DeserializeObject>(content);
+ if (result.code == 0)
+ {
+ result.data.ImageSize = (await file.GetBasicPropertiesAsync()).Size / 1024;
+ Images.Add(result.data);
+ }
+ else
+ {
+ Notify.ShowMessageToast(result.message);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Log("图片上传失败", LogType.Fatal, ex);
+ Notify.ShowMessageToast("图片上传失败");
+ }
+ finally
+ {
+ Uploading = false;
+ ShowImage = Images.Count > 0;
+ }
+ }
+
+ ///
+ /// 转发
+ ///
+ public async Task SendRepost()
+ {
+ var ctrl = "[]";
+ var at_uids = "";
+ m_atlist.Clear();
+
+ if (m_atDisplaylist.Count != 0)
+ {
+
+ foreach (var item in m_atDisplaylist.Where(item => Content.Contains(item.Text)))
+ {
+ m_atlist.Add(new AtModel()
+ {
+ Data = item.Data.ToString(),
+ Length = item.Length - 2,
+ Location = Content.IndexOf(item.Text),
+ Type = 1
+ });
+ var d = item.Text.Replace("[", "").Replace("]", "");
+ Content = Content.Replace(item.Text, d);
+ at_uids += item.Data.ToString() + ",";
+ }
+ ctrl = JsonConvert.SerializeObject(m_atlist);
+ at_uids = at_uids.Remove(at_uids.Length - 1, 1);
+ m_atDisplaylist.Clear();
+ }
+ if (Content == "")
+ {
+ Content = "转发动态";
+ }
+
+ try
+ {
+ var httpResults = await m_dynamicApi.RepostDynamic(RepostInfo.Extend.DynIdStr, Content, at_uids, ctrl)
+ .Request();
+ if (!httpResults.status)
+ throw new CustomizedErrorException(httpResults.message);
+ var data = await httpResults.GetData();
+ if (data.code != 0)
+ throw new CustomizedErrorException("发表动态失败:" + data.message);
+
+ Notify.ShowMessageToast("转发成功");
+ m_atDisplaylist.Clear();
+ return true;
+ }
+ catch (CustomizedErrorException ex)
+ {
+ Notify.ShowMessageToast(ex.Message);
+ _logger.Log(ex.Message, LogType.Error, ex);
+ return false;
+ }
+ catch (Exception ex)
+ {
+ Notify.ShowMessageToast("转发动态失败" + ex.Message);
+ _logger.Log("转发动态失败", LogType.Error, ex);
+ return false;
+ }
+ }
+
+ public async Task SendDynamic()
+ {
+ if (Content.Trim().Length == 0)
+ {
+ Notify.ShowMessageToast("不能发送空白动态");
+ return false;
+ }
+
+ var ctrl = "[]";
+ var at_uids = "";
+ m_atlist.Clear();
+ var txt = Content;
+ if (m_atDisplaylist.Count != 0)
+ {
+ foreach (var item in m_atDisplaylist.Where(item => txt.Contains(item.Text)))
+ {
+ m_atlist.Add(new AtModel()
+ {
+ Data = item.Data.ToString(),
+ Length = item.Length - 2,
+ Location = txt.IndexOf(item.Text),
+ Type = 1
+ });
+ var d = item.Text.Replace("[", "").Replace("]", "");
+ txt = txt.Replace(item.Text, d);
+ at_uids += item.Data.ToString() + ",";
+ }
+ ctrl = JsonConvert.SerializeObject(m_atlist);
+ at_uids = at_uids.Remove(at_uids.Length - 1, 1);
+
+ }
+
+ var sendPics = Images.Select(item => new SendImagesModel() { ImgHeight = item.ImageHeight, ImgSize = item.ImageSize, ImgSrc = item.ImageUrl, ImgWidth = item.ImageWidth }).ToList();
+ var imgStr = JsonConvert.SerializeObject(sendPics);
+ try
+ {
+ HttpResults httpResults;
+ if (sendPics.Count == 0)
+ {
+ httpResults = await m_dynamicApi.CreateDynamicText(txt, at_uids, ctrl).Request();
+ }
+ else
+ {
+ httpResults = await m_dynamicApi.CreateDynamicPhoto(imgStr, txt, at_uids, ctrl).Request();
+ }
+
+ if (!httpResults.status)
+ throw new CustomizedErrorException(httpResults.message);
+
+ var data = await httpResults.GetData();
+ if (data.code != 0)
+ throw new CustomizedErrorException("发表动态失败:" + data.message);
+
+ Notify.ShowMessageToast("发表动态成功");
+ m_atDisplaylist.Clear();
+ return true;
+ }
+ catch (CustomizedErrorException ex)
+ {
+ Notify.ShowMessageToast(ex.Message);
+ _logger.Log(ex.Message, LogType.Error, ex);
+ return false;
+ }
+ catch (Exception ex)
+ {
+ Notify.ShowMessageToast("发表动态发生错误");
+ _logger.Log("发表动态失败", LogType.Error, ex);
+ return false;
+ }
+
+ }
+
+ #endregion
+ }
+}
diff --git a/src/BiliLite.UWP/ViewModels/User/SendDynamic/SendDynamicViewModel.cs b/src/BiliLite.UWP/ViewModels/User/SendDynamic/SendDynamicViewModel.cs
new file mode 100644
index 00000000..502598ae
--- /dev/null
+++ b/src/BiliLite.UWP/ViewModels/User/SendDynamic/SendDynamicViewModel.cs
@@ -0,0 +1,256 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using System.Threading.Tasks;
+using Windows.Storage;
+using BiliLite.Extensions;
+using BiliLite.Models;
+using BiliLite.Models.Common;
+using BiliLite.Models.Common.User.SendDynamic;
+using BiliLite.Models.Exceptions;
+using BiliLite.Models.Requests.Api.User;
+using BiliLite.Models.Responses;
+using BiliLite.Services;
+using BiliLite.ViewModels.Common;
+using BiliLite.ViewModels.UserDynamic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PropertyChanged;
+using RestSharp;
+
+namespace BiliLite.ViewModels.User.SendDynamic
+{
+ public class SendDynamicViewModel : BaseViewModel
+ {
+ #region Fields
+
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+ readonly DynamicAPI m_dynamicApi;
+ private List m_atDisplaylist = new List();
+ private List m_atlist = new List();
+
+ #endregion
+
+ #region Constructors
+
+ public SendDynamicViewModel()
+ {
+ m_dynamicApi = new DynamicAPI();
+ Images = new ObservableCollection();
+ }
+
+ #endregion
+
+ #region Properties
+
+ public bool IsRepost { get; set; }
+
+ public UserDynamicItemDisplayViewModel RepostInfo { get; set; }
+
+ public ObservableCollection Images { get; set; }
+
+ public bool Uploading { get; set; }
+
+ public bool ShowImage { get; set; }
+
+ public string Content { get; set; } = "";
+
+ [DependsOn(nameof(Content))]
+ public int Count => Content.Length;
+
+ #endregion
+
+ #region Public Methods
+
+ public void SetRepost(UserDynamicItemDisplayViewModel repostInfo)
+ {
+ RepostInfo = repostInfo;
+ IsRepost = true;
+ }
+
+ public void AddAtItem(AtDisplayModel atDisplayModel)
+ {
+ m_atDisplaylist.Add(atDisplayModel);
+ }
+
+ public async void UploadImage(StorageFile file)
+ {
+ try
+ {
+ Uploading = true;
+ var api = m_dynamicApi.UploadImage();
+
+ var fileStream = await file.OpenAsync(FileAccessMode.Read);
+ var bytes = new byte[fileStream.Size];
+ await fileStream.ReadAsync(bytes.AsBuffer(), (uint)fileStream.Size, Windows.Storage.Streams.InputStreamOptions.None);
+ var client = new RestClient(api.url);
+ var request = new RestRequest();
+ request.Method = Method.Post;
+ request.AddParameter("biz", "draw");
+ request.AddParameter("category", "daily");
+ request.AddFile("file_up", bytes, file.Name);
+ var response = await client.ExecuteAsync(request);
+ var content = response.Content;
+
+ var result = JsonConvert.DeserializeObject>(content);
+ if (result.code == 0)
+ {
+ result.data.ImageSize = (await file.GetBasicPropertiesAsync()).Size / 1024;
+ Images.Add(result.data);
+ }
+ else
+ {
+ Notify.ShowMessageToast(result.message);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Log("图片上传失败", LogType.Fatal, ex);
+ Notify.ShowMessageToast("图片上传失败");
+ }
+ finally
+ {
+ Uploading = false;
+ ShowImage = Images.Count > 0;
+ }
+ }
+
+ ///
+ /// 转发
+ ///
+ public async Task SendRepost()
+ {
+ var ctrl = "[]";
+ var at_uids = "";
+ m_atlist.Clear();
+
+ if (m_atDisplaylist.Count != 0)
+ {
+
+ foreach (var item in m_atDisplaylist.Where(item => Content.Contains(item.Text)))
+ {
+ m_atlist.Add(new AtModel()
+ {
+ Data = item.Data.ToString(),
+ Length = item.Length - 2,
+ Location = Content.IndexOf(item.Text),
+ Type = 1
+ });
+ var d = item.Text.Replace("[", "").Replace("]", "");
+ Content = Content.Replace(item.Text, d);
+ at_uids += item.Data.ToString() + ",";
+ }
+ ctrl = JsonConvert.SerializeObject(m_atlist);
+ at_uids = at_uids.Remove(at_uids.Length - 1, 1);
+ m_atDisplaylist.Clear();
+ }
+ if (Content == "")
+ {
+ Content = "转发动态";
+ }
+
+ try
+ {
+ var httpResults = await m_dynamicApi.RepostDynamic(RepostInfo.DynamicID, Content, at_uids, ctrl)
+ .Request();
+ if (!httpResults.status)
+ throw new CustomizedErrorException(httpResults.message);
+ var data = await httpResults.GetData();
+ if (data.code != 0)
+ throw new CustomizedErrorException("发表动态失败:" + data.message);
+
+ Notify.ShowMessageToast("转发成功");
+ m_atDisplaylist.Clear();
+ return true;
+ }
+ catch (CustomizedErrorException ex)
+ {
+ Notify.ShowMessageToast(ex.Message);
+ _logger.Log(ex.Message, LogType.Error, ex);
+ return false;
+ }
+ catch (Exception ex)
+ {
+ Notify.ShowMessageToast("转发动态失败" + ex.Message);
+ _logger.Log("转发动态失败", LogType.Error, ex);
+ return false;
+ }
+ }
+
+ public async Task SendDynamic()
+ {
+ if (Content.Trim().Length == 0)
+ {
+ Notify.ShowMessageToast("不能发送空白动态");
+ return false;
+ }
+
+ var ctrl = "[]";
+ var at_uids = "";
+ m_atlist.Clear();
+ var txt = Content;
+ if (m_atDisplaylist.Count != 0)
+ {
+ foreach (var item in m_atDisplaylist.Where(item => txt.Contains(item.Text)))
+ {
+ m_atlist.Add(new AtModel()
+ {
+ Data = item.Data.ToString(),
+ Length = item.Length - 2,
+ Location = txt.IndexOf(item.Text),
+ Type = 1
+ });
+ var d = item.Text.Replace("[", "").Replace("]", "");
+ txt = txt.Replace(item.Text, d);
+ at_uids += item.Data.ToString() + ",";
+ }
+ ctrl = JsonConvert.SerializeObject(m_atlist);
+ at_uids = at_uids.Remove(at_uids.Length - 1, 1);
+
+ }
+
+ var sendPics = Images.Select(item => new SendImagesModel() { ImgHeight = item.ImageHeight, ImgSize = item.ImageSize, ImgSrc = item.ImageUrl, ImgWidth = item.ImageWidth }).ToList();
+ var imgStr = JsonConvert.SerializeObject(sendPics);
+ try
+ {
+ HttpResults httpResults;
+ if (sendPics.Count == 0)
+ {
+ httpResults = await m_dynamicApi.CreateDynamicText(txt, at_uids, ctrl).Request();
+ }
+ else
+ {
+ httpResults = await m_dynamicApi.CreateDynamicPhoto(imgStr, txt, at_uids, ctrl).Request();
+ }
+
+ if (!httpResults.status)
+ throw new CustomizedErrorException(httpResults.message);
+
+ var data = await httpResults.GetData();
+ if (data.code != 0)
+ throw new CustomizedErrorException("发表动态失败:" + data.message);
+
+ Notify.ShowMessageToast("发表动态成功");
+ m_atDisplaylist.Clear();
+ return true;
+ }
+ catch (CustomizedErrorException ex)
+ {
+ Notify.ShowMessageToast(ex.Message);
+ _logger.Log(ex.Message, LogType.Error, ex);
+ return false;
+ }
+ catch (Exception ex)
+ {
+ Notify.ShowMessageToast("发表动态发生错误");
+ _logger.Log("发表动态失败", LogType.Error, ex);
+ return false;
+ }
+
+ }
+
+ #endregion
+ }
+}
diff --git a/src/BiliLite.UWP/Modules/User/SendDynamic/TopicVM.cs b/src/BiliLite.UWP/ViewModels/User/SendDynamic/TopicViewModel.cs
similarity index 61%
rename from src/BiliLite.UWP/Modules/User/SendDynamic/TopicVM.cs
rename to src/BiliLite.UWP/ViewModels/User/SendDynamic/TopicViewModel.cs
index 38a51934..e1f76444 100644
--- a/src/BiliLite.UWP/Modules/User/SendDynamic/TopicVM.cs
+++ b/src/BiliLite.UWP/ViewModels/User/SendDynamic/TopicViewModel.cs
@@ -1,37 +1,29 @@
-using BiliLite.Models;
-using BiliLite.Models.Requests.Api.User;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using System;
+using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using BiliLite.Extensions;
+using BiliLite.Models;
+using BiliLite.Models.Common.User.SendDynamic;
+using BiliLite.Models.Requests.Api.User;
+using BiliLite.ViewModels.Common;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
-namespace BiliLite.Modules.User.SendDynamic
+namespace BiliLite.ViewModels.User.SendDynamic
{
- public class TopicVM : IModules
+ public class TopicViewModel : BaseViewModel
{
readonly DynamicAPI dynamicAPI;
- public TopicVM()
+
+ public TopicViewModel()
{
dynamicAPI = new DynamicAPI();
Items = new ObservableCollection();
}
- private ObservableCollection _items;
-
- public ObservableCollection Items
- {
- get { return _items; }
- set { _items = value; DoPropertyChanged("Items"); }
- }
+ public ObservableCollection Items { get; set; }
- private bool _loading = true;
- public bool Loading
- {
- get { return _loading; }
- set { _loading = value; DoPropertyChanged("Loading"); }
- }
+ public bool Loading { get; set; } = true;
public async Task GetTopic()
{
@@ -62,7 +54,7 @@ public async Task GetTopic()
}
catch (Exception ex)
{
- var handel = HandelError(ex);
+ var handel = HandelError(ex);
Notify.ShowMessageToast(handel.message);
}
finally
@@ -70,19 +62,5 @@ public async Task GetTopic()
Loading = false;
}
}
-
-
- }
-
- public class RcmdTopicModel
- {
- public int topic_id { get; set; }
- public string topic_name { get; set; }
- public int is_activity { get; set; }
- public string display
- {
- get { return "#" + topic_name + "#"; }
- }
-
}
}
diff --git a/src/BiliLite.UWP/ViewModels/UserDynamic/DynamicV2ItemViewModel.cs b/src/BiliLite.UWP/ViewModels/UserDynamic/DynamicV2ItemViewModel.cs
new file mode 100644
index 00000000..219633d3
--- /dev/null
+++ b/src/BiliLite.UWP/ViewModels/UserDynamic/DynamicV2ItemViewModel.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Windows.UI.Xaml.Controls;
+using AutoMapper;
+using Bilibili.App.Dynamic.V2;
+using BiliLite.Extensions;
+using BiliLite.Models.Common;
+using BiliLite.Models.Common.UserDynamic;
+using BiliLite.ViewModels.Common;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json;
+using PropertyChanged;
+
+namespace BiliLite.ViewModels.UserDynamic
+{
+ public class DynamicV2ItemViewModel:BaseViewModel
+ {
+ private ModuleDynamic m_dynamic;
+ private ModuleStat m_stat;
+ private readonly IMapper m_mapper;
+
+ public DynamicV2ItemViewModel()
+ {
+ m_mapper = App.ServiceProvider.GetRequiredService();
+ }
+
+ public UserDynamicSpaceViewModel Parent { get; set; }
+
+ public string CardType { get; set; }
+
+ public string ItemType { get; set; }
+
+ public ModuleAuthor Author { get; set; }
+
+ public ModuleAuthorForward AuthorForward { get; set; }
+
+ public ModuleDynamic Dynamic
+ {
+ get
+ {
+ return m_dynamic;
+ }
+ set
+ {
+ m_dynamic = value;
+ if (value.DynForward != null)
+ {
+ Item = m_mapper.Map(value.DynForward.Item);
+ }
+
+ if (value.DynLiveRcmd != null)
+ {
+ LiveInfo = JsonConvert.DeserializeObject(value.DynLiveRcmd.Content);
+ }
+ }
+ }
+
+ public DynLiveInfo LiveInfo { get; set; }
+
+ public ModuleDesc Desc { get; set; }
+
+ public DynamicV2ItemViewModel Item { get; set; }
+
+ public List Items
+ {
+ get
+ {
+ Item.Parent = Parent;
+ return new List()
+ {
+ Item
+ };
+ }
+ }
+
+ public ModuleStat Stat
+ {
+ get => m_stat;
+ set
+ {
+ m_stat = value;
+ Liked = value.LikeInfo.IsLike;
+ LikeCount = value.Like;
+ }
+ }
+
+ public bool Liked { get; set; }
+
+ public long LikeCount { get; set; }
+
+ public Extend Extend { get; set; }
+
+ [DependsOn(nameof(Content))]
+ public bool ShowContent => Desc != null;
+
+ [DependsOn(nameof(Desc))]
+ public RichTextBlock Content
+ {
+ get
+ {
+ try
+ {
+ if (Desc != null)
+ {
+ return
+ Desc.Text.UserDynamicStringToRichText(
+ Extend.DynIdStr, wordNodes: Extend.OpusSummary?.Summary?.Text?.Nodes?.ToList(),
+ bindingCommands: nameof(Parent));
+ }
+
+ return new RichTextBlock();
+ }
+ catch (Exception ex)
+ {
+ return new RichTextBlock();
+ }
+ }
+ }
+
+ public int CoverWidth => 160;
+
+ [DependsOn(nameof(AuthorForward),nameof(CardType),nameof(ItemType))]
+ public bool IsRepost => AuthorForward != null;
+
+ public List ImageInfos
+ {
+ get
+ {
+ var drawItems = this.Dynamic.DynDraw.Items;
+ var allImages = drawItems.Select(x => x.Src).ToList();
+
+ return drawItems.Select((t, i) => new UserDynamicItemDisplayImageInfo()
+ {
+ AllImages = allImages,
+ Height = t.Height,
+ ImageUrl = t.Src,
+ Width = t.Width,
+ Index = i,
+ ImageCommand = Parent.ImageCommand,
+ })
+ .ToList();
+ }
+ }
+
+ [DoNotNotify]
+ public string Verify { get; set; } = Constants.App.TRANSPARENT_IMAGE;
+
+ [DoNotNotify]
+ public string Pendant { get; set; } = Constants.App.TRANSPARENT_IMAGE;
+ }
+}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/ViewModels/UserDynamic/UserDynamicSpaceViewModel.cs b/src/BiliLite.UWP/ViewModels/UserDynamic/UserDynamicSpaceViewModel.cs
new file mode 100644
index 00000000..73396fd4
--- /dev/null
+++ b/src/BiliLite.UWP/ViewModels/UserDynamic/UserDynamicSpaceViewModel.cs
@@ -0,0 +1,318 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using Windows.UI.Xaml.Controls;
+using AutoMapper;
+using Bilibili.App.Dynamic.V2;
+using BiliLite.Extensions;
+using BiliLite.Models.Common;
+using BiliLite.Models.Exceptions;
+using BiliLite.Modules;
+using BiliLite.Pages;
+using BiliLite.Services;
+using BiliLite.ViewModels.Common;
+using BiliLite.Models.Common.UserDynamic;
+using BiliLite.Pages.User;
+using BiliLite.Models;
+using BiliLite.Models.Requests.Api.User;
+using BiliLite.Dialogs;
+using BiliLite.Modules.User;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json;
+
+namespace BiliLite.ViewModels.UserDynamic
+{
+ public class UserDynamicSpaceViewModel : BaseViewModel
+ {
+ #region Fields
+
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+ private readonly GrpcService m_grpcService;
+ private readonly IMapper m_mapper;
+ private readonly DynamicAPI m_dynamicApi;
+ private readonly WatchLaterVM m_watchLaterVm;
+ private int m_page = 1;
+ private string m_offset = null;
+
+ #endregion
+
+ #region Constructors
+
+ public UserDynamicSpaceViewModel(GrpcService grpcService, IMapper mapper)
+ {
+ m_grpcService = grpcService;
+ m_mapper = mapper;
+ m_dynamicApi = new DynamicAPI();
+ m_watchLaterVm = new WatchLaterVM();
+ LoadMoreCommand = new RelayCommand(LoadMore);
+ UserCommand = new RelayCommand