Merge pull request #31 from toeverything/bugfix/iframe

fix iframe will take away the focus
This commit is contained in:
DiamondThree
2022-08-04 22:03:27 +08:00
committed by GitHub
3 changed files with 169 additions and 36 deletions

View File

@@ -1,6 +1,18 @@
import type { AsyncBlock } from '@toeverything/components/editor-core';
import {
AsyncBlock,
useCurrentView,
useLazyIframe,
} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui';
import type { FC } from 'react';
import {
FC,
ReactElement,
ReactNode,
useEffect,
useRef,
useState,
} from 'react';
import { SCENE_CONFIG } from '../../blocks/group/config';
import { BlockPreview } from './BlockView';
import { formatUrl } from './format-url';
@@ -15,7 +27,18 @@ export interface Props {
}
const getHost = (url: string) => new URL(url).host;
const MouseMaskContainer = styled('div')({
position: 'absolute',
zIndex: 1,
top: '0px',
left: '0px',
right: '0px',
bottom: '0px',
backgroundColor: 'transparent',
'&:hover': {
pointerEvents: 'none',
},
});
const LinkContainer = styled('div')<{
isSelected: boolean;
}>(({ theme, isSelected }) => {
@@ -38,12 +61,28 @@ const LinkContainer = styled('div')<{
},
};
});
const _getLinkStyle = (scene: string) => {
switch (scene) {
case SCENE_CONFIG.PAGE:
return {
width: '420px',
height: '198px',
};
default:
return {
width: '252px',
height: '126px',
};
}
};
const SourceViewContainer = styled('div')<{
isSelected: boolean;
}>(({ theme, isSelected }) => {
scene: string;
}>(({ theme, isSelected, scene }) => {
return {
..._getLinkStyle(scene),
overflow: 'hidden',
position: 'relative',
borderRadius: theme.affine.shape.borderRadius,
background: isSelected ? 'rgba(152, 172, 189, 0.1)' : 'transparent',
padding: '8px',
@@ -52,32 +91,96 @@ const SourceViewContainer = styled('div')<{
height: '100%',
border: '1px solid #EAEEF2',
borderRadius: theme.affine.shape.borderRadius,
userSelect: 'none',
},
};
});
const LazyIframe = ({
src,
delay = 3000,
fallback,
}: {
src: string;
delay?: number;
fallback?: ReactNode;
}) => {
const [show, setShow] = useState(false);
const timer = useRef<number>();
useEffect(() => {
// Hide iframe when the src changed
setShow(false);
}, [src]);
const onLoad = () => {
clearTimeout(timer.current);
timer.current = window.setTimeout(() => {
// Prevent iframe scrolling parent container
// Remove the delay after the issue is resolved
// See W3C https://github.com/w3c/csswg-drafts/issues/7134
// See https://forum.figma.com/t/prevent-figmas-embed-code-from-automatically-scrolling-to-it-on-page-load/26029/6
setShow(true);
}, delay);
};
return (
<>
<div
onMouseDown={e => {
e.preventDefault();
e.stopPropagation();
}}
style={{ display: show ? 'block' : 'none', height: '100%' }}
>
<iframe src={src} onLoad={onLoad} />
</div>
{!show && fallback}
</>
);
};
const Loading = styled('div')(() => {
return {
width: '100%',
height: '100%',
display: 'flex',
lineHeight: '100%',
alignItems: 'center',
justifyContent: 'center',
border: '1px solid #EAEEF2',
};
});
const LoadingContiner = () => {
return <Loading>loading...</Loading>;
};
export const SourceView: FC<Props> = props => {
const { link, isSelected, block, editorElement } = props;
const src = formatUrl(link);
const openTabOnBrowser = () => {
window.open(link, '_blank');
};
// let iframeShow = useLazyIframe(src, 3000, iframeContainer);
const [currentView] = useCurrentView();
const { type } = currentView;
if (src?.startsWith('http')) {
return (
<LinkContainer
isSelected={isSelected}
onMouseDown={e => e.preventDefault()}
onClick={openTabOnBrowser}
>
<p>{getHost(src)}</p>
<p>{src}</p>
</LinkContainer>
<div style={{ display: 'flex' }}>
<SourceViewContainer isSelected={isSelected} scene={type}>
<MouseMaskContainer />
<LazyIframe
src={src}
fallback={LoadingContiner()}
></LazyIframe>
</SourceViewContainer>
</div>
);
} else if (src?.startsWith('affine')) {
return (
<SourceViewContainer
isSelected={isSelected}
style={{ padding: '0' }}
scene={type}
>
<BlockPreview
block={block}