Compare commits

...

34 Commits

Author SHA1 Message Date
Zhe Fang
6820e59597 Update issue templates 2025-11-11 11:55:54 -05:00
Zhe Fang
c7b0d409ad chores: rollback PasswordVaultHelper 2025-11-11 11:22:58 -05:00
Zhe Fang
6c942657fc chores:
- Support reading local album art file passed by LX Music server
- Support listening LX Music portable version
- Fix translation not be read in search window
2025-11-11 10:44:10 -05:00
Zhe Fang
8288d62af2 chores: bump version code 2025-11-10 20:13:59 -05:00
Zhe Fang
bd82deb5ae chores: fix issue switching between top and bottom docked mode 2025-11-10 19:54:31 -05:00
Zhe Fang
5093939bff chores: update templates 2025-11-10 19:38:36 -05:00
Zhe Fang
340a41f920 fix: clone missing properties copy 2025-11-10 18:10:13 -05:00
Zhe Fang
3580f2eb0e chores: bump version code 2025-11-10 17:51:53 -05:00
Zhe Fang
2e792b50b2 chores: disable lyrics x transition 2025-11-10 17:18:14 -05:00
Zhe Fang
7a063a1192 chores: extra about page content from settings page 2025-11-10 14:53:18 -05:00
Zhe Fang
8485990250 fix: support open file/folder picker in flyout 2025-11-10 14:36:09 -05:00
Zhe Fang
fb16874d60 chores: update index.md 2025-11-10 13:27:21 -05:00
Zhe Fang
87afdf539a chores: update index.md in ShareHub 2025-11-10 13:24:47 -05:00
Zhe Fang
ce9cb23d6f chores 2025-11-10 13:21:17 -05:00
Zhe Fang
27629a298b chores: add pre-defined lyrics window status 2025-11-10 13:18:16 -05:00
Zhe Fang
0d051669fc chores: add import and export for lyrics window status 2025-11-10 13:02:13 -05:00
Zhe Fang
a19a97345c chores: bump version code 2025-11-09 17:12:23 -05:00
Zhe Fang
8f12c27d2a chores 2025-11-09 17:00:54 -05:00
Zhe Fang
92f2f20957 fix: lyrics window white space 2025-11-09 14:23:22 -05:00
Zhe Fang
272802214b chores: fix readme 2025-11-08 19:40:39 -05:00
Zhe Fang
7f8455b14e chores: update readme 2025-11-08 19:38:04 -05:00
Zhe Fang
ad421a5541 chores: update readme 2025-11-08 19:33:23 -05:00
Zhe Fang
1eb1d2d72b feat: track stop; chores: ui/ux adjustments, bump version code. 2025-11-08 11:41:59 -05:00
Zhe Fang
252b7e4b25 chores: bump version code 2025-11-08 08:45:27 -05:00
Zhe Fang
bebcfa7819 fix: thread access issue related to ISettingsService 2025-11-08 08:21:31 -05:00
Zhe Fang
073ddfcaee fix: player fail to pass thumbnails 2025-11-07 21:06:37 -05:00
Zhe Fang
1775d947f9 chores: bump version code 2025-11-07 16:26:05 -05:00
Zhe Fang
a5d1831717 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-11-07 15:51:23 -05:00
Zhe Fang
d4a924accf feat: support presistent play queue and index, add settings item: auto open music gallery and auto play music; fix: auto scroll to playing track in play queue; 2025-11-07 15:51:21 -05:00
Zhe Fang
5d65314522 更新 README.md 2025-11-07 07:00:25 -05:00
Zhe Fang
0684069e52 更新 README.CN.md 2025-11-07 06:59:24 -05:00
Zhe Fang
fea617ff98 chores: edit readme 2025-11-06 17:17:44 -05:00
Zhe Fang
4b33776340 chores: update readme 2025-11-06 17:12:56 -05:00
Zhe Fang
ea73d7ed3b chores: add all deps link in readme 2025-11-06 14:23:40 -05:00
74 changed files with 2776 additions and 940 deletions

22
.github/ISSUE_TEMPLATE/bug-反馈.md vendored Normal file
View File

@@ -0,0 +1,22 @@
---
name: Bug 反馈
about: 帮助我们改进 BetterLyrics
title: ''
labels: ''
assignees: ''
---
**描述问题**
**屏幕截图**
**BetterLyrics 版本**
v1.0.XX.0
**日志**
将日志以单文件形式上传到此处。你可以在此处找到日志文件 `%LocalAppData%\Packages\37412.BetterLyrics_rd1g0rsrrtxw8\LocalCache\logs`
**附加信息**

21
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,21 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
**Screenshots**
**BetterLyrics Version**
v1.0.XX.0
**Logs**
Upload logs as a file here. You can find logs at `%LocalAppData%\Packages\37412.BetterLyrics_rd1g0rsrrtxw8\LocalCache\logs`
**Additional context**

View File

@@ -0,0 +1,13 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Describe the solution you'd like**
**Additional context**

13
.github/ISSUE_TEMPLATE/功能建议.md vendored Normal file
View File

@@ -0,0 +1,13 @@
---
name: 功能建议
about: 提供宝贵的功能建议
title: ''
labels: ''
assignees: ''
---
**描述你所构想的解决方案**
**附加信息**

View File

@@ -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>

View File

@@ -12,7 +12,7 @@
<Identity
Name="37412.BetterLyrics"
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
Version="1.0.96.0" />
Version="1.0.112.0" />
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

View File

@@ -68,6 +68,7 @@
<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" />

View File

@@ -74,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()
@@ -116,6 +120,7 @@ namespace BetterLyrics.WinUI3
.AddSingleton<LyricsPageViewModel>()
.AddSingleton<MusicGalleryViewModel>()
.AddSingleton<LyricsRendererViewModel>()
.AddSingleton<AboutControlViewModel>()
.BuildServiceProvider()
);
}

View File

@@ -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" />
@@ -317,6 +318,11 @@
<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>

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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>

View File

@@ -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>();
}
}
}

View File

@@ -55,7 +55,15 @@
Unloaded="AutoStartupToggleSwitch_Unloaded" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7E8;}">
<dev:SettingsCard x:Uid="SettingsPageAutoOpenMusicGalleryWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8F1;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoOpen, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAutoPlayWhenOpenMusicGalleryWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE768;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoPlay, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE711;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" />
</dev:SettingsCard>

View File

@@ -19,7 +19,7 @@
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageTheme">
<dev:SettingsCard x:Uid="SettingsPageTheme" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE790;}">
<ComboBox x:Name="ThemeComboBox" SelectedIndex="{x:Bind LyricsBackgroundSettings.LyricsBackgroundTheme, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageFollowSystem" />
<ComboBoxItem x:Uid="SettingsPageLight" />
@@ -27,7 +27,11 @@
</ComboBox>
</dev:SettingsCard>
<dev:SettingsExpander x:Uid="SettingsPagePureLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
<dev:SettingsExpander
x:Uid="SettingsPagePureLayer"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEB42;}"
IsExpanded="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
@@ -43,7 +47,11 @@
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander x:Uid="SettingsPageAlbumArtLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
<dev:SettingsExpander
x:Uid="SettingsPageAlbumArtLayer"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE93C;}"
IsExpanded="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
@@ -84,7 +92,11 @@
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander x:Uid="SettingsPageFluidLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
<dev:SettingsExpander
x:Uid="SettingsPageFluidLayer"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEDA8;}"
IsExpanded="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
@@ -107,7 +119,11 @@
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander x:Uid="SettingsPageSnowFlakeLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=OneWay}">
<dev:SettingsExpander
x:Uid="SettingsPageSnowFlakeLayer"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEDAD;}"
IsExpanded="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageAmount">
@@ -120,7 +136,7 @@
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageSpectrumLayer">
<dev:SettingsCard x:Uid="SettingsPageSpectrumLayer" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE659;}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=TwoWay}" />
</dev:SettingsCard>

View File

@@ -3,6 +3,7 @@
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"
@@ -28,18 +29,40 @@
RelativePanel.AlignLeftWithPanel="True"
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<Button x:Uid="SettingsPageCreateFromCurrent" Command="{x:Bind ViewModel.CopyLyricsWindowStatusCommand}" />
<Button x:Uid="SettingsPageCreateFromTemplates">
<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=&#xE710;}" 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=&#xE74B;}"
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"
@@ -71,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"

View File

@@ -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"));
}
}
}
}
}

View File

@@ -253,9 +253,8 @@
<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"
@@ -326,8 +325,8 @@
<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"

View File

@@ -106,7 +106,7 @@ namespace BetterLyrics.WinUI3.Controls
}
else
{
DevWinUI.Growl.Success(_resourceService.GetLocalizedString("SettingsPageShortcutRegFailInfo"));
DevWinUI.Growl.Error(_resourceService.GetLocalizedString("SettingsPageShortcutRegFailInfo"));
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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,

View File

@@ -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,

View 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];
}
}
}

View File

@@ -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;
@@ -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}"));
}
}

View File

@@ -315,15 +315,27 @@ namespace BetterLyrics.WinUI3.Helper
// data URL直接解析
return DataUrlToByteArray(url);
}
else if (Uri.TryCreate(url, UriKind.Absolute, out var uri) &&
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
else if (Uri.TryCreate(url, UriKind.Absolute, out var uri))
{
// 普通网络图片,下载
return await DownloadImageAsByteArrayAsync(url);
if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
{
// 普通网络图片,下载
return await DownloadImageAsByteArrayAsync(url);
}
else if (uri.Scheme == Uri.UriSchemeFile)
{
// 本地文件,读取
var file = await StorageFile.GetFileFromPathAsync(uri.LocalPath);
var buffer = await FileIO.ReadBufferAsync(file);
return buffer.ToArray();
}
else
{
return null;
}
}
else
{
// 其他类型暂不支持
return null;
}
}

View File

@@ -74,4 +74,4 @@ namespace BetterLyrics.WinUI3.Helper
}
}
}
}
}

View File

@@ -38,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");
@@ -56,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);

View File

@@ -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;
}
}
}

View 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;
}
}
}

View File

@@ -67,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);
@@ -104,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());
@@ -111,7 +122,8 @@ namespace BetterLyrics.WinUI3.Helper
var lyricsWindow = (LyricsWindow)window;
lyricsWindow.ViewModel.InitShortcuts();
lyricsWindow.ViewModel.InitFgWindowWatcher();
lyricsWindow.ViewModel.RefreshLyricsWindowStatus();
_mediaSessionsService.InitPlaybackShortcuts();
}
}
else

View File

@@ -73,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));
@@ -135,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
@@ -155,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(),
@@ -191,7 +222,6 @@ namespace BetterLyrics.WinUI3.Models
EnvironmentSampleMode = WindowPixelSampleMode.WindowEdge,
LyricsStyleSettings = new()
{
OriginalLyricsFontSize = 20,
LyricsAlignmentType = TextAlignmentType.Center,
},
LyricsBackgroundSettings = new LyricsBackgroundSettings
@@ -203,7 +233,7 @@ namespace BetterLyrics.WinUI3.Models
public static LyricsWindowStatus DockedMode()
{
return new LyricsWindowStatus
var status = new LyricsWindowStatus
{
Name = _resourceService.GetLocalizedString("DockedMode"),
IsWorkArea = true,
@@ -218,7 +248,6 @@ namespace BetterLyrics.WinUI3.Models
LyricsStyleSettings = new LyricsStyleSettings
{
LyricsAlignmentType = TextAlignmentType.Center,
OriginalLyricsFontSize = 18,
},
LyricsBackgroundSettings = new LyricsBackgroundSettings
{
@@ -226,31 +255,26 @@ 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 = _resourceService.GetLocalizedString("FullscreenMode"),
WindowBounds = monitorBounds,
IsAlwaysOnTop = true,
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()

View File

@@ -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,
};
}
}

View File

@@ -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,
};
}
}

View File

@@ -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() { }
}

View File

@@ -10,6 +10,6 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
public interface ILiveStatesService
{
LiveStates LiveStates { get; set; }
void RefreshLyricsWindowStatus();
void InitLyricsWindowStatus();
}
}

View File

@@ -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,14 +127,6 @@ 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;
@@ -99,77 +136,19 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
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(_dispatcherQueue);
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();
}
);
}
}
}
}

View File

@@ -30,6 +30,8 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
void UpdateLyrics();
void UpdateTranslations();
void InitPlaybackShortcuts();
bool IsPlaying { get; }
SongInfo? SongInfo { get; }
TimeSpan Position { get; }

View File

@@ -115,7 +115,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
UpdateLyrics();
}
private void InitPlaybackShortcuts()
public void InitPlaybackShortcuts()
{
UpdatePlayOrPauseSongShortcut();
UpdatePreviousSongShortcut();
@@ -197,7 +197,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
return _settingsService.AppSettings.MediaSourceProvidersInfo.FirstOrDefault(s => s.Provider == id)?.IsEnabled ?? true;
}
private bool IsMediaSourceTimelineSyncEnabled(string id)
private bool IsMediaSourceTimelineSyncEnabled(string? id)
{
return _settingsService.AppSettings.MediaSourceProvidersInfo.FirstOrDefault(s => s.Provider == id)?.IsTimelineSyncEnabled ?? true;
}
@@ -306,7 +306,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
mediaProperties?.Title, mediaProperties?.Artist, mediaProperties?.AlbumTitle);
if (sessionId == Constants.PlayerID.LXMusic)
if (PlayerIdMatcher.IsLXMusic(sessionId))
{
StopSSE();
}
@@ -349,7 +349,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
mediaProperties?.Title, mediaProperties?.Artist, mediaProperties?.AlbumTitle);
if (sessionId == Constants.PlayerID.LXMusic)
if (PlayerIdMatcher.IsLXMusic(sessionId))
{
StartSSE();
}
@@ -358,7 +358,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
StopSSE();
}
if (sessionId == Constants.PlayerID.LXMusic && _lxMusicAlbumArtBytes != null)
if (PlayerIdMatcher.IsLXMusic(sessionId) && _lxMusicAlbumArtBytes != null)
{
_SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer();
}
@@ -519,7 +519,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
{
if (_cachedSongInfo?.PlayerId == Constants.PlayerID.LXMusic)
if (PlayerIdMatcher.IsLXMusic(_cachedSongInfo?.PlayerId))
{
var data = JsonSerializer.Deserialize(e.Message, Serialization.SourceGenerationContext.Default.JsonElement);
if (data.ValueKind == JsonValueKind.Number)
@@ -533,7 +533,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
_lxMusicDurationSeconds = data.GetDouble();
}
if (IsMediaSourceTimelineSyncEnabled(Constants.PlayerID.LXMusic))
if (IsMediaSourceTimelineSyncEnabled(_cachedSongInfo?.PlayerId))
{
TimelineChanged?.Invoke(this, new TimelineChangedEventArgs(TimeSpan.FromSeconds(_lxMusicPositionSeconds), TimeSpan.FromSeconds(_lxMusicDurationSeconds)));
}
@@ -547,7 +547,14 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{
_logger.LogInformation("LX Music Album Art URL: {url}", picUrl);
_lxMusicAlbumArtBytes = await ImageHelper.GetImageBytesFromUrlAsync(picUrl);
_SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer();
if (_lxMusicAlbumArtBytes != null)
{
_SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer();
}
else
{
_SMTCAlbumArtBuffer = null;
}
UpdateAlbumArt();
}
}

View File

@@ -51,6 +51,8 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
AppSettings.StarredPlaylists.CollectionChanged += AppSettings_CollectionChanged;
AppSettings.StarredPlaylists.ItemPropertyChanged += AppSettings_ItemPropertyChanged;
AppSettings.MusicGallerySettings.PlayQueuePaths.CollectionChanged += AppSettings_CollectionChanged;
AppSettings.Version = MetadataHelper.AppVersion;
EnsureMediaSourceProvidersInfo();

View File

@@ -177,7 +177,7 @@
<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">
@@ -186,6 +186,9 @@
<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>
@@ -213,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>
@@ -318,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>
@@ -367,7 +376,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<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">
@@ -427,22 +436,28 @@ 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">
@@ -466,6 +481,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<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>
@@ -500,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>
@@ -574,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>
@@ -634,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>
@@ -790,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>
@@ -865,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>
@@ -1192,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>
@@ -1235,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>

View File

@@ -177,7 +177,7 @@
<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">
@@ -186,6 +186,9 @@
<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>
@@ -213,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>
@@ -318,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>
@@ -353,7 +362,7 @@
<value>BetterLyrics へようこそ</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>プレイリストに追加します</value>
<value>プレイリストに追加</value>
</data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>リストの終わり</value>
@@ -367,7 +376,7 @@
<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">
@@ -416,7 +425,7 @@
<value>ファイルからのインポート</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>プレイリストを作成しま</value>
<value>プレイリストを作成しましょう</value>
</data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>すべてを再生します</value>
@@ -427,22 +436,28 @@
<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">
@@ -466,6 +481,9 @@
<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>
@@ -500,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>
@@ -574,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>
@@ -634,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>
@@ -790,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>
@@ -865,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>
@@ -1192,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>
@@ -1235,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>

View File

@@ -177,7 +177,7 @@
<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">
@@ -186,6 +186,9 @@
<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>
@@ -213,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>
@@ -318,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>
@@ -353,7 +362,7 @@
<value>Betterlyrics에 오신 것을 환영합니다</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>재생 목록에 추가하십시오</value>
<value>재생 목록에 추가</value>
</data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>목록의 끝</value>
@@ -367,7 +376,7 @@
<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">
@@ -416,7 +425,7 @@
<value>파일에서 가져오기</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>재생 목록을 만듭니다</value>
<value>재생목록을 만드세요</value>
</data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>모두 재생하십시오</value>
@@ -427,22 +436,28 @@
<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">
@@ -466,6 +481,9 @@
<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>
@@ -500,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>
@@ -574,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>
@@ -634,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>
@@ -790,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>
@@ -865,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>
@@ -1192,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>
@@ -1235,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>

View File

@@ -177,7 +177,7 @@
<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">
@@ -186,6 +186,9 @@
<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>
@@ -213,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>
@@ -318,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>
@@ -353,7 +362,7 @@
<value>欢迎使用 BetterLyrics</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>添加到歌单</value>
<value>添加到播放列表</value>
</data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>列表的结尾</value>
@@ -367,7 +376,7 @@
<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">
@@ -416,7 +425,7 @@
<value>从文件导入</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>创建歌单</value>
<value>创建播放列表</value>
</data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>播放全部</value>
@@ -427,22 +436,28 @@
<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">
@@ -466,6 +481,9 @@
<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>
@@ -500,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>
@@ -574,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>
@@ -634,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>
@@ -790,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>
@@ -865,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>
@@ -1192,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>
@@ -1235,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>

View File

@@ -177,7 +177,7 @@
<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">
@@ -186,6 +186,9 @@
<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>
@@ -213,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>
@@ -318,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>
@@ -353,7 +362,7 @@
<value>歡迎使用 BetterLyrics</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>添加到歌單</value>
<value>新增到播放清單</value>
</data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>列表的結尾</value>
@@ -367,7 +376,7 @@
<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">
@@ -416,7 +425,7 @@
<value>從檔案匯入</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>建立單</value>
<value>建立播放清單</value>
</data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>播放全部</value>
@@ -427,22 +436,28 @@
<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">
@@ -466,6 +481,9 @@
<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>
@@ -500,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>
@@ -574,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>
@@ -634,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>
@@ -790,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>
@@ -865,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>
@@ -1192,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>
@@ -1235,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>

View File

@@ -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"));
}
}
}

View File

@@ -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;

View File

@@ -193,7 +193,7 @@ 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;
_topMargin = _bottomMargin = _leftMargin = _middleMargin = _rightMargin = Math.Max(_canvasWidth, _canvasHeight) / 30.0;
}
if (_isSongInfoFontSizeChanged || _isSongTitleVisibilityChanged || _isSongArtistsVisibilityChanged)
@@ -201,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;
@@ -229,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);
@@ -260,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
{
@@ -287,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:
@@ -399,8 +399,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
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;
}
@@ -470,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
{
@@ -481,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)
{

View File

@@ -183,7 +183,7 @@ namespace BetterLyrics.WinUI3.ViewModels
{
var lyricsParser = new LyricsParser();
lyricsParser.Parse(
AppSettings.MappedSongSearchQueries.ToList(),
[MappedSongSearchQuery ?? new()],
MappedSongSearchQuery?.OriginalTitle ?? "",
MappedSongSearchQuery?.OriginalArtist ?? "",
MappedSongSearchQuery?.OriginalAlbum ?? "",

View File

@@ -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);
}
}
}

View File

@@ -189,11 +189,6 @@ namespace BetterLyrics.WinUI3
}
}
public void RefreshLyricsWindowStatus()
{
_liveStatesService.RefreshLyricsWindowStatus();
}
public void Receive(PropertyChangedMessage<List<string>> message)
{
if (message.Sender is GeneralSettings)

View File

@@ -38,16 +38,7 @@ namespace BetterLyrics.WinUI3.ViewModels
[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)
{

View File

@@ -71,12 +71,9 @@ namespace BetterLyrics.WinUI3.ViewModels
public partial int SelectedTracksTotalDuration { get; set; } = 0;
[ObservableProperty]
public partial ObservableCollection<PlayQueueItem> TrackPlayingQueue { get; set; } = [];
public partial ObservableCollection<PlayQueueItem> TrackPlayingQueue { get; set; }
public PlayQueueItem? PlayingQueueItem => TrackPlayingQueue.ElementAtOrDefault(PlayingSongIndex);
[ObservableProperty]
public partial PlaybackOrder PlaybackOrder { get; set; }
public PlayQueueItem? PlayingQueueItem => TrackPlayingQueue.ElementAtOrDefault(AppSettings.MusicGallerySettings.PlayQueueIndex);
[ObservableProperty]
public partial CommonSongProperty SongOrderType { get; set; } = CommonSongProperty.Title;
@@ -95,12 +92,6 @@ 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;
@@ -112,6 +103,9 @@ namespace BetterLyrics.WinUI3.ViewModels
_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();
@@ -119,14 +113,14 @@ namespace BetterLyrics.WinUI3.ViewModels
_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;
@@ -136,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)
@@ -155,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:
@@ -191,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:
@@ -425,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;
@@ -445,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();
}
}
@@ -474,16 +469,6 @@ namespace BetterLyrics.WinUI3.ViewModels
ApplySongOrderType();
}
partial void OnPlayingSongIndexChanged(int value)
{
DisplayedPlayingSongIndex = value + 1;
}
partial void OnPlaybackOrderChanged(PlaybackOrder value)
{
_settingsService.AppSettings.MusicGallerySettings.PlaybackOrder = value;
}
private void AddFileToStarredPlaylists(StorageFile file)
{
AppSettings.StarredPlaylists.Add(new SongsTabInfo
@@ -500,16 +485,10 @@ namespace BetterLyrics.WinUI3.ViewModels
[RelayCommand]
private async Task CreatePlaylistAsync()
{
var window = WindowHelper.GetWindowByWindowType<MusicGalleryWindow>();
if (window == null) return;
var picker = new Windows.Storage.Pickers.FileSavePicker();
picker.FileTypeChoices.Add("M3U", new List<string>() { ".m3u" });
var hwnd = WindowNative.GetWindowHandle(window);
InitializeWithWindow.Initialize(picker, hwnd);
var file = await picker.PickSaveFileAsync();
var file = await PickerHelper.PickSaveFileAsync<MusicGalleryWindow>(new Dictionary<string, IList<string>>()
{
{ "M3U", [".m3u"] }
});
if (file != null)
{
@@ -521,16 +500,7 @@ namespace BetterLyrics.WinUI3.ViewModels
[RelayCommand]
private async Task ImportPlaylistAsync()
{
var window = WindowHelper.GetWindowByWindowType<MusicGalleryWindow>();
if (window == null) return;
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".m3u");
var hwnd = WindowNative.GetWindowHandle(window);
InitializeWithWindow.Initialize(picker, hwnd);
var file = await picker.PickSingleFileAsync();
var file = await PickerHelper.PickSingleFileAsync<MusicGalleryWindow>([".m3u"]);
if (file != null)
{
@@ -538,5 +508,17 @@ namespace BetterLyrics.WinUI3.ViewModels
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);
}
}
}

View File

@@ -1,155 +1,24 @@
// 2025/6/23 by Zhe Fang
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Helper.BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services;
using BetterLyrics.WinUI3.Services.LastFMService;
using BetterLyrics.WinUI3.Services.LibWatcherService;
using BetterLyrics.WinUI3.Services.MediaSessionsService;
using BetterLyrics.WinUI3.Services.ResourceService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.TranslateService;
using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.WinUI;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Services.Store;
using Windows.Storage;
using WinRT.Interop;
namespace BetterLyrics.WinUI3.ViewModels
{
public partial class SettingsPageViewModel : BaseViewModel
{
private readonly ISettingsService _settingsService;
private readonly IMediaSessionsService _mediaSessionsService;
private readonly IResourceService _resourceService;
public string Version { get; set; } = MetadataHelper.AppVersion;
[ObservableProperty]
public partial AppSettings AppSettings { get; set; }
[ObservableProperty]
[NotifyPropertyChangedRecipients]
public partial bool IsDebugOverlayEnabled { get; set; } = false;
[ObservableProperty]
public partial object NavViewSelectedItemTag { get; set; } = "App";
public SettingsPageViewModel(ISettingsService settingsService, IMediaSessionsService mediaSessionsService, IResourceService resourceService)
{
_settingsService = settingsService;
_mediaSessionsService = mediaSessionsService;
_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 static void RestartApp()
{
WindowHelper.RestartApp();
}
[RelayCommand]
private async Task ImportSettingsAsync()
{
var window = WindowHelper.GetWindowByWindowType<SettingsWindow>();
if (window == null) return;
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.FileTypeFilter.Add(".json");
var hwnd = WindowNative.GetWindowHandle(window);
InitializeWithWindow.Initialize(picker, hwnd);
var file = await picker.PickSingleFileAsync();
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 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();
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"));
}
public SettingsPageViewModel() { }
}
}

View File

@@ -70,13 +70,24 @@
<Grid>
<!-- Volumn: 0 -->
<FontIcon
x:Name="VolumeLevel0"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE74F;">
<FontIcon FontFamily="{StaticResource IconFontFamily}" Glyph="&#xE74F;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="Equal"
Value="0">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="1" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="NotEqual"
Value="0">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="0" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</FontIcon>
<!-- Volumn: 1-32 -->
@@ -87,6 +98,20 @@
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="GreaterThanOrEqual"
Value="1">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="1" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="LessThan"
Value="1">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="0" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</FontIcon>
<!-- Volumn: 33-65 -->
@@ -97,6 +122,20 @@
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="GreaterThanOrEqual"
Value="33">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="1" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="LessThan"
Value="33">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="0" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</FontIcon>
<!-- Volumn: 66-100 -->
@@ -107,6 +146,20 @@
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="GreaterThanOrEqual"
Value="66">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="1" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.Volume, Mode=OneWay}"
ComparisonCondition="LessThan"
Value="66">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="0" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</FontIcon>
</Grid>
@@ -343,65 +396,5 @@
<uc:SystemTray />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VolumeState">
<VisualState x:Name="Volume0">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
Comparison="Equal"
Value="{x:Bind ViewModel.Volume, Mode=OneWay}"
To="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="VolumeLevel0.Opacity" Value="1" />
<Setter Target="VolumeLevel1.Opacity" Value="0" />
<Setter Target="VolumeLevel2.Opacity" Value="0" />
<Setter Target="VolumeLevel3.Opacity" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Volume1">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
Comparison="LessThanOrEqual"
Value="{x:Bind ViewModel.Volume, Mode=OneWay}"
To="32" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="VolumeLevel0.Opacity" Value="0" />
<Setter Target="VolumeLevel1.Opacity" Value="1" />
<Setter Target="VolumeLevel2.Opacity" Value="0" />
<Setter Target="VolumeLevel3.Opacity" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Volume2">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
Comparison="LessThanOrEqual"
Value="{x:Bind ViewModel.Volume, Mode=OneWay}"
To="65" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="VolumeLevel0.Opacity" Value="0" />
<Setter Target="VolumeLevel1.Opacity" Value="0" />
<Setter Target="VolumeLevel2.Opacity" Value="1" />
<Setter Target="VolumeLevel3.Opacity" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Volume3">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
Comparison="LessThanOrEqual"
Value="{x:Bind ViewModel.Volume, Mode=OneWay}"
To="100" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="VolumeLevel0.Opacity" Value="0" />
<Setter Target="VolumeLevel1.Opacity" Value="0" />
<Setter Target="VolumeLevel2.Opacity" Value="0" />
<Setter Target="VolumeLevel3.Opacity" Value="1" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</Page>

View File

@@ -18,7 +18,7 @@
Width="1"
Height="1"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
VerticalAlignment="Bottom" />
<local:LyricsPage />
@@ -56,14 +56,20 @@
</ToolTipService.ToolTip>
</Button>
<!-- Settings -->
<Button
x:Name="SettingsWindowButton"
Click="SettingsWindowButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE713;}"
Style="{StaticResource TitleBarButtonStyle}" />
Style="{StaticResource TitleBarButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="HostWindowSettingsButtonToolTip" />
</ToolTipService.ToolTip>
</Button>
<!-- Lyrics window switcher -->
<Button Click="LyricsWindowSwitchButton_Click" Style="{StaticResource TitleBarButtonStyle}">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"

View File

@@ -87,7 +87,7 @@ namespace BetterLyrics.WinUI3.Views
{
if (_liveStatesService.LiveStates.IsLyricsWindowStatusRefreshing)
{
//return;
return;
}
if (args.DidPositionChange || args.DidSizeChange)

View File

@@ -15,6 +15,7 @@
xmlns:models="using:BetterLyrics.WinUI3.Models"
xmlns:muxm="using:Microsoft.UI.Xaml.Media"
xmlns:ui="using:CommunityToolkit.WinUI"
Loaded="Page_Loaded"
Unloaded="Page_Unloaded"
mc:Ignorable="d">
<Page.Resources>
@@ -25,15 +26,16 @@
</Page.Resources>
<Grid>
<Grid>
<Grid Padding="12,0,12,0" ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
x:Name="SongViewer"
Grid.Column="0"
Padding="12">
<Grid x:Name="SongViewer" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.Tag>
<Flyout
x:Name="SongFileInfoFlyout"
@@ -170,7 +172,7 @@
</Flyout>
</Grid.Tag>
<StackPanel Spacing="6">
<StackPanel Grid.Row="0" Spacing="6">
<Grid VerticalAlignment="Top">
<Grid.ColumnDefinitions>
@@ -181,10 +183,16 @@
<Button
x:Name="PlaylistButton"
Grid.Column="0"
Content="{ui:FontIcon FontSize=16,
FontFamily={StaticResource IconFontFamily},
Glyph=&#xE728;}"
Style="{StaticResource GhostButtonStyle}">
<Button.Content>
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE728;" />
<TextBlock x:Uid="MusicGalleryPagePlaylist" />
</StackPanel>
</Button.Content>
<Button.Flyout>
<Flyout FlyoutPresenterStyle="{StaticResource FlyoutGhostStyle}">
<Grid>
@@ -290,6 +298,12 @@
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource GhostButtonStyle}"
Visibility="{x:Bind IsClosable, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<ToolTipService.ToolTip>
<Grid>
<TextBlock x:Uid="MusicGalleryPageAddToCustomList" Visibility="{x:Bind IsStarred, Converter={StaticResource BoolNegationToVisibilityConverter}, Mode=OneWay}" />
<TextBlock x:Uid="MusicGalleryPageRemoveFromCustomList" Visibility="{x:Bind IsStarred, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</Grid>
</ToolTipService.ToolTip>
<Button.Content>
<Grid>
<FontIcon
@@ -352,6 +366,7 @@
<AutoSuggestBox
x:Name="SongSearchBox"
x:Uid="MusicGalleryPageSongSearchBox"
Margin="0,-8,0,0"
HorizontalAlignment="Stretch"
QueryIcon="Find"
Text="{x:Bind ViewModel.SongSearchQuery, Mode=TwoWay}" />
@@ -405,7 +420,7 @@
</StackPanel>
<SemanticZoom Margin="0,120,0,0">
<SemanticZoom Grid.Row="1">
<SemanticZoom.ZoomedInView>
<ListView
x:Name="SongListView"
@@ -450,7 +465,10 @@
</ListView.ContextFlyout>
<ListView.ItemTemplate>
<DataTemplate x:DataType="atl:Track">
<Grid Padding="12" ColumnSpacing="12" DoubleTapped="SongListViewItem_DoubleTapped">
<Grid
Padding="12"
ColumnSpacing="12"
DoubleTapped="SongListViewItem_DoubleTapped">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
@@ -561,7 +579,7 @@
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
<Grid Margin="0,120,0,0" Visibility="{x:Bind ViewModel.IsLocalMediaNotFound, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid Grid.Row="1" Visibility="{x:Bind ViewModel.IsLocalMediaNotFound, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
@@ -576,38 +594,140 @@
</Grid>
<Grid
x:Name="PlayQueue"
Grid.Column="1"
Margin="0,0,12,0">
<Grid x:Name="PlayQueue" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Margin="0,10,0,0" Spacing="6">
<Grid Margin="0,6,0,0" VerticalAlignment="Top">
<TextBlock x:Uid="MusicGalleryPagePlayingQueue" Style="{StaticResource BodyStrongTextBlockStyle}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.DisplayedPlayingSongIndex, Mode=OneWay}" />
<StackPanel Grid.Row="0" Spacing="6">
<Grid ColumnSpacing="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
x:Uid="MusicGalleryPagePlayingQueue"
Grid.Column="0"
VerticalAlignment="Center"
Style="{StaticResource BodyStrongTextBlockStyle}" />
<StackPanel
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex, Mode=OneWay, Converter={StaticResource IndexToDisplayConverter}}" />
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="/" />
<TextBlock Text="{x:Bind ViewModel.TrackPlayingQueue.Count, Mode=OneWay}" />
</StackPanel>
<!-- Stop media session -->
<Button
Grid.Column="2"
HorizontalAlignment="Right"
Command="{x:Bind ViewModel.StopTrackCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=16,
Glyph=&#xE71A;}"
Style="{StaticResource GhostButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="MusicGalleryPageStopTrack" />
</ToolTipService.ToolTip>
</Button>
<!-- Playback order -->
<Button
Grid.Column="3"
HorizontalAlignment="Right"
Command="{x:Bind ViewModel.SwitchPlaybackOrderCommand}"
Style="{StaticResource GhostButtonStyle}">
<ToolTipService.ToolTip>
<ToolTip>
<ToolTip.Content>
<Grid>
<TextBlock x:Name="PlaybackRepeatAllHint" x:Uid="MusicGalleryPageQueueLoop" />
<TextBlock x:Name="PlaybackRepeatOneHint" x:Uid="MusicGalleryPageSingleLoop" />
<TextBlock x:Name="PlaybackShuffleHint" x:Uid="MusicGalleryPageQueueRandom" />
</Grid>
</ToolTip.Content>
</ToolTip>
</ToolTipService.ToolTip>
<Button.Content>
<Grid>
<!-- Repeat all -->
<FontIcon
x:Name="PlaybackRepeatAll"
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE8EE;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
<!-- Repeat one -->
<FontIcon
x:Name="PlaybackRepeatOne"
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE8ED;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
<!-- Shuffle -->
<FontIcon
x:Name="PlaybackShuffle"
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE8B1;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
</Grid>
</Button.Content>
</Button>
<!-- Scroll to playing item -->
<Button
Grid.Column="4"
HorizontalAlignment="Right"
Click="ScrollToPlayingItemButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=16,
Glyph=&#xE7B7;}"
Style="{StaticResource GhostButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="MusicGalleryPageScrollToPlayingItem" />
</ToolTipService.ToolTip>
</Button>
<!-- Empty play queue -->
<Button
Grid.Column="5"
HorizontalAlignment="Right"
Click="EmptyPlayingQueueButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=16,
Glyph=&#xE738;}"
Style="{StaticResource GhostButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="MusicGalleryPageEmptyPlayingQueue" />
</ToolTipService.ToolTip>
</Button>
</Grid>
<StackPanel Orientation="Horizontal" Spacing="6">
<Button x:Uid="MusicGalleryPageEmptyPlayingQueue" Click="EmptyPlayingQueueButton_Click" />
<Button x:Uid="MusicGalleryPageScrollToPlayingItem" Click="ScrollToPlayingItemButton_Click" />
</StackPanel>
<controls:Segmented HorizontalAlignment="Stretch" SelectedIndex="{x:Bind ViewModel.PlaybackOrder, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}">
<controls:Segmented.Items>
<controls:SegmentedItem x:Uid="MusicGalleryPageQueueLoop" />
<controls:SegmentedItem x:Uid="MusicGalleryPageSingleLoop" />
<controls:SegmentedItem x:Uid="MusicGalleryPageQueueRandom" />
</controls:Segmented.Items>
</controls:Segmented>
</StackPanel>
<ListView
x:Name="PlayingQueueListView"
Margin="0,136,0,0"
Grid.Row="1"
ItemsSource="{x:Bind ViewModel.TrackPlayingQueue, Mode=OneWay}"
SelectedIndex="{x:Bind ViewModel.PlayingSongIndex, Mode=TwoWay}">
SelectedIndex="{x:Bind ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Padding="0,6">
@@ -637,7 +757,7 @@
</ListView.ItemTemplate>
</ListView>
<Grid Margin="0,136,0,0">
<Grid Grid.Row="1">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.TrackPlayingQueue.Count, Mode=OneWay}"
@@ -692,5 +812,57 @@
dev:Growl.GrowlParent="True" />
</ScrollViewer>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PlaybackOrderState">
<VisualState x:Name="RepeatAll">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
Comparison="Equal"
Value="{x:Bind ViewModel.AppSettings.MusicGallerySettings.PlaybackOrder, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
To="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="PlaybackRepeatAll.Opacity" Value="1" />
<Setter Target="PlaybackRepeatOne.Opacity" Value="0" />
<Setter Target="PlaybackShuffle.Opacity" Value="0" />
<Setter Target="PlaybackRepeatAllHint.Visibility" Value="Visible" />
<Setter Target="PlaybackRepeatOneHint.Visibility" Value="Collapsed" />
<Setter Target="PlaybackShuffleHint.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="RepeatOne">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
Comparison="Equal"
Value="{x:Bind ViewModel.AppSettings.MusicGallerySettings.PlaybackOrder, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
To="1" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="PlaybackRepeatAll.Opacity" Value="0" />
<Setter Target="PlaybackRepeatOne.Opacity" Value="1" />
<Setter Target="PlaybackShuffle.Opacity" Value="0" />
<Setter Target="PlaybackRepeatAllHint.Visibility" Value="Collapsed" />
<Setter Target="PlaybackRepeatOneHint.Visibility" Value="Visible" />
<Setter Target="PlaybackShuffleHint.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Shuffle">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
Comparison="Equal"
Value="{x:Bind ViewModel.AppSettings.MusicGallerySettings.PlaybackOrder, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
To="2" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="PlaybackRepeatAll.Opacity" Value="0" />
<Setter Target="PlaybackRepeatOne.Opacity" Value="0" />
<Setter Target="PlaybackShuffle.Opacity" Value="1" />
<Setter Target="PlaybackRepeatAllHint.Visibility" Value="Collapsed" />
<Setter Target="PlaybackRepeatOneHint.Visibility" Value="Collapsed" />
<Setter Target="PlaybackShuffleHint.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</Page>

View File

@@ -2,6 +2,7 @@ using ATL;
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services.ResourceService;
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
@@ -40,6 +41,22 @@ namespace BetterLyrics.WinUI3.Views
{
InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<MusicGalleryViewModel>();
ViewModel.AppSettings.MusicGallerySettings.PropertyChanged += MusicGallerySettings_PropertyChanged;
}
private void ScrollToPlayingItem()
{
if (ViewModel.PlayingQueueItem == null) return;
if (PlayingQueueListView == null) return;
PlayingQueueListView.ScrollIntoView(ViewModel.PlayingQueueItem);
}
private void MusicGallerySettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(MusicGallerySettings.PlayQueueIndex))
{
ScrollToPlayingItem();
}
}
private async void SongPathHyperlinkButton_Click(object sender, RoutedEventArgs e)
@@ -47,27 +64,26 @@ namespace BetterLyrics.WinUI3.Views
await LauncherHelper.SelectAndShowFile(((Track)((HyperlinkButton)sender).DataContext).Path);
}
private void PlayingQueueListVireItemGrid_Tapped(object sender, TappedRoutedEventArgs e)
private async void PlayingQueueListVireItemGrid_Tapped(object sender, TappedRoutedEventArgs e)
{
var item = (PlayQueueItem)((FrameworkElement)sender).DataContext;
ViewModel.PlayTrack(item);
await ViewModel.PlayTrackAsync(item);
PlayingQueueListView.ScrollIntoView(item);
}
private void EmptyPlayingQueueButton_Click(object sender, RoutedEventArgs e)
private async void EmptyPlayingQueueButton_Click(object sender, RoutedEventArgs e)
{
ViewModel.TrackPlayingQueue.Clear();
ViewModel.PlayingSongIndex = -1;
ViewModel.PlayTrackAt(ViewModel.PlayingSongIndex);
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = -1;
await ViewModel.PlayTrackAtAsync(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
private void ScrollToPlayingItemButton_Click(object sender, RoutedEventArgs e)
{
if (ViewModel.PlayingQueueItem == null) return;
PlayingQueueListView.ScrollIntoView(ViewModel.PlayingQueueItem);
ScrollToPlayingItem();
}
private void RemoveFromPlayingQueueButton_Click(object sender, RoutedEventArgs e)
private async void RemoveFromPlayingQueueButton_Click(object sender, RoutedEventArgs e)
{
bool playNext = false;
var item = (PlayQueueItem)((FrameworkElement)sender).DataContext;
@@ -87,30 +103,30 @@ namespace BetterLyrics.WinUI3.Views
{
index = ViewModel.TrackPlayingQueue.Count - 1;
}
ViewModel.PlayingSongIndex = index;
ViewModel.PlayTrackAt(ViewModel.PlayingSongIndex);
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = index;
await ViewModel.PlayTrackAtAsync(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
}
private void AddSongToQueueNextMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
private async void AddSongToQueueNextMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
bool startPlaying = ViewModel.TrackPlayingQueue.Count == 0;
ViewModel.TrackPlayingQueue.InsertRange(ViewModel.PlayingSongIndex + 1, SongListView.SelectedItems.Cast<Track>().Select(x => new PlayQueueItem(x)));
ViewModel.TrackPlayingQueue.InsertRange(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex + 1, SongListView.SelectedItems.Cast<Track>().Select(x => new PlayQueueItem(x)));
if (startPlaying)
{
ViewModel.PlayingSongIndex = ViewModel.PlayingSongIndex + 1;
ViewModel.PlayTrackAt(ViewModel.PlayingSongIndex);
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex + 1;
await ViewModel.PlayTrackAtAsync(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
}
private void AddSongToQueueEndMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
private async void AddSongToQueueEndMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
bool startPlaying = ViewModel.TrackPlayingQueue.Count == 0;
ViewModel.TrackPlayingQueue.AddRange(SongListView.SelectedItems.Cast<Track>().Select(x => new PlayQueueItem(x)));
if (startPlaying)
{
ViewModel.PlayingSongIndex = ViewModel.PlayingSongIndex + 1;
ViewModel.PlayTrackAt(ViewModel.PlayingSongIndex);
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex + 1;
await ViewModel.PlayTrackAtAsync(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
}
@@ -245,18 +261,23 @@ namespace BetterLyrics.WinUI3.Views
}
}
private void SongListViewItem_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
private async void SongListViewItem_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
var displayedTracks = SongListView.Items.Cast<Track>();
var track = (Track)((FrameworkElement)sender).DataContext;
// Play all the songs
ViewModel.TrackPlayingQueue.Clear();
ViewModel.PlayingSongIndex = -1;
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = -1;
ViewModel.TrackPlayingQueue.InsertRange(ViewModel.PlayingSongIndex + 1, displayedTracks.Select(x => new PlayQueueItem(x)));
ViewModel.PlayingSongIndex = displayedTracks.ToList().IndexOf(track);
ViewModel.PlayTrackAt(ViewModel.PlayingSongIndex);
ViewModel.TrackPlayingQueue.InsertRange(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex + 1, displayedTracks.Select(x => new PlayQueueItem(x)));
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = displayedTracks.ToList().IndexOf(track);
await ViewModel.PlayTrackAtAsync(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
ScrollToPlayingItem();
}
}
}

View File

@@ -24,14 +24,22 @@
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE90B;}"
Style="{StaticResource TitleBarButtonStyle}" />
Style="{StaticResource TitleBarButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="SystemTrayLyrics" />
</ToolTipService.ToolTip>
</Button>
<Button
x:Name="SettingsWindowButton"
Click="SettingsWindowButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE713;}"
Style="{StaticResource TitleBarButtonStyle}" />
Style="{StaticResource TitleBarButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="HostWindowSettingsButtonToolTip" />
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</Grid>

View File

@@ -88,187 +88,7 @@
<!-- About -->
<controls:Case Value="About">
<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 ViewModel.Version, Mode=OneWay}" />
</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>
<uc:AboutControl />
</controls:Case>
</controls:SwitchPresenter>

View File

@@ -23,7 +23,11 @@
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE90B;}"
Style="{StaticResource TitleBarButtonStyle}" />
Style="{StaticResource TitleBarButtonStyle}">
<ToolTipService.ToolTip>
<TextBlock x:Uid="SystemTrayLyrics" />
</ToolTipService.ToolTip>
</Button>
<Button
Click="MusicGalleryButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},

View File

@@ -1,63 +0,0 @@
# Welcome to BetterLyrics
### 🤔 Where can I find the logs?
`%LocalAppData%\Packages\37412.BetterLyrics_rd1g0rsrrtxw8\LocalCache\logs`
### 🤔 Where can I find the lyrics cache?
`%LocalAppData%\Packages\37412.BetterLyrics_rd1g0rsrrtxw8\LocalCache\lyrics`
### 🤔 I cannot see any buttons.
By default, the top command bar and the bottom command bar (playback control panel) are automatically hidden when your mouse is out of those areas. Just hover your mouse back to those areas to show them again.
### 🤔 No music is playing now. What should I do?
Some of the players need additional config, check out **Multiple Music Players Supported** under [this](https://github.com/jayfunc/BetterLyrics/blob/dev/README.md#-highlighted-features) section.
### 🤔 How to add more modes?
If this is the first time that you use this app, only the standard mode was initially added for you. To add more modes, follow the steps below:
Settings -> Lyrics window manager -> Create from templates -> Fullscreen mode
![](PixPin_2025-10-24_18-06-32.gif)
### 🤔 How to switch modes?
You can switch modes by pressing the default shortcuts `Ctrl + Alt + S` and then choosing one of the modes displayed on your screen. (Press `Escape` to close the choosing window)
![](PixPin_2025-10-24_18-07-45.gif)
### 🤔 How to move and resize the window? I cannot touch the window.
If you are not able to select and move the window, make sure that you have both:
- Disabled `Click-through` in `Advanced settings` in `Lyrics window manager`.
- Selected **_other than_** `None` in `Draggable area` in `General` in `Lyrics window manager`.
> Click-through ensure that all mouse activity will go through a pinned widget and straight to the underlying game or application - [Microsoft Learn](https://learn.microsoft.com/en-us/gaming/game-bar/guide/click-through)
Alternatively, you can skip the steps above and directly adjust window position and size in `General` in `Lyrics window manager`. See the clip below.
![](PixPin_2025-10-25_09-08-47.gif)
### 🤔 How to install ".msixbundle" package? (for test package only)
[See this doc](https://github.com/jayfunc/BetterLyrics/blob/dev/Sideloadly/index.md)
### 🤔 Lyrics are moving back and forth constantly.
![](Snipaste_2025-08-22_14-59-53.png)
Go to Settings > Playback sources > Disable "Lyrics timeline sync" or increase "Lyrics timeline sync threshold"
### 🤔 Wrong lyrics are shown.
![](image.png)
Open the search panel to manually search for the correct lyrics.
### 🤔 Bottom command bar (playback control panel) is hidden?
By default, the playback control panel at the bottom is hidden automatically when your mouse is out of that area.
![](Snipaste_2025-08-22_14-50-16.png)
But when the window size is too small to place that panel, only hovering over the bottom of the lyrics window and clicking on the white line can the playback control panel be displayed, or just right-click on the inner side of the window.

View File

@@ -75,7 +75,7 @@ BetterLyrics
- 🎶 **支持众多音乐播放器**
- 点击 [此处](https://github.com/jayfunc/BetterLyrics/wiki/Known-supported-music-players-(configuration-guidance)) 查看详细信息
- 点击 [此处](https://github.com/jayfunc/BetterLyrics/wiki/%5BZH%5D-%E5%B7%B2%E7%9F%A5%E6%94%AF%E6%8C%81%E7%9A%84%E9%9F%B3%E4%B9%90%E6%92%AD%E6%94%BE%E5%99%A8%EF%BC%88%E9%85%8D%E7%BD%AE%E6%8C%87%E5%8D%97%EF%BC%89) 查看详细信息
- 🪟 **多种显示模式**
- **标准模式**
@@ -89,7 +89,7 @@ BetterLyrics
- 🧠 **智能化行为**
- 根据歌曲播放状态自动显隐歌词窗口
## 屏幕截图
## 🖼️ 屏幕截图
![](Screenshots/fs2.png)
![](Screenshots/std.png)
@@ -104,11 +104,11 @@ BetterLyrics
![](Screenshots/PixPin_2025-10-24_18-13-44.gif)
![](Screenshots/PixPin_2025-10-24_18-17-17.gif)
## 演示
## 📹 演示
在 [哔哩哔哩](https://www.bilibili.com/video/BV1QRstz1EGt/) 上观看于 2025 年 10 月 21 日上传的演示视频。
## 即刻体验
## 🧪 即刻体验
<a href="https://apps.microsoft.com/detail/9P1WCD1P597R?referrer=appbadge&mode=direct">
<img src="https://get.microsoft.com/images/zh-cn%20dark.svg" width="200"/>
@@ -116,14 +116,33 @@ BetterLyrics
**无限期**免费试用版和付费版**无任何区别**
如果喜欢该软件,请考虑 [捐赠](#捐赠) 或在 **Microsoft Store** 🧧 购买, 感谢您的支持! 🥰
如果喜欢该软件,请考虑 [捐赠](#-捐赠) 或在 **Microsoft Store** 购买, 感谢您的支持! 🥰
无法从 Microsoft Store 下载?点按 [此处](https://github.com/jayfunc/BetterLyrics/wiki/Alternative-way-to-download-and-install) 查看其他下载安装方式。
无法从 Microsoft Store 下载?点按 [此处](https://github.com/jayfunc/BetterLyrics/wiki/%5BZH%5D-%E5%85%B6%E4%BB%96%E4%B8%8B%E8%BD%BD%E5%92%8C%E5%AE%89%E8%A3%85%E6%96%B9%E5%BC%8F) 查看其他下载安装方式。
## 构建
## 🏗️ 构建
在构建之前确保替换文件 `BetterLyrics\BetterLyrics.WinUI3\BetterLyrics.WinUI3\Constants\LastFMTemplate``BetterLyrics\BetterLyrics.WinUI3\BetterLyrics.WinUI3\Constants\LastFM.cs`
## 🤑 捐赠
如果你喜欢本应用,请考虑捐赠支持开发者。这将有助于本应用的长远发展。
通过以下途径捐赠:
- [PayPal](https://paypal.me/zhefangpay)
- [Buy Me a Coffee](https://buymeacoffee.com/founchoo)
- <details><summary>支付宝</summary>
![](Donate/Alipay.jpg)
</detais>
- <details><summary>微信</summary>
![](Donate/WeChatReward.png)
</details>
## 💖 感谢
部分功能及代码引用或修改自公开资料库,包括但不限于下述开源项目/包、教程等,在此一并感谢。
@@ -143,6 +162,8 @@ BetterLyrics
| [DevWinUI](https://github.com/ghost1372/DevWinUI) | 为 WinUI3 提供众多开箱即用的功能 |
| ... | ... |
点按 [此处](https://github.com/jayfunc/BetterLyrics/network/dependencies) 查看所有依赖。
### 教程、博客等
- [Stackoverflow - How to animate Margin property in WPF](https://stackoverflow.com/a/21542882/11048731)
@@ -167,39 +188,26 @@ BetterLyrics
现在访问 https://crowdin.com/project/betterlyrics/invite?h=c9bfb28fce061484883c0891e7a26f9b2592556 即刻为本应用提供翻译,成为贡献者!
## 星标记录
## 星标记录
<div style="display: flex; justify-content: space-around; align-items: flex-start;">
<img src="https://api.star-history.com/svg?repos=jayfunc/BetterLyrics&type=Date)](https://www.star-history.com/#jayfunc/BetterLyrics&Date" width="100%" >
</div>
## 欢迎反馈问题、提交代码
## 🤗 欢迎反馈问题、提交代码
如果发现 Bug 请在 Issues 内提出,同时也欢迎任何想法、建议。
## 捐赠
如果你喜欢本应用,请考虑捐赠支持开发者。这将有助于本应用的长远发展。
通过以下途径捐赠:
- [PayPal](https://paypal.me/zhefangpay)
- [Buy Me a Coffee](https://buymeacoffee.com/founchoo)
- <details><summary>支付宝</summary>
![](Donate/Alipay.jpg)
</detais>
- <details><summary>微信</summary>
![](Donate/WeChatReward.png)
</details>
## ⚠️ 免责声明
本项目按“原样”提供,不提供任何形式的担保。
所有歌词、字体、图标及其他第三方资源均为其各自版权所有者的财产。
本项目作者不主张对这些资源的所有权。
本项目为非商业用途,不得用于侵犯任何权利。
用户有责任确保其使用符合适用的法律和许可协议。
用户有责任确保其使用符合适用的法律和许可协议。
## 💭 社交媒体分享
![BetterLyrics](https://socialify.git.ci/jayfunc/BetterLyrics/image?description=1&forks=1&issues=1&language=1&name=1&owner=1&pulls=1&stargazers=1&theme=Light)
![BetterLyrics](https://opengraph.githubassets.com/<any_hash_number>/jayfunc/BetterLyrics)

View File

@@ -81,7 +81,7 @@ Check out the article: [BetterLyrics An immersive and smooth lyrics display
- 🎶 **Multiple Music Players Supported**
- Check it out [here](https://github.com/jayfunc/BetterLyrics/wiki/Known-supported-music-players-(configuration-guidance)) for detailed info
- Check it out [here](https://github.com/jayfunc/BetterLyrics/wiki/%5BEN%5D-Known-supported-music-players-(configuration-guidance)) for detailed info
- 🪟 **Multiple Display Modes**
- **Standard Mode**
@@ -95,7 +95,7 @@ Check out the article: [BetterLyrics An immersive and smooth lyrics display
- 🧠 **Smart Behaviors**
- Auto hide when music paused
## Screenshots
## 🖼️ Screenshots
![](Screenshots/fs2.png)
![](Screenshots/std.png)
@@ -110,11 +110,11 @@ Check out the article: [BetterLyrics An immersive and smooth lyrics display
![](Screenshots/PixPin_2025-10-24_18-13-44.gif)
![](Screenshots/PixPin_2025-10-24_18-17-17.gif)
## Demonstration
## 📹 Demonstration
Watch our demo video (uploaded on 21 Oct 2025) on Bilibili [here](https://www.bilibili.com/video/BV1QRstz1EGt/).
## Try it now
## 🧪 Try it now
<a href="https://apps.microsoft.com/detail/9P1WCD1P597R?referrer=appbadge&mode=direct">
<img src="https://get.microsoft.com/images/en-us%20dark.svg" width="200"/>
@@ -122,13 +122,32 @@ Watch our demo video (uploaded on 21 Oct 2025) on Bilibili [here](https://www.bi
**Unlimited** free trail or purchase (there is **no difference** between free and paid version).
If you find it useful, please consider [donating](#donations) or purchasing 🧧 it in **Microsoft Store**, I'll appreciate it! 🥰
If you find it useful, please consider [donating](#-donations) or purchasing it in **Microsoft Store**, I'll appreciate it! 🥰
Having trouble downloading and installing from the MS Store? See the alternative way to install it [here](https://github.com/jayfunc/BetterLyrics/wiki/Alternative-way-to-download-and-install).
Having trouble downloading and installing from the MS Store? See the alternative way to install it [here](https://github.com/jayfunc/BetterLyrics/wiki/%5BEN%5D-Alternative-way-to-download-and-install).
## Build
## 🏗️ Build
Before you build, make sure that you have already replaced `BetterLyrics\BetterLyrics.WinUI3\BetterLyrics.WinUI3\Constants\LastFMTemplate` with `BetterLyrics\BetterLyrics.WinUI3\BetterLyrics.WinUI3\Constants\LastFM.cs`
Before you build, make sure that you have already replaced `BetterLyrics\BetterLyrics.WinUI3\BetterLyrics.WinUI3\Constants\LastFMTemplate` with `BetterLyrics\BetterLyrics.WinUI3\BetterLyrics.WinUI3\Constants\LastFM.cs`.
## 🤑 Donations
If you like this project, please consider supporting it by donating. Your support will help keep the project alive and encourage further development.
You can donate via:
- [PayPal](https://paypal.me/zhefangpay)
- [Buy Me a Coffee](https://buymeacoffee.com/founchoo)
- <details><summary>支付宝</summary>
![](Donate/Alipay.jpg)
</detais>
- <details><summary>微信</summary>
![](Donate/WeChatReward.png)
</details>
## 💖 Many thanks to
@@ -148,6 +167,8 @@ Some functions and code are referenced or modified from public repositories, inc
| [SpectrumVisualization](https://github.com/Johnwikix/SpectrumVisualization) | Audio visualization reference |
| [DevWinUI](https://github.com/ghost1372/DevWinUI) | Provide many out-of-the-box features for building WinUI 3 applications |
| ... | ... |
See all the dependencies [here](https://github.com/jayfunc/BetterLyrics/network/dependencies).
### Tutorials/Blogs/etc.
@@ -173,35 +194,16 @@ Cannot find your language? Or have better translations? Don't worry! Start trans
Visit https://crowdin.com/project/betterlyrics/invite?h=c9bfb28fce061484883c0891e7a26f9b2592556 to accept the invitation and become a valuable translator now!
## Star history
## Star history
<div style="display: flex; justify-content: space-around; align-items: flex-start;">
<img src="https://api.star-history.com/svg?repos=jayfunc/BetterLyrics&type=Date)](https://www.star-history.com/#jayfunc/BetterLyrics&Date" width="100%" >
</div>
## Any issues and PRs are welcome
## 🤗 Any issues and PRs are welcome
If you find a bug, please file it in issues, or if you have any ideas, feel free to share them here.
## Donations
If you like this project, please consider supporting it by donating. Your support will help keep the project alive and encourage further development.
You can donate via:
- [PayPal](https://paypal.me/zhefangpay)
- [Buy Me a Coffee](https://buymeacoffee.com/founchoo)
- <details><summary>支付宝</summary>
![](Donate/Alipay.jpg)
</detais>
- <details><summary>微信</summary>
![](Donate/WeChatReward.png)
</details>
## ⚠️ Disclaimer
This project is provided "as is" without warranty of any kind.
@@ -211,3 +213,9 @@ The author of this project does not claim ownership of such resources.
This project is non-commercial and should not be used to infringe any rights.
Users are responsible for ensuring their own use complies with applicable laws and licenses.
## 💭 Share it on social media
![BetterLyrics](https://socialify.git.ci/jayfunc/BetterLyrics/image?description=1&forks=1&issues=1&language=1&name=1&owner=1&pulls=1&stargazers=1&theme=Light)
![BetterLyrics](https://opengraph.githubassets.com/<any_hash_number>/jayfunc/BetterLyrics)

View File

@@ -0,0 +1,164 @@
{
"Name": "\u684C\u9762\u6A21\u5F0F\uFF08\u900F\u660E\uFF09",
"IsDefault": false,
"MonitorDeviceName": "\\\\.\\DISPLAY1",
"IsWorkArea": false,
"IsBorderless": true,
"IsAlwaysOnTop": true,
"IsAlwaysOnTopPolling": true,
"IsShownInSwitchers": false,
"IsClickThrough": true,
"LyricsLayoutOrientation": 0,
"LyricsDisplayType": 1,
"WindowBounds": {
"X": 100,
"Y": 100,
"Width": 600,
"Height": 250,
"Left": 100,
"Top": 100,
"Right": 700,
"Bottom": 350,
"IsEmpty": false
},
"DockHeight": 64,
"DemoWindowBounds": {
"X": 10,
"Y": 10,
"Width": 60,
"Height": 25,
"Left": 10,
"Top": 10,
"Right": 70,
"Bottom": 35,
"IsEmpty": false
},
"MonitorBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DemoMonitorBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"DockPlacement": 0,
"LyricsStyleSettings": {
"IsDynamicLyricsFontSize": true,
"PhoneticLyricsFontSize": 12,
"OriginalLyricsFontSize": 24,
"TranslatedLyricsFontSize": 12,
"LyricsAlignmentType": 1,
"LyricsBgFontOpacity": 30,
"LyricsFontStrokeWidth": 0,
"LyricsCustomBgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomFgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomStrokeFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsBgFontColorType": 1,
"LyricsFgFontColorType": 1,
"LyricsStrokeFontColorType": 1,
"LyricsFontWeight": 7,
"LyricsLineSpacingFactor": 0.5,
"LyricsTranslationSeparator": "\n",
"LyricsCJKFontFamily": "Arial",
"LyricsWesternFontFamily": "Arial",
"IsActive": false
},
"LyricsEffectSettings": {
"LyricsBlurAmount": 5,
"IsLyricsLineFadeEnabled": true,
"IsLyricsGlowEffectEnabled": true,
"LyricsGlowEffectScope": 0,
"LyricsGlowEffectAmount": 8,
"IsLyricsShadowEnabled": false,
"LyricsShadowScope": 1,
"LyricsShadowAmount": 8,
"OriginalLyricsHighlightScope": 1,
"PhoneticLyricsHighlightAmount": 60,
"OriginalLyricsHighlightAmount": 100,
"TranslatedLyricsHighlightAmount": 60,
"IsLyricsFloatAnimationEnabled": true,
"LyricsFloatAmount": 1,
"LyricsScrollEasingType": 3,
"LyricsScrollDuration": 500,
"LyricsScrollTopDuration": 500,
"LyricsScrollBottomDuration": 500,
"LyricsScrollTopDelay": 0,
"LyricsScrollBottomDelay": 0,
"LyricsVerticalEdgeOpacity": 0,
"IsFanLyricsEnabled": false,
"FanLyricsAngle": 30,
"Is3DLyricsEnabled": false,
"Lyrics3DXAngle": 30,
"Lyrics3DYAngle": 0,
"Lyrics3DZAngle": 0,
"Lyrics3DDepth": 1000,
"IsActive": false
},
"LyricsBackgroundSettings": {
"LyricsBackgroundTheme": 2,
"IsPureColorOverlayEnabled": false,
"PureColorOverlayOpacity": 100,
"IsCoverOverlayEnabled": false,
"CoverOverlayBlurAmount": 100,
"CoverOverlayOpacity": 100,
"CoverOverlaySpeed": 50,
"CoverAcrylicEffectAmount": 0,
"IsFluidOverlayEnabled": false,
"FluidOverlayOpacity": 100,
"PaletteGeneratorType": 0,
"IsSpectrumOverlayEnabled": false,
"IsSnowFlakeOverlayEnabled": false,
"SnowFlakeOverlayAmount": 50,
"IsActive": false
},
"AlbumArtLayoutSettings": {
"SongInfoAlignmentType": 0,
"CoverImageRadius": 12,
"CoverImageShadowAmount": 12,
"IsAutoSongInfoFontSize": true,
"SongInfoFontSize": 18,
"ShowTitle": true,
"ShowArtists": true,
"AlbumArtSize": 64,
"AutoAlbumArtSize": true,
"IsActive": false
},
"IsAdaptToEnvironment": true,
"EnvironmentSampleMode": 3,
"AutoShowOrHideWindow": false,
"TitleBarArea": 1,
"WindowX": 100,
"WindowY": 100,
"WindowWidth": 600,
"WindowHeight": 250,
"IsActive": false
}

View File

@@ -0,0 +1,164 @@
{
"Name": "\u505C\u9760\u6A21\u5F0F",
"IsDefault": false,
"MonitorDeviceName": "\\\\.\\DISPLAY1",
"IsWorkArea": true,
"IsBorderless": true,
"IsAlwaysOnTop": true,
"IsAlwaysOnTopPolling": true,
"IsShownInSwitchers": false,
"IsClickThrough": false,
"LyricsLayoutOrientation": 0,
"LyricsDisplayType": 1,
"WindowBounds": {
"X": 0,
"Y": 1015,
"Width": 1920,
"Height": 65,
"Left": 0,
"Top": 1015,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DockHeight": 64,
"DemoWindowBounds": {
"X": 0,
"Y": 101.5,
"Width": 192,
"Height": 6.5,
"Left": 0,
"Top": 101.5,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"MonitorBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DemoMonitorBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"DockPlacement": 1,
"LyricsStyleSettings": {
"IsDynamicLyricsFontSize": true,
"PhoneticLyricsFontSize": 12,
"OriginalLyricsFontSize": 24,
"TranslatedLyricsFontSize": 12,
"LyricsAlignmentType": 1,
"LyricsBgFontOpacity": 30,
"LyricsFontStrokeWidth": 0,
"LyricsCustomBgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomFgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomStrokeFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsBgFontColorType": 1,
"LyricsFgFontColorType": 1,
"LyricsStrokeFontColorType": 1,
"LyricsFontWeight": 7,
"LyricsLineSpacingFactor": 0.5,
"LyricsTranslationSeparator": "\n",
"LyricsCJKFontFamily": "Arial",
"LyricsWesternFontFamily": "Arial",
"IsActive": false
},
"LyricsEffectSettings": {
"LyricsBlurAmount": 5,
"IsLyricsLineFadeEnabled": true,
"IsLyricsGlowEffectEnabled": true,
"LyricsGlowEffectScope": 0,
"LyricsGlowEffectAmount": 8,
"IsLyricsShadowEnabled": false,
"LyricsShadowScope": 1,
"LyricsShadowAmount": 8,
"OriginalLyricsHighlightScope": 1,
"PhoneticLyricsHighlightAmount": 60,
"OriginalLyricsHighlightAmount": 100,
"TranslatedLyricsHighlightAmount": 60,
"IsLyricsFloatAnimationEnabled": true,
"LyricsFloatAmount": 1,
"LyricsScrollEasingType": 3,
"LyricsScrollDuration": 500,
"LyricsScrollTopDuration": 500,
"LyricsScrollBottomDuration": 500,
"LyricsScrollTopDelay": 0,
"LyricsScrollBottomDelay": 0,
"LyricsVerticalEdgeOpacity": 0,
"IsFanLyricsEnabled": false,
"FanLyricsAngle": 30,
"Is3DLyricsEnabled": false,
"Lyrics3DXAngle": 30,
"Lyrics3DYAngle": 0,
"Lyrics3DZAngle": 0,
"Lyrics3DDepth": 1000,
"IsActive": false
},
"LyricsBackgroundSettings": {
"LyricsBackgroundTheme": 2,
"IsPureColorOverlayEnabled": true,
"PureColorOverlayOpacity": 100,
"IsCoverOverlayEnabled": false,
"CoverOverlayBlurAmount": 100,
"CoverOverlayOpacity": 100,
"CoverOverlaySpeed": 50,
"CoverAcrylicEffectAmount": 0,
"IsFluidOverlayEnabled": false,
"FluidOverlayOpacity": 100,
"PaletteGeneratorType": 0,
"IsSpectrumOverlayEnabled": false,
"IsSnowFlakeOverlayEnabled": false,
"SnowFlakeOverlayAmount": 50,
"IsActive": false
},
"AlbumArtLayoutSettings": {
"SongInfoAlignmentType": 0,
"CoverImageRadius": 12,
"CoverImageShadowAmount": 12,
"IsAutoSongInfoFontSize": true,
"SongInfoFontSize": 18,
"ShowTitle": true,
"ShowArtists": true,
"AlbumArtSize": 64,
"AutoAlbumArtSize": true,
"IsActive": false
},
"IsAdaptToEnvironment": true,
"EnvironmentSampleMode": 1,
"AutoShowOrHideWindow": false,
"TitleBarArea": 0,
"WindowX": 0,
"WindowY": 1015,
"WindowWidth": 1920,
"WindowHeight": 65,
"IsActive": false
}

View File

@@ -0,0 +1,164 @@
{
"Name": "\u505C\u9760\u6A21\u5F0F",
"IsDefault": false,
"MonitorDeviceName": "\\\\.\\DISPLAY1",
"IsWorkArea": true,
"IsBorderless": true,
"IsAlwaysOnTop": true,
"IsAlwaysOnTopPolling": true,
"IsShownInSwitchers": false,
"IsClickThrough": false,
"LyricsLayoutOrientation": 0,
"LyricsDisplayType": 1,
"WindowBounds": {
"X": 0,
"Y": -1,
"Width": 1920,
"Height": 65,
"Left": 0,
"Top": -1,
"Right": 1920,
"Bottom": 64,
"IsEmpty": false
},
"DockHeight": 64,
"DemoWindowBounds": {
"X": 0,
"Y": -0.10000000149011612,
"Width": 192,
"Height": 6.5,
"Left": 0,
"Top": -0.10000000149011612,
"Right": 192,
"Bottom": 6.400000095367432,
"IsEmpty": false
},
"MonitorBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DemoMonitorBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"DockPlacement": 0,
"LyricsStyleSettings": {
"IsDynamicLyricsFontSize": true,
"PhoneticLyricsFontSize": 12,
"OriginalLyricsFontSize": 24,
"TranslatedLyricsFontSize": 12,
"LyricsAlignmentType": 1,
"LyricsBgFontOpacity": 30,
"LyricsFontStrokeWidth": 0,
"LyricsCustomBgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomFgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomStrokeFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsBgFontColorType": 1,
"LyricsFgFontColorType": 1,
"LyricsStrokeFontColorType": 1,
"LyricsFontWeight": 7,
"LyricsLineSpacingFactor": 0.5,
"LyricsTranslationSeparator": "\n",
"LyricsCJKFontFamily": "Arial",
"LyricsWesternFontFamily": "Arial",
"IsActive": false
},
"LyricsEffectSettings": {
"LyricsBlurAmount": 5,
"IsLyricsLineFadeEnabled": true,
"IsLyricsGlowEffectEnabled": true,
"LyricsGlowEffectScope": 0,
"LyricsGlowEffectAmount": 8,
"IsLyricsShadowEnabled": false,
"LyricsShadowScope": 1,
"LyricsShadowAmount": 8,
"OriginalLyricsHighlightScope": 1,
"PhoneticLyricsHighlightAmount": 60,
"OriginalLyricsHighlightAmount": 100,
"TranslatedLyricsHighlightAmount": 60,
"IsLyricsFloatAnimationEnabled": true,
"LyricsFloatAmount": 1,
"LyricsScrollEasingType": 3,
"LyricsScrollDuration": 500,
"LyricsScrollTopDuration": 500,
"LyricsScrollBottomDuration": 500,
"LyricsScrollTopDelay": 0,
"LyricsScrollBottomDelay": 0,
"LyricsVerticalEdgeOpacity": 0,
"IsFanLyricsEnabled": false,
"FanLyricsAngle": 30,
"Is3DLyricsEnabled": false,
"Lyrics3DXAngle": 30,
"Lyrics3DYAngle": 0,
"Lyrics3DZAngle": 0,
"Lyrics3DDepth": 1000,
"IsActive": false
},
"LyricsBackgroundSettings": {
"LyricsBackgroundTheme": 2,
"IsPureColorOverlayEnabled": true,
"PureColorOverlayOpacity": 100,
"IsCoverOverlayEnabled": false,
"CoverOverlayBlurAmount": 100,
"CoverOverlayOpacity": 100,
"CoverOverlaySpeed": 50,
"CoverAcrylicEffectAmount": 0,
"IsFluidOverlayEnabled": false,
"FluidOverlayOpacity": 100,
"PaletteGeneratorType": 0,
"IsSpectrumOverlayEnabled": false,
"IsSnowFlakeOverlayEnabled": false,
"SnowFlakeOverlayAmount": 50,
"IsActive": false
},
"AlbumArtLayoutSettings": {
"SongInfoAlignmentType": 0,
"CoverImageRadius": 12,
"CoverImageShadowAmount": 12,
"IsAutoSongInfoFontSize": true,
"SongInfoFontSize": 18,
"ShowTitle": true,
"ShowArtists": true,
"AlbumArtSize": 64,
"AutoAlbumArtSize": true,
"IsActive": false
},
"IsAdaptToEnvironment": true,
"EnvironmentSampleMode": 0,
"AutoShowOrHideWindow": false,
"TitleBarArea": 0,
"WindowX": 0,
"WindowY": -1,
"WindowWidth": 1920,
"WindowHeight": 65,
"IsActive": false
}

View File

@@ -0,0 +1,164 @@
{
"Name": "\u5168\u5C4F\u6A21\u5F0F",
"IsDefault": false,
"MonitorDeviceName": "\\\\.\\DISPLAY1",
"IsWorkArea": false,
"IsBorderless": true,
"IsAlwaysOnTop": true,
"IsAlwaysOnTopPolling": false,
"IsShownInSwitchers": true,
"IsClickThrough": false,
"LyricsLayoutOrientation": 0,
"LyricsDisplayType": 2,
"WindowBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DockHeight": 64,
"DemoWindowBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"MonitorBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DemoMonitorBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"DockPlacement": 0,
"LyricsStyleSettings": {
"IsDynamicLyricsFontSize": true,
"PhoneticLyricsFontSize": 12,
"OriginalLyricsFontSize": 24,
"TranslatedLyricsFontSize": 12,
"LyricsAlignmentType": 1,
"LyricsBgFontOpacity": 30,
"LyricsFontStrokeWidth": 0,
"LyricsCustomBgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomFgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomStrokeFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsBgFontColorType": 1,
"LyricsFgFontColorType": 1,
"LyricsStrokeFontColorType": 1,
"LyricsFontWeight": 7,
"LyricsLineSpacingFactor": 0.5,
"LyricsTranslationSeparator": "\n",
"LyricsCJKFontFamily": "Arial",
"LyricsWesternFontFamily": "Arial",
"IsActive": false
},
"LyricsEffectSettings": {
"LyricsBlurAmount": 5,
"IsLyricsLineFadeEnabled": true,
"IsLyricsGlowEffectEnabled": true,
"LyricsGlowEffectScope": 0,
"LyricsGlowEffectAmount": 8,
"IsLyricsShadowEnabled": false,
"LyricsShadowScope": 1,
"LyricsShadowAmount": 8,
"OriginalLyricsHighlightScope": 1,
"PhoneticLyricsHighlightAmount": 60,
"OriginalLyricsHighlightAmount": 100,
"TranslatedLyricsHighlightAmount": 60,
"IsLyricsFloatAnimationEnabled": true,
"LyricsFloatAmount": 1,
"LyricsScrollEasingType": 3,
"LyricsScrollDuration": 500,
"LyricsScrollTopDuration": 500,
"LyricsScrollBottomDuration": 500,
"LyricsScrollTopDelay": 0,
"LyricsScrollBottomDelay": 0,
"LyricsVerticalEdgeOpacity": 0,
"IsFanLyricsEnabled": false,
"FanLyricsAngle": 30,
"Is3DLyricsEnabled": false,
"Lyrics3DXAngle": 30,
"Lyrics3DYAngle": 0,
"Lyrics3DZAngle": 0,
"Lyrics3DDepth": 1000,
"IsActive": false
},
"LyricsBackgroundSettings": {
"LyricsBackgroundTheme": 2,
"IsPureColorOverlayEnabled": false,
"PureColorOverlayOpacity": 100,
"IsCoverOverlayEnabled": false,
"CoverOverlayBlurAmount": 100,
"CoverOverlayOpacity": 100,
"CoverOverlaySpeed": 50,
"CoverAcrylicEffectAmount": 0,
"IsFluidOverlayEnabled": true,
"FluidOverlayOpacity": 100,
"PaletteGeneratorType": 0,
"IsSpectrumOverlayEnabled": false,
"IsSnowFlakeOverlayEnabled": false,
"SnowFlakeOverlayAmount": 50,
"IsActive": false
},
"AlbumArtLayoutSettings": {
"SongInfoAlignmentType": 0,
"CoverImageRadius": 12,
"CoverImageShadowAmount": 12,
"IsAutoSongInfoFontSize": true,
"SongInfoFontSize": 18,
"ShowTitle": true,
"ShowArtists": true,
"AlbumArtSize": 64,
"AutoAlbumArtSize": true,
"IsActive": false
},
"IsAdaptToEnvironment": false,
"EnvironmentSampleMode": 3,
"AutoShowOrHideWindow": false,
"TitleBarArea": 0,
"WindowX": 0,
"WindowY": 0,
"WindowWidth": 1920,
"WindowHeight": 1080,
"IsActive": false
}

View File

@@ -0,0 +1,164 @@
{
"Name": "\u5168\u5C4F\u6A21\u5F0F",
"IsDefault": false,
"MonitorDeviceName": "\\\\.\\DISPLAY1",
"IsWorkArea": false,
"IsBorderless": true,
"IsAlwaysOnTop": true,
"IsAlwaysOnTopPolling": false,
"IsShownInSwitchers": true,
"IsClickThrough": false,
"LyricsLayoutOrientation": 1,
"LyricsDisplayType": 2,
"WindowBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DockHeight": 64,
"DemoWindowBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"MonitorBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DemoMonitorBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"DockPlacement": 0,
"LyricsStyleSettings": {
"IsDynamicLyricsFontSize": true,
"PhoneticLyricsFontSize": 12,
"OriginalLyricsFontSize": 24,
"TranslatedLyricsFontSize": 12,
"LyricsAlignmentType": 1,
"LyricsBgFontOpacity": 30,
"LyricsFontStrokeWidth": 0,
"LyricsCustomBgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomFgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomStrokeFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsBgFontColorType": 1,
"LyricsFgFontColorType": 1,
"LyricsStrokeFontColorType": 1,
"LyricsFontWeight": 7,
"LyricsLineSpacingFactor": 0.5,
"LyricsTranslationSeparator": "\n",
"LyricsCJKFontFamily": "Arial",
"LyricsWesternFontFamily": "Arial",
"IsActive": false
},
"LyricsEffectSettings": {
"LyricsBlurAmount": 5,
"IsLyricsLineFadeEnabled": true,
"IsLyricsGlowEffectEnabled": true,
"LyricsGlowEffectScope": 0,
"LyricsGlowEffectAmount": 8,
"IsLyricsShadowEnabled": false,
"LyricsShadowScope": 1,
"LyricsShadowAmount": 8,
"OriginalLyricsHighlightScope": 1,
"PhoneticLyricsHighlightAmount": 60,
"OriginalLyricsHighlightAmount": 100,
"TranslatedLyricsHighlightAmount": 60,
"IsLyricsFloatAnimationEnabled": true,
"LyricsFloatAmount": 1,
"LyricsScrollEasingType": 3,
"LyricsScrollDuration": 500,
"LyricsScrollTopDuration": 500,
"LyricsScrollBottomDuration": 500,
"LyricsScrollTopDelay": 0,
"LyricsScrollBottomDelay": 0,
"LyricsVerticalEdgeOpacity": 0,
"IsFanLyricsEnabled": false,
"FanLyricsAngle": 30,
"Is3DLyricsEnabled": false,
"Lyrics3DXAngle": 30,
"Lyrics3DYAngle": 0,
"Lyrics3DZAngle": 0,
"Lyrics3DDepth": 1000,
"IsActive": false
},
"LyricsBackgroundSettings": {
"LyricsBackgroundTheme": 2,
"IsPureColorOverlayEnabled": false,
"PureColorOverlayOpacity": 100,
"IsCoverOverlayEnabled": false,
"CoverOverlayBlurAmount": 100,
"CoverOverlayOpacity": 100,
"CoverOverlaySpeed": 50,
"CoverAcrylicEffectAmount": 0,
"IsFluidOverlayEnabled": true,
"FluidOverlayOpacity": 100,
"PaletteGeneratorType": 0,
"IsSpectrumOverlayEnabled": false,
"IsSnowFlakeOverlayEnabled": false,
"SnowFlakeOverlayAmount": 50,
"IsActive": false
},
"AlbumArtLayoutSettings": {
"SongInfoAlignmentType": 0,
"CoverImageRadius": 12,
"CoverImageShadowAmount": 12,
"IsAutoSongInfoFontSize": true,
"SongInfoFontSize": 18,
"ShowTitle": true,
"ShowArtists": true,
"AlbumArtSize": 64,
"AutoAlbumArtSize": true,
"IsActive": false
},
"IsAdaptToEnvironment": false,
"EnvironmentSampleMode": 3,
"AutoShowOrHideWindow": false,
"TitleBarArea": 0,
"WindowX": 0,
"WindowY": 0,
"WindowWidth": 1920,
"WindowHeight": 1080,
"IsActive": false
}

View File

@@ -0,0 +1,164 @@
{
"Name": "\u7A84\u5C4F\u6A21\u5F0F",
"IsDefault": false,
"MonitorDeviceName": "\\\\.\\DISPLAY1",
"IsWorkArea": false,
"IsBorderless": false,
"IsAlwaysOnTop": false,
"IsAlwaysOnTopPolling": false,
"IsShownInSwitchers": true,
"IsClickThrough": false,
"LyricsLayoutOrientation": 1,
"LyricsDisplayType": 2,
"WindowBounds": {
"X": 100,
"Y": 100,
"Width": 400,
"Height": 800,
"Left": 100,
"Top": 100,
"Right": 500,
"Bottom": 900,
"IsEmpty": false
},
"DockHeight": 64,
"DemoWindowBounds": {
"X": 10,
"Y": 10,
"Width": 40,
"Height": 80,
"Left": 10,
"Top": 10,
"Right": 50,
"Bottom": 90,
"IsEmpty": false
},
"MonitorBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DemoMonitorBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"DockPlacement": 0,
"LyricsStyleSettings": {
"IsDynamicLyricsFontSize": true,
"PhoneticLyricsFontSize": 12,
"OriginalLyricsFontSize": 24,
"TranslatedLyricsFontSize": 12,
"LyricsAlignmentType": 0,
"LyricsBgFontOpacity": 30,
"LyricsFontStrokeWidth": 0,
"LyricsCustomBgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomFgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomStrokeFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsBgFontColorType": 1,
"LyricsFgFontColorType": 1,
"LyricsStrokeFontColorType": 1,
"LyricsFontWeight": 7,
"LyricsLineSpacingFactor": 0.5,
"LyricsTranslationSeparator": "\n",
"LyricsCJKFontFamily": "Arial",
"LyricsWesternFontFamily": "Arial",
"IsActive": false
},
"LyricsEffectSettings": {
"LyricsBlurAmount": 5,
"IsLyricsLineFadeEnabled": true,
"IsLyricsGlowEffectEnabled": true,
"LyricsGlowEffectScope": 0,
"LyricsGlowEffectAmount": 8,
"IsLyricsShadowEnabled": false,
"LyricsShadowScope": 1,
"LyricsShadowAmount": 8,
"OriginalLyricsHighlightScope": 1,
"PhoneticLyricsHighlightAmount": 60,
"OriginalLyricsHighlightAmount": 100,
"TranslatedLyricsHighlightAmount": 60,
"IsLyricsFloatAnimationEnabled": true,
"LyricsFloatAmount": 1,
"LyricsScrollEasingType": 3,
"LyricsScrollDuration": 500,
"LyricsScrollTopDuration": 500,
"LyricsScrollBottomDuration": 500,
"LyricsScrollTopDelay": 0,
"LyricsScrollBottomDelay": 0,
"LyricsVerticalEdgeOpacity": 0,
"IsFanLyricsEnabled": false,
"FanLyricsAngle": 30,
"Is3DLyricsEnabled": false,
"Lyrics3DXAngle": 30,
"Lyrics3DYAngle": 0,
"Lyrics3DZAngle": 0,
"Lyrics3DDepth": 1000,
"IsActive": false
},
"LyricsBackgroundSettings": {
"LyricsBackgroundTheme": 2,
"IsPureColorOverlayEnabled": false,
"PureColorOverlayOpacity": 100,
"IsCoverOverlayEnabled": false,
"CoverOverlayBlurAmount": 100,
"CoverOverlayOpacity": 100,
"CoverOverlaySpeed": 50,
"CoverAcrylicEffectAmount": 0,
"IsFluidOverlayEnabled": true,
"FluidOverlayOpacity": 100,
"PaletteGeneratorType": 0,
"IsSpectrumOverlayEnabled": false,
"IsSnowFlakeOverlayEnabled": false,
"SnowFlakeOverlayAmount": 50,
"IsActive": false
},
"AlbumArtLayoutSettings": {
"SongInfoAlignmentType": 0,
"CoverImageRadius": 12,
"CoverImageShadowAmount": 12,
"IsAutoSongInfoFontSize": true,
"SongInfoFontSize": 18,
"ShowTitle": true,
"ShowArtists": true,
"AlbumArtSize": 64,
"AutoAlbumArtSize": true,
"IsActive": false
},
"IsAdaptToEnvironment": false,
"EnvironmentSampleMode": 3,
"AutoShowOrHideWindow": false,
"TitleBarArea": 1,
"WindowX": 100,
"WindowY": 100,
"WindowWidth": 400,
"WindowHeight": 800,
"IsActive": false
}

View File

@@ -0,0 +1,164 @@
{
"Name": "\u6807\u51C6\u6A21\u5F0F",
"IsDefault": false,
"MonitorDeviceName": "\\\\.\\DISPLAY1",
"IsWorkArea": false,
"IsBorderless": false,
"IsAlwaysOnTop": false,
"IsAlwaysOnTopPolling": false,
"IsShownInSwitchers": true,
"IsClickThrough": false,
"LyricsLayoutOrientation": 0,
"LyricsDisplayType": 2,
"WindowBounds": {
"X": 100,
"Y": 100,
"Width": 800,
"Height": 500,
"Left": 100,
"Top": 100,
"Right": 900,
"Bottom": 600,
"IsEmpty": false
},
"DockHeight": 64,
"DemoWindowBounds": {
"X": 10,
"Y": 10,
"Width": 80,
"Height": 50,
"Left": 10,
"Top": 10,
"Right": 90,
"Bottom": 60,
"IsEmpty": false
},
"MonitorBounds": {
"X": 0,
"Y": 0,
"Width": 1920,
"Height": 1080,
"Left": 0,
"Top": 0,
"Right": 1920,
"Bottom": 1080,
"IsEmpty": false
},
"DemoMonitorBounds": {
"X": 0,
"Y": 0,
"Width": 192,
"Height": 108,
"Left": 0,
"Top": 0,
"Right": 192,
"Bottom": 108,
"IsEmpty": false
},
"DockPlacement": 0,
"LyricsStyleSettings": {
"IsDynamicLyricsFontSize": true,
"PhoneticLyricsFontSize": 12,
"OriginalLyricsFontSize": 24,
"TranslatedLyricsFontSize": 12,
"LyricsAlignmentType": 0,
"LyricsBgFontOpacity": 30,
"LyricsFontStrokeWidth": 0,
"LyricsCustomBgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomFgFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsCustomStrokeFontColor": {
"A": 255,
"R": 255,
"G": 255,
"B": 255
},
"LyricsBgFontColorType": 1,
"LyricsFgFontColorType": 1,
"LyricsStrokeFontColorType": 1,
"LyricsFontWeight": 7,
"LyricsLineSpacingFactor": 0.5,
"LyricsTranslationSeparator": "\n",
"LyricsCJKFontFamily": "Arial",
"LyricsWesternFontFamily": "Arial",
"IsActive": false
},
"LyricsEffectSettings": {
"LyricsBlurAmount": 5,
"IsLyricsLineFadeEnabled": true,
"IsLyricsGlowEffectEnabled": true,
"LyricsGlowEffectScope": 0,
"LyricsGlowEffectAmount": 8,
"IsLyricsShadowEnabled": false,
"LyricsShadowScope": 1,
"LyricsShadowAmount": 8,
"OriginalLyricsHighlightScope": 1,
"PhoneticLyricsHighlightAmount": 60,
"OriginalLyricsHighlightAmount": 100,
"TranslatedLyricsHighlightAmount": 60,
"IsLyricsFloatAnimationEnabled": true,
"LyricsFloatAmount": 1,
"LyricsScrollEasingType": 3,
"LyricsScrollDuration": 500,
"LyricsScrollTopDuration": 500,
"LyricsScrollBottomDuration": 500,
"LyricsScrollTopDelay": 0,
"LyricsScrollBottomDelay": 0,
"LyricsVerticalEdgeOpacity": 0,
"IsFanLyricsEnabled": false,
"FanLyricsAngle": 30,
"Is3DLyricsEnabled": false,
"Lyrics3DXAngle": 30,
"Lyrics3DYAngle": 0,
"Lyrics3DZAngle": 0,
"Lyrics3DDepth": 1000,
"IsActive": false
},
"LyricsBackgroundSettings": {
"LyricsBackgroundTheme": 2,
"IsPureColorOverlayEnabled": false,
"PureColorOverlayOpacity": 100,
"IsCoverOverlayEnabled": false,
"CoverOverlayBlurAmount": 100,
"CoverOverlayOpacity": 100,
"CoverOverlaySpeed": 50,
"CoverAcrylicEffectAmount": 0,
"IsFluidOverlayEnabled": true,
"FluidOverlayOpacity": 100,
"PaletteGeneratorType": 0,
"IsSpectrumOverlayEnabled": false,
"IsSnowFlakeOverlayEnabled": false,
"SnowFlakeOverlayAmount": 50,
"IsActive": false
},
"AlbumArtLayoutSettings": {
"SongInfoAlignmentType": 0,
"CoverImageRadius": 12,
"CoverImageShadowAmount": 12,
"IsAutoSongInfoFontSize": true,
"SongInfoFontSize": 18,
"ShowTitle": true,
"ShowArtists": true,
"AlbumArtSize": 64,
"AutoAlbumArtSize": true,
"IsActive": false
},
"IsAdaptToEnvironment": false,
"EnvironmentSampleMode": 3,
"AutoShowOrHideWindow": false,
"TitleBarArea": 1,
"WindowX": 100,
"WindowY": 100,
"WindowWidth": 800,
"WindowHeight": 500,
"IsActive": false
}

16
ShareHub/index.md Normal file
View File

@@ -0,0 +1,16 @@
# Welcome to ShareHub
## Shared lyrics window status
[Desktop](LyricsWindowStatus/desktop.json)
[Docked (Bottom)](LyricsWindowStatus/docked-bottom.json)
[Docked (Top)](LyricsWindowStatus/docked-top.json)
[Fullscreen (Horizontal)](LyricsWindowStatus/fs-horiz.json)
[Fullscreen (Vertical)](LyricsWindowStatus/fs-vert.json)
[Standard (Horizontal)](LyricsWindowStatus/std-horiz.json)

View File

@@ -1,35 +0,0 @@
# How to install ".msixbundle" test package
## Pre-steps
Be sure that you have already enable developer mode. To do that, you can follow the steps below:
1. Go to "Settings", select "System", go to "Developer Options".
![alt text](image-0.png)
2. Turn on "Developer Mode" and enable local PowerShell script allowance.
![alt text](image-1.png)
Now you are good to go.
## Step 1
Unzip downloaded .zip file, right-click on "install.ps1", select "Run using PowerShell".
![alt text](image-2.png)
## Step 2
Press "Enter" to continue, and agree on the popup window.
![alt text](image-3.png)
## Step 3
Enter "Y" to install cert.
![alt text](image-5.png)
## Step 4
You are good to go now.
![alt text](image-6.png)
> If you fail to install it with the previous version installed, please try to uninstall the old one and install it again.