Compare commits

...

8 Commits

Author SHA1 Message Date
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
21 changed files with 172 additions and 172 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.97.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

@@ -37,6 +37,7 @@ namespace BetterLyrics.WinUI3
{
private readonly ILogger<App> _logger;
private readonly ISettingsService _settingsService;
public static new App Current => (App)Application.Current;
@@ -53,6 +54,7 @@ namespace BetterLyrics.WinUI3
ConfigureServices();
_logger = Ioc.Default.GetRequiredService<ILogger<App>>();
_settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
UnhandledException += App_UnhandledException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
@@ -74,6 +76,10 @@ namespace BetterLyrics.WinUI3
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
WindowHelper.OpenOrShowWindow<LyricsWindow>();
if (_settingsService.AppSettings.MusicGallerySettings.AutoOpen)
{
WindowHelper.OpenOrShowWindow<MusicGalleryWindow>();
}
}
private static void ConfigureServices()

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

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

@@ -574,6 +574,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

@@ -574,6 +574,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

@@ -574,6 +574,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

@@ -574,6 +574,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

@@ -574,6 +574,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,8 +113,6 @@ 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;
_timelineController = _mediaPlayer.TimelineController = new();
@@ -136,6 +128,16 @@ namespace BetterLyrics.WinUI3.ViewModels
_libWatcherService = libWatcherService;
_libWatcherService.MusicLibraryFilesChanged += LibWatcherService_MusicLibraryFilesChanged;
if (AppSettings.MusicGallerySettings.AutoPlay)
{
PlayTrackAt(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,18 +157,18 @@ namespace BetterLyrics.WinUI3.ViewModels
public void PlayNextTrack()
{
switch (PlaybackOrder)
switch (AppSettings.MusicGallerySettings.PlaybackOrder)
{
case PlaybackOrder.RepeatAll:
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
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);
});
@@ -179,7 +181,7 @@ namespace BetterLyrics.WinUI3.ViewModels
{
if (TrackPlayingQueue.Count > 0)
{
PlayingSongIndex = new Random().Next(0, TrackPlayingQueue.Count);
AppSettings.MusicGallerySettings.PlayQueueIndex = new Random().Next(0, TrackPlayingQueue.Count);
}
PlayTrack(PlayingQueueItem);
});
@@ -191,18 +193,18 @@ namespace BetterLyrics.WinUI3.ViewModels
private void PlayPreviousTrack()
{
switch (PlaybackOrder)
switch (AppSettings.MusicGallerySettings.PlaybackOrder)
{
case PlaybackOrder.RepeatAll:
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
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);
});
@@ -215,7 +217,7 @@ namespace BetterLyrics.WinUI3.ViewModels
{
if (TrackPlayingQueue.Count > 0)
{
PlayingSongIndex = new Random().Next(0, TrackPlayingQueue.Count);
AppSettings.MusicGallerySettings.PlayQueueIndex = new Random().Next(0, TrackPlayingQueue.Count);
}
PlayTrack(PlayingQueueItem);
});
@@ -474,16 +476,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

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>
@@ -450,7 +451,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*" />
@@ -585,7 +589,7 @@
<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}" />
<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>
@@ -594,7 +598,7 @@
<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 HorizontalAlignment="Stretch" SelectedIndex="{x:Bind ViewModel.AppSettings.MusicGallerySettings.PlaybackOrder, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}">
<controls:Segmented.Items>
<controls:SegmentedItem x:Uid="MusicGalleryPageQueueLoop" />
<controls:SegmentedItem x:Uid="MusicGalleryPageSingleLoop" />
@@ -607,7 +611,7 @@
x:Name="PlayingQueueListView"
Margin="0,136,0,0"
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">

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)
@@ -57,14 +74,13 @@ namespace BetterLyrics.WinUI3.Views
private void EmptyPlayingQueueButton_Click(object sender, RoutedEventArgs e)
{
ViewModel.TrackPlayingQueue.Clear();
ViewModel.PlayingSongIndex = -1;
ViewModel.PlayTrackAt(ViewModel.PlayingSongIndex);
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = -1;
ViewModel.PlayTrackAt(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)
@@ -87,19 +103,19 @@ namespace BetterLyrics.WinUI3.Views
{
index = ViewModel.TrackPlayingQueue.Count - 1;
}
ViewModel.PlayingSongIndex = index;
ViewModel.PlayTrackAt(ViewModel.PlayingSongIndex);
ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex = index;
ViewModel.PlayTrackAt(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
}
private 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;
ViewModel.PlayTrackAt(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
}
@@ -109,8 +125,8 @@ namespace BetterLyrics.WinUI3.Views
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;
ViewModel.PlayTrackAt(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
}
@@ -252,11 +268,16 @@ namespace BetterLyrics.WinUI3.Views
// 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);
ViewModel.PlayTrackAt(ViewModel.AppSettings.MusicGallerySettings.PlayQueueIndex);
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
ScrollToPlayingItem();
}
}
}

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.