Browse Source

Add emoji support to editor

Peter Justin 3 years ago
parent
commit
7ccf596f01

+ 1 - 0
flaskbb/themes/aurora/src/app.js

@@ -8,6 +8,7 @@ import "./app/confirm_modal.js";
 
 import "./scss/styles.scss";
 export { BulkActions, show_management_search, check_overview_status } from "./app/flaskbb.js";
+export { EDITORS } from './app/editor.js';
 
 var tooltips = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"], [data-tooltip="tooltip"]'))
 var tooltipList = tooltips.map(function (el) {

+ 91 - 5
flaskbb/themes/aurora/src/app/editor.js

@@ -1,18 +1,104 @@
 import EasyMDE from "easymde";
+import { CodeMirrorEditor } from "@textcomplete/codemirror";
+import EMOJIS from "./emoji";
+import { Textcomplete } from "@textcomplete/core";
+import { parse_emoji } from "./flaskbb";
+export const EDITORS = new Map();
+
+
+
+function startsWith(term, limit = 10) {
+    const results = [];
+    // Whether previous key started with the term
+    let prevMatch = false
+    for (const [key, url] of EMOJIS) {
+        if (key.startsWith(term)) {
+            results.push([key, url])
+            if (results.length === limit) break
+            prevMatch = true
+        } else if (prevMatch) {
+            break
+        }
+    }
+    return results
+}
+
+
+const EMOJI_STRATEGY = {
+    id: "emoji",
+    match: /\B:([\-+\w]*)$/,
+    search: (term, callback) => {
+        callback(EMOJIS.map(value => {
+            let x =  value[0].indexOf(term) !== -1 ? { character: value[1], name: value[0] } : null;
+            return x;
+        }))
+    },
+    replace: (value) => {
+        return `${value.character} `;
+    },
+    template: (value) => {
+        return parse_emoji(value.character) + ' ' + value.name;
+    },
+    context: (text) => {
+        const blockmatch = text.match(/`{3}/g)
+        if (blockmatch && blockmatch.length % 2) {
+            // Cursor is in a code block
+            return false
+        }
+        const inlinematch = text.match(/`/g)
+        if (inlinematch && inlinematch.length % 2) {
+            // Cursor is in a inline code
+            return false
+        }
+        return true
+    },
+}
+
+
 
 function loadEditor(element) {
     const easyMDE = new EasyMDE({
         autoDownloadFontAwesome: false,
         element: element,
-        //autoRefresh: true,
+        autoRefresh: true,
         forceSync: true,
         spellChecker: false,
         sideBySideFullscreen: false,
-        status: false
+        status: false,
     });
+    const textCompleteEditor = new CodeMirrorEditor(easyMDE.codemirror);
+    const textcomp = new Textcomplete(textCompleteEditor, [EMOJI_STRATEGY], { dropdown: { maxCount: 5 }})
+    return easyMDE;
 }
 
-const editors = document.querySelectorAll(".flaskbb-editor");
-for(const e of editors) {
-    loadEditor(e);
+
+function autoresizeTextarea(element) {
+    element.setAttribute(
+        "style",
+        "height:" + element.scrollHeight + "px;overflow-y:hidden;"
+    );
+    element.addEventListener(
+        "input",
+        function (e) {
+            console.log(e)
+            e.target.style.height = "auto";
+            e.target.style.height = e.target.scrollHeight + "px";
+        },
+        false
+    );
 }
+
+const tareas = document.querySelectorAll("[data-autoresize=true]");
+for (const e of tareas) {
+    autoresizeTextarea(e);
+}
+
+const editorsSelector = document.querySelectorAll(".flaskbb-editor");
+editorsSelector.forEach((value, index) => {
+    if (typeof value.id != 'undefined') {
+        EDITORS.set(value.id, loadEditor(value));
+    } else {
+        EDITORS.set(`easyMDE-${index}`, loadEditor(value));
+    }
+
+});

+ 3 - 2
flaskbb/themes/aurora/src/app/flaskbb.js

@@ -4,6 +4,7 @@
  * License: BSD - See LICENSE for more details.
  */
 import { Modal } from "bootstrap";
+import { EDITORS } from "./editor.js";
 
 // get the csrf token from the header
 let csrf_token = document.querySelector("meta[name=csrf-token]").content;
@@ -195,11 +196,11 @@ document.addEventListener("DOMContentLoaded", function (event) {
                     : "";
             const url = `${urlprefix}post/${post_id}/raw`;
 
-            const editor = document.querySelector(".flaskbb-editor");
+            const editor = EDITORS.get("content");
             fetch(url)
                 .then((response) => response.text())
                 .then((data) => {
-                    editor.value = data;
+                    editor.value(data);
                     editor.selectionStart = editor.selectionEnd =
                         editor.value.length;
                     editor.scrollTop = editor.scrollHeight;