Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
64fa3aa
commit 3a6ab6a
Showing
8 changed files
with
317 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Copyright 2022 Signal Messenger, LLC | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
.StoryLinkPreview { | ||
align-items: center; | ||
background-color: $color-white; | ||
border-radius: 36px; | ||
color: $color-gray-90; | ||
display: inline-flex; | ||
max-width: 560px; | ||
min-width: 560px; | ||
overflow: hidden; | ||
|
||
&__content { | ||
margin-left: 24px; | ||
margin-right: 24px; | ||
padding: 16px 0; | ||
} | ||
|
||
&__title { | ||
@include font-body-1-bold; | ||
-webkit-box-orient: vertical; | ||
-webkit-line-clamp: 1; | ||
display: -webkit-box; | ||
overflow: hidden; | ||
font-size: 28px; | ||
line-height: 40px; | ||
letter-spacing: -0.16px; | ||
} | ||
|
||
&__description { | ||
@include font-body-2; | ||
-webkit-box-orient: vertical; | ||
-webkit-line-clamp: 2; | ||
display: -webkit-box; | ||
overflow: hidden; | ||
font-size: 26px; | ||
line-height: 36px; | ||
letter-spacing: -0.06px; | ||
} | ||
|
||
&__location { | ||
@include font-caption; | ||
color: $color-gray-45; | ||
font-size: 22px; | ||
line-height: 28px; | ||
letter-spacing: 0.12px; | ||
} | ||
|
||
&__no-image { | ||
align-items: center; | ||
display: flex; | ||
height: 176px; | ||
justify-content: center; | ||
margin-left: 52px; | ||
margin-right: 52px; | ||
|
||
&::before { | ||
@include color-svg('../images/icons/v2/link-24.svg', $color-gray-90); | ||
content: ''; | ||
display: block; | ||
height: 48px; | ||
width: 48px; | ||
} | ||
} | ||
|
||
&--tall { | ||
flex-direction: column; | ||
} | ||
|
||
&--tiny { | ||
min-width: inherit; | ||
|
||
.StoryLinkPreview__no-image { | ||
height: 100px; | ||
margin-left: 24px; | ||
margin-right: 0; | ||
width: auto; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Copyright 2020-2021 Signal Messenger, LLC | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
import type { Meta, Story } from '@storybook/react'; | ||
import React from 'react'; | ||
|
||
import type { Props } from './StoryLinkPreview'; | ||
import enMessages from '../../_locales/en/messages.json'; | ||
import { StoryLinkPreview } from './StoryLinkPreview'; | ||
import { fakeAttachment } from '../test-both/helpers/fakeAttachment'; | ||
import { setupI18n } from '../util/setupI18n'; | ||
import { IMAGE_JPEG } from '../types/MIME'; | ||
|
||
const LONG_TITLE = | ||
"This is a super-sweet site. And it's got some really amazing content in store for you if you just click that link. Can you click that link for me?"; | ||
const LONG_DESCRIPTION = | ||
"You're gonna love this description. Not only does it have a lot of characters, but it will also be truncated in the UI. How cool is that??"; | ||
|
||
const i18n = setupI18n('en', enMessages); | ||
|
||
export default { | ||
title: 'Components/StoryLinkPreview', | ||
component: StoryLinkPreview, | ||
argTypes: { | ||
description: { | ||
defaultValue: | ||
'Introducing Mac Studio. Stunningly compact. Endless connectivity. And astonishing performance with M1 Max or the new M1 Ultra chip.', | ||
}, | ||
forceCompactMode: { | ||
defaultValue: false, | ||
}, | ||
i18n: { | ||
defaultValue: i18n, | ||
}, | ||
image: { | ||
defaultValue: fakeAttachment({ | ||
// url: 'https://www.apple.com/v/mac-studio/c/images/meta/mac-studio_overview__eedzbosm1t26_og.png', | ||
url: '/fixtures/kitten-4-112-112.jpg', | ||
contentType: IMAGE_JPEG, | ||
}), | ||
}, | ||
title: { | ||
defaultValue: 'Mac Studio', | ||
}, | ||
url: { | ||
defaultValue: 'https://www.apple.com/mac-studio/', | ||
}, | ||
}, | ||
} as Meta; | ||
|
||
const Template: Story<Props> = args => <StoryLinkPreview {...args} />; | ||
|
||
export const Default = Template.bind({}); | ||
|
||
export const CompactMode = Template.bind({}); | ||
CompactMode.args = { | ||
forceCompactMode: true, | ||
}; | ||
|
||
export const NoImage = Template.bind({}); | ||
NoImage.args = { | ||
image: undefined, | ||
}; | ||
|
||
export const ImageNoDescription = Template.bind({}); | ||
ImageNoDescription.args = { | ||
description: '', | ||
}; | ||
ImageNoDescription.storyName = 'Image, No Description'; | ||
|
||
export const ImageNoTitleOrDescription = Template.bind({}); | ||
ImageNoTitleOrDescription.args = { | ||
title: '', | ||
description: '', | ||
}; | ||
ImageNoTitleOrDescription.storyName = 'Image, No Title Or Description'; | ||
|
||
export const NoImageNoTitleOrDescription = Template.bind({}); | ||
NoImageNoTitleOrDescription.args = { | ||
image: undefined, | ||
title: '', | ||
description: '', | ||
}; | ||
NoImageNoTitleOrDescription.storyName = 'Just URL'; | ||
|
||
export const NoImageLongTitleWithDescription = Template.bind({}); | ||
NoImageLongTitleWithDescription.args = { | ||
image: undefined, | ||
title: LONG_TITLE, | ||
}; | ||
NoImageLongTitleWithDescription.storyName = | ||
'No Image, Long Title With Description'; | ||
|
||
export const NoImageLongTitleWithoutDescription = Template.bind({}); | ||
NoImageLongTitleWithoutDescription.args = { | ||
image: undefined, | ||
title: LONG_TITLE, | ||
description: '', | ||
}; | ||
NoImageLongTitleWithoutDescription.storyName = | ||
'No Image, Long Title Without Description'; | ||
|
||
export const ImageLongTitleWithoutDescription = Template.bind({}); | ||
ImageLongTitleWithoutDescription.args = { | ||
description: '', | ||
title: LONG_TITLE, | ||
}; | ||
ImageLongTitleWithoutDescription.storyName = | ||
'Image, Long Title Without Description'; | ||
|
||
export const ImageLongTitleAndDescription = Template.bind({}); | ||
ImageLongTitleAndDescription.args = { | ||
title: LONG_TITLE, | ||
description: LONG_DESCRIPTION, | ||
}; | ||
ImageLongTitleAndDescription.storyName = 'Image, Long Title And Description'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright 2022 Signal Messenger, LLC | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
import React from 'react'; | ||
import classNames from 'classnames'; | ||
import { unescape } from 'lodash'; | ||
|
||
import type { LinkPreviewType } from '../types/message/LinkPreviews'; | ||
import type { LocalizerType } from '../types/Util'; | ||
import { CurveType, Image } from './conversation/Image'; | ||
import { isImageAttachment } from '../types/Attachment'; | ||
import { getDomain } from '../types/LinkPreview'; | ||
|
||
export type Props = LinkPreviewType & { | ||
forceCompactMode?: boolean; | ||
i18n: LocalizerType; | ||
}; | ||
|
||
export const StoryLinkPreview = ({ | ||
description, | ||
domain, | ||
forceCompactMode, | ||
i18n, | ||
image, | ||
title, | ||
url, | ||
}: Props): JSX.Element => { | ||
const isImage = isImageAttachment(image); | ||
const location = domain || getDomain(String(url)); | ||
const isCompact = forceCompactMode || !image; | ||
|
||
let content: JSX.Element | undefined; | ||
if (!title && !description) { | ||
content = ( | ||
<div | ||
className={classNames( | ||
'StoryLinkPreview__content', | ||
'StoryLinkPreview__content--only-url' | ||
)} | ||
> | ||
<div className="StoryLinkPreview__title">{location}</div> | ||
</div> | ||
); | ||
} else { | ||
content = ( | ||
<div className="StoryLinkPreview__content"> | ||
<div className="StoryLinkPreview__title">{title}</div> | ||
{description && ( | ||
<div className="StoryLinkPreview__description"> | ||
{unescape(description)} | ||
</div> | ||
)} | ||
<div className="StoryLinkPreview__footer"> | ||
<div className="StoryLinkPreview__location">{location}</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
const imageWidth = isCompact ? 176 : 560; | ||
const imageHeight = | ||
!isCompact && image | ||
? imageWidth / ((image.width || 1) / (image.height || 1)) | ||
: 176; | ||
|
||
return ( | ||
<div | ||
className={classNames('StoryLinkPreview', { | ||
'StoryLinkPreview--tall': !isCompact, | ||
'StoryLinkPreview--tiny': !title && !description && !image, | ||
})} | ||
> | ||
{isImage && image ? ( | ||
<div className="StoryLinkPreview__icon-container"> | ||
<Image | ||
alt={i18n('stagedPreviewThumbnail', [location])} | ||
attachment={image} | ||
curveBottomLeft={CurveType.Tiny} | ||
curveBottomRight={CurveType.Tiny} | ||
curveTopLeft={CurveType.Tiny} | ||
curveTopRight={CurveType.Tiny} | ||
height={imageHeight} | ||
i18n={i18n} | ||
url={image.url} | ||
width={imageWidth} | ||
/> | ||
</div> | ||
) : null} | ||
{!isImage && <div className="StoryLinkPreview__no-image" />} | ||
{content} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.