@@ -12,6 +12,7 @@ import { getGridTemplate, getInsetEdges } from '@/utils/grid';
|
||||
import { getViewInsets } from '@/utils/insets';
|
||||
import SettingsDialog from '@/components/settings/SettingsDialog';
|
||||
import SearchResultsNav from './sidebar/SearchResultsNav';
|
||||
import BooknotesNav from './sidebar/BooknotesNav';
|
||||
import FoliateViewer from './FoliateViewer';
|
||||
import SectionInfo from './SectionInfo';
|
||||
import HeaderBar from './HeaderBar';
|
||||
@@ -200,6 +201,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
|
||||
)}
|
||||
<Annotator bookKey={bookKey} />
|
||||
<SearchResultsNav bookKey={bookKey} gridInsets={gridInsets} />
|
||||
<BooknotesNav bookKey={bookKey} gridInsets={gridInsets} toc={bookDoc.toc || []} />
|
||||
<FootnotePopup bookKey={bookKey} bookDoc={bookDoc} />
|
||||
<FooterBar
|
||||
bookKey={bookKey}
|
||||
|
||||
@@ -62,7 +62,7 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
const windowButtonVisible = appService?.hasWindowBar && !isTrafficLightVisible;
|
||||
|
||||
const docs = view?.renderer.getContents() ?? [];
|
||||
const pointerInDoc = docs.some(({ doc }) => doc.body?.style.cursor === 'pointer');
|
||||
const pointerInDoc = docs.some(({ doc }) => doc?.body?.style.cursor === 'pointer');
|
||||
|
||||
const enableAnnotationQuickActions = viewSettings?.enableAnnotationQuickActions;
|
||||
const annotationQuickActionButton =
|
||||
|
||||
@@ -629,7 +629,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
if (convertChineseVariant && convertChineseVariant !== 'none') {
|
||||
term = runSimpleCC(term, convertChineseVariant, true);
|
||||
}
|
||||
eventDispatcher.dispatch('search', { term });
|
||||
eventDispatcher.dispatch('search-term', { term, bookKey });
|
||||
};
|
||||
|
||||
const handleDictionary = () => {
|
||||
|
||||
@@ -42,7 +42,7 @@ const FooterBar: React.FC<FooterBarProps> = ({
|
||||
const isVisible = hoveredBookKey === bookKey;
|
||||
|
||||
const docs = view?.renderer.getContents() ?? [];
|
||||
const pointerInDoc = docs.some(({ doc }) => doc.body.style.cursor === 'pointer');
|
||||
const pointerInDoc = docs.some(({ doc }) => doc?.body?.style.cursor === 'pointer');
|
||||
|
||||
const progressInfo = useMemo(
|
||||
() => (bookFormat === 'PDF' ? section : pageinfo),
|
||||
|
||||
@@ -20,9 +20,10 @@ import TextEditor, { TextEditorRef } from '@/components/TextEditor';
|
||||
interface BooknoteItemProps {
|
||||
bookKey: string;
|
||||
item: BookNote;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
const BooknoteItem: React.FC<BooknoteItemProps> = ({ bookKey, item }) => {
|
||||
const BooknoteItem: React.FC<BooknoteItemProps> = ({ bookKey, item, onClick }) => {
|
||||
const _ = useTranslation();
|
||||
const { envConfig } = useEnv();
|
||||
const { settings } = useSettingsStore();
|
||||
@@ -43,6 +44,7 @@ const BooknoteItem: React.FC<BooknoteItemProps> = ({ bookKey, item }) => {
|
||||
event.preventDefault();
|
||||
eventDispatcher.dispatch('navigate', { bookKey, cfi });
|
||||
|
||||
onClick?.();
|
||||
getView(bookKey)?.goTo(cfi);
|
||||
if (note) {
|
||||
setNotebookVisible(true);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import * as CFI from 'foliate-js/epubcfi.js';
|
||||
import { useBookDataStore } from '@/store/bookDataStore';
|
||||
import { useSidebarStore } from '@/store/sidebarStore';
|
||||
import { findTocItemBS } from '@/utils/toc';
|
||||
import { TOCItem } from '@/libs/document';
|
||||
import { BooknoteGroup, BookNoteType } from '@/types/book';
|
||||
@@ -13,7 +13,9 @@ const BooknoteView: React.FC<{
|
||||
toc: TOCItem[];
|
||||
}> = ({ type, bookKey, toc }) => {
|
||||
const { getConfig } = useBookDataStore();
|
||||
const { setActiveBooknoteType, setBooknoteResults } = useSidebarStore();
|
||||
const config = getConfig(bookKey)!;
|
||||
|
||||
const { booknotes: allNotes = [] } = config;
|
||||
const booknotes = allNotes.filter((note) => note.type === type && !note.deletedAt);
|
||||
|
||||
@@ -39,6 +41,14 @@ const BooknoteView: React.FC<{
|
||||
return a.id - b.id;
|
||||
});
|
||||
|
||||
const handleBrowseBookNotes = () => {
|
||||
if (booknotes.length === 0) return;
|
||||
|
||||
const sorted = [...booknotes].sort((a, b) => CFI.compare(a.cfi, b.cfi));
|
||||
setActiveBooknoteType(bookKey, type);
|
||||
setBooknoteResults(bookKey, sorted);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='rounded pt-2'>
|
||||
<ul role='tree' className='px-2'>
|
||||
@@ -47,7 +57,12 @@ const BooknoteView: React.FC<{
|
||||
<h3 className='content font-size-base line-clamp-1 font-normal'>{group.label}</h3>
|
||||
<ul>
|
||||
{group.booknotes.map((item, index) => (
|
||||
<BooknoteItem key={`${index}-${item.cfi}`} bookKey={bookKey} item={item} />
|
||||
<BooknoteItem
|
||||
key={`${index}-${item.cfi}`}
|
||||
bookKey={bookKey}
|
||||
item={item}
|
||||
onClick={handleBrowseBookNotes}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Insets } from '@/types/misc';
|
||||
import { TOCItem } from '@/libs/document';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { useBooknotesNav } from '../../hooks/useBooknotesNav';
|
||||
import ContentNavBar from './ContentNavBar';
|
||||
|
||||
interface BooknotesNavProps {
|
||||
bookKey: string;
|
||||
gridInsets: Insets;
|
||||
toc: TOCItem[];
|
||||
}
|
||||
|
||||
const BooknotesNav: React.FC<BooknotesNavProps> = ({ bookKey, gridInsets, toc }) => {
|
||||
const {
|
||||
activeBooknoteType,
|
||||
currentSection,
|
||||
showBooknotesNav,
|
||||
hasPreviousPage,
|
||||
hasNextPage,
|
||||
handleShowResults,
|
||||
handleClose,
|
||||
handlePrevious,
|
||||
handleNext,
|
||||
} = useBooknotesNav(bookKey, toc);
|
||||
const _ = useTranslation();
|
||||
|
||||
if (!showBooknotesNav) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const getShowResultsTitle = () => {
|
||||
switch (activeBooknoteType) {
|
||||
case 'bookmark':
|
||||
return _('Bookmarks');
|
||||
case 'annotation':
|
||||
return _('Annotations');
|
||||
case 'excerpt':
|
||||
return _('Excerpts');
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ContentNavBar
|
||||
bookKey={bookKey}
|
||||
gridInsets={gridInsets}
|
||||
title={getShowResultsTitle()}
|
||||
section={currentSection}
|
||||
hasPrevious={hasPreviousPage}
|
||||
hasNext={hasNextPage}
|
||||
previousTitle={_('Previous')}
|
||||
nextTitle={_('Next')}
|
||||
showResultsTitle={getShowResultsTitle()}
|
||||
closeTitle={_('Close')}
|
||||
onShowResults={handleShowResults}
|
||||
onClose={handleClose}
|
||||
onPrevious={handlePrevious}
|
||||
onNext={handleNext}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default BooknotesNav;
|
||||
@@ -0,0 +1,133 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { IoIosList, IoMdCloseCircle } from 'react-icons/io';
|
||||
import { HiArrowLongLeft, HiArrowLongRight } from 'react-icons/hi2';
|
||||
|
||||
import { Insets } from '@/types/misc';
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
|
||||
import { useReaderStore } from '@/store/readerStore';
|
||||
|
||||
interface ContentNavBarProps {
|
||||
bookKey: string;
|
||||
gridInsets: Insets;
|
||||
title: string;
|
||||
section?: string;
|
||||
showListButton?: boolean;
|
||||
hasPrevious: boolean;
|
||||
hasNext: boolean;
|
||||
previousLabel?: string;
|
||||
nextLabel?: string;
|
||||
previousTitle?: string;
|
||||
nextTitle?: string;
|
||||
showResultsTitle?: string;
|
||||
closeTitle?: string;
|
||||
onShowResults?: () => void;
|
||||
onClose: () => void;
|
||||
onPrevious: () => void;
|
||||
onNext: () => void;
|
||||
}
|
||||
|
||||
const ContentNavBar: React.FC<ContentNavBarProps> = ({
|
||||
bookKey,
|
||||
gridInsets,
|
||||
title,
|
||||
section,
|
||||
showListButton = true,
|
||||
hasPrevious,
|
||||
hasNext,
|
||||
previousLabel,
|
||||
nextLabel,
|
||||
previousTitle,
|
||||
nextTitle,
|
||||
showResultsTitle,
|
||||
closeTitle,
|
||||
onShowResults,
|
||||
onClose,
|
||||
onPrevious,
|
||||
onNext,
|
||||
}) => {
|
||||
const { appService } = useEnv();
|
||||
const _ = useTranslation();
|
||||
const { getViewSettings } = useReaderStore();
|
||||
const viewSettings = getViewSettings(bookKey);
|
||||
const iconSize16 = useResponsiveSize(16);
|
||||
const iconSize18 = useResponsiveSize(18);
|
||||
const iconSize20 = useResponsiveSize(20);
|
||||
|
||||
const showSection = appService?.isMobile || !viewSettings?.showHeader;
|
||||
|
||||
return (
|
||||
<div
|
||||
className='results-nav-bar pointer-events-none absolute inset-0 z-30 flex flex-col items-center justify-between px-4 py-1'
|
||||
style={{
|
||||
top: gridInsets.top,
|
||||
right: gridInsets.right,
|
||||
bottom: gridInsets.bottom / 4,
|
||||
left: gridInsets.left,
|
||||
}}
|
||||
>
|
||||
{/* Top bar: Info */}
|
||||
<div className='bg-base-200 pointer-events-auto flex items-center justify-between rounded-xl px-4 py-1 shadow-lg sm:gap-6'>
|
||||
{showListButton && onShowResults ? (
|
||||
<button
|
||||
title={showResultsTitle || _('Show Results')}
|
||||
onClick={onShowResults}
|
||||
className='btn btn-ghost h-8 min-h-8 w-8 p-0 hover:bg-transparent'
|
||||
>
|
||||
<IoIosList size={iconSize20} className='text-base-content' />
|
||||
</button>
|
||||
) : (
|
||||
<div className='w-8' />
|
||||
)}
|
||||
|
||||
<div className='flex flex-1 flex-col items-center px-2'>
|
||||
<span className='line-clamp-1 text-sm font-medium'>{title}</span>
|
||||
{section && showSection && (
|
||||
<span className='text-base-content/70 line-clamp-1 text-xs'>{section}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
title={closeTitle || _('Close')}
|
||||
onClick={onClose}
|
||||
className='btn btn-ghost h-8 min-h-8 w-8 p-0 hover:bg-transparent'
|
||||
>
|
||||
<IoMdCloseCircle size={iconSize16} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Bottom bar: Navigation buttons */}
|
||||
<div className='bg-base-200 pointer-events-auto flex items-center justify-between gap-6 rounded-xl px-4 py-0 shadow-lg'>
|
||||
<button
|
||||
title={previousTitle || _('Previous')}
|
||||
onClick={onPrevious}
|
||||
disabled={!hasPrevious}
|
||||
className={clsx(
|
||||
'btn btn-ghost flex h-auto min-h-0 flex-1 flex-col items-center gap-0 p-1 hover:bg-transparent',
|
||||
!hasPrevious && 'opacity-40 disabled:bg-transparent',
|
||||
)}
|
||||
>
|
||||
<HiArrowLongLeft size={iconSize18} className='text-base-content' />
|
||||
<span className='text-sm font-medium'>{previousLabel || _('Previous')}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
title={nextTitle || _('Next')}
|
||||
onClick={onNext}
|
||||
disabled={!hasNext}
|
||||
className={clsx(
|
||||
'btn btn-ghost flex h-auto min-h-0 flex-1 flex-col items-center gap-0 p-1 hover:bg-transparent',
|
||||
!hasNext && 'opacity-40 disabled:bg-transparent',
|
||||
)}
|
||||
>
|
||||
<HiArrowLongRight size={iconSize18} className='text-base-content' />
|
||||
<span className='text-sm font-medium'>{nextLabel || _('Next')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContentNavBar;
|
||||
@@ -32,7 +32,9 @@ const SearchBar: React.FC<SearchBarProps> = ({ isVisible, bookKey, onHideSearchB
|
||||
const { getBookData } = useBookDataStore();
|
||||
const { getConfig, saveConfig } = useBookDataStore();
|
||||
const { getView, getProgress } = useReaderStore();
|
||||
const { searchTerm, setSearchTerm, setSearchResults } = useSidebarStore();
|
||||
const { getSearchNavState, setSearchTerm, setSearchResults } = useSidebarStore();
|
||||
const searchNavState = getSearchNavState(bookKey);
|
||||
const { searchTerm } = searchNavState;
|
||||
const queuedSearchTerm = useRef('');
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const inputFocusedRef = useRef(false);
|
||||
@@ -50,7 +52,7 @@ const SearchBar: React.FC<SearchBarProps> = ({ isVisible, bookKey, onHideSearchB
|
||||
useEffect(() => {
|
||||
handleSearchTermChange(searchTerm);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [bookKey]);
|
||||
}, [bookKey, searchTerm]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible && inputRef.current) {
|
||||
@@ -86,7 +88,7 @@ const SearchBar: React.FC<SearchBarProps> = ({ isVisible, bookKey, onHideSearchB
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
setSearchTerm(value);
|
||||
setSearchTerm(bookKey, value);
|
||||
handleSearchTermChange(value);
|
||||
queuedSearchTerm.current = value;
|
||||
};
|
||||
@@ -125,7 +127,7 @@ const SearchBar: React.FC<SearchBarProps> = ({ isVisible, bookKey, onHideSearchB
|
||||
for await (const result of generator) {
|
||||
if (typeof result === 'string') {
|
||||
if (result === 'done') {
|
||||
setSearchResults([...results]);
|
||||
setSearchResults(bookKey, [...results]);
|
||||
console.log('search done');
|
||||
}
|
||||
} else {
|
||||
@@ -142,7 +144,7 @@ const SearchBar: React.FC<SearchBarProps> = ({ isVisible, bookKey, onHideSearchB
|
||||
}
|
||||
} else {
|
||||
results.push(result);
|
||||
setSearchResults([...results]);
|
||||
setSearchResults(bookKey, [...results]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,9 +159,9 @@ const SearchBar: React.FC<SearchBarProps> = ({ isVisible, bookKey, onHideSearchB
|
||||
);
|
||||
|
||||
const resetSearch = useCallback(() => {
|
||||
setSearchResults([]);
|
||||
setSearchResults(bookKey, []);
|
||||
view?.clearSearch();
|
||||
}, [view, setSearchResults]);
|
||||
}, [bookKey, view, setSearchResults]);
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const handleSearchTermChange = useCallback(
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { IoIosList, IoMdCloseCircle } from 'react-icons/io';
|
||||
import { HiArrowLongLeft, HiArrowLongRight } from 'react-icons/hi2';
|
||||
|
||||
import { Insets } from '@/types/misc';
|
||||
import { BookSearchMatch, BookSearchResult } from '@/types/book';
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
|
||||
import { useSearchNav } from '../../hooks/useSearchNav';
|
||||
import { useReaderStore } from '@/store/readerStore';
|
||||
import ContentNavBar from './ContentNavBar';
|
||||
|
||||
interface SearchResultsNavProps {
|
||||
bookKey: string;
|
||||
@@ -28,87 +23,29 @@ const SearchResultsNav: React.FC<SearchResultsNavProps> = ({ bookKey, gridInsets
|
||||
handlePreviousResult,
|
||||
handleNextResult,
|
||||
} = useSearchNav(bookKey);
|
||||
const { appService } = useEnv();
|
||||
const _ = useTranslation();
|
||||
const { getViewSettings } = useReaderStore();
|
||||
const viewSettings = getViewSettings(bookKey);
|
||||
const iconSize16 = useResponsiveSize(16);
|
||||
const iconSize18 = useResponsiveSize(18);
|
||||
const iconSize20 = useResponsiveSize(20);
|
||||
|
||||
if (!showSearchNav) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const showSection = appService?.isMobile || !viewSettings?.showHeader;
|
||||
|
||||
return (
|
||||
<div
|
||||
className='search-results-nav pointer-events-none absolute inset-0 z-30 flex flex-col items-center justify-between px-4 py-1'
|
||||
style={{
|
||||
top: gridInsets.top,
|
||||
right: gridInsets.right,
|
||||
bottom: gridInsets.bottom / 4,
|
||||
left: gridInsets.left,
|
||||
}}
|
||||
>
|
||||
{/* Top bar: Search info */}
|
||||
<div className='bg-base-200/95 pointer-events-auto flex items-center justify-between rounded-xl px-4 py-1 shadow-lg backdrop-blur-sm sm:gap-6'>
|
||||
<button
|
||||
title={_('Show Search Results')}
|
||||
onClick={handleShowResults}
|
||||
className='btn btn-ghost h-8 min-h-8 w-8 p-0 hover:bg-transparent'
|
||||
>
|
||||
<IoIosList size={iconSize20} className='text-base-content' />
|
||||
</button>
|
||||
|
||||
<div className='flex flex-1 flex-col items-center px-2'>
|
||||
<span className='line-clamp-1 text-sm font-medium'>
|
||||
{_("Search results for '{{term}}'", { term: searchTerm })}
|
||||
</span>
|
||||
{currentSection && showSection && (
|
||||
<span className='text-base-content/70 line-clamp-1 text-xs'>{currentSection}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
title={_('Close Search')}
|
||||
onClick={handleCloseSearch}
|
||||
className='btn btn-ghost h-8 min-h-8 w-8 p-0 hover:bg-transparent'
|
||||
>
|
||||
<IoMdCloseCircle size={iconSize16} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Bottom bar: Navigation buttons */}
|
||||
<div className='bg-base-200/95 pointer-events-auto flex items-center justify-between gap-6 rounded-xl px-4 py-0 shadow-lg backdrop-blur-sm'>
|
||||
<button
|
||||
title={_('Previous Result')}
|
||||
onClick={handlePreviousResult}
|
||||
disabled={!hasPreviousPage}
|
||||
className={clsx(
|
||||
'btn btn-ghost flex h-auto min-h-0 flex-1 flex-col items-center gap-0 p-1 hover:bg-transparent',
|
||||
!hasPreviousPage && 'opacity-40',
|
||||
)}
|
||||
>
|
||||
<HiArrowLongLeft size={iconSize18} className='text-base-content' />
|
||||
<span className='text-sm font-medium'>{_('Previous')}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
title={_('Next Result')}
|
||||
onClick={handleNextResult}
|
||||
disabled={!hasNextPage}
|
||||
className={clsx(
|
||||
'btn btn-ghost flex h-auto min-h-0 flex-1 flex-col items-center gap-0 p-1 hover:bg-transparent',
|
||||
!hasNextPage && 'opacity-40',
|
||||
)}
|
||||
>
|
||||
<HiArrowLongRight size={iconSize18} className='text-base-content' />
|
||||
<span className='text-sm font-medium'>{_('Next')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ContentNavBar
|
||||
bookKey={bookKey}
|
||||
gridInsets={gridInsets}
|
||||
title={_("Search results for '{{term}}'", { term: searchTerm })}
|
||||
section={currentSection}
|
||||
hasPrevious={hasPreviousPage}
|
||||
hasNext={hasNextPage}
|
||||
previousTitle={_('Previous Result')}
|
||||
nextTitle={_('Next Result')}
|
||||
showResultsTitle={_('Show Search Results')}
|
||||
closeTitle={_('Close Search')}
|
||||
onShowResults={handleShowResults}
|
||||
onClose={handleCloseSearch}
|
||||
onPrevious={handlePreviousResult}
|
||||
onNext={handleNextResult}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -33,8 +33,10 @@ const SideBar: React.FC<{
|
||||
const { appService } = useEnv();
|
||||
const { updateAppTheme, safeAreaInsets } = useThemeStore();
|
||||
const { settings } = useSettingsStore();
|
||||
const { sideBarBookKey, searchTerm, searchResults, setSearchTerm, clearSearch } =
|
||||
const { sideBarBookKey, setSideBarBookKey, getSearchNavState, setSearchTerm, clearSearch } =
|
||||
useSidebarStore();
|
||||
const searchNavState = sideBarBookKey ? getSearchNavState(sideBarBookKey) : null;
|
||||
const { searchTerm = '', searchResults = null } = searchNavState || {};
|
||||
const { getBookData } = useBookDataStore();
|
||||
const { getView, getViewSettings } = useReaderStore();
|
||||
const [isSearchBarVisible, setIsSearchBarVisible] = useState(false);
|
||||
@@ -55,11 +57,12 @@ const SideBar: React.FC<{
|
||||
);
|
||||
|
||||
const onSearchEvent = async (event: CustomEvent) => {
|
||||
const { term } = event.detail;
|
||||
const { term, bookKey } = event.detail;
|
||||
setSideBarVisible(true);
|
||||
setSideBarBookKey(bookKey);
|
||||
setIsSearchBarVisible(true);
|
||||
if (term !== undefined && term !== null) {
|
||||
setSearchTerm(term);
|
||||
setSearchTerm(bookKey, term);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -85,10 +88,10 @@ const SideBar: React.FC<{
|
||||
}, [searchTerm]);
|
||||
|
||||
useEffect(() => {
|
||||
eventDispatcher.on('search', onSearchEvent);
|
||||
eventDispatcher.on('search-term', onSearchEvent);
|
||||
eventDispatcher.on('navigate', onNavigateEvent);
|
||||
return () => {
|
||||
eventDispatcher.off('search', onSearchEvent);
|
||||
eventDispatcher.off('search-term', onSearchEvent);
|
||||
eventDispatcher.off('navigate', onNavigateEvent);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -192,7 +195,7 @@ const SideBar: React.FC<{
|
||||
const handleHideSearchBar = useCallback(() => {
|
||||
setIsSearchBarVisible(false);
|
||||
setTimeout(() => {
|
||||
clearSearch();
|
||||
if (sideBarBookKey) clearSearch(sideBarBookKey);
|
||||
}, 100);
|
||||
getView(sideBarBookKey)?.clearSearch();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
Reference in New Issue
Block a user