jeanma's picture
Omnilingual ASR transcription demo
ae238b3 verified
import React from "react";
import CookieBanner from "./CookieBanner";
export const CONSENT_COOKIE_NAME = "omniasr_transcription_consent";
// Declare gtag global function
declare global {
interface Window {
gtag: (...args: any[]) => void;
dataLayer: any[];
}
}
const Analytics = () => {
const [analyticsEnabled, setAnalyticsEnabled] = React.useState(false);
const [consentState, setConsentState] = React.useState<boolean | null>(null); // In-memory fallback
const [showBanner, setShowBanner] = React.useState(false); // Control banner visibility
// Check if we're in iframe (like HuggingFace Spaces)
const isInIframe = () => {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
};
// Get consent with fallback chain: memory -> localStorage -> sessionStorage -> cookies
const getConsent = (): boolean => {
// First check in-memory state (for HF spaces that block all storage)
if (consentState !== null) {
return consentState;
}
// Try localStorage
try {
const localValue = window.localStorage.getItem(CONSENT_COOKIE_NAME);
if (localValue !== null) {
return localValue === "true";
}
} catch (e) {}
// Try sessionStorage
try {
const sessionValue = window.sessionStorage.getItem(CONSENT_COOKIE_NAME);
if (sessionValue !== null) {
return sessionValue === "true";
}
} catch (e) {}
// Try cookies
try {
return document.cookie.includes(`${CONSENT_COOKIE_NAME}=true`);
} catch (e) {}
return false;
};
// Set consent with fallback chain
const setConsent = (accepted: boolean) => {
// Always set in-memory state first (works in all environments)
setConsentState(accepted);
// Try localStorage
try {
window.localStorage.setItem(CONSENT_COOKIE_NAME, accepted.toString());
} catch (e) {}
// Try sessionStorage as fallback
try {
window.sessionStorage.setItem(CONSENT_COOKIE_NAME, accepted.toString());
} catch (e) {}
// Try cookies (mainly for non-iframe environments)
if (!isInIframe()) {
try {
const expires = new Date();
expires.setFullYear(expires.getFullYear() + 1);
document.cookie = `${CONSENT_COOKIE_NAME}=${accepted}; expires=${expires.toUTCString()}; path=/; SameSite=Lax`;
} catch (e) {}
}
};
// Load gtag script dynamically
const loadGtagScript = (gaId: string) => {
return new Promise<void>((resolve, reject) => {
// Check if gtag is already loaded
if (window.gtag) {
resolve();
return;
}
// Create script element
const script = document.createElement('script');
script.async = true;
script.src = `https://www.googletagmanager.com/gtag/js?id=${gaId}`;
script.onload = () => {
// Initialize gtag
window.dataLayer = window.dataLayer || [];
window.gtag = function gtag() {
window.dataLayer.push(arguments);
};
window.gtag('js', new Date());
window.gtag('config', gaId, {
// Settings for iframe environments
send_page_view: false, // We'll send manually
cookie_flags: 'max-age=7200;secure;samesite=none', // For iframe support
});
console.log('GA: gtag script loaded');
resolve();
};
script.onerror = () => {
console.error('❌ Failed to load gtag script');
reject(new Error('Failed to load gtag script'));
};
document.head.appendChild(script);
});
};
// Enable analytics if consent given
const handleAcceptCookie = React.useCallback(() => {
console.log('User accepted analytics cookies');
setConsent(true);
setShowBanner(false); // Hide banner after acceptance
const gaId = import.meta.env.VITE_REACT_APP_GOOGLE_ANALYTICS_ID;
const analyticsEnabled = import.meta.env.VITE_ENABLE_ANALYTICS === 'true';
if (gaId && analyticsEnabled) {
loadGtagScript(gaId)
.then(() => {
setAnalyticsEnabled(true);
console.log('GA initialized successfully');
// Send initial pageview
const pathname = window.location.pathname;
window.gtag('event', 'page_view', {
page_title: document.title,
page_location: window.location.href,
page_path: pathname,
});
})
.catch((e) => {
console.error('GA initialization failed:', e);
});
}
}, []);
const handleDeclineCookie = React.useCallback(() => {
console.log('User declined analytics cookies');
setConsent(false);
setShowBanner(false); // Hide banner after decline
}, []);
// Check for existing consent on mount
React.useEffect(() => {
const existingConsent = getConsent();
if (existingConsent) {
console.log('GA: Found existing consent, initializing...');
handleAcceptCookie();
setShowBanner(false); // Don't show banner if consent already exists
} else {
setShowBanner(true); // Show banner if no consent
}
}, [handleAcceptCookie]);
// Note: pageview is now sent directly in handleAcceptCookie when gtag is loaded
return showBanner ? (
<CookieBanner
onAccept={handleAcceptCookie}
onDecline={handleDeclineCookie}
/>
) : null;
};
export default Analytics;