diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index bd5c2e39..49438a4b 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -6,7 +6,7 @@ import {
faStickyNote,
faSmileBeam
} from '@fortawesome/free-solid-svg-icons'
-import { trim } from 'lodash'
+import { trim, escapeRegExp, startCase } from 'lodash'
library.add(
faBoxOpen,
@@ -21,23 +21,6 @@ const LOAD_EMOJI_BY = 60
// When to start loading new batch emoji, in pixels
const LOAD_EMOJI_MARGIN = 64
-const filterByKeyword = (list, keyword = '') => {
- if (keyword === '') return list
-
- const keywordLowercase = keyword.toLowerCase()
- let orderedEmojiList = []
- for (const emoji of list) {
- const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase)
- if (indexOfKeyword > -1) {
- if (!Array.isArray(orderedEmojiList[indexOfKeyword])) {
- orderedEmojiList[indexOfKeyword] = []
- }
- orderedEmojiList[indexOfKeyword].push(emoji)
- }
- }
- return orderedEmojiList.flat()
-}
-
const EmojiPicker = {
props: {
enableStickerPicker: {
@@ -49,7 +32,7 @@ const EmojiPicker = {
data () {
return {
keyword: '',
- activeGroup: 'custom',
+ activeGroup: 'standard',
showingStickers: false,
groupsScrolledClass: 'scrolled-top',
keepOpen: false,
@@ -80,13 +63,8 @@ const EmojiPicker = {
this.triggerLoadMore(target)
},
highlight (key) {
- const ref = this.$refs['group-' + key]
- const top = ref.offsetTop
this.setShowStickers(false)
this.activeGroup = key
- this.$nextTick(() => {
- this.$refs['emoji-groups'].scrollTop = top + 1
- })
},
updateScrolledClass (target) {
if (target.scrollTop <= 5) {
@@ -155,6 +133,13 @@ const EmojiPicker = {
},
setShowStickers (value) {
this.showingStickers = value
+ },
+ filterByKeyword (list) {
+ if (this.keyword === '') return list
+ const regex = new RegExp(escapeRegExp(trim(this.keyword)), 'i')
+ return list.filter(emoji => {
+ return regex.test(emoji.displayText)
+ })
}
},
watch: {
@@ -175,9 +160,8 @@ const EmojiPicker = {
return 0
},
filteredEmoji () {
- return filterByKeyword(
- this.$store.state.instance.customEmoji || [],
- trim(this.keyword)
+ return this.filterByKeyword(
+ this.$store.state.instance.customEmoji || []
)
},
customEmojiBuffer () {
@@ -185,25 +169,50 @@ const EmojiPicker = {
},
emojis () {
const standardEmojis = this.$store.state.instance.emoji || []
- const customEmojis = this.customEmojiBuffer
-
+ const customEmojis = this.sortedEmoji
+ const emojiPacks = []
+ customEmojis.forEach((pack, id) => {
+ emojiPacks.push({
+ id: id.replace(/^pack:/, ''),
+ text: startCase(id.replace(/^pack:/, '')),
+ first: pack[0],
+ emojis: this.filterByKeyword(pack)
+ })
+ })
return [
- {
- id: 'custom',
- text: this.$t('emoji.custom'),
- icon: 'smile-beam',
- emojis: customEmojis
- },
{
id: 'standard',
text: this.$t('emoji.unicode'),
- icon: 'box-open',
- emojis: filterByKeyword(standardEmojis, trim(this.keyword))
+ first: {
+ imageUrl: '',
+ replacement: '🥴'
+ },
+ emojis: this.filterByKeyword(standardEmojis)
}
- ]
+ ].concat(emojiPacks)
+ },
+ sortedEmoji () {
+ const customEmojis = this.$store.state.instance.customEmoji || []
+ const sortedEmojiGroups = new Map()
+ customEmojis.forEach((emoji) => {
+ if (!sortedEmojiGroups.has(emoji.tags[0])) {
+ sortedEmojiGroups.set(emoji.tags[0], [emoji])
+ } else {
+ sortedEmojiGroups.get(emoji.tags[0]).push(emoji)
+ }
+ })
+ return new Map([...sortedEmojiGroups.entries()].sort())
},
emojisView () {
- return this.emojis.filter(value => value.emojis.length > 0)
+ if (this.keyword === '') {
+ return this.emojis.filter(pack => {
+ return pack.id === this.activeGroup
+ })
+ } else {
+ return this.emojis.filter(pack => {
+ return pack.emojis.length > 0
+ })
+ }
},
stickerPickerEnabled () {
return (this.$store.state.instance.stickers || []).length !== 0
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index 2055e02e..9c814e15 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -35,9 +35,8 @@
}
.heading {
- display: flex;
- height: 32px;
- padding: 10px 7px 5px;
+ margin-top: 10px;
+ height: 4.8em;
}
.content {
@@ -65,15 +64,34 @@
.additional-tabs,
.emoji-tabs {
+ position: absolute;
display: block;
- min-width: 0;
- flex-basis: auto;
- flex-shrink: 1;
+ flex-wrap: nowrap;
+ overflow: auto;
+ width: 100%;
+
+ white-space: nowrap;
+
&-item {
- padding: 0 7px;
+ vertical-align: top;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ padding: .4em;
cursor: pointer;
- font-size: 1.85em;
+
+ img {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ }
+
+ span {
+ font-size: 1.9em;
+ }
&.disabled {
opacity: 0.5;
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index a7269120..408048d2 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -13,10 +13,11 @@
:title="group.text"
@click.prevent="highlight(group.id)"
>
-
+ {{ group.first.replacement }}
+