@eternalheart/react-file-preview 1.5.1 → 1.5.2
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/lib/chunks/{index-Dta7iGov.mjs → index-37FMdXja.mjs} +2 -2
- package/lib/chunks/{index-Dta7iGov.mjs.map → index-37FMdXja.mjs.map} +1 -1
- package/lib/chunks/{index-BFh22D_W.mjs → index-7aRho9r4.mjs} +3 -3
- package/lib/chunks/{index-BFh22D_W.mjs.map → index-7aRho9r4.mjs.map} +1 -1
- package/lib/chunks/{index-CgFv7B_G.mjs → index-BXa7r4uK.mjs} +3 -3
- package/lib/chunks/{index-CgFv7B_G.mjs.map → index-BXa7r4uK.mjs.map} +1 -1
- package/lib/chunks/{index-COOUxB5e.mjs → index-BaSsmMZP.mjs} +2 -2
- package/lib/chunks/{index-COOUxB5e.mjs.map → index-BaSsmMZP.mjs.map} +1 -1
- package/lib/chunks/{index-fSw6Hl5e.mjs → index-Bn0NJNzq.mjs} +2 -2
- package/lib/chunks/{index-fSw6Hl5e.mjs.map → index-Bn0NJNzq.mjs.map} +1 -1
- package/lib/chunks/{index-fQGAUFAX.mjs → index-Btsr3v83.mjs} +2 -2
- package/lib/chunks/{index-fQGAUFAX.mjs.map → index-Btsr3v83.mjs.map} +1 -1
- package/lib/chunks/{index-Bw3Fh4b5.mjs → index-C2uu09Eb.mjs} +2 -2
- package/lib/chunks/{index-Bw3Fh4b5.mjs.map → index-C2uu09Eb.mjs.map} +1 -1
- package/lib/chunks/{index-vRLKumL8.mjs → index-C5o_T3Es.mjs} +18 -19
- package/lib/chunks/index-C5o_T3Es.mjs.map +1 -0
- package/lib/chunks/{index-Cn4ZyhGM.mjs → index-CMehLA91.mjs} +2 -2
- package/lib/chunks/{index-Cn4ZyhGM.mjs.map → index-CMehLA91.mjs.map} +1 -1
- package/lib/chunks/{index-jvNrkVkp.mjs → index-CTEgp9x8.mjs} +2 -2
- package/lib/chunks/{index-jvNrkVkp.mjs.map → index-CTEgp9x8.mjs.map} +1 -1
- package/lib/chunks/{index-DreA69iU.mjs → index-Cbp94jbP.mjs} +20 -20
- package/lib/chunks/{index-DreA69iU.mjs.map → index-Cbp94jbP.mjs.map} +1 -1
- package/lib/chunks/{index-CU1Lc3lV.mjs → index-CmK5E5Oa.mjs} +3 -3
- package/lib/chunks/{index-CU1Lc3lV.mjs.map → index-CmK5E5Oa.mjs.map} +1 -1
- package/lib/chunks/index-CyBXARuf.mjs +5215 -0
- package/lib/chunks/index-CyBXARuf.mjs.map +1 -0
- package/lib/chunks/{index-DVtPyN-s.mjs → index-DTNdG1bB.mjs} +3 -3
- package/lib/chunks/{index-DVtPyN-s.mjs.map → index-DTNdG1bB.mjs.map} +1 -1
- package/lib/chunks/{index-oVJyD-FV.mjs → index-DfzgQFfx.mjs} +2 -2
- package/lib/chunks/{index-oVJyD-FV.mjs.map → index-DfzgQFfx.mjs.map} +1 -1
- package/lib/chunks/{index-CEC_DHgr.mjs → index-DsIUJXpz.mjs} +8 -9
- package/lib/chunks/index-DsIUJXpz.mjs.map +1 -0
- package/lib/chunks/{index-DGNNEnWE.mjs → index-DxUP4apX.mjs} +2 -2
- package/lib/chunks/{index-DGNNEnWE.mjs.map → index-DxUP4apX.mjs.map} +1 -1
- package/lib/chunks/{index-BBYKNNLb.mjs → index-HRUhzosx.mjs} +2 -2
- package/lib/chunks/{index-BBYKNNLb.mjs.map → index-HRUhzosx.mjs.map} +1 -1
- package/lib/chunks/{index-BKXvtJh5.mjs → index-VnjkEX5p.mjs} +2 -2
- package/lib/chunks/{index-BKXvtJh5.mjs.map → index-VnjkEX5p.mjs.map} +1 -1
- package/lib/chunks/{index-DLk08ylq.mjs → index-qWLZuYn6.mjs} +2 -2
- package/lib/chunks/{index-DLk08ylq.mjs.map → index-qWLZuYn6.mjs.map} +1 -1
- package/lib/chunks/{useShikiHighlight-C6nJcETW.mjs → useShikiHighlight-BG7pCfB5.mjs} +2 -2
- package/lib/chunks/{useShikiHighlight-C6nJcETW.mjs.map → useShikiHighlight-BG7pCfB5.mjs.map} +1 -1
- package/lib/index.cjs +1 -1
- package/lib/index.cjs.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.mjs +1 -1
- package/lib/renderers/Csv/index.d.ts +0 -1
- package/lib/renderers/Csv/index.d.ts.map +1 -1
- package/lib/renderers/Xlsx/index.d.ts +0 -1
- package/lib/renderers/Xlsx/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/lib/chunks/index-CEC_DHgr.mjs.map +0 -1
- package/lib/chunks/index-vRLKumL8.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-fQGAUFAX.mjs","sources":["../../src/renderers/Mobi/index.tsx"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n useCallback,\n useImperativeHandle,\n forwardRef,\n} from 'react';\nimport { X, ChevronLeft, ChevronRight, Maximize2, Minimize2, List } from 'lucide-react';\nimport 'foliate-js/view.js';\nimport type { FoliateView, TocItem } from 'foliate-js/view.js';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nconst READER_CSS = `\n @namespace epub \"http://www.idpf.org/2007/ops\";\n html { color-scheme: light; }\n body {\n background: #ffffff !important;\n color: #1a1a1a !important;\n font-family: \"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important;\n font-size: 16px !important;\n line-height: 2 !important;\n max-width: 100% !important;\n box-sizing: border-box !important;\n word-break: break-word !important;\n overflow-wrap: break-word !important;\n }\n p, li, blockquote, dd { line-height: 2; text-align: justify; }\n p { text-indent: 2em; margin: 0.8em 0; }\n h1 { text-align: center; margin: 1.5em 0 1em; }\n h2 { margin: 1.2em 0 0.8em; }\n h3 { margin: 1em 0 0.6em; }\n img { max-width: 100% !important; height: auto !important; }\n a { color: #2563eb; text-decoration: none; }\n pre { white-space: pre-wrap !important; }\n`;\n\nconst A4_WIDTH = 794;\n\nexport interface MobiRendererHandle extends RendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface MobiRendererProps {\n url: string;\n}\n\nexport const MobiRenderer = forwardRef<MobiRendererHandle, MobiRendererProps>(\n ({ url }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const hostRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<FoliateView | null>(null);\n\n // 模拟 epub.js 的 locations 显示\n const totalLocationsRef = useRef(1);\n\n // 内部状态管理\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const [isFullWidth, setIsFullWidth] = useState(false);\n const [currentChapter, setCurrentChapter] = useState(0);\n const [totalChapters, setTotalChapters] = useState(0);\n const isFullWidthRef = useRef(false);\n isFullWidthRef.current = isFullWidth;\n\n const reportProgress = useCallback((current: number, total: number) => {\n if (total > 0) totalLocationsRef.current = total;\n setCurrentChapter(Math.max(1, current + 1));\n setTotalChapters(totalLocationsRef.current);\n }, []);\n\n const handlePrev = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.prev().catch(() => {});\n }, []);\n\n const handleNext = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.next().catch(() => {});\n }, []);\n\n const toggleToc = useCallback(() => setShowToc((prev) => !prev), []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n // 宽度改变后 paginator 需要重新分页\n const view = viewRef.current;\n if (!view) return;\n const renderer = (view as unknown as { renderer?: HTMLElement }).renderer;\n if (renderer) {\n renderer.setAttribute('max-inline-size', newVal ? '9999' : '720');\n }\n }, []);\n\n // 事件发射器:用于通知主组件工具栏状态变化\n const listenersRef = useRef<Set<() => void>>(new Set());\n const notifyToolbarChange = useCallback(() => {\n listenersRef.current.forEach(listener => listener());\n }, []);\n\n // 监听影响工具栏的状态变化\n useEffect(() => {\n notifyToolbarChange();\n }, [currentChapter, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [totalChapters, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [isFullWidth, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [toc.length, notifyToolbarChange]);\n\n // 工具栏配置\n const getToolbarGroups = useCallback((): ToolbarGroup[] => [\n {\n items: [\n { type: 'button', icon: <List className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.toc'), action: toggleToc, disabled: toc.length === 0, active: showToc },\n ],\n },\n {\n items: [\n { type: 'button', icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.prev_page'), action: handlePrev, disabled: currentChapter <= 1 },\n { type: 'text', content: `${currentChapter} / ${totalChapters}`, minWidth: '4rem' },\n { type: 'button', icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.next_page'), action: handleNext, disabled: currentChapter >= totalChapters },\n ],\n },\n {\n items: [\n { type: 'button', icon: isFullWidth ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" /> : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />, tooltip: isFullWidth ? t('toolbar.normal_width') : t('toolbar.full_width'), action: toggleFullWidth, active: isFullWidth },\n ],\n },\n ], [currentChapter, totalChapters, isFullWidth, showToc, toc.length, t, handlePrev, handleNext, toggleToc, toggleFullWidth]);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n setShowToc(false);\n viewRef.current?.goTo(href).catch(() => {});\n }, []);\n\n useImperativeHandle(ref, () => ({\n getToolbarGroups,\n onToolbarChange: (listener: () => void) => {\n listenersRef.current.add(listener);\n return () => listenersRef.current.delete(listener);\n },\n prevPage: handlePrev,\n nextPage: handleNext,\n toggleFullWidth,\n toggleToc,\n }), [getToolbarGroups, handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n // 吞掉 foliate-js paginator 卸载/切换窗口期由 ResizeObserver 触发的 uncaught error。\n // 上游 bug:Paginator.destroy 里 unobserve 目标错了(unobserve(this) 而非 unobserve(container)),\n // observer 从未真正解除,view 已经半 destroy 时仍会触发一次 render,此时 #view / iframe body 已 null。\n // 已知触发:\n // - \"Cannot destructure property 'style' of 'el' as it is null\" (setStylesImportant)\n // - \"Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'\" (#replaceBackground)\n useEffect(() => {\n const handler = (e: ErrorEvent) => {\n if (e.filename?.includes('paginator')) {\n e.preventDefault();\n }\n };\n window.addEventListener('error', handler);\n return () => window.removeEventListener('error', handler);\n }, []);\n\n useEffect(() => {\n const host = hostRef.current;\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (!host || !url) return;\n\n let cancelled = false;\n let view: FoliateView | null = null;\n let progressReported = false;\n // 多 section 文件的页码累加器:记录各 section 的实际页数\n const sectionPagesMap = new Map<number, number>();\n\n const load = async () => {\n if (cancelled) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n setActiveTocHref('');\n host.replaceChildren();\n\n try {\n view = document.createElement('foliate-view') as FoliateView;\n host.appendChild(view);\n viewRef.current = view;\n\n // 先注册事件\n view.addEventListener('relocate', (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (!detail) return;\n\n const currentView = viewRef.current;\n const sectionCount = currentView?.book?.sections.length ?? 0;\n const renderer = (currentView as unknown as {\n renderer?: {\n page?: number;\n pages?: number;\n getContents?: () => Array<{ index: number }>;\n };\n } | null)?.renderer;\n\n // 用 Paginator 的 page/pages 得到精确翻页数:\n // - 单 section:pages - 2 就是全书总页数\n // - 多 section:记录已翻过的 section 的 pages,累加得到全书页码\n const sectionIdx = renderer?.getContents?.()[0]?.index ?? -1;\n if (\n renderer\n && typeof renderer.page === 'number'\n && typeof renderer.pages === 'number'\n && renderer.pages > 2\n && sectionIdx >= 0\n ) {\n progressReported = true;\n const curSectionPages = renderer.pages - 2;\n // 更新当前 section 的实际页数(每次进入该 section 都刷新,防止首次未 render 完整)\n sectionPagesMap.set(sectionIdx, curSectionPages);\n\n // 累加已确知的前置 section pages\n let pagesBefore = 0;\n for (let i = 0; i < sectionIdx; i++) {\n pagesBefore += sectionPagesMap.get(i) ?? 0;\n }\n const currentPage = pagesBefore + Math.min(curSectionPages, Math.max(1, renderer.page));\n\n // total 策略:\n // - 单 section:pages - 2 就是全书精确页数\n // - 多 section:用\"当前 section 字符/页数比\"外推未访问 section 的 pages。\n // 同一本书字体、行距、页宽恒定,比率稳定,比 SectionProgress 字符估算准得多。\n // 翻到末页(fraction ≈ 1)时用 currentPage 覆盖,得到真实总数。\n const atEnd = (detail.fraction ?? 0) >= 0.999;\n let total: number;\n if (sectionCount === 1) {\n total = curSectionPages;\n } else if (atEnd) {\n total = currentPage;\n } else {\n const sections = currentView?.book?.sections ?? [];\n const curSize = (sections[sectionIdx] as { size?: number } | undefined)?.size ?? 0;\n const ratio = curSize > 0 ? curSectionPages / curSize : 0;\n let est = 0;\n for (let i = 0; i < sectionCount; i++) {\n if (sectionPagesMap.has(i)) {\n est += sectionPagesMap.get(i)!;\n } else {\n const s = (sections[i] as { size?: number } | undefined)?.size ?? 0;\n est += Math.max(1, Math.round(s * ratio));\n }\n }\n total = Math.max(currentPage, est);\n }\n\n reportProgress(currentPage - 1, total);\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) setActiveTocHref(tocItem.href);\n return;\n }\n\n // 兜底:SectionProgress.location(基于字符数估算)\n const loc = detail.location as { current?: number; total?: number } | undefined;\n if (loc && typeof loc.current === 'number' && typeof loc.total === 'number') {\n progressReported = true;\n // 当翻到末尾时(fraction 达到 1 表示全书 100%),用 current + 1 作为实际可达的 total,\n // 覆盖 SectionProgress 基于字符数向上取整的估算值(会高估)\n const atEnd = (detail.fraction ?? 0) >= 0.999;\n const actualTotal = atEnd ? loc.current + 1 : loc.total;\n reportProgress(loc.current, actualTotal);\n } else {\n // fallback:用 section 级别估算\n const sections = viewRef.current?.book?.sections ?? [];\n const idx = detail.index ?? 0;\n const frac = detail.fraction ?? 0;\n const total = Math.max(sections.length, 1);\n const current = Math.round((idx + frac) / total * total);\n reportProgress(current, total);\n }\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) {\n setActiveTocHref(tocItem.href);\n }\n });\n\n const res = await fetcher(url);\n if (cancelled) return;\n if (!res.ok) throw new Error(`请求失败: ${res.status}`);\n const blob = await res.blob();\n if (cancelled) return;\n let name = 'book.mobi';\n try {\n const u = new URL(url, window.location.href);\n const base = u.pathname.split('/').pop();\n if (base) name = decodeURIComponent(base);\n } catch { /* blob: URL */ }\n const file = new File([blob], name);\n\n await view.open(file);\n if (cancelled) { view.book?.destroy?.(); return; }\n\n // 配置 paginator:paginated 模式(默认),带动画\n const renderer = (view as unknown as { renderer: HTMLElement & {\n setStyles?: (css: string) => void;\n next?: () => Promise<void>;\n } }).renderer;\n\n if (renderer) {\n // flow=\"paginated\" 是默认值,不需要显式设置\n renderer.setAttribute('animated', '');\n renderer.setAttribute('max-inline-size', '720');\n renderer.setAttribute('margin', '48');\n renderer.setAttribute('gap', '5%');\n // 必须调 next() 渲染首页\n await renderer.next?.();\n // setStyles 依赖 view.document 存在,必须在 next() 触发首次渲染后调用\n renderer.setStyles?.(READER_CSS);\n }\n if (cancelled) return;\n\n setToc(view.book?.toc ?? []);\n setLoading(false);\n // 只在 relocate 事件从未报告 progress 时使用 sections.length 作为 fallback,\n // 避免覆盖 SectionProgress 报告的更准确的 total(通常在首页 render 时通过 relocate 已报告)\n if (!progressReported) {\n reportProgress(0, view.book?.sections.length ?? 1);\n }\n } catch (err) {\n // MOBI/EPUB 加载错误通常是文件损坏或 DRM 保护,用 warn 级别记录\n console.warn('[MobiRenderer] Failed to load ebook:', err instanceof Error ? err.message : String(err));\n if (!cancelled) {\n setError(t('mobi.load_failed'));\n setLoading(false);\n }\n }\n };\n\n // 延迟到 microtask 队列执行,让 StrictMode 的第一次 cleanup 有机会取消,\n // 避免两个并发的 view.open() 污染 foliate-js MOBI 解析器内部状态\n Promise.resolve().then(load);\n\n return () => {\n cancelled = true;\n try { (view as unknown as { close?: () => void })?.close?.(); } catch { /* ignore */ }\n try { view?.book?.destroy?.(); } catch { /* ignore */ }\n if (view && view.parentNode === host) {\n try { host.removeChild(view); } catch { /* ignore */ }\n }\n if (viewRef.current === view) viewRef.current = null;\n };\n }, [url, reportProgress, t]);\n\n const isActive = useCallback(\n (href: string | undefined) => !!href && href === activeTocHref,\n [activeTocHref]\n );\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ listStyle: 'none', padding: 0, margin: depth > 0 ? '0 0 0 16px' : 0 }}>\n {items.map((item, i) => (\n <li key={`${item.href ?? item.label}-${i}`}>\n {item.href ? (\n <button\n onClick={() => handleTocClick(item.href!)}\n className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${\n isActive(item.href)\n ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n }`}\n title={item.label}\n >\n {item.label?.trim()}\n </button>\n ) : (\n <div className=\"rfp-w-full rfp-py-2 rfp-px-3 rfp-text-sm rfp-text-fg-tertiary rfp-truncate\">\n {item.label?.trim()}\n </div>\n )}\n {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n ))}\n </ul>\n );\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-surface-1 rfp-overflow-hidden\">\n {error && <RendererError message={error} />}\n\n {loading && !error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {/* 目录侧栏 */}\n {toc.length > 0 && (\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n style={{ opacity: showToc ? 1 : 0, pointerEvents: showToc ? 'auto' : 'none' }}\n >\n <div\n className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n >\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n <button\n onClick={() => setShowToc(false)}\n className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n >\n <X className=\"rfp-w-4 rfp-h-4\" />\n </button>\n </div>\n <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n {renderTocItems(toc)}\n </div>\n </div>\n <div\n className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n onClick={() => setShowToc(false)}\n />\n </div>\n )}\n\n {!error && (\n <div\n ref={hostRef}\n className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n style={{\n width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n maxWidth: '100%',\n transition: 'width 0.3s ease',\n }}\n />\n )}\n </div>\n );\n }\n);\n\nMobiRenderer.displayName = 'MobiRenderer';\n"],"names":["READER_CSS","A4_WIDTH","MobiRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","hostRef","useRef","viewRef","totalLocationsRef","loading","setLoading","useState","error","setError","toc","setToc","showToc","setShowToc","activeTocHref","setActiveTocHref","isFullWidth","setIsFullWidth","currentChapter","setCurrentChapter","totalChapters","setTotalChapters","isFullWidthRef","reportProgress","useCallback","current","total","handlePrev","view","handleNext","toggleToc","prev","toggleFullWidth","newVal","renderer","listenersRef","notifyToolbarChange","listener","useEffect","getToolbarGroups","List","jsx","ChevronLeft","ChevronRight","Minimize2","Maximize2","handleTocClick","href","_a","useImperativeHandle","handler","e","host","cancelled","progressReported","sectionPagesMap","load","detail","currentView","sectionCount","sectionIdx","curSectionPages","pagesBefore","i","currentPage","atEnd","sections","_d","curSize","_e","ratio","est","s","_f","tocItem","loc","actualTotal","_h","_g","idx","frac","res","blob","name","base","file","_b","_c","err","isActive","renderTocItems","items","depth","item","jsxs","RendererError","X"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-Btsr3v83.mjs","sources":["../../src/renderers/Mobi/index.tsx"],"sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n useCallback,\n useImperativeHandle,\n forwardRef,\n} from 'react';\nimport { X, ChevronLeft, ChevronRight, Maximize2, Minimize2, List } from 'lucide-react';\nimport 'foliate-js/view.js';\nimport type { FoliateView, TocItem } from 'foliate-js/view.js';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nconst READER_CSS = `\n @namespace epub \"http://www.idpf.org/2007/ops\";\n html { color-scheme: light; }\n body {\n background: #ffffff !important;\n color: #1a1a1a !important;\n font-family: \"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important;\n font-size: 16px !important;\n line-height: 2 !important;\n max-width: 100% !important;\n box-sizing: border-box !important;\n word-break: break-word !important;\n overflow-wrap: break-word !important;\n }\n p, li, blockquote, dd { line-height: 2; text-align: justify; }\n p { text-indent: 2em; margin: 0.8em 0; }\n h1 { text-align: center; margin: 1.5em 0 1em; }\n h2 { margin: 1.2em 0 0.8em; }\n h3 { margin: 1em 0 0.6em; }\n img { max-width: 100% !important; height: auto !important; }\n a { color: #2563eb; text-decoration: none; }\n pre { white-space: pre-wrap !important; }\n`;\n\nconst A4_WIDTH = 794;\n\nexport interface MobiRendererHandle extends RendererHandle {\n prevPage: () => void;\n nextPage: () => void;\n toggleFullWidth: () => void;\n toggleToc: () => void;\n}\n\ninterface MobiRendererProps {\n url: string;\n}\n\nexport const MobiRenderer = forwardRef<MobiRendererHandle, MobiRendererProps>(\n ({ url }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const hostRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<FoliateView | null>(null);\n\n // 模拟 epub.js 的 locations 显示\n const totalLocationsRef = useRef(1);\n\n // 内部状态管理\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [toc, setToc] = useState<TocItem[]>([]);\n const [showToc, setShowToc] = useState(false);\n const [activeTocHref, setActiveTocHref] = useState<string>('');\n const [isFullWidth, setIsFullWidth] = useState(false);\n const [currentChapter, setCurrentChapter] = useState(0);\n const [totalChapters, setTotalChapters] = useState(0);\n const isFullWidthRef = useRef(false);\n isFullWidthRef.current = isFullWidth;\n\n const reportProgress = useCallback((current: number, total: number) => {\n if (total > 0) totalLocationsRef.current = total;\n setCurrentChapter(Math.max(1, current + 1));\n setTotalChapters(totalLocationsRef.current);\n }, []);\n\n const handlePrev = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.prev().catch(() => {});\n }, []);\n\n const handleNext = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n view.next().catch(() => {});\n }, []);\n\n const toggleToc = useCallback(() => setShowToc((prev) => !prev), []);\n\n const toggleFullWidth = useCallback(() => {\n const newVal = !isFullWidthRef.current;\n setIsFullWidth(newVal);\n // 宽度改变后 paginator 需要重新分页\n const view = viewRef.current;\n if (!view) return;\n const renderer = (view as unknown as { renderer?: HTMLElement }).renderer;\n if (renderer) {\n renderer.setAttribute('max-inline-size', newVal ? '9999' : '720');\n }\n }, []);\n\n // 事件发射器:用于通知主组件工具栏状态变化\n const listenersRef = useRef<Set<() => void>>(new Set());\n const notifyToolbarChange = useCallback(() => {\n listenersRef.current.forEach(listener => listener());\n }, []);\n\n // 监听影响工具栏的状态变化\n useEffect(() => {\n notifyToolbarChange();\n }, [currentChapter, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [totalChapters, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [isFullWidth, notifyToolbarChange]);\n\n useEffect(() => {\n notifyToolbarChange();\n }, [toc.length, notifyToolbarChange]);\n\n // 工具栏配置\n const getToolbarGroups = useCallback((): ToolbarGroup[] => [\n {\n items: [\n { type: 'button', icon: <List className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.toc'), action: toggleToc, disabled: toc.length === 0, active: showToc },\n ],\n },\n {\n items: [\n { type: 'button', icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.prev_page'), action: handlePrev, disabled: currentChapter <= 1 },\n { type: 'text', content: `${currentChapter} / ${totalChapters}`, minWidth: '4rem' },\n { type: 'button', icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.next_page'), action: handleNext, disabled: currentChapter >= totalChapters },\n ],\n },\n {\n items: [\n { type: 'button', icon: isFullWidth ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" /> : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />, tooltip: isFullWidth ? t('toolbar.normal_width') : t('toolbar.full_width'), action: toggleFullWidth, active: isFullWidth },\n ],\n },\n ], [currentChapter, totalChapters, isFullWidth, showToc, toc.length, t, handlePrev, handleNext, toggleToc, toggleFullWidth]);\n\n const handleTocClick = useCallback((href: string) => {\n setActiveTocHref(href);\n setShowToc(false);\n viewRef.current?.goTo(href).catch(() => {});\n }, []);\n\n useImperativeHandle(ref, () => ({\n getToolbarGroups,\n onToolbarChange: (listener: () => void) => {\n listenersRef.current.add(listener);\n return () => listenersRef.current.delete(listener);\n },\n prevPage: handlePrev,\n nextPage: handleNext,\n toggleFullWidth,\n toggleToc,\n }), [getToolbarGroups, handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n // 吞掉 foliate-js paginator 卸载/切换窗口期由 ResizeObserver 触发的 uncaught error。\n // 上游 bug:Paginator.destroy 里 unobserve 目标错了(unobserve(this) 而非 unobserve(container)),\n // observer 从未真正解除,view 已经半 destroy 时仍会触发一次 render,此时 #view / iframe body 已 null。\n // 已知触发:\n // - \"Cannot destructure property 'style' of 'el' as it is null\" (setStylesImportant)\n // - \"Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'\" (#replaceBackground)\n useEffect(() => {\n const handler = (e: ErrorEvent) => {\n if (e.filename?.includes('paginator')) {\n e.preventDefault();\n }\n };\n window.addEventListener('error', handler);\n return () => window.removeEventListener('error', handler);\n }, []);\n\n useEffect(() => {\n const host = hostRef.current;\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (!host || !url) return;\n\n let cancelled = false;\n let view: FoliateView | null = null;\n let progressReported = false;\n // 多 section 文件的页码累加器:记录各 section 的实际页数\n const sectionPagesMap = new Map<number, number>();\n\n const load = async () => {\n if (cancelled) return;\n\n setLoading(true);\n setError(null);\n setToc([]);\n setShowToc(false);\n setActiveTocHref('');\n host.replaceChildren();\n\n try {\n view = document.createElement('foliate-view') as FoliateView;\n host.appendChild(view);\n viewRef.current = view;\n\n // 先注册事件\n view.addEventListener('relocate', (e: Event) => {\n const detail = (e as CustomEvent).detail;\n if (!detail) return;\n\n const currentView = viewRef.current;\n const sectionCount = currentView?.book?.sections.length ?? 0;\n const renderer = (currentView as unknown as {\n renderer?: {\n page?: number;\n pages?: number;\n getContents?: () => Array<{ index: number }>;\n };\n } | null)?.renderer;\n\n // 用 Paginator 的 page/pages 得到精确翻页数:\n // - 单 section:pages - 2 就是全书总页数\n // - 多 section:记录已翻过的 section 的 pages,累加得到全书页码\n const sectionIdx = renderer?.getContents?.()[0]?.index ?? -1;\n if (\n renderer\n && typeof renderer.page === 'number'\n && typeof renderer.pages === 'number'\n && renderer.pages > 2\n && sectionIdx >= 0\n ) {\n progressReported = true;\n const curSectionPages = renderer.pages - 2;\n // 更新当前 section 的实际页数(每次进入该 section 都刷新,防止首次未 render 完整)\n sectionPagesMap.set(sectionIdx, curSectionPages);\n\n // 累加已确知的前置 section pages\n let pagesBefore = 0;\n for (let i = 0; i < sectionIdx; i++) {\n pagesBefore += sectionPagesMap.get(i) ?? 0;\n }\n const currentPage = pagesBefore + Math.min(curSectionPages, Math.max(1, renderer.page));\n\n // total 策略:\n // - 单 section:pages - 2 就是全书精确页数\n // - 多 section:用\"当前 section 字符/页数比\"外推未访问 section 的 pages。\n // 同一本书字体、行距、页宽恒定,比率稳定,比 SectionProgress 字符估算准得多。\n // 翻到末页(fraction ≈ 1)时用 currentPage 覆盖,得到真实总数。\n const atEnd = (detail.fraction ?? 0) >= 0.999;\n let total: number;\n if (sectionCount === 1) {\n total = curSectionPages;\n } else if (atEnd) {\n total = currentPage;\n } else {\n const sections = currentView?.book?.sections ?? [];\n const curSize = (sections[sectionIdx] as { size?: number } | undefined)?.size ?? 0;\n const ratio = curSize > 0 ? curSectionPages / curSize : 0;\n let est = 0;\n for (let i = 0; i < sectionCount; i++) {\n if (sectionPagesMap.has(i)) {\n est += sectionPagesMap.get(i)!;\n } else {\n const s = (sections[i] as { size?: number } | undefined)?.size ?? 0;\n est += Math.max(1, Math.round(s * ratio));\n }\n }\n total = Math.max(currentPage, est);\n }\n\n reportProgress(currentPage - 1, total);\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) setActiveTocHref(tocItem.href);\n return;\n }\n\n // 兜底:SectionProgress.location(基于字符数估算)\n const loc = detail.location as { current?: number; total?: number } | undefined;\n if (loc && typeof loc.current === 'number' && typeof loc.total === 'number') {\n progressReported = true;\n // 当翻到末尾时(fraction 达到 1 表示全书 100%),用 current + 1 作为实际可达的 total,\n // 覆盖 SectionProgress 基于字符数向上取整的估算值(会高估)\n const atEnd = (detail.fraction ?? 0) >= 0.999;\n const actualTotal = atEnd ? loc.current + 1 : loc.total;\n reportProgress(loc.current, actualTotal);\n } else {\n // fallback:用 section 级别估算\n const sections = viewRef.current?.book?.sections ?? [];\n const idx = detail.index ?? 0;\n const frac = detail.fraction ?? 0;\n const total = Math.max(sections.length, 1);\n const current = Math.round((idx + frac) / total * total);\n reportProgress(current, total);\n }\n const tocItem = detail.tocItem as { href?: string } | undefined;\n if (tocItem?.href) {\n setActiveTocHref(tocItem.href);\n }\n });\n\n const res = await fetcher(url);\n if (cancelled) return;\n if (!res.ok) throw new Error(`请求失败: ${res.status}`);\n const blob = await res.blob();\n if (cancelled) return;\n let name = 'book.mobi';\n try {\n const u = new URL(url, window.location.href);\n const base = u.pathname.split('/').pop();\n if (base) name = decodeURIComponent(base);\n } catch { /* blob: URL */ }\n const file = new File([blob], name);\n\n await view.open(file);\n if (cancelled) { view.book?.destroy?.(); return; }\n\n // 配置 paginator:paginated 模式(默认),带动画\n const renderer = (view as unknown as { renderer: HTMLElement & {\n setStyles?: (css: string) => void;\n next?: () => Promise<void>;\n } }).renderer;\n\n if (renderer) {\n // flow=\"paginated\" 是默认值,不需要显式设置\n renderer.setAttribute('animated', '');\n renderer.setAttribute('max-inline-size', '720');\n renderer.setAttribute('margin', '48');\n renderer.setAttribute('gap', '5%');\n // 必须调 next() 渲染首页\n await renderer.next?.();\n // setStyles 依赖 view.document 存在,必须在 next() 触发首次渲染后调用\n renderer.setStyles?.(READER_CSS);\n }\n if (cancelled) return;\n\n setToc(view.book?.toc ?? []);\n setLoading(false);\n // 只在 relocate 事件从未报告 progress 时使用 sections.length 作为 fallback,\n // 避免覆盖 SectionProgress 报告的更准确的 total(通常在首页 render 时通过 relocate 已报告)\n if (!progressReported) {\n reportProgress(0, view.book?.sections.length ?? 1);\n }\n } catch (err) {\n // MOBI/EPUB 加载错误通常是文件损坏或 DRM 保护,用 warn 级别记录\n console.warn('[MobiRenderer] Failed to load ebook:', err instanceof Error ? err.message : String(err));\n if (!cancelled) {\n setError(t('mobi.load_failed'));\n setLoading(false);\n }\n }\n };\n\n // 延迟到 microtask 队列执行,让 StrictMode 的第一次 cleanup 有机会取消,\n // 避免两个并发的 view.open() 污染 foliate-js MOBI 解析器内部状态\n Promise.resolve().then(load);\n\n return () => {\n cancelled = true;\n try { (view as unknown as { close?: () => void })?.close?.(); } catch { /* ignore */ }\n try { view?.book?.destroy?.(); } catch { /* ignore */ }\n if (view && view.parentNode === host) {\n try { host.removeChild(view); } catch { /* ignore */ }\n }\n if (viewRef.current === view) viewRef.current = null;\n };\n }, [url, reportProgress, t]);\n\n const isActive = useCallback(\n (href: string | undefined) => !!href && href === activeTocHref,\n [activeTocHref]\n );\n\n const renderTocItems = (items: TocItem[], depth = 0) => (\n <ul style={{ listStyle: 'none', padding: 0, margin: depth > 0 ? '0 0 0 16px' : 0 }}>\n {items.map((item, i) => (\n <li key={`${item.href ?? item.label}-${i}`}>\n {item.href ? (\n <button\n onClick={() => handleTocClick(item.href!)}\n className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${\n isActive(item.href)\n ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n }`}\n title={item.label}\n >\n {item.label?.trim()}\n </button>\n ) : (\n <div className=\"rfp-w-full rfp-py-2 rfp-px-3 rfp-text-sm rfp-text-fg-tertiary rfp-truncate\">\n {item.label?.trim()}\n </div>\n )}\n {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n </li>\n ))}\n </ul>\n );\n\n return (\n <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-surface-1 rfp-overflow-hidden\">\n {error && <RendererError message={error} />}\n\n {loading && !error && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n </div>\n )}\n\n {/* 目录侧栏 */}\n {toc.length > 0 && (\n <div\n className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n style={{ opacity: showToc ? 1 : 0, pointerEvents: showToc ? 'auto' : 'none' }}\n >\n <div\n className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n >\n <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n <button\n onClick={() => setShowToc(false)}\n className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n >\n <X className=\"rfp-w-4 rfp-h-4\" />\n </button>\n </div>\n <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n {renderTocItems(toc)}\n </div>\n </div>\n <div\n className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n onClick={() => setShowToc(false)}\n />\n </div>\n )}\n\n {!error && (\n <div\n ref={hostRef}\n className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n style={{\n width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n maxWidth: '100%',\n transition: 'width 0.3s ease',\n }}\n />\n )}\n </div>\n );\n }\n);\n\nMobiRenderer.displayName = 'MobiRenderer';\n"],"names":["READER_CSS","A4_WIDTH","MobiRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","hostRef","useRef","viewRef","totalLocationsRef","loading","setLoading","useState","error","setError","toc","setToc","showToc","setShowToc","activeTocHref","setActiveTocHref","isFullWidth","setIsFullWidth","currentChapter","setCurrentChapter","totalChapters","setTotalChapters","isFullWidthRef","reportProgress","useCallback","current","total","handlePrev","view","handleNext","toggleToc","prev","toggleFullWidth","newVal","renderer","listenersRef","notifyToolbarChange","listener","useEffect","getToolbarGroups","List","jsx","ChevronLeft","ChevronRight","Minimize2","Maximize2","handleTocClick","href","_a","useImperativeHandle","handler","e","host","cancelled","progressReported","sectionPagesMap","load","detail","currentView","sectionCount","sectionIdx","curSectionPages","pagesBefore","i","currentPage","atEnd","sections","_d","curSize","_e","ratio","est","s","_f","tocItem","loc","actualTotal","_h","_g","idx","frac","res","blob","name","base","file","_b","_c","err","isActive","renderTocItems","items","depth","item","jsxs","RendererError","X"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as s, jsxs as y } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef as T, useState as x, useRef as b, useEffect as h, useImperativeHandle as k } from "react";
|
|
3
3
|
import E from "video.js";
|
|
4
|
-
import { u as R } from "./index-
|
|
4
|
+
import { u as R } from "./index-Cbp94jbP.mjs";
|
|
5
5
|
import { R as j } from "./RendererError-D5i8eSpN.mjs";
|
|
6
6
|
const _ = /* @__PURE__ */ new Set(["avi", "wmv", "flv"]), N = (r) => {
|
|
7
7
|
var e;
|
|
@@ -113,4 +113,4 @@ const _ = /* @__PURE__ */ new Set(["avi", "wmv", "flv"]), N = (r) => {
|
|
|
113
113
|
export {
|
|
114
114
|
q as VideoRenderer
|
|
115
115
|
};
|
|
116
|
-
//# sourceMappingURL=index-
|
|
116
|
+
//# sourceMappingURL=index-C2uu09Eb.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-C2uu09Eb.mjs","sources":["../../src/renderers/Video/index.tsx"],"sourcesContent":["import { useRef, useEffect, useState, forwardRef, useImperativeHandle } from 'react';\nimport videojs from 'video.js';\nimport 'video.js/dist/video-js.css';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\n\ntype VideoJsPlayer = ReturnType<typeof videojs>;\n\ninterface VideoRendererProps {\n url: string;\n fileName?: string;\n}\n\n// 浏览器原生不支持的视频容器(无论编码,<video> 都无法播放)\n// — 这些扩展名直接短路 videojs 初始化,给出明确提示\nconst BROWSER_UNSUPPORTED_EXTS = new Set(['avi', 'wmv', 'flv']);\n\n// 根据 URL 获取视频 MIME 类型\nconst getVideoType = (url: string): string => {\n const ext = url.split('.').pop()?.toLowerCase().split('?')[0] || '';\n const typeMap: Record<string, string> = {\n mp4: 'video/mp4',\n webm: 'video/webm',\n ogg: 'video/ogg',\n ogv: 'video/ogg',\n mov: 'video/quicktime', // MOV 使用 QuickTime MIME 类型\n avi: 'video/x-msvideo',\n mkv: 'video/x-matroska',\n m4v: 'video/mp4',\n '3gp': 'video/3gpp',\n flv: 'video/x-flv',\n };\n return typeMap[ext] || 'video/mp4';\n};\n\n// 获取视频文件扩展名(优先用文件名,blob/HTTP URL 都拿不到真扩展名)\nconst getVideoExt = (url: string, fileName?: string): string => {\n const source = fileName || url;\n return source.split('.').pop()?.toLowerCase().split('?')[0] || '';\n};\n\ninterface ErrorState {\n title: string;\n detail: string;\n}\n\nexport const VideoRenderer = forwardRef<RendererHandle, VideoRendererProps>(({ url, fileName }, ref) => {\n const t = useTranslator();\n const [error, setError] = useState<ErrorState | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const videoRef = useRef<HTMLDivElement>(null);\n const playerRef = useRef<VideoJsPlayer | null>(null);\n\n useEffect(() => {\n const videoExt = getVideoExt(url, fileName);\n\n // 已知浏览器不支持的容器:跳过 videojs 初始化,直接展示友好提示\n if (BROWSER_UNSUPPORTED_EXTS.has(videoExt)) {\n setError({\n title: t('video.unsupported_title'),\n detail: t('video.unsupported_detail', { format: videoExt.toUpperCase() }),\n });\n setIsLoading(false);\n return;\n }\n\n // 确保 Video.js 播放器只初始化一次\n if (!playerRef.current && videoRef.current) {\n const videoElement = document.createElement('video-js');\n videoElement.classList.add('vjs-big-play-centered', 'vjs-theme-apple');\n videoRef.current.appendChild(videoElement);\n\n const videoType = getVideoType(url);\n\n // 为特定格式提供多个 MIME 类型作为备用\n let sources: Array<{ src: string; type: string }>;\n\n if (videoType === 'video/quicktime') {\n // MOV 格式 fallback\n sources = [\n { src: url, type: 'video/quicktime' },\n { src: url, type: 'video/mp4' }\n ];\n } else {\n sources = [{ src: url, type: videoType }];\n }\n\n const player = videojs(videoElement, {\n controls: true,\n fill: true,\n preload: 'auto',\n controlBar: {\n children: [\n 'playToggle',\n 'volumePanel',\n 'currentTimeDisplay',\n 'timeDivider',\n 'durationDisplay',\n 'progressControl',\n 'remainingTimeDisplay',\n 'fullscreenToggle'\n ],\n volumePanel: {\n inline: false\n }\n },\n html5: {\n vhs: {\n overrideNative: true\n },\n nativeVideoTracks: false,\n nativeAudioTracks: false,\n nativeTextTracks: false\n },\n sources\n });\n\n // 确保视频保持比例\n const videoEl = player.el().querySelector('video');\n if (videoEl) {\n (videoEl as HTMLVideoElement).style.objectFit = 'contain';\n }\n\n // 监听加载完成\n player.on('loadeddata', () => {\n setIsLoading(false);\n });\n\n player.on('error', () => {\n const err = player.error();\n // 视频加载错误是正常情况(格式不支持、编解码器缺失等),用 warn 级别记录\n console.warn('[VideoRenderer] Video playback error:', err?.message || 'Unknown error');\n\n // MEDIA_ERR_SRC_NOT_SUPPORTED(code=4):编码或容器层面浏览器解不了\n if (err?.code === 4) {\n setError({\n title: t('video.unsupported_title'),\n detail: t('video.unsupported_detail', {\n format: videoExt ? videoExt.toUpperCase() : t('common.unknown_error'),\n }),\n });\n } else {\n setError({\n title: t('video.load_failed'),\n detail: err?.message || t('common.unknown_error'),\n });\n }\n setIsLoading(false);\n });\n\n playerRef.current = player;\n }\n }, [url, fileName, t]);\n\n // 清理函数\n useEffect(() => {\n const player = playerRef.current;\n\n return () => {\n if (player && !player.isDisposed()) {\n player.dispose();\n playerRef.current = null;\n }\n };\n }, []);\n\n // 暴露接口给父组件(必须在所有提前 return 之前)\n useImperativeHandle(ref, () => ({\n getToolbarGroups: () => [],\n }), []);\n\n if (error) {\n return <RendererError message={error.title} detail={error.detail} />;\n }\n\n return (\n <div className=\"rfp-flex rfp-items-center rfp-justify-center rfp-w-full rfp-h-full\">\n <div className=\"rfp-w-full rfp-h-full rfp-relative\">\n {/* 加载状态 */}\n {isLoading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-3 rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-12 rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-3 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('video.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 视频播放器容器 */}\n <div\n ref={videoRef}\n className=\"rfp-overflow-hidden rfp-w-full rfp-h-full [&_video]:rfp-object-contain\"\n style={{\n boxShadow: '0 20px 60px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.05)'\n }}\n />\n </div>\n </div>\n );\n});\n"],"names":["BROWSER_UNSUPPORTED_EXTS","getVideoType","url","ext","_a","getVideoExt","fileName","VideoRenderer","forwardRef","ref","t","useTranslator","error","setError","useState","isLoading","setIsLoading","videoRef","useRef","playerRef","useEffect","videoExt","videoElement","videoType","sources","player","videojs","videoEl","err","useImperativeHandle","RendererError","jsxs","jsx"],"mappings":"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"}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { jsxs as E, jsx as i } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef as z, useState as T, useRef as c, useCallback as y, useEffect as D, useImperativeHandle as H } from "react";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import { u as I, a as L, I as S } from "./index-DreA69iU.mjs";
|
|
3
|
+
import S from "exceljs";
|
|
4
|
+
import { S as W } from "./index-CyBXARuf.mjs";
|
|
5
|
+
import { u as j, a as I, I as L } from "./index-Cbp94jbP.mjs";
|
|
7
6
|
import { R as _ } from "./RendererError-D5i8eSpN.mjs";
|
|
8
|
-
const
|
|
9
|
-
const u =
|
|
7
|
+
const A = z(({ url: m }, k) => {
|
|
8
|
+
const u = j(), M = I(), [w, x] = T(!0), [b, v] = T(null), r = c(null), g = c(null), f = c(null), d = c(null), a = c(null), R = c({ width: 0, height: 0 }), l = y(() => {
|
|
10
9
|
if (!r.current) return { width: 800, height: 600 };
|
|
11
10
|
const t = r.current.clientWidth, s = r.current.clientHeight, n = t > 100 ? t : 800, e = s > 100 ? s : 600;
|
|
12
11
|
return { width: n, height: e };
|
|
13
|
-
}, []),
|
|
12
|
+
}, []), h = y(() => {
|
|
14
13
|
if (!r.current || !f.current) return;
|
|
15
14
|
r.current.innerHTML = "", g.current = null;
|
|
16
|
-
const { width: t, height: s } = l(), n = t < 640, e = new
|
|
15
|
+
const { width: t, height: s } = l(), n = t < 640, e = new W(r.current, {
|
|
17
16
|
mode: "read",
|
|
18
17
|
showToolbar: !1,
|
|
19
18
|
showContextmenu: !1,
|
|
@@ -43,9 +42,9 @@ const J = z(({ url: m }, k) => {
|
|
|
43
42
|
t = !1, R.current = l();
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
46
|
-
const n = l(), e = R.current, o = Math.abs(e.width - n.width),
|
|
47
|
-
o < 10 &&
|
|
48
|
-
f.current &&
|
|
45
|
+
const n = l(), e = R.current, o = Math.abs(e.width - n.width), p = Math.abs(e.height - n.height);
|
|
46
|
+
o < 10 && p < 10 || (R.current = n, a.current && clearTimeout(a.current), a.current = window.setTimeout(() => {
|
|
47
|
+
f.current && h();
|
|
49
48
|
}, 500));
|
|
50
49
|
};
|
|
51
50
|
return d.current = new ResizeObserver(() => {
|
|
@@ -53,7 +52,7 @@ const J = z(({ url: m }, k) => {
|
|
|
53
52
|
}), d.current.observe(r.current), () => {
|
|
54
53
|
d.current && d.current.disconnect(), a.current && clearTimeout(a.current);
|
|
55
54
|
};
|
|
56
|
-
}, [l,
|
|
55
|
+
}, [l, h]), D(() => {
|
|
57
56
|
if (!m) return;
|
|
58
57
|
let t = !0;
|
|
59
58
|
const s = async () => {
|
|
@@ -70,11 +69,11 @@ const J = z(({ url: m }, k) => {
|
|
|
70
69
|
const o = await e.arrayBuffer();
|
|
71
70
|
if (o.byteLength === 0)
|
|
72
71
|
throw new Error("文件为空");
|
|
73
|
-
const
|
|
74
|
-
await
|
|
75
|
-
const N =
|
|
72
|
+
const p = new S.Workbook();
|
|
73
|
+
await p.xlsx.load(o);
|
|
74
|
+
const N = L(p);
|
|
76
75
|
if (!t) return;
|
|
77
|
-
f.current = N,
|
|
76
|
+
f.current = N, h(), x(!1);
|
|
78
77
|
} catch (e) {
|
|
79
78
|
if (t) {
|
|
80
79
|
console.error("Excel 解析错误:", e);
|
|
@@ -91,7 +90,7 @@ const J = z(({ url: m }, k) => {
|
|
|
91
90
|
return () => {
|
|
92
91
|
t = !1, clearTimeout(n), f.current = null, r.current && (r.current.innerHTML = ""), g.current = null;
|
|
93
92
|
};
|
|
94
|
-
}, [m,
|
|
93
|
+
}, [m, h]), H(k, () => ({
|
|
95
94
|
getToolbarGroups: () => []
|
|
96
95
|
}), []), /* @__PURE__ */ E("div", { className: "rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full", children: [
|
|
97
96
|
w && /* @__PURE__ */ i("div", { className: "rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10", children: /* @__PURE__ */ E("div", { className: "rfp-text-center", children: [
|
|
@@ -110,6 +109,6 @@ const J = z(({ url: m }, k) => {
|
|
|
110
109
|
] });
|
|
111
110
|
});
|
|
112
111
|
export {
|
|
113
|
-
|
|
112
|
+
A as XlsxRenderer
|
|
114
113
|
};
|
|
115
|
-
//# sourceMappingURL=index-
|
|
114
|
+
//# sourceMappingURL=index-C5o_T3Es.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-C5o_T3Es.mjs","sources":["../../src/renderers/Xlsx/index.tsx"],"sourcesContent":["import { useState, useEffect, useRef, useCallback, forwardRef, useImperativeHandle } from 'react';\nimport ExcelJS from 'exceljs';\nimport Spreadsheet from 'x-data-spreadsheet';\nimport { convertWorkbookToSpreadsheetData } from '../../utils/excelDataConverter';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\n\ninterface XlsxRendererProps {\n url: string;\n}\n\nexport const XlsxRenderer = forwardRef<RendererHandle, XlsxRendererProps>(({ url }, ref) => {\n const t = useTranslator();\n const fetcher = useFetcher();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const spreadsheetRef = useRef<Spreadsheet | null>(null);\n const sheetDataRef = useRef<Record<string, unknown>[] | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n const resizeTimeoutRef = useRef<number | null>(null);\n const lastDimensionsRef = useRef({ width: 0, height: 0 });\n\n const calculateDimensions = useCallback(() => {\n if (!containerRef.current) return { width: 800, height: 600 };\n const rawWidth = containerRef.current.clientWidth;\n const rawHeight = containerRef.current.clientHeight;\n const width = rawWidth > 100 ? rawWidth : 800;\n const height = rawHeight > 100 ? rawHeight : 600;\n return { width, height };\n }, []);\n\n const mountSpreadsheet = useCallback(() => {\n if (!containerRef.current || !sheetDataRef.current) return;\n\n // 清空容器\n containerRef.current.innerHTML = '';\n spreadsheetRef.current = null;\n\n const { width, height } = calculateDimensions();\n const isMobile = width < 640;\n\n const s = new Spreadsheet(containerRef.current, {\n mode: 'read',\n showToolbar: false,\n showContextmenu: false,\n showGrid: true,\n row: {\n len: 100,\n height: 25,\n },\n col: {\n len: 26,\n width: isMobile ? 80 : 100,\n indexWidth: isMobile ? 40 : 60,\n minWidth: isMobile ? 40 : 60,\n },\n view: {\n height: () => height,\n width: () => width,\n },\n });\n\n s.loadData(sheetDataRef.current as unknown as Record<string, unknown>);\n spreadsheetRef.current = s;\n }, [calculateDimensions]);\n\n // 监听容器尺寸变化\n useEffect(() => {\n if (!containerRef.current) return;\n\n let isInitialRender = true;\n\n const updateDimensions = () => {\n if (isInitialRender) {\n isInitialRender = false;\n lastDimensionsRef.current = calculateDimensions();\n return;\n }\n\n const newDimensions = calculateDimensions();\n const lastDimensions = lastDimensionsRef.current;\n const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n if (widthDiff < 10 && heightDiff < 10) return;\n\n lastDimensionsRef.current = newDimensions;\n\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n resizeTimeoutRef.current = window.setTimeout(() => {\n if (sheetDataRef.current) {\n mountSpreadsheet();\n }\n }, 500);\n };\n\n resizeObserverRef.current = new ResizeObserver(() => {\n updateDimensions();\n });\n\n resizeObserverRef.current.observe(containerRef.current);\n\n return () => {\n if (resizeObserverRef.current) {\n resizeObserverRef.current.disconnect();\n }\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, [calculateDimensions, mountSpreadsheet]);\n\n useEffect(() => {\n // 只有 URL 有效时才加载(避免空字符串或已 revoke 的 blob URL)\n if (!url) return;\n\n let isMounted = true;\n\n const loadExcel = async () => {\n if (!containerRef.current) return;\n\n setLoading(true);\n setError(null);\n\n try {\n const response = await fetcher(url, {\n mode: 'cors',\n credentials: 'omit',\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error(t('xlsx.not_found'));\n } else if (response.status === 403) {\n throw new Error('无权限访问此文件');\n } else {\n throw new Error(`文件加载失败 (${response.status})`);\n }\n }\n\n const arrayBuffer = await response.arrayBuffer();\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error('文件为空');\n }\n\n // 使用 exceljs 解析\n const workbook = new ExcelJS.Workbook();\n await workbook.xlsx.load(arrayBuffer);\n\n // 转换为 x-data-spreadsheet 数据格式\n const sheetData = convertWorkbookToSpreadsheetData(workbook);\n\n if (!isMounted) return;\n\n sheetDataRef.current = sheetData as unknown as Record<string, unknown>[];\n\n // 挂载 x-data-spreadsheet\n mountSpreadsheet();\n\n setLoading(false);\n } catch (err) {\n if (isMounted) {\n console.error('Excel 解析错误:', err);\n let errorMsg = t('xlsx.parse_failed');\n if (err instanceof Error) {\n errorMsg = err.message;\n }\n setError(errorMsg);\n setLoading(false);\n }\n }\n };\n\n const timer = setTimeout(() => {\n requestAnimationFrame(() => {\n loadExcel();\n });\n }, 100);\n\n return () => {\n isMounted = false;\n clearTimeout(timer);\n sheetDataRef.current = null;\n if (containerRef.current) {\n containerRef.current.innerHTML = '';\n }\n spreadsheetRef.current = null;\n };\n }, [url, mountSpreadsheet]);\n\n // 暴露接口给父组件\n useImperativeHandle(ref, () => ({\n getToolbarGroups: () => [],\n }), []);\n\n return (\n <div className=\"rfp-relative rfp-flex rfp-flex-col rfp-items-center rfp-w-full rfp-h-full\">\n {/* 加载状态 */}\n {loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <div className=\"rfp-text-center\">\n <div className=\"rfp-w-10 rfp-h-10 md:rfp-w-12 md:rfp-h-12 rfp-mx-auto rfp-mb-3 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n <p className=\"rfp-text-xs md:rfp-text-sm rfp-text-fg-secondary rfp-font-medium\">{t('xlsx.loading')}</p>\n </div>\n </div>\n )}\n\n {/* 错误状态 */}\n {error && !loading && (\n <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-bg-surface-toolbar rfp-backdrop-blur-sm rfp-z-10\">\n <RendererError message={t('xlsx.load_failed')} detail={error} />\n </div>\n )}\n\n {/* Spreadsheet 容器 */}\n {!error && (\n <div\n ref={containerRef}\n className=\"xlsx-spreadsheet-container rfp-w-full rfp-h-full\"\n style={{ opacity: loading ? 0 : 1 }}\n />\n )}\n </div>\n );\n});\n"],"names":["XlsxRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","loading","setLoading","useState","error","setError","containerRef","useRef","spreadsheetRef","sheetDataRef","resizeObserverRef","resizeTimeoutRef","lastDimensionsRef","calculateDimensions","useCallback","rawWidth","rawHeight","width","height","mountSpreadsheet","isMobile","s","Spreadsheet","useEffect","isInitialRender","updateDimensions","newDimensions","lastDimensions","widthDiff","heightDiff","isMounted","loadExcel","response","arrayBuffer","workbook","ExcelJS","sheetData","convertWorkbookToSpreadsheetData","err","errorMsg","timer","useImperativeHandle","jsxs","jsx","RendererError"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as n } from "react/jsx-runtime";
|
|
|
2
2
|
import { useRef as P, useState as l, useEffect as H, useCallback as C, forwardRef as te, useImperativeHandle as ae } from "react";
|
|
3
3
|
import { motion as m, AnimatePresence as ne } from "framer-motion";
|
|
4
4
|
import { Repeat as ie, SkipBack as se, Pause as oe, Play as le, SkipForward as ce, VolumeX as pe, Volume1 as fe, Volume2 as de } from "lucide-react";
|
|
5
|
-
import { u as ue } from "./index-
|
|
5
|
+
import { u as ue } from "./index-Cbp94jbP.mjs";
|
|
6
6
|
import { R as me } from "./RendererError-D5i8eSpN.mjs";
|
|
7
7
|
function he({
|
|
8
8
|
url: f
|
|
@@ -584,4 +584,4 @@ const ge = ({ text: f, className: c = "", style: G }) => {
|
|
|
584
584
|
export {
|
|
585
585
|
Ee as AudioRenderer
|
|
586
586
|
};
|
|
587
|
-
//# sourceMappingURL=index-
|
|
587
|
+
//# sourceMappingURL=index-CMehLA91.mjs.map
|