Optimise emoji picker loading process

This commit is contained in:
Tusooa Zhu 2021-08-15 00:43:35 -04:00
parent 99a368dbb3
commit 123913f34f
No known key found for this signature in database
GPG Key ID: 7B467EDE43A08224
3 changed files with 34 additions and 71 deletions

View File

@ -106,6 +106,7 @@ const EmojiPicker = {
}, },
triggerLoadMore (target) { triggerLoadMore (target) {
Object.keys(this.allCustomGroups) Object.keys(this.allCustomGroups)
.filter(id => this.filteredEmojiGroups.filter(group => group.id === id).length > 0)
.map(groupId => { .map(groupId => {
const ref = this.$refs[`group-end-${groupId}`][0] const ref = this.$refs[`group-end-${groupId}`][0]
if (!ref) return undefined if (!ref) return undefined
@ -123,9 +124,10 @@ const EmojiPicker = {
const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN
// Always load when at the very top in case there's no scroll space yet // Always load when at the very top in case there's no scroll space yet
const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom
const unscrollable = top - bottom < target.clientHeight
// Don't load when looking at unicode category or at the very bottom // Don't load when looking at unicode category or at the very bottom
const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax
if (!bottomAboveViewport && (approachingBottom || atTop)) { if (!bottomAboveViewport && (approachingBottom || atTop || unscrollable)) {
return groupId return groupId
} }
return undefined return undefined
@ -176,12 +178,6 @@ const EmojiPicker = {
this.firstLoaded = true this.firstLoaded = true
}) })
}) })
const bufferSize = this.customEmojiBuffer.length
const bufferPrefilledAll = bufferSize === this.filteredEmoji.length
if (bufferPrefilledAll && !forceUpdate) {
return
}
this.customEmojiBufferSlice = LOAD_EMOJI_BY
}, },
toggleStickers () { toggleStickers () {
this.showingStickers = !this.showingStickers this.showingStickers = !this.showingStickers
@ -191,6 +187,9 @@ const EmojiPicker = {
}, },
limitedEmojis (list, groupId) { limitedEmojis (list, groupId) {
return list.slice(0, this.loadedCount[groupId]) return list.slice(0, this.loadedCount[groupId])
},
filterByKeyword (list, keyword) {
return filterByKeyword(list, keyword)
} }
}, },
watch: { watch: {
@ -210,51 +209,8 @@ const EmojiPicker = {
} }
return 0 return 0
}, },
allEmojis () {
return this.$store.state.instance.customEmoji || []
},
filteredEmoji () {
return filterByKeyword(
this.allEmojis,
trim(this.keyword)
)
},
customEmojiBuffer () {
return this.filteredEmoji.slice(0, this.customEmojiBufferSlice)
},
groupedCustomEmojis () {
return this.customEmojiBuffer.reduce((res, emoji) => {
const pack = packOf(emoji)
if (!res[pack]) {
res[pack] = {
id: `custom-${pack}`,
text: pack,
/// FIXME
// icon: 'smile-beam',
image: emoji.imageUrl,
emojis: []
}
}
res[pack].emojis.push(emoji)
return res
}, {})
},
allCustomGroups () { allCustomGroups () {
return this.filteredEmoji return this.$store.getters.groupedCustomEmojis
.reduce((res, emoji) => {
const packName = packOf(emoji)
const packId = `custom-${packName}`
if (!res[packId]) {
res[packId] = ({
id: packId,
text: packName,
image: emoji.imageUrl,
emojis: []
})
}
res[packId].emojis.push(emoji)
return res
}, {})
}, },
sensibleInitialAmountForAGroup () { sensibleInitialAmountForAGroup () {
const groupCount = Object.keys(this.allCustomGroups).length const groupCount = Object.keys(this.allCustomGroups).length
@ -271,21 +227,13 @@ const EmojiPicker = {
emojis: filterByKeyword(standardEmojis, this.keyword) emojis: filterByKeyword(standardEmojis, this.keyword)
}) })
}, },
emojis () { filteredEmojiGroups () {
const standardEmojis = this.$store.state.instance.emoji || [] return this.allEmojiGroups
// const customEmojis = this.customEmojiBuffer .map(group => ({
...group,
return [ emojis: filterByKeyword(group.emojis, this.keyword)
...Object }))
.keys(this.groupedCustomEmojis) .filter(group => group.emojis.length > 0)
.map(k => this.groupedCustomEmojis[k]),
{
id: 'standard',
text: this.$t('emoji.unicode'),
icon: 'box-open',
emojis: filterByKeyword(standardEmojis, trim(this.keyword))
}
]
}, },
loadedCount () { loadedCount () {
return Object.keys(this.allCustomGroups) return Object.keys(this.allCustomGroups)
@ -297,9 +245,6 @@ const EmojiPicker = {
lastNonUnicodeGroupId () { lastNonUnicodeGroupId () {
return this.emojis[this.emojis.length - 2].id return this.emojis[this.emojis.length - 2].id
}, },
emojisView () {
return this.emojis.filter(value => value.emojis.length > 0)
},
stickerPickerEnabled () { stickerPickerEnabled () {
return (this.$store.state.instance.stickers || []).length !== 0 return (this.$store.state.instance.stickers || []).length !== 0
} }

View File

@ -3,7 +3,7 @@
<div class="heading"> <div class="heading">
<span class="emoji-tabs"> <span class="emoji-tabs">
<span <span
v-for="group in allEmojiGroups" v-for="group in filteredEmojiGroups"
:key="group.id" :key="group.id"
class="emoji-tabs-item" class="emoji-tabs-item"
:class="{ :class="{
@ -67,7 +67,7 @@
@scroll="onScroll" @scroll="onScroll"
> >
<div <div
v-for="group in allEmojiGroups" v-for="group in filteredEmojiGroups"
:key="group.id" :key="group.id"
class="emoji-group" class="emoji-group"
> >

View File

@ -115,6 +115,24 @@ const instance = {
.map(key => [key, state[key]]) .map(key => [key, state[key]])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
}, },
groupedCustomEmojis (state) {
return state.customEmoji
.reduce((res, emoji) => {
emoji.tags.forEach(packName => {
const packId = `custom-${packName}`
if (!res[packId]) {
res[packId] = ({
id: packId,
text: packName,
image: emoji.imageUrl,
emojis: []
})
}
res[packId].emojis.push(emoji)
})
return res
}, {})
},
instanceDomain (state) { instanceDomain (state) {
return new URL(state.server).hostname return new URL(state.server).hostname
} }