LinkBlockItem: add component

This commit is contained in:
Liam Fitzgerald 2021-06-08 10:42:44 +10:00
parent db516af2a1
commit 27863b7ed5
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
2 changed files with 105 additions and 53 deletions

View File

@ -4,6 +4,8 @@ import { withDesign } from 'storybook-addon-designs';
import { Col, Row } from '@tlon/indigo-react';
import { LinkBlockItem } from '~/views/apps/links/components/LinkBlockItem';
import { createPost, GraphNode } from '@urbit/api';
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
export default {
title: 'Collections/BlockItem',
@ -11,11 +13,37 @@ export default {
decorators: [withDesign]
} as Meta;
const createLink = (text: string, url: string) => ({
post: createPost('sampel-palnet', [{ text }, { url }]),
children: new BigIntOrderedMap<GraphNode>()
});
export const Image = () => (
<Row flexWrap="wrap" m="2" width="700px" backgroundColor="white">
<LinkBlockItem m="2" url="https://media.urbit.org/site/posts/essays/value-of-address-space-pt1.jpg" />
<LinkBlockItem m="2" url="https://media.urbit.org/site/posts/essays/ocean.jpeg" />
<LinkBlockItem m="2" size="512px" url="https://media.urbit.org/site/posts/essays/ocean.jpeg" />
<LinkBlockItem
summary
m="2"
node={createLink(
'Gas',
'https://media.urbit.org/site/posts/essays/value-of-address-space-pt1.jpg'
)}
/>
<LinkBlockItem
summary
m="2"
node={createLink(
'Ocean',
'https://media.urbit.org/site/posts/essays/ocean.jpeg'
)}
/>
<LinkBlockItem
m="2"
size="512px"
node={createLink(
'Big Ocean',
'https://media.urbit.org/site/posts/essays/ocean.jpeg'
)}
/>
</Row>
);
@ -29,8 +57,10 @@ Image.parameters = {
export const Fallback = () => (
<Col gapY="2" p="2" width="500px" backgroundColor="white">
<LinkBlockItem url="https://www.are.na/edouard-urcades/edouard" />
<LinkBlockItem url="https://thejaymo.net" />
<LinkBlockItem
node={createLink('', 'https://www.are.na/edouard-urcades/edouard')}
/>
<LinkBlockItem node={createLink('', 'https://thejaymo.net')} />
</Col>
);
@ -45,8 +75,10 @@ Fallback.parameters = {
export const Audio = () => (
<Col gapY="2" p="2" width="500px" backgroundColor="white">
<LinkBlockItem
title="Artist · Track"
url="https://rovnys-public.s3.amazonaws.com/urbit-from-the-outside-in-1.m4a"
node={createLink(
'Artist · Track',
'https://rovnys-public.s3.amazonaws.com/urbit-from-the-outside-in-1.m4a'
)}
/>
</Col>
);
@ -62,8 +94,17 @@ Audio.parameters = {
export const Youtube = () => (
<Col gapY="2" p="2" width="500px" backgroundColor="white">
<LinkBlockItem
title="Artist · Track"
url="https://www.youtube.com/watch?v=M04AKTCDavc&t=1s"
node={createLink(
'Artist · Track',
'https://www.youtube.com/watch?v=M04AKTCDavc&t=1s'
)}
/>
<LinkBlockItem
summary
node={createLink(
'Artist · Track',
'https://www.youtube.com/watch?v=M04AKTCDavc&t=1s'
)}
/>
</Col>
);

View File

@ -1,50 +1,68 @@
import React from 'react';
import {
BaseImage,
Icon,
Center,
Row,
Text,
BoxProps,
Col,
Box,
CenterProps
} from '@tlon/indigo-react';
import { hasProvider } from 'oembed-parser';
import { AUDIO_REGEX, IMAGE_REGEX } from '~/views/components/RemoteContent';
import { AudioPlayer } from '~/views/components/AudioPlayer';
import { useHistory } from 'react-router';
import { useHovering } from '~/logic/lib/util';
import Author from '~/views/components/Author';
import { GraphNode, Post, TextContent, UrlContent } from '@urbit/api';
import {
GraphNode,
ReferenceContent,
TextContent,
UrlContent
} from '@urbit/api';
import {
RemoteContentEmbedFallback,
RemoteContentImageEmbed,
RemoteContentOembed,
RemoteContentPermalinkEmbed
} from '~/views/components/RemoteContent/embed';
import { PermalinkEmbed } from '../../permalinks/embed';
import { referenceToPermalink } from '~/logic/lib/permalinks';
import GlobalApi from '~/logic/api/global';
export interface LinkBlockItemProps {
node: GraphNode;
size?: BoxProps['height'];
m?: BoxProps['m'];
border?: BoxProps['border'];
size?: CenterProps['height'];
border?: CenterProps['border'];
summary?: boolean;
api: GlobalApi;
}
function getYoutubeId(str: string): string | null {
const youtube = str.match(/youtube\.com.*(\?v=|\/embed\/)(.{11})/);
if (!youtube) {
return null;
}
return youtube.pop();
}
export function LinkBlockItem(props: LinkBlockItemProps) {
const { node, summary, size = '256px', m, border = 1 } = props;
export function LinkBlockItem(props: LinkBlockItemProps & CenterProps) {
const { api, node, summary, size, m, border = 1, ...rest } = props;
const { post, children } = node;
const { contents, index, author } = post;
const [{ text: title }, { url }] = contents as [TextContent, UrlContent];
const [{ text: title }, ...content] = contents as [
TextContent,
UrlContent | ReferenceContent
];
let url = '';
if ('url' in content?.[0]) {
url = content[0].url;
}
const isReference = 'reference' in content[0];
const isImage = IMAGE_REGEX.test(url);
const isAudio = AUDIO_REGEX.test(url);
const youtube = getYoutubeId(url);
const isOembed = hasProvider(url);
const history = useHistory();
const { hovering, bind } = useHovering();
const onClick = () => {
history.push(`${history.location.pathname}/index${index}`);
const { pathname, search } = history.location;
history.push(`${pathname}/index${index}${search}`);
};
return (
<Center
@ -56,36 +74,29 @@ export function LinkBlockItem(props: LinkBlockItemProps) {
height={size}
width={size}
m={m}
{...rest}
{...bind}
>
{isImage ? (
<BaseImage
style={{ objectFit: 'contain' }}
height="100%"
src={url}
width="100%"
/>
{isReference ? (
summary ? (
<RemoteContentPermalinkEmbed
reference={content[0] as ReferenceContent}
/>
) : (
<PermalinkEmbed
link={referenceToPermalink(content[0] as ReferenceContent).link}
api={api}
transcluded={0}
/>
)
) : isImage ? (
<RemoteContentImageEmbed url={url} />
) : isAudio ? (
<AudioPlayer title={title} url={url} />
) : youtube ? (
<BaseImage
style={{ objectFit: 'contain' }}
height="100%"
src={`https://img.youtube.com/vi/${youtube}/${0}.jpg`}
width="100%"
/>
) : isOembed ? (
<RemoteContentOembed url={url} thumbnail={summary} />
) : (
<Row overflow="hidden" gapX="2" alignItems="center" p="2">
<Icon color="gray" icon="ArrowExternal" />
<Text
gray
overflow="hidden"
whiteSpace="nowrap"
textOverflow="ellipsis"
>
{url}
</Text>
</Row>
<RemoteContentEmbedFallback url={url} />
)}
<Box
backgroundColor="white"