TSK-1314: Fix slow Kanban open (#3052)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2023-04-24 16:38:17 +07:00 committed by GitHub
parent 6d17fc0117
commit 904a0614ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 31 deletions

View File

@ -34,6 +34,7 @@
export let buttons: boolean = false export let buttons: boolean = false
export let shrink: boolean = false export let shrink: boolean = false
export let divScroll: HTMLElement | undefined = undefined export let divScroll: HTMLElement | undefined = undefined
export let checkForHeaders = false
export function scroll (top: number, left?: number, behavior: 'auto' | 'smooth' = 'auto') { export function scroll (top: number, left?: number, behavior: 'auto' | 'smooth' = 'auto') {
if (divScroll) { if (divScroll) {
@ -89,22 +90,42 @@
const trackH = divScroll.clientHeight - shiftTop - shiftBottom - 4 const trackH = divScroll.clientHeight - shiftTop - shiftBottom - 4
const scrollH = divScroll.scrollHeight const scrollH = divScroll.scrollHeight
const proc = scrollH / trackH const proc = scrollH / trackH
divBar.style.height = divScroll.clientHeight / proc + 'px'
divBar.style.top = divScroll.scrollTop / proc + shiftTop + 2 + 'px' const newHeight = divScroll.clientHeight / proc + 'px'
if (mask === 'none') divBar.style.visibility = 'hidden' if (divBar.style.height !== 'newHeight') {
else { divBar.style.height = newHeight
divBar.style.visibility = 'visible' }
const newTop = divScroll.scrollTop / proc + shiftTop + 2 + 'px'
if (divBar.style.top !== newTop) {
divBar.style.top = newTop
}
if (mask === 'none') {
if (divBar.style.visibility !== 'hidden') {
divBar.style.visibility = 'hidden'
}
} else {
if (divBar.style.visibility !== 'visible') {
divBar.style.visibility = 'visible'
}
if (divBar) { if (divBar) {
if (timer) { if (timer) {
clearTimeout(timer) clearTimeout(timer)
divBar.style.opacity = '1' if (divBar.style.opacity !== '1') {
divBar.style.opacity = '1'
}
} }
timer = setTimeout(() => { timer = setTimeout(() => {
if (divBar) divBar.style.opacity = '0' if (divBar) {
divBar.style.opacity = '0'
}
}, 1500) }, 1500)
} }
} }
if (divScroll.clientHeight >= divScroll.scrollHeight) divBar.style.visibility = 'hidden' if (divScroll.clientHeight >= divScroll.scrollHeight) {
if (divBar.style.visibility !== 'hidden') {
divBar.style.visibility = 'hidden'
}
}
} }
} }
const checkBarH = (): void => { const checkBarH = (): void => {
@ -220,6 +241,13 @@
} }
} }
let checkBarTimeout: any | undefined = undefined
const delayCall = (op: () => void) => {
clearTimeout(checkBarTimeout)
checkBarTimeout = setTimeout(op, 50)
}
const checkFade = (): void => { const checkFade = (): void => {
if (divScroll) { if (divScroll) {
beforeContent = divScroll.scrollTop beforeContent = divScroll.scrollTop
@ -240,8 +268,8 @@
if (inter.size) checkIntersectionFade() if (inter.size) checkIntersectionFade()
renderFade() renderFade()
} }
if (!isScrolling) checkBar() if (!isScrolling) delayCall(checkBar)
if (!isScrolling && horizontal) checkBarH() if (!isScrolling && horizontal) delayCall(checkBarH)
} }
function checkAutoScroll () { function checkAutoScroll () {
@ -336,8 +364,8 @@
if (divScroll && divBox) { if (divScroll && divBox) {
divScroll.addEventListener('wheel', wheelEvent) divScroll.addEventListener('wheel', wheelEvent)
divScroll.addEventListener('scroll', checkFade) divScroll.addEventListener('scroll', checkFade)
checkBar() delayCall(checkBar)
if (horizontal) checkBarH() if (horizontal) delayCall(checkBarH)
} }
}) })
onDestroy(() => { onDestroy(() => {
@ -349,31 +377,46 @@
}) })
let oldTop: number let oldTop: number
beforeUpdate(() => {
if (divBox && divScroll) oldTop = divScroll.scrollTop
})
afterUpdate(() => {
if (divBox && divScroll) {
if (oldTop !== divScroll.scrollTop) divScroll.scrollTop = oldTop
const tempEls = divBox.querySelectorAll('.categoryHeader') if (checkForHeaders) {
observer = new IntersectionObserver(checkIntersection, { root: null, rootMargin: '0px', threshold: 0.1 }) beforeUpdate(() => {
tempEls.forEach((el) => observer.observe(el)) if (divBox && divScroll) {
const tempCats = divBox.querySelectorAll('.lastCat') oldTop = divScroll.scrollTop
if (tempCats.length > 0) { }
hasLastCategories = true })
tempCats.forEach((el) => observer.observe(el))
} else hasLastCategories = false afterUpdate(() => {
} if (divBox && divScroll) {
}) if (oldTop !== divScroll.scrollTop) {
divScroll.scrollTop = oldTop
}
delayCall(() => {
const tempEls = divBox.querySelectorAll('.categoryHeader')
observer = new IntersectionObserver(checkIntersection, { root: null, rootMargin: '0px', threshold: 0.1 })
tempEls.forEach((el) => observer.observe(el))
const tempCats = divBox.querySelectorAll('.lastCat')
if (tempCats.length > 0) {
hasLastCategories = true
tempCats.forEach((el) => observer.observe(el))
} else {
hasLastCategories = false
}
})
}
})
}
let divHeight: number let divHeight: number
const _resize = (): void => checkFade() const _resize = (): void => checkFade()
const tapScroll = (n: number, dir: 'up' | 'down') => { const tapScroll = (n: number, dir: 'up' | 'down') => {
if (divScroll) { if (divScroll) {
if (orientir === 'horizontal') divScroll.scrollBy({ top: 0, left: dir === 'up' ? -n : n, behavior: 'smooth' }) if (orientir === 'horizontal') {
else divScroll.scrollBy({ top: dir === 'up' ? -n : n, left: 0, behavior: 'smooth' }) divScroll.scrollBy({ top: 0, left: dir === 'up' ? -n : n, behavior: 'smooth' })
} else {
divScroll.scrollBy({ top: dir === 'up' ? -n : n, left: 0, behavior: 'smooth' })
}
} }
} }
</script> </script>

View File

@ -48,7 +48,12 @@
/> />
<div class="w-full h-full py-4 clear-mins"> <div class="w-full h-full py-4 clear-mins">
<Scroller fade={{ multipler: { top: 2.75 * viewOptions.groupBy.length, bottom: 0 } }} padding={'0 1rem'} noFade> <Scroller
fade={{ multipler: { top: 2.75 * viewOptions.groupBy.length, bottom: 0 } }}
padding={'0 1rem'}
noFade
checkForHeaders
>
<List <List
bind:this={list} bind:this={list}
{_class} {_class}