From d7c0b79549ecd786932a8284341664bbcff43b43 Mon Sep 17 00:00:00 2001 From: josedario87 Date: Wed, 27 Aug 2025 18:23:22 -0600 Subject: [PATCH] system message guardados en historial por sala --- client/src/components/DashboardActions.vue | 11 +++++++++-- client/src/components/RoomCard.vue | 20 +++++++++++++++++++- server/src/rooms/GameRoom.ts | 7 +++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/client/src/components/DashboardActions.vue b/client/src/components/DashboardActions.vue index 48aefa5..ab388cf 100644 --- a/client/src/components/DashboardActions.vue +++ b/client/src/components/DashboardActions.vue @@ -30,6 +30,7 @@ interface RoomDetail { gameStatus?: string; variant?: string; round?: number; + systemMessages?: Array<{ text: string; kind: string; timestamp: number }>; } const props = defineProps<{ rooms: any[]; roomDetails: { [key: string]: RoomDetail } }>(); @@ -46,7 +47,8 @@ function buildCsvByRoom(): string { const headers = [ 'roomId', 'variant', 'round', 'status', 'p1_uuid', 'p1_name', 'p1_pavo', 'p1_elote', 'p1_shame', - 'p2_uuid', 'p2_name', 'p2_pavo', 'p2_elote', 'p2_shame' + 'p2_uuid', 'p2_name', 'p2_pavo', 'p2_elote', 'p2_shame', + 'events_history' ]; const lines: string[] = [headers.join(',')]; @@ -59,6 +61,9 @@ function buildCsvByRoom(): string { const p1 = players.find(p => p.role === 'P1') || players[0] || ({} as any); const p2 = players.find(p => p.role === 'P2') || players[1] || ({} as any); + const kinds = ((det.systemMessages || []) as Array<{ kind: string }>).map(m => (m?.kind || '').toString()).filter(Boolean); + const eventsHistory = kinds.join('|'); + const row = [ room.roomId, variant, @@ -73,7 +78,8 @@ function buildCsvByRoom(): string { p2?.name || '', p2?.pavoTokens ?? 0, p2?.eloteTokens ?? 0, - p2?.shameTokens ?? 0 + p2?.shameTokens ?? 0, + eventsHistory ].map(csvEscape).join(','); lines.push(row); }); @@ -114,6 +120,7 @@ function buildCsvByUuid(): string { return lines.join('\n') + '\n'; } + function triggerDownload(csv: string, suffix: string) { const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); diff --git a/client/src/components/RoomCard.vue b/client/src/components/RoomCard.vue index 47537d4..00de836 100644 --- a/client/src/components/RoomCard.vue +++ b/client/src/components/RoomCard.vue @@ -88,6 +88,16 @@ {{ roomDetails.winner }} + +
+
System Messages
+
+
+ {{ formatTime(m.timestamp) }} + {{ m.text }} +
+
+
@@ -116,6 +126,7 @@ interface RoomDetails { }>; timeRemaining: number; winner?: string; + systemMessages?: Array<{ text: string; kind: string; timestamp: number }>; } defineProps<{ @@ -350,4 +361,11 @@ function formatSeconds(seconds: number): string { color: #4caf50; font-weight: bold; } - \ No newline at end of file + +.system-messages { margin-top: 14px; } +.sys-head { font-weight: 800; font-size: 13px; color:#556; margin-bottom: 6px; } +.sys-list { display:flex; flex-direction:column; gap:6px; max-height: 180px; overflow:auto; padding-right: 4px; } +.sys-item { display:flex; gap:8px; align-items:center; background:#f8f9fa; border:1px solid #eee; border-radius:8px; padding:6px 8px; } +.sys-time { font-family: monospace; font-size: 11px; color:#666; } +.sys-text { font-size: 13px; font-weight:600; color:#333; } + diff --git a/server/src/rooms/GameRoom.ts b/server/src/rooms/GameRoom.ts index df102dd..1dafc8d 100644 --- a/server/src/rooms/GameRoom.ts +++ b/server/src/rooms/GameRoom.ts @@ -6,6 +6,7 @@ import { broadcastDashboardUpdate } from "../adminApi"; export class GameRoom extends Room { maxClients = 2; + private systemMessages: { text: string; kind: string; timestamp: number }[] = []; getFilterOptions() { // If waiting for shuffled players, report as available regardless of current client count @@ -45,6 +46,11 @@ export class GameRoom extends Room { if (kind !== 'round_advance') { this.recentSystemMessage = { text, kind, timestamp }; } + // Persist in per-room history (keep last 200) + this.systemMessages.push({ text, kind, timestamp }); + if (this.systemMessages.length > 200) { + this.systemMessages.splice(0, this.systemMessages.length - 200); + } this.broadcast("chat", { id: `${timestamp}-${Math.random().toString(36).slice(2)}`, @@ -937,6 +943,7 @@ export class GameRoom extends Room { variant: this.state.currentVariant, round: this.state.currentRound, recentSystemMessage: this.recentSystemMessage, + systemMessages: this.systemMessages.slice(-50), decisions: { p1Action: this.state.p1Action, p2Action: this.state.p2Action,