fix(frontend): 連合一覧等のページネーションが壊れていたのを修正 (#14439)

* fix

* fix

* fix CHANGELOG.md

* 開発環境以外でログが出ないように

---------

Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com>
This commit is contained in:
おさむのひと 2024-09-24 10:09:55 +09:00 committed by GitHub
parent 23a07c2706
commit 98de7ca526
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 13 deletions

View file

@ -21,6 +21,7 @@
- Fix: 設定変更時のリロード確認ダイアログが複数個表示されることがある問題を修正 - Fix: 設定変更時のリロード確認ダイアログが複数個表示されることがある問題を修正
- Fix: ファイルの詳細ページのファイルの説明で改行が正しく表示されない問題を修正 - Fix: ファイルの詳細ページのファイルの説明で改行が正しく表示されない問題を修正
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/commit/bde6bb0bd2e8b0d027e724d2acdb8ae0585a8110) (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/commit/bde6bb0bd2e8b0d027e724d2acdb8ae0585a8110)
- Fix: 一部画面のページネーションが動作しにくくなっていたのを修正 ( #12766 , #11449 )
### Server ### Server
- Feat: Misskey® Reactions Buffering Technology™ (RBT)により、リアクションの作成負荷を低減することが可能に - Feat: Misskey® Reactions Buffering Technology™ (RBT)により、リアクションの作成負荷を低減することが可能に

View file

@ -36,19 +36,27 @@ export function getScrollPosition(el: HTMLElement | null): number {
return container == null ? window.scrollY : container.scrollTop; return container == null ? window.scrollY : container.scrollTop;
} }
export function onScrollTop(el: HTMLElement, cb: () => unknown, tolerance = 1, once = false) { export function onScrollTop(el: HTMLElement, cb: (topVisible: boolean) => unknown, tolerance = 1, once = false) {
// とりあえず評価してみる // とりあえず評価してみる
if (el.isConnected && isTopVisible(el)) { const firstTopVisible = isTopVisible(el);
cb(); if (el.isConnected && firstTopVisible) {
cb(firstTopVisible);
if (once) return null; if (once) return null;
} }
const container = getScrollContainer(el) ?? window; const container = getScrollContainer(el) ?? window;
// 以下のケースにおいて、cbが何度も呼び出されてしまって具合が悪いので1回呼んだら以降は無視するようにする
// - スクロールイベントは1回のスクロールで複数回発生することがある
// - toleranceの範囲内に収まる程度の微量なスクロールが発生した
let prevTopVisible = firstTopVisible;
const onScroll = () => { const onScroll = () => {
if (!document.body.contains(el)) return; if (!document.body.contains(el)) return;
if (isTopVisible(el, tolerance)) {
cb(); const topVisible = isTopVisible(el, tolerance);
if (topVisible !== prevTopVisible) {
prevTopVisible = topVisible;
cb(topVisible);
if (once) removeListener(); if (once) removeListener();
} }
}; };
@ -126,6 +134,7 @@ export function scrollToBottom(
export function isTopVisible(el: HTMLElement, tolerance = 1): boolean { export function isTopVisible(el: HTMLElement, tolerance = 1): boolean {
const scrollTop = getScrollPosition(el); const scrollTop = getScrollPosition(el);
if (_DEV_) console.log(scrollTop, tolerance, scrollTop <= tolerance);
return scrollTop <= tolerance; return scrollTop <= tolerance;
} }

View file

@ -125,8 +125,6 @@ const items = ref<MisskeyEntityMap>(new Map());
*/ */
const queue = ref<MisskeyEntityMap>(new Map()); const queue = ref<MisskeyEntityMap>(new Map());
const offset = ref(0);
/** /**
* 初期化中かどうかtrueならMkLoadingで全て隠す * 初期化中かどうかtrueならMkLoadingで全て隠す
*/ */
@ -179,7 +177,9 @@ watch([backed, contentEl], () => {
if (!backed.value) { if (!backed.value) {
if (!contentEl.value) return; if (!contentEl.value) return;
scrollRemove.value = (props.pagination.reversed ? onScrollBottom : onScrollTop)(contentEl.value, executeQueue, TOLERANCE); scrollRemove.value = props.pagination.reversed
? onScrollBottom(contentEl.value, executeQueue, TOLERANCE)
: onScrollTop(contentEl.value, (topVisible) => { if (topVisible) executeQueue(); }, TOLERANCE);
} else { } else {
if (scrollRemove.value) scrollRemove.value(); if (scrollRemove.value) scrollRemove.value();
scrollRemove.value = null; scrollRemove.value = null;
@ -223,7 +223,6 @@ async function init(): Promise<void> {
more.value = true; more.value = true;
} }
offset.value = res.length;
error.value = false; error.value = false;
fetching.value = false; fetching.value = false;
}, err => { }, err => {
@ -244,7 +243,7 @@ const fetchMore = async (): Promise<void> => {
...params, ...params,
limit: SECOND_FETCH_LIMIT, limit: SECOND_FETCH_LIMIT,
...(props.pagination.offsetMode ? { ...(props.pagination.offsetMode ? {
offset: offset.value, offset: items.value.size,
} : { } : {
untilId: Array.from(items.value.keys()).at(-1), untilId: Array.from(items.value.keys()).at(-1),
}), }),
@ -294,7 +293,6 @@ const fetchMore = async (): Promise<void> => {
moreFetching.value = false; moreFetching.value = false;
} }
} }
offset.value += res.length;
}, err => { }, err => {
moreFetching.value = false; moreFetching.value = false;
}); });
@ -308,7 +306,7 @@ const fetchMoreAhead = async (): Promise<void> => {
...params, ...params,
limit: SECOND_FETCH_LIMIT, limit: SECOND_FETCH_LIMIT,
...(props.pagination.offsetMode ? { ...(props.pagination.offsetMode ? {
offset: offset.value, offset: items.value.size,
} : { } : {
sinceId: Array.from(items.value.keys()).at(-1), sinceId: Array.from(items.value.keys()).at(-1),
}), }),
@ -320,7 +318,6 @@ const fetchMoreAhead = async (): Promise<void> => {
items.value = concatMapWithArray(items.value, res); items.value = concatMapWithArray(items.value, res);
more.value = true; more.value = true;
} }
offset.value += res.length;
moreFetching.value = false; moreFetching.value = false;
}, err => { }, err => {
moreFetching.value = false; moreFetching.value = false;