import { useContext, useEffect, useRef, useState } from 'react' import { useLocation } from 'react-router-dom' import { Flex, Card, Alert, Button } from 'antd' import { LoadingOutlined } from '@ant-design/icons' import { customAlphabet } from 'nanoid' import AuthParticles from './AppParticles' import FarmControlLogo from '../Logos/FarmControlLogo' import ExclamationOctagonIcon from '../Icons/ExclamationOctagonIcon' import CheckIcon from '../Icons/CheckIcon' import ReloadIcon from '../Icons/ReloadIcon' import { ApiServerContext } from '../Dashboard/context/ApiServerContext' const createLaunchSession = customAlphabet( '01abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 32 ) const AuthLaunch = () => { const location = useLocation() const hasRedirected = useRef(false) const startTimeoutRef = useRef(null) const pollTimeoutRef = useRef(null) const { getAppLaunchSession } = useContext(ApiServerContext) const [launchError, setLaunchError] = useState(false) const [launchErrorMessage, setLaunchErrorMessage] = useState('') const [launchSuccess, setLaunchSuccess] = useState(false) const handleRefresh = () => { window.location.reload() } useEffect(() => { let cancelled = false const redirect = new URLSearchParams(location.search).get('redirect') const redirectType = new URLSearchParams(location.search).get( 'redirectType' ) if (!redirect) { setLaunchError(true) setLaunchErrorMessage('No redirect provided!') return } if (!redirect || hasRedirected.current) { return } startTimeoutRef.current = setTimeout(() => { if (cancelled) { return } hasRedirected.current = true const launchSession = createLaunchSession() let launchCheckCount = 0 setLaunchError(false) setLaunchErrorMessage('') setLaunchSuccess(false) let redirectWithLaunchSession = redirect try { const redirectUrl = new URL(redirect, window.location.origin) redirectUrl.searchParams.set('launchSession', launchSession) redirectWithLaunchSession = redirectUrl.toString() } catch { const hasQuery = redirect.includes('?') const separator = hasQuery ? '&' : '?' redirectWithLaunchSession = `${redirect}${separator}launchSession=${encodeURIComponent( launchSession )}` } const link = document.createElement('a') link.href = redirectWithLaunchSession link.style.display = 'none' if (redirectType === 'app-localhost') { link.addEventListener('click', (event) => { event.preventDefault() window.open( redirectWithLaunchSession, 'farmcontrol-launch', 'width=480,height=640,menubar=no,toolbar=no,location=yes,status=no,resizable=yes,scrollbars=yes' ) }) } document.body.appendChild(link) link.click() document.body.removeChild(link) const checkLaunchSession = async () => { launchCheckCount += 1 let launchComplete = false try { const launchStatus = await getAppLaunchSession(launchSession) launchComplete = launchStatus?.complete === true } catch { launchComplete = false } if (cancelled) { return } if (launchComplete) { setLaunchSuccess(true) return } if (launchCheckCount >= 10) { setLaunchError(true) setLaunchErrorMessage('Failed to open Farm Control.') return } pollTimeoutRef.current = setTimeout(() => { checkLaunchSession() }, 1000) } checkLaunchSession() }, 0) return () => { cancelled = true hasRedirected.current = false if (startTimeoutRef.current) { clearTimeout(startTimeoutRef.current) } if (pollTimeoutRef.current) { clearTimeout(pollTimeoutRef.current) } } }, [getAppLaunchSession, location.search]) return (