Fix iframe reloaded on each theme change (#3491)

* Fix iframe reloaded on each theme change

* CR
This commit is contained in:
Jonatan Witoszek 2023-04-13 14:18:14 +02:00 committed by GitHub
parent 7a3d311aaf
commit 593867f0c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 20 deletions

View file

@ -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"
/>
</>
);

View 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),
);