Skip to content

Commit

Permalink
added link preview
Browse files Browse the repository at this point in the history
added chevron icons

added dropdown to toggle link preview
  • Loading branch information
Spiral-Memory committed Mar 6, 2024
1 parent da8b930 commit 5a115c7
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 0 deletions.
14 changes: 14 additions & 0 deletions packages/react/src/components/Icon/icons/ChevronDown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';

const ChevronDown = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32 32"
fill="currentColor"
{...props}
>
<path d="M8.79289 12.2929C9.18342 11.9024 9.81658 11.9024 10.2071 12.2929L16 18.0858L21.7929 12.2929C22.1834 11.9024 22.8166 11.9024 23.2071 12.2929C23.5976 12.6834 23.5976 13.3166 23.2071 13.7071L16.7071 20.2071C16.3166 20.5976 15.6834 20.5976 15.2929 20.2071L8.79289 13.7071C8.40237 13.3166 8.40237 12.6834 8.79289 12.2929Z" />
</svg>
);

export default ChevronDown;
15 changes: 15 additions & 0 deletions packages/react/src/components/Icon/icons/ChevronLeft.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

const ChevronLeft = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32 32"
className="rcx-svg--directional"
fill="currentColor"
{...props}
>
<path d="M12.2929 23.2071C11.9024 22.8166 11.9024 22.1834 12.2929 21.7929L18.0858 16L12.2929 10.2071C11.9024 9.81658 11.9024 9.18342 12.2929 8.79289C12.6834 8.40237 13.3166 8.40237 13.7071 8.79289L20.2071 15.2929C20.5976 15.6834 20.5976 16.3166 20.2071 16.7071L13.7071 23.2071C13.3166 23.5976 12.6834 23.5976 12.2929 23.2071Z" />
</svg>
);

export default ChevronLeft;
4 changes: 4 additions & 0 deletions packages/react/src/components/Icon/icons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import VideoRecorder from './VideoRecoder';
import DisabledRecorder from './DisableRecorder';
import Clipboard from './Clipboard';
import At from './At';
import ChevronDown from './ChevronDown';
import ChevronLeft from './ChevronLeft';

const icons = {
file: File,
Expand Down Expand Up @@ -84,6 +86,8 @@ const icons = {
'pin-filled': PinFilled,
clipboard: Clipboard,
at: At,
'chevron-down': ChevronDown,
'chevron-left': ChevronLeft,
};

export default icons;
128 changes: 128 additions & 0 deletions packages/react/src/components/LinkPreview/LinkPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { css } from '@emotion/react';
import { Box } from '../Box';
import { ActionButton } from '../ActionButton';
import { Icon } from '../Icon';
import useComponentOverrides from '../../theme/useComponentOverrides';

const LinkPreview = ({ className = '', style = {}, url, meta, ...props }) => {
const { classNames, styleOverrides } = useComponentOverrides('LinkPreview');
const [isPreviewOpen, setIsPreviewOpen] = useState(true);

if (!meta || (typeof meta === 'object' && Object.keys(meta).length === 0)) {
return null;
}

const isDescription =
meta.oembedAuthorName || meta.ogDescription || meta.description;
const isTitle = meta.pageTitle || meta.ogTitle || meta.oembedTitle;
const isThumbnail = meta.oembedThumbnailUrl || meta.ogImage;
const isSiteName = meta.ogSiteName || meta.oembedProviderName;

const ArrowDropDownCss = css`
cursor: pointer;
display: flex;
align-items: center;
`;

const LinkPreviewBoxCss = css`
max-width: 22rem;
border: 1px solid #ccc;
border-radius: 0.25rem;
margin-bottom: 0.75rem;
overflow: hidden;
`;

const TextCss = css`
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin-block-start: 0rem;
margin-block-end: 0rem;
`;

const handleTogglePreview = () => {
setIsPreviewOpen((prev) => !prev);
};

return (
<>
<Box css={ArrowDropDownCss}>
Link Preview
<ActionButton
onClick={handleTogglePreview}
ghost
display="inline"
square
small
>
{isPreviewOpen ? (
<Icon name="chevron-left" size="1.25rem" />
) : (
<Icon name="chevron-down" size="1.25rem" />
)}
</ActionButton>
</Box>

{isPreviewOpen && (
<Box
css={LinkPreviewBoxCss}
className={`ec-linkpreview ${className} ${classNames}`}
style={{ ...styleOverrides, ...style }}
{...props}
>
{isThumbnail && (
<Box style={{ overflow: 'hidden' }}>
<a href={url} target="_blank" rel="noopener noreferrer">
<img
src={
isThumbnail.startsWith('/')
? `${url}${isThumbnail}`
: isThumbnail
}
alt={meta.ogImageAlt}
style={{
width: '100%',
height: 'auto',
}}
/>
</a>
</Box>
)}

<Box style={{ padding: '8px' }}>
<a
href={url}
style={{ color: 'blue' }}
target="_blank"
rel="noopener noreferrer"
>
{isTitle && <p css={TextCss}>{isTitle}</p>}
</a>
{isDescription && <p css={TextCss}>{isDescription}</p>}
{isSiteName && (
<a
href={url}
style={{ color: 'rgba(97, 97, 97, 1)' }}
target="_blank"
rel="noopener noreferrer"
>
{isSiteName}
</a>
)}
</Box>
</Box>
)}
</>
);
};

LinkPreview.propTypes = {
className: PropTypes.string,
style: PropTypes.object,
color: PropTypes.string,
url: PropTypes.string,
meta: PropTypes.object,
};
export default LinkPreview;
1 change: 1 addition & 0 deletions packages/react/src/components/LinkPreview/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as LinkPreview } from './LinkPreview';
15 changes: 15 additions & 0 deletions packages/react/src/components/Message/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { MessageDivider } from './MessageDivider';
import { useToastBarDispatch } from '../../hooks/useToastBarDispatch';
import MessageAvatarContainer from './MessageAvatarContainer';
import MessageBodyContainer from './MessageBodyContainer';
import { LinkPreview } from '../LinkPreview';

const MessageCss = css`
display: flex;
Expand Down Expand Up @@ -157,6 +158,7 @@ const Message = ({

const isStarred = message.starred?.find((u) => u._id === authenticatedUserId);
const shouldShowHeader = !sequential || (!showAvatar && isStarred);
console.log(message);
return (
<>
<Box
Expand Down Expand Up @@ -186,6 +188,19 @@ const Message = ({
) : (
<Markdown body={message} isReaction={false} />
)}

{message.urls &&
message.urls.map(
(url, index) =>
url.meta && (
<LinkPreview
key={index}
url={url.url}
meta={url.meta}
/>
)
)}

{message.blocks && (
<kitContext.Provider value={context} mid={message.mid}>
<UiKitComponent
Expand Down
2 changes: 2 additions & 0 deletions packages/react/tools/icons-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const iconsList = [
'kebab',
'check',
'error-circle',
'chevron-down',
'chevron-left',
];
const svgDirPath = path.join(
__dirname,
Expand Down

0 comments on commit 5a115c7

Please sign in to comment.