diff --git a/src/components/settings/tabs/plugins/index.tsx b/src/components/settings/tabs/plugins/index.tsx index 9ab3cdcbd..ab9e9e9ce 100644 --- a/src/components/settings/tabs/plugins/index.tsx +++ b/src/components/settings/tabs/plugins/index.tsx @@ -25,14 +25,13 @@ import { classNameFactory } from "@api/Styles"; import { CogWheel, InfoIcon } from "@components/Icons"; import { openPluginModal, SettingsTab } from "@components/settings"; import { AddonCard } from "@components/settings/AddonCard"; -import { debounce } from "@shared/debounce"; import { ChangeList } from "@utils/ChangeList"; import { proxyLazy } from "@utils/lazy"; import { Logger } from "@utils/Logger"; import { Margins } from "@utils/margins"; import { classes, isObjectEmpty } from "@utils/misc"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from "@utils/modal"; -import { useAwaiter, useIntersection } from "@utils/react"; +import { useAwaiter } from "@utils/react"; import { Plugin } from "@utils/types"; import { findByPropsLazy } from "@webpack"; import { Alerts, Button, Card, Flex, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common"; @@ -262,13 +261,17 @@ export default function PluginSettings() { .sort((a, b) => a.name.localeCompare(b.name)), []); const [searchValue, setSearchValue] = React.useState({ value: "", status: SearchStatus.ALL }); + const [currentPage, setCurrentPage] = React.useState(1); + const pageSize = 36; const search = searchValue.value.toLowerCase(); const onSearch = (query: string) => { setSearchValue(prev => ({ ...prev, value: query })); + setCurrentPage(1); }; const onStatusChange = (status: SearchStatus) => { setSearchValue(prev => ({ ...prev, status })); + setCurrentPage(1); }; const pluginFilter = (plugin: typeof Plugins[keyof typeof Plugins]) => { @@ -473,22 +476,13 @@ export default function PluginSettings() { const totalUserPlugins = totalPlugins.filter(p => PluginMeta[p].userPlugin).length; const enabledStockPlugins = enabledPlugins.filter(p => !PluginMeta[p].userPlugin).length; const enabledUserPlugins = enabledPlugins.filter(p => PluginMeta[p].userPlugin).length; - const pluginsToLoad = Math.min(36, plugins.length); - const [visibleCount, setVisibleCount] = React.useState(pluginsToLoad); - const loadMore = React.useCallback(() => { - setVisibleCount(v => Math.min(v + pluginsToLoad, plugins.length)); - }, [plugins.length]); - const dLoadMore = useMemo(() => debounce(loadMore, 100), [loadMore]); + const paginatedPlugins = plugins.slice((currentPage - 1) * pageSize, currentPage * pageSize); + const totalPages = Math.ceil(plugins.length / pageSize); - const [sentinelRef, isSentinelVisible] = useIntersection(); - React.useEffect(() => { - if (isSentinelVisible && visibleCount < plugins.length) { - dLoadMore(); - } - }, [isSentinelVisible, visibleCount, plugins.length, dLoadMore]); - - const visiblePlugins = plugins.slice(0, visibleCount); + function goToPage(page: number) { + setCurrentPage(Math.max(1, Math.min(page, totalPages))); + } return ( @@ -541,13 +535,32 @@ export default function PluginSettings() { ? ( <>
- {visiblePlugins.length - ? visiblePlugins + {paginatedPlugins.length + ? paginatedPlugins : No plugins meet the search criteria. }
- {visibleCount < plugins.length && ( -
+ + {totalPages > 1 && ( +
+ +
+ {`Page ${currentPage} of ${totalPages}`} +
+ +
)} ) diff --git a/src/components/settings/tabs/plugins/styles.css b/src/components/settings/tabs/plugins/styles.css index 8266b39c8..7c8302f20 100644 --- a/src/components/settings/tabs/plugins/styles.css +++ b/src/components/settings/tabs/plugins/styles.css @@ -281,9 +281,19 @@ } .vc-plugins-page-buttons { - margin-top: 12px; + margin-top: 20px; display: flex; align-items: center; justify-content: center; gap: 8px; + position: relative; +} + +.vc-plugins-page-text { + width: 120px; + font-size: 14px; + font-weight: 500; + display: flex; + align-items: center; + justify-content: center; } \ No newline at end of file