diff --git a/src/BiliLite.UWP/BiliLite.UWP.csproj b/src/BiliLite.UWP/BiliLite.UWP.csproj
index 0e940315..f82f6883 100644
--- a/src/BiliLite.UWP/BiliLite.UWP.csproj
+++ b/src/BiliLite.UWP/BiliLite.UWP.csproj
@@ -143,6 +143,9 @@
DynamicItemV2Control.xaml
+
+ PlayerToast.xaml
+
UserFollowingTagsFlyout.xaml
@@ -151,16 +154,33 @@
+
+
+
+
+
+
+
+
+
+ UserDynamicPage.xaml
+
+
+
+
+
+
+
@@ -213,6 +233,7 @@
DynamicSpacePage.xaml
+
@@ -722,9 +743,6 @@
RecommendPage.xaml
-
- UserDynamicPage.xaml
-
LiveDetailPage.xaml
@@ -958,6 +976,10 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -966,6 +988,10 @@
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
Designer
MSBuild:Compile
@@ -1118,10 +1144,6 @@
Designer
MSBuild:Compile
-
- Designer
- MSBuild:Compile
-
Designer
MSBuild:Compile
@@ -1322,9 +1344,15 @@
107.3.0
+
+ 2.0.2
+
1.0.7
+
+ 0.17.0
+
0.16.8
diff --git a/src/BiliLite.UWP/Controls/DataTemplateSelectors/UserDynamicItemV2DataTemplateSelector.cs b/src/BiliLite.UWP/Controls/DataTemplateSelectors/UserDynamicItemV2DataTemplateSelector.cs
index 54f8981a..6104b425 100644
--- a/src/BiliLite.UWP/Controls/DataTemplateSelectors/UserDynamicItemV2DataTemplateSelector.cs
+++ b/src/BiliLite.UWP/Controls/DataTemplateSelectors/UserDynamicItemV2DataTemplateSelector.cs
@@ -38,6 +38,11 @@ DataTemplate SelectRowTemplate(UserDynamicItemDataTemplateSelector selector,
{ Constants.DynamicTypes.MUSIC, (selector, model) => selector.MusicTemplate },
{ Constants.DynamicTypes.COMMON_SQUARE, (selector, model) => selector.CommonSquareTemplate },
{ Constants.DynamicTypes.LIVE_RCMD, (selector, model) => selector.LiveRcmdTemplate },
+ { Constants.DynamicTypes.LIVE, (selector, model) => selector.LiveTemplate },
+ { Constants.DynamicTypes.CUSTOM_SEASON, (selector, model) => selector.CustomSeasonTemplate },
+ { Constants.DynamicTypes.CUSTOM_ARTICLE, (selector, model) => selector.CustomArticleTemplate },
+ { Constants.DynamicTypes.UGC_SEASON, (selector, model) => selector.UgcSeasonTemplate },
+ { Constants.DynamicTypes.FOLD, (selector, model) => selector.FoldTemplate },
};
}
@@ -63,6 +68,16 @@ DataTemplate SelectRowTemplate(UserDynamicItemDataTemplateSelector selector,
public DataTemplate LiveRcmdTemplate { get; set; }
+ public DataTemplate LiveTemplate { get; set; }
+
+ public DataTemplate UgcSeasonTemplate { get; set; }
+
+ public DataTemplate FoldTemplate { get; set; }
+
+ public DataTemplate CustomSeasonTemplate { get; set; }
+
+ public DataTemplate CustomArticleTemplate { get; set; }
+
public DataTemplate OtherTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
diff --git a/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml b/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml
index b638f5ad..3820962e 100644
--- a/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml
+++ b/src/BiliLite.UWP/Controls/Dynamic/DynamicItemV2Control.xaml
@@ -56,6 +56,10 @@
+
+
+
+
@@ -108,6 +114,8 @@
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
-
-
-
+
+
-
-
-
+
+
-
-
+
+
+
diff --git a/src/BiliLite.UWP/Controls/Dynamic/DynamicV2Template.xaml b/src/BiliLite.UWP/Controls/Dynamic/DynamicV2Template.xaml
index 07f91c81..32588bf4 100644
--- a/src/BiliLite.UWP/Controls/Dynamic/DynamicV2Template.xaml
+++ b/src/BiliLite.UWP/Controls/Dynamic/DynamicV2Template.xaml
@@ -16,7 +16,12 @@
Draw2x2Template="{StaticResource DynamicDraw2x2}"
Draw3x3Template="{StaticResource DynamicDraw3x3}"
CommonSquareTemplate="{StaticResource DynamicCommonSquare}"
- LiveRcmdTemplate="{StaticResource DynamicLiveRcmd}">
+ LiveRcmdTemplate="{StaticResource DynamicLiveRcmd}"
+ LiveTemplate="{StaticResource DynamicLiveRcmd}"
+ UgcSeasonTemplate="{StaticResource DynamicUgcSeason}"
+ FoldTemplate="{StaticResource DynamicFold}"
+ CustomSeasonTemplate="{StaticResource DynamicCustomSeason}"
+ CustomArticleTemplate="{StaticResource DynamicCustomArticle}">
@@ -147,23 +152,37 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ 资源已失效
+
+
+
@@ -197,6 +216,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -340,6 +388,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Controls/PlayerControl.xaml b/src/BiliLite.UWP/Controls/PlayerControl.xaml
index c9e56aaa..13918e7a 100644
--- a/src/BiliLite.UWP/Controls/PlayerControl.xaml
+++ b/src/BiliLite.UWP/Controls/PlayerControl.xaml
@@ -586,19 +586,8 @@
-
-
-
-
-
-
+
+
diff --git a/src/BiliLite.UWP/Controls/PlayerControl.xaml.cs b/src/BiliLite.UWP/Controls/PlayerControl.xaml.cs
index ac4c834d..3b77c24a 100644
--- a/src/BiliLite.UWP/Controls/PlayerControl.xaml.cs
+++ b/src/BiliLite.UWP/Controls/PlayerControl.xaml.cs
@@ -54,6 +54,7 @@ public sealed partial class PlayerControl : UserControl, IDisposable
private readonly bool m_useNsDanmaku = true;
private readonly IDanmakuController m_danmakuController;
private readonly PlayControlViewModel m_viewModel;
+ private readonly PlayerToastService m_playerToastService;
public event PropertyChangedEventHandler PropertyChanged;
private GestureRecognizer gestureRecognizer;
private void DoPropertyChanged(string name)
@@ -63,6 +64,8 @@ private void DoPropertyChanged(string name)
InteractionVideoVM interactionVideoVM;
+ public Canvas PlayerToastContainer => ToolTipContainer;
+
///
/// 铺满窗口事件
///
@@ -126,6 +129,8 @@ public BiliPlayUrlQualitesInfo playUrlInfo
public PlayerControl()
{
m_viewModel = new PlayControlViewModel();
+ m_playerToastService = App.ServiceProvider.GetRequiredService();
+ m_playerToastService.Init(this);
this.InitializeComponent();
dispRequest = new DisplayRequest();
playerHelper = new PlayerVM();
@@ -234,25 +239,6 @@ private async void PlayerControl_Loaded(object sender, RoutedEventArgs e)
danmuTimer.Start();
timer_focus.Start();
-
- // 检查音量是否偏低
- if (Player.Volume > 0.95) return;
- var toolTipText = "";
- if (Player.Volume == 0)
- {
- toolTipText = "静音";
- }
- else
- {
- toolTipText = "音量:" + Player.Volume.ToString("P");
- }
-
- TxtToolTip.Text = toolTipText;
- ToolTip.Background = new SolidColorBrush(Color.FromArgb(90, 240, 240, 240));
- ToolTip.Visibility = Visibility.Visible;
- await Task.Delay(2000);
- ToolTip.Visibility = Visibility.Collapsed;
- ToolTip.Background = new SolidColorBrush(Color.FromArgb(204, 255, 255, 255));
}
private async void _systemMediaTransportControls_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
@@ -322,10 +308,9 @@ private async void PlayerControl_KeyDown(CoreWindow sender, KeyEventArgs args)
_position = 0;
}
Player.Position = _position;
- TxtToolTip.Text = "进度:" + TimeSpan.FromSeconds(Player.Position).ToString(@"hh\:mm\:ss");
- ToolTip.Visibility = Visibility.Visible;
- await Task.Delay(2000);
- ToolTip.Visibility = Visibility.Collapsed;
+
+ m_playerToastService.Show(
+ PlayerToastService.PROGRESS_KEY, "进度:" + TimeSpan.FromSeconds(Player.Position).ToString(@"hh\:mm\:ss"));
}
}
@@ -344,34 +329,25 @@ private async void PlayerControl_KeyDown(CoreWindow sender, KeyEventArgs args)
_position = Player.Duration;
}
Player.Position = _position;
- TxtToolTip.Text = "进度:" + TimeSpan.FromSeconds(Player.Position).ToString(@"hh\:mm\:ss");
- ToolTip.Visibility = Visibility.Visible;
- await Task.Delay(2000);
- ToolTip.Visibility = Visibility.Collapsed;
+
+ m_playerToastService.Show(
+ PlayerToastService.PROGRESS_KEY, "进度:" + TimeSpan.FromSeconds(Player.Position).ToString(@"hh\:mm\:ss"));
}
}
break;
case Windows.System.VirtualKey.Up:
Player.Volume += 0.1;
- TxtToolTip.Text = "音量:" + Player.Volume.ToString("P");
- ToolTip.Visibility = Visibility.Visible;
- await Task.Delay(2000);
- ToolTip.Visibility = Visibility.Collapsed;
+ m_playerToastService.Show(PlayerToastService.VOLUME_KEY, "音量:" + Player.Volume.ToString("P"));
break;
case Windows.System.VirtualKey.Down:
Player.Volume -= 0.1;
- if (Player.Volume == 0)
+ var txtToolTipText = "静音";
+ if (Player.Volume > 0)
{
- TxtToolTip.Text = "静音";
+ txtToolTipText = "音量:" + Player.Volume.ToString("P");
}
- else
- {
- TxtToolTip.Text = "音量:" + Player.Volume.ToString("P");
- }
- ToolTip.Visibility = Visibility.Visible;
- await Task.Delay(2000);
- ToolTip.Visibility = Visibility.Collapsed;
+ m_playerToastService.Show(PlayerToastService.VOLUME_KEY, txtToolTipText);
break;
case Windows.System.VirtualKey.Escape:
IsFullScreen = false;
@@ -404,10 +380,8 @@ private async void PlayerControl_KeyDown(CoreWindow sender, KeyEventArgs args)
_position = Player.Duration;
}
Player.Position = _position;
- TxtToolTip.Text = "跳过OP(快进90秒)";
- ToolTip.Visibility = Visibility.Visible;
- await Task.Delay(2000);
- ToolTip.Visibility = Visibility.Collapsed;
+
+ m_playerToastService.Show(PlayerToastService.MSG_KEY, "跳过OP(快进90秒)");
}
}
break;
@@ -456,7 +430,7 @@ private async void PlayerControl_KeyDown(CoreWindow sender, KeyEventArgs args)
}
BottomCBSpeed.SelectedIndex += 1;
-
+ m_playerToastService.Show(PlayerToastService.SPEED_KEY,(BottomCBSpeed.SelectedItem as ComboBoxItem).Content.ToString());
break;
case Windows.System.VirtualKey.F2:
case (Windows.System.VirtualKey)222:
@@ -467,6 +441,7 @@ private async void PlayerControl_KeyDown(CoreWindow sender, KeyEventArgs args)
return;
}
BottomCBSpeed.SelectedIndex -= 1;
+ m_playerToastService.Show(PlayerToastService.SPEED_KEY, (BottomCBSpeed.SelectedItem as ComboBoxItem).Content.ToString());
break;
case Windows.System.VirtualKey.F3:
case Windows.System.VirtualKey.V:
@@ -485,6 +460,29 @@ private async void PlayerControl_KeyDown(CoreWindow sender, KeyEventArgs args)
}
}
+ ///
+ /// 检查音量和亮度是否偏低
+ ///
+ private void CheckVolumeAndBrightnessLower()
+ {
+ // 检查音量是否偏低
+ if (Player.Volume > 0.95) return;
+ var toolTipText = "";
+ if (Player.Volume == 0)
+ {
+ toolTipText = "静音";
+ }
+ else
+ {
+ toolTipText = "音量:" + Player.Volume.ToString("P");
+ }
+
+ m_playerToastService.Show(PlayerToastService.VOLUME_KEY, toolTipText);
+
+ // 检查亮度是否偏低
+ if (Math.Abs(Brightness - 1) > 0.8) return;
+ m_playerToastService.Show(PlayerToastService.BRIGHTNESS_KEY, "亮度:" + Math.Abs(Brightness - 1).ToString("P"));
+ }
private void LoadDanmuSetting()
{
@@ -660,16 +658,21 @@ private void LoadDanmuSetting()
}
private void LoadPlayerSetting()
{
-
//音量
- Player.Volume = SettingService.GetValue(SettingConstants.Player.PLAYER_VOLUME, 1.0);
- SliderVolume.ValueChanged += new RangeBaseValueChangedEventHandler((e, args) =>
+ Player.Volume = SettingService.GetValue(SettingConstants.Player.PLAYER_VOLUME, SettingConstants.Player.DEFAULT_PLAYER_VOLUME);
+
+ var lockPlayerVolume = SettingService.GetValue(SettingConstants.Player.LOCK_PLAYER_VOLUME, SettingConstants.Player.DEFAULT_LOCK_PLAYER_VOLUME);
+ if (!lockPlayerVolume)
{
- SettingService.SetValue(SettingConstants.Player.PLAYER_VOLUME, SliderVolume.Value);
- });
+ SliderVolume.ValueChanged += new RangeBaseValueChangedEventHandler((e, args) =>
+ {
+ SettingService.SetValue(SettingConstants.Player.PLAYER_VOLUME, SliderVolume.Value);
+ });
+ }
//亮度
- //_brightness = SettingService.GetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, 0);
- //BrightnessShield.Opacity = _brightness;
+ lockBrightness = SettingService.GetValue(SettingConstants.Player.LOCK_PLAYER_BRIGHTNESS, SettingConstants.Player.DEFAULT_LOCK_PLAYER_BRIGHTNESS);
+ _brightness = SettingService.GetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, SettingConstants.Player.DEFAULT_PLAYER_BRIGHTNESS);
+ BrightnessShield.Opacity = _brightness;
//播放模式
var selectedValue = (PlayUrlCodecMode)SettingService.GetValue(SettingConstants.Player.DEFAULT_VIDEO_TYPE, (int)DefaultVideoTypeOptions.DEFAULT_VIDEO_TYPE);
@@ -1056,6 +1059,8 @@ private async Task SetPlayItem(int index)
await GetPlayerInfo();
+ CheckVolumeAndBrightnessLower();
+
Player.ABPlay = VideoPlayHistoryHelper.FindABPlayHistory(CurrentPlayItem);
if (Player.ABPlay == null)
{
@@ -1922,6 +1927,7 @@ private void TopBtnCloseDanmaku_Click(object sender, RoutedEventArgs e)
double ssValue = 0;
bool ManipulatingBrightness = false;
double _brightness = 0;
+ private bool lockBrightness = true;
PlayerHoldingAction m_playerHoldingAction;
double Brightness
{
@@ -1930,8 +1936,8 @@ double Brightness
{
_brightness = value;
BrightnessShield.Opacity = value;
- //SettingHelper.SetValue(SettingHelper.Player.PLAYER_BRIGHTNESS, _brightness);
- //}
+ if(!lockBrightness)
+ SettingService.SetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, _brightness);
}
}
private void InitializeGesture()
@@ -1986,23 +1992,20 @@ private void StopHolding()
private void StartHighRateSpeedPlay()
{
- TxtToolTip.Text = "倍速播放中";
- ToolTip.Visibility = Visibility.Visible;
+ m_playerToastService.KeepStart(PlayerToastService.ACCELERATING_KEY, "倍速播放中");
var highRatePlaySpeed = SettingService.GetValue(SettingConstants.Player.HIGH_RATE_PLAY_SPEED, 2.0d);
Player.SetRate(highRatePlaySpeed);
}
private void StopHighRateSpeedPlay()
{
- ToolTip.Visibility = Visibility.Collapsed;
+ m_playerToastService.KeepClose(PlayerToastService.ACCELERATING_KEY);
Player.SetRate(SettingService.GetValue(SettingConstants.Player.DEFAULT_VIDEO_SPEED, 1.0d));
}
private void OnManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
ssValue = 0;
- //TxtToolTip.Text = "";
- ToolTip.Visibility = Visibility.Visible;
if (e.Position.X < this.ActualWidth / 2)
ManipulatingBrightness = true;
@@ -2068,7 +2071,6 @@ private void OnManipulationCompleted(object sender, ManipulationCompletedEventAr
{
Player.Position = Player.Position + ssValue;
}
- ToolTip.Visibility = Visibility.Collapsed;
}
private void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)
@@ -2204,8 +2206,7 @@ private void HandleSlideProgressDelta(double delta)
pos = Player.Duration;
//txt_Post.Text = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00") + "/" + mediaElement.MediaPlayer.PlaybackSession.NaturalDuration.TimeSpan.Hours.ToString("00") + ":" + mediaElement.MediaPlayer.PlaybackSession.NaturalDuration.TimeSpan.Minutes.ToString("00") + ":" + mediaElement.MediaPlayer.PlaybackSession.NaturalDuration.TimeSpan.Seconds.ToString("00");
- TxtToolTip.Text = TimeSpan.FromSeconds(pos).ToString(@"hh\:mm\:ss");
- //Notify.ShowMessageToast(ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00"), 3000);
+ m_playerToastService.Show(PlayerToastService.PROGRESS_KEY, TimeSpan.FromSeconds(pos).ToString(@"hh\:mm\:ss"));
}
private void HandleSlideVolumeDelta(double delta)
@@ -2226,8 +2227,7 @@ private void HandleSlideVolumeDelta(double delta)
Player.Volume = volume;
//slider_V.Value += d;
}
- TxtToolTip.Text = "音量:" + Player.Volume.ToString("P");
- //Notify.ShowMessageToast("音量:" + mediaElement.MediaPlayer.Volume.ToString("P"), 3000);
+ m_playerToastService.Show(PlayerToastService.VOLUME_KEY, "音量:" + Player.Volume.ToString("P"));
}
private void HandleSlideBrightnessDelta(double delta)
{
@@ -2240,7 +2240,7 @@ private void HandleSlideBrightnessDelta(double delta)
{
Brightness = Math.Max(Brightness - dd, 0);
}
- TxtToolTip.Text = "亮度:" + Math.Abs(Brightness - 1).ToString("P");
+ m_playerToastService.Show(PlayerToastService.BRIGHTNESS_KEY, "亮度:" + Math.Abs(Brightness - 1).ToString("P"));
}
#endregion
private void BottomBtnList_Click(object sender, RoutedEventArgs e)
@@ -2443,7 +2443,7 @@ private void Player_PlayBufferEnd(object sender, EventArgs e)
m_danmakuController.Resume();
}
- private void Player_PlayMediaEnded(object sender, EventArgs e)
+ private async void Player_PlayMediaEnded(object sender, EventArgs e)
{
if (CurrentPlayItem.is_interaction)
{
@@ -2458,7 +2458,10 @@ private void Player_PlayMediaEnded(object sender, EventArgs e)
}
_logger.Debug("视频结束,上报进度");
- playerHelper.ReportHistory(CurrentPlayItem, Player.Duration).RunWithoutAwait();
+ await playerHelper.ReportHistory(CurrentPlayItem, Player.Duration);
+
+ _logger.Debug("进度归0");
+ await playerHelper.ReportHistory(CurrentPlayItem, 0);
//列表顺序播放
if (PlayerSettingPlayMode.SelectedIndex == 0)
{
diff --git a/src/BiliLite.UWP/Controls/PlayerToast.xaml b/src/BiliLite.UWP/Controls/PlayerToast.xaml
new file mode 100644
index 00000000..b9779b25
--- /dev/null
+++ b/src/BiliLite.UWP/Controls/PlayerToast.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BiliLite.UWP/Controls/PlayerToast.xaml.cs b/src/BiliLite.UWP/Controls/PlayerToast.xaml.cs
new file mode 100644
index 00000000..1b3e7dd6
--- /dev/null
+++ b/src/BiliLite.UWP/Controls/PlayerToast.xaml.cs
@@ -0,0 +1,45 @@
+using System.Threading.Tasks;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Media.Animation;
+using BiliLite.ViewModels;
+
+//https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板
+
+namespace BiliLite.Controls
+{
+ public sealed partial class PlayerToast : UserControl
+ {
+ private readonly PlayerToastViewModel m_viewModel;
+
+ public PlayerToast(PlayerToastViewModel viewModel)
+ {
+ m_viewModel = viewModel;
+ this.InitializeComponent();
+ }
+
+ public string Text
+ {
+ set => m_viewModel.Text = value;
+ }
+
+ public void Show()
+ {
+ var storyboard = (Storyboard)this.Resources["ShowToast"];
+ storyboard.Begin();
+ }
+
+ public async Task Hide()
+ {
+ var storyboard = (Storyboard)this.Resources["HideToast"];
+ storyboard.Begin();
+ var tcs = new TaskCompletionSource();
+
+ storyboard.Completed += (s, e) =>
+ {
+ tcs.SetResult(true);
+ };
+ storyboard.Begin();
+ await tcs.Task;
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Extensions/ControlsExtensions.cs b/src/BiliLite.UWP/Extensions/ControlsExtensions.cs
index 955ccf7a..c192b9d3 100644
--- a/src/BiliLite.UWP/Extensions/ControlsExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/ControlsExtensions.cs
@@ -1,4 +1,5 @@
-using BiliLite.Dialogs;
+using BiliLite.Controls;
+using BiliLite.Dialogs;
using Microsoft.Extensions.DependencyInjection;
namespace BiliLite.Extensions
@@ -9,6 +10,7 @@ public static IServiceCollection AddControls(this IServiceCollection services)
{
services.AddTransient();
services.AddTransient();
+ services.AddTransient();
return services;
}
}
diff --git a/src/BiliLite.UWP/Extensions/MapperExtensions.cs b/src/BiliLite.UWP/Extensions/MapperExtensions.cs
index 60751366..144a79de 100644
--- a/src/BiliLite.UWP/Extensions/MapperExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/MapperExtensions.cs
@@ -144,7 +144,16 @@ public static IServiceCollection AddMapper(this IServiceCollection services)
src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleOpusSummary).ModuleOpusSummary))
.ForMember(dest => dest.Stat,
opt => opt.MapFrom(src =>
- src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleStat).ModuleStat));
+ src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleStat).ModuleStat))
+ .ForMember(dest => dest.Fold,
+ opt => opt.MapFrom(src =>
+ src.Modules.FirstOrDefault(x => x.ModuleType == DynModuleType.ModuleFold).ModuleFold))
+ .ForMember(dest => dest.SourceJson,
+ opt => opt.MapFrom(src =>
+ src.ToString()));
+
+ expression.CreateMap();
+ expression.CreateMap();
}));
services.AddSingleton(mapper);
diff --git a/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs b/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs
index 1b309f2d..a4e5d98a 100644
--- a/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs
+++ b/src/BiliLite.UWP/Extensions/ViewModelExtensions.cs
@@ -34,6 +34,8 @@ public static IServiceCollection AddViewModels(this IServiceCollection services)
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 6a47ea94..dd3df3df 100644
--- a/src/BiliLite.UWP/MainPage.xaml.cs
+++ b/src/BiliLite.UWP/MainPage.xaml.cs
@@ -12,6 +12,7 @@
using BiliLite.Models.Common;
using BiliLite.Extensions;
using BiliLite.Services;
+using Microsoft.Extensions.DependencyInjection;
// https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x804 上介绍了“空白页”项模板
@@ -20,12 +21,15 @@ namespace BiliLite
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class MainPage : Windows.UI.Xaml.Controls.Page
+ public sealed partial class MainPage : Windows.UI.Xaml.Controls.Page, IMainPage
{
private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+ private readonly ShortcutKeyService m_shortcutKeyService;
public MainPage()
{
+ m_shortcutKeyService = App.ServiceProvider.GetRequiredService();
+ m_shortcutKeyService.SetMainPage(this);
this.InitializeComponent();
// 处理标题栏
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
@@ -42,6 +46,26 @@ public MainPage()
App.Current.Suspending += Current_Suspending;
// Window.Current.Content.PointerPressed += Content_PointerPressed;
+
+ Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += Dispatcher_AcceleratorKeyActivated;
+ }
+
+ public object CurrentPage
+ {
+ get
+ {
+ if (!(tabView.SelectedItem is TabViewItem tabItem)) return null;
+ if (!(tabItem.Content is Frame frame)) return null;
+ return frame.Content;
+ }
+ }
+
+ private void Dispatcher_AcceleratorKeyActivated(Windows.UI.Core.CoreDispatcher sender, Windows.UI.Core.AcceleratorKeyEventArgs args)
+ {
+ if (args.EventType.ToString().Contains("Down"))
+ {
+ m_shortcutKeyService.HandleKeyDown(args.VirtualKey);
+ }
}
private async void Current_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
@@ -259,7 +283,6 @@ private void CloseSelectedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sen
ClosePage((TabViewItem)tabView.SelectedItem);
}
args.Handled = true;
-
}
private void tabView_TabItemsChanged(TabView sender, IVectorChangedEventArgs args)
diff --git a/src/BiliLite.UWP/Models/Attributes/SettingDefaultValueAttribute.cs b/src/BiliLite.UWP/Models/Attributes/SettingDefaultValueAttribute.cs
new file mode 100644
index 00000000..3e8746b4
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Attributes/SettingDefaultValueAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace BiliLite.Models.Attributes
+{
+ public class SettingDefaultValueAttribute : Attribute
+ {
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Attributes/SettingKeyAttribute.cs b/src/BiliLite.UWP/Models/Attributes/SettingKeyAttribute.cs
new file mode 100644
index 00000000..6cdd8913
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Attributes/SettingKeyAttribute.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace BiliLite.Models.Attributes
+{
+ public class SettingKeyAttribute:Attribute
+ {
+ public SettingKeyAttribute()
+ {
+ Type = typeof(string);
+ }
+
+ public SettingKeyAttribute(Type type)
+ {
+ Type = type;
+ }
+
+ public Type Type { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs b/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs
index 821b3282..ab32b07b 100644
--- a/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs
+++ b/src/BiliLite.UWP/Models/Builders/DynamicItemDisplayModelBuilder.cs
@@ -82,7 +82,7 @@ public DynamicItemDisplayModelBuilder SwitchType(IMapper mapper, JObject card, J
m_displayViewModel.ImagesInfo = imgs;
break;
}
- case UserDynamicDisplayType.Repost when card.ContainsKey("origin_user"):
+ case UserDynamicDisplayType.Repost when card.ContainsKey("origin_user") && card["origin_user"].ToString() != string.Empty:
{
var originUser = JsonConvert.DeserializeObject(card["origin_user"].ToString());
var model = new DynamicCardModel
diff --git a/src/BiliLite.UWP/Models/Common/Anime/AnimeRankModel.cs b/src/BiliLite.UWP/Models/Common/Anime/AnimeRankModel.cs
index 2526638d..15449ffa 100644
--- a/src/BiliLite.UWP/Models/Common/Anime/AnimeRankModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Anime/AnimeRankModel.cs
@@ -16,11 +16,11 @@ public class AnimeRankModel : ISeasonItem
[JsonProperty("index_show")]
public string IndexShow { get; set; }
- public int Follow { get; set; }
+ public long Follow { get; set; }
- public int Danmaku { get; set; }
+ public long Danmaku { get; set; }
- public int View { get; set; }
+ public long View { get; set; }
[JsonProperty("show_badge")]
public bool ShowBadge => !string.IsNullOrEmpty(Badge);
diff --git a/src/BiliLite.UWP/Models/Common/Constants.cs b/src/BiliLite.UWP/Models/Common/Constants.cs
index 6fce164c..d83ae20d 100644
--- a/src/BiliLite.UWP/Models/Common/Constants.cs
+++ b/src/BiliLite.UWP/Models/Common/Constants.cs
@@ -101,6 +101,18 @@ public static class DynamicTypes
public const string COMMON_SQUARE = "CommonSquare";
public const string LIVE_RCMD = "LiveRcmd";
+
+ public const string LIVE = "Live";
+
+ public const string UGC_SEASON = "UgcSeason";
+
+ public const string FOLD = "Fold";
+
+ public const string BANNER = "Banner";
+
+ public const string CUSTOM_SEASON = "CustomSeason";
+
+ public const string CUSTOM_ARTICLE = "CustomArticle";
}
}
}
diff --git a/src/BiliLite.UWP/Models/Common/Dynamic/DynamicDescModel.cs b/src/BiliLite.UWP/Models/Common/Dynamic/DynamicDescModel.cs
index d6ad714d..3e212886 100644
--- a/src/BiliLite.UWP/Models/Common/Dynamic/DynamicDescModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Dynamic/DynamicDescModel.cs
@@ -14,11 +14,11 @@ public class DynamicDescModel
public string Rid { get; set; }
- public int View { get; set; }
+ public long View { get; set; }
- public int Like { get; set; }
+ public long Like { get; set; }
- public int Comment { get; set; }
+ public long Comment { get; set; }
[JsonProperty("is_liked")]
public int IsLiked { get; set; }
diff --git a/src/BiliLite.UWP/Models/Common/Dynamic/DynamicVideoCardStatModel.cs b/src/BiliLite.UWP/Models/Common/Dynamic/DynamicVideoCardStatModel.cs
index 79d93dab..eb436cc7 100644
--- a/src/BiliLite.UWP/Models/Common/Dynamic/DynamicVideoCardStatModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Dynamic/DynamicVideoCardStatModel.cs
@@ -2,18 +2,18 @@
{
public class DynamicVideoCardStatModel
{
- public int Coin { get; set; }
+ public long Coin { get; set; }
- public int Danmaku { get; set; }
+ public long Danmaku { get; set; }
- public int Favorite { get; set; }
+ public long Favorite { get; set; }
- public int Like { get; set; }
+ public long Like { get; set; }
- public int Reply { get; set; }
+ public long Reply { get; set; }
- public int Share { get; set; }
+ public long Share { get; set; }
- public int View { get; set; }
+ public long View { get; set; }
}
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/Enumerates.cs b/src/BiliLite.UWP/Models/Common/Enumerates.cs
index 5e61cd59..a8d96782 100644
--- a/src/BiliLite.UWP/Models/Common/Enumerates.cs
+++ b/src/BiliLite.UWP/Models/Common/Enumerates.cs
@@ -435,4 +435,12 @@ public enum SeasonIdType
SeasonId,
EpId,
}
+
+ public enum UserDynamicShowType
+ {
+ All = 0,
+ Video = 1,
+ Season = 2,
+ Article = 3
+ }
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs b/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs
index 829c070c..bf47bf1f 100644
--- a/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs
+++ b/src/BiliLite.UWP/Models/Common/Home/DefaultHomeNavItems.cs
@@ -1,9 +1,60 @@
-using System.Collections.Generic;
+using System;
+using BiliLite.Services;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json;
namespace BiliLite.Models.Common.Home
{
public static class DefaultHomeNavItems
{
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+
+ public static List CheckHomeNavItems(List navList)
+ {
+ var defaultItems = GetDefaultHomeNavItems();
+ defaultItems.AddRange(GetDefaultHideHomeNavItems());
+ var result = new List(navList);
+ foreach (var homeNavItem in navList.Where(homeNavItem =>
+ defaultItems.All(x => x.Title != homeNavItem.Title || x.Page != homeNavItem.Page)))
+ {
+ result.Remove(homeNavItem);
+ }
+ SettingService.SetValue(SettingConstants.UI.HOEM_ORDER, result);
+
+ return result;
+ }
+
+ public static List GetHomeNavItems()
+ {
+ var homeNavItemList = new List();
+ var tempHomeNavItemList = SettingService.GetValue>(SettingConstants.UI.HOEM_ORDER,
+ null);
+
+ if (tempHomeNavItemList == null)
+ {
+ homeNavItemList = DefaultHomeNavItems.GetDefaultHomeNavItems();
+ return homeNavItemList;
+ }
+ else
+ {
+ foreach (var item in tempHomeNavItemList)
+ {
+ try
+ {
+ var navItem = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(item));
+ homeNavItemList.Add(navItem);
+ }
+ catch (Exception ex)
+ {
+ _logger.Warn(ex.Message, ex);
+ }
+ }
+ }
+ homeNavItemList = DefaultHomeNavItems.CheckHomeNavItems(homeNavItemList);
+ return homeNavItemList;
+ }
+
public static List GetDefaultHomeNavItems()
{
return new List()
@@ -143,7 +194,7 @@ public static List GetDefaultHideHomeNavItems()
Title = "我的收藏",
NeedLogin = true,
Show = false
- }
+ },
};
}
}
diff --git a/src/BiliLite.UWP/Models/Common/Recommend/RecommendItemArgsModel.cs b/src/BiliLite.UWP/Models/Common/Recommend/RecommendItemArgsModel.cs
index 734803ef..46c6929a 100644
--- a/src/BiliLite.UWP/Models/Common/Recommend/RecommendItemArgsModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Recommend/RecommendItemArgsModel.cs
@@ -18,6 +18,6 @@ public class RecommendItemArgsModel
public string Rname { get; set; }
- public int Aid { get; set; }
+ public long Aid { get; set; }
}
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/Season/SeasonDetailStatModel.cs b/src/BiliLite.UWP/Models/Common/Season/SeasonDetailStatModel.cs
index f40534b0..777da5f5 100644
--- a/src/BiliLite.UWP/Models/Common/Season/SeasonDetailStatModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Season/SeasonDetailStatModel.cs
@@ -2,20 +2,20 @@
{
public class SeasonDetailStatModel
{
- public int Coins { get; set; }
+ public long Coins { get; set; }
- public int Danmakus { get; set; }
+ public long Danmakus { get; set; }
- public int Favorites { get; set; }
+ public long Favorites { get; set; }
public string Followers { get; set; }
public string Play { get; set; }
- public int Reply { get; set; }
+ public long Reply { get; set; }
- public int Share { get; set; }
+ public long Share { get; set; }
- public int Views { get; set; }
+ public long Views { get; set; }
}
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Common/SettingConstants.cs b/src/BiliLite.UWP/Models/Common/SettingConstants.cs
index 84ac4dec..8770c526 100644
--- a/src/BiliLite.UWP/Models/Common/SettingConstants.cs
+++ b/src/BiliLite.UWP/Models/Common/SettingConstants.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using BiliLite.Models.Attributes;
using BiliLite.Services;
namespace BiliLite.Models.Common
@@ -10,75 +11,98 @@ public class UI
///
/// 加载原图
///
+ [SettingKey(typeof(bool))]
public const string ORTGINAL_IMAGE = "originalImage";
///
/// 主题颜色
///
+ [SettingKey(typeof(int))]
public const string THEME_COLOR = "themeColor";
///
/// 主题,0为默认,1为浅色,2为深色
///
+ [SettingKey(typeof(int))]
public const string THEME = "theme";
///
/// 显示模式,0为多标签,1为单窗口,2为多窗口
///
+ [SettingKey(typeof(int))]
public const string DISPLAY_MODE = "displayMode";
///
/// 缓存首页
///
+ [SettingKey(typeof(bool))]
public const string CACHE_HOME = "cacheHome";
///
/// 首页排序
///
+ [SettingKey(typeof(object))]
public const string HOEM_ORDER = "homePageOrder";
///
/// 右侧详情宽度
///
+ [SettingKey(typeof(double))]
public const string RIGHT_DETAIL_WIDTH = "PlayerRightDetailWidth";
///
/// 右侧详情宽度可调整
///
+ [SettingKey(typeof(bool))]
public const string RIGHT_WIDTH_CHANGEABLE = "PlayerRightDetailWidthChangeable";
+ [SettingKey(typeof(double))]
+ public const string DYNAMIC_COMMENT_WIDTH = "DynamicCommentWidth";
+
+ [SettingDefaultValue]
+ public const double DEFAULT_DYNAMIC_COMMENT_WIDTH = 480;
+
///
/// 图片圆角半径
///
+ [SettingKey(typeof(double))]
public const string IMAGE_CORNER_RADIUS = "ImageCornerRadius";
///
/// 视频详情显示封面
///
+ [SettingKey(typeof(bool))]
public const string SHOW_DETAIL_COVER = "showDetailCover";
+
///
/// 新窗口打开图片预览
///
+ [SettingKey(typeof(bool))]
public const string NEW_WINDOW_PREVIEW_IMAGE = "newWindowPreviewImage";
///
/// 动态显示样式
///
+ [SettingKey(typeof(int))]
public const string DYNAMIC_DISPLAY_MODE = "dynamicDiaplayMode";
///
/// 首页推荐样式
///
+ [SettingKey(typeof(int))]
public const string RECMEND_DISPLAY_MODE = "recomendDiaplayMode";
///
/// 右侧选项卡
///
+ [SettingKey(typeof(int))]
public const string DETAIL_DISPLAY = "detailDisplay";
///
/// 动态显示样式
///
+ [SettingKey]
public const string BACKGROUND_IMAGE = "BackgroundImage";
///
/// 鼠标功能键行为
///
+ [SettingKey(typeof(int))]
public const string MOUSE_MIDDLE_ACTION = "MouseMiddleAction";
///
/// 隐藏赞助按钮
@@ -87,35 +111,42 @@ public class UI
///
/// 隐藏广告按钮
///
+ [SettingKey(typeof(bool))]
public const string HIDE_AD = "HideAD";
///
/// 浏览器打开无法处理的链接
///
+ [SettingKey(typeof(bool))]
public const string OPEN_URL_BROWSER = "OpenUrlWithBrowser";
///
/// 启用长评论折叠
///
+ [SettingKey(typeof(bool))]
public const string ENABLE_COMMENT_SHRINK = "EnableCommentShrink";
///
/// 折叠评论长度
///
+ [SettingKey(typeof(int))]
public const string COMMENT_SHRINK_LENGTH = "CommentShrinkLength";
///
/// 默认折叠评论长度
///
+ [SettingDefaultValue]
public const int COMMENT_SHRINK_DEFAULT_LENGTH = 75;
///
/// 显示评论热门回复
///
+ [SettingKey(typeof(bool))]
public const string SHOW_HOT_REPLIES = "ShowHotReplies";
///
/// 显示评论热门回复默认选项
///
+ [SettingDefaultValue]
public const bool DEFAULT_SHOW_HOT_REPLIES = true;
}
@@ -124,62 +155,75 @@ public class Account
///
/// 登录后ACCESS_KEY
///
+ [SettingKey]
public const string ACCESS_KEY = "accesskey";
///
/// 登录后REFRESH_KEY
///
+ [SettingKey]
public const string REFRESH_KEY = "refreshkey";
///
/// 到期时间
///
+ [SettingKey(typeof(object))]
public const string ACCESS_KEY_EXPIRE_DATE = "expireDate";
///
/// 用户ID
///
+ [SettingKey(typeof(long))]
public const string USER_ID = "uid";
///
/// 到期时间
///
+ [SettingKey(typeof(object))]
public const string USER_PROFILE = "userProfile";
///
/// 是否web登录
///
+ [SettingKey(typeof(bool))]
public const string IS_WEB_LOGIN = "isWebLogin";
///
/// Cookies
///
+ [SettingKey]
public const string BILIBILI_COOKIES = "BiliBiliCookies";
///
/// 登录用AppKey
///
+ [SettingKey]
public const string LOGIN_APP_KEY_SECRET = "LoginAppKeySecret";
///
/// 默认登录用AppKey
///
+ [SettingDefaultValue]
public static ApiKeyInfo DefaultLoginAppKeySecret = ApiHelper.AndroidKey;
///
/// Wbi令牌ImgKey参数
///
+ [SettingKey]
public const string WBI_IMG_KEY = "WbiImgKey";
///
/// Wbi令牌SubKey参数
///
+ [SettingKey]
public const string WBI_SUB_KEY = "WbiSubKey";
///
/// Wbi令牌参数获取时间(unix时间戳)
///
+ [SettingKey(typeof(long))]
public const string WBI_KEY_TIME = "WbiKeyTime";
///
/// Wbi令牌参数刷新时间(单位分钟,暂定2小时)
///
+ [SettingDefaultValue]
public const int WBI_KEY_REFRESH_TIME = 120;
}
@@ -188,90 +232,111 @@ public class VideoDanmaku
///
/// 默认弹幕引擎
///
+ [SettingDefaultValue]
public const DanmakuEngineType DEFAULT_DANMAKU_ENGINE = DanmakuEngineType.NSDanmaku;
///
/// 弹幕引擎
///
+ [SettingKey(typeof(int))]
public const string DANMAKU_ENGINE = "DanmakuEngine";
///
/// 显示弹幕 Visibility
///
+ [SettingKey(typeof(object))]
public const string SHOW = "VideoDanmuShow";
///
/// 弹幕缩放 double
///
+ [SettingKey(typeof(double))]
public const string FONT_ZOOM = "VideoDanmuFontZoom";
///
/// 弹幕显示区域
///
+ [SettingKey(typeof(double))]
public const string AREA = "VideoDanmuArea";
///
/// 弹幕速度 int
///
+ [SettingKey(typeof(int))]
public const string SPEED = "VideoDanmuSpeed";
///
/// 弹幕加粗 bool
///
+ [SettingKey(typeof(bool))]
public const string BOLD = "VideoDanmuBold";
///
/// 弹幕边框样式 int
///
+ [SettingKey(typeof(int))]
public const string BORDER_STYLE = "VideoDanmuStyle";
///
/// 弹幕合并 bool
///
+ [SettingKey(typeof(bool))]
public const string MERGE = "VideoDanmuMerge";
///
/// 弹幕半屏显示 bool
///
+ [SettingKey(typeof(bool))]
public const string DOTNET_HIDE_SUBTITLE = "VideoDanmuDotHide";
///
/// 弹幕透明度 double,0-1
///
+ [SettingKey(typeof(double))]
public const string OPACITY = "VideoDanmuOpacity";
///
/// 隐藏顶部 bool
///
+ [SettingKey(typeof(bool))]
public const string HIDE_TOP = "VideoDanmuHideTop";
///
/// 隐藏底部 bool
///
+ [SettingKey(typeof(bool))]
public const string HIDE_BOTTOM = "VideoDanmuHideBottom";
///
/// 隐藏滚动 bool
///
+ [SettingKey(typeof(bool))]
public const string HIDE_ROLL = "VideoDanmuHideRoll";
///
/// 隐藏高级弹幕 bool
///
+ [SettingKey(typeof(bool))]
public const string HIDE_ADVANCED = "VideoDanmuHideAdvanced";
///
/// 关键词屏蔽 ObservableCollection
///
+ [SettingKey(typeof(object))]
public const string SHIELD_WORD = "VideoDanmuShieldWord";
///
/// 用户屏蔽 ObservableCollection
///
+ [SettingKey(typeof(object))]
public const string SHIELD_USER = "VideoDanmuShieldUser";
///
/// 正则屏蔽 ObservableCollection
///
+ [SettingKey(typeof(object))]
public const string SHIELD_REGULAR = "VideoDanmuShieldRegular";
///
/// 顶部距离
///
+ [SettingKey(typeof(double))]
public const string TOP_MARGIN = "VideoDanmuTopMargin";
///
/// 最大数量
///
+ [SettingKey(typeof(double))]
public const string MAX_NUM = "VideoDanmuMaxNum";
///
/// 弹幕云屏蔽等级
///
+ [SettingKey(typeof(int))]
public const string SHIELD_LEVEL = "VideoDanmuShieldLevel";
}
@@ -280,49 +345,62 @@ public class Live
///
/// 直播默认清晰度
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_QUALITY = "LiveDefaultQuality";
///
/// 显示弹幕 Visibility
///
+ [SettingKey(typeof(object))]
public const string SHOW = "LiveDanmuShow";
+
+ [SettingKey(typeof(double))]
public const string AREA = "LiveDanmuArea";
///
/// 弹幕缩放 double
///
+ [SettingKey(typeof(double))]
public const string FONT_ZOOM = "LiveDanmuFontZoom";
///
/// 弹幕速度 int
///
+ [SettingKey(typeof(int))]
public const string SPEED = "LiveDanmuSpeed";
///
/// 弹幕加粗 bool
///
+ [SettingKey(typeof(bool))]
public const string BOLD = "LiveDanmuBold";
///
/// 弹幕边框样式 int
///
+ [SettingKey(typeof(int))]
public const string BORDER_STYLE = "LiveDanmuStyle";
///
/// 弹幕半屏显示 bool
///
+ [SettingKey(typeof(bool))]
public const string DOTNET_HIDE_SUBTITLE = "LiveDanmuDotHide";
///
/// 弹幕透明度 double,0-1
///
+ [SettingKey(typeof(double))]
public const string OPACITY = "LiveDanmuOpacity";
///
/// 关键词屏蔽 ObservableCollection
///
+ [SettingKey(typeof(object))]
public const string SHIELD_WORD = "LiveDanmuShieldWord";
///
/// 硬解 bool
///
+ [SettingKey(typeof(bool))]
public const string HARDWARE_DECODING = "LiveHardwareDecoding";
///
/// 自动开启宝箱 bool
///
+ [SettingKey(typeof(bool))]
public const string AUTO_OPEN_BOX = "LiveAutoOpenBox";
///
@@ -333,16 +411,19 @@ public class Live
///
/// 直播弹幕清理
///
+ [SettingKey(typeof(int))]
public const string DANMU_CLEAN_COUNT = "LiveCleanCount";
///
/// 隐藏进场
///
+ [SettingKey(typeof(bool))]
public const string HIDE_WELCOME = "LiveHideWelcome";
///
/// 隐藏礼物
///
+ [SettingKey(typeof(bool))]
public const string HIDE_GIFT = "LiveHideGift";
///
@@ -352,12 +433,26 @@ public class Live
///
/// 隐藏抽奖
///
+ [SettingKey(typeof(bool))]
public const string HIDE_LOTTERY = "LiveHideLottery";
///
/// 直播流默认源
///
+ [SettingKey(typeof(string))]
public const string DEFAULT_LIVE_PLAY_URL_SOURCE = "DefaultLivePlayUrlSource";
+
+ ///
+ /// 显示底部礼物栏
+ ///
+ [SettingKey(typeof(bool))]
+ public const string SHOW_BOTTOM_GIFT_BAR = "ShowBottomGiftBar";
+
+ ///
+ /// 默认显示底部礼物栏
+ ///
+ [SettingDefaultValue]
+ public const bool DEFAULT_SHOW_BOTTOM_GIFT_BAR = true;
}
public class Player
@@ -365,75 +460,131 @@ public class Player
///
/// 使用外站视频替换无法播放的视频 bool
///
+ [SettingKey(typeof(bool))]
public const string USE_OTHER_SITEVIDEO = "PlayerUseOther";
///
/// 硬解 bool
///
+ [SettingKey(typeof(bool))]
public const string HARDWARE_DECODING = "PlayerHardwareDecoding";
///
/// 自动播放 bool
///
+ [SettingKey(typeof(bool))]
public const string AUTO_PLAY = "PlayerAutoPlay";
///
/// 自动切换下一个视频
///
+ [SettingKey(typeof(bool))]
public const string AUTO_NEXT = "PlayerAutoNext";
///
/// 默认清晰度 int
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_QUALITY = "PlayerDefaultQuality";
///
/// 默认音质 int
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_SOUND_QUALITY = "PlayerDefaultSoundQuality";
///
/// 比例 int
///
+ [SettingKey(typeof(int))]
public const string RATIO = "PlayerDefaultRatio";
///
/// 默认视频类型 int flv=0, dash=1,dash_hevc=2
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_VIDEO_TYPE = "PlayerDefaultVideoType";
+
+ [SettingDefaultValue]
public static List VideoSpeed = new List() { 2.0d, 1.5d, 1.25d, 1.0d, 0.75d, 0.5d };
///
/// 默认视频类型 int 1.0
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_VIDEO_SPEED = "PlayerDefaultSpeed";
///
/// 播放模式 int 0=顺序播放,1=单集循环,2=列表循环
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_PLAY_MODE = "PlayerDefaultPlayMode";
///
/// 音量
///
+ [SettingKey(typeof(double))]
public const string PLAYER_VOLUME = "PlayerVolume";
+
+ ///
+ /// 音量默认值
+ ///
+ [SettingDefaultValue]
+ public const double DEFAULT_PLAYER_VOLUME = 1.0;
+
///
/// 亮度
///
+ [SettingKey(typeof(double))]
public const string PLAYER_BRIGHTNESS = "PlayeBrightness";
+
+ ///
+ /// 亮度默认值
+ ///
+ [SettingDefaultValue]
+ public const double DEFAULT_PLAYER_BRIGHTNESS = 0;
+
+ ///
+ /// 锁定播放器音量设置(播放器内修改音量时不写设置)
+ ///
+ [SettingKey(typeof(bool))]
+ public const string LOCK_PLAYER_VOLUME = "LockPlayerVolume";
+
+ ///
+ /// 锁定播放器音量设置默认值
+ ///
+ [SettingDefaultValue]
+ public const bool DEFAULT_LOCK_PLAYER_VOLUME = false;
+
+ ///
+ /// 锁定播放器亮度设置(播放器内修改亮度时不写设置)
+ ///
+ [SettingKey(typeof(bool))]
+ public const string LOCK_PLAYER_BRIGHTNESS = "LockPlayerBrightness";
+
+ ///
+ /// 锁定播放器亮度设置默认值
+ ///
+ [SettingDefaultValue]
+ public const bool DEFAULT_LOCK_PLAYER_BRIGHTNESS = true;
+
///
/// A-B 循环播放模式的播放记录
///
+ [SettingKey(typeof(object))]
public const string PLAYER_ABPLAY_HISTORIES = "PlayerABPlayHistories";
///
/// 字幕颜色
///
+ [SettingKey(typeof(int))]
public const string SUBTITLE_COLOR = "subtitleColor";
///
/// 字幕背景颜色
///
+ [SettingKey(typeof(int))]
public const string SUBTITLE_BORDER_COLOR = "subtitleBorderColor";
///
/// 字幕大小
///
+ [SettingKey(typeof(double))]
public const string SUBTITLE_SIZE = "subtitleSize";
///
/// 字幕显示
@@ -442,77 +593,95 @@ public class Player
///
/// 字幕透明度
///
+ [SettingKey(typeof(double))]
public const string SUBTITLE_OPACITY = "subtitleOpacity";
///
/// 字幕底部距离
///
+ [SettingKey(typeof(double))]
public const string SUBTITLE_BOTTOM = "subtitleBottom";
///
/// 字幕加粗
///
+ [SettingKey(typeof(bool))]
public const string SUBTITLE_BOLD = "subtitleBold";
///
/// 字幕对齐
/// 0=居中对齐,1=左对齐,2=右对齐
///
+ [SettingKey(typeof(int))]
public const string SUBTITLE_ALIGN = "subtitleAlign";
///
/// 自动跳转进度
///
+ [SettingKey(typeof(bool))]
public const string AUTO_TO_POSITION = "PlayerAutoToPosition";
///
/// 自动铺满窗口
///
+ [SettingKey(typeof(bool))]
public const string AUTO_FULL_WINDOW = "PlayerAutoToFullWindow";
///
/// 自动铺满全屏
///
+ [SettingKey(typeof(bool))]
public const string AUTO_FULL_SCREEN = "PlayerAutoToFullScreen";
///
/// 双击全屏
///
+ [SettingKey(typeof(bool))]
public const string DOUBLE_CLICK_FULL_SCREEN = "PlayerDoubleClickFullScreen";
///
/// 方向键右键行为
///
+ [SettingKey(typeof(int))]
public const string PLAYER_KEY_RIGHT_ACTION = "PlayerKeyRightAction";
///
/// 按住手势行为
///
+ [SettingKey(typeof(int))]
public const string HOLDING_GESTURE_ACTION = "HoldingGestureAction";
///
/// 按住手势可被其他手势取消
///
+ [SettingKey(typeof(bool))]
public const string HOLDING_GESTURE_CAN_CANCEL = "HoldingGestureCanCancel";
///
/// 倍速播放速度
///
+ [SettingKey(typeof(double))]
public const string HIGH_RATE_PLAY_SPEED = "HighRatePlaySpeed";
+
+ [SettingDefaultValue]
public static List HIGH_RATE_PLAY_SPEED_LIST = new List() { 3.0d, 2.0d };
///
/// 自动打开AI字幕
///
+ [SettingKey(typeof(bool))]
public const string AUTO_OPEN_AI_SUBTITLE = "PlayerAutoOpenAISubtitle";
///
/// 替换CDN
///
+ [SettingKey(typeof(int))]
public const string REPLACE_CDN = "PlayerReplaceCDN";
///
/// CDN服务器
///
+ [SettingKey]
public const string CDN_SERVER = "PlayerCDNServer";
///
/// 直播播放器默认模式
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_LIVE_PLAYER_MODE = "DefaultLivePlayerMode";
}
@@ -525,30 +694,35 @@ public class Roaming
///
/// 自定义服务器链接
///
+ [SettingKey(typeof(string))]
public const string CUSTOM_SERVER_URL = "RoamingCustomServerUrl";
///
/// 自定义香港服务器链接
///
+ [SettingKey(typeof(string))]
public const string CUSTOM_SERVER_URL_HK = "RoamingCustomServerUrlHK";
///
/// 自定义台湾服务器链接
///
+ [SettingKey(typeof(string))]
public const string CUSTOM_SERVER_URL_TW = "RoamingCustomServerUrlTW";
///
/// 自定义大陆服务器链接
///
+ [SettingKey(typeof(string))]
public const string CUSTOM_SERVER_URL_CN = "RoamingCustomServerUrlCN";
///
/// 简体中文
///
+ [SettingKey(typeof(bool))]
public const string TO_SIMPLIFIED = "RoamingSubtitleToSimplified";
- ///
- /// 只使用AkamaiCDN链接
- ///
+ /////
+ ///// 只使用AkamaiCDN链接
+ /////
//public const string AKAMAI_CDN = "RoamingAkamaiCDN";
}
@@ -557,36 +731,45 @@ public class Download
///
/// 下载目录
///
+ [SettingKey(typeof(string))]
public const string DOWNLOAD_PATH = "downloadPath";
+ [SettingDefaultValue]
public const string DEFAULT_PATH = "视频库/哔哩哔哩下载";
///
/// 旧版下载目录
///
+ [SettingKey(typeof(string))]
public const string OLD_DOWNLOAD_PATH = "downloadOldPath";
+ [SettingDefaultValue]
public const string DEFAULT_OLD_PATH = "视频库/BiliBiliDownload";
///
/// 允许付费网络下载
///
+ [SettingKey(typeof(bool))]
public const string ALLOW_COST_NETWORK = "allowCostNetwork";
///
/// 并行下载
///
+ [SettingKey(typeof(bool))]
public const string PARALLEL_DOWNLOAD = "parallelDownload";
///
/// 并行下载
///
+ [SettingKey(typeof(bool))]
public const string SEND_TOAST = "sendToast";
///
/// 加载旧版下载视频
///
+ [SettingKey(typeof(bool))]
public const string LOAD_OLD_DOWNLOAD = "loadOldDownload";
///
/// 下载视频类型
///
+ [SettingKey(typeof(int))]
public const string DEFAULT_VIDEO_TYPE = "DownloadDefaultVideoType";
}
@@ -644,6 +827,7 @@ public class Other
///
/// 默认发起请求时使用的build值
///
+ [SettingDefaultValue]
public const string DEFAULT_REQUEST_BUILD = "75900200";
}
}
diff --git a/src/BiliLite.UWP/Models/Common/UserDynamic/IUserDynamicCommands.cs b/src/BiliLite.UWP/Models/Common/UserDynamic/IUserDynamicCommands.cs
new file mode 100644
index 00000000..61dce016
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/UserDynamic/IUserDynamicCommands.cs
@@ -0,0 +1,31 @@
+using System.Windows.Input;
+
+namespace BiliLite.Models.Common.UserDynamic
+{
+ public interface IUserDynamicCommands
+ {
+ public ICommand LaunchUrlCommand { get; set; }
+
+ public ICommand RepostCommand { get; set; }
+
+ public ICommand LikeCommand { get; set; }
+
+ public ICommand CommentCommand { get; set; }
+
+ public ICommand UserCommand { get; set; }
+
+ public ICommand LoadMoreCommand { get; }
+
+ public ICommand WebDetailCommand { get; set; }
+
+ public ICommand DetailCommand { get; set; }
+
+ public ICommand ImageCommand { get; set; }
+
+ public ICommand WatchLaterCommand { get; set; }
+
+ public ICommand CopyDynCommand { get; set; }
+
+ public ICommand TagCommand { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/UserDynamic/NavDynArticle.cs b/src/BiliLite.UWP/Models/Common/UserDynamic/NavDynArticle.cs
new file mode 100644
index 00000000..d0ec07a8
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/UserDynamic/NavDynArticle.cs
@@ -0,0 +1,87 @@
+using Bilibili.App.Dynamic.V2;
+using BiliLite.ViewModels.UserDynamic;
+using Newtonsoft.Json;
+
+namespace BiliLite.Models.Common.UserDynamic
+{
+ public class NavDynArticle
+ {
+ public string Cover { get; set; }
+
+ [JsonProperty("id_str")]
+ public string Id { get; set; }
+
+ [JsonProperty("jump_url")]
+ public string JumpUrl { get; set; }
+
+ [JsonProperty("pub_time")]
+ public string PubTime { get; set; }
+
+ public long Rid { get; set; }
+
+ public string Title { get; set; }
+
+ public bool Visible { get; set; }
+
+ public NavDynArticleAuthor Author { get; set; }
+
+ public DynamicV2ItemViewModel ToDynamicItem()
+ {
+ var item = new DynamicV2ItemViewModel()
+ {
+ CardType = Constants.DynamicTypes.CUSTOM_ARTICLE,
+ CustomArticle = this,
+ Author = new ModuleAuthor()
+ {
+ Mid = Author.Mid,
+ Author = new UserInfo()
+ {
+ Face = Author.Face,
+ Official = new OfficialVerify()
+ {
+ Type = Author.Official.Type
+ },
+ Name = Author.Name,
+ Vip = new VipInfo()
+ {
+ Status = Author.Vip.Status
+ },
+ },
+ PtimeLabelText = PubTime,
+ },
+ Extend = new Extend()
+ {
+ DynIdStr = Id
+ }
+ };
+ return item;
+ }
+ }
+
+ public class NavDynArticleAuthor
+ {
+ public string Face { get; set; }
+
+ public long Mid { get; set; }
+
+ public string Name { get; set; }
+
+ public NavDynArticleAuthorOfficial Official { get; set; }
+
+ public NavDynArticleAuthorVip Vip { get; set; }
+ }
+
+ public class NavDynArticleAuthorOfficial
+ {
+ public int Role { get; set; }
+
+ public int Type { get; set; }
+
+ public string Title { get; set; }
+ }
+
+ public class NavDynArticleAuthorVip
+ {
+ public int Status { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/UserDynamic/NavDynArticles.cs b/src/BiliLite.UWP/Models/Common/UserDynamic/NavDynArticles.cs
new file mode 100644
index 00000000..8c337148
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/UserDynamic/NavDynArticles.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace BiliLite.Models.Common.UserDynamic
+{
+ public class NavDynArticles
+ {
+ [JsonProperty("has_more")]
+ public bool HasMore { get; set; }
+
+ public List Items { get; set; }
+
+ public string Offset { get; set; }
+
+ [JsonProperty("update_baseline")]
+ public string UpdateBaseline { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/UserDynamic/UserDynamicSeasonInfo.cs b/src/BiliLite.UWP/Models/Common/UserDynamic/UserDynamicSeasonInfo.cs
new file mode 100644
index 00000000..7e5a0edc
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Common/UserDynamic/UserDynamicSeasonInfo.cs
@@ -0,0 +1,36 @@
+using BiliLite.ViewModels.UserDynamic;
+
+namespace BiliLite.Models.Common.UserDynamic
+{
+ public class UserDynamicSeasonInfo
+ {
+ public string SeasonId { get; set; }
+
+ public string Url { get; set; }
+
+ public string Cover { get; set; }
+
+ public string Title { get; set; }
+
+ public string SubTitle { get; set; }
+
+ public UserDynamicSeasonNewEpInfo NewEp { get; set; }
+
+ public DynamicV2ItemViewModel ToDynamicItem()
+ {
+ var item = new DynamicV2ItemViewModel()
+ {
+ CardType = Constants.DynamicTypes.CUSTOM_SEASON,
+ Season = this
+ };
+ return item;
+ }
+ }
+
+ public class UserDynamicSeasonNewEpInfo
+ {
+ public string IndexShow { get; set; }
+
+ public string Cover { get; set; }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Common/Video/Detail/VideoDetailStatModel.cs b/src/BiliLite.UWP/Models/Common/Video/Detail/VideoDetailStatModel.cs
index 2d7736be..ed0e2e14 100644
--- a/src/BiliLite.UWP/Models/Common/Video/Detail/VideoDetailStatModel.cs
+++ b/src/BiliLite.UWP/Models/Common/Video/Detail/VideoDetailStatModel.cs
@@ -9,42 +9,42 @@ public class VideoDetailStatModel
///
/// 播放
///
- public int View { get; set; }
+ public long View { get; set; }
///
/// 弹幕
///
- public int Danmaku { get; set; }
+ public long Danmaku { get; set; }
///
/// 评论
///
- public int Reply { get; set; }
+ public long Reply { get; set; }
///
/// 收藏
///
- public int Favorite { get; set; }
+ public long Favorite { get; set; }
///
/// 投币
///
- public int Coin { get; set; }
+ public long Coin { get; set; }
///
/// 分享
///
- public int Share { get; set; }
+ public long Share { get; set; }
///
/// 点赞
///
- public int Like { get; set; }
+ public long Like { get; set; }
///
/// 不喜欢,固定0
///
[JsonProperty("dislike")]
- public int DisLike { get; set; }
+ public long DisLike { get; set; }
}
}
\ No newline at end of file
diff --git a/src/BiliLite.UWP/Models/Dynamic/DynamicModel.cs b/src/BiliLite.UWP/Models/Dynamic/DynamicModel.cs
index 90d1111a..7586bf48 100644
--- a/src/BiliLite.UWP/Models/Dynamic/DynamicModel.cs
+++ b/src/BiliLite.UWP/Models/Dynamic/DynamicModel.cs
@@ -32,10 +32,10 @@ public class DynamicCardDescModel
public string rid_str { get; set; }
public int r_type { get; set; }
public string bvid { get; set; }
- public int view { get; set; }
- public int repost { get; set; }
- public int comment { get; set; }
- public int like { get; set; }
+ public long view { get; set; }
+ public long repost { get; set; }
+ public long comment { get; set; }
+ public long like { get; set; }
public int is_liked { get; set; }
public long timestamp { get; set; }
public string pre_dy_id { get; set; }
diff --git a/src/BiliLite.UWP/Models/Functions/IShortcutFunction.cs b/src/BiliLite.UWP/Models/Functions/IShortcutFunction.cs
new file mode 100644
index 00000000..bcba2d7a
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Functions/IShortcutFunction.cs
@@ -0,0 +1,11 @@
+using System.Threading.Tasks;
+
+namespace BiliLite.Models.Functions
+{
+ public interface IShortcutFunction
+ {
+ public string Name { get; }
+
+ public Task Action(object param);
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Functions/RefreshShortcutFunction.cs b/src/BiliLite.UWP/Models/Functions/RefreshShortcutFunction.cs
new file mode 100644
index 00000000..d4b14234
--- /dev/null
+++ b/src/BiliLite.UWP/Models/Functions/RefreshShortcutFunction.cs
@@ -0,0 +1,16 @@
+using System.Threading.Tasks;
+using BiliLite.Pages;
+
+namespace BiliLite.Models.Functions
+{
+ public class RefreshShortcutFunction : IShortcutFunction
+ {
+ public string Name { get; } = "刷新";
+
+ public async Task Action(object param)
+ {
+ if (!(param is IRefreshablePage page)) return;
+ await page.Refresh();
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs b/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs
index f5da85fa..d8e03522 100644
--- a/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs
+++ b/src/BiliLite.UWP/Models/Requests/Api/User/DynamicAPI.cs
@@ -46,7 +46,8 @@ public ApiModel DyanmicNew(UserDynamicType type)
//使用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;
@@ -115,7 +116,8 @@ public ApiModel HistoryDynamic(string dynamic_id, UserDynamicType type)
};//使用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;
@@ -155,6 +157,20 @@ public ApiModel SpaceHistoryV2(string mid, string offset = "")
return api;
}
+
+ public ApiModel Article(string updateBaseline,string type="article")
+ {
+ var api = new ApiModel()
+ {
+ method = RestSharp.Method.Get,
+ baseUrl = $"https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/nav",
+ parameter = $"type={type}&update_baseline={updateBaseline}",
+ need_cookie = true,
+ };
+
+ return api;
+ }
+
///
/// 推荐话题
///
diff --git a/src/BiliLite.UWP/Modules/Home/CinemaVM.cs b/src/BiliLite.UWP/Modules/Home/CinemaVM.cs
index eefeb05e..87c80217 100644
--- a/src/BiliLite.UWP/Modules/Home/CinemaVM.cs
+++ b/src/BiliLite.UWP/Modules/Home/CinemaVM.cs
@@ -372,9 +372,9 @@ public bool ShowBadge
}
public class CinemaHomeStatModel
{
- public int view { get; set; }
+ public long view { get; set; }
public string follow_view { get; set; }
- public int follow { get; set; }
- public int danmaku { get; set; }
+ public long follow { get; set; }
+ public long danmaku { get; set; }
}
}
diff --git a/src/BiliLite.UWP/Modules/RankVM.cs b/src/BiliLite.UWP/Modules/RankVM.cs
index 5188c83f..1b39cc5f 100644
--- a/src/BiliLite.UWP/Modules/RankVM.cs
+++ b/src/BiliLite.UWP/Modules/RankVM.cs
@@ -194,20 +194,20 @@ public class RankItemModel
public RankItemOwnerModel owner { get; set; }
public RankItemStatModel stat { get; set; }
public string dynamic { get; set; }
- public int cid { get; set; }
+ public long cid { get; set; }
public string bvid { get; set; }
public int score { get; set; }
}
public class RankItemStatModel
{
- public int aid { get; set; }
- public int view { get; set; }
- public int danmaku { get; set; }
- public int reply { get; set; }
- public int favorite { get; set; }
- public int coin { get; set; }
- public int share { get; set; }
+ public long aid { get; set; }
+ public long view { get; set; }
+ public long danmaku { get; set; }
+ public long reply { get; set; }
+ public long favorite { get; set; }
+ public long coin { get; set; }
+ public long share { get; set; }
}
public class RankItemOwnerModel
{
diff --git a/src/BiliLite.UWP/Modules/SearchVM.cs b/src/BiliLite.UWP/Modules/SearchVM.cs
index 66c957b2..e9dd9309 100644
--- a/src/BiliLite.UWP/Modules/SearchVM.cs
+++ b/src/BiliLite.UWP/Modules/SearchVM.cs
@@ -1007,9 +1007,9 @@ public string title
public string category_name { get; set; }
public string type { get; set; }
public string desc { get; set; }
- public int like { get; set; }
- public int view { get; set; }
- public int reply { get; set; }
+ public long like { get; set; }
+ public long view { get; set; }
+ public long reply { get; set; }
public string id { get; set; }
public List image_urls { get; set; }
public string cover
diff --git a/src/BiliLite.UWP/Modules/Season/SeasonRankVM.cs b/src/BiliLite.UWP/Modules/Season/SeasonRankVM.cs
index 8187f593..50ef7e7f 100644
--- a/src/BiliLite.UWP/Modules/Season/SeasonRankVM.cs
+++ b/src/BiliLite.UWP/Modules/Season/SeasonRankVM.cs
@@ -141,9 +141,9 @@ public class SeasonRankItemModel
}
public class SeasonRankItemStatModel
{
- public int danmaku { get; set; }
- public int follow { get; set; }
- public int view { get; set; }
+ public long danmaku { get; set; }
+ public long follow { get; set; }
+ public long view { get; set; }
}
public class SeasonRankItemNewEPModel
{
diff --git a/src/BiliLite.UWP/Modules/User/UserDetail/UserSubmitArticleVM.cs b/src/BiliLite.UWP/Modules/User/UserDetail/UserSubmitArticleVM.cs
index 97300dad..3ca6b0d8 100644
--- a/src/BiliLite.UWP/Modules/User/UserDetail/UserSubmitArticleVM.cs
+++ b/src/BiliLite.UWP/Modules/User/UserDetail/UserSubmitArticleVM.cs
@@ -180,13 +180,13 @@ public string cover
}
public class SubmitArticleStatsModel
{
- public int view { get; set; }
- public int favorite { get; set; }
- public int like { get; set; }
- public int reply { get; set; }
- public int share { get; set; }
- public int coin { get; set; }
- public int dynamic { get; set; }
+ public long view { get; set; }
+ public long favorite { get; set; }
+ public long like { get; set; }
+ public long reply { get; set; }
+ public long share { get; set; }
+ public long coin { get; set; }
+ public long dynamic { get; set; }
}
public class SubmitArticleCategoryModel
{
diff --git a/src/BiliLite.UWP/NoTabMainPage.xaml.cs b/src/BiliLite.UWP/NoTabMainPage.xaml.cs
index 397aa470..8db9dc75 100644
--- a/src/BiliLite.UWP/NoTabMainPage.xaml.cs
+++ b/src/BiliLite.UWP/NoTabMainPage.xaml.cs
@@ -3,6 +3,7 @@
using BiliLite.Models.Common;
using BiliLite.Pages;
using BiliLite.Services;
+using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using Windows.ApplicationModel.Core;
@@ -20,10 +21,14 @@ namespace BiliLite
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class NoTabMainPage : Page
+ public sealed partial class NoTabMainPage : Page, IMainPage
{
+ private readonly ShortcutKeyService m_shortcutKeyService;
+
public NoTabMainPage()
{
+ m_shortcutKeyService = App.ServiceProvider.GetRequiredService();
+ m_shortcutKeyService.SetMainPage(this);
this.InitializeComponent();
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
mode = SettingService.GetValue(SettingConstants.UI.DISPLAY_MODE, 0);
@@ -34,7 +39,20 @@ public NoTabMainPage()
MessageCenter.ViewImageEvent += MessageCenter_ViewImageEvent;
MessageCenter.MiniWindowEvent += MessageCenter_MiniWindowEvent;
Window.Current.Content.PointerPressed += Content_PointerPressed;
+
+ Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += Dispatcher_AcceleratorKeyActivated;
}
+
+ public object CurrentPage => frame.Content;
+
+ private void Dispatcher_AcceleratorKeyActivated(Windows.UI.Core.CoreDispatcher sender, Windows.UI.Core.AcceleratorKeyEventArgs args)
+ {
+ if (args.EventType.ToString().Contains("Down"))
+ {
+ m_shortcutKeyService.HandleKeyDown(args.VirtualKey);
+ }
+ }
+
private void MessageCenter_MiniWindowEvent(object sender, bool e)
{
if (e)
diff --git a/src/BiliLite.UWP/Pages/DownloadPage.xaml.cs b/src/BiliLite.UWP/Pages/DownloadPage.xaml.cs
index 14d91801..cb03cb9c 100644
--- a/src/BiliLite.UWP/Pages/DownloadPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/DownloadPage.xaml.cs
@@ -1,19 +1,12 @@
-using BiliLite.Modules;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
+using System.Threading.Tasks;
using Windows.Storage;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using BiliLite.Extensions;
using BiliLite.Services;
@@ -23,6 +16,7 @@
using BiliLite.Models.Common.Video.PlayUrlInfos;
using BiliLite.ViewModels.Download;
using Microsoft.Extensions.DependencyInjection;
+using System.Text.RegularExpressions;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -31,7 +25,7 @@ namespace BiliLite.Pages
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class DownloadPage : BasePage
+ public sealed partial class DownloadPage : BasePage, IRefreshablePage
{
private static readonly ILogger logger = GlobalLogger.FromCurrentType();
private readonly DownloadPageViewModel m_viewModel;
@@ -50,6 +44,12 @@ protected override void OnNavigatedTo(NavigationEventArgs e)
m_viewModel.RefreshDownloaded();
}
}
+
+ public async Task Refresh()
+ {
+ m_viewModel.RefreshDownloaded();
+ }
+
private void listDowned_ItemClick(object sender, ItemClickEventArgs e)
{
var data = e.ClickedItem as DownloadedItem;
@@ -307,7 +307,8 @@ private async void OutputFile(DownloadedItem data, DownloadedSubItem item)
savePicker.SuggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary;
savePicker.FileTypeChoices.Add("MP4", new List() { ".mp4" });
- savePicker.SuggestedFileName = "导出的视频";
+ var fileName = Regex.Replace(data.Title + "-" + item.Title, "[<>/\\\\|:\":?*]", "");
+ savePicker.SuggestedFileName = fileName;
var file = await savePicker.PickSaveFileAsync();
if (file == null)
return;
diff --git a/src/BiliLite.UWP/Pages/Home/AnimePage.xaml.cs b/src/BiliLite.UWP/Pages/Home/AnimePage.xaml.cs
index c8c33fc8..2b4c6cbb 100644
--- a/src/BiliLite.UWP/Pages/Home/AnimePage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Home/AnimePage.xaml.cs
@@ -19,7 +19,7 @@ namespace BiliLite.Pages.Home
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class AnimePage : Page
+ public sealed partial class AnimePage : Page, IRefreshablePage
{
private AnimeType animeType;
public AnimePageViewModel m_viewModel { get; set; }
@@ -100,11 +100,16 @@ private void btnTimeline_Click(object sender, RoutedEventArgs e)
});
}
- private async void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
+ public async Task Refresh()
{
await LoadData();
}
+ private async void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
+ {
+ await Refresh();
+ }
+
private async void BannerItem_Click(object sender, RoutedEventArgs e)
{
var result = await MessageCenter.HandelUrl(((sender as HyperlinkButton).DataContext as AnimeBannerModel).Url);
diff --git a/src/BiliLite.UWP/Pages/Home/DynamicPage.xaml.cs b/src/BiliLite.UWP/Pages/Home/DynamicPage.xaml.cs
index a6addb75..15cc4a90 100644
--- a/src/BiliLite.UWP/Pages/Home/DynamicPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Home/DynamicPage.xaml.cs
@@ -1,4 +1,5 @@
-using BiliLite.Extensions;
+using System.Threading.Tasks;
+using BiliLite.Extensions;
using BiliLite.Models.Common;
using BiliLite.Services;
using Windows.UI.Xaml;
@@ -16,7 +17,7 @@ namespace BiliLite.Pages.Home
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class DynamicPage : Page
+ public sealed partial class DynamicPage : Page, IRefreshablePage
{
private readonly DynamicPageViewModel m_viewModel;
@@ -38,11 +39,16 @@ protected override async void OnNavigatedTo(NavigationEventArgs e)
}
}
- private void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
+ public async Task Refresh()
{
m_viewModel.Refresh();
}
+ private async void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
+ {
+ await Refresh();
+ }
+
private void AdaptiveGridView_ItemClick(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as DynamicItemModel;
diff --git a/src/BiliLite.UWP/Pages/Home/HotPage.xaml.cs b/src/BiliLite.UWP/Pages/Home/HotPage.xaml.cs
index d8c16b57..42cb53c7 100644
--- a/src/BiliLite.UWP/Pages/Home/HotPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Home/HotPage.xaml.cs
@@ -16,7 +16,7 @@ namespace BiliLite.Pages.Home
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class HotPage : Page
+ public sealed partial class HotPage : Page, IRefreshablePage
{
HotVM hotVM;
public HotPage()
@@ -100,5 +100,10 @@ private void AddToWatchLater_Click(object sender, RoutedEventArgs e)
var data = (sender as MenuFlyoutItem).DataContext as HotDataItemModel;
WatchLaterVM.Instance.AddToWatchlater(data.Param);
}
+
+ public async Task Refresh()
+ {
+ hotVM.Refresh();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs b/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs
index f8cb21cb..1cbc0d20 100644
--- a/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Home/LivePage.xaml.cs
@@ -18,7 +18,7 @@ namespace BiliLite.Pages.Home
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class LivePage : Page
+ public sealed partial class LivePage : Page,IRefreshablePage
{
private Modules.LiveVM liveVM;
public LivePage()
@@ -53,11 +53,16 @@ private async Task LoadData()
}
}
- private async void btnRefresh_Click(object sender, RoutedEventArgs e)
+ public async Task Refresh()
{
await LoadData();
}
+ private async void btnRefresh_Click(object sender, RoutedEventArgs e)
+ {
+ await Refresh();
+ }
+
private async void BannerItem_Click(object sender, RoutedEventArgs e)
{
var result = await MessageCenter.HandelUrl(((sender as HyperlinkButton).DataContext as LiveHomeBannerModel).link);
diff --git a/src/BiliLite.UWP/Pages/Home/MoviePage.xaml.cs b/src/BiliLite.UWP/Pages/Home/MoviePage.xaml.cs
index 048d8fe7..3802c375 100644
--- a/src/BiliLite.UWP/Pages/Home/MoviePage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Home/MoviePage.xaml.cs
@@ -4,19 +4,9 @@
using BiliLite.Modules;
using BiliLite.Services;
using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -26,7 +16,7 @@ namespace BiliLite.Pages.Home
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class MoviePage : Page
+ public sealed partial class MoviePage : Page, IRefreshablePage
{
readonly Modules.CinemaVM cinemaVM;
public MoviePage()
@@ -95,7 +85,7 @@ private async void gvFall_ItemClick(object sender, ItemClickEventArgs e)
}
private async void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
{
- await LoadData();
+ await Refresh();
}
private async void BannerItem_Click(object sender, RoutedEventArgs e)
@@ -184,5 +174,10 @@ private void GridView_ItemClick(object sender, ItemClickEventArgs e)
var item = e.ClickedItem as PageEntranceModel;
MessageCenter.NavigateToPage(this, item.NavigationInfo);
}
+
+ public async Task Refresh()
+ {
+ await LoadData();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/Home/RecommendPage.xaml.cs b/src/BiliLite.UWP/Pages/Home/RecommendPage.xaml.cs
index ea74521e..2981b658 100644
--- a/src/BiliLite.UWP/Pages/Home/RecommendPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Home/RecommendPage.xaml.cs
@@ -21,7 +21,7 @@ namespace BiliLite.Pages.Home
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class RecommendPage : Page
+ public sealed partial class RecommendPage : Page, IRefreshablePage
{
#region Fields
@@ -42,6 +42,15 @@ public RecommendPage()
#endregion
+ #region Public Methods
+
+ public async Task Refresh()
+ {
+ m_viewModel.Refresh();
+ }
+
+ #endregion
+
#region Protected Methods
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
@@ -87,7 +96,7 @@ private async void RecommendGridView_ItemClick(object sender, ItemClickEventArgs
private void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
{
- m_viewModel.Refresh();
+ Refresh();
}
private async void BannerItem_Click(object sender, RoutedEventArgs e)
diff --git a/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml b/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml
index cc8f093d..ec9ec508 100644
--- a/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml
+++ b/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml
@@ -15,7 +15,7 @@
-
+
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
diff --git a/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml.cs b/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml.cs
index d7bffab0..5e307ec1 100644
--- a/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Home/UserDynamicPage.xaml.cs
@@ -1,13 +1,17 @@
-using BiliLite.Services;
+using System.Linq;
+using System.Threading.Tasks;
+using BiliLite.Services;
using BiliLite.Models.Common;
using BiliLite.Models.Requests.Api;
-using BiliLite.Models.Requests.Api.User;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using BiliLite.Extensions;
-using BiliLite.Models.Common.UserDynamic;
using BiliLite.ViewModels.UserDynamic;
+using Microsoft.Extensions.DependencyInjection;
+using BiliLite.Models.Common.Comment;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media.Animation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -16,91 +20,28 @@ namespace BiliLite.Pages.Home
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class UserDynamicPage : Page
+ public sealed partial class UserDynamicPage : Page,IRefreshablePage
{
- readonly UserDynamicViewModel m_userDynamicViewModel;
- private bool IsStaggered { get; set; } = false;
+ readonly UserDynamicAllViewModel m_viewModel;
+ private bool m_isStaggered = false;
+ private UserDynamicShowType m_currentShowType;
+
public UserDynamicPage()
{
+ m_viewModel = App.ServiceProvider.GetRequiredService();
+ m_viewModel.OpenCommentEvent += UserDynamicViewModelOpenCommentEvent;
this.InitializeComponent();
- m_userDynamicViewModel = new UserDynamicViewModel();
- m_userDynamicViewModel.OpenCommentEvent += UserDynamicViewModelOpenCommentEvent;
- splitView.PaneClosed += SplitView_PaneClosed;
- this.DataContext = m_userDynamicViewModel;
- if (SettingService.GetValue(SettingConstants.UI.CACHE_HOME, true))
- {
- this.NavigationCacheMode = NavigationCacheMode.Enabled;
- }
- else
- {
- this.NavigationCacheMode = NavigationCacheMode.Disabled;
- }
+ m_currentShowType = (UserDynamicShowType)DynPivot.SelectedIndex;
}
- private void SplitView_PaneClosed(SplitView sender, object args)
- {
- comment.ClearComment();
- repost.UserDynamicRepostViewModel.Clear();
- }
- string dynamic_id;
- private void UserDynamicViewModelOpenCommentEvent(object sender, UserDynamicItemDisplayViewModel e)
- {
- // splitView.IsPaneOpen = true;
- dynamic_id = e.DynamicID;
- pivotRight.SelectedIndex = 1;
- repostCount.Text = e.ShareCount.ToString();
- commentCount.Text = e.CommentCount.ToString();
- CommentApi.CommentType commentType = CommentApi.CommentType.Dynamic;
- var id = e.ReplyID;
- switch (e.Type)
- {
-
- case UserDynamicDisplayType.Photo:
- commentType = CommentApi.CommentType.Photo;
- break;
- case UserDynamicDisplayType.Video:
-
- commentType = CommentApi.CommentType.Video;
- break;
- case UserDynamicDisplayType.Season:
- id = e.OneRowInfo.AID;
- commentType = CommentApi.CommentType.Video;
- break;
- case UserDynamicDisplayType.ShortVideo:
- commentType = CommentApi.CommentType.MiniVideo;
- break;
- case UserDynamicDisplayType.Music:
- commentType = CommentApi.CommentType.Song;
- break;
- case UserDynamicDisplayType.Article:
- commentType = CommentApi.CommentType.Article;
- break;
- case UserDynamicDisplayType.MediaList:
- if (e.OneRowInfo.Tag != "收藏夹")
- commentType = CommentApi.CommentType.Video;
- break;
- default:
- id = e.DynamicID;
- break;
- }
-
- //comment.LoadComment(new Controls.LoadCommentInfo()
- //{
- // commentMode = (int)commentType,
- // commentSort = Api.CommentApi.commentSort.Hot,
- // oid = id
- //});
- Notify.ShowComment(id, (int)commentType, CommentApi.CommentSort.Hot);
- }
-
- protected async override void OnNavigatedTo(NavigationEventArgs e)
+ protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
SetStaggered();
- if (e.NavigationMode == NavigationMode.New && m_userDynamicViewModel.Items == null)
+ if (e.NavigationMode == NavigationMode.New && m_viewModel.DynamicItems == null)
{
- await m_userDynamicViewModel.GetDynamicItems();
+ await m_viewModel.GetDynamicItems();
if (SettingService.GetValue("动态切换提示", true) && SettingService.GetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0) != 1)
{
SettingService.SetValue("动态切换提示", false);
@@ -109,89 +50,148 @@ protected async override void OnNavigatedTo(NavigationEventArgs e)
}
}
- void SetStaggered()
+ private void SetStaggered()
{
var staggered = SettingService.GetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0) == 1;
- if (staggered != IsStaggered)
+ if (staggered != m_isStaggered)
{
- IsStaggered = staggered;
+ m_isStaggered = staggered;
if (staggered)
{
- btnGrid_Click(this, null);
+ SetGridCore();
}
else
{
- btnList_Click(this, null);
+ SetListCore();
}
}
}
- private void pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ private void SetGridCore()
{
- if ((int)m_userDynamicViewModel.UserDynamicType == pivot.SelectedIndex) return;
- m_userDynamicViewModel.UserDynamicType = (UserDynamicType)pivot.SelectedIndex;
- m_userDynamicViewModel.Refresh();
+ m_isStaggered = true;
+ BtnGrid.Visibility = Visibility.Collapsed;
+ BtnList.Visibility = Visibility.Visible;
+ //XAML
+ ListDyn.ItemsPanel = (ItemsPanelTemplate)this.Resources["GridPanel"];
+
+ //顶部
+ GridTopBar.MaxWidth = double.MaxValue;
+ GridTopBar.Margin = new Thickness(0, 0, 0, 4);
+ BorderTopBar.CornerRadius = new CornerRadius(0);
+ BorderTopBar.Margin = new Thickness(0);
}
- private void btnGrid_Click(object sender, RoutedEventArgs e)
+ private void SetListCore()
{
- SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 1);
- IsStaggered = true;
- btnGrid.Visibility = Visibility.Collapsed;
- btnList.Visibility = Visibility.Visible;
+ m_isStaggered = false;
+ //右下角按钮
+ BtnGrid.Visibility = Visibility.Visible;
+ BtnList.Visibility = Visibility.Collapsed;
+ //XAML
+ ListDyn.ItemsPanel = (ItemsPanelTemplate)this.Resources["ListPanel"];
+
//顶部
- gridTopBar.MaxWidth = double.MaxValue;
- gridTopBar.Margin = new Thickness(0, 0, 0, 4);
- borderTopBar.CornerRadius = new CornerRadius(0);
- borderTopBar.Margin = new Thickness(0);
+ GridTopBar.MaxWidth = 800;
+ GridTopBar.Margin = new Thickness(8, 0, 8, 0);
+ BorderTopBar.CornerRadius = new CornerRadius(4);
+ BorderTopBar.Margin = new Thickness(12, 4, 12, 4);
+ }
- //XAML
- // var tmp = @" ";
- // var xaml = $@"
- // {tmp}
- // ";
- //list.ItemsPanel = (ItemsPanelTemplate)XamlReader.Load(xaml);
- list.ItemsPanel = (ItemsPanelTemplate)this.Resources["GridPanel"];
+ private async void BtnRefreshDynamic_OnClick(object sender, RoutedEventArgs e)
+ {
+ await Refresh();
}
- private void btnList_Click(object sender, RoutedEventArgs e)
+ private void BtnTop_OnClick(object sender, RoutedEventArgs e)
+ {
+ ListDyn.ScrollIntoView(ListDyn.Items.FirstOrDefault());
+ }
+
+ private void BtnList_OnClick(object sender, RoutedEventArgs e)
{
- IsStaggered = false;
- //右下角按钮
- btnGrid.Visibility = Visibility.Visible;
- btnList.Visibility = Visibility.Collapsed;
- //设置
SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 0);
- //顶部
- gridTopBar.MaxWidth = 800;
- gridTopBar.Margin = new Thickness(8, 0, 8, 0);
- borderTopBar.CornerRadius = new CornerRadius(4);
- borderTopBar.Margin = new Thickness(12, 4, 12, 4);
- //XAML
- // var tmp = @" ";
- // var xaml = $@"
- // {tmp}
- // ";
- //list.ItemsPanel = (ItemsPanelTemplate)XamlReader.Load(xaml);
- list.ItemsPanel = (ItemsPanelTemplate)this.Resources["ListPanel"];
+ SetListCore();
}
- private void btnTop_Click(object sender, RoutedEventArgs e)
+ private void BtnGrid_OnClick(object sender, RoutedEventArgs e)
{
- list.ScrollIntoView(list.Items[0]);
+ SettingService.SetValue(SettingConstants.UI.DYNAMIC_DISPLAY_MODE, 1);
+ SetGridCore();
}
- private void pivotRight_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ private async void Pivot_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
- if (pivotRight.SelectedIndex == 0 && splitView.IsPaneOpen && (repost.UserDynamicRepostViewModel.Items == null || repost.UserDynamicRepostViewModel.Items.Count == 0))
+ var showType = (UserDynamicShowType)DynPivot.SelectedIndex;
+ if (showType == m_currentShowType) return;
+ m_currentShowType = showType;
+ await m_viewModel.GetDynamicItems(showType: showType);
+ }
+
+ 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)
{
- repost.LoadData(dynamic_id);
+ 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();
+ }
+
+ public async Task Refresh()
+ {
+ await m_viewModel.GetDynamicItems(showType: m_currentShowType);
}
}
}
diff --git a/src/BiliLite.UWP/Pages/HomePage.xaml.cs b/src/BiliLite.UWP/Pages/HomePage.xaml.cs
index ee619c6f..ac99a0e8 100644
--- a/src/BiliLite.UWP/Pages/HomePage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/HomePage.xaml.cs
@@ -4,6 +4,7 @@
using BiliLite.Services;
using Microsoft.Toolkit.Uwp.Connectivity;
using System;
+using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
@@ -18,7 +19,7 @@ namespace BiliLite.Pages
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class HomePage : Page
+ public sealed partial class HomePage : Page, IRefreshablePage
{
private static readonly ILogger logger = GlobalLogger.FromCurrentType();
@@ -36,6 +37,15 @@ public HomePage()
m_downloadPageViewModel = App.ServiceProvider.GetRequiredService();
this.DataContext = m_viewModel;
}
+
+ public async Task Refresh()
+ {
+ if (frame.Content is IRefreshablePage page)
+ {
+ await page.Refresh();
+ }
+ }
+
private void MessageCenter_LogoutedEvent(object sender, EventArgs e)
{
LaodUserStatus();
diff --git a/src/BiliLite.UWP/Pages/IMainPage.cs b/src/BiliLite.UWP/Pages/IMainPage.cs
new file mode 100644
index 00000000..869a58c8
--- /dev/null
+++ b/src/BiliLite.UWP/Pages/IMainPage.cs
@@ -0,0 +1,7 @@
+namespace BiliLite.Pages
+{
+ public interface IMainPage
+ {
+ public object CurrentPage { get; }
+ }
+}
diff --git a/src/BiliLite.UWP/Pages/IRefreshablePage.cs b/src/BiliLite.UWP/Pages/IRefreshablePage.cs
new file mode 100644
index 00000000..b33ec6c6
--- /dev/null
+++ b/src/BiliLite.UWP/Pages/IRefreshablePage.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace BiliLite.Pages
+{
+ public interface IRefreshablePage
+ {
+ public Task Refresh();
+ }
+}
diff --git a/src/BiliLite.UWP/Pages/Live/LiveAreaDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/Live/LiveAreaDetailPage.xaml.cs
index 22537848..800cf433 100644
--- a/src/BiliLite.UWP/Pages/Live/LiveAreaDetailPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Live/LiveAreaDetailPage.xaml.cs
@@ -1,19 +1,11 @@
using BiliLite.Models.Common;
using BiliLite.Modules.Live;
using BiliLite.Services;
-using System;
-using System.Collections.Generic;
-using System.IO;
using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
+using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -28,7 +20,7 @@ public class LiveAreaPar
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class LiveAreaDetailPage : BasePage
+ public sealed partial class LiveAreaDetailPage : BasePage, IRefreshablePage
{
LiveAreaDetailVM liveAreaDetailVM;
public LiveAreaDetailPage()
@@ -48,9 +40,9 @@ protected async override void OnNavigatedTo(NavigationEventArgs e)
}
}
- private void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
+ private async void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
{
- liveAreaDetailVM.Refresh();
+ await Refresh();
}
private void AdaptiveGridView_ItemClick(object sender, ItemClickEventArgs e)
@@ -75,5 +67,10 @@ private void ToggleButton_Click(object sender, RoutedEventArgs e)
liveAreaDetailVM.SelectTag = data;
liveAreaDetailVM.Refresh();
}
+
+ public async Task Refresh()
+ {
+ liveAreaDetailVM.Refresh();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/Live/LiveCenterPage.xaml.cs b/src/BiliLite.UWP/Pages/Live/LiveCenterPage.xaml.cs
index 7c4658a6..48c53aa4 100644
--- a/src/BiliLite.UWP/Pages/Live/LiveCenterPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Live/LiveCenterPage.xaml.cs
@@ -2,18 +2,8 @@
using BiliLite.Modules.Live.LiveCenter;
using BiliLite.Services;
using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
-using Windows.UI.Xaml;
+using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -23,7 +13,7 @@ namespace BiliLite.Pages.Live
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class LiveCenterPage : BasePage
+ public sealed partial class LiveCenterPage : BasePage, IRefreshablePage
{
readonly LiveAttentionVM liveAttentionVM;
readonly LiveAttentionUnLiveVM liveAttentionUnLiveVM;
@@ -97,5 +87,10 @@ private async void pivot_SelectionChanged(object sender, SelectionChangedEventAr
await liveCenterHistoryVM.Get();
}
}
+
+ public async Task Refresh()
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/Live/LiveRecommendPage.xaml.cs b/src/BiliLite.UWP/Pages/Live/LiveRecommendPage.xaml.cs
index 768a520f..b7608309 100644
--- a/src/BiliLite.UWP/Pages/Live/LiveRecommendPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/Live/LiveRecommendPage.xaml.cs
@@ -1,19 +1,10 @@
using BiliLite.Models.Common;
using BiliLite.Modules.Live;
using BiliLite.Services;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
-using Windows.UI.Xaml;
+using System.Threading.Tasks;
+
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
+
using Windows.UI.Xaml.Navigation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -23,7 +14,7 @@ namespace BiliLite.Pages.Live
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class LiveRecommendPage : BasePage
+ public sealed partial class LiveRecommendPage : BasePage, IRefreshablePage
{
readonly LiveRecommendVM liveRecommendVM;
public LiveRecommendPage()
@@ -72,10 +63,17 @@ private void AdaptiveGridView_ItemClick(object sender, ItemClickEventArgs e)
});
}
- private void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
+ private async void RefreshContainer_RefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer sender, Microsoft.UI.Xaml.Controls.RefreshRequestedEventArgs args)
{
- var data = sender.DataContext as LiveRecommendItem;
- data.Refresh();
+ await Refresh();
+ }
+
+ public async Task Refresh()
+ {
+ if(pivot.SelectedItem is LiveRecommendItem item)
+ {
+ item.Refresh();
+ }
}
}
}
diff --git a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs
index 91ea9b3e..76d8294f 100644
--- a/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/LiveDetailPage.xaml.cs
@@ -534,15 +534,18 @@ private void PreLoadSetting()
private void LoadSetting()
{
//音量
- m_player.Volume = SettingService.GetValue(SettingConstants.Player.PLAYER_VOLUME, 1.0);
+ m_player.Volume = SettingService.GetValue(SettingConstants.Player.PLAYER_VOLUME, SettingConstants.Player.DEFAULT_PLAYER_VOLUME);
SliderVolume.Value = m_player.Volume;
+ var lockPlayerVolume = SettingService.GetValue(SettingConstants.Player.LOCK_PLAYER_VOLUME, SettingConstants.Player.DEFAULT_LOCK_PLAYER_VOLUME);
SliderVolume.ValueChanged += (e, args) =>
{
m_player.Volume = SliderVolume.Value;
- SettingService.SetValue(SettingConstants.Player.PLAYER_VOLUME, SliderVolume.Value);
+ if(!lockPlayerVolume)
+ SettingService.SetValue(SettingConstants.Player.PLAYER_VOLUME, SliderVolume.Value);
};
//亮度
- _brightness = SettingService.GetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, 0);
+ lockBrightness = SettingService.GetValue(SettingConstants.Player.LOCK_PLAYER_BRIGHTNESS, SettingConstants.Player.DEFAULT_LOCK_PLAYER_BRIGHTNESS);
+ _brightness = SettingService.GetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, SettingConstants.Player.DEFAULT_PLAYER_BRIGHTNESS);
BrightnessShield.Opacity = _brightness;
//弹幕顶部距离
@@ -656,6 +659,10 @@ private void LoadSetting()
m_liveRoomViewModel.ReceiveLotteryMsg = !LiveSettingDotReceiveLotteryMsg.IsOn;
SettingService.SetValue(SettingConstants.Live.HIDE_LOTTERY, LiveSettingDotReceiveLotteryMsg.IsOn);
});
+
+ // 显示底部礼物栏
+ m_viewModel.ShowBottomGiftBar = SettingService.GetValue(SettingConstants.Live.SHOW_BOTTOM_GIFT_BAR,
+ SettingConstants.Live.DEFAULT_SHOW_BOTTOM_GIFT_BAR);
}
public void ChangeTitle(string title)
@@ -1185,6 +1192,7 @@ private void Grid_ManipulationStarted(object sender, ManipulationStartedRoutedEv
}
+ private bool lockBrightness = true;
double _brightness;
double Brightness
{
@@ -1193,7 +1201,8 @@ double Brightness
{
_brightness = value;
BrightnessShield.Opacity = value;
- SettingService.SetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, _brightness);
+ if (!lockBrightness)
+ SettingService.SetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, _brightness);
}
}
@@ -1252,6 +1261,7 @@ private async void PlayUrlSourceComboBox_OnSelectionChanged(object sender, Selec
private void BottomBtnSwitchGiftBar_Click(object sender, RoutedEventArgs e)
{
m_viewModel.ShowBottomGiftBar = !m_viewModel.ShowBottomGiftBar;
+ SettingService.SetValue(SettingConstants.Live.SHOW_BOTTOM_GIFT_BAR, m_viewModel.ShowBottomGiftBar);
}
}
}
diff --git a/src/BiliLite.UWP/Pages/RegionDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/RegionDetailPage.xaml.cs
index c2cd55a7..a503de10 100644
--- a/src/BiliLite.UWP/Pages/RegionDetailPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/RegionDetailPage.xaml.cs
@@ -2,19 +2,9 @@
using BiliLite.Modules;
using BiliLite.Pages.Bangumi;
using BiliLite.Services;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
+using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -24,7 +14,7 @@ namespace BiliLite.Pages
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class RegionDetailPage : BasePage
+ public sealed partial class RegionDetailPage : BasePage, IRefreshablePage
{
RegionDetailVM regionDetailVM;
OpenRegionInfo regionInfo;
@@ -155,6 +145,15 @@ private void AddToWatchLater_Click(object sender, RoutedEventArgs e)
Modules.User.WatchLaterVM.Instance.AddToWatchlater(data.param);
}
+
+ public async Task Refresh()
+ {
+ if (cbTags.SelectedItem == null)
+ {
+ return;
+ }
+ (pivot.SelectedItem as RegionDetailChildVM).Refresh();
+ }
}
public class RegionDataTemplateSelector : DataTemplateSelector
{
diff --git a/src/BiliLite.UWP/Pages/SearchPage.xaml.cs b/src/BiliLite.UWP/Pages/SearchPage.xaml.cs
index 3bc486c9..74412c49 100644
--- a/src/BiliLite.UWP/Pages/SearchPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/SearchPage.xaml.cs
@@ -1,4 +1,5 @@
-using BiliLite.Extensions;
+using System.Threading.Tasks;
+using BiliLite.Extensions;
using BiliLite.Models.Common;
using BiliLite.Modules;
using BiliLite.Services;
@@ -55,7 +56,7 @@ public class SearchParameter
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class SearchPage : BasePage
+ public sealed partial class SearchPage : BasePage, IRefreshablePage
{
SearchVM searchVM;
public SearchPage()
@@ -271,6 +272,12 @@ private async void txtKeyword_TextChanged(AutoSuggestBox sender, AutoSuggestBoxT
searchVM.SuggestSearchContents.ReplaceRange(suggestSearchContents);
}
}
+
+ public async Task Refresh()
+ {
+ if (!(pivot.SelectedItem is ISearchVM searchVm)) return;
+ searchVm.Refresh();
+ }
}
public class SearchDataTemplateSelector : DataTemplateSelector
{
diff --git a/src/BiliLite.UWP/Pages/SettingPage.xaml b/src/BiliLite.UWP/Pages/SettingPage.xaml
index 505e8a8e..b4513de7 100644
--- a/src/BiliLite.UWP/Pages/SettingPage.xaml
+++ b/src/BiliLite.UWP/Pages/SettingPage.xaml
@@ -153,6 +153,12 @@
+
+ 动态
+ 动态评论宽度(下次打开应用生效)
+
+
+
图片圆角半径(重启生效)
@@ -313,6 +319,18 @@
+ 音量
+
+
+ 亮度
+
+
+ 锁定播放器音量设置(播放器内修改音量时不写设置)
+
+
+ 锁定播放器亮度设置(播放器内修改亮度时不写设置)
+
+
自动打开AI字幕
部分自动生成的AI字幕会与视频自带字幕冲突
@@ -486,7 +504,7 @@
- 直播弹幕
+ 直播
@@ -600,6 +618,11 @@
+
+ 导出设置
+ 导出设置与登录信息
+ 导入设置
+
更新json请求地址(用于解决github在国内访问不佳的问题)
(SettingConstants.UI.DYNAMIC_COMMENT_WIDTH, SettingConstants.UI.DEFAULT_DYNAMIC_COMMENT_WIDTH);
+ NumBoxDynamicCommentWidth.Loaded += (sender, e) =>
+ {
+ NumBoxDynamicCommentWidth.ValueChanged += (obj, args) =>
+ {
+ SettingService.SetValue(SettingConstants.UI.DYNAMIC_COMMENT_WIDTH, args.NewValue);
+ };
+ };
+
//图片圆角半径
numImageCornerRadius.Value = SettingService.GetValue(SettingConstants.UI.IMAGE_CORNER_RADIUS, 0);
ImageCornerRadiusExample.CornerRadius = new CornerRadius(numImageCornerRadius.Value);
@@ -421,6 +433,70 @@ private void LoadPlayer()
};
};
+ // 音量
+ NumBoxVolume.Value = Math.Round((SettingService.GetValue(SettingConstants.Player.PLAYER_VOLUME,
+ SettingConstants.Player.DEFAULT_PLAYER_VOLUME)) * 100, 2);
+ NumBoxVolume.Loaded += (sender, e) =>
+ {
+ NumBoxVolume.ValueChanged += (obj, args) =>
+ {
+ if (NumBoxVolume.Value > 100)
+ {
+ NumBoxVolume.Value = 100;
+ }
+
+ if (NumBoxVolume.Value < 0)
+ {
+ NumBoxVolume.Value = 0;
+ }
+ SettingService.SetValue(SettingConstants.Player.PLAYER_VOLUME, NumBoxVolume.Value/100);
+ };
+ };
+
+ // 锁定播放器音量设置
+ SwLockPlayerVolume.IsOn = SettingService.GetValue(SettingConstants.Player.LOCK_PLAYER_VOLUME, SettingConstants.Player.DEFAULT_LOCK_PLAYER_VOLUME);
+ SwLockPlayerVolume.Loaded += (sender, e) =>
+ {
+ SwLockPlayerVolume.Toggled += (obj, args) =>
+ {
+ SettingService.SetValue(SettingConstants.Player.LOCK_PLAYER_VOLUME, SwLockPlayerVolume.IsOn);
+ };
+ };
+
+ // 亮度
+ NumBoxBrightness.Value = Math.Round(
+ (Math.Abs(SettingService.GetValue(
+ SettingConstants.Player.PLAYER_BRIGHTNESS,
+ SettingConstants.Player.DEFAULT_PLAYER_BRIGHTNESS) - 1)) * 100, 2);
+ NumBoxBrightness.Loaded += (sender, e) =>
+ {
+ NumBoxBrightness.ValueChanged += (obj, args) =>
+ {
+ if (NumBoxBrightness.Value > 100)
+ {
+ NumBoxBrightness.Value = 100;
+ }
+
+ if (NumBoxBrightness.Value < 0)
+ {
+ NumBoxBrightness.Value = 0;
+ }
+
+ var brightness = Math.Abs((NumBoxBrightness.Value / 100) - 1);
+ SettingService.SetValue(SettingConstants.Player.PLAYER_BRIGHTNESS, brightness);
+ };
+ };
+
+ // 锁定播放器亮度设置
+ SwLockPlayerBrightness.IsOn = SettingService.GetValue(SettingConstants.Player.LOCK_PLAYER_BRIGHTNESS, SettingConstants.Player.DEFAULT_LOCK_PLAYER_BRIGHTNESS);
+ SwLockPlayerBrightness.Loaded += (sender, e) =>
+ {
+ SwLockPlayerBrightness.Toggled += (obj, args) =>
+ {
+ SettingService.SetValue(SettingConstants.Player.LOCK_PLAYER_BRIGHTNESS, SwLockPlayerBrightness.IsOn);
+ };
+ };
+
//自动打开AI字幕
swPlayerSettingAutoOpenAISubtitle.IsOn = SettingService.GetValue(SettingConstants.Player.AUTO_OPEN_AI_SUBTITLE, false);
swPlayerSettingAutoOpenAISubtitle.Loaded += new RoutedEventHandler((sender, e) =>
@@ -1071,5 +1147,35 @@ private void RequestBuildDefaultBtn_OnClick(object sender, RoutedEventArgs e)
RequestBuildTextBox.Text = build;
Notify.ShowMessageToast("已恢复默认");
}
+
+ private async void BtnExportSettings_OnClick(object sender, RoutedEventArgs e)
+ {
+ var exportService = App.ServiceProvider.GetRequiredService();
+ await exportService.ExportSettings();
+ }
+
+ private async void BtnImportSettings_OnClick(object sender, RoutedEventArgs e)
+ {
+ var importService = App.ServiceProvider.GetRequiredService();
+ if (!await importService.ImportSettings())
+ {
+ return;
+ }
+ Notify.ShowMessageToast("导入成功,正在重启应用");
+ // 等用户看提示
+ await Task.Delay(3000);
+ var result = await CoreApplication.RequestRestartAsync("");
+
+ if (result == AppRestartFailureReason.NotInForeground || result == AppRestartFailureReason.Other)
+ {
+ Notify.ShowMessageToast("重启失败,请手动重启应用");
+ }
+ }
+
+ private async void BtnExportSettingsWithAccount_OnClick(object sender, RoutedEventArgs e)
+ {
+ var exportService = App.ServiceProvider.GetRequiredService();
+ await exportService.ExportSettingsWithAccount();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml
index 8ba235e1..691291fc 100644
--- a/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml
+++ b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml
@@ -26,44 +26,74 @@
-
-
-
-
-
-
+
-
+
+
+ Collapsed
+
+
+
Visible
-
+
+
+
Collapsed
+
+
+ Visible
+
+
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
-
+
+
+ Visible
+
+
+
Collapsed
-
+
+
+
Visible
+
+
+ Collapsed
+
+
+
+
+
+
+
+
+
+
@@ -106,16 +136,21 @@
Visibility="Collapsed"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- Background="{ThemeResource HalfTransparentBackground}">
-
+
-
+
+ VerticalAlignment="Stretch" RenderTransformOrigin="0.5,0.5">
+
+
+
diff --git a/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml.cs b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml.cs
index 4a21e0bb..2b231a09 100644
--- a/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/User/DynamicSpacePage.xaml.cs
@@ -1,4 +1,5 @@
using System.Linq;
+using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
@@ -18,7 +19,7 @@ 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
+ public sealed partial class DynamicSpacePage : Page, IRefreshablePage
{
private readonly UserDynamicSpaceViewModel m_viewModel;
private bool m_isStaggered = false;
@@ -75,7 +76,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs e)
private async void BtnRefreshDynamic_OnClick(object sender, RoutedEventArgs e)
{
- await m_viewModel.GetDynamicItems();
+ await Refresh();
}
private void BtnTop_OnClick(object sender, RoutedEventArgs e)
@@ -156,5 +157,10 @@ private void CommentPanel_OnTapped(object sender, TappedRoutedEventArgs e)
{
CloseCommentCore();
}
+
+ public async Task Refresh()
+ {
+ await m_viewModel.GetDynamicItems();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/User/FavoriteDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/User/FavoriteDetailPage.xaml.cs
index 01f9b6a3..23f29a7c 100644
--- a/src/BiliLite.UWP/Pages/User/FavoriteDetailPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/User/FavoriteDetailPage.xaml.cs
@@ -5,6 +5,7 @@
using BiliLite.Services;
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
@@ -22,7 +23,7 @@ public class FavoriteDetailArgs
///
/// 收藏夹详情、播放列表详情
///
- public sealed partial class FavoriteDetailPage : BasePage
+ public sealed partial class FavoriteDetailPage : BasePage, IRefreshablePage
{
FavoriteDetailVM favoriteDetailVM;
public FavoriteDetailPage()
@@ -192,5 +193,10 @@ private async void PlayAll_Click(object sender, RoutedEventArgs e)
}
});
}
+
+ public async Task Refresh()
+ {
+ favoriteDetailVM.Refresh();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/User/FavoritePage.xaml.cs b/src/BiliLite.UWP/Pages/User/FavoritePage.xaml.cs
index 6349f5e0..45fb1924 100644
--- a/src/BiliLite.UWP/Pages/User/FavoritePage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/User/FavoritePage.xaml.cs
@@ -4,18 +4,11 @@
using BiliLite.Modules;
using BiliLite.Services;
using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
+using System.Threading.Tasks;
+
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -32,7 +25,7 @@ public enum OpenFavoriteType
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class FavoritePage : BasePage
+ public sealed partial class FavoritePage : BasePage, IRefreshablePage
{
MyFollowSeasonVM animeVM;
MyFollowSeasonVM cinemaVM;
@@ -164,5 +157,10 @@ private async void btnFavBoxDel_Click(object sender, RoutedEventArgs e)
await videoVM.DelFavorite(data.id);
videoVM.Refresh();
}
+
+ public async Task Refresh()
+ {
+ videoVM.Refresh();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/User/HistoryPage.xaml.cs b/src/BiliLite.UWP/Pages/User/HistoryPage.xaml.cs
index 34d07b71..8cbacf75 100644
--- a/src/BiliLite.UWP/Pages/User/HistoryPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/User/HistoryPage.xaml.cs
@@ -1,4 +1,5 @@
-using BiliLite.Models.Common;
+using System.Threading.Tasks;
+using BiliLite.Models.Common;
using BiliLite.Services;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@@ -14,7 +15,7 @@ namespace BiliLite.Pages.User
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class HistoryPage : BasePage
+ public sealed partial class HistoryPage : BasePage, IRefreshablePage
{
private readonly HistoryViewModel m_viewModel;
public HistoryPage()
@@ -109,5 +110,10 @@ private async void SearchBox_OnQuerySubmitted(AutoSuggestBox sender, AutoSuggest
var keyword = sender.Text;
await m_viewModel.SearchHistory(keyword);
}
+
+ public async Task Refresh()
+ {
+ m_viewModel.Refresh();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/User/WatchlaterPage.xaml.cs b/src/BiliLite.UWP/Pages/User/WatchlaterPage.xaml.cs
index cae560ae..f8c1f446 100644
--- a/src/BiliLite.UWP/Pages/User/WatchlaterPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/User/WatchlaterPage.xaml.cs
@@ -1,19 +1,9 @@
using BiliLite.Models.Common;
using BiliLite.Modules.User;
using BiliLite.Services;
-using System;
using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
-using Windows.UI.Xaml;
+using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-using Windows.UI.Xaml.Data;
-using Windows.UI.Xaml.Input;
-using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板
@@ -23,7 +13,7 @@ namespace BiliLite.Pages.User
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class WatchlaterPage : BasePage
+ public sealed partial class WatchlaterPage : BasePage, IRefreshablePage
{
WatchLaterVM watchLaterVM;
public WatchlaterPage()
@@ -72,5 +62,10 @@ private void Video_ItemClick(object sender, ItemClickEventArgs e)
}
});
}
+
+ public async Task Refresh()
+ {
+ watchLaterVM.Refresh();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs b/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs
index b0df033f..7746477f 100644
--- a/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/UserInfoPage.xaml.cs
@@ -1,4 +1,5 @@
-using BiliLite.Extensions;
+using System.Threading.Tasks;
+using BiliLite.Extensions;
using BiliLite.Models.Common;
using BiliLite.Models.Requests.Api;
using BiliLite.Modules.User.UserDetail;
@@ -34,7 +35,7 @@ public class UserInfoParameter
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
- public sealed partial class UserInfoPage : BasePage
+ public sealed partial class UserInfoPage : BasePage, IRefreshablePage
{
readonly UserDynamicViewModel m_userDynamicViewModel;
UserDetailViewModel m_viewModel;
@@ -405,5 +406,10 @@ private void BtnFollowingTag_OnClick(object sender, RoutedEventArgs e)
{
UserFollowingTagsFlyout.ShowAt(sender as DependencyObject);
}
+
+ public async Task Refresh()
+ {
+ throw new System.NotImplementedException();
+ }
}
}
diff --git a/src/BiliLite.UWP/Pages/VideoDetailPage.xaml.cs b/src/BiliLite.UWP/Pages/VideoDetailPage.xaml.cs
index 9a282891..455f87bf 100644
--- a/src/BiliLite.UWP/Pages/VideoDetailPage.xaml.cs
+++ b/src/BiliLite.UWP/Pages/VideoDetailPage.xaml.cs
@@ -41,7 +41,7 @@ public class VideoPlaylistItem
public string Cover { get; set; }
public string Title { get; set; }
}
- public sealed partial class VideoDetailPage : PlayPage
+ public sealed partial class VideoDetailPage : PlayPage, IRefreshablePage
{
private static readonly ILogger logger = GlobalLogger.FromCurrentType();
@@ -610,12 +610,17 @@ private async void btnDownload_Click(object sender, RoutedEventArgs e)
await downloadDialog.ShowAsync();
}
- private async void btnRefresh_Click(object sender, RoutedEventArgs e)
+ public async Task Refresh()
{
if (m_viewModel.Loading) return;
await InitializeVideo(_id);
}
+ private async void btnRefresh_Click(object sender, RoutedEventArgs e)
+ {
+ await Refresh();
+ }
+
private void btnOpenQR_Click(object sender, RoutedEventArgs e)
{
qrFlyout.ShowAt(btnMore);
diff --git a/src/BiliLite.UWP/Services/GrpcService.cs b/src/BiliLite.UWP/Services/GrpcService.cs
index 5dcd9ccb..86227020 100644
--- a/src/BiliLite.UWP/Services/GrpcService.cs
+++ b/src/BiliLite.UWP/Services/GrpcService.cs
@@ -40,12 +40,17 @@ public async Task SearchSpaceArchive(string mid, int page =
}
}
- public async Task GetDynAll(int page = 1)
+ public async Task GetDynAll(int page = 1, string offset = null)
{
var message = new DynAllReq()
{
- Page = page
+ Page = page,
};
+ if (offset != null)
+ {
+ message.Offset = offset;
+ message.RefreshType = Refresh.History;
+ }
var requestUserInfo = new GrpcBiliUserInfo(
SettingService.Account.AccessKey,
SettingService.Account.UserID,
diff --git a/src/BiliLite.UWP/Services/MessageCenter.cs b/src/BiliLite.UWP/Services/MessageCenter.cs
index 0d916fd1..38198326 100644
--- a/src/BiliLite.UWP/Services/MessageCenter.cs
+++ b/src/BiliLite.UWP/Services/MessageCenter.cs
@@ -94,6 +94,13 @@ private static void ClearCookie()
///
public static async Task HandelUrl(string url, bool dontGoTo = false)
{
+ var uriHref = "";
+ if (url.IsUrl())
+ {
+ var uri = new Uri(url);
+ uriHref = uri.GetLeftPart(UriPartial.Path);
+ }
+
_logger.Debug($"处理链接:{url}");
if (url.First() == '@')
{
@@ -115,7 +122,7 @@ public static async Task HandelUrl(string url, bool dontGoTo = false)
* bilibili://live/5619438
*/
- var live = StringExtensions.RegexMatch(url.Replace("h5", "live").Replace("live.bilibili.com", "live").Replace("/", ""), @"live(\d+)");
+ var live = StringExtensions.RegexMatch(uriHref.Replace("h5", "live").Replace("live.bilibili.com", "live").Replace("/", ""), @"live(\d+)");
if (live != "")
{
NavigateToPage(null, new NavigationInfo()
diff --git a/src/BiliLite.UWP/Services/PlayerToastService.cs b/src/BiliLite.UWP/Services/PlayerToastService.cs
new file mode 100644
index 00000000..6952292f
--- /dev/null
+++ b/src/BiliLite.UWP/Services/PlayerToastService.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Timers;
+using System.Threading.Tasks;
+using Windows.UI.Xaml.Controls;
+using BiliLite.Controls;
+using Windows.UI.Core;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace BiliLite.Services
+{
+ public class PlayerToastService
+ {
+ private PlayerControl m_playerControl;
+ private int[] m_bottomList = new[] { 170, 240, 310, 380, 450, 520 };
+ private readonly Dictionary m_showPlayerToasts = new Dictionary();
+ private readonly Dictionary m_showPlayerToastTimers = new Dictionary();
+ public const string VOLUME_KEY = "Volume";
+ public const string BRIGHTNESS_KEY = "Brightness";
+ public const string PROGRESS_KEY = "Progress";
+ public const string MSG_KEY = "Msg";
+ public const string ACCELERATING_KEY = "Accelerating";
+ public const string SPEED_KEY = "Speed";
+ private readonly IServiceProvider m_serviceProvider;
+
+ public PlayerToastService(IServiceProvider serviceProvider)
+ {
+ m_serviceProvider = serviceProvider;
+ }
+
+ public void Init(PlayerControl control)
+ {
+ m_playerControl = control;
+ }
+
+ public async void KeepStart(string key, string msg)
+ {
+ var newToast = m_serviceProvider.GetRequiredService();
+ newToast.Height = 80;
+ newToast.Width = 200;
+ newToast.Text = msg;
+ Canvas.SetLeft(newToast, 0);
+ double distanceFromBottom = m_bottomList[m_showPlayerToasts.Count];
+ while (m_playerControl.ActualHeight == 0)
+ {
+ await Task.Delay(500);
+ }
+ Canvas.SetTop(newToast, m_playerControl.ActualHeight - distanceFromBottom);
+
+ m_showPlayerToasts.Add(key, newToast);
+ m_playerControl.PlayerToastContainer.Children.Add(newToast);
+ newToast.Show();
+ }
+
+ public async void KeepClose(string key)
+ {
+ if (!m_showPlayerToasts.TryGetValue(key, out var toast)) return;
+ m_playerControl.PlayerToastContainer.Children.Remove(toast);
+ m_showPlayerToasts.Remove(key);
+ }
+
+ public async void Show(string key, string msg)
+ {
+ if (m_showPlayerToasts.TryGetValue(key, out var toast))
+ {
+ toast.Text = msg;
+ var timer = m_showPlayerToastTimers[key];
+ timer.Stop();
+ timer.Start();
+ return;
+ }
+
+ var newToast = m_serviceProvider.GetRequiredService();
+ newToast.Height = 80;
+ newToast.Width = 200;
+ newToast.Text = msg;
+ Canvas.SetLeft(newToast, 0);
+ double distanceFromBottom = m_bottomList[m_showPlayerToasts.Count];
+ while (m_playerControl.ActualHeight == 0)
+ {
+ await Task.Delay(500);
+ }
+ Canvas.SetTop(newToast, m_playerControl.ActualHeight - distanceFromBottom);
+
+ m_showPlayerToasts.Add(key, newToast);
+ m_playerControl.PlayerToastContainer.Children.Add(newToast);
+ newToast.Show();
+
+ var newTimer = new Timer();
+ newTimer.Interval = 2000;
+ newTimer.Elapsed += async (o, e) =>
+ {
+ await m_playerControl.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
+ {
+ newTimer.Stop();
+ m_playerControl.PlayerToastContainer.Children.Remove(newToast);
+ m_showPlayerToasts.Remove(key);
+ m_showPlayerToastTimers.Remove(key);
+ });
+ };
+ m_showPlayerToastTimers.Add(key, newTimer);
+ newTimer.Start();
+ }
+ }
+}
diff --git a/src/BiliLite.UWP/Services/SettingService.cs b/src/BiliLite.UWP/Services/SettingService.cs
index 17c599d7..37356911 100644
--- a/src/BiliLite.UWP/Services/SettingService.cs
+++ b/src/BiliLite.UWP/Services/SettingService.cs
@@ -25,6 +25,11 @@ public static void SetValue(string key, T value)
storageHelper.Save(key, value);
}
+ public static bool HasValue(string key)
+ {
+ return storageHelper.KeyExists(key);
+ }
+
public class UI
{
private static bool? _loadOriginalImage = null;
diff --git a/src/BiliLite.UWP/Services/SettingsImportExportService.cs b/src/BiliLite.UWP/Services/SettingsImportExportService.cs
new file mode 100644
index 00000000..963fb4ed
--- /dev/null
+++ b/src/BiliLite.UWP/Services/SettingsImportExportService.cs
@@ -0,0 +1,257 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using Windows.Storage.Pickers;
+using BiliLite.Models.Attributes;
+using BiliLite.Models.Common;
+using Newtonsoft.Json;
+using Tomlyn;
+using Tomlyn.Model;
+using BiliLite.Extensions;
+using System.Security.Cryptography;
+using Windows.Storage;
+using ArtisanCode.SimpleAesEncryption;
+
+namespace BiliLite.Services
+{
+ public class SettingsImportExportService
+ {
+ private static readonly ILogger _logger = GlobalLogger.FromCurrentType();
+ private const string SETTINGS_EXPORT_KEY = "4bmsD9chgoP1jdohv2+OV9Pv2403r4IfJU18ixpFWQA=";
+ private const string SETTINGS_EXPORT_IV = "ABxrLAWa7MrKg6w1xxtZmw==";
+ private readonly RijndaelMessageEncryptor m_encryptor;
+ private readonly RijndaelMessageDecryptor m_decryptor;
+
+ public SettingsImportExportService()
+ {
+ var config = new SimpleAesEncryptionConfiguration()
+ {
+ CipherMode = CipherMode.CBC,
+ Padding = PaddingMode.PKCS7,
+ EncryptionKey = new EncryptionKeyConfigurationElement(256, SETTINGS_EXPORT_KEY),
+ };
+ m_encryptor = new RijndaelMessageEncryptor(config);
+ m_decryptor = new RijndaelMessageDecryptor(config);
+ }
+
+ private void ExportSettingsCore(TomlTable model, Type settingsType)
+ {
+ var fields = settingsType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
+ foreach (var field in fields)
+ {
+ var attributes = field.GetCustomAttributes(false);
+ var keyAttribute = attributes.FirstOrDefault(x => x.GetType() == typeof(SettingKeyAttribute));
+ if (!(keyAttribute is SettingKeyAttribute settingKeyAttribute)) continue;
+ var key = field.GetRawConstantValue().ToString();
+
+ if (!SettingService.HasValue(key)) continue;
+
+ object value = null;
+ if (settingKeyAttribute.Type == typeof(string))
+ {
+ value = SettingService.GetValue(key, "");
+ }
+ else if (settingKeyAttribute.Type == typeof(int))
+ {
+ value = SettingService.GetValue(key, 0);
+ }
+ else if (settingKeyAttribute.Type == typeof(long))
+ {
+ value = SettingService.GetValue(key, 0);
+ }
+ else if (settingKeyAttribute.Type == typeof(double))
+ {
+ value = SettingService.GetValue(key, 0);
+ }
+ else if (settingKeyAttribute.Type == typeof(object))
+ {
+ value = SettingService.GetValue