This commit is contained in:
tamaina 2023-07-13 07:20:11 +00:00
parent 2bbada3cd4
commit ba3fa8b431
1 changed files with 47 additions and 20 deletions

View File

@ -177,25 +177,27 @@ watch([() => props.pagination.reversed, $$(scrollableElement)], () => {
if (scrollObserver) scrollObserver.disconnect(); if (scrollObserver) scrollObserver.disconnect();
scrollObserver = new IntersectionObserver(entries => { scrollObserver = new IntersectionObserver(entries => {
console.log('scrollObserver', entries[0].isIntersecting);
weakBacked = entries[0].isIntersecting; weakBacked = entries[0].isIntersecting;
}, { }, {
root: scrollableElement, root: scrollableElement,
rootMargin: props.pagination.reversed ? '-100% 0px 100% 0px' : '100% 0px -100% 0px', rootMargin: props.pagination.reversed ? '-100% 0px 100% 0px' : '100% 0px -100% 0px',
threshold: 0.1, // 10%queue threshold: 0.1, // 10%queue
}); });
console.log('new scrollObserver', scrollObserver);
}, { immediate: true }); }, { immediate: true });
watch([$$(rootEl), $$(scrollObserver)], () => { watch([$$(rootEl), $$(scrollObserver)], () => {
scrollObserver?.disconnect(); scrollObserver?.disconnect();
nextTick(() => {
if (rootEl) scrollObserver?.observe(rootEl); if (rootEl) scrollObserver?.observe(rootEl);
}); console.log('scrollObserver observe', rootEl);
}); });
/** /**
* onScrollTop/onScrollBottomで細かく検出する * onScrollTop/onScrollBottomで細かく検出する
*/ */
watch($$(backed), () => { watch($$(backed), () => {
console.log('backed changed', backed);
if (!backed) { if (!backed) {
executeQueue(); executeQueue();
} }
@ -206,13 +208,16 @@ watch([$$(weakBacked), $$(contentEl)], () => {
scrollRemove = null; scrollRemove = null;
if (weakBacked || !contentEl) { if (weakBacked || !contentEl) {
console.log('weakBacked watcher remove scrollRemove', weakBacked, contentEl);
if (weakBacked) backed = true; if (weakBacked) backed = true;
return; return;
} }
console.log('weakBacked watcher add scrollRemove', weakBacked, contentEl);
scrollRemove = (() => { scrollRemove = (() => {
const checkBacked = () => { const checkBacked = () => {
backed = !checkTop(); backed = !checkTop();
console.log('checkBacked', backed);
}; };
// //
@ -235,20 +240,33 @@ function preventDefault(ev: Event) {
* @param fn DOM操作(unshiftItemsなどで) * @param fn DOM操作(unshiftItemsなどで)
*/ */
function adjustScroll(fn: () => void): Promise<void> { function adjustScroll(fn: () => void): Promise<void> {
console.log('adjustScroll');
const oldHeight = scrollableElement ? scrollableElement.scrollHeight : getBodyScrollHeight(); const oldHeight = scrollableElement ? scrollableElement.scrollHeight : getBodyScrollHeight();
const oldScroll = scrollableElement ? scrollableElement.scrollTop : window.scrollY; const oldScroll = scrollableElement ? scrollableElement.scrollTop : window.scrollY;
// //
try {
// scrollableElementOrHtmlundefined
scrollableElementOrHtml.addEventListener('mousewheel', preventDefault, { passive: false }); scrollableElementOrHtml.addEventListener('mousewheel', preventDefault, { passive: false });
scrollableElementOrHtml.addEventListener('touchmove', preventDefault, { passive: false }); scrollableElementOrHtml.addEventListener('touchmove', preventDefault, { passive: false });
// try
scroll(scrollableElement, { top: oldScroll, behavior: 'instant' }); scroll(scrollableElement, { top: oldScroll, behavior: 'instant' });
} catch (err) {
console.error(err, { scrollableElementOrHtml });
}
fn(); fn();
return nextTick(() => { return nextTick(() => {
try {
const top = oldScroll + ((scrollableElement ? scrollableElement.scrollHeight : getBodyScrollHeight()) - oldHeight); const top = oldScroll + ((scrollableElement ? scrollableElement.scrollHeight : getBodyScrollHeight()) - oldHeight);
scroll(scrollableElement, { top, behavior: 'instant' }); scroll(scrollableElement, { top, behavior: 'instant' });
// scrollableElementOrHtmlundefined
scrollableElementOrHtml.removeEventListener('mousewheel', preventDefault); scrollableElementOrHtml.removeEventListener('mousewheel', preventDefault);
scrollableElementOrHtml.removeEventListener('touchmove', preventDefault); scrollableElementOrHtml.removeEventListener('touchmove', preventDefault);
} catch (err) {
console.error(err, { scrollableElementOrHtml });
}
return nextTick(); return nextTick();
}); });
} }
@ -261,6 +279,7 @@ function adjustScroll(fn: () => void): Promise<void> {
* 注意: moreFetchingをtrueにするのでfalseにする必要がある * 注意: moreFetchingをtrueにするのでfalseにする必要がある
*/ */
async function init(): Promise<void> { async function init(): Promise<void> {
console.log('init');
items.value = new Map(); items.value = new Map();
queue.value = new Map(); queue.value = new Map();
fetching.value = true; fetching.value = true;
@ -298,6 +317,7 @@ async function init(): Promise<void> {
* reloadでinitが呼ばれた時はreload内でinitの後に呼ばれる * reloadでinitが呼ばれた時はreload内でinitの後に呼ばれる
*/ */
function scrollAfterInit() { function scrollAfterInit() {
console.log('scrollAfterInit');
if (props.pagination.reversed) { if (props.pagination.reversed) {
nextTick(() => { nextTick(() => {
setTimeout(async () => { setTimeout(async () => {
@ -474,6 +494,8 @@ watch(visibility, visibilityChange);
* @param item アイテム * @param item アイテム
*/ */
const prepend = (item: MisskeyEntity): void => { const prepend = (item: MisskeyEntity): void => {
console.log('prepend', item, 'queueSize', queueSize.value, 'backed', backed, 'isPausingUpdate', isPausingUpdate, 'active', active.value);
if (items.value.size === 0) { if (items.value.size === 0) {
items.value.set(item.id, item); items.value.set(item.id, item);
fetching.value = false; fetching.value = false;
@ -517,9 +539,11 @@ function concatItems(oldItems: MisskeyEntity[]) {
} }
async function executeQueue() { async function executeQueue() {
console.log('executeQueue');
const queueArr = Array.from(queue.value.entries()); const queueArr = Array.from(queue.value.entries());
queue.value = new Map(queueArr.slice(props.pagination.limit)); queue.value = new Map(queueArr.slice(props.pagination.limit));
isPausingUpdate = true; isPausingUpdate = true;
try {
await adjustScroll(() => { await adjustScroll(() => {
unshiftItems( unshiftItems(
queueArr.slice(0, props.pagination.limit).map(v => v[1]).reverse(), queueArr.slice(0, props.pagination.limit).map(v => v[1]).reverse(),
@ -529,7 +553,9 @@ async function executeQueue() {
weakBacked = !checkTop(); weakBacked = !checkTop();
items.value = new Map([...items.value].slice(0, displayLimit.value)); items.value = new Map([...items.value].slice(0, displayLimit.value));
await nextTick(); await nextTick();
} finally {
isPausingUpdate = false; isPausingUpdate = false;
}
} }
function prependQueue(newItem: MisskeyEntity) { function prependQueue(newItem: MisskeyEntity) {
@ -573,6 +599,7 @@ onBeforeUnmount(() => {
preventAppearFetchMoreTimer.value = null; preventAppearFetchMoreTimer.value = null;
} }
scrollObserver?.disconnect(); scrollObserver?.disconnect();
if (scrollRemove) scrollRemove();
}); });
defineExpose({ defineExpose({