Skip to content

Commit

Permalink
支持设置推荐页、搜索页、动态页过滤
Browse files Browse the repository at this point in the history
  • Loading branch information
ywmoyue committed Jul 9, 2024
1 parent 12e851b commit a81dcb5
Show file tree
Hide file tree
Showing 18 changed files with 759 additions and 11 deletions.
16 changes: 16 additions & 0 deletions src/BiliLite.UWP/BiliLite.UWP.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@
<Compile Include="Controls\Dynamic\DynamicItemV2Control.xaml.cs">
<DependentUpon>DynamicItemV2Control.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\FilterSettingsControl.xaml.cs">
<DependentUpon>FilterSettingsControl.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\PlayerToast.xaml.cs">
<DependentUpon>PlayerToast.xaml</DependentUpon>
</Compile>
Expand All @@ -152,6 +155,7 @@
<Compile Include="Controls\VideoListView.xaml.cs">
<DependentUpon>VideoListView.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\FilterRuleTypeConverter.cs" />
<Compile Include="Dialogs\EditPlaySpeedMenuDialog.xaml.cs">
<DependentUpon>EditPlaySpeedMenuDialog.xaml</DependentUpon>
</Compile>
Expand All @@ -170,6 +174,8 @@
<Compile Include="Models\Common\Danmaku\BiliDanmakuItem.cs" />
<Compile Include="Models\Common\Dynamic\DynamicUgcSeasonCardModel.cs" />
<Compile Include="Models\Common\Player\PlaySpeedMenu.cs" />
<Compile Include="Models\Common\Settings\FilterRule.cs" />
<Compile Include="Models\Common\Settings\FilterRuleTypes.cs" />
<Compile Include="Models\Common\UploadFileInfo.cs" />
<Compile Include="Models\Common\UserDynamic\DynamicPicture.cs" />
<Compile Include="Models\Common\UserDynamic\DynLiveInfo.cs" />
Expand Down Expand Up @@ -197,10 +203,13 @@
<Compile Include="Models\Functions\SaveFunction.cs" />
<Compile Include="Pages\ISavablePage.cs" />
<Compile Include="Services\Biz\MediaListService.cs" />
<Compile Include="Services\ContentFilterService.cs" />
<Compile Include="Services\PlaySpeedMenuService.cs" />
<Compile Include="ViewModels\Comment\SendCommentDialogViewModel.cs" />
<Compile Include="ViewModels\Rank\RankRegionViewModel.cs" />
<Compile Include="ViewModels\Settings\EditPlaySpeedMenuViewModel.cs" />
<Compile Include="ViewModels\Settings\FilterRuleViewModel.cs" />
<Compile Include="ViewModels\Settings\FilterSettingsViewModel.cs" />
<Compile Include="ViewModels\User\FavoriteItemViewModel.cs" />
<Compile Include="Pages\Home\UserDynamicPage.xaml.cs">
<DependentUpon>UserDynamicPage.xaml</DependentUpon>
Expand Down Expand Up @@ -1017,6 +1026,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Controls\FilterSettingsControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Controls\PlayerToast.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -1310,6 +1323,9 @@
<PackageReference Include="AutoMapper">
<Version>10.1.1</Version>
</PackageReference>
<PackageReference Include="CommunityToolkit.Uwp.Controls.SettingsControls">
<Version>8.0.240109</Version>
</PackageReference>
<PackageReference Include="DanmakuFrostMaster.muyan">
<Version>1.0.2</Version>
</PackageReference>
Expand Down
156 changes: 156 additions & 0 deletions src/BiliLite.UWP/Controls/FilterSettingsControl.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<UserControl
x:Class="BiliLite.Controls.FilterSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BiliLite.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:settings="using:BiliLite.ViewModels.Settings"
xmlns:models="using:BiliLite.Models.Common.Settings"
xmlns:converters="using:BiliLite.Converters"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<ResourceDictionary>
<converters:FilterRuleTypeConverter x:Key="FilterRuleTypeConverter"></converters:FilterRuleTypeConverter>
</ResourceDictionary>
</UserControl.Resources>

<StackPanel x:Name="FilterSettingsControlGrid" Orientation="Vertical">
<ListView ItemsSource="{x:Bind m_viewModel.RecommendFilterRules,Mode=OneWay}"
x:Name="RecommendFilterRuleListView">
<ListView.Header>
<Grid Margin="16 0">
<TextBlock VerticalAlignment="Center">推荐页过滤</TextBlock>
<Button HorizontalAlignment="Right" x:Name="BtnAddRecommendFilterRule" Click="BtnAddRecommendFilterRule_OnClick">添加规则</Button>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate x:DataType="settings:FilterRuleViewModel">
<controls:SettingsExpander Header="{x:Bind Rule,Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind Enable,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Toggled="OnFilterRuleChanged"></ToggleSwitch>
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="过滤值"
Description="{x:Bind RuleDesc,Mode=OneWay}">
<TextBox Text="{x:Bind Rule,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" TextChanged="OnFilterRuleChanged"></TextBox>
</controls:SettingsCard>
<controls:SettingsCard Header="规则类型"
Description="{x:Bind FilterTypeDesc}">
<ComboBox ItemsSource="{x:Bind models:FilterRuleTypes.FilterTypeOptions}"
Padding="8 0 0 0"
SelectedItem="{x:Bind FilterType,Mode=TwoWay,Converter={StaticResource FilterRuleTypeConverter}}"
SelectionChanged="OnFilterRuleChanged"
DisplayMemberPath="Text">
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard Header="过滤目标"
Description="{x:Bind FilterContentTypeDesc}">
<ComboBox ItemsSource="{x:Bind models:FilterRuleTypes.FilterTargetOptions}"
Padding="8 0 0 0"
SelectedItem="{x:Bind ContentType,Mode=TwoWay,Converter={StaticResource FilterRuleTypeConverter}}"
SelectionChanged="OnFilterRuleChanged"
DisplayMemberPath="Text">
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard Header="删除规则">
<Button Click="BtnDeleteFilterRule_OnClick">确认删除</Button>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

<ListView ItemsSource="{x:Bind m_viewModel.SearchFilterRules,Mode=OneWay}"
Margin="0 16 0 0"
x:Name="SearchFilterRuleListView">
<ListView.Header>
<Grid Margin="16 0">
<TextBlock VerticalAlignment="Center">搜索页过滤</TextBlock>
<Button HorizontalAlignment="Right" x:Name="BtnAddSearchFilterRule" Click="BtnAddSearchFilterRule_OnClick">添加规则</Button>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate x:DataType="settings:FilterRuleViewModel">
<controls:SettingsExpander Header="{x:Bind Rule,Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind Enable,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Toggled="OnFilterRuleChanged"></ToggleSwitch>
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="过滤值"
Description="{x:Bind RuleDesc,Mode=OneWay}">
<TextBox Text="{x:Bind Rule,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" TextChanged="OnFilterRuleChanged"></TextBox>
</controls:SettingsCard>
<controls:SettingsCard Header="规则类型"
Description="{x:Bind FilterTypeDesc}">
<ComboBox ItemsSource="{x:Bind models:FilterRuleTypes.FilterTypeOptions}"
Padding="8 0 0 0"
SelectedItem="{x:Bind FilterType,Mode=TwoWay,Converter={StaticResource FilterRuleTypeConverter}}"
SelectionChanged="OnFilterRuleChanged"
DisplayMemberPath="Text">
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard Header="过滤目标"
Description="{x:Bind FilterContentTypeDesc}">
<ComboBox ItemsSource="{x:Bind models:FilterRuleTypes.FilterTargetOptions}"
Padding="8 0 0 0"
SelectedItem="{x:Bind ContentType,Mode=TwoWay,Converter={StaticResource FilterRuleTypeConverter}}"
SelectionChanged="OnFilterRuleChanged"
DisplayMemberPath="Text">
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard Header="删除规则">
<Button Click="BtnDeleteFilterRule_OnClick">确认删除</Button>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

<ListView ItemsSource="{x:Bind m_viewModel.DynamicFilterRules,Mode=OneWay}"
Margin="0 16 0 0"
x:Name="DynamicFilterRuleListView">
<ListView.Header>
<Grid Margin="16 0">
<TextBlock VerticalAlignment="Center">动态页过滤</TextBlock>
<Button HorizontalAlignment="Right" x:Name="BtnAddDynamicFilterRule" Click="BtnAddDynamicFilterRule_OnClick">添加规则</Button>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate x:DataType="settings:FilterRuleViewModel">
<controls:SettingsExpander Header="{x:Bind Rule,Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind Enable,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Toggled="OnFilterRuleChanged"></ToggleSwitch>
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="过滤值"
Description="{x:Bind RuleDesc,Mode=OneWay}">
<TextBox Text="{x:Bind Rule,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" TextChanged="OnFilterRuleChanged"></TextBox>
</controls:SettingsCard>
<controls:SettingsCard Header="规则类型"
Description="{x:Bind FilterTypeDesc}">
<ComboBox ItemsSource="{x:Bind models:FilterRuleTypes.FilterTypeOptions}"
Padding="8 0 0 0"
SelectedItem="{x:Bind FilterType,Mode=TwoWay,Converter={StaticResource FilterRuleTypeConverter}}"
SelectionChanged="OnFilterRuleChanged"
DisplayMemberPath="Text">
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard Header="过滤目标"
Description="{x:Bind FilterContentTypeDesc}">
<ComboBox ItemsSource="{x:Bind models:FilterRuleTypes.FilterTargetOptions}"
Padding="8 0 0 0"
SelectedItem="{x:Bind ContentType,Mode=TwoWay,Converter={StaticResource FilterRuleTypeConverter}}"
SelectionChanged="OnFilterRuleChanged"
DisplayMemberPath="Text">
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard Header="删除规则">
<Button Click="BtnDeleteFilterRule_OnClick">确认删除</Button>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</UserControl>
112 changes: 112 additions & 0 deletions src/BiliLite.UWP/Controls/FilterSettingsControl.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using AutoMapper;
using BiliLite.Models.Common;
using BiliLite.Models.Common.Settings;
using BiliLite.Services;
using BiliLite.ViewModels.Settings;
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;

//https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板

namespace BiliLite.Controls
{
public sealed partial class FilterSettingsControl : UserControl
{
private readonly ContentFilterService m_contentFilterService;
private readonly FilterSettingsViewModel m_viewModel;
private readonly IMapper m_mapper;

public FilterSettingsControl()
{
m_mapper = App.ServiceProvider.GetRequiredService<IMapper>();
m_viewModel = App.ServiceProvider.GetRequiredService<FilterSettingsViewModel>();
DataContext = m_viewModel;
m_contentFilterService = App.ServiceProvider.GetRequiredService<ContentFilterService>();
m_viewModel.RecommendFilterRules =
new ObservableCollection<FilterRuleViewModel>(
m_mapper.Map<List<FilterRuleViewModel>>(m_contentFilterService.RecommendFilterRules)
);
m_viewModel.SearchFilterRules =
new ObservableCollection<FilterRuleViewModel>(
m_mapper.Map<List<FilterRuleViewModel>>(m_contentFilterService.SearchFilterRules)
);
m_viewModel.DynamicFilterRules =
new ObservableCollection<FilterRuleViewModel>(
m_mapper.Map<List<FilterRuleViewModel>>(m_contentFilterService.DynamicFilterRules)
);
this.InitializeComponent();
}

private FilterRule CreateNewFilterRule(FilterRuleType filterRuleType)
{
var rule = new FilterRule()
{
Id = Guid.NewGuid().ToString(),
Rule = "新规则",
FilterRuleType = filterRuleType,
ContentType = FilterContentType.Title,
FilterType = FilterType.Word,
Enable = true,
};
return rule;
}

private void BtnAddRecommendFilterRule_OnClick(object sender, RoutedEventArgs e)
{
var rule = CreateNewFilterRule(FilterRuleType.Recommend);
m_contentFilterService.AddRecommendFilterRule(rule);
var ruleViewModel = m_mapper.Map<FilterRuleViewModel>(rule);
m_viewModel.RecommendFilterRules.Add(ruleViewModel);
}

private void UpdateFilterRule(FilterRuleViewModel filterRuleViewModel)
{
var rule = m_mapper.Map<FilterRule>(filterRuleViewModel);
m_contentFilterService.UpdateFilterRule(rule);
}

private async void OnFilterRuleChanged<T>(object sender, T e)
{
if (sender is FrameworkElement { DataContext: FilterRuleViewModel filterRuleViewModel })
{
// 等待数据源更新
await Task.Delay(50);
UpdateFilterRule(filterRuleViewModel);
}
}

private void BtnDeleteFilterRule_OnClick(object sender, RoutedEventArgs e)
{
if (sender is FrameworkElement { DataContext: FilterRuleViewModel filterRuleViewModel })
{
var rule = m_mapper.Map<FilterRule>(filterRuleViewModel);
m_contentFilterService.DeleteFilterRule(rule);

m_viewModel.RecommendFilterRules.Remove(filterRuleViewModel);
m_viewModel.SearchFilterRules.Remove(filterRuleViewModel);
m_viewModel.DynamicFilterRules.Remove(filterRuleViewModel);
}
}

private void BtnAddSearchFilterRule_OnClick(object sender, RoutedEventArgs e)
{
var rule = CreateNewFilterRule(FilterRuleType.Search);
m_contentFilterService.AddSearchFilterRule(rule);
var ruleViewModel = m_mapper.Map<FilterRuleViewModel>(rule);
m_viewModel.SearchFilterRules.Add(ruleViewModel);
}

private void BtnAddDynamicFilterRule_OnClick(object sender, RoutedEventArgs e)
{
var rule = CreateNewFilterRule(FilterRuleType.Dynamic);
m_contentFilterService.AddDynamicFilterRule(rule);
var ruleViewModel = m_mapper.Map<FilterRuleViewModel>(rule);
m_viewModel.DynamicFilterRules.Add(ruleViewModel);
}
}
}
48 changes: 48 additions & 0 deletions src/BiliLite.UWP/Converters/FilterRuleTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using BiliLite.Models.Common;
using System;
using System.Linq;
using Windows.UI.Xaml.Data;
using BiliLite.Models.Common.Settings;

namespace BiliLite.Converters
{
public class FilterRuleTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is FilterType filterType)
{
return FilterRuleTypes.FilterTypeOptions.FirstOrDefault(x => x.Type == filterType);
}
else if(value is FilterContentType contentType)
{
return FilterRuleTypes.FilterTargetOptions.FirstOrDefault(x => x.Type == contentType);
}

return null;
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
if (value is FilterTypeOption filterType)
{
return filterType.Type;
}
else if (value is FilterTargetOption contentType)
{
return contentType.Type;
}

if (targetType == typeof(FilterType))
{
return FilterType.Word;
}
if (targetType == typeof(FilterContentType))
{
return FilterContentType.Title;
}

return null;
}
}
}
Loading

0 comments on commit a81dcb5

Please sign in to comment.