瀏覽代碼

Reimpl emoji picker showing logic

Taichi Masuyama 3 年之前
父節點
當前提交
3f36838352

+ 66 - 39
packages/app/src/components/PageEditor/CodeMirrorEditor.jsx

@@ -8,7 +8,6 @@ import PropTypes from 'prop-types';
 import { Button } from 'reactstrap';
 import * as loadScript from 'simple-load-script';
 import urljoin from 'url-join';
-import { debounce } from 'throttle-debounce';
 
 import InterceptorManager from '~/services/interceptor-manager';
 import loggerFactory from '~/utils/logger';
@@ -106,7 +105,8 @@ class CodeMirrorEditor extends AbstractEditor {
       isCheatsheetModalShown: false,
       additionalClassSet: new Set(),
       isEmojiPickerShown: false,
-      emojiSearchText: null,
+      emojiSearchText: '',
+      isEmojiPickerMode: false,
     };
 
     this.cm = React.createRef();
@@ -132,7 +132,15 @@ class CodeMirrorEditor extends AbstractEditor {
     this.pasteHandler = this.pasteHandler.bind(this);
     this.cursorHandler = this.cursorHandler.bind(this);
     this.changeHandler = this.changeHandler.bind(this);
-    this.keyUpHandler = this.keyUpHandler.bind(this);
+    this.onEmojiPickerMode = this.onEmojiPickerMode.bind(this);
+    this.offEmojiPickerMode = this.offEmojiPickerMode.bind(this);
+    this.resetEmojiSearchText = this.resetEmojiSearchText.bind(this);
+    this.resetEmojiPickerInfo = this.resetEmojiPickerInfo.bind(this);
+    this.shouldLoadEmojiPicker = this.shouldLoadEmojiPicker.bind(this);
+    this.loadEmojiSearchText = this.loadEmojiSearchText.bind(this);
+    this.showEmojiPicker = this.showEmojiPicker.bind(this);
+    this.loadEmojiPicker = this.loadEmojiPicker.bind(this);
+    this.keyPressHandler = this.keyPressHandler.bind(this);
 
     this.updateCheatsheetStates = this.updateCheatsheetStates.bind(this);
 
@@ -147,7 +155,6 @@ class CodeMirrorEditor extends AbstractEditor {
 
     this.foldDrawioSection = this.foldDrawioSection.bind(this);
     this.onSaveForDrawio = this.onSaveForDrawio.bind(this);
-    this.checkWhetherEmojiPickerShouldBeShown = this.checkWhetherEmojiPickerShouldBeShown.bind(this);
 
   }
 
@@ -584,26 +591,66 @@ class CodeMirrorEditor extends AbstractEditor {
 
   }
 
-  shouldCallCheckWhetherEmojiPickerShouldBeShown(event) { // 引数は要検討
-    const state = {
-      isEmojiPickerMode: true,
-      currentLetter: 'a', // :, Space, Backspace, Enter
-    };
+  onEmojiPickerMode() {
+    this.setState({ isEmojiPickerMode: true });
+  }
 
-    if (state.currentLetter === 'Space') {
-      state.isEmojiPickerMode = false;
-    }
-    if (state.currentLetter === ':') {
-      state.isEmojiPickerMode = true;
+  offEmojiPickerMode() {
+    this.setState({ isEmojiPickerMode: false });
+  }
+
+  resetEmojiSearchText() {
+    this.setState({ emojiSearchText: '' });
+  }
+
+  resetEmojiPickerInfo() {
+    this.offEmojiPickerMode();
+    this.resetEmojiSearchText();
+  }
+
+  shouldLoadEmojiPicker(ch) {
+    const lowerCh = ch.toLowerCase();
+
+    const isEmojiPickerMode = this.state.isEmojiPickerMode;
+    const isChValid = 'abcdefghijklmnopqrstuvwxyz0123456789-+_'.indexOf(lowerCh) !== -1;
+    return isEmojiPickerMode && isChValid;
+  }
+
+  loadEmojiSearchText(newchar) {
+    if (!this.state.isEmojiPickerMode) {
+      return;
     }
 
-    return event.key !== 'Backspace';
+    this.setState(prev => ({ emojiSearchText: prev.emojiSearchText.concat(newchar) }));
+  }
+
+  showEmojiPicker() {
+    // show emoji picker with a stored word
+    this.setState({ isEmojiPickerShown: true });
+    this.offEmojiPickerMode();
   }
 
-  keyUpHandler(editor, event) {
-    if (this.shouldCallCheckWhetherEmojiPickerShouldBeShown(event)) {
-      debounce(100, () => this.checkWhetherEmojiPickerShouldBeShown());
+  loadEmojiPicker(ch) {
+    this.loadEmojiSearchText(ch);
+
+    this.showEmojiPicker();
+  }
+
+  keyPressHandler(editor, event) {
+    const char = event.key;
+
+    if (char === ':') {
+      this.onEmojiPickerMode();
+      this.resetEmojiSearchText();
+      return;
     }
+
+    if (!this.shouldLoadEmojiPicker(char)) {
+      this.resetEmojiPickerInfo();
+      return;
+    }
+
+    this.loadEmojiPicker(char);
   }
 
   /**
@@ -627,26 +674,6 @@ class CodeMirrorEditor extends AbstractEditor {
 
   }
 
-  /**
-   * Show emoji picker component when emoji pattern (`:` + searchWord ) found
-   * eg `:a`, `:ap`
-   */
-  checkWhetherEmojiPickerShouldBeShown() {
-    const searchWord = this.emojiPickerHelper.getEmoji();
-
-    if (searchWord == null) {
-      this.setState({ isEmojiPickerShown: false });
-      this.setState({ emojiSearchText: null });
-    }
-    else {
-      this.setState({ emojiSearchText: searchWord });
-      // Show emoji picker after user stop typing
-      setTimeout(() => {
-        this.setState({ isEmojiPickerShown: true });
-      }, 700);
-    }
-  }
-
   /**
    * update states which related to cheatsheet
    * @param {boolean} isGfmModeTmp (use state.isGfmMode if null is set)
@@ -1060,7 +1087,7 @@ class CodeMirrorEditor extends AbstractEditor {
               this.props.onDragEnter(event);
             }
           }}
-          onKeyUp={this.keyUpHandler}
+          onKeyPress={this.keyPressHandler}
         />
 
         { this.renderLoadingKeymapOverlay() }

+ 0 - 22
packages/app/src/components/PageEditor/EmojiPickerHelper.ts

@@ -63,28 +63,6 @@ export default class EmojiPickerHelper {
     this.editor.refresh();
   };
 
-  getEmoji = () => {
-    const sc = this.getSearchCursor();
-    const currentPos = this.editor.getCursor();
-
-    if (sc.findPrevious()) {
-      const isInputtingEmoji = (currentPos.line === sc.to().line && currentPos.ch === sc.to().ch);
-      // current search cursor position
-      if (!isInputtingEmoji) {
-        return;
-      }
-      const pos = {
-        line: sc.to().line,
-        ch: sc.to().ch,
-      };
-      const currentSearchText = sc.matches(true, pos).match[0];
-      const searchWord = currentSearchText.replace(':', '');
-      return searchWord;
-    }
-
-    return;
-  };
-
 }
 
 export const getEmojiTranslation = () => {