Update "Last Played" text every minute, localize

This commit is contained in:
Pat Hartl 2026-06-21 23:33:52 -05:00
parent 2e8e4ae3ae
commit 9bc44500fc
2 changed files with 75 additions and 20 deletions

View file

@ -121,6 +121,19 @@
<sys:String x:Key="InstallStatusFailed">Failed</sys:String>
<sys:String x:Key="InstallStatusQueued">Queued</sys:String>
<!-- ── Play Stats ────────────────────────────────────────────────────── -->
<sys:String x:Key="PlayStatNone">None</sys:String>
<sys:String x:Key="PlayTimeMinutes">{0} minutes</sys:String>
<sys:String x:Key="PlayTimeHours">{0} hours</sys:String>
<sys:String x:Key="LastPlayedNever">Never</sys:String>
<sys:String x:Key="LastPlayedJustNow">Just now</sys:String>
<sys:String x:Key="LastPlayedMinuteAgo">{0} minute ago</sys:String>
<sys:String x:Key="LastPlayedMinutesAgo">{0} minutes ago</sys:String>
<sys:String x:Key="LastPlayedHourAgo">{0} hour ago</sys:String>
<sys:String x:Key="LastPlayedHoursAgo">{0} hours ago</sys:String>
<sys:String x:Key="LastPlayedDayAgo">{0} day ago</sys:String>
<sys:String x:Key="LastPlayedDaysAgo">{0} days ago</sys:String>
<!-- ── Game Detail ───────────────────────────────────────────────────── -->
<sys:String x:Key="Singleplayer">Singleplayer</sys:String>
<sys:String x:Key="Genres">Genres</sys:String>

View file

@ -88,10 +88,10 @@ public partial class GameActionBarViewModel : ViewModelBase
// Stats
[ObservableProperty]
private string _playTime = "None";
private string _playTime = Localize("PlayStatNone");
[ObservableProperty]
private string _lastPlayed = "Never";
private string _lastPlayed = Localize("LastPlayedNever");
// Status
[ObservableProperty]
@ -172,6 +172,12 @@ public partial class GameActionBarViewModel : ViewModelBase
// Timer for checking running state
private System.Threading.Timer? _runningCheckTimer;
// Timer for refreshing the "Last Played" relative time text
private System.Threading.Timer? _lastPlayedTimer;
// End time of the most recent play session, used to recompute the relative text
private DateTime? _lastSessionEnd;
// Events
public event EventHandler? LibraryChanged;
public event EventHandler? InstallRequested;
@ -245,8 +251,8 @@ public partial class GameActionBarViewModel : ViewModelBase
IsInstalled = false;
InstallDirectory = null;
IsUpdateAvailable = false;
PlayTime = "None";
LastPlayed = "Never";
PlayTime = Localize("PlayStatNone");
LastPlayed = Localize("LastPlayedNever");
Manuals.Clear();
HasManuals = false;
}
@ -362,12 +368,22 @@ public partial class GameActionBarViewModel : ViewModelBase
null,
TimeSpan.Zero,
TimeSpan.FromMilliseconds(500));
_lastPlayedTimer?.Dispose();
_lastPlayedTimer = new System.Threading.Timer(
_ => Dispatcher.UIThread.Post(UpdateLastPlayedText),
null,
TimeSpan.FromMinutes(1),
TimeSpan.FromMinutes(1));
}
public void StopRunningCheck()
{
_runningCheckTimer?.Dispose();
_runningCheckTimer = null;
_lastPlayedTimer?.Dispose();
_lastPlayedTimer = null;
}
private void CheckRunningState()
@ -443,35 +459,61 @@ public partial class GameActionBarViewModel : ViewModelBase
.Sum(ts => ts.Ticks));
if (totalTime.TotalMinutes < 1)
PlayTime = "None";
PlayTime = Localize("PlayStatNone");
else if (totalTime.TotalHours < 1)
PlayTime = $"{totalTime.TotalMinutes:0} minutes";
PlayTime = Localize("PlayTimeMinutes", $"{totalTime.TotalMinutes:0}");
else
PlayTime = $"{totalTime.TotalHours:0.#} hours";
PlayTime = Localize("PlayTimeHours", $"{totalTime.TotalHours:0.#}");
var lastSession = playSessions
.OrderByDescending(ps => ps.End)
.First();
var elapsed = DateTime.Now - lastSession.End!.Value;
if (elapsed.TotalMinutes < 1)
LastPlayed = "Just now";
else if (elapsed.TotalHours < 1)
LastPlayed = $"{elapsed.TotalMinutes:0} minutes ago";
else if (elapsed.TotalDays < 1)
LastPlayed = $"{elapsed.TotalHours:0} hours ago";
else if (elapsed.TotalDays < 7)
LastPlayed = $"{elapsed.TotalDays:0} days ago";
else
LastPlayed = lastSession.End.Value.ToString("MMM d, yyyy");
_lastSessionEnd = lastSession.End!.Value;
UpdateLastPlayedText();
}
else
{
PlayTime = "None";
LastPlayed = "Never";
PlayTime = Localize("PlayStatNone");
_lastSessionEnd = null;
LastPlayed = Localize("LastPlayedNever");
}
}
/// <summary>
/// Recomputes the relative "Last Played" text from the cached last session end time.
/// Called on load and periodically so the text stays current without re-querying.
/// </summary>
private void UpdateLastPlayedText()
{
if (_lastSessionEnd is not { } end)
{
LastPlayed = Localize("LastPlayedNever");
return;
}
var elapsed = DateTime.Now - end;
if (elapsed.TotalMinutes < 1)
LastPlayed = Localize("LastPlayedJustNow");
else if (elapsed.TotalHours < 1)
{
var minutes = (int)elapsed.TotalMinutes;
LastPlayed = Localize(minutes == 1 ? "LastPlayedMinuteAgo" : "LastPlayedMinutesAgo", minutes);
}
else if (elapsed.TotalDays < 1)
{
var hours = (int)elapsed.TotalHours;
LastPlayed = Localize(hours == 1 ? "LastPlayedHourAgo" : "LastPlayedHoursAgo", hours);
}
else if (elapsed.TotalDays < 7)
{
var days = (int)elapsed.TotalDays;
LastPlayed = Localize(days == 1 ? "LastPlayedDayAgo" : "LastPlayedDaysAgo", days);
}
else
LastPlayed = end.ToString("MMM d, yyyy");
}
/// <summary>
/// Checks the server for available updates and updates local state if found.
/// If no update is available, refreshes the on-disk manifest and scripts.