fix(layout): fixed some rendering problems on Next 16 (#2495)

This commit is contained in:
Huang Xin
2025-11-21 12:53:42 +05:30
committed by GitHub
parent 8849c19e8e
commit b8e979be55
3 changed files with 68 additions and 57 deletions
@@ -129,54 +129,59 @@ const Bookshelf: React.FC<BookshelfProps> = ({
const sort = searchParams?.get('sort') || settings.librarySortBy;
const order = searchParams?.get('order') || (settings.librarySortAscending ? 'asc' : 'desc');
const cover = searchParams?.get('cover') || settings.libraryCoverFit;
const params = new URLSearchParams(searchParams?.toString());
if (query) {
params.set('q', query);
setQueryTerm(query);
} else {
params.delete('q');
setQueryTerm(null);
}
if (sort) {
params.set('sort', sort);
setSortBy(sort);
} else {
params.delete('sort');
}
if (order) {
params.set('order', order);
setSortOrder(order);
} else {
params.delete('order');
}
if (view) {
params.set('view', view);
setViewMode(view);
} else {
params.delete('view');
}
setCoverFit(cover);
if (cover === 'crop') {
params.delete('cover');
}
if (sort === 'updated' && order === 'desc' && view === 'grid') {
params.delete('sort');
params.delete('order');
params.delete('view');
}
setGroupId(group);
if (group) {
if (currentBookshelfItems.length > 0) {
params.set('group', group);
} else {
params.delete('group');
navigateToLibrary(router, `${params.toString()}`);
setQueryTerm(query || null);
setViewMode(view);
setSortBy(sort);
setSortOrder(order);
setCoverFit(cover);
}, [searchParams, settings]);
useEffect(() => {
const params = new URLSearchParams(searchParams?.toString());
let hasChanges = false;
if (queryTerm) {
if (params.get('q') !== queryTerm) {
params.set('q', queryTerm);
hasChanges = true;
}
} else {
params.delete('group');
navigateToLibrary(router, `${params.toString()}`);
if (params.has('q')) {
params.delete('q');
hasChanges = true;
}
}
}, [router, settings, searchParams, currentBookshelfItems, showGroupingModal]);
if (sortBy !== 'updated' && params.get('sort') !== sortBy) {
params.set('sort', sortBy);
hasChanges = true;
} else if (sortBy === 'updated' && sortOrder === 'desc' && viewMode === 'grid') {
if (params.has('sort')) {
params.delete('sort');
hasChanges = true;
}
}
if (groupId) {
if (currentBookshelfItems.length === 0) {
params.delete('group');
hasChanges = true;
} else if (params.get('group') !== groupId) {
params.set('group', groupId);
hasChanges = true;
}
} else if (params.has('group')) {
params.delete('group');
hasChanges = true;
}
if (hasChanges) {
navigateToLibrary(router, params.toString());
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [queryTerm, sortBy, sortOrder, viewMode, coverFit, groupId, currentBookshelfItems.length]);
const toggleSelection = useCallback(
(id: string) => {
@@ -1,6 +1,5 @@
import clsx from 'clsx';
import React from 'react';
import Image from 'next/image';
import React, { useRef } from 'react';
import { MdInfoOutline } from 'react-icons/md';
import { Book } from '@/types/book';
import { useThemeStore } from '@/store/themeStore';
@@ -8,12 +7,14 @@ import { useTranslation } from '@/hooks/useTranslation';
import { eventDispatcher } from '@/utils/event';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
import { formatAuthors, formatTitle } from '@/utils/book';
import BookCover from '@/components/BookCover';
const BookCard = ({ book }: { book: Book }) => {
const { coverImageUrl, title, author, metadata } = book;
const { title, author } = book;
const _ = useTranslation();
const { isDarkMode } = useThemeStore();
const iconSize18 = useResponsiveSize(18);
const bookCoverRef = useRef<HTMLDivElement | null>(null);
const showBookDetails = () => {
eventDispatcher.dispatchSync('show-book-details', book);
@@ -21,19 +22,21 @@ const BookCard = ({ book }: { book: Book }) => {
return (
<div className='flex h-20 w-full items-center'>
<Image
src={metadata?.coverImageUrl || coverImageUrl!}
alt={_('Book Cover')}
width={56}
height={80}
<div
ref={bookCoverRef}
className={clsx(
'me-4 aspect-auto max-h-16 w-[15%] max-w-12 rounded-sm object-cover shadow-md',
'me-4 aspect-[28/41] max-h-16 w-[15%] max-w-12 overflow-hidden rounded-sm shadow-md',
isDarkMode ? 'mix-blend-screen' : 'mix-blend-multiply',
)}
onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none';
}}
/>
>
<BookCover
book={book}
mode='list'
coverFit='crop'
imageClassName='rounded-sm'
onImageError={() => (bookCoverRef.current!.style.display = 'none')}
/>
</div>
<div className='min-w-0 flex-1'>
<h4 className='line-clamp-2 w-[90%] text-sm font-semibold'>{formatTitle(title)}</h4>
<p className='truncate text-xs opacity-75'>{formatAuthors(author)}</p>
@@ -13,6 +13,7 @@ interface BookCoverProps {
imageClassName?: string;
showSpine?: boolean;
isPreview?: boolean;
onImageError?: () => void;
}
const BookCover: React.FC<BookCoverProps> = memo<BookCoverProps>(
@@ -24,6 +25,7 @@ const BookCover: React.FC<BookCoverProps> = memo<BookCoverProps>(
className,
imageClassName,
isPreview,
onImageError,
}) => {
const coverRef = useRef<HTMLDivElement>(null);
const [imageLoaded, setImageLoaded] = useState(false);
@@ -54,6 +56,7 @@ const BookCover: React.FC<BookCoverProps> = memo<BookCoverProps>(
setImageLoaded(false);
setImageError(true);
toggleImageVisibility(false);
onImageError?.();
};
useEffect(() => {