import React from 'react'; import { Alert } from 'antd'; import { Icon } from 'UI'; import { useTranslation } from 'react-i18next'; import { ArrowUpRight, X } from 'lucide-react'; const localhostWarn = (project: string) => `${project}_localhost_warn`; const VersionComparison = { Lower: -1, Same: 0, Higher: 1, }; function parseVersion(version: string) { const cleanVersion = version.split(/[-+]/)[0]; return cleanVersion.split('.').map(Number); } function compareVersions( suppliedVersion: string, currentVersion: string, ): number { if (!suppliedVersion || !currentVersion) return VersionComparison.Same; const v1 = parseVersion(suppliedVersion); const v2 = parseVersion(currentVersion); if (v1[0] < v2[0]) return VersionComparison.Lower; if (v1[0] > v2[0]) return VersionComparison.Higher; return VersionComparison.Same; } // New optional override props added in WarnBadgeExtraProps interface WarnBadgeExtraProps { containerStyle?: React.CSSProperties; containerClassName?: string; localhostWarnStyle?: React.CSSProperties; localhostWarnClassName?: string; trackerWarnStyle?: React.CSSProperties; trackerWarnClassName?: string; } type Warns = [ localhostWarn: boolean, trackerWarn: boolean, virtualElsFailWarn: boolean, ]; const WarnBadge = React.memo( ({ currentLocation, version, siteId, containerStyle, containerClassName, localhostWarnStyle, localhostWarnClassName, trackerWarnStyle, trackerWarnClassName, virtualElsFailed, onVMode, }: { currentLocation: string; version: string; siteId: string; virtualElsFailed: boolean; onVMode: () => void; } & WarnBadgeExtraProps) => { const { t } = useTranslation(); const localhostWarnSiteKey = localhostWarn(siteId); const defaultLocalhostWarn = localStorage.getItem(localhostWarnSiteKey) !== '1'; const localhostWarnActive = Boolean( currentLocation && defaultLocalhostWarn && /(localhost)|(127.0.0.1)|(0.0.0.0)/.test(currentLocation), ); const trackerVersion = window.env.TRACKER_VERSION ?? undefined; const trackerVerDiff = compareVersions(version, trackerVersion); const trackerWarnActive = trackerVerDiff !== VersionComparison.Same; const [warnings, setWarnings] = React.useState([ localhostWarnActive, trackerWarnActive, virtualElsFailed, ]); React.useEffect(() => { setWarnings([localhostWarnActive, trackerWarnActive, virtualElsFailed]); }, [localhostWarnActive, trackerWarnActive, virtualElsFailed]); const closeWarning = (type: 0 | 1 | 2) => { if (type === 1) { localStorage.setItem(localhostWarnSiteKey, '1'); } setWarnings((prev: Warns) => { const newWarnings = [...prev]; newWarnings[type] = false; return newWarnings as Warns; }); }; if (!warnings.some((el) => el === true)) return null; // Default container styles and classes const defaultContainerStyle: React.CSSProperties = { zIndex: 999, position: 'absolute', left: '50%', bottom: '0', transform: 'translate(-50%, 80%)', fontWeight: 500, }; const defaultContainerClass = 'flex flex-col'; const defaultWarnClass = 'px-3 py-.5 border border-gray-lighter shadow-sm rounded bg-active-blue flex items-center justify-between'; // Merge defaults with any overrides const mergedContainerStyle = { ...defaultContainerStyle, ...containerStyle, }; const mergedContainerClassName = containerClassName ? defaultContainerClass + ' ' + containerClassName : defaultContainerClass; const mergedLocalhostWarnClassName = localhostWarnClassName ? defaultWarnClass + ' ' + localhostWarnClassName : defaultWarnClass; const mergedTrackerWarnClassName = trackerWarnClassName ? defaultWarnClass + ' ' + trackerWarnClassName : defaultWarnClass; return (
{warnings[0] ? (
{t('Some assets may load incorrectly on localhost.')} {t('Learn More')}
closeWarning(1)} >
) : null} {warnings[1] ? (
{t('Tracker version')}{' '} {version} {t('for this recording is')}{' '} {trackerVerDiff === VersionComparison.Lower ? 'lower ' : 'ahead of '} {t('the current')} {trackerVersion} {t('version')}.
{t('Some recording might display incorrectly.')} {t('Learn More')}
closeWarning(1)} >
) : null} {warnings[2] ? (
{t( 'If you have issues displaying custom HTML elements (i.e when using LWC), consider turning on Virtual Mode.', )}
{t('Enable')}
closeWarning(1)} >
) : null}
); }, ); export function PartialSessionBadge() { const { t } = useTranslation(); return (
); } export default WarnBadge;