diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 3799359f36..0e59358bd7 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -190,7 +190,7 @@ const getStaticEmoji = async ({ store }) => { imageUrl: false, replacement: values[key] } - }) + }).sort((a, b) => a.displayText - b.displayText) store.dispatch('setInstanceOption', { name: 'emoji', value: emoji }) } else { throw (res) @@ -209,14 +209,16 @@ const getCustomEmoji = async ({ store }) => { if (res.ok) { const result = await res.json() const values = Array.isArray(result) ? Object.assign({}, ...result) : result - const emoji = Object.keys(values).map((key) => { - const imageUrl = values[key].image_url + const emoji = Object.entries(values).map(([key, value]) => { + const imageUrl = value.image_url return { displayText: key, - imageUrl: imageUrl ? store.state.instance.server + imageUrl : values[key], + imageUrl: imageUrl ? store.state.instance.server + imageUrl : value, + tags: imageUrl ? value.tags.sort((a, b) => a > b ? 1 : 0) : ['utf'], replacement: `:${key}: ` } - }) + // Technically could use tags but those are kinda useless right now, should have been "pack" field, that would be more useful + }).sort((a, b) => a.displayText.toLowerCase() > b.displayText.toLowerCase() ? 1 : 0) store.dispatch('setInstanceOption', { name: 'customEmoji', value: emoji }) store.dispatch('setInstanceOption', { name: 'pleromaBackend', value: true }) } else { diff --git a/src/components/emoji-input/emoji-input.js b/src/components/emoji-input/emoji-input.js index 62c58446f3..1c49c71089 100644 --- a/src/components/emoji-input/emoji-input.js +++ b/src/components/emoji-input/emoji-input.js @@ -53,6 +53,11 @@ const EmojiInput = { */ required: true, type: String + }, + emojiPicker: { + required: false, + type: Boolean, + default: false } }, data () { @@ -61,7 +66,8 @@ const EmojiInput = { highlighted: 0, caret: 0, focused: false, - blurTimeout: null + blurTimeout: null, + showPicker: false, } }, components: { @@ -83,12 +89,15 @@ const EmojiInput = { highlighted: index === this.highlighted })) }, - showPopup () { + showSuggestions () { return this.focused && this.suggestions && this.suggestions.length > 0 }, textAtCaret () { return (this.wordAtCaret || {}).word || '' }, + pickerIconBottom () { + return this.input && this.input.tag === 'textarea' + }, wordAtCaret () { if (this.value && this.caret) { const word = Completion.wordAtPosition(this.value, this.caret - 1) || {} @@ -124,11 +133,22 @@ const EmojiInput = { } }, methods: { + togglePicker () { + this.showPicker = !this.showPicker + }, replace (replacement) { const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement) this.$emit('input', newValue) this.caret = 0 }, + insert (insertion) { + const newValue = [ + this.value.substring(0, this.caret), + insertion, + this.value.substring(this.caret) + ].join('') + this.$emit('input', newValue) + }, replaceText (e, suggestion) { const len = this.suggestions.length || 0 if (this.textAtCaret.length === 1) { return } @@ -195,6 +215,7 @@ const EmojiInput = { this.blurTimeout = null } + this.showPicker = false this.focused = true this.setCaret(e) this.resize() @@ -231,6 +252,7 @@ const EmojiInput = { } }, onInput (e) { + this.showPicker = false this.setCaret(e) this.$emit('input', e.target.value) }, @@ -239,6 +261,9 @@ const EmojiInput = { this.resize() this.$emit('input', e.target.value) }, + onClickOutside () { + this.showPicker = false + }, setCaret ({ target: { selectionStart } }) { this.caret = selectionStart }, @@ -247,6 +272,7 @@ const EmojiInput = { if (!panel) return const { offsetHeight, offsetTop } = this.input.elm this.$refs.panel.style.top = (offsetTop + offsetHeight) + 'px' + this.$refs.picker.$el.style.top = (offsetTop + offsetHeight) + 'px' } } } diff --git a/src/components/emoji-input/emoji-input.vue b/src/components/emoji-input/emoji-input.vue index 48739ec846..605882e8ce 100644 --- a/src/components/emoji-input/emoji-input.vue +++ b/src/components/emoji-input/emoji-input.vue @@ -1,10 +1,29 @@