From 125bf1682ec7e8dc4d7dfe2a27f689879c19c023 Mon Sep 17 00:00:00 2001 From: Zhe Fang Date: Mon, 29 Dec 2025 12:15:39 -0500 Subject: [PATCH] chores --- .../BetterLyrics.WinUI3/App.xaml.cs | 7 ++ .../Controls/MediaSettingsControl.xaml | 21 +++--- .../RemoteServerConfigControl.xaml.cs | 44 ++++++------ .../FileSourceTypeToIconConverter.cs | 2 +- .../Enums/FileSourceType.cs | 2 +- .../Helper/WebDavProbeHelper.cs | 72 +++++++++++++++++++ .../BetterLyrics.WinUI3/Models/MediaFolder.cs | 14 ++-- .../Models/PlayHistoryItem.cs | 26 +++++++ .../FileSystemService/FileSystemService.cs | 44 +++++++----- .../Strings/ar/Resources.resw | 43 ++++++----- .../Strings/de/Resources.resw | 43 ++++++----- .../Strings/en/Resources.resw | 9 +++ .../Strings/es/Resources.resw | 43 ++++++----- .../Strings/fr/Resources.resw | 43 ++++++----- .../Strings/hi/Resources.resw | 43 ++++++----- .../Strings/id/Resources.resw | 43 ++++++----- .../Strings/ja/Resources.resw | 43 ++++++----- .../Strings/ko/Resources.resw | 43 ++++++----- .../Strings/ms/Resources.resw | 43 ++++++----- .../Strings/pt/Resources.resw | 43 ++++++----- .../Strings/ru/Resources.resw | 43 ++++++----- .../Strings/th/Resources.resw | 43 ++++++----- .../Strings/vi/Resources.resw | 43 ++++++----- .../Strings/zh-Hans/Resources.resw | 43 ++++++----- .../Strings/zh-Hant/Resources.resw | 43 ++++++----- .../MediaSettingsControlViewModel.cs | 46 ++++++++---- .../ViewModels/MusicGalleryPageViewModel.cs | 15 ++-- .../Views/MusicGalleryPage.xaml | 29 +++----- 28 files changed, 622 insertions(+), 354 deletions(-) create mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WebDavProbeHelper.cs create mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/PlayHistoryItem.cs diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs index 1f3402d..f0d5d5c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs @@ -75,6 +75,13 @@ namespace BetterLyrics.WinUI3 var settingsService = Ioc.Default.GetRequiredService(); var fileSystemService = Ioc.Default.GetRequiredService(); + foreach (var item in settingsService.AppSettings.LocalMediaFolders) + { + if (item.LastSyncTime == null) + { + _ = Task.Run(async () => await fileSystemService.ScanMediaFolderAsync(item, CancellationToken.None)); + } + } fileSystemService.StartAllFolderTimers(); WindowHook.OpenOrShowWindow(); diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/MediaSettingsControl.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/MediaSettingsControl.xaml index 67df3e5..c68bde2 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/MediaSettingsControl.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/MediaSettingsControl.xaml @@ -5,6 +5,7 @@ xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:dev="using:DevWinUI" + xmlns:enums="using:BetterLyrics.WinUI3.Enums" xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:local="using:BetterLyrics.WinUI3.Controls" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" @@ -88,14 +89,18 @@ - + - + IsOpen="True" + Message="{x:Bind StatusText, Mode=OneWay}" + Severity="{x:Bind StatusSeverity, Mode=OneWay}" /> + - - - - + diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/RemoteServerConfigControl.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/RemoteServerConfigControl.xaml.cs index 4cb40a0..0223a80 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/RemoteServerConfigControl.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/RemoteServerConfigControl.xaml.cs @@ -12,13 +12,13 @@ namespace BetterLyrics.WinUI3.Controls { public sealed partial class RemoteServerConfigControl : UserControl { - private readonly string _protocolType; + private readonly FileSourceType _fileSourceType; private readonly ILocalizationService _localizationService = Ioc.Default.GetRequiredService(); - public RemoteServerConfigControl(string protocolType) + public RemoteServerConfigControl(FileSourceType fileSourceType) { this.InitializeComponent(); - _protocolType = protocolType; + _fileSourceType = fileSourceType; SetupDefaults(); CheckPathForWarning(); @@ -26,7 +26,7 @@ namespace BetterLyrics.WinUI3.Controls private void SetupDefaults() { - if (_protocolType.Equals("Local", StringComparison.OrdinalIgnoreCase)) + if (_fileSourceType == FileSourceType.Local) { RemoteFieldsPanel.Visibility = Visibility.Collapsed; AuthFieldsPanel.Visibility = Visibility.Collapsed; @@ -41,17 +41,17 @@ namespace BetterLyrics.WinUI3.Controls RemoteFieldsPanel.Visibility = Visibility.Visible; AuthFieldsPanel.Visibility = Visibility.Visible; - switch (_protocolType.ToUpper()) + switch (_fileSourceType) { - case "SMB": + case FileSourceType.SMB: PortBox.Value = 445; PathBox.PlaceholderText = "SharedMusic"; break; - case "FTP": + case FileSourceType.FTP: PortBox.Value = 21; PathBox.PlaceholderText = "/pub/music"; break; - case "WEBDAV": + case FileSourceType.WebDAV: PortBox.Value = 80; PathBox.PlaceholderText = "/dav/music"; break; @@ -62,15 +62,15 @@ namespace BetterLyrics.WinUI3.Controls private string GetScheme() { string scheme = string.Empty; - switch (_protocolType.ToUpper()) + switch (_fileSourceType) { - case "SMB": + case FileSourceType.SMB: scheme = "smb"; break; - case "FTP": + case FileSourceType.FTP: scheme = "ftp"; break; - case "WEBDAV": + case FileSourceType.WebDAV: scheme = "https"; break; } @@ -81,7 +81,7 @@ namespace BetterLyrics.WinUI3.Controls { string finalName = HostBox.Text.Trim(); - if (_protocolType.Equals("Local", StringComparison.OrdinalIgnoreCase)) + if (_fileSourceType == FileSourceType.Local) { if (string.IsNullOrWhiteSpace(PathBox.Text)) throw new ArgumentException(_localizationService.GetLocalizedString("RemoteServerConfigControlPathRequired")); @@ -109,17 +109,15 @@ namespace BetterLyrics.WinUI3.Controls } else { - finalName = $"{_protocolType} - {HostBox.Text}"; + finalName = $"{_fileSourceType} - {HostBox.Text}"; } - Enum.TryParse(_protocolType, true, out FileSourceType sourceType); - string scheme = GetScheme(); var folder = new MediaFolder { Name = finalName, - SourceType = sourceType, + SourceType = _fileSourceType, UriScheme = scheme, UriHost = HostBox.Text.Trim(), // ȥβո @@ -144,12 +142,7 @@ namespace BetterLyrics.WinUI3.Controls { ProgressBar.Visibility = visibility; } - - private void PathBox_TextChanged(object sender, TextChangedEventArgs e) - { - CheckPathForWarning(); - } - + private void CheckPathForWarning() { string? path = PathBox.Text?.Trim(); @@ -178,6 +171,11 @@ namespace BetterLyrics.WinUI3.Controls } } + private void PathBox_TextChanged(object sender, TextChangedEventArgs e) + { + CheckPathForWarning(); + } + private async void BrowseButton_Click(object sender, RoutedEventArgs e) { try diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/FileSourceTypeToIconConverter.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/FileSourceTypeToIconConverter.cs index 577edf6..41a569c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/FileSourceTypeToIconConverter.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/FileSourceTypeToIconConverter.cs @@ -15,7 +15,7 @@ namespace BetterLyrics.WinUI3.Converter FileSourceType.Local => "\uE8B7", // Folder FileSourceType.SMB => "\uE839", // Network FileSourceType.FTP => "\uE838", // Globe - FileSourceType.WebDav => "\uE753", // Cloud + FileSourceType.WebDAV => "\uE753", // Cloud _ => "\uE8B7" }; } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/FileSourceType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/FileSourceType.cs index b9755ee..625c917 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/FileSourceType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/FileSourceType.cs @@ -5,6 +5,6 @@ Local, SMB, FTP, - WebDav + WebDAV } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WebDavProbeHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WebDavProbeHelper.cs new file mode 100644 index 0000000..b609525 --- /dev/null +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WebDavProbeHelper.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace BetterLyrics.WinUI3.Helper +{ + public static class WebDavProbeHelper + { + /// + /// 自动检测目标主机是 HTTP 还是 HTTPS + /// + /// 返回 "https" 或 "http",如果都连不上返回 null + public static async Task DetectSchemeAsync(string host, int port, string? path, string? user, string? pwd) + { + if (port == 443) return "https"; + if (port == 80) return "http"; + + // 忽略 SSL 证书错误,因为很多 NAS 是自签名的 + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, + UseProxy = false + }; + + // 设置认证 + if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd)) + { + handler.Credentials = new NetworkCredential(user, pwd); + handler.PreAuthenticate = true; + } + + using var client = new HttpClient(handler); + client.Timeout = TimeSpan.FromSeconds(3); + + if (await ProbeUrlAsync(client, "https", host, port, path)) + { + return "https"; + } + + if (await ProbeUrlAsync(client, "http", host, port, path)) + { + return "http"; + } + + // 都失败 + return null; + } + + private static async Task ProbeUrlAsync(HttpClient client, string scheme, string host, int port, string? path) + { + try + { + var uriBuilder = new UriBuilder(scheme, host, port, path); + + // 使用 PROPFIND 方法,且 Depth 为 0,只检测根节点是否存在,不拉取列表 + var request = new HttpRequestMessage(new HttpMethod("PROPFIND"), uriBuilder.Uri); + request.Headers.Add("Depth", "0"); + + var response = await client.SendAsync(request); + + return response.StatusCode != HttpStatusCode.BadRequest; + } + catch + { + return false; + } + } + } +} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MediaFolder.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MediaFolder.cs index db6eb79..46c36de 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MediaFolder.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MediaFolder.cs @@ -3,6 +3,7 @@ using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Services.FileSystemService; using BetterLyrics.WinUI3.Services.FileSystemService.Providers; using CommunityToolkit.Mvvm.ComponentModel; +using Microsoft.UI.Xaml.Controls; using System; using System.Text.Json.Serialization; using System.Threading; @@ -30,6 +31,7 @@ namespace BetterLyrics.WinUI3.Models [ObservableProperty][NotifyPropertyChangedFor(nameof(UriString))] public partial string UriHost { get; set; } [ObservableProperty][NotifyPropertyChangedFor(nameof(UriString))] public partial int UriPort { get; set; } = -1; + [JsonPropertyName("Path")] [ObservableProperty] [NotifyPropertyChangedRecipients] [NotifyPropertyChangedFor(nameof(ConnectionSummary))] @@ -40,12 +42,10 @@ namespace BetterLyrics.WinUI3.Models [JsonIgnore] public bool IsLocal => SourceType == FileSourceType.Local; - [JsonIgnore][ObservableProperty] public partial bool IsIndexing { get; set; } = false; - [JsonIgnore][ObservableProperty] public partial double IndexingProgress { get; set; } = 0; - [JsonIgnore][ObservableProperty] public partial string IndexingStatusText { get; set; } = ""; - - [JsonIgnore][ObservableProperty] public partial bool IsCleaningUp { get; set; } = false; - [JsonIgnore][ObservableProperty] public partial string CleaningUpStatusText { get; set; } = ""; + [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsProcessing { get; set; } = false; + [ObservableProperty] public partial double IndexingProgress { get; set; } = 0; + [ObservableProperty] public partial string StatusText { get; set; } = ""; + [ObservableProperty] public partial InfoBarSeverity StatusSeverity { get; set; } = InfoBarSeverity.Informational; [ObservableProperty][NotifyPropertyChangedRecipients] public partial DateTime? LastSyncTime { get; set; } [ObservableProperty][NotifyPropertyChangedRecipients] public partial AutoScanInterval ScanInterval { get; set; } = AutoScanInterval.Disabled; @@ -118,7 +118,7 @@ namespace BetterLyrics.WinUI3.Models FileSourceType.Local => new LocalFileSystem(this), FileSourceType.SMB => new SMBFileSystem(this), FileSourceType.FTP => new FTPFileSystem(this), - FileSourceType.WebDav => new WebDavFileSystem(this), + FileSourceType.WebDAV => new WebDavFileSystem(this), _ => throw new NotImplementedException() }; } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/PlayHistoryItem.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/PlayHistoryItem.cs new file mode 100644 index 0000000..383f3a2 --- /dev/null +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/PlayHistoryItem.cs @@ -0,0 +1,26 @@ +using SQLite; +using System; +using System.Collections.Generic; +using System.Text; + +namespace BetterLyrics.WinUI3.Models +{ + [Table("PlayHistory")] + public class PlayHistoryItem + { + [PrimaryKey, AutoIncrement] + public int Id { get; set; } + + [Indexed] public string Title { get; set; } + [Indexed] public string Artist { get; set; } + public string Album { get; set; } + public string AlbumArtHash { get; set; } // 不同播放器来源的图可能不同 + + [Indexed] public DateTime StartedAt { get; set; } + public double DurationPlayedMs { get; set; } + public double TotalDurationMs { get; set; } + + [Indexed] + public string PlayerID { get; set; } // "Spotify", "QQMusic", etc. + } +} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/FileSystemService/FileSystemService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/FileSystemService/FileSystemService.cs index 71c6fa1..63c33a6 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/FileSystemService/FileSystemService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/FileSystemService/FileSystemService.cs @@ -8,6 +8,7 @@ using BetterLyrics.WinUI3.ViewModels; using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging.Messages; using Microsoft.Extensions.Logging; +using Microsoft.UI.Xaml.Controls; using SQLite; using System; using System.Collections.Concurrent; @@ -241,8 +242,10 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService { _dispatcherQueue.TryEnqueue(() => { - folder.CleaningUpStatusText = _localizationService.GetLocalizedString("FileSystemServicePrepareToClean"); - folder.IsCleaningUp = true; + folder.IndexingProgress = 0; + folder.StatusSeverity = InfoBarSeverity.Informational; + folder.StatusText = _localizationService.GetLocalizedString("FileSystemServicePrepareToClean"); + folder.IsProcessing = true; }); if (_folderTimerTokens.TryRemove(folder.Id, out var timerCts)) @@ -266,7 +269,7 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService { _dispatcherQueue.TryEnqueue(() => { - folder.CleaningUpStatusText = _localizationService.GetLocalizedString("FileSystemServiceCleaningCache"); + folder.StatusText = _localizationService.GetLocalizedString("FileSystemServiceCleaningCache"); }); await InitializeAsync(); @@ -295,8 +298,7 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService { _dispatcherQueue.TryEnqueue(() => { - folder.CleaningUpStatusText = ""; - folder.IsCleaningUp = false; + folder.IsProcessing = false; folder.LastSyncTime = null; }); } @@ -311,27 +313,32 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService _dispatcherQueue.TryEnqueue(() => { - folder.IsIndexing = true; + folder.StatusSeverity = InfoBarSeverity.Informational; + folder.IsProcessing = true; folder.IndexingProgress = 0; - folder.IndexingStatusText = _localizationService.GetLocalizedString("FileSystemServiceWaitingForScan"); + folder.StatusText = _localizationService.GetLocalizedString("FileSystemServiceWaitingForScan"); }); try { await _folderScanLock.WaitAsync(scanCts.Token); - _dispatcherQueue.TryEnqueue(() => folder.IndexingStatusText = _localizationService.GetLocalizedString("FileSystemServiceConnecting")); + _dispatcherQueue.TryEnqueue(() => folder.StatusText = _localizationService.GetLocalizedString("FileSystemServiceConnecting")); await InitializeAsync(); using var fs = folder.CreateFileSystem(); if (fs == null || !await fs.ConnectAsync()) { - _dispatcherQueue.TryEnqueue(() => folder.IndexingStatusText = _localizationService.GetLocalizedString("FileSystemServiceConnectFailed")); + _dispatcherQueue.TryEnqueue(() => + { + folder.StatusSeverity = InfoBarSeverity.Error; + folder.StatusText = _localizationService.GetLocalizedString("FileSystemServiceConnectFailed"); + }); return; } - _dispatcherQueue.TryEnqueue(() => folder.IndexingStatusText = _localizationService.GetLocalizedString("FileSystemServiceFetchingFileList")); + _dispatcherQueue.TryEnqueue(() => folder.StatusText = _localizationService.GetLocalizedString("FileSystemServiceFetchingFileList")); var filesToProcess = new List(); var foldersToScan = new Queue(); @@ -374,10 +381,10 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService if (current % 10 == 0 || current == total) { double progress = (double)current / total * 100; - _dispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Low, () => + _dispatcherQueue.TryEnqueue(() => { folder.IndexingProgress = progress; - folder.IndexingStatusText = $"{_localizationService.GetLocalizedString("FileSystemServiceParsing")} {current}/{total}"; + folder.StatusText = $"{_localizationService.GetLocalizedString("FileSystemServiceParsing")} {current}/{total}"; }); } @@ -461,6 +468,8 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService _dispatcherQueue.TryEnqueue(() => { + folder.StatusSeverity = InfoBarSeverity.Success; + folder.StatusText = _localizationService.GetLocalizedString("FileSystemServiceReady"); folder.LastSyncTime = DateTime.Now; }); } @@ -470,7 +479,11 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService } catch (Exception ex) { - _dispatcherQueue.TryEnqueue(() => folder.IndexingStatusText = ex.Message); + _dispatcherQueue.TryEnqueue(() => + { + folder.StatusText = ex.Message; + folder.StatusSeverity = InfoBarSeverity.Error; + }); } finally { @@ -480,9 +493,8 @@ namespace BetterLyrics.WinUI3.Services.FileSystemService _dispatcherQueue.TryEnqueue(() => { - folder.IsIndexing = false; - folder.IndexingStatusText = ""; - folder.IndexingProgress = 100; + folder.IsProcessing = false; + folder.IndexingProgress = 0; }); } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw index f659fcf..408fa4d 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ar/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ الوضع المثبت (Docked) + + + تم التصدير بنجاح @@ -183,6 +186,9 @@ التحضير لتنظيف ذاكرة التخزين المؤقت... + + + تم اكتشاف مسار الدليل الجذر. قد يحتوي فهرس القرص الكامل على عدد كبير من الملفات غير الوسائط ويتسبب في استغراق الفحص وقتاً طويلاً جداً. يوصى بتحديد دليل فرعي محدد. @@ -408,6 +414,9 @@ كل الموسيقى + + + مسح قائمة الانتظار diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw index 3e245d0..23c2db4 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/de/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Angedockter Modus + + + Export erfolgreich @@ -183,6 +186,9 @@ Bereinigung des Caches vorbereiten... + + + Der Pfad zum Stammverzeichnis wurde erkannt. Ein vollständiger Festplattenindex kann eine große Anzahl von Nicht-Mediendateien enthalten und dazu führen, dass die Suche zu lange dauert. Es wird empfohlen, ein bestimmtes Unterverzeichnis anzugeben. @@ -408,6 +414,9 @@ Alle Musikstücke + + + Warteschlange leeren diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw index 66cdba7..bac2e26 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en/Resources.resw @@ -159,6 +159,9 @@ Docked Mode + + Error + Export successful @@ -183,6 +186,9 @@ Preparing to clean cache... + + Ready + The root directory path has been detected. A full disk index may contain a large number of non-media files and cause the scan to take too long. It is recommended to specify a specific subdirectory. @@ -408,6 +414,9 @@ All Music + + The data is being processed. You can check the detailed progress in the settings. + Clear queue diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw index 8f7d37d..1c84dc8 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/es/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Modo Acoplado + + + Exportación exitosa @@ -183,6 +186,9 @@ Preparando la limpieza de caché... + + + Se ha detectado la ruta del directorio raíz. Un índice de disco completo puede contener un gran número de archivos no multimedia y hacer que la exploración dure demasiado tiempo. Se recomienda especificar un subdirectorio concreto. @@ -408,6 +414,9 @@ Toda la música + + + Borrar cola diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw index 58b8acd..9ba1df6 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/fr/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Mode Ancré + + + Exportation réussie @@ -183,6 +186,9 @@ Préparation du nettoyage du cache... + + + Le chemin du répertoire racine a été détecté. Un index de disque complet peut contenir un grand nombre de fichiers non multimédias et faire durer l'analyse trop longtemps. Il est recommandé de spécifier un sous-répertoire spécifique. @@ -408,6 +414,9 @@ Toute la musique + + + Vider la file d'attente diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw index 1b5953d..3b05bf1 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/hi/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ डॉक्ड मोड + + + निर्यात सफल रहा @@ -183,6 +186,9 @@ Preparing to clean cache... + + + The root directory path has been detected. A full disk index may contain a large number of non-media files and cause the scan to take too long. It is recommended to specify a specific subdirectory. @@ -408,6 +414,9 @@ सभी गाने + + + प्लेइंग कतार साफ़ करें diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw index 3aec356..0489e69 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/id/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Mode Dok + + + Ekspor berhasil @@ -183,6 +186,9 @@ Bersiap untuk membersihkan cache... + + + Jalur direktori root telah terdeteksi. Indeks disk penuh mungkin berisi sejumlah besar file non-media dan menyebabkan pemindaian memakan waktu terlalu lama. Disarankan untuk menentukan subdirektori tertentu. @@ -408,6 +414,9 @@ Semua Musik + + + Bersihkan antrean putar diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw index 334e51a..f83fb54 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ja/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ ドッキングモード + + + エクスポートが成功しました @@ -183,6 +186,9 @@ キャッシュ・クリーン準備中 + + + ルートディレクトリのパスが検出された。フルディスクインデックスにはメディア以外のファイルが多数含まれている可能性があり、スキャンに時間がかかりすぎる。特定のサブディレクトリを指定することを推奨する。 @@ -408,6 +414,9 @@ すべてのミュージック + + + キューをクリア diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw index cc6852f..9d5d11f 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ko/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ 도킹 모드 + + + 내보내기 성공 @@ -183,6 +186,9 @@ 캐시 정리 준비 중... + + + 루트 디렉터리 경로가 감지되었습니다. 전체 디스크 인덱스에 미디어가 아닌 파일이 많이 포함되어 있어 스캔 시간이 너무 오래 걸릴 수 있습니다. 특정 하위 디렉터리를 지정하는 것이 좋습니다. @@ -408,6 +414,9 @@ 모든 음악 + + + 재생 대기열 비우기 diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw index 8f8ce97..a7ed80b 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ms/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Mod Dok + + + Eksport berjaya @@ -183,6 +186,9 @@ Preparing to clean cache... + + + The root directory path has been detected. A full disk index may contain a large number of non-media files and cause the scan to take too long. It is recommended to specify a specific subdirectory. @@ -408,6 +414,9 @@ Semua Muzik + + + Kosongkan baris gilir main diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw index 75c5001..ef7883d 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/pt/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Modo Acoplado + + + Exportação bem-sucedida @@ -183,6 +186,9 @@ A preparar a limpeza da cache... + + + O caminho do diretório raiz foi detectado. Um índice de disco completo pode conter um grande número de ficheiros não multimédia e fazer com que a pesquisa demore demasiado tempo. Recomenda-se a especificação de um subdiretório específico. @@ -408,6 +414,9 @@ Todas as Músicas + + + Limpar fila de reprodução diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw index beba8fa..cb2b32e 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/ru/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Закрепленный режим + + + Экспорт выполнен успешно @@ -183,6 +186,9 @@ Подготовка к очистке кэша... + + + Обнаружен путь к корневому каталогу. Полный индекс диска может содержать большое количество файлов, не относящихся к мультимедиа, что приведет к слишком долгому сканированию. Рекомендуется указывать конкретный подкаталог. @@ -408,6 +414,9 @@ Вся музыка + + + Очистить очередь воспроизведения diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw index e6f2705..eea0a76 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/th/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ โหมดเชื่อมต่อ (Docked) + + + ส่งออกสำเร็จ @@ -183,6 +186,9 @@ กำลังเตรียมล้างแคช... + + + พบเส้นทางไดเรกทอรีรากแล้ว ดัชนีของดิสก์ทั้งหมดอาจมีไฟล์ที่ไม่ใช่สื่อจำนวนมากและทำให้การสแกนใช้เวลานานเกินไป ขอแนะนำให้ระบุไดเรกทอรีย่อยเฉพาะ @@ -408,6 +414,9 @@ เพลงทั้งหมด + + + ล้างคิวการเล่น diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw index c778b5b..215ad12 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/vi/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ Chế độ neo (Docked) + + + Xuất thành công @@ -183,6 +186,9 @@ Đang chuẩn bị xóa bộ nhớ cache... + + + Đường dẫn thư mục gốc đã được phát hiện. Chỉ mục đĩa đầy đủ có thể chứa một lượng lớn tệp không phải phương tiện và khiến quá trình quét mất quá nhiều thời gian. Khuyến nghị chỉ định một thư mục con cụ thể. @@ -408,6 +414,9 @@ Tất cả bài hát + + + Xóa hàng đợi phát diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw index 91840c9..6fa64fe 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hans/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ 停靠模式 + + 错误 + 导出成功 @@ -183,6 +186,9 @@ 正在准备清理缓存... + + 就绪 + 已检测到根目录路径。全磁盘索引可能包含大量非媒体文件,导致扫描时间过长。建议指定一个特定的子目录。 @@ -408,6 +414,9 @@ 所有音乐 + + 数据处理中,可前往设置查看详细进度 + 清除播放队列 diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw index e3ebb8d..50f163c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-Hant/Resources.resw @@ -59,46 +59,46 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - - + + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -159,6 +159,9 @@ 停靠模式 + + + 匯出成功 @@ -183,6 +186,9 @@ 準備清除快取... + + + 已偵測到根目錄路徑。全磁碟索引可能包含大量非媒體檔案,導致掃描時間過長。建議指定特定的子目錄。 @@ -408,6 +414,9 @@ 所有音樂 + + + 清除播放佇列 diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MediaSettingsControlViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MediaSettingsControlViewModel.cs index 87ad414..ecbd32e 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MediaSettingsControlViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MediaSettingsControlViewModel.cs @@ -1,4 +1,5 @@ using BetterLyrics.WinUI3.Controls; +using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Hooks; using BetterLyrics.WinUI3.Models; @@ -9,6 +10,7 @@ using BetterLyrics.WinUI3.Services.SettingsService; using BetterLyrics.WinUI3.Views; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.WinUI.Animations; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using System; @@ -51,23 +53,25 @@ namespace BetterLyrics.WinUI3.ViewModels public void SyncFolder(MediaFolder folder) { - if (folder.IsIndexing) return; + if (folder.IsProcessing) return; _ = Task.Run(async () => await _fileSystemService.ScanMediaFolderAsync(folder, CancellationToken.None)); } [RelayCommand] - private async Task AddMediaSourceAsync(string protocolType) + private async Task AddMediaSourceAsync(string fileSourceTypeName) { + FileSourceType fileSourceType = Enum.Parse(fileSourceTypeName); + var dialog = new ContentDialog { XamlRoot = WindowHook.GetWindow()?.Content.XamlRoot, Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, - Title = protocolType == "Local" ? _localizationService.GetLocalizedString("MediaSettingsControlLocalFolder") : protocolType, + Title = fileSourceType == FileSourceType.Local ? _localizationService.GetLocalizedString("MediaSettingsControlLocalFolder") : Enum.GetName(fileSourceType), PrimaryButtonText = _localizationService.GetLocalizedString("Add"), CloseButtonText = _localizationService.GetLocalizedString("Cancel"), DefaultButton = ContentDialogButton.Primary, - Content = new RemoteServerConfigControl(protocolType) + Content = new RemoteServerConfigControl(fileSourceType) }; dialog.PrimaryButtonClick += async (s, e) => @@ -86,13 +90,13 @@ namespace BetterLyrics.WinUI3.ViewModels { var tempFolder = configControl.GetConfig(); - if (protocolType == "Local") + if (fileSourceType == FileSourceType.Local) { string path = tempFolder.UriPath; - if (!System.IO.Directory.Exists(path)) + if (!Directory.Exists(path)) { - throw new System.IO.DirectoryNotFoundException(_localizationService.GetLocalizedString("RemoteServerConfigControlPathNotExisted")); + throw new DirectoryNotFoundException(_localizationService.GetLocalizedString("RemoteServerConfigControlPathNotExisted")); } var normalizedPath = Path.GetFullPath(path).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; @@ -126,6 +130,29 @@ namespace BetterLyrics.WinUI3.ViewModels } else { + if (fileSourceType == FileSourceType.WebDAV) + { + // 使用辅助类探测协议 + string? detectedScheme = await WebDavProbeHelper.DetectSchemeAsync( + tempFolder.UriHost, + tempFolder.UriPort, + tempFolder.UriPath, + tempFolder.UserName, + tempFolder.Password + ); + + if (detectedScheme == null) + { + // 探测失败,直接报错返回 + configControl.ShowError(_localizationService.GetLocalizedString("SettingsPageServerTestFailedInfo")); + deferral.Complete(); + return; + } + + // 将探测到的正确协议 (http 或 https) 写入配置对象 + tempFolder.UriScheme = detectedScheme; + } + var newUriString = tempFolder.GetStandardUri().AbsoluteUri.TrimEnd('/') + "/"; foreach (var existingFolder in AppSettings.LocalMediaFolders) @@ -208,10 +235,5 @@ namespace BetterLyrics.WinUI3.ViewModels await dialog.ShowAsync(); } - private void ShowErrorTip(RemoteServerConfigControl control, string message) - { - control.ShowError(message); - } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MusicGalleryPageViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MusicGalleryPageViewModel.cs index 92ea8eb..311803f 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MusicGalleryPageViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MusicGalleryPageViewModel.cs @@ -274,8 +274,6 @@ namespace BetterLyrics.WinUI3.ViewModels { _refreshSongsTimer.Debounce(() => { - IsDataLoading = true; - _ = Task.Run(async () => { var enabledFolderIds = _settingsService.AppSettings.LocalMediaFolders @@ -304,8 +302,6 @@ namespace BetterLyrics.WinUI3.ViewModels IsLocalMediaNotFound = !_filteredTracks.Any(); ApplySongOrderType(); - - IsDataLoading = false; }); }); }, Time.DebounceTimeout); @@ -491,8 +487,7 @@ namespace BetterLyrics.WinUI3.ViewModels if (targetFolder == null) { - - throw new Exception($"找不到文件 {PlayingTrack.FileName} 对应的存储配置。请检查服务器设置是否已启用。"); + throw new FileNotFoundException(null, PlayingTrack.DecodedAbsoluteUri); } _currentProvider = targetFolder.CreateFileSystem(); @@ -509,7 +504,7 @@ namespace BetterLyrics.WinUI3.ViewModels if (sourceStream == null) { - throw new FileNotFoundException("无法打开文件流"); + throw new FileNotFoundException(null, fileCacheStub.Uri); } if (sourceStream.CanSeek) @@ -561,7 +556,7 @@ namespace BetterLyrics.WinUI3.ViewModels } catch (Exception ex) { - ToastHelper.ShowToast($"PlayTrackAsync: Error", ex.Message, InfoBarSeverity.Error); + ToastHelper.ShowToast("Error", ex.Message, InfoBarSeverity.Error); _timelineController.Pause(); } } @@ -665,6 +660,10 @@ namespace BetterLyrics.WinUI3.ViewModels { RefreshSongs(); } + else if (message.PropertyName == nameof(MediaFolder.IsProcessing)) + { + IsDataLoading = message.NewValue; + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MusicGalleryPage.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MusicGalleryPage.xaml index e91cd43..c0984df 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MusicGalleryPage.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MusicGalleryPage.xaml @@ -194,6 +194,7 @@ + @@ -302,7 +303,13 @@ - + + + - + - - - - - - - - - - - - - - - - - -