import React, { useContext, useEffect, useMemo, useState } from "react"; import { Avatar, Box, } from "@mui/material"; import { Add } from "@mui/icons-material"; import { MyContext, getBaseApiReact, isMobile } from "../../App"; import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events"; import { useFrame } from "react-frame-component"; import { useQortalMessageListener } from "./useQortalMessageListener"; export const AppViewer = React.forwardRef(({ app , hide}, iframeRef) => { const { rootHeight } = useContext(MyContext); // const iframeRef = useRef(null); const { document, window: frameWindow } = useFrame(); const {path, history, changeCurrentIndex} = useQortalMessageListener(frameWindow, iframeRef, app?.tabId) const [url, setUrl] = useState('') console.log('historyreact', history) useEffect(()=> { setUrl(`${getBaseApiReact()}/render/${app?.service}/${app?.name}${app?.path != null ? `/${app?.path}` : ''}?theme=dark&identifier=${(app?.identifier != null && app?.identifier != 'null') ? app?.identifier : ''}`) }, [app?.service, app?.name, app?.identifier, app?.path]) const defaultUrl = useMemo(()=> { return url }, [url]) const refreshAppFunc = (e) => { const {tabId} = e.detail if(tabId === app?.tabId){ const constructUrl = `${getBaseApiReact()}/render/${app?.service}/${app?.name}${path != null ? path : ''}?theme=dark&identifier=${app?.identifier != null ? app?.identifier : ''}&time=${new Date().getMilliseconds()}` setUrl(constructUrl) } }; useEffect(() => { subscribeToEvent("refreshApp", refreshAppFunc); return () => { unsubscribeFromEvent("refreshApp", refreshAppFunc); }; }, [app, path]); // Function to navigate back in iframe const navigateBackInIframe = async () => { if (iframeRef.current && iframeRef.current.contentWindow && history?.currentIndex > 0) { // Calculate the previous index and path const previousPageIndex = history.currentIndex - 1; const previousPath = history.customQDNHistoryPaths[previousPageIndex]; // Signal non-manual navigation iframeRef.current.contentWindow.postMessage( { action: 'PERFORMING_NON_MANUAL', currentIndex: previousPageIndex }, '*' ); console.log('previousPageIndex', previousPageIndex) // Update the current index locally changeCurrentIndex(previousPageIndex); // Create a navigation promise with a 200ms timeout const navigationPromise = new Promise((resolve, reject) => { function handleNavigationSuccess(event) { console.log('listeninghandlenav', event) if (event.data?.action === 'NAVIGATION_SUCCESS' && event.data.path === previousPath) { frameWindow.removeEventListener('message', handleNavigationSuccess); resolve(); } } frameWindow.addEventListener('message', handleNavigationSuccess); // Timeout after 200ms if no response setTimeout(() => { window.removeEventListener('message', handleNavigationSuccess); reject(new Error("Navigation timeout")); }, 200); // Send the navigation command after setting up the listener and timeout iframeRef.current.contentWindow.postMessage( { action: 'NAVIGATE_TO_PATH', path: previousPath, requestedHandler: 'UI' }, '*' ); }); // Execute navigation promise and handle timeout fallback try { await navigationPromise; console.log('Navigation succeeded within 200ms.'); } catch (error) { setUrl(`${getBaseApiReact()}/render/${app?.service}/${app?.name}${previousPath != null ? previousPath : ''}?theme=dark&identifier=${(app?.identifier != null && app?.identifier != 'null') ? app?.identifier : ''}&time=${new Date().getMilliseconds()}&isManualNavigation=false`) // iframeRef.current.contentWindow.location.href = previousPath; // Fallback URL update } } else { console.log('Iframe not accessible or does not have a content window.'); } }; const navigateBackAppFunc = (e) => { navigateBackInIframe() }; useEffect(() => { if(!app?.tabId) return subscribeToEvent(`navigateBackApp-${app?.tabId}`, navigateBackAppFunc); return () => { unsubscribeFromEvent(`navigateBackApp-${app?.tabId}`, navigateBackAppFunc); }; }, [app, history]); // Function to navigate back in iframe const navigateForwardInIframe = async () => { if (iframeRef.current && iframeRef.current.contentWindow) { console.log('iframeRef.contentWindow', iframeRef.current.contentWindow); iframeRef.current.contentWindow.postMessage( { action: 'NAVIGATE_FORWARD'}, '*' ); } else { console.log('Iframe not accessible or does not have a content window.'); } }; return ( ); });