Various fixes

This commit is contained in:
chrox
2024-11-21 11:42:05 +01:00
parent 53feabe256
commit 73d933ace4
7 changed files with 57 additions and 37 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ rust-version = "1.71"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "readest"
name = "readestlib"
crate-type = ["staticlib", "cdylib", "lib"]
[build-dependencies]
+1 -1
View File
@@ -2,5 +2,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
readest::run();
readestlib::run();
}
@@ -1,4 +1,5 @@
import * as React from 'react';
import { useState } from 'react';
import { PiPlus } from 'react-icons/pi';
import { MdDelete, MdOpenInNew } from 'react-icons/md';
import { MdCheckCircle, MdCheckCircleOutline } from 'react-icons/md';
@@ -11,6 +12,7 @@ import Alert from '@/components/Alert';
import { useReaderStore } from '@/store/readerStore';
import { useEnv } from '@/context/EnvContext';
import clsx from 'clsx';
import Spinner from '@/components/Spinner';
type BookshelfItem = Book | BooksGroup;
@@ -48,9 +50,10 @@ const Bookshelf: React.FC<BookshelfProps> = ({ libraryBooks, isSelectMode, onImp
const router = useRouter();
const { envConfig } = useEnv();
const { deleteBook } = useReaderStore();
const [selectedBooks, setSelectedBooks] = React.useState<string[]>([]);
const [showDeleteAlert, setShowDeleteAlert] = React.useState(false);
const [clickedImage, setClickedImage] = React.useState<string | null>(null);
const [loading, setLoading] = useState(false);
const [selectedBooks, setSelectedBooks] = useState<string[]>([]);
const [showDeleteAlert, setShowDeleteAlert] = useState(false);
const [clickedImage, setClickedImage] = useState<string | null>(null);
React.useEffect(() => {
setSelectedBooks([]);
@@ -64,6 +67,7 @@ const Bookshelf: React.FC<BookshelfProps> = ({ libraryBooks, isSelectMode, onImp
} else {
setClickedImage(id);
setTimeout(() => setClickedImage(null), 300);
setTimeout(() => setLoading(true), 200);
router.push(`/reader?ids=${id}`);
}
};
@@ -75,6 +79,7 @@ const Bookshelf: React.FC<BookshelfProps> = ({ libraryBooks, isSelectMode, onImp
};
const openSelectedBooks = () => {
setTimeout(() => setLoading(true), 200);
router.push(`/reader?ids=${selectedBooks.join(',')}`);
};
@@ -123,8 +128,8 @@ const Bookshelf: React.FC<BookshelfProps> = ({ libraryBooks, isSelectMode, onImp
/>
<div
className={clsx(
'invisible absolute inset-0 flex items-center justify-center',
'rounded-none text-center font-sans text-lg font-medium text-gray-600',
'invisible absolute inset-0 flex items-center justify-center p-1',
'text-neutral-content rounded-none text-center font-serif text-base font-medium',
)}
>
{item.title}
@@ -196,6 +201,11 @@ const Bookshelf: React.FC<BookshelfProps> = ({ libraryBooks, isSelectMode, onImp
</button>
</div>
)}
{loading && (
<div className='fixed inset-0 z-50 flex items-center justify-center'>
<Spinner loading />
</div>
)}
{showDeleteAlert && (
<Alert
title='Confirm Deletion'
+21 -19
View File
@@ -13,17 +13,19 @@ import Bookshelf from '@/app/library/components/Bookshelf';
const LibraryPage = () => {
const { envConfig, appService } = useEnv();
const { library: libraryBooks, setLibrary } = useReaderStore();
const [loading, setLoading] = useState(true);
const [loading, setLoading] = useState(false);
const isInitiating = useRef(false);
const [isSelectMode, setIsSelectMode] = useState(false);
React.useEffect(() => {
if (isInitiating.current) return;
isInitiating.current = true;
setLoading(true);
const loadingTimeout = setTimeout(() => setLoading(true), 200);
envConfig.getAppService().then(async (appService) => {
console.log('Loading library books...');
setLibrary(await appService.loadLibraryBooks());
if (loadingTimeout) clearTimeout(loadingTimeout);
setLoading(false);
});
}, []);
@@ -73,7 +75,7 @@ const LibraryPage = () => {
};
if (!appService) {
return <Spinner loading />;
return null;
}
return (
@@ -90,29 +92,29 @@ const LibraryPage = () => {
<Spinner loading />
</div>
)}
<div className='mt-12 flex-grow overflow-auto px-2'>
{libraryBooks.length > 0 ? (
{libraryBooks.length > 0 ? (
<div className='mt-12 flex-grow overflow-auto px-2'>
<Bookshelf
libraryBooks={libraryBooks}
isSelectMode={isSelectMode}
onImportBooks={handleImportBooks}
/>
) : (
<div className='hero h-full items-center justify-center'>
<div className='hero-content text-neutral-content text-center'>
<div className='max-w-md'>
<h1 className='mb-5 text-5xl font-bold'>Your Library</h1>
<p className='mb-5'>
Welcome to your library. You can upload your books here and read them anytime.
</p>
<button className='btn btn-primary' onClick={handleImportBooks}>
Upload Books
</button>
</div>
</div>
) : (
<div className='hero h-full items-center justify-center'>
<div className='hero-content text-neutral-content text-center'>
<div className='max-w-md'>
<h1 className='mb-5 text-5xl font-bold'>Your Library</h1>
<p className='mb-5'>
Welcome to your library. You can import your books here and read them anytime.
</p>
<button className='btn btn-primary rounded-xl' onClick={handleImportBooks}>
Import Books
</button>
</div>
</div>
)}
</div>
</div>
)}
</div>
);
};
@@ -116,6 +116,8 @@ const FoliateViewer: React.FC<{
useEffect(() => {
if (isViewCreated.current) return;
isViewCreated.current = true;
const openBook = async () => {
console.log('Opening book', bookKey);
await import('foliate-js/view.js');
@@ -161,13 +163,6 @@ const FoliateViewer: React.FC<{
};
openBook();
isViewCreated.current = true;
return () => {
console.log('Closing book', bookKey);
viewRef.current?.close();
viewRef.current?.remove();
};
}, []);
const initAnnotations = () => {
@@ -1,6 +1,7 @@
'use client';
import * as React from 'react';
import { useState, useRef } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useEnv } from '@/context/EnvContext';
@@ -24,10 +25,15 @@ const ReaderContent: React.FC<{ settings: SystemSettings }> = ({ settings }) =>
useReaderStore();
const { setBookKeys, getBookData, initViewState, getViewState, clearViewState } =
useReaderStore();
const isInitiating = useRef(false);
const [loading, setLoading] = useState(false);
useBookShortcuts({ sideBarBookKey, bookKeys });
React.useEffect(() => {
if (isInitiating.current) return;
isInitiating.current = true;
const initialIds = (searchParams.get('ids') || '').split(',').filter(Boolean);
const initialBookKeys = initialIds.map((id) => `${id}-${uniqueId()}`);
setBookKeys(initialBookKeys);
@@ -45,6 +51,7 @@ const ReaderContent: React.FC<{ settings: SystemSettings }> = ({ settings }) =>
}, []);
const saveConfigAndCloseBook = (bookKey: string) => {
console.log('Closing book', bookKey);
getView(bookKey)?.close();
getView(bookKey)?.remove();
const config = getConfig(bookKey);
@@ -82,10 +89,13 @@ const ReaderContent: React.FC<{ settings: SystemSettings }> = ({ settings }) =>
if (!bookKeys || bookKeys.length === 0) return null;
const bookData = getBookData(bookKeys[0]!);
if (!bookData || !bookData.book || !bookData.bookDoc) {
setTimeout(() => setLoading(true), 200);
return (
<div className={'hero hero-content min-h-screen'}>
<Spinner loading={true} />
</div>
loading && (
<div className={'hero hero-content min-h-screen'}>
<Spinner loading={true} />
</div>
)
);
}
@@ -18,10 +18,13 @@ const BookCard: React.FC<BookCardProps> = ({ cover, title, author }) => {
width={56}
height={80}
className='mr-4 aspect-auto max-h-20 w-[15%] max-w-14 rounded-sm object-cover shadow-md'
onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none';
}}
/>
<div className='min-w-0 flex-1'>
<h4 className='line-clamp-2 w-[90%] text-sm font-semibold'>{title}</h4>
<p className='text-neutral-content truncate text-sm'>{formatAuthors(author)}</p>
<p className='text-neutral-content truncate text-xs'>{formatAuthors(author)}</p>
</div>
<button
className='btn btn-ghost hover:bg-base-300 h-6 min-h-6 w-6 rounded-full p-0 transition-colors'