From f1deb89e348eb8f1a39b51e33a0ae33d59529feb Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Sun, 29 Jun 2025 15:11:25 +0900
Subject: refactor(frontend): improve pagination implementation

---
 packages/frontend/src/pages/explore.users.vue | 110 +++++++++++++++++---------
 1 file changed, 71 insertions(+), 39 deletions(-)

(limited to 'packages/frontend/src/pages/explore.users.vue')

diff --git a/packages/frontend/src/pages/explore.users.vue b/packages/frontend/src/pages/explore.users.vue
index e723f6a1e9..72f2a6813c 100644
--- a/packages/frontend/src/pages/explore.users.vue
+++ b/packages/frontend/src/pages/explore.users.vue
@@ -13,19 +13,19 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<template v-if="tag == null">
 			<MkFoldableSection class="_margin" persistKey="explore-pinned-users">
 				<template #header><i class="ti ti-bookmark ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedUsers }}</template>
-				<MkUserList :pagination="pinnedUsers"/>
+				<MkUserList :paginator="pinnedUsersPaginator"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin" persistKey="explore-popular-users">
 				<template #header><i class="ti ti-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
-				<MkUserList :pagination="popularUsers"/>
+				<MkUserList :paginator="popularUsersPaginator"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin" persistKey="explore-recently-updated-users">
 				<template #header><i class="ti ti-message ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
-				<MkUserList :pagination="recentlyUpdatedUsers"/>
+				<MkUserList :paginator="recentlyUpdatedUsersPaginator"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin" persistKey="explore-recently-registered-users">
 				<template #header><i class="ti ti-plus ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyRegisteredUsers }}</template>
-				<MkUserList :pagination="recentlyRegisteredUsers"/>
+				<MkUserList :paginator="recentlyRegisteredUsersPaginator"/>
 			</MkFoldableSection>
 		</template>
 	</div>
@@ -41,21 +41,21 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 		<MkFoldableSection v-if="tag != null" :key="`${tag}`" class="_margin">
 			<template #header><i class="ti ti-hash ti-fw" style="margin-right: 0.5em;"></i>{{ tag }}</template>
-			<MkUserList :pagination="tagUsers"/>
+			<MkUserList :paginator="tagUsersPaginator"/>
 		</MkFoldableSection>
 
 		<template v-if="tag == null">
 			<MkFoldableSection class="_margin">
 				<template #header><i class="ti ti-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
-				<MkUserList :pagination="popularUsersF"/>
+				<MkUserList :paginator="popularUsersFPaginator"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin">
 				<template #header><i class="ti ti-message ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
-				<MkUserList :pagination="recentlyUpdatedUsersF"/>
+				<MkUserList :paginator="recentlyUpdatedUsersFPaginator"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin">
 				<template #header><i class="ti ti-rocket ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyDiscoveredUsers }}</template>
-				<MkUserList :pagination="recentlyRegisteredUsersF"/>
+				<MkUserList :paginator="recentlyRegisteredUsersFPaginator"/>
 			</MkFoldableSection>
 		</template>
 	</div>
@@ -63,7 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 </template>
 
 <script lang="ts" setup>
-import { watch, ref, useTemplateRef, computed } from 'vue';
+import { watch, ref, useTemplateRef, computed, markRaw } from 'vue';
 import * as Misskey from 'misskey-js';
 import MkUserList from '@/components/MkUserList.vue';
 import MkFoldableSection from '@/components/MkFoldableSection.vue';
@@ -71,6 +71,7 @@ import MkTab from '@/components/MkTab.vue';
 import { misskeyApi } from '@/utility/misskey-api.js';
 import { instance } from '@/instance.js';
 import { i18n } from '@/i18n.js';
+import { Paginator } from '@/utility/paginator.js';
 
 const props = defineProps<{
 	tag?: string;
@@ -85,8 +86,7 @@ watch(() => props.tag, () => {
 	if (tagsEl.value) tagsEl.value.toggleContent(props.tag == null);
 });
 
-const tagUsers = computed(() => ({
-	endpoint: 'hashtags/users' as const,
+const tagUsersPaginator = markRaw(new Paginator('hashtags/users', {
 	limit: 30,
 	params: {
 		tag: props.tag,
@@ -95,34 +95,66 @@ const tagUsers = computed(() => ({
 	},
 }));
 
-const pinnedUsers = { endpoint: 'pinned-users', noPaging: true };
-const popularUsers = { endpoint: 'users', limit: 10, noPaging: true, params: {
-	state: 'alive',
-	origin: 'local',
-	sort: '+follower',
-} };
-const recentlyUpdatedUsers = { endpoint: 'users', limit: 10, noPaging: true, params: {
-	origin: 'local',
-	sort: '+updatedAt',
-} };
-const recentlyRegisteredUsers = { endpoint: 'users', limit: 10, noPaging: true, params: {
-	origin: 'local',
-	state: 'alive',
-	sort: '+createdAt',
-} };
-const popularUsersF = { endpoint: 'users', limit: 10, noPaging: true, params: {
-	state: 'alive',
-	origin: 'remote',
-	sort: '+follower',
-} };
-const recentlyUpdatedUsersF = { endpoint: 'users', limit: 10, noPaging: true, params: {
-	origin: 'combined',
-	sort: '+updatedAt',
-} };
-const recentlyRegisteredUsersF = { endpoint: 'users', limit: 10, noPaging: true, params: {
-	origin: 'combined',
-	sort: '+createdAt',
-} };
+const pinnedUsersPaginator = markRaw(new Paginator('pinned-users', {
+	noPaging: true,
+}));
+
+const popularUsersPaginator = markRaw(new Paginator('users', {
+	limit: 10,
+	noPaging: true,
+	params: {
+		state: 'alive',
+		origin: 'local',
+		sort: '+follower',
+	},
+}));
+
+const recentlyUpdatedUsersPaginator = markRaw(new Paginator('users', {
+	limit: 10,
+	noPaging: true,
+	params: {
+		origin: 'local',
+		sort: '+updatedAt',
+	},
+}));
+
+const recentlyRegisteredUsersPaginator = markRaw(new Paginator('users', {
+	limit: 10,
+	noPaging: true,
+	params: {
+		origin: 'local',
+		state: 'alive',
+		sort: '+createdAt',
+	},
+}));
+
+const popularUsersFPaginator = markRaw(new Paginator('users', {
+	limit: 10,
+	noPaging: true,
+	params: {
+		state: 'alive',
+		origin: 'remote',
+		sort: '+follower',
+	},
+}));
+
+const recentlyUpdatedUsersFPaginator = markRaw(new Paginator('users', {
+	limit: 10,
+	noPaging: true,
+	params: {
+		origin: 'combined',
+		sort: '+updatedAt',
+	},
+}));
+
+const recentlyRegisteredUsersFPaginator = markRaw(new Paginator('users', {
+	limit: 10,
+	noPaging: true,
+	params: {
+		origin: 'combined',
+		sort: '+createdAt',
+	},
+}));
 
 misskeyApi('hashtags/list', {
 	sort: '+attachedLocalUsers',
-- 
cgit v1.2.3-freya

