From 90da9d4aff753aebb0ffe7dd0ca4c809ed9c9f70 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Sat, 27 Dec 2025 10:24:11 +0700 Subject: [PATCH] fix: pagination --- .../src/components/media/media.component.tsx | 103 +++++++++++++----- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/apps/frontend/src/components/media/media.component.tsx b/apps/frontend/src/components/media/media.component.tsx index 8c810dbc..52a2cfa5 100644 --- a/apps/frontend/src/components/media/media.component.tsx +++ b/apps/frontend/src/components/media/media.component.tsx @@ -20,9 +20,7 @@ import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.v import EventEmitter from 'events'; import clsx from 'clsx'; import { VideoFrame } from '@gitroom/react/helpers/video.frame'; -import { - useUppyUploader, -} from '@gitroom/frontend/components/media/new.uploader'; +import { useUppyUploader } from '@gitroom/frontend/components/media/new.uploader'; import dynamic from 'next/dynamic'; import { useUser } from '@gitroom/frontend/components/layout/user.context'; import { AiImage } from '@gitroom/frontend/components/launches/ai.image'; @@ -31,9 +29,7 @@ import { deleteDialog } from '@gitroom/react/helpers/delete.dialog'; import { useT } from '@gitroom/react/translation/get.transation.service.client'; import { ThirdPartyMedia } from '@gitroom/frontend/components/third-parties/third-party.media'; import { ReactSortable } from 'react-sortablejs'; -import { - MediaComponentInner, -} from '@gitroom/frontend/components/launches/helpers/media.settings.component'; +import { MediaComponentInner } from '@gitroom/frontend/components/launches/helpers/media.settings.component'; import { AiVideo } from '@gitroom/frontend/components/launches/ai.video'; import { useModals } from '@gitroom/frontend/components/layout/new-modal'; import { Dashboard } from '@uppy/react'; @@ -62,14 +58,59 @@ export const Pagination: FC<{ const t = useT(); const { current, totalPages, setPage } = props; - const totalPagesList = useMemo(() => { - return Array.from( - { - length: totalPages, - }, - (_, i) => i - ); - }, [totalPages]); + + const paginationItems = useMemo(() => { + // Convert to 1-based for algorithm (current is 0-based) + const c = current + 1; + const m = totalPages; + + // If total pages <= 10, show all pages + if (m <= 10) { + return Array.from({ length: m }, (_, i) => i + 1); + } + + const delta = 3; + const left = c - delta; + const right = c + delta + 1; + const range: number[] = []; + const rangeWithDots: (number | '...')[] = []; + let l: number | undefined; + + // Build the range of pages to show + for (let i = 1; i <= m; i++) { + if (i === 1 || i === m || (i >= left && i < right)) { + range.push(i); + } + } + + // Add dots where there are gaps + for (const i of range) { + if (l !== undefined) { + if (i - l === 2) { + rangeWithDots.push(l + 1); + } else if (i - l !== 1) { + rangeWithDots.push('...'); + } + } + rangeWithDots.push(i); + l = i; + } + + // Limit to maximum 10 items by trimming pages near edges if needed + while (rangeWithDots.length > 10) { + const currentIndex = rangeWithDots.findIndex((item) => item === c); + if (currentIndex !== -1 && currentIndex > rangeWithDots.length / 2) { + // Current is in second half, remove one item from start side + rangeWithDots.splice(2, 1); + } else { + // Current is in first half, remove one item from end side + rangeWithDots.splice(-3, 1); + } + } + + return rangeWithDots; + }, [current, totalPages]); + return (