Initial moving of DLC/updates to UI.Common

This commit is contained in:
Jimmy Reichley 2024-08-15 21:47:04 -04:00
parent 2e93c96c86
commit e1171086f4
No known key found for this signature in database
GPG key ID: 67715DC5A329803C
13 changed files with 167 additions and 79 deletions

View file

@ -497,7 +497,6 @@ namespace Ryujinx.UI.App.Common
: IntegrityCheckLevel.None;
using IFileSystem pfs = PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem);
// Dictionary<ulong, ContentMetaData> updates = pfs.GetContentData(ContentMetaType.AddOnContent, _virtualFileSystem, checkLevel);
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
{
@ -517,11 +516,7 @@ namespace Ryujinx.UI.App.Common
}
}
if (titleUpdates.Count == 0)
{
return false;
}
return true;
return titleUpdates.Count != 0;
}
}
}

View file

@ -0,0 +1,23 @@
namespace Ryujinx.UI.Common.Models
{
public class DownloadableContentModel
{
public ulong TitleId { get; }
public string ContainerPath { get; }
public string FullPath { get; }
public bool Enabled { get; }
public bool IsBundled { get; }
public string FileName => System.IO.Path.GetFileName(ContainerPath);
public string TitleIdStr => TitleId.ToString("X16");
public DownloadableContentModel(ulong titleId, string containerPath, string fullPath, bool enabled)
{
TitleId = titleId;
ContainerPath = containerPath;
FullPath = fullPath;
Enabled = enabled;
IsBundled = System.IO.Path.GetExtension(containerPath)?.ToLower() == ".xci";
}
}
}

View file

@ -0,0 +1,22 @@
namespace Ryujinx.UI.Common.Models
{
public class TitleUpdateModel
{
public ulong TitleId { get; }
public ulong Version { get; }
public string DisplayVersion { get; }
public string Path { get; }
public bool IsBundled { get; }
public string TitleIdStr => TitleId.ToString("X16");
public TitleUpdateModel(ulong titleId, ulong version, string displayVersion, string path)
{
TitleId = titleId;
Version = version;
DisplayVersion = displayVersion;
Path = path;
IsBundled = System.IO.Path.GetExtension(path)?.ToLower() == ".xci";
}
}
}

View file

@ -0,0 +1,42 @@
using Avalonia;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Ryujinx.Ava.Common.Locale;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Ryujinx.Ava.UI.Helpers
{
internal class DownloadableContentLabelConverter : IMultiValueConverter
{
public static DownloadableContentLabelConverter Instance = new();
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Any(it => it is UnsetValueType))
{
return BindingOperations.DoNothing;
}
if (values.Count != 2 || !targetType.IsAssignableFrom(typeof(string)))
{
return null;
}
if (values is not [string label, bool isBundled])
{
return null;
}
return isBundled ? $"{LocaleManager.Instance[LocaleKeys.TitleBundledDlcLabel]} {label}" : label;
}
public object[] ConvertBack(object[] values, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View file

@ -0,0 +1,42 @@
using Avalonia;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Ryujinx.Ava.Common.Locale;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Ryujinx.Ava.UI.Helpers
{
internal class TitleUpdateLabelConverter : IMultiValueConverter
{
public static TitleUpdateLabelConverter Instance = new();
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Any(it => it is UnsetValueType))
{
return BindingOperations.DoNothing;
}
if (values.Count != 2 || !targetType.IsAssignableFrom(typeof(string)))
{
return null;
}
if (values is not [string label, bool isBundled])
{
return null;
}
var key = isBundled ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel;
return LocaleManager.Instance.UpdateAndGetDynamicValue(key, label);
}
public object[] ConvertBack(object[] values, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View file

@ -1,39 +0,0 @@
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.ViewModels;
using System.IO;
namespace Ryujinx.Ava.UI.Models
{
public class DownloadableContentModel : BaseModel
{
private bool _enabled;
public bool Enabled
{
get => _enabled;
set
{
_enabled = value;
OnPropertyChanged();
}
}
public string TitleId { get; }
public string ContainerPath { get; }
public string FullPath { get; }
public string FileName => Path.GetFileName(ContainerPath);
public string Label =>
Path.GetExtension(FileName)?.ToLower() == ".xci" ? $"{LocaleManager.Instance[LocaleKeys.TitleBundledDlcLabel]} {FileName}" : FileName;
public DownloadableContentModel(string titleId, string containerPath, string fullPath, bool enabled)
{
TitleId = titleId;
ContainerPath = containerPath;
FullPath = fullPath;
Enabled = enabled;
}
}
}

View file

@ -1,21 +0,0 @@
using Ryujinx.Ava.Common.Locale;
namespace Ryujinx.Ava.UI.Models
{
public class TitleUpdateModel
{
public uint Version { get; }
public string Path { get; }
public string Label { get; }
public TitleUpdateModel(uint version, string displayVersion, string path)
{
Version = version;
Label = LocaleManager.Instance.UpdateAndGetDynamicValue(
System.IO.Path.GetExtension(path)?.ToLower() == ".xci" ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel,
displayVersion
);
Path = path;
}
}
}

View file

@ -19,6 +19,7 @@ using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.HLE.Utilities;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Models;
using System;
using System.Collections.Generic;
using System.IO;
@ -142,7 +143,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath);
if (nca != null)
{
var content = new DownloadableContentModel(nca.Header.TitleId.ToString("X16"),
var content = new DownloadableContentModel(nca.Header.TitleId,
downloadableContentContainer.ContainerPath,
downloadableContentNca.FullPath,
downloadableContentNca.Enabled);
@ -183,7 +184,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
if (arg is DownloadableContentModel content)
{
return string.IsNullOrWhiteSpace(_search) || content.FileName.ToLower().Contains(_search.ToLower()) || content.TitleId.ToLower().Contains(_search.ToLower());
return string.IsNullOrWhiteSpace(_search) || content.FileName.ToLower().Contains(_search.ToLower()) || content.TitleIdStr.ToLower().Contains(_search.ToLower());
}
return false;
@ -261,7 +262,7 @@ namespace Ryujinx.Ava.UI.ViewModels
continue;
}
var content = new DownloadableContentModel(nca.Header.TitleId.ToString("X16"), path, fileEntry.FullPath, true);
var content = new DownloadableContentModel(nca.Header.TitleId, path, fileEntry.FullPath, true);
DownloadableContents.Add(content);
Dispatcher.UIThread.InvokeAsync(() => SelectedDownloadableContents.Add(content));
@ -327,7 +328,7 @@ namespace Ryujinx.Ava.UI.ViewModels
container.DownloadableContentNcaList.Add(new DownloadableContentNca
{
Enabled = downloadableContent.Enabled,
TitleId = Convert.ToUInt64(downloadableContent.TitleId, 16),
TitleId = downloadableContent.TitleId,
FullPath = downloadableContent.FullPath,
});
}

View file

@ -20,6 +20,7 @@ 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;
using System.IO;
@ -190,7 +191,7 @@ namespace Ryujinx.Ava.UI.ViewModels
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
var displayVersion = controlData.DisplayVersionString.ToString();
var update = new TitleUpdateModel(content.Version.Version, displayVersion, path);
var update = new TitleUpdateModel(content.ApplicationId, content.Version.Version, displayVersion, path);
TitleUpdates.Add(update);

View file

@ -6,13 +6,17 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
xmlns:models="clr-namespace:Ryujinx.UI.Common.Models;assembly=Ryujinx.UI.Common"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
Width="500"
Height="380"
mc:Ignorable="d"
x:DataType="viewModels:DownloadableContentManagerViewModel"
Focusable="True">
<UserControl.Resources>
<helpers:DownloadableContentLabelConverter x:Key="DownloadableContentLabel" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@ -96,8 +100,14 @@
VerticalAlignment="Center"
MaxLines="2"
TextWrapping="Wrap"
TextTrimming="CharacterEllipsis"
Text="{Binding Label}" />
TextTrimming="CharacterEllipsis">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource DownloadableContentLabel}">
<Binding Path="FileName" />
<Binding Path="IsBundled" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock
Grid.Column="1"
Margin="10 0"

View file

@ -8,6 +8,7 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.HLE.FileSystem;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Helper;
using Ryujinx.UI.Common.Models;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows
@ -92,7 +93,7 @@ namespace Ryujinx.Ava.UI.Windows
if (index != -1)
{
ViewModel.DownloadableContents[index].Enabled = true;
// ViewModel.DownloadableContents[index].Enabled = true;
}
}
}
@ -105,7 +106,7 @@ namespace Ryujinx.Ava.UI.Windows
if (index != -1)
{
ViewModel.DownloadableContents[index].Enabled = false;
// ViewModel.DownloadableContents[index].Enabled = false;
}
}
}

View file

@ -6,13 +6,17 @@
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
xmlns:models="clr-namespace:Ryujinx.UI.Common.Models;assembly=Ryujinx.UI.Common"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
Width="500"
Height="300"
mc:Ignorable="d"
x:DataType="viewModels:TitleUpdateViewModel"
Focusable="True">
<UserControl.Resources>
<helpers:TitleUpdateLabelConverter x:Key="TitleUpdateLabel" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
@ -38,8 +42,14 @@
<TextBlock
HorizontalAlignment="Left"
VerticalAlignment="Center"
TextWrapping="Wrap"
Text="{Binding Label}" />
TextWrapping="Wrap">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource TitleUpdateLabel}">
<Binding Path="DisplayVersion" />
<Binding Path="IsBundled" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<StackPanel
Spacing="10"
Orientation="Horizontal"

View file

@ -10,6 +10,7 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.HLE.FileSystem;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Helper;
using Ryujinx.UI.Common.Models;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows