Migrate most React class components to function components

This commit is contained in:
Jamie Kyle 2023-04-12 16:17:56 -07:00 committed by GitHub
parent 4c9baaef80
commit 558b5a4a38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1444 additions and 1775 deletions

View file

@ -323,77 +323,71 @@ export const SUPPORTED_PROTOCOLS = /^(http|https):/i;
const defaultRenderNonLink: RenderTextCallbackType = ({ text }) => text;
export class Linkify extends React.Component<Props> {
public override render():
| JSX.Element
| string
| null
| Array<JSX.Element | string | null> {
const { text, renderNonLink = defaultRenderNonLink } = this.props;
export function Linkify(props: Props): JSX.Element {
const { text, renderNonLink = defaultRenderNonLink } = props;
if (!shouldLinkifyMessage(text)) {
return renderNonLink({ text, key: 1 });
if (!shouldLinkifyMessage(text)) {
return <>{renderNonLink({ text, key: 1 })}</>;
}
const chunkData: Array<{
chunk: string;
matchData: ReadonlyArray<LinkifyIt.Match>;
}> = splitByEmoji(text).map(({ type, value: chunk }) => {
if (type === 'text') {
return { chunk, matchData: linkify.match(chunk) || [] };
}
const chunkData: Array<{
chunk: string;
matchData: ReadonlyArray<LinkifyIt.Match>;
}> = splitByEmoji(text).map(({ type, value: chunk }) => {
if (type === 'text') {
return { chunk, matchData: linkify.match(chunk) || [] };
if (type === 'emoji') {
return { chunk, matchData: [] };
}
throw missingCaseError(type);
});
const results: Array<JSX.Element | string> = [];
let count = 1;
chunkData.forEach(({ chunk, matchData }) => {
if (matchData.length === 0) {
count += 1;
results.push(renderNonLink({ text: chunk, key: count }));
return;
}
let chunkLastIndex = 0;
matchData.forEach(match => {
if (chunkLastIndex < match.index) {
const textWithNoLink = chunk.slice(chunkLastIndex, match.index);
count += 1;
results.push(renderNonLink({ text: textWithNoLink, key: count }));
}
if (type === 'emoji') {
return { chunk, matchData: [] };
}
throw missingCaseError(type);
});
const results: Array<JSX.Element | string> = [];
let count = 1;
chunkData.forEach(({ chunk, matchData }) => {
if (matchData.length === 0) {
count += 1;
results.push(renderNonLink({ text: chunk, key: count }));
return;
}
let chunkLastIndex = 0;
matchData.forEach(match => {
if (chunkLastIndex < match.index) {
const textWithNoLink = chunk.slice(chunkLastIndex, match.index);
count += 1;
results.push(renderNonLink({ text: textWithNoLink, key: count }));
}
const { url, text: originalText } = match;
count += 1;
if (SUPPORTED_PROTOCOLS.test(url) && !isLinkSneaky(url)) {
results.push(
<a key={count} href={url}>
{originalText}
</a>
);
} else {
results.push(renderNonLink({ text: originalText, key: count }));
}
chunkLastIndex = match.lastIndex;
});
if (chunkLastIndex < chunk.length) {
count += 1;
const { url, text: originalText } = match;
count += 1;
if (SUPPORTED_PROTOCOLS.test(url) && !isLinkSneaky(url)) {
results.push(
renderNonLink({
text: chunk.slice(chunkLastIndex),
key: count,
})
<a key={count} href={url}>
{originalText}
</a>
);
} else {
results.push(renderNonLink({ text: originalText, key: count }));
}
chunkLastIndex = match.lastIndex;
});
return results;
}
if (chunkLastIndex < chunk.length) {
count += 1;
results.push(
renderNonLink({
text: chunk.slice(chunkLastIndex),
key: count,
})
);
}
});
return <>{results}</>;
}