{"version":3,"sources":["../../../src/hooks/useCoverBlobUrl.ts","../../../src/components/Reader/StatefulReaderWrapper.tsx"],"names":["StatefulPlayer","useState","useEffect"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport { proxyUrl } from \"@/helpers/proxyUrl\";\n\nexport const useCoverBlobUrl = (coverUrl: string | undefined): { coverBlobUrl: string | undefined; coverReady: boolean } => {\n  const [coverBlobUrl, setCoverBlobUrl] = useState<string | undefined>(undefined);\n  const [coverFailed, setCoverFailed] = useState(false);\n  const revokeRef = useRef<(() => void) | undefined>(undefined);\n\n  useEffect(() => {\n    if (!coverUrl) return;\n    const controller = new AbortController();\n    const fetched = proxyUrl(coverUrl) ?? coverUrl;\n    let objectUrl: string | undefined;\n    fetch(fetched, { signal: controller.signal })\n      .then(r => r.blob())\n      .then(blob => {\n        objectUrl = URL.createObjectURL(blob);\n        revokeRef.current = () => URL.revokeObjectURL(objectUrl!);\n        setCoverBlobUrl(objectUrl);\n      })\n      .catch((err) => {\n        if (err.name === \"AbortError\") return;\n        setCoverFailed(true);\n      });\n    return () => {\n      controller.abort();\n      revokeRef.current?.();\n      revokeRef.current = undefined;\n    };\n  }, [coverUrl]);\n\n  return {\n    coverBlobUrl,\n    coverReady: !coverUrl || !!coverBlobUrl || coverFailed,\n  };\n};\n","import { lazy, Suspense, useState, useEffect } from \"react\";\n\nimport { Publication, Locator } from \"@readium/shared\";\nimport { getScriptMode } from \"@readium/navigator\";\nimport { ThThemeKeys, ThemeKeyType, useTheming } from \"@/preferences\";\n\nimport { usePreferences } from \"@/preferences/hooks/usePreferences\";\nimport { useAudioPreferences } from \"@/preferences/hooks/useAudioPreferences\";\nimport { ThAudioPreferencesProvider } from \"@/preferences/ThAudioPreferencesProvider\";\nimport { ThPreferencesProvider } from \"@/preferences/ThPreferencesProvider\";\nimport { ThI18nProvider } from \"@/i18n/ThI18nProvider\";\n\nimport { useAppSelector, useAppDispatch } from \"@/lib/hooks\";\nimport {\n  setBreakpoint,\n  setContainerBreakpoint,\n  setColorScheme,\n  setContrast,\n  setForcedColors,\n  setMonochrome,\n  setReducedMotion,\n  setReducedTransparency,\n} from \"@/lib/themeReducer\";\nimport { setFontLanguage, setCoverTheme } from \"@/lib/publicationReducer\";\nimport { propsToCSSVars } from \"@/core/Helpers/propsToCSSVars\";\nimport { prefixString } from \"@/core/Helpers/prefixString\";\nimport { useCoverBlobUrl } from \"@/hooks/useCoverBlobUrl\";\nimport { ThPlugin } from \"../Plugins\";\nimport { StatefulLoader } from \"@/components/Misc\";\nimport { ThPreferences, CustomizableKeys } from \"@/preferences/preferences\";\nimport { ThAudioPreferences } from \"@/preferences/audioPreferences\";\nimport { ThPreferencesAdapter } from \"@/preferences/adapters/ThPreferencesAdapter\";\nimport { ThAudioPreferencesAdapter } from \"@/preferences/adapters/ThAudioPreferencesAdapter\";\nimport { InitOptions } from \"i18next\";\n\nconst StatefulEpubReader = lazy(() => import(\"@/components/Epub\").then(mod => ({ default: mod.StatefulReader })));\nconst StatefulWebPubReader = lazy(() => import(\"@/components/WebPub\").then(mod => ({ default: mod.ExperimentalWebPubStatefulReader })));\nconst StatefulPlayer = lazy(() => import(\"@/components/Audio\").then(mod => ({ default: mod.StatefulPlayer })));\n\nexport interface PositionStorage {\n  get: () => Locator | undefined;\n  set: (locator: Locator) => void | Promise<void>;\n}\n\nexport interface StatefulReaderProps {\n  publication: Publication;\n  localDataKey: string | null;\n  plugins?: ThPlugin[];\n  positionStorage?: PositionStorage;\n  containerRefSetter?: (el: Element | null) => void;\n}\n\nexport type ThPluginFactory = () => ThPlugin[] | Promise<ThPlugin[]>;\n\nexport interface ReaderPlugins {\n  epub?: ThPluginFactory;\n  webPub?: ThPluginFactory;\n  audio?: ThPluginFactory;\n}\n\nexport interface ReaderComponentProps<\n  P extends \"epub\" | \"webPub\" | \"audio\" | undefined | null = undefined,\n  K extends CustomizableKeys = {}\n> {\n  profile: P;\n  publication: Publication;\n  localDataKey: string | null;\n  isLoading?: boolean;\n  positionStorage?: PositionStorage;\n  plugins?: ReaderPlugins;\n  i18n?: Partial<InitOptions>;\n  preferences?: P extends \"audio\"\n    ? { initialPreferences?: ThAudioPreferences<K>; adapter?: ThAudioPreferencesAdapter<K> }\n    : P extends \"epub\" | \"webPub\"\n    ? { initialPreferences?: ThPreferences<K>; adapter?: ThPreferencesAdapter<K> }\n    : never;\n}\n\n// ─── Outer wrapper — selects provider based on profile ────────────────────────\n\nexport const StatefulReaderWrapper = ({ profile, plugins, isLoading, preferences, i18n: i18nOptions, ...props }: ReaderComponentProps<any, any>) => {\n  const [resolvedPlugins, setResolvedPlugins] = useState<ThPlugin[] | undefined>(undefined);\n\n  const pendingFactory = profile === \"epub\" ? plugins?.epub\n    : profile === \"webPub\" ? plugins?.webPub\n    : profile === \"audio\" ? plugins?.audio\n    : undefined;\n\n  useEffect(() => {\n    if (!pendingFactory) return;\n    const result = pendingFactory();\n    if (result instanceof Promise) {\n      result.then(setResolvedPlugins);\n    } else {\n      setResolvedPlugins(result);\n    }\n  }, [pendingFactory]);\n\n  if (pendingFactory && resolvedPlugins === undefined) return null;\n\n  const coverUrl = props.publication?.getCover()?.toURL(props.publication.baseURL);\n\n  if (profile === \"audio\") {\n    return (\n      <ThAudioPreferencesProvider\n        devMode={ process.env.NODE_ENV !== \"production\" }\n        initialPreferences={ preferences?.initialPreferences as ThAudioPreferences<any> | undefined }\n        adapter={ preferences?.adapter as ThAudioPreferencesAdapter<any> | undefined }\n      >\n        <ThI18nProvider { ...i18nOptions }>\n          <StatefulAudioContent { ...props } coverUrl={ coverUrl } externalLoading={ isLoading ?? false } />\n        </ThI18nProvider>\n      </ThAudioPreferencesProvider>\n    );\n  }\n\n  return (\n    <ThPreferencesProvider\n      devMode={ process.env.NODE_ENV !== \"production\" }\n      initialPreferences={ preferences?.initialPreferences as ThPreferences<any> | undefined }\n      adapter={ preferences?.adapter as ThPreferencesAdapter<any> | undefined }\n    >\n      <ThI18nProvider { ...i18nOptions }>\n        <StatefulLoader isLoading={ isLoading ?? false }>\n          <StatefulReaderContent profile={ profile } { ...props } coverUrl={ coverUrl } plugins={ resolvedPlugins } />\n        </StatefulLoader>\n      </ThI18nProvider>\n    </ThPreferencesProvider>\n  );\n};\n\n// ─── Audio inner content ──────────────────────────────────────────────────────\n\ninterface AudioContentProps {\n  publication: Publication;\n  localDataKey: string | null;\n  positionStorage?: PositionStorage;\n  coverUrl?: string;\n  externalLoading: boolean;\n}\n\nconst StatefulAudioContent = ({ publication, localDataKey, positionStorage, coverUrl, externalLoading }: AudioContentProps) => {\n  const { preferences } = useAudioPreferences();\n  const themeObject = useAppSelector(state => state.theming.theme);\n  const dispatch = useAppDispatch();\n\n  const { coverBlobUrl, coverReady } = useCoverBlobUrl(coverUrl);\n\n  const { themeResolved, setContainerRef } = useTheming<ThemeKeyType>({\n    theme: themeObject.audio ?? \"auto\",\n    themeKeys: preferences.theming.themes.keys,\n    systemKeys: preferences.theming.themes.systemThemes,\n    breakpointsMap: preferences.theming.breakpoints,\n    coverUrl: coverBlobUrl,\n    autoThemeSource: \"cover\",\n    initProps: {\n      ...propsToCSSVars(preferences.theming.icon, { prefix: prefixString(\"icon\") }),\n      ...propsToCSSVars(preferences.theming.layout, {\n        prefix: prefixString(\"layout\"),\n        exclude: [\"ui\", \"compact\", \"expanded\", \"progressBar\"]\n      })\n    },\n    onCoverThemeGenerated: (themeTokens) => dispatch(setCoverTheme(themeTokens)),\n    onBreakpointChange: (breakpoint) => dispatch(setBreakpoint(breakpoint)),\n    onContainerBreakpointChange: (breakpoint) => dispatch(setContainerBreakpoint(breakpoint)),\n    onColorSchemeChange: (colorScheme) => dispatch(setColorScheme(colorScheme)),\n    onContrastChange: (contrast) => dispatch(setContrast(contrast)),\n    onForcedColorsChange: (forcedColors) => dispatch(setForcedColors(forcedColors)),\n    onMonochromeChange: (isMonochrome) => dispatch(setMonochrome(isMonochrome)),\n    onReducedMotionChange: (reducedMotion) => dispatch(setReducedMotion(reducedMotion)),\n    onReducedTransparencyChange: (reducedTransparency) => dispatch(setReducedTransparency(reducedTransparency))\n  });\n\n  return (\n    <StatefulLoader isLoading={ externalLoading || !themeResolved || !coverReady }>\n      <Suspense>\n        <StatefulPlayer publication={ publication } localDataKey={ localDataKey } positionStorage={ positionStorage } coverUrl={ coverBlobUrl } containerRefSetter={ setContainerRef } />\n      </Suspense>\n    </StatefulLoader>\n  );\n};\n\n// ─── Reader inner content ─────────────────────────────────────────────────────\n\ninterface ReaderContentProps {\n  profile: \"epub\" | \"webPub\" | undefined | null;\n  publication: Publication;\n  localDataKey: string | null;\n  positionStorage?: PositionStorage;\n  plugins?: ThPlugin[];\n  coverUrl?: string;\n}\n\nconst StatefulReaderContent = ({ profile, publication, plugins, coverUrl, ...props }: ReaderContentProps) => {\n  const { preferences, resolveFontLanguage } = usePreferences();\n  const themeObject = useAppSelector(state => state.theming.theme);\n  const isFXL = useAppSelector(state => state.publication.isFXL);\n  const theme = profile === \"epub\" ? (isFXL ? themeObject.fxl : themeObject.reflow) : ThThemeKeys.light;\n  const dispatch = useAppDispatch();\n\n  useEffect(() => {\n    if (!publication) return;\n    const resolvedLang = resolveFontLanguage(\n      publication.metadata.languages?.[0],\n      getScriptMode(publication.metadata)\n    );\n    dispatch(setFontLanguage(resolvedLang));\n  }, [publication, resolveFontLanguage, dispatch]);\n\n  const { setContainerRef } = useTheming<ThemeKeyType>({\n    theme,\n    themeKeys: preferences.theming.themes.keys,\n    systemKeys: preferences.theming.themes.systemThemes,\n    breakpointsMap: preferences.theming.breakpoints,\n    coverUrl,\n    autoThemeSource: \"system\",\n    initProps: {\n      ...propsToCSSVars(preferences.theming.arrow, { prefix: prefixString(\"arrow\") }),\n      ...propsToCSSVars(preferences.theming.icon, { prefix: prefixString(\"icon\") }),\n      ...propsToCSSVars(preferences.theming.layout, {\n        prefix: prefixString(\"layout\"),\n        exclude: [\"ui\"]\n      })\n    },\n    onCoverThemeGenerated: (themeTokens) => dispatch(setCoverTheme(themeTokens)),\n    onBreakpointChange: (breakpoint) => dispatch(setBreakpoint(breakpoint)),\n    onContainerBreakpointChange: (breakpoint) => dispatch(setContainerBreakpoint(breakpoint)),\n    onColorSchemeChange: (colorScheme) => dispatch(setColorScheme(colorScheme)),\n    onContrastChange: (contrast) => dispatch(setContrast(contrast)),\n    onForcedColorsChange: (forcedColors) => dispatch(setForcedColors(forcedColors)),\n    onMonochromeChange: (isMonochrome) => dispatch(setMonochrome(isMonochrome)),\n    onReducedMotionChange: (reducedMotion) => dispatch(setReducedMotion(reducedMotion)),\n    onReducedTransparencyChange: (reducedTransparency) => dispatch(setReducedTransparency(reducedTransparency))\n  });\n\n  switch (profile) {\n    case \"epub\":\n      return <Suspense><StatefulEpubReader publication={ publication } { ...props } plugins={ plugins } containerRefSetter={ setContainerRef } /></Suspense>;\n    case \"webPub\":\n    default:\n      return <Suspense><StatefulWebPubReader publication={ publication } { ...props } plugins={ plugins } containerRefSetter={ setContainerRef } /></Suspense>;\n  }\n};\n"]}