mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-13 03:34:55 +08:00
Compare commits
50 Commits
v1.0.90.0
...
v1.0.112.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8288d62af2 | ||
|
|
bd82deb5ae | ||
|
|
5093939bff | ||
|
|
340a41f920 | ||
|
|
3580f2eb0e | ||
|
|
2e792b50b2 | ||
|
|
7a063a1192 | ||
|
|
8485990250 | ||
|
|
fb16874d60 | ||
|
|
87afdf539a | ||
|
|
ce9cb23d6f | ||
|
|
27629a298b | ||
|
|
0d051669fc | ||
|
|
a19a97345c | ||
|
|
8f12c27d2a | ||
|
|
92f2f20957 | ||
|
|
272802214b | ||
|
|
7f8455b14e | ||
|
|
ad421a5541 | ||
|
|
1eb1d2d72b | ||
|
|
252b7e4b25 | ||
|
|
bebcfa7819 | ||
|
|
073ddfcaee | ||
|
|
1775d947f9 | ||
|
|
a5d1831717 | ||
|
|
d4a924accf | ||
|
|
5d65314522 | ||
|
|
0684069e52 | ||
|
|
fea617ff98 | ||
|
|
4b33776340 | ||
|
|
ea73d7ed3b | ||
|
|
b8fd51cbe8 | ||
|
|
004079a7ee | ||
|
|
30d1ccf67f | ||
|
|
a24885c277 | ||
|
|
a207224bbf | ||
|
|
2c80e0815a | ||
|
|
7f65b4addb | ||
|
|
210df4dd61 | ||
|
|
3c82908890 | ||
|
|
597cc1ec9b | ||
|
|
e354e29ec1 | ||
|
|
dd5fb91764 | ||
|
|
041459e564 | ||
|
|
7de813b645 | ||
|
|
838d663834 | ||
|
|
9add190383 | ||
|
|
fa58360884 | ||
|
|
4dd032655c | ||
|
|
80984218ec |
@@ -44,7 +44,7 @@
|
||||
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
|
||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
|
||||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
|
||||
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<Identity
|
||||
Name="37412.BetterLyrics"
|
||||
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
|
||||
Version="1.0.90.0" />
|
||||
Version="1.0.112.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<!-- Merged dictionaries here -->
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.Segmented/Segmented/Segmented.xaml" />
|
||||
<ResourceDictionary Source="ms-appx:///DevWinUI.Controls/Themes/Generic.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- Theme -->
|
||||
@@ -59,14 +59,21 @@
|
||||
<converter:ShortcutToStringConverter x:Key="ShortcutToStringConverter" />
|
||||
<converter:BoolNegationToVisibilityConverter x:Key="BoolNegationToVisibilityConverter" />
|
||||
<converter:BoolToOpacityConverter x:Key="BoolToOpacityConverter" />
|
||||
<converter:BoolToPartialOpacityConverter x:Key="BoolToPartialOpacityConverter" />
|
||||
<converter:BoolNegationToOpacityConverter x:Key="BoolNegationToOpacityConverter" />
|
||||
<converter:RectToMarginConverter x:Key="RectToMarginConverter" />
|
||||
<converter:LanguageCodeToDisplayedNameConverter x:Key="LanguageCodeToDisplayedNameConverter" />
|
||||
<converter:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter" />
|
||||
<converter:DisplayLanguageCodeToIndexConverter x:Key="DisplayLanguageCodeToIndexConverter" />
|
||||
<converter:PathToParentFolderConverter x:Key="PathToParentFolderConverter" />
|
||||
<converter:TrackToLyricsConverter x:Key="TrackToLyricsConverter" />
|
||||
<converter:IntToBoolConverter x:Key="IntToBoolConverter" />
|
||||
<converter:IndexToDisplayConverter x:Key="IndexToDisplayConverter" />
|
||||
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
|
||||
<converters:ColorToDisplayNameConverter x:Key="ColorToDisplayNameConverter" />
|
||||
<converters:CollectionVisibilityConverter x:Key="CollectionVisibilityConverter" />
|
||||
|
||||
<x:Double x:Key="SettingsCardSpacing">4</x:Double>
|
||||
|
||||
@@ -302,8 +309,12 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ListViewStretchedItemContainerStyle" TargetType="ListViewItem">
|
||||
<Style
|
||||
x:Key="ListViewStretchedItemContainerStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
</Style>
|
||||
@@ -331,6 +342,16 @@
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="FlyoutGhostStyle"
|
||||
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||
TargetType="FlyoutPresenter">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
|
||||
</Style>
|
||||
|
||||
<StaticResource x:Key="ToggleButtonBackgroundChecked" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="ToggleButtonBackgroundCheckedPointerOver" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="ToggleButtonBackgroundCheckedPressed" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
|
||||
@@ -9,6 +9,7 @@ using BetterLyrics.WinUI3.Services.LibWatcherService;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.LyricsSearchService;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Services.TranslateService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
@@ -22,7 +23,6 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.Windows.ApplicationModel.Resources;
|
||||
using Serilog;
|
||||
using ShadowViewer.Controls;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
@@ -39,12 +39,6 @@ namespace BetterLyrics.WinUI3
|
||||
private readonly ILogger<App> _logger;
|
||||
|
||||
public static new App Current => (App)Application.Current;
|
||||
public static DispatcherQueue? DispatcherQueue { get; private set; }
|
||||
public static DispatcherQueueTimer? DispatcherQueueTimer { get; private set; }
|
||||
public static ResourceLoader? ResourceLoader { get; private set; }
|
||||
|
||||
public NotificationPanel? LyricsWindowNotificationPanel { get; set; }
|
||||
public NotificationPanel? SettingsWindowNotificationPanel { get; set; }
|
||||
|
||||
private static Mutex? _instanceMutex;
|
||||
|
||||
@@ -52,10 +46,6 @@ namespace BetterLyrics.WinUI3
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
DispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
DispatcherQueueTimer = DispatcherQueue.CreateTimer();
|
||||
ResourceLoader = new ResourceLoader();
|
||||
|
||||
EnsureSingleInstance();
|
||||
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
@@ -72,12 +62,11 @@ namespace BetterLyrics.WinUI3
|
||||
|
||||
private void EnsureSingleInstance()
|
||||
{
|
||||
bool createdNew;
|
||||
_instanceMutex = new Mutex(true, Constants.App.AppName, out createdNew);
|
||||
_instanceMutex = new Mutex(true, Constants.App.AppName, out bool createdNew);
|
||||
|
||||
if (!createdNew)
|
||||
{
|
||||
User32.MessageBox(HWND.NULL, ResourceLoader!.GetString("TryRunMultipleInstance"), null, User32.MB_FLAGS.MB_APPLMODAL);
|
||||
User32.MessageBox(HWND.NULL, new ResourceLoader().GetString("TryRunMultipleInstance"), null, User32.MB_FLAGS.MB_APPLMODAL);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
@@ -85,6 +74,10 @@ namespace BetterLyrics.WinUI3
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
WindowHelper.OpenOrShowWindow<LyricsWindow>();
|
||||
if (Ioc.Default.GetRequiredService<ISettingsService>().AppSettings.MusicGallerySettings.AutoOpen)
|
||||
{
|
||||
WindowHelper.OpenOrShowWindow<MusicGalleryWindow>();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ConfigureServices()
|
||||
@@ -111,6 +104,7 @@ namespace BetterLyrics.WinUI3
|
||||
.AddSingleton<ILibWatcherService, LibWatcherService>()
|
||||
.AddSingleton<ITranslateService, TranslateService>()
|
||||
.AddSingleton<ILastFMService, LastFMService>()
|
||||
.AddSingleton<IResourceService, ResourceService>()
|
||||
// ViewModels
|
||||
.AddSingleton<AppSettingsControlViewModel>()
|
||||
.AddSingleton<PlaybackSettingsControlViewModel>()
|
||||
@@ -126,6 +120,7 @@ namespace BetterLyrics.WinUI3
|
||||
.AddSingleton<LyricsPageViewModel>()
|
||||
.AddSingleton<MusicGalleryViewModel>()
|
||||
.AddSingleton<LyricsRendererViewModel>()
|
||||
.AddSingleton<AboutControlViewModel>()
|
||||
.BuildServiceProvider()
|
||||
);
|
||||
}
|
||||
|
||||
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/AMLLPlayer.png
Normal file
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/AMLLPlayer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 84 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/HyPlayer.png
Normal file
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/HyPlayer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 830 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/PlanetMusic.png
Normal file
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/PlanetMusic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
@@ -22,6 +22,7 @@
|
||||
<ItemGroup>
|
||||
<None Remove="Assets\Segoe Fluent Icons.ttf" />
|
||||
<None Remove="Assets\Wiki82.profile.xml" />
|
||||
<None Remove="Controls\AboutControl.xaml" />
|
||||
<None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" />
|
||||
<None Remove="Controls\AppSettingsControl.xaml" />
|
||||
<None Remove="Controls\DemoWindowGrid.xaml" />
|
||||
@@ -50,20 +51,16 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="3v.EvtSource" Version="2.0.0" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Controls.OpacityMaskView" Version="0.1.251021-build.2365" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.MarqueeText" Version="0.1.230830" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.OpacityMaskView" Version="0.1.250703-build.2173" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.MetadataControl" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.2.250402" />
|
||||
<PackageReference Include="csharp-kana" Version="1.0.2" />
|
||||
<PackageReference Include="csharp-pinyin" Version="1.0.1" />
|
||||
<PackageReference Include="DevWinUI.Controls" Version="9.4.2" />
|
||||
@@ -74,7 +71,7 @@
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6584" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6901" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251003001" />
|
||||
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
|
||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
@@ -82,7 +79,6 @@
|
||||
<PackageReference Include="NTextCat" Version="0.3.65" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.3-dev-02320" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="ShadowViewer.Controls.Notification" Version="1.2.1" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.10" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.10" />
|
||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
||||
@@ -92,7 +88,7 @@
|
||||
<PackageReference Include="Vanara.PInvoke.Shell32" Version="4.2.1" />
|
||||
<PackageReference Include="Vanara.PInvoke.User32" Version="4.2.1" />
|
||||
<PackageReference Include="WinUIEx" Version="2.9.0" />
|
||||
<PackageReference Include="z440.atl.core" Version="7.5.0" />
|
||||
<PackageReference Include="z440.atl.core" Version="7.6.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" />
|
||||
@@ -117,6 +113,12 @@
|
||||
<Content Update="Assets\AIMP.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AlbumArtPlaceholder.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AMLLPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AppleMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -141,6 +143,9 @@
|
||||
<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>
|
||||
@@ -180,6 +185,9 @@
|
||||
<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>
|
||||
@@ -307,6 +315,14 @@
|
||||
<Generator></Generator>
|
||||
</PRIResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="TemplateSelector\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\AboutControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<!-- Publish Properties -->
|
||||
<PropertyGroup>
|
||||
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
|
||||
|
||||
@@ -9,8 +9,9 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
public static class Link
|
||||
{
|
||||
public const string GitHubUrl = "https://github.com/jayfunc/BetterLyrics";
|
||||
public const string WikiUrl = "https://github.com/jayfunc/BetterLyrics/wiki";
|
||||
public const string AppleMusicCfgUrl = $"{WikiUrl}/Lyrics-provider-configuration#apple-music";
|
||||
public const string ShareHubUrl = $"{GitHubUrl}/blob/dev/ShareHub/index.md";
|
||||
public const string WikiUrl = $"{GitHubUrl}/wiki";
|
||||
public const string AppleMusicCfgUrl = $"{WikiUrl}/%5BEN%5D-Lyrics-provider-configuration#apple-music";
|
||||
public const string FAQUrl = $"{GitHubUrl}/blob/dev/FAQ/index.md";
|
||||
public const string QQGroupUrl = "https://qun.qq.com/universal-share/share?ac=1&authKey=4Q%2BYTq3wZldYpF5SbS5c19ECFsiYoLZFAIcBNNzYpBUtiEjaZ8sZ%2F%2BnFN0qw3lad&busi_data=eyJncm91cENvZGUiOiIxMDU0NzAwMzg4IiwidG9rZW4iOiJiVnhqemVYN0N5QVc3b1ZkR24wWmZOTUtvUkJoWm1JRWlaWW5iZnlBcXJtZUtGc2FFTHNlUlFZMi9iRm03cWF5IiwidWluIjoiMTM5NTczOTY2MCJ9&data=39UmAihyH_o6CZaOs7nk2mO_lz2ruODoDou6pxxh7utcxP4WF5sbDBDOPvZ_Wqfzeey4441anegsLYQJxkrBAA&svctype=4&tempid=h5_group_info";
|
||||
public const string DiscordUrl = "https://discord.gg/5yAQPnyCKv";
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
public static class PlayerID
|
||||
{
|
||||
public const string LXMusic = "cn.toside.music.desktop";
|
||||
public const string LXMusicPortable = "lx-music-desktop.exe";
|
||||
public const string MediaPlayerWindows11 = "Microsoft.ZuneMusic_8wekyb3d8bbwe!Microsoft.ZuneMusic";
|
||||
public const string AIMP = "AIMP.exe";
|
||||
public const string Foobar2000 = "foobar2000.exe";
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
public class PlayerName
|
||||
{
|
||||
public const string LXMusic = "LX Music";
|
||||
public const string LXMusicPortable = "LX Music (Portable)";
|
||||
public const string MediaPlayerWindows11 = "Media Player";
|
||||
public const string AIMP = "AIMP";
|
||||
public const string Foobar2000 = "foobar2000";
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.AboutControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:const="using:BetterLyrics.WinUI3.Constants"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<dev:SettingsExpander HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/Logo.png}" IsExpanded="True">
|
||||
<dev:SettingsExpander.Header>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBlock Text="BetterLyrics" />
|
||||
</StackPanel>
|
||||
</dev:SettingsExpander.Header>
|
||||
<dev:SettingsExpander.Description>
|
||||
<StackPanel
|
||||
Margin="0,2,0,0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="2">
|
||||
<TextBlock Text="©" />
|
||||
<HyperlinkButton
|
||||
Margin="0,-1,0,0"
|
||||
Content="Zhe Fang"
|
||||
NavigateUri="https://github.com/jayfunc" />
|
||||
<TextBlock Text="2025" />
|
||||
</StackPanel>
|
||||
</dev:SettingsExpander.Description>
|
||||
<RichTextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}">
|
||||
<Paragraph>
|
||||
<Run x:Uid="SettingsPageVersion" />
|
||||
<Run Text="{x:Bind helper:MetadataHelper.AppVersion}" />
|
||||
</Paragraph>
|
||||
</RichTextBlock>
|
||||
<dev:SettingsExpander.Items>
|
||||
|
||||
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock x:Uid="SetingsPageInstructions" />
|
||||
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
|
||||
<HyperlinkButton Content="GitHub" NavigateUri="{x:Bind const:Link.GitHubUrl}" />
|
||||
<HyperlinkButton Content="Wiki" NavigateUri="{x:Bind const:Link.WikiUrl}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock x:Uid="SetingsPageFeedback" />
|
||||
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
|
||||
<HyperlinkButton x:Uid="SettingsPageQQGroup" NavigateUri="{x:Bind const:Link.QQGroupUrl}" />
|
||||
<HyperlinkButton x:Uid="SettingsPageDiscord" NavigateUri="{x:Bind const:Link.DiscordUrl}" />
|
||||
<HyperlinkButton x:Uid="SettingsPageTelegram" NavigateUri="{x:Bind const:Link.TelegramUrl}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock x:Uid="SetingsPageDonation" />
|
||||
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
|
||||
<HyperlinkButton Content="Buy Me a Coffee" NavigateUri="https://buymeacoffee.com/founchoo" />
|
||||
<HyperlinkButton Content="PayPal" NavigateUri="https://paypal.me/zhefangpay" />
|
||||
<Button
|
||||
Content="支付宝"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
|
||||
Style="{StaticResource GhostButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<Flyout.FlyoutPresenterStyle>
|
||||
<Style TargetType="FlyoutPresenter">
|
||||
<Setter Property="CornerRadius" Value="12" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
</Style>
|
||||
</Flyout.FlyoutPresenterStyle>
|
||||
<Image Height="300" Source="/Assets/Alipay.jpg" />
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
<Button
|
||||
Content="微信"
|
||||
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
|
||||
Style="{StaticResource GhostButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<Flyout.FlyoutPresenterStyle>
|
||||
<Style TargetType="FlyoutPresenter">
|
||||
<Setter Property="CornerRadius" Value="12" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
</Style>
|
||||
</Flyout.FlyoutPresenterStyle>
|
||||
<Image Height="300" Source="/Assets/WeChatReward.png" />
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="*" />
|
||||
<TextBlock
|
||||
x:Uid="SetingsPageThanks"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock x:Uid="SetingsPageContributors" />
|
||||
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
|
||||
<HyperlinkButton Content="jayfunc" NavigateUri="https://github.com/jayfunc" />
|
||||
<HyperlinkButton Content="Raspberry-Monster" NavigateUri="https://github.com/Raspberry-Monster" />
|
||||
<HyperlinkButton Content="ZHider" NavigateUri="https://github.com/ZHider" />
|
||||
<HyperlinkButton Content="kusutori" NavigateUri="https://github.com/kusutori" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</dev:SettingsExpander.Items>
|
||||
<dev:SettingsExpander.ItemsFooter>
|
||||
<InfoBar
|
||||
x:Uid="SettingsPageDisclaimer"
|
||||
BorderThickness="0"
|
||||
CornerRadius="0"
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
Severity="Warning" />
|
||||
</dev:SettingsExpander.ItemsFooter>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageMockMusicPlaying">
|
||||
<HyperlinkButton x:Uid="SettingsPagePlayingMockMusicButton" NavigateUri="https://soundcloud.com/carlyraejepsen/cut-to-the-feeling" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsExpander x:Uid="SettingsPageCache" IsExpanded="True">
|
||||
<Button x:Uid="SettingsPageOpenFolderButton" Command="{x:Bind ViewModel.OpenCacheFolderCommand}" />
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard>
|
||||
<Button x:Uid="SettingsPageClearCache" Command="{x:Bind ViewModel.ClearCacheFilesCommand}" />
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageSettings">
|
||||
<Button x:Uid="SettingsPageOpenFolderButton" Command="{x:Bind ViewModel.OpenSettingsFolderCommand}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsExpander x:Uid="SettingsPageSettingsManager" IsExpanded="True">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<Button x:Uid="SettingsPageImportSettingsButton" Command="{x:Bind ViewModel.ImportSettingsCommand}" />
|
||||
<Button x:Uid="SettingsPageExportSettingsButton" Command="{x:Bind ViewModel.ExportSettingsCommand}" />
|
||||
</StackPanel>
|
||||
<dev:SettingsExpander.ItemsHeader>
|
||||
<InfoBar
|
||||
x:Uid="SettingsPageImportSettingsInfo"
|
||||
BorderThickness="0"
|
||||
CornerRadius="0"
|
||||
IsClosable="False"
|
||||
IsOpen="True"
|
||||
Severity="Warning" />
|
||||
</dev:SettingsExpander.ItemsHeader>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageDebugOverlay">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.IsDebugOverlayEnabled, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageFixedTimeStep" Visibility="Collapsed">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.AdvancedSettings.IsFixedTimeStep, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageFPS" Visibility="Collapsed">
|
||||
<uc:ExtendedSlider
|
||||
Default="60"
|
||||
Frequency="10"
|
||||
Maximum="240"
|
||||
Minimum="30"
|
||||
Value="{x:Bind ViewModel.AppSettings.AdvancedSettings.FPS, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,33 @@
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
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.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 AboutControl : UserControl
|
||||
{
|
||||
public AboutControlViewModel ViewModel => (AboutControlViewModel)DataContext;
|
||||
|
||||
public AboutControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<AboutControlViewModel>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
@@ -17,16 +18,16 @@
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAlbumArt" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageAlbumArtSize"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard IsEnabled="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard IsEnabled="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="800"
|
||||
@@ -34,49 +35,49 @@
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="px"
|
||||
Value="{x:Bind AlbumArtLayoutSettings.AlbumArtSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="12"
|
||||
Frequency="1"
|
||||
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind AlbumArtLayoutSettings.CoverImageRadius, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAlbumShadowAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageAlbumShadowAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="12"
|
||||
Frequency="1"
|
||||
|
||||
Maximum="64"
|
||||
Minimum="0"
|
||||
Value="{x:Bind AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<TextBlock x:Uid="SettingsPageSongInfo" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageSongInfoAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageSongInfoAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageSongInfoLeft" />
|
||||
<ComboBoxItem x:Uid="SettingsPageSongInfoCenter" />
|
||||
<ComboBoxItem x:Uid="SettingsPageSongInfoRight" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsFontSize"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.IsAutoSongInfoFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard>
|
||||
<local:ExtendedSlider
|
||||
Default="18"
|
||||
Frequency="2"
|
||||
@@ -84,22 +85,22 @@
|
||||
Maximum="72"
|
||||
Minimum="8"
|
||||
Value="{x:Bind AlbumArtLayoutSettings.SongInfoFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageShowTitle"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageShowArtists">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageShowArtists">
|
||||
<ToggleSwitch IsEnabled="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=OneWay}" IsOn="{x:Bind AlbumArtLayoutSettings.ShowArtists, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:globalization="using:Windows.Globalization"
|
||||
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
@@ -22,7 +23,7 @@
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAppAppearance" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageLanguage"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
@@ -36,63 +37,71 @@
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard>
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard>
|
||||
<Button x:Uid="SettingsPageRestart" Command="{x:Bind ViewModel.RestartAppCommand}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- App behavior -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAppBehavior" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoStart" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageAutoStart" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch
|
||||
x:Name="AutoStartupToggleSwitch"
|
||||
Loaded="AutoStartupToggleSwitch_Loaded"
|
||||
Unloaded="AutoStartupToggleSwitch_Unloaded" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageAutoOpenMusicGalleryWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoOpen, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageAutoPlayWhenOpenMusicGalleryWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoPlay, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageListenNewSession" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageListenNewSession" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ListenOnNewPlaybackSource, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageShowHideHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageShowHideHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBorderlessHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageBorderlessHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.BorderlessShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageClickThroughHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageClickThroughHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ClickThroughShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.LyricsWindowSwitchShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- Playback shortcut -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPagePlaybackShortcut" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PlayOrPauseShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageNextSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageNextSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.NextSongShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPagePreviousSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPagePreviousSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PreviousSongShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FrequencyProperty =
|
||||
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(1));
|
||||
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(1.0));
|
||||
public static readonly DependencyProperty MinimumProperty =
|
||||
DependencyProperty.Register(nameof(Minimum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||
public static readonly DependencyProperty MaximumProperty =
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:enums="using:BetterLyrics.WinUI3.Enums"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
@@ -18,117 +19,126 @@
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageTheme">
|
||||
<dev:SettingsCard x:Uid="SettingsPageTheme" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox x:Name="ThemeComboBox" SelectedIndex="{x:Bind LyricsBackgroundSettings.LyricsBackgroundTheme, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageFollowSystem" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageDark" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPagePureLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPagePureLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<dev:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.PureColorOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageAlbumArtLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageAlbumArtLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<dev:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageSpeed" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageSpeed" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="50"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverOverlaySpeed, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBlurAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageBlurAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverOverlayBlurAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBackgroundAcrylicEffectAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageBackgroundAcrylicEffectAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverAcrylicEffectAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageFluidLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageFluidLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<dev:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.FluidOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPagePaletteGeneratorType">
|
||||
<dev:SettingsCard x:Uid="SettingsPagePaletteGeneratorType">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsBackgroundSettings.PaletteGeneratorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageMedianCut" />
|
||||
<ComboBoxItem x:Uid="SettingsPageOctTree" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageSnowFlakeLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageSnowFlakeLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageAmount">
|
||||
<uc:ExtendedSlider
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="10"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsBackgroundSettings.SnowFlakeOverlayAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageSpectrumLayer">
|
||||
<dev:SettingsCard x:Uid="SettingsPageSpectrumLayer" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@@ -23,36 +24,34 @@
|
||||
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="Effect" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsVerticalEdgeOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsVerticalEdgeOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsVerticalEdgeOpacitySlider"
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsVerticalEdgeOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsBlurAmountExtendedSlider"
|
||||
Default="5"
|
||||
Frequency="1"
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsBlurAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- 高亮 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsHighlight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
<dev:SettingsExpander x:Uid="SettingsPageLyricsHighlight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPagePhoneticText">
|
||||
<dev:SettingsCard x:Uid="SettingsPagePhoneticText">
|
||||
<local:ExtendedSlider
|
||||
Default="60"
|
||||
Frequency="5"
|
||||
@@ -60,17 +59,17 @@
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.PhoneticLyricsHighlightAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsHighlightScope">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsHighlightScope">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.OriginalLyricsHighlightScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOriginalText">
|
||||
<dev:SettingsCard x:Uid="SettingsPageOriginalText">
|
||||
<local:ExtendedSlider
|
||||
Default="60"
|
||||
Frequency="5"
|
||||
@@ -78,9 +77,9 @@
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.OriginalLyricsHighlightAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageTranslatedText">
|
||||
<dev:SettingsCard x:Uid="SettingsPageTranslatedText">
|
||||
<local:ExtendedSlider
|
||||
Default="60"
|
||||
Frequency="5"
|
||||
@@ -88,139 +87,132 @@
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.TranslatedLyricsHighlightAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 阴影 -->
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsShadow"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="8"
|
||||
Frequency="1"
|
||||
Maximum="20"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 辉光效果 -->
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsGlowEffect"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsGlowEffectScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="8"
|
||||
Frequency="1"
|
||||
Maximum="20"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsGlowEffectAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 浮动动画 -->
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsFloatAnimation"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsFloatAnimationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="1"
|
||||
Frequency="1"
|
||||
Maximum="4"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsFloatAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 扇形歌词 -->
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageFan"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard IsEnabled="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard IsEnabled="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="30"
|
||||
Frequency="1"
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.FanLyricsAngle, Mode=TwoWay}" />
|
||||
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 3D 歌词 -->
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPage3DLyrics"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard Header="X" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard Header="X" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DXAngle, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="Y" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard Header="Y" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DYAngle, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="Z" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard Header="Z" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DZAngle, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPage3DLyricsDepth" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPage3DLyricsDepth" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="1000"
|
||||
Frequency="10"
|
||||
@@ -228,12 +220,12 @@
|
||||
Minimum="100"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DDepth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 滚动动画 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageScrollEasing" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsExpander x:Uid="SettingsPageScrollEasing" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
|
||||
@@ -248,8 +240,8 @@
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollTopDuration">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScrollTopDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
@@ -257,8 +249,8 @@
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollDuration">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScrollDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
@@ -266,8 +258,8 @@
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
@@ -275,8 +267,8 @@
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollTopDelay">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScrollTopDelay">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="50"
|
||||
@@ -284,8 +276,8 @@
|
||||
Minimum="0"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDelay, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDelay">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageScrollBottomDelay">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="50"
|
||||
@@ -293,9 +285,9 @@
|
||||
Minimum="0"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDelay, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
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">
|
||||
|
||||
@@ -23,81 +25,127 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<controls:SettingsExpander x:Uid="LyricsSearchControlSongInfoMapping" IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="LyricsSearchControlTitle" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalTitle, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedTitle, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ResetMappedTitleCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="LyricsSearchControlArtist" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalArtist, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedArtist, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ResetMappedArtistCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard>
|
||||
<CheckBox x:Uid="LyricsSearchControlMarkAsPureMusic" IsChecked="{x:Bind ViewModel.MappedSongSearchQuery.IsMarkedAsPureMusic, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<ScrollViewer>
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<TextBlock x:Uid="LyricsSearchControlSongInfoMapping" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="LyricsSearchControlTargetSearchProvider">
|
||||
<Button
|
||||
x:Uid="LyricsSearchControlSearch"
|
||||
Command="{x:Bind ViewModel.SearchCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</controls:SettingsCard>
|
||||
<Grid
|
||||
Padding="16"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
CornerRadius="4">
|
||||
<StackPanel Spacing="6">
|
||||
<TextBlock x:Uid="LyricsSearchControlTitle" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind ViewModel.MappedSongSearchQuery.OriginalTitle, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
</StackPanel>
|
||||
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedTitle, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ResetMappedTitleCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
Padding="16"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
CornerRadius="4">
|
||||
<StackPanel Spacing="6">
|
||||
|
||||
<TextBlock x:Uid="LyricsSearchControlArtist" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind ViewModel.MappedSongSearchQuery.OriginalArtist, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedArtist, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ResetMappedArtistCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
Padding="16"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
CornerRadius="4">
|
||||
<StackPanel Spacing="6">
|
||||
|
||||
<TextBlock x:Uid="LyricsSearchControlAlbum" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
IsTextSelectionEnabled="True"
|
||||
Text="{x:Bind ViewModel.MappedSongSearchQuery.OriginalAlbum, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedAlbum, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ResetMappedAlbumCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<dev:SettingsCard>
|
||||
<CheckBox x:Uid="LyricsSearchControlMarkAsPureMusic" IsChecked="{x:Bind ViewModel.MappedSongSearchQuery.IsMarkedAsPureMusic, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="LyricsSearchControlTargetSearchProvider">
|
||||
<Button
|
||||
x:Uid="LyricsSearchControlSearch"
|
||||
Command="{x:Bind ViewModel.SearchCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
<ListView ItemsSource="{x:Bind ViewModel.LyricsSearchResults, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsSearchResult, Mode=TwoWay}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ListViewItem IsEnabled="{Binding IsFound}">
|
||||
<Grid Opacity="{Binding IsFound, Converter={StaticResource BoolToOpacityConverter}}">
|
||||
<RelativePanel Padding="0,6">
|
||||
<TextBlock
|
||||
x:Name="SearchedTitle"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
Text="{Binding Title}"
|
||||
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="SearchedArtists"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
RelativePanel.Below="SearchedTitle"
|
||||
Text="{Binding Artist}"
|
||||
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="SearchedProvider"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||
Text="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||
</RelativePanel>
|
||||
<DataTemplate x:DataType="models:LyricsSearchResult">
|
||||
<ListViewItem IsEnabled="{x:Bind IsFound}">
|
||||
<StackPanel Padding="3,6" Opacity="{x:Bind IsFound, Converter={StaticResource BoolToPartialOpacityConverter}}">
|
||||
<TextBlock Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Text="{x:Bind Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||
<TextBlock
|
||||
Text="{x:Bind Title}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind Artist}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind Album}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Uid="LyricsSearchControlNotFound"
|
||||
VerticalAlignment="Center"
|
||||
Text="Not found"
|
||||
Visibility="{Binding IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
Visibility="{x:Bind IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
</ListViewItem>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@@ -20,26 +21,26 @@
|
||||
|
||||
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsLeft" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsCenter" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRight" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageCJK">
|
||||
<dev:SettingsExpander x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageCJK">
|
||||
<local:FontFamilyAutoSuggestBox SelectedFontFamily="{x:Bind LyricsStyleSettings.LyricsCJKFontFamily, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageWesternChar">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageWesternChar">
|
||||
<local:FontFamilyAutoSuggestBox SelectedFontFamily="{x:Bind LyricsStyleSettings.LyricsWesternFontFamily, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontWeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsFontWeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFontWeight, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsThin" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraLight" />
|
||||
@@ -53,39 +54,37 @@
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsBlack" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBlack" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="30"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsBgFontOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="5"
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsFontStrokeWidth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- 字体颜色 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageStrokeFontColor">
|
||||
<dev:SettingsExpander x:Uid="SettingsPageFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageStrokeFontColor">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard HorizontalContentAlignment="Left">
|
||||
<dev:SettingsCard HorizontalContentAlignment="Left">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
@@ -110,17 +109,17 @@
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomStrokeFontColor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontColor">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsBgFontColor">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard>
|
||||
<dev:SettingsCard>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
@@ -145,17 +144,17 @@
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomBgFontColor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFgFontColor">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsFgFontColor">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard>
|
||||
<dev:SettingsCard>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
@@ -180,43 +179,44 @@
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomFgFontColor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<!-- 字体大小 -->
|
||||
<dev:SettingsExpander x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPagePhoneticText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPagePhoneticText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="96"
|
||||
Maximum="256"
|
||||
Minimum="12"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsStyleSettings.PhoneticLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageOriginalText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageOriginalText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="96"
|
||||
Maximum="256"
|
||||
Minimum="12"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsStyleSettings.OriginalLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTranslatedText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageTranslatedText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="96"
|
||||
Maximum="256"
|
||||
Minimum="12"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsStyleSettings.TranslatedLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsLineSpacingFactor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsLineSpacingFactor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsLineSpacingFactorSlider"
|
||||
Default="0.5"
|
||||
@@ -225,14 +225,14 @@
|
||||
Minimum="0"
|
||||
Unit="x"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsLineSpacingFactor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBox AcceptsReturn="True" Text="{x:Bind LyricsStyleSettings.LyricsTranslationSeparator, Mode=TwoWay}" />
|
||||
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=}" Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsWindowSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:constants="using:BetterLyrics.WinUI3.Constants"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
@@ -26,21 +28,41 @@
|
||||
x:Uid="SettingsPageRecordedWindowStatus"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<Button x:Uid="SettingsPageCreateFromCurrent" Command="{x:Bind ViewModel.CopyLyricsWindowStatusCommand}" />
|
||||
<Button
|
||||
x:Uid="SettingsPageCreateFromTemplates"
|
||||
VerticalAlignment="Center"
|
||||
RelativePanel.AlignRightWithPanel="True">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem x:Uid="SettingsPageStandardMode" Command="{x:Bind ViewModel.CreateStandardLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageDesktopMode" Command="{x:Bind ViewModel.CreateTransparentLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageDockedMode" Command="{x:Bind ViewModel.CreateDockedLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageFullscreenMode" Command="{x:Bind ViewModel.CreateFullLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageNarrowMode" Command="{x:Bind ViewModel.CreateNarrowLyricsWindowStatusCommand}" />
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="3">
|
||||
|
||||
<!-- Create from templates -->
|
||||
<Button Content="{ui:FontIcon FontSize=16, FontFamily={StaticResource IconFontFamily}, Glyph=}" Style="{StaticResource GhostButtonStyle}">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Uid="SettingsPageCreateFromTemplates" />
|
||||
</ToolTipService.ToolTip>
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem x:Uid="SettingsPageStandardMode" Command="{x:Bind ViewModel.CreateStandardLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageDesktopMode" Command="{x:Bind ViewModel.CreateTransparentLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageDockedMode" Command="{x:Bind ViewModel.CreateDockedLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageFullscreenMode" Command="{x:Bind ViewModel.CreateFullLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageNarrowMode" Command="{x:Bind ViewModel.CreateNarrowLyricsWindowStatusCommand}" />
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
<!-- Import -->
|
||||
<Button
|
||||
Click="ImportButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=16,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Uid="SettingsPageImport" />
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
|
||||
<!-- Sharing hub -->
|
||||
<HyperlinkButton x:Uid="SettingsPageShareHub" NavigateUri="{x:Bind constants:Link.ShareHubUrl}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
Padding="24,0"
|
||||
@@ -72,6 +94,8 @@
|
||||
x:Uid="LyricsWindowSettingsControlSetDefault"
|
||||
Click="SetDefaultMenuFlyoutItem_Click"
|
||||
IsEnabled="{Binding IsDefault, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageCreateFromCurrent" Click="CopyMenuFlyoutItem_Click" />
|
||||
<MenuFlyoutItem x:Uid="LyricsWindowSettingsControlShare" Click="ShareMenuFlyoutItem_Click" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SettingsPageDelete"
|
||||
Click="DeleteMenuFlyoutItem_Click"
|
||||
@@ -173,7 +197,7 @@
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageConfigName" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageConfigName" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<StackPanel
|
||||
Margin="0,6,0,0"
|
||||
Orientation="Horizontal"
|
||||
@@ -181,9 +205,9 @@
|
||||
<TextBox Text="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.Name, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=}" Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageDisplayTypeSwitcher"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
@@ -193,41 +217,40 @@
|
||||
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLayoutOrientation">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageLayoutOrientation">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageWorkArea"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageWorkAreaHeight" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageWorkAreaHeight" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="64"
|
||||
Frequency="1"
|
||||
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}"
|
||||
Minimum="64"
|
||||
Unit="px"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockHeight, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDockPlacement" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageDockPlacement" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockPlacement, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageDockPlacementTop" />
|
||||
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageDockMonitor" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
|
||||
<Button
|
||||
@@ -237,19 +260,19 @@
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageAdaptEnvColor"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard
|
||||
x:Uid="SettingsPageEnvColorSample"
|
||||
Header="Environment color sample mode"
|
||||
IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
|
||||
@@ -259,59 +282,59 @@
|
||||
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleInner" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleEdge" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageWindowBounds"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard Header="X">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard Header="X">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="Y">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard Header="Y">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageWidth">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageWidth">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageHeight">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageHeight">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowHeight, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageAOT"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageForceAlwaysOnTop" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageForceAlwaysOnTop" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
@@ -344,25 +367,25 @@
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageShowInSwitchers" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageShowInSwitchers" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsShownInSwitchers, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageClickThrough" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageClickThrough" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsClickThrough, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBorderless" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageBorderless" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsBorderless, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDragArea" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageDragArea" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TitleBarArea, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaNone" />
|
||||
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaTop" />
|
||||
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaWhole" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Serialization;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
@@ -21,6 +23,8 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.Storage;
|
||||
using WinRT.Interop;
|
||||
using static Vanara.PInvoke.ComCtl32;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
@@ -34,6 +38,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
|
||||
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public LyricsWindowSettingsControl()
|
||||
{
|
||||
@@ -45,9 +50,12 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
if (sender is MenuFlyoutItem menuFlyoutItem)
|
||||
{
|
||||
var data = menuFlyoutItem.DataContext as LyricsWindowStatus;
|
||||
if (data != null)
|
||||
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus == data)
|
||||
{
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus = ViewModel.AppSettings.WindowBoundsRecords.First();
|
||||
}
|
||||
ViewModel.AppSettings.WindowBoundsRecords.Remove(data);
|
||||
}
|
||||
}
|
||||
@@ -57,8 +65,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
if (sender is MenuFlyoutItem menuFlyoutItem)
|
||||
{
|
||||
var data = menuFlyoutItem.DataContext as LyricsWindowStatus;
|
||||
if (data != null)
|
||||
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
|
||||
{
|
||||
ViewModel.AppSettings.WindowBoundsRecords.ForEach(x => x.IsDefault = false);
|
||||
data.IsDefault = true;
|
||||
@@ -66,6 +73,50 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
}
|
||||
|
||||
private async void ShareMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is MenuFlyoutItem menuFlyoutItem)
|
||||
{
|
||||
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
|
||||
{
|
||||
IDictionary<string, IList<string>> fileTypeChoices = new Dictionary<string, IList<string>>()
|
||||
{
|
||||
{ "JSON", new List<string>() { ".json" } }
|
||||
};
|
||||
StorageFile? file;
|
||||
if (this.Parent is FlyoutPresenter)
|
||||
{
|
||||
file = await PickerHelper.PickSaveFileAsync<LyricsWindow>(fileTypeChoices);
|
||||
}
|
||||
else
|
||||
{
|
||||
file = await PickerHelper.PickSaveFileAsync<SettingsWindow>(fileTypeChoices);
|
||||
}
|
||||
if (file != null)
|
||||
{
|
||||
var clonedData = (LyricsWindowStatus)data.Clone();
|
||||
clonedData.IsDefault = false;
|
||||
var json = System.Text.Json.JsonSerializer.Serialize(clonedData, SourceGenerationContext.Default.LyricsWindowStatus);
|
||||
File.WriteAllText(file.Path, json);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("ExportSettingsSuccess"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is MenuFlyoutItem menuFlyoutItem)
|
||||
{
|
||||
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
|
||||
{
|
||||
var clonedData = (LyricsWindowStatus)data.Clone();
|
||||
clonedData.IsDefault = false;
|
||||
ViewModel.AppSettings.WindowBoundsRecords.Add(clonedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StackPanel_RightTapped(object sender, RightTappedRoutedEventArgs e)
|
||||
{
|
||||
if (sender is StackPanel stackPanel)
|
||||
@@ -87,5 +138,29 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void ImportButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string[] fileTypeFilter = [".json"];
|
||||
StorageFile? file;
|
||||
if (this.Parent is FlyoutPresenter)
|
||||
{
|
||||
file = await PickerHelper.PickSingleFileAsync<LyricsWindow>(fileTypeFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
file = await PickerHelper.PickSingleFileAsync<SettingsWindow>(fileTypeFilter);
|
||||
}
|
||||
if (file != null)
|
||||
{
|
||||
var json = File.ReadAllText(file.Path);
|
||||
var data = System.Text.Json.JsonSerializer.Deserialize(json, SourceGenerationContext.Default.LyricsWindowStatus);
|
||||
if (data != null)
|
||||
{
|
||||
ViewModel.AppSettings.WindowBoundsRecords.Add(data);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("ImportSettingsSuccess"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@@ -18,7 +19,7 @@
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageMusicLib" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
<dev:SettingsCard x:Uid="SettingsPageMusicLib" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
|
||||
<InfoBar
|
||||
x:Uid="SettingsPageRemoveInfo"
|
||||
@@ -49,38 +50,38 @@
|
||||
SelectionMode="None">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<controls:SettingsExpander>
|
||||
<controls:SettingsExpander.Header>
|
||||
<dev:SettingsExpander>
|
||||
<dev:SettingsExpander.Header>
|
||||
<HyperlinkButton
|
||||
Click="LocalFolderHyperlinkButton_Click"
|
||||
Content="{Binding Path, Mode=OneWay}"
|
||||
Tag="{Binding Path, Mode=OneWay}" />
|
||||
</controls:SettingsExpander.Header>
|
||||
</dev:SettingsExpander.Header>
|
||||
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard>
|
||||
<controls:SettingsCard.Header>
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard>
|
||||
<dev:SettingsCard.Header>
|
||||
<HyperlinkButton
|
||||
x:Uid="SettingsPageRemovePath"
|
||||
Click="SettingsPageRemovePathButton_Click"
|
||||
Tag="{Binding}" />
|
||||
</controls:SettingsCard.Header>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageMusicLibRealTimeWatch">
|
||||
</dev:SettingsCard.Header>
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageMusicLibRealTimeWatch">
|
||||
<ToggleSwitch IsOn="{Binding IsRealTimeWatchEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAddFolder" Style="{StaticResource DefaultSettingsExpanderItemStyle}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageAddFolder" Style="{StaticResource DefaultSettingsExpanderItemStyle}">
|
||||
<Button
|
||||
x:Uid="SettingsPageAddFolderButton"
|
||||
Command="{x:Bind ViewModel.SelectAndAddFolderCommand}"
|
||||
CommandParameter="{Binding ElementName=RootGrid}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:constants="using:BetterLyrics.WinUI3.Constants"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dev="using:DevWinUI"
|
||||
xmlns:globalization="using:Windows.Globalization"
|
||||
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
@@ -25,19 +26,19 @@
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageMediaSourceProvidersConfig">
|
||||
<dev:SettingsCard x:Uid="SettingsPageMediaSourceProvidersConfig">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLastFMTrack" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
<dev:SettingsCard x:Uid="SettingsPageLastFMTrack" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsLastFMTrackEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- 时间轴相关配置 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True">
|
||||
<dev:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="100"
|
||||
Maximum="1000"
|
||||
@@ -45,10 +46,10 @@
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="ms"
|
||||
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.TimelineSyncThreshold, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<controls:SettingsExpander x:Uid="MainPagePositionOffsetSlider" IsExpanded="True">
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
<dev:SettingsExpander x:Uid="MainPagePositionOffsetSlider" IsExpanded="True">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPagePositionOffsetReset"
|
||||
Default="0"
|
||||
@@ -57,12 +58,12 @@
|
||||
Minimum="-5000"
|
||||
Unit="ms"
|
||||
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.PositionOffset, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="LyricsPagePositionOffsetHint">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="LyricsPagePositionOffsetHint">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.ResetPositionOffsetOnSongChanged, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- 专辑封面源配置 -->
|
||||
<TextBlock x:Uid="SettingsPageAlbumArtSearchProvidersConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
@@ -80,12 +81,12 @@
|
||||
</ListView.OpacityTransition>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:AlbumArtSearchProviderInfo">
|
||||
<controls:SettingsCard Header="{Binding Provider, Converter={StaticResource AlbumArtSearchProviderToDisplayNameConverter}, Mode=OneWay}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<dev:SettingsCard Header="{Binding Provider, Converter={StaticResource AlbumArtSearchProviderToDisplayNameConverter}, Mode=OneWay}">
|
||||
<dev:SettingsCard.HeaderIcon>
|
||||
<FontIcon FontFamily="Segoe UI Symbol" Glyph="⠿" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</dev:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
@@ -112,12 +113,12 @@
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:LyricsSearchProviderInfo">
|
||||
<controls:SettingsCard Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}">
|
||||
<controls:SettingsCard.HeaderIcon>
|
||||
<dev:SettingsCard Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}">
|
||||
<dev:SettingsCard.HeaderIcon>
|
||||
<FontIcon FontFamily="Segoe UI Symbol" Glyph="⠿" />
|
||||
</controls:SettingsCard.HeaderIcon>
|
||||
</dev:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
@@ -209,25 +210,25 @@
|
||||
|
||||
<!-- Provider info -->
|
||||
<TextBlock x:Uid="SettingsPageRealtimeStatus" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
|
||||
<dev:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
|
||||
<HyperlinkButton
|
||||
Content="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}"
|
||||
IsEnabled="False"
|
||||
NavigateUri="{x:Bind ViewModel.OriginalLyricsRef, Mode=OneWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
|
||||
<HyperlinkButton
|
||||
Content="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}"
|
||||
IsEnabled="False"
|
||||
NavigateUri="{x:Bind ViewModel.TranslatedLyricsRef, Mode=OneWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- Lyrics translation -->
|
||||
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander x:Uid="LyricsPageTranslationEnabled" IsExpanded="True">
|
||||
<dev:SettingsExpander x:Uid="LyricsPageTranslationEnabled" IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTargetLanguage" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageTargetLanguage" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<ComboBox ItemsSource="{x:Bind helper:LanguageHelper.SupportedTranslationTargetLanguages}" SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:ExtendedLanguage">
|
||||
@@ -237,60 +238,59 @@
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTranslationConfig" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<controls:SettingsCard.Description>
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageTranslationConfig" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<dev:SettingsCard.Description>
|
||||
<HyperlinkButton Margin="0,6,0,0" NavigateUri="https://github.com/LibreTranslate/LibreTranslate">
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageTranslationInfoLink"
|
||||
FontSize="14"
|
||||
TextWrapping="Wrap" />
|
||||
</HyperlinkButton>
|
||||
</controls:SettingsCard.Description>
|
||||
</dev:SettingsCard.Description>
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="12">
|
||||
<TextBox
|
||||
x:Name="LibreTranslateServerTextBox"
|
||||
x:Uid="LibreTranslateServerTextBox"
|
||||
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||
PlaceholderText="http://localhost:5000"
|
||||
Text="{x:Bind ViewModel.AppSettings.TranslationSettings.LibreTranslateServer, Mode=TwoWay}" />
|
||||
<Button
|
||||
x:Uid="SettingsPageServerTestButton"
|
||||
Command="{x:Bind ViewModel.LibreTranslateServerTestCommand}"
|
||||
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- Lyrics phonetic -->
|
||||
<TextBlock x:Uid="SettingsPagePhonetic" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander x:Uid="SettingsPageChinese" IsExpanded="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander x:Uid="SettingsPageChinese" IsExpanded="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.ChineseRomanization, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}">
|
||||
<ComboBoxItem x:Uid="SettingsPagePinyin" />
|
||||
<ComboBoxItem x:Uid="SettingsPageJyutping" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<controls:SettingsCard x:Uid="SettingsPageJapanese">
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
<dev:SettingsCard x:Uid="SettingsPageJapanese">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- 中文简体繁体偏好 -->
|
||||
<TextBlock x:Uid="SettingsPageChineseLyrics" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsCard x:Uid="SettingsPageChinesePreference">
|
||||
<dev:SettingsCard x:Uid="SettingsPageChinesePreference">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTraditionalChineseEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- Last.fm -->
|
||||
<TextBlock x:Uid="SettingsPageLastFM" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander
|
||||
<dev:SettingsExpander
|
||||
x:Uid="SettingsPageLastFMManager"
|
||||
HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/LastFM.png}"
|
||||
IsExpanded="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
@@ -304,40 +304,40 @@
|
||||
Command="{x:Bind ViewModel.LastFMUnAuthCommand}"
|
||||
IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLastFMUsername" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageLastFMUsername" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
<HyperlinkButton Content="{x:Bind ViewModel.LastFMUser.Name, Mode=OneWay}" NavigateUri="{x:Bind ViewModel.LastFMUser.Url, Mode=OneWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLastFMPlaycount" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageLastFMPlaycount" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Bind ViewModel.LastFMUser.Playcount, Mode=OneWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLastFMRegistered" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard x:Uid="SettingsPageLastFMRegistered" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
<TextBlock Text="{x:Bind ViewModel.LastFMUser.Registered.ToLongDateString(), Mode=OneWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
</dev:SettingsCard>
|
||||
<dev:SettingsCard IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||
<Button x:Uid="SettingsPageLastFMRefresh" Command="{x:Bind ViewModel.LastFMRefreshCommand}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
</dev:SettingsCard>
|
||||
</dev:SettingsExpander.Items>
|
||||
</dev:SettingsExpander>
|
||||
|
||||
<!-- LX music server -->
|
||||
<TextBlock x:Uid="SettingsPageLXMusicServer" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsCard x:Uid="SettingsPageServerAddress">
|
||||
<dev:SettingsCard x:Uid="SettingsPageServerAddress">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBox
|
||||
x:Uid="SettingsPageLXMusicServerInput"
|
||||
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||
PlaceholderText="http://127.0.0.1:23330"
|
||||
Text="{x:Bind ViewModel.AppSettings.GeneralSettings.LXMusicServer, Mode=TwoWay}" />
|
||||
<Button
|
||||
x:Uid="SettingsPageServerTestButton"
|
||||
Command="{x:Bind ViewModel.LXMusicServerTestCommand}"
|
||||
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
<!-- Apple Music token -->
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="Apple Muisc media-user-token" />
|
||||
<controls:SettingsCard
|
||||
<dev:SettingsCard
|
||||
Background="{ThemeResource SystemFillColorCautionBackgroundBrush}"
|
||||
Description="Use at your own risk"
|
||||
Foreground="{ThemeResource SystemFillColorCautionBrush}"
|
||||
@@ -356,7 +356,7 @@
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
</dev:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -23,6 +25,8 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class ShortcutTextBox : UserControl
|
||||
{
|
||||
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public ShortcutTextBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -98,15 +102,11 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
bool registered = GlobalHotKeyHelper.IsHotKeyRegistered(Shortcut);
|
||||
if (registered)
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(
|
||||
App.ResourceLoader!.GetString("SettingsPageShortcutRegSuccessInfo"),
|
||||
InfoBarSeverity.Success);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("SettingsPageShortcutRegSuccessInfo"));
|
||||
}
|
||||
else
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(
|
||||
App.ResourceLoader!.GetString("SettingsPageShortcutRegFailInfo"),
|
||||
InfoBarSeverity.Error);
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("SettingsPageShortcutRegFailInfo"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
Command="{x:Bind ViewModel.OpenLyricsWindowSwitchCommand}"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SystemTraySearch"
|
||||
Command="{x:Bind ViewModel.OpenLyricsSearchWindowCommand}"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SystemTrayLyrics"
|
||||
Command="{x:Bind ViewModel.OpenLyricsCommand}"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -10,14 +12,16 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class AlbumArtSearchProviderToDisplayNameConverter : IValueConverter
|
||||
{
|
||||
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is AlbumArtSearchProvider provider)
|
||||
{
|
||||
return provider switch
|
||||
{
|
||||
AlbumArtSearchProvider.Local => App.ResourceLoader!.GetString("AlbumArtSearchLocalProvider"),
|
||||
AlbumArtSearchProvider.SMTC => App.ResourceLoader!.GetString("AlbumArtSearchSMTCProvider"),
|
||||
AlbumArtSearchProvider.Local => _resourceService.GetLocalizedString("AlbumArtSearchLocalProvider"),
|
||||
AlbumArtSearchProvider.SMTC => _resourceService.GetLocalizedString("AlbumArtSearchSMTCProvider"),
|
||||
AlbumArtSearchProvider.iTunes => "iTunes",
|
||||
_ => throw new Exception($"Unknown AlbumArtSearchProvider: {provider}"),
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class BoolNegationToOpacityConverter: IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 0.0 : 1.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,13 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public class BoolToOpacityConverter : IValueConverter
|
||||
public partial class BoolToOpacityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1.0 : 0.3;
|
||||
return boolValue ? 1.0 : 0.0;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public class BoolToPartialOpacityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1.0 : 0.3;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -29,11 +30,11 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
return PathHelper.AlbumArtPlaceholderPath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return PathHelper.AlbumArtPlaceholderPath;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class IndexToDisplayConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
int display = 0;
|
||||
if (value is int index)
|
||||
{
|
||||
display = index + 1;
|
||||
}
|
||||
return display.ToString();
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class IntToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is int intValue)
|
||||
{
|
||||
return intValue != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class LyricsSearchProviderToDisplayNameConverter : IValueConverter
|
||||
{
|
||||
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is LyricsSearchProvider provider)
|
||||
@@ -20,10 +24,10 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
LyricsSearchProvider.Kugou => "酷狗音乐",
|
||||
LyricsSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
||||
LyricsSearchProvider.AppleMusic => "Apple Music",
|
||||
LyricsSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
||||
LyricsSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
||||
LyricsSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
||||
LyricsSearchProvider.LocalTtmlFile => App.ResourceLoader!.GetString("LyricsSearchProviderTtmlFile"),
|
||||
LyricsSearchProvider.LocalLrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalLrcFile"),
|
||||
LyricsSearchProvider.LocalMusicFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalMusicFile"),
|
||||
LyricsSearchProvider.LocalEslrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderEslrcFile"),
|
||||
LyricsSearchProvider.LocalTtmlFile => _resourceService.GetLocalizedString("LyricsSearchProviderTtmlFile"),
|
||||
_ => "N/A",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class MatchedLocalFilesPathToVisibilityConverter : IValueConverter
|
||||
{
|
||||
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is string path)
|
||||
{
|
||||
if (path == App.ResourceLoader!.GetString("MainPageNoLocalFilesMatched"))
|
||||
if (path == _resourceService.GetLocalizedString("MainPageNoLocalFilesMatched"))
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
PlayerID.NetEaseCloudMusic => PlayerName.NetEaseCloudMusic,
|
||||
PlayerID.QQMusic => PlayerName.QQMusic,
|
||||
PlayerID.LXMusic => PlayerName.LXMusic,
|
||||
PlayerID.LXMusicPortable => PlayerName.LXMusicPortable,
|
||||
PlayerID.MediaPlayerWindows11 => PlayerName.MediaPlayerWindows11,
|
||||
PlayerID.AIMP => PlayerName.AIMP,
|
||||
PlayerID.Foobar2000 => PlayerName.Foobar2000,
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
PlayerID.NetEaseCloudMusic => PathHelper.NetEaseCloudMusicLogoPath,
|
||||
PlayerID.QQMusic => PathHelper.QQMusicLogoPath,
|
||||
PlayerID.LXMusic => PathHelper.LXMusicLogoPath,
|
||||
PlayerID.LXMusicPortable => PathHelper.LXMusicLogoPath,
|
||||
PlayerID.MediaPlayerWindows11 => PathHelper.MediaPlayerWindows11LogoPath,
|
||||
PlayerID.AIMP => PathHelper.AIMPLogoPath,
|
||||
PlayerID.Foobar2000 => PathHelper.Foobar2000LogoPath,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class PathToParentFolderConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is string path)
|
||||
{
|
||||
return Directory.GetParent(path)?.Name ?? "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,27 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
TimeSpan timeSpan = TimeSpan.Zero;
|
||||
if (value is double seconds)
|
||||
{
|
||||
return TimeSpan.FromSeconds(seconds).ToString(@"mm\:ss");
|
||||
timeSpan = TimeSpan.FromSeconds(seconds);
|
||||
}
|
||||
else if (value is int secondsInt)
|
||||
{
|
||||
return TimeSpan.FromSeconds(secondsInt).ToString(@"mm\:ss");
|
||||
timeSpan = TimeSpan.FromSeconds(secondsInt);
|
||||
}
|
||||
if (timeSpan.Days > 0)
|
||||
{
|
||||
return timeSpan.ToString(@"dd\.hh\:mm\:ss");
|
||||
}
|
||||
else if (timeSpan.Hours > 0)
|
||||
{
|
||||
return timeSpan.ToString(@"hh\:mm\:ss");
|
||||
}
|
||||
else
|
||||
{
|
||||
return timeSpan.ToString(@"mm\:ss");
|
||||
}
|
||||
return value?.ToString() ?? "";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using ATL;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class TrackToLyricsConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is Track track)
|
||||
{
|
||||
return track.GetLyrics();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class TranslationSearchProviderToDisplayNameConverter : IValueConverter
|
||||
{
|
||||
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is TranslationSearchProvider provider)
|
||||
@@ -20,10 +24,10 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
TranslationSearchProvider.Kugou => "酷狗音乐",
|
||||
TranslationSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
||||
TranslationSearchProvider.AppleMusic => "Apple Music",
|
||||
TranslationSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
||||
TranslationSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
||||
TranslationSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
||||
TranslationSearchProvider.LocalTtmlFile => App.ResourceLoader!.GetString("LyricsSearchProviderTtmlFile"),
|
||||
TranslationSearchProvider.LocalLrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalLrcFile"),
|
||||
TranslationSearchProvider.LocalMusicFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalMusicFile"),
|
||||
TranslationSearchProvider.LocalEslrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderEslrcFile"),
|
||||
TranslationSearchProvider.LocalTtmlFile => _resourceService.GetLocalizedString("LyricsSearchProviderTtmlFile"),
|
||||
TranslationSearchProvider.LibreTranslate => "LibreTranslate",
|
||||
_ => "N/A",
|
||||
};
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
Title,
|
||||
Album,
|
||||
Artist
|
||||
Artist,
|
||||
Folder,
|
||||
M3UFilePath
|
||||
}
|
||||
}
|
||||
|
||||
21
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/EnumHelper.cs
Normal file
21
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/EnumHelper.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class EnumExtensions
|
||||
{
|
||||
public static T GetNext<T>(this T value) where T : struct, Enum
|
||||
{
|
||||
T[] values = Enum.GetValues<T>();
|
||||
int currentIndex = Array.IndexOf(values, value);
|
||||
int nextIndex = (currentIndex + 1) % values.Length;
|
||||
return values[nextIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using ATL;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -37,9 +39,9 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string? ReadLyricsCache(string title, string artist, LyricsFormat format, string cacheFolderPath)
|
||||
public static string? ReadLyricsCache(string title, string artist, string album, LyricsFormat format, string cacheFolderPath)
|
||||
{
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title}{format.ToFileExtension()}"));
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title} - {album}{format.ToFileExtension()}"));
|
||||
if (File.Exists(cacheFilePath))
|
||||
{
|
||||
return File.ReadAllText(cacheFilePath);
|
||||
@@ -57,9 +59,9 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void WriteLyricsCache(string title, string artist, string lyrics, LyricsFormat format, string cacheFolderPath)
|
||||
public static void WriteLyricsCache(string title, string artist, string album, string lyrics, LyricsFormat format, string cacheFolderPath)
|
||||
{
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title}{format.ToFileExtension()}"));
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title} - {album}{format.ToFileExtension()}"));
|
||||
File.WriteAllText(cacheFilePath, lyrics);
|
||||
}
|
||||
|
||||
@@ -86,7 +88,5 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
".wav", ".aiff", ".aif", ".pcm", ".cda", ".dsf", ".dff", ".au", ".snd",
|
||||
".mid", ".midi", ".mod", ".xm", ".it", ".s3m"
|
||||
};
|
||||
|
||||
public static string MusicSearchPattern => string.Join("|", MusicExtensions.Select(x => $"*{x}"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ using System.Numerics;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI;
|
||||
using static Vanara.PInvoke.Ole32;
|
||||
@@ -46,43 +47,13 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return RandomAccessStreamReference.CreateFromStream(stream);
|
||||
}
|
||||
|
||||
public static async Task<IRandomAccessStream> CreateTextPlaceholderBytesAsync(int width, int height)
|
||||
public static async Task<IRandomAccessStream> GetAlbumArtPlaceholderAsync()
|
||||
{
|
||||
using var device = CanvasDevice.GetSharedDevice();
|
||||
using var renderTarget = new CanvasRenderTarget(device, width, height, 96);
|
||||
|
||||
// 随机生成渐变色
|
||||
Windows.UI.Color RandomColor()
|
||||
{
|
||||
var rand = new Random(Guid.NewGuid().GetHashCode());
|
||||
double h = rand.NextDouble() * 360;
|
||||
double s = 0.35 + rand.NextDouble() * 0.3; // 0.35~0.65,适中饱和度
|
||||
double l = 0.5 + rand.NextDouble() * 0.3; // 0.5~0.8,明亮
|
||||
return CommunityToolkit.WinUI.Helpers.ColorHelper.FromHsl(h, s, l);
|
||||
}
|
||||
|
||||
Windows.UI.Color color1 = RandomColor();
|
||||
Windows.UI.Color color2 = RandomColor();
|
||||
|
||||
using (var ds = renderTarget.CreateDrawingSession())
|
||||
{
|
||||
// 绘制线性渐变背景
|
||||
using var gradientBrush = new Microsoft.Graphics.Canvas.Brushes.CanvasLinearGradientBrush(ds, color1, color2)
|
||||
{
|
||||
StartPoint = new Vector2(0, 0),
|
||||
EndPoint = new Vector2(width, height)
|
||||
};
|
||||
ds.FillRectangle(0, 0, width, height, gradientBrush);
|
||||
}
|
||||
|
||||
// 保存为 PNG 并转为 byte[]
|
||||
var stream = new InMemoryRandomAccessStream();
|
||||
await renderTarget.SaveAsync(stream, CanvasBitmapFileFormat.Png);
|
||||
stream.Seek(0);
|
||||
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(PathHelper.AlbumArtPlaceholderPath));
|
||||
IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
public static Task<ThemeColorResult> GetAccentColorAsync(BitmapDecoder decoder, PaletteGeneratorType generatorType)
|
||||
{
|
||||
return generatorType switch
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using NTextCat;
|
||||
using NTextCat.Commons;
|
||||
using System.Collections.Generic;
|
||||
@@ -13,6 +15,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
private static readonly RankedLanguageIdentifierFactory _factory = new();
|
||||
private static readonly RankedLanguageIdentifier _identifier;
|
||||
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public static List<ExtendedLanguage> SupportedTranslationTargetLanguages { get; set; } =
|
||||
[
|
||||
@@ -89,7 +92,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
public static List<ExtendedLanguage> SupportedDisplayLanguages { get; set; } =
|
||||
[
|
||||
new ExtendedLanguage("", App.ResourceLoader!.GetString("SettingsPageSystemLanguage")),
|
||||
new ExtendedLanguage("", _resourceService.GetLocalizedString("SettingsPageSystemLanguage")),
|
||||
new ExtendedLanguage("en-US", "English"),
|
||||
new ExtendedLanguage("ja-JP"),
|
||||
new ExtendedLanguage("ko-KR"),
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Vanara.PInvoke;
|
||||
using LyricsData = BetterLyrics.WinUI3.Models.LyricsData;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
@@ -19,10 +20,23 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public List<LyricsData> LyricsDataArr { get; private set; } = [];
|
||||
|
||||
public LyricsData? LibreTranslationLyricsData => LyricsDataArr.LastOrDefault();
|
||||
|
||||
public void Parse(string title, string artist, string? raw, int? durationMs, LyricsSearchProvider? lyricsSearchProvider)
|
||||
public void Parse(List<MappedSongSearchQuery> mappedSongSearchQueries, string title, string artist, string album, string? raw, int? durationMs, LyricsSearchProvider? lyricsSearchProvider)
|
||||
{
|
||||
var overridenTitle = title;
|
||||
var overridenArtist = artist;
|
||||
var overridenAlbum = album;
|
||||
|
||||
var found = mappedSongSearchQueries
|
||||
.Where(x => x.OriginalTitle == overridenTitle && x.OriginalArtist == overridenArtist && x.OriginalAlbum == overridenAlbum)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (found != null)
|
||||
{
|
||||
overridenTitle = found.MappedTitle;
|
||||
overridenArtist = found.MappedArtist;
|
||||
overridenAlbum = found.MappedAlbum;
|
||||
}
|
||||
|
||||
LyricsDataArr = [];
|
||||
durationMs ??= (int)TimeSpan.FromMinutes(99).TotalMilliseconds;
|
||||
if (raw == null)
|
||||
@@ -51,22 +65,22 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
}
|
||||
FillRomanizationLyricsData();
|
||||
FillTranslationFromCache(title, artist, lyricsSearchProvider);
|
||||
FillTranslationFromCache(overridenTitle, overridenArtist, overridenAlbum, lyricsSearchProvider);
|
||||
}
|
||||
|
||||
private void FillTranslationFromCache(string title, string artist, LyricsSearchProvider? provider)
|
||||
private void FillTranslationFromCache(string title, string artist, string album, LyricsSearchProvider? provider)
|
||||
{
|
||||
string? translationRaw = null;
|
||||
switch (provider)
|
||||
{
|
||||
case LyricsSearchProvider.QQ:
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, LyricsFormat.Lrc, PathHelper.QQTranslationCacheDirectory);
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.QQTranslationCacheDirectory);
|
||||
break;
|
||||
case LyricsSearchProvider.Kugou:
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, LyricsFormat.Lrc, PathHelper.KugouTranslationCacheDirectory);
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.KugouTranslationCacheDirectory);
|
||||
break;
|
||||
case LyricsSearchProvider.Netease:
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, LyricsFormat.Lrc, PathHelper.NeteaseTranslationCacheDirectory);
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.NeteaseTranslationCacheDirectory);
|
||||
break;
|
||||
case LyricsSearchProvider.LrcLib:
|
||||
break;
|
||||
@@ -99,7 +113,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FillRomanizationLyricsData()
|
||||
private void FillRomanizationLyricsData()
|
||||
{
|
||||
var chinese = LyricsDataArr.Where(x => x.LanguageCode == "zh").FirstOrDefault();
|
||||
if (chinese != null)
|
||||
|
||||
@@ -20,17 +20,10 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
var vault = new PasswordVault();
|
||||
|
||||
// 删除旧值(避免重复存储)
|
||||
try
|
||||
var oldCredential = vault.FindAllByResource(resource).Where(x => x.UserName == key).FirstOrDefault();
|
||||
if (oldCredential != null)
|
||||
{
|
||||
var oldCredential = vault.Retrieve(resource, key);
|
||||
if (oldCredential != null)
|
||||
{
|
||||
vault.Remove(oldCredential);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 没有旧值就忽略
|
||||
vault.Remove(oldCredential);
|
||||
}
|
||||
|
||||
vault.Add(new PasswordCredential(resource, key, value));
|
||||
@@ -45,13 +38,13 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
public static string? Get(string resource, string key)
|
||||
{
|
||||
var vault = new PasswordVault();
|
||||
try
|
||||
var credential = vault.FindAllByResource(resource).Where(x => x.UserName == key).FirstOrDefault();
|
||||
if (credential != null)
|
||||
{
|
||||
var credential = vault.Retrieve(resource, key);
|
||||
credential.RetrievePassword();
|
||||
return credential.Password;
|
||||
}
|
||||
catch
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -63,15 +56,11 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
public static void Delete(string resource, string key)
|
||||
{
|
||||
var vault = new PasswordVault();
|
||||
try
|
||||
var credential = vault.FindAllByResource(resource).Where(x => x.UserName == key).FirstOrDefault();
|
||||
if (credential != null)
|
||||
{
|
||||
var credential = vault.Retrieve(resource, key);
|
||||
vault.Remove(credential);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 不存在就忽略
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
public static string LanguageProfilePath => Path.Combine(AssetsFolder, "Wiki82.profile.xml");
|
||||
public static string LogoPath => Path.Combine(AssetsFolder, "Logo.ico");
|
||||
public static string AlbumArtPlaceholderPath => "ms-appx:///Assets/AlbumArtPlaceholder.png";
|
||||
public static string AIMPLogoPath => Path.Combine(AssetsFolder, "AIMP.png");
|
||||
public static string Foobar2000LogoPath => Path.Combine(AssetsFolder, "foobar2000.png");
|
||||
public static string MusicBeeLogoPath => Path.Combine(AssetsFolder, "MusicBee.png");
|
||||
@@ -37,14 +38,12 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
public static string SaltPlayerForWindowsLogoPath => Path.Combine(AssetsFolder, "SaltPlayerForWindows.png");
|
||||
public static string MoeKoeMusicLogoPath => Path.Combine(AssetsFolder, "MoeKoeMusic.png");
|
||||
public static string Listen1LogoPath => Path.Combine(AssetsFolder, "Listen1.png");
|
||||
|
||||
public static string UnknownPlayerLogoPath => Path.Combine(AssetsFolder, "Question.png");
|
||||
|
||||
public static string LogDirectory => Path.Combine(CacheFolder, "logs");
|
||||
public static string LogFilePattern => Path.Combine(LogDirectory, "log-.txt");
|
||||
|
||||
public static string LyricsCacheDirectory => Path.Combine(CacheFolder, "lyrics");
|
||||
|
||||
public static string LrcLibLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "lrclib");
|
||||
public static string NeteaseLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "netease");
|
||||
public static string QQLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "qq");
|
||||
@@ -55,15 +54,15 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
public static string AmllTtmlDbLastUpdatedPath => Path.Combine(LyricsCacheDirectory, "amll-ttml-db-last-updated.txt");
|
||||
|
||||
public static string TranslationCacheDirectory => Path.Combine(CacheFolder, "translations");
|
||||
|
||||
public static string QQTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "qq");
|
||||
public static string NeteaseTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "netease");
|
||||
public static string KugouTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "kugou");
|
||||
|
||||
public static string AlbumArtCacheDirectory => Path.Combine(CacheFolder, "album-art");
|
||||
|
||||
public static string iTunesAlbumArtCacheDirectory => Path.Combine(AlbumArtCacheDirectory, "itunes");
|
||||
|
||||
public static string PlayQueuePath => Path.Combine(CacheFolder, "play-queue.m3u");
|
||||
|
||||
public static void EnsureDirectories()
|
||||
{
|
||||
Directory.CreateDirectory(SettingsDirectory);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -8,6 +10,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class PhoneticHelper
|
||||
{
|
||||
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public const string PinyinCode = "zh-pinyin";
|
||||
public const string JyutpingCode = "zh-jyutping";
|
||||
public const string RomajiCode = "ja-romaji";
|
||||
@@ -22,11 +26,11 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
switch (code)
|
||||
{
|
||||
case PinyinCode:
|
||||
return App.ResourceLoader!.GetString("Pinyin");
|
||||
return _resourceService.GetLocalizedString("Pinyin");
|
||||
case JyutpingCode:
|
||||
return App.ResourceLoader!.GetString("Jyutping");
|
||||
return _resourceService.GetLocalizedString("Jyutping");
|
||||
case RomajiCode:
|
||||
return App.ResourceLoader!.GetString("Romaji");
|
||||
return _resourceService.GetLocalizedString("Romaji");
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(code));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using WinRT.Interop;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class PickerHelper
|
||||
{
|
||||
public static async Task<StorageFolder?> PickSingleFolderAsync<T>()
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<T>();
|
||||
if (window == null) return null;
|
||||
|
||||
var picker = new Windows.Storage.Pickers.FolderPicker();
|
||||
picker.FileTypeFilter.Add("*");
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
InitializeWithWindow.Initialize(picker, hwnd);
|
||||
|
||||
var folder = await picker.PickSingleFolderAsync();
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
public static async Task<StorageFile?> PickSingleFileAsync<T>(string[] fileTypeFilter)
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<T>();
|
||||
if (window == null) return null;
|
||||
|
||||
var picker = new Windows.Storage.Pickers.FileOpenPicker();
|
||||
picker.FileTypeFilter.AddRange(fileTypeFilter);
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
InitializeWithWindow.Initialize(picker, hwnd);
|
||||
|
||||
var file = await picker.PickSingleFileAsync();
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public static async Task<StorageFile?> PickSaveFileAsync<T>(IDictionary<string, IList<string>> fileTypeChoices)
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<T>();
|
||||
if (window == null) return null;
|
||||
|
||||
var picker = new Windows.Storage.Pickers.FileSavePicker();
|
||||
picker.FileTypeChoices.AddRange(fileTypeChoices);
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
InitializeWithWindow.Initialize(picker, hwnd);
|
||||
|
||||
var file = await picker.PickSaveFileAsync();
|
||||
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,21 +5,26 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class PlayerIdMatcher
|
||||
{
|
||||
private static readonly List<string> _neteaseFamilyRegex =
|
||||
private static readonly List<string> neteaseFamilyRegex =
|
||||
[
|
||||
"cloudmusic.exe", //NetEaseCloudMusic
|
||||
"^17588BrandonWong\\.LyricEase_", //LyricEase
|
||||
"^48848aaaaaaccd\\.HyPlayer_" //HyPlayer
|
||||
];
|
||||
|
||||
public static bool IsNeteaseFamily(string player)
|
||||
public static bool IsNeteaseFamily(string id)
|
||||
{
|
||||
foreach (var regex in _neteaseFamilyRegex)
|
||||
foreach (var regex in neteaseFamilyRegex)
|
||||
{
|
||||
var isMatch = Regex.IsMatch(player, regex);
|
||||
var isMatch = Regex.IsMatch(id, regex);
|
||||
if (isMatch) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsLXMusic(string? id)
|
||||
{
|
||||
return id == Constants.PlayerID.LXMusic || id == Constants.PlayerID.LXMusicPortable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
// 补偿曲线
|
||||
float[] frequencies = { 20, 50, 100, 200, 500, 1000, 2000, 4000, 8000, 16000, 20000 };
|
||||
float[] gains = { 0.5f, 0.3f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.3f, 1.1f, 0.9f, 0.8f };
|
||||
//float[] gains = { 0.5f, 0.3f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.3f, 1.1f, 0.9f, 0.8f };
|
||||
float[] gains = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
if (freq <= frequencies[0])
|
||||
{
|
||||
return gains[0];
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class TrackHelper
|
||||
{
|
||||
public static string GetParentFolderName(this ATL.Track track)
|
||||
{
|
||||
return Directory.GetParent(track.Path)?.Name ?? "";
|
||||
}
|
||||
|
||||
public static string GetParentFolderPath(this ATL.Track track)
|
||||
{
|
||||
return Directory.GetParent(track.Path)?.FullName ?? "";
|
||||
}
|
||||
|
||||
public static string GetLyrics(this ATL.Track track)
|
||||
{
|
||||
if (track.Path is string path)
|
||||
{
|
||||
return TagLib.File.Create(path).Tag.Lyrics;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
@@ -31,6 +32,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
private static readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
private static readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
|
||||
|
||||
private static DispatcherQueueTimer? _setLyricsWindowVisibilityByPlayingStatusTimer;
|
||||
|
||||
public static void HideWindow<T>()
|
||||
{
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
@@ -64,6 +67,15 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return default;
|
||||
}
|
||||
|
||||
public static IntPtr? GetWindowHandle(object? obj)
|
||||
{
|
||||
if (obj is FrameworkElement frameworkElement)
|
||||
{
|
||||
return frameworkElement.XamlRoot.ContentIslandEnvironment.AppWindowId.GetWindowHandle();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void OpenOrShowWindow<T>()
|
||||
{
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
@@ -101,6 +113,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
if (typeof(T) == typeof(LyricsWindow))
|
||||
{
|
||||
_liveStatesService.InitLyricsWindowStatus();
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(castedWindow);
|
||||
_defaultWindowStyle.Add(hwnd, castedWindow.GetWindowStyle());
|
||||
_defaultExtendedWindowStyle.Add(hwnd, castedWindow.GetExtendedWindowStyle());
|
||||
@@ -108,7 +122,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
var lyricsWindow = (LyricsWindow)window;
|
||||
lyricsWindow.ViewModel.InitShortcuts();
|
||||
lyricsWindow.ViewModel.InitFgWindowWatcher();
|
||||
lyricsWindow.ViewModel.RefreshLyricsWindowStatus();
|
||||
|
||||
_mediaSessionsService.InitPlaybackShortcuts();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -346,27 +361,36 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
||||
}
|
||||
|
||||
public static void SetLyricsWindowVisibilityByPlayingStatus()
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dispatcherQueue">请确保此参数指向同一个对象,建议传值 BaseViewModel._dispatcherQueue</param>
|
||||
public static void SetLyricsWindowVisibilityByPlayingStatus(DispatcherQueue dispatcherQueue)
|
||||
{
|
||||
var window = GetWindowByWindowType<LyricsWindow>();
|
||||
if (window == null) return;
|
||||
_setLyricsWindowVisibilityByPlayingStatusTimer ??= dispatcherQueue.CreateTimer();
|
||||
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && !_mediaSessionsService.IsPlaying)
|
||||
_setLyricsWindowVisibilityByPlayingStatusTimer.Debounce(() =>
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
var window = GetWindowByWindowType<LyricsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && !_mediaSessionsService.IsPlaying)
|
||||
{
|
||||
SetIsWorkArea<LyricsWindow>(false);
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
SetIsWorkArea<LyricsWindow>(false);
|
||||
}
|
||||
HideWindow<LyricsWindow>();
|
||||
}
|
||||
HideWindow<LyricsWindow>();
|
||||
}
|
||||
else if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && _mediaSessionsService.IsPlaying)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
else if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && _mediaSessionsService.IsPlaying)
|
||||
{
|
||||
SetIsWorkArea<LyricsWindow>(true);
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
SetIsWorkArea<LyricsWindow>(true);
|
||||
}
|
||||
OpenOrShowWindow<LyricsWindow>();
|
||||
}
|
||||
OpenOrShowWindow<LyricsWindow>();
|
||||
}
|
||||
}, Constants.Time.DebounceTimeout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Lyricify.Lyrics.Helpers.General;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -13,6 +15,8 @@ namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public class LyricsData
|
||||
{
|
||||
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public List<LyricsLine> LyricsLines { get; set; }
|
||||
private string? _languageCode;
|
||||
public string? LanguageCode
|
||||
@@ -138,7 +142,7 @@ namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
StartMs = 0,
|
||||
EndMs = durationMs,
|
||||
OriginalText = App.ResourceLoader!.GetString("LyricsNotFound"),
|
||||
OriginalText = _resourceService.GetLocalizedString("LyricsNotFound"),
|
||||
LyricsChars = [],
|
||||
}]);
|
||||
}
|
||||
|
||||
@@ -16,5 +16,6 @@ namespace BetterLyrics.WinUI3.Models
|
||||
|
||||
public string? Title { get; set; }
|
||||
public string? Artist { get; set; }
|
||||
public string? Album { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Windowing;
|
||||
using System;
|
||||
using Windows.Foundation;
|
||||
@@ -71,6 +73,16 @@ namespace BetterLyrics.WinUI3.Models
|
||||
newValue.PropertyChanged += OldAlbumArtLayoutSettings_PropertyChanged;
|
||||
}
|
||||
|
||||
partial void OnWindowBoundsChanged(Rect value)
|
||||
{
|
||||
UpdateMonitorNameAndBounds();
|
||||
UpdateDemoWindowAndMonitorBounds();
|
||||
WindowX = WindowBounds.X;
|
||||
WindowY = WindowBounds.Y;
|
||||
WindowWidth = WindowBounds.Width;
|
||||
WindowHeight = WindowBounds.Height;
|
||||
}
|
||||
|
||||
private void OldLyricsStyleSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
this.OnPropertyChanged(nameof(LyricsStyleSettings));
|
||||
@@ -91,11 +103,6 @@ namespace BetterLyrics.WinUI3.Models
|
||||
this.OnPropertyChanged(nameof(AlbumArtLayoutSettings));
|
||||
}
|
||||
|
||||
partial void OnAutoShowOrHideWindowChanged(bool value)
|
||||
{
|
||||
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
|
||||
}
|
||||
|
||||
public void UpdateMonitorNameAndBounds()
|
||||
{
|
||||
var lyricsWindow = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
@@ -138,6 +145,26 @@ namespace BetterLyrics.WinUI3.Models
|
||||
);
|
||||
}
|
||||
|
||||
public Rect GetWindowBoundsWhenWorkArea()
|
||||
{
|
||||
return new Rect(
|
||||
MonitorBounds.X,
|
||||
DockPlacement switch
|
||||
{
|
||||
DockPlacement.Top => MonitorBounds.Top,
|
||||
DockPlacement.Bottom => MonitorBounds.Bottom - DockHeight,
|
||||
_ => MonitorBounds.Top,
|
||||
} - 1,
|
||||
MonitorBounds.Width,
|
||||
DockPlacement switch
|
||||
{
|
||||
DockPlacement.Top => DockHeight,
|
||||
DockPlacement.Bottom => DockHeight,
|
||||
_ => DockHeight,
|
||||
} + 1
|
||||
);
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
@@ -158,6 +185,7 @@ namespace BetterLyrics.WinUI3.Models
|
||||
DemoWindowBounds = this.DemoWindowBounds,
|
||||
MonitorBounds = this.MonitorBounds,
|
||||
DemoMonitorBounds = this.DemoMonitorBounds,
|
||||
DockPlacement = this.DockPlacement,
|
||||
LyricsStyleSettings = (LyricsStyleSettings)this.LyricsStyleSettings.Clone(),
|
||||
LyricsEffectSettings = (LyricsEffectSettings)this.LyricsEffectSettings.Clone(),
|
||||
LyricsBackgroundSettings = (LyricsBackgroundSettings)this.LyricsBackgroundSettings.Clone(),
|
||||
@@ -176,11 +204,13 @@ namespace BetterLyrics.WinUI3.Models
|
||||
|
||||
public static class LyricsWindowStatusExtensions
|
||||
{
|
||||
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
|
||||
|
||||
public static LyricsWindowStatus DesktopMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("DesktopMode"),
|
||||
Name = _resourceService.GetLocalizedString("DesktopMode"),
|
||||
LyricsDisplayType = LyricsDisplayType.LyricsOnly,
|
||||
WindowBounds = new Rect(100, 100, 600, 250),
|
||||
IsAlwaysOnTop = true,
|
||||
@@ -192,7 +222,6 @@ namespace BetterLyrics.WinUI3.Models
|
||||
EnvironmentSampleMode = WindowPixelSampleMode.WindowEdge,
|
||||
LyricsStyleSettings = new()
|
||||
{
|
||||
OriginalLyricsFontSize = 20,
|
||||
LyricsAlignmentType = TextAlignmentType.Center,
|
||||
},
|
||||
LyricsBackgroundSettings = new LyricsBackgroundSettings
|
||||
@@ -204,9 +233,9 @@ namespace BetterLyrics.WinUI3.Models
|
||||
|
||||
public static LyricsWindowStatus DockedMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
var status = new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("DockedMode"),
|
||||
Name = _resourceService.GetLocalizedString("DockedMode"),
|
||||
IsWorkArea = true,
|
||||
IsAlwaysOnTop = true,
|
||||
IsAlwaysOnTopPolling = true,
|
||||
@@ -219,7 +248,6 @@ namespace BetterLyrics.WinUI3.Models
|
||||
LyricsStyleSettings = new LyricsStyleSettings
|
||||
{
|
||||
LyricsAlignmentType = TextAlignmentType.Center,
|
||||
OriginalLyricsFontSize = 18,
|
||||
},
|
||||
LyricsBackgroundSettings = new LyricsBackgroundSettings
|
||||
{
|
||||
@@ -227,38 +255,33 @@ namespace BetterLyrics.WinUI3.Models
|
||||
IsPureColorOverlayEnabled = true,
|
||||
}
|
||||
};
|
||||
status.WindowBounds = status.GetWindowBoundsWhenWorkArea();
|
||||
return status;
|
||||
}
|
||||
|
||||
public static LyricsWindowStatus FullscreenMode(Rect monitorBounds)
|
||||
public static LyricsWindowStatus FullscreenMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
var status = new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("FullscreenMode"),
|
||||
WindowBounds = monitorBounds,
|
||||
IsAlwaysOnTop = true,
|
||||
Name = _resourceService.GetLocalizedString("FullscreenMode"),
|
||||
IsBorderless = true,
|
||||
IsShownInSwitchers = false,
|
||||
TitleBarArea = Enums.TitleBarArea.None,
|
||||
LyricsLayoutOrientation = Enums.LyricsLayoutOrientation.Vertical,
|
||||
IsAlwaysOnTop = true,
|
||||
TitleBarArea = TitleBarArea.None,
|
||||
LyricsLayoutOrientation = LyricsLayoutOrientation.Vertical,
|
||||
LyricsStyleSettings = new LyricsStyleSettings
|
||||
{
|
||||
OriginalLyricsFontSize = 72,
|
||||
LyricsAlignmentType = Enums.TextAlignmentType.Center,
|
||||
LyricsAlignmentType = TextAlignmentType.Center,
|
||||
},
|
||||
AlbumArtLayoutSettings = new AlbumArtLayoutSettings
|
||||
{
|
||||
AutoAlbumArtSize = false,
|
||||
AlbumArtSize = 128,
|
||||
SongInfoFontSize = 36,
|
||||
}
|
||||
};
|
||||
status.WindowBounds = status.MonitorBounds;
|
||||
return status;
|
||||
}
|
||||
|
||||
public static LyricsWindowStatus StandardMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("StandardMode"),
|
||||
Name = _resourceService.GetLocalizedString("StandardMode"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -266,7 +289,7 @@ namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("NarrowMode"),
|
||||
Name = _resourceService.GetLocalizedString("NarrowMode"),
|
||||
WindowBounds = new Rect(100, 100, 400, 800),
|
||||
LyricsLayoutOrientation = LyricsLayoutOrientation.Vertical,
|
||||
};
|
||||
|
||||
@@ -12,9 +12,11 @@ namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalTitle { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalArtist { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalAlbum { get; set; } = string.Empty;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedTitle { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedArtist { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedAlbum { get; set; } = string.Empty;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsMarkedAsPureMusic { get; set; } = false;
|
||||
|
||||
@@ -26,8 +28,10 @@ namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
OriginalTitle = this.OriginalTitle,
|
||||
OriginalArtist = this.OriginalArtist,
|
||||
OriginalAlbum = this.OriginalAlbum,
|
||||
MappedTitle = this.MappedTitle,
|
||||
MappedArtist = this.MappedArtist,
|
||||
MappedAlbum = this.MappedAlbum,
|
||||
IsMarkedAsPureMusic = this.IsMarkedAsPureMusic,
|
||||
LyricsSearchProvider = this.LyricsSearchProvider
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MediaSourceProviderInfo> MediaSourceProvidersInfo { get; set; } = [];
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MappedSongSearchQuery> MappedSongSearchQueries { get; set; } = [];
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<LyricsWindowStatus> WindowBoundsRecords { get; set; } = [];
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<SongsTabInfo> StarredPlaylists { get; set; } = [];
|
||||
|
||||
public AppSettings() { }
|
||||
}
|
||||
|
||||
@@ -40,12 +40,24 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
return new LyricsBackgroundSettings
|
||||
{
|
||||
LyricsBackgroundTheme = this.LyricsBackgroundTheme,
|
||||
|
||||
IsPureColorOverlayEnabled = this.IsPureColorOverlayEnabled,
|
||||
PureColorOverlayOpacity = this.PureColorOverlayOpacity,
|
||||
|
||||
IsCoverOverlayEnabled = this.IsCoverOverlayEnabled,
|
||||
CoverOverlayBlurAmount = this.CoverOverlayBlurAmount,
|
||||
CoverOverlayOpacity = this.CoverOverlayOpacity,
|
||||
PureColorOverlayOpacity = this.PureColorOverlayOpacity,
|
||||
CoverOverlaySpeed = this.CoverOverlaySpeed,
|
||||
CoverAcrylicEffectAmount = this.CoverAcrylicEffectAmount,
|
||||
PaletteGeneratorType = this.PaletteGeneratorType
|
||||
|
||||
IsFluidOverlayEnabled = this.IsFluidOverlayEnabled,
|
||||
FluidOverlayOpacity = this.FluidOverlayOpacity,
|
||||
PaletteGeneratorType = this.PaletteGeneratorType,
|
||||
|
||||
IsSpectrumOverlayEnabled = this.IsSpectrumOverlayEnabled,
|
||||
|
||||
IsSnowFlakeOverlayEnabled = this.IsSnowFlakeOverlayEnabled,
|
||||
SnowFlakeOverlayAmount = this.SnowFlakeOverlayAmount,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,24 +61,42 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
return new LyricsEffectSettings(this.LyricsScrollTopDuration, this.LyricsScrollDuration, this.LyricsScrollBottomDuration, this.LyricsScrollEasingType)
|
||||
{
|
||||
LyricsBlurAmount = this.LyricsBlurAmount,
|
||||
|
||||
IsLyricsLineFadeEnabled = this.IsLyricsLineFadeEnabled,
|
||||
|
||||
IsLyricsGlowEffectEnabled = this.IsLyricsGlowEffectEnabled,
|
||||
LyricsGlowEffectScope = this.LyricsGlowEffectScope,
|
||||
LyricsGlowEffectAmount = this.LyricsGlowEffectAmount,
|
||||
|
||||
IsLyricsShadowEnabled = this.IsLyricsShadowEnabled,
|
||||
LyricsShadowScope = this.LyricsShadowScope,
|
||||
LyricsShadowAmount = this.LyricsShadowAmount,
|
||||
|
||||
OriginalLyricsHighlightScope = this.OriginalLyricsHighlightScope,
|
||||
PhoneticLyricsHighlightAmount = this.PhoneticLyricsHighlightAmount,
|
||||
OriginalLyricsHighlightAmount = this.OriginalLyricsHighlightAmount,
|
||||
TranslatedLyricsHighlightAmount = this.TranslatedLyricsHighlightAmount,
|
||||
|
||||
IsLyricsFloatAnimationEnabled = this.IsLyricsFloatAnimationEnabled,
|
||||
LyricsFloatAmount = this.LyricsFloatAmount,
|
||||
|
||||
LyricsScrollEasingType = this.LyricsScrollEasingType,
|
||||
LyricsScrollDuration = this.LyricsScrollDuration,
|
||||
LyricsScrollTopDuration = this.LyricsScrollTopDuration,
|
||||
LyricsScrollBottomDuration = this.LyricsScrollBottomDuration,
|
||||
LyricsScrollTopDelay = this.LyricsScrollTopDelay,
|
||||
LyricsScrollBottomDelay = this.LyricsScrollBottomDelay,
|
||||
|
||||
LyricsVerticalEdgeOpacity = this.LyricsVerticalEdgeOpacity,
|
||||
|
||||
IsFanLyricsEnabled = this.IsFanLyricsEnabled,
|
||||
FanLyricsAngle = this.FanLyricsAngle,
|
||||
|
||||
Is3DLyricsEnabled = this.Is3DLyricsEnabled,
|
||||
Lyrics3DXAngle = this.Lyrics3DXAngle,
|
||||
Lyrics3DYAngle = this.Lyrics3DYAngle,
|
||||
Lyrics3DZAngle = this.Lyrics3DZAngle,
|
||||
Lyrics3DDepth = this.Lyrics3DDepth,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -11,6 +12,10 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
public partial class MusicGallerySettings : ObservableRecipient
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial PlaybackOrder PlaybackOrder { get; set; } = PlaybackOrder.RepeatAll;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial ObservableCollection<string> PlayQueuePaths { get; set; } = [];
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int PlayQueueIndex { get; set; } = -1;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoOpen { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoPlay { get; set; } = false;
|
||||
|
||||
public MusicGallerySettings() { }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.UI;
|
||||
|
||||
@@ -9,7 +10,7 @@ namespace BetterLyrics.WinUI3.Models
|
||||
public partial class SongInfo : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
public partial string? Album { get; set; }
|
||||
public partial string Album { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Artist { get; set; }
|
||||
@@ -31,4 +32,14 @@ namespace BetterLyrics.WinUI3.Models
|
||||
|
||||
public SongInfo() { }
|
||||
}
|
||||
|
||||
public static class SongInfoExtensions
|
||||
{
|
||||
public static SongInfo Placeholder => new()
|
||||
{
|
||||
Title = "N/A",
|
||||
Album = "N/A",
|
||||
Artist = "N/A",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public class SongsTabInfo
|
||||
public partial class SongsTabInfo : BaseViewModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
@@ -10,6 +12,9 @@ namespace BetterLyrics.WinUI3.Models
|
||||
|
||||
public bool IsClosable { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsStarred { get; set; }
|
||||
|
||||
public CommonSongProperty FilterProperty { get; set; }
|
||||
|
||||
public string FilterValue { get; set; }
|
||||
@@ -19,15 +24,17 @@ namespace BetterLyrics.WinUI3.Models
|
||||
Name = string.Empty;
|
||||
Icon = string.Empty;
|
||||
IsClosable = true;
|
||||
IsStarred = false;
|
||||
FilterProperty = CommonSongProperty.Title;
|
||||
FilterValue = string.Empty;
|
||||
}
|
||||
|
||||
public SongsTabInfo(string name, string icon, bool isClosable, CommonSongProperty filterProperty, string filterValue)
|
||||
public SongsTabInfo(string name, string icon, bool isClosable, bool isStarred, CommonSongProperty filterProperty, string filterValue)
|
||||
{
|
||||
Name = name;
|
||||
Icon = icon;
|
||||
IsClosable = isClosable;
|
||||
IsStarred = isStarred;
|
||||
FilterProperty = filterProperty;
|
||||
FilterValue = filterValue;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<Grid>
|
||||
<canvas:CanvasAnimatedControl
|
||||
x:Name="LyricsCanvas"
|
||||
CreateResources="LyricsCanvas_CreateResources"
|
||||
Draw="LyricsCanvas_Draw"
|
||||
Update="LyricsCanvas_Update" />
|
||||
</Grid>
|
||||
|
||||
@@ -35,5 +35,10 @@ namespace BetterLyrics.WinUI3.Renderer
|
||||
LyricsCanvas.RemoveFromVisualTree();
|
||||
LyricsCanvas = null;
|
||||
}
|
||||
|
||||
private void LyricsCanvas_CreateResources(Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
|
||||
{
|
||||
ViewModel.CreateResources(sender, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using BetterLyrics.WinUI3.Events;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
@@ -25,6 +27,8 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
|
||||
public partial class LastFMService : ILastFMService
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IResourceService _resourceService;
|
||||
|
||||
private readonly LastfmClient _client;
|
||||
|
||||
public event EventHandler<LastFMUserChangedEventArgs>? UserChanged;
|
||||
@@ -34,9 +38,10 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
|
||||
|
||||
public bool IsAuthenticated { get; private set; }
|
||||
|
||||
public LastFMService(ISettingsService settingsService)
|
||||
public LastFMService(ISettingsService settingsService, IResourceService resourceService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_resourceService = resourceService;
|
||||
|
||||
_client = new LastfmClient(Constants.LastFM.ApiKey, Constants.LastFM.SharedSecret);
|
||||
_client.Session.SessionKey = PasswordVaultHelper.Get(Constants.App.AppName, Constants.LastFM.SessionKeyCredentialKey) ?? string.Empty;
|
||||
@@ -53,7 +58,7 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader?.GetString("LastFMAuthFailed") ?? "", InfoBarSeverity.Error);
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("LastFMAuthFailed") ?? "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,10 +79,10 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
|
||||
|
||||
var dialog = new ContentDialog
|
||||
{
|
||||
Title = App.ResourceLoader?.GetString("LastFMRequestAuthTitle") ?? "",
|
||||
Content = App.ResourceLoader?.GetString("LastFMRequestAuthDesc") ?? "",
|
||||
PrimaryButtonText = App.ResourceLoader?.GetString("LastFMRequestAuthConfirm") ?? "",
|
||||
CloseButtonText = App.ResourceLoader?.GetString("Cancel") ?? "",
|
||||
Title = _resourceService.GetLocalizedString("LastFMRequestAuthTitle") ?? "",
|
||||
Content = _resourceService.GetLocalizedString("LastFMRequestAuthDesc") ?? "",
|
||||
PrimaryButtonText = _resourceService.GetLocalizedString("LastFMRequestAuthConfirm") ?? "",
|
||||
CloseButtonText = _resourceService.GetLocalizedString("Cancel") ?? "",
|
||||
DefaultButton = ContentDialogButton.Close,
|
||||
XamlRoot = dialogXamlRoot,
|
||||
};
|
||||
@@ -101,10 +106,10 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
|
||||
|
||||
var dialog = new ContentDialog
|
||||
{
|
||||
Title = App.ResourceLoader?.GetString("LastFMRequestUnAuthTitle") ?? "",
|
||||
Content = App.ResourceLoader?.GetString("LastFMRequestUnAuthDesc") ?? "",
|
||||
PrimaryButtonText = App.ResourceLoader?.GetString("LastFMRequestUnAuthConfirm") ?? "",
|
||||
CloseButtonText = App.ResourceLoader?.GetString("Cancel") ?? "",
|
||||
Title = _resourceService.GetLocalizedString("LastFMRequestUnAuthTitle") ?? "",
|
||||
Content = _resourceService.GetLocalizedString("LastFMRequestUnAuthDesc") ?? "",
|
||||
PrimaryButtonText = _resourceService.GetLocalizedString("LastFMRequestUnAuthConfirm") ?? "",
|
||||
CloseButtonText = _resourceService.GetLocalizedString("Cancel") ?? "",
|
||||
DefaultButton = ContentDialogButton.Close,
|
||||
XamlRoot = dialogXamlRoot,
|
||||
};
|
||||
|
||||
@@ -10,6 +10,6 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
|
||||
public interface ILiveStatesService
|
||||
{
|
||||
LiveStates LiveStates { get; set; }
|
||||
void RefreshLyricsWindowStatus();
|
||||
void InitLyricsWindowStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using CommunityToolkit.WinUI.Controls;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@@ -11,32 +13,75 @@ using Windows.Foundation;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.LiveStatesService
|
||||
{
|
||||
public partial class LiveStatesService : BaseViewModel, ILiveStatesService
|
||||
public partial class LiveStatesService : BaseViewModel, ILiveStatesService,
|
||||
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public LiveStates LiveStates { get; set; } = new();
|
||||
public LiveStates LiveStates { get; set; } = new LiveStates();
|
||||
|
||||
public LiveStatesService(ISettingsService settingsService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
LiveStates.PropertyChanged += LiveStates_PropertyChanged;
|
||||
LiveStates.PropertyChanging += LiveStates_PropertyChanging;
|
||||
InitLyricsWindowStatus();
|
||||
}
|
||||
|
||||
private void LiveStates_PropertyChanging(object? sender, System.ComponentModel.PropertyChangingEventArgs e)
|
||||
public void InitLyricsWindowStatus()
|
||||
{
|
||||
if (e.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
var defaultLyricsWindowStatus = _settingsService.AppSettings.WindowBoundsRecords.FirstOrDefault(x => x.IsDefault);
|
||||
if (defaultLyricsWindowStatus == null)
|
||||
{
|
||||
LiveStates.LyricsWindowStatus.PropertyChanged -= LyricsWindowStatus_PropertyChanged;
|
||||
defaultLyricsWindowStatus = LyricsWindowStatusExtensions.StandardMode();
|
||||
defaultLyricsWindowStatus.IsDefault = true;
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(defaultLyricsWindowStatus);
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.DesktopMode());
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.DockedMode());
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.NarrowMode());
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.FullscreenMode());
|
||||
}
|
||||
LiveStates.LyricsWindowStatus = defaultLyricsWindowStatus;
|
||||
}
|
||||
|
||||
private async void RefreshLyricsWindowStatus()
|
||||
{
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
|
||||
LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
|
||||
|
||||
WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
WindowHelper.UpdateWorkArea<LyricsWindow>();
|
||||
}
|
||||
await Task.Delay(300);
|
||||
|
||||
WindowHelper.SetIsShowInSwitchers<LyricsWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers);
|
||||
WindowHelper.SetIsAlwaysOnTop<LyricsWindow>(LiveStates.LyricsWindowStatus.IsAlwaysOnTop);
|
||||
|
||||
WindowHelper.SetIsClickThrough<LyricsWindow>(LiveStates.LyricsWindowStatus.IsClickThrough);
|
||||
WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
|
||||
|
||||
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
|
||||
WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
|
||||
|
||||
// 下述代码可以删除,但是为了避免给用户造成操作上的疑虑,暂时保留
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
LiveStates.LyricsWindowStatus.WindowBounds = LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea();
|
||||
}
|
||||
|
||||
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds);
|
||||
LiveStates.LyricsWindowStatus.WindowX = LiveStates.LyricsWindowStatus.WindowBounds.X;
|
||||
LiveStates.LyricsWindowStatus.WindowY = LiveStates.LyricsWindowStatus.WindowBounds.Y;
|
||||
LiveStates.LyricsWindowStatus.WindowWidth = LiveStates.LyricsWindowStatus.WindowBounds.Width;
|
||||
LiveStates.LyricsWindowStatus.WindowHeight = LiveStates.LyricsWindowStatus.WindowBounds.Height;
|
||||
|
||||
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
|
||||
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = false;
|
||||
}
|
||||
|
||||
private async void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(LyricsWindowStatus.IsWorkArea):
|
||||
@@ -44,7 +89,7 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
await Task.Delay(300);
|
||||
WindowHelper.MoveAndResize<LyricsWindow>(GetWindowBoundsWhenWorkArea());
|
||||
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea());
|
||||
}
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.DockHeight):
|
||||
@@ -55,7 +100,7 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
|
||||
{
|
||||
WindowHelper.UpdateWorkArea<LyricsWindow>();
|
||||
await Task.Delay(300);
|
||||
WindowHelper.MoveAndResize<LyricsWindow>(GetWindowBoundsWhenWorkArea());
|
||||
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea());
|
||||
}
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsShownInSwitchers):
|
||||
@@ -82,91 +127,28 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
|
||||
case nameof(LyricsWindowStatus.WindowHeight):
|
||||
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithHeight(LiveStates.LyricsWindowStatus.WindowHeight));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowBounds):
|
||||
LiveStates.LyricsWindowStatus.UpdateMonitorNameAndBounds();
|
||||
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
|
||||
LiveStates.LyricsWindowStatus.WindowX = LiveStates.LyricsWindowStatus.WindowBounds.X;
|
||||
LiveStates.LyricsWindowStatus.WindowY = LiveStates.LyricsWindowStatus.WindowBounds.Y;
|
||||
LiveStates.LyricsWindowStatus.WindowWidth = LiveStates.LyricsWindowStatus.WindowBounds.Width;
|
||||
LiveStates.LyricsWindowStatus.WindowHeight = LiveStates.LyricsWindowStatus.WindowBounds.Height;
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.TitleBarArea):
|
||||
WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.AutoShowOrHideWindow):
|
||||
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
}
|
||||
|
||||
private void LiveStates_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
public void Receive(PropertyChangedMessage<LyricsWindowStatus> message)
|
||||
{
|
||||
if (e.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
if (message.Sender is LiveStates)
|
||||
{
|
||||
LiveStates.LyricsWindowStatus.PropertyChanged += LyricsWindowStatus_PropertyChanged;
|
||||
RefreshLyricsWindowStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitLyricsWindowStatus()
|
||||
{
|
||||
var defaultLyricsWindowStatus = _settingsService.AppSettings.WindowBoundsRecords.FirstOrDefault(x => x.IsDefault);
|
||||
if (defaultLyricsWindowStatus == null)
|
||||
{
|
||||
defaultLyricsWindowStatus = LyricsWindowStatusExtensions.StandardMode();
|
||||
defaultLyricsWindowStatus.IsDefault = true;
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(defaultLyricsWindowStatus);
|
||||
}
|
||||
LiveStates.LyricsWindowStatus = defaultLyricsWindowStatus;
|
||||
}
|
||||
|
||||
public async void RefreshLyricsWindowStatus()
|
||||
{
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
|
||||
LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
|
||||
|
||||
WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
|
||||
await Task.Delay(300);
|
||||
|
||||
WindowHelper.SetIsShowInSwitchers<LyricsWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers);
|
||||
WindowHelper.SetIsAlwaysOnTop<LyricsWindow>(LiveStates.LyricsWindowStatus.IsAlwaysOnTop);
|
||||
WindowHelper.SetIsClickThrough<LyricsWindow>(LiveStates.LyricsWindowStatus.IsClickThrough);
|
||||
WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
|
||||
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
|
||||
WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
|
||||
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
LiveStates.LyricsWindowStatus.WindowBounds = GetWindowBoundsWhenWorkArea();
|
||||
}
|
||||
|
||||
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds);
|
||||
|
||||
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
|
||||
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = false;
|
||||
}
|
||||
|
||||
private Rect GetWindowBoundsWhenWorkArea()
|
||||
{
|
||||
return new Rect(
|
||||
LiveStates.LyricsWindowStatus.MonitorBounds.X,
|
||||
LiveStates.LyricsWindowStatus.DockPlacement switch
|
||||
if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
{
|
||||
Enums.DockPlacement.Top => LiveStates.LyricsWindowStatus.MonitorBounds.Top,
|
||||
Enums.DockPlacement.Bottom => LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - LiveStates.LyricsWindowStatus.DockHeight - 1,
|
||||
_ => LiveStates.LyricsWindowStatus.MonitorBounds.Top,
|
||||
},
|
||||
LiveStates.LyricsWindowStatus.MonitorBounds.Width,
|
||||
LiveStates.LyricsWindowStatus.DockPlacement switch
|
||||
{
|
||||
Enums.DockPlacement.Top => LiveStates.LyricsWindowStatus.DockHeight,
|
||||
Enums.DockPlacement.Bottom => LiveStates.LyricsWindowStatus.DockHeight + 1,
|
||||
_ => LiveStates.LyricsWindowStatus.DockHeight,
|
||||
message.OldValue.PropertyChanged -= LyricsWindowStatus_PropertyChanged;
|
||||
message.NewValue.PropertyChanged += LyricsWindowStatus_PropertyChanged;
|
||||
RefreshLyricsWindowStatus();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,17 +98,19 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
|
||||
string overridenTitle = title;
|
||||
string overridenArtist = artist;
|
||||
string overridenAlbum = album;
|
||||
|
||||
_logger.LogInformation("Searching img for: {Title} - {Artist} (Album: {Album}, Duration: {DurationMs}ms)", title, artist, album, durationMs);
|
||||
|
||||
var found = _settingsService.AppSettings.MappedSongSearchQueries
|
||||
.Where(x => x.OriginalTitle == title && x.OriginalArtist == artist)
|
||||
.Where(x => x.OriginalTitle == overridenTitle && x.OriginalArtist == overridenArtist && x.OriginalAlbum == overridenAlbum)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (found != null)
|
||||
{
|
||||
overridenTitle = found.MappedTitle;
|
||||
overridenArtist = found.MappedArtist;
|
||||
overridenAlbum = found.MappedAlbum;
|
||||
|
||||
_logger.LogInformation("Found mapped song search query: {MappedSongSearchQuery}", found);
|
||||
|
||||
@@ -117,6 +119,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
lyricsSearchResult.Title = overridenTitle;
|
||||
lyricsSearchResult.Artist = overridenArtist;
|
||||
lyricsSearchResult.Album = overridenAlbum;
|
||||
lyricsSearchResult.Raw = "[99:00.000]🎶🎶🎶";
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
@@ -124,7 +127,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
var targetProvider = found.LyricsSearchProvider;
|
||||
if (targetProvider != null)
|
||||
{
|
||||
return await SearchSingleAsync(targetProvider.Value, overridenTitle, overridenArtist, album, durationMs, songId, token);
|
||||
return await SearchSingleAsync(targetProvider.Value, overridenTitle, overridenArtist, overridenAlbum, durationMs, songId, token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +138,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
continue;
|
||||
}
|
||||
|
||||
lyricsSearchResult = await SearchSingleAsync(provider.Provider, overridenTitle, overridenArtist, album, durationMs, null, token);
|
||||
lyricsSearchResult = await SearchSingleAsync(provider.Provider, overridenTitle, overridenArtist, overridenAlbum, durationMs, null, token);
|
||||
|
||||
if (lyricsSearchResult.IsFound)
|
||||
{
|
||||
@@ -172,12 +175,13 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
// Check cache first
|
||||
if (provider.IsRemote())
|
||||
{
|
||||
var cachedLyrics = FileHelper.ReadLyricsCache(title, artist, lyricsFormat, provider.GetCacheDirectory());
|
||||
var cachedLyrics = FileHelper.ReadLyricsCache(title, artist, album, lyricsFormat, provider.GetCacheDirectory());
|
||||
if (!string.IsNullOrWhiteSpace(cachedLyrics))
|
||||
{
|
||||
lyricsSearchResult.Raw = cachedLyrics;
|
||||
lyricsSearchResult.Title = title;
|
||||
lyricsSearchResult.Artist = artist;
|
||||
lyricsSearchResult.Album = album;
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
}
|
||||
@@ -186,11 +190,11 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
if (provider == LyricsSearchProvider.LocalMusicFile)
|
||||
{
|
||||
lyricsSearchResult = SearchEmbedded(title, artist);
|
||||
lyricsSearchResult = SearchEmbedded(title, artist, album);
|
||||
}
|
||||
else
|
||||
{
|
||||
lyricsSearchResult = await SearchFile(title, artist, lyricsFormat);
|
||||
lyricsSearchResult = await SearchFile(title, artist, album, lyricsFormat);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -210,7 +214,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, songId, Searchers.Netease);
|
||||
break;
|
||||
case LyricsSearchProvider.AmllTtmlDb:
|
||||
lyricsSearchResult = await SearchAmllTtmlDbAsync(title, artist);
|
||||
lyricsSearchResult = await SearchAmllTtmlDbAsync(title, artist, album);
|
||||
break;
|
||||
case LyricsSearchProvider.AppleMusic:
|
||||
lyricsSearchResult = await SearchAppleMusicAsync(title, artist, album, (int)durationMs);
|
||||
@@ -229,7 +233,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
if (provider.IsRemote())
|
||||
{
|
||||
FileHelper.WriteLyricsCache(title, artist, lyricsSearchResult.Raw!, lyricsFormat, provider.GetCacheDirectory());
|
||||
FileHelper.WriteLyricsCache(title, artist, album, lyricsSearchResult.Raw!, lyricsFormat, provider.GetCacheDirectory());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,7 +244,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
|
||||
private async Task<LyricsSearchResult> SearchFile(string title, string artist, LyricsFormat format)
|
||||
private async Task<LyricsSearchResult> SearchFile(string title, string artist, string album, LyricsFormat format)
|
||||
{
|
||||
var lyricsSearchResult = new LyricsSearchResult
|
||||
{
|
||||
@@ -263,6 +267,9 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
lyricsSearchResult.Raw = raw;
|
||||
lyricsSearchResult.Title = title;
|
||||
lyricsSearchResult.Artist = artist;
|
||||
lyricsSearchResult.Album = album;
|
||||
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +282,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
|
||||
private LyricsSearchResult SearchEmbedded(string title, string artist)
|
||||
private LyricsSearchResult SearchEmbedded(string title, string artist, string album)
|
||||
{
|
||||
var lyricsSearchResult = new LyricsSearchResult
|
||||
{
|
||||
@@ -291,14 +298,19 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
if (FileHelper.MusicExtensions.Contains(Path.GetExtension(file)))
|
||||
{
|
||||
var track = new Track(file);
|
||||
if ((track.Title == title && track.Artist == artist) || FileHelper.IsSwitchableNormalizedMatch(Path.GetFileNameWithoutExtension(file), title, artist))
|
||||
if ((album != "" && track.Title == title && track.Artist == artist && track.Album == album)
|
||||
|| (album == "" && track.Title == title && track.Artist == artist)
|
||||
|| (album == "" && FileHelper.IsSwitchableNormalizedMatch(Path.GetFileNameWithoutExtension(file), title, artist)))
|
||||
{
|
||||
var plain = TagLib.File.Create(file).Tag.Lyrics;
|
||||
var plain = track.GetLyrics();
|
||||
if (!plain.IsNullOrEmpty())
|
||||
{
|
||||
lyricsSearchResult.Raw = plain;
|
||||
lyricsSearchResult.Title = track.Title;
|
||||
lyricsSearchResult.Artist = artist;
|
||||
lyricsSearchResult.Artist = track.Artist;
|
||||
lyricsSearchResult.Album = track.Album;
|
||||
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +320,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
|
||||
private async Task<LyricsSearchResult> SearchAmllTtmlDbAsync(string title, string artist)
|
||||
private async Task<LyricsSearchResult> SearchAmllTtmlDbAsync(string title, string artist, string album)
|
||||
{
|
||||
var lyricsSearchResult = new LyricsSearchResult
|
||||
{
|
||||
@@ -382,6 +394,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
lyricsSearchResult.Raw = lyrics;
|
||||
lyricsSearchResult.Title = title;
|
||||
lyricsSearchResult.Artist = artist;
|
||||
lyricsSearchResult.Album = album;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -421,6 +434,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
string? original = null;
|
||||
string? searchedTitle = null;
|
||||
string? searchedArtist = null;
|
||||
string? searchedAlbum = null;
|
||||
|
||||
if (jArr.ValueKind == JsonValueKind.Array && jArr.GetArrayLength() > 0)
|
||||
{
|
||||
@@ -428,11 +442,13 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
original = first.GetProperty("syncedLyrics").GetString();
|
||||
searchedTitle = first.GetProperty("trackName").GetString();
|
||||
searchedArtist = first.GetProperty("artistName").GetString();
|
||||
searchedAlbum = first.GetProperty("albumName").GetString();
|
||||
}
|
||||
|
||||
lyricsSearchResult.Raw = original;
|
||||
lyricsSearchResult.Title = searchedTitle;
|
||||
lyricsSearchResult.Artist = searchedArtist;
|
||||
lyricsSearchResult.Album = searchedAlbum;
|
||||
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
@@ -475,89 +491,93 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
}, searcher);
|
||||
}
|
||||
|
||||
if (result is QQMusicSearchResult qqResult)
|
||||
if (result != null)
|
||||
{
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.QQMusicApi.GetLyricsAsync(qqResult.Id);
|
||||
var original = response?.Lyrics;
|
||||
var translated = response?.Trans;
|
||||
if (!string.IsNullOrEmpty(translated))
|
||||
if (result is QQMusicSearchResult qqResult)
|
||||
{
|
||||
FileHelper.WriteLyricsCache(
|
||||
title,
|
||||
artist,
|
||||
translated,
|
||||
LyricsFormat.Lrc,
|
||||
PathHelper.QQTranslationCacheDirectory
|
||||
);
|
||||
}
|
||||
|
||||
lyricsSearchResult.Raw = original;
|
||||
lyricsSearchResult.Title = qqResult.Title;
|
||||
lyricsSearchResult.Artist = qqResult.Artists.Join(" | ");
|
||||
}
|
||||
else if (result is NeteaseSearchResult neteaseResult)
|
||||
{
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.NeteaseApi.GetLyric(neteaseResult.Id);
|
||||
var original = response?.Lrc?.Lyric;
|
||||
var translated = response?.Tlyric?.Lyric;
|
||||
if (!string.IsNullOrEmpty(translated))
|
||||
{
|
||||
FileHelper.WriteLyricsCache(
|
||||
title,
|
||||
artist,
|
||||
translated,
|
||||
LyricsFormat.Lrc,
|
||||
PathHelper.NeteaseTranslationCacheDirectory
|
||||
);
|
||||
}
|
||||
|
||||
lyricsSearchResult.Raw = original;
|
||||
lyricsSearchResult.Title = neteaseResult.Title;
|
||||
lyricsSearchResult.Artist = neteaseResult.Artists.Join(" | ");
|
||||
}
|
||||
else if (result is KugouSearchResult kugouResult)
|
||||
{
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.KugouApi.GetSearchLyrics(hash: kugouResult.Hash);
|
||||
string? original = null;
|
||||
var candidate = response?.Candidates.FirstOrDefault();
|
||||
if (candidate != null)
|
||||
{
|
||||
original = await Lyricify.Lyrics.Decrypter.Krc.Helper.GetLyricsAsync(candidate.Id, candidate.AccessKey);
|
||||
if (original != null)
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.QQMusicApi.GetLyricsAsync(qqResult.Id);
|
||||
var original = response?.Lyrics;
|
||||
var translated = response?.Trans;
|
||||
if (!string.IsNullOrEmpty(translated))
|
||||
{
|
||||
var parsedList = Lyricify.Lyrics.Parsers.KrcParser.ParseLyrics(original);
|
||||
if (parsedList != null)
|
||||
FileHelper.WriteLyricsCache(
|
||||
title,
|
||||
artist,
|
||||
album,
|
||||
translated,
|
||||
LyricsFormat.Lrc,
|
||||
PathHelper.QQTranslationCacheDirectory
|
||||
);
|
||||
}
|
||||
|
||||
lyricsSearchResult.Raw = original;
|
||||
}
|
||||
else if (result is NeteaseSearchResult neteaseResult)
|
||||
{
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.NeteaseApi.GetLyric(neteaseResult.Id);
|
||||
var original = response?.Lrc?.Lyric;
|
||||
var translated = response?.Tlyric?.Lyric;
|
||||
if (!string.IsNullOrEmpty(translated))
|
||||
{
|
||||
FileHelper.WriteLyricsCache(
|
||||
title,
|
||||
artist,
|
||||
album,
|
||||
translated,
|
||||
LyricsFormat.Lrc,
|
||||
PathHelper.NeteaseTranslationCacheDirectory
|
||||
);
|
||||
}
|
||||
|
||||
lyricsSearchResult.Raw = original;
|
||||
}
|
||||
else if (result is KugouSearchResult kugouResult)
|
||||
{
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.KugouApi.GetSearchLyrics(hash: kugouResult.Hash);
|
||||
string? original = null;
|
||||
var candidate = response?.Candidates.FirstOrDefault();
|
||||
if (candidate != null)
|
||||
{
|
||||
original = await Lyricify.Lyrics.Decrypter.Krc.Helper.GetLyricsAsync(candidate.Id, candidate.AccessKey);
|
||||
if (original != null)
|
||||
{
|
||||
string translated = "";
|
||||
foreach (var item in parsedList)
|
||||
var parsedList = Lyricify.Lyrics.Parsers.KrcParser.ParseLyrics(original);
|
||||
if (parsedList != null)
|
||||
{
|
||||
if (item is Lyricify.Lyrics.Models.FullSyllableLineInfo fullSyllableLineInfo)
|
||||
string translated = "";
|
||||
foreach (var item in parsedList)
|
||||
{
|
||||
var startTimeSpan = TimeSpan.FromMilliseconds(fullSyllableLineInfo.StartTime ?? 0);
|
||||
string startTimeStr = startTimeSpan.ToString(@"mm\:ss\.ff");
|
||||
string chTranslation = fullSyllableLineInfo.Translations.GetValueOrDefault("zh") ?? "";
|
||||
translated += $"[{startTimeStr}]{chTranslation}\n";
|
||||
if (item is Lyricify.Lyrics.Models.FullSyllableLineInfo fullSyllableLineInfo)
|
||||
{
|
||||
var startTimeSpan = TimeSpan.FromMilliseconds(fullSyllableLineInfo.StartTime ?? 0);
|
||||
string startTimeStr = startTimeSpan.ToString(@"mm\:ss\.ff");
|
||||
string chTranslation = fullSyllableLineInfo.Translations.GetValueOrDefault("zh") ?? "";
|
||||
translated += $"[{startTimeStr}]{chTranslation}\n";
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(translated))
|
||||
{
|
||||
FileHelper.WriteLyricsCache(
|
||||
title,
|
||||
artist,
|
||||
album,
|
||||
translated,
|
||||
LyricsFormat.Lrc,
|
||||
PathHelper.KugouTranslationCacheDirectory
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(translated))
|
||||
{
|
||||
FileHelper.WriteLyricsCache(
|
||||
title,
|
||||
artist,
|
||||
translated,
|
||||
LyricsFormat.Lrc,
|
||||
PathHelper.KugouTranslationCacheDirectory
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lyricsSearchResult.Raw = original;
|
||||
lyricsSearchResult.Title = kugouResult.Title;
|
||||
lyricsSearchResult.Artist = kugouResult.Artists.Join(" | ");
|
||||
lyricsSearchResult.Raw = original;
|
||||
}
|
||||
}
|
||||
|
||||
lyricsSearchResult.Title = result?.Title;
|
||||
lyricsSearchResult.Artist = result?.Artists.Join(" | ");
|
||||
lyricsSearchResult.Album = result?.Album;
|
||||
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
|
||||
@@ -575,6 +595,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
lyricsSearchResult.Raw = raw;
|
||||
lyricsSearchResult.Title = title;
|
||||
lyricsSearchResult.Artist = artist;
|
||||
lyricsSearchResult.Album = "";
|
||||
}
|
||||
|
||||
return lyricsSearchResult;
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
void UpdateLyrics();
|
||||
void UpdateTranslations();
|
||||
|
||||
void InitPlaybackShortcuts();
|
||||
|
||||
bool IsPlaying { get; }
|
||||
SongInfo? SongInfo { get; }
|
||||
TimeSpan Position { get; }
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
SongInfo?.PlayerId ?? "",
|
||||
_cachedSongInfo.Title,
|
||||
_cachedSongInfo.Artist,
|
||||
_cachedSongInfo?.Album ?? string.Empty,
|
||||
_cachedSongInfo.Album,
|
||||
_SMTCAlbumArtBuffer,
|
||||
token
|
||||
), token);
|
||||
@@ -46,7 +46,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
|
||||
if (buffer == null)
|
||||
{
|
||||
using var placeHolderStream = await ImageHelper.CreateTextPlaceholderBytesAsync(500, 500);
|
||||
using var placeHolderStream = await ImageHelper.GetAlbumArtPlaceholderAsync();
|
||||
var tempBuffer = new Windows.Storage.Streams.Buffer((uint)placeHolderStream.Size);
|
||||
await placeHolderStream.ReadAsync(tempBuffer, (uint)placeHolderStream.Size, InputStreamOptions.None);
|
||||
buffer = tempBuffer;
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
if (originalText == null) return;
|
||||
|
||||
string? originalLangCode = LanguageHelper.DetectLanguageCode(originalText);
|
||||
_logger.LogInformation("Original language code: {OriginalLangCode}", originalLangCode ?? "null");
|
||||
_logger.LogInformation("Original language code: {OriginalLangCode}", originalLangCode);
|
||||
|
||||
if (originalLangCode == targetLangCode)
|
||||
{
|
||||
@@ -83,7 +83,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
int found = _translateService.SearchTranslatedLyricsItself(_lyricsDataArr, targetLangCode);
|
||||
if (found >= 0)
|
||||
{
|
||||
_logger.LogInformation("Found translation in lyrics data at index {FoundIndex}", found);
|
||||
_logger.LogInformation("Found translated text in lyrics data at index {FoundIndex}", found);
|
||||
|
||||
_lyricsDataArr[0].SetTranslatedText(_lyricsDataArr[found], _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsTranslationSeparator, 50);
|
||||
TranslationSearchProvider = LyricsSearchProvider.ToTranslationSearchProvider();
|
||||
@@ -104,7 +104,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
App.Current.LyricsWindowNotificationPanel?.Notify(App.ResourceLoader?.GetString("LibreTranslateFailed")!, Microsoft.UI.Xaml.Controls.InfoBarSeverity.Error);
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("LibreTranslateFailed")!);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
if (originalText == null) return;
|
||||
|
||||
string? originalLangCode = LanguageHelper.DetectLanguageCode(originalText);
|
||||
_logger.LogInformation("Original language code: {OriginalLangCode}", originalLangCode ?? "null");
|
||||
_logger.LogInformation("Original phonetic code: {OriginalLangCode}", originalLangCode);
|
||||
|
||||
if (originalLangCode == "zh" && _settingsService.AppSettings.TranslationSettings.IsChineseRomanizationEnabled)
|
||||
{
|
||||
@@ -139,7 +139,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
int found = _translateService.SearchTranslatedLyricsItself(_lyricsDataArr, targetPhoneticCode);
|
||||
if (found >= 0)
|
||||
{
|
||||
_logger.LogInformation("Found translation in lyrics data at index {FoundIndex}", found);
|
||||
_logger.LogInformation("Found phonetic text in lyrics data at index {FoundIndex}", found);
|
||||
_lyricsDataArr[0].SetPhoneticText(_lyricsDataArr[found], _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsTranslationSeparator, 50);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
SongInfo.PlayerId ?? "",
|
||||
SongInfo.Title,
|
||||
SongInfo.Artist,
|
||||
SongInfo.Album ?? "",
|
||||
SongInfo.Album,
|
||||
SongInfo.DurationMs ?? 0,
|
||||
SongInfo.SongId,
|
||||
token
|
||||
@@ -174,10 +174,12 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
if (token.IsCancellationRequested) return;
|
||||
LyricsSearchProvider = lyricsSearchResult?.Provider;
|
||||
|
||||
_logger.LogInformation("Lyrics was found? {Found}, Provider: {LyricsSearchProvider}", lyricsSearchResult?.IsFound, LyricsSearchProvider?.ToString() ?? "null");
|
||||
_logger.LogInformation("Lyrics was found? {Found}, Provider: {LyricsSearchProvider}", lyricsSearchResult?.IsFound, LyricsSearchProvider);
|
||||
|
||||
var lyricsParser = new LyricsParser();
|
||||
lyricsParser.Parse(SongInfo.Title, SongInfo.Artist, lyricsSearchResult?.Raw, (int?)SongInfo?.DurationMs, LyricsSearchProvider);
|
||||
lyricsParser.Parse(
|
||||
_settingsService.AppSettings.MappedSongSearchQueries.ToList(),
|
||||
SongInfo.Title, SongInfo.Artist, SongInfo.Album, lyricsSearchResult?.Raw, (int?)SongInfo?.DurationMs, LyricsSearchProvider);
|
||||
_lyricsDataArr = lyricsParser.LyricsDataArr;
|
||||
ApplyChinesePreference();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ using BetterLyrics.WinUI3.Services.AlbumArtSearchService;
|
||||
using BetterLyrics.WinUI3.Services.LibWatcherService;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.LyricsSearchService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Services.TranslateService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
@@ -46,6 +47,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILibWatcherService _libWatcherService;
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
private readonly IResourceService _resourceService;
|
||||
private readonly ILogger<MediaSessionsService> _logger;
|
||||
|
||||
private double _lxMusicPositionSeconds = 0;
|
||||
@@ -77,7 +79,8 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
ILyricsSearchService musicSearchService,
|
||||
ILibWatcherService libWatcherService,
|
||||
ILiveStatesService liveStatesService,
|
||||
ITranslateService libreTranslateService)
|
||||
ITranslateService libreTranslateService,
|
||||
IResourceService resourceService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_albumArtSearchService = albumArtSearchService;
|
||||
@@ -85,6 +88,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
_libWatcherService = libWatcherService;
|
||||
_translateService = libreTranslateService;
|
||||
_liveStatesService = liveStatesService;
|
||||
_resourceService = resourceService;
|
||||
_logger = Ioc.Default.GetRequiredService<ILogger<MediaSessionsService>>();
|
||||
|
||||
_settingsService.AppSettings.MediaSourceProvidersInfo.ItemPropertyChanged += MediaSourceProvidersInfo_ItemPropertyChanged;
|
||||
@@ -111,7 +115,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
UpdateLyrics();
|
||||
}
|
||||
|
||||
private void InitPlaybackShortcuts()
|
||||
public void InitPlaybackShortcuts()
|
||||
{
|
||||
UpdatePlayOrPauseSongShortcut();
|
||||
UpdatePreviousSongShortcut();
|
||||
@@ -213,14 +217,14 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
_mediaManager.CurrentMediaSessions.ToList().ForEach(x => RecordMediaSourceProviderInfo(x.Value));
|
||||
}
|
||||
|
||||
private void MediaManager_OnFocusedSessionChanged(MediaManager.MediaSession? mediaSession)
|
||||
private async void MediaManager_OnFocusedSessionChanged(MediaManager.MediaSession? mediaSession)
|
||||
{
|
||||
if (!_mediaManager.IsStarted) return;
|
||||
|
||||
SendFocusedMessagesAsync();
|
||||
await SendFocusedMessagesAsync();
|
||||
}
|
||||
|
||||
private void MediaManager_OnAnyTimelinePropertyChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionTimelineProperties timelineProperties)
|
||||
private void MediaManager_OnAnyTimelinePropertyChanged(MediaManager.MediaSession? mediaSession, GlobalSystemMediaTransportControlsSessionTimelineProperties? timelineProperties)
|
||||
{
|
||||
if (!_mediaManager.IsStarted) return;
|
||||
if (mediaSession == null) return;
|
||||
@@ -241,16 +245,16 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
{
|
||||
if (IsMediaSourceTimelineSyncEnabled(mediaSession.Id))
|
||||
{
|
||||
_cachedPosition = timelineProperties.Position;
|
||||
_cachedPosition = timelineProperties?.Position ?? TimeSpan.Zero;
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
TimelineChanged?.Invoke(this, new TimelineChangedEventArgs(_cachedPosition, timelineProperties.EndTime));
|
||||
TimelineChanged?.Invoke(this, new TimelineChangedEventArgs(_cachedPosition, timelineProperties?.EndTime ?? TimeSpan.Zero));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MediaManager_OnAnyPlaybackStateChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo)
|
||||
private void MediaManager_OnAnyPlaybackStateChanged(MediaManager.MediaSession? mediaSession, GlobalSystemMediaTransportControlsSessionPlaybackInfo? playbackInfo)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
@@ -268,7 +272,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
}
|
||||
else
|
||||
{
|
||||
_cachedIsPlaying = playbackInfo.PlaybackStatus switch
|
||||
_cachedIsPlaying = playbackInfo?.PlaybackStatus switch
|
||||
{
|
||||
GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing => true,
|
||||
_ => false,
|
||||
@@ -279,28 +283,30 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
});
|
||||
}
|
||||
|
||||
private void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
|
||||
private void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSession? mediaSession, GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProperties)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
|
||||
{
|
||||
if (!_mediaManager.IsStarted) return;
|
||||
if (mediaSession == null) return;
|
||||
if (mediaSession == null)
|
||||
{
|
||||
_cachedSongInfo = SongInfoExtensions.Placeholder;
|
||||
}
|
||||
|
||||
string sessionId = mediaSession.Id;
|
||||
string? sessionId = mediaSession?.Id;
|
||||
|
||||
var desiredSession = GetCurrentSession();
|
||||
|
||||
//RecordMediaSourceProviderInfo(mediaSession);
|
||||
if (mediaSession != desiredSession) return;
|
||||
|
||||
if (!IsMediaSourceEnabled(sessionId))
|
||||
if (sessionId != null && !IsMediaSourceEnabled(sessionId))
|
||||
{
|
||||
_cachedSongInfo = null;
|
||||
_cachedSongInfo = SongInfoExtensions.Placeholder;
|
||||
|
||||
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
|
||||
mediaProperties.Title, mediaProperties.Artist, mediaProperties.AlbumTitle);
|
||||
mediaProperties?.Title, mediaProperties?.Artist, mediaProperties?.AlbumTitle);
|
||||
|
||||
if (sessionId == Constants.PlayerID.LXMusic)
|
||||
if (PlayerIdMatcher.IsLXMusic(sessionId))
|
||||
{
|
||||
StopSSE();
|
||||
}
|
||||
@@ -315,35 +321,35 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
currentMediaSourceProviderInfo?.PositionOffset = 0;
|
||||
}
|
||||
|
||||
string fixedArtist = mediaProperties.Artist;
|
||||
string fixedAlbum = mediaProperties.AlbumTitle;
|
||||
string fixedArtist = mediaProperties?.Artist ?? "N/A";
|
||||
string fixedAlbum = mediaProperties?.AlbumTitle ?? "N/A";
|
||||
string? songId = null;
|
||||
|
||||
if (sessionId == Constants.PlayerID.AppleMusic || sessionId == Constants.PlayerID.AppleMusicAlternative)
|
||||
{
|
||||
fixedArtist = mediaProperties.Artist.Split(" — ").FirstOrDefault() ?? mediaProperties.Artist;
|
||||
fixedAlbum = mediaProperties.Artist.Split(" — ").LastOrDefault() ?? mediaProperties.AlbumTitle;
|
||||
fixedArtist = mediaProperties?.Artist.Split(" — ").FirstOrDefault() ?? (mediaProperties?.Artist ?? "N/A");
|
||||
fixedAlbum = mediaProperties?.Artist.Split(" — ").LastOrDefault() ?? (mediaProperties?.AlbumTitle ?? "N/A");
|
||||
}
|
||||
else if (PlayerIdMatcher.IsNeteaseFamily(sessionId))
|
||||
else if (PlayerIdMatcher.IsNeteaseFamily(sessionId ?? ""))
|
||||
{
|
||||
songId = mediaProperties.Genres.FirstOrDefault()?.Replace("NCM-", "");
|
||||
songId = mediaProperties?.Genres.FirstOrDefault()?.Replace("NCM-", "");
|
||||
}
|
||||
|
||||
_cachedSongInfo = new SongInfo
|
||||
{
|
||||
Title = mediaProperties.Title,
|
||||
Title = mediaProperties?.Title ?? "N/A",
|
||||
Artist = fixedArtist,
|
||||
Album = fixedAlbum,
|
||||
DurationMs = mediaSession.ControlSession.GetTimelineProperties().EndTime.TotalMilliseconds,
|
||||
DurationMs = mediaSession?.ControlSession?.GetTimelineProperties().EndTime.TotalMilliseconds,
|
||||
PlayerId = sessionId,
|
||||
SongId = songId
|
||||
};
|
||||
_cachedSongInfo.Duration = (int)(_cachedSongInfo.DurationMs / 1000f);
|
||||
_cachedSongInfo.Duration = (int)((_cachedSongInfo.DurationMs ?? 0) / 1000f);
|
||||
|
||||
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
|
||||
mediaProperties.Title, mediaProperties.Artist, mediaProperties.AlbumTitle);
|
||||
mediaProperties?.Title, mediaProperties?.Artist, mediaProperties?.AlbumTitle);
|
||||
|
||||
if (sessionId == Constants.PlayerID.LXMusic)
|
||||
if (PlayerIdMatcher.IsLXMusic(sessionId))
|
||||
{
|
||||
StartSSE();
|
||||
}
|
||||
@@ -352,11 +358,11 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
StopSSE();
|
||||
}
|
||||
|
||||
if (sessionId == Constants.PlayerID.LXMusic && _lxMusicAlbumArtBytes != null)
|
||||
if (PlayerIdMatcher.IsLXMusic(sessionId) && _lxMusicAlbumArtBytes != null)
|
||||
{
|
||||
_SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer();
|
||||
}
|
||||
else if (mediaProperties.Thumbnail is IRandomAccessStreamReference streamReference)
|
||||
else if (mediaProperties?.Thumbnail is IRandomAccessStreamReference streamReference)
|
||||
{
|
||||
_SMTCAlbumArtBuffer = await ImageHelper.ToBufferAsync(streamReference);
|
||||
}
|
||||
@@ -438,7 +444,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
_cachedSongInfo = null;
|
||||
_cachedSongInfo = SongInfoExtensions.Placeholder;
|
||||
_cachedIsPlaying = false;
|
||||
SongInfoChanged?.Invoke(this, new SongInfoChangedEventArgs(_cachedSongInfo));
|
||||
IsPlayingChanged?.Invoke(this, new IsPlayingChangedEventArgs(_cachedIsPlaying));
|
||||
@@ -448,14 +454,21 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
|
||||
private async Task SendFocusedMessagesAsync()
|
||||
{
|
||||
var desiredSession = GetCurrentSession();
|
||||
if (desiredSession == null || desiredSession.ControlSession == null) return;
|
||||
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps = null;
|
||||
|
||||
var mediaProps = await desiredSession.ControlSession.TryGetMediaPropertiesAsync();
|
||||
if (desiredSession == null || desiredSession.ControlSession == null) return;
|
||||
MediaManager_OnAnyTimelinePropertyChanged(desiredSession, desiredSession.ControlSession.GetTimelineProperties());
|
||||
var desiredSession = GetCurrentSession();
|
||||
//if (desiredSession == null || desiredSession.ControlSession == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
mediaProps = await desiredSession?.ControlSession?.TryGetMediaPropertiesAsync();
|
||||
}
|
||||
catch (Exception) { }
|
||||
//if (desiredSession == null || desiredSession.ControlSession == null) return;
|
||||
|
||||
MediaManager_OnAnyTimelinePropertyChanged(desiredSession, desiredSession?.ControlSession?.GetTimelineProperties());
|
||||
MediaManager_OnAnyMediaPropertyChanged(desiredSession, mediaProps);
|
||||
MediaManager_OnAnyPlaybackStateChanged(desiredSession, desiredSession.ControlSession.GetPlaybackInfo());
|
||||
MediaManager_OnAnyPlaybackStateChanged(desiredSession, desiredSession?.ControlSession?.GetPlaybackInfo());
|
||||
}
|
||||
|
||||
private void StartSSE()
|
||||
@@ -476,7 +489,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
_logger.LogError("Failed to start SSE connection for LX Music.");
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
App.Current.LyricsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("FailToStartLXMusicServer"), Microsoft.UI.Xaml.Controls.InfoBarSeverity.Error);
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("FailToStartLXMusicServer"));
|
||||
});
|
||||
StopSSE();
|
||||
}
|
||||
@@ -654,7 +667,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
{
|
||||
if (message.PropertyName == nameof(TranslationSettings.SelectedTargetLanguageCode))
|
||||
{
|
||||
_logger.LogInformation("Target language code changed: {code}", _settingsService.AppSettings.TranslationSettings.SelectedTargetLanguageCode);
|
||||
_logger.LogInformation("Target LibreTranslate language code changed: {code}", _settingsService.AppSettings.TranslationSettings.SelectedTargetLanguageCode);
|
||||
UpdateTranslations();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.ResourceService
|
||||
{
|
||||
public interface IResourceService
|
||||
{
|
||||
string GetLocalizedString(string id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Windows.ApplicationModel.Resources;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.ResourceService
|
||||
{
|
||||
public class ResourceService : IResourceService
|
||||
{
|
||||
private readonly ResourceLoader _resourceLoader = new();
|
||||
|
||||
public string GetLocalizedString(string id)
|
||||
{
|
||||
return _resourceLoader.GetString(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Serialization;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using System;
|
||||
@@ -17,14 +16,17 @@ using Windows.Globalization;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.SettingsService
|
||||
{
|
||||
// TODO 初始化时从文件读取到对象,后续独写操作先操纵对象,写入用 Debounce 写入文件
|
||||
// 新建一个 AppSettings 类
|
||||
public partial class SettingsService : BaseViewModel, ISettingsService
|
||||
{
|
||||
private DispatcherQueueTimer _writeAppSettingsTimer;
|
||||
|
||||
public AppSettings AppSettings { get; set; }
|
||||
|
||||
public SettingsService()
|
||||
{
|
||||
_writeAppSettingsTimer = _dispatcherQueue.CreateTimer();
|
||||
|
||||
AppSettings = ReadAppSettings();
|
||||
|
||||
AppSettings.PropertyChanged += AppSettings_PropertyChanged;
|
||||
@@ -46,6 +48,11 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
|
||||
AppSettings.WindowBoundsRecords.CollectionChanged += AppSettings_CollectionChanged;
|
||||
AppSettings.WindowBoundsRecords.ItemPropertyChanged += AppSettings_ItemPropertyChanged;
|
||||
|
||||
AppSettings.StarredPlaylists.CollectionChanged += AppSettings_CollectionChanged;
|
||||
AppSettings.StarredPlaylists.ItemPropertyChanged += AppSettings_ItemPropertyChanged;
|
||||
|
||||
AppSettings.MusicGallerySettings.PlayQueuePaths.CollectionChanged += AppSettings_CollectionChanged;
|
||||
|
||||
AppSettings.Version = MetadataHelper.AppVersion;
|
||||
|
||||
EnsureMediaSourceProvidersInfo();
|
||||
@@ -93,12 +100,12 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
|
||||
|
||||
private void AppSettings_ItemPropertyChanged(object? sender, ItemPropertyChangedEventArgs e)
|
||||
{
|
||||
WriteAppSettingsDebounce();
|
||||
WriteAppSettings();
|
||||
}
|
||||
|
||||
private void AppSettings_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
WriteAppSettingsDebounce();
|
||||
WriteAppSettings();
|
||||
}
|
||||
|
||||
private void AppSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
@@ -111,7 +118,7 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
|
||||
default:
|
||||
break;
|
||||
}
|
||||
WriteAppSettingsDebounce();
|
||||
WriteAppSettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -132,7 +139,6 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
|
||||
/// <returns></returns>
|
||||
public bool ImportSettings(string importPath)
|
||||
{
|
||||
// TODO 导入有问题
|
||||
if (!File.Exists(importPath))
|
||||
return false;
|
||||
|
||||
@@ -161,9 +167,9 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
|
||||
return data;
|
||||
}
|
||||
|
||||
private void WriteAppSettingsDebounce()
|
||||
private void WriteAppSettings()
|
||||
{
|
||||
_dispatcherQueueTimer.Debounce(() =>
|
||||
_writeAppSettingsTimer.Debounce(() =>
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.TranslateService
|
||||
{
|
||||
public class TranslateService : BaseViewModel, ITranslateService
|
||||
public partial class TranslateService : BaseViewModel, ITranslateService
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
|
||||
<value>Playlist was created successfully</value>
|
||||
</data>
|
||||
<data name="DemoWindowControlDefault.Text" xml:space="preserve">
|
||||
<value>Default</value>
|
||||
</data>
|
||||
@@ -174,12 +177,18 @@
|
||||
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
|
||||
<value>Music gallery</value>
|
||||
</data>
|
||||
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve">
|
||||
<data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>Playlist was imported successfully</value>
|
||||
</data>
|
||||
<data name="ImportSettingsFailed" xml:space="preserve">
|
||||
<value>Settings file import failed, application settings remain unchanged</value>
|
||||
</data>
|
||||
<data name="ImportSettingsSuccess" xml:space="preserve">
|
||||
<value>Import successful</value>
|
||||
</data>
|
||||
<data name="Jyutping" xml:space="preserve">
|
||||
<value>Cantonese pinyin</value>
|
||||
</data>
|
||||
@@ -207,6 +216,9 @@
|
||||
<data name="LibreTranslateFailed" xml:space="preserve">
|
||||
<value>Requesting translation from LibreTranslate failed, please check the settings or the native LibreTranslate configuration</value>
|
||||
</data>
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>e.g. http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>Loading lyrics...</value>
|
||||
</data>
|
||||
@@ -249,7 +261,10 @@
|
||||
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
|
||||
<value>Translation provider</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
|
||||
<value>Album</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
|
||||
<value>Artist</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlHelp.Text" xml:space="preserve">
|
||||
@@ -273,13 +288,13 @@
|
||||
<data name="LyricsSearchControlSearch.Content" xml:space="preserve">
|
||||
<value>Search</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
|
||||
<value>Song info mapping</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
|
||||
<value>Target lyrics search provider</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTitle.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlTitle.Text" xml:space="preserve">
|
||||
<value>Title</value>
|
||||
</data>
|
||||
<data name="LyricsSearchPageTitle" xml:space="preserve">
|
||||
@@ -309,6 +324,9 @@
|
||||
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
|
||||
<value>Set as default</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSettingsControlShare.Text" xml:space="preserve">
|
||||
<value>Export</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
|
||||
<value>Lyrics window switcher</value>
|
||||
</data>
|
||||
@@ -343,7 +361,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>Welcome to BetterLyrics</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
|
||||
<value>Add to playlist</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
|
||||
@@ -352,13 +370,13 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
|
||||
<value>Next items</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
|
||||
<value>Add to play queue</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAllSongs" xml:space="preserve">
|
||||
<value>All songs</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
|
||||
<value>Clear play queue</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
|
||||
@@ -385,6 +403,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
|
||||
<value>Format</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
|
||||
<value>Lyrics</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
|
||||
<value>Path</value>
|
||||
</data>
|
||||
@@ -400,6 +421,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
|
||||
<value>No songs were found in the media library</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
|
||||
<value>Import from file</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
|
||||
<value>Create a playlist</value>
|
||||
</data>
|
||||
@@ -412,26 +436,32 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
|
||||
<value>Play queue is empty</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
|
||||
<value>Playlists</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
|
||||
<value>List loop</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
|
||||
<value>Remove from playlists</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
|
||||
<value>Remove from play queue</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
|
||||
<value>Scroll to playing item</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
|
||||
<value>Select all</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
|
||||
<value>Single loop</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Search songs</value>
|
||||
<value>Search for song title, artist, album or folder path</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
|
||||
<value>Album</value>
|
||||
@@ -439,12 +469,21 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
|
||||
<value>Artist</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
|
||||
<value>Folder</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
|
||||
<value>Title</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortType.Text" xml:space="preserve">
|
||||
<value>Sort type</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
|
||||
<value>Starred playlists</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
|
||||
<value>Stop</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageTitle" xml:space="preserve">
|
||||
<value>Music gallery - BetterLyrics</value>
|
||||
</data>
|
||||
@@ -457,6 +496,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="Pinyin" xml:space="preserve">
|
||||
<value>Mandarin pinyin</value>
|
||||
</data>
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>Unable to view tracks since the path is not existed</value>
|
||||
</data>
|
||||
<data name="Romaji" xml:space="preserve">
|
||||
<value>Romaji</value>
|
||||
</data>
|
||||
@@ -476,7 +518,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<value>If you like this project, please consider supporting it by donating. Your support will help keep the project alive and encourage further development.</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
|
||||
<value>3D lyrics</value>
|
||||
<value>[Experimental] Depth effect</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
|
||||
<value>Depth</value>
|
||||
@@ -550,6 +592,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
|
||||
<value>Automatic adjustment</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>Open the music library window when the app starts</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>Automatically continue playing when the music library window is opened</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
|
||||
<value>Automatic startup</value>
|
||||
</data>
|
||||
@@ -610,8 +658,8 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="SettingsPageConfigName.Header" xml:space="preserve">
|
||||
<value>Configuration name</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromCurrent.Content" xml:space="preserve">
|
||||
<value>Create from the current lyrics window status</value>
|
||||
<data name="SettingsPageCreateFromCurrent.Text" xml:space="preserve">
|
||||
<value>Copy</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromTemplates.Content" xml:space="preserve">
|
||||
<value>Create from templates</value>
|
||||
@@ -766,6 +814,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="SettingsPageHideWindow.Header" xml:space="preserve">
|
||||
<value>Automatically hide/show windows</value>
|
||||
</data>
|
||||
<data name="SettingsPageImport.Content" xml:space="preserve">
|
||||
<value>Import</value>
|
||||
</data>
|
||||
<data name="SettingsPageImportSettingsButton.Content" xml:space="preserve">
|
||||
<value>Import settings</value>
|
||||
</data>
|
||||
@@ -841,6 +892,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
|
||||
<value>LX Music Server</value>
|
||||
</data>
|
||||
<data name="SettingsPageLXMusicServerInput.PlaceholderText" xml:space="preserve">
|
||||
<value>e.g. http://127.0.0.1:23330</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>Alignment</value>
|
||||
</data>
|
||||
@@ -1168,6 +1222,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="SettingsPageSettingsManager.Header" xml:space="preserve">
|
||||
<value>Settings manager</value>
|
||||
</data>
|
||||
<data name="SettingsPageShareHub.Content" xml:space="preserve">
|
||||
<value>Browse online resources sharing hub</value>
|
||||
</data>
|
||||
<data name="SettingsPageShortcutRegFailInfo" xml:space="preserve">
|
||||
<value>This hotkey was not successfully registered</value>
|
||||
</data>
|
||||
@@ -1211,7 +1268,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpectrumLayer.Header" xml:space="preserve">
|
||||
<value>Spectrum layer</value>
|
||||
<value>[Experimental] Spectrum Layer</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpeed.Header" xml:space="preserve">
|
||||
<value>Motion rate</value>
|
||||
@@ -1312,12 +1369,21 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
|
||||
<data name="SystemTrayRestart.Text" xml:space="preserve">
|
||||
<value>Restart</value>
|
||||
</data>
|
||||
<data name="SystemTraySearch.Text" xml:space="preserve">
|
||||
<value>Lyrics search window</value>
|
||||
</data>
|
||||
<data name="SystemTraySettings.Text" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="SystemTraySwitch.Text" xml:space="preserve">
|
||||
<value>Lyrics window switcher</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
|
||||
<value>Unable to add tracks since the path is not existed</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>Selected tracks have been added to this playlist</value>
|
||||
</data>
|
||||
<data name="TranslateServerNotSet" xml:space="preserve">
|
||||
<value>Translate server is not set, please configure it in settings first</value>
|
||||
</data>
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>キャンセル</value>
|
||||
</data>
|
||||
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
|
||||
<value>正常に作成されました</value>
|
||||
</data>
|
||||
<data name="DemoWindowControlDefault.Text" xml:space="preserve">
|
||||
<value>デフォルト</value>
|
||||
</data>
|
||||
@@ -174,12 +177,18 @@
|
||||
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
|
||||
<value>ミュージックギャラリー</value>
|
||||
</data>
|
||||
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve">
|
||||
<data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>プレイリストが正常にインポートされました</value>
|
||||
</data>
|
||||
<data name="ImportSettingsFailed" xml:space="preserve">
|
||||
<value>設定ファイルのインポートに失敗し、アプリケーション設定は変更されません</value>
|
||||
</data>
|
||||
<data name="ImportSettingsSuccess" xml:space="preserve">
|
||||
<value>インポート成功</value>
|
||||
</data>
|
||||
<data name="Jyutping" xml:space="preserve">
|
||||
<value>広東語のピンイン</value>
|
||||
</data>
|
||||
@@ -207,6 +216,9 @@
|
||||
<data name="LibreTranslateFailed" xml:space="preserve">
|
||||
<value>リブレットランスレートからの翻訳のリクエストが失敗しました。設定またはネイティブリブレットランレート構成を確認してください</value>
|
||||
</data>
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>例:http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>歌詞の読み込み...</value>
|
||||
</data>
|
||||
@@ -249,7 +261,10 @@
|
||||
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
|
||||
<value>翻訳プロバイダー</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
|
||||
<value>アルバム</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
|
||||
<value>アーティスト</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlHelp.Text" xml:space="preserve">
|
||||
@@ -273,13 +288,13 @@
|
||||
<data name="LyricsSearchControlSearch.Content" xml:space="preserve">
|
||||
<value>検索する</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
|
||||
<value>曲情報マッピング</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
|
||||
<value>ターゲット歌詞検索プロバイダー</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTitle.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlTitle.Text" xml:space="preserve">
|
||||
<value>タイトル</value>
|
||||
</data>
|
||||
<data name="LyricsSearchPageTitle" xml:space="preserve">
|
||||
@@ -309,6 +324,9 @@
|
||||
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
|
||||
<value>既定のブラウザーに設定する</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSettingsControlShare.Text" xml:space="preserve">
|
||||
<value>エクスポート</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
|
||||
<value>歌詞ウィンドウスイッチャー</value>
|
||||
</data>
|
||||
@@ -343,8 +361,8 @@
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>BetterLyrics へようこそ</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
|
||||
<value>プレイリストに追加します</value>
|
||||
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
|
||||
<value>プレイリストに追加</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
|
||||
<value>リストの終わり</value>
|
||||
@@ -352,13 +370,13 @@
|
||||
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
|
||||
<value>次のアイテム</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
|
||||
<value>キューを再生するために追加します</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAllSongs" xml:space="preserve">
|
||||
<value>すべての曲</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
|
||||
<value>クリアプレイキュー</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
|
||||
@@ -385,6 +403,9 @@
|
||||
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
|
||||
<value>形式</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
|
||||
<value>歌詞</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
|
||||
<value>パス</value>
|
||||
</data>
|
||||
@@ -400,8 +421,11 @@
|
||||
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
|
||||
<value>メディアライブラリには歌が見つかりませんでした</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
|
||||
<value>ファイルからのインポート</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
|
||||
<value>プレイリストを作成します</value>
|
||||
<value>プレイリストを作成しましょう</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
|
||||
<value>すべてを再生します</value>
|
||||
@@ -412,26 +436,32 @@
|
||||
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
|
||||
<value>キューを再生するのは空です</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
|
||||
<value>プレイリスト</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
|
||||
<value>ループをリストします</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
|
||||
<value>ランダム</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
|
||||
<value>プレイリストから削除</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
|
||||
<value>プレイリストから取り外します</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
|
||||
<value>アイテムを再生するための位置</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
|
||||
<value>すべてを選択します</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
|
||||
<value>シングルループ</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
|
||||
<value>曲を検索します</value>
|
||||
<value>曲名、アーティスト、アルバム、フォルダパスを検索してください</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
|
||||
<value>アルバム</value>
|
||||
@@ -439,12 +469,21 @@
|
||||
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
|
||||
<value>アーティスト</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
|
||||
<value>フォルダー</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
|
||||
<value>タイトル</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortType.Text" xml:space="preserve">
|
||||
<value>並べ替えタイプ</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
|
||||
<value>スター付きプレイリスト</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
|
||||
<value>立ち止まる</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageTitle" xml:space="preserve">
|
||||
<value>音楽ギャラリー - BetterLyrics</value>
|
||||
</data>
|
||||
@@ -457,6 +496,9 @@
|
||||
<data name="Pinyin" xml:space="preserve">
|
||||
<value>マンダリンのピンイン</value>
|
||||
</data>
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>パスが存在しないため、トラックを表示できません</value>
|
||||
</data>
|
||||
<data name="Romaji" xml:space="preserve">
|
||||
<value>ローマン</value>
|
||||
</data>
|
||||
@@ -476,7 +518,7 @@
|
||||
<value>このプロジェクトが気に入っている場合は、寄付してサポートすることを検討してください。あなたのサポートは、プロジェクトを生かし続け、さらなる開発を促進するのに役立ちます。</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
|
||||
<value>3 D 歌詞</value>
|
||||
<value>[実験的] 奥行き効果</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
|
||||
<value>深度</value>
|
||||
@@ -550,6 +592,12 @@
|
||||
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
|
||||
<value>自動調整</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>アプリが起動したら、音楽ライブラリウィンドウを開きます</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>音楽ライブラリウィンドウを開くと、自動的に再生が続行されます</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
|
||||
<value>自動起動</value>
|
||||
</data>
|
||||
@@ -610,8 +658,8 @@
|
||||
<data name="SettingsPageConfigName.Header" xml:space="preserve">
|
||||
<value>設定名</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromCurrent.Content" xml:space="preserve">
|
||||
<value>現在の歌詞ウィンドウのステータスから作成</value>
|
||||
<data name="SettingsPageCreateFromCurrent.Text" xml:space="preserve">
|
||||
<value>コピー</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromTemplates.Content" xml:space="preserve">
|
||||
<value>テンプレートから作成</value>
|
||||
@@ -766,6 +814,9 @@
|
||||
<data name="SettingsPageHideWindow.Header" xml:space="preserve">
|
||||
<value>Windowsを自動的に非表示/表示します</value>
|
||||
</data>
|
||||
<data name="SettingsPageImport.Content" xml:space="preserve">
|
||||
<value>インポート</value>
|
||||
</data>
|
||||
<data name="SettingsPageImportSettingsButton.Content" xml:space="preserve">
|
||||
<value>設定をインポートします</value>
|
||||
</data>
|
||||
@@ -841,6 +892,9 @@
|
||||
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
|
||||
<value>LX Music Server</value>
|
||||
</data>
|
||||
<data name="SettingsPageLXMusicServerInput.PlaceholderText" xml:space="preserve">
|
||||
<value>例)http://127.0.0.1: 23330</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>アライメント</value>
|
||||
</data>
|
||||
@@ -1168,6 +1222,9 @@
|
||||
<data name="SettingsPageSettingsManager.Header" xml:space="preserve">
|
||||
<value>設定マネージャー</value>
|
||||
</data>
|
||||
<data name="SettingsPageShareHub.Content" xml:space="preserve">
|
||||
<value>オンラインリソース共有ハブを閲覧しましょう</value>
|
||||
</data>
|
||||
<data name="SettingsPageShortcutRegFailInfo" xml:space="preserve">
|
||||
<value>このホットキーは正常に登録されていません</value>
|
||||
</data>
|
||||
@@ -1211,7 +1268,7 @@
|
||||
<value>右</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpectrumLayer.Header" xml:space="preserve">
|
||||
<value>スペクトラムレイヤー</value>
|
||||
<value>[実験的] スペクトラムレイヤー</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpeed.Header" xml:space="preserve">
|
||||
<value>モーション</value>
|
||||
@@ -1312,12 +1369,21 @@
|
||||
<data name="SystemTrayRestart.Text" xml:space="preserve">
|
||||
<value>再起動</value>
|
||||
</data>
|
||||
<data name="SystemTraySearch.Text" xml:space="preserve">
|
||||
<value>歌詞検索ウィンドウ</value>
|
||||
</data>
|
||||
<data name="SystemTraySettings.Text" xml:space="preserve">
|
||||
<value>設定を開く</value>
|
||||
</data>
|
||||
<data name="SystemTraySwitch.Text" xml:space="preserve">
|
||||
<value>歌詞ウィンドウスイッチャー</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
|
||||
<value>パスが存在しないため、トラックを追加できません</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>選択したトラックがこのプレイリストに追加されました</value>
|
||||
</data>
|
||||
<data name="TranslateServerNotSet" xml:space="preserve">
|
||||
<value>翻訳サーバーは設定されていません。最初に設定で構成してください</value>
|
||||
</data>
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>취소</value>
|
||||
</data>
|
||||
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
|
||||
<value>재생 목록이 성공적으로 생성되었습니다</value>
|
||||
</data>
|
||||
<data name="DemoWindowControlDefault.Text" xml:space="preserve">
|
||||
<value>기본</value>
|
||||
</data>
|
||||
@@ -174,12 +177,18 @@
|
||||
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
|
||||
<value>음악 갤러리</value>
|
||||
</data>
|
||||
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve">
|
||||
<data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
|
||||
<value>설정</value>
|
||||
</data>
|
||||
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>재생 목록을 성공적으로 가져왔습니다</value>
|
||||
</data>
|
||||
<data name="ImportSettingsFailed" xml:space="preserve">
|
||||
<value>설정 파일 가져 오기 실패, 응용 프로그램 설정은 변경되지 않았습니다</value>
|
||||
</data>
|
||||
<data name="ImportSettingsSuccess" xml:space="preserve">
|
||||
<value>가져 오기 성공</value>
|
||||
</data>
|
||||
<data name="Jyutping" xml:space="preserve">
|
||||
<value>광둥어 병음</value>
|
||||
</data>
|
||||
@@ -207,6 +216,9 @@
|
||||
<data name="LibreTranslateFailed" xml:space="preserve">
|
||||
<value>LibreTranslate에서 번역 요청 실패, 설정 또는 기본 LibreTranslate 구성을 확인하십시오.</value>
|
||||
</data>
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>예: http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>가사로드 ...</value>
|
||||
</data>
|
||||
@@ -249,7 +261,10 @@
|
||||
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
|
||||
<value>번역 제공자</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
|
||||
<value>앨범</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
|
||||
<value>아티스트</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlHelp.Text" xml:space="preserve">
|
||||
@@ -273,13 +288,13 @@
|
||||
<data name="LyricsSearchControlSearch.Content" xml:space="preserve">
|
||||
<value>검색</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
|
||||
<value>노래 정보 매핑</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
|
||||
<value>가사 검색 공급자를 타겟팅하십시오</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTitle.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlTitle.Text" xml:space="preserve">
|
||||
<value>제목</value>
|
||||
</data>
|
||||
<data name="LyricsSearchPageTitle" xml:space="preserve">
|
||||
@@ -309,6 +324,9 @@
|
||||
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
|
||||
<value>기본 값으로 설정</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSettingsControlShare.Text" xml:space="preserve">
|
||||
<value>내보내기</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
|
||||
<value>가사 창 전환기</value>
|
||||
</data>
|
||||
@@ -343,8 +361,8 @@
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>Betterlyrics에 오신 것을 환영합니다</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
|
||||
<value>재생 목록에 추가하십시오</value>
|
||||
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
|
||||
<value>재생 목록에 추가</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
|
||||
<value>목록의 끝</value>
|
||||
@@ -352,13 +370,13 @@
|
||||
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
|
||||
<value>다음 항목</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
|
||||
<value>재생 큐에 추가하십시오</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAllSongs" xml:space="preserve">
|
||||
<value>모든 노래</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
|
||||
<value>플레이 대기열을 클리어합니다</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
|
||||
@@ -385,6 +403,9 @@
|
||||
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
|
||||
<value>체재</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
|
||||
<value>가사</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
|
||||
<value>길</value>
|
||||
</data>
|
||||
@@ -400,8 +421,11 @@
|
||||
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
|
||||
<value>미디어 라이브러리에는 노래가 없습니다</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
|
||||
<value>파일에서 가져오기</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
|
||||
<value>재생 목록을 만듭니다</value>
|
||||
<value>재생목록을 만드세요</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
|
||||
<value>모두 재생하십시오</value>
|
||||
@@ -412,26 +436,32 @@
|
||||
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
|
||||
<value>플레이 대기열이 비어 있습니다</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
|
||||
<value>재생 목록</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
|
||||
<value>목록 루프</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
|
||||
<value>무작위의</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
|
||||
<value>재생 목록에서 제거</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
|
||||
<value>재생 목록에서 제거하십시오</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
|
||||
<value>아이템을 재생하기위한 포지셔닝</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
|
||||
<value>모두를 선택하십시오</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
|
||||
<value>단일 루프</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
|
||||
<value>노래 검색</value>
|
||||
<value>노래 제목, 아티스트, 앨범 또는 폴더 경로를 검색하세요</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
|
||||
<value>앨범</value>
|
||||
@@ -439,12 +469,21 @@
|
||||
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
|
||||
<value>아티스트</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
|
||||
<value>폴더</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
|
||||
<value>제목</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortType.Text" xml:space="preserve">
|
||||
<value>정렬 유형</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
|
||||
<value>별표 표시된 재생 목록</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
|
||||
<value>멈추기</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageTitle" xml:space="preserve">
|
||||
<value>음악 갤러리 - BetterLyrics</value>
|
||||
</data>
|
||||
@@ -457,6 +496,9 @@
|
||||
<data name="Pinyin" xml:space="preserve">
|
||||
<value>만다린의 피니 인</value>
|
||||
</data>
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>경로가 존재하지 않으므로 트랙을 볼 수 없습니다</value>
|
||||
</data>
|
||||
<data name="Romaji" xml:space="preserve">
|
||||
<value>로만</value>
|
||||
</data>
|
||||
@@ -476,7 +518,7 @@
|
||||
<value>이 프로젝트가 마음에 들면 기부하여 지원을 고려하십시오. 귀하의 지원은 프로젝트를 계속 유지하고 추가 개발을 장려하는 데 도움이 될 것입니다.</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
|
||||
<value>3D 가사</value>
|
||||
<value>[실험] 깊이 효과</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
|
||||
<value>심도</value>
|
||||
@@ -550,6 +592,12 @@
|
||||
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
|
||||
<value>자동 조정</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>앱이 시작되면 음악 라이브러리 창을 여세요</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>음악 라이브러리 창이 열리면 자동으로 계속 재생됩니다</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
|
||||
<value>자동 시작</value>
|
||||
</data>
|
||||
@@ -610,8 +658,8 @@
|
||||
<data name="SettingsPageConfigName.Header" xml:space="preserve">
|
||||
<value>환경 설정</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromCurrent.Content" xml:space="preserve">
|
||||
<value>현재 가사 창 상태에서 만들기</value>
|
||||
<data name="SettingsPageCreateFromCurrent.Text" xml:space="preserve">
|
||||
<value>접수</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromTemplates.Content" xml:space="preserve">
|
||||
<value>템플릿에서 만들기</value>
|
||||
@@ -766,6 +814,9 @@
|
||||
<data name="SettingsPageHideWindow.Header" xml:space="preserve">
|
||||
<value>Windows를 자동으로 숨기고 표시합니다</value>
|
||||
</data>
|
||||
<data name="SettingsPageImport.Content" xml:space="preserve">
|
||||
<value>가져오기</value>
|
||||
</data>
|
||||
<data name="SettingsPageImportSettingsButton.Content" xml:space="preserve">
|
||||
<value>가져 오기 설정</value>
|
||||
</data>
|
||||
@@ -841,6 +892,9 @@
|
||||
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
|
||||
<value>LX 음악 서버</value>
|
||||
</data>
|
||||
<data name="SettingsPageLXMusicServerInput.PlaceholderText" xml:space="preserve">
|
||||
<value>예: http://127.0.0.1: 23330</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>조정</value>
|
||||
</data>
|
||||
@@ -1168,6 +1222,9 @@
|
||||
<data name="SettingsPageSettingsManager.Header" xml:space="preserve">
|
||||
<value>설정 관리자</value>
|
||||
</data>
|
||||
<data name="SettingsPageShareHub.Content" xml:space="preserve">
|
||||
<value>온라인 리소스 공유 허브를 둘러보세요</value>
|
||||
</data>
|
||||
<data name="SettingsPageShortcutRegFailInfo" xml:space="preserve">
|
||||
<value>이 핫키는 성공적으로 등록되지 않았습니다</value>
|
||||
</data>
|
||||
@@ -1211,7 +1268,7 @@
|
||||
<value>오른쪽</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpectrumLayer.Header" xml:space="preserve">
|
||||
<value>스펙트럼 레이어</value>
|
||||
<value>[실험] 스펙트럼 레이어</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpeed.Header" xml:space="preserve">
|
||||
<value>모션</value>
|
||||
@@ -1312,12 +1369,21 @@
|
||||
<data name="SystemTrayRestart.Text" xml:space="preserve">
|
||||
<value>다시 시작</value>
|
||||
</data>
|
||||
<data name="SystemTraySearch.Text" xml:space="preserve">
|
||||
<value>가사 검색 창</value>
|
||||
</data>
|
||||
<data name="SystemTraySettings.Text" xml:space="preserve">
|
||||
<value>열기 설정</value>
|
||||
</data>
|
||||
<data name="SystemTraySwitch.Text" xml:space="preserve">
|
||||
<value>가사 창 전환기</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
|
||||
<value>경로가 존재하지 않으므로 트랙을 추가할 수 없습니다</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>선택한 트랙이 이 재생 목록에 추가되었습니다</value>
|
||||
</data>
|
||||
<data name="TranslateServerNotSet" xml:space="preserve">
|
||||
<value>번역 서버가 설정되지 않았습니다. 먼저 설정으로 구성하십시오.</value>
|
||||
</data>
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
|
||||
<value>播放列表创建成功</value>
|
||||
</data>
|
||||
<data name="DemoWindowControlDefault.Text" xml:space="preserve">
|
||||
<value>默认</value>
|
||||
</data>
|
||||
@@ -174,12 +177,18 @@
|
||||
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
|
||||
<value>音乐库</value>
|
||||
</data>
|
||||
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve">
|
||||
<data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
|
||||
<value>设置</value>
|
||||
</data>
|
||||
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>播放列表已成功导入</value>
|
||||
</data>
|
||||
<data name="ImportSettingsFailed" xml:space="preserve">
|
||||
<value>设置文件导入失败,应用程序设置保持不变</value>
|
||||
</data>
|
||||
<data name="ImportSettingsSuccess" xml:space="preserve">
|
||||
<value>导入成功</value>
|
||||
</data>
|
||||
<data name="Jyutping" xml:space="preserve">
|
||||
<value>粤语拼音</value>
|
||||
</data>
|
||||
@@ -207,6 +216,9 @@
|
||||
<data name="LibreTranslateFailed" xml:space="preserve">
|
||||
<value>向 LibreTranslate 请求翻译失败,请检查设置或本机 LibreTranslate 配置</value>
|
||||
</data>
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>例如 http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>加载歌词中...</value>
|
||||
</data>
|
||||
@@ -249,7 +261,10 @@
|
||||
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
|
||||
<value>翻译来源</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
|
||||
<value>专辑</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
|
||||
<value>艺术家</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlHelp.Text" xml:space="preserve">
|
||||
@@ -273,13 +288,13 @@
|
||||
<data name="LyricsSearchControlSearch.Content" xml:space="preserve">
|
||||
<value>搜索</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
|
||||
<value>歌曲信息映射</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
|
||||
<value>目标歌词搜索提供商</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTitle.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlTitle.Text" xml:space="preserve">
|
||||
<value>标题</value>
|
||||
</data>
|
||||
<data name="LyricsSearchPageTitle" xml:space="preserve">
|
||||
@@ -309,6 +324,9 @@
|
||||
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
|
||||
<value>设为默认</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSettingsControlShare.Text" xml:space="preserve">
|
||||
<value>导出</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
|
||||
<value>歌词窗口切换器</value>
|
||||
</data>
|
||||
@@ -343,8 +361,8 @@
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>欢迎使用 BetterLyrics</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
|
||||
<value>添加到歌单</value>
|
||||
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
|
||||
<value>添加到播放列表</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
|
||||
<value>列表的结尾</value>
|
||||
@@ -352,13 +370,13 @@
|
||||
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
|
||||
<value>下一个项目</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
|
||||
<value>添加到播放队列</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAllSongs" xml:space="preserve">
|
||||
<value>所有歌曲</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
|
||||
<value>清除播放队列</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
|
||||
@@ -385,6 +403,9 @@
|
||||
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
|
||||
<value>格式</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
|
||||
<value>歌词</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
|
||||
<value>路径</value>
|
||||
</data>
|
||||
@@ -400,8 +421,11 @@
|
||||
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
|
||||
<value>未在媒体库内找到任何歌曲</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
|
||||
<value>从文件导入</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
|
||||
<value>创建歌单</value>
|
||||
<value>创建播放列表</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
|
||||
<value>播放全部</value>
|
||||
@@ -412,26 +436,32 @@
|
||||
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
|
||||
<value>播放队列是空的</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
|
||||
<value>播放列表</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
|
||||
<value>列表循环</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
|
||||
<value>随机</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
|
||||
<value>从播放列表中删除</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
|
||||
<value>从播放列表移除</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
|
||||
<value>定位到播放项</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
|
||||
<value>选择全部</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
|
||||
<value>单曲循环</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
|
||||
<value>搜索歌曲</value>
|
||||
<value>搜索歌曲名、艺术家、专辑或所在文件夹路径</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
|
||||
<value>专辑</value>
|
||||
@@ -439,12 +469,21 @@
|
||||
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
|
||||
<value>艺术家</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
|
||||
<value>文件夹</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
|
||||
<value>标题</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortType.Text" xml:space="preserve">
|
||||
<value>排序类型</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
|
||||
<value>已加星标的歌单</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
|
||||
<value>停止</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageTitle" xml:space="preserve">
|
||||
<value>音乐库 - BetterLyrics</value>
|
||||
</data>
|
||||
@@ -457,6 +496,9 @@
|
||||
<data name="Pinyin" xml:space="preserve">
|
||||
<value>普通话拼音</value>
|
||||
</data>
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>无法查看曲目,因为路径不存在</value>
|
||||
</data>
|
||||
<data name="Romaji" xml:space="preserve">
|
||||
<value>罗马音</value>
|
||||
</data>
|
||||
@@ -476,7 +518,7 @@
|
||||
<value>如果您喜欢这个项目,请考虑通过捐赠来支持它。您的支持将有助于保持项目的生命并鼓励进一步的发展。</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
|
||||
<value>3D 歌词</value>
|
||||
<value>[实验性] 纵深效果</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
|
||||
<value>深度</value>
|
||||
@@ -550,6 +592,12 @@
|
||||
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
|
||||
<value>自动调整</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>应用程序启动时打开音乐库窗口</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>打开音乐库窗口时自动继续播放</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
|
||||
<value>自动启动</value>
|
||||
</data>
|
||||
@@ -610,8 +658,8 @@
|
||||
<data name="SettingsPageConfigName.Header" xml:space="preserve">
|
||||
<value>配置名称</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromCurrent.Content" xml:space="preserve">
|
||||
<value>从当前歌词窗口状态创建</value>
|
||||
<data name="SettingsPageCreateFromCurrent.Text" xml:space="preserve">
|
||||
<value>拷贝</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromTemplates.Content" xml:space="preserve">
|
||||
<value>从模板创建</value>
|
||||
@@ -766,6 +814,9 @@
|
||||
<data name="SettingsPageHideWindow.Header" xml:space="preserve">
|
||||
<value>自动隐藏/显示窗口</value>
|
||||
</data>
|
||||
<data name="SettingsPageImport.Content" xml:space="preserve">
|
||||
<value>导入</value>
|
||||
</data>
|
||||
<data name="SettingsPageImportSettingsButton.Content" xml:space="preserve">
|
||||
<value>导入设置</value>
|
||||
</data>
|
||||
@@ -841,6 +892,9 @@
|
||||
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
|
||||
<value>LX 音乐服务器</value>
|
||||
</data>
|
||||
<data name="SettingsPageLXMusicServerInput.PlaceholderText" xml:space="preserve">
|
||||
<value>例如 http://127.0.0.1: 23330</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>对齐方式</value>
|
||||
</data>
|
||||
@@ -1168,6 +1222,9 @@
|
||||
<data name="SettingsPageSettingsManager.Header" xml:space="preserve">
|
||||
<value>设置管理器</value>
|
||||
</data>
|
||||
<data name="SettingsPageShareHub.Content" xml:space="preserve">
|
||||
<value>浏览在线资源共享中心</value>
|
||||
</data>
|
||||
<data name="SettingsPageShortcutRegFailInfo" xml:space="preserve">
|
||||
<value>该热键未成功注册</value>
|
||||
</data>
|
||||
@@ -1211,7 +1268,7 @@
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpectrumLayer.Header" xml:space="preserve">
|
||||
<value>频谱层</value>
|
||||
<value>[实验性] 频谱层</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpeed.Header" xml:space="preserve">
|
||||
<value>运动速率</value>
|
||||
@@ -1312,12 +1369,21 @@
|
||||
<data name="SystemTrayRestart.Text" xml:space="preserve">
|
||||
<value>重新启动</value>
|
||||
</data>
|
||||
<data name="SystemTraySearch.Text" xml:space="preserve">
|
||||
<value>歌词搜索窗口</value>
|
||||
</data>
|
||||
<data name="SystemTraySettings.Text" xml:space="preserve">
|
||||
<value>打开设置</value>
|
||||
</data>
|
||||
<data name="SystemTraySwitch.Text" xml:space="preserve">
|
||||
<value>歌词窗口切换器</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
|
||||
<value>由于路径不存在,无法添加曲目</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>所选曲目已添加到此播放列表</value>
|
||||
</data>
|
||||
<data name="TranslateServerNotSet" xml:space="preserve">
|
||||
<value>未设置Translate服务器,请先在设置中进行配置</value>
|
||||
</data>
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
|
||||
<value>已成功建立播放清單</value>
|
||||
</data>
|
||||
<data name="DemoWindowControlDefault.Text" xml:space="preserve">
|
||||
<value>預設</value>
|
||||
</data>
|
||||
@@ -174,12 +177,18 @@
|
||||
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
|
||||
<value>音樂庫</value>
|
||||
</data>
|
||||
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve">
|
||||
<data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>已成功匯入播放清單</value>
|
||||
</data>
|
||||
<data name="ImportSettingsFailed" xml:space="preserve">
|
||||
<value>設置文件導入失敗,應用程序設置保持不變</value>
|
||||
</data>
|
||||
<data name="ImportSettingsSuccess" xml:space="preserve">
|
||||
<value>匯入成功</value>
|
||||
</data>
|
||||
<data name="Jyutping" xml:space="preserve">
|
||||
<value>粵語拼音</value>
|
||||
</data>
|
||||
@@ -207,6 +216,9 @@
|
||||
<data name="LibreTranslateFailed" xml:space="preserve">
|
||||
<value>向 LibreTranslate 請求翻譯失敗,請檢查設置或本機 LibreTranslate 配置</value>
|
||||
</data>
|
||||
<data name="LibreTranslateServerTextBox.PlaceholderText" xml:space="preserve">
|
||||
<value>例如 http://localhost:5000</value>
|
||||
</data>
|
||||
<data name="LyricsLoading" xml:space="preserve">
|
||||
<value>載入歌詞中...</value>
|
||||
</data>
|
||||
@@ -249,7 +261,10 @@
|
||||
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
|
||||
<value>翻譯來源</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
|
||||
<value>專輯</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
|
||||
<value>藝術家</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlHelp.Text" xml:space="preserve">
|
||||
@@ -273,13 +288,13 @@
|
||||
<data name="LyricsSearchControlSearch.Content" xml:space="preserve">
|
||||
<value>搜索</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
|
||||
<value>歌曲信息映射</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
|
||||
<value>目標歌詞搜尋提供者</value>
|
||||
</data>
|
||||
<data name="LyricsSearchControlTitle.Header" xml:space="preserve">
|
||||
<data name="LyricsSearchControlTitle.Text" xml:space="preserve">
|
||||
<value>標題</value>
|
||||
</data>
|
||||
<data name="LyricsSearchPageTitle" xml:space="preserve">
|
||||
@@ -309,6 +324,9 @@
|
||||
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
|
||||
<value>設為預設</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSettingsControlShare.Text" xml:space="preserve">
|
||||
<value>匯出</value>
|
||||
</data>
|
||||
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
|
||||
<value>歌詞視窗切換器</value>
|
||||
</data>
|
||||
@@ -343,8 +361,8 @@
|
||||
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
|
||||
<value>歡迎使用 BetterLyrics</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
|
||||
<value>添加到歌單</value>
|
||||
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
|
||||
<value>新增到播放清單</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
|
||||
<value>列表的結尾</value>
|
||||
@@ -352,13 +370,13 @@
|
||||
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
|
||||
<value>下一個項目</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
|
||||
<value>新增到播放隊列</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageAllSongs" xml:space="preserve">
|
||||
<value>所有歌曲</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
|
||||
<value>清除播放隊列</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
|
||||
@@ -385,6 +403,9 @@
|
||||
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
|
||||
<value>格式</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
|
||||
<value>歌词</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
|
||||
<value>路徑</value>
|
||||
</data>
|
||||
@@ -400,8 +421,11 @@
|
||||
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
|
||||
<value>未在媒體庫內找到任何歌曲</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
|
||||
<value>從檔案匯入</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
|
||||
<value>建立歌單</value>
|
||||
<value>建立播放清單</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
|
||||
<value>播放全部</value>
|
||||
@@ -412,26 +436,32 @@
|
||||
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
|
||||
<value>播放隊列是空的</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
|
||||
<value>播放清單</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
|
||||
<value>列表循環</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
|
||||
<value>隨機</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
|
||||
<value>從播放列表中刪除</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
|
||||
<value>從播放列表移除</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
|
||||
<value>定位到播放項</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
|
||||
<value>選擇全部</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve">
|
||||
<data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
|
||||
<value>單曲循環</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
|
||||
<value>搜索歌曲</value>
|
||||
<value>搜尋歌曲名稱、藝人、專輯或所在資料夾路徑</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
|
||||
<value>專輯</value>
|
||||
@@ -439,12 +469,21 @@
|
||||
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
|
||||
<value>藝術家</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
|
||||
<value>文件夹</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
|
||||
<value>標題</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageSortType.Text" xml:space="preserve">
|
||||
<value>排序類型</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
|
||||
<value>已加星號的歌单</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
|
||||
<value>停止</value>
|
||||
</data>
|
||||
<data name="MusicGalleryPageTitle" xml:space="preserve">
|
||||
<value>音樂庫 - BetterLyrics</value>
|
||||
</data>
|
||||
@@ -457,6 +496,9 @@
|
||||
<data name="Pinyin" xml:space="preserve">
|
||||
<value>普通話拼音</value>
|
||||
</data>
|
||||
<data name="PlaylistViewFailed" xml:space="preserve">
|
||||
<value>由於路徑不存在,因此無法檢視曲目</value>
|
||||
</data>
|
||||
<data name="Romaji" xml:space="preserve">
|
||||
<value>羅馬音</value>
|
||||
</data>
|
||||
@@ -476,7 +518,7 @@
|
||||
<value>如果您喜歡這個項目,請考慮通過捐贈來支持它。您的支持將有助於保持項目的生命並鼓勵進一步的發展。</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
|
||||
<value>3D 歌詞</value>
|
||||
<value>[實驗性] 縱深效果</value>
|
||||
</data>
|
||||
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
|
||||
<value>深度</value>
|
||||
@@ -550,6 +592,12 @@
|
||||
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
|
||||
<value>自動調整</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>應用程式啟動時開啟音樂庫視窗</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
|
||||
<value>打開音樂庫視窗時自動繼續播放</value>
|
||||
</data>
|
||||
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
|
||||
<value>自動啟動</value>
|
||||
</data>
|
||||
@@ -610,8 +658,8 @@
|
||||
<data name="SettingsPageConfigName.Header" xml:space="preserve">
|
||||
<value>配置名稱</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromCurrent.Content" xml:space="preserve">
|
||||
<value>從目前的歌詞視窗狀態建立</value>
|
||||
<data name="SettingsPageCreateFromCurrent.Text" xml:space="preserve">
|
||||
<value>複製</value>
|
||||
</data>
|
||||
<data name="SettingsPageCreateFromTemplates.Content" xml:space="preserve">
|
||||
<value>從範本建立</value>
|
||||
@@ -766,6 +814,9 @@
|
||||
<data name="SettingsPageHideWindow.Header" xml:space="preserve">
|
||||
<value>自動隱藏/顯示窗口</value>
|
||||
</data>
|
||||
<data name="SettingsPageImport.Content" xml:space="preserve">
|
||||
<value>匯入</value>
|
||||
</data>
|
||||
<data name="SettingsPageImportSettingsButton.Content" xml:space="preserve">
|
||||
<value>導入設置</value>
|
||||
</data>
|
||||
@@ -841,6 +892,9 @@
|
||||
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
|
||||
<value>LX 音樂服務器</value>
|
||||
</data>
|
||||
<data name="SettingsPageLXMusicServerInput.PlaceholderText" xml:space="preserve">
|
||||
<value>例如 http://127.0.0.1: 23330</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>對齊方式</value>
|
||||
</data>
|
||||
@@ -1168,6 +1222,9 @@
|
||||
<data name="SettingsPageSettingsManager.Header" xml:space="preserve">
|
||||
<value>設置管理器</value>
|
||||
</data>
|
||||
<data name="SettingsPageShareHub.Content" xml:space="preserve">
|
||||
<value>瀏覽線上資源分享中心</value>
|
||||
</data>
|
||||
<data name="SettingsPageShortcutRegFailInfo" xml:space="preserve">
|
||||
<value>該熱鍵未成功註冊</value>
|
||||
</data>
|
||||
@@ -1211,7 +1268,7 @@
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpectrumLayer.Header" xml:space="preserve">
|
||||
<value>光譜層</value>
|
||||
<value>[實驗性] 頻譜層</value>
|
||||
</data>
|
||||
<data name="SettingsPageSpeed.Header" xml:space="preserve">
|
||||
<value>動作速率</value>
|
||||
@@ -1312,12 +1369,21 @@
|
||||
<data name="SystemTrayRestart.Text" xml:space="preserve">
|
||||
<value>重新啟動</value>
|
||||
</data>
|
||||
<data name="SystemTraySearch.Text" xml:space="preserve">
|
||||
<value>歌詞搜尋視窗</value>
|
||||
</data>
|
||||
<data name="SystemTraySettings.Text" xml:space="preserve">
|
||||
<value>打開設置</value>
|
||||
</data>
|
||||
<data name="SystemTraySwitch.Text" xml:space="preserve">
|
||||
<value>歌詞視窗切換器</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
|
||||
<value>路徑不存在,無法新增曲目</value>
|
||||
</data>
|
||||
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
|
||||
<value>所選曲目已新增到此播放列表</value>
|
||||
</data>
|
||||
<data name="TranslateServerNotSet" xml:space="preserve">
|
||||
<value>未設定翻譯伺服器,請先在設定中進行配置</value>
|
||||
</data>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace BetterLyrics.WinUI3.TemplateSelector;
|
||||
|
||||
public class SongOrderTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate ByTitleTemplate { get; set; }
|
||||
public DataTemplate ByAlbumTemplate { get; set; }
|
||||
public DataTemplate ByArtistTemplate { get; set; }
|
||||
|
||||
public CommonSongProperty SongOrderType { get; set; }
|
||||
|
||||
protected override DataTemplate SelectTemplateCore(object item)
|
||||
{
|
||||
return SongOrderType switch
|
||||
{
|
||||
CommonSongProperty.Title => ByTitleTemplate,
|
||||
CommonSongProperty.Album => ByAlbumTemplate,
|
||||
CommonSongProperty.Artist => ByArtistTemplate,
|
||||
_ => ByTitleTemplate
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Helper.BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
public partial class AboutControlViewModel : BaseViewModel
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IResourceService _resourceService;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial bool IsDebugOverlayEnabled { get; set; } = false;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AppSettings AppSettings { get; set; }
|
||||
|
||||
public AboutControlViewModel(ISettingsService settingsService, IResourceService resourceService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_resourceService = resourceService;
|
||||
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task LaunchProjectGitHubPageAsync()
|
||||
{
|
||||
await Windows.System.Launcher.LaunchUriAsync(new Uri(Constants.Link.GitHubUrl));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private static async Task OpenCacheFolderAsync()
|
||||
{
|
||||
await Windows.System.Launcher.LaunchFolderPathAsync(PathHelper.CacheFolder);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private static async Task OpenSettingsFolderAsync()
|
||||
{
|
||||
await Windows.System.Launcher.LaunchFolderPathAsync(PathHelper.LocalFolder);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ImportSettingsAsync()
|
||||
{
|
||||
var file = await PickerHelper.PickSingleFileAsync<SettingsWindow>([".json"]);
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
var succeed = _settingsService.ImportSettings(file.Path);
|
||||
if (succeed)
|
||||
{
|
||||
WindowHelper.RestartApp();
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("ImportSettingsFailed") ?? "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ExportSettingsAsync()
|
||||
{
|
||||
var folder = await PickerHelper.PickSingleFolderAsync<SettingsWindow>();
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
_settingsService.ExportSettings(folder.Path);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("ExportSettingsSuccess") ?? "");
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void ClearCacheFiles()
|
||||
{
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.LogDirectory);
|
||||
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.LyricsCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.AmllTtmlDbLyricsCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.KugouLyricsCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.LrcLibLyricsCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.NeteaseLyricsCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.QQLyricsCacheDirectory);
|
||||
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.TranslationCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.KugouTranslationCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.NeteaseTranslationCacheDirectory);
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.QQTranslationCacheDirectory);
|
||||
|
||||
DirectoryHelper.DeleteAllFiles(PathHelper.iTunesAlbumArtCacheDirectory);
|
||||
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("ActionCompleted"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,12 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
public partial class BaseViewModel : ObservableRecipient
|
||||
{
|
||||
private protected readonly DispatcherQueue _dispatcherQueue;
|
||||
private protected readonly DispatcherQueueTimer _dispatcherQueueTimer;
|
||||
|
||||
public BaseViewModel()
|
||||
{
|
||||
IsActive = true;
|
||||
|
||||
_dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
_dispatcherQueueTimer = _dispatcherQueue.CreateTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
{
|
||||
public partial class LyricsRendererViewModel
|
||||
{
|
||||
public void CreateResources(Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
|
||||
{
|
||||
_logger.LogInformation("Creating resources... Reason: {Reason}", args.Reason);
|
||||
switch (args.Reason)
|
||||
{
|
||||
case Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesReason.FirstTime:
|
||||
_isDeviceChanged = true;
|
||||
break;
|
||||
case Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesReason.NewDevice:
|
||||
_isDeviceChanged = true;
|
||||
break;
|
||||
case Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesReason.DpiChanged:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ using System.Numerics;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics.Effects;
|
||||
using Windows.UI;
|
||||
using static Vanara.PInvoke.Shell32;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
{
|
||||
@@ -128,21 +129,20 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
for (int i = 0; i < _spectrumAnalyzer.BarCount; i++)
|
||||
{
|
||||
float x = i * pointSpacing;
|
||||
float amplitude = _spectrumAnalyzer.SmoothSpectrum.Average() * 10 + _spectrumAnalyzer.SmoothSpectrum[i] * 0.5f;
|
||||
float y = (float)_canvasHeight - amplitude;
|
||||
float y = _spectrumAnalyzer.SmoothSpectrum[i];
|
||||
points[i] = new Vector2(x, y);
|
||||
}
|
||||
|
||||
// 限制最高点高度
|
||||
var minY = points.OrderBy(p => p.Y).FirstOrDefault().Y;
|
||||
var limitY = _canvasHeight * (1 - 0.1f);
|
||||
if (minY < limitY)
|
||||
var maxY = points.OrderByDescending(p => p.Y).FirstOrDefault().Y;
|
||||
var limitY = _canvasHeight * 0.2f;
|
||||
if (maxY > limitY)
|
||||
{
|
||||
var num = (float)(limitY / minY);
|
||||
var num = (float)(limitY / maxY);
|
||||
points = points.Select(p => new Vector2(p.X, p.Y * num)).ToArray();
|
||||
}
|
||||
// 防止越过画布边界
|
||||
points = points.Select(p => new Vector2(p.X, (float)(Math.Min(_canvasHeight, p.Y)))).ToArray();
|
||||
|
||||
points = points.Select(p => new Vector2(p.X, (float)(_canvasHeight - p.Y))).ToArray();
|
||||
|
||||
// 用于填充的闭合路径
|
||||
using var pathBuilder = new CanvasPathBuilder(ds);
|
||||
@@ -176,7 +176,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
var gradientStops = new CanvasGradientStop[]
|
||||
{
|
||||
new() { Position = 0.0f, Color = Colors.Transparent },
|
||||
new() { Position = 0.8f, Color = Colors.Transparent },
|
||||
new() { Position = 0.7f, Color = Colors.Transparent },
|
||||
new() { Position = 1.0f, Color = _adaptiveColoredFontColor ?? _albumArtAccentColor1Transition.Value }
|
||||
};
|
||||
|
||||
|
||||
@@ -36,9 +36,9 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
|
||||
public void Receive(PropertyChangedMessage<bool> message)
|
||||
{
|
||||
if (message.Sender is SettingsPageViewModel)
|
||||
if (message.Sender is AboutControlViewModel)
|
||||
{
|
||||
if (message.PropertyName == nameof(SettingsPageViewModel.IsDebugOverlayEnabled))
|
||||
if (message.PropertyName == nameof(AboutControlViewModel.IsDebugOverlayEnabled))
|
||||
{
|
||||
_isDebugOverlayEnabled = message.NewValue;
|
||||
_isDebugOverlayEnabledChanged = true;
|
||||
@@ -408,6 +408,9 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
UpdateSongInfoFontSize();
|
||||
|
||||
_isLayoutChanged = true;
|
||||
|
||||
// 模拟设备变更,执行全局强制刷新以避免旧值被误用
|
||||
_isDeviceChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
{
|
||||
public partial class LyricsRendererViewModel
|
||||
{
|
||||
private bool _isLayoutChanged = true;
|
||||
|
||||
private bool _isCanvasWidthChanged = false;
|
||||
private bool _isCanvasHeightChanged = false;
|
||||
|
||||
@@ -60,6 +62,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
|
||||
private bool _isLyrics3DMatrixChanged = true;
|
||||
|
||||
private bool _isDeviceChanged = true;
|
||||
|
||||
public void Update(ICanvasAnimatedControl control, CanvasAnimatedUpdateEventArgs args)
|
||||
{
|
||||
_elapsedTime = args.Timing.ElapsedTime;
|
||||
@@ -77,7 +81,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
|
||||
//_effect?.Properties["iTime"] = Convert.ToSingle(TotalTime.TotalSeconds);
|
||||
|
||||
if (_isFluidOverlayEnabledChanged)
|
||||
if (_isDeviceChanged || _isFluidOverlayEnabledChanged)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.IsFluidOverlayEnabled)
|
||||
{
|
||||
@@ -142,8 +146,11 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
_isDebugOverlayEnabledChanged = false;
|
||||
}
|
||||
|
||||
_rotateAngle += _coverRotateBaseSpeed * _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.CoverOverlaySpeed / 100.0;
|
||||
_rotateAngle %= Math.PI * 2;
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.CoverOverlaySpeed > 0)
|
||||
{
|
||||
_rotateAngle += _coverRotateBaseSpeed * _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.CoverOverlaySpeed / 100.0;
|
||||
_rotateAngle %= Math.PI * 2;
|
||||
}
|
||||
|
||||
if (_isSpectrumOverlayEnabledChanged)
|
||||
{
|
||||
@@ -176,7 +183,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
// }
|
||||
//}
|
||||
|
||||
if (_isCanvasWidthChanged || _isCanvasHeightChanged)
|
||||
if (_isDeviceChanged || _isCanvasWidthChanged || _isCanvasHeightChanged)
|
||||
{
|
||||
UpdateSongInfoFontSize();
|
||||
|
||||
@@ -185,6 +192,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
|
||||
_fluidEffect?.Properties["Width"] = (float)control.ConvertDipsToPixels((float)_canvasWidth, CanvasDpiRounding.Round);
|
||||
_fluidEffect?.Properties["Height"] = (float)control.ConvertDipsToPixels((float)_canvasHeight, CanvasDpiRounding.Round);
|
||||
|
||||
_topMargin = _bottomMargin = _leftMargin = _middleMargin = _rightMargin = Math.Max(_canvasWidth, _canvasHeight) / 30.0;
|
||||
}
|
||||
|
||||
if (_isSongInfoFontSizeChanged || _isSongTitleVisibilityChanged || _isSongArtistsVisibilityChanged)
|
||||
@@ -192,7 +201,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
_songInfoHeight = 0;
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowTitle)
|
||||
{
|
||||
_songInfoHeight += (int)_titleTextFormat.FontSize;
|
||||
_songInfoHeight += (int)(_titleTextFormat.FontSize * (1.0 + 0.5));
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowArtists)
|
||||
{
|
||||
_songInfoHeight += (int)_artistTextFormat.FontSize;
|
||||
@@ -200,7 +209,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
}
|
||||
}
|
||||
|
||||
if (_isDisplayTypeChanged || _isLyricsLayoutOrientationChanged || _isAlbumArtSizeChanged ||
|
||||
if (_isDeviceChanged || _isDisplayTypeChanged || _isLyricsLayoutOrientationChanged || _isAlbumArtSizeChanged ||
|
||||
_isSongInfoFontSizeChanged || _isSongTitleVisibilityChanged || _isSongArtistsVisibilityChanged ||
|
||||
_isCanvasWidthChanged || _isCanvasHeightChanged ||
|
||||
_isAlbumArtSizeChanged)
|
||||
@@ -220,7 +229,6 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
{
|
||||
_albumArtSize = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.AlbumArtSize;
|
||||
}
|
||||
//_albumArtYTransition.StartTransition((_canvasHeight - _albumArtSize * 1.05 - _songInfoHeight) / 2.0, jumpTo);
|
||||
_albumArtYTransition.StartTransition((_canvasHeight - _albumArtSize - _songInfoHeight) / 2.0, jumpTo);
|
||||
_titleYTransition.StartTransition(_albumArtYTransition.TargetValue + _albumArtSize * 1.05, jumpTo);
|
||||
_lyricsYTransition.StartTransition(0, jumpTo);
|
||||
@@ -251,7 +259,9 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
case LyricsLayoutOrientation.Vertical:
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.AutoAlbumArtSize)
|
||||
{
|
||||
_albumArtSize = 64;
|
||||
_albumArtSize = Math.Min((_canvasHeight - _topMargin - _bottomMargin) * 3.0 / 16.0,
|
||||
(_canvasWidth - _leftMargin - _middleMargin - _rightMargin) * 4.0 / 16.0);
|
||||
_albumArtSize = Math.Max(0, _albumArtSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -278,7 +288,6 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
_titleYTransition.StartTransition(_topMargin, jumpTo);
|
||||
_lyricsOpacityTransition.StartTransition(1f, jumpTo);
|
||||
_albumArtOpacityTransition.StartTransition(1f, jumpTo);
|
||||
//_lyricsYTransition.StartTransition(_albumArtSize, jumpTo);
|
||||
_lyricsYTransition.StartTransition(_topMargin, jumpTo);
|
||||
break;
|
||||
default:
|
||||
@@ -320,20 +329,18 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
// 将当前背景图放到 _lastAlbumArtSwBitmap 中 并设置不透明度为 1
|
||||
// 将新的背景图放到 _albumArtSwBitmap 中 并设置不透明度为 0
|
||||
// 这样可以实现背景图的连贯渐变效果
|
||||
if (_albumArtChanged || _isLyricsLayoutOrientationChanged || _isAlbumArtSizeChanged ||
|
||||
if (_isDeviceChanged || _albumArtChanged || _isLyricsLayoutOrientationChanged || _isAlbumArtSizeChanged ||
|
||||
_isCanvasHeightChanged || _isCanvasWidthChanged ||
|
||||
_lyricsBgBrightnessTransition.IsTransitioning ||
|
||||
_albumArtBgTransition.IsTransitioning)
|
||||
{
|
||||
// 必须先在此处重置动画
|
||||
if (_albumArtChanged)
|
||||
if (_isDeviceChanged || _albumArtChanged)
|
||||
{
|
||||
// 必须先在此处重置动画
|
||||
_albumArtBgTransition.Reset(0f);
|
||||
_albumArtBgTransition.StartTransition(1f);
|
||||
}
|
||||
// 更新 last 和 current
|
||||
if (_albumArtChanged)
|
||||
{
|
||||
|
||||
// 更新 last 和 current
|
||||
if (_lastAlbumArtSwBitmap != null)
|
||||
{
|
||||
_lastAlbumArtCanvasBitmap?.Dispose();
|
||||
@@ -360,53 +367,39 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
_isLyricsLayoutOrientationChanged = false;
|
||||
_isAlbumArtSizeChanged = false;
|
||||
|
||||
if (_isCoverAcrylicEffectAmountChanged)
|
||||
if (_isDeviceChanged || _isAlbumArtBgOpacityChanged || _isAlbumArtBgBlurAmountChanged || _isCoverAcrylicEffectAmountChanged)
|
||||
{
|
||||
UpdateCoverAcrylicOverlay(control);
|
||||
if (_isDeviceChanged || _isCoverAcrylicEffectAmountChanged)
|
||||
{
|
||||
UpdateCoverAcrylicOverlay(control);
|
||||
}
|
||||
|
||||
DisposeAlbumArtBgRenderTarget();
|
||||
UpdateAlbumArtBgEffect(control);
|
||||
_isAlbumArtBgEffectChanged = true;
|
||||
|
||||
_isCoverAcrylicEffectAmountChanged = false;
|
||||
}
|
||||
|
||||
if (_isAlbumArtBgOpacityChanged)
|
||||
{
|
||||
DisposeAlbumArtBgRenderTarget();
|
||||
UpdateAlbumArtBgEffect(control);
|
||||
_isAlbumArtBgEffectChanged = true;
|
||||
|
||||
_isAlbumArtBgOpacityChanged = false;
|
||||
}
|
||||
|
||||
if (_isAlbumArtBgBlurAmountChanged)
|
||||
{
|
||||
DisposeAlbumArtBgRenderTarget();
|
||||
UpdateAlbumArtBgEffect(control);
|
||||
_isAlbumArtBgEffectChanged = true;
|
||||
|
||||
_isAlbumArtBgBlurAmountChanged = false;
|
||||
_isCoverAcrylicEffectAmountChanged = false;
|
||||
}
|
||||
|
||||
_albumArtChanged = false;
|
||||
|
||||
if (!_isAlbumArtEffectChanged && _albumArtEffect != null)
|
||||
if (_isDeviceChanged || (!_isAlbumArtEffectChanged && _albumArtEffect != null))
|
||||
{
|
||||
UpdateAlbumArtRenderTarget(control);
|
||||
DisposeAlbumArtEffect();
|
||||
}
|
||||
|
||||
if (!_isAlbumArtBgEffectChanged && _albumArtBgEffect != null)
|
||||
if (_isDeviceChanged || (!_isAlbumArtBgEffectChanged && _albumArtBgEffect != null))
|
||||
{
|
||||
UpdateAlbumArtBgRenderTarget(control);
|
||||
DisposeAlbumArtBgEffect();
|
||||
}
|
||||
|
||||
if (_isCanvasHeightChanged || _isCanvasWidthChanged || _lyricsXTransition.IsTransitioning)
|
||||
if (_isDeviceChanged || _isCanvasHeightChanged || _isCanvasWidthChanged || _lyricsXTransition.IsTransitioning)
|
||||
{
|
||||
_maxLyricsWidth = _canvasWidth - _lyricsXTransition.Value - _rightMargin;
|
||||
_maxLyricsWidth = Math.Max(_maxLyricsWidth, 0);
|
||||
_maxLyricsWidth = Math.Max(_canvasWidth - _lyricsXTransition.Value - _rightMargin, 0);
|
||||
_isLayoutChanged = true;
|
||||
_isLyrics3DMatrixChanged = true;
|
||||
}
|
||||
@@ -458,6 +451,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
_lyricsBgBrightnessTransition.Update(_elapsedTime);
|
||||
_songInfoOpacityTransition.Update(_elapsedTime);
|
||||
_canvasYScrollTransition.Update(_elapsedTime);
|
||||
|
||||
_isDeviceChanged = false;
|
||||
}
|
||||
|
||||
private string AutoSelectFontFamily(string text)
|
||||
@@ -474,8 +469,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.IsDynamicLyricsFontSize)
|
||||
{
|
||||
_originalLyricsFontSize = (int)Math.Clamp(Math.Min(_canvasHeight, _canvasWidth) / 15, 12, 96);
|
||||
_translatedLyricsFontSize = _phoneticLyricsFontSize = (int)(_originalLyricsFontSize * 0.6);
|
||||
_originalLyricsFontSize = (int)Math.Clamp(Math.Min(_canvasHeight, _canvasWidth) / 15, 18, 96);
|
||||
_translatedLyricsFontSize = _phoneticLyricsFontSize = (int)(_originalLyricsFontSize * 2.0 / 3.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -485,6 +480,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
}
|
||||
|
||||
_originalLyricsFontWeight = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight;
|
||||
_titleTextFormat.FontWeight = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight.ToFontWeight();
|
||||
_artistTextFormat.FontWeight = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight.ToFontWeight();
|
||||
|
||||
if (SongInfo != null)
|
||||
{
|
||||
|
||||
@@ -97,17 +97,17 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly double _leftMargin = 36f;
|
||||
private readonly double _middleMargin = 36f;
|
||||
private readonly double _rightMargin = 36f;
|
||||
private readonly double _topMargin = 36f;
|
||||
private readonly double _bottomMargin = 36f;
|
||||
private double _leftMargin = 36f;
|
||||
private double _middleMargin = 36f;
|
||||
private double _rightMargin = 36f;
|
||||
private double _topMargin = 36f;
|
||||
private double _bottomMargin = 36f;
|
||||
|
||||
private Color _adaptiveGrayedFontColor = Colors.Transparent;
|
||||
private Color? _adaptiveColoredFontColor = null;
|
||||
|
||||
private List<Color> _albumArtLightAccentColors = Enumerable.Repeat(Colors.Transparent, 4).ToList();
|
||||
private List<Color> _albumArtDarkAccentColors = Enumerable.Repeat(Colors.Transparent, 4).ToList();
|
||||
private List<Color> _albumArtLightAccentColors = Enumerable.Repeat(Colors.Black, 4).ToList();
|
||||
private List<Color> _albumArtDarkAccentColors = Enumerable.Repeat(Colors.Black, 4).ToList();
|
||||
private Color _environmentalColor = Colors.Transparent;
|
||||
private Color _grayedEnvironmentalColor = Colors.Transparent;
|
||||
|
||||
@@ -130,8 +130,6 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
|
||||
[ObservableProperty]
|
||||
public partial bool IsPlaying { get; set; } = false;
|
||||
|
||||
private bool _isLayoutChanged = true;
|
||||
|
||||
private int _timelineSyncThreshold = 0;
|
||||
|
||||
private int _phoneticLyricsFontSize = 18;
|
||||
|
||||
@@ -78,8 +78,10 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
OriginalTitle = _mediaSessionsService.SongInfo.Title,
|
||||
OriginalArtist = _mediaSessionsService.SongInfo.Artist,
|
||||
OriginalAlbum = _mediaSessionsService.SongInfo.Album,
|
||||
MappedTitle = _mediaSessionsService.SongInfo.Title,
|
||||
MappedArtist = _mediaSessionsService.SongInfo.Artist,
|
||||
MappedAlbum = _mediaSessionsService.SongInfo.Album,
|
||||
};
|
||||
}
|
||||
else
|
||||
@@ -95,9 +97,11 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var found = AppSettings.MappedSongSearchQueries
|
||||
.Where(x => x.OriginalTitle == _mediaSessionsService.SongInfo.Title && x.OriginalArtist == _mediaSessionsService.SongInfo.Artist).FirstOrDefault();
|
||||
return found;
|
||||
.Where(x => x.OriginalTitle == _mediaSessionsService.SongInfo.Title && x.OriginalArtist == _mediaSessionsService.SongInfo.Artist && x.OriginalAlbum == _mediaSessionsService.SongInfo.Album);
|
||||
|
||||
return found.FirstOrDefault();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -118,7 +122,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
return await _lyricsSearchService.SearchAllAsync(
|
||||
MappedSongSearchQuery.MappedTitle,
|
||||
MappedSongSearchQuery.MappedArtist,
|
||||
_mediaSessionsService.SongInfo?.Album ?? "",
|
||||
MappedSongSearchQuery.MappedAlbum,
|
||||
_mediaSessionsService.SongInfo?.DurationMs ?? 0, token);
|
||||
}, token)];
|
||||
IsSearching = false;
|
||||
@@ -166,6 +170,12 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
MappedSongSearchQuery?.MappedArtist = MappedSongSearchQuery?.OriginalArtist ?? string.Empty;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void ResetMappedAlbum()
|
||||
{
|
||||
MappedSongSearchQuery?.MappedAlbum = MappedSongSearchQuery?.OriginalAlbum ?? string.Empty;
|
||||
}
|
||||
|
||||
partial void OnSelectedLyricsSearchResultChanged(LyricsSearchResult? value)
|
||||
{
|
||||
MappedSongSearchQuery?.LyricsSearchProvider = value?.Provider;
|
||||
@@ -173,8 +183,10 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
var lyricsParser = new LyricsParser();
|
||||
lyricsParser.Parse(
|
||||
MappedSongSearchQuery?.MappedTitle ?? "",
|
||||
MappedSongSearchQuery?.MappedArtist ?? "",
|
||||
AppSettings.MappedSongSearchQueries.ToList(),
|
||||
MappedSongSearchQuery?.OriginalTitle ?? "",
|
||||
MappedSongSearchQuery?.OriginalArtist ?? "",
|
||||
MappedSongSearchQuery?.OriginalAlbum ?? "",
|
||||
value?.Raw, (int?)_mediaSessionsService.SongInfo?.DurationMs, value?.Provider);
|
||||
LyricsDataArr = [.. lyricsParser.LyricsDataArr];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Serialization;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
@@ -10,6 +12,7 @@ using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -21,6 +24,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
private readonly IResourceService _resourceService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial LiveStates LiveStates { get; set; }
|
||||
@@ -34,29 +38,22 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<string> MonitorDeviceNames { get; set; }
|
||||
|
||||
public LyricsWindowSettingsControlViewModel(ISettingsService settingsService, ILiveStatesService liveStatesService)
|
||||
public LyricsWindowSettingsControlViewModel(ISettingsService settingsService, ILiveStatesService liveStatesService, IResourceService resourceService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_liveStatesService = liveStatesService;
|
||||
_resourceService = resourceService;
|
||||
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
AppSettings.WindowBoundsRecords.CollectionChanged += WindowBoundsRecords_CollectionChanged;
|
||||
LiveStates = _liveStatesService.LiveStates;
|
||||
MonitorDeviceNames = [.. MonitorHelper.GetAllMonitorDeviceNames()];
|
||||
}
|
||||
|
||||
private void WindowBoundsRecords_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (!AppSettings.WindowBoundsRecords.Any(x => x == LiveStates.LyricsWindowStatus))
|
||||
{
|
||||
LiveStates.LyricsWindowStatus = AppSettings.WindowBoundsRecords.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void RefreshMonitorDeviceNames()
|
||||
{
|
||||
MonitorDeviceNames = [.. MonitorHelper.GetAllMonitorDeviceNames()];
|
||||
LiveStates.LyricsWindowStatus.MonitorDeviceName = MonitorDeviceNames.FirstOrDefault() ?? "";
|
||||
LiveStates.LyricsWindowStatus?.MonitorDeviceName = MonitorDeviceNames.FirstOrDefault() ?? "";
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -80,7 +77,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[RelayCommand]
|
||||
private void CreateFullLyricsWindowStatus()
|
||||
{
|
||||
AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.FullscreenMode(LiveStates.LyricsWindowStatus.MonitorBounds));
|
||||
AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.FullscreenMode());
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -88,13 +85,5 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.NarrowMode());
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CopyLyricsWindowStatus()
|
||||
{
|
||||
var data = (LyricsWindowStatus)LiveStates.LyricsWindowStatus.Clone();
|
||||
data.IsDefault = false;
|
||||
AppSettings.WindowBoundsRecords.Add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@ using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System.Collections.Generic;
|
||||
using Vanara.PInvoke;
|
||||
using Windows.Foundation;
|
||||
using Windows.System;
|
||||
using Windows.UI;
|
||||
using WinRT.Interop;
|
||||
using WinUIEx;
|
||||
@@ -39,6 +39,7 @@ namespace BetterLyrics.WinUI3
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
|
||||
private ForegroundWindowWatcher? _fgWindowWatcher = null;
|
||||
private DispatcherQueueTimer? _fgWindowWatcherTimer = null;
|
||||
|
||||
public LyricsWindowViewModel(ISettingsService settingsService, IMediaSessionsService mediaSessionsService, ILiveStatesService liveStatesService)
|
||||
{
|
||||
@@ -54,7 +55,7 @@ namespace BetterLyrics.WinUI3
|
||||
|
||||
private void PlaybackService_IsPlayingChanged(object? sender, Events.IsPlayingChangedEventArgs e)
|
||||
{
|
||||
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
|
||||
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
|
||||
}
|
||||
|
||||
[ObservableProperty] public partial AppSettings AppSettings { get; set; }
|
||||
@@ -142,11 +143,13 @@ namespace BetterLyrics.WinUI3
|
||||
if (window == null) return;
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
_fgWindowWatcherTimer = _dispatcherQueue.CreateTimer();
|
||||
_fgWindowWatcher = new ForegroundWindowWatcher(
|
||||
hwnd,
|
||||
fgHwnd =>
|
||||
{
|
||||
_dispatcherQueueTimer.Debounce(() =>
|
||||
_fgWindowWatcherTimer.Debounce(() =>
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsAlwaysOnTop &&
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling &&
|
||||
@@ -186,11 +189,6 @@ namespace BetterLyrics.WinUI3
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshLyricsWindowStatus()
|
||||
{
|
||||
_liveStatesService.RefreshLyricsWindowStatus();
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<List<string>> message)
|
||||
{
|
||||
if (message.Sender is GeneralSettings)
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.LibWatcherService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -21,29 +23,22 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
public partial class MediaSettingsControlViewModel : BaseViewModel
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IResourceService _resourceService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AppSettings AppSettings { get; set; }
|
||||
|
||||
public MediaSettingsControlViewModel(ISettingsService settingsService)
|
||||
public MediaSettingsControlViewModel(ISettingsService settingsService, IResourceService resourceService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_resourceService = resourceService;
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task SelectAndAddFolderAsync(UIElement sender)
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<SettingsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
var picker = new Windows.Storage.Pickers.FolderPicker();
|
||||
picker.FileTypeFilter.Add("*");
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
InitializeWithWindow.Initialize(picker, hwnd);
|
||||
|
||||
var folder = await picker.PickSingleFolderAsync();
|
||||
var folder = await PickerHelper.PickSingleFolderAsync<SettingsWindow>();
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
@@ -57,18 +52,18 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
if (AppSettings.LocalMediaFolders.Any(x => Path.GetFullPath(x.Path).TrimEnd(Path.DirectorySeparatorChar).Equals(normalizedPath.TrimEnd(Path.DirectorySeparatorChar), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPagePathExistedInfo"), InfoBarSeverity.Warning);
|
||||
DevWinUI.Growl.Warning(_resourceService.GetLocalizedString("SettingsPagePathExistedInfo"));
|
||||
}
|
||||
else if (AppSettings.LocalMediaFolders.Any(item => normalizedPath.StartsWith(Path.GetFullPath(item.Path).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
// 添加的文件夹是现有文件夹的子文件夹
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPagePathBeIncludedInfo"), InfoBarSeverity.Warning);
|
||||
DevWinUI.Growl.Warning(_resourceService.GetLocalizedString("SettingsPagePathBeIncludedInfo"));
|
||||
}
|
||||
else if (AppSettings.LocalMediaFolders.Any(item => Path.GetFullPath(item.Path).TrimEnd(Path.DirectorySeparatorChar).StartsWith(normalizedPath, StringComparison.OrdinalIgnoreCase))
|
||||
)
|
||||
{
|
||||
// 添加的文件夹是现有文件夹的父文件夹
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPagePathIncludingOthersInfo"), InfoBarSeverity.Warning);
|
||||
DevWinUI.Growl.Warning(_resourceService.GetLocalizedString("SettingsPagePathIncludingOthersInfo"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -7,8 +7,11 @@ using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using BetterLyrics.WinUI3.Services.LibWatcherService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using CommunityToolkit.WinUI;
|
||||
@@ -25,6 +28,8 @@ using Windows.ApplicationModel;
|
||||
using Windows.Media;
|
||||
using Windows.Media.Core;
|
||||
using Windows.Media.Playback;
|
||||
using Windows.Storage;
|
||||
using WinRT.Interop;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
@@ -32,11 +37,14 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
private readonly ILibWatcherService _libWatcherService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IResourceService _resourceService;
|
||||
|
||||
private readonly MediaPlayer _mediaPlayer = new();
|
||||
private readonly MediaTimelineController _timelineController = new();
|
||||
private readonly SystemMediaTransportControls _smtc;
|
||||
|
||||
private readonly DispatcherQueueTimer _refreshSongsTimer;
|
||||
|
||||
// All songs
|
||||
private List<Track> _tracks = [];
|
||||
// Songs in current playlist
|
||||
@@ -44,6 +52,9 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
// Filtered songs based on search query for current playlist
|
||||
private List<Track> _filteredTracks = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AppSettings AppSettings { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsLocalMediaNotFound { get; set; }
|
||||
|
||||
@@ -57,12 +68,12 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
public partial List<Track> SelectedTracks { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<PlayQueueItem> TrackPlayingQueue { get; set; } = [];
|
||||
|
||||
public PlayQueueItem? PlayingQueueItem => TrackPlayingQueue.ElementAtOrDefault(PlayingSongIndex);
|
||||
public partial int SelectedTracksTotalDuration { get; set; } = 0;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial PlaybackOrder PlaybackOrder { get; set; }
|
||||
public partial ObservableCollection<PlayQueueItem> TrackPlayingQueue { get; set; }
|
||||
|
||||
public PlayQueueItem? PlayingQueueItem => TrackPlayingQueue.ElementAtOrDefault(AppSettings.MusicGallerySettings.PlayQueueIndex);
|
||||
|
||||
[ObservableProperty]
|
||||
public partial CommonSongProperty SongOrderType { get; set; } = CommonSongProperty.Title;
|
||||
@@ -81,34 +92,35 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[ObservableProperty]
|
||||
public partial Track TrackRightTapped { get; set; } = new();
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int PlayingSongIndex { get; set; } = -1;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int DisplayedPlayingSongIndex { get; set; } = 0;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string SongSearchQuery { get; set; } = string.Empty;
|
||||
|
||||
public MusicGalleryViewModel(ISettingsService settingsService, ILibWatcherService libWatcherService)
|
||||
public MusicGalleryViewModel(ISettingsService settingsService, ILibWatcherService libWatcherService, IResourceService resourceService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_refreshSongsTimer = _dispatcherQueue.CreateTimer();
|
||||
|
||||
SongsTabInfoList.Add(new SongsTabInfo(App.ResourceLoader!.GetString("MusicGalleryPageAllSongs"), "\uE8A9", false, CommonSongProperty.Title, string.Empty));
|
||||
_settingsService = settingsService;
|
||||
_resourceService = resourceService;
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
|
||||
TrackPlayingQueue = [.. AppSettings.MusicGallerySettings.PlayQueuePaths.Select(x => new PlayQueueItem(new Track(x)))];
|
||||
TrackPlayingQueue.CollectionChanged += TrackPlayingQueue_CollectionChanged;
|
||||
|
||||
SongsTabInfoList.Add(new SongsTabInfo(_resourceService.GetLocalizedString("MusicGalleryPageAllSongs"), "\uE8A9", false, false, CommonSongProperty.Title, string.Empty));
|
||||
|
||||
RefreshSongs();
|
||||
|
||||
_settingsService.AppSettings.LocalMediaFolders.CollectionChanged += LocalMediaFolders_CollectionChanged;
|
||||
_settingsService.AppSettings.LocalMediaFolders.ItemPropertyChanged += LocalMediaFolders_ItemPropertyChanged;
|
||||
|
||||
PlaybackOrder = _settingsService.AppSettings.MusicGallerySettings.PlaybackOrder;
|
||||
|
||||
_mediaPlayer.MediaOpened += MediaPlayer_MediaOpened;
|
||||
_mediaPlayer.MediaEnded += MediaPlayer_MediaEnded;
|
||||
_mediaPlayer.CommandManager.IsEnabled = false;
|
||||
|
||||
_timelineController = _mediaPlayer.TimelineController = new();
|
||||
_timelineController.PositionChanged += TimelineController_PositionChanged;
|
||||
|
||||
_smtc = _mediaPlayer.SystemMediaTransportControls;
|
||||
_mediaPlayer.CommandManager.IsEnabled = false;
|
||||
_smtc.IsPlayEnabled = true;
|
||||
_smtc.IsPauseEnabled = true;
|
||||
_smtc.IsNextEnabled = true;
|
||||
@@ -118,6 +130,16 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
_libWatcherService = libWatcherService;
|
||||
_libWatcherService.MusicLibraryFilesChanged += LibWatcherService_MusicLibraryFilesChanged;
|
||||
|
||||
if (AppSettings.MusicGallerySettings.AutoPlay)
|
||||
{
|
||||
_ = PlayTrackAtAsync(AppSettings.MusicGallerySettings.PlayQueueIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void TrackPlayingQueue_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
AppSettings.MusicGallerySettings.PlayQueuePaths = [.. TrackPlayingQueue.Select(x => x.Track.Path)];
|
||||
}
|
||||
|
||||
private void LocalMediaFolders_ItemPropertyChanged(object? sender, ItemPropertyChangedEventArgs e)
|
||||
@@ -137,33 +159,33 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
public void PlayNextTrack()
|
||||
{
|
||||
switch (PlaybackOrder)
|
||||
switch (AppSettings.MusicGallerySettings.PlaybackOrder)
|
||||
{
|
||||
case PlaybackOrder.RepeatAll:
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
|
||||
{
|
||||
if (PlayingSongIndex < TrackPlayingQueue.Count - 1)
|
||||
if (AppSettings.MusicGallerySettings.PlayQueueIndex < TrackPlayingQueue.Count - 1)
|
||||
{
|
||||
PlayingSongIndex++;
|
||||
AppSettings.MusicGallerySettings.PlayQueueIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayingSongIndex = 0;
|
||||
AppSettings.MusicGallerySettings.PlayQueueIndex = 0;
|
||||
}
|
||||
PlayTrack(PlayingQueueItem);
|
||||
await PlayTrackAsync(PlayingQueueItem);
|
||||
});
|
||||
break;
|
||||
case PlaybackOrder.RepeatOne:
|
||||
_timelineController.Position = TimeSpan.Zero;
|
||||
break;
|
||||
case PlaybackOrder.Shuffle:
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
|
||||
{
|
||||
if (TrackPlayingQueue.Count > 0)
|
||||
{
|
||||
PlayingSongIndex = new Random().Next(0, TrackPlayingQueue.Count);
|
||||
AppSettings.MusicGallerySettings.PlayQueueIndex = new Random().Next(0, TrackPlayingQueue.Count);
|
||||
}
|
||||
PlayTrack(PlayingQueueItem);
|
||||
await PlayTrackAsync(PlayingQueueItem);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
@@ -173,33 +195,33 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
private void PlayPreviousTrack()
|
||||
{
|
||||
switch (PlaybackOrder)
|
||||
switch (AppSettings.MusicGallerySettings.PlaybackOrder)
|
||||
{
|
||||
case PlaybackOrder.RepeatAll:
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
|
||||
{
|
||||
if (PlayingSongIndex > 0)
|
||||
if (AppSettings.MusicGallerySettings.PlayQueueIndex > 0)
|
||||
{
|
||||
PlayingSongIndex--;
|
||||
AppSettings.MusicGallerySettings.PlayQueueIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayingSongIndex = TrackPlayingQueue.Count - 1;
|
||||
AppSettings.MusicGallerySettings.PlayQueueIndex = TrackPlayingQueue.Count - 1;
|
||||
}
|
||||
PlayTrack(PlayingQueueItem);
|
||||
await PlayTrackAsync(PlayingQueueItem);
|
||||
});
|
||||
break;
|
||||
case PlaybackOrder.RepeatOne:
|
||||
_timelineController.Position = TimeSpan.Zero;
|
||||
break;
|
||||
case PlaybackOrder.Shuffle:
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
|
||||
{
|
||||
if (TrackPlayingQueue.Count > 0)
|
||||
{
|
||||
PlayingSongIndex = new Random().Next(0, TrackPlayingQueue.Count);
|
||||
AppSettings.MusicGallerySettings.PlayQueueIndex = new Random().Next(0, TrackPlayingQueue.Count);
|
||||
}
|
||||
PlayTrack(PlayingQueueItem);
|
||||
await PlayTrackAsync(PlayingQueueItem);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
@@ -259,7 +281,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
public void RefreshSongs()
|
||||
{
|
||||
_dispatcherQueueTimer.Debounce(() =>
|
||||
_refreshSongsTimer.Debounce(() =>
|
||||
{
|
||||
IsDataLoading = true;
|
||||
_tracks.Clear();
|
||||
@@ -319,6 +341,24 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
case CommonSongProperty.Artist:
|
||||
_playlistTracks = _tracks.Where(t => t.Artist.Equals(SelectedSongsTabInfo.FilterValue, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
break;
|
||||
case CommonSongProperty.Folder:
|
||||
_playlistTracks = _tracks.Where(t => t.GetParentFolderPath().Equals(SelectedSongsTabInfo.FilterValue, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
break;
|
||||
case CommonSongProperty.M3UFilePath:
|
||||
if (SelectedSongsTabInfo.FilterValue is string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var m3uFileContent = File.ReadAllText(path);
|
||||
_playlistTracks = _tracks.Where(t => m3uFileContent.Contains(t.Path)).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
_playlistTracks = [];
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("PlaylistViewFailed"), path);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -338,7 +378,8 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
_filteredTracks = _playlistTracks.Where(t =>
|
||||
t.Title.Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
t.Artist.Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
t.Album.Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
t.Album.Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
t.GetParentFolderPath().Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
}
|
||||
|
||||
private void ApplySongOrderType()
|
||||
@@ -363,6 +404,12 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
o => ((Track)o).Album
|
||||
);
|
||||
break;
|
||||
case CommonSongProperty.Folder:
|
||||
GroupedTracks = _filteredTracks.GetGroupedBy(
|
||||
t => LanguageHelper.GetOrderChar(t.GetParentFolderName()),
|
||||
o => ((Track)o).Album
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,12 +429,12 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
ApplyPlaylist();
|
||||
}
|
||||
|
||||
public void PlayTrackAt(int index)
|
||||
public async Task PlayTrackAtAsync(int index)
|
||||
{
|
||||
PlayTrack(TrackPlayingQueue.ElementAtOrDefault(index));
|
||||
await PlayTrackAsync(TrackPlayingQueue.ElementAtOrDefault(index));
|
||||
}
|
||||
|
||||
public void PlayTrack(PlayQueueItem? playQueueItem)
|
||||
public async Task PlayTrackAsync(PlayQueueItem? playQueueItem)
|
||||
{
|
||||
_timelineController.Pause();
|
||||
_mediaPlayer.Source = null;
|
||||
@@ -402,18 +449,9 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
_smtc.IsEnabled = true;
|
||||
_mediaPlayer.Source = MediaSource.CreateFromUri(new Uri(track.Path));
|
||||
updater.AppMediaId = Package.Current.Id.FullName;
|
||||
updater.Type = MediaPlaybackType.Music;
|
||||
updater.MusicProperties.Title = track.Title;
|
||||
updater.MusicProperties.Artist = track.Artist;
|
||||
updater.MusicProperties.AlbumTitle = track.Album;
|
||||
if (track.EmbeddedPictures.FirstOrDefault()?.PictureData is byte[] pictureData)
|
||||
{
|
||||
updater.Thumbnail = ImageHelper.ByteArrayToRandomAccessStreamReference(pictureData);
|
||||
}
|
||||
else
|
||||
{
|
||||
updater.Thumbnail = null;
|
||||
}
|
||||
|
||||
var storageFile = await StorageFile.GetFileFromPathAsync(track.Path);
|
||||
await updater.CopyFromFileAsync(MediaPlaybackType.Music, storageFile);
|
||||
updater.Update();
|
||||
}
|
||||
}
|
||||
@@ -431,14 +469,56 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
ApplySongOrderType();
|
||||
}
|
||||
|
||||
partial void OnPlayingSongIndexChanged(int value)
|
||||
private void AddFileToStarredPlaylists(StorageFile file)
|
||||
{
|
||||
DisplayedPlayingSongIndex = value + 1;
|
||||
AppSettings.StarredPlaylists.Add(new SongsTabInfo
|
||||
{
|
||||
FilterProperty = CommonSongProperty.M3UFilePath,
|
||||
FilterValue = file.Path,
|
||||
Icon = "\uE7BC",
|
||||
IsStarred = true,
|
||||
IsClosable = true,
|
||||
Name = file.Name
|
||||
});
|
||||
}
|
||||
|
||||
partial void OnPlaybackOrderChanged(PlaybackOrder value)
|
||||
[RelayCommand]
|
||||
private async Task CreatePlaylistAsync()
|
||||
{
|
||||
_settingsService.AppSettings.MusicGallerySettings.PlaybackOrder = value;
|
||||
var file = await PickerHelper.PickSaveFileAsync<MusicGalleryWindow>(new Dictionary<string, IList<string>>()
|
||||
{
|
||||
{ "M3U", [".m3u"] }
|
||||
});
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
AddFileToStarredPlaylists(file);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("CreatePlaylistSuccessfully"), file.Path);
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task ImportPlaylistAsync()
|
||||
{
|
||||
var file = await PickerHelper.PickSingleFileAsync<MusicGalleryWindow>([".m3u"]);
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
AddFileToStarredPlaylists(file);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("ImportPlaylistSuccessfully"), file.Path);
|
||||
}
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void SwitchPlaybackOrder()
|
||||
{
|
||||
AppSettings.MusicGallerySettings.PlaybackOrder = AppSettings.MusicGallerySettings.PlaybackOrder.GetNext();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task StopTrackAsync()
|
||||
{
|
||||
await PlayTrackAtAsync(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using BetterLyrics.WinUI3.Services.LastFMService;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Services.TranslateService;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
@@ -33,6 +34,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private readonly ITranslateService _libreTranslateService;
|
||||
private readonly ILastFMService _lastFMService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IResourceService _resourceService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AppSettings AppSettings { get; set; }
|
||||
@@ -74,11 +76,13 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
ISettingsService settingsService,
|
||||
IMediaSessionsService mediaSessionsService,
|
||||
ITranslateService libreTranslateService,
|
||||
ILastFMService lastFMService)
|
||||
ILastFMService lastFMService,
|
||||
IResourceService resourceService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_mediaSessionsService = mediaSessionsService;
|
||||
_libreTranslateService = libreTranslateService;
|
||||
_resourceService = resourceService;
|
||||
|
||||
_lastFMService = lastFMService;
|
||||
_lastFMService.UserChanged += LastFMService_UserChanged;
|
||||
@@ -143,14 +147,14 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
"Hello, world!", AppSettings.TranslationSettings.SelectedTargetLanguageCode, new System.Threading.CancellationToken());
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestSuccessInfo"), InfoBarSeverity.Success);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("SettingsPageServerTestSuccessInfo"));
|
||||
});
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestFailedInfo"), InfoBarSeverity.Error);
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("SettingsPageServerTestFailedInfo"));
|
||||
});
|
||||
}
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
@@ -189,11 +193,11 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
if (testResult)
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestSuccessInfo"), InfoBarSeverity.Success);
|
||||
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("SettingsPageServerTestSuccessInfo"));
|
||||
}
|
||||
else
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestFailedInfo"), InfoBarSeverity.Error);
|
||||
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("SettingsPageServerTestFailedInfo"));
|
||||
}
|
||||
IsLXMusicServerTesting = false;
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user