fix iframe will take away the focus

This commit is contained in:
DiamondThree
2022-08-02 16:17:10 +08:00
parent 00d37af421
commit e8f390a0d2
2 changed files with 85 additions and 18 deletions

View File

@@ -1,6 +1,11 @@
import type { AsyncBlock } from '@toeverything/components/editor-core'; import {
AsyncBlock,
useCurrentView,
useLazyIframe,
} from '@toeverything/components/editor-core';
import { styled } from '@toeverything/components/ui'; import { styled } from '@toeverything/components/ui';
import type { FC } from 'react'; import { FC, useRef } from 'react';
import { SCENE_CONFIG } from '../../blocks/group/config';
import { BlockPreview } from './BlockView'; import { BlockPreview } from './BlockView';
import { formatUrl } from './format-url'; import { formatUrl } from './format-url';
@@ -15,7 +20,18 @@ export interface Props {
} }
const getHost = (url: string) => new URL(url).host; 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')<{ const LinkContainer = styled('div')<{
isSelected: boolean; isSelected: boolean;
}>(({ theme, isSelected }) => { }>(({ theme, isSelected }) => {
@@ -38,12 +54,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')<{ const SourceViewContainer = styled('div')<{
isSelected: boolean; isSelected: boolean;
}>(({ theme, isSelected }) => { scene: string;
}>(({ theme, isSelected, scene }) => {
return { return {
..._getLinkStyle(scene),
overflow: 'hidden', overflow: 'hidden',
position: 'relative',
borderRadius: theme.affine.shape.borderRadius, borderRadius: theme.affine.shape.borderRadius,
background: isSelected ? 'rgba(152, 172, 189, 0.1)' : 'transparent', background: isSelected ? 'rgba(152, 172, 189, 0.1)' : 'transparent',
padding: '8px', padding: '8px',
@@ -52,32 +84,46 @@ const SourceViewContainer = styled('div')<{
height: '100%', height: '100%',
border: '1px solid #EAEEF2', border: '1px solid #EAEEF2',
borderRadius: theme.affine.shape.borderRadius, borderRadius: theme.affine.shape.borderRadius,
userSelect: 'none',
}, },
}; };
}); });
const IframeContainer = styled('div')<{ show: boolean }>(({ show }) => {
return {
height: '100%',
display: show ? 'block' : 'none',
};
});
export const SourceView: FC<Props> = props => { export const SourceView: FC<Props> = props => {
const { link, isSelected, block, editorElement } = props; const { link, isSelected, block, editorElement } = props;
const src = formatUrl(link); const src = formatUrl(link);
const openTabOnBrowser = () => {
window.open(link, '_blank'); const iframeContainer = useRef(null);
}; let iframeShow = useLazyIframe(src, 3000, iframeContainer);
const [currentView] = useCurrentView();
const { type } = currentView;
if (src?.startsWith('http')) { if (src?.startsWith('http')) {
return ( return (
<LinkContainer <div style={{ display: 'flex' }}>
isSelected={isSelected} <SourceViewContainer isSelected={isSelected} scene={type}>
onMouseDown={e => e.preventDefault()} <MouseMaskContainer />
onClick={openTabOnBrowser} <IframeContainer
> onMouseDown={e => {
<p>{getHost(src)}</p> e.preventDefault();
<p>{src}</p> e.stopPropagation();
</LinkContainer> }}
show={iframeShow}
ref={iframeContainer}
></IframeContainer>
</SourceViewContainer>
</div>
); );
} else if (src?.startsWith('affine')) { } else if (src?.startsWith('affine')) {
return ( return (
<SourceViewContainer <SourceViewContainer
isSelected={isSelected} isSelected={isSelected}
style={{ padding: '0' }} style={{ padding: '0' }}
scene={type}
> >
<BlockPreview <BlockPreview
block={block} block={block}

View File

@@ -1,5 +1,5 @@
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { useCallback } from 'react'; import { MutableRefObject, useCallback, useEffect, useState } from 'react';
import { useRecastBlock } from './Context'; import { useRecastBlock } from './Context';
import { import {
KanbanView, KanbanView,
@@ -50,7 +50,28 @@ export const useCurrentView = () => {
); );
return [currentView, setCurrentView] as const; return [currentView, setCurrentView] as const;
}; };
export const useLazyIframe = (
link: string,
timers: number,
container: MutableRefObject<any>
) => {
const [iframeShow, setIframeShow] = useState(false);
useEffect(() => {
const iframe = document.createElement('iframe');
iframe.src = link;
iframe.onload = () => {
setTimeout(() => {
setIframeShow(true);
}, timers);
};
container.current.appendChild(iframe);
return () => {
iframe.remove();
};
}, [link, container]);
return iframeShow;
};
export const useRecastView = () => { export const useRecastView = () => {
const recastBlock = useRecastBlock(); const recastBlock = useRecastBlock();
const recastViews = const recastViews =