diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2025-08-22 19:34:20 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-22 19:34:20 +0900 |
| commit | ade603ff7a6e2985a236949ed3d737ddab095aa1 (patch) | |
| tree | 1e114908e404489a10ee6b972b87ef81b24c2b5c /packages/frontend/src/utility | |
| parent | fix(frontend): follow-up of #16380 (diff) | |
| download | misskey-ade603ff7a6e2985a236949ed3d737ddab095aa1.tar.gz misskey-ade603ff7a6e2985a236949ed3d737ddab095aa1.tar.bz2 misskey-ade603ff7a6e2985a236949ed3d737ddab095aa1.zip | |
fix(frontend): ページネーションの進行方向を指定できるように (#16433)
* fix(frontend): ページネーションの進行方向を指定できるように
* Update Changelog
* fix lint
* fix: directionをMkPaginationに移動
* fix
* fix
* fix
---------
Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Diffstat (limited to 'packages/frontend/src/utility')
| -rw-r--r-- | packages/frontend/src/utility/paginator.ts | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/packages/frontend/src/utility/paginator.ts b/packages/frontend/src/utility/paginator.ts index 63525b311a..7db55db7d6 100644 --- a/packages/frontend/src/utility/paginator.ts +++ b/packages/frontend/src/utility/paginator.ts @@ -37,6 +37,7 @@ export interface IPaginator<T = unknown, _T = T & MisskeyEntity> { fetchingOlder: Ref<boolean>; fetchingNewer: Ref<boolean>; canFetchOlder: Ref<boolean>; + canFetchNewer: Ref<boolean>; canSearch: boolean; error: Ref<boolean>; computedParams: ComputedRef<Misskey.Endpoints[PaginatorCompatibleEndpointPaths]['req'] | null | undefined> | null; @@ -77,6 +78,7 @@ export class Paginator< public fetchingOlder = ref(false); public fetchingNewer = ref(false); public canFetchOlder = ref(false); + public canFetchNewer = ref(false); public canSearch = false; public error = ref(false); private endpoint: Endpoint; @@ -85,7 +87,12 @@ export class Paginator< public computedParams: ComputedRef<E['req'] | null | undefined> | null; public initialId: MisskeyEntity['id'] | null = null; public initialDate: number | null = null; + + // 初回読み込み時、initialIdを基準にそれより新しいものを取得するか古いものを取得するか + // newer: initialIdより新しいものを取得する + // older: initialIdより古いものを取得する (default) public initialDirection: 'newer' | 'older'; + private offsetMode: boolean; public noPaging: boolean; public searchQuery = ref<null | string>(''); @@ -116,6 +123,7 @@ export class Paginator< initialId?: MisskeyEntity['id']; initialDate?: number | null; initialDirection?: 'newer' | 'older'; + order?: 'newest' | 'oldest'; // 一部のAPIはさらに遡れる場合でもパフォーマンス上の理由でlimit以下の結果を返す場合があり、その場合はsafe、それ以外はlimitにすることを推奨 @@ -222,15 +230,15 @@ export class Paginator< if (this.canFetchDetection === 'limit') { if (apiRes.length < FIRST_FETCH_LIMIT) { - this.canFetchOlder.value = false; + (this.initialDirection === 'older' ? this.canFetchOlder : this.canFetchNewer).value = false; } else { - this.canFetchOlder.value = true; + (this.initialDirection === 'older' ? this.canFetchOlder : this.canFetchNewer).value = true; } } else if (this.canFetchDetection === 'safe' || this.canFetchDetection == null) { if (apiRes.length === 0 || this.noPaging) { - this.canFetchOlder.value = false; + (this.initialDirection === 'older' ? this.canFetchOlder : this.canFetchNewer).value = false; } else { - this.canFetchOlder.value = true; + (this.initialDirection === 'older' ? this.canFetchOlder : this.canFetchNewer).value = true; } } @@ -273,7 +281,11 @@ export class Paginator< if (i === 10) item._shouldInsertAd_ = true; } - this.pushItems(apiRes); + if (this.order.value === 'oldest') { + this.unshiftItems(apiRes.toReversed(), false); + } else { + this.pushItems(apiRes); + } if (this.canFetchDetection === 'limit') { if (apiRes.length < FIRST_FETCH_LIMIT) { @@ -313,7 +325,11 @@ export class Paginator< this.fetchingNewer.value = false; - if (apiRes == null || apiRes.length === 0) return; // これやらないと余計なre-renderが走る + if (apiRes == null || apiRes.length === 0) { + this.canFetchNewer.value = false; + // 余計なre-renderを防止するためここで終了 + return; + } if (options.toQueue) { this.aheadQueue.unshift(...apiRes.toReversed()); @@ -325,9 +341,19 @@ export class Paginator< if (this.order.value === 'oldest') { this.pushItems(apiRes); } else { - this.unshiftItems(apiRes.toReversed()); + this.unshiftItems(apiRes.toReversed(), false); } } + + if (this.canFetchDetection === 'limit') { + if (apiRes.length < FIRST_FETCH_LIMIT) { + this.canFetchNewer.value = false; + } else { + this.canFetchNewer.value = true; + } + } + // canFetchDetectionが'safe'の場合・apiRes.length === 0 の場合は apiRes.length === 0 の場合に canFetchNewer.value = false になるが、 + // 余計な re-render を防ぐために上部で処理している。そのため、ここでは何もしない } public trim(trigger = true): void { @@ -336,10 +362,10 @@ export class Paginator< if (this.useShallowRef && trigger) triggerRef(this.items); } - public unshiftItems(newItems: T[]): void { + public unshiftItems(newItems: T[], trim = true): void { if (newItems.length === 0) return; // これやらないと余計なre-renderが走る this.items.value.unshift(...newItems.filter(x => !this.items.value.some(y => y.id === x.id))); // ストリーミングやポーリングのタイミングによっては重複することがあるため - this.trim(false); + if (trim) this.trim(true); if (this.useShallowRef) triggerRef(this.items); } |