RemoteContent: center iframes

Fixes urbit/landscape#1005
This commit is contained in:
Liam Fitzgerald 2021-06-29 13:04:23 +10:00
parent 6f2f44608f
commit aa8551a3ab
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
2 changed files with 37 additions and 14 deletions

View File

@ -20,8 +20,8 @@ export function LinkDetail(props: LinkDetailProps) {
const [{ text: title }] = post.contents as [TextContent, UrlContent]; const [{ text: title }] = post.contents as [TextContent, UrlContent];
return ( return (
/* @ts-ignore indio props?? */ /* @ts-ignore indio props?? */
<Row flexDirection={['column', 'column', 'row']} {...rest}> <Row width="100%" flexDirection={['column', 'column', 'row']} {...rest}>
<LinkBlockItem flexGrow={1} border={0} node={node} /> <LinkBlockItem maxWidth={['100%', '100%', 'calc(100% - 350px)']} flexGrow={1} border={0} node={node} />
<Col <Col
flexShrink={0} flexShrink={0}
width={['100%', '100%', '350px']} width={['100%', '100%', '350px']}

View File

@ -1,6 +1,7 @@
import React, { import React, {
MouseEvent, MouseEvent,
useCallback useCallback,
useMemo
} from 'react'; } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import UnstyledEmbedContainer from 'react-oembed-container'; import UnstyledEmbedContainer from 'react-oembed-container';
@ -142,23 +143,33 @@ const EmbedContainer = styled(UnstyledEmbedContainer)`
height: 100%; height: 100%;
`; `;
const EmbedBox = styled.div<{ aspect?: number }>` const EmbedBox = styled.div<{ aspect?: number; iHeight?: number; iWidth?: number; }>`
${p => p.aspect ? ` ${p => p.aspect ? `
height: 0; height: 0;
overflow: hidden; overflow: hidden;
padding-bottom: calc(100% / ${p.aspect}); padding-bottom: calc(100% / ${p.aspect});
position: relative; position: relative;
` : ` ` : `
height: auto; display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%; width: 100%;
`} `}
& iframe { & iframe {
${p => (p.iHeight && p.iWidth) ? `
height: ${p.iHeight}px !important;
width: ${p.iWidth}px !important;
` : `
height: 100%; height: 100%;
width: 100%; width: 100%;
`
}
${p => p.aspect && 'position: absolute;'} ${p => p.aspect && 'position: absolute;'}
} }
`; `;
@ -235,7 +246,11 @@ type RemoteContentOembedProps = {
} & RemoteContentEmbedProps & } & RemoteContentEmbedProps &
PropFunc<typeof Box>; PropFunc<typeof Box>;
const YOUTUBE = /youtu(\.?)be/; /**
* Some providers do not report sizes correctly, so we report an aspect ratio
* instead of a height/width
*/
const BAD_SIZERS = [/youtu(\.?)be/];
export const RemoteContentOembed = React.forwardRef< export const RemoteContentOembed = React.forwardRef<
HTMLDivElement, HTMLDivElement,
@ -246,11 +261,17 @@ export const RemoteContentOembed = React.forwardRef<
const embed = oembed.read(); const embed = oembed.read();
const fallbackError = new Error('fallback'); const fallbackError = new Error('fallback');
const aspect = const [aspect, width, height] = useMemo(() => {
YOUTUBE.test(url) && if(!('height' in embed && typeof embed.height === 'number'
'height' in embed && typeof embed.height === 'number' && 'width' in embed && typeof embed.width === 'number')) {
&& 'width' in embed && typeof embed.width === 'number' return [undefined, undefined, undefined];
? (embed.width / embed.height) : undefined; }
const { height, width } = embed;
if(BAD_SIZERS.some(r => r.test(url))) {
return [width/height, undefined, undefined];
}
return [undefined, width, height];
}, [embed, url]);
const detail = ( const detail = (
<Col <Col
@ -272,6 +293,8 @@ export const RemoteContentOembed = React.forwardRef<
<EmbedBox <EmbedBox
ref={ref} ref={ref}
aspect={aspect} aspect={aspect}
iHeight={height}
iWidth={width}
dangerouslySetInnerHTML={{ __html: embed.html }} dangerouslySetInnerHTML={{ __html: embed.html }}
></EmbedBox> ></EmbedBox>
</EmbedContainer> </EmbedContainer>
@ -300,7 +323,6 @@ export function RemoteContentEmbedFallback(props: RemoteContentEmbedProps) {
return ( return (
<Row maxWidth="100%" overflow="hidden" gapX="2" alignItems="center" p="2"> <Row maxWidth="100%" overflow="hidden" gapX="2" alignItems="center" p="2">
<Icon color="gray" icon="ArrowExternal" /> <Icon color="gray" icon="ArrowExternal" />
<TruncatedText maxWidth="100%" gray>
<BaseAnchor <BaseAnchor
href={url} href={url}
target="_blank" target="_blank"
@ -311,9 +333,10 @@ export function RemoteContentEmbedFallback(props: RemoteContentEmbedProps) {
textOverflow="ellipsis" textOverflow="ellipsis"
color="gray" color="gray"
> >
<TruncatedText maxWidth="100%" gray>
{url} {url}
</BaseAnchor> </TruncatedText>
</TruncatedText> </BaseAnchor>
</Row> </Row>
); );
} }