Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display Youtube player in notice when youtube link found #760

Merged
merged 3 commits into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/app/content/App/Notice/Details/Details.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { withKnobs, text, date, number, boolean } from '@storybook/addon-knobs';
import Faker from 'faker';
import {
defaultMessage,
generateStatefulNotice
generateStatefulNotice,
messageWithYoutubeVideo
} from 'test/fakers/generateNotice';
import { Details } from '.';
import { subMonths } from 'date-fns';
Expand Down Expand Up @@ -68,4 +69,20 @@ storiesOf('Extension/Notice/Details', module)
disliked: boolean('disliked', false)
})}
/>
))
.add('with youtube video', () => (
<Details
{...commonProps}
notice={generateStatefulNotice({
contributor: generateContributor({
name: text('contributor', defaultContributorName)
}),
message: `<p>${text('message', messageWithYoutubeVideo)}</p>`,
created: new Date(date('created', defaultDate)),
likes: number('likes', 42),
dislikes: number('dislikes', 2),
liked: boolean('liked', false),
disliked: boolean('disliked', false)
})}
/>
));
5 changes: 5 additions & 0 deletions src/app/lmem/format/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import getMessageWithMediaPlayer from '../../utils/getMessageWithMediaPlayer';

export const formatMessage = (message: string): string => {
return getMessageWithMediaPlayer(message) || message;
};
13 changes: 13 additions & 0 deletions src/app/utils/getMessageWithMediaPlayer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const youtubeRegex = /(https?:\/\/)?(www\.)?(youtube\.com)(\/)(watch\?v=|embed\/)([a-zA-Z0-9_?=/-]+)/g;

const getMessageWithMediaPlayer = (message: string): string | null => {
const youtubeLink = youtubeRegex.exec(message);
if (!youtubeLink) return null;

const mediaLink = youtubeLink[0].replace(youtubeLink[5], 'embed/');

const replaceValue = `<iframe width='100%' height='auto' src=${mediaLink} allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen/>`;
return message.replace(youtubeRegex, replaceValue);
};

export default getMessageWithMediaPlayer;
10 changes: 6 additions & 4 deletions src/app/utils/linkify.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { youtubeRegex } from './getMessageWithMediaPlayer';

// eslint-disable-next-line no-useless-escape
const LINK_DETECTION_REGEX = /(([a-z]+:\/\/)?(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&amp;]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi;

export default (text: string) =>
text.replace(
LINK_DETECTION_REGEX,
url =>
`<a target="_blank" rel="noopener noreferrer" href="${url}">${url}</a>`
text.replace(LINK_DETECTION_REGEX, url =>
url.match(youtubeRegex)
? url
: `<a target="_blank" rel="noopener noreferrer" href="${url}">${url}</a>`
);
1 change: 1 addition & 0 deletions src/components/organisms/NoticeDetails/Feedbacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default styled.div<FeedbacksProps>`
display: flex;
justify-content: flex-end;
margin-top: auto;
margin-right: 30px;
font-size: 14px;

& ${Button} {
Expand Down
13 changes: 12 additions & 1 deletion src/components/organisms/NoticeDetails/NoticeDetails.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { action } from '@storybook/addon-actions';
import NoticeDetails from './NoticeDetails';
import { subMonths } from 'date-fns';
import Faker from 'faker';
import { generateStatefulNotice } from 'test/fakers/generateNotice';
import {
generateStatefulNotice,
messageWithYoutubeVideo
} from 'test/fakers/generateNotice';
import { boolean, date, number, text } from '@storybook/addon-knobs';
import { generateContributor } from 'test/fakers/generateContributor';

Expand Down Expand Up @@ -73,4 +76,12 @@ storiesOf('Components/Organisms/NoticeDetails', module)
notice={generateStatefulNotice({ disliked: true })}
relayer={generateContributor()}
/>
))
.add('Youtube video', () => (
<NoticeDetails
{...commonProps}
notice={generateStatefulNotice({
message: messageWithYoutubeVideo
})}
/>
));
5 changes: 4 additions & 1 deletion src/components/organisms/NoticeDetails/NoticeDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Message from './Message';
import Feedbacks from './Feedbacks';
import Date from './Date';
import { Contributor } from 'app/lmem/contributor';
import { formatMessage } from 'app/lmem/format/message';

const DetailsMetaValue = styled.div`
margin-left: 10px;
Expand Down Expand Up @@ -248,7 +249,9 @@ class NoticeDetails extends PureComponent<NoticeDetailsProps, CountDownState> {
</DetailsMetaValue>
</DetailsMeta>

<Message onClick={this.handleMessageClick}>{message}</Message>
<Message onClick={this.handleMessageClick}>
{formatMessage(message)}
</Message>

<Feedbacks>
<Button onClick={this.handleLikeClick}>
Expand Down
56 changes: 56 additions & 0 deletions src/components/organisms/NoticePreview.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { MemoryRouter as Router } from 'react-router-dom';
import { storiesOf } from '@storybook/react';
import Faker from 'faker';
import NoticePreview from './NoticePreview';
import {
defaultMessage,
messageWithYoutubeVideo
} from 'test/fakers/generateNotice';

storiesOf('Components/Organisms/NoticePreview', module)
.add('normal', () => (
<Router>
<NoticePreview
contribution={{
url: Faker.internet.url(),
created: new Date(),
contributor: {
name: Faker.name.findName(),
email: Faker.internet.email()
},
message: defaultMessage
}}
/>
</Router>
))
.add('with links', () => (
<Router>
<NoticePreview
contribution={{
url: Faker.internet.url(),
created: new Date(),
contributor: {
name: Faker.name.findName(),
email: Faker.internet.email()
},
message: `${defaultMessage} https://github.com/dis-moi/extension`
}}
/>
</Router>
))
.add('with youtube video', () => (
<Router>
<NoticePreview
contribution={{
url: Faker.internet.url(),
created: new Date(),
contributor: {
name: Faker.name.findName(),
email: Faker.internet.email()
},
message: messageWithYoutubeVideo
}}
/>
</Router>
));
3 changes: 2 additions & 1 deletion src/components/organisms/NoticePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Contribution } from 'app/lmem/notice';
import Avatar from 'components/molecules/Avatar/Avatar';
import linkify from 'app/utils/linkify';
import lineBreaksToBr from 'app/utils/lineBreaksToBr';
import { formatMessage } from 'app/lmem/format/message';

const DetailsMetaValue = styled.div`
margin-left: 10px;
Expand Down Expand Up @@ -44,7 +45,7 @@ class NoticePreview extends PureComponent<NoticePreviewProps> {
</DetailsMetaValue>
</DetailsMeta>

<Message>{lineBreaksToBr(linkify(message))}</Message>
<Message>{lineBreaksToBr(formatMessage(linkify(message)))}</Message>
</DetailsContent>
{children}
</Container>
Expand Down
1 change: 1 addition & 0 deletions test/fakers/generateNotice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface Options {
}

export const defaultMessage = `L’économie est (vraiment) un sport de combat : “La boule puante de MM. Cahuc et Zylberberg contre le “négationnisme” des économistes critiques le confirme : le combat idéologique tombe parfois dans le caniveau. Depuis vingt ans pourtant, s’est construit en France une contre-expertise économique crédible qui veut fournir aux dominés des outils pour penser (et résister à) la pseudo” construit en France une contre-expertise`;
export const messageWithYoutubeVideo = `Saviez-vous que Dark Vador n'a pas dit, "Luke, je suis ton père", mais "Non... Je suis ton père" ? La preuve en vidéo : https://www.youtube.com/watch?v=5OQiE9Nj3ko.`;

export const generateStatefulNotice = ({
message,
Expand Down