mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-13 03:34:55 +08:00
Compare commits
65 Commits
efc175668e
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f735170961 | ||
|
|
a215abc41b | ||
|
|
2ddd7d19ab | ||
|
|
4d270df594 | ||
|
|
7fdb7ed870 | ||
|
|
aad648d078 | ||
|
|
d93fad6f3b | ||
|
|
a6bdf92341 | ||
|
|
96229d4346 | ||
|
|
bea29bdf9f | ||
|
|
4ad4959c39 | ||
|
|
7457cb1139 | ||
|
|
b6a6cd8659 | ||
|
|
6173dae1fa | ||
|
|
b6aac2b968 | ||
|
|
290f84cea0 | ||
|
|
3031d298d5 | ||
|
|
ed74e96aeb | ||
|
|
affa55b057 | ||
|
|
305f5e2cac | ||
|
|
b8d4fc4130 | ||
|
|
da5fd90d44 | ||
|
|
f4a6aa78b6 | ||
|
|
52b81cd959 | ||
|
|
d79933d41e | ||
|
|
a82f1bdb53 | ||
|
|
2cac55b55e | ||
|
|
4efe897ab2 | ||
|
|
173f808a88 | ||
|
|
e73c27c705 | ||
|
|
3724ef5f7e | ||
|
|
7ca0ecde16 | ||
|
|
2e0700dba5 | ||
|
|
9ec12e3a08 | ||
|
|
d042993eb7 | ||
|
|
fea7367671 | ||
|
|
2b3169e5f6 | ||
|
|
9d2e245a99 | ||
|
|
0513c3a128 | ||
|
|
5082c4c245 | ||
|
|
659b4d0e60 | ||
|
|
85f67c2ec6 | ||
|
|
bdbeb391ea | ||
|
|
3357e7aaf4 | ||
|
|
e43461d624 | ||
|
|
3e1907ad8c | ||
|
|
74eeffc8a6 | ||
|
|
c32eb3b877 | ||
|
|
047e53b830 | ||
|
|
fdb7bd16f6 | ||
|
|
4e33444d8e | ||
|
|
8fc67711b6 | ||
|
|
28757d9880 | ||
|
|
e5fb04f577 | ||
|
|
9d03c8f688 | ||
|
|
094fe7b7a1 | ||
|
|
bc32a3f34c | ||
|
|
b23d3c280f | ||
|
|
2738d45b69 | ||
|
|
77a9bb0a1b | ||
|
|
c07389acfb | ||
|
|
042229ae74 | ||
|
|
caaf93cf27 | ||
|
|
92e4b9468c | ||
|
|
6f60952d09 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -408,3 +408,6 @@ FodyWeavers.xsd
|
||||
/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package)_TemporaryKey.pfx
|
||||
/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/LastFM.cs
|
||||
/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Discord.cs
|
||||
/BetterLyrics.Plugins.Romaji/unidic
|
||||
/Plugins/BetterLyrics.Plugins.Romaji/unidic
|
||||
/Plugins/BetterLyrics.Plugins.Transliteration.Romaji/unidic
|
||||
|
||||
12
BetterLyrics.Core/BetterLyrics.Core.csproj
Normal file
12
BetterLyrics.Core/BetterLyrics.Core.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
||||
<Private>false</Private>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
12
BetterLyrics.Core/Interfaces/Features/ILyricsSource.cs
Normal file
12
BetterLyrics.Core/Interfaces/Features/ILyricsSource.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using BetterLyrics.Core.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.Core.Interfaces.Features
|
||||
{
|
||||
public interface ILyricsSource
|
||||
{
|
||||
Task<LyricsSearchResult> GetLyricsAsync(string title, string artist, string album, double duration);
|
||||
}
|
||||
}
|
||||
11
BetterLyrics.Core/Interfaces/Features/ILyricsTranslator.cs
Normal file
11
BetterLyrics.Core/Interfaces/Features/ILyricsTranslator.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.Core.Interfaces.Features
|
||||
{
|
||||
public interface ILyricsTranslator
|
||||
{
|
||||
Task<string?> GetTranslationAsync(string text, string targetLangCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.Core.Interfaces.Features
|
||||
{
|
||||
public interface ILyricsTransliterator
|
||||
{
|
||||
Task<string?> GetTransliterationAsync(string text, string targetLangCode);
|
||||
}
|
||||
}
|
||||
20
BetterLyrics.Core/Interfaces/IPlugin.cs
Normal file
20
BetterLyrics.Core/Interfaces/IPlugin.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using BetterLyrics.Core.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.Core.Interfaces
|
||||
{
|
||||
public interface IPlugin
|
||||
{
|
||||
string Id { get; }
|
||||
string Name { get; }
|
||||
string Description { get; }
|
||||
string Author { get; }
|
||||
string Version { get; }
|
||||
DateTime LastUpdated { get; }
|
||||
|
||||
void OnLoad(IPluginContext context);
|
||||
void OnUnload();
|
||||
}
|
||||
}
|
||||
14
BetterLyrics.Core/Interfaces/IPluginContext.cs
Normal file
14
BetterLyrics.Core/Interfaces/IPluginContext.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using BetterLyrics.Core.Interfaces.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.Core.Interfaces
|
||||
{
|
||||
public interface IPluginContext
|
||||
{
|
||||
string PluginDirectory { get; }
|
||||
|
||||
IAIService? AIService { get; }
|
||||
}
|
||||
}
|
||||
11
BetterLyrics.Core/Interfaces/Services/IAIService.cs
Normal file
11
BetterLyrics.Core/Interfaces/Services/IAIService.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.Core.Interfaces.Services
|
||||
{
|
||||
public interface IAIService
|
||||
{
|
||||
Task<string> ChatAsync(string systemPrompt, string userPrompt);
|
||||
}
|
||||
}
|
||||
16
BetterLyrics.Core/Models/LyricsSearchResult.cs
Normal file
16
BetterLyrics.Core/Models/LyricsSearchResult.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.Core.Models
|
||||
{
|
||||
public record LyricsSearchResult(
|
||||
string? Title,
|
||||
string? Artist,
|
||||
string? Album,
|
||||
double? Duration,
|
||||
string Raw,
|
||||
string? Translation = null,
|
||||
string? Transliteration = null,
|
||||
string? Reference = null);
|
||||
}
|
||||
@@ -143,7 +143,7 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7175" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7463" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251106002" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<Identity
|
||||
Name="37412.BetterLyrics"
|
||||
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
|
||||
Version="1.2.246.0" />
|
||||
Version="1.2.260.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using BetterLyrics.WinUI3.Services.LocalizationService;
|
||||
using BetterLyrics.WinUI3.Services.LyricsCacheService;
|
||||
using BetterLyrics.WinUI3.Services.LyricsSearchService;
|
||||
using BetterLyrics.WinUI3.Services.PlayHistoryService;
|
||||
using BetterLyrics.WinUI3.Services.PluginService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Services.SMTCService;
|
||||
using BetterLyrics.WinUI3.Services.SongSearchMapService;
|
||||
@@ -22,7 +23,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Windows.AppLifecycle; // 关键:App生命周期管理
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@@ -154,6 +155,10 @@ namespace BetterLyrics.WinUI3
|
||||
}
|
||||
fileSystemService.StartAllFolderTimers();
|
||||
|
||||
// Ensure plugins
|
||||
var pluginService = Ioc.Default.GetRequiredService<IPluginService>();
|
||||
pluginService.LoadPlugins();
|
||||
|
||||
// Init system tray
|
||||
m_window = WindowHook.OpenOrShowWindow<SystemTrayWindow>();
|
||||
|
||||
@@ -248,6 +253,7 @@ namespace BetterLyrics.WinUI3
|
||||
.AddSingleton<IPlayHistoryService, PlayHistoryService>()
|
||||
.AddSingleton<ILyricsCacheService, LyricsCacheService>()
|
||||
.AddSingleton<ISongSearchMapService, SongSearchMapService>()
|
||||
.AddSingleton<IPluginService, PluginService>()
|
||||
|
||||
// ViewModels
|
||||
.AddSingleton<AppSettingsControlViewModel>()
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<None Remove="Controls\PatronControl.xaml" />
|
||||
<None Remove="Controls\PlaybackSettingsControl.xaml" />
|
||||
<None Remove="Controls\PlayQueue.xaml" />
|
||||
<None Remove="Controls\PluginManagerControl.xaml" />
|
||||
<None Remove="Controls\PropertyRow.xaml" />
|
||||
<None Remove="Controls\RemoteServerConfigControl.xaml" />
|
||||
<None Remove="Controls\ShortcutTextBox.xaml" />
|
||||
@@ -82,7 +83,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.2.251219" />
|
||||
<PackageReference Include="ComputeSharp.D2D1.WinUI" Version="3.2.0" />
|
||||
<PackageReference Include="csharp-pinyin" Version="1.0.1" />
|
||||
<PackageReference Include="DevWinUI.Controls" Version="9.8.1" />
|
||||
<PackageReference Include="DevWinUI.Controls" Version="9.9.2" />
|
||||
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.6" />
|
||||
<PackageReference Include="F23.StringSimilarity" Version="7.0.1" />
|
||||
<PackageReference Include="FlaUI.UIA3" Version="5.0.0" />
|
||||
@@ -96,10 +97,14 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7175" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7463" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251106002" />
|
||||
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
|
||||
<PackageReference Include="NTextCat" Version="0.3.65" />
|
||||
@@ -118,11 +123,12 @@
|
||||
<PackageReference Include="VCollab.DiscordRichPresence" Version="1.7.0" />
|
||||
<PackageReference Include="WebDav.Client" Version="2.9.0" />
|
||||
<PackageReference Include="WinUIEx" Version="2.9.0" />
|
||||
<PackageReference Include="z440.atl.core" Version="7.9.0" />
|
||||
<PackageReference Include="z440.atl.core" Version="7.10.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" />
|
||||
<ProjectReference Include="..\..\Impressionist\Impressionist\Impressionist.csproj" />
|
||||
<ProjectReference Include="..\..\BetterLyrics.Core\BetterLyrics.Core.csproj" />
|
||||
<ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" />
|
||||
<ProjectReference Include="..\..\Impressionist\Impressionist\Impressionist.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Rendering\InAppLyricsRenderer.xaml">
|
||||
@@ -134,252 +140,245 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<!--Disable Trimming for Specific Packages-->
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="FlaUI.UIA3" />
|
||||
<TrimmerRootAssembly Include="Interop.UIAutomationClient" />
|
||||
<TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore" />
|
||||
<TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore.Abstractions" />
|
||||
<TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore.Relational" />
|
||||
<TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
||||
<TrimmerRootAssembly Include="NAudio.Wasapi" />
|
||||
<TrimmerRootAssembly Include="TagLibSharp" />
|
||||
<TrimmerRootAssembly Include="Vanara.PInvoke.DwmApi" />
|
||||
<TrimmerRootAssembly Include="Vanara.PInvoke.Gdi32" />
|
||||
<TrimmerRootAssembly Include="Vanara.PInvoke.Shell32" />
|
||||
<TrimmerRootAssembly Include="Vanara.PInvoke.User32" />
|
||||
<TrimmerRootAssembly Include="Vanara.Windows.Shell" />
|
||||
<TrimmerRootDescriptor Include="PluginConfigs\**\*_TrimmerRoots.xml" />
|
||||
<TrimmerRootDescriptor Include="Core_TrimmerRoots.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="Assets\AIMP.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AlbumArtPlaceholder.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Alipay.jpg">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AMLLPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AppleMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Chrome.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Edge.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\FluidEffect.bin">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Empty.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\EmptyBox.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\EmptyState.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Folder.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\foobar2000.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\HyPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\iTunes.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\KugouMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\LastFM.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Leaf.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Listen1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Logo.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Logo.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\LXMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MediaPlayerWindows11.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MoeKoeMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MusicBee.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\NetEaseCloudMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\OriginalSoundHQPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Page.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\PlanetMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\PotPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\QQMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Question.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\RevolvingHearts.gif">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\SaltPlayerForWindows.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Segoe Fluent Icons.ttf">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Spotify.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\WeChatReward.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Wiki82.profile.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AIMP.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AlbumArtPlaceholder.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Alipay.jpg">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AMLLPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AppleMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Chrome.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Edge.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\FluidEffect.bin">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Empty.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\EmptyBox.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\EmptyState.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Folder.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\foobar2000.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\HyPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\iTunes.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\KugouMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\LastFM.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Leaf.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Listen1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Logo.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Logo.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\LXMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MediaPlayerWindows11.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MoeKoeMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MusicBee.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\NetEaseCloudMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\OriginalSoundHQPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Page.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\PlanetMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\PotPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\QQMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Question.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\RevolvingHearts.gif">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\SaltPlayerForWindows.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Segoe Fluent Icons.ttf">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Spotify.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\WeChatReward.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Wiki82.profile.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\PatronControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\PluginManagerControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Styles\GhostSliderStyle.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\PatronControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Styles\Converters.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Styles\GhostSliderStyle.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\PlayQueue.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Styles\Converters.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\StatsDashboardControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\PlayQueue.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\FontFamilyAutoSuggestBox.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\StatsDashboardControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsStyleSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\FontFamilyAutoSuggestBox.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\LyricsWindowSwitchWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\LyricsStyleSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsWindowSwitchControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\LyricsWindowSwitchWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\DemoWindowGrid.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\LyricsWindowSwitchControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsWindowSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\DemoWindowGrid.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\LyricsSearchWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\LyricsWindowSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsSearchControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\LyricsSearchWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\ShortcutTextBox.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\LyricsSearchControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\ExtendedSlider.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\ShortcutTextBox.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsEffectSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\ExtendedSlider.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\MediaSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\LyricsEffectSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\PlaybackSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\MediaSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\AlbumArtAreaStyleSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\PlaybackSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsBackgroundSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\AlbumArtAreaStyleSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\AppSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\LyricsBackgroundSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\MusicGalleryWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\AppSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\MusicGalleryPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\MusicGalleryWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\MusicGalleryPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\SettingsWindow.xaml">
|
||||
@@ -392,54 +391,57 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\RemoteServerConfigControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\RemoteServerConfigControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\NowPlayingBar.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\NowPlayingBar.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\SystemTrayWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Views\SystemTrayWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\WindowSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\WindowSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\AlbumArtAreaEffectSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\AlbumArtAreaEffectSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\ImageSwitcher.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\ImageSwitcher.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\ShadowImage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\ShadowImage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\PropertyRow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\PropertyRow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\AboutControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Controls\AboutControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Styles\InteractiveListViewHeaderStyle.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Update="Styles\InteractiveListViewHeaderStyle.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="PluginConfigs\" />
|
||||
</ItemGroup>
|
||||
<!-- Publish Properties -->
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
{
|
||||
public static readonly TimeSpan DebounceTimeout = TimeSpan.FromMilliseconds(250);
|
||||
public static readonly TimeSpan AnimationDuration = TimeSpan.FromMilliseconds(350);
|
||||
public static readonly TimeSpan LongAnimationDuration = TimeSpan.FromMilliseconds(650);
|
||||
public static readonly TimeSpan WaitingDuration = TimeSpan.FromMilliseconds(300);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock x:Uid="SettingsPagePatrons" />
|
||||
<dev:WrapPanel Margin="-12,0,0,0" Orientation="Horizontal">
|
||||
<uc:PatronControl Date="Jan 8, 2026" PatronName="Eureka-K_K" />
|
||||
<uc:PatronControl Date="Jan 3, 2026" PatronName="**轩" />
|
||||
<uc:PatronControl Date="Dec 13, 2025" PatronName="<Anonymous>" />
|
||||
<uc:PatronControl Date="Dec 3, 2025" PatronName="YE" />
|
||||
@@ -282,12 +283,6 @@
|
||||
</dev:SettingsExpander.ItemsHeader>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageSettingsPlayHistory" Visibility="Collapsed">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<Button x:Uid="SettingsPageExportPlayHistoryButton" Command="{x:Bind ViewModel.ExportPlayHistoryCommand}" />
|
||||
</StackPanel>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageFixedTimeStep" Visibility="Collapsed">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.AdvancedSettings.IsFixedTimeStep, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
@@ -58,42 +58,43 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
|
||||
private readonly ValueTransition<Color> _immersiveBgColorTransition = new(
|
||||
initialValue: Colors.Transparent,
|
||||
durationSeconds: 0.3f,
|
||||
defaultTotalDuration: 0.3f,
|
||||
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
|
||||
);
|
||||
private readonly ValueTransition<double> _immersiveBgOpacityTransition = new(
|
||||
initialValue: 1f,
|
||||
durationSeconds: 0.3f
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: 0.3f
|
||||
);
|
||||
private readonly ValueTransition<Color> _accentColor1Transition = new(
|
||||
initialValue: Colors.Transparent,
|
||||
durationSeconds: 0.3f,
|
||||
defaultTotalDuration: 0.3f,
|
||||
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
|
||||
);
|
||||
private readonly ValueTransition<Color> _accentColor2Transition = new(
|
||||
initialValue: Colors.Transparent,
|
||||
durationSeconds: 0.3f,
|
||||
defaultTotalDuration: 0.3f,
|
||||
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
|
||||
);
|
||||
private readonly ValueTransition<Color> _accentColor3Transition = new(
|
||||
initialValue: Colors.Transparent,
|
||||
durationSeconds: 0.3f,
|
||||
defaultTotalDuration: 0.3f,
|
||||
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
|
||||
);
|
||||
private readonly ValueTransition<Color> _accentColor4Transition = new(
|
||||
initialValue: Colors.Transparent,
|
||||
durationSeconds: 0.3f,
|
||||
defaultTotalDuration: 0.3f,
|
||||
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
|
||||
);
|
||||
private readonly ValueTransition<double> _canvasYScrollTransition = new(
|
||||
initialValue: 0f,
|
||||
durationSeconds: 0.3f,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: 0.3f
|
||||
);
|
||||
private readonly ValueTransition<double> _mouseYScrollTransition = new(
|
||||
initialValue: 0f,
|
||||
durationSeconds: 0.3f,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: 0.3f
|
||||
);
|
||||
|
||||
private TimeSpan _songPositionWithOffset;
|
||||
@@ -119,7 +120,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
private bool _isLayoutChanged = true;
|
||||
private bool _isMouseScrollingChanged = false;
|
||||
|
||||
private int _playingLineIndex;
|
||||
private int _primaryPlayingLineIndex;
|
||||
private (int Start, int End) _visibleRange;
|
||||
private double _canvasTargetScrollOffset;
|
||||
|
||||
@@ -292,7 +293,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
else if (e.Property == MouseScrollOffsetProperty)
|
||||
{
|
||||
canvas._mouseYScrollTransition.StartTransition(Convert.ToDouble(e.NewValue));
|
||||
canvas._mouseYScrollTransition.Start(Convert.ToDouble(e.NewValue));
|
||||
}
|
||||
else if (e.Property == MousePositionProperty)
|
||||
{
|
||||
@@ -318,11 +319,11 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
else if (e.Property == AlbumArtThemeColorsProperty)
|
||||
{
|
||||
var albumArtThemeColors = (AlbumArtThemeColors)e.NewValue;
|
||||
canvas._immersiveBgColorTransition.StartTransition(albumArtThemeColors.EnvColor);
|
||||
canvas._accentColor1Transition.StartTransition(albumArtThemeColors.AccentColor1);
|
||||
canvas._accentColor2Transition.StartTransition(albumArtThemeColors.AccentColor2);
|
||||
canvas._accentColor3Transition.StartTransition(albumArtThemeColors.AccentColor3);
|
||||
canvas._accentColor4Transition.StartTransition(albumArtThemeColors.AccentColor4);
|
||||
canvas._immersiveBgColorTransition.Start(albumArtThemeColors.EnvColor);
|
||||
canvas._accentColor1Transition.Start(albumArtThemeColors.AccentColor1);
|
||||
canvas._accentColor2Transition.Start(albumArtThemeColors.AccentColor2);
|
||||
canvas._accentColor3Transition.Start(albumArtThemeColors.AccentColor3);
|
||||
canvas._accentColor4Transition.Start(albumArtThemeColors.AccentColor4);
|
||||
|
||||
canvas._albumArtThemeColors = albumArtThemeColors;
|
||||
canvas._isLayoutChanged = true;
|
||||
@@ -344,7 +345,6 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
var lyricsEffect = _lyricsWindowStatus.LyricsEffectSettings;
|
||||
|
||||
double songDuration = _gsmtcService.CurrentSongInfo.DurationMs;
|
||||
bool isForceWordByWord = _settingsService.AppSettings.GeneralSettings.IsForceWordByWordEffect;
|
||||
|
||||
Color overlayColor;
|
||||
double finalOpacity;
|
||||
@@ -382,7 +382,6 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
control: sender,
|
||||
ds: args.DrawingSession,
|
||||
lines: _renderLyricsLines,
|
||||
playingLineIndex: _playingLineIndex,
|
||||
mouseHoverLineIndex: _mouseHoverLineIndex,
|
||||
isMousePressing: _isMousePressing,
|
||||
startVisibleIndex: _visibleRange.Start,
|
||||
@@ -411,9 +410,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
return _synchronizer.GetLinePlayingProgress(
|
||||
_songPositionWithOffset.TotalMilliseconds,
|
||||
line,
|
||||
nextLine,
|
||||
songDuration,
|
||||
isForceWordByWord
|
||||
lyricsEffect.WordByWordEffectMode
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -476,22 +473,29 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
|
||||
#region UpdatePlayingLineIndex
|
||||
|
||||
int newPlayingIndex = _synchronizer.GetCurrentLineIndex(_songPositionWithOffset.TotalMilliseconds, _renderLyricsLines);
|
||||
bool isPlayingLineChanged = newPlayingIndex != _playingLineIndex;
|
||||
_playingLineIndex = newPlayingIndex;
|
||||
int primaryPlayingIndex = _synchronizer.GetCurrentLineIndex(_songPositionWithOffset.TotalMilliseconds, _renderLyricsLines);
|
||||
bool isPrimaryPlayingLineChanged = primaryPlayingIndex != _primaryPlayingLineIndex;
|
||||
_primaryPlayingLineIndex = primaryPlayingIndex;
|
||||
|
||||
#endregion
|
||||
|
||||
#region UpdateTargetScrollOffset
|
||||
|
||||
if (isPlayingLineChanged || _isLayoutChanged)
|
||||
if (isPrimaryPlayingLineChanged || _isLayoutChanged)
|
||||
{
|
||||
var targetScroll = LyricsLayoutManager.CalculateTargetScrollOffset(_renderLyricsLines, _playingLineIndex);
|
||||
var targetScroll = LyricsLayoutManager.CalculateTargetScrollOffset(_renderLyricsLines, _primaryPlayingLineIndex);
|
||||
if (targetScroll.HasValue) _canvasTargetScrollOffset = targetScroll.Value;
|
||||
|
||||
_canvasYScrollTransition.SetEasingType(lyricsEffect.LyricsScrollEasingType);
|
||||
_canvasYScrollTransition.SetDuration(lyricsEffect.LyricsScrollDuration / 1000.0);
|
||||
_canvasYScrollTransition.StartTransition(_canvasTargetScrollOffset, _isLayoutChanged);
|
||||
if (_isLayoutChanged)
|
||||
{
|
||||
_canvasYScrollTransition.JumpTo(_canvasTargetScrollOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
_canvasYScrollTransition.SetDurationMs(lyricsEffect.LyricsScrollDuration);
|
||||
_canvasYScrollTransition.SetInterpolator(EasingHelper.GetInterpolatorByEasingType<double>(lyricsEffect.LyricsScrollEasingType, lyricsEffect.LyricsScrollEasingMode));
|
||||
_canvasYScrollTransition.Start(_canvasTargetScrollOffset);
|
||||
}
|
||||
}
|
||||
_canvasYScrollTransition.Update(elapsedTime);
|
||||
|
||||
@@ -524,7 +528,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
_renderLyricsLines,
|
||||
_isMouseScrolling ? maxRange.Start : _visibleRange.Start,
|
||||
_isMouseScrolling ? maxRange.End : _visibleRange.End,
|
||||
_playingLineIndex,
|
||||
_primaryPlayingLineIndex,
|
||||
sender.Size.Height,
|
||||
_canvasTargetScrollOffset,
|
||||
lyricsStyle.PlayingLineTopOffset / 100.0,
|
||||
@@ -536,7 +540,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
elapsedTime,
|
||||
_isMouseScrolling,
|
||||
_isLayoutChanged,
|
||||
isPlayingLineChanged,
|
||||
isPrimaryPlayingLineChanged,
|
||||
_isMouseScrollingChanged,
|
||||
_songPositionWithOffset.TotalMilliseconds
|
||||
);
|
||||
@@ -669,15 +673,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
private void UpdateRenderLyricsLines()
|
||||
{
|
||||
_renderLyricsLines = null;
|
||||
var lines = _gsmtcService.CurrentLyricsData?.LyricsLines.Select(x => new RenderLyricsLine()
|
||||
{
|
||||
LyricsSyllables = x.LyricsSyllables,
|
||||
StartMs = x.StartMs,
|
||||
EndMs = x.EndMs,
|
||||
PhoneticText = x.PhoneticText,
|
||||
OriginalText = x.OriginalText,
|
||||
TranslatedText = x.TranslatedText
|
||||
}).ToList();
|
||||
var lines = _gsmtcService.CurrentLyricsData?.LyricsLines.Select(x => new RenderLyricsLine(x)).ToList();
|
||||
if (lines != null)
|
||||
{
|
||||
LyricsLayoutManager.CalculateLanes(lines);
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="Effect" />
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsWordByWordEffectMode" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.WordByWordEffectMode, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsWordByWordEffectModeAuto" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsWordByWordEffectModeNever" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsWordByWordEffectModeAlways" />
|
||||
</ComboBox>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- 模糊效果 -->
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsBlurEffect" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsBlurEffectEnabled, Mode=TwoWay}" />
|
||||
@@ -108,6 +116,14 @@
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsFloatAnimationAmount, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="LyricsEffectSettingsControlAnimationDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="450"
|
||||
Maximum="2000"
|
||||
Minimum="0"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsFloatAnimationDuration, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
@@ -180,18 +196,25 @@
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutSine" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuad" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCubic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuart" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuint" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutExpo" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCirc" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBack" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseSine" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseQuad" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseCubic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseQuart" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseQuint" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseExpo" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseCirc" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseBack" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseElastic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseBounce" />
|
||||
</ComboBox>
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageEasingMode">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingMode, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingModeIn" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingModeOut" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingModeInOut" />
|
||||
</ComboBox>
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScrollTopDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="500"
|
||||
|
||||
@@ -291,7 +291,7 @@
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</Button>
|
||||
</Grid>
|
||||
<local:PropertyRow Grid.Column="1" Value="{x:Bind OriginalText, Mode=OneWay}" />
|
||||
<local:PropertyRow Grid.Column="1" Value="{x:Bind PrimaryText, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
|
||||
@@ -447,7 +447,7 @@
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind ViewModel.TimelineSliderThumbLyricsLine.StartMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}, Mode=OneWay}" />
|
||||
<!-- TODO 原文翻译共同显示 -->
|
||||
<TextBlock Margin="0,0,0,2" Text="{x:Bind ViewModel.TimelineSliderThumbLyricsLine.OriginalText, Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,2" Text="{x:Bind ViewModel.TimelineSliderThumbLyricsLine.PrimaryText, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid
|
||||
|
||||
@@ -228,6 +228,9 @@
|
||||
</dev:SettingsExpander.HeaderIcon>
|
||||
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="LyricsSearchControlIgnoreCache">
|
||||
<CheckBox IsChecked="{Binding IgnoreCacheWhenSearching, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageOverwriteMatchingThreshold">
|
||||
<ToggleSwitch IsOn="{Binding IsMatchingThresholdOverwritten, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
@@ -362,10 +365,6 @@
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ListenOnNewPlaybackSource, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageForceWordByWordEffect">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IsForceWordByWordEffect, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- Lyrics translation -->
|
||||
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<dev:SettingsExpander x:Uid="LyricsPageTranslationEnabled" IsExpanded="True">
|
||||
@@ -425,30 +424,6 @@
|
||||
</dev:SettingsExpander>
|
||||
<dev:SettingsExpander x:Uid="SettingsPageJapanese" IsExpanded="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" />
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageCutletDockerServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard.Description>
|
||||
<HyperlinkButton Content="https://github.com/jayfunc/cutlet-docker" NavigateUri="https://github.com/jayfunc/cutlet-docker" />
|
||||
</dev:SettingsCard.Description>
|
||||
<Grid ColumnSpacing="6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox
|
||||
x:Uid="CutletServerTextBox"
|
||||
Grid.Column="0"
|
||||
IsEnabled="{x:Bind ViewModel.IsCutletDockerServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.AppSettings.TranslationSettings.CutletDockerServer, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
x:Uid="SettingsPageServerTestButton"
|
||||
Grid.Column="1"
|
||||
Command="{x:Bind ViewModel.CutletDockerServerTestCommand}"
|
||||
IsEnabled="{x:Bind ViewModel.IsCutletDockerServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 中文简体繁体偏好 -->
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.PluginManagerControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:models="using:BetterLyrics.WinUI3.Models"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid Padding="36,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
<TextBlock x:Uid="PluginManagerControlTitle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
</Grid>
|
||||
|
||||
<ListView
|
||||
Grid.Row="1"
|
||||
ItemContainerStyle="{StaticResource ListViewStretchedItemContainerStyle}"
|
||||
ItemsSource="{x:Bind Plugins, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:PluginDisplayModel">
|
||||
<dev:SettingsExpander
|
||||
Description="{x:Bind Description}"
|
||||
Header="{x:Bind Name}"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}">
|
||||
<TextBlock Text="{x:Bind Version}" />
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
|
||||
<StackPanel Spacing="6">
|
||||
<local:PropertyRow Header="Author" Value="{x:Bind Author}" />
|
||||
<local:PropertyRow Header="ID" Value="{x:Bind Id}" />
|
||||
</StackPanel>
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard>
|
||||
<Button
|
||||
x:Uid="PluginManagerControlUninstall"
|
||||
Click="OnUninstallClick"
|
||||
Tag="{x:Bind Plugin}" />
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{x:Bind IsListEmpty, Mode=OneWay}">
|
||||
<FontIcon
|
||||
FontSize="48"
|
||||
Glyph=""
|
||||
Opacity="0.3" />
|
||||
<TextBlock
|
||||
x:Uid="PluginManagerControlNoPluginsInstalled"
|
||||
Margin="0,12,0,0"
|
||||
Opacity="0.5" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="2" Margin="0,6,0,20">
|
||||
<Button
|
||||
x:Uid="PluginManagerControlInstall"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Click="OnInstallPluginClick"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
@@ -0,0 +1,149 @@
|
||||
using BetterLyrics.Core.Interfaces;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.PluginService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class PluginManagerControl : UserControl
|
||||
{
|
||||
public ObservableCollection<PluginDisplayModel> Plugins { get; } = new();
|
||||
|
||||
public Visibility IsListEmpty => Plugins.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
private readonly IPluginService _pluginService;
|
||||
|
||||
public PluginManagerControl()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_pluginService = Ioc.Default.GetRequiredService<IPluginService>();
|
||||
|
||||
this.Loaded += (s, e) =>
|
||||
{
|
||||
RefreshPluginList();
|
||||
};
|
||||
}
|
||||
|
||||
private void RefreshPluginList()
|
||||
{
|
||||
Plugins.Clear();
|
||||
|
||||
var allPlugins = _pluginService.Plugins;
|
||||
|
||||
foreach (var plugin in allPlugins)
|
||||
{
|
||||
Plugins.Add(new PluginDisplayModel(plugin));
|
||||
}
|
||||
|
||||
Bindings.Update();
|
||||
}
|
||||
|
||||
private async void OnInstallPluginClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var file = await Helper.PickerHelper.PickSingleFileAsync<SettingsWindow>([".zip"]);
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 显示加载条...
|
||||
|
||||
// 3. 调用我们在上一步写的 InstallPlugin 方法
|
||||
_pluginService.InstallPlugin(file.Path);
|
||||
|
||||
// 4. 重新加载所有插件 (这会触发热重载)
|
||||
_pluginService.LoadPlugins();
|
||||
|
||||
// 5. 刷新界面
|
||||
RefreshPluginList();
|
||||
|
||||
ShowTip("安装成功", $"插件 {file.Name} 已安装。");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowError("安装失败", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 卸载按钮点击事件
|
||||
private async void OnUninstallClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button btn && btn.Tag is IPlugin plugin)
|
||||
{
|
||||
// 二次确认对话框
|
||||
ContentDialog deleteDialog = new ContentDialog
|
||||
{
|
||||
XamlRoot = this.XamlRoot,
|
||||
Title = "卸载插件",
|
||||
Content = $"确定要删除 \"{plugin.Name}\" 吗?此操作无法撤销。",
|
||||
PrimaryButtonText = "删除",
|
||||
CloseButtonText = "取消",
|
||||
DefaultButton = ContentDialogButton.Close
|
||||
};
|
||||
|
||||
var result = await deleteDialog.ShowAsync();
|
||||
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
try
|
||||
{
|
||||
_pluginService.UninstallPlugin(plugin.Id);
|
||||
|
||||
// 暂时我们只能刷新列表演示
|
||||
RefreshPluginList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowError("卸载失败", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 简单的弹窗辅助方法
|
||||
private async void ShowTip(string title, string content)
|
||||
{
|
||||
ContentDialog dialog = new ContentDialog
|
||||
{
|
||||
XamlRoot = this.XamlRoot,
|
||||
Title = title,
|
||||
Content = content,
|
||||
CloseButtonText = "关闭"
|
||||
};
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
|
||||
private async void ShowError(string title, string content)
|
||||
{
|
||||
ContentDialog dialog = new ContentDialog
|
||||
{
|
||||
XamlRoot = this.XamlRoot,
|
||||
Title = title,
|
||||
Content = content,
|
||||
CloseButtonText = "关闭"
|
||||
};
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,7 @@
|
||||
<ComboBoxItem x:Uid="StatsDashboardControlThisMonth" />
|
||||
<ComboBoxItem x:Uid="StatsDashboardControlThisQuarter" />
|
||||
<ComboBoxItem x:Uid="StatsDashboardControlThisYear" />
|
||||
<ComboBoxItem x:Uid="StatsDashboardControlAllTime" />
|
||||
<ComboBoxItem x:Uid="StatsDashboardControlCustom" />
|
||||
</ComboBox>
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<linker>
|
||||
<assembly fullname="FlaUI.UIA3" preserve="all" />
|
||||
<assembly fullname="Interop.UIAutomationClient" preserve="all" />
|
||||
|
||||
<assembly fullname="Microsoft.EntityFrameworkCore" preserve="all" />
|
||||
<assembly fullname="Microsoft.EntityFrameworkCore.Abstractions" preserve="all" />
|
||||
<assembly fullname="Microsoft.EntityFrameworkCore.Relational" preserve="all" />
|
||||
<assembly fullname="Microsoft.EntityFrameworkCore.Sqlite" preserve="all" />
|
||||
|
||||
<assembly fullname="NAudio.Wasapi" preserve="all" />
|
||||
<assembly fullname="TagLibSharp" preserve="all" />
|
||||
|
||||
<assembly fullname="Vanara.PInvoke.DwmApi" preserve="all" />
|
||||
<assembly fullname="Vanara.PInvoke.Gdi32" preserve="all" />
|
||||
<assembly fullname="Vanara.PInvoke.Shell32" preserve="all" />
|
||||
<assembly fullname="Vanara.PInvoke.User32" preserve="all" />
|
||||
<assembly fullname="Vanara.Windows.Shell" preserve="all" />
|
||||
|
||||
</linker>
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace BetterLyrics.WinUI3.Enums;
|
||||
|
||||
public enum EaseMode
|
||||
{
|
||||
In,
|
||||
Out,
|
||||
InOut,
|
||||
}
|
||||
@@ -6,15 +6,15 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
Linear,
|
||||
SmoothStep,
|
||||
EaseInOutSine,
|
||||
EaseInOutQuad,
|
||||
EaseInOutCubic,
|
||||
EaseInOutQuart,
|
||||
EaseInOutQuint,
|
||||
EaseInOutExpo,
|
||||
EaseInOutCirc,
|
||||
EaseInOutBack,
|
||||
EaseInOutElastic,
|
||||
EaseInOutBounce,
|
||||
Sine,
|
||||
Quad,
|
||||
Cubic,
|
||||
Quart,
|
||||
Quint,
|
||||
Expo,
|
||||
Circle,
|
||||
Back,
|
||||
Elastic,
|
||||
Bounce,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,5 +14,6 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
LocalEslrcFile,
|
||||
LocalTtmlFile,
|
||||
AppleMusic,
|
||||
Plugin = 999,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
ThisMonth,
|
||||
ThisQuarter,
|
||||
ThisYear,
|
||||
AllTime,
|
||||
Custom
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
LocalEslrcFile,
|
||||
LocalTtmlFile,
|
||||
LibreTranslate,
|
||||
Plugin = 999,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
LocalEslrcFile,
|
||||
LocalTtmlFile,
|
||||
BetterLyrics,
|
||||
CutletDocker
|
||||
CutletDocker,
|
||||
Plugin = 999,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
public enum WordByWordEffectMode
|
||||
{
|
||||
Auto,
|
||||
Never,
|
||||
Always,
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Lyrics;
|
||||
using BetterLyrics.WinUI3.Services.LocalizationService;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -18,14 +19,27 @@ namespace BetterLyrics.WinUI3.Extensions
|
||||
new LyricsLine
|
||||
{
|
||||
StartMs = 0,
|
||||
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
|
||||
OriginalText = "● ● ●",
|
||||
EndMs = (int)TimeSpan.FromSeconds(30).TotalMilliseconds,
|
||||
PrimaryText = "● ● ●",
|
||||
PrimarySyllables = [new BaseLyrics { Text = "● ● ●", StartMs = 0, EndMs = (int)TimeSpan.FromSeconds(30).TotalMilliseconds }],
|
||||
IsPrimaryHasRealSyllableInfo = true,
|
||||
},
|
||||
],
|
||||
LanguageCode = "N/A",
|
||||
};
|
||||
}
|
||||
|
||||
public static LyricsData GetNotfoundPlaceholder()
|
||||
{
|
||||
return new LyricsData([new LyricsLine
|
||||
{
|
||||
StartMs = 0,
|
||||
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
|
||||
PrimaryText = "N/A",
|
||||
PrimarySyllables = [new BaseLyrics { Text = "N/A", StartMs = 0, EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds }],
|
||||
}]);
|
||||
}
|
||||
|
||||
public void SetTranslatedText(LyricsData translationData, int toleranceMs = 50)
|
||||
{
|
||||
foreach (var line in lyricsData.LyricsLines)
|
||||
@@ -37,12 +51,12 @@ namespace BetterLyrics.WinUI3.Extensions
|
||||
if (transLine != null)
|
||||
{
|
||||
// 此处 transLine.OriginalText 指翻译中的“原文”属性
|
||||
line.TranslatedText = transLine.OriginalText;
|
||||
line.SecondaryText = transLine.PrimaryText;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 没有匹配的翻译
|
||||
line.TranslatedText = "";
|
||||
line.SecondaryText = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,12 +72,12 @@ namespace BetterLyrics.WinUI3.Extensions
|
||||
if (transLine != null)
|
||||
{
|
||||
// 此处 transLine.OriginalText 指音译中的“原文”属性
|
||||
line.PhoneticText = transLine.OriginalText;
|
||||
line.TertiaryText = transLine.PrimaryText;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 没有匹配的音译
|
||||
line.PhoneticText = "";
|
||||
line.TertiaryText = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,11 +90,11 @@ namespace BetterLyrics.WinUI3.Extensions
|
||||
{
|
||||
if (i >= translationArr.Count)
|
||||
{
|
||||
line.TranslatedText = ""; // No translation available, keep empty
|
||||
line.SecondaryText = ""; // No translation available, keep empty
|
||||
}
|
||||
else
|
||||
{
|
||||
line.TranslatedText = translationArr[i];
|
||||
line.SecondaryText = translationArr[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -94,11 +108,11 @@ namespace BetterLyrics.WinUI3.Extensions
|
||||
{
|
||||
if (i >= transliterationArr.Count)
|
||||
{
|
||||
line.PhoneticText = ""; // No transliteration available, keep empty
|
||||
line.TertiaryText = ""; // No transliteration available, keep empty
|
||||
}
|
||||
else
|
||||
{
|
||||
line.PhoneticText = transliterationArr[i];
|
||||
line.TertiaryText = transliterationArr[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,12 @@ namespace BetterLyrics.WinUI3.Extensions
|
||||
return songInfo;
|
||||
}
|
||||
|
||||
public SongInfo WithSongId(string value)
|
||||
{
|
||||
songInfo.SongId = value;
|
||||
return songInfo;
|
||||
}
|
||||
|
||||
public PlayHistoryItem? ToPlayHistoryItem(double actualPlayedMs)
|
||||
{
|
||||
if (songInfo == null) return null;
|
||||
|
||||
@@ -56,6 +56,57 @@
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://learn.microsoft.com/zh-cn/dotnet/standard/io/how-to-copy-directories
|
||||
/// </summary>
|
||||
/// <param name="sourceDir"></param>
|
||||
/// <param name="destinationDir"></param>
|
||||
/// <param name="recursive"></param>
|
||||
/// <exception cref="DirectoryNotFoundException"></exception>
|
||||
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
|
||||
{
|
||||
// Get information about the source directory
|
||||
var dir = new DirectoryInfo(sourceDir);
|
||||
|
||||
// Check if the source directory exists
|
||||
if (!dir.Exists)
|
||||
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
|
||||
|
||||
// Cache directories before we start copying
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
|
||||
// Create the destination directory
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
|
||||
// Get the files in the source directory and copy to the destination directory
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
string targetFilePath = Path.Combine(destinationDir, file.Name);
|
||||
|
||||
CopyLockedFile(file.FullName, targetFilePath);
|
||||
}
|
||||
|
||||
// If recursive and copying subdirectories, recursively call this method
|
||||
if (recursive)
|
||||
{
|
||||
foreach (DirectoryInfo subDir in dirs)
|
||||
{
|
||||
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
|
||||
CopyDirectory(subDir.FullName, newDestinationDir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyLockedFile(string sourcePath, string targetPath)
|
||||
{
|
||||
using (var sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
using (var destStream = new FileStream(targetPath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
sourceStream.CopyTo(destStream);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,114 +1,170 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class EasingHelper
|
||||
{
|
||||
public static double EaseInOutSine(double t)
|
||||
{
|
||||
return -(Math.Cos(Math.PI * t) - 1f) / 2f;
|
||||
}
|
||||
public static double EaseInOutQuad(double t)
|
||||
{
|
||||
return t < 0.5f ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
||||
}
|
||||
#region Interpolators
|
||||
|
||||
public static double EaseInOutCubic(double t)
|
||||
public static Func<T, T, double, T> GetInterpolatorByEasingType<T>(EasingType? type, EaseMode easingMode = EaseMode.Out)
|
||||
where T : INumber<T>, IFloatingPointIeee754<T>
|
||||
{
|
||||
return t < 0.5f ? 4 * t * t * t : 1 - Math.Pow(-2 * t + 2, 3) / 2;
|
||||
}
|
||||
public static double EaseInOutQuart(double t)
|
||||
{
|
||||
return t < 0.5f ? 8 * t * t * t * t : 1 - Math.Pow(-2 * t + 2, 4) / 2;
|
||||
}
|
||||
|
||||
public static double EaseInOutQuint(double t)
|
||||
{
|
||||
return t < 0.5f ? 16 * t * t * t * t * t : 1 - Math.Pow(-2 * t + 2, 5) / 2;
|
||||
}
|
||||
|
||||
public static double EaseInOutExpo(double t)
|
||||
{
|
||||
return t == 0
|
||||
? 0
|
||||
: t == 1
|
||||
? 1
|
||||
: t < 0.5 ? Math.Pow(2, 20 * t - 10) / 2
|
||||
: (2 - Math.Pow(2, -20 * t + 10)) / 2;
|
||||
}
|
||||
|
||||
public static double EaseInOutCirc(double t)
|
||||
{
|
||||
return t < 0.5f
|
||||
? (1 - Math.Sqrt(1 - Math.Pow(2 * t, 2))) / 2
|
||||
: (Math.Sqrt(1 - Math.Pow(-2 * t + 2, 2)) + 1) / 2;
|
||||
}
|
||||
|
||||
public static double EaseInOutBack(double t)
|
||||
{
|
||||
double c1 = 1.70158f;
|
||||
double c2 = c1 * 1.525f;
|
||||
|
||||
return t < 0.5
|
||||
? (Math.Pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
|
||||
: (Math.Pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
|
||||
}
|
||||
|
||||
public static double EaseInOutElastic(double t)
|
||||
{
|
||||
if (t == 0 || t == 1) return t;
|
||||
double p = 0.3f;
|
||||
double s = p / 4;
|
||||
return t < 0.5f
|
||||
? -(Math.Pow(2, 20 * t - 10) * Math.Sin((20 * t - 11.125f) * (2 * Math.PI) / p)) / 2
|
||||
: (Math.Pow(2, -20 * t + 10) * Math.Sin((20 * t - 11.125f) * (2 * Math.PI) / p)) / 2 + 1;
|
||||
}
|
||||
|
||||
private static double EaseOutBounce(double t)
|
||||
{
|
||||
if (t < 4 / 11f)
|
||||
return (start, end, progress) =>
|
||||
{
|
||||
return (121 * t * t) / 16f;
|
||||
Func<T, T> easeInFunc = type switch
|
||||
{
|
||||
EasingType.Sine => EaseInSine,
|
||||
EasingType.Quad => EaseInQuad,
|
||||
EasingType.Cubic => EaseInCubic,
|
||||
EasingType.Quart => EaseInQuart,
|
||||
EasingType.Quint => EaseInQuint,
|
||||
EasingType.Expo => EaseInExpo,
|
||||
EasingType.Circle => EaseInCircle,
|
||||
EasingType.Back => EaseInBack,
|
||||
EasingType.Elastic => EaseInElastic,
|
||||
EasingType.Bounce => EaseInBounce,
|
||||
EasingType.SmoothStep => SmoothStep,
|
||||
EasingType.Linear => Linear,
|
||||
_ => EaseInQuad,
|
||||
};
|
||||
double t = Ease(progress, easingMode, easeInFunc);
|
||||
return start + ((end - start) * T.CreateChecked(t));
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static double Ease<T>(double t, EaseMode mode, Func<T, T> easeIn)
|
||||
where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
t = Math.Clamp(t, 0.0, 1.0);
|
||||
|
||||
T tt = T.CreateChecked(t);
|
||||
T half = T.CreateChecked(0.5);
|
||||
T two = T.CreateChecked(2);
|
||||
T tResult = mode switch
|
||||
{
|
||||
EaseMode.In => easeIn(tt),
|
||||
EaseMode.Out => T.One - easeIn(T.One - tt),
|
||||
EaseMode.InOut => tt < half
|
||||
? easeIn(tt * two) / two
|
||||
: T.One - (easeIn((T.One - tt) * two) / two),
|
||||
_ => easeIn(tt),
|
||||
};
|
||||
|
||||
return double.CreateChecked(tResult);
|
||||
}
|
||||
|
||||
public static T EaseInSine<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
return T.One - T.Cos((t * T.Pi) / T.CreateChecked(2));
|
||||
}
|
||||
|
||||
public static T EaseInQuad<T>(T t) where T : INumber<T>
|
||||
{
|
||||
return t * t;
|
||||
}
|
||||
|
||||
public static T EaseInCubic<T>(T t) where T : INumber<T>
|
||||
{
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
public static T EaseInQuart<T>(T t) where T : INumber<T>
|
||||
{
|
||||
return t * t * t * t;
|
||||
}
|
||||
|
||||
public static T EaseInQuint<T>(T t) where T : INumber<T>
|
||||
{
|
||||
return t * t * t * t * t;
|
||||
}
|
||||
|
||||
public static T EaseInExpo<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
if (t == T.Zero)
|
||||
{
|
||||
return T.Zero;
|
||||
}
|
||||
else if (t < 8 / 11f)
|
||||
|
||||
return T.Pow(T.CreateChecked(2), (T.CreateChecked(10) * t) - T.CreateChecked(10));
|
||||
}
|
||||
|
||||
public static T EaseInCircle<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
return T.One - T.Sqrt(T.One - (t * t));
|
||||
}
|
||||
|
||||
public static T EaseInBack<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
T c1 = T.CreateChecked(1.70158);
|
||||
T c3 = c1 + T.One;
|
||||
|
||||
return (c3 * t * t * t) - (c1 * t * t);
|
||||
}
|
||||
|
||||
public static T EaseInElastic<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
if (t == T.Zero || t == T.One)
|
||||
{
|
||||
return (363 / 40f * t * t) - (99 / 10f * t) + 17 / 5f;
|
||||
return t;
|
||||
}
|
||||
else if (t < 9 / 10f)
|
||||
|
||||
const double springiness = 6;
|
||||
const double oscillations = 1;
|
||||
|
||||
double td = double.CreateChecked(t);
|
||||
|
||||
double expo = (Math.Exp(springiness * td) - 1.0) / (Math.Exp(springiness) - 1.0);
|
||||
double result = 0.7 * expo * Math.Sin((Math.PI * 2.0 * oscillations + (Math.PI * 0.5)) * td);
|
||||
|
||||
return T.CreateChecked(result);
|
||||
}
|
||||
|
||||
private static T EaseOutBounce<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
if (t < T.CreateChecked(4.0 / 11.0))
|
||||
{
|
||||
return (4356 / 361f * t * t) - (35442 / 1805f * t) + 16061 / 1805f;
|
||||
return (T.CreateChecked(121) * t * t) / T.CreateChecked(16);
|
||||
}
|
||||
else if (t < T.CreateChecked(8.0 / 11.0))
|
||||
{
|
||||
return ((T.CreateChecked(363.0 / 40.0) * t * t) - (T.CreateChecked(99.0 / 10.0) * t)) + T.CreateChecked(17.0 / 5.0);
|
||||
}
|
||||
else if (t < T.CreateChecked(9.0 / 10.0))
|
||||
{
|
||||
return ((T.CreateChecked(4356.0 / 361.0) * t * t) - (T.CreateChecked(35442.0 / 1805.0) * t)) + T.CreateChecked(16061.0 / 1805.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (54 / 5f * t * t) - (513 / 25f * t) + 268 / 25f;
|
||||
return ((T.CreateChecked(54.0 / 5.0) * t * t) - (T.CreateChecked(513.0 / 25.0) * t)) + T.CreateChecked(268.0 / 25.0);
|
||||
}
|
||||
}
|
||||
|
||||
public static double EaseInOutBounce(double t)
|
||||
public static T EaseInBounce<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
if (t < 0.5f)
|
||||
{
|
||||
return (1 - EaseOutBounce(1 - 2 * t)) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (1 + EaseOutBounce(2 * t - 1)) / 2;
|
||||
}
|
||||
return T.One - EaseOutBounce(T.One - t);
|
||||
}
|
||||
|
||||
public static double SmoothStep(double t)
|
||||
public static T SmoothStep<T>(T t) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
return t * t * (3f - 2f * t);
|
||||
return t * t * (T.CreateChecked(3) - (T.CreateChecked(2) * t));
|
||||
}
|
||||
|
||||
public static double CubicBezier(double t, double p0, double p1, double p2, double p3)
|
||||
public static T CubicBezier<T>(T t, T p0, T p1, T p2, T p3) where T : IFloatingPointIeee754<T>
|
||||
{
|
||||
double u = 1 - t;
|
||||
return u * u * u * p0 + 3 * u * u * t * p1 + 3 * u * t * t * p2 + t * t * t * p3;
|
||||
T u = T.One - t;
|
||||
|
||||
return (u * u * u * p0)
|
||||
+ (T.CreateChecked(3) * u * u * t * p1)
|
||||
+ (T.CreateChecked(3) * u * t * t * p2)
|
||||
+ (t * t * t * p3);
|
||||
}
|
||||
|
||||
public static double Linear(double t) => t;
|
||||
public static T Linear<T>(T t) where T : INumber<T> => t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Entities;
|
||||
using F23.StringSimilarity;
|
||||
using System;
|
||||
using System.IO;
|
||||
@@ -9,29 +10,39 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static partial class MetadataComparer
|
||||
{
|
||||
private const double WeightTitle = 0.40;
|
||||
private const double WeightArtist = 0.40;
|
||||
private const double WeightTitle = 0.30;
|
||||
private const double WeightArtist = 0.30;
|
||||
private const double WeightAlbum = 0.10;
|
||||
private const double WeightDuration = 0.10;
|
||||
private const double WeightDuration = 0.30;
|
||||
|
||||
// JaroWinkler 适合短字符串匹配
|
||||
private static readonly JaroWinkler _algo = new();
|
||||
|
||||
public static int CalculateScore(SongInfo local, LyricsCacheItem remote)
|
||||
public static int CalculateScore(SongInfo songInfo, LyricsCacheItem remote)
|
||||
{
|
||||
if (local == null || remote == null) return 0;
|
||||
return CalculateScore(songInfo, remote.Title, remote.Artist, remote.Album, remote.Duration);
|
||||
}
|
||||
|
||||
public static int CalculateScore(SongInfo songInfo, FilesIndexItem local)
|
||||
{
|
||||
return CalculateScore(songInfo, local.Title, local.Artist, local.Album, local.Duration, local.FileName);
|
||||
}
|
||||
|
||||
public static int CalculateScore(
|
||||
SongInfo songInfo,
|
||||
string? compareTitle, string? compareArtist, string? compareAlbum, double? compareDuration, string? compareFileName = null)
|
||||
{
|
||||
double totalScore = 0;
|
||||
|
||||
bool localHasMetadata = !string.IsNullOrWhiteSpace(local.Title);
|
||||
bool remoteHasMetadata = !string.IsNullOrWhiteSpace(remote.Title);
|
||||
bool localHasMetadata = !string.IsNullOrWhiteSpace(songInfo.Title);
|
||||
bool remoteHasMetadata = !string.IsNullOrWhiteSpace(compareTitle);
|
||||
|
||||
if (localHasMetadata && remoteHasMetadata)
|
||||
{
|
||||
double titleScore = GetStringSimilarity(local.Title, remote.Title);
|
||||
double artistScore = GetStringSimilarity(local.Artist, remote.Artist);
|
||||
double albumScore = GetStringSimilarity(local.Album, remote.Album);
|
||||
double durationScore = GetDurationSimilarity(local.DurationMs, remote.Duration);
|
||||
double titleScore = GetStringSimilarity(songInfo.Title, compareTitle);
|
||||
double artistScore = GetStringSimilarity(songInfo.Artist, compareArtist);
|
||||
double albumScore = GetStringSimilarity(songInfo.Album, compareAlbum);
|
||||
double durationScore = GetDurationSimilarity(songInfo.Duration, compareDuration);
|
||||
|
||||
totalScore = (titleScore * WeightTitle) +
|
||||
(artistScore * WeightArtist) +
|
||||
@@ -41,12 +52,12 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
else
|
||||
{
|
||||
string? localQuery = localHasMetadata
|
||||
? $"{local.Title} {local.Artist}"
|
||||
: Path.GetFileNameWithoutExtension(local.LinkedFileName);
|
||||
? $"{songInfo.Title} {songInfo.Artist}"
|
||||
: Path.GetFileNameWithoutExtension(songInfo.LinkedFileName);
|
||||
|
||||
string? remoteQuery = remoteHasMetadata
|
||||
? $"{remote.Title} {remote.Artist}"
|
||||
: null;
|
||||
? $"{compareTitle} {compareArtist}"
|
||||
: Path.GetFileNameWithoutExtension(compareFileName);
|
||||
|
||||
string fp1 = CreateSortedFingerprint(localQuery);
|
||||
string fp2 = CreateSortedFingerprint(remoteQuery);
|
||||
@@ -83,19 +94,18 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return _algo.Similarity(s1, s2);
|
||||
}
|
||||
|
||||
private static double GetDurationSimilarity(double localMs, double? remoteSeconds)
|
||||
private static double GetDurationSimilarity(double localSeconds, double? remoteSeconds)
|
||||
{
|
||||
if (remoteSeconds == null || remoteSeconds == 0) return 0.0; // 远程没有时长数据,不匹配
|
||||
|
||||
double localSeconds = localMs / 1000.0;
|
||||
double diff = Math.Abs(localSeconds - remoteSeconds.Value);
|
||||
|
||||
// 差距 <= 3秒:100% 相似
|
||||
// 差距 >= 20秒:0% 相似
|
||||
// 差距 <= 1 秒:100 % 相似
|
||||
// 差距 >= 10 秒:0 % 相似
|
||||
// 中间线性插值
|
||||
|
||||
const double PerfectTolerance = 3.0;
|
||||
const double MaxTolerance = 20.0;
|
||||
const double PerfectTolerance = 1.0;
|
||||
const double MaxTolerance = 10.0;
|
||||
|
||||
if (diff <= PerfectTolerance) return 1.0;
|
||||
if (diff >= MaxTolerance) return 0.0;
|
||||
|
||||
@@ -42,19 +42,23 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return file;
|
||||
}
|
||||
|
||||
public static async Task<StorageFile?> PickSaveFileAsync<T>(IDictionary<string, IList<string>> fileTypeChoices)
|
||||
public static async Task<StorageFile?> PickSaveFileAsync<T>(IDictionary<string, IList<string>> fileTypeChoices, string? suggestedFileName = null)
|
||||
{
|
||||
var window = WindowHook.GetWindow<T>();
|
||||
|
||||
return await PickSaveFileAsync(window, fileTypeChoices);
|
||||
return await PickSaveFileAsync(window, fileTypeChoices, suggestedFileName);
|
||||
}
|
||||
|
||||
public static async Task<StorageFile?> PickSaveFileAsync<T>(T? window, IDictionary<string, IList<string>> fileTypeChoices)
|
||||
public static async Task<StorageFile?> PickSaveFileAsync<T>(T? window, IDictionary<string, IList<string>> fileTypeChoices, string? suggestedFileName = null)
|
||||
{
|
||||
if (window == null) return null;
|
||||
|
||||
var picker = new Windows.Storage.Pickers.FileSavePicker();
|
||||
picker.FileTypeChoices.AddRange(fileTypeChoices);
|
||||
if (suggestedFileName != null)
|
||||
{
|
||||
picker.SuggestedFileName = suggestedFileName;
|
||||
}
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
InitializeWithWindow.Initialize(picker, hwnd);
|
||||
|
||||
@@ -1,153 +1,232 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static BetterLyrics.WinUI3.Helper.EasingHelper;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class ValueTransition<T>
|
||||
where T : struct
|
||||
public class ValueTransition<T> where T : struct
|
||||
{
|
||||
// 状态变量
|
||||
private T _currentValue;
|
||||
private double _durationSeconds;
|
||||
private double _delaySeconds;
|
||||
private double _delayRemaining;
|
||||
private EasingType? _easingType;
|
||||
private Func<T, T, double, T> _interpolator;
|
||||
private bool _isTransitioning;
|
||||
private double _progress;
|
||||
private T _startValue;
|
||||
private T _targetValue;
|
||||
|
||||
public double DurationSeconds => _durationSeconds;
|
||||
public double DelaySeconds => _delaySeconds;
|
||||
// 核心队列
|
||||
private readonly Queue<Keyframe<T>> _keyframeQueue = new Queue<Keyframe<T>>();
|
||||
|
||||
public bool IsTransitioning => _isTransitioning;
|
||||
// 时间控制
|
||||
private double _stepDuration; // 当前这一段的时长 (动态变化)
|
||||
private double _totalDurationForAutoSplit; // 自动均分模式的总时长
|
||||
private double _configuredDelaySeconds; // 配置的延迟时长
|
||||
|
||||
// 动画状态
|
||||
private Func<T, T, double, T> _interpolator;
|
||||
private bool _isTransitioning;
|
||||
private double _progress; // 当前段的进度 (0.0 ~ 1.0)
|
||||
|
||||
// 公开属性
|
||||
public T Value => _currentValue;
|
||||
public T StartValue => _startValue;
|
||||
public T TargetValue => _targetValue;
|
||||
public EasingType? EasingType => _easingType;
|
||||
public double Progress => _progress;
|
||||
public bool IsTransitioning => _isTransitioning;
|
||||
public T TargetValue => _targetValue; // 获取当前段的目标值
|
||||
public double DurationSeconds => _totalDurationForAutoSplit;
|
||||
|
||||
public ValueTransition(T initialValue, double durationSeconds, Func<T, T, double, T>? interpolator = null, EasingType? easingType = null, double delaySeconds = 0)
|
||||
public Func<T, T, double, T> Interpolator => _interpolator;
|
||||
|
||||
public ValueTransition(T initialValue, Func<T, T, double, T>? interpolator, double defaultTotalDuration = 0.3)
|
||||
{
|
||||
_currentValue = initialValue;
|
||||
_startValue = initialValue;
|
||||
_targetValue = initialValue;
|
||||
_durationSeconds = durationSeconds;
|
||||
_delaySeconds = delaySeconds;
|
||||
_delayRemaining = 0;
|
||||
_progress = 1f;
|
||||
_isTransitioning = false;
|
||||
_totalDurationForAutoSplit = defaultTotalDuration;
|
||||
|
||||
if (interpolator != null)
|
||||
{
|
||||
_interpolator = interpolator;
|
||||
_easingType = null;
|
||||
}
|
||||
else if (easingType.HasValue)
|
||||
{
|
||||
_easingType = easingType;
|
||||
_interpolator = GetInterpolatorByEasingType(_easingType.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_easingType = Enums.EasingType.EaseInOutQuad;
|
||||
_interpolator = GetInterpolatorByEasingType(_easingType.Value);
|
||||
}
|
||||
}
|
||||
|
||||
#region Configuration
|
||||
|
||||
public void SetDuration(double seconds)
|
||||
{
|
||||
if (seconds < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(seconds), "Duration must be positive.");
|
||||
_durationSeconds = seconds;
|
||||
if (seconds < 0) throw new ArgumentOutOfRangeException(nameof(seconds));
|
||||
_totalDurationForAutoSplit = seconds;
|
||||
}
|
||||
|
||||
public void SetDurationMs(double millionSeconds) => SetDuration(millionSeconds / 1000.0);
|
||||
|
||||
/// <summary>
|
||||
/// 设置启动延迟。
|
||||
/// 原理:在动画队列最前方插入一个“数值不变”的关键帧。
|
||||
/// </summary>
|
||||
public void SetDelay(double seconds)
|
||||
{
|
||||
_delaySeconds = seconds;
|
||||
_configuredDelaySeconds = seconds;
|
||||
}
|
||||
|
||||
private void JumpTo(T value)
|
||||
public void SetInterpolator(Func<T, T, double, T> interpolator)
|
||||
{
|
||||
_interpolator = interpolator;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Control Methods
|
||||
|
||||
/// <summary>
|
||||
/// 立即跳转到指定值(停止动画)
|
||||
/// </summary>
|
||||
public void JumpTo(T value)
|
||||
{
|
||||
_keyframeQueue.Clear();
|
||||
_currentValue = value;
|
||||
_startValue = value;
|
||||
_targetValue = value;
|
||||
_progress = 1f;
|
||||
_delayRemaining = 0;
|
||||
_isTransitioning = false;
|
||||
_progress = 0;
|
||||
}
|
||||
|
||||
public void Reset(T value)
|
||||
/// <summary>
|
||||
/// 模式 A: 精确控制模式
|
||||
/// 显式指定每一段的目标值和时长。
|
||||
/// </summary>
|
||||
public void Start(params Keyframe<T>[] keyframes)
|
||||
{
|
||||
_currentValue = value;
|
||||
_startValue = value;
|
||||
_targetValue = value;
|
||||
_progress = 0f;
|
||||
_delayRemaining = 0;
|
||||
_isTransitioning = false;
|
||||
}
|
||||
if (keyframes == null || keyframes.Length == 0) return;
|
||||
|
||||
public void StartTransition(T targetValue, bool jumpTo = false)
|
||||
{
|
||||
if (jumpTo)
|
||||
PrepareStart();
|
||||
|
||||
// 1. 处理延迟 (插入静止帧)
|
||||
if (_configuredDelaySeconds > 0)
|
||||
{
|
||||
JumpTo(targetValue);
|
||||
return;
|
||||
_keyframeQueue.Enqueue(new Keyframe<T>(_currentValue, _configuredDelaySeconds));
|
||||
}
|
||||
|
||||
if (!targetValue.Equals(_currentValue))
|
||||
// 2. 入队用户帧
|
||||
foreach (var kf in keyframes)
|
||||
{
|
||||
_startValue = _currentValue;
|
||||
_targetValue = targetValue;
|
||||
_progress = 0f;
|
||||
_delayRemaining = _delaySeconds;
|
||||
_isTransitioning = true;
|
||||
_keyframeQueue.Enqueue(kf);
|
||||
}
|
||||
|
||||
MoveToNextSegment(firstStart: true);
|
||||
}
|
||||
|
||||
public static bool Equals(double x, double y, double tolerance)
|
||||
/// <summary>
|
||||
/// 模式 B: 自动均分模式 (兼容旧写法)
|
||||
/// 指定一串目标值,系统根据 SetDuration 的总时长平均分配。
|
||||
/// </summary>
|
||||
public void Start(params T[] values)
|
||||
{
|
||||
var diff = Math.Abs(x - y);
|
||||
return diff <= tolerance || diff <= Math.Max(Math.Abs(x), Math.Abs(y)) * tolerance;
|
||||
if (values == null || values.Length == 0) return;
|
||||
|
||||
// 如果目标就是当前值且只有1帧,直接跳过以省性能
|
||||
if (values.Length == 1 && values[0].Equals(_currentValue) && _configuredDelaySeconds <= 0) return;
|
||||
|
||||
PrepareStart();
|
||||
|
||||
// 1. 处理延迟
|
||||
if (_configuredDelaySeconds > 0)
|
||||
{
|
||||
_keyframeQueue.Enqueue(new Keyframe<T>(_currentValue, _configuredDelaySeconds));
|
||||
}
|
||||
|
||||
// 2. 计算均分时长
|
||||
double autoStepDuration = _totalDurationForAutoSplit / values.Length;
|
||||
|
||||
// 3. 入队生成帧
|
||||
foreach (var val in values)
|
||||
{
|
||||
_keyframeQueue.Enqueue(new Keyframe<T>(val, autoStepDuration));
|
||||
}
|
||||
|
||||
MoveToNextSegment(firstStart: true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Core Logic
|
||||
|
||||
private void PrepareStart()
|
||||
{
|
||||
_keyframeQueue.Clear();
|
||||
_isTransitioning = true;
|
||||
}
|
||||
|
||||
private void MoveToNextSegment(bool firstStart = false)
|
||||
{
|
||||
if (_keyframeQueue.Count > 0)
|
||||
{
|
||||
var kf = _keyframeQueue.Dequeue();
|
||||
|
||||
// 起点逻辑:如果是刚开始,起点是当前值;如果是中间切换,起点是上一段的终点
|
||||
_startValue = firstStart ? _currentValue : _targetValue;
|
||||
_targetValue = kf.Value;
|
||||
_stepDuration = kf.Duration;
|
||||
|
||||
if (firstStart) _progress = 0f;
|
||||
// 注意:非 firstStart 时不重置 _progress,保留溢出值以平滑过渡
|
||||
}
|
||||
else
|
||||
{
|
||||
// 队列耗尽,动画结束
|
||||
_currentValue = _targetValue;
|
||||
_isTransitioning = false;
|
||||
_progress = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(TimeSpan elapsedTime)
|
||||
{
|
||||
if (!_isTransitioning) return;
|
||||
|
||||
if (_delayRemaining > 0)
|
||||
{
|
||||
double consume = Math.Min(_delayRemaining, elapsedTime.TotalSeconds);
|
||||
_delayRemaining -= consume;
|
||||
if (_delayRemaining > 0)
|
||||
return;
|
||||
elapsedTime = TimeSpan.FromSeconds(elapsedTime.TotalSeconds - consume);
|
||||
}
|
||||
double timeStep = elapsedTime.TotalSeconds;
|
||||
|
||||
if (_durationSeconds <= 0)
|
||||
// 使用 while 处理单帧时间过长跨越多段的情况
|
||||
while (timeStep > 0 && _isTransitioning)
|
||||
{
|
||||
_progress = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
_progress += elapsedTime.TotalSeconds / _durationSeconds;
|
||||
}
|
||||
// 计算当前帧的步进比例
|
||||
// 极小值保护,防止除以0
|
||||
double progressDelta = (_stepDuration > 0.000001) ? (timeStep / _stepDuration) : 1.0;
|
||||
|
||||
if (_progress >= 1f)
|
||||
{
|
||||
_progress = 1f;
|
||||
_currentValue = _targetValue;
|
||||
_isTransitioning = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentValue = _interpolator(_startValue, _targetValue, _progress);
|
||||
if (_progress + progressDelta >= 1.0)
|
||||
{
|
||||
// === 当前段结束 ===
|
||||
|
||||
// 1. 计算这一段实际消耗的时间
|
||||
double timeConsumed = (1.0 - _progress) * _stepDuration;
|
||||
|
||||
// 2. 剩余时间留给下一段
|
||||
timeStep -= timeConsumed;
|
||||
|
||||
// 3. 修正当前值到目标值
|
||||
_progress = 1.0;
|
||||
_currentValue = _targetValue;
|
||||
|
||||
// 4. 切换到下一段
|
||||
MoveToNextSegment();
|
||||
|
||||
// 5. 如果还有下一段,进度归零
|
||||
if (_isTransitioning) _progress = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// === 当前段进行中 ===
|
||||
_progress += progressDelta;
|
||||
timeStep = 0; // 时间耗尽
|
||||
|
||||
// 插值计算
|
||||
_currentValue = _interpolator(_startValue, _targetValue, _progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Func<T, T, double, T> GetInterpolatorByEasingType(EasingType? type)
|
||||
#endregion
|
||||
|
||||
#region Interpolators
|
||||
|
||||
public static Func<T, T, double, T> GetInterpolatorByEasingType(EasingType? type, EaseMode easingMode)
|
||||
{
|
||||
if (typeof(T) == typeof(double))
|
||||
{
|
||||
@@ -155,59 +234,32 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
double s = (double)(object)start;
|
||||
double e = (double)(object)end;
|
||||
double t = progress;
|
||||
switch (type)
|
||||
|
||||
Func<double, double> easeInFunc = type switch
|
||||
{
|
||||
case Enums.EasingType.EaseInOutSine:
|
||||
t = EasingHelper.EaseInOutSine(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutQuad:
|
||||
t = EasingHelper.EaseInOutQuad(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutCubic:
|
||||
t = EasingHelper.EaseInOutCubic(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutQuart:
|
||||
t = EasingHelper.EaseInOutQuart(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutQuint:
|
||||
t = EasingHelper.EaseInOutQuint(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutExpo:
|
||||
t = EasingHelper.EaseInOutExpo(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutCirc:
|
||||
t = EasingHelper.EaseInOutCirc(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutBack:
|
||||
t = EasingHelper.EaseInOutBack(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutElastic:
|
||||
t = EasingHelper.EaseInOutElastic(t);
|
||||
break;
|
||||
case Enums.EasingType.EaseInOutBounce:
|
||||
t = EasingHelper.EaseInOutBounce(t);
|
||||
break;
|
||||
case Enums.EasingType.SmoothStep:
|
||||
t = EasingHelper.SmoothStep(t);
|
||||
break;
|
||||
case Enums.EasingType.Linear:
|
||||
t = EasingHelper.Linear(t);
|
||||
break;
|
||||
default:
|
||||
t = EasingHelper.EaseInOutQuad(t);
|
||||
break;
|
||||
}
|
||||
Enums.EasingType.Sine => EaseInSine,
|
||||
Enums.EasingType.Quad => EaseInQuad,
|
||||
Enums.EasingType.Cubic => EaseInCubic,
|
||||
Enums.EasingType.Quart => EaseInQuart,
|
||||
Enums.EasingType.Quint => EaseInQuint,
|
||||
Enums.EasingType.Expo => EaseInExpo,
|
||||
Enums.EasingType.Circle => EaseInCircle,
|
||||
Enums.EasingType.Back => EaseInBack,
|
||||
Enums.EasingType.Elastic => EaseInElastic,
|
||||
Enums.EasingType.Bounce => EaseInBounce,
|
||||
Enums.EasingType.SmoothStep => SmoothStep,
|
||||
Enums.EasingType.Linear => Linear,
|
||||
_ => EaseInQuad,
|
||||
};
|
||||
double t = Ease(progress, easingMode, easeInFunc);
|
||||
|
||||
return (T)(object)(s + (e - s) * t);
|
||||
};
|
||||
}
|
||||
throw new NotSupportedException($"Easing type {type} is not supported for type {typeof(T)}.");
|
||||
|
||||
throw new NotSupportedException($"Type {typeof(T)} is not supported.");
|
||||
}
|
||||
|
||||
public void SetEasingType(EasingType? easingType)
|
||||
{
|
||||
_easingType = easingType;
|
||||
_interpolator = GetInterpolatorByEasingType(easingType);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Constants;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Lyrics;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using DevWinUI;
|
||||
@@ -35,38 +36,79 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
double currentPositionMs
|
||||
)
|
||||
{
|
||||
if (lines == null) return;
|
||||
if (lines == null || lines.Count == 0) return;
|
||||
|
||||
var currentPlayingLine = lines.ElementAtOrDefault(primaryPlayingLineIndex);
|
||||
if (currentPlayingLine == null) return;
|
||||
if (primaryPlayingLineIndex < 0 || primaryPlayingLineIndex >= lines.Count) return;
|
||||
var primaryPlayingLine = lines[primaryPlayingLineIndex];
|
||||
|
||||
var phoneticOpacity = lyricsStyle.PhoneticLyricsOpacity / 100.0;
|
||||
var originalOpacity = lyricsStyle.OriginalLyricsOpacity / 100.0;
|
||||
var translatedOpacity = lyricsStyle.TranslatedLyricsOpacity / 100.0;
|
||||
|
||||
for (int i = startIndex; i <= endIndex + 1; i++)
|
||||
{
|
||||
var line = lines.ElementAtOrDefault(i);
|
||||
if (line == null) continue;
|
||||
double topHeightFactor = canvasHeight * playingLineTopOffsetFactor;
|
||||
double bottomHeightFactor = canvasHeight * (1 - playingLineTopOffsetFactor);
|
||||
|
||||
bool isSecondaryLinePlaying = line.StartMs <= currentPositionMs && currentPositionMs <= line.EndMs;
|
||||
if (i == primaryPlayingLineIndex) isSecondaryLinePlaying = true;
|
||||
double scrollTopDurationSec = lyricsEffect.LyricsScrollTopDuration / 1000.0;
|
||||
double scrollTopDelaySec = lyricsEffect.LyricsScrollTopDelay / 1000.0;
|
||||
double scrollBottomDurationSec = lyricsEffect.LyricsScrollBottomDuration / 1000.0;
|
||||
double scrollBottomDelaySec = lyricsEffect.LyricsScrollBottomDelay / 1000.0;
|
||||
double canvasTransDuration = canvasYScrollTransition.DurationSeconds;
|
||||
|
||||
bool isBlurEnabled = lyricsEffect.IsLyricsBlurEffectEnabled;
|
||||
bool isOutOfSightEnabled = lyricsEffect.IsLyricsOutOfSightEffectEnabled;
|
||||
bool isFanEnabled = lyricsEffect.IsFanLyricsEnabled;
|
||||
double fanAngleRad = Math.PI * (lyricsEffect.FanLyricsAngle / 180.0);
|
||||
bool isGlowEnabled = lyricsEffect.IsLyricsGlowEffectEnabled;
|
||||
bool isFloatEnabled = lyricsEffect.IsLyricsFloatAnimationEnabled;
|
||||
bool isScaleEnabled = lyricsEffect.IsLyricsScaleEffectEnabled;
|
||||
|
||||
int safeStart = Math.Max(0, startIndex);
|
||||
int safeEnd = Math.Min(lines.Count - 1, endIndex + 1);
|
||||
|
||||
for (int i = safeStart; i <= safeEnd; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
var lineHeight = line.PrimaryLineHeight;
|
||||
if (lineHeight == null || lineHeight <= 0) continue;
|
||||
|
||||
bool isWordAnimationEnabled = lyricsEffect.WordByWordEffectMode switch
|
||||
{
|
||||
Enums.WordByWordEffectMode.Auto => line.IsPrimaryHasRealSyllableInfo,
|
||||
Enums.WordByWordEffectMode.Always => true,
|
||||
Enums.WordByWordEffectMode.Never => false,
|
||||
_ => line.IsPrimaryHasRealSyllableInfo
|
||||
};
|
||||
|
||||
double targetCharFloat = lyricsEffect.IsLyricsFloatAnimationAmountAutoAdjust
|
||||
? lineHeight.Value * 0.1
|
||||
: lyricsEffect.LyricsFloatAnimationAmount;
|
||||
double targetCharGlow = lyricsEffect.IsLyricsGlowEffectAmountAutoAdjust
|
||||
? lineHeight.Value * 0.2
|
||||
: lyricsEffect.LyricsGlowEffectAmount;
|
||||
double targetCharScale = lyricsEffect.IsLyricsScaleEffectAmountAutoAdjust
|
||||
? 1.15
|
||||
: lyricsEffect.LyricsScaleEffectAmount / 100.0;
|
||||
|
||||
var maxAnimationDurationMs = Math.Max(line.EndMs ?? 0 - currentPositionMs, 0);
|
||||
|
||||
bool isSecondaryLinePlaying = line.GetIsPlaying(currentPositionMs);
|
||||
bool isSecondaryLinePlayingChanged = line.IsPlayingLastFrame != isSecondaryLinePlaying;
|
||||
line.IsPlayingLastFrame = isSecondaryLinePlaying;
|
||||
|
||||
if (isLayoutChanged || isPrimaryPlayingLineChanged || isMouseScrollingChanged || isSecondaryLinePlayingChanged)
|
||||
// 行动画
|
||||
if (isLayoutChanged || isPrimaryPlayingLineChanged || isMouseScrollingChanged)
|
||||
{
|
||||
int lineCountDelta = i - primaryPlayingLineIndex;
|
||||
double distanceFromPlayingLine = Math.Abs(line.OriginalPosition.Y - currentPlayingLine.OriginalPosition.Y);
|
||||
double distanceFromPlayingLine = Math.Abs(line.PrimaryPosition.Y - primaryPlayingLine.PrimaryPosition.Y);
|
||||
|
||||
double distanceFactor;
|
||||
if (lineCountDelta < 0)
|
||||
{
|
||||
distanceFactor = Math.Clamp(distanceFromPlayingLine / (canvasHeight * playingLineTopOffsetFactor), 0, 1);
|
||||
distanceFactor = Math.Clamp(distanceFromPlayingLine / topHeightFactor, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
distanceFactor = Math.Clamp(distanceFromPlayingLine / (canvasHeight * (1 - playingLineTopOffsetFactor)), 0, 1);
|
||||
distanceFactor = Math.Clamp(distanceFromPlayingLine / bottomHeightFactor, 0, 1);
|
||||
}
|
||||
|
||||
double yScrollDuration;
|
||||
@@ -75,178 +117,179 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
if (lineCountDelta < 0)
|
||||
{
|
||||
yScrollDuration =
|
||||
canvasYScrollTransition.DurationSeconds +
|
||||
distanceFactor * (lyricsEffect.LyricsScrollTopDuration / 1000.0 - canvasYScrollTransition.DurationSeconds);
|
||||
yScrollDelay = distanceFactor * lyricsEffect.LyricsScrollTopDelay / 1000.0;
|
||||
canvasTransDuration +
|
||||
distanceFactor * (scrollTopDurationSec - canvasTransDuration);
|
||||
yScrollDelay = distanceFactor * scrollTopDelaySec;
|
||||
}
|
||||
else if (lineCountDelta == 0)
|
||||
{
|
||||
yScrollDuration = canvasYScrollTransition.DurationSeconds;
|
||||
yScrollDuration = canvasTransDuration;
|
||||
yScrollDelay = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yScrollDuration =
|
||||
canvasYScrollTransition.DurationSeconds +
|
||||
distanceFactor * (lyricsEffect.LyricsScrollBottomDuration / 1000.0 - canvasYScrollTransition.DurationSeconds);
|
||||
yScrollDelay = distanceFactor * lyricsEffect.LyricsScrollBottomDelay / 1000.0;
|
||||
canvasTransDuration +
|
||||
distanceFactor * (scrollBottomDurationSec - canvasTransDuration);
|
||||
yScrollDelay = distanceFactor * scrollBottomDelaySec;
|
||||
}
|
||||
|
||||
line.BlurAmountTransition.SetDuration(yScrollDuration);
|
||||
line.BlurAmountTransition.SetDelay(yScrollDelay);
|
||||
line.BlurAmountTransition.StartTransition(
|
||||
line.BlurAmountTransition.Start(
|
||||
(isMouseScrolling || isSecondaryLinePlaying) ? 0 :
|
||||
(lyricsEffect.IsLyricsBlurEffectEnabled ? (5 * distanceFactor) : 0));
|
||||
(isBlurEnabled ? (5 * distanceFactor) : 0));
|
||||
|
||||
line.ScaleTransition.SetDuration(yScrollDuration);
|
||||
line.ScaleTransition.SetDelay(yScrollDelay);
|
||||
line.ScaleTransition.StartTransition(
|
||||
line.ScaleTransition.Start(
|
||||
isSecondaryLinePlaying ? _highlightedScale :
|
||||
(lyricsEffect.IsLyricsOutOfSightEffectEnabled ?
|
||||
(isOutOfSightEnabled ?
|
||||
(_highlightedScale - distanceFactor * (_highlightedScale - _defaultScale)) :
|
||||
_highlightedScale));
|
||||
|
||||
line.PhoneticOpacityTransition.SetDuration(yScrollDuration);
|
||||
line.PhoneticOpacityTransition.SetDelay(yScrollDelay);
|
||||
line.PhoneticOpacityTransition.StartTransition(
|
||||
line.PhoneticOpacityTransition.Start(
|
||||
isSecondaryLinePlaying ? phoneticOpacity :
|
||||
CalculateTargetOpacity(phoneticOpacity, phoneticOpacity, distanceFactor, isMouseScrolling, lyricsEffect));
|
||||
|
||||
// 原文不透明度(已播放)
|
||||
line.PlayedOriginalOpacityTransition.SetDuration(yScrollDuration);
|
||||
line.PlayedOriginalOpacityTransition.SetDelay(yScrollDelay);
|
||||
line.PlayedOriginalOpacityTransition.StartTransition(
|
||||
line.PlayedOriginalOpacityTransition.Start(
|
||||
isSecondaryLinePlaying ? 1.0 :
|
||||
CalculateTargetOpacity(originalOpacity, 1.0, distanceFactor, isMouseScrolling, lyricsEffect));
|
||||
// 原文不透明度(未播放)
|
||||
line.UnplayedOriginalOpacityTransition.SetDuration(yScrollDuration);
|
||||
line.UnplayedOriginalOpacityTransition.SetDelay(yScrollDelay);
|
||||
line.UnplayedOriginalOpacityTransition.StartTransition(
|
||||
line.UnplayedOriginalOpacityTransition.Start(
|
||||
isSecondaryLinePlaying ? originalOpacity :
|
||||
CalculateTargetOpacity(originalOpacity, originalOpacity, distanceFactor, isMouseScrolling, lyricsEffect));
|
||||
|
||||
line.TranslatedOpacityTransition.SetDuration(yScrollDuration);
|
||||
line.TranslatedOpacityTransition.SetDelay(yScrollDelay);
|
||||
line.TranslatedOpacityTransition.StartTransition(
|
||||
line.TranslatedOpacityTransition.Start(
|
||||
isSecondaryLinePlaying ? translatedOpacity :
|
||||
CalculateTargetOpacity(translatedOpacity, translatedOpacity, distanceFactor, isMouseScrolling, lyricsEffect));
|
||||
|
||||
line.ColorTransition.SetDuration(yScrollDuration);
|
||||
line.ColorTransition.SetDelay(yScrollDelay);
|
||||
line.ColorTransition.StartTransition(isSecondaryLinePlaying ? fgColor : bgColor);
|
||||
line.ColorTransition.Start(isSecondaryLinePlaying ? fgColor : bgColor);
|
||||
|
||||
line.AngleTransition.SetEasingType(canvasYScrollTransition.EasingType);
|
||||
line.AngleTransition.SetInterpolator(canvasYScrollTransition.Interpolator);
|
||||
line.AngleTransition.SetDuration(yScrollDuration);
|
||||
line.AngleTransition.SetDelay(yScrollDelay);
|
||||
line.AngleTransition.StartTransition(
|
||||
(lyricsEffect.IsFanLyricsEnabled && !isMouseScrolling) ?
|
||||
Math.PI * (lyricsEffect.FanLyricsAngle / 180.0) * distanceFactor * (i > primaryPlayingLineIndex ? 1 : -1) :
|
||||
line.AngleTransition.Start(
|
||||
(isFanEnabled && !isMouseScrolling) ?
|
||||
fanAngleRad * distanceFactor * (i > primaryPlayingLineIndex ? 1 : -1) :
|
||||
0);
|
||||
|
||||
line.YOffsetTransition.SetEasingType(canvasYScrollTransition.EasingType);
|
||||
line.YOffsetTransition.SetInterpolator(canvasYScrollTransition.Interpolator);
|
||||
line.YOffsetTransition.SetDuration(yScrollDuration);
|
||||
line.YOffsetTransition.SetDelay(yScrollDelay);
|
||||
// 设计之初是当 isLayoutChanged 为真时 jumpTo
|
||||
// 但考虑到动画视觉,强制使用动画
|
||||
line.YOffsetTransition.StartTransition(targetYScrollOffset);
|
||||
line.YOffsetTransition.Start(targetYScrollOffset);
|
||||
}
|
||||
|
||||
if (line.RenderLyricsOriginalChars != null)
|
||||
if (isWordAnimationEnabled)
|
||||
{
|
||||
foreach (var renderChar in line.RenderLyricsOriginalChars)
|
||||
if (isSecondaryLinePlayingChanged)
|
||||
{
|
||||
var syllable = line.LyricsSyllables.FirstOrDefault(x => x.StartIndex <= renderChar.Index && renderChar.Index <= x.EndIndex);
|
||||
if (syllable == null) continue;
|
||||
// 辉光动画
|
||||
if (isGlowEnabled && lyricsEffect.LyricsGlowEffectScope == Enums.LyricsEffectScope.LineStartToCurrentChar
|
||||
&& isSecondaryLinePlaying)
|
||||
{
|
||||
foreach (var renderChar in line.PrimaryRenderChars)
|
||||
{
|
||||
var stepInOutDuration = Math.Min(Time.AnimationDuration.TotalMilliseconds, maxAnimationDurationMs) / 2.0 / 1000.0;
|
||||
var stepLastingDuration = Math.Max(maxAnimationDurationMs / 1000.0 - stepInOutDuration * 2, 0);
|
||||
renderChar.GlowTransition.Start(
|
||||
new Models.Keyframe<double>(targetCharGlow, stepInOutDuration),
|
||||
new Models.Keyframe<double>(targetCharGlow, stepLastingDuration),
|
||||
new Models.Keyframe<double>(0, stepInOutDuration)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var avgCharDuration = syllable.DurationMs / syllable.Length;
|
||||
if (avgCharDuration == null || avgCharDuration == 0) continue;
|
||||
// 浮动动画
|
||||
if (isFloatEnabled)
|
||||
{
|
||||
foreach (var renderChar in line.PrimaryRenderChars)
|
||||
{
|
||||
renderChar.FloatTransition.Start(isSecondaryLinePlaying ? targetCharFloat : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var charStartMs = syllable.StartMs + (renderChar.Index - syllable.StartIndex) * avgCharDuration.Value;
|
||||
var charEndMs = charStartMs + avgCharDuration;
|
||||
var progressPlayed = (currentPositionMs - charStartMs) / avgCharDuration.Value;
|
||||
progressPlayed = Math.Clamp(progressPlayed, 0, 1);
|
||||
renderChar.ProgressPlayed = progressPlayed;
|
||||
// 字符动画
|
||||
foreach (var renderChar in line.PrimaryRenderChars)
|
||||
{
|
||||
renderChar.ProgressPlayed = renderChar.GetPlayProgress(currentPositionMs);
|
||||
|
||||
bool isCharPlaying = charStartMs <= currentPositionMs && currentPositionMs <= charEndMs;
|
||||
bool isCharPlaying = renderChar.GetIsPlaying(currentPositionMs);
|
||||
bool isCharPlayingChanged = renderChar.IsPlayingLastFrame != isCharPlaying;
|
||||
|
||||
if (isSecondaryLinePlayingChanged || isCharPlayingChanged)
|
||||
if (isCharPlayingChanged)
|
||||
{
|
||||
if (lyricsEffect.IsLyricsScaleEffectEnabled)
|
||||
if (isFloatEnabled)
|
||||
{
|
||||
double targetScale =
|
||||
lyricsEffect.IsLyricsScaleEffectAmountAutoAdjust ? 1.15 : lyricsEffect.LyricsScaleEffectAmount / 100.0;
|
||||
|
||||
if (isCharPlayingChanged)
|
||||
{
|
||||
if (syllable.DurationMs >= lyricsEffect.LyricsScaleEffectLongSyllableDuration)
|
||||
{
|
||||
renderChar.ScaleTransition.SetDuration((syllable.DurationMs ?? 0) / 1000.0 / 2);
|
||||
renderChar.ScaleTransition.StartTransition(isCharPlaying ? targetScale : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lyricsEffect.IsLyricsGlowEffectEnabled)
|
||||
{
|
||||
double targetGlow = lyricsEffect.IsLyricsGlowEffectAmountAutoAdjust ? renderChar.LayoutRect.Height * 0.2 : lyricsEffect.LyricsGlowEffectAmount;
|
||||
switch (lyricsEffect.LyricsGlowEffectScope)
|
||||
{
|
||||
case Enums.LyricsEffectScope.LongDurationSyllable:
|
||||
if (isCharPlayingChanged)
|
||||
{
|
||||
if (syllable.DurationMs >= lyricsEffect.LyricsGlowEffectLongSyllableDuration)
|
||||
{
|
||||
renderChar.GlowTransition.SetDuration((syllable.DurationMs ?? 0) / 1000.0 / 2);
|
||||
renderChar.GlowTransition.StartTransition(isCharPlaying ? targetGlow : 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Enums.LyricsEffectScope.LineStartToCurrentChar:
|
||||
if (isSecondaryLinePlayingChanged)
|
||||
{
|
||||
renderChar.GlowTransition.SetDuration(renderChar.AnimationDuration);
|
||||
renderChar.GlowTransition.StartTransition(isSecondaryLinePlaying ? targetGlow : 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lyricsEffect.IsLyricsFloatAnimationEnabled)
|
||||
{
|
||||
double targetFloat =
|
||||
lyricsEffect.IsLyricsFloatAnimationAmountAutoAdjust ? renderChar.LayoutRect.Height * 0.1 : lyricsEffect.LyricsFloatAnimationAmount;
|
||||
|
||||
if (isSecondaryLinePlayingChanged)
|
||||
{
|
||||
renderChar.FloatTransition.StartTransition(isSecondaryLinePlaying ? targetFloat : 0);
|
||||
}
|
||||
if (isCharPlayingChanged)
|
||||
{
|
||||
renderChar.FloatTransition.StartTransition(0);
|
||||
}
|
||||
renderChar.FloatTransition.SetDurationMs(Math.Min(lyricsEffect.LyricsFloatAnimationDuration, maxAnimationDurationMs));
|
||||
renderChar.FloatTransition.Start(0);
|
||||
}
|
||||
|
||||
renderChar.IsPlayingLastFrame = isCharPlaying;
|
||||
}
|
||||
}
|
||||
|
||||
renderChar.ScaleTransition.Update(elapsedTime);
|
||||
renderChar.GlowTransition.Update(elapsedTime);
|
||||
renderChar.FloatTransition.Update(elapsedTime);
|
||||
// 音节动画
|
||||
foreach (var syllable in line.PrimaryRenderSyllables)
|
||||
{
|
||||
bool isSyllablePlaying = syllable.GetIsPlaying(currentPositionMs);
|
||||
bool isSyllablePlayingChanged = syllable.IsPlayingLastFrame != isSyllablePlaying;
|
||||
|
||||
if (isSyllablePlayingChanged)
|
||||
{
|
||||
if (isScaleEnabled && isSyllablePlaying)
|
||||
{
|
||||
foreach (var renderChar in syllable.ChildrenRenderLyricsChars)
|
||||
{
|
||||
if (syllable.DurationMs >= lyricsEffect.LyricsScaleEffectLongSyllableDuration)
|
||||
{
|
||||
var stepDuration = Math.Min(syllable.DurationMs, maxAnimationDurationMs) / 2.0 / 1000.0;
|
||||
renderChar.ScaleTransition.Start(
|
||||
new Models.Keyframe<double>(targetCharScale, stepDuration),
|
||||
new Models.Keyframe<double>(1.0, stepDuration)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isGlowEnabled && isSyllablePlaying && lyricsEffect.LyricsGlowEffectScope == Enums.LyricsEffectScope.LongDurationSyllable
|
||||
&& syllable.DurationMs >= lyricsEffect.LyricsGlowEffectLongSyllableDuration)
|
||||
{
|
||||
foreach (var renderChar in syllable.ChildrenRenderLyricsChars)
|
||||
{
|
||||
var stepDuration = Math.Min(syllable.DurationMs, maxAnimationDurationMs) / 2.0 / 1000.0;
|
||||
renderChar.GlowTransition.Start(
|
||||
new Models.Keyframe<double>(targetCharGlow, stepDuration),
|
||||
new Models.Keyframe<double>(0, stepDuration)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
syllable.IsPlayingLastFrame = isSyllablePlaying;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var renderChar in line.PrimaryRenderChars)
|
||||
{
|
||||
renderChar.Update(elapsedTime);
|
||||
}
|
||||
}
|
||||
|
||||
line.AngleTransition.Update(elapsedTime);
|
||||
line.ScaleTransition.Update(elapsedTime);
|
||||
line.BlurAmountTransition.Update(elapsedTime);
|
||||
line.PhoneticOpacityTransition.Update(elapsedTime);
|
||||
line.PlayedOriginalOpacityTransition.Update(elapsedTime);
|
||||
line.UnplayedOriginalOpacityTransition.Update(elapsedTime);
|
||||
line.TranslatedOpacityTransition.Update(elapsedTime);
|
||||
line.YOffsetTransition.Update(elapsedTime);
|
||||
line.ColorTransition.Update(elapsedTime);
|
||||
line.Update(elapsedTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,52 +79,52 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
// 左上角坐标
|
||||
line.TopLeftPosition = new Vector2(0, (float)currentY);
|
||||
// 注音层
|
||||
line.PhoneticPosition = line.TopLeftPosition;
|
||||
if (line.PhoneticCanvasTextLayout != null)
|
||||
line.TertiaryPosition = line.TopLeftPosition;
|
||||
if (line.TertiaryTextLayout != null)
|
||||
{
|
||||
currentY += line.PhoneticCanvasTextLayout.LayoutBounds.Height;
|
||||
currentY += line.TertiaryTextLayout.LayoutBounds.Height;
|
||||
// 间距
|
||||
currentY += (line.PhoneticCanvasTextLayout.LayoutBounds.Height / line.PhoneticCanvasTextLayout.LineCount) * 0.1;
|
||||
currentY += (line.TertiaryTextLayout.LayoutBounds.Height / line.TertiaryTextLayout.LineCount) * 0.1;
|
||||
|
||||
actualWidth = Math.Max(actualWidth, line.PhoneticCanvasTextLayout.LayoutBounds.Width);
|
||||
actualWidth = Math.Max(actualWidth, line.TertiaryTextLayout.LayoutBounds.Width);
|
||||
}
|
||||
|
||||
// 原文层
|
||||
line.OriginalPosition = new Vector2(0, (float)currentY);
|
||||
if (line.OriginalCanvasTextLayout != null)
|
||||
line.PrimaryPosition = new Vector2(0, (float)currentY);
|
||||
if (line.PrimaryTextLayout != null)
|
||||
{
|
||||
currentY += line.OriginalCanvasTextLayout.LayoutBounds.Height;
|
||||
currentY += line.PrimaryTextLayout.LayoutBounds.Height;
|
||||
|
||||
actualWidth = Math.Max(actualWidth, line.OriginalCanvasTextLayout.LayoutBounds.Width);
|
||||
actualWidth = Math.Max(actualWidth, line.PrimaryTextLayout.LayoutBounds.Width);
|
||||
}
|
||||
|
||||
// 翻译层
|
||||
if (line.TranslatedCanvasTextLayout != null)
|
||||
if (line.SecondaryTextLayout != null)
|
||||
{
|
||||
// 间距
|
||||
currentY += (line.TranslatedCanvasTextLayout.LayoutBounds.Height / line.TranslatedCanvasTextLayout.LineCount) * 0.1;
|
||||
currentY += (line.SecondaryTextLayout.LayoutBounds.Height / line.SecondaryTextLayout.LineCount) * 0.1;
|
||||
}
|
||||
line.TranslatedPosition = new Vector2(0, (float)currentY);
|
||||
if (line.TranslatedCanvasTextLayout != null)
|
||||
line.SecondaryPosition = new Vector2(0, (float)currentY);
|
||||
if (line.SecondaryTextLayout != null)
|
||||
{
|
||||
currentY += line.TranslatedCanvasTextLayout.LayoutBounds.Height;
|
||||
currentY += line.SecondaryTextLayout.LayoutBounds.Height;
|
||||
|
||||
actualWidth = Math.Max(actualWidth, line.TranslatedCanvasTextLayout.LayoutBounds.Width);
|
||||
actualWidth = Math.Max(actualWidth, line.SecondaryTextLayout.LayoutBounds.Width);
|
||||
}
|
||||
|
||||
// 右下角坐标
|
||||
line.BottomRightPosition = new Vector2(0 + (float)actualWidth, (float)currentY);
|
||||
|
||||
// 行间距
|
||||
if (line.OriginalCanvasTextLayout != null)
|
||||
if (line.PrimaryTextLayout != null)
|
||||
{
|
||||
currentY += (line.OriginalCanvasTextLayout.LayoutBounds.Height / line.OriginalCanvasTextLayout.LineCount) * style.LyricsLineSpacingFactor;
|
||||
currentY += (line.PrimaryTextLayout.LayoutBounds.Height / line.PrimaryTextLayout.LineCount) * style.LyricsLineSpacingFactor;
|
||||
}
|
||||
|
||||
// 更新中心点
|
||||
line.UpdateCenterPosition(lyricsWidth, style.LyricsAlignmentType);
|
||||
|
||||
line.RecalculateCharacterGeometries();
|
||||
line.RecreateRenderChars();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,9 +140,9 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
var currentLine = lines.ElementAtOrDefault(playingLineIndex);
|
||||
var firstLine = lines.FirstOrDefault();
|
||||
|
||||
if (currentLine?.OriginalCanvasTextLayout == null || firstLine == null) return null;
|
||||
if (currentLine?.PrimaryTextLayout == null || firstLine == null) return null;
|
||||
|
||||
return -currentLine.OriginalPosition.Y + firstLine.OriginalPosition.Y
|
||||
return -currentLine.PrimaryPosition.Y + firstLine.PrimaryPosition.Y
|
||||
- (currentLine.BottomRightPosition.Y - currentLine.TopLeftPosition.Y) / 2.0;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
{
|
||||
int mid = (left + right) / 2;
|
||||
var line = lines[mid];
|
||||
if (line.OriginalCanvasTextLayout == null) break;
|
||||
if (line.PrimaryTextLayout == null) break;
|
||||
double value = offset + line.BottomRightPosition.Y;
|
||||
if (value >= mousePosition.Y) { result = mid; right = mid - 1; }
|
||||
else { left = mid + 1; }
|
||||
@@ -267,7 +267,7 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
{
|
||||
int mid = (left + right) / 2;
|
||||
var line = lines[mid];
|
||||
if (line.OriginalCanvasTextLayout == null) break;
|
||||
if (line.PrimaryTextLayout == null) break;
|
||||
double value = offset + line.BottomRightPosition.Y;
|
||||
// 理论上说应该使用下面这一行来精确计算视野内的首个可见行,但是考虑到动画视觉效果,还是注释掉了
|
||||
//if (value >= lyricsY) { result = mid; right = mid - 1; }
|
||||
@@ -284,7 +284,7 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
{
|
||||
int mid = (left + right) / 2;
|
||||
var line = lines[mid];
|
||||
if (line.OriginalCanvasTextLayout == null) break;
|
||||
if (line.PrimaryTextLayout == null) break;
|
||||
double value = offset + line.BottomRightPosition.Y;
|
||||
// 同理
|
||||
//if (value >= lyricsY + lyricsHeight) { result = mid; right = mid - 1; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Lyrics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -66,19 +67,14 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
|
||||
public LinePlaybackState GetLinePlayingProgress(
|
||||
double currentTimeMs,
|
||||
LyricsLine line,
|
||||
LyricsLine? nextLine,
|
||||
double songDurationMs,
|
||||
bool isForceWordByWord)
|
||||
RenderLyricsLine line,
|
||||
WordByWordEffectMode wordByWordEffectMode)
|
||||
{
|
||||
var state = new LinePlaybackState { SyllableStartIndex = 0, SyllableLength = 0, SyllableProgress = 0 };
|
||||
|
||||
if (line == null) return state;
|
||||
|
||||
double lineEndMs;
|
||||
if (line.EndMs != null) lineEndMs = line.EndMs.Value;
|
||||
else if (nextLine != null) lineEndMs = nextLine.StartMs;
|
||||
else lineEndMs = songDurationMs;
|
||||
double lineEndMs = line.EndMs ?? 0;
|
||||
|
||||
// 还没到
|
||||
if (currentTimeMs < line.StartMs) return state;
|
||||
@@ -87,42 +83,53 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
if (currentTimeMs > lineEndMs)
|
||||
{
|
||||
state.SyllableProgress = 1f;
|
||||
state.SyllableStartIndex = Math.Max(0, line.OriginalText.Length - 1);
|
||||
state.SyllableStartIndex = Math.Max(0, line.PrimaryText.Length - 1);
|
||||
state.SyllableLength = 1;
|
||||
return state;
|
||||
}
|
||||
|
||||
// 逐字
|
||||
if (line.LyricsSyllables != null && line.LyricsSyllables.Count > 1)
|
||||
switch (wordByWordEffectMode)
|
||||
{
|
||||
return CalculateSyllableProgress(currentTimeMs, line, lineEndMs);
|
||||
}
|
||||
|
||||
// 强制逐字
|
||||
if (isForceWordByWord && line.OriginalText.Length > 0)
|
||||
{
|
||||
return CalculateSimulatedProgress(currentTimeMs, line, lineEndMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 普通行
|
||||
state.SyllableStartIndex = line.OriginalText.Length;
|
||||
state.SyllableProgress = 1f;
|
||||
return state;
|
||||
case WordByWordEffectMode.Auto:
|
||||
if (line.IsPrimaryHasRealSyllableInfo)
|
||||
{
|
||||
return CalculateSyllableProgress(currentTimeMs, line, lineEndMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.SyllableStartIndex = line.PrimaryText.Length;
|
||||
state.SyllableProgress = 1f;
|
||||
return state;
|
||||
}
|
||||
case WordByWordEffectMode.Never:
|
||||
state.SyllableStartIndex = line.PrimaryText.Length;
|
||||
state.SyllableProgress = 1f;
|
||||
return state;
|
||||
case WordByWordEffectMode.Always:
|
||||
if (line.IsPrimaryHasRealSyllableInfo)
|
||||
{
|
||||
return CalculateSyllableProgress(currentTimeMs, line, lineEndMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CalculateSimulatedProgress(currentTimeMs, line, lineEndMs);
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
private LinePlaybackState CalculateSyllableProgress(double time, LyricsLine line, double lineEndMs)
|
||||
private LinePlaybackState CalculateSyllableProgress(double time, RenderLyricsLine line, double lineEndMs)
|
||||
{
|
||||
var state = new LinePlaybackState();
|
||||
int count = line.LyricsSyllables.Count;
|
||||
int count = line.PrimaryRenderSyllables.Count;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var timing = line.LyricsSyllables[i];
|
||||
var nextTiming = (i + 1 < count) ? line.LyricsSyllables[i + 1] : null;
|
||||
var timing = line.PrimaryRenderSyllables[i];
|
||||
var nextTiming = (i + 1 < count) ? line.PrimaryRenderSyllables[i + 1] : null;
|
||||
|
||||
double timingEndMs = timing.EndMs ?? nextTiming?.StartMs ?? lineEndMs;
|
||||
double timingEndMs = timing.EndMs ?? 0;
|
||||
|
||||
// 在当前字范围内
|
||||
if (time >= timing.StartMs && time <= timingEndMs)
|
||||
@@ -146,10 +153,10 @@ namespace BetterLyrics.WinUI3.Logic
|
||||
return state;
|
||||
}
|
||||
|
||||
private LinePlaybackState CalculateSimulatedProgress(double time, LyricsLine line, double lineEndMs)
|
||||
private LinePlaybackState CalculateSimulatedProgress(double time, RenderLyricsLine line, double lineEndMs)
|
||||
{
|
||||
var state = new LinePlaybackState();
|
||||
int textLength = line.OriginalText.Length;
|
||||
int textLength = line.PrimaryText.Length;
|
||||
|
||||
double progress = (time - line.StartMs) / (lineEndMs - line.StartMs);
|
||||
progress = Math.Clamp(progress, 0, 1);
|
||||
|
||||
18
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Keyframe.cs
Normal file
18
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Keyframe.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public struct Keyframe<T>
|
||||
{
|
||||
public T Value { get; }
|
||||
public double Duration { get; }
|
||||
|
||||
public Keyframe(T value, double durationSeconds)
|
||||
{
|
||||
Value = value;
|
||||
Duration = durationSeconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class BaseLyrics
|
||||
{
|
||||
public int StartMs { get; set; }
|
||||
public int? EndMs { get; set; } = null;
|
||||
public int DurationMs => Math.Max((EndMs ?? 0) - StartMs, 0);
|
||||
|
||||
public string Text { get; set; } = "";
|
||||
public int Length => Text.Length;
|
||||
|
||||
public int StartIndex { get; set; }
|
||||
public int EndIndex => StartIndex + Length - 1;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class BaseRenderLyrics : BaseLyrics
|
||||
{
|
||||
public bool IsPlayingLastFrame { get; set; } = false;
|
||||
|
||||
public BaseRenderLyrics(BaseLyrics baseLyrics)
|
||||
{
|
||||
this.Text = baseLyrics.Text;
|
||||
this.StartMs = baseLyrics.StartMs;
|
||||
this.EndMs = baseLyrics.EndMs;
|
||||
this.StartIndex = baseLyrics.StartIndex;
|
||||
}
|
||||
|
||||
public bool GetIsPlaying(double currentMs) => this.StartMs <= currentMs && currentMs < this.EndMs;
|
||||
public double GetPlayProgress(double currentMs) => Math.Clamp((currentMs - this.StartMs) / this.DurationMs, 0, 1);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class LyricsChar
|
||||
{
|
||||
public int StartMs { get; set; }
|
||||
public int EndMs { get; set; }
|
||||
public int DurationMs => EndMs - StartMs;
|
||||
|
||||
public string Text { get; set; } = "";
|
||||
public int Index { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,6 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class LyricsData
|
||||
{
|
||||
private static readonly ILocalizationService _localizationService = Ioc.Default.GetRequiredService<ILocalizationService>();
|
||||
|
||||
public List<LyricsLine> LyricsLines { get; set; } = [];
|
||||
public string? LanguageCode
|
||||
{
|
||||
@@ -18,7 +16,7 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
set => field = value;
|
||||
}
|
||||
public bool AutoGenerated { get; set; } = false;
|
||||
public string WrappedOriginalText => string.Join(StringHelper.NewLine, LyricsLines.Select(line => line.OriginalText));
|
||||
public string WrappedOriginalText => string.Join(StringHelper.NewLine, LyricsLines.Select(line => line.PrimaryText));
|
||||
|
||||
public LyricsData()
|
||||
{
|
||||
@@ -29,15 +27,5 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
LyricsLines = lyricsLines;
|
||||
}
|
||||
|
||||
public static LyricsData GetNotfoundPlaceholder()
|
||||
{
|
||||
return new LyricsData([new LyricsLine
|
||||
{
|
||||
StartMs = 0,
|
||||
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
|
||||
OriginalText = _localizationService.GetLocalizedString("LyricsNotFound"),
|
||||
}]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,51 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class LyricsLine
|
||||
public class LyricsLine : BaseLyrics
|
||||
{
|
||||
public List<LyricsSyllable> LyricsSyllables { get; set; } = [];
|
||||
public List<BaseLyrics> PrimarySyllables { get; set; } = [];
|
||||
public List<BaseLyrics> SecondarySyllables { get; set; } = [];
|
||||
public List<BaseLyrics> TertiarySyllables { get; set; } = [];
|
||||
|
||||
public int? DurationMs => EndMs - StartMs;
|
||||
public int? EndMs { get; set; }
|
||||
public int StartMs { get; set; }
|
||||
public List<BaseLyrics> PrimaryChars { get; private set; } = [];
|
||||
public List<BaseLyrics> SecondaryChars { get; private set; } = [];
|
||||
public List<BaseLyrics> TertiaryChars { get; private set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 原文
|
||||
/// </summary>
|
||||
public string OriginalText { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 译文
|
||||
/// </summary>
|
||||
public string TranslatedText { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 注音
|
||||
/// </summary>
|
||||
public string PhoneticText { get; set; } = "";
|
||||
public string PrimaryText { get; set; } = "";
|
||||
public string SecondaryText { get; set; } = "";
|
||||
public string TertiaryText { get; set; } = "";
|
||||
|
||||
public new string Text => PrimaryText;
|
||||
public new int StartIndex = 0;
|
||||
|
||||
public bool IsPrimaryHasRealSyllableInfo { get; set; } = false;
|
||||
|
||||
public LyricsLine()
|
||||
{
|
||||
for (int charStartIndex = 0; charStartIndex < PrimaryText.Length; charStartIndex++)
|
||||
{
|
||||
var syllable = PrimarySyllables.FirstOrDefault(x => x.StartIndex <= charStartIndex && charStartIndex <= x.EndIndex);
|
||||
if (syllable == null) continue;
|
||||
|
||||
var avgCharDuration = syllable.DurationMs / syllable.Length;
|
||||
if (avgCharDuration == 0) continue;
|
||||
|
||||
var charStartMs = syllable.StartMs + (charStartIndex - syllable.StartIndex) * avgCharDuration;
|
||||
var charEndMs = charStartMs + avgCharDuration;
|
||||
|
||||
PrimaryChars.Add(new BaseLyrics
|
||||
{
|
||||
StartIndex = charStartIndex,
|
||||
StartMs = charStartMs,
|
||||
EndMs = charEndMs,
|
||||
Text = PrimaryText[charStartIndex].ToString()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class LyricsSyllable
|
||||
{
|
||||
public string Text { get; set; } = string.Empty;
|
||||
public int Length => Text.Length;
|
||||
|
||||
public int StartIndex { get; set; }
|
||||
public int EndIndex => StartIndex + Length - 1;
|
||||
|
||||
public int StartMs { get; set; }
|
||||
public int? EndMs { get; set; }
|
||||
|
||||
public int? DurationMs => EndMs - StartMs;
|
||||
public bool IsLongDuration => DurationMs >= 700;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Constants;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using System;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class RenderLyricsChar : LyricsChar
|
||||
public class RenderLyricsChar : BaseRenderLyrics
|
||||
{
|
||||
public Rect LayoutRect { get; set; }
|
||||
|
||||
public double AnimationDuration { get; set; } = 0.3;
|
||||
public Rect LayoutRect { get; private set; }
|
||||
|
||||
public ValueTransition<double> ScaleTransition { get; set; }
|
||||
public ValueTransition<double> GlowTransition { get; set; }
|
||||
@@ -16,25 +16,32 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
|
||||
public double ProgressPlayed { get; set; } = 0; // 0~1
|
||||
|
||||
public bool IsPlayingLastFrame { get; set; } = false;
|
||||
|
||||
public RenderLyricsChar()
|
||||
public RenderLyricsChar(BaseLyrics lyricsChars, Rect layoutRect) : base(lyricsChars)
|
||||
{
|
||||
ScaleTransition = new(
|
||||
initialValue: 1.0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: Time.AnimationDuration.TotalSeconds
|
||||
);
|
||||
GlowTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: Time.AnimationDuration.TotalSeconds
|
||||
);
|
||||
FloatTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: Time.LongAnimationDuration.TotalSeconds
|
||||
);
|
||||
LayoutRect = layoutRect;
|
||||
}
|
||||
|
||||
public void Update(TimeSpan elapsedTime)
|
||||
{
|
||||
ScaleTransition.Update(elapsedTime);
|
||||
GlowTransition.Update(elapsedTime);
|
||||
FloatTransition.Update(elapsedTime);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.Graphics.Canvas.Geometry;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using Microsoft.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
@@ -12,9 +13,10 @@ using Windows.UI;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class RenderLyricsLine : LyricsLine
|
||||
public class RenderLyricsLine : BaseRenderLyrics
|
||||
{
|
||||
public List<RenderLyricsChar> RenderLyricsOriginalChars { get; set; } = [];
|
||||
public List<RenderLyricsChar> PrimaryRenderChars { get; private set; } = [];
|
||||
public List<RenderLyricsSyllable> PrimaryRenderSyllables { get; private set; }
|
||||
|
||||
public double AnimationDuration { get; set; } = 0.3;
|
||||
|
||||
@@ -28,22 +30,22 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
public ValueTransition<double> YOffsetTransition { get; set; }
|
||||
public ValueTransition<Color> ColorTransition { get; set; }
|
||||
|
||||
public CanvasTextLayout? OriginalCanvasTextLayout { get; private set; }
|
||||
public CanvasTextLayout? TranslatedCanvasTextLayout { get; private set; }
|
||||
public CanvasTextLayout? PhoneticCanvasTextLayout { get; private set; }
|
||||
public CanvasTextLayout? PrimaryTextLayout { get; private set; }
|
||||
public CanvasTextLayout? SecondaryTextLayout { get; private set; }
|
||||
public CanvasTextLayout? TertiaryTextLayout { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原文坐标(相对于坐标原点)
|
||||
/// </summary>
|
||||
public Vector2 OriginalPosition { get; set; }
|
||||
public Vector2 PrimaryPosition { get; set; }
|
||||
/// <summary>
|
||||
/// 译文坐标(相对于坐标原点)
|
||||
/// </summary>
|
||||
public Vector2 TranslatedPosition { get; set; }
|
||||
public Vector2 SecondaryPosition { get; set; }
|
||||
/// <summary>
|
||||
/// 注音坐标(相对于坐标原点)
|
||||
/// </summary>
|
||||
public Vector2 PhoneticPosition { get; set; }
|
||||
public Vector2 TertiaryPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 顶部坐标(相对于坐标原点)
|
||||
@@ -58,72 +60,84 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
/// </summary>
|
||||
public Vector2 BottomRightPosition { get; set; }
|
||||
|
||||
public CanvasGeometry? OriginalCanvasGeometry { get; private set; }
|
||||
public CanvasGeometry? TranslatedCanvasGeometry { get; private set; }
|
||||
public CanvasGeometry? PhoneticCanvasGeometry { get; private set; }
|
||||
public CanvasGeometry? PrimaryCanvasGeometry { get; private set; }
|
||||
public CanvasGeometry? SecondaryCanvasGeometry { get; private set; }
|
||||
public CanvasGeometry? TertiaryCanvasGeometry { get; private set; }
|
||||
|
||||
public string PrimaryText { get; set; } = "";
|
||||
public string SecondaryText { get; set; } = "";
|
||||
public string TertiaryText { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 轨道索引 (0 = 主轨道, 1 = 第一副轨道, etc.)
|
||||
/// 用于布局计算时的堆叠逻辑
|
||||
/// </summary>
|
||||
public int LaneIndex { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 是否为背景人声/和声
|
||||
/// </summary>
|
||||
public bool IsPlayingLastFrame { get; set; } = false;
|
||||
|
||||
public RenderLyricsLine()
|
||||
public double? PrimaryLineHeight => PrimaryRenderChars.FirstOrDefault()?.LayoutRect.Height;
|
||||
|
||||
public bool IsPrimaryHasRealSyllableInfo { get; set; }
|
||||
|
||||
public RenderLyricsLine(LyricsLine lyricsLine) : base(lyricsLine)
|
||||
{
|
||||
AngleTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
BlurAmountTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
PhoneticOpacityTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
PlayedOriginalOpacityTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
UnplayedOriginalOpacityTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
TranslatedOpacityTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
ScaleTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
YOffsetTransition = new(
|
||||
initialValue: 0,
|
||||
durationSeconds: AnimationDuration,
|
||||
easingType: EasingType.EaseInOutSine
|
||||
EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Sine),
|
||||
defaultTotalDuration: AnimationDuration
|
||||
);
|
||||
ColorTransition = new(
|
||||
initialValue: Colors.Transparent,
|
||||
durationSeconds: 0.3f,
|
||||
defaultTotalDuration: 0.3f,
|
||||
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
|
||||
);
|
||||
|
||||
StartMs = lyricsLine.StartMs;
|
||||
EndMs = lyricsLine.EndMs;
|
||||
TertiaryText = lyricsLine.TertiaryText;
|
||||
PrimaryText = lyricsLine.PrimaryText;
|
||||
SecondaryText = lyricsLine.SecondaryText;
|
||||
PrimaryRenderSyllables = lyricsLine.PrimarySyllables.Select(x => new RenderLyricsSyllable(x)).ToList();
|
||||
IsPrimaryHasRealSyllableInfo = lyricsLine.IsPrimaryHasRealSyllableInfo;
|
||||
}
|
||||
|
||||
public void UpdateCenterPosition(double maxWidth, TextAlignmentType type)
|
||||
{
|
||||
if (OriginalCanvasTextLayout == null)
|
||||
if (PrimaryTextLayout == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -141,14 +155,14 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
|
||||
public void DisposeTextLayout()
|
||||
{
|
||||
PhoneticCanvasTextLayout?.Dispose();
|
||||
PhoneticCanvasTextLayout = null;
|
||||
TertiaryTextLayout?.Dispose();
|
||||
TertiaryTextLayout = null;
|
||||
|
||||
OriginalCanvasTextLayout?.Dispose();
|
||||
OriginalCanvasTextLayout = null;
|
||||
PrimaryTextLayout?.Dispose();
|
||||
PrimaryTextLayout = null;
|
||||
|
||||
TranslatedCanvasTextLayout?.Dispose();
|
||||
TranslatedCanvasTextLayout = null;
|
||||
SecondaryTextLayout?.Dispose();
|
||||
SecondaryTextLayout = null;
|
||||
}
|
||||
|
||||
public void RecreateTextLayout(
|
||||
@@ -161,9 +175,9 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
DisposeTextLayout();
|
||||
|
||||
if (createPhonetic && PhoneticText != "")
|
||||
if (createPhonetic && TertiaryText != "")
|
||||
{
|
||||
PhoneticCanvasTextLayout = new CanvasTextLayout(control, PhoneticText, new CanvasTextFormat
|
||||
TertiaryTextLayout = new CanvasTextLayout(control, TertiaryText, new CanvasTextFormat
|
||||
{
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Left,
|
||||
VerticalAlignment = CanvasVerticalAlignment.Top,
|
||||
@@ -173,10 +187,10 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
HorizontalAlignment = type.ToCanvasHorizontalAlignment(),
|
||||
};
|
||||
PhoneticCanvasTextLayout.SetFontFamily(PhoneticText, fontFamilyCJK, fontFamilyWestern);
|
||||
TertiaryTextLayout.SetFontFamily(TertiaryText, fontFamilyCJK, fontFamilyWestern);
|
||||
}
|
||||
|
||||
OriginalCanvasTextLayout = new CanvasTextLayout(control, OriginalText, new CanvasTextFormat
|
||||
PrimaryTextLayout = new CanvasTextLayout(control, PrimaryText, new CanvasTextFormat
|
||||
{
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Left,
|
||||
VerticalAlignment = CanvasVerticalAlignment.Top,
|
||||
@@ -186,11 +200,11 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
HorizontalAlignment = type.ToCanvasHorizontalAlignment()
|
||||
};
|
||||
OriginalCanvasTextLayout.SetFontFamily(OriginalText, fontFamilyCJK, fontFamilyWestern);
|
||||
PrimaryTextLayout.SetFontFamily(PrimaryText, fontFamilyCJK, fontFamilyWestern);
|
||||
|
||||
if (createTranslated && TranslatedText != "")
|
||||
if (createTranslated && SecondaryText != "")
|
||||
{
|
||||
TranslatedCanvasTextLayout = new CanvasTextLayout(control, TranslatedText, new CanvasTextFormat
|
||||
SecondaryTextLayout = new CanvasTextLayout(control, SecondaryText, new CanvasTextFormat
|
||||
{
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Left,
|
||||
VerticalAlignment = CanvasVerticalAlignment.Top,
|
||||
@@ -200,62 +214,92 @@ namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
HorizontalAlignment = type.ToCanvasHorizontalAlignment()
|
||||
};
|
||||
TranslatedCanvasTextLayout.SetFontFamily(TranslatedText, fontFamilyCJK, fontFamilyWestern);
|
||||
SecondaryTextLayout.SetFontFamily(SecondaryText, fontFamilyCJK, fontFamilyWestern);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisposeTextGeometry()
|
||||
{
|
||||
PhoneticCanvasGeometry?.Dispose();
|
||||
PhoneticCanvasGeometry = null;
|
||||
TertiaryCanvasGeometry?.Dispose();
|
||||
TertiaryCanvasGeometry = null;
|
||||
|
||||
OriginalCanvasGeometry?.Dispose();
|
||||
OriginalCanvasGeometry = null;
|
||||
PrimaryCanvasGeometry?.Dispose();
|
||||
PrimaryCanvasGeometry = null;
|
||||
|
||||
TranslatedCanvasGeometry?.Dispose();
|
||||
TranslatedCanvasGeometry = null;
|
||||
SecondaryCanvasGeometry?.Dispose();
|
||||
SecondaryCanvasGeometry = null;
|
||||
}
|
||||
|
||||
public void RecreateTextGeometry()
|
||||
{
|
||||
DisposeTextGeometry();
|
||||
|
||||
if (PhoneticCanvasTextLayout != null)
|
||||
if (TertiaryTextLayout != null)
|
||||
{
|
||||
PhoneticCanvasGeometry = CanvasGeometry.CreateText(PhoneticCanvasTextLayout);
|
||||
TertiaryCanvasGeometry = CanvasGeometry.CreateText(TertiaryTextLayout);
|
||||
}
|
||||
|
||||
if (OriginalCanvasTextLayout != null)
|
||||
if (PrimaryTextLayout != null)
|
||||
{
|
||||
OriginalCanvasGeometry = CanvasGeometry.CreateText(OriginalCanvasTextLayout);
|
||||
PrimaryCanvasGeometry = CanvasGeometry.CreateText(PrimaryTextLayout);
|
||||
}
|
||||
|
||||
if (TranslatedCanvasTextLayout != null)
|
||||
if (SecondaryTextLayout != null)
|
||||
{
|
||||
TranslatedCanvasGeometry = CanvasGeometry.CreateText(TranslatedCanvasTextLayout);
|
||||
SecondaryCanvasGeometry = CanvasGeometry.CreateText(SecondaryTextLayout);
|
||||
}
|
||||
}
|
||||
|
||||
public void RecalculateCharacterGeometries()
|
||||
public void RecreateRenderChars()
|
||||
{
|
||||
RenderLyricsOriginalChars.Clear();
|
||||
if (OriginalCanvasTextLayout == null) return;
|
||||
PrimaryRenderChars.Clear();
|
||||
if (PrimaryTextLayout == null) return;
|
||||
|
||||
var textLength = OriginalText.Length;
|
||||
|
||||
for (int i = 0; i < textLength; i++)
|
||||
foreach (var syllable in PrimaryRenderSyllables)
|
||||
{
|
||||
var region = OriginalCanvasTextLayout.GetCharacterRegions(i, 1).FirstOrDefault();
|
||||
syllable.ChildrenRenderLyricsChars.Clear();
|
||||
}
|
||||
|
||||
var textLength = PrimaryText.Length;
|
||||
|
||||
for (int startCharIndex = 0; startCharIndex < textLength; startCharIndex++)
|
||||
{
|
||||
var region = PrimaryTextLayout.GetCharacterRegions(startCharIndex, 1).FirstOrDefault();
|
||||
var bounds = region.LayoutBounds;
|
||||
|
||||
RenderLyricsOriginalChars.Add(new RenderLyricsChar()
|
||||
var syllable = PrimaryRenderSyllables.FirstOrDefault(x => x.StartIndex <= startCharIndex && startCharIndex <= x.EndIndex);
|
||||
if (syllable == null) continue;
|
||||
|
||||
var avgCharDuration = syllable.DurationMs / syllable.Length;
|
||||
var charStartMs = syllable.StartMs + (startCharIndex - syllable.StartIndex) * avgCharDuration;
|
||||
var charEndMs = charStartMs + avgCharDuration;
|
||||
|
||||
var renderLyricsChar = new RenderLyricsChar(new BaseLyrics
|
||||
{
|
||||
Index = i,
|
||||
LayoutRect = bounds,
|
||||
Text = OriginalText[i].ToString()
|
||||
});
|
||||
StartIndex = startCharIndex,
|
||||
Text = PrimaryText[startCharIndex].ToString(),
|
||||
StartMs = charStartMs,
|
||||
EndMs = charEndMs,
|
||||
}, bounds);
|
||||
|
||||
syllable.ChildrenRenderLyricsChars.Add(renderLyricsChar);
|
||||
|
||||
PrimaryRenderChars.Add(renderLyricsChar);
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(TimeSpan elapsedTime)
|
||||
{
|
||||
AngleTransition.Update(elapsedTime);
|
||||
ScaleTransition.Update(elapsedTime);
|
||||
BlurAmountTransition.Update(elapsedTime);
|
||||
PhoneticOpacityTransition.Update(elapsedTime);
|
||||
PlayedOriginalOpacityTransition.Update(elapsedTime);
|
||||
UnplayedOriginalOpacityTransition.Update(elapsedTime);
|
||||
TranslatedOpacityTransition.Update(elapsedTime);
|
||||
YOffsetTransition.Update(elapsedTime);
|
||||
ColorTransition.Update(elapsedTime);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Lyrics
|
||||
{
|
||||
public class RenderLyricsSyllable : BaseRenderLyrics
|
||||
{
|
||||
public List<RenderLyricsChar> ChildrenRenderLyricsChars { get; set; } = [];
|
||||
|
||||
public RenderLyricsSyllable(BaseLyrics lyricsSyllable) : base(lyricsSyllable) { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using BetterLyrics.Core.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public class PluginDisplayModel
|
||||
{
|
||||
public IPlugin Plugin { get; }
|
||||
|
||||
public string Name => Plugin.Name;
|
||||
public string Description => Plugin.Description;
|
||||
public string Id => Plugin.Id;
|
||||
public string Author => Plugin.Author;
|
||||
public string Version => "v1.0.0"; // 如果您的接口有 Version 字段就读接口的
|
||||
|
||||
public string Glyph => !string.IsNullOrEmpty(Name) ? Name.Substring(0, 1) : "?";
|
||||
|
||||
public PluginDisplayModel(IPlugin plugin)
|
||||
{
|
||||
Plugin = plugin;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LanguageCode { get; set; } = "";
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LXMusicServer { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string AmllTtmlDbBaseUrl { get; set; } = Constants.AmllTTmlDB.BaseUrl;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsForceWordByWordEffect { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ShowOrHideLyricsWindowShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "H" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ExitOnLyricsWindowClosed { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ListenOnNewPlaybackSource { get; set; } = true;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using static BetterLyrics.WinUI3.Helper.EasingHelper;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class LyricsEffectSettings : ObservableRecipient, ICloneable
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial WordByWordEffectMode WordByWordEffectMode { get; set; } = WordByWordEffectMode.Auto;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsBlurEffectEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFadeOutEffectEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsOutOfSightEffectEnabled { get; set; } = true;
|
||||
@@ -24,8 +27,10 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationAmountAutoAdjust { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFloatAnimationAmount { get; set; } = 8;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFloatAnimationDuration { get; set; } = 450; // 450ms
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial EasingType LyricsScrollEasingType { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial EaseMode LyricsScrollEasingMode { get; set; } = EaseMode.Out;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollDuration { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollTopDuration { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollBottomDuration { get; set; }
|
||||
@@ -53,6 +58,8 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
return new LyricsEffectSettings(this.LyricsScrollTopDuration, this.LyricsScrollDuration, this.LyricsScrollBottomDuration, this.LyricsScrollEasingType)
|
||||
{
|
||||
WordByWordEffectMode = this.WordByWordEffectMode,
|
||||
|
||||
IsLyricsBlurEffectEnabled = this.IsLyricsBlurEffectEnabled,
|
||||
IsLyricsFadeOutEffectEnabled = this.IsLyricsFadeOutEffectEnabled,
|
||||
IsLyricsOutOfSightEffectEnabled = this.IsLyricsOutOfSightEffectEnabled,
|
||||
@@ -71,8 +78,10 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
IsLyricsFloatAnimationEnabled = this.IsLyricsFloatAnimationEnabled,
|
||||
IsLyricsFloatAnimationAmountAutoAdjust = this.IsLyricsFloatAnimationAmountAutoAdjust,
|
||||
LyricsFloatAnimationAmount = this.LyricsFloatAnimationAmount,
|
||||
LyricsFloatAnimationDuration = this.LyricsFloatAnimationDuration,
|
||||
|
||||
LyricsScrollEasingType = this.LyricsScrollEasingType,
|
||||
LyricsScrollEasingMode = this.LyricsScrollEasingMode,
|
||||
LyricsScrollDuration = this.LyricsScrollDuration,
|
||||
LyricsScrollTopDuration = this.LyricsScrollTopDuration,
|
||||
LyricsScrollBottomDuration = this.LyricsScrollBottomDuration,
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsSearchProvider Provider { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsMatchingThresholdOverwritten { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int MatchingThreshold { get; set; } = 40;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IgnoreCacheWhenSearching { get; set; } = false;
|
||||
|
||||
public LyricsSearchProviderInfo() { }
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty] public partial Rect DemoMonitorBounds { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial DockPlacement DockPlacement { get; set; } = DockPlacement.Top;
|
||||
[ObservableProperty] public partial LyricsStyleSettings LyricsStyleSettings { get; set; } = new();
|
||||
[ObservableProperty] public partial LyricsEffectSettings LyricsEffectSettings { get; set; } = new(500, 500, 500, EasingType.EaseInOutQuad);
|
||||
[ObservableProperty] public partial LyricsEffectSettings LyricsEffectSettings { get; set; } = new(500, 500, 500, EasingType.Quad);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsBackgroundSettings LyricsBackgroundSettings { get; set; } = new();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial AlbumArtAreaStyleSettings AlbumArtLayoutSettings { get; set; } = new();
|
||||
[ObservableProperty] public partial AlbumArtAreaEffectSettings AlbumArtAreaEffectSettings { get; set; } = new();
|
||||
|
||||
@@ -13,7 +13,6 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial ChineseRomanization ChineseRomanization { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsChineseRomanizationEnabled { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsJapaneseRomanizationEnabled { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string CutletDockerServer { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsTraditionalChineseEnabled { get; set; } = false;
|
||||
|
||||
public TranslationSettings() { }
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var matches = syllableRegex.Matches(line);
|
||||
var syllables = new List<LyricsSyllable>();
|
||||
var syllables = new List<BaseLyrics>();
|
||||
|
||||
int startIndex = 0;
|
||||
for (int i = 0; i < matches.Count; i++)
|
||||
@@ -36,30 +36,18 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
int totalMs = min * 60_000 + sec * 1000 + ms;
|
||||
string text = match.Groups[6].Value;
|
||||
|
||||
syllables.Add(new LyricsSyllable { StartMs = totalMs, Text = text, StartIndex = startIndex });
|
||||
syllables.Add(new BaseLyrics { StartMs = totalMs, Text = text, StartIndex = startIndex });
|
||||
startIndex += text.Length;
|
||||
}
|
||||
|
||||
int lineEndMs = 0;
|
||||
|
||||
if (syllables.Count > 0)
|
||||
{
|
||||
var lastSyllable = syllables[syllables.Count - 1];
|
||||
if (string.IsNullOrWhiteSpace(lastSyllable.Text))
|
||||
{
|
||||
lineEndMs = lastSyllable.StartMs;
|
||||
syllables.RemoveAt(syllables.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (syllables.Count > 0)
|
||||
if (syllables.Count > 1)
|
||||
{
|
||||
lrcLines.Add(new LyricsLine
|
||||
{
|
||||
StartMs = syllables[0].StartMs,
|
||||
EndMs = lineEndMs,
|
||||
OriginalText = string.Concat(syllables.Select(s => s.Text)),
|
||||
LyricsSyllables = syllables
|
||||
PrimaryText = string.Concat(syllables.Select(s => s.Text)),
|
||||
PrimarySyllables = syllables,
|
||||
IsPrimaryHasRealSyllableInfo = true
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -81,7 +69,13 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
content = bracketRegex!.Replace(line, "").Trim();
|
||||
if (content == "//") content = "";
|
||||
|
||||
lrcLines.Add(new LyricsLine { StartMs = lineStartMs, OriginalText = content });
|
||||
var lyricsLine = new LyricsLine
|
||||
{
|
||||
StartMs = lineStartMs,
|
||||
PrimaryText = content,
|
||||
IsPrimaryHasRealSyllableInfo = false
|
||||
};
|
||||
lrcLines.Add(lyricsLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,5 +119,6 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
for (int lineIndex = 0; lineIndex < lines.Count; lineIndex++)
|
||||
{
|
||||
var lineRead = lines[lineIndex];
|
||||
var nextLineRead = lines.ElementAtOrDefault(lineIndex + 1);
|
||||
var lineWrite = new LyricsLine
|
||||
{
|
||||
StartMs = lineRead.StartTime ?? 0,
|
||||
EndMs = lineRead.EndTime ?? 0,
|
||||
OriginalText = lineRead.Text,
|
||||
LyricsSyllables = [],
|
||||
PrimaryText = lineRead.Text,
|
||||
IsPrimaryHasRealSyllableInfo = true,
|
||||
};
|
||||
|
||||
var syllables = (lineRead as Lyricify.Lyrics.Models.SyllableLineInfo)?.Syllables;
|
||||
@@ -36,14 +36,14 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
)
|
||||
{
|
||||
var syllable = syllables[syllableIndex];
|
||||
var charTiming = new LyricsSyllable
|
||||
var charTiming = new BaseLyrics
|
||||
{
|
||||
StartMs = syllable.StartTime,
|
||||
EndMs = syllable.EndTime,
|
||||
Text = syllable.Text,
|
||||
StartIndex = startIndex,
|
||||
};
|
||||
lineWrite.LyricsSyllables.Add(charTiming);
|
||||
lineWrite.PrimarySyllables.Add(charTiming);
|
||||
startIndex += syllable.Text.Length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
}
|
||||
}
|
||||
|
||||
var syllables = new List<LyricsSyllable>();
|
||||
var syllables = new List<BaseLyrics>();
|
||||
int startIndex = 0;
|
||||
var sbText = new System.Text.StringBuilder();
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
int sEndMs = ParseTtmlTime(span.Attribute("end")?.Value);
|
||||
string text = span.Value;
|
||||
|
||||
syllables.Add(new LyricsSyllable
|
||||
syllables.Add(new BaseLyrics
|
||||
{
|
||||
StartMs = sStartMs,
|
||||
EndMs = sEndMs,
|
||||
@@ -126,8 +126,9 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
{
|
||||
StartMs = containerStartMs,
|
||||
EndMs = containerEndMs,
|
||||
OriginalText = fullOriginalText,
|
||||
LyricsSyllables = syllables
|
||||
PrimaryText = fullOriginalText,
|
||||
PrimarySyllables = syllables,
|
||||
IsPrimaryHasRealSyllableInfo = true,
|
||||
});
|
||||
|
||||
var transSpan = container.Elements()
|
||||
@@ -151,7 +152,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
{
|
||||
StartMs = startMs,
|
||||
EndMs = endMs,
|
||||
OriginalText = text
|
||||
PrimaryText = text,
|
||||
IsPrimaryHasRealSyllableInfo = false,
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -160,7 +162,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
{
|
||||
StartMs = startMs,
|
||||
EndMs = endMs,
|
||||
OriginalText = ""
|
||||
PrimaryText = "",
|
||||
IsPrimaryHasRealSyllableInfo = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
LoadTransliteration(lyricsSearchResult);
|
||||
GenerateTransliterationLyricsData();
|
||||
|
||||
EnsureEndMs(lyricsSearchResult?.Duration);
|
||||
EnsureSyllables();
|
||||
|
||||
return _lyricsDataArr;
|
||||
}
|
||||
|
||||
@@ -126,7 +129,7 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
{
|
||||
romaji = await transliterationService.TransliterateText(main.WrappedOriginalText, PhoneticHelper.RomanCode, token);
|
||||
_lyricsDataArr.FirstOrDefault()?.SetTransliteration(romaji);
|
||||
transliterationSearchProvider = TransliterationSearchProvider.CutletDocker;
|
||||
transliterationSearchProvider = TransliterationSearchProvider.Plugin;
|
||||
}
|
||||
catch (TaskCanceledException) { }
|
||||
catch (Exception)
|
||||
@@ -167,14 +170,14 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
{
|
||||
foreach (var item in main.LyricsLines)
|
||||
{
|
||||
item.OriginalText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.OriginalText) : ChineseHelper.ToSC(item.OriginalText);
|
||||
item.PrimaryText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.PrimaryText) : ChineseHelper.ToSC(item.PrimaryText);
|
||||
}
|
||||
}
|
||||
if (settings.SelectedTargetLanguageCode == LanguageHelper.ChineseCode)
|
||||
{
|
||||
foreach (var item in main.LyricsLines)
|
||||
{
|
||||
item.TranslatedText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.TranslatedText) : ChineseHelper.ToSC(item.TranslatedText);
|
||||
item.SecondaryText = settings.IsTraditionalChineseEnabled ? ChineseHelper.ToTC(item.SecondaryText) : ChineseHelper.ToSC(item.SecondaryText);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,8 +238,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = PhoneticHelper.ToPinyin(line.OriginalText),
|
||||
LyricsSyllables = line.LyricsSyllables.Select(c => new LyricsSyllable
|
||||
PrimaryText = PhoneticHelper.ToPinyin(line.PrimaryText),
|
||||
PrimarySyllables = line.PrimarySyllables.Select(c => new BaseLyrics
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
@@ -256,8 +259,8 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = PhoneticHelper.ToJyutping(line.OriginalText),
|
||||
LyricsSyllables = line.LyricsSyllables.Select(c => new LyricsSyllable
|
||||
PrimaryText = PhoneticHelper.ToJyutping(line.PrimaryText),
|
||||
PrimarySyllables = line.PrimarySyllables.Select(c => new BaseLyrics
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
@@ -271,5 +274,84 @@ namespace BetterLyrics.WinUI3.Parsers.LyricsParser
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureEndMs(double? duration)
|
||||
{
|
||||
foreach (var lyricsData in _lyricsDataArr)
|
||||
{
|
||||
var lines = lyricsData.LyricsLines;
|
||||
// 计算结束时间
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
{
|
||||
// 计算行结束时间
|
||||
if (lines[i].EndMs == null)
|
||||
{
|
||||
if (i + 1 < lines.Count)
|
||||
{
|
||||
lines[i].EndMs = lines[i + 1].StartMs;
|
||||
}
|
||||
else
|
||||
{
|
||||
lines[i].EndMs = (int)(duration ?? 0) * 1000;
|
||||
}
|
||||
}
|
||||
// 计算音节结束时间
|
||||
for (int j = 0; j < lines[i].PrimarySyllables.Count; j++)
|
||||
{
|
||||
var syllable = lines[i].PrimarySyllables[j];
|
||||
if (syllable.EndMs == null)
|
||||
{
|
||||
if (j < lines[i].PrimarySyllables.Count - 1)
|
||||
{
|
||||
syllable.EndMs = lines[i].PrimarySyllables[j + 1].StartMs;
|
||||
}
|
||||
else
|
||||
{
|
||||
syllable.EndMs = lines[i].EndMs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke this after <see cref="EnsureEndMs"/>
|
||||
/// </summary>
|
||||
private void EnsureSyllables()
|
||||
{
|
||||
foreach (var lyricsData in _lyricsDataArr)
|
||||
{
|
||||
if (lyricsData == null) continue;
|
||||
|
||||
var lines = lyricsData.LyricsLines;
|
||||
if (lines == null) continue;
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line == null) continue;
|
||||
if (line.IsPrimaryHasRealSyllableInfo) continue;
|
||||
if (line.PrimarySyllables.Count > 0) continue;
|
||||
|
||||
var content = line.PrimaryText;
|
||||
var length = content.Length;
|
||||
if (length == 0) continue;
|
||||
|
||||
var avgSyllableDuration = line.DurationMs / length;
|
||||
if (avgSyllableDuration == 0) continue;
|
||||
|
||||
for (int j = 0; j < length; j++)
|
||||
{
|
||||
line.PrimarySyllables.Add(new BaseLyrics
|
||||
{
|
||||
Text = content[j].ToString(),
|
||||
StartIndex = j,
|
||||
StartMs = line.StartMs + avgSyllableDuration * j,
|
||||
EndMs = line.StartMs + avgSyllableDuration * (j + 1),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
<linker>
|
||||
<assembly fullname="Microsoft.Extensions.Logging.Abstractions" preserve="all" />
|
||||
<assembly fullname="System.Collections" preserve="all" />
|
||||
<assembly fullname="System.Collections.Concurrent" preserve="all" />
|
||||
<assembly fullname="System.ComponentModel" preserve="all" />
|
||||
<assembly fullname="System.ComponentModel.Annotations" preserve="all" />
|
||||
<assembly fullname="System.ComponentModel.Primitives" preserve="all" />
|
||||
<assembly fullname="System.Diagnostics.Process" preserve="all" />
|
||||
<assembly fullname="System.Drawing.Primitives" preserve="all" />
|
||||
<assembly fullname="System.IO.MemoryMappedFiles" preserve="all" />
|
||||
<assembly fullname="System.Linq" preserve="all" />
|
||||
<assembly fullname="System.Memory" preserve="all" />
|
||||
<assembly fullname="System.Net.Http" preserve="all" />
|
||||
<assembly fullname="System.Net.Mail" preserve="all" />
|
||||
<assembly fullname="System.Numerics.Tensors" preserve="all" />
|
||||
<assembly fullname="System.Numerics.Vectors" preserve="all" />
|
||||
<assembly fullname="System.Runtime" preserve="all" />
|
||||
<assembly fullname="System.Runtime.InteropServices" preserve="all" />
|
||||
<assembly fullname="System.Runtime.Intrinsics" preserve="all" />
|
||||
<assembly fullname="System.Security.Cryptography" preserve="all" />
|
||||
<assembly fullname="System.Text.Encodings.Web" preserve="all" />
|
||||
<assembly fullname="System.Text.Json" preserve="all" />
|
||||
<assembly fullname="System.Text.RegularExpressions" preserve="all" />
|
||||
<assembly fullname="System.Threading" preserve="all" />
|
||||
<assembly fullname="System.Threading.Tasks.Parallel" preserve="all" />
|
||||
<assembly fullname="BetterLyrics.WinUI3">
|
||||
<type fullname="BetterLyrics.WinUI3.PluginConfigs.BetterLyrics_Plugins_AI_Config" preserve="all" />
|
||||
</assembly>
|
||||
</linker>
|
||||
@@ -0,0 +1,415 @@
|
||||
// Auto-Generated by PluginAnalyzer
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace BetterLyrics.WinUI3.PluginConfigs;
|
||||
internal static class BetterLyrics_Plugins_AI_Config
|
||||
{
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Microsoft.Win32.SafeHandles.SafeMemoryMappedViewHandle))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Action<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Action<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AppContext))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AppDomain))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArgumentException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArgumentNullException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArgumentOutOfRangeException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Array))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArraySegment<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArrayTypeMismatchException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AsyncCallback))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Attribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AttributeTargets))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AttributeUsageAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Base64FormattingOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Boolean))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffer))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.ArrayPool<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.Binary.BinaryPrimitives))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.IBufferWriter<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.IMemoryOwner<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.IPinnable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.MemoryHandle))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.MemoryManager<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.ReadOnlySequence<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.ReadOnlySequence<>.Enumerator))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.SearchValues))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.SearchValues<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffers.Text.Base64))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Byte))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Char))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.CLSCompliantAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.CodeDom.Compiler.GeneratedCodeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.BitArray))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Concurrent.ConcurrentDictionary<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.Dictionary<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.Dictionary<,>.Enumerator))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.Dictionary<,>.KeyCollection))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.Dictionary<,>.ValueCollection))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.EqualityComparer<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.HashSet<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.HashSet<>.Enumerator))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IAsyncEnumerable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IAsyncEnumerator<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.ICollection<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IComparer<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IDictionary<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IEnumerable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IEnumerator<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IEqualityComparer<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IList<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IReadOnlyCollection<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IReadOnlyDictionary<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IReadOnlyList<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.KeyNotFoundException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.KeyValuePair<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.List<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.List<>.Enumerator))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.Queue<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.ICollection))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.IEnumerable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.IEnumerator))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.IList))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.AllowedValuesAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.Base64StringAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.DataType))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.DataTypeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.DeniedValuesAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.EmailAddressAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.LengthAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.MaxLengthAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.MinLengthAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.RangeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.RegularExpressionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DataAnnotations.UrlAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DescriptionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.DisplayNameAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.EditorBrowsableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.EditorBrowsableState))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.InvalidEnumArgumentException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Convert))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.DateTime))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.DateTimeKind))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.DateTimeOffset))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.DBNull))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Decimal))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Delegate))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.AllowNullAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.ExperimentalAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.NotNullAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.NotNullWhenAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.StringSyntaxAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DataReceivedEventArgs))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DataReceivedEventHandler))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.Debug))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggableAttribute.DebuggingModes))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerBrowsableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerBrowsableState))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerDisplayAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerHiddenAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerStepThroughAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerTypeProxyAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.Process))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.ProcessStartInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.DllNotFoundException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Double))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Drawing.Rectangle))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Enum))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Environment))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Exception))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.FlagsAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.FormatException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Func<,,,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Func<,,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Func<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Func<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.GC))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Globalization.CultureInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Guid))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Half))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.HashCode))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IAsyncDisposable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IAsyncResult))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IConvertible))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IDisposable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IEquatable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IFormatProvider))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Index))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IndexOutOfRangeException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Int16))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Int32))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Int64))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IntPtr))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.InvalidCastException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.InvalidOperationException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.Directory))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.DirectoryInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.File))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.FileAccess))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.FileMode))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.FileStream))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.MemoryMappedFiles.MemoryMappedFile))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.MemoryMappedFiles.MemoryMappedViewAccessor))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.MemoryStream))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.Path))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.SeekOrigin))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.Stream))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.UnmanagedMemoryStream))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IProgress<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IServiceProvider))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Linq.Enumerable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Linq.IOrderedEnumerable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Math))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.MathF))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Memory<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.MemoryExtensions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.MemoryExtensions.TryWriteInterpolatedStringHandler))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.MulticastDelegate))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Net.Http.Headers.MediaTypeHeaderValue))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Net.Mime.MediaTypeNames))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Net.WebUtility))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.NotSupportedException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Nullable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Nullable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Numerics.BitOperations))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Numerics.Tensors.TensorPrimitives))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Numerics.Vector))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Numerics.Vector<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Object))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ObjectDisposedException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ObsoleteAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.OperatingSystem))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.OperationCanceledException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.OverflowException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ParamArrayAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.PlatformNotSupportedException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Predicate<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Random))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Range))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ReadOnlyMemory<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ReadOnlySpan<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.Assembly))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyCompanyAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyConfigurationAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyCopyrightAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyDefaultAliasAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyDescriptionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyFileVersionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyInformationalVersionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyMetadataAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyProductAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyTitleAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.Binder))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.BindingFlags))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.ConstructorInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.CustomAttributeExtensions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.DefaultMemberAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.ICustomAttributeProvider))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.MemberInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.MethodBase))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.MethodInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.ParameterInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.ParameterModifier))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.PropertyInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.AsyncIteratorMethodBuilder))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.AsyncIteratorStateMachineAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.AsyncStateMachineAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.AsyncTaskMethodBuilder))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.AsyncTaskMethodBuilder<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.CallerArgumentExpressionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConditionalWeakTable<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConditionalWeakTable<,>.CreateValueCallback))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable<>.Enumerator))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredTaskAwaitable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable<>.ConfiguredValueTaskAwaiter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.DefaultInterpolatedStringHandler))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.EnumeratorCancellationAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ExtensionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.FixedBufferAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IAsyncStateMachine))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.InlineArrayAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IsByRefLikeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IsExternalInit))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IsReadOnlyAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IsUnmanagedAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IteratorStateMachineAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.NullableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.NullableContextAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.RefSafetyRulesAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.RequiresLocationAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.RuntimeCompatibilityAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.RuntimeHelpers))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.SkipLocalsInitAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.TaskAwaiter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.TaskAwaiter<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.TupleElementNamesAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.Unsafe))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.UnsafeValueTypeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ValueTaskAwaiter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ValueTaskAwaiter<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.ExceptionServices.ExceptionDispatchInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.CallingConvention))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.CollectionsMarshal))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.DllImportResolver))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.DllImportSearchPath))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.GCHandle))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.GCHandleType))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.InAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.Marshal))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.MemoryMarshal))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.NativeLibrary))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.OSPlatform))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.RuntimeInformation))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.SafeBuffer))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.SafeHandle))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.UnmanagedType))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.Arm.ArmBase))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.Arm.ArmBase.Arm64))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.Avx))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.Avx2))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.Avx512BW))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.Avx512F))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.Avx512Vbmi))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.Bmi1))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.Bmi1.X64))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Intrinsics.X86.X86Base))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Versioning.SupportedOSPlatformAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Versioning.TargetFrameworkAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Versioning.TargetPlatformAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.RuntimeTypeHandle))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.SByte))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.Cryptography.HashAlgorithmName))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.Cryptography.IncrementalHash))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.Permissions.SecurityAction))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.Permissions.SecurityPermissionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.UnverifiableCodeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Single))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Span<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.String))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.StringComparer))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.StringComparison))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.StringSplitOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Decoder))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Encoding))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Encodings.Web.JavaScriptEncoder))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonDocument))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonDocumentOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonElement))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonEncodedText))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonReaderOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonSerializer))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonSerializerDefaults))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonSerializerOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonTokenType))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.JsonValueKind))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Nodes.JsonArray))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Nodes.JsonNode))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Nodes.JsonNodeOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Nodes.JsonObject))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Nodes.JsonValue))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Schema.JsonSchemaExporter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Schema.JsonSchemaExporterContext))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Schema.JsonSchemaExporterOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonConstructorAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonConverter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonConverter<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonConverterAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonConverterFactory))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonDerivedTypeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonIgnoreAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonIgnoreCondition))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonIncludeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonNumberHandling))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonPolymorphicAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonPropertyNameAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonSerializableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonSerializerContext))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonSourceGenerationOptionsAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonDerivedType))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonMetadataServices))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonObjectInfoValues<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonParameterInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonParameterInfoValues))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonPolymorphismOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonPropertyInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonTypeInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonTypeInfo<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonTypeInfoKind))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Serialization.Metadata.JsonTypeInfoResolver))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Utf8JsonReader))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Json.Utf8JsonWriter))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Capture))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.GeneratedRegexAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Group))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.GroupCollection))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Match))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Regex))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.RegexOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.RegexRunner))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.RegexRunnerFactory))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.StringBuilder))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.StringBuilder.AppendInterpolatedStringHandler))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.CancellationToken))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.CancellationTokenSource))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Interlocked))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Monitor))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.SpinLock))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Parallel))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.ParallelLoopResult))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.ParallelOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Sources.IValueTaskSource))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Sources.IValueTaskSource<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Sources.ValueTaskSourceStatus))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Task))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Task<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.TaskAsyncEnumerableExtensions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.ValueTask))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.ValueTask<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.ThreadLocal<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ThreadStaticAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.TimeSpan))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Type))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.UInt16))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.UInt32))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.UInt64))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.UIntPtr))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Uri))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.UriFormatException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ValueTuple<,,,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ValueTuple<,,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ValueTuple<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ValueType))]
|
||||
//[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Void))]
|
||||
[ModuleInitializer]
|
||||
internal static void Initialize()
|
||||
{
|
||||
// This method runs automatically on startup.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
<linker>
|
||||
<assembly fullname="System.Collections" preserve="all" />
|
||||
<assembly fullname="System.IO.MemoryMappedFiles" preserve="all" />
|
||||
<assembly fullname="System.Linq" preserve="all" />
|
||||
<assembly fullname="System.Memory" preserve="all" />
|
||||
<assembly fullname="System.ObjectModel" preserve="all" />
|
||||
<assembly fullname="System.Runtime" preserve="all" />
|
||||
<assembly fullname="System.Runtime.InteropServices" preserve="all" />
|
||||
<assembly fullname="System.Text.RegularExpressions" preserve="all" />
|
||||
<assembly fullname="System.Threading" preserve="all" />
|
||||
<assembly fullname="BetterLyrics.WinUI3">
|
||||
<type fullname="BetterLyrics.WinUI3.PluginConfigs.BetterLyrics_Plugins_Romaji_Config" preserve="all" />
|
||||
</assembly>
|
||||
</linker>
|
||||
@@ -0,0 +1,145 @@
|
||||
// Auto-Generated by PluginAnalyzer
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace BetterLyrics.WinUI3.PluginConfigs;
|
||||
internal static class BetterLyrics_Plugins_Romaji_Config
|
||||
{
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AppContext))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AppDomain))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArgumentException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArgumentNullException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ArgumentOutOfRangeException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Array))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.AsyncCallback))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Boolean))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Buffer))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Byte))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Char))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.Dictionary<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.EqualityComparer<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.ICollection<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IEnumerable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IEnumerator<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IList<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IReadOnlyCollection<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.IReadOnlyList<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.LinkedList<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.LinkedListNode<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.Generic.List<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.ICollection))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.IEnumerable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.IEnumerator))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.IList))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.ObjectModel.Collection<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Collections.ObjectModel.ObservableCollection<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.INotifyPropertyChanged))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.PropertyChangedEventArgs))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ComponentModel.PropertyChangedEventHandler))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.DateTime))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Delegate))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggableAttribute.DebuggingModes))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerBrowsableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerBrowsableState))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Diagnostics.DebuggerHiddenAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Enum))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Environment))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Exception))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Func<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.GC))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IAsyncResult))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IComparable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IDisposable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IndexOutOfRangeException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Int16))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Int32))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Int64))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.InvalidOperationException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.BinaryReader))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.File))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.FileAccess))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.FileMode))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.FileShare))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.FileStream))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.HandleInheritability))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.MemoryMappedFiles.MemoryMappedFile))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.MemoryMappedFiles.MemoryMappedFileAccess))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.MemoryMappedFiles.MemoryMappedViewAccessor))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.MemoryMappedFiles.MemoryMappedViewStream))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.Path))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.Stream))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.StreamReader))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.TextReader))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.IO.UnmanagedMemoryAccessor))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Linq.Enumerable))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Linq.IGrouping<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Math))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.MemoryExtensions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.MulticastDelegate))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.NotImplementedException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.NotSupportedException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Nullable<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Object))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ObjectDisposedException))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ObsoleteAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ParamArrayAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ReadOnlySpan<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyCompanyAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyConfigurationAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyCopyrightAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyDescriptionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyFileVersionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyInformationalVersionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyMetadataAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyProductAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyTitleAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.AssemblyTrademarkAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Reflection.DefaultMemberAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.CallerMemberNameAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.ExtensionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IsReadOnlyAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.IteratorStateMachineAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.NullableAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.NullableContextAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.RefSafetyRulesAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.RuntimeCompatibilityAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.CompilerServices.TupleElementNamesAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.InteropServices.InAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Serialization.SerializationInfo))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Serialization.StreamingContext))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Versioning.SupportedOSPlatformAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Versioning.TargetFrameworkAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Runtime.Versioning.TargetPlatformAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.Permissions.SecurityAction))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.Permissions.SecurityPermissionAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Security.UnverifiableCodeAttribute))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Single))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.String))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.StringSplitOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.Encoding))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Capture))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Group))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.GroupCollection))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Match))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.MatchCollection))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.Regex))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.RegularExpressions.RegexOptions))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Text.StringBuilder))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Interlocked))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Task))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Threading.Tasks.Task<>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.TimeSpan))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.Type))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.UInt16))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.UInt32))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ValueTuple<,>))]
|
||||
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(System.ValueType))]
|
||||
[ModuleInitializer]
|
||||
internal static void Initialize()
|
||||
{
|
||||
// This method runs automatically on startup.
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
|
||||
public CoverBackgroundRenderer()
|
||||
{
|
||||
_crossfadeTransition = new ValueTransition<double>(1.0, 0.7, easingType: EasingType.Linear);
|
||||
_crossfadeTransition = new ValueTransition<double>(1.0, EasingHelper.GetInterpolatorByEasingType<double>(EasingType.Linear), 0.7);
|
||||
}
|
||||
|
||||
public void SetCoverBitmap(CanvasBitmap? newBitmap)
|
||||
@@ -73,18 +73,18 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
|
||||
if (_currentBitmap == null)
|
||||
{
|
||||
_crossfadeTransition.StartTransition(1.0, jumpTo: true);
|
||||
_crossfadeTransition.JumpTo(1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_previousBitmap == null)
|
||||
{
|
||||
_crossfadeTransition.StartTransition(1.0, jumpTo: true);
|
||||
_crossfadeTransition.JumpTo(1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_crossfadeTransition.Reset(0.0);
|
||||
_crossfadeTransition.StartTransition(1.0);
|
||||
_crossfadeTransition.JumpTo(0.0);
|
||||
_crossfadeTransition.Start(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
ICanvasAnimatedControl control,
|
||||
CanvasDrawingSession ds,
|
||||
IList<RenderLyricsLine>? lines,
|
||||
int playingLineIndex,
|
||||
int mouseHoverLineIndex,
|
||||
bool isMousePressing,
|
||||
int startVisibleIndex,
|
||||
@@ -57,7 +56,6 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
control,
|
||||
layerDs,
|
||||
lines,
|
||||
playingLineIndex,
|
||||
mouseHoverLineIndex,
|
||||
isMousePressing,
|
||||
startVisibleIndex,
|
||||
@@ -89,7 +87,6 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
control,
|
||||
ds,
|
||||
lines,
|
||||
playingLineIndex,
|
||||
mouseHoverLineIndex,
|
||||
isMousePressing,
|
||||
startVisibleIndex,
|
||||
@@ -114,7 +111,6 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
ICanvasAnimatedControl control,
|
||||
CanvasDrawingSession ds,
|
||||
IList<RenderLyricsLine>? lines,
|
||||
int playingLineIndex,
|
||||
int mouseHoverLineIndex,
|
||||
bool isMousePressing,
|
||||
int startVisibleIndex,
|
||||
@@ -134,9 +130,6 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
{
|
||||
if (lines == null) return;
|
||||
|
||||
var currentPlayingLine = lines.ElementAtOrDefault(playingLineIndex);
|
||||
if (currentPlayingLine == null) return;
|
||||
|
||||
var effectSettings = windowStatus.LyricsEffectSettings;
|
||||
var styleSettings = windowStatus.LyricsStyleSettings;
|
||||
|
||||
@@ -148,8 +141,8 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
var line = lines.ElementAtOrDefault(i);
|
||||
if (line == null) continue;
|
||||
|
||||
if (line.OriginalCanvasTextLayout == null) continue;
|
||||
if (line.OriginalCanvasTextLayout.LayoutBounds.Width <= 0) continue;
|
||||
if (line.PrimaryTextLayout == null) continue;
|
||||
if (line.PrimaryTextLayout.LayoutBounds.Width <= 0) continue;
|
||||
|
||||
double xOffset = lyricsX;
|
||||
double yOffset = line.YOffsetTransition.Value + userScrollOffset + lyricsY + lyricsHeight * playingLineTopOffsetFactor;
|
||||
@@ -167,8 +160,7 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
|
||||
using (var textOnlyLayer = RenderBaseTextLayer(control, line, styleSettings.LyricsFontStrokeWidth, strokeColor, line.ColorTransition.Value))
|
||||
{
|
||||
bool isPlaying = currentProgressMs >= line.StartMs && currentProgressMs <= line.EndMs;
|
||||
if (i == playingLineIndex) isPlaying = true;
|
||||
bool isPlaying = line.GetIsPlaying(currentProgressMs);
|
||||
|
||||
if (isPlaying)
|
||||
{
|
||||
@@ -206,14 +198,14 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
{
|
||||
if (strokeWidth > 0)
|
||||
{
|
||||
DrawGeometrySafely(clds, line.PhoneticCanvasGeometry, line.PhoneticPosition, strokeColor, strokeWidth);
|
||||
DrawGeometrySafely(clds, line.OriginalCanvasGeometry, line.OriginalPosition, strokeColor, strokeWidth);
|
||||
DrawGeometrySafely(clds, line.TranslatedCanvasGeometry, line.TranslatedPosition, strokeColor, strokeWidth);
|
||||
DrawGeometrySafely(clds, line.TertiaryCanvasGeometry, line.TertiaryPosition, strokeColor, strokeWidth);
|
||||
DrawGeometrySafely(clds, line.PrimaryCanvasGeometry, line.PrimaryPosition, strokeColor, strokeWidth);
|
||||
DrawGeometrySafely(clds, line.SecondaryCanvasGeometry, line.SecondaryPosition, strokeColor, strokeWidth);
|
||||
}
|
||||
|
||||
DrawTextLayoutSafely(clds, line.PhoneticCanvasTextLayout, line.PhoneticPosition, fillColor);
|
||||
DrawTextLayoutSafely(clds, line.OriginalCanvasTextLayout, line.OriginalPosition, fillColor);
|
||||
DrawTextLayoutSafely(clds, line.TranslatedCanvasTextLayout, line.TranslatedPosition, fillColor);
|
||||
DrawTextLayoutSafely(clds, line.TertiaryTextLayout, line.TertiaryPosition, fillColor);
|
||||
DrawTextLayoutSafely(clds, line.PrimaryTextLayout, line.PrimaryPosition, fillColor);
|
||||
DrawTextLayoutSafely(clds, line.SecondaryTextLayout, line.SecondaryPosition, fillColor);
|
||||
}
|
||||
return commandList;
|
||||
}
|
||||
|
||||
@@ -26,24 +26,24 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
Color fgColor,
|
||||
LyricsEffectSettings settings)
|
||||
{
|
||||
DrawPhonetic(ds, textOnlyLayer, line);
|
||||
DrawOriginalText(control, ds, textOnlyLayer, line, playbackState, bgColor, fgColor, settings);
|
||||
DrawTranslated(ds, textOnlyLayer, line);
|
||||
DrawTertiaryText(ds, textOnlyLayer, line);
|
||||
DrawPrimaryText(control, ds, textOnlyLayer, line, playbackState, bgColor, fgColor, settings);
|
||||
DrawSecondaryText(ds, textOnlyLayer, line);
|
||||
}
|
||||
|
||||
private void DrawPhonetic(CanvasDrawingSession ds, ICanvasImage source, RenderLyricsLine line)
|
||||
private void DrawTertiaryText(CanvasDrawingSession ds, ICanvasImage source, RenderLyricsLine line)
|
||||
{
|
||||
if (line.PhoneticCanvasTextLayout == null) return;
|
||||
if (line.TertiaryTextLayout == null) return;
|
||||
|
||||
var opacity = line.PhoneticOpacityTransition.Value;
|
||||
var blur = line.BlurAmountTransition.Value;
|
||||
var bounds = line.PhoneticCanvasTextLayout.LayoutBounds;
|
||||
var bounds = line.TertiaryTextLayout.LayoutBounds;
|
||||
|
||||
if (double.IsNaN(opacity)) return;
|
||||
|
||||
var destRect = new Rect(
|
||||
bounds.X + line.PhoneticPosition.X,
|
||||
bounds.Y + line.PhoneticPosition.Y,
|
||||
bounds.X + line.TertiaryPosition.X,
|
||||
bounds.Y + line.TertiaryPosition.Y,
|
||||
bounds.Width,
|
||||
bounds.Height
|
||||
);
|
||||
@@ -65,19 +65,19 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawTranslated(CanvasDrawingSession ds, ICanvasImage source, RenderLyricsLine line)
|
||||
private void DrawSecondaryText(CanvasDrawingSession ds, ICanvasImage source, RenderLyricsLine line)
|
||||
{
|
||||
if (line.TranslatedCanvasTextLayout == null) return;
|
||||
if (line.SecondaryTextLayout == null) return;
|
||||
|
||||
var opacity = line.TranslatedOpacityTransition.Value;
|
||||
var blur = line.BlurAmountTransition.Value;
|
||||
var bounds = line.TranslatedCanvasTextLayout.LayoutBounds;
|
||||
var bounds = line.SecondaryTextLayout.LayoutBounds;
|
||||
|
||||
if (double.IsNaN(opacity)) return;
|
||||
|
||||
var destRect = new Rect(
|
||||
bounds.X + line.TranslatedPosition.X,
|
||||
bounds.Y + line.TranslatedPosition.Y,
|
||||
bounds.X + line.SecondaryPosition.X,
|
||||
bounds.Y + line.SecondaryPosition.Y,
|
||||
bounds.Width,
|
||||
bounds.Height
|
||||
);
|
||||
@@ -99,7 +99,7 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawOriginalText(
|
||||
private void DrawPrimaryText(
|
||||
ICanvasResourceCreator resourceCreator,
|
||||
CanvasDrawingSession ds,
|
||||
ICanvasImage source,
|
||||
@@ -109,12 +109,12 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
Color fgColor,
|
||||
LyricsEffectSettings settings)
|
||||
{
|
||||
if (line.OriginalCanvasTextLayout == null) return;
|
||||
if (line.PrimaryTextLayout == null) return;
|
||||
|
||||
var curCharIndex = state.SyllableStartIndex + state.SyllableLength * state.SyllableProgress;
|
||||
float fadeWidth = (1f / Math.Max(1, line.OriginalText.Length)) * 0.5f;
|
||||
float fadeWidth = (1f / Math.Max(1, line.PrimaryText.Length)) * 0.5f;
|
||||
|
||||
var lineRegions = line.OriginalCanvasTextLayout.GetCharacterRegions(0, line.OriginalText.Length);
|
||||
var lineRegions = line.PrimaryTextLayout.GetCharacterRegions(0, line.PrimaryText.Length);
|
||||
|
||||
foreach (var subLineRegion in lineRegions)
|
||||
{
|
||||
@@ -139,8 +139,8 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
|
||||
var subLineLayoutBounds = subLineRegion.LayoutBounds;
|
||||
Rect subLineRect = new(
|
||||
subLineLayoutBounds.X + line.OriginalPosition.X,
|
||||
subLineLayoutBounds.Y + line.OriginalPosition.Y,
|
||||
subLineLayoutBounds.X + line.PrimaryPosition.X,
|
||||
subLineLayoutBounds.Y + line.PrimaryPosition.Y,
|
||||
subLineLayoutBounds.Width,
|
||||
subLineLayoutBounds.Height
|
||||
);
|
||||
@@ -208,14 +208,14 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
int charIndex,
|
||||
ICanvasImage source)
|
||||
{
|
||||
if (charIndex >= line.RenderLyricsOriginalChars.Count) return;
|
||||
if (charIndex >= line.PrimaryRenderChars.Count) return;
|
||||
|
||||
RenderLyricsChar renderChar = line.RenderLyricsOriginalChars[charIndex];
|
||||
RenderLyricsChar renderChar = line.PrimaryRenderChars[charIndex];
|
||||
|
||||
var rect = renderChar.LayoutRect;
|
||||
var sourceCharRect = new Rect(
|
||||
rect.X + line.OriginalPosition.X,
|
||||
rect.Y + line.OriginalPosition.Y,
|
||||
rect.X + line.PrimaryPosition.X,
|
||||
rect.Y + line.PrimaryPosition.Y,
|
||||
rect.Width,
|
||||
rect.Height
|
||||
);
|
||||
|
||||
@@ -17,32 +17,32 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
{
|
||||
var blurAmount = (float)line.BlurAmountTransition.Value;
|
||||
|
||||
if (line.PhoneticCanvasTextLayout != null)
|
||||
if (line.TertiaryTextLayout != null)
|
||||
{
|
||||
var opacity = line.PhoneticOpacityTransition.Value;
|
||||
DrawPart(ds, textOnlyLayer,
|
||||
line.PhoneticCanvasTextLayout,
|
||||
line.PhoneticPosition,
|
||||
line.TertiaryTextLayout,
|
||||
line.TertiaryPosition,
|
||||
blurAmount,
|
||||
(float)opacity);
|
||||
}
|
||||
|
||||
if (line.OriginalCanvasTextLayout != null)
|
||||
if (line.PrimaryTextLayout != null)
|
||||
{
|
||||
double opacity = Math.Max(line.PlayedOriginalOpacityTransition.Value, line.UnplayedOriginalOpacityTransition.Value);
|
||||
DrawPart(ds, textOnlyLayer,
|
||||
line.OriginalCanvasTextLayout,
|
||||
line.OriginalPosition,
|
||||
line.PrimaryTextLayout,
|
||||
line.PrimaryPosition,
|
||||
blurAmount,
|
||||
(float)opacity);
|
||||
}
|
||||
|
||||
if (line.TranslatedCanvasTextLayout != null)
|
||||
if (line.SecondaryTextLayout != null)
|
||||
{
|
||||
var opacity = line.TranslatedOpacityTransition.Value;
|
||||
DrawPart(ds, textOnlyLayer,
|
||||
line.TranslatedCanvasTextLayout,
|
||||
line.TranslatedPosition,
|
||||
line.SecondaryTextLayout,
|
||||
line.SecondaryPosition,
|
||||
blurAmount,
|
||||
(float)opacity);
|
||||
}
|
||||
|
||||
@@ -251,11 +251,7 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService
|
||||
.Where(x => x.MediaFolderId == folder.Id)
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
// VACUUM 是 SQLite 特有的命令
|
||||
if (context.Database.IsSqlite())
|
||||
{
|
||||
await context.Database.ExecuteSqlRawAsync("VACUUM");
|
||||
}
|
||||
await context.Database.ExecuteSqlRawAsync("VACUUM");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -22,13 +22,12 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
|
||||
{
|
||||
_logger.LogInformation("RefreshLyricsAsync");
|
||||
|
||||
CurrentLyricsSearchResult = null;
|
||||
CurrentLyricsData = LyricsData.GetLoadingPlaceholder();
|
||||
|
||||
if (CurrentSongInfo != SongInfoExtensions.Placeholder)
|
||||
{
|
||||
CurrentLyricsSearchResult = await Task.Run(async () => await _lyrcsSearchService.SearchSmartlyAsync(
|
||||
CurrentSongInfo, true, CurrentMediaSourceProviderInfo?.LyricsSearchType, token), token);
|
||||
CurrentSongInfo, CurrentMediaSourceProviderInfo?.LyricsSearchType, token), token);
|
||||
|
||||
if (CurrentLyricsSearchResult != null)
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.AlbumArtSearchService;
|
||||
using BetterLyrics.WinUI3.Services.DiscordService;
|
||||
using BetterLyrics.WinUI3.Services.LastFMService;
|
||||
using BetterLyrics.WinUI3.Services.LocalizationService;
|
||||
using BetterLyrics.WinUI3.Services.LyricsSearchService;
|
||||
using BetterLyrics.WinUI3.Services.PlayHistoryService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
@@ -19,6 +20,7 @@ using BetterLyrics.WinUI3.Services.TransliterationService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using CommunityToolkit.WinUI;
|
||||
@@ -206,7 +208,6 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
|
||||
private void InitMediaManager()
|
||||
{
|
||||
_mediaManager.Start();
|
||||
|
||||
_mediaManager.CurrentMediaSessions.ToList().ForEach(x => RecordMediaSession(x.Value.Id));
|
||||
|
||||
_mediaManager.OnAnySessionOpened += MediaManager_OnAnySessionOpened;
|
||||
@@ -696,10 +697,6 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
|
||||
_logger.LogInformation("Target LibreTranslate language code changed: {code}", _settingsService.AppSettings.TranslationSettings.SelectedTargetLanguageCode);
|
||||
UpdateLyrics();
|
||||
}
|
||||
else if (message.PropertyName == nameof(TranslationSettings.CutletDockerServer))
|
||||
{
|
||||
UpdateLyrics();
|
||||
}
|
||||
else if (message.PropertyName == nameof(TranslationSettings.LibreTranslateServer))
|
||||
{
|
||||
UpdateLyrics();
|
||||
|
||||
@@ -8,5 +8,6 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService
|
||||
{
|
||||
Task<LyricsCacheItem?> GetLyricsAsync(SongInfo songInfo, LyricsSearchProvider provider);
|
||||
Task SaveLyricsAsync(SongInfo songInfo, LyricsCacheItem result);
|
||||
Task ClearCacheAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write cache to DB
|
||||
/// Write or update cache to DB
|
||||
/// </summary>
|
||||
public async Task SaveLyricsAsync(SongInfo songInfo, LyricsCacheItem result)
|
||||
{
|
||||
@@ -52,12 +52,31 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService
|
||||
}
|
||||
else
|
||||
{
|
||||
// No need to handle this case
|
||||
return;
|
||||
existingItem.Title = result.Title;
|
||||
existingItem.Artist = result.Artist;
|
||||
existingItem.Album = result.Album;
|
||||
existingItem.Duration = result.Duration;
|
||||
|
||||
existingItem.TransliterationProvider = result.TransliterationProvider;
|
||||
existingItem.TranslationProvider = result.TranslationProvider;
|
||||
|
||||
existingItem.Raw = result.Raw;
|
||||
existingItem.Translation = result.Translation;
|
||||
|
||||
existingItem.MatchPercentage = result.MatchPercentage;
|
||||
existingItem.Reference = result.Reference;
|
||||
}
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task ClearCacheAsync()
|
||||
{
|
||||
using var context = await _contextFactory.CreateDbContextAsync();
|
||||
|
||||
await context.LyricsCache.ExecuteDeleteAsync();
|
||||
await context.Database.ExecuteSqlRawAsync("VACUUM;");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
public interface ILyricsSearchService
|
||||
{
|
||||
Task<LyricsCacheItem?> SearchSmartlyAsync(SongInfo songInfo, bool checkCache, LyricsSearchType? lyricsSearchType, CancellationToken token);
|
||||
Task<LyricsCacheItem?> SearchSmartlyAsync(SongInfo songInfo, LyricsSearchType? lyricsSearchType, CancellationToken token);
|
||||
|
||||
Task<List<LyricsCacheItem>> SearchAllAsync(SongInfo songInfo, bool checkCache, CancellationToken token);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using BetterLyrics.Core.Interfaces.Features;
|
||||
using BetterLyrics.WinUI3.Constants;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Extensions;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
@@ -9,6 +11,7 @@ using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Providers;
|
||||
using BetterLyrics.WinUI3.Services.FileSystemService;
|
||||
using BetterLyrics.WinUI3.Services.LyricsCacheService;
|
||||
using BetterLyrics.WinUI3.Services.PluginService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Services.SongSearchMapService;
|
||||
using Lyricify.Lyrics.Helpers;
|
||||
@@ -29,12 +32,13 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
private readonly HttpClient _amllTtmlDbHttpClient;
|
||||
private readonly HttpClient _lrcLibHttpClient;
|
||||
private readonly AppleMusic _appleMusic;
|
||||
private readonly Providers.AppleMusic _appleMusic;
|
||||
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IFileSystemService _fileSystemService;
|
||||
private readonly ILyricsCacheService _lyricsCacheService;
|
||||
private readonly ISongSearchMapService _songSearchMapService;
|
||||
private readonly IPluginService _pluginService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public LyricsSearchService(
|
||||
@@ -42,6 +46,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
IFileSystemService fileSystemService,
|
||||
ILyricsCacheService lyricsCacheService,
|
||||
ISongSearchMapService songSearchMapService,
|
||||
IPluginService pluginService,
|
||||
ILogger<LyricsSearchService> logger
|
||||
)
|
||||
{
|
||||
@@ -49,15 +54,16 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
_fileSystemService = fileSystemService;
|
||||
_lyricsCacheService = lyricsCacheService;
|
||||
_songSearchMapService = songSearchMapService;
|
||||
_pluginService = pluginService;
|
||||
_logger = logger;
|
||||
|
||||
_lrcLibHttpClient = new();
|
||||
_lrcLibHttpClient.DefaultRequestHeaders.Add(
|
||||
"User-Agent",
|
||||
$"{Constants.App.AppName} {MetadataHelper.AppVersion} ({Constants.Link.BetterLyricsGitHub})"
|
||||
$"{Constants.App.AppName} {MetadataHelper.AppVersion} ({Link.BetterLyricsGitHub})"
|
||||
);
|
||||
_amllTtmlDbHttpClient = new();
|
||||
_appleMusic = new AppleMusic();
|
||||
_appleMusic = new Providers.AppleMusic();
|
||||
}
|
||||
|
||||
private static bool IsAmllTtmlDbIndexInvalid()
|
||||
@@ -104,7 +110,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LyricsCacheItem?> SearchSmartlyAsync(SongInfo songInfo, bool checkCache, LyricsSearchType? lyricsSearchType, CancellationToken token)
|
||||
public async Task<LyricsCacheItem?> SearchSmartlyAsync(SongInfo songInfo, LyricsSearchType? lyricsSearchType, CancellationToken token)
|
||||
{
|
||||
if (lyricsSearchType == null)
|
||||
{
|
||||
@@ -112,8 +118,6 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
}
|
||||
|
||||
var lyricsSearchResult = new LyricsCacheItem();
|
||||
//lyricsSearchResult.Raw = File.ReadAllText("C:\\Users\\Zhe\\Desktop\\星河回响 (Tech Demo).lrc");
|
||||
//return lyricsSearchResult;
|
||||
|
||||
string overridenTitle = songInfo.Title;
|
||||
string overridenArtist = songInfo.Artist;
|
||||
@@ -150,7 +154,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
.WithTitle(overridenTitle)
|
||||
.WithArtist(overridenArtist)
|
||||
.WithAlbum(overridenAlbum),
|
||||
targetProvider.Value, checkCache, token);
|
||||
targetProvider.Value, true, token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +176,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
.WithTitle(overridenTitle)
|
||||
.WithArtist(overridenArtist)
|
||||
.WithAlbum(overridenAlbum),
|
||||
provider.Provider, checkCache, token);
|
||||
provider.Provider, !provider.IgnoreCacheWhenSearching, token);
|
||||
|
||||
int matchingThreshold = mediaSourceProviderInfo.MatchingThreshold;
|
||||
if (provider.IsMatchingThresholdOverwritten)
|
||||
@@ -208,11 +212,26 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
_logger.LogInformation("SearchAllAsync {SongInfo}", songInfo);
|
||||
var results = new List<LyricsCacheItem>();
|
||||
|
||||
foreach (var provider in Enum.GetValues<LyricsSearchProvider>())
|
||||
{
|
||||
if (provider == LyricsSearchProvider.Plugin) continue;
|
||||
|
||||
var searchResult = await SearchSingleAsync(songInfo, provider, checkCache, token);
|
||||
results.Add(searchResult);
|
||||
}
|
||||
|
||||
foreach (var plugin in _pluginService.Plugins)
|
||||
{
|
||||
if (token.IsCancellationRequested) break;
|
||||
|
||||
if (plugin is ILyricsSource lyricsSearchPlugin)
|
||||
{
|
||||
var pluginResult = await SearchPluginAsync(songInfo, lyricsSearchPlugin, token);
|
||||
results.Add(pluginResult);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -288,7 +307,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
|
||||
private async Task<LyricsCacheItem> SearchFile(SongInfo songInfo, LyricsFormat format)
|
||||
{
|
||||
int maxScore = 0;
|
||||
int maxScore = -1;
|
||||
|
||||
FilesIndexItem? bestFileEntity = null;
|
||||
MediaFolder? bestFolderConfig = null;
|
||||
@@ -316,7 +335,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
if (item.FileName.EndsWith(targetExt, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
int score = MetadataComparer.CalculateScore(songInfo, new LyricsCacheItem { Reference = item.FileName });
|
||||
int score = MetadataComparer.CalculateScore(songInfo, item);
|
||||
|
||||
if (score > maxScore)
|
||||
{
|
||||
@@ -363,13 +382,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
if (string.IsNullOrEmpty(item.EmbeddedLyrics)) continue;
|
||||
|
||||
int score = MetadataComparer.CalculateScore(songInfo, new LyricsCacheItem
|
||||
{
|
||||
Title = item.Title,
|
||||
Artist = item.Artist,
|
||||
Album = item.Album,
|
||||
Duration = item.Duration
|
||||
});
|
||||
int score = MetadataComparer.CalculateScore(songInfo, item);
|
||||
|
||||
if (score > maxScore)
|
||||
{
|
||||
@@ -410,6 +423,8 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
}
|
||||
|
||||
string? rawLyricFile = null;
|
||||
string? bestNcmMusicId = null;
|
||||
|
||||
await foreach (var line in File.ReadLinesAsync(PathHelper.AmllTtmlDbIndexPath))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
@@ -424,6 +439,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
string? title = null;
|
||||
string? artist = null;
|
||||
string? album = null;
|
||||
string? ncmMusicId = null;
|
||||
|
||||
foreach (var meta in metadataArr.EnumerateArray())
|
||||
{
|
||||
@@ -437,6 +453,8 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
artist = string.Join(" / ", valueArr.EnumerateArray());
|
||||
if (key == "album" && valueArr.GetArrayLength() > 0)
|
||||
album = valueArr[0].GetString();
|
||||
if (key == "ncmMusicId" && valueArr.GetArrayLength() > 0)
|
||||
ncmMusicId = valueArr[0].GetString();
|
||||
}
|
||||
|
||||
int score = MetadataComparer.CalculateScore(songInfo, new LyricsCacheItem
|
||||
@@ -449,6 +467,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
if (root.TryGetProperty("rawLyricFile", out var rawLyricFileProp))
|
||||
{
|
||||
bestNcmMusicId = ncmMusicId;
|
||||
rawLyricFile = rawLyricFileProp.GetString();
|
||||
lyricsSearchResult.Title = title;
|
||||
lyricsSearchResult.Artist = artist;
|
||||
@@ -465,19 +484,28 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
|
||||
// 下载歌词内容
|
||||
var url = $"{_settingsService.AppSettings.GeneralSettings.AmllTtmlDbBaseUrl}/{Constants.AmllTTmlDB.QueryPrefix}/{rawLyricFile}";
|
||||
var url = $"{_settingsService.AppSettings.GeneralSettings.AmllTtmlDbBaseUrl}/{AmllTTmlDB.QueryPrefix}/{rawLyricFile}";
|
||||
lyricsSearchResult.Reference = url;
|
||||
try
|
||||
{
|
||||
// 下载写入歌词
|
||||
using var response = await _amllTtmlDbHttpClient.GetAsync(url);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
string lyrics = await response.Content.ReadAsStringAsync();
|
||||
|
||||
lyricsSearchResult.Raw = lyrics;
|
||||
|
||||
// 反查时长
|
||||
if (bestNcmMusicId != null && lyricsSearchResult.Duration == null)
|
||||
{
|
||||
var tmp = await SearchQQNeteaseKugouAsync(
|
||||
((SongInfo)songInfo.Clone()).WithSongId($"{ExtendedGenreFiled.NetEaseCloudMusicTrackID}{bestNcmMusicId}"),
|
||||
Searchers.Netease);
|
||||
lyricsSearchResult.Duration = tmp.Duration;
|
||||
lyricsSearchResult.MatchPercentage = MetadataComparer.CalculateScore(songInfo, lyricsSearchResult);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -640,7 +668,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
}
|
||||
|
||||
lyricsSearchResult.Title = result?.Title;
|
||||
lyricsSearchResult.Artist = string.Join(" / ", result?.Artists ?? []);
|
||||
lyricsSearchResult.Artist = result?.Artist;
|
||||
lyricsSearchResult.Album = result?.Album;
|
||||
lyricsSearchResult.Duration = result?.DurationMs / 1000;
|
||||
|
||||
@@ -665,5 +693,40 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
|
||||
private async Task<LyricsCacheItem> SearchPluginAsync(SongInfo songInfo, ILyricsSource plugin, CancellationToken token)
|
||||
{
|
||||
var cacheItem = new LyricsCacheItem
|
||||
{
|
||||
Provider = LyricsSearchProvider.Plugin,
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var result = await plugin.GetLyricsAsync(songInfo.Title, songInfo.Artist, songInfo.Album, songInfo.Duration);
|
||||
|
||||
if (result != null && !string.IsNullOrEmpty(result.Raw))
|
||||
{
|
||||
cacheItem.Title = result.Title;
|
||||
cacheItem.Artist = result.Artist;
|
||||
cacheItem.Album = result.Album;
|
||||
cacheItem.Duration = result.Duration;
|
||||
|
||||
cacheItem.Raw = result.Raw;
|
||||
cacheItem.Translation = result.Translation;
|
||||
cacheItem.Transliteration = result.Transliteration;
|
||||
|
||||
cacheItem.Reference = result.Reference ?? "about:blank";
|
||||
cacheItem.MatchPercentage = MetadataComparer.CalculateScore(songInfo, cacheItem);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Plugin {PluginName} failed to search", plugin.Name);
|
||||
}
|
||||
|
||||
return cacheItem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using BetterLyrics.Core.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.PluginService
|
||||
{
|
||||
public interface IPluginService
|
||||
{
|
||||
IReadOnlyList<IPlugin> Plugins { get; }
|
||||
|
||||
T? GetPlugin<T>() where T : class, IPlugin;
|
||||
void LoadPlugins();
|
||||
void InstallPlugin(string zipPath);
|
||||
void UninstallPlugin(string pluginId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using BetterLyrics.Core.Interfaces;
|
||||
using BetterLyrics.Core.Interfaces.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.PluginService
|
||||
{
|
||||
public class PluginContext : IPluginContext
|
||||
{
|
||||
private readonly IPluginService _pluginService;
|
||||
|
||||
public string PluginDirectory { get; }
|
||||
public IAIService? AIService => _pluginService.GetPlugin<IAIService>();
|
||||
|
||||
public PluginContext(IPluginService pluginService, string pluginDir)
|
||||
{
|
||||
_pluginService = pluginService;
|
||||
PluginDirectory = pluginDir;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.PluginService
|
||||
{
|
||||
public class PluginLoadContext : AssemblyLoadContext
|
||||
{
|
||||
private AssemblyDependencyResolver _resolver;
|
||||
|
||||
public PluginLoadContext(string pluginPath) : base(isCollectible: true)
|
||||
{
|
||||
_resolver = new AssemblyDependencyResolver(pluginPath);
|
||||
}
|
||||
|
||||
protected override Assembly? Load(AssemblyName assemblyName)
|
||||
{
|
||||
var assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
|
||||
if (assemblyPath != null)
|
||||
{
|
||||
return LoadFromAssemblyPath(assemblyPath);
|
||||
}
|
||||
|
||||
// return null to use the default AssemblyLoadContext
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
|
||||
{
|
||||
var libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
|
||||
if (libraryPath != null)
|
||||
{
|
||||
return LoadUnmanagedDllFromPath(libraryPath);
|
||||
}
|
||||
|
||||
// return IntPtr.Zero to use the default AssemblyLoadContext
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
using BetterLyrics.Core.Interfaces;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.PluginService
|
||||
{
|
||||
public class PluginService : IPluginService
|
||||
{
|
||||
private List<IPlugin> _plugins = new();
|
||||
public IReadOnlyList<IPlugin> Plugins => _plugins;
|
||||
private Dictionary<string, PluginLoadContext> _pluginContexts = new();
|
||||
private HashSet<string> _loadedDllPaths = new();
|
||||
|
||||
private readonly ILogger<PluginService> _logger;
|
||||
|
||||
public PluginService(ILogger<PluginService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public T? GetPlugin<T>() where T : class, IPlugin
|
||||
{
|
||||
return _plugins.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
public void LoadPlugins()
|
||||
{
|
||||
string pluginsRoot = Path.Combine(ApplicationData.Current.LocalFolder.Path, "plugins");
|
||||
if (!Directory.Exists(pluginsRoot)) Directory.CreateDirectory(pluginsRoot);
|
||||
|
||||
var pluginFolders = Directory.GetDirectories(pluginsRoot);
|
||||
|
||||
foreach (var folder in pluginFolders)
|
||||
{
|
||||
var dllFiles = Directory.GetFiles(folder, "*.dll");
|
||||
|
||||
foreach (var dllPath in dllFiles)
|
||||
{
|
||||
if (_loadedDllPaths.Contains(dllPath)) continue;
|
||||
|
||||
TryLoadPlugin(dllPath);
|
||||
}
|
||||
}
|
||||
|
||||
InitializePlugins();
|
||||
}
|
||||
|
||||
private void InitializePlugins()
|
||||
{
|
||||
foreach (var plugin in _plugins)
|
||||
{
|
||||
try
|
||||
{
|
||||
string dllPath = plugin.GetType().Assembly.Location;
|
||||
string? pluginDir = Path.GetDirectoryName(dllPath);
|
||||
if (pluginDir == null) continue;
|
||||
|
||||
var context = new PluginContext(this, pluginDir);
|
||||
plugin.OnLoad(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to initialize plugin {Name}", plugin.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TryLoadPlugin(string dllPath)
|
||||
{
|
||||
// 1. Create Context
|
||||
var loadContext = new PluginLoadContext(dllPath);
|
||||
|
||||
try
|
||||
{
|
||||
var assembly = loadContext.LoadFromAssemblyPath(dllPath);
|
||||
int loadedCount = 0; // Track successfully loaded plugins
|
||||
|
||||
// 2. [Safety Check] Safely retrieve types
|
||||
IEnumerable<Type> types;
|
||||
try
|
||||
{
|
||||
types = assembly.GetExportedTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
// If some types fail to load, only keep the usable ones!
|
||||
types = ex.Types.Where(t => t != null)!;
|
||||
foreach (var loaderEx in ex.LoaderExceptions)
|
||||
{
|
||||
_logger.LogWarning("Partial type loading failure in DLL {path}: {msg}", dllPath, loaderEx?.Message);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
// 3. Check if it is a valid plugin class
|
||||
if (typeof(IPlugin).IsAssignableFrom(type) && !type.IsAbstract)
|
||||
{
|
||||
IPlugin? plugin = null;
|
||||
try
|
||||
{
|
||||
// 4. [Instantiation Guard] Prevent plugin constructor errors from crashing the main app
|
||||
plugin = (IPlugin?)Activator.CreateInstance(type);
|
||||
if (plugin == null) continue;
|
||||
|
||||
// 5. Check for duplicate IDs
|
||||
if (_plugins.Any(p => p.Id == plugin.Id))
|
||||
{
|
||||
_logger.LogWarning("Skipping duplicate plugin: {id} ({path})", plugin.Id, dllPath);
|
||||
// Explicitly break reference to aid Unload
|
||||
plugin = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 7. Add to collection
|
||||
_plugins.Add(plugin);
|
||||
_pluginContexts.Add(plugin.Id, loadContext);
|
||||
loadedCount++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to initialize/instantiate plugin {type}", type.FullName);
|
||||
|
||||
// If plugin initialization fails, explicitly dispose if possible
|
||||
if (plugin is IDisposable disposable)
|
||||
{
|
||||
try { disposable.Dispose(); } catch { }
|
||||
}
|
||||
plugin = null; // Break reference
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Finalize: If no usable plugins were found in this DLL, unload Context
|
||||
if (loadedCount > 0)
|
||||
{
|
||||
_loadedDllPaths.Add(dllPath);
|
||||
_logger.LogInformation("Successfully loaded {count} plugin(s) from {path}", loadedCount, dllPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("No valid plugins found in {path}. Unloading context.", dllPath);
|
||||
// No plugin instances remain alive at this point, safe to unload
|
||||
loadContext.Unload();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to load assembly: {path}", dllPath);
|
||||
// Only unload here if the loading process completely crashed
|
||||
try { loadContext.Unload(); } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public void UninstallPlugin(string pluginId)
|
||||
{
|
||||
var plugin = _plugins.FirstOrDefault(p => p.Id == pluginId);
|
||||
if (plugin == null) return;
|
||||
|
||||
var dllPath = plugin.GetType().Assembly.Location;
|
||||
var folderPath = Path.GetDirectoryName(dllPath);
|
||||
|
||||
_plugins.Remove(plugin);
|
||||
_loadedDllPaths.Remove(dllPath);
|
||||
|
||||
if (_pluginContexts.TryGetValue(pluginId, out var context))
|
||||
{
|
||||
context.Unload();
|
||||
_pluginContexts.Remove(pluginId);
|
||||
}
|
||||
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
|
||||
if (Directory.Exists(folderPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(folderPath, true);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to delete plugin folder {}", folderPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void InstallPlugin(string zipPath)
|
||||
{
|
||||
string pluginsRoot = Path.Combine(ApplicationData.Current.LocalFolder.Path, "plugins");
|
||||
string folderName = Path.GetFileNameWithoutExtension(zipPath);
|
||||
string installDir = Path.Combine(pluginsRoot, folderName);
|
||||
|
||||
if (Directory.Exists(installDir))
|
||||
{
|
||||
// TODO: 最好是先 Find plugin by path -> UninstallPlugin(id)
|
||||
// 否则文件被锁住无法 Delete
|
||||
try
|
||||
{
|
||||
Directory.Delete(installDir, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to delete existing plugin folder {}", installDir);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(installDir);
|
||||
ZipFile.ExtractToDirectory(zipPath, installDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
using BetterLyrics.WinUI3.Models.Http;
|
||||
using BetterLyrics.Core.Interfaces.Features;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Http;
|
||||
using BetterLyrics.WinUI3.Serialization;
|
||||
using BetterLyrics.WinUI3.Services.PluginService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -12,37 +16,31 @@ namespace BetterLyrics.WinUI3.Services.TransliterationService
|
||||
public class TransliterationService : ITransliterationService
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IPluginService _pluginService;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public TransliterationService(ISettingsService settingsService)
|
||||
public TransliterationService(ISettingsService settingsService, IPluginService pluginService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_pluginService = pluginService;
|
||||
_httpClient = new HttpClient();
|
||||
}
|
||||
|
||||
public async Task<string> TransliterateText(string text, string targetLangCode, CancellationToken token)
|
||||
{
|
||||
string? result = null;
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
throw new Exception(text + " is empty or null.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_settingsService.AppSettings.TranslationSettings.CutletDockerServer))
|
||||
var plugin = _pluginService.Plugins.OfType<ILyricsTransliterator>().FirstOrDefault();
|
||||
if (plugin != null)
|
||||
{
|
||||
throw new Exception("cutlet-docker server URL is not set in settings.");
|
||||
result = await plugin.GetTransliterationAsync(text, PhoneticHelper.RomanCode);
|
||||
}
|
||||
|
||||
var request = new CutletDockerRequest { Text = text };
|
||||
var reqJson = System.Text.Json.JsonSerializer.Serialize(request, SourceGenerationContext.Default.CutletDockerRequest);
|
||||
|
||||
var url = $"{_settingsService.AppSettings.TranslationSettings.CutletDockerServer}/convert";
|
||||
var response = await _httpClient.PostAsync(url, new StringContent(reqJson, Encoding.UTF8, "application/json"));
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
var resJson = await response.Content.ReadAsStringAsync(token);
|
||||
|
||||
var result = System.Text.Json.JsonSerializer.Deserialize(resJson, SourceGenerationContext.Default.CutletDockerResponse);
|
||||
return result?.RomajiText ?? string.Empty;
|
||||
return result ?? "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>مثال: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>المدة</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>جارٍ تحميل الكلمات...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>لا يمكن عرض المقطوعات لأن المسار غير موجود</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>سياسة الخصوصية</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>منطقة قابلة للسحب</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>EaseInOutBack</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>EaseInOutBounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>EaseInOutCirc</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>EaseInOutCubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>EaseInOutElastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>EaseInOutExpo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuad</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuart</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuint</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>EaseInOutSine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>فرض البقاء في المقدمة</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>فرض محاكاة تأثير كلمة بكلمة حتى إذا كانت الكلمات الحالية لا تحتوي على معلومات كلمة بكلمة</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>فرض تفعيل تأثير الكلمات كلمة بكلمة</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>معدل إطارات التصيير (FPS)</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>بعد الاستيراد الناجح، سيقوم البرنامج بإعادة التشغيل تلقائياً</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>ستعطى الأولوية لقراءة النقل الصوتي داخل ملف الكلمات، وإذا لم يوجد تطابق، سيتم طلب نقل صوتي آلي من خادم cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>الصوتيات اليابانية</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>اختصار تبديل حالة نافذة الكلمات</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>استراتيجية الرسوم المتحركة كلمة بكلمة</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>دائماً</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>السيارات</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>أبداً</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>سيؤثر ضبط هذه القيمة على نتائج البحث المتسلسل والبحث بأفضل تطابق، ولكنه لن يؤثر على نتائج البحث في واجهة البحث اليدوي عن الكلمات</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>اختصار التشغيل والإيقاف المؤقت</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>اختصار الأغنية السابقة</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>النشاط بالساعة</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>كل الوقت</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>مخصص</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>z. B. http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Dauer</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Songtext wird geladen...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Titel können nicht angezeigt werden, da der Pfad nicht existiert</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Datenschutzrichtlinie</value>
|
||||
</data>
|
||||
@@ -795,35 +810,38 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Ziehbereich</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<value>Back Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<value>Bounce Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<value>Circular Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>Bounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<value>Cubic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>Circular</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<value>Elastic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>Cubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<value>Exponential Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>Elastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>Exponential</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<value>Quartic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<value>Quintic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>Quartic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<value>Sine Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>Quintic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>Sine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
<value>Linear</value>
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Immer im Vordergrund erzwingen</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Wort-für-Wort-Simulation erzwingen, auch wenn der aktuelle Songtext keine entsprechenden Infos enthält</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Wort-für-Wort-Effekt erzwingen</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>Rendering-FPS</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>Die App startet nach erfolgreichem Import automatisch neu</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Priorisiere Transliterationen innerhalb des Songtextes; falls keine Übereinstimmung gefunden wird, fordere maschinelle Transliteration vom cutlet-docker-Server an</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Japanische Lautschrift</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Tastenkürzel für Songtext-Fensterstatuswechsel</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Wort-für-Wort-Animationsstrategie</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Immer</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Auto</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Niemals</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Das Anpassen dieses Wertes beeinflusst die sequenzielle Suche und die Suche nach der besten Übereinstimmung, hat jedoch keinen Einfluss auf die Suchergebnisse in der manuellen Songtext-Suchoberfläche</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Tastenkürzel für Wiedergabe/Pause</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Tastenkürzel für vorherigen Titel</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Aktivität nach Stunden</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Alle Zeiten</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Benutzerdefiniert</value>
|
||||
</data>
|
||||
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>e.g. http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Duration</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Loading lyrics...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Unable to view tracks because the path does not exist</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value>Install plugin</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value>No plugins installed</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value>Plugin Manager</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value>Uninstall plugin</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Privacy Policy</value>
|
||||
</data>
|
||||
@@ -795,35 +810,47 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Draggable Area</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<value>Back Ease In-Out</value>
|
||||
<data name="SettingsPageEasingMode.Header" xml:space="preserve">
|
||||
<value>Easing Mode</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<value>Bounce Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeIn.Content" xml:space="preserve">
|
||||
<value>In</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<value>Circular Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeInOut.Content" xml:space="preserve">
|
||||
<value>In-Out</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<value>Cubic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value>Out</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<value>Elastic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<value>Exponential Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>Bounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>Circular</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<value>Quartic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>Cubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<value>Quintic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>Elastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<value>Sine Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>Exponential</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>Quartic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>Quintic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>Sine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
<value>Linear</value>
|
||||
@@ -888,12 +915,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Force Always on Top</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Force word-by-word simulation even if current lyrics don't have word-by-word info</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Force Word-by-Word Effect</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>Render FPS</value>
|
||||
</data>
|
||||
@@ -927,9 +948,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>The app will restart automatically after successful import</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Prioritize reading transliteration within lyrics; if no match, request machine transliteration from cutlet-docker server</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Japanese Phonetic</value>
|
||||
</data>
|
||||
@@ -1140,6 +1158,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Lyrics Window Status Switch Shortcut</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Word-by-word Animation Strategy</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Always</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Auto</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Never</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Adjusting this value will affect sequential search and best match search results, but will not affect search results in the manual lyrics search interface</value>
|
||||
</data>
|
||||
@@ -1245,6 +1275,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Play/Pause Shortcut</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value>Plugins</value>
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Previous Track Shortcut</value>
|
||||
</data>
|
||||
@@ -1470,6 +1503,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Activity by Hour</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>All Time</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Custom</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>ej. http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Duración</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Cargando letra...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>No se pueden ver las pistas porque la ruta no existe</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Política de privacidad</value>
|
||||
</data>
|
||||
@@ -795,35 +810,41 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Área arrastrable</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<value>Back Ease In-Out</value>
|
||||
<data name="SettingsPageEasingMode.Header" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<value>Bounce Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<value>Circular Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<value>Cubic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>Bounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<value>Elastic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>Circular</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<value>Exponential Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>Cubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>Elastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<value>Quartic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>Exponential</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<value>Quintic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<value>Sine Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>Quartic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>Quintic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>Sine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
<value>Lineal</value>
|
||||
@@ -888,12 +909,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Forzar siempre visible</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Forzar simulación palabra por palabra incluso si la letra actual no tiene información palabra por palabra</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Forzar efecto palabra por palabra</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>FPS de renderizado</value>
|
||||
</data>
|
||||
@@ -927,9 +942,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>La aplicación se reiniciará automáticamente después de una importación exitosa</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Priorizar la lectura de transliteración dentro de la letra; si no hay coincidencia, solicitar transliteración automática al servidor cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Fonética japonesa</value>
|
||||
</data>
|
||||
@@ -1140,6 +1152,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Atajo de cambio de estado de ventana de letras</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Estrategia de animación palabra por palabra</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Siempre</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Auto</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Nunca</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Ajustar este valor afectará a la búsqueda secuencial y a los resultados de la búsqueda de mejor coincidencia, pero no afectará a los resultados de búsqueda en la interfaz de búsqueda manual de letras</value>
|
||||
</data>
|
||||
@@ -1245,6 +1269,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Atajo de Reproducir/Pausar</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Atajo de pista anterior</value>
|
||||
</data>
|
||||
@@ -1470,6 +1497,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Actividad por horas</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Todos los tiempos</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>A medida</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>ex : http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Durée de l'accord</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Chargement des paroles...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Impossible d'afficher les pistes car le chemin n'existe pas</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Politique de confidentialité</value>
|
||||
</data>
|
||||
@@ -795,35 +810,38 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Zone déplaçable</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<value>Back Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<value>Bounce Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<value>Circular Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>Bounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<value>Cubic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>Circular</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<value>Elastic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>Cubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<value>Exponential Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>Elastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>Exponential</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<value>Quartic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<value>Quintic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>Quartic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<value>Sine Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>Quintic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>Sine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
<value>Linéaire</value>
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Forcer toujours au premier plan</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Forcer la simulation mot à mot même si les paroles n'ont pas d'infos mot à mot</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Forcer l'effet mot à mot</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>FPS de rendu</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>L'application redémarrera automatiquement après une importation réussie</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Prioriser la lecture de la translittération dans les paroles ; si aucune correspondance, demander une translittération automatique au serveur cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Phonétique japonaise</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Raccourci changement état fenêtre paroles</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Stratégie d'animation mot à mot</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Toujours</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Auto</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Jamais</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>L'ajustement de cette valeur affectera les résultats de la recherche séquentielle et de la meilleure correspondance, mais n'affectera pas les résultats de la recherche manuelle</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Raccourci Lecture/Pause</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Raccourci piste précédente</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Activité par heure</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Tout le temps</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Sur mesure</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>उदाहरण http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>समयांतराल</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>बोल लोड हो रहे हैं...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>ट्रैक देखने में असमर्थ क्योंकि पथ मौजूद नहीं है</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>गोपनीयता नीति</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>खींचने योग्य क्षेत्र</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>EaseInOutBack</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>EaseInOutBounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>EaseInOutCirc</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>EaseInOutCubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>EaseInOutElastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>EaseInOutExpo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuad</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuart</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuint</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>EaseInOutSine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>हमेशा शीर्ष पर रखने के लिए बाध्य करें</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>शब्द-दर-शब्द प्रभाव का अनुकरण करने के लिए बाध्य करें, भले ही वर्तमान बोल में शब्द-दर-शब्द जानकारी न हो</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>शब्द-दर-शब्द प्रभाव सक्षम करने के लिए बाध्य करें</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>रेंडरिंग फ्रेम दर</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>सफल आयात के बाद, प्रोग्राम स्वचालित रूप से पुनरारंभ हो जाएगा</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>बोल के भीतर लिप्यंतरण पढ़ने को प्राथमिकता दी जाएगी, यदि कोई मेल नहीं मिलता है तो cutlet-docker सर्वर से मशीनी लिप्यंतरण का अनुरोध किया जाएगा</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>जापानी ध्वन्यात्मकता</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>बोल विंडो स्थिति स्विच शॉर्टकट</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>शब्द-दर-शब्द एनिमेशन रणनीति</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>हमेशा</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>स्वतः</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>कभी नहीं</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>इस मान को समायोजित करने से अनुक्रमिक खोज और सर्वोत्तम मिलान खोज परिणाम प्रभावित होंगे, लेकिन मैनुअल बोल खोज इंटरफ़ेस में खोज परिणाम प्रभावित नहीं होंगे</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>प्ले और पॉज़ शॉर्टकट</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>पिछला ट्रैक शॉर्टकट</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>घंटे के हिसाब से गतिविधि</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>अब तक के सारे</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>कस्टम</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Contoh: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Durasi</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Memuat lirik...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Tidak dapat melihat trek karena jalur tidak ada</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Kebijakan Privasi</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Area yang Dapat Diseret</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>EaseInOutBack</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>EaseInOutBounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>EaseInOutCirc</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>EaseInOutCubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>EaseInOutElastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>EaseInOutExpo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuad</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuart</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuint</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>EaseInOutSine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Paksa Selalu di Atas</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Paksa simulasi efek kata-demi-kata meskipun lirik saat ini tidak memiliki informasi kata-demi-kata</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Paksa Aktifkan Efek Kata-demi-Kata</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>Frame Rate Rendering</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>Setelah impor berhasil, program akan dimuat ulang secara otomatis</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Akan memprioritaskan membaca transliterasi di dalam lirik, jika tidak ada kecocokan maka akan meminta transliterasi mesin dari server cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Fonetik Bahasa Jepang</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Pintasan Pengalih Status Jendela Lirik</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Strategi Animasi Kata per Kata</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Selalu</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Otomatis</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Tidak pernah</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Menyesuaikan nilai ini akan memengaruhi hasil pencarian berurutan dan pencarian kecocokan terbaik, tetapi tidak akan memengaruhi hasil pencarian di antarmuka pencarian manual lirik</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Pintasan Putar dan Jeda</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Pintasan Lagu Sebelumnya</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Aktivitas per Jam</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Semua Waktu</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Kustom</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>例: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>持続時間</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>歌詞を読み込んでいます…</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>パスが存在しないため、曲を表示できません</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>個人情報保護方針</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>ドラッグ可能エリア</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>バックイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>バウンスイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>サーキュラーイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>キュービックイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>エラスティックイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>エキスポネンシャルイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>クアドラティックイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>クオートイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>クイントイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>サインイーズ イン アウト</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>常にトップに強制的に表示</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>現在の歌詞に文字単位の情報がない場合でも、文字単位の歌詞シミュレーションをします</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>文字単位の歌詞効果を強制する</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>描画 FPS</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>インポートが成功すると、アプリは自動的に再起動します</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>歌詞内の音訳を優先します。一致しない場合は、cutlet-docker サーバーからマシンの音訳を要求します</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>ローマ字ルビ</value>
|
||||
</data>
|
||||
@@ -1054,7 +1063,7 @@
|
||||
<value>カスタム</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsFontFamily.Header" xml:space="preserve">
|
||||
<value>フォントファミリー</value>
|
||||
<value>フォント</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsFontSize.Header" xml:space="preserve">
|
||||
<value>フォントサイズ</value>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>歌詞ウィンドウスイッチャーのショートカットキー</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>文字単位の効果方式</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>常に</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>自動</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>なし</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>この値を調整すると、順次検索とベストマッチ検索の結果に影響しますが、手動歌詞検索インターフェイスの検索結果には影響しません</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>再生/一時停止のショートカットキー</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>次のトラックのショートカットキー</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>アクティブ時間帯</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>全期間</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>カスタム</value>
|
||||
</data>
|
||||
@@ -1483,7 +1510,7 @@
|
||||
<value>最多アクティブ</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlRecording.Title" xml:space="preserve">
|
||||
<value>再生記録中...</value>
|
||||
<value>再生履歴記録中...</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlSources.Text" xml:space="preserve">
|
||||
<value>再生ソース</value>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>예: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>기간</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>가사 불러오는 중...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>경로가 존재하지 않아 트랙을 볼 수 없습니다</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>개인정보 처리방침</value>
|
||||
</data>
|
||||
@@ -795,35 +810,38 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>드래그 가능 영역</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<value>Back Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<value>Bounce Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<value>Circular Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>Bounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<value>Cubic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>Circular</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<value>Elastic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>Cubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<value>Exponential Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>Elastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>Exponential</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<value>Quartic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<value>Quintic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>Quartic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<value>Sine Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>Quintic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>Sine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
<value>Linear (선형)</value>
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>항상 위에 표시 강제</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>현재 가사에 글자 단위 정보가 없더라도 글자 단위 시뮬레이션을 강제합니다</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>단어 단위 효과 강제 적용</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>렌더링 FPS</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>가져오기가 성공하면 프로그램이 자동으로 다시 시작됩니다</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>가사 내의 발음 표기를 우선적으로 읽습니다. 일치하는 항목이 없으면 cutlet-docker 서버에 기계 음역을 요청합니다</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>일본어 발음 표기</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>가사 창 상태 전환 단축키</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>단어별 애니메이션 전략</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>항상</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>자동</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>절대로</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>이 값을 조정하면 순차 검색 및 최적 일치 검색 결과에 영향을 미치지만 수동 가사 검색 인터페이스의 검색 결과에는 영향을 미치지 않습니다</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>재생 및 일시정지 단축키</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>이전 곡 단축키</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>시간별 활동</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>모든 시간</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>사용자 지정</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Contoh: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Durasi</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Memuatkan lirik...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Tidak dapat melihat trek kerana laluan tidak wujud</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Dasar Privasi</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Kawasan Boleh Diseret</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>EaseInOutBack</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>EaseInOutBounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>EaseInOutCirc</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>EaseInOutCubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>EaseInOutElastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>EaseInOutExpo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuad</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuart</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuint</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>EaseInOutSine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Paksa Sentiasa di Atas</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Paksa simulasi kesan perkataan-demi-perkataan walaupun lirik semasa tidak mempunyai maklumat perkataan-demi-perkataan</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Paksa Dayakan Kesan Perkataan-demi-Perkataan</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>Kadar Bingkai Penyajian (FPS)</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>Selepas import berjaya, program akan dimulakan semula secara automatik</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Akan mengutamakan pembacaan transliterasi dalam lirik, jika tiada padanan maka akan meminta transliterasi mesin daripada pelayan cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Fonetik Bahasa Jepun</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Pintasan Tukar Status Tetingkap Lirik</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Strategi Animasi Perkataan demi Perkataan</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Sentiasa</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Automatik</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Tak pernah</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Melaraskan nilai ini akan mempengaruhi hasil carian jujukan dan carian padanan terbaik, tetapi tidak akan mempengaruhi hasil carian dalam antara muka carian lirik manual</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Pintasan Main dan Jeda</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Pintasan Lagu Sebelumnya</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Aktiviti mengikut Jam</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Semua</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Tersuai</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Exemplo: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Duração</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>A carregar a letra...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Não foi possível ver as faixas porque o caminho não existe</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Política de Privacidade</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Área de Arrastar</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>EaseInOutBack</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>EaseInOutBounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>EaseInOutCirc</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>EaseInOutCubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>EaseInOutElastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>EaseInOutExpo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuad</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuart</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuint</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>EaseInOutSine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Forçar Sempre no Topo</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Forçar a simulação do efeito palavra por palavra, mesmo que a letra atual não tenha informações palavra por palavra</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Forçar Efeito Palavra por Palavra</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>Taxa de Fotogramas de Renderização</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>Após a importação bem-sucedida, o programa será reiniciado automaticamente</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Dará prioridade à leitura da transliteração dentro da letra; se não houver correspondência, solicitará transliteração automática ao servidor cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Fonética Japonesa</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Atalho de Alternância de Estado da Janela</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Estratégia de animação palavra a palavra</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Sempre</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Automóvel</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Nunca</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Ajustar este valor afetará os resultados da pesquisa sequencial e de melhor correspondência, mas não afetará os resultados na interface de pesquisa manual de letras</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Atalho para Reproduzir e Pausar</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Atalho para Faixa Anterior</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Atividade por hora</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Todo o tempo</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Personalizado</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>например, http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Продолжительность</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Загрузка текста...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Невозможно просмотреть треки, так как путь не существует</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Политика конфиденциальности</value>
|
||||
</data>
|
||||
@@ -795,35 +810,38 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Перетаскиваемая область</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<value>Back Ease In-Out</value>
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<value>Bounce Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>Back</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<value>Circular Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>Bounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<value>Cubic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>Circular</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<value>Elastic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>Cubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<value>Exponential Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>Elastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>Exponential</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<value>Quartic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>Quadratic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<value>Quintic Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>Quartic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<value>Sine Ease In-Out</value>
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>Quintic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>Sine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
<value>Linear</value>
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Принудительно поверх всех окон</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Принудительно имитировать пословный эффект, даже если текущий текст не имеет пословной информации</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Принудительно включить пословный эффект</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>FPS рендеринга</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>После успешного импорта приложение перезапустится автоматически</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Приоритет отдается чтению транслитерации внутри текста; если совпадений нет, запрашивается машинная транслитерация у сервера cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Японская фонетика</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Горячая клавиша переключения состояния окна</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Стратегия словесной анимации</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Всегда</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Авто</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Никогда</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Настройка этого значения повлияет на результаты последовательного поиска и поиска лучшего совпадения, но не повлияет на результаты в интерфейсе ручного поиска</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Горячая клавиша Воспроизведение/Пауза</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Горячая клавиша предыдущего трека</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Активность по часам</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Все время</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Пользовательское</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>ตัวอย่าง http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>ระยะเวลา</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>กำลังโหลดเนื้อเพลง...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>ไม่สามารถดูแทร็กได้เนื่องจากเส้นทางไม่มีอยู่</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>นโยบายความเป็นส่วนตัว</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>พื้นที่ลาก</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>EaseInOutBack</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>EaseInOutBounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>EaseInOutCirc</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>EaseInOutCubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>EaseInOutElastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>EaseInOutExpo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuad</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuart</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuint</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>EaseInOutSine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>บังคับให้อยู่บนสุดเสมอ</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>บังคับจำลองเอฟเฟกต์ทีละคำแม้ว่าเนื้อเพลงปัจจุบันจะไม่มีข้อมูลทีละคำ</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>บังคับเปิดใช้เอฟเฟกต์ทีละคำ</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>เฟรมเรตการเรนเดอร์</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>หลังจากนำเข้าสำเร็จ โปรแกรมจะรีสตาร์ทอัตโนมัติ</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>จะให้ความสำคัญกับการอ่านคำอ่านในเนื้อเพลงก่อน หากไม่พบจะขอคำอ่านจากเครื่องผ่านเซิร์ฟเวอร์ cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>คำอ่านภาษาญี่ปุ่น</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>ทางลัดสลับสถานะหน้าต่างเนื้อเพลง</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>กลยุทธ์การสร้างแอนิเมชันแบบคำต่อคำ</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>เสมอ</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>ออโต้</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>ไม่เคย</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>การปรับค่านี้จะมีผลกับผลการค้นหาแบบตามลำดับและแบบตรงกันที่สุด แต่จะไม่มีผลกับผลการค้นหาในหน้าค้นหาเนื้อเพลงด้วยตนเอง</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>ทางลัดเล่นและหยุดชั่วคราว</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>ทางลัดเพลงก่อนหน้า</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>กิจกรรมตามชั่วโมง</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>ตลอดเวลา</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>กำหนดเอง</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Ví dụ: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>Thời gian</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Đang tải lời bài hát...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Không thể xem các bài hát vì đường dẫn không tồn tại</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>Chính sách bảo mật</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>Vùng có thể kéo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>EaseInOutBack</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>EaseInOutBounce</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>EaseInOutCirc</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>EaseInOutCubic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>EaseInOutElastic</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>EaseInOutExpo</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuad</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuart</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>EaseInOutQuint</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>EaseInOutSine</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>Buộc luôn ở trên cùng</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>Buộc mô phỏng hiệu ứng từng từ ngay cả khi lời bài hát hiện tại không có thông tin từng từ</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>Buộc bật hiệu ứng từng từ</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>Tốc độ khung hình kết xuất</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>Sau khi nhập thành công, chương trình sẽ tự động khởi động lại</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>Sẽ ưu tiên đọc phiên âm trong lời bài hát, nếu không khớp sẽ yêu cầu phiên âm máy từ máy chủ cutlet-docker</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>Phiên âm tiếng Nhật</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>Phím tắt chuyển trạng thái cửa sổ lời bài hát</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>Chiến lược hoạt hình từng từ</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>Luôn luôn</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>Tự động</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>Không bao giờ</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>Điều chỉnh giá trị này sẽ ảnh hưởng đến kết quả tìm kiếm tuần tự và khớp nhất, nhưng sẽ không ảnh hưởng đến kết quả tìm kiếm trong giao diện tìm kiếm lời bài hát thủ công</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>Phím tắt phát và tạm dừng</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>Phím tắt bài hát trước</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>Hoạt động theo giờ</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>Mọi thời đại</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>Tùy chỉnh</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>例如 http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>持续时间</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>加载歌词中...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>无法查看曲目,因为路径不存在</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value>安装插件</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value>未安装任何插件</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value>插件管理</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value>卸载插件</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>隐私政策</value>
|
||||
</data>
|
||||
@@ -795,35 +810,47 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>可拖动区域</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<value>回弹缓入缓出</value>
|
||||
<data name="SettingsPageEasingMode.Header" xml:space="preserve">
|
||||
<value>缓动类型</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<value>弹跳缓入缓出</value>
|
||||
<data name="SettingsPageEasingModeIn.Content" xml:space="preserve">
|
||||
<value>缓入</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<value>圆形缓入缓出</value>
|
||||
<data name="SettingsPageEasingModeInOut.Content" xml:space="preserve">
|
||||
<value>缓出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<value>三次缓入缓出</value>
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value>缓入缓出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<value>弹性缓入缓出</value>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>回弹</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<value>指数缓入缓出</value>
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>弹跳</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<value>二次缓入缓出</value>
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>圆形</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<value>四次缓入缓出</value>
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>三次</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<value>五次缓入缓出</value>
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>弹性</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<value>正弦缓入缓出</value>
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>指数</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>二次</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>四次</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>五次</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>正弦</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
<value>线性</value>
|
||||
@@ -888,12 +915,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>强制置于顶层</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>即使当前歌词没有逐字信息,仍强制模拟逐字效果</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>强制启用逐字歌词效果</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>渲染帧率</value>
|
||||
</data>
|
||||
@@ -927,9 +948,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>导入成功后,该程序将自动重新启动</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>将优先读取歌词内音译,若无匹配则向 cutlet-docker 服务器请求机器音译</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>日语注音</value>
|
||||
</data>
|
||||
@@ -1140,6 +1158,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>歌词窗口状态切换快捷键</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>逐字动画策略</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>总是</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>自动</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>从不</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>调整此值将影响顺序搜索和最佳匹配搜索结果,但不会影响手动歌词搜索界面中的搜索结果</value>
|
||||
</data>
|
||||
@@ -1245,6 +1275,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>播放与暂停快捷键</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value>插件</value>
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>上一曲目快捷键</value>
|
||||
</data>
|
||||
@@ -1470,6 +1503,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>活跃时段</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>全部时间</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>自定义</value>
|
||||
</data>
|
||||
|
||||
@@ -59,46 +59,46 @@
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string"/>
|
||||
<xsd:attribute name="type" type="xsd:string"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string"/>
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
|
||||
<xsd:attribute ref="xml:space"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
@@ -243,6 +243,9 @@
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>例如 http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsEffectSettingsControlAnimationDuration.Header" xml:space="preserve">
|
||||
<value>時間長度</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>載入歌詞中...</value>
|
||||
</data>
|
||||
@@ -552,6 +555,18 @@
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>無法檢視曲目,因為路徑不存在</value>
|
||||
</data>
|
||||
<data name="PluginManagerControlInstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlNoPluginsInstalled.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlTitle.Text" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PluginManagerControlUninstall.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="PrivacyPolicy.Content" xml:space="preserve">
|
||||
<value>隱私權政策</value>
|
||||
</data>
|
||||
@@ -795,34 +810,37 @@
|
||||
<data name="SettingsPageDragArea.Header" xml:space="preserve">
|
||||
<value>可拖曳區域</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBack.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingModeOut.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseBack.Content" xml:space="preserve">
|
||||
<value>回彈緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutBounce.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseBounce.Content" xml:space="preserve">
|
||||
<value>彈跳緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCirc.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCirc.Content" xml:space="preserve">
|
||||
<value>圓形緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutCubic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseCubic.Content" xml:space="preserve">
|
||||
<value>三次緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutElastic.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseElastic.Content" xml:space="preserve">
|
||||
<value>彈性緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutExpo.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseExpo.Content" xml:space="preserve">
|
||||
<value>指數緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuad.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuad.Content" xml:space="preserve">
|
||||
<value>二次緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuart.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuart.Content" xml:space="preserve">
|
||||
<value>四次緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutQuint.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseQuint.Content" xml:space="preserve">
|
||||
<value>五次緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeEaseInOutSine.Content" xml:space="preserve">
|
||||
<data name="SettingsPageEasingTypeEaseSine.Content" xml:space="preserve">
|
||||
<value>正弦緩入緩出</value>
|
||||
</data>
|
||||
<data name="SettingsPageEasingTypeLinear.Content" xml:space="preserve">
|
||||
@@ -888,12 +906,6 @@
|
||||
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
|
||||
<value>強制置於頂層</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
|
||||
<value>即使目前歌詞沒有逐字資訊,仍強制模擬逐字效果</value>
|
||||
</data>
|
||||
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
|
||||
<value>強制啟用逐字歌詞效果</value>
|
||||
</data>
|
||||
<data name="SettingsPageFPS.Header" xml:space="preserve">
|
||||
<value>渲染畫面播放速率</value>
|
||||
</data>
|
||||
@@ -927,9 +939,6 @@
|
||||
<data name="SettingsPageImportSettingsInfo.Content" xml:space="preserve">
|
||||
<value>匯入成功後,該程式將自動重新啟動</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Description" xml:space="preserve">
|
||||
<value>將優先讀取歌詞內音譯,若無符合則向 cutlet-docker 伺服器請求機器音譯</value>
|
||||
</data>
|
||||
<data name="SettingsPageJapanese.Header" xml:space="preserve">
|
||||
<value>日語注音</value>
|
||||
</data>
|
||||
@@ -1140,6 +1149,18 @@
|
||||
<data name="SettingsPageLyricsWindowSwitchHotKey.Header" xml:space="preserve">
|
||||
<value>歌詞視窗狀態切換快速鍵</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectMode.Header" xml:space="preserve">
|
||||
<value>逐字動畫策略</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAlways.Content" xml:space="preserve">
|
||||
<value>永遠</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeAuto.Content" xml:space="preserve">
|
||||
<value>自動</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsWordByWordEffectModeNever.Content" xml:space="preserve">
|
||||
<value>從不</value>
|
||||
</data>
|
||||
<data name="SettingsPageMatchingThreshold.Description" xml:space="preserve">
|
||||
<value>調整此值將影響順序搜尋和最佳符合搜尋結果,但不會影響手動歌詞搜尋介面中的搜尋結果</value>
|
||||
</data>
|
||||
@@ -1245,6 +1266,9 @@
|
||||
<data name="SettingsPagePlayOrPauseSongHotKey.Header" xml:space="preserve">
|
||||
<value>播放與暫停快速鍵</value>
|
||||
</data>
|
||||
<data name="SettingsPagePlugins.Content" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="SettingsPagePreviousSongHotKey.Header" xml:space="preserve">
|
||||
<value>上一曲目快速鍵</value>
|
||||
</data>
|
||||
@@ -1470,6 +1494,9 @@
|
||||
<data name="StatsDashboardControlActivityByHour.Text" xml:space="preserve">
|
||||
<value>每小時的活動</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlAllTime.Content" xml:space="preserve">
|
||||
<value>所有時間</value>
|
||||
</data>
|
||||
<data name="StatsDashboardControlCustom.Content" xml:space="preserve">
|
||||
<value>自訂</value>
|
||||
</data>
|
||||
|
||||
@@ -2,27 +2,35 @@
|
||||
using BetterLyrics.WinUI3.Helper.BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.LyricsCacheService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using WinRT.Interop;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
public partial class AboutControlViewModel : BaseViewModel
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILyricsCacheService _lyricsCacheService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AppSettings AppSettings { get; set; }
|
||||
|
||||
public AboutControlViewModel(ISettingsService settingsService)
|
||||
public AboutControlViewModel(ISettingsService settingsService, ILyricsCacheService lyricsCacheService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_lyricsCacheService = lyricsCacheService;
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
}
|
||||
|
||||
@@ -47,18 +55,34 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[RelayCommand]
|
||||
private async Task ImportSettingsAsync()
|
||||
{
|
||||
var file = await PickerHelper.PickSingleFileAsync<SettingsWindow>([".json"]);
|
||||
var file = await PickerHelper.PickSingleFileAsync<SettingsWindow>([".zip"]);
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
var succeed = _settingsService.ImportSettings(file.Path);
|
||||
if (succeed)
|
||||
try
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
|
||||
SqliteConnection.ClearAllPools();
|
||||
|
||||
string tempExtractPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempExtractPath);
|
||||
|
||||
using (var stream = await file.OpenStreamForReadAsync())
|
||||
{
|
||||
ZipFile.ExtractToDirectory(stream, tempExtractPath);
|
||||
}
|
||||
|
||||
DirectoryHelper.CopyDirectory(tempExtractPath, PathHelper.LocalFolder, true);
|
||||
|
||||
Directory.Delete(tempExtractPath, true);
|
||||
|
||||
WindowHook.RestartApp();
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
ToastHelper.ShowToast("ImportSettingsFailed", null, InfoBarSeverity.Error);
|
||||
ToastHelper.ShowToast("ImportSettingsFailed", ex.Message, InfoBarSeverity.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,31 +90,49 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[RelayCommand]
|
||||
private async Task ExportSettingsAsync()
|
||||
{
|
||||
var folder = await PickerHelper.PickSingleFolderAsync<SettingsWindow>();
|
||||
|
||||
if (folder != null)
|
||||
try
|
||||
{
|
||||
_settingsService.ExportSettings(folder.Path);
|
||||
var suggestedFileName = $"{Constants.App.AppName}_{_settingsService.AppSettings.Version}_{DateTime.Now:yyyyMMdd_HHmmss}";
|
||||
IDictionary<string, IList<string>> fileTypeChoices = new Dictionary<string, IList<string>>()
|
||||
{
|
||||
{ "Zip Archive", new List<string>() { ".zip" } }
|
||||
};
|
||||
|
||||
var destinationFile = await PickerHelper.PickSaveFileAsync<SettingsWindow>(fileTypeChoices, suggestedFileName);
|
||||
if (destinationFile == null) return;
|
||||
|
||||
string tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
DirectoryHelper.CopyDirectory(PathHelper.LocalFolder, tempDir, true);
|
||||
|
||||
string tempZipPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".zip");
|
||||
|
||||
ZipFile.CreateFromDirectory(tempDir, tempZipPath);
|
||||
|
||||
using (var sourceStream = File.OpenRead(tempZipPath))
|
||||
using (var destStream = await destinationFile.OpenStreamForWriteAsync())
|
||||
{
|
||||
sourceStream.CopyTo(destStream);
|
||||
destStream.SetLength(sourceStream.Length);
|
||||
}
|
||||
|
||||
Directory.Delete(tempDir, true);
|
||||
File.Delete(tempZipPath);
|
||||
|
||||
ToastHelper.ShowToast("ExportSettingsSuccess", null, InfoBarSeverity.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ToastHelper.ShowToast("Error", ex.Message, InfoBarSeverity.Error);
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ExportPlayHistoryAsync()
|
||||
private async Task ClearCacheFilesAsync()
|
||||
{
|
||||
var folder = await PickerHelper.PickSingleFolderAsync<SettingsWindow>();
|
||||
await _lyricsCacheService.ClearCacheAsync();
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
var dest = Path.Combine(folder.Path, $"BetterLyrics_Play_History_Export_{DateTime.Now:yyyyMMdd_HHmmss}.db");
|
||||
await FileHelper.CopyFileAsync(PathHelper.PlayHistoryPath, dest);
|
||||
ToastHelper.ShowToast("ExportSettingsSuccess", null, InfoBarSeverity.Success);
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void ClearCacheFiles()
|
||||
{
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.LogDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.LyricsCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.iTunesAlbumArtCacheDirectory);
|
||||
|
||||
@@ -39,9 +39,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[ObservableProperty]
|
||||
public partial bool IsLibreTranslateServerTesting { get; set; } = false;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsCutletDockerServerTesting { get; set; } = false;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsLXMusicServerTesting { get; set; } = false;
|
||||
|
||||
@@ -125,35 +122,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
});
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CutletDockerServerTest()
|
||||
{
|
||||
IsCutletDockerServerTesting = true;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = await _transliterationService.TransliterateText(
|
||||
"こんにちは", PhoneticHelper.RomanCode, new System.Threading.CancellationToken());
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
ToastHelper.ShowToast("SettingsPageServerTestSuccessInfo", null, InfoBarSeverity.Success);
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
ToastHelper.ShowToast("SettingsPageServerTestFailedInfo", null, InfoBarSeverity.Error);
|
||||
});
|
||||
}
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
IsCutletDockerServerTesting = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task LastFMAuthAsync()
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user