layout: apply custom css also to the library page, tweaks on fitted cover images (#1481)

This commit is contained in:
Huang Xin
2025-06-27 16:01:17 +08:00
committed by GitHub
parent 4fde9955b2
commit 7737c05c8f
5 changed files with 53 additions and 29 deletions
@@ -54,7 +54,7 @@ const BookItem: React.FC<BookItemProps> = ({
<div
className={clsx(
'book-item flex',
mode === 'grid' && 'h-full flex-col',
mode === 'grid' && 'h-full flex-col justify-end',
mode === 'list' && 'h-28 flex-row gap-4 overflow-hidden',
appService?.hasContextMenu ? 'cursor-pointer' : '',
)}
@@ -65,7 +65,7 @@ const BookItem: React.FC<BookItemProps> = ({
mode === 'list' && 'min-w-20',
)}
>
<BookCover mode={mode} book={book} coverFit={coverFit} className='drop-shadow-md' />
<BookCover mode={mode} book={book} coverFit={coverFit} />
{selectedBooks.includes(book.hash) && (
<div className='absolute inset-0 bg-black opacity-30 transition-opacity duration-300'></div>
)}
@@ -1,6 +1,7 @@
import clsx from 'clsx';
import { MdCheckCircle, MdCheckCircleOutline } from 'react-icons/md';
import { useEnv } from '@/context/EnvContext';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
import { BooksGroup } from '@/types/book';
import BookCover from '@/components/BookCover';
@@ -12,10 +13,12 @@ interface GroupItemProps {
const GroupItem: React.FC<GroupItemProps> = ({ group, isSelectMode, selectedBooks }) => {
const { appService } = useEnv();
const iconSize15 = useResponsiveSize(15);
return (
<div
className={clsx(
'group-item flex h-full flex-col',
'group-item flex h-full flex-col justify-end',
appService?.hasContextMenu ? 'cursor-pointer' : '',
)}
>
@@ -40,10 +43,13 @@ const GroupItem: React.FC<GroupItemProps> = ({ group, isSelectMode, selectedBook
</div>
)}
</div>
<div className='min-w-0 flex-1 pt-2'>
<h4 className='block overflow-hidden text-ellipsis whitespace-nowrap text-xs font-semibold'>
{group.name}
</h4>
<div className={clsx('flex w-full flex-col pt-2')}>
<div className='min-w-0 flex-1'>
<h4 className='block overflow-hidden text-ellipsis whitespace-nowrap text-xs font-semibold'>
{group.name}
</h4>
</div>
<div className='placeholder' style={{ height: `${iconSize15}px` }}></div>
</div>
</div>
);
+4 -1
View File
@@ -26,6 +26,7 @@ import { useLibraryStore } from '@/store/libraryStore';
import { useSettingsStore } from '@/store/settingsStore';
import { usePullToRefresh } from '@/hooks/usePullToRefresh';
import { useTheme } from '@/hooks/useTheme';
import { useUICSS } from '@/hooks/useUICSS';
import { useDemoBooks } from './hooks/useDemoBooks';
import { useBooksSync } from './hooks/useBooksSync';
import { useSafeAreaInsets } from '@/hooks/useSafeAreaInsets';
@@ -68,7 +69,6 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
setCheckLastOpenBooks,
} = useLibraryStore();
const _ = useTranslation();
useTheme({ systemUIVisible: true, appThemeColor: 'base-200' });
const insets = useSafeAreaInsets();
const { settings, setSettings, saveSettings } = useSettingsStore();
const [loading, setLoading] = useState(false);
@@ -87,6 +87,9 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
const containerRef = useRef<HTMLDivElement>(null);
const pageRef = useRef<HTMLDivElement>(null);
useTheme({ systemUIVisible: true, appThemeColor: 'base-200' });
useUICSS();
useOpenWithBooks();
const { pullLibrary, pushLibrary } = useBooksSync({
+28 -16
View File
@@ -22,22 +22,34 @@ const BookCover: React.FC<BookCoverProps> = ({
isPreview,
}) => {
return (
<div className={clsx('relative flex h-full w-full', className)}>
<Image
src={book.coverImageUrl!}
alt={book.title}
fill={true}
className={clsx(
coverFit === 'crop'
? 'object-cover'
: `object-contain ${mode === 'grid' ? 'object-bottom' : ''}`,
imageClassName,
)}
onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none';
(e.target as HTMLImageElement).nextElementSibling?.classList.remove('invisible');
}}
/>
<div className={clsx('relative flex h-full w-full shadow-md', className)}>
{coverFit === 'crop' ? (
<Image
src={book.coverImageUrl!}
alt={book.title}
fill={true}
className={clsx('crop-cover-img object-cover', imageClassName)}
onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none';
(e.target as HTMLImageElement).nextElementSibling?.classList.remove('invisible');
}}
/>
) : (
<div className='flex h-full w-full items-end justify-center'>
<Image
src={book.coverImageUrl!}
alt={book.title}
width={0}
height={0}
sizes='100vw'
className={clsx('fit-cover-img h-auto max-h-full w-auto max-w-full', imageClassName)}
onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none';
(e.target as HTMLImageElement).nextElementSibling?.classList.remove('invisible');
}}
/>
</div>
)}
<div
className={clsx(
'invisible absolute inset-0 rounded-none p-2',
+8 -5
View File
@@ -1,20 +1,23 @@
import { useEffect, useState } from 'react';
import { useReaderStore } from '@/store/readerStore';
import { useSettingsStore } from '@/store/settingsStore';
// This hook allows you to inject custom CSS into the reader UI.
// Note that the book content is rendered in an iframe, so UI CSS won't affect book rendering.
export const useUICSS = (bookKey: string) => {
export const useUICSS = (bookKey?: string) => {
const { settings } = useSettingsStore();
const { getViewSettings } = useReaderStore();
const viewSettings = getViewSettings(bookKey);
const viewSettings = getViewSettings(bookKey || '');
const [styleElement, setStyleElement] = useState<HTMLStyleElement | null>(null);
useEffect(() => {
if (!viewSettings) return;
if (styleElement) {
styleElement.remove();
}
const rawCSS = viewSettings.userUIStylesheet || '';
const rawCSS =
viewSettings?.userUIStylesheet || settings?.globalViewSettings?.userUIStylesheet || '';
const newStyleEl = document.createElement('style');
newStyleEl.textContent = rawCSS.replace('foliate-view', `#foliate-view-${bookKey}`);
document.head.appendChild(newStyleEl);
@@ -24,5 +27,5 @@ export const useUICSS = (bookKey: string) => {
newStyleEl.remove();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [viewSettings]);
}, [viewSettings?.userUIStylesheet, settings?.globalViewSettings?.userUIStylesheet, bookKey]);
};