diff --git a/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx b/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx
index d9cf2c7db..b063fc72b 100644
--- a/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx
+++ b/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx
@@ -1,4 +1,5 @@
+import { useStore } from "App/mstore";
import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
@@ -25,7 +26,7 @@ const SESSIONS_ROUTE = sessionsRoute();
function PlayerBlockHeader(props: any) {
const [hideBack, setHideBack] = React.useState(false);
const { player, store } = React.useContext(PlayerContext);
-
+ const { uxtestingStore } = useStore()
const playerState = store?.get?.() || { width: 0, height: 0, showEvents: false }
const { width = 0, height = 0, showEvents = false } = playerState
@@ -92,7 +93,7 @@ function PlayerBlockHeader(props: any) {
- {live && !hideBack && (
+ {live && !hideBack && !uxtestingStore.isUxt() && (
<>
diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json
index e5e5d698e..9e29003dd 100644
--- a/tracker/tracker/package.json
+++ b/tracker/tracker/package.json
@@ -1,7 +1,7 @@
{
"name": "@openreplay/tracker",
"description": "The OpenReplay tracker main package",
- "version": "11.0.1-11",
+ "version": "11.0.1-19",
"keywords": [
"logging",
"replay"
diff --git a/tracker/tracker/src/main/app/index.ts b/tracker/tracker/src/main/app/index.ts
index c8d5e3fb0..7d495efaf 100644
--- a/tracker/tracker/src/main/app/index.ts
+++ b/tracker/tracker/src/main/app/index.ts
@@ -721,7 +721,9 @@ export default class App {
uxtId = qId ? parseInt(qId, 10) : undefined
}
}
- if (uxtId) this.uxtManager.getTest(uxtId, token, Boolean(savedUxtTag))
+ if (uxtId && !this.uxtManager.isActive) {
+ this.uxtManager.getTest(uxtId, token, Boolean(savedUxtTag))
+ }
return SuccessfulStart(onStartInfo)
})
diff --git a/tracker/tracker/src/main/modules/userTesting/index.ts b/tracker/tracker/src/main/modules/userTesting/index.ts
index 6ab6ddc0f..c72580ae4 100644
--- a/tracker/tracker/src/main/modules/userTesting/index.ts
+++ b/tracker/tracker/src/main/modules/userTesting/index.ts
@@ -53,6 +53,7 @@ export default class UserTestManager {
private widgetGuidelinesVisible = true
private widgetTasksVisible = false
private widgetVisible = true
+ public isActive = false
private descriptionSection: HTMLElement | null = null
private taskSection: HTMLElement | null = null
private endSection: HTMLElement | null = null
@@ -159,6 +160,7 @@ export default class UserTestManager {
})
.then((res) => res.json())
.then(({ test }: { test: Test }) => {
+ this.isActive = true
this.test = test
this.createGreeting(test.title, test.reqMic, test.reqCamera)
if (inProgress) {
@@ -552,7 +554,7 @@ export default class UserTestManager {
fontSize: '1.25rem',
fontWeight: '500',
},
- this.test?.reqMic || this.test?.reqCamera ? 'Uploading test recording...' : 'Thank you! 👍',
+ 'Thank you! 👍',
)
const description = createElement(
'div',
@@ -569,13 +571,27 @@ export default class UserTestManager {
styles.buttonWidgetStyle,
'Submitting Feedback',
)
+ const spinner = createSpinner()
+ button.appendChild(spinner)
if (this.test?.reqMic || this.test?.reqCamera) {
- void this.userRecorder.sendToAPI().then(() => {
- title.textContent = 'Thank you! 👍'
- button.textContent = 'End Session'
- isLoading = false
- })
+ void this.userRecorder
+ .sendToAPI()
+ .then(() => {
+ button.removeChild(spinner)
+ button.textContent = 'End Session'
+ isLoading = false
+ })
+ .catch((err) => {
+ console.error(err)
+ button.removeChild(spinner)
+ button.textContent = 'End Session'
+ isLoading = false
+ })
+ } else {
+ button.removeChild(spinner)
+ button.textContent = 'End Session'
+ isLoading = false
}
if (this.taskSection) {
@@ -646,3 +662,32 @@ function generateChevron() {
})
return container
}
+
+const spinnerStyles = {
+ border: '4px solid rgba(255, 255, 255, 0.4)',
+ width: '16px',
+ height: '16px',
+ borderRadius: '50%',
+ borderLeftColor: '#fff',
+ animation: 'spin 0.5s linear infinite',
+}
+
+function addKeyframes() {
+ const styleSheet = document.createElement('style')
+ styleSheet.type = 'text/css'
+ styleSheet.innerText = `@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }`
+ document.head.appendChild(styleSheet)
+}
+
+function createSpinner() {
+ addKeyframes()
+ const spinner = document.createElement('div')
+ spinner.classList.add('spinner')
+
+ Object.assign(spinner.style, spinnerStyles)
+
+ return spinner
+}