mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-05 00:45:50 +02:00
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>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user