aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Ryujinx.Ava/AppHost.cs2
-rw-r--r--src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml2
-rw-r--r--src/Ryujinx.Ava/UI/Helpers/NullableDateTimeConverter.cs38
-rw-r--r--src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs15
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs5
-rw-r--r--src/Ryujinx.Ui.Common/App/ApplicationData.cs45
-rw-r--r--src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs23
-rw-r--r--src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs13
-rw-r--r--src/Ryujinx/Ui/MainWindow.cs13
9 files changed, 113 insertions, 43 deletions
diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs
index 0955fb27..795c3f7a 100644
--- a/src/Ryujinx.Ava/AppHost.cs
+++ b/src/Ryujinx.Ava/AppHost.cs
@@ -671,7 +671,7 @@ namespace Ryujinx.Ava
_viewModel.ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata =>
{
- appMetadata.LastPlayed = DateTime.UtcNow.ToString();
+ appMetadata.LastPlayed = DateTime.UtcNow;
});
return true;
diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
index fa8ebf62..227b4723 100644
--- a/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
+++ b/src/Ryujinx.Ava/UI/Controls/ApplicationListView.axaml
@@ -129,7 +129,7 @@
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
- Text="{Binding LastPlayed}"
+ Text="{Binding LastPlayed, Converter={helpers:NullableDateTimeConverter}}"
TextAlignment="Right"
TextWrapping="Wrap" />
<TextBlock
diff --git a/src/Ryujinx.Ava/UI/Helpers/NullableDateTimeConverter.cs b/src/Ryujinx.Ava/UI/Helpers/NullableDateTimeConverter.cs
new file mode 100644
index 00000000..1d862de0
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Helpers/NullableDateTimeConverter.cs
@@ -0,0 +1,38 @@
+using Avalonia.Data.Converters;
+using Avalonia.Markup.Xaml;
+using Ryujinx.Ava.Common.Locale;
+using System;
+using System.Globalization;
+
+namespace Ryujinx.Ava.UI.Helpers
+{
+ internal class NullableDateTimeConverter : MarkupExtension, IValueConverter
+ {
+ private static readonly NullableDateTimeConverter _instance = new();
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value == null)
+ {
+ return LocaleManager.Instance[LocaleKeys.Never];
+ }
+
+ if (value is DateTime dateTime)
+ {
+ return dateTime.ToLocalTime().ToString(culture);
+ }
+
+ throw new NotSupportedException();
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override object ProvideValue(IServiceProvider serviceProvider)
+ {
+ return _instance;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs b/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
index 98caceb5..3627ada9 100644
--- a/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
+++ b/src/Ryujinx.Ava/UI/Models/Generic/LastPlayedSortComparer.cs
@@ -1,4 +1,3 @@
-using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ui.App.Common;
using System;
using System.Collections.Generic;
@@ -14,20 +13,20 @@ namespace Ryujinx.Ava.UI.Models.Generic
public int Compare(ApplicationData x, ApplicationData y)
{
- string aValue = x.LastPlayed;
- string bValue = y.LastPlayed;
+ var aValue = x.LastPlayed;
+ var bValue = y.LastPlayed;
- if (aValue == LocaleManager.Instance[LocaleKeys.Never])
+ if (!aValue.HasValue)
{
- aValue = DateTime.UnixEpoch.ToString();
+ aValue = DateTime.UnixEpoch;
}
- if (bValue == LocaleManager.Instance[LocaleKeys.Never])
+ if (!bValue.HasValue)
{
- bValue = DateTime.UnixEpoch.ToString();
+ bValue = DateTime.UnixEpoch;
}
- return (IsAscending ? 1 : -1) * DateTime.Compare(DateTime.Parse(bValue), DateTime.Parse(aValue));
+ return (IsAscending ? 1 : -1) * DateTime.Compare(bValue.Value, aValue.Value);
}
}
} \ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
index 4db78afe..f8dd4143 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
@@ -1524,10 +1524,9 @@ namespace Ryujinx.Ava.UI.ViewModels
{
ApplicationLibrary.LoadAndSaveMetaData(titleId, appMetadata =>
{
- if (DateTime.TryParse(appMetadata.LastPlayed, out DateTime lastPlayedDateTime))
+ if (appMetadata.LastPlayed.HasValue)
{
- double sessionTimePlayed = DateTime.UtcNow.Subtract(lastPlayedDateTime).TotalSeconds;
-
+ double sessionTimePlayed = DateTime.UtcNow.Subtract(appMetadata.LastPlayed.Value).TotalSeconds;
appMetadata.TimePlayed += Math.Round(sessionTimePlayed, MidpointRounding.AwayFromZero);
}
});
diff --git a/src/Ryujinx.Ui.Common/App/ApplicationData.cs b/src/Ryujinx.Ui.Common/App/ApplicationData.cs
index d9d3cf68..f0aa40be 100644
--- a/src/Ryujinx.Ui.Common/App/ApplicationData.cs
+++ b/src/Ryujinx.Ui.Common/App/ApplicationData.cs
@@ -10,27 +10,44 @@ using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem;
using System;
+using System.Globalization;
using System.IO;
+using System.Text.Json.Serialization;
namespace Ryujinx.Ui.App.Common
{
public class ApplicationData
{
- public bool Favorite { get; set; }
- public byte[] Icon { get; set; }
- public string TitleName { get; set; }
- public string TitleId { get; set; }
- public string Developer { get; set; }
- public string Version { get; set; }
- public string TimePlayed { get; set; }
- public double TimePlayedNum { get; set; }
- public string LastPlayed { get; set; }
- public string FileExtension { get; set; }
- public string FileSize { get; set; }
- public double FileSizeBytes { get; set; }
- public string Path { get; set; }
+ public bool Favorite { get; set; }
+ public byte[] Icon { get; set; }
+ public string TitleName { get; set; }
+ public string TitleId { get; set; }
+ public string Developer { get; set; }
+ public string Version { get; set; }
+ public string TimePlayed { get; set; }
+ public double TimePlayedNum { get; set; }
+ public DateTime? LastPlayed { get; set; }
+ public string FileExtension { get; set; }
+ public string FileSize { get; set; }
+ public double FileSizeBytes { get; set; }
+ public string Path { get; set; }
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
-
+
+ [JsonIgnore]
+ public string LastPlayedString
+ {
+ get
+ {
+ if (!LastPlayed.HasValue)
+ {
+ // TODO: maybe put localized string here instead of just "Never"
+ return "Never";
+ }
+
+ return LastPlayed.Value.ToLocalTime().ToString(CultureInfo.CurrentCulture);
+ }
+ }
+
public static string GetApplicationBuildId(VirtualFileSystem virtualFileSystem, string titleFilePath)
{
using FileStream file = new(titleFilePath, FileMode.Open, FileAccess.Read);
diff --git a/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs b/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs
index b7b57f1a..0407036a 100644
--- a/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs
+++ b/src/Ryujinx.Ui.Common/App/ApplicationLibrary.cs
@@ -414,21 +414,28 @@ namespace Ryujinx.Ui.App.Common
ApplicationMetadata appMetadata = LoadAndSaveMetaData(titleId, appMetadata =>
{
appMetadata.Title = titleName;
- });
- if (appMetadata.LastPlayed != "Never")
- {
- if (!DateTime.TryParse(appMetadata.LastPlayed, out _))
+ if (appMetadata.LastPlayedOld == default || appMetadata.LastPlayed.HasValue)
{
- Logger.Warning?.Print(LogClass.Application, $"Last played datetime \"{appMetadata.LastPlayed}\" is invalid for current system culture, skipping (did current culture change?)");
+ // Don't do the migration if last_played doesn't exist or last_played_utc already has a value.
+ return;
+ }
- appMetadata.LastPlayed = "Never";
+ // Migrate from string-based last_played to DateTime-based last_played_utc.
+ if (DateTime.TryParse(appMetadata.LastPlayedOld, out DateTime lastPlayedOldParsed))
+ {
+ Logger.Info?.Print(LogClass.Application, $"last_played found: \"{appMetadata.LastPlayedOld}\", migrating to last_played_utc");
+ appMetadata.LastPlayed = lastPlayedOldParsed;
+
+ // Migration successful: deleting last_played from the metadata file.
+ appMetadata.LastPlayedOld = default;
}
else
{
- appMetadata.LastPlayed = appMetadata.LastPlayed[..^3];
+ // Migration failed: emitting warning but leaving the unparsable value in the metadata file so the user can fix it.
+ Logger.Warning?.Print(LogClass.Application, $"Last played string \"{appMetadata.LastPlayedOld}\" is invalid for current system culture, skipping (did current culture change?)");
}
- }
+ });
ApplicationData data = new()
{
diff --git a/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs b/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs
index e19f7483..0abd4680 100644
--- a/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs
+++ b/src/Ryujinx.Ui.Common/App/ApplicationMetadata.cs
@@ -1,10 +1,19 @@
-namespace Ryujinx.Ui.App.Common
+using System;
+using System.Text.Json.Serialization;
+
+namespace Ryujinx.Ui.App.Common
{
public class ApplicationMetadata
{
public string Title { get; set; }
public bool Favorite { get; set; }
public double TimePlayed { get; set; }
- public string LastPlayed { get; set; } = "Never";
+
+ [JsonPropertyName("last_played_utc")]
+ public DateTime? LastPlayed { get; set; } = null;
+
+ [JsonPropertyName("last_played")]
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
+ public string LastPlayedOld { get; set; }
}
} \ No newline at end of file
diff --git a/src/Ryujinx/Ui/MainWindow.cs b/src/Ryujinx/Ui/MainWindow.cs
index f4cb3d07..7cae6222 100644
--- a/src/Ryujinx/Ui/MainWindow.cs
+++ b/src/Ryujinx/Ui/MainWindow.cs
@@ -876,7 +876,7 @@ namespace Ryujinx.Ui
_applicationLibrary.LoadAndSaveMetaData(_emulationContext.Processes.ActiveApplication.ProgramIdText, appMetadata =>
{
- appMetadata.LastPlayed = DateTime.UtcNow.ToString();
+ appMetadata.LastPlayed = DateTime.UtcNow;
});
}
}
@@ -1019,10 +1019,11 @@ namespace Ryujinx.Ui
{
_applicationLibrary.LoadAndSaveMetaData(titleId, appMetadata =>
{
- DateTime lastPlayedDateTime = DateTime.Parse(appMetadata.LastPlayed);
- double sessionTimePlayed = DateTime.UtcNow.Subtract(lastPlayedDateTime).TotalSeconds;
-
- appMetadata.TimePlayed += Math.Round(sessionTimePlayed, MidpointRounding.AwayFromZero);
+ if (appMetadata.LastPlayed.HasValue)
+ {
+ double sessionTimePlayed = DateTime.UtcNow.Subtract(appMetadata.LastPlayed.Value).TotalSeconds;
+ appMetadata.TimePlayed += Math.Round(sessionTimePlayed, MidpointRounding.AwayFromZero);
+ }
});
}
}
@@ -1089,7 +1090,7 @@ namespace Ryujinx.Ui
args.AppData.Developer,
args.AppData.Version,
args.AppData.TimePlayed,
- args.AppData.LastPlayed,
+ args.AppData.LastPlayedString,
args.AppData.FileExtension,
args.AppData.FileSize,
args.AppData.Path,