Files
BetterLyrics/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/PlaybackSettingsControlViewModel.cs
Zhe Fang e467ab9c73 替换 SourceAppUserModelId 为 PlayerId 并新增 SongId
将 SongInfo 中的 SourceAppUserModelId 属性替换为 PlayerId,新增可选属性 SongId 以支持更精确的歌曲标识。
更新了相关服务和方法的参数签名,增加对 SongId 的支持,包括 SearchSmartlyAsync 和 SearchSingleAsync 方法。
调整了 MediaSessionsService 的逻辑,支持不同播放器的 SongId 处理。
优化了代码的灵活性和可扩展性,便于处理多播放器和歌曲标识。
2025-10-10 11:29:50 -04:00

230 lines
9.1 KiB
C#

using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Extensions;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services;
using BetterLyrics.WinUI3.Services.LastFMService;
using BetterLyrics.WinUI3.Services.MediaSessionsService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.TranslateService;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using CommunityToolkit.WinUI;
using Hqub.Lastfm.Entities;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.ViewModels
{
public partial class PlaybackSettingsControlViewModel : BaseViewModel,
IRecipient<PropertyChangedMessage<LyricsSearchProvider?>>,
IRecipient<PropertyChangedMessage<TranslationSearchProvider?>>
{
private readonly IMediaSessionsService _mediaSessionsService;
private readonly ITranslateService _libreTranslateService;
private readonly ILastFMService _lastFMService;
private readonly ISettingsService _settingsService;
[ObservableProperty]
public partial AppSettings AppSettings { get; set; }
[ObservableProperty]
public partial MediaSourceProviderInfo? SelectedMediaSourceProvider { get; set; }
[ObservableProperty]
public partial bool IsLastFMAuthenticated { get; set; }
[ObservableProperty]
public partial User? LastFMUser { get; set; }
[ObservableProperty]
public partial bool IsLibreTranslateServerTesting { get; set; } = false;
[ObservableProperty]
public partial bool IsLXMusicServerTesting { get; set; } = false;
[ObservableProperty]
public partial LyricsSearchProvider? LyricsSearchProvider { get; set; } = null;
[ObservableProperty]
public partial TranslationSearchProvider? TranslationSearchProvider { get; set; } = null;
[ObservableProperty]
public partial int SelectedTargetLanguageIndex { get; set; }
[ObservableProperty]
public partial string AppleMusicMediaUserToken { get; set; }
public PlaybackSettingsControlViewModel(
ISettingsService settingsService,
IMediaSessionsService mediaSessionsService,
ITranslateService libreTranslateService,
ILastFMService lastFMService)
{
_settingsService = settingsService;
_mediaSessionsService = mediaSessionsService;
_libreTranslateService = libreTranslateService;
_lastFMService = lastFMService;
_lastFMService.UserChanged += LastFMService_UserChanged;
_lastFMService.IsAuthenticatedChanged += LastFMService_IsAuthenticatedChanged;
_mediaSessionsService.SongInfoChanged += MediaSessionsService_SongInfoChanged;
AppSettings = _settingsService.AppSettings;
AppSettings.MediaSourceProvidersInfo.CollectionChanged += MediaSourceProvidersInfo_CollectionChanged;
AppleMusicMediaUserToken = PasswordVaultHelper.Get(Constants.App.AppName, Constants.AppleMusic.MediaUserTokenKey) ?? "";
SelectedTargetLanguageIndex = LanguageHelper.SupportedTargetLanguages.ToList().FindIndex(x => x.Code == AppSettings.TranslationSettings.SelectedTargetLanguageCode);
IsLastFMAuthenticated = _lastFMService.IsAuthenticated;
LastFMUser = _lastFMService.User;
LyricsSearchProvider = _mediaSessionsService.LyricsSearchProvider;
TranslationSearchProvider = _mediaSessionsService.TranslationSearchProvider;
SelectedMediaSourceProvider = AppSettings.MediaSourceProvidersInfo.FirstOrDefault();
}
private void MediaSourceProvidersInfo_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
SelectedMediaSourceProvider = AppSettings.MediaSourceProvidersInfo.FirstOrDefault();
}
private void LastFMService_IsAuthenticatedChanged(object? sender, Events.LastFMIsAuthenticatedChangedEventArgs e)
{
IsLastFMAuthenticated = e.IsAuthenticated;
}
private void LastFMService_UserChanged(object? sender, Events.LastFMUserChangedEventArgs e)
{
LastFMUser = e.User;
}
private void MediaSessionsService_SongInfoChanged(object? sender, Events.SongInfoChangedEventArgs e)
{
var current = AppSettings.MediaSourceProvidersInfo.Where(x => x.Provider == e.SongInfo?.PlayerId)?.FirstOrDefault();
if (_mediaSessionsService.Position.TotalSeconds <= 1 && current?.ResetPositionOffsetOnSongChanged == true)
{
current.PositionOffset = 0;
}
}
private void MediaSessionsService_SessionIdsChanged(object? sender, Events.MediaSourceProvidersInfoEventArgs e)
{
SelectedMediaSourceProvider = AppSettings.MediaSourceProvidersInfo.FirstOrDefault();
}
[RelayCommand]
private void LibreTranslateServerTest()
{
IsLibreTranslateServerTesting = true;
Task.Run(async () =>
{
try
{
string result = await _libreTranslateService.TranslateTextAsync(
"Hello, world!", AppSettings.TranslationSettings.SelectedTargetLanguageCode, new System.Threading.CancellationToken());
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestSuccessInfo"), InfoBarSeverity.Success);
});
}
catch (Exception)
{
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestFailedInfo"), InfoBarSeverity.Error);
});
}
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
IsLibreTranslateServerTesting = false;
});
});
}
[RelayCommand]
private async Task LastFMAuthAsync()
{
await _lastFMService.AuthAsync();
}
[RelayCommand]
private async Task LastFMUnAuthAsync()
{
await _lastFMService.UnAuthAsync();
}
[RelayCommand]
private async Task LastFMRefreshAsync()
{
await _lastFMService.RefreshAsync();
}
[RelayCommand]
private void LXMusicServerTest()
{
IsLXMusicServerTesting = true;
Task.Run(async () =>
{
bool testResult = await NetHelper.CheckConnectivity($"{AppSettings.GeneralSettings.LXMusicServer}/status");
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
if (testResult)
{
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestSuccessInfo"), InfoBarSeverity.Success);
}
else
{
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("SettingsPageServerTestFailedInfo"), InfoBarSeverity.Error);
}
IsLXMusicServerTesting = false;
});
});
}
[RelayCommand]
private void SaveAppleMusicMediaUserToken()
{
PasswordVaultHelper.Save(Constants.App.AppName, Constants.AppleMusic.MediaUserTokenKey, AppleMusicMediaUserToken);
_mediaSessionsService.UpdateLyrics();
}
public void Receive(PropertyChangedMessage<LyricsSearchProvider?> message)
{
if (message.Sender is MediaSessionsService)
{
if (message.PropertyName == nameof(MediaSessionsService.LyricsSearchProvider))
{
LyricsSearchProvider = message.NewValue;
}
}
}
public void Receive(PropertyChangedMessage<TranslationSearchProvider?> message)
{
if (message.Sender is MediaSessionsService)
{
if (message.PropertyName == nameof(MediaSessionsService.TranslationSearchProvider))
{
TranslationSearchProvider = message.NewValue;
}
}
}
partial void OnSelectedTargetLanguageIndexChanged(int value)
{
AppSettings.TranslationSettings.SelectedTargetLanguageCode = LanguageHelper.SupportedTargetLanguages[value].Code;
}
}
}