From 525fc39cbfc178feac60a4088e72bf485d821d29 Mon Sep 17 00:00:00 2001 From: Delirium Date: Wed, 16 Oct 2024 12:40:06 +0200 Subject: [PATCH] ui: show tracker version incompat warning * tracker version warn * ui: show tracker version incompat warning --- frontend/app/components/Session_/Subheader.js | 59 ++----- .../app/components/Session_/WarnBadge.tsx | 146 ++++++++++++++++++ frontend/app/types/session/session.ts | 1 + 3 files changed, 159 insertions(+), 47 deletions(-) create mode 100644 frontend/app/components/Session_/WarnBadge.tsx diff --git a/frontend/app/components/Session_/Subheader.js b/frontend/app/components/Session_/Subheader.js index dcadfad65..ce8cd0464 100644 --- a/frontend/app/components/Session_/Subheader.js +++ b/frontend/app/components/Session_/Subheader.js @@ -1,5 +1,5 @@ import { ShareAltOutlined } from '@ant-design/icons'; -import { Button as AntButton, Switch, Tooltip } from 'antd'; +import { Button as AntButton, Popover, Switch, Tooltip } from 'antd'; import cn from 'classnames'; import { Link2 } from 'lucide-react'; import { observer } from 'mobx-react-lite'; @@ -11,7 +11,7 @@ import { useStore } from 'App/mstore'; import { checkParam, truncateStringToFit } from 'App/utils'; import SessionTabs from 'Components/Session/Player/SharedComponents/SessionTabs'; import KeyboardHelp from 'Components/Session_/Player/Controls/components/KeyboardHelp'; -import { Icon } from 'UI'; +import WarnBadge from 'Components/Session_/WarnBadge'; import Bookmark from 'Shared/Bookmark'; @@ -20,18 +20,13 @@ import Issues from './Issues/Issues'; import QueueControls from './QueueControls'; import NotePopup from './components/NotePopup'; -const localhostWarn = (project) => project + '_localhost_warn'; const disableDevtools = 'or_devtools_uxt_toggle'; function SubHeader(props) { - const { uxtestingStore, projectsStore, userStore, integrationsStore } = useStore(); + const { uxtestingStore, integrationsStore, sessionStore, projectsStore } = useStore(); + const currentSession = sessionStore.current + const projectId = projectsStore.siteId; const integrations = integrationsStore.issues.list; - const defaultLocalhostWarn = React.useMemo(() => { - const siteId = projectsStore.siteId; - const localhostWarnKey = localhostWarn(siteId); - return localStorage.getItem(localhostWarnKey) !== '1'; - }, [projectsStore.siteId]); - const [showWarningModal, setWarning] = React.useState(defaultLocalhostWarn); const { store } = React.useContext(PlayerContext); const { location: currentLocation = 'loading...' } = store.get(); const hasIframe = localStorage.getItem(IFRAME) === 'true'; @@ -56,15 +51,6 @@ function SubHeader(props) { window.innerWidth - 200 ); - const showWarning = - currentLocation && - /(localhost)|(127.0.0.1)|(0.0.0.0)/.test(currentLocation) && - showWarningModal; - const closeWarning = () => { - localStorage.setItem(localhostWarnKey, '1'); - setWarning(false); - }; - const toggleDevtools = (enabled) => { localStorage.setItem(disableDevtools, enabled ? '0' : '1'); uxtestingStore.setHideDevtools(!enabled); @@ -82,32 +68,11 @@ function SubHeader(props) { : undefined, }} > - {showWarning ? ( -
- Some assets may load incorrectly on localhost. - - Learn More - -
- -
-
- ) : null} + @@ -120,9 +85,9 @@ function SubHeader(props) { style={{ width: 'max-content' }} > - + - {enabledIntegration && } + {enabledIntegration && } project + '_localhost_warn'; + +const VersionComparison = { + Lower: -1, + Same: 0, + Higher: 1, +}; + +function compareVersions( + suppliedVersion: string, + currentVersion: string +): number { + function parseVersion(version: string) { + const cleanVersion = version.split(/[-+]/)[0]; + return cleanVersion.split('.').map(Number); + } + + const v1 = parseVersion(suppliedVersion); + const v2 = parseVersion(currentVersion); + + const length = Math.max(v1.length, v2.length); + while (v1.length < length) v1.push(0); + while (v2.length < length) v2.push(0); + + for (let i = 0; i < length; i++) { + if (v1[i] < v2[i]) return VersionComparison.Lower; + if (v1[i] > v2[i]) return VersionComparison.Higher; + } + + return VersionComparison.Same; +} + +const WarnBadge = React.memo( + ({ + currentLocation, + version, + siteId, + }: { + currentLocation: string; + version: string; + siteId: string; + }) => { + const localhostWarnSiteKey = localhostWarn(siteId); + const defaultLocalhostWarn = + localStorage.getItem(localhostWarnSiteKey) !== '1'; + const localhostWarnActive = + currentLocation && + defaultLocalhostWarn && + /(localhost)|(127.0.0.1)|(0.0.0.0)/.test(currentLocation); + const trackerVersion = window.env.TRACKER_VERSION ?? '1.0.0'; + const trackerVerDiff = compareVersions(version, trackerVersion); + const trackerWarnActive = trackerVerDiff !== VersionComparison.Same; + + const [showLocalhostWarn, setLocalhostWarn] = + React.useState(localhostWarnActive); + const [showTrackerWarn, setTrackerWarn] = React.useState(trackerWarnActive); + + const closeWarning = (type: 1 | 2) => { + if (type === 1) { + localStorage.setItem(localhostWarnSiteKey, '1'); + setLocalhostWarn(false); + } + if (type === 2) { + setTrackerWarn(false); + } + }; + + if (!showLocalhostWarn && !showTrackerWarn) return null; + + return ( +
+ {showLocalhostWarn ? ( +
+
+ Some assets may load incorrectly on localhost. + + Learn More + +
+ +
closeWarning(1)}> + +
+
+ ) : null} + {showTrackerWarn ? ( +
+
+
+ Tracker version({version}) for this recording is{' '} + {trackerVerDiff === VersionComparison.Lower + ? 'lower ' + : 'ahead of '} + the current({trackerVersion}) version. +
+
+ Some recording might display incorrectly. + + Learn More + +
+
+ +
closeWarning(2)}> + +
+
+ ) : null} +
+ ); + } +); + +export default WarnBadge; diff --git a/frontend/app/types/session/session.ts b/frontend/app/types/session/session.ts index 3de179b97..f1ac1042f 100644 --- a/frontend/app/types/session/session.ts +++ b/frontend/app/types/session/session.ts @@ -225,6 +225,7 @@ export default class Session { platform: ISession['platform']; isMobileNative?: ISession['isMobileNative']; audio?: ISession['audio']; + trackerVersion?: string; fileKey: ISession['fileKey']; durationSeconds: number;