link to another pager

This commit is contained in:
hamid zarghami
2026-01-07 15:02:44 +03:30
parent 9e1dd09097
commit 7a2bdfba56
3 changed files with 312 additions and 57 deletions
+109 -33
View File
@@ -11,6 +11,7 @@ type BookViewerProps = {
interface PageFlipAPI {
flipNext: () => void;
flipPrev: () => void;
turnToPage: (page: number) => void;
}
interface FlipBookInstance {
@@ -43,14 +44,14 @@ const BookViewer: FC<BookViewerProps> = ({ pages }) => {
// react-pageflip شماره صفحه را به صورت 0-based برمی‌گرداند
// اما باید مطمئن شویم که در محدوده معتبر است
let pageNum = e.data;
// اگر pageNum منفی است یا بزرگتر از تعداد صفحات، آن را محدود می‌کنیم
if (pageNum < 0) {
pageNum = 0;
} else if (pageNum >= pages.length) {
pageNum = pages.length - 1;
}
setCurrentPage(pageNum);
}, [pages.length]);
@@ -66,6 +67,81 @@ const BookViewer: FC<BookViewerProps> = ({ pages }) => {
}
}, [currentPage]);
const handleLinkClick = useCallback((linkUrl: string) => {
if (linkUrl.startsWith('page://')) {
const action = linkUrl.replace('page://', '');
const pageFlipAPI = bookRef.current?.pageFlip();
if (!pageFlipAPI) return;
if (action === 'next') {
goToNextPage();
} else if (action === 'prev') {
goToPrevPage();
} else if (action === 'first') {
// رفتن به صفحه اول
const flipToFirst = () => {
if (currentPage > 0) {
pageFlipAPI.flipPrev();
setTimeout(() => {
setCurrentPage(prev => {
if (prev > 1) {
flipToFirst();
}
return prev - 1;
});
}, 300);
}
};
flipToFirst();
} else if (action === 'last') {
// رفتن به صفحه آخر
const lastPageIndex = pages.length - 1;
const flipToLast = () => {
if (currentPage < lastPageIndex) {
pageFlipAPI.flipNext();
setTimeout(() => {
setCurrentPage(prev => {
if (prev < lastPageIndex - 1) {
flipToLast();
}
return prev + 1;
});
}, 300);
}
};
flipToLast();
} else {
// شماره صفحه مشخص (مثل page://3)
const pageNum = parseInt(action, 10);
if (!isNaN(pageNum) && pageNum >= 1 && pageNum <= pages.length) {
const targetIndex = pageNum - 1;
const diff = targetIndex - currentPage;
const flipToTarget = (remaining: number) => {
if (remaining === 0) return;
if (remaining > 0) {
pageFlipAPI.flipNext();
setTimeout(() => {
setCurrentPage(prev => prev + 1);
flipToTarget(remaining - 1);
}, 300);
} else {
pageFlipAPI.flipPrev();
setTimeout(() => {
setCurrentPage(prev => prev - 1);
flipToTarget(remaining + 1);
}, 300);
}
};
flipToTarget(diff);
}
}
}
}, [currentPage, pages.length, goToNextPage, goToPrevPage]);
return (
<div className="flex flex-col items-center gap-4 md:gap-6 w-full h-full" dir="rtl">
{/* نمایش کتاب */}
@@ -78,39 +154,39 @@ const BookViewer: FC<BookViewerProps> = ({ pages }) => {
}}
/>
<div style={{ overflow: 'hidden', isolation: 'isolate' }}>
<HTMLFlipBook
ref={bookRef}
width={397}
height={561}
size="fixed"
minWidth={397}
minHeight={561}
maxWidth={397}
maxHeight={561}
drawShadow={true}
flippingTime={800}
usePortrait={false}
startPage={0}
autoSize={false}
maxShadowOpacity={0.5}
showCover={true}
mobileScrollSupport={true}
clickEventForward={true}
useMouseEvents={true}
swipeDistance={30}
startZIndex={1}
showPageCorners={true}
disableFlipByClick={false}
className="flipbook-container mx-auto"
style={{
direction: 'rtl',
}}
onFlip={handlePageFlip}
>
<HTMLFlipBook
ref={bookRef}
width={397}
height={561}
size="fixed"
minWidth={397}
minHeight={561}
maxWidth={397}
maxHeight={561}
drawShadow={true}
flippingTime={800}
usePortrait={false}
startPage={0}
autoSize={false}
maxShadowOpacity={0.5}
showCover={true}
mobileScrollSupport={true}
clickEventForward={true}
useMouseEvents={true}
swipeDistance={30}
startZIndex={1}
showPageCorners={true}
disableFlipByClick={true}
className="flipbook-container mx-auto"
style={{
direction: 'rtl',
}}
onFlip={handlePageFlip}
>
{pages.map((page) => (
<BookPage key={page.id} page={page} scale={0.5} />
<BookPage key={page.id} page={page} scale={0.5} onLinkClick={handleLinkClick} />
))}
</HTMLFlipBook>
</HTMLFlipBook>
</div>
</div>