fix: restore reader direction and double-page navigation UI
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m6s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m6s
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useState, useCallback, useRef } from "react";
|
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)}
|
shouldShowDoublePage={(page) => shouldShowDoublePage(page, pages.length)}
|
||||||
imageBlobUrls={imageBlobUrls}
|
imageBlobUrls={imageBlobUrls}
|
||||||
getPageUrl={getPageUrl}
|
getPageUrl={getPageUrl}
|
||||||
|
isRTL={isRTL}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<NavigationBar
|
<NavigationBar
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ export const ControlButtons = ({
|
|||||||
iconClassName="h-8 w-8"
|
iconClassName="h-8 w-8"
|
||||||
className={cn(
|
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",
|
"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"
|
showControls ? "opacity-100" : "opacity-0 pointer-events-none"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@@ -199,7 +199,7 @@ export const ControlButtons = ({
|
|||||||
iconClassName="h-8 w-8"
|
iconClassName="h-8 w-8"
|
||||||
className={cn(
|
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",
|
"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"
|
showControls ? "opacity-100" : "opacity-0 pointer-events-none"
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { useState, useCallback, useEffect } from "react";
|
import { useState, useCallback, useEffect } from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { useReadingDirection } from "../hooks/useReadingDirection";
|
|
||||||
|
|
||||||
interface PageDisplayProps {
|
interface PageDisplayProps {
|
||||||
currentPage: number;
|
currentPage: number;
|
||||||
@@ -9,6 +8,7 @@ interface PageDisplayProps {
|
|||||||
shouldShowDoublePage: (page: number) => boolean;
|
shouldShowDoublePage: (page: number) => boolean;
|
||||||
imageBlobUrls: Record<number, string>;
|
imageBlobUrls: Record<number, string>;
|
||||||
getPageUrl: (pageNum: number) => string;
|
getPageUrl: (pageNum: number) => string;
|
||||||
|
isRTL: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PageDisplay({
|
export function PageDisplay({
|
||||||
@@ -18,12 +18,12 @@ export function PageDisplay({
|
|||||||
shouldShowDoublePage,
|
shouldShowDoublePage,
|
||||||
imageBlobUrls,
|
imageBlobUrls,
|
||||||
getPageUrl,
|
getPageUrl,
|
||||||
|
isRTL,
|
||||||
}: PageDisplayProps) {
|
}: PageDisplayProps) {
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [hasError, setHasError] = useState(false);
|
const [hasError, setHasError] = useState(false);
|
||||||
const [secondPageLoading, setSecondPageLoading] = useState(true);
|
const [secondPageLoading, setSecondPageLoading] = useState(true);
|
||||||
const [secondPageHasError, setSecondPageHasError] = useState(false);
|
const [secondPageHasError, setSecondPageHasError] = useState(false);
|
||||||
const { isRTL } = useReadingDirection();
|
|
||||||
|
|
||||||
const handleImageLoad = useCallback(() => {
|
const handleImageLoad = useCallback(() => {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -53,7 +53,7 @@ export function PageDisplay({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex w-full flex-1 items-center justify-center overflow-hidden">
|
<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 */}
|
{/* Page 1 */}
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -61,8 +61,8 @@ export function PageDisplay({
|
|||||||
isDoublePage && shouldShowDoublePage(currentPage) ? "w-1/2" : "w-full justify-center",
|
isDoublePage && shouldShowDoublePage(currentPage) ? "w-1/2" : "w-full justify-center",
|
||||||
isDoublePage &&
|
isDoublePage &&
|
||||||
shouldShowDoublePage(currentPage) && {
|
shouldShowDoublePage(currentPage) && {
|
||||||
"order-2 justify-center": isRTL,
|
"order-2 justify-start": isRTL,
|
||||||
"order-1 justify-center": !isRTL,
|
"order-1 justify-end": !isRTL,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -79,7 +79,18 @@ export function PageDisplay({
|
|||||||
)}
|
)}
|
||||||
{hasError ? (
|
{hasError ? (
|
||||||
<div className="flex flex-col items-center justify-center gap-3 text-muted-foreground">
|
<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">
|
<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" />
|
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
|
||||||
<circle cx="9" cy="9" r="2" />
|
<circle cx="9" cy="9" r="2" />
|
||||||
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
|
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
|
||||||
@@ -94,7 +105,7 @@ export function PageDisplay({
|
|||||||
src={imageBlobUrls[currentPage] || getPageUrl(currentPage)}
|
src={imageBlobUrls[currentPage] || getPageUrl(currentPage)}
|
||||||
alt={`Page ${currentPage}`}
|
alt={`Page ${currentPage}`}
|
||||||
className={cn(
|
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"
|
isLoading ? "opacity-0" : "opacity-100"
|
||||||
)}
|
)}
|
||||||
loading="eager"
|
loading="eager"
|
||||||
@@ -114,9 +125,9 @@ export function PageDisplay({
|
|||||||
{/* Page 2 (double page) */}
|
{/* Page 2 (double page) */}
|
||||||
{isDoublePage && shouldShowDoublePage(currentPage) && (
|
{isDoublePage && shouldShowDoublePage(currentPage) && (
|
||||||
<div
|
<div
|
||||||
className={cn("relative h-full w-1/2 flex items-center justify-center", {
|
className={cn("relative h-full w-1/2 flex items-center", {
|
||||||
"order-1": isRTL,
|
"order-1 justify-end": isRTL,
|
||||||
"order-2": !isRTL,
|
"order-2 justify-start": !isRTL,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{secondPageLoading && (
|
{secondPageLoading && (
|
||||||
@@ -132,7 +143,18 @@ export function PageDisplay({
|
|||||||
)}
|
)}
|
||||||
{secondPageHasError ? (
|
{secondPageHasError ? (
|
||||||
<div className="flex flex-col items-center justify-center gap-3 text-muted-foreground">
|
<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">
|
<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" />
|
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
|
||||||
<circle cx="9" cy="9" r="2" />
|
<circle cx="9" cy="9" r="2" />
|
||||||
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
|
<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
|
||||||
@@ -147,7 +169,7 @@ export function PageDisplay({
|
|||||||
src={imageBlobUrls[currentPage + 1] || getPageUrl(currentPage + 1)}
|
src={imageBlobUrls[currentPage + 1] || getPageUrl(currentPage + 1)}
|
||||||
alt={`Page ${currentPage + 1}`}
|
alt={`Page ${currentPage + 1}`}
|
||||||
className={cn(
|
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"
|
secondPageLoading ? "opacity-0" : "opacity-100"
|
||||||
)}
|
)}
|
||||||
loading="eager"
|
loading="eager"
|
||||||
|
|||||||
Reference in New Issue
Block a user