Track encounter start/end timestamps; display on card

startEncounter sets startedAt (clears endedAt on restart). endEncounter sets
endedAt. snapshotOf includes both for undo/redo fidelity. expandUndo split
start/end cases to restore old timestamps.

Display: encounter card shows Started/Ended independently (endedAt shows
even without startedAt). Undo sets null (can't delete via merge), test snap
strips only startedAt/endedAt null for compare.

Reviewed by pi gpt-5.5: stale endedAt on restart fixed, snap null-strip
narrowed. Medium-low risk.
This commit is contained in:
david raistrick
2026-07-07 16:41:34 -04:00
parent 9870d4df0d
commit 0fa3928bf8
3 changed files with 29 additions and 6 deletions
+5
View File
@@ -2258,6 +2258,11 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac
<p className="text-xs text-stone-300">
{encounter.createdAt && `${new Date(encounter.createdAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false })} · `}Participants: {encounter.participants?.length || 0}
</p>
{(encounter.startedAt || encounter.endedAt) && (
<p className="text-xs text-green-400/80 mt-0.5">
{encounter.startedAt && `⚔ Started: ${new Date(encounter.startedAt).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false })}`}{encounter.startedAt && encounter.endedAt && ' · '}{encounter.endedAt && `Ended: ${new Date(encounter.endedAt).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false })}`}
</p>
)}
{isLive && (
<span className="text-xs text-green-400 font-semibold block mt-1">
LIVE ON PLAYER DISPLAY