diff --git a/apps/readest-app/src/app/reader/components/sidebar/Content.tsx b/apps/readest-app/src/app/reader/components/sidebar/Content.tsx
index 4fc086d4..8923551b 100644
--- a/apps/readest-app/src/app/reader/components/sidebar/Content.tsx
+++ b/apps/readest-app/src/app/reader/components/sidebar/Content.tsx
@@ -73,7 +73,7 @@ const SidebarContent: React.FC<{
})}
>
{targetTab === 'toc' && bookDoc.toc && (
-
+
)}
{targetTab === 'annotations' && (
diff --git a/apps/readest-app/src/app/reader/components/sidebar/SideBar.tsx b/apps/readest-app/src/app/reader/components/sidebar/SideBar.tsx
index 3f36d30c..db3bbcac 100644
--- a/apps/readest-app/src/app/reader/components/sidebar/SideBar.tsx
+++ b/apps/readest-app/src/app/reader/components/sidebar/SideBar.tsx
@@ -293,7 +293,7 @@ const SideBar: React.FC<{
)}
) => {
const TOCView: React.FC<{
bookKey: string;
toc: TOCItem[];
-}> = ({ bookKey, toc }) => {
+ sections?: SectionItem[];
+}> = ({ bookKey, toc, sections }) => {
const { appService } = useEnv();
const { getView, getProgress, getViewState, getViewSettings } = useReaderStore();
const { sideBarBookKey, isSideBarVisible } = useSidebarStore();
@@ -183,7 +184,7 @@ const TOCView: React.FC<{
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [activeHref]);
+ }, [flatItems, activeHref]);
const virtualItemSize = useMemo(() => {
return window.innerWidth >= 640 && !viewSettings?.translationEnabled ? 37 : 57;
@@ -214,12 +215,12 @@ const TOCView: React.FC<{
useEffect(() => {
if (flatItems.length > 0) {
- setTimeout(scrollToActiveItem, appService?.isAndroidApp ? 300 : 0);
+ setTimeout(scrollToActiveItem, appService?.isAndroidApp ? 300 : 100);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [scrollToActiveItem]);
+ }, [progress]);
- return flatItems.length > 256 ? (
+ return sections && sections.length > 256 ? (
((set, get) => ({
const primaryLanguage = getPrimaryLanguage(bookDoc.metadata.language);
book.primaryLanguage = book.primaryLanguage ?? primaryLanguage;
book.metadata = book.metadata ?? bookDoc.metadata;
- book.metaHash = book.metaHash ?? getMetadataHash(bookDoc.metadata);
+ // TODO: uncomment this when we can ensure metaHash is correctly generated for all books
+ // book.metaHash = book.metaHash ?? getMetadataHash(bookDoc.metadata);
+ book.metaHash = getMetadataHash(bookDoc.metadata);
const isFixedLayout = FIXED_LAYOUT_FORMATS.has(book.format);
useBookDataStore.setState((state) => ({
diff --git a/apps/readest-app/src/utils/book.ts b/apps/readest-app/src/utils/book.ts
index c86c0d58..525e6562 100644
--- a/apps/readest-app/src/utils/book.ts
+++ b/apps/readest-app/src/utils/book.ts
@@ -220,9 +220,13 @@ const getTitleForHash = (title: string | LanguageMap) => {
const getAuthorsList = (contributors: string | string[] | Contributor | Contributor[]) => {
if (!contributors) return [];
return Array.isArray(contributors)
- ? contributors.map((contributor) =>
- typeof contributor === 'string' ? contributor : formatLanguageMap(contributor?.name, true),
- )
+ ? contributors
+ .map((contributor) =>
+ typeof contributor === 'string'
+ ? contributor
+ : formatLanguageMap(contributor?.name, true),
+ )
+ .filter(Boolean)
: [
typeof contributors === 'string'
? contributors
@@ -231,12 +235,16 @@ const getAuthorsList = (contributors: string | string[] | Contributor | Contribu
};
const normalizeIdentifier = (identifier: string) => {
- if (identifier.includes('urn:')) {
- // Slice after the last ':'
- return identifier.match(/[^:]+$/)![0];
- } else if (identifier.includes(':')) {
- // Slice after the first ':'
- return identifier.match(/^[^:]+:(.+)$/)![1];
+ try {
+ if (identifier.includes('urn:')) {
+ // Slice after the last ':'
+ return identifier.match(/[^:]+$/)?.[0] || '';
+ } else if (identifier.includes(':')) {
+ // Slice after the first ':'
+ return identifier.match(/^[^:]+:(.+)$/)?.[1] || '';
+ }
+ } catch {
+ return identifier;
}
return identifier;
};
@@ -246,9 +254,11 @@ const getIdentifiersList = (
) => {
if (!identifiers) return [];
return Array.isArray(identifiers)
- ? identifiers.map((identifier) =>
- typeof identifier === 'string' ? normalizeIdentifier(identifier) : identifier.value,
- )
+ ? identifiers
+ .map((identifier) =>
+ typeof identifier === 'string' ? normalizeIdentifier(identifier) : identifier.value,
+ )
+ .filter(Boolean)
: typeof identifiers === 'string'
? [normalizeIdentifier(identifiers)]
: [identifiers.value];