mirror of
https://github.com/real-zony/ZonyLrcToolsX.git
synced 2025-07-01 20:23:22 +00:00
feat: Mostly completed bidirectional binding for settings page and configuration.
This commit is contained in:
parent
e66ef89e7a
commit
9ab9cd50e2
@ -8,4 +8,9 @@ public class TagInfoOptions
|
|||||||
/// 屏蔽词功能相关配置。
|
/// 屏蔽词功能相关配置。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BlockWordOptions BlockWord { get; set; } = null!;
|
public BlockWordOptions BlockWord { get; set; } = null!;
|
||||||
|
|
||||||
|
public TagInfoProviderOptions GetTagProviderOption(string name)
|
||||||
|
{
|
||||||
|
return Plugin.FirstOrDefault(x => x.Name == name)!;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,8 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using YamlDotNet.Core;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
using YamlDotNet.Serialization.NamingConventions;
|
||||||
|
using ZonyLrcTools.Common.Configuration;
|
||||||
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
|
using ZonyLrcTools.Common.Infrastructure.DependencyInject;
|
||||||
using ZonyLrcTools.Common.Infrastructure.Network;
|
using ZonyLrcTools.Common.Infrastructure.Network;
|
||||||
using ZonyLrcTools.Desktop.ViewModels;
|
using ZonyLrcTools.Desktop.ViewModels;
|
||||||
@ -15,6 +21,13 @@ public class App : Application
|
|||||||
public new static App Current => (App)Application.Current!;
|
public new static App Current => (App)Application.Current!;
|
||||||
public IServiceProvider Services { get; } = ConfigureServices();
|
public IServiceProvider Services { get; } = ConfigureServices();
|
||||||
|
|
||||||
|
public IOptions<GlobalOptions> GlobalOptions => Services.GetRequiredService<IOptions<GlobalOptions>>();
|
||||||
|
|
||||||
|
private Lazy<ISerializer> _yamlSerializer = new(() => new SerializerBuilder()
|
||||||
|
.WithNamingConvention(CamelCaseNamingConvention.Instance)
|
||||||
|
.WithDefaultScalarStyle(ScalarStyle.DoubleQuoted)
|
||||||
|
.Build());
|
||||||
|
|
||||||
private static IServiceProvider ConfigureServices()
|
private static IServiceProvider ConfigureServices()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
@ -44,4 +57,11 @@ public class App : Application
|
|||||||
|
|
||||||
base.OnFrameworkInitializationCompleted();
|
base.OnFrameworkInitializationCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateConfiguration()
|
||||||
|
{
|
||||||
|
var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.yaml");
|
||||||
|
var yamlString = _yamlSerializer.Value.Serialize(GlobalOptions.Value);
|
||||||
|
File.WriteAllText(configPath, yamlString);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,3 @@
|
|||||||
using System;
|
|
||||||
using ReactiveUI;
|
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using ZonyLrcTools.Common.Configuration;
|
using ZonyLrcTools.Common.Configuration;
|
||||||
|
|
||||||
@ -12,12 +10,8 @@ public class BlockWordViewModel : ViewModelBase
|
|||||||
IsEnable = options.Provider.Tag.BlockWord.IsEnable;
|
IsEnable = options.Provider.Tag.BlockWord.IsEnable;
|
||||||
FilePath = options.Provider.Tag.BlockWord.FilePath;
|
FilePath = options.Provider.Tag.BlockWord.FilePath;
|
||||||
|
|
||||||
this.WhenAnyValue(x => x.IsEnable, x => x.FilePath)
|
SubscribeToProperty(this, x => x.IsEnable, x => options.Provider.Tag.BlockWord.IsEnable = x);
|
||||||
.Subscribe(_ =>
|
SubscribeToProperty(this, x => x.FilePath, x => options.Provider.Tag.BlockWord.FilePath = x!);
|
||||||
{
|
|
||||||
options.Provider.Tag.BlockWord.IsEnable = IsEnable;
|
|
||||||
options.Provider.Tag.BlockWord.FilePath = FilePath;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reactive] public bool IsEnable { get; set; }
|
[Reactive] public bool IsEnable { get; set; }
|
||||||
|
@ -21,14 +21,10 @@ public class GlobalConfigurationViewModel : ViewModelBase
|
|||||||
IsSkipExistLyricFiles = globalConfig.IsSkipExistLyricFiles;
|
IsSkipExistLyricFiles = globalConfig.IsSkipExistLyricFiles;
|
||||||
IsOnlyOutputTranslation = globalConfig.IsOnlyOutputTranslation;
|
IsOnlyOutputTranslation = globalConfig.IsOnlyOutputTranslation;
|
||||||
|
|
||||||
this.WhenAnyValue(x => x.IsOneLine)
|
SubscribeToProperty(this, x => x.IsOneLine, x => globalConfig.IsOneLine = x);
|
||||||
.Subscribe(x => globalConfig.IsOneLine = x);
|
SubscribeToProperty(this, x => x.IsEnableTranslation, x => globalConfig.IsEnableTranslation = x);
|
||||||
this.WhenAnyValue(x => x.IsEnableTranslation)
|
SubscribeToProperty(this, x => x.IsSkipExistLyricFiles, x => globalConfig.IsSkipExistLyricFiles = x);
|
||||||
.Subscribe(x => globalConfig.IsEnableTranslation = x);
|
SubscribeToProperty(this, x => x.IsOnlyOutputTranslation, x => globalConfig.IsOnlyOutputTranslation = x);
|
||||||
this.WhenAnyValue(x => x.IsSkipExistLyricFiles)
|
|
||||||
.Subscribe(x => globalConfig.IsSkipExistLyricFiles = x);
|
|
||||||
this.WhenAnyValue(x => x.IsOnlyOutputTranslation)
|
|
||||||
.Subscribe(x => globalConfig.IsOnlyOutputTranslation = x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reactive] public bool IsOneLine { get; set; }
|
[Reactive] public bool IsOneLine { get; set; }
|
||||||
|
@ -4,7 +4,6 @@ using Avalonia.Data;
|
|||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using ReactiveUI;
|
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using ZonyLrcTools.Common.Configuration;
|
using ZonyLrcTools.Common.Configuration;
|
||||||
|
|
||||||
@ -20,10 +19,8 @@ public class LyricsProviderViewModel : ViewModelBase
|
|||||||
Priority = options.Priority;
|
Priority = options.Priority;
|
||||||
Depth = options.Depth;
|
Depth = options.Depth;
|
||||||
|
|
||||||
this.WhenAnyValue(x => x.Priority)
|
SubscribeToProperty(this, x => x.Priority, x => globalOptions.Provider.Lyric.GetLyricProviderOption(Name).Priority = x);
|
||||||
.Subscribe(priority => globalOptions.Provider.Lyric.GetLyricProviderOption(Name).Priority = priority);
|
SubscribeToProperty(this, x => x.Depth, x => globalOptions.Provider.Lyric.GetLyricProviderOption(Name).Depth = x);
|
||||||
this.WhenAnyValue(x => x.Depth)
|
|
||||||
.Subscribe(depth => globalOptions.Provider.Lyric.GetLyricProviderOption(Name).Depth = depth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using ZonyLrcTools.Common.Configuration;
|
using ZonyLrcTools.Common.Configuration;
|
||||||
|
|
||||||
@ -9,14 +11,32 @@ public class TagInfoProviderViewModel : ViewModelBase
|
|||||||
{
|
{
|
||||||
public TagInfoProviderViewModel(TagInfoProviderOptions options)
|
public TagInfoProviderViewModel(TagInfoProviderOptions options)
|
||||||
{
|
{
|
||||||
|
var globalOptions = App.Current.Services.GetRequiredService<IOptions<GlobalOptions>>().Value;
|
||||||
|
|
||||||
Name = options.Name;
|
Name = options.Name;
|
||||||
Priority = options.Priority;
|
Priority = options.Priority;
|
||||||
Extensions = new ObservableCollection<KeyValuePair<string, string>>(options.Extensions ?? new Dictionary<string, string>());
|
Extensions = options.Extensions == null ? [] : new ObservableCollection<ObservableKeyValuePair>(options.Extensions.Select(x => new ObservableKeyValuePair(x.Key, x.Value)));
|
||||||
|
|
||||||
|
SubscribeToProperty(this, x => x.Priority, x => globalOptions.Provider.Tag.GetTagProviderOption(Name).Priority = x);
|
||||||
|
SubscribeToProperty(this, x => x.Extensions, x => globalOptions.Provider.Tag.GetTagProviderOption(Name).Extensions = x.ToDictionary(pair => pair.Key, pair => pair.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
|
||||||
[Reactive] public int Priority { get; set; }
|
[Reactive] public int Priority { get; set; }
|
||||||
|
|
||||||
public ObservableCollection<KeyValuePair<string, string>> Extensions { get; }
|
[Reactive] public ObservableCollection<ObservableKeyValuePair> Extensions { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ObservableKeyValuePair : ViewModelBase
|
||||||
|
{
|
||||||
|
[Reactive] public string Key { get; set; }
|
||||||
|
|
||||||
|
[Reactive] public string Value { get; set; }
|
||||||
|
|
||||||
|
public ObservableKeyValuePair(string key, string value)
|
||||||
|
{
|
||||||
|
Key = key;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,11 +6,8 @@ namespace ZonyLrcTools.Desktop.ViewModels.Settings;
|
|||||||
|
|
||||||
public class TagInfoViewModel : ViewModelBase
|
public class TagInfoViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
private readonly GlobalOptions _options;
|
|
||||||
|
|
||||||
public TagInfoViewModel(GlobalOptions options)
|
public TagInfoViewModel(GlobalOptions options)
|
||||||
{
|
{
|
||||||
_options = options;
|
|
||||||
BlockWord = new BlockWordViewModel(options);
|
BlockWord = new BlockWordViewModel(options);
|
||||||
TagInfoProviders = new ObservableCollection<TagInfoProviderViewModel>(options.Provider.Tag.Plugin.Select(p => new TagInfoProviderViewModel(p)));
|
TagInfoProviders = new ObservableCollection<TagInfoProviderViewModel>(options.Provider.Tag.Plugin.Select(p => new TagInfoProviderViewModel(p)));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
using ReactiveUI;
|
using System;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
namespace ZonyLrcTools.Desktop.ViewModels;
|
namespace ZonyLrcTools.Desktop.ViewModels;
|
||||||
|
|
||||||
public abstract class ViewModelBase : ReactiveObject;
|
public abstract class ViewModelBase : ReactiveObject
|
||||||
|
{
|
||||||
|
protected void SubscribeToProperty<TSender, TRet>(TSender sender, Expression<Func<TSender, TRet>> property, Action<TRet> updateGlobalConfigAction)
|
||||||
|
{
|
||||||
|
sender.WhenAnyValue(property)
|
||||||
|
.Subscribe(x =>
|
||||||
|
{
|
||||||
|
updateGlobalConfigAction(x);
|
||||||
|
App.Current.UpdateConfiguration();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="config.yaml"/>
|
<None Remove="config.yaml"/>
|
||||||
<Content Include="config.yaml">
|
<Content Include="config.yaml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -5,12 +5,14 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
|
using Xunit;
|
||||||
using ZonyLrcTools.Common.Album;
|
using ZonyLrcTools.Common.Album;
|
||||||
|
|
||||||
namespace ZonyLrcTools.Tests.Infrastructure.Album
|
namespace ZonyLrcTools.Tests.Infrastructure.Album
|
||||||
{
|
{
|
||||||
public class QQMusicAlbumDownloaderTests : TestBase
|
public class QQMusicAlbumDownloaderTests : TestBase
|
||||||
{
|
{
|
||||||
|
[Fact]
|
||||||
public async Task DownloadDataAsync_Test()
|
public async Task DownloadDataAsync_Test()
|
||||||
{
|
{
|
||||||
var downloader = ServiceProvider.GetRequiredService<IEnumerable<IAlbumProvider>>()
|
var downloader = ServiceProvider.GetRequiredService<IEnumerable<IAlbumProvider>>()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user