fix: amll-ttml-db lyrics searching issue (due to metadata matching calculator error)

This commit is contained in:
Zhe Fang
2026-01-06 16:43:16 -05:00
parent 5037b92913
commit 8d7fbe63c5
13 changed files with 206 additions and 170 deletions

View File

@@ -12,6 +12,7 @@ using BetterLyrics.WinUI3.Services.LyricsSearchService;
using BetterLyrics.WinUI3.Services.PlayHistoryService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.SMTCService;
using BetterLyrics.WinUI3.Services.SongSearchMapService;
using BetterLyrics.WinUI3.Services.TranslationService;
using BetterLyrics.WinUI3.Services.TransliterationService;
using BetterLyrics.WinUI3.ViewModels;
@@ -127,13 +128,25 @@ namespace BetterLyrics.WinUI3
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
// 初始化数据库
await EnsureDatabasesAsync();
await InitDatabasesAsync();
var settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
// Migrate MappedSongSearchQueries
var songSearchMapService = Ioc.Default.GetRequiredService<ISongSearchMapService>();
var obsoleteSongSearchMap = settingsService.AppSettings.MappedSongSearchQueries;
if (obsoleteSongSearchMap.Count > 0)
{
foreach (var item in obsoleteSongSearchMap)
{
await songSearchMapService.SaveMappingAsync(item);
}
obsoleteSongSearchMap.Clear();
}
// Start scan tasks in background
var fileSystemService = Ioc.Default.GetRequiredService<IFileSystemService>();
// 开始后台扫描任务
foreach (var item in settingsService.AppSettings.LocalMediaFolders)
{
if (item.LastSyncTime == null)
@@ -143,10 +156,10 @@ namespace BetterLyrics.WinUI3
}
fileSystemService.StartAllFolderTimers();
// 初始化托盘
// Init system tray
m_window = WindowHook.OpenOrShowWindow<SystemTrayWindow>();
// 根据设置打开歌词窗口
// Open lyrics window if set
if (settingsService.AppSettings.GeneralSettings.AutoStartLyricsWindow)
{
var defaultStatus = settingsService.AppSettings.WindowBoundsRecords.Where(x => x.IsDefault);
@@ -163,109 +176,39 @@ namespace BetterLyrics.WinUI3
}
}
// 根据设置自动打开主界面
// Open music gallery if set
if (settingsService.AppSettings.MusicGallerySettings.AutoOpen)
{
WindowHook.OpenOrShowWindow<MusicGalleryWindow>();
}
}
private async Task EnsureDatabasesAsync()
private async Task InitDatabasesAsync()
{
// Init databases
var playHistoryFactory = Ioc.Default.GetRequiredService<IDbContextFactory<PlayHistoryDbContext>>();
var songSearchMapFactory = Ioc.Default.GetRequiredService<IDbContextFactory<SongSearchMapDbContext>>();
var filesIndexFactory = Ioc.Default.GetRequiredService<IDbContextFactory<FilesIndexDbContext>>();
var lyricsCacheFactory = Ioc.Default.GetRequiredService<IDbContextFactory<LyricsCacheDbContext>>();
await SafeInitDatabaseAsync(
"PlayHistory",
PathHelper.PlayHistoryPath,
async () =>
{
using var db = await playHistoryFactory.CreateDbContextAsync();
await db.Database.EnsureCreatedAsync();
},
isCritical: true
);
await SafeInitDatabaseAsync(
"FileCache",
PathHelper.FilesIndexPath,
async () =>
{
using var db = await filesIndexFactory.CreateDbContextAsync();
await db.Database.EnsureCreatedAsync();
},
isCritical: false
);
await SafeInitDatabaseAsync(
"LyricsCache",
PathHelper.FilesIndexPath,
async () =>
{
using var db = await lyricsCacheFactory.CreateDbContextAsync();
await db.Database.EnsureCreatedAsync();
},
isCritical: false
);
}
private async Task SafeInitDatabaseAsync(string dbName, string dbPath, Func<Task> initAction, bool isCritical)
{
try
using (var playHistoryDb = await playHistoryFactory.CreateDbContextAsync())
{
await initAction();
await playHistoryDb.Database.EnsureCreatedAsync();
}
catch (Exception ex)
using (var songSearchMapDb = await songSearchMapFactory.CreateDbContextAsync())
{
System.Diagnostics.Debug.WriteLine($"[DB Error] {dbName} init failed: {ex.Message}");
try
{
if (File.Exists(dbPath))
{
// 尝试清理连接池
SqliteConnection.ClearAllPools();
if (isCritical)
{
var backupPath = dbPath + ".bak_" + DateTime.Now.ToString("yyyyMMddHHmmss");
File.Move(dbPath, backupPath, true);
await ShowErrorDialogAsync("Database Recovery", $"Database {dbName} is damaged, the old database has been backed up to {backupPath}, and the program will create a new database.");
}
else
{
File.Delete(dbPath);
}
}
await initAction();
System.Diagnostics.Debug.WriteLine($"[DB Info] {dbName} recovered successfully.");
}
catch (Exception fatalEx)
{
System.Diagnostics.Debug.WriteLine($"[] : {fatalEx.Message}");
await ShowErrorDialogAsync("Fatal Error", $"{dbName} recovery failed, please delete the file at {dbPath} and try again by restarting the program. ({fatalEx.Message})");
}
await songSearchMapDb.Database.EnsureCreatedAsync();
}
}
private async Task ShowErrorDialogAsync(string title, string content)
{
// 这里假设 m_window 已经存在。如果没有显示主窗口,这个弹窗可能无法显示。
// 在 App 启动极早期的错误,可能需要退化为 Log 或者 System.Diagnostics.Process.Start 打开记事本报错
if (m_window != null)
using (var filesIndexDb = await filesIndexFactory.CreateDbContextAsync())
{
m_window.DispatcherQueue.TryEnqueue(async () =>
{
var dialog = new Microsoft.UI.Xaml.Controls.ContentDialog
{
Title = title,
Content = content,
CloseButtonText = "OK",
XamlRoot = m_window.Content?.XamlRoot // 确保 Content 不为空
};
if (dialog.XamlRoot != null) await dialog.ShowAsync();
});
await filesIndexDb.Database.EnsureCreatedAsync();
}
using (var lyricsCacheDb = await lyricsCacheFactory.CreateDbContextAsync())
{
await lyricsCacheDb.Database.EnsureCreatedAsync();
}
}
@@ -283,6 +226,7 @@ namespace BetterLyrics.WinUI3
.AddDbContextFactory<PlayHistoryDbContext>(options => options.UseSqlite($"Data Source={PathHelper.PlayHistoryPath}"))
.AddDbContextFactory<FilesIndexDbContext>(options => options.UseSqlite($"Data Source={PathHelper.FilesIndexPath}"))
.AddDbContextFactory<LyricsCacheDbContext>(options => options.UseSqlite($"Data Source={PathHelper.LyricsCachePath}"))
.AddDbContextFactory<SongSearchMapDbContext>(options => options.UseSqlite($"Data Source={PathHelper.SongSearchMapPath}"))
// 日志
.AddLogging(loggingBuilder =>
@@ -305,6 +249,7 @@ namespace BetterLyrics.WinUI3
.AddSingleton<IFileSystemService, FileSystemService>()
.AddSingleton<IPlayHistoryService, PlayHistoryService>()
.AddSingleton<ILyricsCacheService, LyricsCacheService>()
.AddSingleton<ISongSearchMapService, SongSearchMapService>()
// ViewModels
.AddSingleton<AppSettingsControlViewModel>()

View File

@@ -44,9 +44,9 @@ namespace BetterLyrics.WinUI3.Helper
? $"{local.Title} {local.Artist}"
: Path.GetFileNameWithoutExtension(local.LinkedFileName);
string remoteQuery = remoteHasMetadata
string? remoteQuery = remoteHasMetadata
? $"{remote.Title} {remote.Artist}"
: Path.GetFileNameWithoutExtension(remote.Reference);
: null;
string fp1 = CreateSortedFingerprint(localQuery);
string fp2 = CreateSortedFingerprint(remoteQuery);

View File

@@ -51,6 +51,7 @@ namespace BetterLyrics.WinUI3.Helper
public static string PlayQueuePath => Path.Combine(LocalFolder, "play-queue.m3u");
public static string PlayHistoryPath => Path.Combine(LocalFolder, "play-history.db");
public static string FilesIndexPath => Path.Combine(LocalFolder, "files-index.db");
public static string SongSearchMapPath => Path.Combine(LocalFolder, "song-search-map.db");
public static string LyricsCachePath => Path.Combine(LyricsCacheDirectory, "lyrics-cache.db");
public static void EnsureDirectories()

View File

@@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
namespace BetterLyrics.WinUI3.Models.Db
{
public partial class SongSearchMapDbContext : DbContext
{
public DbSet<MappedSongSearchQuery> SongSearchMap { get; set; }
public SongSearchMapDbContext(DbContextOptions<SongSearchMapDbContext> options) : base(options) { }
}
}

View File

@@ -10,9 +10,7 @@ namespace BetterLyrics.WinUI3.Models
[Index(nameof(Uri), IsUnique = true)] // 唯一索引
public class FilesIndexItem
{
[Key] // 主键
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] // 明确指定为自增 (Identity)
public int Id { get; set; }
[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; }
// 关联到 MediaFolder.Id
// 注意:作为索引列,必须限制长度,否则 SQL Server 会报错 (索引最大900字节)

View File

@@ -1,10 +1,18 @@
using BetterLyrics.WinUI3.Enums;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace BetterLyrics.WinUI3.Models
{
public partial class MappedSongSearchQuery : ObservableRecipient
[Table("SongSearchMap")]
[Index(nameof(OriginalTitle), nameof(OriginalArtist), nameof(OriginalAlbum))]
public partial class MappedSongSearchQuery : ObservableRecipient, ICloneable
{
[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)] public string Id { get; set; }
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalTitle { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalArtist { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalAlbum { get; set; } = string.Empty;
@@ -17,7 +25,7 @@ namespace BetterLyrics.WinUI3.Models
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsSearchProvider? LyricsSearchProvider { get; set; }
public MappedSongSearchQuery Clone()
public object Clone()
{
return new MappedSongSearchQuery
{

View File

@@ -1,5 +1,6 @@
using BetterLyrics.WinUI3.Collections;
using CommunityToolkit.Mvvm.ComponentModel;
using System;
namespace BetterLyrics.WinUI3.Models.Settings
{
@@ -14,7 +15,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MediaFolder> LocalMediaFolders { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MediaSourceProviderInfo> MediaSourceProvidersInfo { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MappedSongSearchQuery> MappedSongSearchQueries { get; set; } = [];
[Obsolete][ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MappedSongSearchQuery> MappedSongSearchQueries { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<LyricsWindowStatus> WindowBoundsRecords { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<SongsTabInfo> StarredPlaylists { get; set; } = [];

View File

@@ -110,9 +110,6 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
_settingsService.AppSettings.LocalMediaFolders.CollectionChanged += LocalMediaFolders_CollectionChanged;
_settingsService.AppSettings.MappedSongSearchQueries.CollectionChanged += MappedSongSearchQueries_CollectionChanged;
_settingsService.AppSettings.MappedSongSearchQueries.ItemPropertyChanged += MappedSongSearchQueries_ItemPropertyChanged;
InitMediaManager();
}
@@ -151,16 +148,6 @@ namespace BetterLyrics.WinUI3.Services.GSMTCService
}
}
private void MappedSongSearchQueries_ItemPropertyChanged(object? sender, ItemPropertyChangedEventArgs e)
{
UpdateLyrics();
}
private void MappedSongSearchQueries_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
UpdateLyrics();
}
private void LocalMediaFolders_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
UpdateAlbumArt();

View File

@@ -35,7 +35,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService
}
/// <summary>
/// Write or update cache to DB
/// Write cache to DB
/// </summary>
public async Task SaveLyricsAsync(SongInfo songInfo, LyricsCacheItem result)
{
@@ -46,16 +46,17 @@ namespace BetterLyrics.WinUI3.Services.LyricsCacheService
var existingItem = await context.LyricsCache
.FirstOrDefaultAsync(x => x.CacheKey == key && x.Provider == result.Provider);
var newItem = (LyricsCacheItem)result.Clone();
newItem.CacheKey = key;
if (existingItem == null)
{
var newItem = (LyricsCacheItem)result.Clone();
newItem.CacheKey = key;
if (existingItem != null)
{
context.LyricsCache.Update(newItem);
await context.LyricsCache.AddAsync(newItem);
}
else
{
await context.LyricsCache.AddAsync(newItem);
// No need to handle this case
return;
}
await context.SaveChangesAsync();

View File

@@ -8,6 +8,7 @@ using BetterLyrics.WinUI3.Providers;
using BetterLyrics.WinUI3.Services.FileSystemService;
using BetterLyrics.WinUI3.Services.LyricsCacheService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.SongSearchMapService;
using Lyricify.Lyrics.Helpers;
using Lyricify.Lyrics.Searchers;
using Microsoft.Extensions.Logging;
@@ -32,18 +33,21 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
private readonly ISettingsService _settingsService;
private readonly IFileSystemService _fileSystemService;
private readonly ILyricsCacheService _lyricsCacheService;
private readonly ISongSearchMapService _songSearchMapService;
private readonly ILogger _logger;
public LyricsSearchService(
ISettingsService settingsService,
IFileSystemService fileSystemService,
ILyricsCacheService lyricsCacheService,
ISettingsService settingsService,
IFileSystemService fileSystemService,
ILyricsCacheService lyricsCacheService,
ISongSearchMapService songSearchMapService,
ILogger<LyricsSearchService> logger
)
{
_settingsService = settingsService;
_fileSystemService = fileSystemService;
_lyricsCacheService = lyricsCacheService;
_songSearchMapService = songSearchMapService;
_logger = logger;
_lrcLibHttpClient = new();
@@ -117,11 +121,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
_logger.LogInformation("SearchSmartlyAsync {SongInfo}", songInfo);
// 先检查该曲目是否已被用户映射
var found = _settingsService.AppSettings.MappedSongSearchQueries
.FirstOrDefault(x =>
x.OriginalTitle == overridenTitle &&
x.OriginalArtist == overridenArtist &&
x.OriginalAlbum == overridenAlbum);
var found = await _songSearchMapService.GetMappingAsync(overridenTitle, overridenArtist, overridenAlbum);
if (found != null)
{
@@ -408,7 +408,6 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
}
}
int bestScore = 0;
string? rawLyricFile = null;
await foreach (var line in File.ReadLinesAsync(PathHelper.AmllTtmlDbIndexPath))
{
@@ -445,7 +444,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
Artist = artist,
Album = album,
});
if (score > bestScore)
if (score > lyricsSearchResult.MatchPercentage)
{
if (root.TryGetProperty("rawLyricFile", out var rawLyricFileProp))
{
@@ -453,15 +452,13 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
lyricsSearchResult.Title = title;
lyricsSearchResult.Artist = artist;
lyricsSearchResult.Album = album;
bestScore = score;
lyricsSearchResult.MatchPercentage = score;
}
}
}
catch { }
}
lyricsSearchResult.MatchPercentage = MetadataComparer.CalculateScore(songInfo, lyricsSearchResult);
if (string.IsNullOrWhiteSpace(rawLyricFile))
{
return lyricsSearchResult;

View File

@@ -0,0 +1,15 @@
using BetterLyrics.WinUI3.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Services.SongSearchMapService
{
public interface ISongSearchMapService
{
Task SaveMappingAsync(MappedSongSearchQuery mapping);
Task<MappedSongSearchQuery?> GetMappingAsync(string title, string artist, string album);
Task DeleteMappingAsync(MappedSongSearchQuery mapping);
}
}

View File

@@ -0,0 +1,78 @@
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Db;
using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Services.SongSearchMapService
{
public class SongSearchMapService : ISongSearchMapService
{
private readonly IDbContextFactory<SongSearchMapDbContext> _contextFactory;
public SongSearchMapService(IDbContextFactory<SongSearchMapDbContext> contextFactory)
{
_contextFactory = contextFactory;
}
public async Task SaveMappingAsync(MappedSongSearchQuery mapping)
{
using var context = await _contextFactory.CreateDbContextAsync();
var existing = await context.SongSearchMap
.FirstOrDefaultAsync(x =>
x.OriginalTitle == mapping.OriginalTitle &&
x.OriginalArtist == mapping.OriginalArtist &&
x.OriginalAlbum == mapping.OriginalAlbum);
if (existing != null)
{
existing.MappedTitle = mapping.MappedTitle;
existing.MappedArtist = mapping.MappedArtist;
existing.MappedAlbum = mapping.MappedAlbum;
existing.IsMarkedAsPureMusic = mapping.IsMarkedAsPureMusic;
existing.LyricsSearchProvider = mapping.LyricsSearchProvider;
context.SongSearchMap.Update(existing);
}
else
{
var newItem = (MappedSongSearchQuery)mapping.Clone();
await context.SongSearchMap.AddAsync(newItem);
}
await context.SaveChangesAsync();
}
public async Task<MappedSongSearchQuery?> GetMappingAsync(string title, string artist, string album)
{
using var context = await _contextFactory.CreateDbContextAsync();
return await context.SongSearchMap
.AsNoTracking()
.FirstOrDefaultAsync(x =>
x.OriginalTitle == title &&
x.OriginalArtist == artist &&
x.OriginalAlbum == album);
}
public async Task DeleteMappingAsync(MappedSongSearchQuery mapping)
{
using var context = await _contextFactory.CreateDbContextAsync();
var target = await context.SongSearchMap
.FirstOrDefaultAsync(x =>
x.OriginalTitle == mapping.OriginalTitle &&
x.OriginalArtist == mapping.OriginalArtist &&
x.OriginalAlbum == mapping.OriginalAlbum);
if (target != null)
{
context.SongSearchMap.Remove(target);
await context.SaveChangesAsync();
}
}
}
}

View File

@@ -3,9 +3,10 @@ using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Parsers.LyricsParser;
using BetterLyrics.WinUI3.Services.LyricsSearchService;
using BetterLyrics.WinUI3.Services.GSMTCService;
using BetterLyrics.WinUI3.Services.LyricsSearchService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.SongSearchMapService;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
@@ -22,6 +23,7 @@ namespace BetterLyrics.WinUI3.ViewModels
private readonly ILyricsSearchService _lyricsSearchService;
private readonly IGSMTCService _gsmtcService;
private readonly ISettingsService _settingsService;
private readonly ISongSearchMapService _songSearchMapService;
private LatestOnlyTaskRunner _lyricsSearchRunner = new();
@@ -43,24 +45,34 @@ namespace BetterLyrics.WinUI3.ViewModels
[ObservableProperty]
public partial bool IsSearching { get; set; } = false;
public LyricsSearchControlViewModel(ILyricsSearchService lyricsSearchService, IGSMTCService gsmtcService, ISettingsService settingsService)
public LyricsSearchControlViewModel(
ILyricsSearchService lyricsSearchService,
IGSMTCService gsmtcService,
ISettingsService settingsService,
ISongSearchMapService songSearchMapService
)
{
_lyricsSearchService = lyricsSearchService;
_gsmtcService = gsmtcService;
_settingsService = settingsService;
_songSearchMapService = songSearchMapService;
AppSettings = _settingsService.AppSettings;
InitMappedSongSearchQuery();
_ = InitMappedSongSearchQueryAsync();
}
private void InitMappedSongSearchQuery()
private async Task InitMappedSongSearchQueryAsync()
{
LyricsSearchResults.Clear();
LyricsDataArr = null;
if (_gsmtcService.CurrentSongInfo != null)
{
var found = GetMappedSongSearchQueryFromSettings();
var found = await _songSearchMapService.GetMappingAsync(
_gsmtcService.CurrentSongInfo.Title,
_gsmtcService.CurrentSongInfo.Artist,
_gsmtcService.CurrentSongInfo.Album);
if (found == null)
{
MappedSongSearchQuery = new MappedSongSearchQuery
@@ -75,27 +87,11 @@ namespace BetterLyrics.WinUI3.ViewModels
}
else
{
MappedSongSearchQuery = found.Clone();
MappedSongSearchQuery = (MappedSongSearchQuery)found.Clone();
}
}
}
private MappedSongSearchQuery? GetMappedSongSearchQueryFromSettings()
{
if (_gsmtcService.CurrentSongInfo == null)
{
return null;
}
var found = AppSettings.MappedSongSearchQueries
.FirstOrDefault(x =>
x.OriginalTitle == _gsmtcService.CurrentSongInfo.Title &&
x.OriginalArtist == _gsmtcService.CurrentSongInfo.Artist &&
x.OriginalAlbum == _gsmtcService.CurrentSongInfo.Album);
return found;
}
public void PlayLyricsLine(LyricsLine? value)
{
if (value?.StartMs == null)
@@ -134,32 +130,27 @@ namespace BetterLyrics.WinUI3.ViewModels
}
[RelayCommand]
private void Save()
private async Task SaveAsync()
{
if (MappedSongSearchQuery == null)
{
return;
}
var existing = GetMappedSongSearchQueryFromSettings();
if (existing != null)
{
AppSettings.MappedSongSearchQueries.Remove(existing);
}
AppSettings.MappedSongSearchQueries.Add(MappedSongSearchQuery);
MappedSongSearchQuery = MappedSongSearchQuery.Clone();
await _songSearchMapService.SaveMappingAsync(MappedSongSearchQuery);
MappedSongSearchQuery = (MappedSongSearchQuery)MappedSongSearchQuery.Clone();
_gsmtcService.UpdateLyrics();
}
[RelayCommand]
private void Reset()
private async Task ResetAsync()
{
var existing = GetMappedSongSearchQueryFromSettings();
if (existing != null)
{
AppSettings.MappedSongSearchQueries.Remove(existing);
}
InitMappedSongSearchQuery();
if (MappedSongSearchQuery == null) return;
await _songSearchMapService.DeleteMappingAsync(MappedSongSearchQuery);
await InitMappedSongSearchQueryAsync();
SelectedLyricsSearchResult = null;
_gsmtcService.UpdateLyrics();
}
[RelayCommand]
@@ -200,7 +191,7 @@ namespace BetterLyrics.WinUI3.ViewModels
{
if (message.PropertyName == nameof(IGSMTCService.CurrentSongInfo))
{
InitMappedSongSearchQuery();
_ = InitMappedSongSearchQueryAsync();
}
}
}