milesj / interweave

🌀 React library to safely render HTML, filter attributes, autowrap text with matchers, render emoji characters, and much more.
https://interweave.dev
MIT License
1.1k stars 38 forks source link

Interweave: Missing emoji source data. #236

Closed elhe26 closed 2 years ago

elhe26 commented 2 years ago

Hi,

I'm using Interweave with this configuration:

...
              <Interweave
                content={message.text}
                emojiPath={(hexcode: string, { size }: PathConfig) =>
                  `https://twemoji.maxcdn.com/v/latest/${size}/${hexcode}.png`
                }
                matchers={[
                  new UrlMatcher('url'),
                  new HashtagMatcher('hashtag'),
                  new EmojiMatcher('emoji', {
                    convertEmoticon: true,
                    convertShortcode: true,
                  }),
                ]}
...

I'm getting this error: Error: Missing emoji source data. Have you loaded with theuseEmojiDatahook and passed theemojiSourceprop?

Do I need to create a component? Where Can I find an example code?

Regards.

elhe26 commented 2 years ago

What do you think @milesj ?

milesj commented 2 years ago

@elhe26 You need to manually load the data: https://interweave.dev/docs/exts/emoji#loading-emoji-data

elhe26 commented 2 years ago

@milesj , When I use the example, I get JSX element type 'BaseInterweave' does not have any construct or call signatures..

milesj commented 2 years ago

@elhe26 Are you importing it like the example? import BaseInterweave, { InterweaveProps } from 'interweave';

elhe26 commented 2 years ago

@milesj , yes. This is an example from a reply:

import { stripHexcode } from 'emojibase';
import type { InterweaveProps } from 'interweave';
import BaseInterweave from 'interweave';
import type { PathConfig } from 'interweave-emoji';
import { useEmojiData } from 'interweave-emoji';
import React from 'react';

function getEmojiPath(hexcode: string, { enlarged }: PathConfig): string {
  return `//cdn.jsdelivr.net/emojione/assets/3.1/png/${enlarged ? 64 : 32}/${stripHexcode(
    hexcode
  ).toLowerCase()}.png`;
}

export default function Interweave(props: InterweaveProps) {
  const [source] = useEmojiData({ compact: false, shortcodes: ['emojibase'] });

  return <BaseInterweave {...props} emojiSource={source} emojiPath={getEmojiPath} />;
milesj commented 2 years ago

@elhe26 Try import { Interweave as BaseInterweave } from 'interweave';

elhe26 commented 2 years ago

Thanks @milesj .

Do I need to add emojiPath after using useEmojiData? I'm getting 404 errors from https://twemoji.maxcdn.com/v/latest/24/1F920.png, etc...

Since emojiData is already downloaded (from useEmojiData), how can I use it instead of emojiPath?

milesj commented 2 years ago

@elhe26 Yes you need both. Data is just JSON, while the path is the img/svg location.

This just sounds like the twemoji URL is incorrect.

elhe26 commented 2 years ago

Thanks @milesj.

Per documentation:

Using any of these solutions causes this error: Uncaught TypeError: Cannot read properties of undefined (reading 'replace').

Is there a way to avoid rendering 404 emojis?

milesj commented 2 years ago

@elhe26 Don't render img/svg and just use native unicode. https://interweave.dev/docs/exts/emoji/#displaying-unicode-characters

elhe26 commented 2 years ago

Sorry, @milesj. The last issue is happening when using EmojiPicker.

This is the configuration:

...
          <EmojiPicker
            compact
            disableSkinTones
            // hideShortcodes
            // hideEmoticon
            emojiSize={32}
            emojiLargeSize={64}
            columnCount={15}
            rowCount={5}
            locale="es-mx"
            blockList={[
              '1F4A9',
              '1F52B',
            ]}
            emojiPath={(hexcode: string, { size }: PathConfig) =>
              `https://cdn.jsdelivr.net/npm/emojione-assets@4.5.0/png/${size}/${stripHexcode(
                hexcode
              ).toLowerCase()}.png`
            }
            onSelectEmoji={selectedEmoji}
          />
...
milesj commented 2 years ago

@elhe26 Is there a stack trace? Hard to know unless I know whats calling the replace.

elhe26 commented 2 years ago

Hi @milesj . I was using EmojiPicker and Interweave as input and was getting this error. I switched to a normal input instead and I'm not getting that error.

I'm still getting this view when using EmojiPicker:

image

This is my configuration:

EmojiPicker

...
          <EmojiPicker
            compact
            disableSkinTones
            // hideShortcodes
            // hideEmoticon
            avoidFetch
            disableGroups
            maxCommonlyUsed={5}
            emojiSize={32}
            emojiLargeSize={64}
            // columnCount={15}
            // rowCount={5}
            locale="es-mx"
            blockList={[
              '1F4A9', // poop
              '1F52B', // gun
            ]}
            emojiPath={(hexcode: string, { size }: PathConfig) =>
              `https://cdn.jsdelivr.net/npm/emojione-assets@4.5.0/png/${size}/${stripHexcode(
                hexcode
              ).toLowerCase()}.png`
            }
            onSelectEmoji={selectedEmoji}
          />
...

Edit:

The onSelectEmoji event has the emoji value (CanonicalEmoji) but when we select one, these are the results:

emoji: undefined
emoji Text: undefined
emoji Unicode: undefined
emoji Label: mano haciendo el gesto de llamar
emoji Emoticon: undefined
emoji canonical_shortcodes: :call_me_hand:

Is there a way to get any value to work inside input tag?

Sorry for all the questions. Thank you for all your help.

milesj commented 2 years ago

@elhe26 It's probably because you're using compact mode. Try removing that prop.

elhe26 commented 2 years ago

Thanks @milesj . Removing compact did the trick.

Do you have any URL I could use to avoid this:

image

Any recommendation? I'm using jsdelivr @4.5 but I'm getting lots of 404 errors.

milesj commented 2 years ago

@elhe26 You can maybe try this: https://github.com/milesj/interweave/blob/master/tests/bundle.tsx#L34

Not all emoji icon sets support the latest emoji versions. You can set the maxEmojiVersion to control this.

elhe26 commented 2 years ago

Everything is working without issues! Thank you very much @milesj !

Closing this issue.

Notes:

We can use TailwindCSS to format (to a certain extent) EmojiPicker.

elhe26 commented 2 years ago

Adding my configuration just in case someone needs an example:

EmojiPicker

...
            <EmojiPicker
              disableSkinTones
              disablePreview
              noPreview
              avoidFetch
              disableGroups
              maxCommonlyUsed={5}
              emojiSize={32}
              emojiLargeSize={64}
              maxEmojiVersion={4}
              locale="es-mx"
              blockList={[
                '1F4A9', // poop
                '1F52B', // gun
              ]}
              // Good Path
              emojiPath={(hexcode: string, { enlarged }: PathConfig) =>
                `https://cdn.jsdelivr.net/gh/joypixels/emoji-assets@latest/png/${
                  enlarged ? 64 : 32
                }/${stripHexcode(hexcode).toLowerCase()}.png`
              }
              onSelectEmoji={selectedEmoji}
              classNames={{
                emojisHeader: 'bg-white', // Tailwind Class
                emojisHeaderSticky: 'bg-white', // Tailwind Class
                emojisBody: 'bg-white', // Tailwind Class
                search: 'rounded rounded-xl', // Tailwind Class
                searchInput: 'rounded rounded-xl', // Tailwind Class
              }}
            />
...

Interweave (Component)

import type { InterweaveProps } from 'interweave';
import { Interweave as BaseInterweave } from 'interweave';
import { useEmojiData } from 'interweave-emoji';
import React from 'react';

export default function Interweave(props: InterweaveProps) {
  const [source] = useEmojiData({ compact: true, shortcodes: ['cldr', 'emojibase'] });

  return <BaseInterweave {...props} emojiSource={source} />;
}

Interweave (Instantiation)

              <Interweave
                className="text-sm"
                content={message.textMessage.text}
                emojiPath={(hexcode: string, { enlarged }: PathConfig) =>
                  `https://cdn.jsdelivr.net/gh/joypixels/emoji-assets@latest/png/${
                    enlarged ? 64 : 32
                  }/${stripHexcode(hexcode).toLowerCase()}.png`
                }
                matchers={[
                  new UrlMatcher('url'),
                  new HashtagMatcher('hashtag'),
                  new EmojiMatcher('emoji', {
                    renderUnicode: true,
                  }),
                ]}
              />

Regards,

milesj commented 2 years ago

Glad its working 👍