diff --git a/src/Filee.App/Services/ConversionService.cs b/src/Filee.App/Services/ConversionService.cs index 44b0c0fd9..7b8a99e7c 100644 --- a/src/Filee.App/Services/ConversionService.cs +++ b/src/Filee.App/Services/ConversionService.cs @@ -213,6 +213,8 @@ private void OnJobUpdated(object? sender, ConversionJob job) private void OnJobFinished(object? sender, ConversionJob job) { var entry = HistoryEntry.From(job); + if (string.IsNullOrWhiteSpace(job.Preset.Name) && job.Preset.NameKey is { } key && _loc[key] == job.PresetDisplayName) + entry.PresetNameKey = key; entry.WatchRuleId = _watchJobs.GetValueOrDefault(job.Id); _store.AddHistory(entry); if (_waiting.TryGetValue(job.Id, out var waiting)) diff --git a/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs b/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs index 663c6bfd5..e6487327d 100644 --- a/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs +++ b/src/Filee.App/ViewModels/Pages/HomePageViewModel.cs @@ -34,7 +34,7 @@ public HistoryItemViewModel(HistoryEntry entry, ILocalizer loc, IPlatformService _platform = platform; _conversions = conversions; _store = store; - Title = entry.PresetName; + Title = NameOf(entry, loc); Subtitle = entry.Sources.Count == 1 ? Path.GetFileName(entry.Sources[0]) : loc.Format("home.files", entry.Sources.Count); Time = entry.FinishedAt.Date == DateTime.Today ? entry.FinishedAt.ToString("t") : entry.FinishedAt.ToString("d"); Failures = entry.Failures.Count > 0 @@ -61,6 +61,10 @@ public HistoryItemViewModel(HistoryEntry entry, ILocalizer loc, IPlatformService UndoneText = entry.Undone ? loc[entry.OriginalsInTrash ? "home.undone_original" : "home.undone"] : ""; } + /// The preset's name in the language Filee is in now when it is a built-in one, else as it was saved. + internal static string NameOf(HistoryEntry entry, ILocalizer loc) => + entry.PresetNameKey is { } key && loc[key] is var name && name != key ? name : entry.PresetName; + /// /// Undo (#553) is offered while the results not moved yet are all as the job left them, so a file changed since is /// never moved; after an Undo that stopped half-way, for the ones it didn't get to. @@ -288,7 +292,7 @@ private void Reload() var query = Search.Trim(); // The entries are picked first, then built: building one looks for its outputs on disk. var entries = _store.History - .Where(entry => query.Length == 0 || Matches(entry, query)) + .Where(entry => query.Length == 0 || Matches(entry, query, _loc)) .Take(Shown) .ToList(); History.Clear(); @@ -338,9 +342,9 @@ private void LoadThumbnails() }, token); } - private static bool Matches(HistoryEntry entry, string query) + private static bool Matches(HistoryEntry entry, string query, ILocalizer loc) { - return Contains(entry.PresetName) || entry.Sources.Any(source => Contains(Path.GetFileName(source))); + return Contains(HistoryItemViewModel.NameOf(entry, loc)) || Contains(entry.PresetName) || entry.Sources.Any(source => Contains(Path.GetFileName(source))); bool Contains(string? text) => text?.Contains(query, StringComparison.CurrentCultureIgnoreCase) == true; } diff --git a/src/Filee.Core/History/HistoryEntry.cs b/src/Filee.Core/History/HistoryEntry.cs index 9efa654ac..3fa418fa7 100644 --- a/src/Filee.Core/History/HistoryEntry.cs +++ b/src/Filee.Core/History/HistoryEntry.cs @@ -12,6 +12,12 @@ public sealed class HistoryEntry public DateTime FinishedAt { get; set; } public string PresetId { get; set; } = ""; public string PresetName { get; set; } = ""; + + /// + /// The built-in preset's name key when the job showed its translated name, so the entry follows the language Filee + /// is in now (#744); null for the user's own names and in entries from before. + /// + public string? PresetNameKey { get; set; } public JobState State { get; set; } public List Sources { get; set; } = []; public List Outputs { get; set; } = []; diff --git a/tests/Filee.App.Tests/RecentConversionTests.cs b/tests/Filee.App.Tests/RecentConversionTests.cs index 5b5f7292b..4d5433820 100644 --- a/tests/Filee.App.Tests/RecentConversionTests.cs +++ b/tests/Filee.App.Tests/RecentConversionTests.cs @@ -399,6 +399,25 @@ public void Recent_conversions_show_their_results(string language, bool dark) } } + [AvaloniaFact] + public void A_built_in_preset_name_follows_the_language_filee_is_in_now() + { + // #744: converted while Filee was in Chinese, looked at in English. + TestServices.EnsureInitialized("en"); + var loc = AppHost.Get(); + var platform = new OpeningPlatform(false); + var builtIn = Entry([], "长图"); + builtIn.PresetNameKey = "preset.long_image"; + Assert.Equal(loc["preset.long_image"], new HistoryItemViewModel(builtIn, loc, platform).Title); + Assert.NotEqual("长图", loc["preset.long_image"]); + + // The user's own name, an older entry and a key Filee no longer has keep the saved name. + Assert.Equal("My PNG", new HistoryItemViewModel(Entry([], "My PNG"), loc, platform).Title); + var gone = Entry([], "旧名"); + gone.PresetNameKey = "preset.no_such_preset"; + Assert.Equal("旧名", new HistoryItemViewModel(gone, loc, platform).Title); + } + private static HistoryEntry Entry(List outputs, string preset = "PNG", List? sources = null) => new() { FinishedAt = DateTime.Now,