How to implement a reaction to type emulation (in real time)?

I have a chat application written in response.

I need the following:

  • When a user writes a smile name, for example. :smile: should be converted to emojione, not unicode .
  • The entry should be in the form of a code below.
  • The emoji on the tab should look the same as in the conversation.
 <div contentEditable styles={this.state.messageInputStyle} className="message-input"> </div> 
+5
source share
2 answers

here is a great way to make div contentEditable with html and onChange details. I used this with the emojione shortnameToImage function.

here is the working code

styles can be added to contentEditable details if you want them to come from state

the only thing that needs to be addressed is the carriage position after adding emoji.

 class Application extends React.Component { state = { value: "Start Writing Here" }; render() { return ( <ContentEditable html={emojione.shortnameToImage(this.state.value)} onChange={this._onChange} /> ); } _onChange = e => { this.setState({ value: e.target.value }); }; } var ContentEditable = React.createClass({ render: function() { return ( <div contentEditable className="message-input" onInput={this.emitChange} onBlur={this.emitChange} dangerouslySetInnerHTML={{ __html: this.props.html }} /> ); }, shouldComponentUpdate: function(nextProps) { return nextProps.html !== this.getDOMNode().innerHTML; }, componentDidUpdate: function() { if (this.props.html !== this.getDOMNode().innerHTML) { this.getDOMNode().innerHTML = this.props.html; } }, emitChange: function() { var html = this.getDOMNode().innerHTML; if (this.props.onChange && html !== this.lastHtml) { this.props.onChange({ target: { value: html } }); } this.lastHtml = html; } }); React.render(<Application />, document.getElementById("app")); 
 html, body { height: 100% } .message-input { width: 100%; height: 100%; font-size: 30px; } .emojione { height: 30px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.min.js"></script> <div id="app"></div> 
+1
source

I used emojione and this piece of code basically came up with a very non-responsive solution, as shown below. Hope this helps.

 import React from 'react'; import {render} from 'react-dom'; import emojione from 'emojione'; class App extends React.Component { constructor(props) { super(props); } updateText = () => { const html = emojione.shortnameToImage(this.refs.inputDiv.innerHTML); let sel, range; if (window.getSelection) { // IE9 and non-IE sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); range.deleteContents(); // Range.createContextualFragment() would be useful here but is // non-standard and not supported in all browsers (IE9, for one) let el = this.refs.inputDiv; el.innerHTML = html; let frag = document.createDocumentFragment(), node, lastNode; while ((node = el.firstChild)) { lastNode = frag.appendChild(node); } range.insertNode(frag); // Preserve the selection if (lastNode) { range = range.cloneRange(); range.setStartAfter(lastNode); range.collapse(true); sel.removeAllRanges(); sel.addRange(range); } } } else if (document.selection && document.selection.type !== "Control") { // IE < 9 document.selection.createRange().pasteHTML(html); } }; render() { return ( <div ref="inputDiv" contentEditable onInput={this.updateText}/> ); } } render(<App/>, document.getElementById('root')); 

Here is a working example https://codesandbox.io/s/ol2lmkqqlq

+1
source

Source: https://habr.com/ru/post/1275085/


All Articles