fix(Fixed some issues in the settings page.):

This commit is contained in:
real-zony 2024-07-02 18:27:52 +08:00
parent b57739f543
commit d5689164b5
7 changed files with 116 additions and 125 deletions

View File

@ -8,6 +8,10 @@
xmlns:settings="clr-namespace:ZonyLrcTools.Desktop.ViewModels.Settings" xmlns:settings="clr-namespace:ZonyLrcTools.Desktop.ViewModels.Settings"
x:DataType="settings:SettingsViewModel"> x:DataType="settings:SettingsViewModel">
<UserControl.Resources>
<settings:NullToDefaultValueConverter x:Key="NullToDefaultValueConverter" />
</UserControl.Resources>
<ScrollViewer> <ScrollViewer>
<StackPanel Orientation="Vertical" Margin="24" Spacing="8"> <StackPanel Orientation="Vertical" Margin="24" Spacing="8">
<Grid ColumnDefinitions="Auto,*,Auto,Auto"> <Grid ColumnDefinitions="Auto,*,Auto,Auto">
@ -80,7 +84,7 @@
<!-- 歌词下载器配置 --> <!-- 歌词下载器配置 -->
<ui:SettingsExpander Header="歌词下载器设置" Description="配置每个单独的歌词下载器参数" IconSource="{StaticResource DownloadIcon}"> <ui:SettingsExpander Header="歌词下载器设置" Description="配置每个单独的歌词下载器参数" IconSource="{StaticResource DownloadIcon}">
<ItemsRepeater ItemsSource="{Binding Plugin}"> <ItemsRepeater ItemsSource="{Binding LyricsProviders}">
<ItemsRepeater.ItemTemplate> <ItemsRepeater.ItemTemplate>
<DataTemplate> <DataTemplate>
<ui:SettingsExpander Margin="0,0,0,10"> <ui:SettingsExpander Margin="0,0,0,10">
@ -90,13 +94,13 @@
<ui:SettingsExpanderItem Content="下载器优先级"> <ui:SettingsExpanderItem Content="下载器优先级">
<ui:SettingsExpanderItem.Footer> <ui:SettingsExpanderItem.Footer>
<NumericUpDown Value="{Binding Priority}" Minimum="-1" Maximum="100" /> <NumericUpDown Value="{Binding Priority}" Minimum="-1" Maximum="100" Increment="1" />
</ui:SettingsExpanderItem.Footer> </ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem> </ui:SettingsExpanderItem>
<ui:SettingsExpanderItem Content="搜索深度"> <ui:SettingsExpanderItem Content="搜索深度">
<ui:SettingsExpanderItem.Footer> <ui:SettingsExpanderItem.Footer>
<NumericUpDown Value="{Binding Depth}" Minimum="1" Maximum="100" /> <NumericUpDown Value="{Binding Depth}" Minimum="1" Maximum="100" Increment="1" />
</ui:SettingsExpanderItem.Footer> </ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem> </ui:SettingsExpanderItem>
</ui:SettingsExpander> </ui:SettingsExpander>
@ -118,13 +122,13 @@
<ui:SettingsExpanderItem.Footer> <ui:SettingsExpanderItem.Footer>
<StackPanel Orientation="Horizontal" Spacing="10"> <StackPanel Orientation="Horizontal" Spacing="10">
<TextBox Text="{Binding Tag.BlockWord.FilePath}" Width="200" /> <TextBox Text="{Binding Tag.BlockWord.FilePath}" Width="200" />
<Button Content="浏览" Command="{Binding BrowseBlockWordFileCommand}" /> <Button Content="浏览" Command="{Binding BrowseBlockWordFileCommand}" CommandParameter="{Binding $parent[Window]}" />
</StackPanel> </StackPanel>
</ui:SettingsExpanderItem.Footer> </ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem> </ui:SettingsExpanderItem>
<ui:SettingsExpander Header="标签扫描器" Description="配置标签扫描器"> <ui:SettingsExpander Header="标签扫描器" Description="配置标签扫描器">
<ItemsRepeater ItemsSource="{Binding Tag.Plugin}"> <ItemsRepeater ItemsSource="{Binding Tag.TagInfoProviders}">
<ItemsRepeater.ItemTemplate> <ItemsRepeater.ItemTemplate>
<DataTemplate> <DataTemplate>
<ui:SettingsExpander Margin="0,0,0,10"> <ui:SettingsExpander Margin="0,0,0,10">
@ -134,7 +138,7 @@
<ui:SettingsExpanderItem Content="优先级"> <ui:SettingsExpanderItem Content="优先级">
<ui:SettingsExpanderItem.Footer> <ui:SettingsExpanderItem.Footer>
<NumericUpDown Value="{Binding Priority}" Minimum="-1" Maximum="100" /> <NumericUpDown Value="{Binding Priority}" Minimum="-1" Maximum="100" Increment="1" />
</ui:SettingsExpanderItem.Footer> </ui:SettingsExpanderItem.Footer>
</ui:SettingsExpanderItem> </ui:SettingsExpanderItem>

View File

@ -1,37 +1,26 @@
using System;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using ZonyLrcTools.Common.Configuration; using ZonyLrcTools.Common.Configuration;
namespace ZonyLrcTools.Desktop.ViewModels.Settings; namespace ZonyLrcTools.Desktop.ViewModels.Settings;
public class BlockWordViewModel : ViewModelBase public class BlockWordViewModel : ViewModelBase
{ {
private readonly BlockWordOptions _options; public BlockWordViewModel(GlobalOptions options)
public BlockWordViewModel(BlockWordOptions options)
{ {
_options = options; IsEnable = options.Provider.Tag.BlockWord.IsEnable;
FilePath = options.Provider.Tag.BlockWord.FilePath;
this.WhenAnyValue(x => x.IsEnable, x => x.FilePath)
.Subscribe(_ =>
{
options.Provider.Tag.BlockWord.IsEnable = IsEnable;
options.Provider.Tag.BlockWord.FilePath = FilePath;
});
} }
public bool IsEnable [Reactive] public bool IsEnable { get; set; }
{
get => _options.IsEnable;
set
{
if (_options.IsEnable != value)
{
_options.IsEnable = value;
}
}
}
public string FilePath [Reactive] public string? FilePath { get; set; }
{
get => _options.FilePath;
set
{
if (_options.FilePath != value)
{
_options.FilePath = value;
}
}
}
} }

View File

@ -10,26 +10,25 @@ namespace ZonyLrcTools.Desktop.ViewModels.Settings;
public class GlobalConfigurationViewModel : ViewModelBase public class GlobalConfigurationViewModel : ViewModelBase
{ {
private readonly GlobalLyricsConfigOptions _config; public GlobalConfigurationViewModel(GlobalOptions config)
public GlobalConfigurationViewModel(GlobalLyricsConfigOptions config)
{ {
_config = config; var globalConfig = config.Provider.Lyric.Config;
InitializeLineBreakComboBoxItem();
IsOneLine = _config.IsOneLine; InitializeLineBreakComboBoxItem(globalConfig);
IsEnableTranslation = _config.IsEnableTranslation;
IsSkipExistLyricFiles = _config.IsSkipExistLyricFiles; IsOneLine = globalConfig.IsOneLine;
IsOnlyOutputTranslation = _config.IsOnlyOutputTranslation; IsEnableTranslation = globalConfig.IsEnableTranslation;
IsSkipExistLyricFiles = globalConfig.IsSkipExistLyricFiles;
IsOnlyOutputTranslation = globalConfig.IsOnlyOutputTranslation;
this.WhenAnyValue(x => x.IsOneLine) this.WhenAnyValue(x => x.IsOneLine)
.Subscribe(x => _config.IsOneLine = x); .Subscribe(x => globalConfig.IsOneLine = x);
this.WhenAnyValue(x => x.IsEnableTranslation) this.WhenAnyValue(x => x.IsEnableTranslation)
.Subscribe(x => _config.IsEnableTranslation = x); .Subscribe(x => globalConfig.IsEnableTranslation = x);
this.WhenAnyValue(x => x.IsSkipExistLyricFiles) this.WhenAnyValue(x => x.IsSkipExistLyricFiles)
.Subscribe(x => _config.IsSkipExistLyricFiles = x); .Subscribe(x => globalConfig.IsSkipExistLyricFiles = x);
this.WhenAnyValue(x => x.IsOnlyOutputTranslation) this.WhenAnyValue(x => x.IsOnlyOutputTranslation)
.Subscribe(x => _config.IsOnlyOutputTranslation = x); .Subscribe(x => globalConfig.IsOnlyOutputTranslation = x);
} }
[Reactive] public bool IsOneLine { get; set; } [Reactive] public bool IsOneLine { get; set; }
@ -38,11 +37,9 @@ public class GlobalConfigurationViewModel : ViewModelBase
[Reactive] public bool IsSkipExistLyricFiles { get; set; } [Reactive] public bool IsSkipExistLyricFiles { get; set; }
[Reactive] public string FileEncoding { get; set; }
[Reactive] public bool IsOnlyOutputTranslation { get; set; } [Reactive] public bool IsOnlyOutputTranslation { get; set; }
private void InitializeLineBreakComboBoxItem() private void InitializeLineBreakComboBoxItem(GlobalLyricsConfigOptions config)
{ {
LineBreakOptions = LineBreakOptions =
[ [
@ -50,20 +47,20 @@ public class GlobalConfigurationViewModel : ViewModelBase
new TextComboboxItem { Name = "Unix", Value = "\n" }, new TextComboboxItem { Name = "Unix", Value = "\n" },
new TextComboboxItem { Name = "Mac", Value = "\r" } new TextComboboxItem { Name = "Mac", Value = "\r" }
]; ];
SelectedLineBreak = LineBreakOptions.FirstOrDefault(x => x.Value == _config.LineBreak) SelectedLineBreak = LineBreakOptions.FirstOrDefault(x => x.Value == config.LineBreak)
?? LineBreakOptions.First(); ?? LineBreakOptions.First();
FileEncodingOptions = Encoding.GetEncodings() FileEncodingOptions = Encoding.GetEncodings()
.Select(x => new TextComboboxItem { Name = x.DisplayName, Value = x.Name }) .Select(x => new TextComboboxItem { Name = x.DisplayName, Value = x.Name })
.ToList(); .ToList();
FileEncodingOptions.Insert(0, new TextComboboxItem { Name = "UTF-8-BOM", Value = "utf-8-bom" }); FileEncodingOptions.Insert(0, new TextComboboxItem { Name = "UTF-8-BOM", Value = "utf-8-bom" });
SelectedFileEncoding = FileEncodingOptions.FirstOrDefault(x => x.Value == _config.FileEncoding) SelectedFileEncoding = FileEncodingOptions.FirstOrDefault(x => x.Value == config.FileEncoding)
?? FileEncodingOptions.First(); ?? FileEncodingOptions.First();
this.WhenAnyValue(x => x.SelectedLineBreak) this.WhenAnyValue(x => x.SelectedLineBreak)
.Subscribe(x => _config.LineBreak = x.Value); .Subscribe(x => config.LineBreak = x.Value);
this.WhenAnyValue(x => x.SelectedFileEncoding) this.WhenAnyValue(x => x.SelectedFileEncoding)
.Subscribe(x => _config.FileEncoding = x.Value); .Subscribe(x => config.FileEncoding = x.Value);
} }
public List<TextComboboxItem> LineBreakOptions { get; private set; } public List<TextComboboxItem> LineBreakOptions { get; private set; }

View File

@ -1,49 +1,52 @@
using System;
using System.Globalization;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using ZonyLrcTools.Common.Configuration; using ZonyLrcTools.Common.Configuration;
namespace ZonyLrcTools.Desktop.ViewModels.Settings; namespace ZonyLrcTools.Desktop.ViewModels.Settings;
public class LyricsProviderViewModel : ViewModelBase public class LyricsProviderViewModel : ViewModelBase
{ {
private readonly LyricsProviderOptions _options;
public LyricsProviderViewModel(LyricsProviderOptions options) public LyricsProviderViewModel(LyricsProviderOptions options)
{ {
_options = options; var globalOptions = App.Current.Services.GetRequiredService<IOptions<GlobalOptions>>().Value;
Name = options.Name;
Priority = options.Priority;
Depth = options.Depth;
this.WhenAnyValue(x => x.Priority)
.Subscribe(priority => globalOptions.Provider.Lyric.GetLyricProviderOption(Name).Priority = priority);
this.WhenAnyValue(x => x.Depth)
.Subscribe(depth => globalOptions.Provider.Lyric.GetLyricProviderOption(Name).Depth = depth);
} }
public string Name public string Name { get; set; }
[Reactive] public int Priority { get; set; }
[Reactive] public int Depth { get; set; }
}
internal class NullToDefaultValueConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
get => _options.Name; return value != null ? System.Convert.ToDecimal(value) : 0;
set
{
if (_options.Name != value)
{
_options.Name = value;
}
}
} }
public int Priority public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
get => _options.Priority; if (value is decimal dValue)
set
{ {
if (_options.Priority != value) return System.Convert.ToInt32(dValue);
{
_options.Priority = value;
}
}
} }
public int Depth return BindingOperations.DoNothing;
{
get => _options.Depth;
set
{
if (_options.Depth != value)
{
_options.Depth = value;
}
}
} }
} }

View File

@ -1,6 +1,9 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Reactive; using System.Reactive;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
using ReactiveUI; using ReactiveUI;
using ZonyLrcTools.Common.Configuration; using ZonyLrcTools.Common.Configuration;
@ -8,31 +11,46 @@ namespace ZonyLrcTools.Desktop.ViewModels.Settings;
public class SettingsViewModel : ViewModelBase public class SettingsViewModel : ViewModelBase
{ {
private readonly GlobalOptions _globalOptions;
public SettingsViewModel(GlobalOptions globalOptions) public SettingsViewModel(GlobalOptions globalOptions)
{ {
_globalOptions = globalOptions; Config = new GlobalConfigurationViewModel(globalOptions);
LyricsProviders = new ObservableCollection<LyricsProviderViewModel>(globalOptions.Provider.Lyric.Plugin.Select(p => new LyricsProviderViewModel(p)));
Config = new GlobalConfigurationViewModel(globalOptions.Provider.Lyric.Config); Tag = new TagInfoViewModel(globalOptions);
Plugin = new ObservableCollection<LyricsProviderViewModel>(globalOptions.Provider.Lyric.Plugin.Select(p => new LyricsProviderViewModel(p))); BrowseBlockWordFileCommand = ReactiveCommand.CreateFromTask<Window>(BrowseBlockWordFile);
Tag = new TagInfoViewModel(globalOptions.Provider.Tag);
BrowseBlockWordFileCommand = ReactiveCommand.Create(BrowseBlockWordFile);
} }
public static string Version => typeof(Program).Assembly.GetName().Version!.ToString(); public static string Version => typeof(Program).Assembly.GetName().Version!.ToString();
public TagInfoViewModel Tag { get; } public TagInfoViewModel Tag { get; }
public ReactiveCommand<Unit, Unit> BrowseBlockWordFileCommand { get; } public ReactiveCommand<Window, Unit> BrowseBlockWordFileCommand { get; }
public GlobalConfigurationViewModel Config { get; } public GlobalConfigurationViewModel Config { get; }
public ObservableCollection<LyricsProviderViewModel> Plugin { get; } public ObservableCollection<LyricsProviderViewModel> LyricsProviders { get; }
private void BrowseBlockWordFile() private async Task BrowseBlockWordFile(Window parentWindow)
{ {
// Implement file browsing logic here var storage = parentWindow.StorageProvider;
// Update Tag.BlockWord.FilePath with the selected file path if (storage.CanOpen)
{
var options = new FilePickerOpenOptions
{
AllowMultiple = false,
FileTypeFilter = new[]
{
new FilePickerFileType("JSON")
{
Patterns = new[] { "*.json" }
}
}
};
var files = await storage.OpenFilePickerAsync(options);
if (files.Count > 0)
{
Tag.BlockWord.FilePath = files[0].Path.LocalPath;
}
}
} }
} }

View File

@ -1,42 +1,22 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using ReactiveUI.Fody.Helpers;
using ZonyLrcTools.Common.Configuration; using ZonyLrcTools.Common.Configuration;
namespace ZonyLrcTools.Desktop.ViewModels.Settings; namespace ZonyLrcTools.Desktop.ViewModels.Settings;
public class TagInfoProviderViewModel : ViewModelBase public class TagInfoProviderViewModel : ViewModelBase
{ {
private readonly TagInfoProviderOptions _options;
public TagInfoProviderViewModel(TagInfoProviderOptions options) public TagInfoProviderViewModel(TagInfoProviderOptions options)
{ {
_options = options; Name = options.Name;
Priority = options.Priority;
Extensions = new ObservableCollection<KeyValuePair<string, string>>(options.Extensions ?? new Dictionary<string, string>()); Extensions = new ObservableCollection<KeyValuePair<string, string>>(options.Extensions ?? new Dictionary<string, string>());
} }
public string Name public string? Name { get; set; }
{
get => _options.Name;
set
{
if (_options.Name != value)
{
_options.Name = value;
}
}
}
public int Priority [Reactive] public int Priority { get; set; }
{
get => _options.Priority;
set
{
if (_options.Priority != value)
{
_options.Priority = value;
}
}
}
public ObservableCollection<KeyValuePair<string, string>> Extensions { get; } public ObservableCollection<KeyValuePair<string, string>> Extensions { get; }
} }

View File

@ -6,16 +6,16 @@ namespace ZonyLrcTools.Desktop.ViewModels.Settings;
public class TagInfoViewModel : ViewModelBase public class TagInfoViewModel : ViewModelBase
{ {
private readonly TagInfoOptions _options; private readonly GlobalOptions _options;
public TagInfoViewModel(TagInfoOptions options) public TagInfoViewModel(GlobalOptions options)
{ {
_options = options; _options = options;
BlockWord = new BlockWordViewModel(options.BlockWord); BlockWord = new BlockWordViewModel(options);
Plugin = new ObservableCollection<TagInfoProviderViewModel>( TagInfoProviders = new ObservableCollection<TagInfoProviderViewModel>(options.Provider.Tag.Plugin.Select(p => new TagInfoProviderViewModel(p)));
options.Plugin.Select(p => new TagInfoProviderViewModel(p)));
} }
public BlockWordViewModel BlockWord { get; } public BlockWordViewModel BlockWord { get; }
public ObservableCollection<TagInfoProviderViewModel> Plugin { get; }
public ObservableCollection<TagInfoProviderViewModel> TagInfoProviders { get; }
} }