aboutsummaryrefslogtreecommitdiff
path: root/src/components/emoji_picker
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/emoji_picker')
-rw-r--r--src/components/emoji_picker/emoji_picker.js77
-rw-r--r--src/components/emoji_picker/emoji_picker.scss28
-rw-r--r--src/components/emoji_picker/emoji_picker.vue14
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"