From c13f5a9b04aaa1ba0c2138946785b667317b45c8 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 30 Aug 2025 16:58:23 +0300 Subject: [PATCH] refactor(react/collections/list): split pagination into separate file --- .../src/widgets/collections/Pagination.tsx | 83 ++++++++++++++++++ .../widgets/collections/legacy/ListView.tsx | 85 +------------------ 2 files changed, 86 insertions(+), 82 deletions(-) create mode 100644 apps/client/src/widgets/collections/Pagination.tsx diff --git a/apps/client/src/widgets/collections/Pagination.tsx b/apps/client/src/widgets/collections/Pagination.tsx new file mode 100644 index 000000000..b37824e00 --- /dev/null +++ b/apps/client/src/widgets/collections/Pagination.tsx @@ -0,0 +1,83 @@ +import { ComponentChildren } from "preact"; +import { Dispatch, StateUpdater, useEffect, useState } from "preact/hooks"; +import FNote from "../../entities/fnote"; +import froca from "../../services/froca"; +import { useNoteLabel } from "../react/hooks"; + +interface PaginationContext { + page: number; + setPage: Dispatch>; + pageNotes?: FNote[]; + pageCount: number; + pageSize: number; + totalNotes: number; +} + +export function Pager({ page, pageSize, setPage, pageCount, totalNotes }: Omit) { + if (pageCount < 1) return; + + let lastPrinted = false; + let children: ComponentChildren[] = []; + for (let i = 1; i <= pageCount; i++) { + if (pageCount < 20 || i <= 5 || pageCount - i <= 5 || Math.abs(page - i) <= 2) { + lastPrinted = true; + + const startIndex = (i - 1) * pageSize + 1; + const endIndex = Math.min(totalNotes, i * pageSize); + + if (i !== page) { + children.push(( + setPage(i)} + > + {i} + + )) + } else { + // Current page + children.push({i}) + } + + children.push(<>{" "} {" "}); + } else if (lastPrinted) { + children.push(<>{"... "} {" "}); + lastPrinted = false; + } + } + + return ( +
+ {children} +
+ ) +} + +export function usePagination(note: FNote, noteIds: string[]): PaginationContext { + const [ page, setPage ] = useState(1); + const [ pageNotes, setPageNotes ] = useState(); + + // Parse page size. + const [ pageSize ] = useNoteLabel(note, "pageSize"); + const pageSizeNum = parseInt(pageSize ?? "", 10); + const normalizedPageSize = (pageSizeNum && pageSizeNum > 0 ? pageSizeNum : 20); + + // Calculate start/end index. + const startIdx = (page - 1) * normalizedPageSize; + const endIdx = startIdx + normalizedPageSize; + const pageCount = Math.ceil(noteIds.length / normalizedPageSize); + + // Obtain notes within the range. + const pageNoteIds = noteIds.slice(startIdx, Math.min(endIdx, noteIds.length)); + + useEffect(() => { + froca.getNotes(pageNoteIds).then(setPageNotes); + }, [ note, noteIds, page, pageSize ]); + + return { + page, setPage, pageNotes, pageCount, + pageSize: normalizedPageSize, + totalNotes: noteIds.length + }; +} \ No newline at end of file diff --git a/apps/client/src/widgets/collections/legacy/ListView.tsx b/apps/client/src/widgets/collections/legacy/ListView.tsx index 7c061921b..c9fc455b1 100644 --- a/apps/client/src/widgets/collections/legacy/ListView.tsx +++ b/apps/client/src/widgets/collections/legacy/ListView.tsx @@ -1,13 +1,12 @@ -import { Dispatch, StateUpdater, useEffect, useMemo, useRef, useState } from "preact/hooks"; +import { useEffect, useMemo, useRef, useState } from "preact/hooks"; import FNote from "../../../entities/fnote"; import Icon from "../../react/Icon"; import { ViewModeProps } from "../interface"; -import { useNoteLabel, useNoteLabelBoolean, useNoteProperty } from "../../react/hooks"; -import froca from "../../../services/froca"; +import { useNoteLabelBoolean, useNoteProperty } from "../../react/hooks"; import NoteLink from "../../react/NoteLink"; import "./ListOrGridView.css"; import content_renderer from "../../../services/content_renderer"; -import { ComponentChildren, VNode } from "preact"; +import { Pager, usePagination } from "../Pagination"; export default function ListView({ note, noteIds }: ViewModeProps) { const [ isExpanded ] = useNoteLabelBoolean(note, "expanded"); @@ -97,81 +96,3 @@ function NoteChildren({ note }: { note: FNote}) { return childNotes?.map(childNote => ) } - -function Pager({ page, pageSize, setPage, pageCount, totalNotes }: Omit) { - if (pageCount < 1) return; - - let lastPrinted = false; - let children: ComponentChildren[] = []; - for (let i = 1; i <= pageCount; i++) { - if (pageCount < 20 || i <= 5 || pageCount - i <= 5 || Math.abs(page - i) <= 2) { - lastPrinted = true; - - const startIndex = (i - 1) * pageSize + 1; - const endIndex = Math.min(totalNotes, i * pageSize); - - if (i !== page) { - children.push(( - setPage(i)} - > - {i} - - )) - } else { - // Current page - children.push({i}) - } - - children.push(<>{" "} {" "}); - } else if (lastPrinted) { - children.push(<>{"... "} {" "}); - lastPrinted = false; - } - } - - return ( -
- {children} -
- ) -} - -interface PaginationContext { - page: number; - setPage: Dispatch>; - pageNotes?: FNote[]; - pageCount: number; - pageSize: number; - totalNotes: number; -} - -function usePagination(note: FNote, noteIds: string[]): PaginationContext { - const [ page, setPage ] = useState(1); - const [ pageNotes, setPageNotes ] = useState(); - - // Parse page size. - const [ pageSize ] = useNoteLabel(note, "pageSize"); - const pageSizeNum = parseInt(pageSize ?? "", 10); - const normalizedPageSize = (pageSizeNum && pageSizeNum > 0 ? pageSizeNum : 20); - - // Calculate start/end index. - const startIdx = (page - 1) * normalizedPageSize; - const endIdx = startIdx + normalizedPageSize; - const pageCount = Math.ceil(noteIds.length / normalizedPageSize); - - // Obtain notes within the range. - const pageNoteIds = noteIds.slice(startIdx, Math.min(endIdx, noteIds.length)); - - useEffect(() => { - froca.getNotes(pageNoteIds).then(setPageNotes); - }, [ note, noteIds, page, pageSize ]); - - return { - page, setPage, pageNotes, pageCount, - pageSize: normalizedPageSize, - totalNotes: noteIds.length - }; -} \ No newline at end of file