@cyber-harbour/ui 3.0.0-next-gen.77 → 3.0.0-next-gen.78

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.
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkYAP3G27F_js=require('./chunk-YAP3G27F.js');require('./chunk-NQZUCXJV.js');var chunkS3RLHUDJ_js=require('./chunk-S3RLHUDJ.js'),chunkAYDF3IFZ_js=require('./chunk-AYDF3IFZ.js'),react=require('react'),V=require('lodash.debounce'),reactPdf=require('react-pdf');require('react-pdf/dist/Page/AnnotationLayer.css'),require('react-pdf/dist/Page/TextLayer.css');var reactVirtuoso=require('react-virtuoso'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var V__default=/*#__PURE__*/_interopDefault(V);var f="/pdfjs";typeof window<"u"&&typeof document<"u"&&(reactPdf.pdfjs.GlobalWorkerOptions.workerSrc=`${f}/pdf.worker.min.js`);var xe=1e3,we=400,Ne=150,Ce=70,Pe=1.414,D=400,Ue=chunkAYDF3IFZ_js.a(({url:W,filename:F,onDownload:I,onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})=>{let J=!!(y||R),[i,Q]=react.useState(0),[s,h]=react.useState(1),[X,E]=react.useState(true),[L,ee]=react.useState(null),[v,te]=react.useState(D),[oe,re]=react.useState(D),[c,k]=react.useState(1),[x,ne]=react.useState(D),[A,ae]=react.useState(Pe),d=react.useRef(null),T=react.useRef(null),w=react.useRef(false),u=react.useRef(null),N=react.useRef(false),p=react.useCallback((t,o=true)=>{t<1||t>i||(w.current=true,T.current?.scrollToIndex({index:t-1,align:"start",behavior:o?"smooth":"auto"}),u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{N.current&&(w.current=false);},xe));},[i]),C=react.useMemo(()=>V__default.default((t,o=false)=>{p(t,o);},we),[p]),ie=react.useCallback(()=>{k(t=>Math.min(t+.25,4));},[]),se=react.useCallback(()=>{k(t=>Math.max(t-.25,.25));},[]);react.useEffect(()=>{if(!d.current)return;let t=V__default.default(()=>{d.current&&(te(d.current.offsetWidth-Ce),re(d.current.clientHeight));},Ne);t();let o=new ResizeObserver(t);return o.observe(d.current),()=>{o.disconnect(),t.cancel();}},[]);let le=react.useMemo(()=>({cMapPacked:true,cMapUrl:`${f}/cmaps/`,standardFontDataUrl:`${f}/standard_fonts/`,wasmUrl:`${f}/wasm/`,iccUrl:`${f}/icc/`}),[]),ce=react.useCallback(({numPages:t})=>{Q(t),E(false);},[]),de=react.useCallback(t=>{ee(`Failed to load PDF: ${t.message}`),E(false);},[]),g=react.useCallback(t=>{let o=s+t;h(o),p(o);},[s,p]),ue=react.useCallback(()=>{g(-1);},[g]),me=react.useCallback(()=>{g(1);},[g]),fe=react.useCallback(t=>{if(w.current)return;let o=t.startIndex+1;o!==s&&h(o);},[s]);return react.useEffect(()=>(N.current=true,()=>{N.current=false,C.cancel(),u.current&&clearTimeout(u.current);}),[C]),react.useEffect(()=>{ne(v*c*A);},[v,c,A]),L?jsxRuntime.jsx("div",{"data-testid":"file-viewer-error","data-driver-kind":"pdf",className:"flex items-center justify-center h-full w-full px-8.5",children:jsxRuntime.jsx("div",{className:"text-center text-sm text-text-secondary",children:jsxRuntime.jsx("p",{children:L})})}):jsxRuntime.jsxs("div",{"data-testid":"file-viewer-driver","data-driver-kind":"pdf",className:"relative h-full w-full flex flex-col overflow-hidden bg-background-page",children:[X&&jsxRuntime.jsx("div",{className:"flex items-center justify-center h-full px-8.5",children:jsxRuntime.jsx("div",{className:"text-text-secondary",children:"Loading PDF..."})}),jsxRuntime.jsxs("div",{ref:d,className:"relative flex-1 overflow-hidden min-h-0",children:[jsxRuntime.jsx(reactPdf.Document,{options:le,file:W,onLoadSuccess:ce,onLoadError:de,loading:jsxRuntime.jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsxRuntime.jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),children:jsxRuntime.jsx(reactVirtuoso.Virtuoso,{ref:T,style:{height:oe||"calc(100dvh - 120px)",width:"100%",scrollbarGutter:"stable both-edges"},totalCount:i,rangeChanged:fe,defaultItemHeight:x,itemContent:t=>jsxRuntime.jsx("div",{className:"mx-auto w-fit mb-4 border border-border-subtle",children:jsxRuntime.jsx(reactPdf.Page,{pageNumber:t+1,renderTextLayer:true,renderAnnotationLayer:true,width:v*c,onLoadSuccess:o=>{if(t===0){let pe=o.height/o.width;ae(pe);}},loading:jsxRuntime.jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsxRuntime.jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),className:"h-auto w-full transition-[width] duration-[600ms] ease-in-out"})})})}),i>0&&jsxRuntime.jsxs(chunkYAP3G27F_js.a,{"aria-label":"PDF controls",children:[jsxRuntime.jsxs(chunkYAP3G27F_js.b,{children:[jsxRuntime.jsx(chunkYAP3G27F_js.e,{"aria-label":"Zoom out",onClick:se,disabled:c<=.25,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.k,{width:16,height:16})}),jsxRuntime.jsxs(chunkYAP3G27F_js.e,{"aria-label":"Current zoom",children:[Math.round(c*100),"%"]}),jsxRuntime.jsx(chunkYAP3G27F_js.e,{"aria-label":"Zoom in",onClick:ie,disabled:c>=4,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.j,{width:16,height:16})})]}),jsxRuntime.jsx(chunkYAP3G27F_js.d,{}),jsxRuntime.jsxs(chunkYAP3G27F_js.c,{children:[jsxRuntime.jsx(chunkYAP3G27F_js.e,{"aria-label":"Previous page",onClick:ue,disabled:s<=1,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.c,{width:12,height:12})}),jsxRuntime.jsxs("span",{className:"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center",children:[jsxRuntime.jsx("input",{type:"number",min:1,max:i,value:s,onChange:t=>{let o=parseInt(t.target.value,10);o>=1&&o<=i&&(h(o),C(o,false));},className:"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"}),jsxRuntime.jsxs("span",{children:["/",i]})]}),jsxRuntime.jsx(chunkYAP3G27F_js.e,{"aria-label":"Next page",onClick:me,disabled:s>=i,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.d,{width:12,height:12})})]}),J&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(chunkYAP3G27F_js.d,{}),jsxRuntime.jsx(chunkYAP3G27F_js.f,{onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})]}),I&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(chunkYAP3G27F_js.d,{}),jsxRuntime.jsx(chunkYAP3G27F_js.e,{"aria-label":F?`Download ${F}`:"Download",onClick:I,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.b,{width:16,height:16})})]})]})]})]})},"PdfDriver");exports.PdfDriver=Ue;//# sourceMappingURL=PdfDriver-IKR2GCUT.js.map
2
- //# sourceMappingURL=PdfDriver-IKR2GCUT.js.map
1
+ 'use strict';var chunkJVDLOXO7_js=require('./chunk-JVDLOXO7.js'),chunkS3RLHUDJ_js=require('./chunk-S3RLHUDJ.js');require('./chunk-NQZUCXJV.js');var chunkAYDF3IFZ_js=require('./chunk-AYDF3IFZ.js'),react=require('react'),V=require('lodash.debounce'),reactPdf=require('react-pdf');require('react-pdf/dist/Page/AnnotationLayer.css'),require('react-pdf/dist/Page/TextLayer.css');var reactVirtuoso=require('react-virtuoso'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var V__default=/*#__PURE__*/_interopDefault(V);var f="/pdfjs";typeof window<"u"&&typeof document<"u"&&(reactPdf.pdfjs.GlobalWorkerOptions.workerSrc=`${f}/pdf.worker.min.js`);var xe=1e3,we=400,Ne=150,Ce=70,Pe=1.414,D=400,Ue=chunkAYDF3IFZ_js.a(({url:W,filename:F,onDownload:I,onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})=>{let J=!!(y||R),[i,Q]=react.useState(0),[s,h]=react.useState(1),[X,E]=react.useState(true),[L,ee]=react.useState(null),[v,te]=react.useState(D),[oe,re]=react.useState(D),[c,k]=react.useState(1),[x,ne]=react.useState(D),[A,ae]=react.useState(Pe),d=react.useRef(null),T=react.useRef(null),w=react.useRef(false),u=react.useRef(null),N=react.useRef(false),p=react.useCallback((t,o=true)=>{t<1||t>i||(w.current=true,T.current?.scrollToIndex({index:t-1,align:"start",behavior:o?"smooth":"auto"}),u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{N.current&&(w.current=false);},xe));},[i]),C=react.useMemo(()=>V__default.default((t,o=false)=>{p(t,o);},we),[p]),ie=react.useCallback(()=>{k(t=>Math.min(t+.25,4));},[]),se=react.useCallback(()=>{k(t=>Math.max(t-.25,.25));},[]);react.useEffect(()=>{if(!d.current)return;let t=V__default.default(()=>{d.current&&(te(d.current.offsetWidth-Ce),re(d.current.clientHeight));},Ne);t();let o=new ResizeObserver(t);return o.observe(d.current),()=>{o.disconnect(),t.cancel();}},[]);let le=react.useMemo(()=>({cMapPacked:true,cMapUrl:`${f}/cmaps/`,standardFontDataUrl:`${f}/standard_fonts/`,wasmUrl:`${f}/wasm/`,iccUrl:`${f}/icc/`}),[]),ce=react.useCallback(({numPages:t})=>{Q(t),E(false);},[]),de=react.useCallback(t=>{ee(`Failed to load PDF: ${t.message}`),E(false);},[]),g=react.useCallback(t=>{let o=s+t;h(o),p(o);},[s,p]),ue=react.useCallback(()=>{g(-1);},[g]),me=react.useCallback(()=>{g(1);},[g]),fe=react.useCallback(t=>{if(w.current)return;let o=t.startIndex+1;o!==s&&h(o);},[s]);return react.useEffect(()=>(N.current=true,()=>{N.current=false,C.cancel(),u.current&&clearTimeout(u.current);}),[C]),react.useEffect(()=>{ne(v*c*A);},[v,c,A]),L?jsxRuntime.jsx("div",{"data-testid":"file-viewer-error","data-driver-kind":"pdf",className:"flex items-center justify-center h-full w-full px-8.5",children:jsxRuntime.jsx("div",{className:"text-center text-sm text-text-secondary",children:jsxRuntime.jsx("p",{children:L})})}):jsxRuntime.jsxs("div",{"data-testid":"file-viewer-driver","data-driver-kind":"pdf",className:"relative h-full w-full flex flex-col overflow-hidden bg-background-page",children:[X&&jsxRuntime.jsx("div",{className:"flex items-center justify-center h-full px-8.5",children:jsxRuntime.jsx("div",{className:"text-text-secondary",children:"Loading PDF..."})}),jsxRuntime.jsxs("div",{ref:d,className:"relative flex-1 overflow-hidden min-h-0",children:[jsxRuntime.jsx(reactPdf.Document,{options:le,file:W,onLoadSuccess:ce,onLoadError:de,loading:jsxRuntime.jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsxRuntime.jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),children:jsxRuntime.jsx(reactVirtuoso.Virtuoso,{ref:T,style:{height:oe||"calc(100dvh - 120px)",width:"100%",scrollbarGutter:"stable both-edges"},totalCount:i,rangeChanged:fe,defaultItemHeight:x,itemContent:t=>jsxRuntime.jsx("div",{className:"mx-auto w-fit mb-4 border border-border-subtle",children:jsxRuntime.jsx(reactPdf.Page,{pageNumber:t+1,renderTextLayer:true,renderAnnotationLayer:true,width:v*c,onLoadSuccess:o=>{if(t===0){let pe=o.height/o.width;ae(pe);}},loading:jsxRuntime.jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsxRuntime.jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),className:"h-auto w-full transition-[width] duration-[600ms] ease-in-out"})})})}),i>0&&jsxRuntime.jsxs(chunkJVDLOXO7_js.a,{"aria-label":"PDF controls",children:[jsxRuntime.jsxs(chunkJVDLOXO7_js.b,{children:[jsxRuntime.jsx(chunkJVDLOXO7_js.e,{"aria-label":"Zoom out",onClick:se,disabled:c<=.25,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.k,{width:16,height:16})}),jsxRuntime.jsxs(chunkJVDLOXO7_js.e,{"aria-label":"Current zoom",children:[Math.round(c*100),"%"]}),jsxRuntime.jsx(chunkJVDLOXO7_js.e,{"aria-label":"Zoom in",onClick:ie,disabled:c>=4,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.j,{width:16,height:16})})]}),jsxRuntime.jsx(chunkJVDLOXO7_js.d,{}),jsxRuntime.jsxs(chunkJVDLOXO7_js.c,{children:[jsxRuntime.jsx(chunkJVDLOXO7_js.e,{"aria-label":"Previous page",onClick:ue,disabled:s<=1,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.c,{width:12,height:12})}),jsxRuntime.jsxs("span",{className:"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center",children:[jsxRuntime.jsx("input",{type:"number",min:1,max:i,value:s,onChange:t=>{let o=parseInt(t.target.value,10);o>=1&&o<=i&&(h(o),C(o,false));},className:"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"}),jsxRuntime.jsxs("span",{children:["/",i]})]}),jsxRuntime.jsx(chunkJVDLOXO7_js.e,{"aria-label":"Next page",onClick:me,disabled:s>=i,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.d,{width:12,height:12})})]}),J&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(chunkJVDLOXO7_js.d,{}),jsxRuntime.jsx(chunkJVDLOXO7_js.f,{onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})]}),I&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(chunkJVDLOXO7_js.d,{}),jsxRuntime.jsx(chunkJVDLOXO7_js.e,{"aria-label":F?`Download ${F}`:"Download",onClick:I,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.b,{width:16,height:16})})]})]})]})]})},"PdfDriver");exports.PdfDriver=Ue;//# sourceMappingURL=PdfDriver-IRXY5HVF.js.map
2
+ //# sourceMappingURL=PdfDriver-IRXY5HVF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","filename","onDownload","onPrev","onNext","hasPrev","hasNext","positionLabel","hasNav","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","FloatingControls","FloatingControlsGroup","FloatingControlsButton","ZoomOutIcon","ZoomInIcon","FloatingControlsDivider","FloatingControlsBoxedGroup","KeyboardArrowLeftIcon","e","KeyboardArrowRightIcon","Fragment","MediaNavGroup","DownloadIcon"],"mappings":"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","file":"PdfDriver-IKR2GCUT.js","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { DownloadIcon } from '../../../Icons/DownloadIcon';\nimport { KeyboardArrowLeftIcon } from '../../../Icons/KeyboardArrowLeftIcon';\nimport { KeyboardArrowRightIcon } from '../../../Icons/KeyboardArrowRightIcon';\nimport { ZoomInIcon } from '../../../Icons/ZoomInIcon';\nimport { ZoomOutIcon } from '../../../Icons/ZoomOutIcon';\nimport {\n FloatingControls,\n FloatingControlsBoxedGroup,\n FloatingControlsButton,\n FloatingControlsDivider,\n FloatingControlsGroup,\n MediaNavGroup,\n} from '../_shared';\nimport type { FileViewerNavProps } from '../../types';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps extends FileViewerNavProps {\n url: string;\n filename?: string;\n onDownload?: () => void;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({\n url,\n filename,\n onDownload,\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n}) => {\n const hasNav = !!(onPrev || onNext);\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div\n data-testid=\"file-viewer-error\"\n data-driver-kind=\"pdf\"\n className=\"flex items-center justify-center h-full w-full px-8.5\"\n >\n <div className=\"text-center text-sm text-text-secondary\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"file-viewer-driver\"\n data-driver-kind=\"pdf\"\n className=\"relative h-full w-full flex flex-col overflow-hidden bg-background-page\"\n >\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-text-secondary\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"relative flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{\n height: height || 'calc(100dvh - 120px)',\n width: '100%',\n scrollbarGutter: 'stable both-edges',\n }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className=\"mx-auto w-fit mb-4 border border-border-subtle\">\n <Page\n pageNumber={index + 1}\n renderTextLayer\n renderAnnotationLayer\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n\n {numPages > 0 && (\n <FloatingControls aria-label=\"PDF controls\">\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label=\"Zoom out\"\n onClick={handleZoomOut}\n disabled={scale <= 0.25}\n >\n <ZoomOutIcon width={16} height={16} />\n </FloatingControlsButton>\n <FloatingControlsButton aria-label=\"Current zoom\">\n {Math.round(scale * 100)}%\n </FloatingControlsButton>\n <FloatingControlsButton\n aria-label=\"Zoom in\"\n onClick={handleZoomIn}\n disabled={scale >= 4}\n >\n <ZoomInIcon width={16} height={16} />\n </FloatingControlsButton>\n </FloatingControlsGroup>\n\n <FloatingControlsDivider />\n\n <FloatingControlsBoxedGroup>\n <FloatingControlsButton\n aria-label=\"Previous page\"\n onClick={previousPage}\n disabled={pageNumber <= 1}\n className=\"px-3!\"\n >\n <KeyboardArrowLeftIcon width={12} height={12} />\n </FloatingControlsButton>\n <span className=\"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center\">\n <input\n type=\"number\"\n min={1}\n max={numPages}\n value={pageNumber}\n onChange={(e) => {\n const page = parseInt(e.target.value, 10);\n if (page >= 1 && page <= numPages) {\n setPageNumber(page);\n debouncedScroll(page, false);\n }\n }}\n className=\"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n />\n <span>/{numPages}</span>\n </span>\n <FloatingControlsButton\n aria-label=\"Next page\"\n onClick={nextPage}\n disabled={pageNumber >= numPages}\n className=\"px-3!\"\n >\n <KeyboardArrowRightIcon width={12} height={12} />\n </FloatingControlsButton>\n </FloatingControlsBoxedGroup>\n\n {hasNav && (\n <>\n <FloatingControlsDivider />\n <MediaNavGroup\n onPrev={onPrev}\n onNext={onNext}\n hasPrev={hasPrev}\n hasNext={hasNext}\n positionLabel={positionLabel}\n />\n </>\n )}\n\n {onDownload && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={filename ? `Download ${filename}` : 'Download'}\n onClick={onDownload}\n >\n <DownloadIcon width={16} height={16} />\n </FloatingControlsButton>\n </>\n )}\n </FloatingControls>\n )}\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","filename","onDownload","onPrev","onNext","hasPrev","hasNext","positionLabel","hasNav","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","FloatingControls","FloatingControlsGroup","FloatingControlsButton","ZoomOutIcon","ZoomInIcon","FloatingControlsDivider","FloatingControlsBoxedGroup","KeyboardArrowLeftIcon","e","KeyboardArrowRightIcon","Fragment","MediaNavGroup","DownloadIcon"],"mappings":"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","file":"PdfDriver-IRXY5HVF.js","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { DownloadIcon } from '../../../Icons/DownloadIcon';\nimport { KeyboardArrowLeftIcon } from '../../../Icons/KeyboardArrowLeftIcon';\nimport { KeyboardArrowRightIcon } from '../../../Icons/KeyboardArrowRightIcon';\nimport { ZoomInIcon } from '../../../Icons/ZoomInIcon';\nimport { ZoomOutIcon } from '../../../Icons/ZoomOutIcon';\nimport {\n FloatingControls,\n FloatingControlsBoxedGroup,\n FloatingControlsButton,\n FloatingControlsDivider,\n FloatingControlsGroup,\n MediaNavGroup,\n} from '../_shared';\nimport type { FileViewerNavProps } from '../../types';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps extends FileViewerNavProps {\n url: string;\n filename?: string;\n onDownload?: () => void;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({\n url,\n filename,\n onDownload,\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n}) => {\n const hasNav = !!(onPrev || onNext);\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div\n data-testid=\"file-viewer-error\"\n data-driver-kind=\"pdf\"\n className=\"flex items-center justify-center h-full w-full px-8.5\"\n >\n <div className=\"text-center text-sm text-text-secondary\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"file-viewer-driver\"\n data-driver-kind=\"pdf\"\n className=\"relative h-full w-full flex flex-col overflow-hidden bg-background-page\"\n >\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-text-secondary\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"relative flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{\n height: height || 'calc(100dvh - 120px)',\n width: '100%',\n scrollbarGutter: 'stable both-edges',\n }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className=\"mx-auto w-fit mb-4 border border-border-subtle\">\n <Page\n pageNumber={index + 1}\n renderTextLayer\n renderAnnotationLayer\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n\n {numPages > 0 && (\n <FloatingControls aria-label=\"PDF controls\">\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label=\"Zoom out\"\n onClick={handleZoomOut}\n disabled={scale <= 0.25}\n >\n <ZoomOutIcon width={16} height={16} />\n </FloatingControlsButton>\n <FloatingControlsButton aria-label=\"Current zoom\">\n {Math.round(scale * 100)}%\n </FloatingControlsButton>\n <FloatingControlsButton\n aria-label=\"Zoom in\"\n onClick={handleZoomIn}\n disabled={scale >= 4}\n >\n <ZoomInIcon width={16} height={16} />\n </FloatingControlsButton>\n </FloatingControlsGroup>\n\n <FloatingControlsDivider />\n\n <FloatingControlsBoxedGroup>\n <FloatingControlsButton\n aria-label=\"Previous page\"\n onClick={previousPage}\n disabled={pageNumber <= 1}\n className=\"px-3!\"\n >\n <KeyboardArrowLeftIcon width={12} height={12} />\n </FloatingControlsButton>\n <span className=\"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center\">\n <input\n type=\"number\"\n min={1}\n max={numPages}\n value={pageNumber}\n onChange={(e) => {\n const page = parseInt(e.target.value, 10);\n if (page >= 1 && page <= numPages) {\n setPageNumber(page);\n debouncedScroll(page, false);\n }\n }}\n className=\"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n />\n <span>/{numPages}</span>\n </span>\n <FloatingControlsButton\n aria-label=\"Next page\"\n onClick={nextPage}\n disabled={pageNumber >= numPages}\n className=\"px-3!\"\n >\n <KeyboardArrowRightIcon width={12} height={12} />\n </FloatingControlsButton>\n </FloatingControlsBoxedGroup>\n\n {hasNav && (\n <>\n <FloatingControlsDivider />\n <MediaNavGroup\n onPrev={onPrev}\n onNext={onNext}\n hasPrev={hasPrev}\n hasNext={hasNext}\n positionLabel={positionLabel}\n />\n </>\n )}\n\n {onDownload && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={filename ? `Download ${filename}` : 'Download'}\n onClick={onDownload}\n >\n <DownloadIcon width={16} height={16} />\n </FloatingControlsButton>\n </>\n )}\n </FloatingControls>\n )}\n </div>\n </div>\n );\n};\n"]}
@@ -1,2 +1,2 @@
1
- import {a as a$1,b,e,d,c,f as f$1}from'./chunk-55VY3QRK.mjs';import'./chunk-7LHQWEWV.mjs';import {k,j,c as c$1,d as d$1,b as b$1}from'./chunk-4O4WHXDT.mjs';import {a}from'./chunk-QWPVIX2T.mjs';import {useState,useRef,useCallback,useMemo,useEffect}from'react';import V from'lodash.debounce';import {pdfjs,Document,Page}from'react-pdf';import'react-pdf/dist/Page/AnnotationLayer.css';import'react-pdf/dist/Page/TextLayer.css';import {Virtuoso}from'react-virtuoso';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var f="/pdfjs";typeof window<"u"&&typeof document<"u"&&(pdfjs.GlobalWorkerOptions.workerSrc=`${f}/pdf.worker.min.js`);var xe=1e3,we=400,Ne=150,Ce=70,Pe=1.414,D=400,Oe=a(({url:W,filename:F,onDownload:I,onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})=>{let J=!!(y||R),[i,Q]=useState(0),[s,h]=useState(1),[X,E]=useState(true),[L,ee]=useState(null),[v,te]=useState(D),[oe,re]=useState(D),[c$2,k$1]=useState(1),[x,ne]=useState(D),[A,ae]=useState(Pe),d$2=useRef(null),T=useRef(null),w=useRef(false),u=useRef(null),N=useRef(false),p=useCallback((t,o=true)=>{t<1||t>i||(w.current=true,T.current?.scrollToIndex({index:t-1,align:"start",behavior:o?"smooth":"auto"}),u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{N.current&&(w.current=false);},xe));},[i]),C=useMemo(()=>V((t,o=false)=>{p(t,o);},we),[p]),ie=useCallback(()=>{k$1(t=>Math.min(t+.25,4));},[]),se=useCallback(()=>{k$1(t=>Math.max(t-.25,.25));},[]);useEffect(()=>{if(!d$2.current)return;let t=V(()=>{d$2.current&&(te(d$2.current.offsetWidth-Ce),re(d$2.current.clientHeight));},Ne);t();let o=new ResizeObserver(t);return o.observe(d$2.current),()=>{o.disconnect(),t.cancel();}},[]);let le=useMemo(()=>({cMapPacked:true,cMapUrl:`${f}/cmaps/`,standardFontDataUrl:`${f}/standard_fonts/`,wasmUrl:`${f}/wasm/`,iccUrl:`${f}/icc/`}),[]),ce=useCallback(({numPages:t})=>{Q(t),E(false);},[]),de=useCallback(t=>{ee(`Failed to load PDF: ${t.message}`),E(false);},[]),g=useCallback(t=>{let o=s+t;h(o),p(o);},[s,p]),ue=useCallback(()=>{g(-1);},[g]),me=useCallback(()=>{g(1);},[g]),fe=useCallback(t=>{if(w.current)return;let o=t.startIndex+1;o!==s&&h(o);},[s]);return useEffect(()=>(N.current=true,()=>{N.current=false,C.cancel(),u.current&&clearTimeout(u.current);}),[C]),useEffect(()=>{ne(v*c$2*A);},[v,c$2,A]),L?jsx("div",{"data-testid":"file-viewer-error","data-driver-kind":"pdf",className:"flex items-center justify-center h-full w-full px-8.5",children:jsx("div",{className:"text-center text-sm text-text-secondary",children:jsx("p",{children:L})})}):jsxs("div",{"data-testid":"file-viewer-driver","data-driver-kind":"pdf",className:"relative h-full w-full flex flex-col overflow-hidden bg-background-page",children:[X&&jsx("div",{className:"flex items-center justify-center h-full px-8.5",children:jsx("div",{className:"text-text-secondary",children:"Loading PDF..."})}),jsxs("div",{ref:d$2,className:"relative flex-1 overflow-hidden min-h-0",children:[jsx(Document,{options:le,file:W,onLoadSuccess:ce,onLoadError:de,loading:jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),children:jsx(Virtuoso,{ref:T,style:{height:oe||"calc(100dvh - 120px)",width:"100%",scrollbarGutter:"stable both-edges"},totalCount:i,rangeChanged:fe,defaultItemHeight:x,itemContent:t=>jsx("div",{className:"mx-auto w-fit mb-4 border border-border-subtle",children:jsx(Page,{pageNumber:t+1,renderTextLayer:true,renderAnnotationLayer:true,width:v*c$2,onLoadSuccess:o=>{if(t===0){let pe=o.height/o.width;ae(pe);}},loading:jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),className:"h-auto w-full transition-[width] duration-[600ms] ease-in-out"})})})}),i>0&&jsxs(a$1,{"aria-label":"PDF controls",children:[jsxs(b,{children:[jsx(e,{"aria-label":"Zoom out",onClick:se,disabled:c$2<=.25,children:jsx(k,{width:16,height:16})}),jsxs(e,{"aria-label":"Current zoom",children:[Math.round(c$2*100),"%"]}),jsx(e,{"aria-label":"Zoom in",onClick:ie,disabled:c$2>=4,children:jsx(j,{width:16,height:16})})]}),jsx(d,{}),jsxs(c,{children:[jsx(e,{"aria-label":"Previous page",onClick:ue,disabled:s<=1,className:"px-3!",children:jsx(c$1,{width:12,height:12})}),jsxs("span",{className:"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center",children:[jsx("input",{type:"number",min:1,max:i,value:s,onChange:t=>{let o=parseInt(t.target.value,10);o>=1&&o<=i&&(h(o),C(o,false));},className:"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"}),jsxs("span",{children:["/",i]})]}),jsx(e,{"aria-label":"Next page",onClick:me,disabled:s>=i,className:"px-3!",children:jsx(d$1,{width:12,height:12})})]}),J&&jsxs(Fragment,{children:[jsx(d,{}),jsx(f$1,{onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})]}),I&&jsxs(Fragment,{children:[jsx(d,{}),jsx(e,{"aria-label":F?`Download ${F}`:"Download",onClick:I,children:jsx(b$1,{width:16,height:16})})]})]})]})]})},"PdfDriver");export{Oe as PdfDriver};//# sourceMappingURL=PdfDriver-LEHFENEC.mjs.map
2
- //# sourceMappingURL=PdfDriver-LEHFENEC.mjs.map
1
+ import {a as a$1,b,e,d,c,f as f$1}from'./chunk-47BJH42B.mjs';import {k,j,c as c$1,d as d$1,b as b$1}from'./chunk-4O4WHXDT.mjs';import'./chunk-7LHQWEWV.mjs';import {a}from'./chunk-QWPVIX2T.mjs';import {useState,useRef,useCallback,useMemo,useEffect}from'react';import V from'lodash.debounce';import {pdfjs,Document,Page}from'react-pdf';import'react-pdf/dist/Page/AnnotationLayer.css';import'react-pdf/dist/Page/TextLayer.css';import {Virtuoso}from'react-virtuoso';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var f="/pdfjs";typeof window<"u"&&typeof document<"u"&&(pdfjs.GlobalWorkerOptions.workerSrc=`${f}/pdf.worker.min.js`);var xe=1e3,we=400,Ne=150,Ce=70,Pe=1.414,D=400,Oe=a(({url:W,filename:F,onDownload:I,onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})=>{let J=!!(y||R),[i,Q]=useState(0),[s,h]=useState(1),[X,E]=useState(true),[L,ee]=useState(null),[v,te]=useState(D),[oe,re]=useState(D),[c$2,k$1]=useState(1),[x,ne]=useState(D),[A,ae]=useState(Pe),d$2=useRef(null),T=useRef(null),w=useRef(false),u=useRef(null),N=useRef(false),p=useCallback((t,o=true)=>{t<1||t>i||(w.current=true,T.current?.scrollToIndex({index:t-1,align:"start",behavior:o?"smooth":"auto"}),u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{N.current&&(w.current=false);},xe));},[i]),C=useMemo(()=>V((t,o=false)=>{p(t,o);},we),[p]),ie=useCallback(()=>{k$1(t=>Math.min(t+.25,4));},[]),se=useCallback(()=>{k$1(t=>Math.max(t-.25,.25));},[]);useEffect(()=>{if(!d$2.current)return;let t=V(()=>{d$2.current&&(te(d$2.current.offsetWidth-Ce),re(d$2.current.clientHeight));},Ne);t();let o=new ResizeObserver(t);return o.observe(d$2.current),()=>{o.disconnect(),t.cancel();}},[]);let le=useMemo(()=>({cMapPacked:true,cMapUrl:`${f}/cmaps/`,standardFontDataUrl:`${f}/standard_fonts/`,wasmUrl:`${f}/wasm/`,iccUrl:`${f}/icc/`}),[]),ce=useCallback(({numPages:t})=>{Q(t),E(false);},[]),de=useCallback(t=>{ee(`Failed to load PDF: ${t.message}`),E(false);},[]),g=useCallback(t=>{let o=s+t;h(o),p(o);},[s,p]),ue=useCallback(()=>{g(-1);},[g]),me=useCallback(()=>{g(1);},[g]),fe=useCallback(t=>{if(w.current)return;let o=t.startIndex+1;o!==s&&h(o);},[s]);return useEffect(()=>(N.current=true,()=>{N.current=false,C.cancel(),u.current&&clearTimeout(u.current);}),[C]),useEffect(()=>{ne(v*c$2*A);},[v,c$2,A]),L?jsx("div",{"data-testid":"file-viewer-error","data-driver-kind":"pdf",className:"flex items-center justify-center h-full w-full px-8.5",children:jsx("div",{className:"text-center text-sm text-text-secondary",children:jsx("p",{children:L})})}):jsxs("div",{"data-testid":"file-viewer-driver","data-driver-kind":"pdf",className:"relative h-full w-full flex flex-col overflow-hidden bg-background-page",children:[X&&jsx("div",{className:"flex items-center justify-center h-full px-8.5",children:jsx("div",{className:"text-text-secondary",children:"Loading PDF..."})}),jsxs("div",{ref:d$2,className:"relative flex-1 overflow-hidden min-h-0",children:[jsx(Document,{options:le,file:W,onLoadSuccess:ce,onLoadError:de,loading:jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),children:jsx(Virtuoso,{ref:T,style:{height:oe||"calc(100dvh - 120px)",width:"100%",scrollbarGutter:"stable both-edges"},totalCount:i,rangeChanged:fe,defaultItemHeight:x,itemContent:t=>jsx("div",{className:"mx-auto w-fit mb-4 border border-border-subtle",children:jsx(Page,{pageNumber:t+1,renderTextLayer:true,renderAnnotationLayer:true,width:v*c$2,onLoadSuccess:o=>{if(t===0){let pe=o.height/o.width;ae(pe);}},loading:jsx("div",{className:"flex items-center justify-center",style:{height:x},children:jsx("div",{className:"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent"})}),className:"h-auto w-full transition-[width] duration-[600ms] ease-in-out"})})})}),i>0&&jsxs(a$1,{"aria-label":"PDF controls",children:[jsxs(b,{children:[jsx(e,{"aria-label":"Zoom out",onClick:se,disabled:c$2<=.25,children:jsx(k,{width:16,height:16})}),jsxs(e,{"aria-label":"Current zoom",children:[Math.round(c$2*100),"%"]}),jsx(e,{"aria-label":"Zoom in",onClick:ie,disabled:c$2>=4,children:jsx(j,{width:16,height:16})})]}),jsx(d,{}),jsxs(c,{children:[jsx(e,{"aria-label":"Previous page",onClick:ue,disabled:s<=1,className:"px-3!",children:jsx(c$1,{width:12,height:12})}),jsxs("span",{className:"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center",children:[jsx("input",{type:"number",min:1,max:i,value:s,onChange:t=>{let o=parseInt(t.target.value,10);o>=1&&o<=i&&(h(o),C(o,false));},className:"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"}),jsxs("span",{children:["/",i]})]}),jsx(e,{"aria-label":"Next page",onClick:me,disabled:s>=i,className:"px-3!",children:jsx(d$1,{width:12,height:12})})]}),J&&jsxs(Fragment,{children:[jsx(d,{}),jsx(f$1,{onPrev:y,onNext:R,hasPrev:K,hasNext:Y,positionLabel:q})]}),I&&jsxs(Fragment,{children:[jsx(d,{}),jsx(e,{"aria-label":F?`Download ${F}`:"Download",onClick:I,children:jsx(b$1,{width:16,height:16})})]})]})]})]})},"PdfDriver");export{Oe as PdfDriver};//# sourceMappingURL=PdfDriver-XCFXTEEH.mjs.map
2
+ //# sourceMappingURL=PdfDriver-XCFXTEEH.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","filename","onDownload","onPrev","onNext","hasPrev","hasNext","positionLabel","hasNav","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","FloatingControls","FloatingControlsGroup","FloatingControlsButton","ZoomOutIcon","ZoomInIcon","FloatingControlsDivider","FloatingControlsBoxedGroup","KeyboardArrowLeftIcon","e","KeyboardArrowRightIcon","Fragment","MediaNavGroup","DownloadIcon"],"mappings":"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","file":"PdfDriver-LEHFENEC.mjs","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { DownloadIcon } from '../../../Icons/DownloadIcon';\nimport { KeyboardArrowLeftIcon } from '../../../Icons/KeyboardArrowLeftIcon';\nimport { KeyboardArrowRightIcon } from '../../../Icons/KeyboardArrowRightIcon';\nimport { ZoomInIcon } from '../../../Icons/ZoomInIcon';\nimport { ZoomOutIcon } from '../../../Icons/ZoomOutIcon';\nimport {\n FloatingControls,\n FloatingControlsBoxedGroup,\n FloatingControlsButton,\n FloatingControlsDivider,\n FloatingControlsGroup,\n MediaNavGroup,\n} from '../_shared';\nimport type { FileViewerNavProps } from '../../types';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps extends FileViewerNavProps {\n url: string;\n filename?: string;\n onDownload?: () => void;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({\n url,\n filename,\n onDownload,\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n}) => {\n const hasNav = !!(onPrev || onNext);\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div\n data-testid=\"file-viewer-error\"\n data-driver-kind=\"pdf\"\n className=\"flex items-center justify-center h-full w-full px-8.5\"\n >\n <div className=\"text-center text-sm text-text-secondary\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"file-viewer-driver\"\n data-driver-kind=\"pdf\"\n className=\"relative h-full w-full flex flex-col overflow-hidden bg-background-page\"\n >\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-text-secondary\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"relative flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{\n height: height || 'calc(100dvh - 120px)',\n width: '100%',\n scrollbarGutter: 'stable both-edges',\n }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className=\"mx-auto w-fit mb-4 border border-border-subtle\">\n <Page\n pageNumber={index + 1}\n renderTextLayer\n renderAnnotationLayer\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n\n {numPages > 0 && (\n <FloatingControls aria-label=\"PDF controls\">\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label=\"Zoom out\"\n onClick={handleZoomOut}\n disabled={scale <= 0.25}\n >\n <ZoomOutIcon width={16} height={16} />\n </FloatingControlsButton>\n <FloatingControlsButton aria-label=\"Current zoom\">\n {Math.round(scale * 100)}%\n </FloatingControlsButton>\n <FloatingControlsButton\n aria-label=\"Zoom in\"\n onClick={handleZoomIn}\n disabled={scale >= 4}\n >\n <ZoomInIcon width={16} height={16} />\n </FloatingControlsButton>\n </FloatingControlsGroup>\n\n <FloatingControlsDivider />\n\n <FloatingControlsBoxedGroup>\n <FloatingControlsButton\n aria-label=\"Previous page\"\n onClick={previousPage}\n disabled={pageNumber <= 1}\n className=\"px-3!\"\n >\n <KeyboardArrowLeftIcon width={12} height={12} />\n </FloatingControlsButton>\n <span className=\"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center\">\n <input\n type=\"number\"\n min={1}\n max={numPages}\n value={pageNumber}\n onChange={(e) => {\n const page = parseInt(e.target.value, 10);\n if (page >= 1 && page <= numPages) {\n setPageNumber(page);\n debouncedScroll(page, false);\n }\n }}\n className=\"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n />\n <span>/{numPages}</span>\n </span>\n <FloatingControlsButton\n aria-label=\"Next page\"\n onClick={nextPage}\n disabled={pageNumber >= numPages}\n className=\"px-3!\"\n >\n <KeyboardArrowRightIcon width={12} height={12} />\n </FloatingControlsButton>\n </FloatingControlsBoxedGroup>\n\n {hasNav && (\n <>\n <FloatingControlsDivider />\n <MediaNavGroup\n onPrev={onPrev}\n onNext={onNext}\n hasPrev={hasPrev}\n hasNext={hasNext}\n positionLabel={positionLabel}\n />\n </>\n )}\n\n {onDownload && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={filename ? `Download ${filename}` : 'Download'}\n onClick={onDownload}\n >\n <DownloadIcon width={16} height={16} />\n </FloatingControlsButton>\n </>\n )}\n </FloatingControls>\n )}\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","filename","onDownload","onPrev","onNext","hasPrev","hasNext","positionLabel","hasNav","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","FloatingControls","FloatingControlsGroup","FloatingControlsButton","ZoomOutIcon","ZoomInIcon","FloatingControlsDivider","FloatingControlsBoxedGroup","KeyboardArrowLeftIcon","e","KeyboardArrowRightIcon","Fragment","MediaNavGroup","DownloadIcon"],"mappings":"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","file":"PdfDriver-XCFXTEEH.mjs","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { DownloadIcon } from '../../../Icons/DownloadIcon';\nimport { KeyboardArrowLeftIcon } from '../../../Icons/KeyboardArrowLeftIcon';\nimport { KeyboardArrowRightIcon } from '../../../Icons/KeyboardArrowRightIcon';\nimport { ZoomInIcon } from '../../../Icons/ZoomInIcon';\nimport { ZoomOutIcon } from '../../../Icons/ZoomOutIcon';\nimport {\n FloatingControls,\n FloatingControlsBoxedGroup,\n FloatingControlsButton,\n FloatingControlsDivider,\n FloatingControlsGroup,\n MediaNavGroup,\n} from '../_shared';\nimport type { FileViewerNavProps } from '../../types';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps extends FileViewerNavProps {\n url: string;\n filename?: string;\n onDownload?: () => void;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({\n url,\n filename,\n onDownload,\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n}) => {\n const hasNav = !!(onPrev || onNext);\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div\n data-testid=\"file-viewer-error\"\n data-driver-kind=\"pdf\"\n className=\"flex items-center justify-center h-full w-full px-8.5\"\n >\n <div className=\"text-center text-sm text-text-secondary\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"file-viewer-driver\"\n data-driver-kind=\"pdf\"\n className=\"relative h-full w-full flex flex-col overflow-hidden bg-background-page\"\n >\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-text-secondary\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"relative flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{\n height: height || 'calc(100dvh - 120px)',\n width: '100%',\n scrollbarGutter: 'stable both-edges',\n }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className=\"mx-auto w-fit mb-4 border border-border-subtle\">\n <Page\n pageNumber={index + 1}\n renderTextLayer\n renderAnnotationLayer\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border-2 border-border-subtle animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n\n {numPages > 0 && (\n <FloatingControls aria-label=\"PDF controls\">\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label=\"Zoom out\"\n onClick={handleZoomOut}\n disabled={scale <= 0.25}\n >\n <ZoomOutIcon width={16} height={16} />\n </FloatingControlsButton>\n <FloatingControlsButton aria-label=\"Current zoom\">\n {Math.round(scale * 100)}%\n </FloatingControlsButton>\n <FloatingControlsButton\n aria-label=\"Zoom in\"\n onClick={handleZoomIn}\n disabled={scale >= 4}\n >\n <ZoomInIcon width={16} height={16} />\n </FloatingControlsButton>\n </FloatingControlsGroup>\n\n <FloatingControlsDivider />\n\n <FloatingControlsBoxedGroup>\n <FloatingControlsButton\n aria-label=\"Previous page\"\n onClick={previousPage}\n disabled={pageNumber <= 1}\n className=\"px-3!\"\n >\n <KeyboardArrowLeftIcon width={12} height={12} />\n </FloatingControlsButton>\n <span className=\"font-plex text-sm leading-4 tracking-[0.16px] text-text-body flex items-center\">\n <input\n type=\"number\"\n min={1}\n max={numPages}\n value={pageNumber}\n onChange={(e) => {\n const page = parseInt(e.target.value, 10);\n if (page >= 1 && page <= numPages) {\n setPageNumber(page);\n debouncedScroll(page, false);\n }\n }}\n className=\"w-8 text-center bg-transparent outline-none font-plex text-sm leading-4 tracking-[0.16px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n />\n <span>/{numPages}</span>\n </span>\n <FloatingControlsButton\n aria-label=\"Next page\"\n onClick={nextPage}\n disabled={pageNumber >= numPages}\n className=\"px-3!\"\n >\n <KeyboardArrowRightIcon width={12} height={12} />\n </FloatingControlsButton>\n </FloatingControlsBoxedGroup>\n\n {hasNav && (\n <>\n <FloatingControlsDivider />\n <MediaNavGroup\n onPrev={onPrev}\n onNext={onNext}\n hasPrev={hasPrev}\n hasNext={hasNext}\n positionLabel={positionLabel}\n />\n </>\n )}\n\n {onDownload && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={filename ? `Download ${filename}` : 'Download'}\n onClick={onDownload}\n >\n <DownloadIcon width={16} height={16} />\n </FloatingControlsButton>\n </>\n )}\n </FloatingControls>\n )}\n </div>\n </div>\n );\n};\n"]}
@@ -1,2 +1,2 @@
1
- import {a as a$1}from'./chunk-7LHQWEWV.mjs';import {c,d,f,g,h,i,a as a$2,e,b}from'./chunk-4O4WHXDT.mjs';import {a}from'./chunk-QWPVIX2T.mjs';import {forwardRef,useRef,useState,useEffect,useCallback}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var me=forwardRef(a(function({className:o,children:n,...s},a){return jsx("div",{ref:a,role:"toolbar",className:a$1("absolute left-1/2 -translate-x-1/2 bottom-4 z-10","flex items-center justify-center gap-2 p-2","bg-background-surface border border-border-subtle shadow-radar-overlay",o),...s,children:n})},"FloatingControls")),A=forwardRef(a(function({className:o,children:n,...s},a){return jsx("div",{ref:a,className:a$1("flex items-center gap-1",o),...s,children:n})},"FloatingControlsGroup")),X=forwardRef(a(function({className:o,children:n,...s},a){return jsx("div",{ref:a,className:a$1("flex items-center border border-border-subtle",o),...s,children:n})},"FloatingControlsBoxedGroup")),k=a(()=>jsx("span",{"aria-hidden":true,className:"self-stretch w-px bg-border-subtle"}),"FloatingControlsDivider"),m=forwardRef(a(function({active:o,className:n,children:s,type:a,...v},d){return jsx("button",{ref:d,type:a??"button",className:a$1("inline-flex items-center justify-center px-2 py-[7px]","font-plex text-sm leading-4 tracking-[0.16px] text-text-body","hover:bg-background-surface-secondary","disabled:opacity-40 disabled:pointer-events-none",o&&"bg-background-surface-secondary",n),...v,children:s})},"FloatingControlsButton"));var z=a(({onPrev:t,onNext:o,hasPrev:n,hasNext:s,positionLabel:a})=>!t&&!o?null:jsxs(X,{"aria-label":"File navigation",children:[jsx(m,{"aria-label":"Previous file",onClick:t,disabled:!t||n===false,className:"px-3!",children:jsx(c,{width:12,height:12})}),a?jsx("span",{className:"flex shrink-0 items-center whitespace-nowrap px-1 font-plex text-sm leading-4 tracking-[0.16px] text-text-body tabular-nums",children:a}):null,jsx(m,{"aria-label":"Next file",onClick:o,disabled:!o||s===false,className:"px-3!",children:jsx(d,{width:12,height:12})})]}),"MediaNavGroup");var V=a(({value:t,max:o,buffered:n,step:s,disabled:a$2,ariaLabel:v,ariaValueText:d,className:x,onChange:u,onChangeStart:E,onChangeEnd:P})=>{let g=useRef(null),p=useRef(false),b=a(i=>Math.min(o,Math.max(0,i)),"clamp"),F=o>0?b(t)/o:0,T=n!=null&&o>0?b(n)/o:0,L=s??(o>0?o/20:.05),D=a(i=>{let S=g.current;if(!S)return 0;let w=S.getBoundingClientRect(),U=w.width>0?(i-w.left)/w.width:0;return b(U*o)},"valueFromClientX"),G=a(i=>{a$2||(i.preventDefault(),p.current=true,g.current?.setPointerCapture(i.pointerId),E?.(),u(D(i.clientX)));},"handlePointerDown"),C=a(i=>{p.current&&u(D(i.clientX));},"handlePointerMove"),H=a(i=>{p.current&&(p.current=false,g.current?.releasePointerCapture(i.pointerId),P?.());},"handlePointerUp"),K=a(i=>{a$2||(i.key==="ArrowLeft"||i.key==="ArrowDown"?(i.preventDefault(),i.stopPropagation(),u(b(t-L))):i.key==="ArrowRight"||i.key==="ArrowUp"?(i.preventDefault(),i.stopPropagation(),u(b(t+L))):i.key==="Home"?(i.preventDefault(),u(0)):i.key==="End"&&(i.preventDefault(),u(o)));},"handleKeyDown");return jsx("div",{ref:g,role:"slider","aria-label":v,"aria-valuemin":0,"aria-valuemax":Number.isFinite(o)?Math.round(o):void 0,"aria-valuenow":Math.round(b(t)),"aria-valuetext":d,"aria-disabled":a$2||void 0,tabIndex:a$2?-1:0,onPointerDown:G,onPointerMove:C,onPointerUp:H,onKeyDown:K,className:a$1("group/slider relative flex h-4 shrink-0 select-none items-center",a$2?"pointer-events-none opacity-40":"cursor-pointer",x),children:jsxs("div",{className:"relative h-1 w-full bg-background-surface-secondary",children:[T>0&&jsx("div",{className:"absolute inset-y-0 left-0 bg-border-disabled",style:{width:`${T*100}%`}}),jsx("div",{className:"absolute inset-y-0 left-0 bg-interactive-link",style:{width:`${F*100}%`}}),jsx("div",{"aria-hidden":true,className:"absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-interactive-link opacity-0 transition-opacity group-hover/slider:opacity-100 group-focus-visible/slider:opacity-100",style:{left:`${F*100}%`}})]})})},"MediaSlider");var $=a(t=>{if(!Number.isFinite(t)||t<0)return "0:00";let o=Math.floor(t),n=Math.floor(o/3600),s=Math.floor(o%3600/60),a=String(o%60).padStart(2,"0");return n>0?`${n}:${String(s).padStart(2,"0")}:${a}`:`${s}:${a}`},"formatTime"),ve=a(({player:t,filename:o,onDownload:n,isFullscreen:s,onToggleFullscreen:a,onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E,className:P})=>{let g$1=!!(v||d),p=!Number.isFinite(t.duration)||t.duration<=0;return jsxs("div",{role:"toolbar","aria-label":"Media controls",className:a$1("flex flex-col gap-2 border border-border-subtle bg-background-surface p-2 shadow-radar-overlay",P),children:[jsx(V,{ariaLabel:"Seek",ariaValueText:`${$(t.currentTime)} / ${$(t.duration)}`,value:t.currentTime,max:t.duration,buffered:t.buffered,step:5,disabled:p,onChange:t.seek,onChangeStart:t.seekStart,onChangeEnd:t.seekEnd}),jsxs("div",{className:"flex items-center gap-2",children:[jsxs(A,{children:[jsx(m,{"aria-label":t.isPlaying?"Pause":"Play",onClick:t.togglePlay,children:t.isPlaying?jsx(f,{width:16,height:16}):jsx(g,{width:16,height:16})}),jsxs(m,{"aria-label":"Playback position",className:"pointer-events-none tabular-nums",children:[$(t.currentTime)," / ",$(t.duration)]})]}),jsx("div",{className:"flex-1"}),jsxs(A,{children:[jsx(m,{"aria-label":t.isMuted||t.volume===0?"Unmute":"Mute",onClick:t.toggleMute,children:t.isMuted||t.volume===0?jsx(h,{width:16,height:16}):jsx(i,{width:16,height:16})}),jsx(V,{ariaLabel:"Volume",value:t.isMuted?0:t.volume,max:1,step:.05,className:"w-20",onChange:t.changeVolume})]}),a&&jsxs(Fragment,{children:[jsx(k,{}),jsx(m,{"aria-label":s?"Exit fullscreen":"Enter fullscreen",onClick:a,children:s?jsx(a$2,{width:16,height:16}):jsx(e,{width:16,height:16})})]}),g$1&&jsxs(Fragment,{children:[jsx(k,{}),jsx(z,{onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E})]}),n&&jsxs(Fragment,{children:[jsx(k,{}),jsx(m,{"aria-label":o?`Download ${o}`:"Download",onClick:n,children:jsx(b,{width:16,height:16})})]})]})]})},"MediaControlBar");var be=a((t,o)=>{let n=useRef(t);n.current=t;let[s,a$1]=useState(false),[v,d]=useState(0),[x,u]=useState(0),[E,P]=useState(0),[g,p]=useState(1),[b,F]=useState(false),[T,L]=useState(false),[D,G]=useState(false),C=useRef(false),H=useRef(false);useEffect(()=>{let e=n.current();if(!e)return;a$1(false),d(0),u(0),P(0),L(false),G(false),C.current=false;let c=a(()=>{u(e.duration),p(e.volume),F(e.muted),L(true);},"onLoadedMetadata"),J=a(()=>u(e.duration),"onDurationChange"),Q=a(()=>{C.current||d(e.currentTime);},"onTimeUpdate"),W=a(()=>{e.buffered.length>0&&P(e.buffered.end(e.buffered.length-1));},"onProgress"),Y=a(()=>a$1(true),"onPlay"),Z=a(()=>a$1(false),"onPause"),_=a(()=>a$1(false),"onEnded"),j=a(()=>{p(e.volume),F(e.muted);},"onVolumeChange"),ee=a(()=>G(true),"onError");return e.addEventListener("loadedmetadata",c),e.addEventListener("durationchange",J),e.addEventListener("timeupdate",Q),e.addEventListener("progress",W),e.addEventListener("play",Y),e.addEventListener("pause",Z),e.addEventListener("ended",_),e.addEventListener("volumechange",j),e.addEventListener("error",ee),e.readyState>=1&&c(),()=>{e.removeEventListener("loadedmetadata",c),e.removeEventListener("durationchange",J),e.removeEventListener("timeupdate",Q),e.removeEventListener("progress",W),e.removeEventListener("play",Y),e.removeEventListener("pause",Z),e.removeEventListener("ended",_),e.removeEventListener("volumechange",j),e.removeEventListener("error",ee);}},[o]);let K=useCallback(()=>{let e=n.current();e&&(e.paused||e.ended?(e.ended&&(e.currentTime=0),e.play().catch(()=>{})):e.pause());},[]),i=useCallback(()=>{let e=n.current();e&&(e.muted||e.volume===0?(e.muted=false,e.volume===0&&(e.volume=.5)):e.muted=true);},[]),S=useCallback(e=>{let c=n.current();c&&(c.volume=e,c.muted=e===0);},[]),w=useCallback(e=>{let c=n.current();c&&(c.currentTime=e,d(e));},[]),U=useCallback(()=>{let e=n.current();C.current=true,H.current=!!e&&!e.paused,e?.pause();},[]),ce=useCallback(()=>{C.current=false,H.current&&n.current()?.play().catch(()=>{});},[]);return {isPlaying:s,currentTime:v,duration:x,buffered:E,volume:g,isMuted:b,metadataLoaded:T,hasError:D,togglePlay:K,toggleMute:i,changeVolume:S,seek:w,seekStart:U,seekEnd:ce}},"useMediaPlayer");export{me as a,A as b,X as c,k as d,m as e,z as f,ve as g,be as h};//# sourceMappingURL=chunk-55VY3QRK.mjs.map
2
- //# sourceMappingURL=chunk-55VY3QRK.mjs.map
1
+ import {c,d,f,g,h,i,a as a$2,e,b}from'./chunk-4O4WHXDT.mjs';import {a as a$1}from'./chunk-7LHQWEWV.mjs';import {a}from'./chunk-QWPVIX2T.mjs';import {forwardRef,useRef,useState,useEffect,useCallback}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var me=forwardRef(a(function({className:o,children:n,...s},a){return jsx("div",{ref:a,role:"toolbar",className:a$1("absolute left-1/2 -translate-x-1/2 bottom-4 z-10","flex items-center justify-center gap-2 p-2","bg-background-surface border border-border-subtle shadow-radar-overlay",o),...s,children:n})},"FloatingControls")),A=forwardRef(a(function({className:o,children:n,...s},a){return jsx("div",{ref:a,className:a$1("flex items-center gap-1",o),...s,children:n})},"FloatingControlsGroup")),X=forwardRef(a(function({className:o,children:n,...s},a){return jsx("div",{ref:a,className:a$1("flex items-center border border-border-subtle",o),...s,children:n})},"FloatingControlsBoxedGroup")),k=a(()=>jsx("span",{"aria-hidden":true,className:"self-stretch w-px bg-border-subtle"}),"FloatingControlsDivider"),m=forwardRef(a(function({active:o,className:n,children:s,type:a,...v},d){return jsx("button",{ref:d,type:a??"button",className:a$1("inline-flex items-center justify-center px-2 py-[7px]","font-plex text-sm leading-4 tracking-[0.16px] text-text-body","hover:bg-background-surface-secondary","disabled:opacity-40 disabled:pointer-events-none",o&&"bg-background-surface-secondary",n),...v,children:s})},"FloatingControlsButton"));var z=a(({onPrev:t,onNext:o,hasPrev:n,hasNext:s,positionLabel:a})=>!t&&!o?null:jsxs(X,{"aria-label":"File navigation",children:[jsx(m,{"aria-label":"Previous file",onClick:t,disabled:!t||n===false,className:"px-3!",children:jsx(c,{width:12,height:12})}),a?jsx("span",{className:"flex shrink-0 items-center whitespace-nowrap px-1 font-plex text-sm leading-4 tracking-[0.16px] text-text-body tabular-nums",children:a}):null,jsx(m,{"aria-label":"Next file",onClick:o,disabled:!o||s===false,className:"px-3!",children:jsx(d,{width:12,height:12})})]}),"MediaNavGroup");var V=a(({value:t,max:o,buffered:n,step:s,disabled:a$2,ariaLabel:v,ariaValueText:d,className:x,onChange:u,onChangeStart:E,onChangeEnd:P})=>{let g=useRef(null),p=useRef(false),b=a(i=>Math.min(o,Math.max(0,i)),"clamp"),F=o>0?b(t)/o:0,T=n!=null&&o>0?b(n)/o:0,L=s??(o>0?o/20:.05),D=a(i=>{let S=g.current;if(!S)return 0;let w=S.getBoundingClientRect(),U=w.width>0?(i-w.left)/w.width:0;return b(U*o)},"valueFromClientX"),G=a(i=>{a$2||(i.preventDefault(),p.current=true,g.current?.setPointerCapture(i.pointerId),E?.(),u(D(i.clientX)));},"handlePointerDown"),C=a(i=>{p.current&&u(D(i.clientX));},"handlePointerMove"),H=a(i=>{p.current&&(p.current=false,g.current?.releasePointerCapture(i.pointerId),P?.());},"handlePointerUp"),K=a(i=>{a$2||(i.key==="ArrowLeft"||i.key==="ArrowDown"?(i.preventDefault(),i.stopPropagation(),u(b(t-L))):i.key==="ArrowRight"||i.key==="ArrowUp"?(i.preventDefault(),i.stopPropagation(),u(b(t+L))):i.key==="Home"?(i.preventDefault(),u(0)):i.key==="End"&&(i.preventDefault(),u(o)));},"handleKeyDown");return jsx("div",{ref:g,role:"slider","aria-label":v,"aria-valuemin":0,"aria-valuemax":Number.isFinite(o)?Math.round(o):void 0,"aria-valuenow":Math.round(b(t)),"aria-valuetext":d,"aria-disabled":a$2||void 0,tabIndex:a$2?-1:0,onPointerDown:G,onPointerMove:C,onPointerUp:H,onKeyDown:K,className:a$1("group/slider relative flex h-4 shrink-0 select-none items-center",a$2?"pointer-events-none opacity-40":"cursor-pointer",x),children:jsxs("div",{className:"relative h-1 w-full bg-background-surface-secondary",children:[T>0&&jsx("div",{className:"absolute inset-y-0 left-0 bg-border-disabled",style:{width:`${T*100}%`}}),jsx("div",{className:"absolute inset-y-0 left-0 bg-interactive-link",style:{width:`${F*100}%`}}),jsx("div",{"aria-hidden":true,className:"absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-interactive-link opacity-0 transition-opacity group-hover/slider:opacity-100 group-focus-visible/slider:opacity-100",style:{left:`${F*100}%`}})]})})},"MediaSlider");var $=a(t=>{if(!Number.isFinite(t)||t<0)return "0:00";let o=Math.floor(t),n=Math.floor(o/3600),s=Math.floor(o%3600/60),a=String(o%60).padStart(2,"0");return n>0?`${n}:${String(s).padStart(2,"0")}:${a}`:`${s}:${a}`},"formatTime"),ve=a(({player:t,filename:o,onDownload:n,isFullscreen:s,onToggleFullscreen:a,onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E,className:P})=>{let g$1=!!(v||d),p=!Number.isFinite(t.duration)||t.duration<=0;return jsxs("div",{role:"toolbar","aria-label":"Media controls",className:a$1("flex flex-col gap-2 border border-border-subtle bg-background-surface p-2 shadow-radar-overlay",P),children:[jsx(V,{ariaLabel:"Seek",ariaValueText:`${$(t.currentTime)} / ${$(t.duration)}`,value:t.currentTime,max:t.duration,buffered:t.buffered,step:5,disabled:p,onChange:t.seek,onChangeStart:t.seekStart,onChangeEnd:t.seekEnd}),jsxs("div",{className:"flex items-center gap-2",children:[jsxs(A,{children:[jsx(m,{"aria-label":t.isPlaying?"Pause":"Play",onClick:t.togglePlay,children:t.isPlaying?jsx(f,{width:16,height:16}):jsx(g,{width:16,height:16})}),jsxs(m,{"aria-label":"Playback position",className:"pointer-events-none tabular-nums",children:[$(t.currentTime)," / ",$(t.duration)]})]}),jsx("div",{className:"flex-1"}),jsxs(A,{children:[jsx(m,{"aria-label":t.isMuted||t.volume===0?"Unmute":"Mute",onClick:t.toggleMute,children:t.isMuted||t.volume===0?jsx(h,{width:16,height:16}):jsx(i,{width:16,height:16})}),jsx(V,{ariaLabel:"Volume",value:t.isMuted?0:t.volume,max:1,step:.05,className:"w-20",onChange:t.changeVolume})]}),a&&jsxs(Fragment,{children:[jsx(k,{}),jsx(m,{"aria-label":s?"Exit fullscreen":"Enter fullscreen",onClick:a,children:s?jsx(a$2,{width:16,height:16}):jsx(e,{width:16,height:16})})]}),g$1&&jsxs(Fragment,{children:[jsx(k,{}),jsx(z,{onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E})]}),n&&jsxs(Fragment,{children:[jsx(k,{}),jsx(m,{"aria-label":o?`Download ${o}`:"Download",onClick:n,children:jsx(b,{width:16,height:16})})]})]})]})},"MediaControlBar");var be=a((t,o)=>{let n=useRef(t);n.current=t;let[s,a$1]=useState(false),[v,d]=useState(0),[x,u]=useState(0),[E,P]=useState(0),[g,p]=useState(1),[b,F]=useState(false),[T,L]=useState(false),[D,G]=useState(false),C=useRef(false),H=useRef(false);useEffect(()=>{let e=n.current();if(!e)return;a$1(false),d(0),u(0),P(0),L(false),G(false),C.current=false;let c=a(()=>{u(e.duration),p(e.volume),F(e.muted),L(true);},"onLoadedMetadata"),J=a(()=>u(e.duration),"onDurationChange"),Q=a(()=>{C.current||d(e.currentTime);},"onTimeUpdate"),W=a(()=>{e.buffered.length>0&&P(e.buffered.end(e.buffered.length-1));},"onProgress"),Y=a(()=>a$1(true),"onPlay"),Z=a(()=>a$1(false),"onPause"),_=a(()=>a$1(false),"onEnded"),j=a(()=>{p(e.volume),F(e.muted);},"onVolumeChange"),ee=a(()=>G(true),"onError");return e.addEventListener("loadedmetadata",c),e.addEventListener("durationchange",J),e.addEventListener("timeupdate",Q),e.addEventListener("progress",W),e.addEventListener("play",Y),e.addEventListener("pause",Z),e.addEventListener("ended",_),e.addEventListener("volumechange",j),e.addEventListener("error",ee),e.readyState>=1&&c(),()=>{e.removeEventListener("loadedmetadata",c),e.removeEventListener("durationchange",J),e.removeEventListener("timeupdate",Q),e.removeEventListener("progress",W),e.removeEventListener("play",Y),e.removeEventListener("pause",Z),e.removeEventListener("ended",_),e.removeEventListener("volumechange",j),e.removeEventListener("error",ee);}},[o]);let K=useCallback(()=>{let e=n.current();e&&(e.paused||e.ended?(e.ended&&(e.currentTime=0),e.play().catch(()=>{})):e.pause());},[]),i=useCallback(()=>{let e=n.current();e&&(e.muted||e.volume===0?(e.muted=false,e.volume===0&&(e.volume=.5)):e.muted=true);},[]),S=useCallback(e=>{let c=n.current();c&&(c.volume=e,c.muted=e===0);},[]),w=useCallback(e=>{let c=n.current();c&&(c.currentTime=e,d(e));},[]),U=useCallback(()=>{let e=n.current();C.current=true,H.current=!!e&&!e.paused,e?.pause();},[]),ce=useCallback(()=>{C.current=false,H.current&&n.current()?.play().catch(()=>{});},[]);return {isPlaying:s,currentTime:v,duration:x,buffered:E,volume:g,isMuted:b,metadataLoaded:T,hasError:D,togglePlay:K,toggleMute:i,changeVolume:S,seek:w,seekStart:U,seekEnd:ce}},"useMediaPlayer");export{me as a,A as b,X as c,k as d,m as e,z as f,ve as g,be as h};//# sourceMappingURL=chunk-47BJH42B.mjs.map
2
+ //# sourceMappingURL=chunk-47BJH42B.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/FileViewer/drivers/_shared/FloatingControls.tsx","../src/FileViewer/drivers/_shared/MediaNavGroup.tsx","../src/FileViewer/drivers/_shared/MediaSlider.tsx","../src/FileViewer/drivers/_shared/MediaControlBar.tsx","../src/FileViewer/drivers/_shared/useMediaPlayer.ts"],"names":["FloatingControls","forwardRef","__name","className","children","rest","ref","jsx","cn","FloatingControlsGroup","FloatingControlsBoxedGroup","FloatingControlsDivider","FloatingControlsButton","active","type","MediaNavGroup","onPrev","onNext","hasPrev","hasNext","positionLabel","jsxs","KeyboardArrowLeftIcon","KeyboardArrowRightIcon","MediaSlider","value","max","buffered","step","disabled","ariaLabel","ariaValueText","onChange","onChangeStart","onChangeEnd","trackRef","useRef","draggingRef","clamp","v","fraction","bufferedFraction","keyStep","valueFromClientX","clientX","el","rect","ratio","handlePointerDown","e","handlePointerMove","handlePointerUp","handleKeyDown","formatTime","seconds","total","h","m","s","MediaControlBar","player","filename","onDownload","isFullscreen","onToggleFullscreen","hasNav","seekDisabled","PauseIcon","PlayArrowIcon","VolumeOffIcon","VolumeUpIcon","Fragment","CloseFullscreenIcon","OpenInFullIcon","DownloadIcon","useMediaPlayer","getMedia","url","getMediaRef","isPlaying","setIsPlaying","useState","currentTime","setCurrentTime","duration","setDuration","setBuffered","volume","setVolume","isMuted","setIsMuted","metadataLoaded","setMetadataLoaded","hasError","setHasError","scrubbingRef","wasPlayingBeforeScrubRef","useEffect","media","onLoadedMetadata","onDurationChange","onTimeUpdate","onProgress","onPlay","onPause","onEnded","onVolumeChange","onError","togglePlay","useCallback","toggleMute","changeVolume","seek","seekStart","seekEnd"],"mappings":"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","file":"chunk-55VY3QRK.mjs","sourcesContent":["import {\n forwardRef,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cn } from '../../../lib/cn';\n\n// Tokens follow Figma \"Document toolbar/Variants\" (Radar-Components 458:22503):\n// - container/buttons/groups have NO rounded corners,\n// - text uses IBM Plex Sans (font-plex) 14px / leading-4 / tracking-[0.16px],\n// - icon-only buttons are 30px tall (px-[8px] py-[7px] + 16px icon),\n// - text-only buttons (e.g. \"100%\") use px-[8px] py-[7px] without an icon spacer.\n\nexport type FloatingControlsProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n};\n\nexport const FloatingControls = forwardRef<HTMLDivElement, FloatingControlsProps>(\n function FloatingControls({ className, children, ...rest }, ref) {\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n className={cn(\n 'absolute left-1/2 -translate-x-1/2 bottom-4 z-10',\n 'flex items-center justify-center gap-2 p-2',\n 'bg-background-surface border border-border-subtle shadow-radar-overlay',\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n }\n);\n\nexport type FloatingControlsGroupProps = HTMLAttributes<HTMLDivElement>;\n\nexport const FloatingControlsGroup = forwardRef<HTMLDivElement, FloatingControlsGroupProps>(\n function FloatingControlsGroup({ className, children, ...rest }, ref) {\n return (\n <div ref={ref} className={cn('flex items-center gap-1', className)} {...rest}>\n {children}\n </div>\n );\n }\n);\n\nexport type FloatingControlsBoxedGroupProps = HTMLAttributes<HTMLDivElement>;\n\nexport const FloatingControlsBoxedGroup = forwardRef<HTMLDivElement, FloatingControlsBoxedGroupProps>(\n function FloatingControlsBoxedGroup({ className, children, ...rest }, ref) {\n return (\n <div\n ref={ref}\n className={cn('flex items-center border border-border-subtle', className)}\n {...rest}\n >\n {children}\n </div>\n );\n }\n);\n\nexport const FloatingControlsDivider = () => (\n <span aria-hidden className=\"self-stretch w-px bg-border-subtle\" />\n);\n\nexport type FloatingControlsButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n active?: boolean;\n};\n\nexport const FloatingControlsButton = forwardRef<HTMLButtonElement, FloatingControlsButtonProps>(\n function FloatingControlsButton({ active, className, children, type, ...rest }, ref) {\n return (\n <button\n ref={ref}\n type={type ?? 'button'}\n className={cn(\n 'inline-flex items-center justify-center px-2 py-[7px]',\n 'font-plex text-sm leading-4 tracking-[0.16px] text-text-body',\n 'hover:bg-background-surface-secondary',\n 'disabled:opacity-40 disabled:pointer-events-none',\n active && 'bg-background-surface-secondary',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n );\n }\n);\n","import { KeyboardArrowLeftIcon } from '../../../Icons/KeyboardArrowLeftIcon';\nimport { KeyboardArrowRightIcon } from '../../../Icons/KeyboardArrowRightIcon';\nimport type { FileViewerNavProps } from '../../types';\nimport { FloatingControlsBoxedGroup, FloatingControlsButton } from './FloatingControls';\n\nexport type MediaNavGroupProps = FileViewerNavProps;\n\n/**\n * Shared prev/next navigation group. Mirrors the PdfDriver page switcher: a\n * bordered group with prev/next buttons around a non-interactive position\n * label. Renders nothing when neither `onPrev` nor `onNext` is provided.\n */\nexport const MediaNavGroup = ({\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n}: MediaNavGroupProps) => {\n if (!onPrev && !onNext) return null;\n\n return (\n <FloatingControlsBoxedGroup aria-label=\"File navigation\">\n <FloatingControlsButton\n aria-label=\"Previous file\"\n onClick={onPrev}\n disabled={!onPrev || hasPrev === false}\n className=\"px-3!\"\n >\n <KeyboardArrowLeftIcon width={12} height={12} />\n </FloatingControlsButton>\n {positionLabel ? (\n <span className=\"flex shrink-0 items-center whitespace-nowrap px-1 font-plex text-sm leading-4 tracking-[0.16px] text-text-body tabular-nums\">\n {positionLabel}\n </span>\n ) : null}\n <FloatingControlsButton\n aria-label=\"Next file\"\n onClick={onNext}\n disabled={!onNext || hasNext === false}\n className=\"px-3!\"\n >\n <KeyboardArrowRightIcon width={12} height={12} />\n </FloatingControlsButton>\n </FloatingControlsBoxedGroup>\n );\n};\n","import {\n useRef,\n type KeyboardEvent as ReactKeyboardEvent,\n type PointerEvent as ReactPointerEvent,\n} from 'react';\nimport { cn } from '../../../lib/cn';\n\nexport interface MediaSliderProps {\n value: number;\n max: number;\n /** Optional secondary fill (e.g. buffered range), in the same unit as `value`. */\n buffered?: number;\n step?: number;\n disabled?: boolean;\n ariaLabel: string;\n ariaValueText?: string;\n className?: string;\n onChange: (value: number) => void;\n onChangeStart?: () => void;\n onChangeEnd?: () => void;\n}\n\n/** Pointer/keyboard slider track shared by the seek bar and the volume control. */\nexport const MediaSlider = ({\n value,\n max,\n buffered,\n step,\n disabled,\n ariaLabel,\n ariaValueText,\n className,\n onChange,\n onChangeStart,\n onChangeEnd,\n}: MediaSliderProps) => {\n const trackRef = useRef<HTMLDivElement>(null);\n const draggingRef = useRef(false);\n\n const clamp = (v: number) => Math.min(max, Math.max(0, v));\n const fraction = max > 0 ? clamp(value) / max : 0;\n const bufferedFraction = buffered != null && max > 0 ? clamp(buffered) / max : 0;\n const keyStep = step ?? (max > 0 ? max / 20 : 0.05);\n\n const valueFromClientX = (clientX: number) => {\n const el = trackRef.current;\n if (!el) return 0;\n const rect = el.getBoundingClientRect();\n const ratio = rect.width > 0 ? (clientX - rect.left) / rect.width : 0;\n return clamp(ratio * max);\n };\n\n const handlePointerDown = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n draggingRef.current = true;\n trackRef.current?.setPointerCapture(e.pointerId);\n onChangeStart?.();\n onChange(valueFromClientX(e.clientX));\n };\n\n const handlePointerMove = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n onChange(valueFromClientX(e.clientX));\n };\n\n const handlePointerUp = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n draggingRef.current = false;\n trackRef.current?.releasePointerCapture(e.pointerId);\n onChangeEnd?.();\n };\n\n const handleKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {\n e.preventDefault();\n e.stopPropagation();\n onChange(clamp(value - keyStep));\n } else if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n onChange(clamp(value + keyStep));\n } else if (e.key === 'Home') {\n e.preventDefault();\n onChange(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n onChange(max);\n }\n };\n\n return (\n <div\n ref={trackRef}\n role=\"slider\"\n aria-label={ariaLabel}\n aria-valuemin={0}\n aria-valuemax={Number.isFinite(max) ? Math.round(max) : undefined}\n aria-valuenow={Math.round(clamp(value))}\n aria-valuetext={ariaValueText}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : 0}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onKeyDown={handleKeyDown}\n className={cn(\n 'group/slider relative flex h-4 shrink-0 select-none items-center',\n disabled ? 'pointer-events-none opacity-40' : 'cursor-pointer',\n className\n )}\n >\n <div className=\"relative h-1 w-full bg-background-surface-secondary\">\n {bufferedFraction > 0 && (\n <div\n className=\"absolute inset-y-0 left-0 bg-border-disabled\"\n style={{ width: `${bufferedFraction * 100}%` }}\n />\n )}\n <div\n className=\"absolute inset-y-0 left-0 bg-interactive-link\"\n style={{ width: `${fraction * 100}%` }}\n />\n <div\n aria-hidden\n className=\"absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-interactive-link opacity-0 transition-opacity group-hover/slider:opacity-100 group-focus-visible/slider:opacity-100\"\n style={{ left: `${fraction * 100}%` }}\n />\n </div>\n </div>\n );\n};\n","import { cn } from '../../../lib/cn';\nimport { CloseFullscreenIcon } from '../../../Icons/CloseFullscreenIcon';\nimport { DownloadIcon } from '../../../Icons/DownloadIcon';\nimport { OpenInFullIcon } from '../../../Icons/OpenInFullIcon';\nimport { PauseIcon } from '../../../Icons/PauseIcon';\nimport { PlayArrowIcon } from '../../../Icons/PlayArrowIcon';\nimport { VolumeOffIcon } from '../../../Icons/VolumeOffIcon';\nimport { VolumeUpIcon } from '../../../Icons/VolumeUpIcon';\nimport type { FileViewerNavProps } from '../../types';\nimport { FloatingControlsButton, FloatingControlsDivider, FloatingControlsGroup } from './FloatingControls';\nimport { MediaNavGroup } from './MediaNavGroup';\nimport { MediaSlider } from './MediaSlider';\nimport type { MediaPlayerApi } from './useMediaPlayer';\n\nconst formatTime = (seconds: number): string => {\n if (!Number.isFinite(seconds) || seconds < 0) return '0:00';\n const total = Math.floor(seconds);\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = String(total % 60).padStart(2, '0');\n return h > 0 ? `${h}:${String(m).padStart(2, '0')}:${s}` : `${m}:${s}`;\n};\n\ninterface MediaControlBarProps extends FileViewerNavProps {\n player: MediaPlayerApi;\n filename?: string;\n onDownload?: () => void;\n /** When `onToggleFullscreen` is provided, a fullscreen button is rendered. */\n isFullscreen?: boolean;\n onToggleFullscreen?: () => void;\n className?: string;\n}\n\n/**\n * Branded control bar for the audio/video drivers — seek bar + play, time,\n * volume, optional fullscreen, prev/next navigation and download. Uses the\n * FloatingControls toolbar tokens for visual consistency with the other drivers.\n */\nexport const MediaControlBar = ({\n player,\n filename,\n onDownload,\n isFullscreen,\n onToggleFullscreen,\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n className,\n}: MediaControlBarProps) => {\n const hasNav = !!(onPrev || onNext);\n const seekDisabled = !Number.isFinite(player.duration) || player.duration <= 0;\n\n return (\n <div\n role=\"toolbar\"\n aria-label=\"Media controls\"\n className={cn(\n 'flex flex-col gap-2 border border-border-subtle bg-background-surface p-2 shadow-radar-overlay',\n className\n )}\n >\n <MediaSlider\n ariaLabel=\"Seek\"\n ariaValueText={`${formatTime(player.currentTime)} / ${formatTime(player.duration)}`}\n value={player.currentTime}\n max={player.duration}\n buffered={player.buffered}\n step={5}\n disabled={seekDisabled}\n onChange={player.seek}\n onChangeStart={player.seekStart}\n onChangeEnd={player.seekEnd}\n />\n\n <div className=\"flex items-center gap-2\">\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label={player.isPlaying ? 'Pause' : 'Play'}\n onClick={player.togglePlay}\n >\n {player.isPlaying ? (\n <PauseIcon width={16} height={16} />\n ) : (\n <PlayArrowIcon width={16} height={16} />\n )}\n </FloatingControlsButton>\n <FloatingControlsButton\n aria-label=\"Playback position\"\n className=\"pointer-events-none tabular-nums\"\n >\n {formatTime(player.currentTime)} / {formatTime(player.duration)}\n </FloatingControlsButton>\n </FloatingControlsGroup>\n\n <div className=\"flex-1\" />\n\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label={player.isMuted || player.volume === 0 ? 'Unmute' : 'Mute'}\n onClick={player.toggleMute}\n >\n {player.isMuted || player.volume === 0 ? (\n <VolumeOffIcon width={16} height={16} />\n ) : (\n <VolumeUpIcon width={16} height={16} />\n )}\n </FloatingControlsButton>\n <MediaSlider\n ariaLabel=\"Volume\"\n value={player.isMuted ? 0 : player.volume}\n max={1}\n step={0.05}\n className=\"w-20\"\n onChange={player.changeVolume}\n />\n </FloatingControlsGroup>\n\n {onToggleFullscreen && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n onClick={onToggleFullscreen}\n >\n {isFullscreen ? (\n <CloseFullscreenIcon width={16} height={16} />\n ) : (\n <OpenInFullIcon width={16} height={16} />\n )}\n </FloatingControlsButton>\n </>\n )}\n\n {hasNav && (\n <>\n <FloatingControlsDivider />\n <MediaNavGroup\n onPrev={onPrev}\n onNext={onNext}\n hasPrev={hasPrev}\n hasNext={hasNext}\n positionLabel={positionLabel}\n />\n </>\n )}\n\n {onDownload && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={filename ? `Download ${filename}` : 'Download'}\n onClick={onDownload}\n >\n <DownloadIcon width={16} height={16} />\n </FloatingControlsButton>\n </>\n )}\n </div>\n </div>\n );\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface MediaPlayerApi {\n isPlaying: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n metadataLoaded: boolean;\n hasError: boolean;\n togglePlay: () => void;\n toggleMute: () => void;\n changeVolume: (value: number) => void;\n seek: (value: number) => void;\n seekStart: () => void;\n seekEnd: () => void;\n}\n\n/**\n * Shared playback state + controls for the `<video>`/`<audio>` drivers. Binds\n * listeners imperatively to the media element (returned by `getMedia`) and\n * resets when `url` changes — both elements are `HTMLMediaElement`, so the\n * logic is identical. Pass a `() => ref.current` getter to avoid ref-type\n * coupling between the two element kinds.\n */\nexport const useMediaPlayer = (\n getMedia: () => HTMLMediaElement | null,\n url: string\n): MediaPlayerApi => {\n const getMediaRef = useRef(getMedia);\n getMediaRef.current = getMedia;\n\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [buffered, setBuffered] = useState(0);\n const [volume, setVolume] = useState(1);\n const [isMuted, setIsMuted] = useState(false);\n const [metadataLoaded, setMetadataLoaded] = useState(false);\n const [hasError, setHasError] = useState(false);\n\n const scrubbingRef = useRef(false);\n const wasPlayingBeforeScrubRef = useRef(false);\n\n useEffect(() => {\n const media = getMediaRef.current();\n if (!media) return;\n\n // Reset for the new source — the driver is reused across navigation.\n setIsPlaying(false);\n setCurrentTime(0);\n setDuration(0);\n setBuffered(0);\n setMetadataLoaded(false);\n setHasError(false);\n scrubbingRef.current = false;\n\n const onLoadedMetadata = () => {\n setDuration(media.duration);\n setVolume(media.volume);\n setIsMuted(media.muted);\n setMetadataLoaded(true);\n };\n const onDurationChange = () => setDuration(media.duration);\n const onTimeUpdate = () => {\n if (!scrubbingRef.current) setCurrentTime(media.currentTime);\n };\n const onProgress = () => {\n if (media.buffered.length > 0) setBuffered(media.buffered.end(media.buffered.length - 1));\n };\n const onPlay = () => setIsPlaying(true);\n const onPause = () => setIsPlaying(false);\n const onEnded = () => setIsPlaying(false);\n const onVolumeChange = () => {\n setVolume(media.volume);\n setIsMuted(media.muted);\n };\n const onError = () => setHasError(true);\n\n media.addEventListener('loadedmetadata', onLoadedMetadata);\n media.addEventListener('durationchange', onDurationChange);\n media.addEventListener('timeupdate', onTimeUpdate);\n media.addEventListener('progress', onProgress);\n media.addEventListener('play', onPlay);\n media.addEventListener('pause', onPause);\n media.addEventListener('ended', onEnded);\n media.addEventListener('volumechange', onVolumeChange);\n media.addEventListener('error', onError);\n\n // Metadata may already be available (cached / fast blob URL).\n if (media.readyState >= 1 /* HAVE_METADATA */) onLoadedMetadata();\n\n return () => {\n media.removeEventListener('loadedmetadata', onLoadedMetadata);\n media.removeEventListener('durationchange', onDurationChange);\n media.removeEventListener('timeupdate', onTimeUpdate);\n media.removeEventListener('progress', onProgress);\n media.removeEventListener('play', onPlay);\n media.removeEventListener('pause', onPause);\n media.removeEventListener('ended', onEnded);\n media.removeEventListener('volumechange', onVolumeChange);\n media.removeEventListener('error', onError);\n };\n }, [url]);\n\n const togglePlay = useCallback(() => {\n const media = getMediaRef.current();\n if (!media) return;\n if (media.paused || media.ended) {\n if (media.ended) media.currentTime = 0;\n void media.play().catch(() => {});\n } else {\n media.pause();\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n const media = getMediaRef.current();\n if (!media) return;\n if (media.muted || media.volume === 0) {\n media.muted = false;\n if (media.volume === 0) media.volume = 0.5;\n } else {\n media.muted = true;\n }\n }, []);\n\n const changeVolume = useCallback((value: number) => {\n const media = getMediaRef.current();\n if (!media) return;\n media.volume = value;\n media.muted = value === 0;\n }, []);\n\n const seek = useCallback((value: number) => {\n const media = getMediaRef.current();\n if (!media) return;\n media.currentTime = value;\n setCurrentTime(value);\n }, []);\n\n const seekStart = useCallback(() => {\n const media = getMediaRef.current();\n scrubbingRef.current = true;\n wasPlayingBeforeScrubRef.current = !!media && !media.paused;\n media?.pause();\n }, []);\n\n const seekEnd = useCallback(() => {\n scrubbingRef.current = false;\n if (wasPlayingBeforeScrubRef.current) void getMediaRef.current()?.play().catch(() => {});\n }, []);\n\n return {\n isPlaying,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n metadataLoaded,\n hasError,\n togglePlay,\n toggleMute,\n changeVolume,\n seek,\n seekStart,\n seekEnd,\n };\n};\n"]}
1
+ {"version":3,"sources":["../src/FileViewer/drivers/_shared/FloatingControls.tsx","../src/FileViewer/drivers/_shared/MediaNavGroup.tsx","../src/FileViewer/drivers/_shared/MediaSlider.tsx","../src/FileViewer/drivers/_shared/MediaControlBar.tsx","../src/FileViewer/drivers/_shared/useMediaPlayer.ts"],"names":["FloatingControls","forwardRef","__name","className","children","rest","ref","jsx","cn","FloatingControlsGroup","FloatingControlsBoxedGroup","FloatingControlsDivider","FloatingControlsButton","active","type","MediaNavGroup","onPrev","onNext","hasPrev","hasNext","positionLabel","jsxs","KeyboardArrowLeftIcon","KeyboardArrowRightIcon","MediaSlider","value","max","buffered","step","disabled","ariaLabel","ariaValueText","onChange","onChangeStart","onChangeEnd","trackRef","useRef","draggingRef","clamp","v","fraction","bufferedFraction","keyStep","valueFromClientX","clientX","el","rect","ratio","handlePointerDown","e","handlePointerMove","handlePointerUp","handleKeyDown","formatTime","seconds","total","h","m","s","MediaControlBar","player","filename","onDownload","isFullscreen","onToggleFullscreen","hasNav","seekDisabled","PauseIcon","PlayArrowIcon","VolumeOffIcon","VolumeUpIcon","Fragment","CloseFullscreenIcon","OpenInFullIcon","DownloadIcon","useMediaPlayer","getMedia","url","getMediaRef","isPlaying","setIsPlaying","useState","currentTime","setCurrentTime","duration","setDuration","setBuffered","volume","setVolume","isMuted","setIsMuted","metadataLoaded","setMetadataLoaded","hasError","setHasError","scrubbingRef","wasPlayingBeforeScrubRef","useEffect","media","onLoadedMetadata","onDurationChange","onTimeUpdate","onProgress","onPlay","onPause","onEnded","onVolumeChange","onError","togglePlay","useCallback","toggleMute","changeVolume","seek","seekStart","seekEnd"],"mappings":"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","file":"chunk-47BJH42B.mjs","sourcesContent":["import {\n forwardRef,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cn } from '../../../lib/cn';\n\n// Tokens follow Figma \"Document toolbar/Variants\" (Radar-Components 458:22503):\n// - container/buttons/groups have NO rounded corners,\n// - text uses IBM Plex Sans (font-plex) 14px / leading-4 / tracking-[0.16px],\n// - icon-only buttons are 30px tall (px-[8px] py-[7px] + 16px icon),\n// - text-only buttons (e.g. \"100%\") use px-[8px] py-[7px] without an icon spacer.\n\nexport type FloatingControlsProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n};\n\nexport const FloatingControls = forwardRef<HTMLDivElement, FloatingControlsProps>(\n function FloatingControls({ className, children, ...rest }, ref) {\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n className={cn(\n 'absolute left-1/2 -translate-x-1/2 bottom-4 z-10',\n 'flex items-center justify-center gap-2 p-2',\n 'bg-background-surface border border-border-subtle shadow-radar-overlay',\n className\n )}\n {...rest}\n >\n {children}\n </div>\n );\n }\n);\n\nexport type FloatingControlsGroupProps = HTMLAttributes<HTMLDivElement>;\n\nexport const FloatingControlsGroup = forwardRef<HTMLDivElement, FloatingControlsGroupProps>(\n function FloatingControlsGroup({ className, children, ...rest }, ref) {\n return (\n <div ref={ref} className={cn('flex items-center gap-1', className)} {...rest}>\n {children}\n </div>\n );\n }\n);\n\nexport type FloatingControlsBoxedGroupProps = HTMLAttributes<HTMLDivElement>;\n\nexport const FloatingControlsBoxedGroup = forwardRef<HTMLDivElement, FloatingControlsBoxedGroupProps>(\n function FloatingControlsBoxedGroup({ className, children, ...rest }, ref) {\n return (\n <div\n ref={ref}\n className={cn('flex items-center border border-border-subtle', className)}\n {...rest}\n >\n {children}\n </div>\n );\n }\n);\n\nexport const FloatingControlsDivider = () => (\n <span aria-hidden className=\"self-stretch w-px bg-border-subtle\" />\n);\n\nexport type FloatingControlsButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n active?: boolean;\n};\n\nexport const FloatingControlsButton = forwardRef<HTMLButtonElement, FloatingControlsButtonProps>(\n function FloatingControlsButton({ active, className, children, type, ...rest }, ref) {\n return (\n <button\n ref={ref}\n type={type ?? 'button'}\n className={cn(\n 'inline-flex items-center justify-center px-2 py-[7px]',\n 'font-plex text-sm leading-4 tracking-[0.16px] text-text-body',\n 'hover:bg-background-surface-secondary',\n 'disabled:opacity-40 disabled:pointer-events-none',\n active && 'bg-background-surface-secondary',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n );\n }\n);\n","import { KeyboardArrowLeftIcon } from '../../../Icons/KeyboardArrowLeftIcon';\nimport { KeyboardArrowRightIcon } from '../../../Icons/KeyboardArrowRightIcon';\nimport type { FileViewerNavProps } from '../../types';\nimport { FloatingControlsBoxedGroup, FloatingControlsButton } from './FloatingControls';\n\nexport type MediaNavGroupProps = FileViewerNavProps;\n\n/**\n * Shared prev/next navigation group. Mirrors the PdfDriver page switcher: a\n * bordered group with prev/next buttons around a non-interactive position\n * label. Renders nothing when neither `onPrev` nor `onNext` is provided.\n */\nexport const MediaNavGroup = ({\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n}: MediaNavGroupProps) => {\n if (!onPrev && !onNext) return null;\n\n return (\n <FloatingControlsBoxedGroup aria-label=\"File navigation\">\n <FloatingControlsButton\n aria-label=\"Previous file\"\n onClick={onPrev}\n disabled={!onPrev || hasPrev === false}\n className=\"px-3!\"\n >\n <KeyboardArrowLeftIcon width={12} height={12} />\n </FloatingControlsButton>\n {positionLabel ? (\n <span className=\"flex shrink-0 items-center whitespace-nowrap px-1 font-plex text-sm leading-4 tracking-[0.16px] text-text-body tabular-nums\">\n {positionLabel}\n </span>\n ) : null}\n <FloatingControlsButton\n aria-label=\"Next file\"\n onClick={onNext}\n disabled={!onNext || hasNext === false}\n className=\"px-3!\"\n >\n <KeyboardArrowRightIcon width={12} height={12} />\n </FloatingControlsButton>\n </FloatingControlsBoxedGroup>\n );\n};\n","import {\n useRef,\n type KeyboardEvent as ReactKeyboardEvent,\n type PointerEvent as ReactPointerEvent,\n} from 'react';\nimport { cn } from '../../../lib/cn';\n\nexport interface MediaSliderProps {\n value: number;\n max: number;\n /** Optional secondary fill (e.g. buffered range), in the same unit as `value`. */\n buffered?: number;\n step?: number;\n disabled?: boolean;\n ariaLabel: string;\n ariaValueText?: string;\n className?: string;\n onChange: (value: number) => void;\n onChangeStart?: () => void;\n onChangeEnd?: () => void;\n}\n\n/** Pointer/keyboard slider track shared by the seek bar and the volume control. */\nexport const MediaSlider = ({\n value,\n max,\n buffered,\n step,\n disabled,\n ariaLabel,\n ariaValueText,\n className,\n onChange,\n onChangeStart,\n onChangeEnd,\n}: MediaSliderProps) => {\n const trackRef = useRef<HTMLDivElement>(null);\n const draggingRef = useRef(false);\n\n const clamp = (v: number) => Math.min(max, Math.max(0, v));\n const fraction = max > 0 ? clamp(value) / max : 0;\n const bufferedFraction = buffered != null && max > 0 ? clamp(buffered) / max : 0;\n const keyStep = step ?? (max > 0 ? max / 20 : 0.05);\n\n const valueFromClientX = (clientX: number) => {\n const el = trackRef.current;\n if (!el) return 0;\n const rect = el.getBoundingClientRect();\n const ratio = rect.width > 0 ? (clientX - rect.left) / rect.width : 0;\n return clamp(ratio * max);\n };\n\n const handlePointerDown = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n draggingRef.current = true;\n trackRef.current?.setPointerCapture(e.pointerId);\n onChangeStart?.();\n onChange(valueFromClientX(e.clientX));\n };\n\n const handlePointerMove = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n onChange(valueFromClientX(e.clientX));\n };\n\n const handlePointerUp = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (!draggingRef.current) return;\n draggingRef.current = false;\n trackRef.current?.releasePointerCapture(e.pointerId);\n onChangeEnd?.();\n };\n\n const handleKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {\n e.preventDefault();\n e.stopPropagation();\n onChange(clamp(value - keyStep));\n } else if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n onChange(clamp(value + keyStep));\n } else if (e.key === 'Home') {\n e.preventDefault();\n onChange(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n onChange(max);\n }\n };\n\n return (\n <div\n ref={trackRef}\n role=\"slider\"\n aria-label={ariaLabel}\n aria-valuemin={0}\n aria-valuemax={Number.isFinite(max) ? Math.round(max) : undefined}\n aria-valuenow={Math.round(clamp(value))}\n aria-valuetext={ariaValueText}\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : 0}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onKeyDown={handleKeyDown}\n className={cn(\n 'group/slider relative flex h-4 shrink-0 select-none items-center',\n disabled ? 'pointer-events-none opacity-40' : 'cursor-pointer',\n className\n )}\n >\n <div className=\"relative h-1 w-full bg-background-surface-secondary\">\n {bufferedFraction > 0 && (\n <div\n className=\"absolute inset-y-0 left-0 bg-border-disabled\"\n style={{ width: `${bufferedFraction * 100}%` }}\n />\n )}\n <div\n className=\"absolute inset-y-0 left-0 bg-interactive-link\"\n style={{ width: `${fraction * 100}%` }}\n />\n <div\n aria-hidden\n className=\"absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-interactive-link opacity-0 transition-opacity group-hover/slider:opacity-100 group-focus-visible/slider:opacity-100\"\n style={{ left: `${fraction * 100}%` }}\n />\n </div>\n </div>\n );\n};\n","import { cn } from '../../../lib/cn';\nimport { CloseFullscreenIcon } from '../../../Icons/CloseFullscreenIcon';\nimport { DownloadIcon } from '../../../Icons/DownloadIcon';\nimport { OpenInFullIcon } from '../../../Icons/OpenInFullIcon';\nimport { PauseIcon } from '../../../Icons/PauseIcon';\nimport { PlayArrowIcon } from '../../../Icons/PlayArrowIcon';\nimport { VolumeOffIcon } from '../../../Icons/VolumeOffIcon';\nimport { VolumeUpIcon } from '../../../Icons/VolumeUpIcon';\nimport type { FileViewerNavProps } from '../../types';\nimport { FloatingControlsButton, FloatingControlsDivider, FloatingControlsGroup } from './FloatingControls';\nimport { MediaNavGroup } from './MediaNavGroup';\nimport { MediaSlider } from './MediaSlider';\nimport type { MediaPlayerApi } from './useMediaPlayer';\n\nconst formatTime = (seconds: number): string => {\n if (!Number.isFinite(seconds) || seconds < 0) return '0:00';\n const total = Math.floor(seconds);\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = String(total % 60).padStart(2, '0');\n return h > 0 ? `${h}:${String(m).padStart(2, '0')}:${s}` : `${m}:${s}`;\n};\n\ninterface MediaControlBarProps extends FileViewerNavProps {\n player: MediaPlayerApi;\n filename?: string;\n onDownload?: () => void;\n /** When `onToggleFullscreen` is provided, a fullscreen button is rendered. */\n isFullscreen?: boolean;\n onToggleFullscreen?: () => void;\n className?: string;\n}\n\n/**\n * Branded control bar for the audio/video drivers — seek bar + play, time,\n * volume, optional fullscreen, prev/next navigation and download. Uses the\n * FloatingControls toolbar tokens for visual consistency with the other drivers.\n */\nexport const MediaControlBar = ({\n player,\n filename,\n onDownload,\n isFullscreen,\n onToggleFullscreen,\n onPrev,\n onNext,\n hasPrev,\n hasNext,\n positionLabel,\n className,\n}: MediaControlBarProps) => {\n const hasNav = !!(onPrev || onNext);\n const seekDisabled = !Number.isFinite(player.duration) || player.duration <= 0;\n\n return (\n <div\n role=\"toolbar\"\n aria-label=\"Media controls\"\n className={cn(\n 'flex flex-col gap-2 border border-border-subtle bg-background-surface p-2 shadow-radar-overlay',\n className\n )}\n >\n <MediaSlider\n ariaLabel=\"Seek\"\n ariaValueText={`${formatTime(player.currentTime)} / ${formatTime(player.duration)}`}\n value={player.currentTime}\n max={player.duration}\n buffered={player.buffered}\n step={5}\n disabled={seekDisabled}\n onChange={player.seek}\n onChangeStart={player.seekStart}\n onChangeEnd={player.seekEnd}\n />\n\n <div className=\"flex items-center gap-2\">\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label={player.isPlaying ? 'Pause' : 'Play'}\n onClick={player.togglePlay}\n >\n {player.isPlaying ? (\n <PauseIcon width={16} height={16} />\n ) : (\n <PlayArrowIcon width={16} height={16} />\n )}\n </FloatingControlsButton>\n <FloatingControlsButton\n aria-label=\"Playback position\"\n className=\"pointer-events-none tabular-nums\"\n >\n {formatTime(player.currentTime)} / {formatTime(player.duration)}\n </FloatingControlsButton>\n </FloatingControlsGroup>\n\n <div className=\"flex-1\" />\n\n <FloatingControlsGroup>\n <FloatingControlsButton\n aria-label={player.isMuted || player.volume === 0 ? 'Unmute' : 'Mute'}\n onClick={player.toggleMute}\n >\n {player.isMuted || player.volume === 0 ? (\n <VolumeOffIcon width={16} height={16} />\n ) : (\n <VolumeUpIcon width={16} height={16} />\n )}\n </FloatingControlsButton>\n <MediaSlider\n ariaLabel=\"Volume\"\n value={player.isMuted ? 0 : player.volume}\n max={1}\n step={0.05}\n className=\"w-20\"\n onChange={player.changeVolume}\n />\n </FloatingControlsGroup>\n\n {onToggleFullscreen && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n onClick={onToggleFullscreen}\n >\n {isFullscreen ? (\n <CloseFullscreenIcon width={16} height={16} />\n ) : (\n <OpenInFullIcon width={16} height={16} />\n )}\n </FloatingControlsButton>\n </>\n )}\n\n {hasNav && (\n <>\n <FloatingControlsDivider />\n <MediaNavGroup\n onPrev={onPrev}\n onNext={onNext}\n hasPrev={hasPrev}\n hasNext={hasNext}\n positionLabel={positionLabel}\n />\n </>\n )}\n\n {onDownload && (\n <>\n <FloatingControlsDivider />\n <FloatingControlsButton\n aria-label={filename ? `Download ${filename}` : 'Download'}\n onClick={onDownload}\n >\n <DownloadIcon width={16} height={16} />\n </FloatingControlsButton>\n </>\n )}\n </div>\n </div>\n );\n};\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface MediaPlayerApi {\n isPlaying: boolean;\n currentTime: number;\n duration: number;\n buffered: number;\n volume: number;\n isMuted: boolean;\n metadataLoaded: boolean;\n hasError: boolean;\n togglePlay: () => void;\n toggleMute: () => void;\n changeVolume: (value: number) => void;\n seek: (value: number) => void;\n seekStart: () => void;\n seekEnd: () => void;\n}\n\n/**\n * Shared playback state + controls for the `<video>`/`<audio>` drivers. Binds\n * listeners imperatively to the media element (returned by `getMedia`) and\n * resets when `url` changes — both elements are `HTMLMediaElement`, so the\n * logic is identical. Pass a `() => ref.current` getter to avoid ref-type\n * coupling between the two element kinds.\n */\nexport const useMediaPlayer = (\n getMedia: () => HTMLMediaElement | null,\n url: string\n): MediaPlayerApi => {\n const getMediaRef = useRef(getMedia);\n getMediaRef.current = getMedia;\n\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n const [buffered, setBuffered] = useState(0);\n const [volume, setVolume] = useState(1);\n const [isMuted, setIsMuted] = useState(false);\n const [metadataLoaded, setMetadataLoaded] = useState(false);\n const [hasError, setHasError] = useState(false);\n\n const scrubbingRef = useRef(false);\n const wasPlayingBeforeScrubRef = useRef(false);\n\n useEffect(() => {\n const media = getMediaRef.current();\n if (!media) return;\n\n // Reset for the new source — the driver is reused across navigation.\n setIsPlaying(false);\n setCurrentTime(0);\n setDuration(0);\n setBuffered(0);\n setMetadataLoaded(false);\n setHasError(false);\n scrubbingRef.current = false;\n\n const onLoadedMetadata = () => {\n setDuration(media.duration);\n setVolume(media.volume);\n setIsMuted(media.muted);\n setMetadataLoaded(true);\n };\n const onDurationChange = () => setDuration(media.duration);\n const onTimeUpdate = () => {\n if (!scrubbingRef.current) setCurrentTime(media.currentTime);\n };\n const onProgress = () => {\n if (media.buffered.length > 0) setBuffered(media.buffered.end(media.buffered.length - 1));\n };\n const onPlay = () => setIsPlaying(true);\n const onPause = () => setIsPlaying(false);\n const onEnded = () => setIsPlaying(false);\n const onVolumeChange = () => {\n setVolume(media.volume);\n setIsMuted(media.muted);\n };\n const onError = () => setHasError(true);\n\n media.addEventListener('loadedmetadata', onLoadedMetadata);\n media.addEventListener('durationchange', onDurationChange);\n media.addEventListener('timeupdate', onTimeUpdate);\n media.addEventListener('progress', onProgress);\n media.addEventListener('play', onPlay);\n media.addEventListener('pause', onPause);\n media.addEventListener('ended', onEnded);\n media.addEventListener('volumechange', onVolumeChange);\n media.addEventListener('error', onError);\n\n // Metadata may already be available (cached / fast blob URL).\n if (media.readyState >= 1 /* HAVE_METADATA */) onLoadedMetadata();\n\n return () => {\n media.removeEventListener('loadedmetadata', onLoadedMetadata);\n media.removeEventListener('durationchange', onDurationChange);\n media.removeEventListener('timeupdate', onTimeUpdate);\n media.removeEventListener('progress', onProgress);\n media.removeEventListener('play', onPlay);\n media.removeEventListener('pause', onPause);\n media.removeEventListener('ended', onEnded);\n media.removeEventListener('volumechange', onVolumeChange);\n media.removeEventListener('error', onError);\n };\n }, [url]);\n\n const togglePlay = useCallback(() => {\n const media = getMediaRef.current();\n if (!media) return;\n if (media.paused || media.ended) {\n if (media.ended) media.currentTime = 0;\n void media.play().catch(() => {});\n } else {\n media.pause();\n }\n }, []);\n\n const toggleMute = useCallback(() => {\n const media = getMediaRef.current();\n if (!media) return;\n if (media.muted || media.volume === 0) {\n media.muted = false;\n if (media.volume === 0) media.volume = 0.5;\n } else {\n media.muted = true;\n }\n }, []);\n\n const changeVolume = useCallback((value: number) => {\n const media = getMediaRef.current();\n if (!media) return;\n media.volume = value;\n media.muted = value === 0;\n }, []);\n\n const seek = useCallback((value: number) => {\n const media = getMediaRef.current();\n if (!media) return;\n media.currentTime = value;\n setCurrentTime(value);\n }, []);\n\n const seekStart = useCallback(() => {\n const media = getMediaRef.current();\n scrubbingRef.current = true;\n wasPlayingBeforeScrubRef.current = !!media && !media.paused;\n media?.pause();\n }, []);\n\n const seekEnd = useCallback(() => {\n scrubbingRef.current = false;\n if (wasPlayingBeforeScrubRef.current) void getMediaRef.current()?.play().catch(() => {});\n }, []);\n\n return {\n isPlaying,\n currentTime,\n duration,\n buffered,\n volume,\n isMuted,\n metadataLoaded,\n hasError,\n togglePlay,\n toggleMute,\n changeVolume,\n seek,\n seekStart,\n seekEnd,\n };\n};\n"]}
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkNQZUCXJV_js=require('./chunk-NQZUCXJV.js'),chunkS3RLHUDJ_js=require('./chunk-S3RLHUDJ.js'),chunkAYDF3IFZ_js=require('./chunk-AYDF3IFZ.js'),react=require('react'),jsxRuntime=require('react/jsx-runtime');var pe=react.forwardRef(chunkAYDF3IFZ_js.a(function({className:o,children:n,...s},a){return jsxRuntime.jsx("div",{ref:a,role:"toolbar",className:chunkNQZUCXJV_js.a("absolute left-1/2 -translate-x-1/2 bottom-4 z-10","flex items-center justify-center gap-2 p-2","bg-background-surface border border-border-subtle shadow-radar-overlay",o),...s,children:n})},"FloatingControls")),I=react.forwardRef(chunkAYDF3IFZ_js.a(function({className:o,children:n,...s},a){return jsxRuntime.jsx("div",{ref:a,className:chunkNQZUCXJV_js.a("flex items-center gap-1",o),...s,children:n})},"FloatingControlsGroup")),z=react.forwardRef(chunkAYDF3IFZ_js.a(function({className:o,children:n,...s},a){return jsxRuntime.jsx("div",{ref:a,className:chunkNQZUCXJV_js.a("flex items-center border border-border-subtle",o),...s,children:n})},"FloatingControlsBoxedGroup")),N=chunkAYDF3IFZ_js.a(()=>jsxRuntime.jsx("span",{"aria-hidden":true,className:"self-stretch w-px bg-border-subtle"}),"FloatingControlsDivider"),m=react.forwardRef(chunkAYDF3IFZ_js.a(function({active:o,className:n,children:s,type:a,...v},d){return jsxRuntime.jsx("button",{ref:d,type:a??"button",className:chunkNQZUCXJV_js.a("inline-flex items-center justify-center px-2 py-[7px]","font-plex text-sm leading-4 tracking-[0.16px] text-text-body","hover:bg-background-surface-secondary","disabled:opacity-40 disabled:pointer-events-none",o&&"bg-background-surface-secondary",n),...v,children:s})},"FloatingControlsButton"));var O=chunkAYDF3IFZ_js.a(({onPrev:t,onNext:o,hasPrev:n,hasNext:s,positionLabel:a})=>!t&&!o?null:jsxRuntime.jsxs(z,{"aria-label":"File navigation",children:[jsxRuntime.jsx(m,{"aria-label":"Previous file",onClick:t,disabled:!t||n===false,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.c,{width:12,height:12})}),a?jsxRuntime.jsx("span",{className:"flex shrink-0 items-center whitespace-nowrap px-1 font-plex text-sm leading-4 tracking-[0.16px] text-text-body tabular-nums",children:a}):null,jsxRuntime.jsx(m,{"aria-label":"Next file",onClick:o,disabled:!o||s===false,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.d,{width:12,height:12})})]}),"MediaNavGroup");var $=chunkAYDF3IFZ_js.a(({value:t,max:o,buffered:n,step:s,disabled:a,ariaLabel:v,ariaValueText:d,className:x,onChange:u,onChangeStart:E,onChangeEnd:P})=>{let g=react.useRef(null),p=react.useRef(false),b=chunkAYDF3IFZ_js.a(i=>Math.min(o,Math.max(0,i)),"clamp"),F=o>0?b(t)/o:0,D=n!=null&&o>0?b(n)/o:0,L=s??(o>0?o/20:.05),G=chunkAYDF3IFZ_js.a(i=>{let R=g.current;if(!R)return 0;let w=R.getBoundingClientRect(),X=w.width>0?(i-w.left)/w.width:0;return b(X*o)},"valueFromClientX"),H=chunkAYDF3IFZ_js.a(i=>{a||(i.preventDefault(),p.current=true,g.current?.setPointerCapture(i.pointerId),E?.(),u(G(i.clientX)));},"handlePointerDown"),C=chunkAYDF3IFZ_js.a(i=>{p.current&&u(G(i.clientX));},"handlePointerMove"),S=chunkAYDF3IFZ_js.a(i=>{p.current&&(p.current=false,g.current?.releasePointerCapture(i.pointerId),P?.());},"handlePointerUp"),U=chunkAYDF3IFZ_js.a(i=>{a||(i.key==="ArrowLeft"||i.key==="ArrowDown"?(i.preventDefault(),i.stopPropagation(),u(b(t-L))):i.key==="ArrowRight"||i.key==="ArrowUp"?(i.preventDefault(),i.stopPropagation(),u(b(t+L))):i.key==="Home"?(i.preventDefault(),u(0)):i.key==="End"&&(i.preventDefault(),u(o)));},"handleKeyDown");return jsxRuntime.jsx("div",{ref:g,role:"slider","aria-label":v,"aria-valuemin":0,"aria-valuemax":Number.isFinite(o)?Math.round(o):void 0,"aria-valuenow":Math.round(b(t)),"aria-valuetext":d,"aria-disabled":a||void 0,tabIndex:a?-1:0,onPointerDown:H,onPointerMove:C,onPointerUp:S,onKeyDown:U,className:chunkNQZUCXJV_js.a("group/slider relative flex h-4 shrink-0 select-none items-center",a?"pointer-events-none opacity-40":"cursor-pointer",x),children:jsxRuntime.jsxs("div",{className:"relative h-1 w-full bg-background-surface-secondary",children:[D>0&&jsxRuntime.jsx("div",{className:"absolute inset-y-0 left-0 bg-border-disabled",style:{width:`${D*100}%`}}),jsxRuntime.jsx("div",{className:"absolute inset-y-0 left-0 bg-interactive-link",style:{width:`${F*100}%`}}),jsxRuntime.jsx("div",{"aria-hidden":true,className:"absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-interactive-link opacity-0 transition-opacity group-hover/slider:opacity-100 group-focus-visible/slider:opacity-100",style:{left:`${F*100}%`}})]})})},"MediaSlider");var K=chunkAYDF3IFZ_js.a(t=>{if(!Number.isFinite(t)||t<0)return "0:00";let o=Math.floor(t),n=Math.floor(o/3600),s=Math.floor(o%3600/60),a=String(o%60).padStart(2,"0");return n>0?`${n}:${String(s).padStart(2,"0")}:${a}`:`${s}:${a}`},"formatTime"),ge=chunkAYDF3IFZ_js.a(({player:t,filename:o,onDownload:n,isFullscreen:s,onToggleFullscreen:a,onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E,className:P})=>{let g=!!(v||d),p=!Number.isFinite(t.duration)||t.duration<=0;return jsxRuntime.jsxs("div",{role:"toolbar","aria-label":"Media controls",className:chunkNQZUCXJV_js.a("flex flex-col gap-2 border border-border-subtle bg-background-surface p-2 shadow-radar-overlay",P),children:[jsxRuntime.jsx($,{ariaLabel:"Seek",ariaValueText:`${K(t.currentTime)} / ${K(t.duration)}`,value:t.currentTime,max:t.duration,buffered:t.buffered,step:5,disabled:p,onChange:t.seek,onChangeStart:t.seekStart,onChangeEnd:t.seekEnd}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsxs(I,{children:[jsxRuntime.jsx(m,{"aria-label":t.isPlaying?"Pause":"Play",onClick:t.togglePlay,children:t.isPlaying?jsxRuntime.jsx(chunkS3RLHUDJ_js.f,{width:16,height:16}):jsxRuntime.jsx(chunkS3RLHUDJ_js.g,{width:16,height:16})}),jsxRuntime.jsxs(m,{"aria-label":"Playback position",className:"pointer-events-none tabular-nums",children:[K(t.currentTime)," / ",K(t.duration)]})]}),jsxRuntime.jsx("div",{className:"flex-1"}),jsxRuntime.jsxs(I,{children:[jsxRuntime.jsx(m,{"aria-label":t.isMuted||t.volume===0?"Unmute":"Mute",onClick:t.toggleMute,children:t.isMuted||t.volume===0?jsxRuntime.jsx(chunkS3RLHUDJ_js.h,{width:16,height:16}):jsxRuntime.jsx(chunkS3RLHUDJ_js.i,{width:16,height:16})}),jsxRuntime.jsx($,{ariaLabel:"Volume",value:t.isMuted?0:t.volume,max:1,step:.05,className:"w-20",onChange:t.changeVolume})]}),a&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(N,{}),jsxRuntime.jsx(m,{"aria-label":s?"Exit fullscreen":"Enter fullscreen",onClick:a,children:s?jsxRuntime.jsx(chunkS3RLHUDJ_js.a,{width:16,height:16}):jsxRuntime.jsx(chunkS3RLHUDJ_js.e,{width:16,height:16})})]}),g&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(N,{}),jsxRuntime.jsx(O,{onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E})]}),n&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(N,{}),jsxRuntime.jsx(m,{"aria-label":o?`Download ${o}`:"Download",onClick:n,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.b,{width:16,height:16})})]})]})]})},"MediaControlBar");var he=chunkAYDF3IFZ_js.a((t,o)=>{let n=react.useRef(t);n.current=t;let[s,a]=react.useState(false),[v,d]=react.useState(0),[x,u]=react.useState(0),[E,P]=react.useState(0),[g,p]=react.useState(1),[b,F]=react.useState(false),[D,L]=react.useState(false),[G,H]=react.useState(false),C=react.useRef(false),S=react.useRef(false);react.useEffect(()=>{let e=n.current();if(!e)return;a(false),d(0),u(0),P(0),L(false),H(false),C.current=false;let c=chunkAYDF3IFZ_js.a(()=>{u(e.duration),p(e.volume),F(e.muted),L(true);},"onLoadedMetadata"),Q=chunkAYDF3IFZ_js.a(()=>u(e.duration),"onDurationChange"),W=chunkAYDF3IFZ_js.a(()=>{C.current||d(e.currentTime);},"onTimeUpdate"),Y=chunkAYDF3IFZ_js.a(()=>{e.buffered.length>0&&P(e.buffered.end(e.buffered.length-1));},"onProgress"),Z=chunkAYDF3IFZ_js.a(()=>a(true),"onPlay"),_=chunkAYDF3IFZ_js.a(()=>a(false),"onPause"),j=chunkAYDF3IFZ_js.a(()=>a(false),"onEnded"),ee=chunkAYDF3IFZ_js.a(()=>{p(e.volume),F(e.muted);},"onVolumeChange"),te=chunkAYDF3IFZ_js.a(()=>H(true),"onError");return e.addEventListener("loadedmetadata",c),e.addEventListener("durationchange",Q),e.addEventListener("timeupdate",W),e.addEventListener("progress",Y),e.addEventListener("play",Z),e.addEventListener("pause",_),e.addEventListener("ended",j),e.addEventListener("volumechange",ee),e.addEventListener("error",te),e.readyState>=1&&c(),()=>{e.removeEventListener("loadedmetadata",c),e.removeEventListener("durationchange",Q),e.removeEventListener("timeupdate",W),e.removeEventListener("progress",Y),e.removeEventListener("play",Z),e.removeEventListener("pause",_),e.removeEventListener("ended",j),e.removeEventListener("volumechange",ee),e.removeEventListener("error",te);}},[o]);let U=react.useCallback(()=>{let e=n.current();e&&(e.paused||e.ended?(e.ended&&(e.currentTime=0),e.play().catch(()=>{})):e.pause());},[]),i=react.useCallback(()=>{let e=n.current();e&&(e.muted||e.volume===0?(e.muted=false,e.volume===0&&(e.volume=.5)):e.muted=true);},[]),R=react.useCallback(e=>{let c=n.current();c&&(c.volume=e,c.muted=e===0);},[]),w=react.useCallback(e=>{let c=n.current();c&&(c.currentTime=e,d(e));},[]),X=react.useCallback(()=>{let e=n.current();C.current=true,S.current=!!e&&!e.paused,e?.pause();},[]),me=react.useCallback(()=>{C.current=false,S.current&&n.current()?.play().catch(()=>{});},[]);return {isPlaying:s,currentTime:v,duration:x,buffered:E,volume:g,isMuted:b,metadataLoaded:D,hasError:G,togglePlay:U,toggleMute:i,changeVolume:R,seek:w,seekStart:X,seekEnd:me}},"useMediaPlayer");exports.a=pe;exports.b=I;exports.c=z;exports.d=N;exports.e=m;exports.f=O;exports.g=ge;exports.h=he;//# sourceMappingURL=chunk-YAP3G27F.js.map
2
- //# sourceMappingURL=chunk-YAP3G27F.js.map
1
+ 'use strict';var chunkS3RLHUDJ_js=require('./chunk-S3RLHUDJ.js'),chunkNQZUCXJV_js=require('./chunk-NQZUCXJV.js'),chunkAYDF3IFZ_js=require('./chunk-AYDF3IFZ.js'),react=require('react'),jsxRuntime=require('react/jsx-runtime');var pe=react.forwardRef(chunkAYDF3IFZ_js.a(function({className:o,children:n,...s},a){return jsxRuntime.jsx("div",{ref:a,role:"toolbar",className:chunkNQZUCXJV_js.a("absolute left-1/2 -translate-x-1/2 bottom-4 z-10","flex items-center justify-center gap-2 p-2","bg-background-surface border border-border-subtle shadow-radar-overlay",o),...s,children:n})},"FloatingControls")),I=react.forwardRef(chunkAYDF3IFZ_js.a(function({className:o,children:n,...s},a){return jsxRuntime.jsx("div",{ref:a,className:chunkNQZUCXJV_js.a("flex items-center gap-1",o),...s,children:n})},"FloatingControlsGroup")),z=react.forwardRef(chunkAYDF3IFZ_js.a(function({className:o,children:n,...s},a){return jsxRuntime.jsx("div",{ref:a,className:chunkNQZUCXJV_js.a("flex items-center border border-border-subtle",o),...s,children:n})},"FloatingControlsBoxedGroup")),N=chunkAYDF3IFZ_js.a(()=>jsxRuntime.jsx("span",{"aria-hidden":true,className:"self-stretch w-px bg-border-subtle"}),"FloatingControlsDivider"),m=react.forwardRef(chunkAYDF3IFZ_js.a(function({active:o,className:n,children:s,type:a,...v},d){return jsxRuntime.jsx("button",{ref:d,type:a??"button",className:chunkNQZUCXJV_js.a("inline-flex items-center justify-center px-2 py-[7px]","font-plex text-sm leading-4 tracking-[0.16px] text-text-body","hover:bg-background-surface-secondary","disabled:opacity-40 disabled:pointer-events-none",o&&"bg-background-surface-secondary",n),...v,children:s})},"FloatingControlsButton"));var O=chunkAYDF3IFZ_js.a(({onPrev:t,onNext:o,hasPrev:n,hasNext:s,positionLabel:a})=>!t&&!o?null:jsxRuntime.jsxs(z,{"aria-label":"File navigation",children:[jsxRuntime.jsx(m,{"aria-label":"Previous file",onClick:t,disabled:!t||n===false,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.c,{width:12,height:12})}),a?jsxRuntime.jsx("span",{className:"flex shrink-0 items-center whitespace-nowrap px-1 font-plex text-sm leading-4 tracking-[0.16px] text-text-body tabular-nums",children:a}):null,jsxRuntime.jsx(m,{"aria-label":"Next file",onClick:o,disabled:!o||s===false,className:"px-3!",children:jsxRuntime.jsx(chunkS3RLHUDJ_js.d,{width:12,height:12})})]}),"MediaNavGroup");var $=chunkAYDF3IFZ_js.a(({value:t,max:o,buffered:n,step:s,disabled:a,ariaLabel:v,ariaValueText:d,className:x,onChange:u,onChangeStart:E,onChangeEnd:P})=>{let g=react.useRef(null),p=react.useRef(false),b=chunkAYDF3IFZ_js.a(i=>Math.min(o,Math.max(0,i)),"clamp"),F=o>0?b(t)/o:0,D=n!=null&&o>0?b(n)/o:0,L=s??(o>0?o/20:.05),G=chunkAYDF3IFZ_js.a(i=>{let R=g.current;if(!R)return 0;let w=R.getBoundingClientRect(),X=w.width>0?(i-w.left)/w.width:0;return b(X*o)},"valueFromClientX"),H=chunkAYDF3IFZ_js.a(i=>{a||(i.preventDefault(),p.current=true,g.current?.setPointerCapture(i.pointerId),E?.(),u(G(i.clientX)));},"handlePointerDown"),C=chunkAYDF3IFZ_js.a(i=>{p.current&&u(G(i.clientX));},"handlePointerMove"),S=chunkAYDF3IFZ_js.a(i=>{p.current&&(p.current=false,g.current?.releasePointerCapture(i.pointerId),P?.());},"handlePointerUp"),U=chunkAYDF3IFZ_js.a(i=>{a||(i.key==="ArrowLeft"||i.key==="ArrowDown"?(i.preventDefault(),i.stopPropagation(),u(b(t-L))):i.key==="ArrowRight"||i.key==="ArrowUp"?(i.preventDefault(),i.stopPropagation(),u(b(t+L))):i.key==="Home"?(i.preventDefault(),u(0)):i.key==="End"&&(i.preventDefault(),u(o)));},"handleKeyDown");return jsxRuntime.jsx("div",{ref:g,role:"slider","aria-label":v,"aria-valuemin":0,"aria-valuemax":Number.isFinite(o)?Math.round(o):void 0,"aria-valuenow":Math.round(b(t)),"aria-valuetext":d,"aria-disabled":a||void 0,tabIndex:a?-1:0,onPointerDown:H,onPointerMove:C,onPointerUp:S,onKeyDown:U,className:chunkNQZUCXJV_js.a("group/slider relative flex h-4 shrink-0 select-none items-center",a?"pointer-events-none opacity-40":"cursor-pointer",x),children:jsxRuntime.jsxs("div",{className:"relative h-1 w-full bg-background-surface-secondary",children:[D>0&&jsxRuntime.jsx("div",{className:"absolute inset-y-0 left-0 bg-border-disabled",style:{width:`${D*100}%`}}),jsxRuntime.jsx("div",{className:"absolute inset-y-0 left-0 bg-interactive-link",style:{width:`${F*100}%`}}),jsxRuntime.jsx("div",{"aria-hidden":true,className:"absolute top-1/2 size-3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-interactive-link opacity-0 transition-opacity group-hover/slider:opacity-100 group-focus-visible/slider:opacity-100",style:{left:`${F*100}%`}})]})})},"MediaSlider");var K=chunkAYDF3IFZ_js.a(t=>{if(!Number.isFinite(t)||t<0)return "0:00";let o=Math.floor(t),n=Math.floor(o/3600),s=Math.floor(o%3600/60),a=String(o%60).padStart(2,"0");return n>0?`${n}:${String(s).padStart(2,"0")}:${a}`:`${s}:${a}`},"formatTime"),ge=chunkAYDF3IFZ_js.a(({player:t,filename:o,onDownload:n,isFullscreen:s,onToggleFullscreen:a,onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E,className:P})=>{let g=!!(v||d),p=!Number.isFinite(t.duration)||t.duration<=0;return jsxRuntime.jsxs("div",{role:"toolbar","aria-label":"Media controls",className:chunkNQZUCXJV_js.a("flex flex-col gap-2 border border-border-subtle bg-background-surface p-2 shadow-radar-overlay",P),children:[jsxRuntime.jsx($,{ariaLabel:"Seek",ariaValueText:`${K(t.currentTime)} / ${K(t.duration)}`,value:t.currentTime,max:t.duration,buffered:t.buffered,step:5,disabled:p,onChange:t.seek,onChangeStart:t.seekStart,onChangeEnd:t.seekEnd}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsxs(I,{children:[jsxRuntime.jsx(m,{"aria-label":t.isPlaying?"Pause":"Play",onClick:t.togglePlay,children:t.isPlaying?jsxRuntime.jsx(chunkS3RLHUDJ_js.f,{width:16,height:16}):jsxRuntime.jsx(chunkS3RLHUDJ_js.g,{width:16,height:16})}),jsxRuntime.jsxs(m,{"aria-label":"Playback position",className:"pointer-events-none tabular-nums",children:[K(t.currentTime)," / ",K(t.duration)]})]}),jsxRuntime.jsx("div",{className:"flex-1"}),jsxRuntime.jsxs(I,{children:[jsxRuntime.jsx(m,{"aria-label":t.isMuted||t.volume===0?"Unmute":"Mute",onClick:t.toggleMute,children:t.isMuted||t.volume===0?jsxRuntime.jsx(chunkS3RLHUDJ_js.h,{width:16,height:16}):jsxRuntime.jsx(chunkS3RLHUDJ_js.i,{width:16,height:16})}),jsxRuntime.jsx($,{ariaLabel:"Volume",value:t.isMuted?0:t.volume,max:1,step:.05,className:"w-20",onChange:t.changeVolume})]}),a&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(N,{}),jsxRuntime.jsx(m,{"aria-label":s?"Exit fullscreen":"Enter fullscreen",onClick:a,children:s?jsxRuntime.jsx(chunkS3RLHUDJ_js.a,{width:16,height:16}):jsxRuntime.jsx(chunkS3RLHUDJ_js.e,{width:16,height:16})})]}),g&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(N,{}),jsxRuntime.jsx(O,{onPrev:v,onNext:d,hasPrev:x,hasNext:u,positionLabel:E})]}),n&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(N,{}),jsxRuntime.jsx(m,{"aria-label":o?`Download ${o}`:"Download",onClick:n,children:jsxRuntime.jsx(chunkS3RLHUDJ_js.b,{width:16,height:16})})]})]})]})},"MediaControlBar");var he=chunkAYDF3IFZ_js.a((t,o)=>{let n=react.useRef(t);n.current=t;let[s,a]=react.useState(false),[v,d]=react.useState(0),[x,u]=react.useState(0),[E,P]=react.useState(0),[g,p]=react.useState(1),[b,F]=react.useState(false),[D,L]=react.useState(false),[G,H]=react.useState(false),C=react.useRef(false),S=react.useRef(false);react.useEffect(()=>{let e=n.current();if(!e)return;a(false),d(0),u(0),P(0),L(false),H(false),C.current=false;let c=chunkAYDF3IFZ_js.a(()=>{u(e.duration),p(e.volume),F(e.muted),L(true);},"onLoadedMetadata"),Q=chunkAYDF3IFZ_js.a(()=>u(e.duration),"onDurationChange"),W=chunkAYDF3IFZ_js.a(()=>{C.current||d(e.currentTime);},"onTimeUpdate"),Y=chunkAYDF3IFZ_js.a(()=>{e.buffered.length>0&&P(e.buffered.end(e.buffered.length-1));},"onProgress"),Z=chunkAYDF3IFZ_js.a(()=>a(true),"onPlay"),_=chunkAYDF3IFZ_js.a(()=>a(false),"onPause"),j=chunkAYDF3IFZ_js.a(()=>a(false),"onEnded"),ee=chunkAYDF3IFZ_js.a(()=>{p(e.volume),F(e.muted);},"onVolumeChange"),te=chunkAYDF3IFZ_js.a(()=>H(true),"onError");return e.addEventListener("loadedmetadata",c),e.addEventListener("durationchange",Q),e.addEventListener("timeupdate",W),e.addEventListener("progress",Y),e.addEventListener("play",Z),e.addEventListener("pause",_),e.addEventListener("ended",j),e.addEventListener("volumechange",ee),e.addEventListener("error",te),e.readyState>=1&&c(),()=>{e.removeEventListener("loadedmetadata",c),e.removeEventListener("durationchange",Q),e.removeEventListener("timeupdate",W),e.removeEventListener("progress",Y),e.removeEventListener("play",Z),e.removeEventListener("pause",_),e.removeEventListener("ended",j),e.removeEventListener("volumechange",ee),e.removeEventListener("error",te);}},[o]);let U=react.useCallback(()=>{let e=n.current();e&&(e.paused||e.ended?(e.ended&&(e.currentTime=0),e.play().catch(()=>{})):e.pause());},[]),i=react.useCallback(()=>{let e=n.current();e&&(e.muted||e.volume===0?(e.muted=false,e.volume===0&&(e.volume=.5)):e.muted=true);},[]),R=react.useCallback(e=>{let c=n.current();c&&(c.volume=e,c.muted=e===0);},[]),w=react.useCallback(e=>{let c=n.current();c&&(c.currentTime=e,d(e));},[]),X=react.useCallback(()=>{let e=n.current();C.current=true,S.current=!!e&&!e.paused,e?.pause();},[]),me=react.useCallback(()=>{C.current=false,S.current&&n.current()?.play().catch(()=>{});},[]);return {isPlaying:s,currentTime:v,duration:x,buffered:E,volume:g,isMuted:b,metadataLoaded:D,hasError:G,togglePlay:U,toggleMute:i,changeVolume:R,seek:w,seekStart:X,seekEnd:me}},"useMediaPlayer");exports.a=pe;exports.b=I;exports.c=z;exports.d=N;exports.e=m;exports.f=O;exports.g=ge;exports.h=he;//# sourceMappingURL=chunk-JVDLOXO7.js.map
2
+ //# sourceMappingURL=chunk-JVDLOXO7.js.map