Răsfoiți Sursa

feat: display emoji-mart suggestions

- Install emoji-mart packages
- implement emoji autocomplete with codemirror
- implement codemirror showHint after typing colon ":"
mudana 4 ani în urmă
părinte
comite
243fced7a2

+ 1 - 0
packages/app/package.json

@@ -180,6 +180,7 @@
     "csv-to-markdown-table": "^1.0.1",
     "diff2html": "^3.1.2",
     "eazy-logger": "^3.1.0",
+    "emoji-mart": "^3.0.1",
     "file-loader": "^5.0.2",
     "handsontable": "=6.2.2",
     "hard-source-webpack-plugin": "^0.13.1",

+ 69 - 5
packages/app/src/components/PageEditor/CodeMirrorEditor.jsx

@@ -12,6 +12,7 @@ import * as loadScript from 'simple-load-script';
 import * as loadCssSync from 'load-css-file';
 
 import { createValidator } from '@growi/codemirror-textlint';
+import emojiData from 'emoji-mart/data/all.json';
 import InterceptorManager from '~/services/interceptor-manager';
 import loggerFactory from '~/utils/logger';
 
@@ -32,7 +33,6 @@ import HandsontableModal from './HandsontableModal';
 import EditorIcon from './EditorIcon';
 import DrawioModal from './DrawioModal';
 import { UncontrolledCodeMirror } from '../UncontrolledCodeMirror';
-
 // Textlint
 window.JSHINT = JSHINT;
 window.kuromojin = { dicPath: '/static/dict' };
@@ -170,10 +170,10 @@ export default class CodeMirrorEditor extends AbstractEditor {
   }
 
   componentWillMount() {
-    if (this.props.emojiStrategy != null) {
-      this.emojiAutoCompleteHelper = new EmojiAutoCompleteHelper(this.props.emojiStrategy);
-      this.setState({ isEnabledEmojiAutoComplete: true });
-    }
+    // if (this.props.emojiStrategy != null) {
+    // this.emojiAutoCompleteHelper = new EmojiAutoCompleteHelper(this.props.emojiStrategy);
+    this.setState({ isEnabledEmojiAutoComplete: true });
+    // }
 
     this.initializeTextlint();
   }
@@ -767,6 +767,69 @@ export default class CodeMirrorEditor extends AbstractEditor {
     return range;
   }
 
+  getEmojiList() {
+    const emojiList = [];
+    emojiData.forEach((key) => {
+      emojiList.push({
+        text: `${key}`,
+        render: (element) => {
+          element.innerHTML = `<img width="15" height="15" src="${emojiData[key]}" alt="icon" async></img> ${key}`;
+        },
+      });
+    });
+    return emojiList;
+  }
+
+  emojiComplete(cm) {
+    codemirror.showHint(cm, () => {
+
+      const cur = cm.getCursor(); const
+        token = cm.getTokenAt(cur);
+
+      const start = token.start; const end = cur.ch; const
+        word = token.string.slice(0, end - start);
+
+      let ch = cur.ch; const
+        line = cur.line;
+
+      let currentWord = token.string;
+
+      while (ch-- > -1) {
+
+        const t = cm.getTokenAt({ ch, line }).string;
+
+        if (t === ':') {
+          const emojiList = this.getEmojiList();
+          // eslint-disable-next-line no-loop-func
+          const filteredList = emojiList.filter((item) => {
+
+            return item.text.indexOf(currentWord) === 0;
+
+          });
+
+          if (filteredList.length >= 1) {
+
+            return {
+
+              list: filteredList,
+
+              from: codemirror.Pos(line, ch),
+
+              to: codemirror.Pos(line, end),
+
+            };
+
+          }
+
+        }
+
+        currentWord = t + currentWord;
+
+      }
+
+    }, { completeSingle: false });
+  }
+
   getNavbarItems() {
     return [
       <Button
@@ -940,6 +1003,7 @@ export default class CodeMirrorEditor extends AbstractEditor {
             autoCloseTags: true,
             placeholder,
             matchBrackets: true,
+            emoji: true,
             matchTags: { bothTags: true },
             // folding
             foldGutter: this.props.lineNumbers,

+ 22 - 5
yarn.lock

@@ -7289,6 +7289,14 @@ emittery@^0.8.1:
   resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860"
   integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==
 
+emoji-mart@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/emoji-mart/-/emoji-mart-3.0.1.tgz#9ce86706e02aea0506345f98464814a662ca54c6"
+  integrity sha512-sxpmMKxqLvcscu6mFn9ITHeZNkGzIvD0BSNFE/LJESPbCA8s1jM6bCDPjWbV31xHq7JXaxgpHxLB54RCbBZSlg==
+  dependencies:
+    "@babel/runtime" "^7.0.0"
+    prop-types "^15.6.0"
+
 emoji-regex@^6.4.1:
   version "6.5.1"
   resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2"
@@ -16125,6 +16133,15 @@ prop-types@^15.5.10, prop-types@^15.5.8:
     loose-envify "^1.3.1"
     object-assign "^4.1.1"
 
+prop-types@^15.6.0:
+  version "15.8.1"
+  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
+  integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+  dependencies:
+    loose-envify "^1.4.0"
+    object-assign "^4.1.1"
+    react-is "^16.13.1"
+
 prop-types@^15.6.1:
   version "15.6.1"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
@@ -16571,16 +16588,16 @@ react-images@~1.0.0:
     react-transition-group "^2.2.1"
     react-view-pager "^0.6.0"
 
+react-is@^16.13.1, react-is@^16.8.1:
+  version "16.13.1"
+  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
+  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
 react-is@^16.7.0:
   version "16.13.0"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527"
   integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==
 
-react-is@^16.8.1:
-  version "16.13.1"
-  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
-  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-
 react-is@^17.0.1:
   version "17.0.2"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"