From ec37b3ac9246fcf3f78a3f9ed4fb70536ca19b46 Mon Sep 17 00:00:00 2001 From: supertiger Date: Tue, 19 Mar 2019 16:03:40 +0000 Subject: [PATCH] emoji suggestions finished --- src/components/app/RightPanel.vue | 83 ++++++++++++++-------- src/components/app/emojiSuggestions.vue | 52 +++++++------- src/store/index.js | 4 +- src/store/modules/emojiSuggestionModule.js | 47 ++++++++++++ 4 files changed, 133 insertions(+), 53 deletions(-) create mode 100644 src/store/modules/emojiSuggestionModule.js diff --git a/src/components/app/RightPanel.vue b/src/components/app/RightPanel.vue index 64a20ce..7b245d9 100644 --- a/src/components/app/RightPanel.vue +++ b/src/components/app/RightPanel.vue @@ -31,8 +31,8 @@
-
- +
+
@@ -103,9 +103,7 @@ export default { postTimerID: null, getTimerID: null, typing: false, - whosTyping: "", - showEmojiSuggestions: false, - emojiSuggestionsArray: [] + whosTyping: "" }; }, methods: { @@ -132,7 +130,7 @@ export default { if (this.message == "") return; if (this.message.length > 5000) return; - this.showEmojiSuggestions = false; + (this.$store.dispatch('setEmojiArray', null)); clearInterval(this.postTimerID); this.postTimerID = null; this.messageLength = 0; @@ -198,48 +196,53 @@ export default { } }, emojiSwitchKey(event) { - if (!this.showEmojiSuggestions) return; + if (!this.emojiArray) return; const keyCode = event.keyCode; if (keyCode == 38) { //up - bus.$emit("emojiSuggestions:up"); + bus.$emit("emojiSuggestions:key", "up"); event.preventDefault(); return; } if (keyCode == 40) { //down - bus.$emit("emojiSuggestions:down"); + bus.$emit("emojiSuggestions:key", "down"); event.preventDefault(); return; } }, - GetWordByPos(str, pos) { - let left = str.substr(0, pos); - let right = str.substr(pos); - - left = left.replace(/^.+ /g, ""); - right = right.replace(/ .+$/g, ""); - - return left + right; + ReturnWord(text, caretPos) { + var index = text.indexOf(caretPos); + var preText = text.substring(0, caretPos); + if (preText.indexOf(" ") > 0) { + var words = preText.split(" "); + return words[words.length - 1]; //return last word + } else { + return preText; + } }, showEmojiPopout(event) { if (event.keyCode == 38 || event.keyCode == 40) return; // up/down const cursorPosition = event.target.selectionStart; - const cursorWord = this.GetWordByPos(this.message, cursorPosition) - const cursorLetter = this.message.substring(cursorPosition - 1, cursorPosition) + const cursorWord = this.ReturnWord(this.message, cursorPosition); + const cursorLetter = this.message.substring( + cursorPosition - 1, + cursorPosition + ); - if (cursorLetter.trim() == "" || cursorWord.endsWith(":")) - return this.showEmojiSuggestions = false; - - if (cursorWord.startsWith(":") && cursorWord.length >= 3) { - const searchArr = emojiParser.searchEmoji(cursorWord.slice(1, -1)); - if (searchArr.length <= 0) return (this.showEmojiSuggestions = false); - this.emojiSuggestionsArray = searchArr; - this.showEmojiSuggestions = true; - } + if (cursorLetter.trim() == "" || cursorWord.endsWith(":")) + return (this.$store.dispatch('setEmojiArray', null)); + + if (!cursorWord.startsWith(":") || cursorWord.length <= 2) + return (this.$store.dispatch('setEmojiArray', null)); + + const searchArr = emojiParser.searchEmoji(cursorWord.slice(1, -1)); + if (searchArr.length <= 0) return (this.$store.dispatch('setEmojiArray', null)); + + (this.$store.dispatch('setEmojiArray', searchArr)); }, async onInput(event) { this.resize(event); @@ -254,6 +257,18 @@ export default { this.resize(event); this.showEmojiPopout(event); }, + enterEmojiSuggestion(){ + this.$refs["input-box"].focus(); + const emojiShortCode = `:${this.emojiArray[this.emojiIndex].shortcodes[0]}:` + const cursorPosition = this.$refs['input-box'].selectionStart; + const cursorWord = this.ReturnWord(this.message, cursorPosition); + + const start = cursorPosition - cursorWord.length; + const end = cursorPosition; + + this.message = this.message.substring(0, start) + emojiShortCode + this.message.substring(end); + return (this.$store.dispatch('setEmojiArray', null)); + }, keyDown(event) { this.resize(event); this.emojiSwitchKey(event); @@ -262,6 +277,10 @@ export default { // and the shift key is not held if (!event.shiftKey) { event.preventDefault(); + if (this.emojiArray){ + this.enterEmojiSuggestion(); + return; + } this.sendMessage(); } } @@ -333,6 +352,7 @@ export default { }, 2500); }; bus.$on("newMessage", this.hideTypingStatus); + bus.$on("emojiSuggestions:Selected", this.enterEmojiSuggestion) //dismiss notification on focus window.onfocus = () => { bus.$emit("title:change", "Nertivia"); @@ -349,6 +369,7 @@ export default { }, beforeDestroy() { bus.$off("newMessage", this.hideTypingStatus); + bus.$off("emojiSuggestions:Selected", this.enterEmojiSuggestion) delete this.$options.sockets.typingStatus; }, computed: { @@ -381,6 +402,12 @@ export default { }, channelName() { return this.$store.getters.channelName; + }, + emojiArray() { + return this.$store.getters.emojiArray; + }, + emojiIndex() { + return this.$store.getters.getEmojiIndex; } } }; diff --git a/src/components/app/emojiSuggestions.vue b/src/components/app/emojiSuggestions.vue index c4a4c9c..1907fc2 100644 --- a/src/components/app/emojiSuggestions.vue +++ b/src/components/app/emojiSuggestions.vue @@ -2,8 +2,9 @@
@@ -17,48 +18,51 @@ import { bus } from "@/main"; import emojiParser from "@/utils/emojiParser.js"; export default { props: ["emojiArray"], - data() { - return { - selectedIndex: 0 - }; - }, methods: { emojiParser(emoji) { return emojiParser.replaceEmojis(emoji); }, hoverEvent(event) { - const emoji = event.target.closest(".emoji"); + const emoji = event.target.closest(".emojiItem"); const parent = event.target.parentElement.children; - if (!emoji || !emoji) return; + if (!emoji) return; const index = [...parent].findIndex(el => el === emoji); - if (index >= 0) this.selectedIndex = index; + if (index >= 0) this.$store.dispatch("changeIndex", index); }, KeySwitch(key) { if (key == "up") { - if (this.selectedIndex == 0) - return (this.selectedIndex = - this.$props.emojiArray.slice(0, 10).length - 1); + if (this.emojiIndex == 0) + return this.$store.dispatch( + "changeIndex", + this.$props.emojiArray.slice(0, 10).length - 1 + ); - this.selectedIndex--; + this.$store.dispatch("changeIndex", this.emojiIndex - 1); } if (key == "down") { - if ( - this.selectedIndex == - this.$props.emojiArray.slice(0, 10).length - 1 - ) - return (this.selectedIndex = 0); - - this.selectedIndex++; + if (this.emojiIndex == this.$props.emojiArray.slice(0, 10).length - 1) + return this.$store.dispatch("changeIndex", 0); + this.$store.dispatch("changeIndex", this.emojiIndex + 1); } }, + clickEvent() { + bus.$emit('emojiSuggestions:Selected') + } }, mounted() { - bus.$on("emojiSuggestions:up", () => this.KeySwitch("up")); - bus.$on("emojiSuggestions:down", () => this.KeySwitch("down")); + bus.$on("emojiSuggestions:key", this.KeySwitch); + }, + destroyed() { + bus.$off("emojiSuggestions:key", this.KeySwitch); }, watch: { emojiArray() { - this.selectedIndex = 0; + this.$store.dispatch("changeIndex", 0); + } + }, + computed: { + emojiIndex() { + return this.$store.getters.getEmojiIndex; } } }; @@ -96,7 +100,7 @@ export default { .short-code { margin-right: 10px; } -.emoji { +.emojiItem { display: flex; padding: 5px; align-content: center; diff --git a/src/store/index.js b/src/store/index.js index c34e3e6..cfa8ff7 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -8,6 +8,7 @@ import notificationsModule from './modules/notificationsModule'; import settingsModule from './modules/settingsModule'; import uploadFilesModule from './modules/uploadFilesModule'; import popoutsModule from './modules/popoutsModule'; +import emojiSuggestionModule from './modules/emojiSuggestionModule'; import { router } from './../router' @@ -23,7 +24,8 @@ export const store = new Vuex.Store({ socketModule, settingsModule, uploadFilesModule, - popoutsModule + popoutsModule, + emojiSuggestionModule }, state: { diff --git a/src/store/modules/emojiSuggestionModule.js b/src/store/modules/emojiSuggestionModule.js new file mode 100644 index 0000000..50bc6ab --- /dev/null +++ b/src/store/modules/emojiSuggestionModule.js @@ -0,0 +1,47 @@ +import axios from 'axios' +import Vue from 'vue' +import { + bus +} from '../../main' +import VueRouter from 'vue-router'; +import NotificationSounds from '@/utils/notificationSound'; + +const state = { + array: null, + index: 0, +} + +const getters = { + emojiArray(state) { + return state.array; + }, + getEmojiIndex(state) { + return state.index; + } +} + +const actions = { + setEmojiArray(context, array) { + context.commit('setEmojiArray', array) + }, + changeIndex(context, index) { + context.commit('changeIndex', index) + } +} + +const mutations = { + setEmojiArray(state, array) { + Vue.set(state, "array", array); + }, + changeIndex(state, index) { + Vue.set(state, "index", index); + } +} + +export default { + namespace: true, + state, + getters, + actions, + mutations +} \ No newline at end of file