Jump to content

in Slate.js, how to parse emojis?

QQ_cazo

my code so far:

 

import Prism from 'prismjs'
//import 'prismjs/components/prism-markdown'
import './md'
import React, { useCallback, useMemo,useRef } from 'react'
import { Slate, Editable, withReact,ReactEditor  } from 'slate-react'
import { Text, createEditor, Descendant,Transforms,Editor,Node,Range  } from 'slate'
import { useSelected, useFocused, useSlate } from 'slate-react';
import { withHistory } from 'slate-history'
import twemoji from 'twemoji';
import Emoji from 'emoji-dictionary'
import emojiRegex from 'emoji-regex';
const withEmoji = editor => {
  const { insertText } = editor;
  editor.insertText = text => {
    const regex = emojiRegex();
    const match = text.match(regex);

    if (match && !editor.isInsertingEmoji) {
      editor.isInsertingEmoji = true;
      const emoji = { type: 'emoji', children: [{ text: text + ' ' }] };
      Transforms.insertNodes(editor, emoji);
      editor.isInsertingEmoji = false;
      return;
    }
    insertText(text);
  };
  return editor;
};

const MarkdownPreviewExample = (props) => {
  const renderLeaf = useCallback(props => <Leaf {...props} />, [])
  const editor = useMemo(() => (withHistory(withReact(createEditor()))), [])
  const reset = () =>{
    Transforms.delete(editor, {
      at: {
        anchor: Editor.start(editor, []),
        focus: Editor.end(editor, []),
      },
    });
    ReactEditor.focus(editor);
  }
  const getTextLength = (node) => {
    if (Node.string(node)) {
      return Node.string(node).length;
    } else {
      return node.children.reduce((acc, child) => acc + getTextLength(child), 0);
    }
  };
  
  // Assuming you have the `editor` variable referring to your Slate editor instance
  const getTextLength2 = () => {
    if (editor.children) {
      try {
        return editor.children.reduce((acc, node) => acc + getTextLength(node), 0)
      } catch (error) {
        return 0
      }
    }else{
      return 0
    }
  }
  props.reffer.current = {reset: reset, getTextLength: getTextLength2,editor: editor}
  const decorate = useCallback(([node, path]) => {
    const ranges = []

    if (!Text.isText(node)) {
      return ranges
    }

    const getLength = token => {
      if (typeof token === 'string') {
        return token.length
      } else if (typeof token.content === 'string') {
        return token.content.length
      } else {
        return token.content.reduce((l, t) => l + getLength(t), 0)
      }
    }

    const tokens = Prism.tokenize(node.text, Prism.languages.markdown)
    let start = 0

    for (const token of tokens) {
      const length = getLength(token)
      const end = start + length
      if (typeof token !== 'string') {
        let startP2 = start
        for (const subToken of token.content) {
          if (subToken.type === "punctuation") {
            const end2 = startP2 + getLength(subToken)
            ranges.push({
              "punctuation": true,
              anchor: { path, offset: startP2 },
              focus: { path, offset: end2 },
            })
            startP2 = end2
          }else{
            const end2 = startP2 + getLength(subToken)
            ranges.push({
              [token.type]: true,
              anchor: { path, offset: startP2 },
              focus: { path, offset: end2 },
            })
            startP2 = end2
          }
          
        }
      }

      start = end
    }
    return ranges
  }, [])
  return (
    <Slate editor={editor} initialValue={initialValue} onChange={(value) => {props.onChange(value)}}>
      <Editable
        decorate={decorate}
        renderLeaf={renderLeaf}
        renderElement={Element}
        placeholder={`Message @${props.inputName}`}
      />
    </Slate>
  )
}

const Leaf = ({ attributes, children, leaf }) => {
  return (
    <span
      {...attributes}
      style={{
        fontWeight: leaf.bold ? 'bold' : 'normal',
        fontStyle: leaf.italic ? 'italic' : 'normal',
        textDecoration: leaf.underlined ? 'underline' : 'none',
        ...(leaf.title && {
          display: 'inline-block',
          fontWeight: 'bold',
          fontSize: '20px',
          margin: '20px 0 10px 0',
        }),
        ...(leaf.boldItalic && {
          fontWeight: 'bold',
          fontStyle: 'italic',
        
        }),
        ...(leaf.punctuation && {
          opacity: '0.75',        
        }),
        ...(leaf.list && {
          paddingLeft: '10px',
          fontSize: '20px',
          lineHeight: '10px',
        }),
        ...(leaf.strike && {
          textDecoration: 'line-through'
        }),
        ...(leaf.blockquote && {
          display: 'inline-block',
          borderLeft: '2px solid #ddd',
          paddingLeft: '10px',
          color: '#aaa',
          fontStyle: 'italic',
        }),
        ...(leaf.code && {
          fontFamily: 'monospace',
          backgroundColor: '#eee',
          padding: '3px',
        }),
      }}
    >
      {children}
    </span>
  );
};
const Element = ({ attributes, children, element }) => {
  console.log(element)
  switch (element.type) {
      case 'paragraph':
        return <div style={{"position": "relative"}} {...attributes}>{children}</div>;
      //case 'emoji':
      //  return <div style={{"position": "relative"}} className='emoji' {...attributes}>{children}</div>;
      default:
          return <div style={{"position": "relative"}} {...attributes}>{children}</div>;
  }
};


const initialValue = [
  {
    type: 'paragraph',
    children: [{ text: '' }],
  },
]
export default MarkdownPreviewExample

 

 

my goal, im trying to figure out how to parse emojis within slate. i wanted to use twemoji as they are a standard.

i dont know where im going wrong, i asked github copolit and it just give me this (the withEmoji, nothing else)

if i can get help, i can throw a few bucks to someone

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×