import {useEffect, useRef, useState} from 'react'; import {FormattedMessage} from 'react-intl'; import {Button, Header, Icon, Message, Modal} from 'semantic-ui-react'; import {googleDriveService} from '../datasource/google_drive_service'; interface Props { /** The Google Drive file ID that initially failed to load. */ failedFileId: string; /** Callback triggered when the authentication and file selection are successful. */ onAuthSuccess: (fileId: string) => void; /** Callback triggered when the user cancels the modal. */ onCancel: () => void; } /** * Modal dialog that prompts the user to authenticate and select a specific file * from Google Drive when direct file loading fails due to insufficient permissions. */ export function GoogleAuthModal(props: Props) { const [loading, setLoading] = useState(false); const [showPickerInstructions, setShowPickerInstructions] = useState(false); const [errorMessage, setErrorMessage] = useState(null); const timeoutRef = useRef(null); useEffect(() => { return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); } }; }, []); async function completeAuthFlow(token: string) { const response = await window.fetch( `https://www.googleapis.com/drive/v3/files/${props.failedFileId}?alt=media`, { headers: { Authorization: `Bearer ${token}`, }, }, ); if (response.status === 200) { setLoading(false); props.onAuthSuccess(props.failedFileId); return; } setShowPickerInstructions(true); googleDriveService.showPicker( (pickedFileId) => { setLoading(false); props.onAuthSuccess(pickedFileId); }, () => { setLoading(false); }, ); } async function handleConnect() { setLoading(true); setErrorMessage(null); if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(() => { setLoading(false); timeoutRef.current = null; }, 20000); try { const token = await googleDriveService.requestToken(false); if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } await completeAuthFlow(token); } catch (err: unknown) { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } console.error('Auth error in fallback modal:', err); setErrorMessage( (err as Error).message || 'An error occurred during authentication.', ); setLoading(false); } } async function handleSwitchAccount() { setLoading(true); setErrorMessage(null); if (timeoutRef.current) { clearTimeout(timeoutRef.current); } timeoutRef.current = setTimeout(() => { setLoading(false); timeoutRef.current = null; }, 20000); try { const token = await googleDriveService.requestToken(true); if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } await completeAuthFlow(token); } catch (err: unknown) { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } console.error('Switch account error in fallback modal:', err); setErrorMessage( (err as Error).message || 'An error occurred during authentication.', ); setLoading(false); } } return (

{showPickerInstructions && (

)} {errorMessage && (

{errorMessage}

)}
{showPickerInstructions && ( )}
); }