This commit is contained in:
Zhe Fang
2026-01-04 14:54:15 -05:00
parent 1e5a95c55e
commit 572d2cd8ba
9 changed files with 56 additions and 49 deletions

View File

@@ -31,7 +31,7 @@ namespace BetterLyrics.WinUI3.Controls
public sealed partial class LyricsCanvas : UserControl,
IRecipient<PropertyChangedMessage<TimeSpan>>,
IRecipient<PropertyChangedMessage<LyricsData?>>,
IRecipient<PropertyChangedMessage<SongInfo?>>,
IRecipient<PropertyChangedMessage<SongInfo>>,
IRecipient<PropertyChangedMessage<int>>,
IRecipient<PropertyChangedMessage<double>>,
IRecipient<PropertyChangedMessage<bool>>,
@@ -343,7 +343,7 @@ namespace BetterLyrics.WinUI3.Controls
var lyricsStyle = _lyricsWindowStatus.LyricsStyleSettings;
var lyricsEffect = _lyricsWindowStatus.LyricsEffectSettings;
double songDuration = _gsmtcService.CurrentSongInfo?.DurationMs ?? 0;
double songDuration = _gsmtcService.CurrentSongInfo.DurationMs;
bool isForceWordByWord = _settingsService.AppSettings.GeneralSettings.IsForceWordByWordEffect;
Color overlayColor;
@@ -726,7 +726,7 @@ namespace BetterLyrics.WinUI3.Controls
}
}
public void Receive(PropertyChangedMessage<SongInfo?> message)
public void Receive(PropertyChangedMessage<SongInfo> message)
{
if (message.Sender is IGSMTCService)
{
@@ -891,5 +891,6 @@ namespace BetterLyrics.WinUI3.Controls
}
}
}
}
}

View File

@@ -22,7 +22,7 @@ using BetterLyrics.WinUI3.Extensions;
namespace BetterLyrics.WinUI3.Controls;
public sealed partial class NowPlayingBar : UserControl,
IRecipient<PropertyChangedMessage<SongInfo?>>,
IRecipient<PropertyChangedMessage<SongInfo>>,
IRecipient<PropertyChangedMessage<BitmapImage?>>,
IRecipient<PropertyChangedMessage<TimeSpan>>
{
@@ -312,14 +312,14 @@ public sealed partial class NowPlayingBar : UserControl,
PlaybackOrder = PlaybackOrder.GetNext();
}
public void Receive(PropertyChangedMessage<SongInfo?> message)
public void Receive(PropertyChangedMessage<SongInfo> message)
{
if (message.Sender is IGSMTCService)
{
if (message.PropertyName == nameof(IGSMTCService.CurrentSongInfo))
{
TitleTextBlock.Text = message.NewValue?.Title;
ArtistsTextBlock.Text = message.NewValue?.DisplayArtists;
TitleTextBlock.Text = message.NewValue.Title;
ArtistsTextBlock.Text = message.NewValue.DisplayArtists;
}
}
}
@@ -344,5 +344,4 @@ public sealed partial class NowPlayingBar : UserControl,
}
}
}
}

View File

@@ -44,7 +44,7 @@ namespace BetterLyrics.WinUI3.Extensions
PlayerId = songInfo.PlayerId ?? "N/A",
TotalDurationMs = songInfo.DurationMs,
DurationPlayedMs = actualPlayedMs,
StartedAt = DateTime.Now.AddMilliseconds(-actualPlayedMs)
StartedAt = DateTime.FromBinary(songInfo.StartedAt)
};
}
}

View File

@@ -6,7 +6,7 @@ using System;
namespace BetterLyrics.WinUI3.Models
{
public partial class SongInfo : ObservableObject, ICloneable
public partial class SongInfo : ObservableRecipient, ICloneable
{
[ObservableProperty]
public partial string Album { get; set; }
@@ -26,6 +26,8 @@ namespace BetterLyrics.WinUI3.Models
[ObservableProperty]
public partial string? SongId { get; set; } = null;
[ObservableProperty] public partial long StartedAt { get; set; } = DateTime.Now.ToBinary();
public string? LinkedFileName { get; set; } = null;
public double Duration => DurationMs / 1000;
@@ -45,6 +47,7 @@ namespace BetterLyrics.WinUI3.Models
PlayerId = this.PlayerId,
SongId = this.SongId,
LinkedFileName = this.LinkedFileName,
StartedAt = this.StartedAt,
};
}

View File

@@ -3,7 +3,9 @@ using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Parsers.LyricsParser;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.WinUI;
using Microsoft.Extensions.Logging;
using Microsoft.UI.Dispatching;
using System.Threading;
using System.Threading.Tasks;
@@ -11,13 +13,13 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
{
public partial class GSMTCService : IGSMTCService
{
private LatestOnlyTaskRunner _refreshLyricsRunner = new();
private readonly DispatcherQueueTimer _refreshLyricsTimer;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsData? CurrentLyricsData { get; private set; }
[ObservableProperty] public partial LyricsSearchResult? CurrentLyricsSearchResult { get; private set; }
private async Task RefreshLyricsAsync(CancellationToken token)
private async Task RefreshLyricsAsync()
{
_logger.LogInformation("RefreshLyricsAsync");
@@ -27,12 +29,7 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
if (CurrentSongInfo != SongInfoExtensions.Placeholder)
{
CurrentLyricsSearchResult = await Task.Run(async () => await _lyrcsSearchService.SearchSmartlyAsync(
CurrentSongInfo,
true,
CurrentMediaSourceProviderInfo?.LyricsSearchType,
token),
token);
if (token.IsCancellationRequested) return;
CurrentSongInfo, true, CurrentMediaSourceProviderInfo?.LyricsSearchType, CancellationToken.None));
if (CurrentLyricsSearchResult != null)
{
@@ -40,12 +37,8 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
(CurrentLyricsData, CurrentLyricsSearchResult.TransliterationProvider, CurrentLyricsSearchResult.TranslationProvider) =
await Task.Run(async () => await lyricsParser.Parse(
_translationService,
_transliterationService,
_settingsService.AppSettings.TranslationSettings,
CurrentLyricsSearchResult,
token),
token);
_translationService, _transliterationService, _settingsService.AppSettings.TranslationSettings, CurrentLyricsSearchResult,
CancellationToken.None));
}
}
@@ -57,10 +50,10 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
public async void UpdateLyrics()
{
await _refreshLyricsRunner.RunAsync(async (token) =>
_refreshLyricsTimer.Debounce(async () =>
{
await RefreshLyricsAsync(token);
});
await RefreshLyricsAsync();
}, Constants.Time.DebounceTimeout);
}
}

View File

@@ -105,6 +105,7 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
_scrobbleTimer.Tick += ScrobbleTimer_Tick;
_onMediaPropsChangedTimer = _dispatcherQueue.CreateTimer();
_refreshLyricsTimer = _dispatcherQueue.CreateTimer();
_settingsService.AppSettings.MediaSourceProvidersInfo.ItemPropertyChanged += MediaSourceProvidersInfo_ItemPropertyChanged;
@@ -340,13 +341,17 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
.FirstOrDefault(x => x.StartsWith(ExtendedGenreFiled.FileName))?
.Replace(ExtendedGenreFiled.FileName, "");
CurrentSongInfo.Title = fixedTitle;
CurrentSongInfo.Artists = fixedArtist.SplitByCommonSplitter();
CurrentSongInfo.Album = fixedAlbum;
CurrentSongInfo.DurationMs = mediaSession.ControlSession.GetTimelineProperties().EndTime.TotalMilliseconds;
CurrentSongInfo.PlayerId = sessionId;
CurrentSongInfo.SongId = songId;
CurrentSongInfo.LinkedFileName = linkedFileName;
CurrentSongInfo = new()
{
Title = fixedTitle,
Artists = fixedArtist.SplitByCommonSplitter(),
Album = fixedAlbum,
DurationMs = mediaSession.ControlSession.GetTimelineProperties().EndTime.TotalMilliseconds,
PlayerId = sessionId,
SongId = songId,
LinkedFileName = linkedFileName,
StartedAt = DateTime.Now.ToBinary(),
};
UpdateTargetScrobbledDuration();
IsScrobbled = false;
@@ -647,7 +652,7 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
{
if (WindowHook.GetWindowHandle<NowPlayingWindow>() is IntPtr hwnd)
{
TaskbarList.SetProgressValue(hwnd, (ulong)value.TotalSeconds, (ulong)(CurrentSongInfo?.Duration ?? value.TotalSeconds));
TaskbarList.SetProgressValue(hwnd, (ulong)value.TotalSeconds, (ulong)(CurrentSongInfo.Duration));
}
}

View File

@@ -31,7 +31,7 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
TimeSpan TargetScrobbledDuration { get; }
bool CurrentIsPlaying { get; }
SongInfo? CurrentSongInfo { get; }
SongInfo CurrentSongInfo { get; }
TimeSpan CurrentPosition { get; }
LyricsData? CurrentLyricsData { get; }

View File

@@ -17,7 +17,7 @@ using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.ViewModels
{
public partial class LyricsSearchControlViewModel : BaseViewModel,
IRecipient<PropertyChangedMessage<SongInfo?>>
IRecipient<PropertyChangedMessage<SongInfo>>
{
private readonly ILyricsSearchService _lyricsSearchService;
private readonly IGSMTCService _gsmtcService;
@@ -121,7 +121,7 @@ namespace BetterLyrics.WinUI3.ViewModels
LyricsSearchResults = [..await Task.Run(async () =>
{
var result = await _lyricsSearchService.SearchAllAsync(
((SongInfo?)_gsmtcService.CurrentSongInfo?.Clone() ?? new())
((SongInfo)_gsmtcService.CurrentSongInfo.Clone())
.WithTitle(MappedSongSearchQuery.MappedTitle)
.WithArtist(MappedSongSearchQuery.MappedArtist.SplitByCommonSplitter())
.WithAlbum(MappedSongSearchQuery.MappedAlbum),
@@ -194,7 +194,7 @@ namespace BetterLyrics.WinUI3.ViewModels
}
}
public void Receive(PropertyChangedMessage<SongInfo?> message)
public void Receive(PropertyChangedMessage<SongInfo> message)
{
if (message.Sender is IGSMTCService)
{

View File

@@ -27,7 +27,7 @@ using Windows.Storage.Streams;
namespace BetterLyrics.WinUI3.Views
{
public sealed partial class NowPlayingPage : Page,
IRecipient<PropertyChangedMessage<SongInfo?>>,
IRecipient<PropertyChangedMessage<SongInfo>>,
IRecipient<PropertyChangedMessage<LyricsLayoutOrientation>>,
IRecipient<PropertyChangedMessage<LyricsDisplayType>>,
IRecipient<PropertyChangedMessage<int>>,
@@ -114,9 +114,9 @@ namespace BetterLyrics.WinUI3.Views
var artistsFontSize = albumArtLayoutSettings.IsAutoSongInfoFontSize ? lyricsLayoutMetrics.ArtistNameSize : albumArtLayoutSettings.SongInfoFontSize * 0.8;
var albumFontSize = albumArtLayoutSettings.IsAutoSongInfoFontSize ? lyricsLayoutMetrics.AlbumNameSize : albumArtLayoutSettings.SongInfoFontSize * 0.8;
RenderTextBlock(TitleTextBlock, _gsmtcService.CurrentSongInfo?.Title, titleFontSize);
RenderTextBlock(ArtistsTextBlock, _gsmtcService.CurrentSongInfo?.DisplayArtists, artistsFontSize);
RenderTextBlock(AlbumTextBlock, _gsmtcService.CurrentSongInfo?.Album, albumFontSize);
RenderTextBlock(TitleTextBlock, _gsmtcService.CurrentSongInfo.Title, titleFontSize);
RenderTextBlock(ArtistsTextBlock, _gsmtcService.CurrentSongInfo.DisplayArtists, artistsFontSize);
RenderTextBlock(AlbumTextBlock, _gsmtcService.CurrentSongInfo.Album, albumFontSize);
}
private void UpdateSongInfoOpacity()
@@ -139,6 +139,15 @@ namespace BetterLyrics.WinUI3.Views
}
}
private async void RefreshSongInfo()
{
SongInfoStackPanel.Opacity = 0;
await Task.Delay(Constants.Time.AnimationDuration);
RenderSongInfo();
SongInfoStackPanel.Opacity = 1;
UpdateSongInfoOpacity();
}
// ==== AlbumArt
private void UpdateAlbumArtOpacity()
{
@@ -575,17 +584,13 @@ namespace BetterLyrics.WinUI3.Views
// ====
public async void Receive(PropertyChangedMessage<SongInfo?> message)
public async void Receive(PropertyChangedMessage<SongInfo> message)
{
if (message.Sender is IGSMTCService)
{
if (message.PropertyName == nameof(IGSMTCService.CurrentSongInfo))
{
SongInfoStackPanel.Opacity = 0;
await Task.Delay(Constants.Time.AnimationDuration);
RenderSongInfo();
SongInfoStackPanel.Opacity = 1;
UpdateSongInfoOpacity();
RefreshSongInfo();
}
}
}
@@ -686,5 +691,6 @@ namespace BetterLyrics.WinUI3.Views
}
}
}
}