mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-03-24 17:04:43 +00:00
Stats page should auto push stats when it reconnects to the websocket. Spectate page should auto pull when it reconnects to the websocket.
This commit is contained in:
@@ -13,6 +13,8 @@ export default class extends Controller {
|
||||
|
||||
connect() {
|
||||
console.log("Match data controller connected")
|
||||
this.isConnected = false
|
||||
this.pendingLocalSync = { w1: false, w2: false }
|
||||
|
||||
this.w1 = {
|
||||
name: "w1",
|
||||
@@ -69,6 +71,7 @@ export default class extends Controller {
|
||||
wrestler.updated_at = new Date().toISOString()
|
||||
this.updateHtmlValues()
|
||||
this.saveToLocalStorage(wrestler)
|
||||
if (!this.isConnected) this.pendingLocalSync[wrestler.name] = true
|
||||
|
||||
// Send the update via Action Cable if subscribed
|
||||
if (this.matchSubscription) {
|
||||
@@ -109,6 +112,7 @@ export default class extends Controller {
|
||||
// Update the internal JS object
|
||||
wrestler.stats = newValue
|
||||
wrestler.updated_at = new Date().toISOString()
|
||||
if (!this.isConnected) this.pendingLocalSync[wrestler.name] = true
|
||||
|
||||
// Save to localStorage
|
||||
this.saveToLocalStorage(wrestler)
|
||||
@@ -334,15 +338,18 @@ export default class extends Controller {
|
||||
{
|
||||
connected: () => {
|
||||
console.log(`[Stats AC] Connected to MatchStatsChannel for match ID: ${matchId}`)
|
||||
this.isConnected = true
|
||||
if (this.statusIndicatorTarget) {
|
||||
this.statusIndicatorTarget.innerText = "Connected: Stats will update in real-time."
|
||||
this.statusIndicatorTarget.classList.remove('alert-info', 'alert-warning', 'alert-danger')
|
||||
this.statusIndicatorTarget.classList.add('alert-success')
|
||||
}
|
||||
this.sendCurrentStatsOnReconnect()
|
||||
},
|
||||
|
||||
disconnected: () => {
|
||||
console.log(`[Stats AC] Disconnected from MatchStatsChannel`)
|
||||
this.isConnected = false
|
||||
if (this.statusIndicatorTarget) {
|
||||
this.statusIndicatorTarget.innerText = "Disconnected: Stats updates paused."
|
||||
this.statusIndicatorTarget.classList.remove('alert-info', 'alert-success', 'alert-danger')
|
||||
@@ -356,15 +363,25 @@ export default class extends Controller {
|
||||
// Update w1 stats
|
||||
if (data.w1_stat !== undefined && this.w1StatTarget) {
|
||||
console.log(`[Stats AC] Updating w1_stat: ${data.w1_stat.substring(0, 30)}...`)
|
||||
if (!this.pendingLocalSync.w1 || data.w1_stat === this.w1.stats) {
|
||||
this.w1.stats = data.w1_stat
|
||||
this.w1StatTarget.value = data.w1_stat
|
||||
this.pendingLocalSync.w1 = false
|
||||
} else {
|
||||
console.log('[Stats AC] Skipping w1_stat overwrite due to pending local changes.')
|
||||
}
|
||||
}
|
||||
|
||||
// Update w2 stats
|
||||
if (data.w2_stat !== undefined && this.w2StatTarget) {
|
||||
console.log(`[Stats AC] Updating w2_stat: ${data.w2_stat.substring(0, 30)}...`)
|
||||
if (!this.pendingLocalSync.w2 || data.w2_stat === this.w2.stats) {
|
||||
this.w2.stats = data.w2_stat
|
||||
this.w2StatTarget.value = data.w2_stat
|
||||
this.pendingLocalSync.w2 = false
|
||||
} else {
|
||||
console.log('[Stats AC] Skipping w2_stat overwrite due to pending local changes.')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -381,4 +398,23 @@ export default class extends Controller {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
sendCurrentStatsOnReconnect() {
|
||||
if (!this.matchSubscription) return
|
||||
const payload = {}
|
||||
if (typeof this.w1?.stats === 'string' && this.w1.stats.length > 0) {
|
||||
payload.new_w1_stat = this.w1.stats
|
||||
this.pendingLocalSync.w1 = true
|
||||
}
|
||||
if (typeof this.w2?.stats === 'string' && this.w2.stats.length > 0) {
|
||||
payload.new_w2_stat = this.w2.stats
|
||||
this.pendingLocalSync.w2 = true
|
||||
}
|
||||
if (Object.keys(payload).length > 0) {
|
||||
console.log('[ActionCable] Reconnect sync: sending current stats payload:', payload)
|
||||
this.matchSubscription.perform('send_stat', payload)
|
||||
} else {
|
||||
console.log('[ActionCable] Reconnect sync: no local stats to send.')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,11 @@ export default class extends Controller {
|
||||
this.statusIndicatorTarget.classList.remove('alert-danger', 'alert-secondary', 'text-danger', 'text-dark')
|
||||
this.statusIndicatorTarget.classList.add('alert-success')
|
||||
}
|
||||
try {
|
||||
this.matchSubscription.perform('request_sync')
|
||||
} catch (e) {
|
||||
console.error('[Spectator AC] request_sync perform failed:', e)
|
||||
}
|
||||
},
|
||||
disconnected: () => {
|
||||
console.log(`[Spectator AC Callback] Disconnected: ${matchId}`)
|
||||
|
||||
@@ -60,4 +60,29 @@ class MatchChannel < ApplicationCable::Channel
|
||||
Rails.logger.info "[MatchChannel] No new stat data provided in send_stat for match #{@match.id}, not updating DB or broadcasting."
|
||||
end
|
||||
end
|
||||
|
||||
# Called when client wants the latest stats immediately after reconnect
|
||||
def request_sync
|
||||
unless @match
|
||||
Rails.logger.error "[MatchChannel] Error: request_sync called but @match is nil. Client params on sub: #{params[:match_id]}"
|
||||
return
|
||||
end
|
||||
|
||||
payload = {
|
||||
w1_stat: @match.w1_stat,
|
||||
w2_stat: @match.w2_stat,
|
||||
score: @match.score,
|
||||
win_type: @match.win_type,
|
||||
winner_name: @match.winner&.name,
|
||||
winner_id: @match.winner_id,
|
||||
finished: @match.finished
|
||||
}.compact
|
||||
|
||||
if payload.present?
|
||||
Rails.logger.info "[MatchChannel] request_sync transmit for match #{@match.id} with payload: #{payload.inspect}"
|
||||
transmit(payload)
|
||||
else
|
||||
Rails.logger.info "[MatchChannel] request_sync payload empty for match #{@match.id}, not transmitting."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user