fix: restore reader direction and double-page navigation UI
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m6s

This commit is contained in:
2026-03-04 06:49:40 +01:00
parent 6a06e5a7d3
commit 23fa884af7
3 changed files with 43 additions and 21 deletions

View File

@@ -1,4 +1,3 @@
"use client";
import { useEffect, useState, useCallback, useRef } from "react";
@@ -218,6 +217,7 @@ export function PhotoswipeReader({ book, pages, onClose, nextBook }: BookReaderP
shouldShowDoublePage={(page) => shouldShowDoublePage(page, pages.length)}
imageBlobUrls={imageBlobUrls}
getPageUrl={getPageUrl}
isRTL={isRTL}
/>
<NavigationBar

View File

@@ -179,7 +179,7 @@ export const ControlButtons = ({
iconClassName="h-8 w-8"
className={cn(
"absolute top-1/2 z-20 -translate-y-1/2 rounded-full border border-border/60 bg-background/55 shadow-[0_8px_24px_-16px_rgba(0,0,0,0.75)] backdrop-blur-xl transition-all duration-300 hover:bg-background/70",
direction === "rtl" ? "right-4" : "left-4",
"left-4",
showControls ? "opacity-100" : "opacity-0 pointer-events-none"
)}
/>
@@ -199,7 +199,7 @@ export const ControlButtons = ({
iconClassName="h-8 w-8"
className={cn(
"absolute top-1/2 z-20 -translate-y-1/2 rounded-full border border-border/60 bg-background/55 shadow-[0_8px_24px_-16px_rgba(0,0,0,0.75)] backdrop-blur-xl transition-all duration-300 hover:bg-background/70",
direction === "rtl" ? "left-4" : "right-4",
"right-4",
showControls ? "opacity-100" : "opacity-0 pointer-events-none"
)}
/>

View File

@@ -1,6 +1,5 @@
import { useState, useCallback, useEffect } from "react";
import { cn } from "@/lib/utils";
import { useReadingDirection } from "../hooks/useReadingDirection";
interface PageDisplayProps {
currentPage: number;
@@ -9,6 +8,7 @@ interface PageDisplayProps {
shouldShowDoublePage: (page: number) => boolean;
imageBlobUrls: Record<number, string>;
getPageUrl: (pageNum: number) => string;
isRTL: boolean;
}
export function PageDisplay({
@@ -18,12 +18,12 @@ export function PageDisplay({
shouldShowDoublePage,
imageBlobUrls,
getPageUrl,
isRTL,
}: PageDisplayProps) {
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
const [secondPageLoading, setSecondPageLoading] = useState(true);
const [secondPageHasError, setSecondPageHasError] = useState(false);
const { isRTL } = useReadingDirection();
const handleImageLoad = useCallback(() => {
setIsLoading(false);
@@ -53,7 +53,7 @@ export function PageDisplay({
return (
<div className="relative flex w-full flex-1 items-center justify-center overflow-hidden">
<div className="relative flex h-[calc(100vh-2.5rem)] w-full items-center justify-center gap-1 px-2 sm:px-4">
<div className="relative flex h-[calc(100vh-2.5rem)] w-full items-center justify-center px-2 sm:px-4">
{/* Page 1 */}
<div
className={cn(
@@ -61,8 +61,8 @@ export function PageDisplay({
isDoublePage && shouldShowDoublePage(currentPage) ? "w-1/2" : "w-full justify-center",
isDoublePage &&
shouldShowDoublePage(currentPage) && {
"order-2 justify-center": isRTL,
"order-1 justify-center": !isRTL,
"order-2 justify-start": isRTL,
"order-1 justify-end": !isRTL,
}
)}
>
@@ -79,10 +79,21 @@ export function PageDisplay({
)}
{hasError ? (
<div className="flex flex-col items-center justify-center gap-3 text-muted-foreground">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="opacity-40">
<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/>
<circle cx="9" cy="9" r="2"/>
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
className="opacity-40"
>
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
<circle cx="9" cy="9" r="2" />
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
</svg>
<span className="text-sm opacity-60">Image non disponible</span>
</div>
@@ -94,7 +105,7 @@ export function PageDisplay({
src={imageBlobUrls[currentPage] || getPageUrl(currentPage)}
alt={`Page ${currentPage}`}
className={cn(
"max-h-full max-w-full cursor-pointer rounded-md object-contain transition-opacity",
"max-h-full max-w-full cursor-pointer object-contain transition-opacity",
isLoading ? "opacity-0" : "opacity-100"
)}
loading="eager"
@@ -114,9 +125,9 @@ export function PageDisplay({
{/* Page 2 (double page) */}
{isDoublePage && shouldShowDoublePage(currentPage) && (
<div
className={cn("relative h-full w-1/2 flex items-center justify-center", {
"order-1": isRTL,
"order-2": !isRTL,
className={cn("relative h-full w-1/2 flex items-center", {
"order-1 justify-end": isRTL,
"order-2 justify-start": !isRTL,
})}
>
{secondPageLoading && (
@@ -132,10 +143,21 @@ export function PageDisplay({
)}
{secondPageHasError ? (
<div className="flex flex-col items-center justify-center gap-3 text-muted-foreground">
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="opacity-40">
<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/>
<circle cx="9" cy="9" r="2"/>
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
className="opacity-40"
>
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
<circle cx="9" cy="9" r="2" />
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
</svg>
<span className="text-sm opacity-60">Image non disponible</span>
</div>
@@ -147,7 +169,7 @@ export function PageDisplay({
src={imageBlobUrls[currentPage + 1] || getPageUrl(currentPage + 1)}
alt={`Page ${currentPage + 1}`}
className={cn(
"max-h-full max-w-full cursor-pointer rounded-md object-contain transition-opacity",
"max-h-full max-w-full cursor-pointer object-contain transition-opacity",
secondPageLoading ? "opacity-0" : "opacity-100"
)}
loading="eager"