From 472feb968076e465e5e46d0f78c387060c3fdcbf Mon Sep 17 00:00:00 2001 From: Jimmy Reichley Date: Fri, 16 Aug 2024 20:17:21 -0400 Subject: [PATCH] Fix a bug with DLC window; rework some logic --- .../DownloadableContentManagerViewModel.cs | 12 +++++- .../UI/ViewModels/TitleUpdateViewModel.cs | 39 ++++++------------- .../DownloadableContentManagerWindow.axaml | 3 +- .../UI/Windows/TitleUpdateWindow.axaml | 2 +- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs b/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs index 45496722b..9f96ed4a5 100644 --- a/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs @@ -176,12 +176,22 @@ namespace Ryujinx.Ava.UI.ViewModels .Filter(Filter) .Bind(out var view).AsObservableList(); + // NOTE(jpr): this works around a bug where calling _views.Clear also clears SelectedDownloadableContents for + // some reason. so we save the items here and add them back after + var items = SelectedDownloadableContents.ToArray(); + _views.Clear(); _views.AddRange(view); + + foreach (DownloadableContentModel item in items) + { + SelectedDownloadableContents.ReplaceOrAdd(item, item); + } + OnPropertyChanged(nameof(Views)); } - private bool Filter(object arg) + private bool Filter(T arg) { if (arg is DownloadableContentModel content) { diff --git a/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs b/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs index 8d651d6cf..605bf6aee 100644 --- a/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs @@ -2,24 +2,14 @@ using Avalonia.Collections; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Platform.Storage; using Avalonia.Threading; -using LibHac.Common; -using LibHac.Fs; -using LibHac.Fs.Fsa; -using LibHac.Ncm; -using LibHac.Ns; -using LibHac.Tools.FsSystem; -using LibHac.Tools.FsSystem.NcaUtils; +using DynamicData.Kernel; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.Models; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.Loaders.Processes.Extensions; -using Ryujinx.HLE.Utilities; using Ryujinx.UI.App.Common; -using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Models; using System; using System.Collections.Generic; @@ -27,14 +17,15 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using Application = Avalonia.Application; -using ContentType = LibHac.Ncm.ContentType; using Path = System.IO.Path; -using SpanHelpers = LibHac.Common.SpanHelpers; namespace Ryujinx.Ava.UI.ViewModels { + public record TitleUpdateViewNoUpdateSentinal(); + public class TitleUpdateViewModel : BaseModel { + public TitleUpdateMetadata TitleUpdateWindowData; public readonly string TitleUpdateJsonPath; private VirtualFileSystem VirtualFileSystem { get; } @@ -43,7 +34,7 @@ namespace Ryujinx.Ava.UI.ViewModels private AvaloniaList _titleUpdates = new(); private AvaloniaList _views = new(); - private object _selectedUpdate; + private object _selectedUpdate = new TitleUpdateViewNoUpdateSentinal(); private static readonly TitleUpdateMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); @@ -123,9 +114,8 @@ namespace Ryujinx.Ava.UI.ViewModels AddUpdate(path); } - TitleUpdateModel selected = TitleUpdates.FirstOrDefault(x => x.Path == TitleUpdateWindowData.Selected, null); - - SelectedUpdate = selected; + var selected = TitleUpdates.FirstOrOptional(x => x.Path == TitleUpdateWindowData.Selected); + SelectedUpdate = selected.HasValue ? selected.Value : new TitleUpdateViewNoUpdateSentinal(); // NOTE: Save the list again to remove leftovers. Save(); @@ -137,23 +127,16 @@ namespace Ryujinx.Ava.UI.ViewModels var sortedUpdates = TitleUpdates.OrderByDescending(update => update.Version); Views.Clear(); - Views.Add(new BaseModel()); + Views.Add(new TitleUpdateViewNoUpdateSentinal()); Views.AddRange(sortedUpdates); - if (SelectedUpdate == null) + if (SelectedUpdate is TitleUpdateViewNoUpdateSentinal) { SelectedUpdate = Views[0]; } - else if (!TitleUpdates.Contains(SelectedUpdate)) + else if (!TitleUpdates.Contains((TitleUpdateModel)SelectedUpdate)) { - if (Views.Count > 1) - { - SelectedUpdate = Views[1]; - } - else - { - SelectedUpdate = Views[0]; - } + SelectedUpdate = Views.Count > 1 ? Views[1] : Views[0]; } } diff --git a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml index 9ba655e0e..fa6116780 100644 --- a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml +++ b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml @@ -77,9 +77,8 @@ SelectionMode="Multiple, Toggle" Background="Transparent" SelectionChanged="OnSelectionChanged" - SelectedItems="{Binding SelectedDownloadableContents}" + SelectedItems="{Binding SelectedDownloadableContents, Mode=OneWay}" ItemsSource="{Binding Views}"> - diff --git a/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml b/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml index c0e84279a..28fcd3343 100644 --- a/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml +++ b/src/Ryujinx/UI/Windows/TitleUpdateWindow.axaml @@ -82,7 +82,7 @@ + DataType="viewModels:TitleUpdateViewNoUpdateSentinal">