diff options
Diffstat (limited to 'src/components/emoji_picker')
| -rw-r--r-- | src/components/emoji_picker/emoji_picker.js | 77 | ||||
| -rw-r--r-- | src/components/emoji_picker/emoji_picker.scss | 28 | ||||
| -rw-r--r-- | src/components/emoji_picker/emoji_picker.vue | 14 |
3 files changed, 109 insertions, 10 deletions
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index b1d70176..76d1f26b 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -1,5 +1,10 @@ +import { set } from 'vue' import Checkbox from '../checkbox/checkbox.vue' +const LOAD_EMOJI_BY = 50 +const LOAD_EMOJI_INTERVAL = 100 +const LOAD_EMOJI_SANE_AMOUNT = 500 + const filterByKeyword = (list, keyword = '') => { return list.filter(x => x.displayText.includes(keyword)) } @@ -18,7 +23,12 @@ const EmojiPicker = { activeGroup: 'custom', showingStickers: false, groupsScrolledClass: 'scrolled-top', - keepOpen: false + keepOpen: false, + customEmojiBuffer: (this.$store.state.instance.customEmoji || []) + .slice(0, LOAD_EMOJI_BY), + customEmojiTimeout: null, + customEmojiCounter: LOAD_EMOJI_BY, + customEmojiLoadAllConfirmed: false } }, components: { @@ -58,6 +68,50 @@ const EmojiPicker = { }) }) }, + loadEmojiInsane () { + this.customEmojiLoadAllConfirmed = true + this.continueEmojiLoad() + }, + loadEmoji () { + const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length + const saneLoaded = this.customEmojiBuffer.length >= LOAD_EMOJI_SANE_AMOUNT && + !this.customEmojiLoadAllConfirmed + + if (allLoaded || saneLoaded) { + return + } + + this.customEmojiBuffer.push( + ...this.filteredEmoji.slice( + this.customEmojiCounter, + this.customEmojiCounter + LOAD_EMOJI_BY + ) + ) + this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL) + this.customEmojiCounter += LOAD_EMOJI_BY + }, + startEmojiLoad (forceUpdate = false) { + const bufferSize = this.customEmojiBuffer.length + const bufferPrefilledSane = bufferSize === LOAD_EMOJI_SANE_AMOUNT && !this.customEmojiLoadAllConfirmed + const bufferPrefilledAll = bufferSize === this.filteredEmoji.length + if (forceUpdate || bufferPrefilledSane || bufferPrefilledAll) { + return + } + if (this.customEmojiTimeout) { + window.clearTimeout(this.customEmojiTimeout) + } + + set( + this, + 'customEmojiBuffer', + this.filteredEmoji.slice(0, LOAD_EMOJI_BY) + ) + this.customEmojiCounter = LOAD_EMOJI_BY + this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL) + }, + continueEmojiLoad () { + this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL) + }, toggleStickers () { this.showingStickers = !this.showingStickers }, @@ -73,7 +127,9 @@ const EmojiPicker = { }, watch: { keyword () { + this.customEmojiLoadAllConfirmed = false this.scrolledGroup() + this.startEmojiLoad(true) } }, computed: { @@ -86,15 +142,30 @@ const EmojiPicker = { } return 0 }, + saneAmount () { + // for UI + return LOAD_EMOJI_SANE_AMOUNT + }, + filteredEmoji () { + return filterByKeyword( + this.$store.state.instance.customEmoji || [], + this.keyword + ) + }, + askForSanity () { + return this.customEmojiBuffer.length >= LOAD_EMOJI_SANE_AMOUNT && + !this.customEmojiLoadAllConfirmed + }, emojis () { const standardEmojis = this.$store.state.instance.emoji || [] - const customEmojis = this.$store.state.instance.customEmoji || [] + const customEmojis = this.customEmojiBuffer + return [ { id: 'custom', text: this.$t('emoji.custom'), icon: 'icon-smile', - emojis: filterByKeyword(customEmojis, this.keyword) + emojis: customEmojis }, { id: 'standard', diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index d99539b0..6608f393 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -6,15 +6,25 @@ position: absolute; right: 0; left: 0; - height: 320px; margin: 0 !important; z-index: 1; - .keep-open { + .keep-open, + .too-many-emoji { padding: 7px; line-height: normal; } + .too-many-emoji { + display: flex; + flex-direction: column; + } + + .keep-open-label { + padding: 0 7px; + display: flex; + } + .heading { display: flex; height: 32px; @@ -24,7 +34,7 @@ .content { display: flex; flex-direction: column; - flex: 1 1 0; + flex: 1 1 auto; min-height: 0px; } @@ -32,12 +42,16 @@ flex-grow: 1; } + .emoji-groups { + min-height: 200px; + } + .additional-tabs { border-left: 1px solid; border-left-color: $fallback--icon; border-left-color: var(--icon, $fallback--icon); padding-left: 7px; - flex: 0 0 0; + flex: 0 0 auto; } .additional-tabs, @@ -68,7 +82,7 @@ } .sticker-picker { - flex: 1 1 0 + flex: 1 1 auto } .stickers, @@ -76,7 +90,7 @@ &-content { display: flex; flex-direction: column; - flex: 1 1 0; + flex: 1 1 auto; min-height: 0; &.hidden { @@ -90,7 +104,7 @@ .emoji { &-search { padding: 5px; - flex: 0 0 0; + flex: 0 0 auto; input { width: 100%; diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index b974fce9..43da6aa2 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -80,6 +80,20 @@ {{ $t('emoji.keep_open') }} </Checkbox> </div> + <div + v-if="askForSanity" + class="too-many-emoji" + > + <div class="alert warning hint"> + {{ $t('emoji.load_all_hint', { saneAmount } ) }} + </div> + <button + class="btn btn-default" + @click.prevent="loadEmojiInsane" + > + {{ $t('emoji.load_all', { emojiAmount: filteredEmoji.length } ) }} + </button> + </div> </div> <div v-if="showingStickers" |
