From 2099401803a122c23523f587ed88e47fa0092cbc Mon Sep 17 00:00:00 2001 From: PhilReact Date: Sat, 10 May 2025 22:27:56 +0300 Subject: [PATCH 1/2] added event for UI language to qapp --- src/components/Apps/AppViewer.tsx | 43 ++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/components/Apps/AppViewer.tsx b/src/components/Apps/AppViewer.tsx index 06a64c5..7ffeecd 100644 --- a/src/components/Apps/AppViewer.tsx +++ b/src/components/Apps/AppViewer.tsx @@ -5,6 +5,7 @@ import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events'; import { useFrame } from 'react-frame-component'; import { useQortalMessageListener } from './useQortalMessageListener'; import { useThemeContext } from '../Theme/ThemeContext'; +import { useTranslation } from 'react-i18next'; export const AppViewer = React.forwardRef( ({ app, hide, isDevMode, skipAuth }, iframeRef) => { @@ -22,11 +23,13 @@ export const AppViewer = React.forwardRef( ); const [url, setUrl] = useState(''); const { themeMode } = useThemeContext(); + const { i18n } = useTranslation(['core']); + const currentLang = i18n.language; useEffect(() => { if (app?.isPreview) return; if (isDevMode) { - setUrl(app?.url); + setUrl(app?.url + `?theme=${themeMode}&lang=${currentLang}`); return; } let hasQueryParam = false; @@ -35,14 +38,14 @@ export const AppViewer = React.forwardRef( } setUrl( - `${getBaseApiReact()}/render/${app?.service}/${app?.name}${app?.path != null ? `/${app?.path}` : ''}${hasQueryParam ? '&' : '?'}theme=${themeMode}&identifier=${app?.identifier != null && app?.identifier != 'null' ? app?.identifier : ''}` + `${getBaseApiReact()}/render/${app?.service}/${app?.name}${app?.path != null ? `/${app?.path}` : ''}${hasQueryParam ? '&' : '?'}theme=${themeMode}&lang=${currentLang}&identifier=${app?.identifier != null && app?.identifier != 'null' ? app?.identifier : ''}` ); }, [app?.service, app?.name, app?.identifier, app?.path, app?.isPreview]); useEffect(() => { if (app?.isPreview && app?.url) { resetHistory(); - setUrl(app.url); + setUrl(app.url + `&theme=${themeMode}&lang=${currentLang}`); } }, [app?.url, app?.isPreview]); const defaultUrl = useMemo(() => { @@ -55,11 +58,14 @@ export const AppViewer = React.forwardRef( if (isDevMode) { resetHistory(); if (!app?.isPreview || app?.isPrivate) { - setUrl(app?.url + `?time=${Date.now()}`); + setUrl( + app?.url + + `?time=${Date.now()}&theme=${themeMode}&lang=${currentLang}` + ); } return; } - const constructUrl = `${getBaseApiReact()}/render/${app?.service}/${app?.name}${path != null ? path : ''}?theme=${themeMode}&identifier=${app?.identifier != null ? app?.identifier : ''}&time=${new Date().getMilliseconds()}`; + const constructUrl = `${getBaseApiReact()}/render/${app?.service}/${app?.name}${path != null ? path : ''}?theme=${themeMode}&lang=${currentLang}&identifier=${app?.identifier != null ? app?.identifier : ''}&time=${new Date().getMilliseconds()}`; setUrl(constructUrl); } }; @@ -70,7 +76,7 @@ export const AppViewer = React.forwardRef( return () => { unsubscribeFromEvent('refreshApp', refreshAppFunc); }; - }, [app, path, isDevMode]); + }, [app, path, isDevMode, themeMode, currentLang]); useEffect(() => { const iframe = iframeRef?.current; @@ -87,6 +93,25 @@ export const AppViewer = React.forwardRef( } }, [themeMode]); + useEffect(() => { + const iframe = iframeRef?.current; + if (!iframe) return; + + try { + const targetOrigin = new URL(iframe.src).origin; + iframe.contentWindow?.postMessage( + { + action: 'LANGUAGE_CHANGED', + language: currentLang, + requestedHandler: 'UI', + }, + targetOrigin + ); + } catch (err) { + console.error('Failed to send theme change to iframe:', err); + } + }, [currentLang]); + const removeTrailingSlash = (str) => str.replace(/\/$/, ''); const copyLinkFunc = (e) => { @@ -181,12 +206,12 @@ export const AppViewer = React.forwardRef( } catch (error) { if (isDevMode) { setUrl( - `${url}${previousPath != null ? previousPath : ''}?theme=${themeMode}&time=${new Date().getMilliseconds()}&isManualNavigation=false` + `${url}${previousPath != null ? previousPath : ''}?theme=${themeMode}&lang=${currentLang}&time=${new Date().getMilliseconds()}&isManualNavigation=false` ); return; } setUrl( - `${getBaseApiReact()}/render/${app?.service}/${app?.name}${previousPath != null ? previousPath : ''}?theme=${themeMode}&identifier=${app?.identifier != null && app?.identifier != 'null' ? app?.identifier : ''}&time=${new Date().getMilliseconds()}&isManualNavigation=false` + `${getBaseApiReact()}/render/${app?.service}/${app?.name}${previousPath != null ? previousPath : ''}?theme=${themeMode}&lang=${currentLang}&identifier=${app?.identifier != null && app?.identifier != 'null' ? app?.identifier : ''}&time=${new Date().getMilliseconds()}&isManualNavigation=false` ); // iframeRef.current.contentWindow.location.href = previousPath; // Fallback URL update } @@ -209,7 +234,7 @@ export const AppViewer = React.forwardRef( navigateBackAppFunc ); }; - }, [app, history]); + }, [app, history, themeMode, currentLang]); // Function to navigate back in iframe const navigateForwardInIframe = async () => { From 54fa211e0653f0773d0ef3d135950ae9c6cd6d1e Mon Sep 17 00:00:00 2001 From: "nico.benaz" <52411515+nbenaglia@users.noreply.github.com> Date: Sat, 10 May 2025 23:09:18 +0200 Subject: [PATCH 2/2] Update src/components/Apps/AppViewer.tsx --- src/components/Apps/AppViewer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Apps/AppViewer.tsx b/src/components/Apps/AppViewer.tsx index 7ffeecd..87f88e8 100644 --- a/src/components/Apps/AppViewer.tsx +++ b/src/components/Apps/AppViewer.tsx @@ -108,7 +108,7 @@ export const AppViewer = React.forwardRef( targetOrigin ); } catch (err) { - console.error('Failed to send theme change to iframe:', err); + console.error('Failed to send language change to iframe:', err); } }, [currentLang]);