feat: add cloud save timestamp and force sync button

Shows a relative time label (e.g. "☁️ 2m ago") in the resource bar
seeded from the server on load and updated after every auto-save or
manual save. A 💾 button lets players trigger an immediate cloud save
outside the 30-second auto-save cycle, with a  spinner and disabled
state while the request is in-flight.
This commit is contained in:
2026-03-06 18:22:28 -08:00
committed by Naomi Carrigan
parent 285c38255b
commit 24beaf3131
4 changed files with 97 additions and 2 deletions
@@ -6,13 +6,29 @@ interface ResourceBarProps {
prestigeCount: number;
profileUrl: string;
onEditProfile: () => void;
lastSavedAt: number | null;
isSyncing: boolean;
onForceSync: () => Promise<void>;
}
const formatRelativeTime = (timestamp: number): string => {
const seconds = Math.floor((Date.now() - timestamp) / 1000);
if (seconds < 10) return "just now";
if (seconds < 60) return `${seconds}s ago`;
const minutes = Math.floor(seconds / 60);
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
return `${hours}h ago`;
};
export const ResourceBar = ({
resources,
prestigeCount,
profileUrl,
onEditProfile,
lastSavedAt,
isSyncing,
onForceSync,
}: ResourceBarProps): React.JSX.Element => (
<header className="resource-bar">
<div className="resource">
@@ -41,6 +57,20 @@ export const ResourceBar = ({
</div>
)}
<div className="profile-buttons">
{lastSavedAt !== null && (
<span className="save-status" title={new Date(lastSavedAt).toLocaleString()}>
{formatRelativeTime(lastSavedAt)}
</span>
)}
<button
className="force-save-button"
disabled={isSyncing}
onClick={onForceSync}
title="Force cloud save"
type="button"
>
{isSyncing ? "⏳" : "💾"}
</button>
<a
className="profile-link-button"
href={profileUrl}