diff --git a/front/src/App.vue b/front/src/App.vue index 9675a49..f138ed3 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -87,37 +87,20 @@ export default { }, setUpDoc(stream) { - - api - .zulip - .getMsgs(this.zulipClient, stream, 'content') - .then(result => { + + api.zulip.getMsgs(this.zulipClient, stream, "content").then((result) => { for (let m = 0; m < result.messages.length; m++) { const message = result.messages[m] this.$store.commit('addMessage', message) } - // this - // .$store - // .commit( 'setContents', - // result - // .messages - // ) - }) - - api - .zulip - .getMsgs(this.zulipClient, stream, 'rules') - .then(result => { - this - .$store - .commit( 'setRules', - result - .messages - ) - }) - + }); + + api.zulip.getMsgs(this.zulipClient, stream, "rules").then((result) => { + this.$store.commit("setRules", result.messages); + }); + api.zulip.listen(this.zulipClient, this.eventHandler) - + }, eventHandler(event) { diff --git a/front/src/components/Rules/Rule.vue b/front/src/components/Rules/Rule.vue index bb4e6de..5db22e1 100644 --- a/front/src/components/Rules/Rule.vue +++ b/front/src/components/Rules/Rule.vue @@ -1,35 +1,27 @@ \ No newline at end of file diff --git a/front/src/components/Rules/Styles.vue b/front/src/components/Rules/Styles.vue index 1709ce3..938ab3c 100644 --- a/front/src/components/Rules/Styles.vue +++ b/front/src/components/Rules/Styles.vue @@ -1,12 +1,15 @@ \ No newline at end of file diff --git a/front/src/mixins/emoji.js b/front/src/mixins/emoji.js index 97c2177..e80162a 100644 --- a/front/src/mixins/emoji.js +++ b/front/src/mixins/emoji.js @@ -1,34 +1,40 @@ -let toUTF16 = (codePoint) => { - var TEN_BITS = parseInt("1111111111", 2); - if (codePoint <= 0xffff) { - return u(codePoint); - } - codePoint -= 0x10000; - // Shift right to get to most significant 10 bits - var leadSurrogate = 0xd800 + (codePoint >> 10); - // Mask to get least significant 10 bits - var tailSurrogate = 0xdc00 + (codePoint & TEN_BITS); - return u(leadSurrogate) + (tailSurrogate); -} +// let toUTF16 = (codePoint) => { +// var TEN_BITS = parseInt("1111111111", 2); +// if (codePoint <= 0xffff) { +// return u(codePoint); +// } +// codePoint -= 0x10000; +// // Shift right to get to most significant 10 bits +// var leadSurrogate = 0xd800 + (codePoint >> 10); +// // Mask to get least significant 10 bits +// var tailSurrogate = 0xdc00 + (codePoint & TEN_BITS); +// return u(leadSurrogate) + (tailSurrogate); +// } -let u = (codeUnit) => { - return "\\u" + codeUnit.toString(16).toUpperCase(); -} +// let u = (codeUnit) => { +// return "\\u" + codeUnit.toString(16).toUpperCase(); +// } export default { methods: { - // toEmojiCode: (emoji) => { - // console.log(emoji); - // emoji.replace(/\p{Emoji}/gu, (m) => m.codePointAt(0).toString(16)); - // }, - toEmojiCode: (emoji) => { - emoji.replace(/\p{Emoji}/gu, function (m) { - toUTF16(m.codePointAt(0)); - }); - console.log(emoji) - return emoji; + console.log(emoji); + return emoji.replace(/\p{Emoji}/gu, (m) => m.codePointAt(0).toString(16)); + }, + + // toEmojiCode: (emoji) => { + // console.log(emoji) + // emoji.replace(/\p{Emoji}/gu, function (m) { + // toUTF16(m.codePointAt(0)); + // }); + // console.log(emoji) + // return emoji; + // }, + + containsEmoji(str) { + // Regular expression to match emoji + const regexExp = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/gi; + return regexExp.test(str); // true }, - } } \ No newline at end of file diff --git a/front/src/store/index.js b/front/src/store/index.js index 0d457a6..1d7d180 100644 --- a/front/src/store/index.js +++ b/front/src/store/index.js @@ -1,56 +1,40 @@ +/*eslint no-unused-vars: "off"*/ +/*eslint no-undef: "off"*/ + import { createStore } from 'vuex' import emoji from "../mixins/emoji"; +import { stripHtml } from "string-strip-html"; -const toCSS = (poll, currentStream) => { - let - className = "", +var EmojiConvertor = require('emoji-js'); +var emojiConv = new EmojiConvertor(); + +let toCSS = (message, currentStream) => { + let className = "", emoji_code = "", - options = [], - rules = [], - subs = poll.submessages.map((s) => JSON.parse(s.content)), + rules = [], parentClassName = currentStream - - subs.forEach(sub => { - if (sub.widget_type && sub.widget_type == "poll") { - className = sub.extra_data.question - emoji_code = emoji.methods.toEmojiCode(className) - options = sub.extra_data.options - // console.log(emoji_code) - if (options) { - options.forEach(option => { - let r = constructRule(option, options, subs) - if (validateRule(r)) { - rules.push(r) - } - }) - } - } else if (sub.type && sub.type == "new_option") { - let r = constructRule(sub.option, options, subs) - if (validateRule(r)) { - rules.push(r) - } + + // let regex = /[/s]?(?.+)\s*\n?{\n?(?[\s\w.~:>-]+\s*:\s*.+;?\n?)*\n?}/gm + let regex = /[/s]?(?.+)\s*\n?{\n?(?(.*;\n?)+)}/gm + let content = stripHtml(message.content).result; + let results = content.matchAll(regex); + results = Array.from(results); + if (results.length > 0) { + className = emojiConv.replace_colons(results[0]['groups']['selector']); + if (emoji.methods.containsEmoji(className)) { + emoji_code = emoji.methods.toEmojiCode(className); } - }) - return { parentClassName, className, emoji_code, rules } + rules = results[0]['groups']['props'].split("\n"); + rules = rules.filter((rule) => validateRule(rule)) + return { className, emoji_code, rules }; + } + return null; } -const constructRule = (option, options, subs) => { - const - text = option, - votes = subs.filter( s => - s.type == "vote" && - s.key.replace("canned,", "") == options.indexOf(option) - ), - weight = - votes.length > 0 - ? votes.map((s) => s.vote).reduce((a, b) => a + b) - : 0 - return { text, weight } +let validateRule = (rule) => { + return rule.match(/.+:.+;/gm); } -// minimal validation. rules have to contain a colon and semicolon -const validateRule = rule => rule.text.match(/.+:.+;/gm) - export default createStore({ strict: process.env.NODE_ENV !== 'production', @@ -82,14 +66,6 @@ export default createStore({ .replace(/[^]+.*```quote\n/gm, '') .replace(/ \n```/gm, '') } - // console.log(message.responseTo) - // const referenceMessage = state.contents.find(m => { - // m.id == message.responseTo.id - // // && - // // m.sender_id == message.responseTo.sender_id - // // m.content.includes(message.responseTo.quote) - // }) - // console.log(referenceMessage) } state.contents.push(message) }, @@ -118,12 +94,16 @@ export default createStore({ } }, - - setRules: (state, rules) => { state.rules = - rules - .filter((r) => r.content.match(/\/poll/gm)) - .map((r) => toCSS(r, state.currentStream)) + setRules: (state, rules) => { + state.rules = rules.reduce((acc, cur) => { + let rule = toCSS(cur, state.currentStream); + if (rule !== null) { + acc.push(rule); + } + return acc + }, []) }, + addRule: (state, rule) => { if (rule.content.match(/\/poll/gm)) { state.rules.push(toCSS(rule)) diff --git a/package-lock.json b/package-lock.json index ae7c4da..3323709 100644 --- a/package-lock.json +++ b/package-lock.json @@ -169,6 +169,19 @@ "safer-buffer": "^2.1.0" } }, + "emoji-datasource": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoji-datasource/-/emoji-datasource-4.1.0.tgz", + "integrity": "sha1-tEVX94ot+sLzUDkzkbFwpWfsKK0=" + }, + "emoji-js": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/emoji-js/-/emoji-js-3.5.0.tgz", + "integrity": "sha512-5uaULzdR3g6ALBC8xUzyoxAx6izT1M4+DEsxHLRS2/gaOKC/p62831itMoMsYfUj1fKX3YG01u5YVz2v7qpsWg==", + "requires": { + "emoji-datasource": "4.1.0" + } + }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -268,6 +281,11 @@ "har-schema": "^2.0.0" } }, + "html-entities": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", + "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==" + }, "html2canvas": { "version": "1.0.0-rc.7", "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-rc.7.tgz", @@ -412,6 +430,26 @@ "type-check": "~0.3.2" } }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.trim": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", + "integrity": "sha1-NkJefukL5KpeJ7zruFt9EepHqlc=" + }, + "lodash.without": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.without/-/lodash.without-4.4.0.tgz", + "integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=" + }, "mime-db": { "version": "1.48.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", @@ -488,6 +526,44 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "ranges-apply": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ranges-apply/-/ranges-apply-5.1.0.tgz", + "integrity": "sha512-VF3a0XUuYS/BQHv2RaIyX1K7S1hbfrs64hkGKgPVk0Y7p4XFwSucjTTttrBqmkcmB/PZx5ISTZdxErRZi/89aQ==", + "requires": { + "@babel/runtime": "^7.14.0", + "ranges-merge": "^7.1.0" + } + }, + "ranges-merge": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ranges-merge/-/ranges-merge-7.1.0.tgz", + "integrity": "sha512-coTHcyAEIhoEdsBs9f5f+q0rmy7UHvS/5nfuXzuj5oLX/l/tbqM5uxRb6eh8WMdetXia3lK67ZO4tarH4ieulQ==", + "requires": { + "@babel/runtime": "^7.14.0", + "ranges-push": "^5.1.0", + "ranges-sort": "^4.1.0" + } + }, + "ranges-push": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ranges-push/-/ranges-push-5.1.0.tgz", + "integrity": "sha512-vqGcaGq7GWV1zBa9w83E+dzYkOvE9/3pIRUPvLf12c+mGQCf1nesrkBI7Ob8taN2CC9V1HDSJx0KAQl0SgZftA==", + "requires": { + "@babel/runtime": "^7.14.0", + "ranges-merge": "^7.1.0", + "string-collapse-leading-whitespace": "^5.1.0", + "string-trim-spaces-only": "^3.1.0" + } + }, + "ranges-sort": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ranges-sort/-/ranges-sort-4.1.0.tgz", + "integrity": "sha512-GOQgk6UtsrfKFeYa53YLiBVnLINwYmOk5l2QZG1csZpT6GdImUwooh+/cRrp7b+fYawZX/rnyA3Ul+pdgQBIzA==", + "requires": { + "@babel/runtime": "^7.14.0" + } + }, "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", @@ -584,6 +660,47 @@ "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-1.4.1.tgz", "integrity": "sha1-hJqm+UsnL/JvZHH6QTDtH35HlVs=" }, + "string-collapse-leading-whitespace": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/string-collapse-leading-whitespace/-/string-collapse-leading-whitespace-5.1.0.tgz", + "integrity": "sha512-mYz9/Kb5uvRB4DZj46zILwI4y9lD9JsvXG9Xb7zjbwm0I/R40G7oFfMsqJ28l2d7gWMTLJL569NfJQVLQbnHCw==", + "requires": { + "@babel/runtime": "^7.14.0" + } + }, + "string-left-right": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-left-right/-/string-left-right-4.1.0.tgz", + "integrity": "sha512-ic/WvfNVUygWWsgg8akzSzp2NuttfhrdbH7QmSnda5b5RFmT9aCEDiS/M+gmTJwtFy7+b/2AXU4Z6vejcePQqQ==", + "requires": { + "@babel/runtime": "^7.14.0", + "lodash.clonedeep": "^4.5.0", + "lodash.isplainobject": "^4.0.6" + } + }, + "string-strip-html": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/string-strip-html/-/string-strip-html-8.3.0.tgz", + "integrity": "sha512-1+rjTPt0JjpFr1w0bfNL1S6O0I9fJDqM+P3pFTpC6eEEpIXhmBvPLnaQoEuWarswiH219qCefDSxTLxGQyHKUg==", + "requires": { + "@babel/runtime": "^7.14.0", + "html-entities": "^2.3.2", + "lodash.isplainobject": "^4.0.6", + "lodash.trim": "^4.5.1", + "lodash.without": "^4.4.0", + "ranges-apply": "^5.1.0", + "ranges-push": "^5.1.0", + "string-left-right": "^4.1.0" + } + }, + "string-trim-spaces-only": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-trim-spaces-only/-/string-trim-spaces-only-3.1.0.tgz", + "integrity": "sha512-AW7RSi3+QtE6wR+4m/kmwlyy39neBbCIzrzzu1/RGzNRiPKQOeB3rGzr4ubg4UIQgYtr2w0PrxhKPXgyqJ0vaQ==", + "requires": { + "@babel/runtime": "^7.14.0" + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index c2db051..b3d7da9 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "author": "Karl Moubarak", "license": "ISC", "dependencies": { + "emoji-js": "^3.5.0", + "string-strip-html": "^8.3.0", "vue-html2pdf": "^1.8.0", "zulip-js": "^2.0.9" }