Compare commits

...

12 Commits

Author SHA1 Message Date
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
26 changed files with 532 additions and 277 deletions

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.99.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()

View File

@@ -10,7 +10,7 @@ namespace BetterLyrics.WinUI3.Constants
{
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 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

@@ -48,34 +48,42 @@
<TextBlock x:Uid="SettingsPageAppBehavior" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageAutoStart" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF71C;}">
<dev:SettingsCard x:Uid="SettingsPageAutoStart">
<ToggleSwitch
x:Name="AutoStartupToggleSwitch"
Loaded="AutoStartupToggleSwitch_Loaded"
Unloaded="AutoStartupToggleSwitch_Unloaded" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7E8;}">
<dev:SettingsCard x:Uid="SettingsPageAutoOpenMusicGalleryWindow">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoOpen, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAutoPlayWhenOpenMusicGalleryWindow">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoPlay, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageListenNewSession" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF270;}">
<dev:SettingsCard x:Uid="SettingsPageListenNewSession">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ListenOnNewPlaybackSource, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageShowHideHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPageShowHideHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageBorderlessHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPageBorderlessHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.BorderlessShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageClickThroughHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPageClickThroughHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ClickThroughShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.LyricsWindowSwitchShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
@@ -83,15 +91,15 @@
<TextBlock x:Uid="SettingsPagePlaybackShortcut" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PlayOrPauseShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageNextSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPageNextSongHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.NextSongShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPagePreviousSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPagePreviousSongHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PreviousSongShortcut, Mode=TwoWay}" />
</dev:SettingsCard>

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

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

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

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

@@ -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">
@@ -367,7 +367,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 +427,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 +472,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>
@@ -574,6 +583,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>

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">
@@ -353,7 +353,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 +367,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 +416,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 +427,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 +472,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>
@@ -574,6 +583,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>

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">
@@ -353,7 +353,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 +367,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 +416,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 +427,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 +472,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>
@@ -574,6 +583,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>

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">
@@ -353,7 +353,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 +367,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 +416,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 +427,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 +472,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>
@@ -574,6 +583,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>

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">
@@ -353,7 +353,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 +367,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 +416,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 +427,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 +472,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>
@@ -574,6 +583,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>

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
@@ -538,5 +523,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

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

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

@@ -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) 查看详细信息
- 🪟 **多种显示模式**
- **标准模式**
@@ -118,7 +118,7 @@ BetterLyrics
☕ 如果喜欢该软件,请考虑 [捐赠](#捐赠) 或在 **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) 查看其他下载安装方式。
## 构建
@@ -143,6 +143,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)

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**
@@ -124,11 +124,11 @@ Watch our demo video (uploaded on 21 Oct 2025) on Bilibili [here](https://www.bi
☕ 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
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`.
## 💖 Many thanks to
@@ -148,6 +148,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.

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.