@edrlab/thorium-web 1.5.4 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ThPreferencesAdapter-B3a-f5v-.d.mts → ThPreferencesAdapter-GepvYoaL.d.mts} +4 -3
- package/dist/{ThSettingsWrapper-D4WIzlXA.d.mts → ThSettingsWrapper-DyYC678Q.d.mts} +1 -1
- package/dist/{actions-C33UN3Ji.d.mts → actions-CTg9C4C-.d.mts} +1 -1
- package/dist/{actionsReducer-Bzcj3wk3.d.mts → actionsReducer-Cnd7Cdh9.d.mts} +1 -1
- package/dist/{chunk-VYSDLACR.mjs → chunk-3R5JARA2.mjs} +3 -3
- package/dist/{chunk-VYSDLACR.mjs.map → chunk-3R5JARA2.mjs.map} +1 -1
- package/dist/{chunk-X6Z4WZLX.mjs → chunk-5IT53TCU.mjs} +55 -35
- package/dist/chunk-5IT53TCU.mjs.map +1 -0
- package/dist/{chunk-7WGC22F3.mjs → chunk-6DR4EAK3.mjs} +42 -49
- package/dist/chunk-6DR4EAK3.mjs.map +1 -0
- package/dist/chunk-7SMOXFAF.mjs +121 -0
- package/dist/chunk-7SMOXFAF.mjs.map +1 -0
- package/dist/{chunk-AEEGHJVM.mjs → chunk-CXKDZVAV.mjs} +113 -258
- package/dist/chunk-CXKDZVAV.mjs.map +1 -0
- package/dist/{chunk-MD5LZNDG.mjs → chunk-DKF53WEQ.mjs} +39 -16
- package/dist/chunk-DKF53WEQ.mjs.map +1 -0
- package/dist/{chunk-GFSLVQIG.mjs → chunk-EREFYF5J.mjs} +3 -3
- package/dist/{chunk-GFSLVQIG.mjs.map → chunk-EREFYF5J.mjs.map} +1 -1
- package/dist/{chunk-YE5QOQUT.mjs → chunk-I765HTBI.mjs} +15 -109
- package/dist/chunk-I765HTBI.mjs.map +1 -0
- package/dist/{chunk-G4T4RXFB.mjs → chunk-LF6IMH7J.mjs} +83 -70
- package/dist/chunk-LF6IMH7J.mjs.map +1 -0
- package/dist/{chunk-NQ2ZSGCX.mjs → chunk-MFVZ5AEN.mjs} +7 -3
- package/dist/chunk-MFVZ5AEN.mjs.map +1 -0
- package/dist/{chunk-2YRT7RNW.mjs → chunk-QOU3R5ZT.mjs} +9 -3
- package/dist/chunk-QOU3R5ZT.mjs.map +1 -0
- package/dist/{chunk-G35H3K32.mjs → chunk-VWKUZP5V.mjs} +43 -48
- package/dist/chunk-VWKUZP5V.mjs.map +1 -0
- package/dist/{chunk-IVCUCIYN.mjs → chunk-WOJR6ALR.mjs} +41 -18
- package/dist/chunk-WOJR6ALR.mjs.map +1 -0
- package/dist/components/Audio/index.css +1 -0
- package/dist/components/Audio/index.css.map +1 -1
- package/dist/components/Audio/index.d.mts +13 -13
- package/dist/components/Audio/index.mjs +10 -11
- package/dist/components/Epub/index.d.mts +13 -13
- package/dist/components/Epub/index.mjs +11 -12
- package/dist/components/Reader/index.css +1 -0
- package/dist/components/Reader/index.css.map +1 -1
- package/dist/components/Reader/index.d.mts +12 -12
- package/dist/components/Reader/index.mjs +18 -18
- package/dist/components/Reader/index.mjs.map +1 -1
- package/dist/components/WebPub/index.d.mts +13 -13
- package/dist/components/WebPub/index.mjs +11 -12
- package/dist/core/Components/index.d.mts +6 -6
- package/dist/core/Helpers/index.d.mts +4 -4
- package/dist/core/Helpers/index.mjs +2 -2
- package/dist/core/Hooks/index.d.mts +14 -9
- package/dist/core/Hooks/index.mjs +4 -4
- package/dist/lib/index.d.mts +43 -33
- package/dist/lib/index.mjs +3 -4
- package/dist/locales/ar/thorium-shared.json +39 -0
- package/dist/locales/bg/thorium-web.json +23 -0
- package/dist/locales/brh/thorium-shared.json +1 -0
- package/dist/locales/brh/thorium-web.json +1 -0
- package/dist/locales/da/thorium-shared.json +3 -0
- package/dist/locales/el/thorium-web.json +41 -6
- package/dist/locales/en/thorium-shared.json +3 -0
- package/dist/locales/es/thorium-shared.json +3 -0
- package/dist/locales/et/thorium-shared.json +3 -0
- package/dist/locales/fi/thorium-shared.json +3 -0
- package/dist/locales/fi/thorium-web.json +4 -4
- package/dist/locales/he/thorium-shared.json +3 -1
- package/dist/locales/it/thorium-shared.json +3 -0
- package/dist/locales/lt/thorium-shared.json +30 -4
- package/dist/locales/pt-PT/thorium-shared.json +8 -5
- package/dist/locales/sv/thorium-shared.json +3 -3
- package/dist/locales/sv/thorium-web.json +7 -7
- package/dist/locales/tr/thorium-shared.json +80 -0
- package/dist/preferences/index.d.mts +10 -10
- package/dist/preferences/index.mjs +4 -5
- package/dist/{settingsReducer-Pp9aoiiC.d.mts → settingsReducer-DRWEq8Cm.d.mts} +1 -1
- package/dist/{ui-DnZZhozX.d.mts → ui-DHQ_zvWn.d.mts} +7 -1
- package/dist/{useAudioNavigator-9RuOpLGB.d.mts → useAudioNavigator-B4NBPvmZ.d.mts} +4 -5
- package/dist/{useContrast-Bl08zDTU.d.mts → useContrast-Unp3534Z.d.mts} +1 -1
- package/dist/{usePreferences-Cy7-JN2x.d.mts → usePreferences-Bi-ptif0.d.mts} +6 -9
- package/dist/usePublicationProgress-DT-X5ZLf.d.mts +44 -0
- package/dist/{useReaderTransitions-BsTdWZDK.d.mts → useReaderTransitions-B9fOF61y.d.mts} +10 -14
- package/package.json +13 -10
- package/dist/chunk-2YRT7RNW.mjs.map +0 -1
- package/dist/chunk-7WGC22F3.mjs.map +0 -1
- package/dist/chunk-A575ZW4A.mjs +0 -10
- package/dist/chunk-A575ZW4A.mjs.map +0 -1
- package/dist/chunk-AEEGHJVM.mjs.map +0 -1
- package/dist/chunk-G35H3K32.mjs.map +0 -1
- package/dist/chunk-G4T4RXFB.mjs.map +0 -1
- package/dist/chunk-IVCUCIYN.mjs.map +0 -1
- package/dist/chunk-MD5LZNDG.mjs.map +0 -1
- package/dist/chunk-NQ2ZSGCX.mjs.map +0 -1
- package/dist/chunk-TEZB4ULX.mjs +0 -57
- package/dist/chunk-TEZB4ULX.mjs.map +0 -1
- package/dist/chunk-X6Z4WZLX.mjs.map +0 -1
- package/dist/chunk-YE5QOQUT.mjs.map +0 -1
- package/dist/useTimeline-DCZ1qoCO.d.mts +0 -55
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect } from 'react';
|
|
2
|
+
import { useDispatch, useSelector, useStore } from 'react-redux';
|
|
2
3
|
|
|
3
4
|
// src/core/Hooks/useMediaQuery.ts
|
|
4
5
|
var useMediaQuery = (query) => {
|
|
@@ -64,7 +65,10 @@ var useContrast = (onChange) => {
|
|
|
64
65
|
}, [onChange, prefersNoContrast, prefersLessContrast, prefersMoreContrast, prefersCustomContrast]);
|
|
65
66
|
return contrast;
|
|
66
67
|
};
|
|
68
|
+
var useAppDispatch = useDispatch;
|
|
69
|
+
var useAppSelector = useSelector;
|
|
70
|
+
var useAppStore = useStore;
|
|
67
71
|
|
|
68
|
-
export { ThColorScheme, ThContrast, useColorScheme, useContrast, useMediaQuery };
|
|
69
|
-
//# sourceMappingURL=chunk-
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
72
|
+
export { ThColorScheme, ThContrast, useAppDispatch, useAppSelector, useAppStore, useColorScheme, useContrast, useMediaQuery };
|
|
73
|
+
//# sourceMappingURL=chunk-MFVZ5AEN.mjs.map
|
|
74
|
+
//# sourceMappingURL=chunk-MFVZ5AEN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/Hooks/useMediaQuery.ts","../src/core/Hooks/useColorScheme.ts","../src/core/Hooks/useContrast.ts","../src/lib/hooks.ts"],"names":["ThColorScheme","useState","useEffect","ThContrast"],"mappings":"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","file":"chunk-MFVZ5AEN.mjs","sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nexport const useMediaQuery = (query: string | null) => {\n const [matches, setMatches] = useState(false);\n\n useEffect(() => {\n if (!query) return;\n\n const mq = window.matchMedia(query);\n\n // Checking if media query is supported or well-formed\n // The media property is the normalized and resolved string representation of the query. \n // If matchMedia encounters something it doesn’t understand, that changes to \"not all\"\n const resolvedMediaQuery = mq.media;\n if (query !== resolvedMediaQuery) {\n console.error(\"Either this query is not supported or not well formed. Please double-check.\");\n return;\n };\n\n if (mq.matches !== matches) {\n setMatches(mq.matches);\n }\n\n const handleMatch = () => setMatches(mq.matches);\n mq.addEventListener(\"change\", handleMatch);\n\n return () => mq.removeEventListener(\"change\", handleMatch);\n }, [matches, query]);\n\n return matches;\n}","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useMediaQuery } from \"./useMediaQuery\";\n\nexport enum ThColorScheme {\n light = \"light\",\n dark = \"dark\"\n}\n\nexport const useColorScheme = (onChange?: (colorScheme: ThColorScheme) => void) => {\n const [colorScheme, setColorScheme] = useState(ThColorScheme.light);\n const prefersDarkMode = useMediaQuery(\"(prefers-color-scheme: dark)\");\n\n useEffect(() => {\n const scheme = prefersDarkMode ? ThColorScheme.dark : ThColorScheme.light;\n setColorScheme(scheme);\n onChange && onChange(scheme);\n }, [onChange, prefersDarkMode]);\n\n return colorScheme;\n}","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useMediaQuery } from \"./useMediaQuery\";\n\nexport enum ThContrast {\n none = \"no-preference\",\n more = \"more\",\n less = \"less\",\n custom = \"custom\"\n}\n\nexport const useContrast = (onChange?: (contrast: ThContrast) => void) => {\n const [contrast, setContrast] = useState(ThContrast.none);\n\n const prefersNoContrast = useMediaQuery(`(prefers-contrast: ${ ThContrast.none })`);\n const prefersLessContrast = useMediaQuery(`(prefers-contrast: ${ ThContrast.less })`);\n const prefersMoreContrast = useMediaQuery(`(prefers-contrast: ${ ThContrast.more })`);\n const prefersCustomContrast = useMediaQuery(`(prefers-contrast: ${ ThContrast.custom })`);\n\n useEffect(() => {\n let newContrast: ThContrast = ThContrast.none;\n if (prefersNoContrast) {\n newContrast = ThContrast.none;\n } else if (prefersLessContrast) {\n newContrast = ThContrast.less;\n } else if (prefersMoreContrast) {\n newContrast = ThContrast.more;\n } else if (prefersCustomContrast) {\n newContrast = ThContrast.custom;\n }\n setContrast(newContrast);\n onChange && onChange(newContrast);\n }, [onChange, prefersNoContrast, prefersLessContrast, prefersMoreContrast, prefersCustomContrast]);\n\n return contrast;\n}","import { TypedUseSelectorHook, useDispatch, useSelector, useStore } from \"react-redux\";\nimport type { AppDispatch, AppStore, RootState } from \"./store\";\n\n// Use throughout your app instead of plain `useDispatch` and `useSelector`\nexport const useAppDispatch: () => AppDispatch = useDispatch;\nexport const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;\nexport const useAppStore: () => AppStore = useStore;"]}
|
|
@@ -5,6 +5,12 @@ var ThArrowVariant = /* @__PURE__ */ ((ThArrowVariant2) => {
|
|
|
5
5
|
ThArrowVariant2["layered"] = "layered";
|
|
6
6
|
return ThArrowVariant2;
|
|
7
7
|
})(ThArrowVariant || {});
|
|
8
|
+
var ThNavigationAffordance = /* @__PURE__ */ ((ThNavigationAffordance2) => {
|
|
9
|
+
ThNavigationAffordance2["timeline"] = "timeline";
|
|
10
|
+
ThNavigationAffordance2["readingOrder"] = "readingOrder";
|
|
11
|
+
ThNavigationAffordance2["toc"] = "toc";
|
|
12
|
+
return ThNavigationAffordance2;
|
|
13
|
+
})(ThNavigationAffordance || {});
|
|
8
14
|
var ThBreakpoints = /* @__PURE__ */ ((ThBreakpoints2) => {
|
|
9
15
|
ThBreakpoints2["compact"] = "compact";
|
|
10
16
|
ThBreakpoints2["medium"] = "medium";
|
|
@@ -93,6 +99,6 @@ var propsToCSSVars = (props, { prefix, exclude = [] } = {}) => {
|
|
|
93
99
|
}, {});
|
|
94
100
|
};
|
|
95
101
|
|
|
96
|
-
export { ThArrowVariant, ThAudioPlayerComponent, ThAudioProgressBarVariant, ThAudioPublicationMetadataComponent, ThBackLinkVariant, ThBreakpoints, ThDocumentTitleFormat, ThLayoutDirection, ThLayoutUI, ThProgressionFormat, ThRunningHeadFormat, propsToCSSVars };
|
|
97
|
-
//# sourceMappingURL=chunk-
|
|
98
|
-
//# sourceMappingURL=chunk-
|
|
102
|
+
export { ThArrowVariant, ThAudioPlayerComponent, ThAudioProgressBarVariant, ThAudioPublicationMetadataComponent, ThBackLinkVariant, ThBreakpoints, ThDocumentTitleFormat, ThLayoutDirection, ThLayoutUI, ThNavigationAffordance, ThProgressionFormat, ThRunningHeadFormat, propsToCSSVars };
|
|
103
|
+
//# sourceMappingURL=chunk-QOU3R5ZT.mjs.map
|
|
104
|
+
//# sourceMappingURL=chunk-QOU3R5ZT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/preferences/models/ui.ts","../src/core/Helpers/propsToCSSVars.ts"],"names":["ThArrowVariant","ThNavigationAffordance","ThBreakpoints","ThBackLinkVariant","ThDocumentTitleFormat","ThLayoutDirection","ThLayoutUI","ThProgressionFormat","ThRunningHeadFormat","ThAudioPlayerComponent","ThAudioProgressBarVariant","ThAudioPublicationMetadataComponent"],"mappings":"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","file":"chunk-QOU3R5ZT.mjs","sourcesContent":["export type ThBackLinkContent = \n | { \n type: \"img\";\n src: string;\n alt?: string;\n }\n | {\n type: \"svg\";\n content: string; // Raw SVG string\n };\n\nexport interface ThBackLinkPref {\n href: string;\n variant?: ThBackLinkVariant;\n visibility?: \"always\" | \"partially\";\n content?: ThBackLinkContent;\n}\n\nexport interface ThFormatPrefValue<T extends string | Array<string>> {\n variants: T;\n displayInImmersive?: boolean;\n displayInFullscreen?: boolean;\n}\n\nexport interface ThFormatPref<T extends string | Array<string>> {\n default: ThFormatPrefValue<T>;\n breakpoints?: { \n [key in ThBreakpoints]?: ThFormatPrefValue<T>;\n };\n}\n\nexport interface ThPaginatedAffordancePrefValue {\n variant: ThArrowVariant;\n discard?: Array<\"navigation\" | \"immersive\" | \"fullscreen\"> | \"none\";\n hint?: Array<\"immersiveChange\" | \"fullscreenChange\" | \"layoutChange\"> | \"none\";\n}\n\nexport interface ThPaginatedAffordancePref {\n default: Required<ThPaginatedAffordancePrefValue>;\n breakpoints?: {\n [key in ThBreakpoints]?: ThPaginatedAffordancePrefValue;\n };\n}\n\nexport enum ThArrowVariant {\n none = \"none\",\n stacked = \"stacked\",\n layered = \"layered\"\n}\n\nexport enum ThNavigationAffordance {\n timeline = \"timeline\",\n readingOrder = \"readingOrder\",\n toc = \"toc\"\n}\n\n// `toc` is excluded: a toc entry can span multiple reading-order resources,\n// so navigating strictly by toc entry can skip resources that have no toc\n// entry of their own. `timeline` already walks every reading-order resource.\nexport type ThScrollAffordance = Exclude<ThNavigationAffordance, ThNavigationAffordance.toc>;\n\nexport enum ThBreakpoints {\n compact = \"compact\",\n medium = \"medium\",\n expanded = \"expanded\",\n large = \"large\",\n xLarge = \"xLarge\"\n}\n\nexport enum ThBackLinkVariant {\n arrow = \"arrow\",\n home = \"home\",\n library = \"library\",\n custom = \"custom\"\n}\n\nexport enum ThDocumentTitleFormat {\n title = \"title\",\n chapter = \"chapter\",\n titleAndChapter = \"titleAndChapter\",\n none = \"none\"\n}\n\nexport enum ThLayoutDirection {\n rtl = \"rtl\",\n ltr = \"ltr\"\n}\n\nexport enum ThLayoutUI {\n stacked = \"stacked-ui\",\n layered = \"layered-ui\"\n}\n\nexport enum ThProgressionFormat {\n positionsPercentOfTotal = \"positionsPercentOfTotal\", // x-y of z (%)\n positionsOfTotal = \"positionsOfTotal\", // x-y of z\n positions = \"positions\", // x-y\n overallProgression = \"overallProgression\", // x%\n positionsLeft = \"positionsLeft\", // x left in chapter\n readingOrderIndex = \"readingOrderIndex\", // x of y\n resourceProgression = \"resourceProgression\", // x%\n progressionOfResource = \"progressionOfResource\", // x% of y\n none = \"none\" // nothing displayed\n}\n\nexport enum ThRunningHeadFormat {\n title = \"title\",\n chapter = \"chapter\",\n // titleAndChapter = \"titleAndChapter\",\n none = \"none\"\n}\n\nexport enum ThAudioPlayerComponent {\n cover = \"cover\",\n metadata = \"metadata\",\n playbackControls = \"playbackControls\",\n progressBar = \"progressBar\",\n mediaActions = \"mediaActions\"\n}\n\nexport enum ThAudioProgressBarVariant {\n normal = \"normal\",\n segmented = \"segmented\"\n}\n\nexport enum ThAudioPublicationMetadataComponent {\n title = \"title\",\n titleWithSubtitle = \"titleWithSubtitle\",\n subtitleWithTitle = \"subtitleWithTitle\",\n authors = \"authors\"\n}\n\ntype TitleVariant = ThAudioPublicationMetadataComponent.title | ThAudioPublicationMetadataComponent.titleWithSubtitle | ThAudioPublicationMetadataComponent.subtitleWithTitle;\n\nexport type ThPublicationMetadataOrder = [TitleVariant] | [TitleVariant, ThAudioPublicationMetadataComponent.authors] | [ThAudioPublicationMetadataComponent.authors, TitleVariant];","\"use client\";\n\ninterface PropsToCSSVarsOptions {\n prefix?: string;\n exclude?: string[];\n}\n\n/** \n * Converts Object properties to CSS custom properties, recursively.\n * @param props - The object containing CSS property values\n * @param options - Configuration options\n * @param options.prefix - Optional prefix for CSS variable names (applies to all levels)\n * @param options.exclude - Array of property names to exclude\n */\nexport const propsToCSSVars = (props: { [x: string]: any; }, { prefix, exclude = [] }: PropsToCSSVarsOptions = {}) => {\n return Object.entries(props)\n .reduce((acc: { [key: string]: any }, [key, value]) => {\n if (exclude.includes(key)) {\n return acc;\n }\n const cssVar = prefix ? `--${prefix}-${key}` : `--${key}`;\n if (typeof value === \"object\" && value !== null) {\n // Keep the same prefix for nested objects\n Object.assign(acc, propsToCSSVars(value, { prefix: prefix ? `${prefix}-${key}` : key }));\n } else if (value != null) {\n const cssValue = typeof value === \"number\" ? `${value}px` : value;\n acc[cssVar] = cssValue;\n } \n return acc;\n }, {});\n}"]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { useNavigator, StatefulActionIcon, usePlugins, ThPluginRegistry, createAudioDefaultPlugin, ThPluginProvider, useFocusedDockableKey, usePositionStorage, fromActionPeripheralType, fromDockingPeripheralType, NavigatorProvider, StatefulDockingWrapper, toActionPeripheralType, toDockingPeripheralType, useReaderHeaderBase, StatefulBackLink, thorium_web_reader_header_default, StatefulCollapsibleActionsBar, thorium_web_overflow_default } from './chunk-
|
|
2
|
-
import { useAudioNavigator, useDocumentTitle, useAudioSettingsCache } from './chunk-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { useAudioPreferences, resolveAudioContentProtectionConfig, useAudioActionsPreferences, proxyUrl } from './chunk-
|
|
6
|
-
import { useAppSelector, useAppDispatch } from './chunk-
|
|
1
|
+
import { useNavigator, StatefulActionIcon, usePlugins, ThPluginRegistry, createAudioDefaultPlugin, ThPluginProvider, useFocusedDockableKey, usePositionStorage, useTocEntryTracking, fromActionPeripheralType, fromDockingPeripheralType, useTocTreeBuilder, NavigatorProvider, StatefulDockingWrapper, toActionPeripheralType, toDockingPeripheralType, useReaderHeaderBase, StatefulBackLink, thorium_web_reader_header_default, StatefulCollapsibleActionsBar, thorium_web_overflow_default } from './chunk-LF6IMH7J.mjs';
|
|
2
|
+
import { useAudioNavigator, useDocumentTitle, useTimelineAdjacency, useAudioSettingsCache } from './chunk-CXKDZVAV.mjs';
|
|
3
|
+
import { setSleepTimerOnFragmentEnd, toggleActionOpen, dockAction, setRemotePlaybackState, setStatus, setSeekableRanges, setSeeking, setStalled, setSleepTimerOnTrackEnd, setTrackReady, debounce, setLoading } from './chunk-I765HTBI.mjs';
|
|
4
|
+
import { setPublicationStart, setPublicationEnd } from './chunk-7SMOXFAF.mjs';
|
|
5
|
+
import { useAudioPreferences, ThAudioAffordance, resolveAudioContentProtectionConfig, useAudioActionsPreferences, proxyUrl } from './chunk-6DR4EAK3.mjs';
|
|
6
|
+
import { useAppSelector, useAppDispatch } from './chunk-MFVZ5AEN.mjs';
|
|
7
7
|
import { ThActionsBar, ThAudioProgress } from './chunk-ES2Y5MC7.mjs';
|
|
8
8
|
import { useI18n } from './chunk-2NCN2AG2.mjs';
|
|
9
9
|
import { useCallback, useState, useMemo, useLayoutEffect, useRef, useEffect, Fragment as Fragment$1 } from 'react';
|
|
10
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
|
-
import {
|
|
11
|
+
import { Locator, LocatorLocations, Link } from '@readium/shared';
|
|
12
12
|
import classNames from 'classnames';
|
|
13
13
|
|
|
14
14
|
var SvgPause = (props) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 -960 960 960", width: "24px", fill: "inherit", ...props, children: /* @__PURE__ */ jsx("path", { d: "M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z" }) });
|
|
@@ -51,18 +51,18 @@ var StatefulPlayPauseButton = ({ isDisabled }) => {
|
|
|
51
51
|
var SvgSkipPrevious = (props) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24px", viewBox: "0 -960 960 960", width: "24px", fill: "inherit", ...props, children: /* @__PURE__ */ jsx("path", { d: "M220-240v-480h80v480h-80Zm520 0L380-480l360-240v480Zm-80-240Zm0 90v-180l-136 90 136 90Z" }) });
|
|
52
52
|
var skip_previous_default = SvgSkipPrevious;
|
|
53
53
|
|
|
54
|
-
// src/components/
|
|
54
|
+
// src/components/hooks/useAdjacentTocItems.ts
|
|
55
55
|
var flattenTocTree = (items) => {
|
|
56
56
|
const result = [];
|
|
57
57
|
for (const item of items) {
|
|
58
|
-
result.push(item);
|
|
58
|
+
if (item.href) result.push(item);
|
|
59
59
|
if (item.children) result.push(...flattenTocTree(item.children));
|
|
60
60
|
}
|
|
61
61
|
return result;
|
|
62
62
|
};
|
|
63
63
|
var useAdjacentTocItems = () => {
|
|
64
|
-
const tocTree = useAppSelector((state) => state.publication.
|
|
65
|
-
const tocCurrentEntry = useAppSelector((state) => state.publication.
|
|
64
|
+
const tocTree = useAppSelector((state) => state.publication.toc?.tree);
|
|
65
|
+
const tocCurrentEntry = useAppSelector((state) => state.publication.toc?.currentEntry);
|
|
66
66
|
if (!tocTree || !tocCurrentEntry) return { previous: null, next: null };
|
|
67
67
|
const flat = flattenTocTree(tocTree);
|
|
68
68
|
const index = flat.findIndex((item) => item.href === tocCurrentEntry.href);
|
|
@@ -80,8 +80,8 @@ var StatefulPreviousButton = ({ isDisabled }) => {
|
|
|
80
80
|
const previousTimelineItem = useAppSelector((state) => state.publication.adjacentTimelineItems.previous);
|
|
81
81
|
const { previous: previousTocItem } = useAdjacentTocItems();
|
|
82
82
|
const affordance = preferences.affordances.previous;
|
|
83
|
-
const isTimeline = affordance ===
|
|
84
|
-
const isToc = affordance ===
|
|
83
|
+
const isTimeline = affordance === ThAudioAffordance.timeline;
|
|
84
|
+
const isToc = affordance === ThAudioAffordance.toc;
|
|
85
85
|
const previousItem = isToc ? previousTocItem : previousTimelineItem;
|
|
86
86
|
const label = (isTimeline || isToc) && previousItem?.title ? previousItem.title : t("reader.actions.goToPreviousResource.descriptive");
|
|
87
87
|
const handlePress = () => isTimeline || isToc ? previousItem && goLink(new Link({ href: previousItem.href }), false, () => {
|
|
@@ -109,8 +109,8 @@ var StatefulNextButton = ({ isDisabled }) => {
|
|
|
109
109
|
const nextTimelineItem = useAppSelector((state) => state.publication.adjacentTimelineItems.next);
|
|
110
110
|
const { next: nextTocItem } = useAdjacentTocItems();
|
|
111
111
|
const affordance = preferences.affordances.next;
|
|
112
|
-
const isTimeline = affordance ===
|
|
113
|
-
const isToc = affordance ===
|
|
112
|
+
const isTimeline = affordance === ThAudioAffordance.timeline;
|
|
113
|
+
const isToc = affordance === ThAudioAffordance.toc;
|
|
114
114
|
const nextItem = isToc ? nextTocItem : nextTimelineItem;
|
|
115
115
|
const label = (isTimeline || isToc) && nextItem?.title ? nextItem.title : t("reader.actions.goToNextResource.descriptive");
|
|
116
116
|
const handlePress = () => isTimeline || isToc ? nextItem && goLink(new Link({ href: nextItem.href }), false, () => {
|
|
@@ -217,7 +217,7 @@ var thorium_web_audioProgressBar_default = {
|
|
|
217
217
|
var StatefulAudioProgressBar = () => {
|
|
218
218
|
const { t } = useI18n();
|
|
219
219
|
const { preferences } = useAudioPreferences();
|
|
220
|
-
const tocEntry = useAppSelector((state) => state.publication.
|
|
220
|
+
const tocEntry = useAppSelector((state) => state.publication.toc?.currentEntry);
|
|
221
221
|
const currentChapter = tocEntry?.title;
|
|
222
222
|
const isStalled = useAppSelector((state) => state.player.isStalled);
|
|
223
223
|
const isTrackReady = useAppSelector((state) => state.player.isTrackReady);
|
|
@@ -238,7 +238,13 @@ var StatefulAudioProgressBar = () => {
|
|
|
238
238
|
const locator = currentLocator();
|
|
239
239
|
const tl = timeline();
|
|
240
240
|
if (!locator || !tl) return;
|
|
241
|
-
const
|
|
241
|
+
const time = progression * total;
|
|
242
|
+
const hoverLocator = new Locator({
|
|
243
|
+
href: locator.href,
|
|
244
|
+
type: locator.type,
|
|
245
|
+
locations: new LocatorLocations({ fragments: [`t=${time}`] })
|
|
246
|
+
});
|
|
247
|
+
const item = tl.locate(hoverLocator);
|
|
242
248
|
setHoverLabel(item?.title);
|
|
243
249
|
}, [currentLocator, timeline, total]);
|
|
244
250
|
const parseTimestamp = (href) => {
|
|
@@ -539,10 +545,7 @@ var useAudioPlayerInit = ({
|
|
|
539
545
|
const config = {
|
|
540
546
|
publication,
|
|
541
547
|
listeners,
|
|
542
|
-
initialPosition: initialPosition
|
|
543
|
-
...initialPosition,
|
|
544
|
-
locations: initialPosition.locations ? new LocatorLocations(initialPosition.locations) : void 0
|
|
545
|
-
}) : void 0,
|
|
548
|
+
initialPosition: initialPosition ?? void 0,
|
|
546
549
|
preferences: audioPreferences,
|
|
547
550
|
defaults: audioDefaults,
|
|
548
551
|
contentProtection: contentProtectionConfig,
|
|
@@ -649,29 +652,17 @@ var StatefulPlayerInner = ({ publication, localDataKey, positionStorage, coverUr
|
|
|
649
652
|
const dispatch = useAppDispatch();
|
|
650
653
|
const getFocusedDockableKey = useFocusedDockableKey();
|
|
651
654
|
const audioNavigator = useAudioNavigator();
|
|
652
|
-
const { canGoBackward, canGoForward, submitPreferences, pause, isPlaying } = audioNavigator;
|
|
655
|
+
const { canGoBackward, canGoForward, submitPreferences, pause, isPlaying, timeline: getNavigatorTimeline } = audioNavigator;
|
|
653
656
|
const { setLocalData, getLocalData } = usePositionStorage(localDataKey, positionStorage);
|
|
654
657
|
const documentTitle = publication?.metadata?.title?.getTranslation("en");
|
|
655
658
|
useDocumentTitle(documentTitle);
|
|
656
|
-
const tocTree = useAppSelector((state) => state.publication.
|
|
657
|
-
const
|
|
658
|
-
|
|
659
|
-
tocTreeRef.current = tocTree;
|
|
660
|
-
}, [tocTree]);
|
|
659
|
+
const tocTree = useAppSelector((state) => state.publication.toc?.tree);
|
|
660
|
+
const { updateAdjacentItems, clearAdjacentItems } = useTimelineAdjacency(getNavigatorTimeline);
|
|
661
|
+
const { updateCurrentTocEntry, clearCurrentTocEntry } = useTocEntryTracking(getNavigatorTimeline, tocTree);
|
|
661
662
|
const handleTimelineNavigation = useCallback((item) => {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
const matched = findTocItemByHref(tocTreeRef.current || [], link.href);
|
|
666
|
-
dispatch(setTocEntry(matched || null));
|
|
667
|
-
}
|
|
668
|
-
const { previous, next } = tl.adjacentTo(item);
|
|
669
|
-
dispatch(setAdjacentTimelineItems({
|
|
670
|
-
previous: previous ? { title: previous.title, href: tl.linkFor(previous)?.href ?? "" } : null,
|
|
671
|
-
next: next ? { title: next.title, href: tl.linkFor(next)?.href ?? "" } : null
|
|
672
|
-
}));
|
|
673
|
-
return { previous, next };
|
|
674
|
-
}, [dispatch, publication]);
|
|
663
|
+
updateAdjacentItems(item);
|
|
664
|
+
updateCurrentTocEntry(item);
|
|
665
|
+
}, [updateAdjacentItems, updateCurrentTocEntry]);
|
|
675
666
|
const isFragmentAffordance = useCallback((affordance) => {
|
|
676
667
|
return affordance === "timeline" || affordance === "toc";
|
|
677
668
|
}, []);
|
|
@@ -693,12 +684,12 @@ var StatefulPlayerInner = ({ publication, localDataKey, positionStorage, coverUr
|
|
|
693
684
|
const listeners = useMemo(() => ({
|
|
694
685
|
timelineItemChanged: (item) => {
|
|
695
686
|
if (!item) {
|
|
696
|
-
|
|
697
|
-
|
|
687
|
+
clearCurrentTocEntry();
|
|
688
|
+
clearAdjacentItems();
|
|
698
689
|
return;
|
|
699
690
|
}
|
|
700
691
|
const previousNextItem = cache.current.adjacentTimelineItems.next;
|
|
701
|
-
const currentItemHref =
|
|
692
|
+
const currentItemHref = getNavigatorTimeline()?.linkFor(item)?.href ?? "";
|
|
702
693
|
handleTimelineNavigation(item);
|
|
703
694
|
const isTransitionToNext = previousNextItem !== null && previousNextItem.href === currentItemHref;
|
|
704
695
|
handleSleepTimerEndOfFragment(isTransitionToNext);
|
|
@@ -782,9 +773,12 @@ var StatefulPlayerInner = ({ publication, localDataKey, positionStorage, coverUr
|
|
|
782
773
|
},
|
|
783
774
|
contextMenu: (_data) => {
|
|
784
775
|
}
|
|
785
|
-
}), [setLocalData, canGoBackward, canGoForward, isPlaying, dispatch, cache, submitPreferences,
|
|
786
|
-
const initialPosition = useMemo(() =>
|
|
787
|
-
|
|
776
|
+
}), [setLocalData, canGoBackward, canGoForward, isPlaying, dispatch, cache, submitPreferences, getNavigatorTimeline, handleTimelineNavigation, clearCurrentTocEntry, clearAdjacentItems, handleSleepTimerEndOfFragment, handleContinuousPlay, profile, getFocusedDockableKey]);
|
|
777
|
+
const initialPosition = useMemo(() => {
|
|
778
|
+
const stored = getLocalData();
|
|
779
|
+
return stored ? Locator.deserialize(stored) ?? null : null;
|
|
780
|
+
}, [getLocalData]);
|
|
781
|
+
const { navigatorReady } = useAudioPlayerInit({
|
|
788
782
|
publication,
|
|
789
783
|
initialPosition,
|
|
790
784
|
listeners,
|
|
@@ -794,6 +788,7 @@ var StatefulPlayerInner = ({ publication, localDataKey, positionStorage, coverUr
|
|
|
794
788
|
keyboardPeripherals,
|
|
795
789
|
onNavigatorLoaded: () => dispatch(setLoading(false))
|
|
796
790
|
});
|
|
791
|
+
useTocTreeBuilder(publication, navigatorReady, getNavigatorTimeline);
|
|
797
792
|
const { compact, expanded } = preferences.theming.layout;
|
|
798
793
|
const renderPlayerComponent = useCallback((component) => {
|
|
799
794
|
switch (component) {
|
|
@@ -891,5 +886,5 @@ var StatefulPlayerInner = ({ publication, localDataKey, positionStorage, coverUr
|
|
|
891
886
|
};
|
|
892
887
|
|
|
893
888
|
export { StatefulAudioMediaActions, StatefulAudioPlaybackControls, StatefulAudioProgressBar, StatefulNextButton, StatefulPlayPauseButton, StatefulPlayer, StatefulPreviousButton, StatefulSkipBackwardButton, StatefulSkipForwardButton };
|
|
894
|
-
//# sourceMappingURL=chunk-
|
|
895
|
-
//# sourceMappingURL=chunk-
|
|
889
|
+
//# sourceMappingURL=chunk-VWKUZP5V.mjs.map
|
|
890
|
+
//# sourceMappingURL=chunk-VWKUZP5V.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Audio/controls/assets/icons/pause.svg","../src/components/Audio/controls/assets/icons/play_arrow.svg","../src/components/Audio/controls/assets/styles/thorium-web.audioPlayback.module.css","../src/components/Audio/controls/StatefulPlayPauseButton.tsx","../src/components/Audio/controls/assets/icons/skip_previous.svg","../src/components/hooks/useAdjacentTocItems.ts","../src/components/Audio/controls/StatefulPreviousButton.tsx","../src/components/Audio/controls/assets/icons/skip_next.svg","../src/components/Audio/controls/StatefulNextButton.tsx","../src/components/Audio/controls/assets/icons/replay.svg","../src/components/Audio/controls/assets/icons/replay_5.svg","../src/components/Audio/controls/assets/icons/replay_10.svg","../src/components/Audio/controls/assets/icons/replay_30.svg","../src/components/Audio/controls/StatefulSkipBackwardButton.tsx","../src/components/Audio/controls/assets/icons/forward_media.svg","../src/components/Audio/controls/assets/icons/forward_5.svg","../src/components/Audio/controls/assets/icons/forward_10.svg","../src/components/Audio/controls/assets/icons/forward_30.svg","../src/components/Audio/controls/StatefulSkipForwardButton.tsx","../src/components/Audio/controls/StatefulAudioPlaybackControls.tsx","../src/components/Audio/controls/assets/styles/thorium-web.audioProgressBar.module.css","../src/components/Audio/controls/StatefulAudioProgressBar.tsx","../src/components/Audio/actions/assets/styles/thorium-web.audioActions.module.css","../src/components/Audio/actions/StatefulAudioMediaActions.tsx","../src/components/Audio/assets/styles/thorium-web.audio.app.module.css","../src/components/Audio/assets/styles/thorium-web.audioPlayer.module.css","../src/components/Audio/StatefulPlayerHeader.tsx","../src/components/Audio/assets/styles/thorium-web.audioCover.module.css","../src/components/Audio/assets/icons/music_note.svg","../src/components/Audio/assets/icons/sync.svg","../src/components/Audio/StatefulAudioCover.tsx","../src/components/Audio/assets/styles/thorium-web.audioMetadata.module.css","../src/components/Audio/StatefulAudioMetadata.tsx","../src/components/Audio/Hooks/useAudioStatelessCache.ts","../src/components/Audio/Hooks/useAudioPreferencesConfig.ts","../src/components/Audio/Hooks/useAudioPlayerInit.ts","../src/components/Audio/Hooks/useAudioKeyboardPeripherals.ts","../src/helpers/browser.ts","../src/components/Audio/StatefulPlayer.tsx"],"names":["jsx","audioControls","audioPreviousButton","audioNextButton","audioSkipBackwardButton","audioSkipForwardButton","audioPlayPauseButton","Link","wrapper","current","slider","track","thumb","seekableRange","elapsed","remaining","tick","tooltip","useCallback","segments","jsxs","Fragment","main","shell","topBar","audioPlayerWrapper","audioPlayerWrapperExpanded","audioPlayerExpandedStart","audioPlayerExpandedEnd","coverMetadataGroup","audioCoverSection","audioCoverImage","audioCoverPlaceholder","audioCoverSyncOverlay","audioCoverSyncIcon","audioMetadata","audioMetadataTitle","audioMetadataSubtitle","audioMetadataAuthors","useRef","useMemo","useState","actionKey","Locator","useEffect"],"mappings":"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","file":"chunk-VWKUZP5V.mjs","sourcesContent":["import * as React from \"react\";\nconst SvgPause = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z\" /></svg>;\nexport default SvgPause;","import * as React from \"react\";\nconst SvgPlayArrow = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M320-200v-560l440 280-440 280Z\" /></svg>;\nexport default SvgPlayArrow;",".audioControls {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 1rem;\n --audio-icon-base: var(--th-icon-size, 24px);\n}\n\n@container (max-width: 300px) {\n .audioControls {\n --th-icon-size: 18px;\n }\n}\n\n.audioPreviousButton,\n.audioNextButton {\n --th-icon-size: calc(var(--audio-icon-base) * (5/4));\n padding: calc(var(--th-icon-size) * (1/5));\n}\n\n.audioSkipBackwardButton,\n.audioSkipForwardButton {\n --th-icon-size: calc(var(--audio-icon-base) * (3/2));\n padding: calc(var(--th-icon-size) * (1/6));\n}\n\n.audioPlayPauseButton {\n --th-icon-size: calc(var(--audio-icon-base) * 2);\n padding: calc(var(--th-icon-size) * (1/8));\n}\n","\"use client\";\n\nimport { useCallback } from \"react\";\n\nimport PauseIcon from \"./assets/icons/pause.svg\";\nimport PlayIcon from \"./assets/icons/play_arrow.svg\";\n\nimport { StatefulActionIcon } from \"../../Actions/Triggers/StatefulActionIcon\";\nimport audioStyles from \"./assets/styles/thorium-web.audioPlayback.module.css\";\n\nimport { useNavigator } from \"@/core/Navigator\";\nimport { useAppSelector } from \"@/lib/hooks\";\nimport { useI18n } from \"@/i18n/useI18n\";\n\nexport const StatefulPlayPauseButton = ({ isDisabled }: { isDisabled?: boolean }) => {\n const { t } = useI18n();\n const { play, pause } = useNavigator().media;\n const isPlaying = useAppSelector(state => state.player.status === \"playing\");\n\n const handlePress = useCallback(() => {\n if (isPlaying) {\n pause();\n } else {\n play();\n }\n }, [isPlaying, play, pause]);\n\n return (\n <StatefulActionIcon\n onPress={ handlePress }\n isDisabled={ isDisabled }\n aria-label={ isPlaying ? t(\"reader.playback.actions.pause\") : t(\"reader.playback.actions.play\") }\n tooltipLabel={ isPlaying ? t(\"reader.playback.actions.pause\") : t(\"reader.playback.actions.play\") }\n className={ audioStyles.audioPlayPauseButton }\n >\n {isPlaying ? (\n <PauseIcon aria-hidden=\"true\" focusable=\"false\" />\n ) : (\n <PlayIcon aria-hidden=\"true\" focusable=\"false\" />\n )}\n </StatefulActionIcon>\n );\n};\n","import * as React from \"react\";\nconst SvgSkipPrevious = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M220-240v-480h80v480h-80Zm520 0L380-480l360-240v480Zm-80-240Zm0 90v-180l-136 90 136 90Z\" /></svg>;\nexport default SvgSkipPrevious;","import { TocItem } from \"@/helpers/buildTocTree\";\nimport { useAppSelector } from \"@/lib/hooks\";\n\nconst flattenTocTree = (items: TocItem[]): TocItem[] => {\n const result: TocItem[] = [];\n for (const item of items) {\n if (item.href) result.push(item);\n if (item.children) result.push(...flattenTocTree(item.children));\n }\n return result;\n};\n\nexport const useAdjacentTocItems = (): { previous: TocItem | null; next: TocItem | null } => {\n const tocTree = useAppSelector(state => state.publication.toc?.tree);\n const tocCurrentEntry = useAppSelector(state => state.publication.toc?.currentEntry);\n\n if (!tocTree || !tocCurrentEntry) return { previous: null, next: null };\n\n const flat = flattenTocTree(tocTree);\n const index = flat.findIndex(item => item.href === tocCurrentEntry.href);\n\n if (index < 0) return { previous: null, next: null };\n\n return {\n previous: index > 0 ? flat[index - 1] : null,\n next: index < flat.length - 1 ? flat[index + 1] : null,\n };\n};\n","\"use client\";\n\nimport SkipPreviousIcon from \"./assets/icons/skip_previous.svg\";\n\nimport { StatefulActionIcon } from \"../../Actions/Triggers/StatefulActionIcon\";\nimport audioStyles from \"./assets/styles/thorium-web.audioPlayback.module.css\";\n\nimport { useNavigator } from \"@/core/Navigator\";\nimport { useAppSelector } from \"@/lib/hooks\";\nimport { useI18n } from \"@/i18n/useI18n\";\nimport { useAudioPreferences } from \"@/preferences/hooks/useAudioPreferences\";\nimport { ThAudioAffordance } from \"@/preferences/audioPreferences\";\nimport { useAdjacentTocItems } from \"../../hooks/useAdjacentTocItems\";\nimport { Link } from \"@readium/shared\";\n\nexport const StatefulPreviousButton = ({ isDisabled }: { isDisabled?: boolean }) => {\n const { t } = useI18n();\n const { preferences } = useAudioPreferences();\n const { goBackward, goLink } = useNavigator().media;\n const atStart = useAppSelector(state => state.publication.atPublicationStart);\n const previousTimelineItem = useAppSelector(state => state.publication.adjacentTimelineItems.previous);\n const { previous: previousTocItem } = useAdjacentTocItems();\n\n const affordance = preferences.affordances.previous;\n const isTimeline = affordance === ThAudioAffordance.timeline;\n const isToc = affordance === ThAudioAffordance.toc;\n\n const previousItem = isToc ? previousTocItem : previousTimelineItem;\n\n const label = (isTimeline || isToc) && previousItem?.title\n ? previousItem.title\n : t(\"reader.actions.goToPreviousResource.descriptive\");\n\n const handlePress = () => (isTimeline || isToc)\n ? previousItem && goLink(new Link({ href: previousItem.href }), false, () => {})\n : goBackward(false, () => {});\n\n return (\n <StatefulActionIcon\n onPress={ handlePress }\n isDisabled={ isDisabled || ((isTimeline || isToc) ? !previousItem : atStart) }\n aria-label={ label }\n tooltipLabel={ label }\n className={ audioStyles.audioPreviousButton }\n >\n <SkipPreviousIcon aria-hidden=\"true\" focusable=\"false\" />\n </StatefulActionIcon>\n );\n};\n","import * as React from \"react\";\nconst SvgSkipNext = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M660-240v-480h80v480h-80Zm-440 0v-480l360 240-360 240Zm80-240Zm0 90 136-90-136-90v180Z\" /></svg>;\nexport default SvgSkipNext;","\"use client\";\n\nimport SkipNextIcon from \"./assets/icons/skip_next.svg\";\n\nimport { StatefulActionIcon } from \"../../Actions/Triggers/StatefulActionIcon\";\nimport audioStyles from \"./assets/styles/thorium-web.audioPlayback.module.css\";\n\nimport { useNavigator } from \"@/core/Navigator\";\nimport { useAppSelector } from \"@/lib/hooks\";\nimport { useI18n } from \"@/i18n/useI18n\";\nimport { useAudioPreferences } from \"@/preferences\";\nimport { ThAudioAffordance } from \"@/preferences/audioPreferences\";\nimport { useAdjacentTocItems } from \"../../hooks/useAdjacentTocItems\";\nimport { Link } from \"@readium/shared\";\n\nexport const StatefulNextButton = ({ isDisabled }: { isDisabled?: boolean }) => {\n const { t } = useI18n();\n const { preferences } = useAudioPreferences();\n const { goForward, goLink } = useNavigator().media;\n const atEnd = useAppSelector(state => state.publication.atPublicationEnd);\n const nextTimelineItem = useAppSelector(state => state.publication.adjacentTimelineItems.next);\n const { next: nextTocItem } = useAdjacentTocItems();\n\n const affordance = preferences.affordances.next;\n const isTimeline = affordance === ThAudioAffordance.timeline;\n const isToc = affordance === ThAudioAffordance.toc;\n\n const nextItem = isToc ? nextTocItem : nextTimelineItem;\n\n const label = (isTimeline || isToc) && nextItem?.title\n ? nextItem.title\n : t(\"reader.actions.goToNextResource.descriptive\");\n\n const handlePress = () => (isTimeline || isToc)\n ? nextItem && goLink(new Link({ href: nextItem.href }), false, () => {})\n : goForward(false, () => {});\n\n return (\n <StatefulActionIcon\n onPress={ handlePress }\n isDisabled={ isDisabled || ((isTimeline || isToc) ? !nextItem : atEnd) }\n aria-label={ label }\n tooltipLabel={ label }\n className={ audioStyles.audioNextButton }\n >\n <SkipNextIcon aria-hidden=\"true\" focusable=\"false\" />\n </StatefulActionIcon>\n );\n};\n","import * as React from \"react\";\nconst SvgReplay = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.85Q140-369.23 140-440h60q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440q0-117-81.5-198.5T480-720h-10.62l63.54 63.54-42.15 43.38-136.92-137.3 137.69-137.31 42.15 43.38L469.38-780H480q70.77 0 132.61 26.77 61.85 26.77 107.85 72.77 46 46 72.77 107.85Q820-510.77 820-440q0 70.77-26.77 132.61-26.77 61.85-72.77 107.85-46 46-107.85 72.77Q550.77-100 480-100q-70.77 0-132.61-26.77Z\" /></svg>;\nexport default SvgReplay;","import * as React from \"react\";\nconst SvgReplay5 = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.83Q140-369.2 140-440h60q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440q0-117-81.5-198.5T480-720h-10.62l63.54 63.54-42.15 43.38-136.92-137.3 137.69-137.31 42.15 43.38L469.38-780H480q70.8 0 132.63 26.77t107.83 72.77q46 46 72.77 107.82Q820-510.81 820-440.02t-26.77 132.63q-26.77 61.85-72.77 107.85-46 46-107.82 72.77Q550.81-100 480.02-100t-132.63-26.77Zm38.76-199.38v-47.7h120v-48.46h-120v-131.54h167.7v47.7h-120v48.46H520q14.38 0 24.12 9.73 9.73 9.73 9.73 24.11V-360q0 14.38-9.73 24.12-9.74 9.73-24.12 9.73H386.15Z\" /></svg>;\nexport default SvgReplay5;","import * as React from \"react\";\nconst SvgReplay10 = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.85Q140-369.23 140-440h60q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440q0-117-81.5-198.5T480-720h-10.62l63.54 63.54-42.15 43.38-136.92-137.3 137.69-137.31 42.15 43.38L469.38-780H480q70.77 0 132.61 26.77 61.85 26.77 107.85 72.77 46 46 72.77 107.85Q820-510.77 820-440q0 70.77-26.77 132.61-26.77 61.85-72.77 107.85-46 46-107.85 72.77Q550.77-100 480-100q-70.77 0-132.61-26.77Zm21.07-199.38v-180h-57.69v-47.7h105.38v227.7h-47.69Zm135.39 0q-17 0-28.5-11.5t-11.5-28.5v-147.7q0-17 11.5-28.5t28.5-11.5h75.38q17 0 28.5 11.5t11.5 28.5v147.7q0 17-11.5 28.5t-28.5 11.5h-75.38Zm12.3-47.7h50.77q2.31 0 3.47-1.15 1.15-1.15 1.15-3.46v-123.08q0-2.31-1.15-3.46-1.16-1.15-3.47-1.15h-50.77q-2.3 0-3.46 1.15-1.15 1.15-1.15 3.46v123.08q0 2.31 1.15 3.46 1.16 1.15 3.46 1.15Z\" /></svg>;\nexport default SvgReplay10;","import * as React from \"react\";\nconst SvgReplay30 = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.85Q140-369.23 140-440h60q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440q0-117-81.5-198.5T480-720h-10.62l63.54 63.54-42.15 43.38-136.92-137.3 137.69-137.31 42.15 43.38L469.38-780H480q70.77 0 132.61 26.77 61.85 26.77 107.85 72.77 46 46 72.77 107.85Q820-510.77 820-440q0 70.77-26.77 132.61-26.77 61.85-72.77 107.85-46 46-107.85 72.77Q550.77-100 480-100q-70.77 0-132.61-26.77Zm-46.62-199.38v-47.7h107.69v-48.46h-71.54v-35.38h71.54v-48.46H300.77v-47.7h121.54q14.69 0 24.27 9.58 9.57 9.58 9.57 24.27v160q0 14.69-9.57 24.27-9.58 9.58-24.27 9.58H300.77Zm243.08 0q-17 0-28.5-11.5t-11.5-28.5v-147.7q0-17 11.5-28.5t28.5-11.5h75.38q17 0 28.5 11.5t11.5 28.5v147.7q0 17-11.5 28.5t-28.5 11.5h-75.38Zm12.3-47.7h50.77q2.31 0 3.47-1.15 1.15-1.15 1.15-3.46v-123.08q0-2.31-1.15-3.46-1.16-1.15-3.47-1.15h-50.77q-2.3 0-3.46 1.15-1.15 1.15-1.15 3.46v123.08q0 2.31 1.15 3.46 1.16 1.15 3.46 1.15Z\" /></svg>;\nexport default SvgReplay30;","\"use client\";\n\nimport ReplayIcon from \"./assets/icons/replay.svg\";\nimport Replay5Icon from \"./assets/icons/replay_5.svg\";\nimport Replay10Icon from \"./assets/icons/replay_10.svg\";\nimport Replay30Icon from \"./assets/icons/replay_30.svg\";\n\nimport { StatefulActionIcon } from \"../../Actions/Triggers/StatefulActionIcon\";\nimport audioStyles from \"./assets/styles/thorium-web.audioPlayback.module.css\";\n\nimport { useNavigator } from \"@/core/Navigator\";\nimport { useAppSelector } from \"@/lib/hooks\";\nimport { useI18n } from \"@/i18n/useI18n\";\n\nconst replayIconMap: Record<number, React.ElementType> = {\n 5: Replay5Icon,\n 10: Replay10Icon,\n 30: Replay30Icon,\n};\n\nexport const StatefulSkipBackwardButton = ({ isDisabled }: { isDisabled?: boolean }) => {\n const { t } = useI18n();\n const { skipBackward } = useNavigator().media;\n const skipBackwardInterval = useAppSelector(state => state.audioSettings.skipBackwardInterval);\n\n const Icon = replayIconMap[skipBackwardInterval] ?? ReplayIcon;\n\n return (\n <StatefulActionIcon\n onPress={ skipBackward }\n isDisabled={ isDisabled }\n aria-label={ t(\"reader.playback.actions.skipBackward.descriptive\") }\n tooltipLabel={ t(\"reader.playback.actions.skipBackward.descriptive\") }\n className={ audioStyles.audioSkipBackwardButton }\n >\n <Icon aria-hidden=\"true\" focusable=\"false\" />\n </StatefulActionIcon>\n );\n};\n","import * as React from \"react\";\nconst SvgForwardMedia = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.85Q140-369.23 140-440q0-70.77 26.77-132.61 26.77-61.85 72.77-107.85 46-46 107.85-72.77Q409.23-780 480-780h10.62l-64.31-64.31 42.15-43.38 137.69 137.31-136.92 137.3-42.15-43.38L490.62-720H480q-117 0-198.5 81.5T200-440q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440h60q0 70.77-26.77 132.61-26.77 61.85-72.77 107.85-46 46-107.85 72.77Q550.77-100 480-100q-70.77 0-132.61-26.77Z\" /></svg>;\nexport default SvgForwardMedia;","import * as React from \"react\";\nconst SvgForward5 = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.82Q140-369.19 140-439.98t26.77-132.63q26.77-61.85 72.77-107.85 46-46 107.83-72.77Q409.2-780 480-780h10.62l-64.31-64.31 42.15-43.38 137.69 137.31-136.92 137.3-42.15-43.38L490.62-720H480q-117 0-198.5 81.5T200-440q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440h60q0 70.8-26.77 132.63t-72.77 107.83q-46 46-107.82 72.77Q550.81-100 480.02-100t-132.63-26.77Zm38.76-199.38v-47.7h120v-48.46h-120v-131.54h167.7v47.7h-120v48.46H520q14.38 0 24.12 9.73 9.73 9.73 9.73 24.11V-360q0 14.38-9.73 24.12-9.74 9.73-24.12 9.73H386.15Z\" /></svg>;\nexport default SvgForward5;","import * as React from \"react\";\nconst SvgForward10 = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M368.46-326.15v-180h-57.69v-47.7h105.38v227.7h-47.69Zm135.39 0q-17 0-28.5-11.5t-11.5-28.5v-147.7q0-17 11.5-28.5t28.5-11.5h75.38q17 0 28.5 11.5t11.5 28.5v147.7q0 17-11.5 28.5t-28.5 11.5h-75.38Zm12.3-47.7h50.77q2.31 0 3.47-1.15 1.15-1.15 1.15-3.46v-123.08q0-2.31-1.15-3.46-1.16-1.15-3.47-1.15h-50.77q-2.3 0-3.46 1.15-1.15 1.15-1.15 3.46v123.08q0 2.31 1.15 3.46 1.16 1.15 3.46 1.15ZM347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.85Q140-369.23 140-440q0-70.77 26.77-132.61 26.77-61.85 72.77-107.85 46-46 107.85-72.77Q409.23-780 480-780h10.62l-64.31-64.31 42.15-43.38 137.69 137.31-136.92 137.3-42.15-43.38L490.62-720H480q-117 0-198.5 81.5T200-440q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440h60q0 70.77-26.77 132.61-26.77 61.85-72.77 107.85-46 46-107.85 72.77Q550.77-100 480-100q-70.77 0-132.61-26.77Z\" /></svg>;\nexport default SvgForward10;","import * as React from \"react\";\nconst SvgForward30 = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M300.77-326.15v-47.7h107.69v-48.46h-71.54v-35.38h71.54v-48.46H300.77v-47.7h121.54q14.69 0 24.27 9.58 9.57 9.58 9.57 24.27v160q0 14.69-9.57 24.27-9.58 9.58-24.27 9.58H300.77Zm243.08 0q-17 0-28.5-11.5t-11.5-28.5v-147.7q0-17 11.5-28.5t28.5-11.5h75.38q17 0 28.5 11.5t11.5 28.5v147.7q0 17-11.5 28.5t-28.5 11.5h-75.38Zm12.3-47.7h50.77q2.31 0 3.47-1.15 1.15-1.15 1.15-3.46v-123.08q0-2.31-1.15-3.46-1.16-1.15-3.47-1.15h-50.77q-2.3 0-3.46 1.15-1.15 1.15-1.15 3.46v123.08q0 2.31 1.15 3.46 1.16 1.15 3.46 1.15ZM347.39-126.77q-61.85-26.77-107.85-72.77-46-46-72.77-107.85Q140-369.23 140-440q0-70.77 26.77-132.61 26.77-61.85 72.77-107.85 46-46 107.85-72.77Q409.23-780 480-780h10.62l-64.31-64.31 42.15-43.38 137.69 137.31-136.92 137.3-42.15-43.38L490.62-720H480q-117 0-198.5 81.5T200-440q0 117 81.5 198.5T480-160q117 0 198.5-81.5T760-440h60q0 70.77-26.77 132.61-26.77 61.85-72.77 107.85-46 46-107.85 72.77Q550.77-100 480-100q-70.77 0-132.61-26.77Z\" /></svg>;\nexport default SvgForward30;","\"use client\";\n\nimport ForwardIcon from \"./assets/icons/forward_media.svg\";\nimport Forward5Icon from \"./assets/icons/forward_5.svg\";\nimport Forward10Icon from \"./assets/icons/forward_10.svg\";\nimport Forward30Icon from \"./assets/icons/forward_30.svg\";\n\nimport { StatefulActionIcon } from \"../../Actions/Triggers/StatefulActionIcon\";\nimport audioStyles from \"./assets/styles/thorium-web.audioPlayback.module.css\";\n\nimport { useNavigator } from \"@/core/Navigator\";\nimport { useAppSelector } from \"@/lib/hooks\";\nimport { useI18n } from \"@/i18n/useI18n\";\n\nconst forwardIconMap: Record<number, React.ElementType> = {\n 5: Forward5Icon,\n 10: Forward10Icon,\n 30: Forward30Icon,\n};\n\nexport const StatefulSkipForwardButton = ({ isDisabled }: { isDisabled?: boolean }) => {\n const { t } = useI18n();\n const { skipForward } = useNavigator().media;\n const skipForwardInterval = useAppSelector(state => state.audioSettings.skipForwardInterval);\n\n const Icon = forwardIconMap[skipForwardInterval] ?? ForwardIcon;\n\n return (\n <StatefulActionIcon\n onPress={ skipForward }\n isDisabled={ isDisabled }\n aria-label={ t(\"reader.playback.actions.skipForward.descriptive\") }\n tooltipLabel={ t(\"reader.playback.actions.skipForward.descriptive\") }\n className={ audioStyles.audioSkipForwardButton }\n >\n <Icon aria-hidden=\"true\" focusable=\"false\" />\n </StatefulActionIcon>\n );\n};\n","\"use client\";\n\nimport audioStyles from \"./assets/styles/thorium-web.audioPlayback.module.css\";\n\nimport { StatefulPreviousButton } from \"./StatefulPreviousButton\";\nimport { StatefulSkipBackwardButton } from \"./StatefulSkipBackwardButton\";\nimport { StatefulPlayPauseButton } from \"./StatefulPlayPauseButton\";\nimport { StatefulSkipForwardButton } from \"./StatefulSkipForwardButton\";\nimport { StatefulNextButton } from \"./StatefulNextButton\";\n\nimport { ThActionsBar } from \"@/core/Components/Actions/ThActionsBar\";\n\nimport { useI18n } from \"@/i18n/useI18n\";\nimport { useAppSelector } from \"@/lib/hooks\";\n\nexport const StatefulAudioPlaybackControls = () => {\n const { t } = useI18n();\n const isTrackReady = useAppSelector(state => state.player.isTrackReady);\n const isStalled = useAppSelector(state => state.player.isStalled);\n\n return (\n <ThActionsBar className={ audioStyles.audioControls } aria-label={ t(\"audio.player.controls\") } dir=\"ltr\">\n <StatefulPreviousButton isDisabled={ !isTrackReady || isStalled } />\n <StatefulSkipBackwardButton isDisabled={ !isTrackReady || isStalled } />\n <StatefulPlayPauseButton isDisabled={ !isTrackReady || isStalled } />\n <StatefulSkipForwardButton isDisabled={ !isTrackReady || isStalled } />\n <StatefulNextButton isDisabled={ !isTrackReady || isStalled } />\n </ThActionsBar>\n );\n};\n",".wrapper {\n width: 100%;\n max-width: 600px;\n display: grid;\n grid-template-areas:\n \"chapter chapter chapter\"\n \"progress progress progress\"\n \"elapsed . remaining\";\n grid-template-columns: 1fr 1fr 1fr;\n align-items: center;\n gap: 0.5rem;\n container-type: inline-size;\n}\n\n.current {\n grid-area: chapter;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.slider {\n grid-area: progress;\n}\n\n.track {\n grid-area: progress;\n position: relative;\n height: 30px;\n width: auto;\n box-sizing: border-box;\n margin-inline: calc(var(--th-layout-spacing) / 2);\n}\n\n.track::before {\n content: \"\";\n display: block;\n position: absolute;\n background: var(--th-theme-subdue);\n height: 3px;\n width: 100%;\n top: 50%;\n transform: translateY(-50%);\n}\n\n.thumb {\n z-index: 2;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: 50%;\n background: var(--th-theme-text);\n border: none;\n top: 50%;\n transform: translateY(-50%);\n}\n\n.slider[data-disabled] .track::before {\n background: var(--th-theme-disable);\n}\n\n.slider[data-disabled] .thumb {\n background: var(--th-theme-disable);\n}\n\n.slider[data-disabled] .seekableRange {\n background: var(--th-theme-disable);\n}\n\n.slider[data-disabled] .current,\n.slider[data-disabled] .elapsed,\n.slider[data-disabled] .remaining {\n color: var(--th-theme-disable);\n}\n\n.thumb[data-dragging] {\n background: var(--th-theme-subdue);\n}\n\n.thumb[data-focus-visible] {\n outline: 2px solid var(--th-theme-focus);\n}\n\n.seekableRange {\n position: absolute;\n height: 3px;\n top: 50%;\n transform: translateY(-50%);\n background: color-mix(in srgb, var(--th-theme-text) 55%, var(--th-theme-subdue));\n pointer-events: none;\n border-radius: 1px;\n z-index: 1;\n}\n\n.tick {\n position: absolute;\n width: 1px;\n height: 15px;\n top: 50%;\n transform: translateY(-50%);\n background: var(--th-theme-text);\n pointer-events: none;\n z-index: 1;\n}\n\n.tooltip {\n background-color: var(--th-theme-text);\n color: var(--th-theme-background);\n border-radius: var(--th-layout-radius);\n padding: calc(var(--th-layout-spacing) / 2);\n font-size: 0.75rem;\n pointer-events: none;\n max-width: 320px;\n text-wrap: pretty;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow: hidden;\n}\n\n.elapsed {\n grid-area: elapsed;\n justify-self: start;\n font-size: 0.875rem;\n color: var(--th-theme-text);\n}\n\n.remaining {\n grid-area: remaining;\n justify-self: end;\n font-size: 0.875rem;\n color: var(--th-theme-text);\n}\n\n@container (max-width: 300px) {\n .current {\n font-size: 0.875rem;\n }\n}\n","\"use client\";\n\nimport React, { useCallback, useState, useMemo } from \"react\";\n\nimport { Locator, LocatorLocations } from \"@readium/shared\";\n\nimport audioStyles from \"./assets/styles/thorium-web.audioProgressBar.module.css\";\n\nimport { ThAudioProgress } from \"@/core/Components/Audio/ThAudioProgress\";\n\nimport { useNavigator } from \"@/core/Navigator\";\nimport { useAppSelector } from \"@/lib\";\nimport { useI18n } from \"@/i18n/useI18n\";\nimport { useAudioPreferences } from \"@/preferences/hooks/useAudioPreferences\";\nimport { ThAudioProgressBarVariant } from \"@/preferences/models/ui\";\n\nexport const StatefulAudioProgressBar = () => {\n const { t } = useI18n();\n const { preferences } = useAudioPreferences();\n\n const tocEntry = useAppSelector(state => state.publication.toc?.currentEntry);\n const currentChapter = tocEntry?.title;\n\n const isStalled = useAppSelector(state => state.player.isStalled);\n const isTrackReady = useAppSelector(state => state.player.isTrackReady);\n const seekableRanges = useAppSelector(state => state.player.seekableRanges);\n const playbackRate = useAppSelector(state => state.audioSettings.playbackRate);\n\n const { currentTime, duration, seek, currentLocator, timeline } = useNavigator().media;\n\n const current = currentTime();\n const total = duration();\n\n const [hoverLabel, setHoverLabel] = useState<string | undefined>(undefined);\n\n const handleSeek = useCallback((time: number) => {\n seek(time);\n }, [seek]);\n\n const handleHoverProgression = useCallback((progression: number | null) => {\n if (progression === null) {\n setHoverLabel(undefined);\n return;\n }\n const locator = currentLocator();\n const tl = timeline();\n if (!locator || !tl) return;\n const time = progression * total;\n const hoverLocator = new Locator({\n href: locator.href,\n type: locator.type,\n locations: new LocatorLocations({ fragments: [`t=${ time }`] })\n });\n const item = tl.locate(hoverLocator);\n setHoverLabel(item?.title);\n }, [currentLocator, timeline, total]);\n\n // Parse timestamp from fragment href (e.g., \"file.mp3#t=123.45\")\n const parseTimestamp = (href: string): number => {\n const match = href.match(/#t=(\\d+(?:\\.\\d+)?)$/);\n return match ? parseFloat(match[1]) : 0;\n };\n\n // Get timeline segments for fragmented progress bar\n const segments = useMemo(() => {\n const locator = currentLocator();\n const tl = timeline();\n if (!locator || !tl || preferences.theming.layout.progressBar?.variant !== ThAudioProgressBarVariant.segmented) return [];\n \n const segments = tl.segmentsForHref(locator.href);\n if (!segments || !Array.isArray(segments)) return [];\n \n return segments.map((segment) => {\n // Parse timestamp from first reference href (e.g., \"track1.mp3#t=60\")\n const referenceHref = segment.references?.[0] || \"\";\n const timestamp = parseTimestamp(referenceHref);\n \n // Calculate percentage based on timestamp and total duration\n const percentage = total > 0 ? (timestamp / total) * 100 : 0;\n \n return {\n title: segment.title,\n timestamp,\n percentage\n };\n });\n }, [currentLocator, timeline, total, preferences.theming.layout.progressBar?.variant]);\n\n return (\n <ThAudioProgress\n currentTime={ current }\n duration={ total }\n playbackRate={ playbackRate }\n onSeek={ handleSeek }\n currentChapter={ currentChapter || \"\" } // Zero-width space to prevent shift\n isDisabled={ !isTrackReady || isStalled }\n seekableRanges={ seekableRanges }\n hoverLabel={ hoverLabel }\n onHoverProgression={ handleHoverProgression }\n segments={ segments }\n compounds={{\n wrapper: {\n className: audioStyles.wrapper,\n onKeyDown: (e: React.KeyboardEvent) => {\n if (e.key === \"Escape\") (document.activeElement as HTMLElement)?.blur();\n }\n },\n current: {\n className: audioStyles.current\n },\n slider: {\n className: audioStyles.slider,\n \"aria-label\": t(\"audio.player.progress\")\n },\n track: {\n className: audioStyles.track\n },\n thumb: {\n className: audioStyles.thumb\n },\n elapsedTime: {\n className: audioStyles.elapsed\n },\n remainingTime: {\n className: audioStyles.remaining\n },\n seekableRange: {\n className: audioStyles.seekableRange\n },\n fragmentTick: {\n className: audioStyles.tick\n },\n tooltip: {\n className: audioStyles.tooltip,\n offset: preferences.theming.icon.tooltipOffset\n }\n }}\n />\n );\n};\n",".wrapper {\n display: flex;\n align-items: flex-start;\n justify-content: center;\n gap: 1rem;\n --audio-icon-base: var(--th-icon-size, 24px);\n}\n\n@container (max-width: 300px) {\n .wrapper {\n --th-icon-size: 18px;\n }\n}\n\n.popover {\n /* Override the default popover width — audio controls are more compact */\n width: auto;\n max-width: 95%;\n}","\"use client\";\n\nimport { Fragment, useRef } from \"react\";\n\nimport audioStyles from \"./assets/styles/thorium-web.audioActions.module.css\";\n\nimport { ThActionsBar, ThActionsTriggerVariant } from \"@/core/Components/Actions/ThActionsBar\";\nimport { usePlugins } from \"@/components/Plugins/PluginProvider\";\nimport { ActionComponent } from \"@/components/Plugins/PluginRegistry\";\n\nimport { useI18n } from \"@/i18n/useI18n\";\nimport { useAudioPreferences } from \"@/preferences/hooks/useAudioPreferences\";\n\nconst AudioActionPair = ({ action }: { action: ActionComponent }) => {\n const triggerRef = useRef<HTMLButtonElement>(null);\n const { Trigger, Target } = action;\n return (\n <Fragment>\n <Trigger ref={ triggerRef } variant={ ThActionsTriggerVariant.button } />\n { Target && <Target triggerRef={ triggerRef } placement=\"top\" /> }\n </Fragment>\n );\n};\n\nexport const StatefulAudioMediaActions = () => {\n const { t } = useI18n();\n const { preferences } = useAudioPreferences();\n const { primaryAudioActionsMap } = usePlugins();\n\n const displayOrder = preferences.actions.primary.displayOrder;\n\n return (\n <ThActionsBar className={ audioStyles.wrapper } aria-label={ t(\"audio.player.mediaActions\") }>\n { displayOrder.map(key => {\n const action = primaryAudioActionsMap[key];\n if (!action) return null;\n return <AudioActionPair key={ key } action={ action } />;\n }) }\n </ThActionsBar>\n );\n};\n",".main {\n width: 100%;\n height: 100%;\n margin: 0;\n}\n\n.shell {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n height: 100vh;\n height: 100dvh;\n max-height: 100%;\n background-color: var(--th-theme-background);\n}\n\n.topBar {\n flex: 0 0 calc(var(--th-icon-size, 24px) * 2.5);\n height: calc(var(--th-icon-size, 24px) * 2.5);\n box-sizing: border-box;\n gap: 2px;\n touch-action: manipulation;\n background-color: var(--th-theme-background);\n}\n",".audioPlayerWrapper {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n gap: var(--th-layout-spacing);\n padding: var(--th-layout-spacing);\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n.audioPlayerWrapperExpanded {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n box-sizing: border-box;\n gap: var(--th-layout-spacing);\n padding: var(--th-layout-spacing);\n height: 100%;\n width: 100%;\n max-width: 960px;\n margin-inline: auto;\n container-type: inline-size;\n}\n\n.audioPlayerExpandedStart {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1 1 0;\n min-width: 0;\n gap: var(--th-layout-spacing);\n container-type: inline-size;\n}\n\n.audioPlayerExpandedEnd {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1 1 0;\n min-width: 0;\n gap: var(--th-layout-spacing);\n container-type: inline-size;\n}\n\n.coverMetadataGroup {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--th-layout-spacing);\n flex: 0 1 auto;\n width: 100%;\n}\n","\"use client\";\n\nimport audioLayoutStyles from \"./assets/styles/thorium-web.audio.app.module.css\";\nimport readerHeaderStyles from \"../assets/styles/thorium-web.reader.header.module.css\";\nimport overflowMenuStyles from \"../Actions/assets/styles/thorium-web.overflow.module.css\";\n\nimport { StatefulBackLink } from \"../StatefulBackLink\";\nimport { StatefulCollapsibleActionsBar } from \"../Actions/StatefulCollapsibleActionsBar\";\n\nimport { useReaderHeaderBase } from \"../hooks/useReaderHeaderBase\";\nimport { useAudioPreferences } from \"@/preferences/hooks/useAudioPreferences\";\n\nimport classNames from \"classnames\";\n\nexport const StatefulPlayerHeader = ({\n actionKeys,\n actionsOrder,\n}: {\n actionKeys: string[];\n actionsOrder: string[];\n}) => {\n const {\n headerRef, listActionItems, t,\n } = useReaderHeaderBase(actionKeys);\n\n const { preferences } = useAudioPreferences();\n\n return (\n <>\n <div\n ref={ headerRef }\n className={ classNames(audioLayoutStyles.topBar, readerHeaderStyles.header) }\n >\n { preferences.theming.header?.backLink && <StatefulBackLink className={ readerHeaderStyles.backlinkWrapper } /> }\n\n <StatefulCollapsibleActionsBar\n id=\"reader-header-overflowMenu\"\n items={ listActionItems() }\n prefs={{ ...preferences.actions.secondary, displayOrder: actionsOrder }}\n className={ readerHeaderStyles.actionsWrapper }\n aria-label={ t(\"reader.app.header.actions\") }\n overflowMenuClassName={ overflowMenuStyles.hint }\n />\n </div>\n </>\n );\n};\n",".audioCoverSection {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n flex: 1 1 auto;\n min-height: 100px;\n max-height: var(--th-layout-constraints-cover, 300px);\n width: 100%;\n margin: 0;\n}\n\n.audioCoverImage {\n height: 100%;\n width: auto;\n max-width: 100%;\n object-fit: contain;\n border-radius: var(--th-layout-radius);\n filter: drop-shadow(var(--th-theme-elevate));\n}\n\n.audioCoverPlaceholder {\n height: 100%;\n max-height: var(--th-layout-constraints-cover, 300px);\n width: auto;\n max-width: 100%;\n aspect-ratio: 1 / 1;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: var(--th-theme-background);\n border-radius: var(--th-layout-radius);\n border: 1px solid var(--th-theme-subdue);\n filter: drop-shadow(var(--th-theme-elevate));\n}\n\n.audioCoverPlaceholder svg {\n width: 50%;\n height: 50%;\n fill: var(--th-theme-text);\n}\n\n.audioCoverSyncOverlay {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n max-height: var(--th-layout-constraints-cover, 300px);\n width: auto;\n max-width: 100%;\n aspect-ratio: 1 / 1;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--th-layout-radius);\n background-color: color-mix(in srgb, var(--th-theme-background) 60%, transparent);\n}\n\n.audioCoverSyncIcon {\n width: calc(var(--th-icon-size, 24px) * 2);\n height: calc(var(--th-icon-size, 24px) * 2);\n fill: var(--th-theme-text);\n animation: audioCoverSpin 1.2s linear infinite;\n}\n\n@keyframes audioCoverSpin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n","import * as React from \"react\";\nconst SvgMusicNote = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M287-167q-47-47-47-113t47-113q47-47 113-47 23 0 42.5 5.5T480-418v-422h240v160H560v400q0 66-47 113t-113 47q-66 0-113-47Z\" /></svg>;\nexport default SvgMusicNote;","import * as React from \"react\";\nconst SvgSync = props => <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"inherit\" {...props}><path d=\"M160-160v-80h110l-16-14q-52-46-73-105t-21-119q0-111 66.5-197.5T400-790v84q-72 26-116 88.5T240-478q0 45 17 87.5t53 78.5l10 10v-98h80v240H160Zm400-10v-84q72-26 116-88.5T720-482q0-45-17-87.5T650-648l-10-10v98h-80v-240h240v80H690l16 14q49 49 71.5 106.5T800-482q0 111-66.5 197.5T560-170Z\" /></svg>;\nexport default SvgSync;","import { Ref } from \"react\";\n\nimport styles from \"./assets/styles/thorium-web.audioCover.module.css\";\n\nimport MusicNoteIcon from \"./assets/icons/music_note.svg\";\nimport SyncIcon from \"./assets/icons/sync.svg\";\n\nimport { useI18n } from \"@/i18n/useI18n\";\n\nimport { useAppSelector } from \"@/lib/hooks\";\n\nimport { proxyUrl } from \"@/helpers/proxyUrl\";\n\ninterface StatefulAudioCoverProps {\n ref?: Ref<HTMLElement>;\n coverUrl?: string;\n title?: string;\n}\n\nexport function StatefulAudioCover({ ref, coverUrl, title }: StatefulAudioCoverProps) {\n const { t } = useI18n();\n const isTrackReady = useAppSelector(state => state.player.isTrackReady);\n const isStalled = useAppSelector(state => state.player.isStalled);\n\n const showSyncOverlay = !isTrackReady || isStalled;\n\n return (\n <figure ref={ ref } className={ styles.audioCoverSection }>\n { coverUrl ? (\n <img\n src={ proxyUrl(coverUrl) }\n alt={ title || t(\"audio.player.coverAlt\") }\n className={ styles.audioCoverImage }\n crossOrigin=\"anonymous\"\n />\n ) : (\n <div className={ styles.audioCoverPlaceholder }>\n { showSyncOverlay ? (\n <SyncIcon className={ styles.audioCoverSyncIcon } aria-hidden=\"true\" />\n ) : (\n <MusicNoteIcon />\n ) }\n </div>\n ) }\n { coverUrl && showSyncOverlay && (\n <div className={ styles.audioCoverSyncOverlay } aria-hidden=\"true\">\n <SyncIcon className={ styles.audioCoverSyncIcon } />\n </div>\n ) }\n </figure>\n );\n}\n",".audioMetadata {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin: 0;\n gap: var(--th-layout-spacing);\n text-align: center;\n}\n\n.audioMetadata hgroup {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0;\n margin: 0;\n}\n\n.audioMetadataTitle {\n margin: 0;\n font-size: 1em;\n font-weight: bold;\n color: var(--th-theme-text);\n}\n\n.audioMetadataSubtitle {\n display: block;\n margin: 0;\n margin-top: calc(var(--th-layout-spacing) / 4);\n font-weight: normal;\n color: var(--th-theme-text);\n}\n\n.audioMetadataAuthors {\n margin: 0;\n color: var(--th-theme-subdue-text);\n}\n\n@container (max-width: 300px) {\n .audioMetadata {\n font-size: 0.875rem;\n }\n}\n","import styles from \"./assets/styles/thorium-web.audioMetadata.module.css\";\n\nimport { Publication } from \"@readium/shared\";\nimport { useAudioPreferences } from \"@/preferences/hooks/useAudioPreferences\";\nimport { ThAudioPublicationMetadataComponent } from \"@/preferences/models\";\n\ninterface StatefulAudioMetadataProps {\n publication: Publication;\n}\n\nexport function StatefulAudioMetadata({ publication }: StatefulAudioMetadataProps) {\n const { preferences } = useAudioPreferences();\n const { metadata } = publication;\n\n const title = metadata.title.getTranslation(\"en\");\n const subtitle = metadata.subtitle?.getTranslation(\"en\");\n const authors = metadata.authors?.items.map(a => a.name.getTranslation(\"en\"));\n\n const metadataOrder = preferences.theming.layout.publicationMetadata.order;\n\n const renderMetadataComponents = () => {\n return metadataOrder.map((component: ThAudioPublicationMetadataComponent) => {\n switch (component) {\n case ThAudioPublicationMetadataComponent.title:\n return <h1 key=\"title\" className={ styles.audioMetadataTitle }>{ title }</h1>;\n\n case ThAudioPublicationMetadataComponent.titleWithSubtitle:\n return (\n <hgroup key=\"title-with-subtitle\">\n <h1 className={ styles.audioMetadataTitle }>{ title }</h1>\n { subtitle && <p className={ styles.audioMetadataSubtitle }>{ subtitle }</p> }\n </hgroup>\n );\n\n case ThAudioPublicationMetadataComponent.subtitleWithTitle:\n return (\n <hgroup key=\"subtitle-with-title\">\n { subtitle && <p className={ styles.audioMetadataSubtitle }>{ subtitle }</p> }\n <h1 className={ styles.audioMetadataTitle }>{ title }</h1>\n </hgroup>\n );\n\n case ThAudioPublicationMetadataComponent.authors:\n return authors && authors.length > 0 ? (\n <p key=\"authors\" className={ styles.audioMetadataAuthors }>{ authors.join(\", \") }</p>\n ) : null;\n \n default:\n return null;\n }\n }).filter(Boolean);\n };\n\n return (\n <header className={ styles.audioMetadata }>\n { renderMetadataComponents() }\n </header>\n );\n}\n","\"use client\";\n\nimport { useRef } from \"react\";\nimport { AudioSettings, useAudioSettingsCache } from \"@/core/Hooks/Audio/useAudioSettingsCache\";\nimport { TimelineItemRef } from \"@/lib/publicationReducer\";\n\nexport interface AudioStatelessCache {\n settings: AudioSettings;\n sleepTimerOnTrackEnd: boolean;\n sleepTimerOnFragmentEnd: boolean;\n adjacentTimelineItems: {\n previous: TimelineItemRef | null;\n next: TimelineItemRef | null;\n };\n}\n\nexport const useAudioStatelessCache = (\n volume: number,\n playbackRate: number,\n preservePitch: boolean,\n skipBackwardInterval: number,\n skipForwardInterval: number,\n skipInterval: number,\n pollInterval: number,\n autoPlay: boolean,\n enableMediaSession: boolean,\n sleepTimerOnTrackEnd: boolean,\n sleepTimerOnFragmentEnd: boolean,\n adjacentTimelineItems: {\n previous: TimelineItemRef | null;\n next: TimelineItemRef | null;\n }\n) => {\n const settingsCache = useAudioSettingsCache(\n volume,\n playbackRate,\n preservePitch,\n skipBackwardInterval,\n skipForwardInterval,\n skipInterval,\n pollInterval,\n autoPlay,\n enableMediaSession\n );\n\n const cache = useRef<AudioStatelessCache>({\n settings: settingsCache.current.settings,\n sleepTimerOnTrackEnd,\n sleepTimerOnFragmentEnd,\n adjacentTimelineItems,\n });\n\n // Update cache synchronously on every render to ensure fresh values\n cache.current.settings = settingsCache.current.settings;\n cache.current.sleepTimerOnTrackEnd = sleepTimerOnTrackEnd;\n cache.current.sleepTimerOnFragmentEnd = sleepTimerOnFragmentEnd;\n cache.current.adjacentTimelineItems = adjacentTimelineItems;\n\n return cache;\n};\n","\"use client\";\n\nimport { useMemo } from \"react\";\n\nimport { ThAudioPreferences } from \"@/preferences/audioPreferences\";\nimport { ThAudioKeys } from \"@/preferences/models/audio\";\nimport { AudioSettings } from \"@/core/Hooks/Audio/useAudioSettingsCache\";\n\ninterface UseAudioPreferencesConfigProps {\n settings: AudioSettings;\n preferences: ThAudioPreferences;\n}\n\nexport const useAudioPreferencesConfig = ({\n settings,\n preferences,\n}: UseAudioPreferencesConfigProps) => {\n const audioPreferences = useMemo(() => {\n const isSkipIntervalMode = ThAudioKeys.skipInterval in preferences.settings.keys;\n return {\n volume: settings.volume,\n playbackRate: settings.playbackRate,\n preservePitch: settings.preservePitch,\n skipBackwardInterval: isSkipIntervalMode ? settings.skipInterval : settings.skipBackwardInterval,\n skipForwardInterval: isSkipIntervalMode ? settings.skipInterval : settings.skipForwardInterval,\n pollInterval: settings.pollInterval,\n autoPlay: settings.autoPlay,\n enableMediaSession: settings.enableMediaSession,\n };\n }, [settings, preferences.settings.keys]);\n\n const audioDefaults = useMemo(() => {\n return {\n volume: 1.0,\n playbackRate: 1.0,\n preservePitch: true,\n skipBackwardInterval: 10,\n skipForwardInterval: 10,\n pollInterval: 1000,\n autoPlay: false,\n enableMediaSession: true,\n };\n }, []);\n\n return { audioPreferences, audioDefaults };\n};\n","\"use client\";\n\nimport { useCallback, useEffect, useState, useRef } from \"react\";\n\nimport { Locator, Publication } from \"@readium/shared\";\nimport { AudioNavigatorListeners, IAudioContentProtectionConfig, IKeyboardPeripheralsConfig } from \"@readium/navigator\";\nimport { ThAudioPreferences } from \"@/preferences/audioPreferences\";\n\nimport { AudioStatelessCache } from \"./useAudioStatelessCache\";\nimport { useAudioPreferencesConfig } from \"./useAudioPreferencesConfig\";\nimport { useAudioNavigator, AudioNavigatorLoadProps } from \"@/core/Hooks/Audio/useAudioNavigator\";\n\ninterface UseAudioPlayerInitProps {\n publication: Publication | null;\n initialPosition: Locator | null;\n listeners: AudioNavigatorListeners;\n preferences: ThAudioPreferences;\n cache: React.RefObject<AudioStatelessCache>;\n contentProtectionConfig?: IAudioContentProtectionConfig;\n keyboardPeripherals?: IKeyboardPeripheralsConfig;\n onNavigatorReady?: () => void;\n onNavigatorLoaded?: () => void;\n onCleanup?: () => void;\n}\n\nexport const useAudioPlayerInit = ({\n publication,\n initialPosition,\n listeners,\n preferences,\n cache,\n contentProtectionConfig,\n keyboardPeripherals,\n onNavigatorReady,\n onNavigatorLoaded,\n onCleanup,\n}: UseAudioPlayerInitProps) => {\n const [navigatorReady, setNavigatorReady] = useState(false);\n\n const { audioPreferences, audioDefaults } = useAudioPreferencesConfig({\n settings: cache.current.settings,\n preferences,\n });\n\n const handleCleanup = useCallback(() => {\n onCleanup?.();\n }, [onCleanup]);\n\n const { AudioNavigatorLoad, AudioNavigatorDestroy } = useAudioNavigator();\n const isNavigatorLoadedAudio = useRef(false);\n\n useEffect(() => {\n // Only initialize once, never re-render\n if (!publication || isNavigatorLoadedAudio.current) return;\n\n // Initialize navigator for Audio\n\n const config: AudioNavigatorLoadProps = {\n publication,\n listeners,\n initialPosition: initialPosition ?? undefined,\n preferences: audioPreferences,\n defaults: audioDefaults,\n contentProtection: contentProtectionConfig,\n keyboardPeripherals,\n };\n\n isNavigatorLoadedAudio.current = true;\n\n // Call onNavigatorReady outside of navigator load\n onNavigatorReady?.();\n\n // Pass onNavigatorLoaded as the callback to AudioNavigatorLoad\n AudioNavigatorLoad(config, () => {\n // Set navigatorReady to true only after navigator actually loads\n setNavigatorReady(true);\n onNavigatorLoaded?.();\n });\n\n return () => {\n if (isNavigatorLoadedAudio.current) {\n setNavigatorReady(false);\n AudioNavigatorDestroy(() => {\n isNavigatorLoadedAudio.current = false;\n handleCleanup();\n });\n }\n };\n }, []);\n\n return {\n navigatorReady,\n };\n};\n","\"use client\";\n\nimport { useMemo } from \"react\";\n\nimport { IKeyboardPeripheralsConfig } from \"@readium/navigator\";\n\nimport { useAudioActionsPreferences } from \"@/preferences/hooks/useActionsPreferences\";\n\nimport { toActionPeripheralType, toDockingPeripheralType } from \"@/helpers/peripherals\";\n\nexport const useAudioKeyboardPeripherals = (): IKeyboardPeripheralsConfig => {\n const { primaryActionsKeys, secondaryActionsKeys, primaryDisplayOrder, secondaryDisplayOrder, docking } = useAudioActionsPreferences();\n\n return useMemo(() => {\n const config: IKeyboardPeripheralsConfig = [];\n const allKeys = { ...primaryActionsKeys, ...secondaryActionsKeys };\n\n for (const [key, tokens] of Object.entries(allKeys)) {\n const shortcut = tokens?.shortcut;\n const isInOrder = primaryDisplayOrder.includes(key) || secondaryDisplayOrder.includes(key);\n if (shortcut && isInOrder) config.push({ type: toActionPeripheralType(key), keyCombos: shortcut.keyCombos });\n }\n\n for (const [key, tokens] of Object.entries(docking.keys)) {\n if (tokens?.shortcut) config.push({ type: toDockingPeripheralType(key), keyCombos: tokens.shortcut.keyCombos });\n }\n\n return config;\n }, [primaryActionsKeys, secondaryActionsKeys, primaryDisplayOrder, secondaryDisplayOrder, docking.keys]);\n};\n","/**\n * True for any browser running on the WebKit engine without Chrome's Blink layer\n * (Safari on macOS/iOS, and all iOS browsers which are forced onto WebKit).\n * Used to gate around WebKit-specific platform quirks.\n */\nexport const isWebKit = typeof navigator !== \"undefined\"\n && /webkit/i.test(navigator.userAgent)\n && !/chrome/i.test(navigator.userAgent);\n","\"use client\";\n\nimport { useLayoutEffect, useState, useMemo, useCallback, useRef, useEffect } from \"react\";\n\nimport audioLayoutStyles from \"./assets/styles/thorium-web.audio.app.module.css\";\nimport audioStyles from \"./assets/styles/thorium-web.audioPlayer.module.css\";\n\nimport { ThPluginRegistry } from \"../Plugins/PluginRegistry\";\n\nimport { ThPluginProvider } from \"../Plugins/PluginProvider\";\nimport { NavigatorProvider } from \"@/core/Navigator\";\n\nimport { Locator, Publication } from \"@readium/shared\";\nimport { ContextMenuEvent, SuspiciousActivityEvent } from \"@readium/navigator-html-injectables\";\nimport { fromActionPeripheralType, fromDockingPeripheralType } from \"@/helpers/peripherals\";\nimport { AudioNavigatorListeners, KeyboardPeripheralEventData } from \"@readium/navigator\";\nimport { PositionStorage } from \"../Reader/StatefulReaderWrapper\";\nimport { ThAudioPlayerComponent } from \"@/preferences/models\";\n\nimport { StatefulDockingWrapper } from \"../Docking/StatefulDockingWrapper\";\nimport { StatefulPlayerHeader } from \"./StatefulPlayerHeader\";\n\nimport { StatefulAudioCover } from \"./StatefulAudioCover\";\nimport { StatefulAudioMetadata } from \"./StatefulAudioMetadata\";\nimport { StatefulAudioPlaybackControls } from \"./controls/StatefulAudioPlaybackControls\";\nimport { StatefulAudioMediaActions } from \"./actions/StatefulAudioMediaActions\";\nimport { StatefulAudioProgressBar } from \"./controls/StatefulAudioProgressBar\";\n\nimport { useAudioPreferences } from \"@/preferences/hooks/useAudioPreferences\";\nimport { useAudioNavigator } from \"@/core/Hooks/Audio/useAudioNavigator\";\nimport { useAudioStatelessCache } from \"./Hooks/useAudioStatelessCache\";\nimport { useI18n } from \"@/i18n/useI18n\";\nimport { resolveAudioContentProtectionConfig } from \"@/preferences/models/protection\";\nimport { usePositionStorage } from \"@/hooks/usePositionStorage\";\nimport { useDocumentTitle } from \"@/core/Hooks/useDocumentTitle\";\nimport { useAudioPlayerInit } from \"./Hooks/useAudioPlayerInit\";\nimport { useAudioKeyboardPeripherals } from \"./Hooks/useAudioKeyboardPeripherals\";\nimport { useFocusedDockableKey } from \"../Docking/hooks/useFocusedDockableKey\";\n\nimport { useAppSelector, useAppDispatch } from \"@/lib/hooks\";\nimport {\n setLoading\n} from \"@/lib/readerReducer\";\nimport { toggleActionOpen, dockAction } from \"@/lib/actionsReducer\";\nimport { ThDockingKeys } from \"@/preferences/models\";\nimport {\n setPublicationStart,\n setPublicationEnd,\n} from \"@/lib/publicationReducer\";\nimport { useTocTreeBuilder } from \"@/core/Hooks/useTocTreeBuilder\";\nimport { useTimelineAdjacency } from \"@/core/Hooks/useTimelineAdjacency\";\nimport { useTocEntryTracking } from \"@/components/Actions/Toc/useTocEntryTracking\";\nimport { isWebKit } from \"@/helpers/browser\";\nimport { TimelineItem } from \"@readium/shared\";\nimport { \n setStatus,\n setSeeking,\n setStalled,\n setTrackReady,\n setSleepTimerOnTrackEnd,\n setSleepTimerOnFragmentEnd,\n setRemotePlaybackState,\n setSeekableRanges\n} from \"@/lib/playerReducer\";\n\nimport { createAudioDefaultPlugin } from \"../Plugins/helpers/createAudioDefaultPlugin\";\nimport debounce from \"debounce\";\n\nexport interface StatefulPlayerProps {\n publication: Publication;\n localDataKey: string | null;\n plugins?: any[];\n positionStorage?: PositionStorage;\n coverUrl?: string;\n containerRefSetter?: (el: Element | null) => void;\n}\n\nexport const StatefulPlayer = ({\n publication,\n localDataKey,\n plugins,\n positionStorage,\n coverUrl,\n containerRefSetter\n}: StatefulPlayerProps) => {\n const [pluginsRegistered, setPluginsRegistered] = useState(false);\n\n useLayoutEffect(() => {\n if (plugins && plugins.length > 0) {\n plugins.forEach(plugin => {\n ThPluginRegistry.register(plugin);\n });\n } else {\n ThPluginRegistry.register(createAudioDefaultPlugin());\n }\n setPluginsRegistered(true);\n }, [plugins]);\n\n if (!pluginsRegistered) {\n return null;\n }\n\n return (\n <ThPluginProvider>\n <StatefulPlayerInner publication={ publication } localDataKey={ localDataKey } positionStorage={ positionStorage } coverUrl={ coverUrl } containerRefSetter={ containerRefSetter } />\n </ThPluginProvider>\n );\n};\n\nconst StatefulPlayerInner = ({ publication, localDataKey, positionStorage, coverUrl, containerRefSetter }: { publication: Publication; localDataKey: string | null; positionStorage?: PositionStorage; coverUrl?: string; containerRefSetter?: (el: Element | null) => void }) => {\n const { preferences } = useAudioPreferences();\n const { t } = useI18n();\n const profile = useAppSelector(state => state.reader.profile);\n const keyboardPeripherals = useAudioKeyboardPeripherals();\n\n const wrapperRef = useRef<HTMLElement>(null);\n const coverSectionRef = useRef<HTMLElement>(null);\n const compactMinHeight = useRef<number>(0);\n const [isExpanded, setIsExpanded] = useState(false);\n\n const sleepOnTrackEnd = useAppSelector(state => state.player.sleepTimer.onTrackEnd);\n const sleepOnFragmentEnd = useAppSelector(state => state.player.sleepTimer.onFragmentEnd);\n const adjacentTimelineItems = useAppSelector(state => state.publication.adjacentTimelineItems);\n const volume = useAppSelector(state => state.audioSettings.volume);\n const playbackRate = useAppSelector(state => state.audioSettings.playbackRate);\n const preservePitch = useAppSelector(state => state.audioSettings.preservePitch);\n const skipBackwardInterval = useAppSelector(state => state.audioSettings.skipBackwardInterval);\n const skipForwardInterval = useAppSelector(state => state.audioSettings.skipForwardInterval);\n const skipInterval = useAppSelector(state => state.audioSettings.skipInterval);\n const pollInterval = useAppSelector(state => state.audioSettings.pollInterval);\n const autoPlay = useAppSelector(state => state.audioSettings.autoPlay);\n const enableMediaSession = useAppSelector(state => state.audioSettings.enableMediaSession);\n\n const cache = useAudioStatelessCache(\n volume,\n playbackRate,\n preservePitch,\n skipBackwardInterval,\n skipForwardInterval,\n skipInterval,\n pollInterval,\n autoPlay,\n enableMediaSession,\n sleepOnTrackEnd,\n sleepOnFragmentEnd,\n adjacentTimelineItems\n );\n\n const dispatch = useAppDispatch();\n const getFocusedDockableKey = useFocusedDockableKey();\n\n const audioNavigator = useAudioNavigator();\n const { canGoBackward, canGoForward, submitPreferences, pause, isPlaying, timeline: getNavigatorTimeline } = audioNavigator;\n\n const { setLocalData, getLocalData } = usePositionStorage(localDataKey, positionStorage);\n\n const documentTitle = publication?.metadata?.title?.getTranslation(\"en\");\n useDocumentTitle(documentTitle);\n\n const tocTree = useAppSelector(state => state.publication.toc?.tree);\n\n const { updateAdjacentItems, clearAdjacentItems } = useTimelineAdjacency(getNavigatorTimeline);\n const { updateCurrentTocEntry, clearCurrentTocEntry } = useTocEntryTracking(getNavigatorTimeline, tocTree);\n\n // Callback to handle timeline navigation state updates\n const handleTimelineNavigation = useCallback((item: TimelineItem) => {\n updateAdjacentItems(item);\n updateCurrentTocEntry(item);\n }, [updateAdjacentItems, updateCurrentTocEntry]);\n\n // Callback to check if affordance is timeline or toc (fragment-based)\n const isFragmentAffordance = useCallback((affordance: string) => {\n return affordance === \"timeline\" || affordance === \"toc\";\n }, []);\n\n // Callback to handle sleep timer endOfFragment logic\n const handleSleepTimerEndOfFragment = useCallback((isTransitionToNext: boolean) => {\n if (!cache.current.sleepTimerOnFragmentEnd || !isTransitionToNext) return;\n \n const nextAffordance = preferences.affordances.next;\n if (isFragmentAffordance(nextAffordance)) {\n pause();\n dispatch(setSleepTimerOnFragmentEnd(false));\n }\n }, [cache, preferences.affordances.next, isFragmentAffordance, pause, dispatch]);\n\n // Callback to handle continuous play logic\n const handleContinuousPlay = useCallback((isTransitionToNext: boolean) => {\n if (!cache.current.settings.autoPlay && isTransitionToNext) {\n if (isFragmentAffordance(preferences.affordances.next)) {\n pause();\n }\n }\n }, [cache, preferences.affordances.next, isFragmentAffordance, pause]);\n\n const listeners: AudioNavigatorListeners = useMemo(() => ({\n timelineItemChanged: (item: TimelineItem | undefined) => {\n if (!item) {\n clearCurrentTocEntry();\n clearAdjacentItems();\n return;\n }\n\n // Capture the previous \"next\" item from cache BEFORE handleTimelineNavigation updates Redux state\n const previousNextItem = cache.current.adjacentTimelineItems.next;\n const currentItemHref = getNavigatorTimeline()?.linkFor(item)?.href ?? \"\";\n\n // Update TOC entry and adjacent items (this updates Redux state)\n handleTimelineNavigation(item);\n\n // Check if we're transitioning to the next fragment by comparing current item href with previous next item href\n const isTransitionToNext = previousNextItem !== null &&\n previousNextItem.href === currentItemHref;\n\n handleSleepTimerEndOfFragment(isTransitionToNext);\n handleContinuousPlay(isTransitionToNext);\n },\n positionChanged: (locator) => {\n setLocalData(locator);\n\n if (canGoBackward()) {\n dispatch(setPublicationStart(false));\n } else {\n dispatch(setPublicationStart(true));\n }\n\n if (canGoForward()) {\n dispatch(setPublicationEnd(false));\n } else {\n dispatch(setPublicationEnd(true));\n }\n },\n trackLoaded: () => {\n dispatch(setTrackReady(true));\n dispatch(setStalled(false));\n dispatch(setStatus(isPlaying() ? \"playing\" : \"paused\"));\n },\n trackEnded: () => {\n if (cache.current.sleepTimerOnTrackEnd) {\n submitPreferences({ autoPlay: false });\n }\n if (cache.current.sleepTimerOnFragmentEnd) {\n submitPreferences({ autoPlay: false });\n dispatch(setSleepTimerOnFragmentEnd(false));\n }\n },\n metadataLoaded: () => {},\n play: () => {\n if (cache.current.sleepTimerOnTrackEnd) {\n submitPreferences({ autoPlay: cache.current.settings.autoPlay });\n dispatch(setSleepTimerOnTrackEnd(false));\n }\n dispatch(setStatus(\"playing\"));\n },\n pause: () => {\n dispatch(setStatus(\"paused\"));\n },\n stalled: (isStalled) => {\n dispatch(setStalled(isStalled));\n },\n seeking: (isSeeking) => {\n dispatch(setSeeking(isSeeking));\n },\n seekable: (timeRanges) => {\n const ranges = [];\n for (let i = 0; i < timeRanges.length; i++) {\n ranges.push({ start: timeRanges.start(i), end: timeRanges.end(i) });\n }\n dispatch(setSeekableRanges(ranges));\n },\n error: (error, locator) => {\n console.error(\"[AudioNavigator] playback error\", error, locator);\n dispatch(setStatus(\"paused\"));\n },\n remotePlaybackStateChanged: (state) => {\n if (isWebKit) return;\n dispatch(setRemotePlaybackState(state));\n },\n contentProtection: (_type: string, _detail: SuspiciousActivityEvent) => {},\n peripheral: (data: KeyboardPeripheralEventData) => {\n const actionKey = fromActionPeripheralType(data.type);\n\n if (actionKey && profile) {\n dispatch(toggleActionOpen({ key: actionKey, profile }));\n return;\n }\n\n const dockingKey = fromDockingPeripheralType(data.type);\n\n if (dockingKey && profile) {\n const actionKey = getFocusedDockableKey(dockingKey as ThDockingKeys);\n if (actionKey) {\n dispatch(dockAction({ key: actionKey, dockingKey: dockingKey as ThDockingKeys, profile }));\n }\n }\n },\n contextMenu: (_data: ContextMenuEvent) => {}\n }), [setLocalData, canGoBackward, canGoForward, isPlaying, dispatch, cache, submitPreferences, getNavigatorTimeline, handleTimelineNavigation, clearCurrentTocEntry, clearAdjacentItems, handleSleepTimerEndOfFragment, handleContinuousPlay, profile, getFocusedDockableKey]);\n\n // getLocalData() returns a plain JSON.parse()'d object on cold load (not yet a real\n // Locator instance) — the navigator calls Timeline.locate() on this at startup, which\n // needs real prototype methods (.time(), etc.), so deserialize it here at the point of use.\n const initialPosition = useMemo(() => {\n const stored = getLocalData();\n return stored ? (Locator.deserialize(stored) ?? null) : null;\n }, [getLocalData]);\n\n const { navigatorReady } = useAudioPlayerInit({\n publication,\n initialPosition,\n listeners,\n preferences,\n cache,\n contentProtectionConfig: resolveAudioContentProtectionConfig(preferences.contentProtection, t),\n keyboardPeripherals,\n onNavigatorLoaded: () => dispatch(setLoading(false)),\n });\n\n useTocTreeBuilder(publication, navigatorReady, getNavigatorTimeline);\n\n const { compact, expanded } = preferences.theming.layout;\n\n const renderPlayerComponent = useCallback((component: ThAudioPlayerComponent) => {\n switch (component) {\n case ThAudioPlayerComponent.cover:\n return <StatefulAudioCover key={ component } ref={ coverSectionRef } coverUrl={ coverUrl } title={ publication?.metadata?.title?.getTranslation(\"en\") } />;\n case ThAudioPlayerComponent.metadata:\n return publication ? <StatefulAudioMetadata key={ component } publication={ publication } /> : null;\n case ThAudioPlayerComponent.playbackControls:\n return <StatefulAudioPlaybackControls key={ component } />;\n case ThAudioPlayerComponent.progressBar:\n return <StatefulAudioProgressBar key={ component } />;\n case ThAudioPlayerComponent.mediaActions:\n return <StatefulAudioMediaActions key={ component } />;\n }\n }, [coverUrl, publication]);\n\n const renderCompactComponents = useCallback(() => {\n const coverIdx = compact.order.indexOf(ThAudioPlayerComponent.cover);\n const metaIdx = compact.order.indexOf(ThAudioPlayerComponent.metadata);\n const adjacent = coverIdx !== -1 && metaIdx !== -1 && Math.abs(coverIdx - metaIdx) === 1;\n\n if (!adjacent) {\n return compact.order.map(renderPlayerComponent);\n }\n\n const groupStart = Math.min(coverIdx, metaIdx);\n const nodes: React.ReactNode[] = [];\n for (let i = 0; i < compact.order.length; i++) {\n if (i === groupStart) {\n nodes.push(\n <div key=\"cover-metadata-group\" className={ audioStyles.coverMetadataGroup }>\n { renderPlayerComponent(compact.order[i]) }\n { renderPlayerComponent(compact.order[i + 1]) }\n </div>\n );\n i++;\n } else {\n nodes.push(renderPlayerComponent(compact.order[i]));\n }\n }\n return nodes;\n }, [compact.order, renderPlayerComponent]);\n\n useEffect(() => {\n const el = wrapperRef.current;\n if (!el) return;\n\n const check = debounce(() => {\n if (!isExpanded) {\n const overflow = el.scrollHeight - el.clientHeight;\n if (overflow > 0) {\n const coverEl = coverSectionRef.current;\n if (coverEl) {\n const minHeight = parseFloat(getComputedStyle(coverEl).minHeight) || 0;\n const newMaxHeight = coverEl.clientHeight - overflow;\n if (newMaxHeight >= minHeight) {\n el.style.setProperty(\"--th-layout-constraints-cover\", `${ newMaxHeight }px`);\n return;\n }\n }\n el.style.removeProperty(\"--th-layout-constraints-cover\");\n compactMinHeight.current = el.scrollHeight;\n setIsExpanded(true);\n } else {\n el.style.removeProperty(\"--th-layout-constraints-cover\");\n }\n } else {\n if (el.clientHeight > compactMinHeight.current) {\n setIsExpanded(false);\n }\n }\n }, 100);\n\n const observer = new ResizeObserver(check);\n\n observer.observe(el);\n return () => {\n check.clear();\n observer.disconnect();\n };\n }, [isExpanded]);\n\n return (\n <>\n <NavigatorProvider mediaNavigator={ audioNavigator }>\n <main className={ audioLayoutStyles.main }>\n <StatefulDockingWrapper>\n <div ref={ containerRefSetter } className={ audioLayoutStyles.shell }>\n <StatefulPlayerHeader\n actionKeys={ preferences.actions.secondary.displayOrder as string[] }\n actionsOrder={ preferences.actions.secondary.displayOrder as string[] }\n />\n\n <article\n ref={ wrapperRef }\n className={ isExpanded ? audioStyles.audioPlayerWrapperExpanded : audioStyles.audioPlayerWrapper }\n >\n { isExpanded ? (\n <>\n <div className={ audioStyles.audioPlayerExpandedStart }>\n { expanded.start.map(renderPlayerComponent) }\n </div>\n <div className={ audioStyles.audioPlayerExpandedEnd }>\n { expanded.end.map(renderPlayerComponent) }\n </div>\n </>\n ) : renderCompactComponents() }\n </article>\n </div>\n </StatefulDockingWrapper>\n </main>\n </NavigatorProvider>\n </>\n );\n};\n"]}
|