Load visible emoji groups when scrolling
This commit is contained in:
parent
992d57ef69
commit
ba1b006e05
@ -57,7 +57,8 @@ const EmojiPicker = {
|
|||||||
keepOpen: false,
|
keepOpen: false,
|
||||||
customEmojiBufferSlice: LOAD_EMOJI_BY,
|
customEmojiBufferSlice: LOAD_EMOJI_BY,
|
||||||
customEmojiTimeout: null,
|
customEmojiTimeout: null,
|
||||||
customEmojiLoadAllConfirmed: false
|
customEmojiLoadAllConfirmed: false,
|
||||||
|
groupLoadedCount: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@ -79,7 +80,9 @@ const EmojiPicker = {
|
|||||||
const target = (e && e.target) || this.$refs['emoji-groups']
|
const target = (e && e.target) || this.$refs['emoji-groups']
|
||||||
this.updateScrolledClass(target)
|
this.updateScrolledClass(target)
|
||||||
this.scrolledGroup(target)
|
this.scrolledGroup(target)
|
||||||
|
this.$nextTick(() => {
|
||||||
this.triggerLoadMore(target)
|
this.triggerLoadMore(target)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
highlight (key) {
|
highlight (key) {
|
||||||
const ref = this.$refs['group-' + key]
|
const ref = this.$refs['group-' + key]
|
||||||
@ -88,6 +91,7 @@ const EmojiPicker = {
|
|||||||
this.activeGroup = key
|
this.activeGroup = key
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs['emoji-groups'].scrollTop = top + 1
|
this.$refs['emoji-groups'].scrollTop = top + 1
|
||||||
|
this.loadEmoji(key)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
updateScrolledClass (target) {
|
updateScrolledClass (target) {
|
||||||
@ -100,10 +104,16 @@ const EmojiPicker = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
triggerLoadMore (target) {
|
triggerLoadMore (target) {
|
||||||
const ref = this.$refs[`group-end-${this.lastNonUnicodeGroupId}`][0]
|
Object.keys(this.allCustomGroups)
|
||||||
if (!ref) return
|
.map(groupId => {
|
||||||
|
const ref = this.$refs[`group-end-${groupId}`][0]
|
||||||
|
if (!ref) return undefined
|
||||||
|
|
||||||
const bottom = ref.offsetTop + ref.offsetHeight
|
const bottom = ref.offsetTop + ref.offsetHeight
|
||||||
|
|
||||||
|
const group = this.$refs[`group-${groupId}`][0]
|
||||||
|
const top = group.offsetTop
|
||||||
|
|
||||||
const scrollerBottom = target.scrollTop + target.clientHeight
|
const scrollerBottom = target.scrollTop + target.clientHeight
|
||||||
const scrollerTop = target.scrollTop
|
const scrollerTop = target.scrollTop
|
||||||
const scrollerMax = target.scrollHeight
|
const scrollerMax = target.scrollHeight
|
||||||
@ -111,17 +121,23 @@ const EmojiPicker = {
|
|||||||
// Loads more emoji when they come into view
|
// Loads more emoji when they come into view
|
||||||
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 < 5
|
const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom
|
||||||
// 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)) {
|
||||||
this.loadEmoji()
|
return groupId
|
||||||
}
|
}
|
||||||
|
return undefined
|
||||||
|
})
|
||||||
|
.filter(k => k)
|
||||||
|
.map(k => {
|
||||||
|
this.loadEmoji(k)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
scrolledGroup (target) {
|
scrolledGroup (target) {
|
||||||
const top = target.scrollTop + 5
|
const top = target.scrollTop + 5
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.emojisView.forEach(group => {
|
this.allEmojiGroups.forEach(group => {
|
||||||
const ref = this.$refs['group-' + group.id]
|
const ref = this.$refs['group-' + group.id]
|
||||||
if (ref.offsetTop <= top) {
|
if (ref.offsetTop <= top) {
|
||||||
this.activeGroup = group.id
|
this.activeGroup = group.id
|
||||||
@ -129,14 +145,21 @@ const EmojiPicker = {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
loadEmoji () {
|
loadEmoji (loadGroup) {
|
||||||
const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length
|
if (!this.allCustomGroups[loadGroup]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const allLoaded = this.loadedCount[loadGroup] >= this.allCustomGroups[loadGroup].emojis.length
|
||||||
|
|
||||||
if (allLoaded) {
|
if (allLoaded) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.customEmojiBufferSlice += LOAD_EMOJI_BY
|
this.groupLoadedCount = {
|
||||||
|
...this.groupLoadedCount,
|
||||||
|
[loadGroup]: this.loadedCount[loadGroup] + LOAD_EMOJI_BY
|
||||||
|
}
|
||||||
},
|
},
|
||||||
startEmojiLoad (forceUpdate = false) {
|
startEmojiLoad (forceUpdate = false) {
|
||||||
if (!forceUpdate) {
|
if (!forceUpdate) {
|
||||||
@ -157,6 +180,9 @@ const EmojiPicker = {
|
|||||||
},
|
},
|
||||||
setShowStickers (value) {
|
setShowStickers (value) {
|
||||||
this.showingStickers = value
|
this.showingStickers = value
|
||||||
|
},
|
||||||
|
limitedEmojis (list, groupId) {
|
||||||
|
return list.slice(0, this.loadedCount[groupId])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -205,24 +231,36 @@ const EmojiPicker = {
|
|||||||
return res
|
return res
|
||||||
}, {})
|
}, {})
|
||||||
},
|
},
|
||||||
allEmojiGroups () {
|
allCustomGroups () {
|
||||||
return this.allEmojis
|
return this.filteredEmoji
|
||||||
.reduce((res, emoji) => {
|
.reduce((res, emoji) => {
|
||||||
const packName = packOf(emoji)
|
const packName = packOf(emoji)
|
||||||
const packId = `custom-${packName}`
|
const packId = `custom-${packName}`
|
||||||
if (res.filter(k => k.id === packId).length === 0) {
|
if (!res[packId]) {
|
||||||
res.push({
|
res[packId] = ({
|
||||||
id: packId,
|
id: packId,
|
||||||
text: packName,
|
text: packName,
|
||||||
image: emoji.imageUrl
|
image: emoji.imageUrl,
|
||||||
|
emojis: []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
res[packId].emojis.push(emoji)
|
||||||
return res
|
return res
|
||||||
}, [])
|
}, {})
|
||||||
|
},
|
||||||
|
sensibleInitialAmountForAGroup () {
|
||||||
|
const groupCount = Object.keys(this.allCustomGroups).length
|
||||||
|
return Math.max(Math.floor(LOAD_EMOJI_BY / Math.max(groupCount, 1)), 1)
|
||||||
|
},
|
||||||
|
allEmojiGroups () {
|
||||||
|
const standardEmojis = this.$store.state.instance.emoji || []
|
||||||
|
return Object.entries(this.allCustomGroups)
|
||||||
|
.map(([_, v]) => v)
|
||||||
.concat({
|
.concat({
|
||||||
id: 'standard',
|
id: 'standard',
|
||||||
text: this.$t('emoji.unicode'),
|
text: this.$t('emoji.unicode'),
|
||||||
icon: 'box-open'
|
icon: 'box-open',
|
||||||
|
emojis: filterByKeyword(standardEmojis, this.keyword)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
emojis () {
|
emojis () {
|
||||||
@ -241,6 +279,13 @@ const EmojiPicker = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
loadedCount () {
|
||||||
|
return Object.keys(this.allCustomGroups)
|
||||||
|
.reduce((res, groupId) => {
|
||||||
|
res[groupId] = this.groupLoadedCount[groupId] || this.sensibleInitialAmountForAGroup
|
||||||
|
return res
|
||||||
|
}, {})
|
||||||
|
},
|
||||||
lastNonUnicodeGroupId () {
|
lastNonUnicodeGroupId () {
|
||||||
return this.emojis[this.emojis.length - 2].id
|
return this.emojis[this.emojis.length - 2].id
|
||||||
},
|
},
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
@scroll="onScroll"
|
@scroll="onScroll"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="group in emojisView"
|
v-for="group in allEmojiGroups"
|
||||||
:key="group.id"
|
:key="group.id"
|
||||||
class="emoji-group"
|
class="emoji-group"
|
||||||
>
|
>
|
||||||
@ -78,7 +78,7 @@
|
|||||||
{{ group.text }}
|
{{ group.text }}
|
||||||
</h6>
|
</h6>
|
||||||
<span
|
<span
|
||||||
v-for="emoji in group.emojis"
|
v-for="emoji in limitedEmojis(group.emojis, group.id)"
|
||||||
:key="group.id + emoji.displayText"
|
:key="group.id + emoji.displayText"
|
||||||
:title="emoji.displayText"
|
:title="emoji.displayText"
|
||||||
class="emoji-item"
|
class="emoji-item"
|
||||||
|
Loading…
Reference in New Issue
Block a user