This commit is contained in:
syuilo 2025-05-10 18:28:26 +09:00
parent 90ac029317
commit ade38bfe2f
2 changed files with 35 additions and 15 deletions

View File

@ -85,7 +85,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@dragend="isDragSource = false" @dragend="isDragSource = false"
/> />
</div> </div>
<MkButton v-if="foldersPaginator.canFetchOlder" primary rounded @click="foldersPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton> <MkButton v-if="foldersPaginator.canFetchOlder.value" primary rounded @click="foldersPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton>
</div> </div>
<div v-show="filesPaginator.items.value.length > 0"> <div v-show="filesPaginator.items.value.length > 0">
@ -110,7 +110,7 @@ SPDX-License-Identifier: AGPL-3.0-only
/> />
</div> </div>
</MkStickyContainer> </MkStickyContainer>
<MkButton v-show="filesPaginator.canFetchOlder" primary rounded @click="filesPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton> <MkButton v-show="filesPaginator.canFetchOlder.value" primary rounded @click="filesPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton>
</div> </div>
<div v-if="filesPaginator.items.value.length == 0 && foldersPaginator.items.value.length == 0 && !fetching" :class="$style.empty"> <div v-if="filesPaginator.items.value.length == 0 && foldersPaginator.items.value.length == 0 && !fetching" :class="$style.empty">
@ -203,6 +203,7 @@ const filesPaginator = usePagination({
ctx: { ctx: {
endpoint: 'drive/files', endpoint: 'drive/files',
limit: 30, limit: 30,
canFetchDetection: 'limit',
params: computed(() => ({ params: computed(() => ({
folderId: folder.value ? folder.value.id : null, folderId: folder.value ? folder.value.id : null,
type: props.type, type: props.type,
@ -217,6 +218,7 @@ const foldersPaginator = usePagination({
ctx: { ctx: {
endpoint: 'drive/folders', endpoint: 'drive/folders',
limit: 30, limit: 30,
canFetchDetection: 'limit',
params: computed(() => ({ params: computed(() => ({
folderId: folder.value ? folder.value.id : null, folderId: folder.value ? folder.value.id : null,
})), })),

View File

@ -35,6 +35,9 @@ export type PagingCtx<E extends keyof Misskey.Endpoints = keyof Misskey.Endpoint
baseId?: MisskeyEntity['id']; baseId?: MisskeyEntity['id'];
direction?: 'newer' | 'older'; direction?: 'newer' | 'older';
// 一部のAPIはさらに遡れる場合でもパフォーマンス上の理由でlimit以下の結果を返す場合があり、その場合はsafe、それ以外はlimitにすることを推奨
canFetchDetection?: 'safe' | 'limit';
}; };
export function usePagination<Endpoint extends keyof Misskey.Endpoints, T = Misskey.Endpoints[Endpoint]['res'] extends (infer I)[] ? I : never>(props: { export function usePagination<Endpoint extends keyof Misskey.Endpoints, T = Misskey.Endpoints[Endpoint]['res'] extends (infer I)[] ? I : never>(props: {
@ -95,13 +98,21 @@ export function usePagination<Endpoint extends keyof Misskey.Endpoints, T = Miss
if (i === 3) item._shouldInsertAd_ = true; if (i === 3) item._shouldInsertAd_ = true;
} }
if (res.length === 0 || props.ctx.noPaging) {
pushItems(res); pushItems(res);
if (props.ctx.canFetchDetection === 'limit') {
if (res.length < FIRST_FETCH_LIMIT) {
canFetchOlder.value = false; canFetchOlder.value = false;
} else { } else {
pushItems(res);
canFetchOlder.value = true; canFetchOlder.value = true;
} }
} else if (props.ctx.canFetchDetection === 'safe' || props.ctx.canFetchDetection == null) {
if (res.length === 0 || props.ctx.noPaging) {
canFetchOlder.value = false;
} else {
canFetchOlder.value = true;
}
}
error.value = false; error.value = false;
fetching.value = false; fetching.value = false;
@ -133,13 +144,20 @@ export function usePagination<Endpoint extends keyof Misskey.Endpoints, T = Miss
if (i === 10) item._shouldInsertAd_ = true; if (i === 10) item._shouldInsertAd_ = true;
} }
pushItems(res);
if (props.ctx.canFetchDetection === 'limit') {
if (res.length < FIRST_FETCH_LIMIT) {
canFetchOlder.value = false;
} else {
canFetchOlder.value = true;
}
} else if (props.ctx.canFetchDetection === 'safe' || props.ctx.canFetchDetection == null) {
if (res.length === 0) { if (res.length === 0) {
canFetchOlder.value = false; canFetchOlder.value = false;
fetchingOlder.value = false;
} else { } else {
pushItems(res);
canFetchOlder.value = true; canFetchOlder.value = true;
fetchingOlder.value = false; }
} }
}, err => { }, err => {
fetchingOlder.value = false; fetchingOlder.value = false;