From 0e26e2c7c57291f21c93b955fbee7b8454b582c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rmungandrk?= Date: Thu, 8 Jan 2026 21:59:52 +0700 Subject: [PATCH 1/2] feat: refactor countdown update in AFKOverlay Refactor updateCountdown method to use textContent for countdown updates. --- Frontend/ui-library/src/Overlay/AFKOverlay.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Frontend/ui-library/src/Overlay/AFKOverlay.ts b/Frontend/ui-library/src/Overlay/AFKOverlay.ts index 289d60412..9a5b64eea 100644 --- a/Frontend/ui-library/src/Overlay/AFKOverlay.ts +++ b/Frontend/ui-library/src/Overlay/AFKOverlay.ts @@ -44,6 +44,9 @@ export class AFKOverlay extends ActionOverlay { * @param countdown - the count down number to be inserted into the span for updating */ public updateCountdown(countdown: number): void { - this.textElement.innerHTML = `
No activity detected
Disconnecting in ${countdown} seconds
Click to continue
`; + const countDownSpan = this.textElement.querySelector('#afkCountDownNumber') as HTMLSpanElement | null; + if (countDownSpan) { + countDownSpan.textContent = String(countdown); + } } } From a812d0a8eef7116371844d79f84a22c8c93a5d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rmungandrk?= Date: Thu, 8 Jan 2026 15:44:36 +0000 Subject: [PATCH 2/2] fix: address additional issues identified during constructed from library input --- .../src/UI/DataChannelLatencyTest.ts | 35 +++++++++---- Frontend/ui-library/src/UI/LatencyTest.ts | 52 +++++++++++-------- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/Frontend/ui-library/src/UI/DataChannelLatencyTest.ts b/Frontend/ui-library/src/UI/DataChannelLatencyTest.ts index f415621a9..da02dc8c6 100644 --- a/Frontend/ui-library/src/UI/DataChannelLatencyTest.ts +++ b/Frontend/ui-library/src/UI/DataChannelLatencyTest.ts @@ -73,21 +73,34 @@ export class DataChannelLatencyTest { * Check we have results, NaN would mean that UE version we talk to doesn't support our test */ if (isNaN(result.dataChannelRtt)) { - this.latencyTestResultsElement.innerHTML = '
Not supported
'; + // Clear any previous content and show a simple "Not supported" message. + this.latencyTestResultsElement.textContent = ''; + const notSupportedDiv = document.createElement('div'); + notSupportedDiv.textContent = 'Not supported'; + this.latencyTestResultsElement.appendChild(notSupportedDiv); return; } - let latencyStatsInnerHTML = ''; - latencyStatsInnerHTML += '
Data channel RTT (ms): ' + result.dataChannelRtt + '
'; + + // Clear previous results before showing new ones. + this.latencyTestResultsElement.textContent = ''; + + const rttDiv = document.createElement('div'); + rttDiv.textContent = 'Data channel RTT (ms): ' + result.dataChannelRtt; + this.latencyTestResultsElement.appendChild(rttDiv); /** * Separate path time discovery works only when UE and Player clocks have been synchronized. */ if (result.playerToStreamerTime >= 0 && result.streamerToPlayerTime >= 0) { - latencyStatsInnerHTML += - '
Player to Streamer path (ms): ' + result.playerToStreamerTime + '
'; - latencyStatsInnerHTML += - '
Streamer to Player path (ms): ' + result.streamerToPlayerTime + '
'; + const playerToStreamerDiv = document.createElement('div'); + playerToStreamerDiv.textContent = + 'Player to Streamer path (ms): ' + result.playerToStreamerTime; + this.latencyTestResultsElement.appendChild(playerToStreamerDiv); + + const streamerToPlayerDiv = document.createElement('div'); + streamerToPlayerDiv.textContent = + 'Streamer to Player path (ms): ' + result.streamerToPlayerTime; + this.latencyTestResultsElement.appendChild(streamerToPlayerDiv); } - this.latencyTestResultsElement.innerHTML = latencyStatsInnerHTML; //setup button to download the detailed results const downloadButton: HTMLInputElement = document.createElement('input'); downloadButton.type = 'button'; @@ -111,6 +124,10 @@ export class DataChannelLatencyTest { } public handleTestStart() { - this.latencyTestResultsElement.innerHTML = '
Test in progress
'; + // Clear any previous results and show a "Test in progress" message. + this.latencyTestResultsElement.textContent = ''; + const inProgressDiv = document.createElement('div'); + inProgressDiv.textContent = 'Test in progress'; + this.latencyTestResultsElement.appendChild(inProgressDiv); } } diff --git a/Frontend/ui-library/src/UI/LatencyTest.ts b/Frontend/ui-library/src/UI/LatencyTest.ts index c02b89bce..55f086b75 100644 --- a/Frontend/ui-library/src/UI/LatencyTest.ts +++ b/Frontend/ui-library/src/UI/LatencyTest.ts @@ -70,50 +70,60 @@ export class LatencyTest { */ public handleTestResult(latencyTimings: LatencyTestResults) { Logger.Info(JSON.stringify(latencyTimings)); - let latencyStatsInnerHTML = ''; + + // Clear any previous results + const resultsElement = this.latencyTestResultsElement; + resultsElement.innerHTML = ''; if (latencyTimings.networkLatency !== undefined && latencyTimings.networkLatency > 0) { - latencyStatsInnerHTML += '
Net latency RTT (ms): ' + latencyTimings.networkLatency + '
'; + const div = document.createElement('div'); + div.textContent = 'Net latency RTT (ms): ' + latencyTimings.networkLatency; + resultsElement.appendChild(div); } if (latencyTimings.EncodeMs !== undefined && latencyTimings.EncodeMs > 0) { - latencyStatsInnerHTML += '
UE Encode (ms): ' + latencyTimings.EncodeMs + '
'; + const div = document.createElement('div'); + div.textContent = 'UE Encode (ms): ' + latencyTimings.EncodeMs; + resultsElement.appendChild(div); } if (latencyTimings.CaptureToSendMs !== undefined && latencyTimings.CaptureToSendMs > 0) { - latencyStatsInnerHTML += '
UE Capture (ms): ' + latencyTimings.CaptureToSendMs + '
'; + const div = document.createElement('div'); + div.textContent = 'UE Capture (ms): ' + latencyTimings.CaptureToSendMs; + resultsElement.appendChild(div); } if (latencyTimings.browserSendLatency !== undefined && latencyTimings.browserSendLatency > 0) { - latencyStatsInnerHTML += - '
Browser send latency (ms): ' + latencyTimings.browserSendLatency + '
'; + const div = document.createElement('div'); + div.textContent = 'Browser send latency (ms): ' + latencyTimings.browserSendLatency; + resultsElement.appendChild(div); } if ( latencyTimings.frameDisplayDeltaTimeMs !== undefined && latencyTimings.browserReceiptTimeMs !== undefined ) { - latencyStatsInnerHTML += - latencyTimings.frameDisplayDeltaTimeMs && latencyTimings.browserReceiptTimeMs - ? '
Browser receive latency (ms): ' + - latencyTimings.frameDisplayDeltaTimeMs + - '
' - : ''; + if (latencyTimings.frameDisplayDeltaTimeMs && latencyTimings.browserReceiptTimeMs) { + const div = document.createElement('div'); + div.textContent = + 'Browser receive latency (ms): ' + latencyTimings.frameDisplayDeltaTimeMs; + resultsElement.appendChild(div); + } } if (latencyTimings.latencyExcludingDecode !== undefined) { - latencyStatsInnerHTML += - '
Total latency (excluding browser) (ms): ' + - latencyTimings.latencyExcludingDecode + - '
'; + const div = document.createElement('div'); + div.textContent = + 'Total latency (excluding browser) (ms): ' + latencyTimings.latencyExcludingDecode; + resultsElement.appendChild(div); } if (latencyTimings.endToEndLatency !== undefined) { - latencyStatsInnerHTML += latencyTimings.endToEndLatency - ? '
Total latency (ms): ' + latencyTimings.endToEndLatency + '
' - : ''; + if (latencyTimings.endToEndLatency) { + const div = document.createElement('div'); + div.textContent = 'Total latency (ms): ' + latencyTimings.endToEndLatency; + resultsElement.appendChild(div); + } } - - this.latencyTestResultsElement.innerHTML = latencyStatsInnerHTML; } }