121 lines
3.5 KiB
TypeScript
Executable File
121 lines
3.5 KiB
TypeScript
Executable File
import { stripHexcode } from 'emojibase';
|
|
import { InterweaveProps, FilterInterface, MatcherInterface, Interweave, Matcher, MatchResponse, Node } from 'interweave';
|
|
import { IpMatcher, UrlMatcher, EmailMatcher, HashtagMatcher } from 'interweave-autolink';
|
|
import { EmojiMatcher, PathConfig } from 'interweave-emoji';
|
|
|
|
class SevenTVMatcher extends Matcher {
|
|
private emotes: Record<string, string> = {
|
|
'booba': '01F6N31ETR0004P7N4A9PKS5X9',
|
|
'pepeJAM': '5f1f0ea5cf6d2144653d7501',
|
|
'OMEGALUL': '5f4b3bc28fb088567e5cbb3b',
|
|
'monkaS': '01F78CHJ2G0005TDSTZFBDGMK4',
|
|
'Sadge': '5f1f0f61b5e9d35e9a2f8a0e',
|
|
'PogU': '5f1f0c1235c7c40e6a3f9c1b',
|
|
};
|
|
|
|
replaceWith(match: string): Node {
|
|
const emoteName = match.replace(/:/g, '').trim();
|
|
const emoteId = this.emotes[emoteName];
|
|
|
|
if (emoteId) {
|
|
return (
|
|
<img
|
|
src={`https://cdn.7tv.app/emote/${emoteId}/3x.avif`}
|
|
alt={emoteName}
|
|
title={emoteName}
|
|
style={{
|
|
display: 'inline-block',
|
|
height: '28px',
|
|
verticalAlign: 'middle',
|
|
margin: '0 2px'
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return match;
|
|
}
|
|
|
|
asTag(): string {
|
|
return 'span';
|
|
}
|
|
|
|
match(value: string): MatchResponse<{}> | null {
|
|
const emoteNames = Object.keys(this.emotes).join('|');
|
|
// Match emote names wrapped in colons: :emoteName:
|
|
const pattern = new RegExp(`:(${emoteNames}):`, 'g');
|
|
const result = pattern.exec(value);
|
|
|
|
if (!result) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
index: result.index,
|
|
length: result[0].length,
|
|
match: result[0],
|
|
valid: true,
|
|
};
|
|
}
|
|
}
|
|
|
|
const globalFilters: FilterInterface[] = [];
|
|
|
|
const globalMatchers: MatcherInterface[] = [
|
|
new EmailMatcher('email'),
|
|
new IpMatcher('ip'),
|
|
new UrlMatcher('url'),
|
|
new HashtagMatcher('hashtag'),
|
|
new EmojiMatcher('emoji', {
|
|
convertEmoticon: true,
|
|
convertShortcode: true,
|
|
convertUnicode: true,
|
|
}),
|
|
new SevenTVMatcher('7tv'),
|
|
];
|
|
|
|
function getEmojiPath(hexcode: string, { enlarged }: PathConfig): string {
|
|
return `//cdn.jsdelivr.net/emojione/assets/3.1/png/${enlarged ? 64 : 32}/${stripHexcode(
|
|
hexcode,
|
|
).toLowerCase()}.png`;
|
|
}
|
|
|
|
interface Props extends InterweaveProps {
|
|
instagram?: boolean;
|
|
twitter?: boolean;
|
|
}
|
|
|
|
export default function CustomInterweave({
|
|
filters = [],
|
|
matchers = [],
|
|
twitter,
|
|
instagram,
|
|
...props
|
|
}: Props) {
|
|
// let hashtagUrl = '';
|
|
|
|
// if (twitter) {
|
|
// hashtagUrl = 'https://twitter.com/hashtag/{{hashtag}}';
|
|
// } else if (instagram) {
|
|
// hashtagUrl = 'https://instagram.com/explore/tags/{{hashtag}}';
|
|
// }
|
|
|
|
return (
|
|
<Interweave
|
|
filters={[...globalFilters, ...filters]}
|
|
matchers={[...globalMatchers, ...matchers]}
|
|
// hashtagUrl={hashtagUrl}
|
|
emojiSource={getEmojiPath}
|
|
// newWindow
|
|
{...props}
|
|
/>
|
|
// <BaseInterweave
|
|
// filters={[...globalFilters, ...filters]}
|
|
// matchers={[...globalMatchers, ...matchers]}
|
|
// hashtagUrl={hashtagUrl}
|
|
// emojiPath={getEmojiPath}
|
|
// newWindow
|
|
// {...props}
|
|
// />
|
|
);
|
|
} |