Fix iframe reloaded on each theme change (#3491)
* Fix iframe reloaded on each theme change * CR
This commit is contained in:
parent
7a3d311aaf
commit
593867f0c5
2 changed files with 62 additions and 20 deletions
|
@ -1,15 +1,14 @@
|
|||
import { useAppDashboardUpdates } from "@dashboard/apps/components/AppFrame/useAppDashboardUpdates";
|
||||
import {
|
||||
AppDetailsUrlQueryParams,
|
||||
AppUrls,
|
||||
prepareFeatureFlagsList,
|
||||
} from "@dashboard/apps/urls";
|
||||
import { useAllFlags } from "@dashboard/hooks/useFlags";
|
||||
import { CircularProgress } from "@material-ui/core";
|
||||
import { useTheme } from "@saleor/macaw-ui";
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
|
||||
import { AppIFrame } from "./AppIFrame";
|
||||
import { useStyles } from "./styles";
|
||||
import { useAppActions } from "./useAppActions";
|
||||
import useTokenRefresh from "./useTokenRefresh";
|
||||
|
@ -21,7 +20,6 @@ interface Props {
|
|||
className?: string;
|
||||
params?: AppDetailsUrlQueryParams;
|
||||
refetch?: () => void;
|
||||
onLoad?(): void;
|
||||
onError?(): void;
|
||||
}
|
||||
|
||||
|
@ -32,13 +30,11 @@ export const AppFrame: React.FC<Props> = ({
|
|||
appToken,
|
||||
appId,
|
||||
className,
|
||||
params = {},
|
||||
onLoad,
|
||||
params,
|
||||
onError,
|
||||
refetch,
|
||||
}) => {
|
||||
const frameRef = React.useRef<HTMLIFrameElement | null>(null);
|
||||
const { themeType } = useTheme();
|
||||
const classes = useStyles();
|
||||
const appOrigin = getOrigin(src);
|
||||
const flags = useAllFlags();
|
||||
|
@ -60,7 +56,7 @@ export const AppFrame: React.FC<Props> = ({
|
|||
|
||||
useTokenRefresh(appToken, refetch);
|
||||
|
||||
const handleLoad = () => {
|
||||
const handleLoad = useCallback(() => {
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
|
@ -76,11 +72,9 @@ export const AppFrame: React.FC<Props> = ({
|
|||
});
|
||||
|
||||
setHandshakeDone(true);
|
||||
}, [appToken, postToExtension, setHandshakeDone]);
|
||||
|
||||
if (onLoad) {
|
||||
onLoad();
|
||||
}
|
||||
};
|
||||
const featureFlags = useMemo(() => prepareFeatureFlagsList(flags), [flags]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -89,19 +83,17 @@ export const AppFrame: React.FC<Props> = ({
|
|||
<CircularProgress color="primary" />
|
||||
</div>
|
||||
)}
|
||||
<iframe
|
||||
<AppIFrame
|
||||
ref={frameRef}
|
||||
src={AppUrls.resolveAppIframeUrl(appId, src, {
|
||||
...params,
|
||||
featureFlags: prepareFeatureFlagsList(flags),
|
||||
theme: themeType,
|
||||
})}
|
||||
onError={onError}
|
||||
src={src}
|
||||
appId={appId}
|
||||
featureFlags={featureFlags}
|
||||
params={params}
|
||||
onLoad={handleLoad}
|
||||
onError={onError}
|
||||
className={clsx(classes.iframe, className, {
|
||||
[classes.iframeHidden]: !handshakeDone,
|
||||
})}
|
||||
sandbox="allow-same-origin allow-forms allow-scripts"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
50
src/apps/components/AppFrame/AppIFrame.tsx
Normal file
50
src/apps/components/AppFrame/AppIFrame.tsx
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { AppDetailsUrlQueryParams, AppUrls } from "@dashboard/apps/urls";
|
||||
import { ThemeType } from "@saleor/app-sdk/app-bridge";
|
||||
import { useTheme } from "@saleor/macaw-ui";
|
||||
import isEqualWith from "lodash/isEqualWith";
|
||||
import React, { forwardRef, memo, useEffect, useRef } from "react";
|
||||
|
||||
interface AppIFrameProps {
|
||||
appId: string;
|
||||
src: string;
|
||||
featureFlags: Record<string, string>;
|
||||
params: AppDetailsUrlQueryParams;
|
||||
onLoad: () => void;
|
||||
onError: () => void;
|
||||
className: string;
|
||||
}
|
||||
|
||||
const _AppIFrame = forwardRef<HTMLIFrameElement, AppIFrameProps>(
|
||||
({ appId, src, featureFlags, params, onLoad, onError, className }, ref) => {
|
||||
const themeRef = useRef<ThemeType>();
|
||||
const { themeType } = useTheme();
|
||||
|
||||
// Ignore updates to themeType - iframe will be notified via events
|
||||
// Otherwise this will cause reload of entire iframe
|
||||
useEffect(() => {
|
||||
themeRef.current = themeType;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const iframeSrc = AppUrls.resolveAppIframeUrl(appId, src, {
|
||||
...params,
|
||||
featureFlags,
|
||||
theme: themeRef.current,
|
||||
});
|
||||
|
||||
return (
|
||||
<iframe
|
||||
ref={ref}
|
||||
src={iframeSrc}
|
||||
onLoad={onLoad}
|
||||
onError={onError}
|
||||
className={className}
|
||||
sandbox="allow-same-origin allow-forms allow-scripts"
|
||||
/>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const AppIFrame = memo(_AppIFrame, (prev, next) =>
|
||||
isEqualWith(prev, next),
|
||||
);
|
Loading…
Reference in a new issue